diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 70ead21a3..51e6039f1 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -23,7 +23,7 @@ namespace hex::plugin::builtin { std::string& get(prv::Provider *provider); [[nodiscard]] bool hasProviderSpecificSource(prv::Provider *provider) const; - bool isSynced() const; + [[nodiscard]] bool isSynced() const; void enableSync(bool enabled); private: @@ -41,18 +41,9 @@ namespace hex::plugin::builtin { void drawAlwaysVisibleContent() override; std::unique_ptr *getPatternLanguage() { return &m_editorRuntime; } ui::TextEditor *getTextEditor(); - u32 getRunningParsers () const { return m_runningParsers;} - u32 getRunningEvaluators () const { return m_runningEvaluators;} - u32 getRunningHighlighters () const { return m_runningHighlighters;} - void incrementRunningParsers( i32 amount) { m_runningParsers += amount; } - void incrementRunningEvaluators( i32 amount) { m_runningEvaluators += amount; } void incrementRunningHighlighters( i32 amount) { m_runningHighlighters += amount; } - bool hasUnevaluatedChanges(prv::Provider *provider) const; - void setChangesWereParsed(bool changesWereParsed) { m_changesWereParsed = changesWereParsed;} void setChangesWereColored(bool changesWereColored) { m_changesWereColored = changesWereColored; } void drawContent() override; - void setPopupWindowHeight(u32 height) { m_popupWindowHeight = height; } - u32 getPopupWindowHeight() const { return m_popupWindowHeight; } enum class DangerousFunctionPerms : u8 { Ask, Allow, Deny }; void drawHelpText() override; @@ -64,14 +55,14 @@ namespace hex::plugin::builtin { class PopupAcceptPattern; struct PatternVariable { - bool inVariable; - bool outVariable; + bool inVariable{}; + bool outVariable{}; - pl::core::Token::ValueType type; + pl::core::Token::ValueType type{}; pl::core::Token::Literal value; }; - enum class EnvVarType + enum class EnvVarType : u8 { Integer, Float, @@ -137,15 +128,8 @@ namespace hex::plugin::builtin { std::mutex m_logMutex; - PerProvider m_cursorPosition; PerProvider m_scroll; PerProvider m_consoleScroll; - PerProvider m_codeFoldState; - PerProvider m_consoleCursorPosition; - PerProvider m_selection; - PerProvider m_consoleSelection; - PerProvider m_consoleLongestLineLength; - PerProvider m_breakpoints; PerProvider> m_lastEvaluationError; PerProvider> m_lastCompileError; PerProvider*> m_callStack; @@ -168,7 +152,6 @@ namespace hex::plugin::builtin { ContentRegistry::Settings::SettingsVariable m_parentHighlightingEnabled = false; bool m_replaceMode = false; bool m_openFindReplacePopUp = false; bool m_openGotoLinePopUp = false; - bool m_patternEvaluating = false; std::map m_patternNames; PerProvider m_changeTracker; PerProvider m_ignoreNextChangeEvent; diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 922a5a853..40a3cfdcb 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -455,6 +455,9 @@ namespace hex::plugin::builtin { auto defaultEditorSize = ImGui::GetContentRegionAvail(); defaultEditorSize.y *= 0.66F; + //if (getLastFocusedView() == this) { + // m_textEditor.get(provider).setFocus(false); + //} fonts::CodeEditor().push(); ImGui::SetNextWindowSizeConstraints( @@ -1289,11 +1292,11 @@ namespace hex::plugin::builtin { if (ImGui::BeginChild("##debugger", size, true)) { auto &evaluator = runtime.getInternals().evaluator; - m_breakpoints = m_textEditor.get(provider).getBreakpoints(); - evaluator->setBreakpoints(m_breakpoints); + ui::TextEditor::Breakpoints breakpoints = m_textEditor.get(provider).getBreakpoints(); + evaluator->setBreakpoints(breakpoints); - m_breakpoints = evaluator->getBreakpoints(); - m_textEditor.get(provider).setBreakpoints(m_breakpoints); + breakpoints = evaluator->getBreakpoints(); + m_textEditor.get(provider).setBreakpoints(breakpoints); if (*m_breakpointHit) { auto displayValue = [&](const auto &parent, size_t index) { @@ -1431,12 +1434,12 @@ namespace hex::plugin::builtin { { if (m_textEditor.get(provider).isBreakpointsChanged()) { - m_breakpoints = m_textEditor.get(provider).getBreakpoints(); + ui::TextEditor::Breakpoints breakpoints = m_textEditor.get(provider).getBreakpoints(); m_textEditor.get(provider).clearBreakpointsChanged(); const auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &evaluator = runtime.getInternals().evaluator; if (evaluator) { - evaluator->setBreakpoints(m_breakpoints); + evaluator->setBreakpoints(breakpoints); } } @@ -1644,7 +1647,7 @@ namespace hex::plugin::builtin { this->evaluatePattern(code, provider); m_textEditor.get(provider).setText(code, true); m_textEditor.get(provider).removeHiddenLinesFromPattern(); - m_sourceCode.get(provider) = code; + m_sourceCode.get(provider) = m_textEditor.get(provider).getText(); if (trackFile) { m_changeTracker.get(provider) = wolv::io::ChangeTracker(file); m_changeTracker.get(provider).startTracking([this, provider]{ this->handleFileChange(provider); }); @@ -1709,7 +1712,7 @@ namespace hex::plugin::builtin { m_consoleEditor.get(provider).clearActionables(); m_console.get(provider).clear(); - m_consoleLongestLineLength.get(provider) = 0; + m_consoleEditor.get(provider).setLongestLineLength(0); m_consoleNeedsUpdate = true; m_consoleEditor.get(provider).setText(""); @@ -1782,8 +1785,7 @@ namespace hex::plugin::builtin { default: break; } } - if (m_consoleLongestLineLength.get(provider) < line.size()) { - m_consoleLongestLineLength.get(provider) = line.size(); + if (m_consoleEditor.get(provider).getLongestLineLength() < line.size()) { m_consoleEditor.get(provider).setLongestLineLength(line.size()); } m_console.get(provider).emplace_back(line); @@ -1853,6 +1855,11 @@ namespace hex::plugin::builtin { EventProviderOpened::subscribe(this, [this](prv::Provider *provider) { m_textEditor.get(provider).setLanguageDefinition(PatternLanguage()); m_textEditor.get(provider).setShowWhitespaces(false); + m_textEditor.get(provider).setCursorPosition(ui::TextEditor::Coordinates(0, 0),false,false); + //if (getLastFocusedView() == this) { + // m_textEditor.get(provider).setFocus(true); + //} + m_consoleEditor.get(provider).setLanguageDefinition(ConsoleLog()); m_consoleEditor.get(provider).setShowWhitespaces(false); @@ -1871,39 +1878,26 @@ namespace hex::plugin::builtin { m_envVarEntries.get(provider).emplace_back(0, "", i128(0), EnvVarType::Integer); m_debuggerDrawer.get(provider) = std::make_unique(); - m_cursorPosition.get(provider) = ui::TextEditor::Coordinates(0, 0); }); EventProviderChanged::subscribe(this, [this](prv::Provider *oldProvider, prv::Provider *newProvider) { if (oldProvider != nullptr) { m_sourceCode.get(oldProvider) = m_textEditor.get(oldProvider).getText(); m_scroll.get(oldProvider) = m_textEditor.get(oldProvider).getScroll(); - m_cursorPosition.get(oldProvider) = m_textEditor.get(oldProvider).getCursorPosition(); - m_selection.get(oldProvider) = m_textEditor.get(oldProvider).getSelection(); - m_breakpoints.get(oldProvider) = m_textEditor.get(oldProvider).getBreakpoints(); - m_codeFoldState.get(oldProvider) = m_textEditor.get(oldProvider).getLines().getCodeFoldState(); - m_consoleCursorPosition.get(oldProvider) = m_consoleEditor.get(oldProvider).getCursorPosition(); - m_consoleSelection.get(oldProvider) = m_consoleEditor.get(oldProvider).getSelection(); - m_consoleLongestLineLength.get(oldProvider) = m_consoleEditor.get(oldProvider).getLongestLineLength(); m_consoleScroll.get(oldProvider) = m_consoleEditor.get(oldProvider).getScroll(); } if (newProvider != nullptr) { m_textEditor.get(newProvider).setText(wolv::util::preprocessText(m_sourceCode.get(newProvider))); - m_textEditor.get(newProvider).setCursorPosition(m_cursorPosition.get(newProvider),false,false); m_textEditor.get(newProvider).setScroll(m_scroll.get(newProvider)); - m_textEditor.get(newProvider).setSelection(m_selection.get(newProvider)); - m_textEditor.get(newProvider).setBreakpoints(m_breakpoints.get(newProvider)); - m_textEditor.get(newProvider).getLines().setCodeFoldState(m_codeFoldState.get(newProvider)); m_textEditor.get(newProvider).setTextChanged(false); m_hasUnevaluatedChanges.get(newProvider) = true; m_consoleEditor.get(newProvider).setText(wolv::util::combineStrings(m_console.get(newProvider), "\n")); - m_consoleEditor.get(newProvider).setCursorPosition(m_consoleCursorPosition.get(newProvider)); - m_consoleEditor.get(newProvider).setLongestLineLength(m_consoleLongestLineLength.get(newProvider)); - m_consoleEditor.get(newProvider).setSelection(m_consoleSelection.get(newProvider)); m_consoleEditor.get(newProvider).setScroll(m_consoleScroll.get(newProvider)); - } + //if (getLastFocusedView() == this) { + // m_textEditor.get(newProvider).setFocus(false); + //} }); @@ -2135,16 +2129,16 @@ namespace hex::plugin::builtin { const auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &evaluator = runtime.getInternals().evaluator; - m_breakpoints = m_textEditor.get(ImHexApi::Provider::get()).getBreakpoints(); - evaluator->setBreakpoints(m_breakpoints); + ui::TextEditor::Breakpoints breakpoints = m_textEditor.get(ImHexApi::Provider::get()).getBreakpoints(); + evaluator->setBreakpoints(breakpoints); - if (m_breakpoints->contains(line)) + if (breakpoints.contains(line)) evaluator->removeBreakpoint(line); else evaluator->addBreakpoint(line); - m_breakpoints = evaluator->getBreakpoints(); - m_textEditor.get(ImHexApi::Provider::get()).setBreakpoints(m_breakpoints); + breakpoints = evaluator->getBreakpoints(); + m_textEditor.get(ImHexApi::Provider::get()).setBreakpoints(breakpoints); }, [] { return ImHexApi::Provider::isValid(); }, this); @@ -2341,24 +2335,17 @@ namespace hex::plugin::builtin { .required = false, .load = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) { const auto sourceCode = wolv::util::preprocessText(tar.readString(basePath)); - - m_sourceCode.get(provider) = sourceCode; - - if (provider == ImHexApi::Provider::get()) { - m_textEditor.get(provider).setText(sourceCode); - m_textEditor.get(provider).removeHiddenLinesFromPattern(); - } + m_textEditor.get(provider).setText(sourceCode); + m_textEditor.get(provider).removeHiddenLinesFromPattern(); + m_sourceCode.get(provider) = m_textEditor.get(provider).getText(); m_hasUnevaluatedChanges.get(provider) = true; return true; }, .store = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) { - if (provider == ImHexApi::Provider::get()) { - m_textEditor.get(provider).addHiddenLinesToPattern(); - m_sourceCode.get(provider) = m_textEditor.get(provider).getText(); - } + m_sourceCode.get(provider) = m_textEditor.get(provider).getText(); - const auto &sourceCode = m_sourceCode.get(provider); + auto sourceCode = m_textEditor.get(provider).getText(true); tar.writeString(basePath, wolv::util::trim(sourceCode)); return true; @@ -2750,8 +2737,7 @@ namespace hex::plugin::builtin { fs::DialogMode::Save, { {"Pattern File", "hexpat"}, {"Pattern Import File", "pat"} }, [this, provider, trackFile](const auto &path) { wolv::io::File file(path, wolv::io::File::Mode::Create); - m_textEditor.get(provider).addHiddenLinesToPattern(); - file.writeString(wolv::util::trim(m_textEditor.get(provider).getText())); + file.writeString(wolv::util::trim(m_textEditor.get(provider).getText(true))); m_patternFileDirty.get(provider) = false; auto loadedPath = m_changeTracker.get(provider).getPath(); if ((loadedPath.empty() && loadedPath != path) || (!loadedPath.empty() && !trackFile) || loadedPath == path) @@ -2774,8 +2760,7 @@ namespace hex::plugin::builtin { wolv::io::File file(path, wolv::io::File::Mode::Create); if (file.isValid() && trackFile) { if (isPatternDirty(provider)) { - m_textEditor.get(provider).addHiddenLinesToPattern(); - file.writeString(wolv::util::trim(m_textEditor.get(provider).getText())); + file.writeString(wolv::util::trim(m_textEditor.get(provider).getText(true))); m_patternFileDirty.get(provider) = false; } return; diff --git a/plugins/ui/include/ui/text_editor.hpp b/plugins/ui/include/ui/text_editor.hpp index 21f8a8577..c3db8d5ca 100644 --- a/plugins/ui/include/ui/text_editor.hpp +++ b/plugins/ui/include/ui/text_editor.hpp @@ -716,7 +716,7 @@ namespace hex::ui { void removeLines(i32 start, i32 end); void removeLine(i32 index); float textDistanceToLineStart(const Coordinates &from); - std::string getText(); + std::string getText(bool addHiddenLines = false); void setCursorPosition(); void ensureSelectionNotFolded(); bool hasSelection(); @@ -747,6 +747,7 @@ namespace hex::ui { void moveToStringIndex(i32 stringIndex, i32 ¤tTokenId, Location &location); void resetToTokenId(i32 &lineIndex, i32 ¤tTokenId, Location &location); i32 findNextDelimiter(bool openOnly); + void resetCodeFoldStates(); constexpr static u32 Normal = 0; constexpr static u32 Not = 1; @@ -947,7 +948,7 @@ namespace hex::ui { void setLanguageDefinition(const LanguageDefinition &aLanguageDef) { m_lines.setLanguageDefinition(aLanguageDef); } std::string getLineText(i32 line); void setTextChanged(bool value) { m_lines.setTextChanged(value); } - std::string getText() { return m_lines.getText(); } + std::string getText(bool addHiddenLines = false) { return m_lines.getText(addHiddenLines); } void addUndo(UndoRecords value) { m_lines.addUndo(value); } bool isTextChanged() { return m_lines.isTextChanged(); } void setHandleMouseInputs(bool value) { m_handleMouseInputs = value; } @@ -984,6 +985,7 @@ namespace hex::ui { void setScroll(ImVec2 scroll); ImVec2 getScroll() const {return m_scroll;} Coordinates getCursorPosition() { return m_lines.lineCoordinates(m_lines.m_state.m_cursorPosition); } + void setFocus(bool scrollTOCursor); //Support private: diff --git a/plugins/ui/source/ui/text_editor/codeFolder.cpp b/plugins/ui/source/ui/text_editor/codeFolder.cpp index 56fb7f757..b631e7f68 100644 --- a/plugins/ui/source/ui/text_editor/codeFolder.cpp +++ b/plugins/ui/source/ui/text_editor/codeFolder.cpp @@ -469,10 +469,10 @@ namespace hex::ui { } else codeFoldIndex++; } - if (!m_hiddenLines.empty()) - m_hiddenLines.clear(); if (closedFoldIncrements.empty()) return; + if (!m_hiddenLines.empty()) + m_hiddenLines.clear(); std::string result = "//+-#:"; for (u32 i = 0; i < closedFoldIncrements.size(); ++i) { result += std::to_string(closedFoldIncrements[i]); @@ -489,12 +489,19 @@ namespace hex::ui { void TextEditor::Lines::setCodeFoldState(CodeFoldState state) { m_codeFoldState = state; + saveCodeFoldStates(); } CodeFoldState TextEditor::Lines::getCodeFoldState() const { return m_codeFoldState; } + void TextEditor::Lines::resetCodeFoldStates() { + m_codeFoldState.clear(); + for (auto key: m_codeFoldKeys) + m_codeFoldState[key] = true; + } + void TextEditor::Lines::applyCodeFoldStates() { std::string commentLine; @@ -505,8 +512,7 @@ namespace hex::ui { } } if (commentLine.size() < 6 || !commentLine.starts_with("//+-#:")) { - for (auto key: m_codeFoldKeys) - m_codeFoldState[key] = true; + resetCodeFoldStates(); return; } auto states = commentLine.substr(6); @@ -527,7 +533,7 @@ namespace hex::ui { std::from_chars(stateStr.data(), stateStr.data() + stateStr.size(), value); closedFoldIncrements[i] = value; } - m_codeFoldState.clear(); + resetCodeFoldStates(); auto codeFoldKeyIter = m_codeFoldKeys.begin(); i32 closeFold = 0; for (auto closedFoldIncrement: closedFoldIncrements) { diff --git a/plugins/ui/source/ui/text_editor/editor.cpp b/plugins/ui/source/ui/text_editor/editor.cpp index ceed9f986..00f0e5d95 100644 --- a/plugins/ui/source/ui/text_editor/editor.cpp +++ b/plugins/ui/source/ui/text_editor/editor.cpp @@ -327,14 +327,8 @@ namespace hex::ui { m_lines.m_unfoldedLines.resize(1); m_lines.m_unfoldedLines[0].clear(); } else { - m_lines.m_hiddenLines.clear(); - u64 i = 0; - while (vectorString[i].starts_with("//+-")) { - m_lines.m_hiddenLines.emplace_back(i, vectorString[i]), i++; - } - vectorString.erase(vectorString.begin(), vectorString.begin() + i); lineCount = vectorString.size(); - i = 0; + u64 i = 0; m_lines.m_unfoldedLines.clear(); m_lines.m_unfoldedLines.resize(lineCount); @@ -886,14 +880,21 @@ namespace hex::ui { m_lines.refreshSearchResults(); } - std::string TextEditor::Lines::getText() { + std::string TextEditor::Lines::getText(bool includeHiddenLines) { auto start = lineCoordinates(0, 0); auto size = m_unfoldedLines.size(); auto line = m_unfoldedLines[size - 1]; auto end = Coordinates( size - 1, line.m_lineMaxColumn); if (start == Invalid || end == Invalid) return ""; - return getRange(Range(start, end)); + std::string result; + if (includeHiddenLines) { + for (const auto &hiddenLine: m_hiddenLines) { + result += hiddenLine.m_line + "\n"; + } + } + result += getRange(Range(start, end)); + return result; } StringVector TextEditor::getTextLines() const { diff --git a/plugins/ui/source/ui/text_editor/navigate.cpp b/plugins/ui/source/ui/text_editor/navigate.cpp index 993fb91ca..67c8acc39 100644 --- a/plugins/ui/source/ui/text_editor/navigate.cpp +++ b/plugins/ui/source/ui/text_editor/navigate.cpp @@ -432,6 +432,10 @@ namespace hex::ui { } } + void TextEditor::setFocus(bool scrollToCursor) { + m_lines.setFocusAtCoords(m_lines.m_state.m_cursorPosition, scrollToCursor); + } + void TextEditor::Lines::setFocusAtCoords(const Coordinates &coords, bool scrollToCursor) { m_focusAtCoords = coords; m_state.m_cursorPosition = coords; @@ -460,7 +464,7 @@ namespace hex::ui { if (std::abs(m_line) > maxLine) return false; auto maxColumn = lines.lineMaxColumn(m_line); - return std::abs(m_column) > maxColumn; + return std::abs(m_column) <= maxColumn; } TextEditor::Coordinates TextEditor::Coordinates::sanitize(Lines &lines) { diff --git a/plugins/ui/source/ui/text_editor/render.cpp b/plugins/ui/source/ui/text_editor/render.cpp index 0ee2544cc..583f874a4 100644 --- a/plugins/ui/source/ui/text_editor/render.cpp +++ b/plugins/ui/source/ui/text_editor/render.cpp @@ -1025,6 +1025,8 @@ namespace hex::ui { } void TextEditor::FoldedLine::loadSegments() { + if (m_keys.empty()) + return; m_foldedSegments.clear(); m_unfoldedSegments.clear(); i32 keyCount = (i32)m_keys.size(); diff --git a/plugins/ui/source/ui/text_editor/support.cpp b/plugins/ui/source/ui/text_editor/support.cpp index 8c3ce0a0c..de34d15ca 100644 --- a/plugins/ui/source/ui/text_editor/support.cpp +++ b/plugins/ui/source/ui/text_editor/support.cpp @@ -1320,15 +1320,13 @@ namespace hex::ui { } void TextEditor::Lines::removeHiddenLinesFromPattern() { - m_hiddenLines.clear(); i32 lineIndex = 0; const auto totalLines = (i32)m_unfoldedLines.size(); while (lineIndex < totalLines && m_unfoldedLines[lineIndex].m_chars.starts_with("//+-")) lineIndex++; if (lineIndex > 0) { + m_hiddenLines.clear(); setSelection(Range(lineCoordinates(0, 0), lineCoordinates(lineIndex, 0))); - auto hiddenLinesText = getSelectedText(); - auto lines = wolv::util::splitString(hiddenLinesText, "\n"); for (i32 i = 0; i < lineIndex; i++) { HiddenLine hiddenLine(i, m_unfoldedLines[i].m_chars); m_hiddenLines.emplace_back(std::move(hiddenLine)); @@ -1336,7 +1334,6 @@ namespace hex::ui { } deleteSelection(); } - setAllCodeFolds(); } void TextEditor::Lines::addHiddenLinesToPattern() { @@ -1348,6 +1345,8 @@ namespace hex::ui { lineIndex = size() + hiddenLine.m_lineIndex; else lineIndex = hiddenLine.m_lineIndex; + if (m_unfoldedLines[lineIndex].m_chars.starts_with("//+-")) + m_unfoldedLines.erase(m_unfoldedLines.begin() + lineIndex); insertLine(lineIndex, hiddenLine.m_line); } }