diff --git a/plugins/builtin/source/content/text_highlighting/pattern_language.cpp b/plugins/builtin/source/content/text_highlighting/pattern_language.cpp index 0dd1c7e10..403b695ab 100644 --- a/plugins/builtin/source/content/text_highlighting/pattern_language.cpp +++ b/plugins/builtin/source/content/text_highlighting/pattern_language.cpp @@ -33,11 +33,11 @@ namespace hex::plugin::builtin { } bool TokenInterval::operator<(const TokenInterval &other) const { - return other.m_end > m_end; + return other.m_end == m_end ? other.m_start < m_start : m_end < other.m_end; } bool TokenInterval::operator>(const TokenInterval &other) const { - return m_end > other.m_end; + return other.m_end == m_end ? other.m_start > m_start : m_end > other.m_end; } bool TokenInterval::operator==(const TokenInterval &other) const { @@ -49,11 +49,11 @@ namespace hex::plugin::builtin { } bool TokenInterval::operator<=(const TokenInterval &other) const { - return other.m_end >= m_end; + return other.m_end == m_end ? other.m_start <= m_start : m_end < other.m_end; } bool TokenInterval::operator>=(const TokenInterval &other) const { - return m_end >= other.m_end; + return other.m_end == m_end ? other.m_start >= m_start : m_end > other.m_end; } [[nodiscard]] bool TokenInterval::contains(const TokenInterval &other) const { @@ -124,11 +124,8 @@ namespace hex::plugin::builtin { auto &result = m_textHighlighter->getPatternLanguage()->getInternals().preprocessor->getResult(); std::ranges::copy(result.begin(),result.end(),std::back_inserter(fullTokens)); editedText = editor->getText(); - m_textHighlighter->loadText();; + m_textHighlighter->loadText(); - linesOfColors.clear(); - for (auto &line : m_textHighlighter->m_lines) - linesOfColors.emplace_back(line.size(), ' '); } void TextHighlighter::RequiredInputs::setCompileErrors() { @@ -1605,8 +1602,8 @@ namespace hex::plugin::builtin { curr = m_curr; } if (peek(tkn::Literal::Identifier)) { - std::string nameScape; - if (findNamespace(nameScape) && !nameScape.empty() && std::ranges::find(m_UDTs, (nameScape.append( "::" + name))) != m_UDTs.end()) { + std::string nameSpace; + if (findNamespace(nameSpace) && !nameSpace.empty() && std::ranges::find(m_UDTs, fmt::format("{}::{}",nameSpace, name)) != m_UDTs.end()) { m_scopeChains.insert(tokenIndex); } } @@ -1805,7 +1802,7 @@ namespace hex::plugin::builtin { continue; } if (findNamespace(nameSpace,tokenId)) { - auto fullName = nameSpace + "::" + variableName; + auto fullName = fmt::format("{}::{}",nameSpace, variableName); auto typeName = findIdentifierType(fullName, ""); if (typeName != IdentifierType::Unknown) { setIdentifierColor(-1, typeName); @@ -1834,10 +1831,12 @@ namespace hex::plugin::builtin { while (m_firstTokenIdOfLine.at(topLine) == -1) topLine++; auto bottomLine = previousLine(m_firstTokenIdOfLine.size()); + m_requiredInputs.linesOfColors.resize(m_lines.size()); for (u32 line = topLine; line < bottomLine; line = nextLine(line)) { if (m_lines[line].empty()) continue; - std::string &lineOfColors = m_requiredInputs.linesOfColors[line];//std::string(m_lines[line].size(), 0); + m_requiredInputs.linesOfColors[line] = std::string(m_lines[line].size(), 0); + auto &lineOfColors = m_requiredInputs.linesOfColors[line]; for (auto tokenIndex = m_firstTokenIdOfLine.at(line); tokenIndex < m_firstTokenIdOfLine.at(nextLine(line)); tokenIndex++) { auto *token = const_cast(&m_requiredInputs.fullTokens.at(tokenIndex)); if (m_tokenColors.contains(tokenIndex) && token->type == Token::Type::Identifier) { @@ -1864,12 +1863,12 @@ namespace hex::plugin::builtin { if (auto iterator = m_inheritances.find(name); iterator != m_inheritances.end()) { auto inheritances = std::move(iterator->second); m_inheritances.erase(iterator); - for (auto inheritance: inheritances) { + for (const auto& inheritance: inheritances) { recurseInheritances(inheritance); auto definitions = m_UDTVariables[inheritance]; if (definitions.empty()) definitions = m_ImportedUDTVariables[inheritance]; - for (auto [variableName, variableDefinitions]: definitions) { + for (const auto &[variableName, variableDefinitions]: definitions) { auto tokenRange = m_UDTTokenRange[name]; u32 tokenIndex = tokenRange.m_start; for (auto token = tokenRange.m_start; token < tokenRange.m_end; token++) { @@ -1946,13 +1945,15 @@ namespace hex::plugin::builtin { if (length < 0) return false; - if (length > (i32) m_lines[line].size()-col) + if (line < (i32) m_lines.size() && length > (i32) m_lines[line].size()-col) length -= (i32)( m_lines[line].size()-col); - while (m_firstTokenIdOfLine[line] == m_firstTokenIdOfLine[line + 1]) { + while (line < (i32) m_lines.size() && m_firstTokenIdOfLine[line] == m_firstTokenIdOfLine[line + 1]) { length -= (i32) m_lines[line].size(); line++; } - return !(length > (i32) m_lines[line].size()-col && m_firstTokenIdOfLine[line + 1] != -1); + if (line < (i32) m_lines.size()) + return length <= (i32) m_lines[line].size()-col || m_firstTokenIdOfLine[line + 1] == -1; + return false; } // Find the string of the variable type. This works on function variables, views, @@ -2578,7 +2579,5 @@ namespace hex::plugin::builtin { log::debug("TextHighlighter::highlightSourceCode: Out of range error: {}", e.what()); return; } - - return; } } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 40a3cfdcb..4671fafb9 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -455,9 +455,6 @@ 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( diff --git a/plugins/ui/include/ui/text_editor.hpp b/plugins/ui/include/ui/text_editor.hpp index c3db8d5ca..c2e5a685b 100644 --- a/plugins/ui/include/ui/text_editor.hpp +++ b/plugins/ui/include/ui/text_editor.hpp @@ -93,10 +93,10 @@ namespace hex::ui { bool operator==(const Range &o) const; bool operator!=(const Range &o) const; bool operator<(const Range &o) const { - return m_end < o.m_end; + return o.m_end == m_end ? o.m_start < m_start : m_end < o.m_end; } bool operator>(const Range &o) const { - return m_end > o.m_end; + return o.m_end == m_end ? o.m_start > m_start : m_end > o.m_end; } bool operator<=(const Range &o) const { return !(*this > o); @@ -125,12 +125,12 @@ namespace hex::ui { Interval &operator=(const Interval &interval); Interval &operator=(Interval &&interval) noexcept; - bool operator<(const Interval &other) const { return other.m_end > m_end; } - bool operator>(const Interval &other) const { return m_end > other.m_end; } + bool operator<(const Interval &other) const { return other.m_end == m_end ? other.m_start < m_start : m_end < other.m_end; } + bool operator>(const Interval &other) const { return other.m_end == m_end ? other.m_start > m_start : m_end > other.m_end; } bool operator==(const Interval &other) const { return m_start == other.m_start && m_end == other.m_end; } bool operator!=(const Interval &other) const { return m_start != other.m_start || m_end != other.m_end; } - bool operator<=(const Interval &other) const { return other.m_end >= m_end; } - bool operator>=(const Interval &other) const { return m_end >= other.m_end; } + bool operator<=(const Interval &other) const { return other.m_end == m_end ? other.m_start <= m_start : m_end < other.m_end; } + bool operator>=(const Interval &other) const { return other.m_end == m_end ? other.m_start >= m_start : m_end > other.m_end; } [[nodiscard]] bool contains_or_equals(const Interval &other) const { return other.m_start >= m_start && other.m_end <= m_end; } [[nodiscard]] bool contains(const Interval &other) const { return (other.m_start >= m_start && other.m_end < m_end) || (other.m_start > m_start && other.m_end <= m_end); } [[nodiscard]] bool contains(i32 value, bool inclusive = true) const; @@ -738,7 +738,7 @@ namespace hex::ui { i32 getTokenId(SafeTokenIterator tokenIterator); i32 getTokenId(); void loadFirstTokenIdOfLine(); - i32 nextLine(i32 line); + i32 nextLineIndex(i32 lineIndex); void setAllCodeFolds(); void setCodeFoldState(CodeFoldState states); CodeFoldState getCodeFoldState() const; @@ -844,7 +844,6 @@ namespace hex::ui { Tokens m_tokens; SafeTokenIterator m_curr; SafeTokenIterator m_startToken, m_originalPosition, m_partOriginalPosition; - bool m_interrupt = false; Indices m_firstTokenIdOfLine; CodeFoldBlocks m_foldPoints; GlobalBlocks m_globalBlocks; @@ -887,9 +886,8 @@ namespace hex::ui { void clearActionables() { m_lines.clearActionables();} void saveCodeFoldStates(); void applyCodeFoldStates(); - void removeHiddenLinesFromPattern() { m_lines.removeHiddenLinesFromPattern(); }; - void addHiddenLinesToPattern() { m_lines.addHiddenLinesToPattern(); }; - + void removeHiddenLinesFromPattern() { m_lines.removeHiddenLinesFromPattern(); } + void addHiddenLinesToPattern() { m_lines.addHiddenLinesToPattern(); } // Highlighting private: void preRender(); @@ -1009,8 +1007,8 @@ namespace hex::ui { void codeFoldCollapse(i32 level=1, bool recursive=false, bool all=false); i32 getCodeFoldLevel(i32 line) const; void resetFoldedSelections(); - void computeLPSArray(const std::string &pattern, Indices & lps); - Indices KMPSearch(const std::string& text, const std::string& pattern); + //void computeLPSArray(const std::string &pattern, Indices & lps); + //Indices KMPSearch(const std::string& text, const std::string& pattern); bool isEmpty(); // utf8 diff --git a/plugins/ui/source/ui/text_editor/codeFolder.cpp b/plugins/ui/source/ui/text_editor/codeFolder.cpp index b631e7f68..0f16991c1 100644 --- a/plugins/ui/source/ui/text_editor/codeFolder.cpp +++ b/plugins/ui/source/ui/text_editor/codeFolder.cpp @@ -27,7 +27,7 @@ namespace hex::ui { Interval result = NotValid; auto tokenStart = SafeTokenIterator(m_tokens.begin(), m_tokens.end()); - bool foundKey = false; + bool foundKeyword = false; bool foundComment = false; m_curr = tokenStart + interval.m_start; while (interval.m_end >= getTokenId()) { @@ -37,8 +37,8 @@ namespace hex::ui { return NotValid; while (true) { - if (const auto *docComment = const_cast(getValue(0)); docComment != nullptr) { - if (foundKey) + if (const auto *docComment = const_cast(getValue(0)); docComment != nullptr && getTokenId() == m_firstTokenIdOfLine.at(m_curr->location.line - 1)) { + if (foundKeyword) break; if (docComment->singleLine) { foundComment = true; @@ -48,8 +48,8 @@ namespace hex::ui { break; return {result.m_start, result.m_start}; } - } else if (const auto *comment = const_cast(getValue(0)); comment != nullptr) { - if (foundKey) + } else if (const auto *comment = const_cast(getValue(0)); comment != nullptr && getTokenId() == m_firstTokenIdOfLine.at(m_curr->location.line - 1)) { + if (foundKeyword) break; if (comment->singleLine) { foundComment = true; @@ -59,24 +59,30 @@ namespace hex::ui { break; return {result.m_start, result.m_start}; } - } else if (const auto *keyword = const_cast(getValue(0));keyword != nullptr && *keyword == Token::Keyword::Import) { + } else if (const auto *keyword = const_cast(getValue(0));keyword != nullptr && *keyword == Token::Keyword::Import && getTokenId() == m_firstTokenIdOfLine.at(m_curr->location.line - 1)) { if (foundComment) break; - foundKey = true; - while (!peek(tkn::Separator::Semicolon) && !peek(tkn::Separator::EndOfProgram)) - next(); - next(); - } else if (const auto *directive = const_cast(getValue(0));directive != nullptr && *directive == Token::Directive::Include) { + foundKeyword = true; + i32 lineIndex = m_curr->location.line - 1; + auto nextIndex = nextLineIndex(lineIndex); + if (nextIndex == lineIndex || nextIndex == -1) + break; + auto tokenId = m_firstTokenIdOfLine.at(nextIndex); + next(tokenId - getTokenId()); + } else if (const auto *directive = const_cast(getValue(0));directive != nullptr && *directive == Token::Directive::Include && getTokenId() == m_firstTokenIdOfLine.at(m_curr->location.line - 1)) { if (foundComment) break; - foundKey = true; - u32 line = m_curr->location.line; - while (m_curr->location.line == line && !peek(tkn::Separator::EndOfProgram)) - next(); + foundKeyword = true; + i32 lineIndex = m_curr->location.line - 1; + auto nextIndex = nextLineIndex(lineIndex); + if (nextIndex == lineIndex || nextIndex == -1) + break; + auto tokenId = m_firstTokenIdOfLine.at(nextIndex); + next(tokenId - getTokenId()); } else break; } - if (foundKey || foundComment) { + if (foundKeyword || foundComment) { auto currentId = getTokenId(); if (peek(tkn::Separator::EndOfProgram) || (currentId > 0 && currentId < (i32) m_tokens.size())) { next(-1); @@ -235,7 +241,7 @@ namespace hex::ui { void TextEditor::Lines::advanceToNextLine(i32 &lineIndex, i32 ¤tTokenId, Location &location) { i32 tempLineIndex; - if (tempLineIndex = nextLine(lineIndex); lineIndex == tempLineIndex) { + if (tempLineIndex = nextLineIndex(lineIndex); lineIndex == tempLineIndex) { lineIndex++; currentTokenId = -1; location = Location::Empty(); @@ -469,18 +475,18 @@ namespace hex::ui { } else codeFoldIndex++; } - 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]); - if (i < closedFoldIncrements.size() - 1) - result += ","; + if (!closedFoldIncrements.empty()) { + std::string result = "//+-#:"; + for (u32 i = 0; i < closedFoldIncrements.size(); ++i) { + result += std::to_string(closedFoldIncrements[i]); + if (i < closedFoldIncrements.size() - 1) + result += ","; + } + auto lineIndex = 0; + m_hiddenLines.emplace_back(lineIndex, result); } - auto lineIndex = 0; - m_hiddenLines.emplace_back(lineIndex, result); } void TextEditor::applyCodeFoldStates() { @@ -752,10 +758,6 @@ namespace hex::ui { } void TextEditor::Lines::next(i32 count) { - if (m_interrupt) { - m_interrupt = false; - throw std::out_of_range("Highlights were deliberately interrupted"); - } if (count == 0) return; i32 id = getTokenId(); diff --git a/plugins/ui/source/ui/text_editor/editor.cpp b/plugins/ui/source/ui/text_editor/editor.cpp index 00f0e5d95..ebddc67f5 100644 --- a/plugins/ui/source/ui/text_editor/editor.cpp +++ b/plugins/ui/source/ui/text_editor/editor.cpp @@ -348,7 +348,6 @@ namespace hex::ui { if (u.m_addedRange.m_start == Invalid || u.m_addedRange.m_end == Invalid) return; } - m_lines.m_textChanged = true; if (!m_lines.m_readOnly && undo) { u.m_after = m_lines.m_state; UndoRecords v; diff --git a/plugins/ui/source/ui/text_editor/render.cpp b/plugins/ui/source/ui/text_editor/render.cpp index 583f874a4..639371a87 100644 --- a/plugins/ui/source/ui/text_editor/render.cpp +++ b/plugins/ui/source/ui/text_editor/render.cpp @@ -746,12 +746,12 @@ namespace hex::ui { continue; for (i32 i = 0; i < count; i++) { Interval sgm = {foldedLine.m_foldedSegments[2 * i].m_column, foldedLine.m_foldedSegments[2 * i + 1].m_column}; - m_rowToFoldSegments[row].push_back({foldedLine.m_keys[i].m_start, indexScreenPosition(lineIndex, sgm)}); + m_rowToFoldSegments[row].emplace_back(foldedLine.m_keys[i].m_start, indexScreenPosition(lineIndex, sgm)); ImVec2 screenPosEnd = indexCoordsToScreen(lineCoordinates(lineIndex, foldedLine.m_ellipsisIndices[i])); m_rowCodeFoldTooltips[row].emplace_back(this, foldedLine.m_keys[i],ImRect(screenPosEnd, screenPosEnd + ImVec2(Ellipsis.lineTextSize(), m_charAdvance.y))); } Interval sgm = {foldedLine.m_foldedSegments[2 * count].m_column, foldedLine.m_foldedSegments[2 * count + 1].m_column}; - m_rowToFoldSegments[row].push_back({foldedLine.m_keys[count - 1].m_end, indexScreenPosition(lineIndex, sgm)}); + m_rowToFoldSegments[row].emplace_back(foldedLine.m_keys[count - 1].m_end, indexScreenPosition(lineIndex, sgm)); } } @@ -1221,7 +1221,7 @@ namespace hex::ui { ImGui::BeginChild(m_lines.m_title.c_str()); } if (m_showCursor) - drawCursor(0,textEditorSize, true, drawList); + drawCursor(0,textEditorSize, ImGui::IsWindowFocused(), drawList); ImGui::Dummy(m_lines.m_charAdvance); } diff --git a/plugins/ui/source/ui/text_editor/support.cpp b/plugins/ui/source/ui/text_editor/support.cpp index de34d15ca..2a820e7e9 100644 --- a/plugins/ui/source/ui/text_editor/support.cpp +++ b/plugins/ui/source/ui/text_editor/support.cpp @@ -172,12 +172,7 @@ namespace hex::ui { return *this; } - LineIterator &LineIterator::operator=(const LineIterator &other) { - m_charsIter = other.m_charsIter; - m_colorsIter = other.m_colorsIter; - m_flagsIter = other.m_flagsIter; - return *this; - } + LineIterator &LineIterator::operator=(const LineIterator &other) = default; bool LineIterator::operator!=(const LineIterator &other) const { return m_charsIter != other.m_charsIter || m_colorsIter != other.m_colorsIter || @@ -537,8 +532,8 @@ namespace hex::ui { bool TextEditor::ActionableBox::trigger() { auto mousePos = ImGui::GetMousePos(); - return !(mousePos.x <= m_box.Min.x || mousePos.x >= m_box.Max.x || - mousePos.y < m_box.Min.y || mousePos.y > m_box.Max.y); + return mousePos.x > m_box.Min.x && mousePos.x < m_box.Max.x && + mousePos.y >= m_box.Min.y && mousePos.y <= m_box.Max.y; } void TextEditor::ActionableBox::shiftBoxVertically(float lineCount, float lineHeight) { @@ -1052,7 +1047,7 @@ namespace hex::ui { while (iter != end) { iter++; - if (((pos = iter->position()) > byteIndex)) + if (pos = iter->position(); pos > byteIndex) break; } } @@ -1279,6 +1274,7 @@ namespace hex::ui { } void TextEditor::Lines::setAllCodeFolds() { + initializeCodeFolds(); CodeFoldBlocks intervals = foldPointsFromSource(); m_codeFoldKeys.clear(); m_codeFolds.clear(); @@ -1333,6 +1329,7 @@ namespace hex::ui { m_useSavedFoldStatesRequested = true; } deleteSelection(); + setTextChanged(false); } } @@ -1348,6 +1345,7 @@ namespace hex::ui { if (m_unfoldedLines[lineIndex].m_chars.starts_with("//+-")) m_unfoldedLines.erase(m_unfoldedLines.begin() + lineIndex); insertLine(lineIndex, hiddenLine.m_line); + setTextChanged(false); } } @@ -1506,7 +1504,7 @@ namespace hex::ui { if (!isLocationValid(location)) return -1; i32 line1 = location.line - 1; - i32 line2 = nextLine(line1); + i32 line2 = nextLineIndex(line1); auto tokenCount = m_tokens.size(); i32 lineCount = m_firstTokenIdOfLine.size(); if (line1 < 0 || line1 >= lineCount || tokenCount == 0) @@ -1527,14 +1525,14 @@ namespace hex::ui { return -1; } - i32 TextEditor::Lines::nextLine(i32 line) { - if (line < 0 || line >= size()) + i32 TextEditor::Lines::nextLineIndex(i32 lineIndex) { + if (lineIndex < 0 || lineIndex >= size()) return -1; - auto currentTokenId = m_firstTokenIdOfLine[line]; + auto currentTokenId = m_firstTokenIdOfLine[lineIndex]; i32 i = 1; - while (line + i < size() && - (m_firstTokenIdOfLine[line + i] == currentTokenId || m_firstTokenIdOfLine[line + i] == (i32) 0xFFFFFFFF)) + while (lineIndex + i < size() && + (m_firstTokenIdOfLine[lineIndex + i] == currentTokenId || m_firstTokenIdOfLine[lineIndex + i] == (i32) 0xFFFFFFFF)) i++; - return i + line; + return i + lineIndex; } } \ No newline at end of file