mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-28 16:49:54 +02:00
SynEdit / IDE: Keep cursor at position, if codetools makes changes to toher location (like updating component names) issue #12344
git-svn-id: trunk@21829 -
This commit is contained in:
parent
53a1e55eb8
commit
d033ed3dfc
@ -1350,11 +1350,11 @@ begin
|
||||
NewBlockBegin, NewBlockEnd, KeyChar, Shift);
|
||||
if (CompareCarets(NewBlockBegin, NewBlockEnd) <> 0) or (Value <> '') then
|
||||
begin
|
||||
TextBetweenPoints[NewBlockBegin, NewBlockEnd] := Value;
|
||||
TextBetweenPointsEx[NewBlockBegin, NewBlockEnd, scamEnd] := Value;
|
||||
TCustomSynEdit(F.CurrentEditor).SetFocus;
|
||||
end;
|
||||
end else begin
|
||||
TextBetweenPoints[NewBlockBegin, NewBlockEnd] := ItemList[Position];
|
||||
TextBetweenPointsEx[NewBlockBegin, NewBlockEnd, scamEnd] := ItemList[Position];
|
||||
TCustomSynEdit(F.CurrentEditor).SetFocus;
|
||||
end;
|
||||
end;
|
||||
|
@ -176,6 +176,12 @@ type
|
||||
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction) of object;
|
||||
|
||||
TSynEditCaretType = (ctVerticalLine, ctHorizontalLine, ctHalfBlock, ctBlock);
|
||||
TSynCaretAdjustMode = ( // used in TextBetweenPointsEx
|
||||
scamIgnore, // Caret stays at the same numeric values, if text is inserted before caret, the text moves, but the caret stays
|
||||
scamAdjust, // Caret moves with text, if text is inserted
|
||||
scamEnd,
|
||||
scamBegin
|
||||
);
|
||||
|
||||
TSynStateFlag = (sfCaretVisible, sfCaretChanged, sfHideCursor,
|
||||
sfEnsureCursorPos, sfEnsureCursorPosAtResize,
|
||||
@ -471,6 +477,8 @@ type
|
||||
procedure SetMouseActions(const AValue: TSynEditMouseActions);
|
||||
procedure SetMouseSelActions(const AValue: TSynEditMouseActions);
|
||||
procedure SetTextBetweenPoints(aStartPoint, aEndPoint: TPoint; const AValue: String);
|
||||
procedure SetTextBetweenPointsEx(aStartPoint, aEndPoint: TPoint;
|
||||
aCaretMode: TSynCaretAdjustMode; const AValue: String);
|
||||
procedure SurrenderPrimarySelection;
|
||||
procedure BookMarkOptionsChanged(Sender: TObject);
|
||||
procedure ComputeCaret(X, Y: Integer);
|
||||
@ -850,7 +858,7 @@ type
|
||||
{$ENDIF}
|
||||
procedure WndProc(var Msg: TMessage); override;
|
||||
public
|
||||
procedure InsertTextAtCaret(aText: String);
|
||||
procedure InsertTextAtCaret(aText: String; aCaretMode : TSynCaretAdjustMode = scamEnd);
|
||||
property BlockBegin: TPoint read GetBlockBegin write SetBlockBegin; // Set Blockbegin. For none persistent also sets Blockend. Setting Caret may undo this and should be done before setting block
|
||||
property BlockEnd: TPoint read GetBlockEnd write SetBlockEnd;
|
||||
property FoldState: String read GetFoldState write SetFoldState;
|
||||
@ -890,6 +898,8 @@ type
|
||||
// Logical Points
|
||||
property TextBetweenPoints[aStartPoint, aEndPoint: TPoint]: String
|
||||
read GetTextBetweenPoints write SetTextBetweenPoints;
|
||||
property TextBetweenPointsEx[aStartPoint, aEndPoint: TPoint; CaretMode: TSynCaretAdjustMode]: String
|
||||
write SetTextBetweenPointsEx;
|
||||
property TopLine: Integer read fTopLine write SetTopLine;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
property UseUTF8: boolean read FUseUTF8;
|
||||
@ -1816,6 +1826,8 @@ begin
|
||||
FreeAndNil(FHookedKeyTranslationList);
|
||||
fHookedCommandHandlers:=nil;
|
||||
fPlugins:=nil;
|
||||
FCaret.Lines := nil;
|
||||
FInternalCaret.Lines := nil;
|
||||
FreeAndNil(fScrollTimer);
|
||||
FreeAndNil(fTSearch);
|
||||
FreeAndNil(fMarkupManager);
|
||||
@ -1832,12 +1844,12 @@ begin
|
||||
FreeAndNil(fTextDrawer);
|
||||
FreeAndNil(fFontDummy);
|
||||
FreeAndNil(FWordBreaker);
|
||||
FreeAndNil(FFoldedLinesView);
|
||||
FreeAndNil(FFoldedLinesView); // has reference to caret
|
||||
FreeAndNil(FInternalBlockSelection);
|
||||
FreeAndNil(FBlockSelection);
|
||||
FreeAndNil(FStrings);
|
||||
FreeAndNil(FTabbedLinesView);
|
||||
FreeAndNil(FTrimmedLinesView);
|
||||
FreeAndNil(FTrimmedLinesView); // has reference to caret
|
||||
FreeAndNil(FDoubleWidthChrLinesView);
|
||||
FreeAndNil(fLines);
|
||||
FreeAndNil(fCaret);
|
||||
@ -4977,12 +4989,33 @@ begin
|
||||
FInternalBlockSelection.StartLineBytePos := aStartPoint;
|
||||
FInternalBlockSelection.EndLineBytePos := aEndPoint;
|
||||
FInternalBlockSelection.SelText := AValue;
|
||||
FCaret.LineBytePos := FInternalBlockSelection.StartLineBytePos;
|
||||
finally
|
||||
EndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetTextBetweenPointsEx(aStartPoint, aEndPoint: TPoint;
|
||||
aCaretMode: TSynCaretAdjustMode; const AValue: String);
|
||||
begin
|
||||
BeginUndoBlock;
|
||||
try
|
||||
if aCaretMode = scamAdjust then
|
||||
FCaret.AutoMoveOnEdit := True;
|
||||
FInternalBlockSelection.SelectionMode := smNormal;
|
||||
FInternalBlockSelection.StartLineBytePos := aStartPoint;
|
||||
FInternalBlockSelection.EndLineBytePos := aEndPoint;
|
||||
if aCaretMode = scamBegin then
|
||||
FCaret.LineBytePos := FInternalBlockSelection.StartLineBytePos;
|
||||
FInternalBlockSelection.SelText := AValue;
|
||||
if aCaretMode = scamEnd then
|
||||
FCaret.LineBytePos := FInternalBlockSelection.StartLineBytePos;
|
||||
finally
|
||||
if aCaretMode = scamAdjust then
|
||||
FCaret.AutoMoveOnEdit := False;
|
||||
EndUndoBlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.GetLineState(ALine: Integer): TSynLineState;
|
||||
begin
|
||||
with TSynEditStringList(fLines) do
|
||||
@ -5089,9 +5122,9 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.InsertTextAtCaret(aText: String);
|
||||
procedure TCustomSynEdit.InsertTextAtCaret(aText: String; aCaretMode : TSynCaretAdjustMode = scamEnd);
|
||||
begin
|
||||
TextBetweenPoints[FCaret.LineBytePos, FCaret.LineBytePos] := aText;
|
||||
TextBetweenPointsEx[FCaret.LineBytePos, FCaret.LineBytePos, aCaretMode] := aText;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DragOver(Source: TObject; X, Y: Integer;
|
||||
@ -6063,7 +6096,7 @@ begin
|
||||
ecBlockCopy:
|
||||
begin
|
||||
if SelAvail then
|
||||
InsertTextAtCaret(FBlockSelection.SelText);
|
||||
InsertTextAtCaret(FBlockSelection.SelText, scamEnd);
|
||||
end;
|
||||
ecBlockDelete:
|
||||
begin
|
||||
|
@ -54,6 +54,7 @@ type
|
||||
FLines: TSynEditStrings;
|
||||
FOnChangeList: TMethodList;
|
||||
FLockCount: Integer;
|
||||
procedure SetLines(const AValue: TSynEditStrings); virtual;
|
||||
procedure DoLock; virtual;
|
||||
Procedure DoUnlock; virtual;
|
||||
public
|
||||
@ -64,7 +65,7 @@ type
|
||||
procedure RemoveChangeHandler(AHandler: TNotifyEvent);
|
||||
procedure Lock;
|
||||
Procedure Unlock;
|
||||
property Lines: TSynEditStrings read FLines write FLines;
|
||||
property Lines: TSynEditStrings read FLines write SetLines;
|
||||
property Locked: Boolean read GetLocked;
|
||||
end;
|
||||
|
||||
@ -168,6 +169,7 @@ type
|
||||
TSynEditCaret = class(TSynEditPointBase)
|
||||
private
|
||||
FAllowPastEOL: Boolean;
|
||||
FAutoMoveOnEdit: Boolean;
|
||||
FForcePastEOL: Integer;
|
||||
FForceAdjustToNextChar: Integer;
|
||||
FKeepCaretX: Boolean;
|
||||
@ -200,10 +202,14 @@ type
|
||||
procedure SetLineText(const AValue : string);
|
||||
procedure SetSkipTabs(const AValue: Boolean);
|
||||
protected
|
||||
procedure SetLines(const AValue: TSynEditStrings); override;
|
||||
procedure DoLock; override;
|
||||
Procedure DoUnlock; override;
|
||||
procedure DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePos, aCount,
|
||||
aLineBrkCnt: Integer; aText: String);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure AssignFrom(Src: TSynEditCaret);
|
||||
procedure IncForcePastEOL;
|
||||
procedure DecForcePastEOL;
|
||||
@ -228,6 +234,7 @@ type
|
||||
property AllowPastEOL: Boolean read FAllowPastEOL write SetAllowPastEOL;
|
||||
property KeepCaretX: Boolean read FKeepCaretX write SetKeepCaretX;
|
||||
property MaxLeftChar: PInteger write FMaxLeftChar;
|
||||
property AutoMoveOnEdit: Boolean write FAutoMoveOnEdit;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -239,6 +246,11 @@ begin
|
||||
Result := FLockCount > 0;
|
||||
end;
|
||||
|
||||
procedure TSynEditPointBase.SetLines(const AValue: TSynEditStrings);
|
||||
begin
|
||||
FLines := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditPointBase.DoLock;
|
||||
begin
|
||||
end;
|
||||
@ -298,6 +310,15 @@ begin
|
||||
fCharPos:= 1;
|
||||
FAllowPastEOL := True;
|
||||
FForcePastEOL := 0;
|
||||
if FLines <> nil then
|
||||
FLines.AddEditHandler(@DoLinesEdited);
|
||||
end;
|
||||
|
||||
destructor TSynEditCaret.Destroy;
|
||||
begin
|
||||
if FLines <> nil then
|
||||
FLines.RemoveEditHandler(@DoLinesEdited);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.AssignFrom(Src: TSynEditCaret);
|
||||
@ -519,6 +540,16 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.SetLines(const AValue: TSynEditStrings);
|
||||
begin
|
||||
if FLines = AValue then exit;
|
||||
if FLines <> nil then
|
||||
FLines.RemoveEditHandler(@DoLinesEdited);
|
||||
inherited SetLines(AValue);
|
||||
if FLines <> nil then
|
||||
FLines.AddEditHandler(@DoLinesEdited);
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.DoLock;
|
||||
begin
|
||||
FTouched := False;
|
||||
@ -539,6 +570,47 @@ begin
|
||||
FOldLinePos := FLinePos;
|
||||
end;
|
||||
|
||||
procedure TSynEditCaret.DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePos, aCount,
|
||||
aLineBrkCnt: Integer; aText: String);
|
||||
// Todo: refactor / this is a copy from selection
|
||||
function AdjustPoint(aPoint: Tpoint): TPoint; inline;
|
||||
begin
|
||||
Result := aPoint;
|
||||
if aLineBrkCnt < 0 then begin
|
||||
(* Lines Deleted *)
|
||||
if aPoint.y > aLinePos then begin
|
||||
Result.y := Max(aLinePos, Result.y + aLineBrkCnt);
|
||||
if Result.y = aLinePos then
|
||||
Result.x := Result.x + aBytePos - 1;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if aLineBrkCnt > 0 then begin
|
||||
(* Lines Inserted *)
|
||||
if (aPoint.y = aLinePos) and (aPoint.x >= aBytePos) then begin
|
||||
Result.x := Result.x - aBytePos + 1;
|
||||
Result.y := Result.y + aLineBrkCnt;
|
||||
end;
|
||||
if aPoint.y > aLinePos then begin
|
||||
Result.y := Result.y + aLineBrkCnt;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if aCount <> 0 then begin
|
||||
(* Chars Insert/Deleted *)
|
||||
if (aPoint.y = aLinePos) and (aPoint.x >= aBytePos) then
|
||||
Result.x := Max(aBytePos, Result.x + aCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
if FAutoMoveOnEdit then begin
|
||||
IncForcePastEOL;
|
||||
LineBytePos := AdjustPoint(LineBytePos);
|
||||
DecForcePastEOL;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TSynEditSelection }
|
||||
|
||||
constructor TSynEditSelection.Create(ALines : TSynEditStrings; aActOnLineChanges: Boolean);
|
||||
|
@ -2607,13 +2607,13 @@ procedure TSourceEditor.OnCodeBufferChanged(Sender: TSourceLog;
|
||||
var Txt: string;
|
||||
begin
|
||||
if DirectionForward then begin
|
||||
FEditor.TextBetweenPoints[MoveToPos, MoveToPos] :=
|
||||
FEditor.TextBetweenPointsEx[MoveToPos, MoveToPos, scamAdjust] :=
|
||||
FEditor.TextBetweenPoints[StartPos, EndPos];
|
||||
FEditor.TextBetweenPoints[StartPos, EndPos] := '';
|
||||
FEditor.TextBetweenPointsEx[StartPos, EndPos, scamAdjust] := '';
|
||||
end else begin
|
||||
Txt := FEditor.TextBetweenPoints[StartPos, EndPos];
|
||||
FEditor.TextBetweenPoints[StartPos, EndPos] := '';
|
||||
FEditor.TextBetweenPoints[MoveToPos, MoveToPos] := Txt;;
|
||||
FEditor.TextBetweenPointsEx[StartPos, EndPos, scamAdjust] := '';
|
||||
FEditor.TextBetweenPointsEx[MoveToPos, MoveToPos, scamAdjust] := Txt;;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2634,7 +2634,7 @@ begin
|
||||
begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position,StartPos.Y,StartPos.X);
|
||||
if StartPos.Y>=1 then
|
||||
FEditor.TextBetweenPoints[StartPos, StartPos] := SrcLogEntry.Txt;
|
||||
FEditor.TextBetweenPointsEx[StartPos, StartPos, scamAdjust] := SrcLogEntry.Txt;
|
||||
end;
|
||||
sleoDelete:
|
||||
begin
|
||||
@ -2642,7 +2642,7 @@ begin
|
||||
Sender.AbsoluteToLineCol(SrcLogEntry.Position+SrcLogEntry.Len,
|
||||
EndPos.Y,EndPos.X);
|
||||
if (StartPos.Y>=1) and (EndPos.Y>=1) then
|
||||
FEditor.TextBetweenPoints[StartPos, EndPos] := '';
|
||||
FEditor.TextBetweenPointsEx[StartPos, EndPos, scamAdjust] := '';
|
||||
end;
|
||||
sleoMove:
|
||||
begin
|
||||
@ -2806,9 +2806,9 @@ procedure TSourceEditor.ReplaceLines(StartLine, EndLine: integer;
|
||||
const NewText: string);
|
||||
begin
|
||||
if ReadOnly then Exit;
|
||||
FEditor.TextBetweenPoints[Point(1,StartLine),
|
||||
Point(length(FEditor.Lines[Endline-1])+1,EndLine)] :=
|
||||
NewText;
|
||||
FEditor.TextBetweenPointsEx[Point(1,StartLine),
|
||||
Point(length(FEditor.Lines[Endline-1])+1,EndLine),
|
||||
scamEnd] := NewText;
|
||||
end;
|
||||
|
||||
procedure TSourceEditor.EncloseSelection;
|
||||
@ -4020,7 +4020,7 @@ Begin
|
||||
SrcEdit:=GetActiveSE;
|
||||
Editor:=SrcEdit.EditorComponent;
|
||||
if ValueType <> icvNone then
|
||||
Editor.TextBetweenPoints[SourceStart, SourceEnd] := NewValue;
|
||||
Editor.TextBetweenPointsEx[SourceStart, SourceEnd, scamEnd] := NewValue;
|
||||
if CursorToLeft>0 then
|
||||
begin
|
||||
NewCaretXY:=Editor.CaretXY;
|
||||
|
Loading…
Reference in New Issue
Block a user