mirror of https://github.com/WerWolv/ImHex
Fix segfault when opening recent file with pattern sync; Don't show p… (#2448)
…attern selection popup when pattern is already open This PR does two things. Most importantly, it fixes a segfault that can be caused by opening a recent file with pattern sync enabled. Secondly, it makes it so that the pattern selection popup does not appear if you already have text in the pattern editor for a given provider (due to CLI args, a project file, pattern sync, etc.). If you open a file normally, that text field is empty and the popup will appear so you can select a pre-made pattern like usual.
This commit is contained in:
parent
f08b182bf2
commit
67efea6444
|
|
@ -40,8 +40,12 @@ namespace hex::plugin::builtin {
|
||||||
return &m_editorRuntime;
|
return &m_editorRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui::TextEditor &getTextEditor() {
|
ui::TextEditor *getTextEditor() {
|
||||||
return m_textEditor;
|
auto provider = ImHexApi::Provider::get();
|
||||||
|
if (provider == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &m_textEditor.get(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getChangesWereParsed() const {
|
bool getChangesWereParsed() const {
|
||||||
|
|
|
||||||
|
|
@ -1252,7 +1252,11 @@ namespace hex::plugin::builtin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_viewPatternEditor->getTextEditor().setErrorMarkers(errorMarkers);
|
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||||
|
if (editor != nullptr)
|
||||||
|
editor->setErrorMarkers(errorMarkers);
|
||||||
|
else
|
||||||
|
log::warn("Text editor not found, provider is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates a map from variable names to a vector of token indices
|
// creates a map from variable names to a vector of token indices
|
||||||
|
|
@ -1590,7 +1594,11 @@ namespace hex::plugin::builtin {
|
||||||
lineOfColors[tokenOffset + j] = color;
|
lineOfColors[tokenOffset + j] = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_viewPatternEditor->getTextEditor().setColorizedLine(line, lineOfColors);
|
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||||
|
if (editor != nullptr)
|
||||||
|
editor->setColorizedLine(line, lineOfColors);
|
||||||
|
else
|
||||||
|
log::warn("Text editor not found, provider is null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1918,8 +1926,13 @@ namespace hex::plugin::builtin {
|
||||||
if (!m_lines.empty())
|
if (!m_lines.empty())
|
||||||
m_lines.clear();
|
m_lines.clear();
|
||||||
|
|
||||||
if (m_text.empty())
|
if (m_text.empty()) {
|
||||||
m_text = m_viewPatternEditor->getTextEditor().getText();
|
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||||
|
if (editor != nullptr)
|
||||||
|
m_text = editor->getText();
|
||||||
|
else
|
||||||
|
log::warn("Text editor not found, provider is null");
|
||||||
|
}
|
||||||
|
|
||||||
m_lines = wolv::util::splitString(m_text, "\n");
|
m_lines = wolv::util::splitString(m_text, "\n");
|
||||||
m_lines.push_back("");
|
m_lines.push_back("");
|
||||||
|
|
@ -2248,72 +2261,85 @@ namespace hex::plugin::builtin {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
m_runningColorizers++;
|
m_runningColorizers++;
|
||||||
auto preprocessor = patternLanguage->get()->getInternals().preprocessor.get();
|
auto preprocessor = patternLanguage->get()->getInternals().preprocessor.get();
|
||||||
auto parser = patternLanguage->get()->getInternals().parser.get();
|
auto parser = patternLanguage->get()->getInternals().parser.get();
|
||||||
using Types = std::map<std::string, pl::hlp::safe_shared_ptr<pl::core::ast::ASTNodeTypeDecl>>;
|
using Types = std::map<std::string, pl::hlp::safe_shared_ptr<pl::core::ast::ASTNodeTypeDecl>>;
|
||||||
Types types = parser->getTypes();
|
Types types = parser->getTypes();
|
||||||
|
|
||||||
if (!m_UDTs.empty())
|
if (!m_UDTs.empty())
|
||||||
m_UDTs.clear();
|
m_UDTs.clear();
|
||||||
for (auto &[name, type]: types)
|
for (auto &[name, type]: types)
|
||||||
m_UDTs.push_back(name);
|
m_UDTs.push_back(name);
|
||||||
|
|
||||||
// Namespaces from included files.
|
// Namespaces from included files.
|
||||||
m_nameSpaces.clear();
|
m_nameSpaces.clear();
|
||||||
m_nameSpaces = preprocessor->getNamespaces();
|
m_nameSpaces = preprocessor->getNamespaces();
|
||||||
clearVariables();
|
clearVariables();
|
||||||
|
|
||||||
|
m_parsedImports = preprocessor->getParsedImports();
|
||||||
|
for (auto &[name, tokens]: m_parsedImports) {
|
||||||
|
m_tokens = tokens;
|
||||||
|
m_text = tokens[0].location.source->content;
|
||||||
|
if (m_text.empty() || m_text == "\n")
|
||||||
|
return;
|
||||||
|
loadText();
|
||||||
|
processSource();
|
||||||
|
if (!m_tokenColors.empty())
|
||||||
|
m_tokenColors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tokens = preprocessor->getResult();
|
||||||
|
if (m_tokens.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_globalTokenRange.empty())
|
||||||
|
m_globalTokenRange.clear();
|
||||||
|
m_globalTokenRange.insert(Interval(0, m_tokens.size()-1));
|
||||||
|
|
||||||
|
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||||
|
if (editor != nullptr)
|
||||||
|
m_text = editor->getText();
|
||||||
|
else
|
||||||
|
log::warn("Text editor not found, provider is null");
|
||||||
|
|
||||||
m_parsedImports = preprocessor->getParsedImports();
|
|
||||||
for (auto &[name, tokens]: m_parsedImports) {
|
|
||||||
m_tokens = tokens;
|
|
||||||
m_text = tokens[0].location.source->content;
|
|
||||||
if (m_text.empty() || m_text == "\n")
|
if (m_text.empty() || m_text == "\n")
|
||||||
return;
|
return;
|
||||||
loadText();
|
loadText();
|
||||||
processSource();
|
|
||||||
if (!m_tokenColors.empty())
|
|
||||||
m_tokenColors.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_tokens = preprocessor->getResult();
|
getAllTokenRanges(IdentifierType::NameSpace);
|
||||||
if (m_tokens.empty())
|
getAllTokenRanges(IdentifierType::UDT);
|
||||||
return;
|
getAllTokenRanges(IdentifierType::Function);
|
||||||
|
getGlobalTokenRanges();
|
||||||
|
fixGlobalVariables();
|
||||||
|
setInitialColors();
|
||||||
|
loadInstances();
|
||||||
|
getAllTokenRanges(IdentifierType::Attribute);
|
||||||
|
getDefinitions();
|
||||||
|
fixAutos();
|
||||||
|
fixChains();
|
||||||
|
|
||||||
if (!m_globalTokenRange.empty())
|
m_excludedLocations = preprocessor->getExcludedLocations();
|
||||||
m_globalTokenRange.clear();
|
|
||||||
m_globalTokenRange.insert(Interval(0, m_tokens.size()-1));
|
|
||||||
|
|
||||||
m_text = m_viewPatternEditor->getTextEditor().getText();
|
colorRemainingIdentifierTokens();
|
||||||
|
setRequestedIdentifierColors();
|
||||||
|
|
||||||
if (m_text.empty() || m_text == "\n")
|
editor = m_viewPatternEditor->getTextEditor();
|
||||||
return;
|
if (editor != nullptr)
|
||||||
loadText();
|
editor->clearErrorMarkers();
|
||||||
|
else
|
||||||
|
log::warn("Text editor not found, provider is null");
|
||||||
|
m_compileErrors = patternLanguage->get()->getCompileErrors();
|
||||||
|
|
||||||
getAllTokenRanges(IdentifierType::NameSpace);
|
if (!m_compileErrors.empty())
|
||||||
getAllTokenRanges(IdentifierType::UDT);
|
renderErrors();
|
||||||
getAllTokenRanges(IdentifierType::Function);
|
else {
|
||||||
getGlobalTokenRanges();
|
editor = m_viewPatternEditor->getTextEditor();
|
||||||
fixGlobalVariables();
|
if (editor != nullptr)
|
||||||
setInitialColors();
|
editor->clearErrorMarkers();
|
||||||
loadInstances();
|
else
|
||||||
getAllTokenRanges(IdentifierType::Attribute);
|
log::warn("Text editor not found, provider is null");
|
||||||
getDefinitions();
|
}
|
||||||
fixAutos();
|
|
||||||
fixChains();
|
|
||||||
|
|
||||||
m_excludedLocations = preprocessor->getExcludedLocations();
|
|
||||||
|
|
||||||
colorRemainingIdentifierTokens();
|
|
||||||
setRequestedIdentifierColors();
|
|
||||||
|
|
||||||
m_viewPatternEditor->getTextEditor().clearErrorMarkers();
|
|
||||||
m_compileErrors = patternLanguage->get()->getCompileErrors();
|
|
||||||
|
|
||||||
if (!m_compileErrors.empty())
|
|
||||||
renderErrors();
|
|
||||||
else
|
|
||||||
m_viewPatternEditor->getTextEditor().clearErrorMarkers();
|
|
||||||
} catch (const std::out_of_range &e) {
|
} catch (const std::out_of_range &e) {
|
||||||
log::debug("TextHighlighter::highlightSourceCode: Out of range error: {}", e.what());
|
log::debug("TextHighlighter::highlightSourceCode: Out of range error: {}", e.what());
|
||||||
m_wasInterrupted = true;
|
m_wasInterrupted = true;
|
||||||
|
|
@ -2321,4 +2347,4 @@ namespace hex::plugin::builtin {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
#include <fonts/fonts.hpp>
|
#include <fonts/fonts.hpp>
|
||||||
#include <hex/api/events/requests_gui.hpp>
|
#include <hex/api/events/requests_gui.hpp>
|
||||||
#include <hex/helpers/menu_items.hpp>
|
#include <hex/helpers/menu_items.hpp>
|
||||||
|
#include <hex/helpers/logger.hpp>
|
||||||
|
|
||||||
namespace hex::plugin::builtin {
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
|
@ -70,6 +71,16 @@ namespace hex::plugin::builtin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui::TextEditor *editor = m_view->getTextEditor();
|
||||||
|
if (editor != nullptr) {
|
||||||
|
if (!editor->isEmpty()) {
|
||||||
|
this->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::warn("Text editor not found, provider is null");
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiExt::TextFormattedWrapped("{}", static_cast<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
|
ImGuiExt::TextFormattedWrapped("{}", static_cast<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
|
||||||
|
|
||||||
if (ImGui::BeginListBox("##patterns_accept", ImVec2(400_scaled, 0))) {
|
if (ImGui::BeginListBox("##patterns_accept", ImVec2(400_scaled, 0))) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <ui/text_editor.hpp>
|
#include <ui/text_editor.hpp>
|
||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
|
#include <hex/helpers/logger.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace hex::ui {
|
namespace hex::ui {
|
||||||
|
|
@ -50,8 +51,11 @@ namespace hex::ui {
|
||||||
|
|
||||||
std::smatch results;
|
std::smatch results;
|
||||||
std::string id;
|
std::string id;
|
||||||
if (m_languageDefinition.m_tokenize == nullptr)
|
if (m_languageDefinition.m_tokenize == nullptr) {
|
||||||
m_languageDefinition.m_tokenize = [](strConstIter, strConstIter, strConstIter &, strConstIter &, PaletteIndex &) { return false; };
|
m_languageDefinition.m_tokenize = [](strConstIter, strConstIter, strConstIter &, strConstIter &, PaletteIndex &) { return false; };
|
||||||
|
log::warn("Syntax highlighting tokenize callback is nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
i32 linesSize = m_lines.size();
|
i32 linesSize = m_lines.size();
|
||||||
for (i32 i = 0; i < linesSize; ++i) {
|
for (i32 i = 0; i < linesSize; ++i) {
|
||||||
auto &line = m_lines[i];
|
auto &line = m_lines[i];
|
||||||
|
|
@ -74,28 +78,11 @@ namespace hex::ui {
|
||||||
PaletteIndex token_color = PaletteIndex::Default;
|
PaletteIndex token_color = PaletteIndex::Default;
|
||||||
|
|
||||||
bool hasTokenizeResult = m_languageDefinition.m_tokenize(current.m_charsIter, last.m_charsIter, token_begin, token_end, token_color);
|
bool hasTokenizeResult = m_languageDefinition.m_tokenize(current.m_charsIter, last.m_charsIter, token_begin, token_end, token_color);
|
||||||
auto token_offset = token_begin - first.m_charsIter;
|
|
||||||
|
|
||||||
if (!hasTokenizeResult) {
|
|
||||||
// todo : remove
|
|
||||||
// printf("using regex for %.*s\n", first + 10 < last ? 10 : i32(last - first), first);
|
|
||||||
|
|
||||||
for (auto &p: m_regexList) {
|
|
||||||
if (std::regex_search(first.m_charsIter, last.m_charsIter, results, p.first, std::regex_constants::match_continuous)) {
|
|
||||||
hasTokenizeResult = true;
|
|
||||||
|
|
||||||
const auto &v = results.begin();
|
|
||||||
token_begin = v->first;
|
|
||||||
token_end = v->second;
|
|
||||||
token_color = p.second;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasTokenizeResult)
|
if (!hasTokenizeResult)
|
||||||
current = current + 1;
|
current = current + 1;
|
||||||
else {
|
else {
|
||||||
|
auto token_offset = token_begin - first.m_charsIter;
|
||||||
current = first + token_offset;
|
current = first + token_offset;
|
||||||
u64 token_length = 0;
|
u64 token_length = 0;
|
||||||
Line::Flags flags(0);
|
Line::Flags flags(0);
|
||||||
|
|
@ -1181,4 +1168,4 @@ namespace hex::ui {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue