diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Document.cxx | 11 | ||||
-rw-r--r-- | src/Document.h | 5 | ||||
-rw-r--r-- | src/Editor.cxx | 36 | ||||
-rw-r--r-- | src/Editor.h | 9 |
4 files changed, 50 insertions, 11 deletions
diff --git a/src/Document.cxx b/src/Document.cxx index 0237cef78..6a638471d 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -1242,6 +1242,17 @@ void Document::CheckReadOnly() { } } +void Document::TrimReplacement(std::string_view &text, Range &range) const noexcept { + while (!text.empty() && !range.Empty() && (text.front() == CharAt(range.start))) { + text.remove_prefix(1); + range.start++; + } + while (!text.empty() && !range.Empty() && (text.back() == CharAt(range.end-1))) { + text.remove_suffix(1); + range.end--; + } +} + // Document only modified by gateways DeleteChars, InsertString, Undo, Redo, and SetStyleAt. // SetStyleAt does not change the persistent state of a document diff --git a/src/Document.h b/src/Document.h index ae784180a..ac9c6670c 100644 --- a/src/Document.h +++ b/src/Document.h @@ -46,6 +46,10 @@ public: return (start != Sci::invalidPosition) && (end != Sci::invalidPosition); } + [[nodiscard]] bool Empty() const noexcept { + return start == end; + } + Sci::Position First() const noexcept { return (start <= end) ? start : end; } @@ -369,6 +373,7 @@ public: // Gateways to modifying document void ModifiedAt(Sci::Position pos) noexcept; void CheckReadOnly(); + void TrimReplacement(std::string_view &text, Range &range) const noexcept; bool DeleteChars(Sci::Position pos, Sci::Position len); Sci::Position InsertString(Sci::Position position, const char *s, Sci::Position insertLength); Sci::Position InsertString(Sci::Position position, std::string_view sv); diff --git a/src/Editor.cxx b/src/Editor.cxx index 2e1467e32..1fb6d960d 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -5696,15 +5696,27 @@ Sci::Position Editor::GetTag(char *tagValue, int tagNumber) { return length; } -Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci::Position length) { +Sci::Position Editor::ReplaceTarget(ReplaceType replaceType, std::string_view text) { UndoGroup ug(pdoc); - if (length == -1) - length = strlen(text); - if (replacePatterns) { - text = pdoc->SubstituteByPosition(text, &length); - if (!text) { + if (replaceType == ReplaceType::patterns) { + Sci::Position length = text.length(); + const char *p = pdoc->SubstituteByPosition(text.data(), &length); + if (!p) { return 0; } + text = std::string_view(p, length); + } + + if (replaceType == ReplaceType::minimal) { + // Check for prefix and suffix and reduce text and target to match. + // This is performed with Range which doesn't support virtual space. + Range range(targetRange.start.Position(), targetRange.end.Position()); + pdoc->TrimReplacement(text, range); + // Re-apply virtual space to start if start position didn't change. + // Don't bother with end as its virtual space is not used + const SelectionPosition start(range.start == targetRange.start.Position() ? + targetRange.start : SelectionPosition(range.start)); + targetRange = SelectionSegment(start, SelectionPosition(range.end)); } // Remove the text inside the range @@ -5718,9 +5730,9 @@ Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci: targetRange.end = targetRange.start; // Insert the new text - const Sci::Position lengthInserted = pdoc->InsertString(targetRange.start.Position(), text, length); + const Sci::Position lengthInserted = pdoc->InsertString(targetRange.start.Position(), text); targetRange.end.SetPosition(targetRange.start.Position() + lengthInserted); - return length; + return text.length(); } bool Editor::IsUnicodeMode() const noexcept { @@ -6240,11 +6252,15 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { case Message::ReplaceTarget: PLATFORM_ASSERT(lParam); - return ReplaceTarget(false, ConstCharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); + return ReplaceTarget(ReplaceType::basic, ViewFromParams(lParam, wParam)); case Message::ReplaceTargetRE: PLATFORM_ASSERT(lParam); - return ReplaceTarget(true, ConstCharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); + return ReplaceTarget(ReplaceType::patterns, ViewFromParams(lParam, wParam)); + + case Message::ReplaceTargetMinimal: + PLATFORM_ASSERT(lParam); + return ReplaceTarget(ReplaceType::minimal, ViewFromParams(lParam, wParam)); case Message::SearchInTarget: PLATFORM_ASSERT(lParam); diff --git a/src/Editor.h b/src/Editor.h index 128abf234..85d95e21d 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -581,7 +581,8 @@ protected: // ScintillaBase subclass needs access to much of Editor void FoldAll(Scintilla::FoldAction action); Sci::Position GetTag(char *tagValue, int tagNumber); - Sci::Position ReplaceTarget(bool replacePatterns, const char *text, Sci::Position length=-1); + enum class ReplaceType {basic, patterns, minimal}; + Sci::Position ReplaceTarget(ReplaceType replaceType, std::string_view text); bool PositionIsHotspot(Sci::Position position) const noexcept; bool PointIsHotspot(Point pt); @@ -625,6 +626,12 @@ protected: // ScintillaBase subclass needs access to much of Editor static unsigned char *UCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return static_cast<unsigned char *>(PtrFromSPtr(lParam)); } + static std::string_view ViewFromParams(Scintilla::sptr_t lParam, Scintilla::uptr_t wParam) noexcept { + if (SPtrFromUPtr(wParam) == -1) { + return std::string_view(CharPtrFromSPtr(lParam)); + } + return std::string_view(CharPtrFromSPtr(lParam), wParam); + } static void *PtrFromUPtr(Scintilla::uptr_t wParam) noexcept { return reinterpret_cast<void *>(wParam); } |