diff --git a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp index f41129506..0c0da39df 100644 --- a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp +++ b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp @@ -247,6 +247,18 @@ int TextEditor::InsertTextAt(Coordinates & /* inout */ aWhere, const char *aValu if (*aValue == '\r') { // skip ++aValue; + } else if (*aValue == '\t') { + auto &line = mLines[aWhere.mLine]; + auto c = GetCharacterColumn(aWhere.mLine, cindex); + auto r = c % mTabSize; + auto d = mTabSize - r; + auto i = d; + while (i-- > 0) + line.insert(line.begin() + cindex++, Glyph(' ', PaletteIndex::Default)); + + cindex += d; + aWhere.mColumn += d; + aValue++; } else if (*aValue == '\n') { if (cindex < (int)mLines[aWhere.mLine].size()) { auto &newLine = InsertLine(aWhere.mLine + 1); diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index c7dfeb4d2..29f9497b4 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -73,6 +73,8 @@ namespace hex::plugin::builtin { } public: + std::string preprocessText(const std::string &code); + struct VirtualFile { std::fs::path path; std::vector data; diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index a1e31abf4..006b9c62d 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -1662,7 +1662,7 @@ namespace hex::plugin::builtin { void ViewPatternEditor::loadPatternFile(const std::fs::path &path, prv::Provider *provider) { wolv::io::File file(path, wolv::io::File::Mode::Read); if (file.isValid()) { - auto code = file.readString(); + auto code = preprocessText(file.readString()); this->evaluatePattern(code, provider); m_textEditor.SetText(code); @@ -1826,6 +1826,15 @@ namespace hex::plugin::builtin { }); } + std::string ViewPatternEditor::preprocessText(const std::string &code) { + std::string result = wolv::util::replaceStrings(code, "\r\n", "\n"); + result = wolv::util::replaceStrings(result, "\r", "\n"); + result = wolv::util::replaceTabsWithSpaces(result, 4); + while (result.ends_with('\n')) + result.pop_back(); + return result; + } + void ViewPatternEditor::registerEvents() { RequestPatternEditorSelectionChange::subscribe(this, [this](u32 line, u32 column) { if (line == 0) @@ -1849,8 +1858,9 @@ namespace hex::plugin::builtin { }); RequestSetPatternLanguageCode::subscribe(this, [this](const std::string &code) { - m_textEditor.SetText(code); - m_sourceCode.set(ImHexApi::Provider::get(), code); + const std::string preprocessed = preprocessText(code); + m_textEditor.SetText(preprocessed); + m_sourceCode.set(ImHexApi::Provider::get(), preprocessed); m_hasUnevaluatedChanges = true; }); @@ -2109,7 +2119,7 @@ namespace hex::plugin::builtin { .basePath = "pattern_source_code.hexpat", .required = false, .load = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) { - const auto sourceCode = tar.readString(basePath); + const auto sourceCode = preprocessText(tar.readString(basePath)); m_sourceCode.set(provider, sourceCode);