Skip to content

Commit a9c305c

Browse files
committed
Improve replacement of rectangular selections
Entities --------- * correctly size the buffer by using `SCI_GETSELTEXT` to measure the selection region instead of the wrapper object's relative positions; fixes an off-by-one bug that could lead to an invalid free and a fatal exception when using the heap tracer (debug builds only) * trim trailing newlines from the replacement text Unicode escapes --------------- * only replace as many characters as are actually within the selection *Not (yet) implemented:* * accurate replacement of Unicode escapes in multiple stream selections (via the new `... Multi-select` suite of functions) * accurate replacement of discontinuous selections (i.e., via the new `Skip Current & Go to Next Multi-select` function). This will probably require multiple `TextRange` objects, one for each selection, instead of a straightforward call to `SCI_REPLACESEL`
1 parent 8b0a7ec commit a9c305c

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

src/LibNppPlugin/NppSimpleObjects.pas

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,11 @@ procedure TSelection.SetStart(const AValue: Sci_Position);
517517
function TSelection.GetText: WideString;
518518
var
519519
Chars: AnsiString;
520+
LenSel: Sci_Position;
520521
begin
521-
Chars := StringOfChar(#0, Self.GetLength + 1);
522+
LenSel := FEditor.SendMessage(SCI_GETSELTEXT, 0, Nil);
523+
if FEditor.ApiLevel >= sciApi_GTE_515 then Inc(LenSel);
524+
Chars := StringOfChar(#0, LenSel);
522525
FEditor.SendMessage(SCI_GETSELTEXT, 0, PAnsiChar(Chars));
523526
case FEditor.SendMessage(SCI_GETCODEPAGE) of
524527
SC_CP_UTF8:
@@ -540,6 +543,10 @@ procedure TSelection.SetText(const AValue: WideString);
540543
else
541544
Chars := RawByteString(AValue);
542545
end;
546+
if (FEditor.SendMessage(SCI_GETSELECTIONS) > 1) then begin
547+
FEditor.SendMessage(SCI_SETSEL, Self.Anchor, Self.GetCurrentPos);
548+
Chars := TrimRight(Chars);
549+
end;
543550
NewLength := System.Length(Chars) - 1;
544551
Reversed := (Self.Anchor > Self.GetCurrentPos);
545552
FEditor.SendMessage(SCI_REPLACESEL, 0, PAnsiChar(Chars));

src/U_JSEncode.pas

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,15 @@ function DecodeJS(Scope: TEntityReplacementScope = ersSelection): Integer;
116116
npp: TApplication;
117117
doc: TActiveDocument;
118118
Target, Match, MatchNext: TTextRange;
119+
ColumnSel: Boolean;
119120
HiByte, LoByte: Cardinal;
120121
EmojiChars: array [0..1] of WideChar;
121122
begin
122123
Result := 0;
123124

124125
npp := GetApplication();
125126
doc := npp.ActiveDocument;
126-
127+
ColumnSel := (doc.SendMessage(SCI_GETSELECTIONMODE) <> SC_SEL_STREAM);
127128
Target := TTextRange.Create(doc, doc.Selection.StartPos, doc.Selection.EndPos);
128129
Match := TTextRange.Create(doc);
129130
try
@@ -161,7 +162,7 @@ function DecodeJS(Scope: TEntityReplacementScope = ersSelection): Integer;
161162
if (Result < 1) then doc.Selection.StartPos := Match.StartPos;
162163
Inc(Result);
163164
end;
164-
until Match.Length = 0;
165+
until (Match.Length = 0) or (ColumnSel and (Result = doc.SendMessage(SCI_GETSELECTIONS)));
165166

166167
if Result > 0 then doc.Selection.ClearSelection;
167168
finally

0 commit comments

Comments
 (0)