SynEdit: fix single-line (mode=smLine) selection was not restored by undo (e.g. after undo after indent). Related to issue #29591

(cherry picked from commit a66269e8bb)
This commit is contained in:
Martin 2025-03-06 17:50:58 +01:00
parent 1b39a66408
commit a182389908
2 changed files with 17 additions and 11 deletions

View File

@ -694,7 +694,8 @@ type
procedure SetBlockIndent(const AValue: integer); procedure SetBlockIndent(const AValue: integer);
procedure SetCaretAndSelection(const ptCaret, ptBefore, ptAfter: TPoint; procedure SetCaretAndSelection(const ptCaret, ptBefore, ptAfter: TPoint;
Mode: TSynSelectionMode = smCurrent; Mode: TSynSelectionMode = smCurrent;
MakeSelectionVisible: Boolean = False MakeSelectionVisible: Boolean = False;
AForceSingleLineSelected: Boolean = False
); );
procedure SetGutter(const Value: TSynGutter); procedure SetGutter(const Value: TSynGutter);
procedure SetRightGutter(const AValue: TSynGutter); procedure SetRightGutter(const AValue: TSynGutter);
@ -1439,12 +1440,13 @@ type
private private
FCaretPos, FBeginPos, FEndPos: TPoint; FCaretPos, FBeginPos, FEndPos: TPoint;
FBlockMode: TSynSelectionMode; FBlockMode: TSynSelectionMode;
FForceSingleLineSelected: Boolean;
protected protected
function IsEqualContent(AnItem: TSynEditUndoItem): Boolean; override; function IsEqualContent(AnItem: TSynEditUndoItem): Boolean; override;
function DebugString: String; override; function DebugString: String; override;
public public
function IsCaretInfo: Boolean; override; function IsCaretInfo: Boolean; override;
constructor Create(CaretPos, BeginPos, EndPos: TPoint; BlockMode: TSynSelectionMode); constructor Create(CaretPos, BeginPos, EndPos: TPoint; BlockMode: TSynSelectionMode; AForceSingleLineSelected: Boolean);
function PerformUndo(Caller: TObject): Boolean; override; function PerformUndo(Caller: TObject): Boolean; override;
end; end;
@ -1540,12 +1542,13 @@ end;
{ TSynEditUndoSelCaret } { TSynEditUndoSelCaret }
constructor TSynEditUndoSelCaret.Create(CaretPos, BeginPos, EndPos: TPoint; constructor TSynEditUndoSelCaret.Create(CaretPos, BeginPos, EndPos: TPoint;
BlockMode: TSynSelectionMode); BlockMode: TSynSelectionMode; AForceSingleLineSelected: Boolean);
begin begin
FCaretPos := CaretPos; FCaretPos := CaretPos;
FBeginPos := BeginPos; FBeginPos := BeginPos;
FEndPos := EndPos; FEndPos := EndPos;
FBlockMode := BlockMode; FBlockMode := BlockMode;
FForceSingleLineSelected := AForceSingleLineSelected;
{$IFDEF SynUndoDebugItems}debugln(['--- Undo Insert ',DbgSName(self), ' ', dbgs(Self), ' - ', DebugString]);{$ENDIF} {$IFDEF SynUndoDebugItems}debugln(['--- Undo Insert ',DbgSName(self), ' ', dbgs(Self), ' - ', DebugString]);{$ENDIF}
end; end;
@ -1557,7 +1560,8 @@ begin
and (FBeginPos.y = TSynEditUndoSelCaret(AnItem).FBeginPos.y) and (FBeginPos.y = TSynEditUndoSelCaret(AnItem).FBeginPos.y)
and (FEndPos.x = TSynEditUndoSelCaret(AnItem).FEndPos.x) and (FEndPos.x = TSynEditUndoSelCaret(AnItem).FEndPos.x)
and (FEndPos.y = TSynEditUndoSelCaret(AnItem).FEndPos.y) and (FEndPos.y = TSynEditUndoSelCaret(AnItem).FEndPos.y)
and (FBlockMode = TSynEditUndoSelCaret(AnItem).FBlockMode); and (FBlockMode = TSynEditUndoSelCaret(AnItem).FBlockMode)
and (FForceSingleLineSelected = TSynEditUndoSelCaret(AnItem).FForceSingleLineSelected);
end; end;
function TSynEditUndoSelCaret.DebugString: String; function TSynEditUndoSelCaret.DebugString: String;
@ -1576,9 +1580,9 @@ begin
if Result then if Result then
{$IFDEF SynUndoDebugItems}debugln(['--- Undo Perform ',DbgSName(self), ' ', dbgs(Self), ' - ', DebugString]);{$ENDIF} {$IFDEF SynUndoDebugItems}debugln(['--- Undo Perform ',DbgSName(self), ' ', dbgs(Self), ' - ', DebugString]);{$ENDIF}
with TCustomSynEdit(Caller) do begin with TCustomSynEdit(Caller) do begin
SetCaretAndSelection(FCaretPos, FBeginPos, FEndPos, FBlockMode, True); SetCaretAndSelection(FCaretPos, FBeginPos, FEndPos, FBlockMode, True, FForceSingleLineSelected);
FTheLinesView.CurUndoList.AddChange(TSynEditUndoSelCaret.Create(FCaretPos, FBeginPos, FTheLinesView.CurUndoList.AddChange(TSynEditUndoSelCaret.Create(FCaretPos, FBeginPos,
FEndPos, FBlockMode)); FEndPos, FBlockMode, FForceSingleLineSelected));
end; end;
end; end;
@ -4814,7 +4818,7 @@ begin
if SelAvail then if SelAvail then
Result := TSynEditUndoSelCaret.Create(FCaret.LineCharPos, Result := TSynEditUndoSelCaret.Create(FCaret.LineCharPos,
FBlockSelection.StartLineBytePos, FBlockSelection.EndLineBytePos, FBlockSelection.StartLineBytePos, FBlockSelection.EndLineBytePos,
FBlockSelection.ActiveSelectionMode) FBlockSelection.ActiveSelectionMode, FBlockSelection.ForceSingleLineSelected)
else else
Result := TSynEditUndoCaret.Create(FCaret.LineCharPos); Result := TSynEditUndoCaret.Create(FCaret.LineCharPos);
end; end;
@ -8838,8 +8842,8 @@ begin
DoDecPaintLock(Self); DoDecPaintLock(Self);
end; end;
procedure TCustomSynEdit.SetCaretAndSelection(const ptCaret, ptBefore, procedure TCustomSynEdit.SetCaretAndSelection(const ptCaret, ptBefore, ptAfter: TPoint;
ptAfter: TPoint; Mode: TSynSelectionMode = smCurrent; MakeSelectionVisible: Boolean = False); Mode: TSynSelectionMode; MakeSelectionVisible: Boolean; AForceSingleLineSelected: Boolean);
// caret is physical (screen) // caret is physical (screen)
// Before, After is logical (byte) // Before, After is logical (byte)
var var
@ -8850,6 +8854,7 @@ begin
CaretXY := ptCaret; CaretXY := ptCaret;
SetBlockBegin(ptBefore); SetBlockBegin(ptBefore);
SetBlockEnd(ptAfter); SetBlockEnd(ptAfter);
FBlockSelection.ForceSingleLineSelected := AForceSingleLineSelected;
if Mode <> smCurrent then if Mode <> smCurrent then
FBlockSelection.ActiveSelectionMode := Mode; FBlockSelection.ActiveSelectionMode := Mode;

View File

@ -2115,7 +2115,7 @@ procedure TSynEditSelection.DoLinesEdited(Sender: TSynEditStrings; aLinePos,
end; end;
end end
else else
if aCount <> 0 then begin if (aCount <> 0) and (FActiveSelectionMode <> smLine) then begin
(* Chars Insert/Deleted *) (* Chars Insert/Deleted *)
if (aPoint.y = aLinePos) then begin if (aPoint.y = aLinePos) then begin
if (FWeakPersistentIdx > 0) and (FWeakPersistentIdx > FStrongPersistentIdx) then begin if (FWeakPersistentIdx > 0) and (FWeakPersistentIdx > FStrongPersistentIdx) then begin
@ -2160,7 +2160,8 @@ begin
if FPersistent or (FPersistentLock > 0) or if FPersistent or (FPersistentLock > 0) or
((FCaret <> nil) and (not FCaret.Locked)) ((FCaret <> nil) and (not FCaret.Locked))
then begin then begin
empty := (FStartBytePos = FEndBytePos) and (FStartLinePos = FEndLinePos); empty := (FStartBytePos = FEndBytePos) and (FStartLinePos = FEndLinePos) and
not( (FActiveSelectionMode = smLine) and (FForceSingleLineSelected) );
back := IsBackwardSel; back := IsBackwardSel;
AdjustStartLineBytePos(AdjustPoint(StartLineBytePos, not back)); AdjustStartLineBytePos(AdjustPoint(StartLineBytePos, not back));
if empty then if empty then