mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-04 03:37:59 +01:00
SYnEdit: multi caret, IDE integration, and refactor
git-svn-id: trunk@48395 -
This commit is contained in:
parent
6e3dd69f06
commit
5e498c6211
@ -149,8 +149,8 @@ const
|
||||
ecColSelEditorBottom = ecEditorBottom + ecColumnSelection;
|
||||
ecColSelLineTextStart= ecLineTextStart + ecColumnSelection;
|
||||
|
||||
ecSelColCmdRangeStart = ecLeft + ecColumnSelection;
|
||||
ecSelColCmdRangeEnd = ecLeft + ecColumnSelection + 48; // 1 less for ecSelectAll
|
||||
ecSelColCmdRangeStart = ecColumnSelection;
|
||||
ecSelColCmdRangeEnd = ecColumnSelection + 48; // 1 less for ecSelectAll
|
||||
|
||||
|
||||
ecSelectAll = 199; // Select entire contents of editor, cursor to end
|
||||
|
||||
@ -39,6 +39,24 @@ const
|
||||
|
||||
type
|
||||
|
||||
TSynMultiCaretCommandAction = (
|
||||
ccaDefaultAction, // build in default, if any
|
||||
ccaNoneRepeatCommand, // Run Command (onc), clear carets IF any changes (text,selection,main-caret)
|
||||
ccaRepeatCommand, // Repeat the command for each caret
|
||||
ccaRepeatCommandPerLine, // Repeat the command for the first caret on each line
|
||||
ccaClearCarets, // Always Clear all carets
|
||||
ccaAdjustCarets // Run the command once (for main-caret), keep and adjust all carets
|
||||
);
|
||||
TSynMultiCaretCommandFlag = ( // for extension
|
||||
ccfDummy // do not use
|
||||
);
|
||||
TSynMultiCaretCommandFlags = set of TSynMultiCaretCommandFlag;
|
||||
|
||||
TSynMultiCaretBeforeCommand = procedure(Sender: TObject;
|
||||
ACommand: TSynEditorCommand;
|
||||
var AnAction: TSynMultiCaretCommandAction;
|
||||
var AFlags: TSynMultiCaretCommandFlags) of object;
|
||||
|
||||
TLogCaretPointArray = Array of TLogCaretPoint;
|
||||
TSynPluginMultiCaretVisualList = class;
|
||||
|
||||
@ -151,6 +169,7 @@ type
|
||||
FIterationDoneCount: Integer;
|
||||
FLowCaret, FHighCaret: PCaretData; // used in AdjustAfterChange
|
||||
FIteratoreMode: (mciNone, mciUp, mciDown);
|
||||
function GetCurrentCaretFlags: TCaretFlags; inline;
|
||||
function GetCurrentCaretFull: TLogCaretPoint; inline;
|
||||
function GetCurrentCaretKeepX: Integer; inline;
|
||||
procedure SetCurrentCaretFull(AValue: TLogCaretPoint); inline;
|
||||
@ -163,10 +182,14 @@ type
|
||||
function IterateNextUp: Boolean; inline;
|
||||
procedure StartIteratorAtLast;
|
||||
function IterateNextDown: Boolean; inline;
|
||||
function CanPeekCaret(AIndexOffset: Integer): Boolean; inline;
|
||||
function PeekCaretY(AIndexOffset: Integer): Integer; inline;
|
||||
function PeekCaretFull(AIndexOffset: Integer): TLogCaretPoint; inline;
|
||||
//procedure AbortIterator;
|
||||
|
||||
property CurrentCaretFull: TLogCaretPoint read GetCurrentCaretFull write SetCurrentCaretFull;
|
||||
property CurrentCaretKeepX: Integer read GetCurrentCaretKeepX write SetCurrentCaretKeepX;
|
||||
property CurrentCaretFlags: TCaretFlags read GetCurrentCaretFlags;
|
||||
//property CurrentCaret: TPoint read GetCurrentCaret write SetCurrentCaret;
|
||||
//property CurrentCaretX: Integer read GetCurrentCaretX write SetCurrentCaretX;
|
||||
//property CurrentCaretOffs: Integer read GetCurrentCaretOffs write SetCurrentCaretOffs;
|
||||
@ -196,7 +219,8 @@ type
|
||||
function GetTextArea: TLazSynTextArea;
|
||||
procedure DoTextSizeChanged(Sender: TObject);
|
||||
procedure DoBoundsChanged(Sender: TObject);
|
||||
procedure MergeAndRemoveCarets;
|
||||
procedure MergeAndRemoveCarets(AForce: Boolean = False);
|
||||
function IsCaretMergeRequested: Boolean;
|
||||
procedure DoEditorPaintEvent(Sender: TObject; EventType: TSynPaintEvent;
|
||||
const prcClip: TRect);
|
||||
procedure DoEditorScrollEvent(Sender: TObject; EventType: TSynScrollEvent; dx,
|
||||
@ -256,7 +280,8 @@ type
|
||||
TSynPluginMultiCaretDefaultMode = mcmCancelOnCaretMove..mcmMoveAllCarets;
|
||||
|
||||
TSynPluginMultiCaretStateFlag = (
|
||||
sfProcessingCmd, sfProcessingMain,
|
||||
sfProcessingCmd, sfProcessingMain, sfProcessingRepeat,
|
||||
sfNoChangeIndicator,
|
||||
sfExtendingColumnSel, sfSkipCaretsAtSelection,
|
||||
sfCreateCaretAtCurrentPos,
|
||||
sfSkipSelChanged, sfSkipCaretChanged,
|
||||
@ -293,13 +318,16 @@ type
|
||||
FDefaultMode: TSynPluginMultiCaretDefaultMode;
|
||||
FEnableWithColumnSelection: Boolean;
|
||||
FKeyStrokes: TSynPluginMultiCaretKeyStrokes;
|
||||
FOnBeforeCommand: TSynMultiCaretBeforeCommand;
|
||||
FStateFlags: TSynPluginMultiCaretStateFlags;
|
||||
FMouseActions: TSynPluginMultiCaretMouseActions;
|
||||
FSelY1, FSelY2, FSelX: Integer;
|
||||
FColSelDoneY1, FColSelDoneY2, FColSelDonePhysX: Integer;
|
||||
FSpaceTrimmerLocked: Boolean;
|
||||
FForeignPaintLock: Integer;
|
||||
FForeignPaintLock, FNestedCommandProcessor: Integer;
|
||||
|
||||
function GetIsInMainExecution: Boolean;
|
||||
function GetIsInRepeatExecution: Boolean;
|
||||
procedure RemoveCaretsInSelection;
|
||||
procedure SetActiveMode(AValue: TSynPluginMultiCaretMode);
|
||||
procedure SetDefaultColumnSelectMode(AValue: TSynPluginMultiCaretDefaultMode);
|
||||
@ -354,12 +382,16 @@ type
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure AddCaretAtLogPos(X, Y, Offs: Integer);
|
||||
property IsInMainExecution: Boolean read GetIsInMainExecution;
|
||||
property IsInRepeatExecution: Boolean read GetIsInRepeatExecution;
|
||||
property MouseActions: TSynPluginMultiCaretMouseActions read FMouseActions;
|
||||
property KeyStrokes: TSynPluginMultiCaretKeyStrokes read FKeyStrokes;
|
||||
property EnableWithColumnSelection: Boolean read FEnableWithColumnSelection write FEnableWithColumnSelection default True;
|
||||
property ActiveMode: TSynPluginMultiCaretMode read FActiveMode write SetActiveMode;
|
||||
property DefaultMode: TSynPluginMultiCaretDefaultMode read FDefaultMode write SetDefaultMode default mcmMoveAllCarets;
|
||||
property DefaultColumnSelectMode: TSynPluginMultiCaretDefaultMode read FDefaultColumnSelectMode write SetDefaultColumnSelectMode default mcmCancelOnCaretMove;
|
||||
property DefaultColumnSelectMode: TSynPluginMultiCaretDefaultMode
|
||||
read FDefaultColumnSelectMode write SetDefaultColumnSelectMode default mcmCancelOnCaretMove;
|
||||
property OnBeforeCommand: TSynMultiCaretBeforeCommand read FOnBeforeCommand write FOnBeforeCommand;
|
||||
end;
|
||||
|
||||
TSynPluginMultiCaret = class(TSynCustomPluginMultiCaret)
|
||||
@ -369,6 +401,7 @@ type
|
||||
property EnableWithColumnSelection;
|
||||
property DefaultMode;
|
||||
property DefaultColumnSelectMode;
|
||||
property OnBeforeCommand;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -805,9 +838,10 @@ begin
|
||||
if (Result <= FHighIndex) and (FCarets[Result].x = x) and (FCarets[Result].y = y) and
|
||||
(FCarets[Result].offs = Offs) and not(cfAddDuplicate in flags)
|
||||
then begin
|
||||
FCarets[Result].Flags := flags - [cfMainCaret];
|
||||
if cfMainCaret in flags then
|
||||
if cfMainCaret in flags then begin
|
||||
FMainCaretIndex := Result;
|
||||
FCarets[Result].Flags := flags + [cfMainCaret];
|
||||
end;
|
||||
// TODO maybe update PhysX;
|
||||
Result := Result - FLowIndex;
|
||||
exit;
|
||||
@ -870,7 +904,7 @@ begin
|
||||
FCarets[Result].y := y;
|
||||
FCarets[Result].KeepX := PhysX;
|
||||
FCarets[Result].Visual := nil;
|
||||
FCarets[Result].Flags := flags - [cfMainCaret, cfAddDuplicate];
|
||||
FCarets[Result].Flags := flags - [cfAddDuplicate];
|
||||
|
||||
if cfMainCaret in flags then
|
||||
FMainCaretIndex := Result;
|
||||
@ -1082,6 +1116,11 @@ begin
|
||||
Result.Offs := FCurrenCaret^.offs;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.GetCurrentCaretFlags: TCaretFlags;
|
||||
begin
|
||||
Result := FCurrenCaret^.Flags;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.GetCurrentCaretKeepX: Integer;
|
||||
begin
|
||||
Result := FCurrenCaret^.KeepX;
|
||||
@ -1285,6 +1324,26 @@ begin
|
||||
until False;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.CanPeekCaret(AIndexOffset: Integer): Boolean;
|
||||
begin
|
||||
if AIndexOffset < 0 then
|
||||
Result := FCurrenCaret + AIndexOffset >= FLowCaret
|
||||
else
|
||||
Result := FCurrenCaret + AIndexOffset <= FHighCaret;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.PeekCaretY(AIndexOffset: Integer): Integer;
|
||||
begin
|
||||
Result := (FCurrenCaret+AIndexOffset)^.y;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.PeekCaretFull(AIndexOffset: Integer): TLogCaretPoint;
|
||||
begin
|
||||
Result.X := (FCurrenCaret+AIndexOffset)^.x;
|
||||
Result.Y := (FCurrenCaret+AIndexOffset)^.y;
|
||||
Result.Offs := (FCurrenCaret+AIndexOffset)^.offs;
|
||||
end;
|
||||
|
||||
{ TSynPluginMultiCaretBase }
|
||||
|
||||
procedure TSynPluginMultiCaretBase.DoBoundsChanged(Sender: TObject);
|
||||
@ -1303,11 +1362,11 @@ begin
|
||||
UpdateCaretsPos;
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretBase.MergeAndRemoveCarets;
|
||||
procedure TSynPluginMultiCaretBase.MergeAndRemoveCarets(AForce: Boolean);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if FPaintLock > 0 then begin
|
||||
if (FPaintLock > 0) and (not AForce) then begin
|
||||
include(FPaintLockFlags, plfMergeCarets);
|
||||
exit;
|
||||
end;
|
||||
@ -1318,6 +1377,11 @@ begin
|
||||
Carets.RemoveCaret(i);
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretBase.IsCaretMergeRequested: Boolean;
|
||||
begin
|
||||
Result := plfMergeCarets in FPaintLockFlags;
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretBase.DoLinesEdited(Sender: TSynEditStrings; aLinePos, aBytePos,
|
||||
aCount, aLineBrkCnt: Integer; aText: String);
|
||||
begin
|
||||
@ -1843,6 +1907,16 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynCustomPluginMultiCaret.GetIsInMainExecution: Boolean;
|
||||
begin
|
||||
Result := sfProcessingMain in FStateFlags;
|
||||
end;
|
||||
|
||||
function TSynCustomPluginMultiCaret.GetIsInRepeatExecution: Boolean;
|
||||
begin
|
||||
Result := sfProcessingRepeat in FStateFlags;
|
||||
end;
|
||||
|
||||
procedure TSynCustomPluginMultiCaret.SetActiveMode(AValue: TSynPluginMultiCaretMode);
|
||||
begin
|
||||
if FActiveMode = AValue then Exit;
|
||||
@ -2041,13 +2115,14 @@ begin
|
||||
|
||||
|
||||
inherited DoLinesEdited(Sender, aLinePos, aBytePos, aCount, aLineBrkCnt, aText);
|
||||
Exclude(FStateFlags, sfCreateCaretAtCurrentPos);
|
||||
FStateFlags := FStateFlags - [sfCreateCaretAtCurrentPos, sfSkipCaretsAtSelection, sfNoChangeIndicator];
|
||||
end;
|
||||
|
||||
procedure TSynCustomPluginMultiCaret.DoCaretChanged(Sender: TObject);
|
||||
var
|
||||
p: TLogCaretPoint;
|
||||
begin
|
||||
Exclude(FStateFlags, sfNoChangeIndicator);
|
||||
if (sfCreateCaretAtCurrentPos in FStateFlags) then begin
|
||||
p := CaretObj.OldFullLogicalPos;
|
||||
AddCaret(p.x, p.y, p.Offs);
|
||||
@ -2110,6 +2185,7 @@ var
|
||||
SelFirstY, SelLastY, CurY: Integer;
|
||||
CurCaret: TLogCaretPoint;
|
||||
begin
|
||||
Exclude(FStateFlags, sfNoChangeIndicator);
|
||||
if (FStateFlags * [sfProcessingCmd, sfSkipSelChanged] <> []) or
|
||||
(FForeignPaintLock > 0)
|
||||
then exit;
|
||||
@ -2196,17 +2272,29 @@ end;
|
||||
|
||||
procedure TSynCustomPluginMultiCaret.DoBeforeSetSelText(Sender: TObject; AMode: TSynSelectionMode;
|
||||
ANewText: PChar);
|
||||
var
|
||||
skip: Boolean;
|
||||
begin
|
||||
SelectionObj.RemoveBeforeSetSelTextHandler(@DoBeforeSetSelText);
|
||||
|
||||
// only here if selectionexists and is smColumn;
|
||||
skip := //Editor.SelAvail and (SelectionObj.ActiveSelectionMode = smColumn) and
|
||||
not(eoPersistentBlock in Editor.Options2);
|
||||
if skip then
|
||||
SetSkipCaretAtSel;
|
||||
|
||||
RemoveCaretsInSelection;
|
||||
SelectionObj.SelText := '';
|
||||
|
||||
if Carets.MainCaretIndex >= 0 then begin
|
||||
Editor.LogicalCaretXY := Carets.Caret[Carets.MainCaretIndex];
|
||||
FSelX := Carets.Caret[Carets.MainCaretIndex].x;
|
||||
end
|
||||
else
|
||||
assert(False, 'TSynCustomPluginMultiCaret.ProcessAllSynCommand: Maincaret index not found');
|
||||
|
||||
if skip then
|
||||
Include(FStateFlags, sfSkipCaretsAtSelection); // restore the flag
|
||||
end;
|
||||
|
||||
procedure TSynCustomPluginMultiCaret.ProcessMySynCommand(Sender: TObject;
|
||||
@ -2261,50 +2349,79 @@ procedure TSynCustomPluginMultiCaret.ProcessAllSynCommand(Sender: TObject; After
|
||||
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
|
||||
HandlerData: pointer);
|
||||
|
||||
procedure ExecCommandRepeated;
|
||||
procedure ExecCommandRepeated(AOnePerLine: Boolean = False);
|
||||
var
|
||||
c, i, y: Integer;
|
||||
i, y: Integer;
|
||||
p: TLogCaretPoint;
|
||||
skip, noChange, SelAvail, IsUser: Boolean;
|
||||
MainY: Integer;
|
||||
begin
|
||||
Handled := True;
|
||||
Editor.BeginUpdate(True);
|
||||
FCarets.IncMergeLock;
|
||||
try
|
||||
c := AddCaret(Editor.LogicalCaretXY.x, Editor.CaretY, CaretObj.BytePosOffset,
|
||||
AddCaret(Editor.LogicalCaretXY.x, Editor.CaretY, CaretObj.BytePosOffset,
|
||||
[cfMainCaret, cfNoneVisual {, cfAddDuplicate}], CaretObj.KeepCaretXPos);
|
||||
|
||||
// Execute Command at current caret pos
|
||||
Include(FStateFlags, sfProcessingMain);
|
||||
Include(FStateFlags, sfNoChangeIndicator);
|
||||
if Editor.SelAvail and (SelectionObj.ActiveSelectionMode = smColumn) then
|
||||
SelectionObj.AddBeforeSetSelTextHandler(@DoBeforeSetSelText);
|
||||
Editor.CommandProcessor(Command, AChar, data, [hcfInit, hcfFinish]);
|
||||
SelectionObj.RemoveBeforeSetSelTextHandler(@DoBeforeSetSelText);
|
||||
Exclude(FStateFlags, sfProcessingMain);
|
||||
// if there was no change, then do not re-exec ?
|
||||
noChange := sfNoChangeIndicator in FStateFlags;
|
||||
Exclude(FStateFlags, sfNoChangeIndicator);
|
||||
|
||||
if noChange then begin
|
||||
if Carets.MainCaretIndex >= 0 then
|
||||
RemoveCaret(Carets.MainCaretIndex)
|
||||
else
|
||||
assert(False, 'TSynCustomPluginMultiCaret.ProcessAllSynCommand: Maincaret index not found');
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Repeat command
|
||||
Include(FStateFlags, sfProcessingRepeat);
|
||||
CaretObj.IncForcePastEOL;
|
||||
i := CaretsCount;
|
||||
skip := sfSkipCaretsAtSelection in FStateFlags;
|
||||
MainY := CaretObj.LinePos;
|
||||
SelAvail := Editor.SelAvail;
|
||||
IsUser := Command >= ecUserFirst;
|
||||
|
||||
y := FSelY2;
|
||||
while i > 0 do begin
|
||||
dec(i);
|
||||
if i = c then continue;
|
||||
p := Carets.CaretFull[i];
|
||||
Carets.StartIteratorAtLast;
|
||||
while Carets.IterateNextDown do begin
|
||||
if cfMainCaret in Carets.CurrentCaretFlags then
|
||||
continue;
|
||||
p := Carets.CurrentCaretFull;
|
||||
if y > p.y then y := p.y;
|
||||
if (sfSkipCaretsAtSelection in FStateFlags) and (y >= FSelY1) and
|
||||
if (skip) and (y >= FSelY1) and
|
||||
(y = p.y) and (FSelX = p.x)
|
||||
then begin
|
||||
dec(y);
|
||||
continue;
|
||||
end;
|
||||
if AOnePerLine and
|
||||
( (p.y = MainY) or
|
||||
( Carets.CanPeekCaret(-1) and (Carets.PeekCaretY(-1) = p.y) ) )
|
||||
then
|
||||
continue;
|
||||
|
||||
CaretObj.FullLogicalPos := p;
|
||||
//j := Carets.CaretKeepX[i];
|
||||
//if j > 0 then
|
||||
// CaretObj.KeepCaretXPos := j;
|
||||
if IsUser and not SelAvail then
|
||||
SelectionObj.StartLineBytePos := Point(p.x, p.y);
|
||||
i := Carets.CurrentCaretKeepX;
|
||||
if i > 0 then
|
||||
CaretObj.KeepCaretXPos := i;
|
||||
Editor.CommandProcessor(Command, AChar, nil, [hcfInit, hcfFinish]);
|
||||
Carets.CaretFull[i] := CaretObj.FullLogicalPos;
|
||||
Carets.CaretKeepX[i] := -1;
|
||||
Carets.CurrentCaretFull := CaretObj.FullLogicalPos;
|
||||
Carets.CurrentCaretKeepX := -1;
|
||||
end;
|
||||
|
||||
CaretObj.DecForcePastEOL;
|
||||
Exclude(FStateFlags, sfProcessingRepeat);
|
||||
|
||||
if Carets.MainCaretIndex >= 0 then begin
|
||||
CaretObj.FullLogicalPos := Carets.CaretFull[Carets.MainCaretIndex];
|
||||
@ -2314,6 +2431,9 @@ procedure TSynCustomPluginMultiCaret.ProcessAllSynCommand(Sender: TObject; After
|
||||
else
|
||||
assert(False, 'TSynCustomPluginMultiCaret.ProcessAllSynCommand: Maincaret index not found');
|
||||
finally
|
||||
Exclude(FStateFlags, sfSkipCaretsAtSelection);
|
||||
FCarets.DecMergeLock;
|
||||
MergeAndRemoveCarets;
|
||||
Editor.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
@ -2335,8 +2455,7 @@ procedure TSynCustomPluginMultiCaret.ProcessAllSynCommand(Sender: TObject; After
|
||||
Exclude(FStateFlags, sfProcessingMain);
|
||||
|
||||
// Repeat command
|
||||
// TODO lock sorting, and sort at end only
|
||||
// TODO: ecPageTop ecLineTextStart moves both dir.
|
||||
Include(FStateFlags, sfProcessingRepeat);
|
||||
case Command of
|
||||
ecLeft, ecUp, ecWordLeft, ecLineStart, ecPageUp, ecPageLeft,
|
||||
ecPageTop, ecLineTextStart, ecWordEndLeft, ecHalfWordLeft:
|
||||
@ -2367,6 +2486,7 @@ procedure TSynCustomPluginMultiCaret.ProcessAllSynCommand(Sender: TObject; After
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Exclude(FStateFlags, sfProcessingRepeat);
|
||||
|
||||
finally
|
||||
FCarets.DecMergeLock;
|
||||
@ -2386,68 +2506,117 @@ procedure TSynCustomPluginMultiCaret.ProcessAllSynCommand(Sender: TObject; After
|
||||
|
||||
var
|
||||
ClipHelper: TSynClipboardStream;
|
||||
Action: TSynMultiCaretCommandAction;
|
||||
Flags: TSynMultiCaretCommandFlags;
|
||||
begin
|
||||
// hcfInit / hcfFinish
|
||||
if (sfProcessingCmd in FStateFlags) or (CaretsCount = 0) then
|
||||
exit;
|
||||
// hcfFinish
|
||||
if AfterProcessing then begin
|
||||
//if sfExtendingColumnSel in FStateFlags then
|
||||
// HandleNewColSelection;
|
||||
Exclude(FStateFlags, sfExtendingColumnSel);
|
||||
if (FNestedCommandProcessor > 0) then begin
|
||||
dec(FNestedCommandProcessor);
|
||||
exit;
|
||||
end;
|
||||
|
||||
FStateFlags := FStateFlags - [sfProcessingCmd, sfSkipUndoCarets, sfExtendingColumnSel];
|
||||
if (CaretsCount = 0) then
|
||||
exit;
|
||||
|
||||
if IsCaretMergeRequested then
|
||||
MergeAndRemoveCarets(True); // is case of several commands in one paintlock
|
||||
UpdateCaretsPos;
|
||||
|
||||
exit;
|
||||
end;
|
||||
if Handled then exit;
|
||||
|
||||
|
||||
// hcfInit
|
||||
(* use Editor.CommandProcessor(... SkipInit=[hcfInit, hcfFinish])
|
||||
command is already initialized / prevent macro recorder from recording again.
|
||||
*)
|
||||
|
||||
try
|
||||
case Command of
|
||||
// TODO: delete and smColumn -- only delete once
|
||||
ecDeleteLastChar..ecDeleteLine,
|
||||
ecLineBreak..ecChar:
|
||||
begin
|
||||
StartEditing;
|
||||
if ((Command = ecDeleteChar) or (Command = ecDeleteLastChar)) and
|
||||
Editor.SelAvail and (SelectionObj.ActiveSelectionMode = smColumn) and
|
||||
not(eoPersistentBlock in Editor.Options2)
|
||||
then
|
||||
SetSkipCaretAtSel;
|
||||
if Editor.ReadOnly then exit;
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
ecPaste:
|
||||
begin
|
||||
StartEditing;
|
||||
if Editor.ReadOnly then exit;
|
||||
if (sfProcessingCmd in FStateFlags) then
|
||||
inc(FNestedCommandProcessor);
|
||||
if (sfProcessingCmd in FStateFlags) or (CaretsCount = 0) then
|
||||
exit;
|
||||
if Handled then
|
||||
exit;
|
||||
|
||||
if (SelectionObj.ActiveSelectionMode = smColumn) and
|
||||
(SelectionObj.StartLinePos <> SelectionObj.EndLinePos)
|
||||
then begin
|
||||
ClipHelper := TSynClipboardStream.Create;
|
||||
try
|
||||
ClipHelper.ReadFromClipboard(Clipboard);
|
||||
if ClipHelper.SelectionMode = smColumn then begin
|
||||
Exclude(FStateFlags, sfProcessingCmd);
|
||||
exit;
|
||||
end;
|
||||
finally
|
||||
ClipHelper.Free;
|
||||
|
||||
case Command of
|
||||
ecCopy, ecCut: Action := ccaNoneRepeatCommand;
|
||||
ecGotoMarker0..ecGotoMarker9: Action := ccaClearCarets;
|
||||
ecSelectAll: Action := ccaClearCarets;
|
||||
else
|
||||
if Command >= ecUserFirst then
|
||||
Action := ccaNoneRepeatCommand
|
||||
else
|
||||
Action := ccaDefaultAction;
|
||||
end;
|
||||
Flags := [];
|
||||
if FOnBeforeCommand <> nil then
|
||||
FOnBeforeCommand(Self, Command, Action, Flags);
|
||||
|
||||
case Action of
|
||||
//ccaDefaultAction: ;
|
||||
ccaNoneRepeatCommand: begin
|
||||
exit;
|
||||
end;
|
||||
ccaRepeatCommand: begin
|
||||
StartEditing;
|
||||
ExecCommandRepeated;
|
||||
exit;
|
||||
end;
|
||||
ccaRepeatCommandPerLine: begin
|
||||
StartEditing;
|
||||
ExecCommandRepeated(True);
|
||||
exit;
|
||||
end;
|
||||
ccaClearCarets: begin
|
||||
ClearCarets;
|
||||
exit;
|
||||
end;
|
||||
ccaAdjustCarets: begin
|
||||
Include(FStateFlags, sfProcessingCmd);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
case Command of
|
||||
// TODO: delete and smColumn -- only delete once
|
||||
ecDeleteLastChar..ecDeleteLine,
|
||||
ecLineBreak..ecChar:
|
||||
begin
|
||||
StartEditing;
|
||||
if Editor.ReadOnly then exit;
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
ecPaste:
|
||||
begin
|
||||
StartEditing;
|
||||
if Editor.ReadOnly then exit;
|
||||
|
||||
if (SelectionObj.ActiveSelectionMode = smColumn) and
|
||||
(SelectionObj.StartLinePos <> SelectionObj.EndLinePos)
|
||||
then begin
|
||||
ClipHelper := TSynClipboardStream.Create;
|
||||
try
|
||||
ClipHelper.ReadFromClipboard(Clipboard);
|
||||
if ClipHelper.SelectionMode = smColumn then begin
|
||||
Exclude(FStateFlags, sfProcessingCmd);
|
||||
exit;
|
||||
end;
|
||||
finally
|
||||
ClipHelper.Free;
|
||||
end;
|
||||
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
ecTab..ecShiftTab:
|
||||
begin
|
||||
StartEditing;
|
||||
if Editor.ReadOnly then exit;
|
||||
|
||||
if (eoTabIndent in Editor.Options) and Editor.SelAvail and
|
||||
(SelectionObj.ActiveSelectionMode = smColumn)
|
||||
then begin
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
ecTab..ecShiftTab:
|
||||
begin
|
||||
StartEditing;
|
||||
if Editor.ReadOnly then exit;
|
||||
if (eoTabIndent in Editor.Options) and Editor.SelAvail then begin
|
||||
if (SelectionObj.ActiveSelectionMode = smColumn) then begin
|
||||
// no indent for column mode, when multicaret
|
||||
Editor.BeginUpdate(True);
|
||||
try
|
||||
@ -2464,54 +2633,48 @@ begin
|
||||
Editor.EndUpdate;
|
||||
end;
|
||||
end
|
||||
else
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
ecSelColCmdRangeStart..ecSelColCmdRangeEnd:
|
||||
begin
|
||||
Include(FStateFlags, sfSkipUndoCarets);
|
||||
Include(FStateFlags, sfExtendingColumnSel);
|
||||
end;
|
||||
ecLeft..ecHalfWordRight: begin
|
||||
Include(FStateFlags, sfSkipUndoCarets);
|
||||
if ActiveMode = mcmMoveAllCarets then begin
|
||||
Include(FStateFlags, sfProcessingCmd);
|
||||
ExecCaretMoveRepeated;
|
||||
end
|
||||
else
|
||||
if ActiveMode = mcmAddingCarets then
|
||||
Include(FStateFlags, sfProcessingCmd)
|
||||
else
|
||||
ClearCarets;
|
||||
end;
|
||||
ecUndo, ecRedo:
|
||||
begin
|
||||
// handle now / prevent carets from being cleared
|
||||
else // exec once and adjust
|
||||
exit;
|
||||
end
|
||||
else
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
ecSelColCmdRangeStart..ecSelColCmdRangeEnd:
|
||||
begin
|
||||
Include(FStateFlags, sfSkipUndoCarets);
|
||||
Include(FStateFlags, sfExtendingColumnSel);
|
||||
end;
|
||||
ecLeft..ecHalfWordRight: begin
|
||||
Include(FStateFlags, sfSkipUndoCarets);
|
||||
if ActiveMode = mcmMoveAllCarets then begin
|
||||
Include(FStateFlags, sfProcessingCmd);
|
||||
Include(FStateFlags, sfSkipUndoCarets);
|
||||
Carets.Clear(False, Carets.Capacity); // will be restored at end of undo
|
||||
Editor.CommandProcessor(Command, AChar, data, [hcfInit, hcfFinish]);
|
||||
Handled := True;
|
||||
end;
|
||||
ecCopy,
|
||||
ecScrollUp..ecScrollRight,
|
||||
ecInsertMode..ecToggleMode,
|
||||
ecNormalSelect, ecLineSelect,
|
||||
ecSetMarker0..ecSetMarker9,
|
||||
ecToggleMarker0..ecToggleMarker9,
|
||||
EcFoldLevel1..EcFoldLevel9, EcFoldLevel0, EcFoldCurrent,
|
||||
ecGotFocus, ecLostFocus
|
||||
:
|
||||
; // Ignore, if no changes occur
|
||||
ecPluginFirstMultiCaret..ecPluginLastMultiCaret: ; // ignore and handle in hcfPreExec
|
||||
else
|
||||
ClearCarets;
|
||||
end;
|
||||
|
||||
Exclude(FStateFlags, sfSkipCaretsAtSelection);
|
||||
finally
|
||||
FStateFlags := FStateFlags - [sfProcessingCmd, sfSkipUndoCarets];
|
||||
ExecCaretMoveRepeated;
|
||||
end
|
||||
else
|
||||
if ActiveMode = mcmAddingCarets then
|
||||
Include(FStateFlags, sfProcessingCmd)
|
||||
else
|
||||
ClearCarets;
|
||||
end;
|
||||
ecUndo, ecRedo:
|
||||
begin
|
||||
// handle now / prevent carets from being cleared
|
||||
Include(FStateFlags, sfProcessingCmd);
|
||||
Include(FStateFlags, sfSkipUndoCarets);
|
||||
Carets.Clear(False, Carets.Capacity); // will be restored at end of undo
|
||||
Editor.CommandProcessor(Command, AChar, data, [hcfInit, hcfFinish]);
|
||||
Handled := True;
|
||||
end;
|
||||
ecPluginFirstMultiCaret..ecPluginLastMultiCaret: ; // ignore and handle in hcfPreExec
|
||||
else
|
||||
begin
|
||||
StartEditing;
|
||||
if Editor.ReadOnly then exit;
|
||||
ExecCommandRepeated;
|
||||
end;
|
||||
end;
|
||||
|
||||
//Exclude(FStateFlags, sfSkipCaretsAtSelection);
|
||||
end;
|
||||
|
||||
function TSynCustomPluginMultiCaret.MaybeHandleMouseAction(var AnInfo: TSynEditMouseActionInfo;
|
||||
|
||||
@ -183,7 +183,7 @@ type
|
||||
FAreaMarkupEnabled: Boolean;
|
||||
FMarkupEnabled: Boolean;
|
||||
FEnabled: Boolean;
|
||||
FEditing: Boolean;
|
||||
FEditing: Boolean; // In ApplyChangeList, edit actions are caused by the plugin itself
|
||||
FPaintLock: Integer;
|
||||
FOwnPaintLock: Integer;
|
||||
FTextBufferChanging: Boolean;
|
||||
|
||||
@ -766,16 +766,15 @@ begin
|
||||
|
||||
RunCmdSeq([ecChar], ['A']);
|
||||
TestIsCaretLogAndFullText('', 2, 6, LocalText1A);
|
||||
TestExtraCaretPos('', 4, [2,2, 2,3, 2,4, 2,5]);
|
||||
|
||||
RunCmdSeq([ecDeleteLastChar], []);
|
||||
TestIsCaretLogAndFullText('', 1, 6, LocalText1);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
TestExtraCaretPos('', 4, [1,2, 1,3, 1,4, 1,5]);
|
||||
|
||||
RunCmdSeq([ecDeleteLastChar], []);
|
||||
TestIsCaretLogAndFullText('', 6, 1, LocalText1Del);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
TestExtraCaretPos('', 4, [2,1, 3,1, 4,1, 5,1]);
|
||||
|
||||
RunCmdSeq([ecDeleteLastChar], []);
|
||||
TestIsCaretLogAndFullText('', 1, 1, LocalText1Del, [1, '6']);
|
||||
@ -1129,62 +1128,82 @@ procedure TTestMultiCaret.TabKey;
|
||||
Result[6] := '7g';
|
||||
Result[7] := '';
|
||||
end;
|
||||
function LocalText1AfterIndent: TStringArray;
|
||||
begin
|
||||
SetLength(Result, 8);
|
||||
Result[0] := '1a';
|
||||
Result[1] := ' 2b';
|
||||
Result[2] := ' 3c';
|
||||
Result[3] := ' 4d';
|
||||
Result[4] := '5e';
|
||||
Result[5] := '6f';
|
||||
Result[6] := '7g';
|
||||
Result[7] := '';
|
||||
end;
|
||||
begin
|
||||
PushBaseName('ZERO width selection -- WITH eoTabIndent');
|
||||
ReCreateEdit;
|
||||
SynEdit.Options := SynEdit.Options + [eoTabIndent] - [eoTabsToSpaces, eoSmartTabs, eoTrimTrailingSpaces];
|
||||
SetLines(LocalText1);
|
||||
PushBaseName('WITH eoTabIndent');
|
||||
FOptAdd := [eoTabIndent];
|
||||
FOptRemove := [eoTabsToSpaces, eoSmartTabs, eoTrimTrailingSpaces];
|
||||
|
||||
SetCaretAndColumnSelect(2,2, 4,0);
|
||||
TestIsCaretLogAndFullText('', 2, 6, LocalText1);
|
||||
PushBaseName('ZERO width selection');
|
||||
ReCreateEdit(LocalText1);
|
||||
SetCaretAndColumnSelect(2,2, 4,0);
|
||||
TestIsCaretLogAndFullText('', 2, 6, LocalText1);
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1Tab);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1Tab);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
|
||||
PopPushBaseName('ONE width selection');
|
||||
ReCreateEdit(LocalText1);
|
||||
SetCaretAndColumnSelect(2,2, 4,1);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1);
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1TabOver);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
PopBaseName;
|
||||
|
||||
PopPushBaseName('indent selection');
|
||||
ReCreateEdit(LocalText1);
|
||||
SetCaretAndSel(2,2, 2,4);
|
||||
FMultiCaret.AddCaretAtLogPos(3,4,0);
|
||||
FMultiCaret.ActiveMode := mcmMoveAllCarets;
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 4, 4, LocalText1AfterIndent);
|
||||
TestExtraCaretPos('', 1, [5,4]);
|
||||
PopBaseName;
|
||||
|
||||
PopBaseName;
|
||||
|
||||
PushBaseName('WITHOUT eoTabIndent');
|
||||
FOptAdd := [];
|
||||
FOptRemove := [eoTabIndent, eoTabsToSpaces, eoSmartTabs, eoTrimTrailingSpaces];
|
||||
|
||||
PushBaseName('ZERO width selection');
|
||||
ReCreateEdit(LocalText1);
|
||||
SetCaretAndColumnSelect(2,2, 4,0);
|
||||
TestIsCaretLogAndFullText('', 2, 6, LocalText1);
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1Tab);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
|
||||
|
||||
PopPushBaseName('ONE width selection -- WITH eoTabIndent');
|
||||
ReCreateEdit;
|
||||
SynEdit.Options := SynEdit.Options + [eoTabIndent] - [eoTabsToSpaces, eoSmartTabs, eoTrimTrailingSpaces];
|
||||
SetLines(LocalText1);
|
||||
PopPushBaseName('ONE width selection');
|
||||
ReCreateEdit(LocalText1);
|
||||
SetCaretAndColumnSelect(2,2, 4,1);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1);
|
||||
|
||||
SetCaretAndColumnSelect(2,2, 4,1);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1);
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1TabOver);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
|
||||
|
||||
|
||||
PopPushBaseName('ZERO width selection -- WITHOUT eoTabIndent');
|
||||
ReCreateEdit;
|
||||
SynEdit.Options := SynEdit.Options - [eoTabIndent] - [eoTabsToSpaces, eoSmartTabs, eoTrimTrailingSpaces];
|
||||
SetLines(LocalText1);
|
||||
|
||||
SetCaretAndColumnSelect(2,2, 4,0);
|
||||
TestIsCaretLogAndFullText('', 2, 6, LocalText1);
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1Tab);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
|
||||
|
||||
PopPushBaseName('ONE width selection -- WITHOUT eoTabIndent');
|
||||
ReCreateEdit;
|
||||
SynEdit.Options := SynEdit.Options - [eoTabIndent] - [eoTabsToSpaces, eoSmartTabs, eoTrimTrailingSpaces];
|
||||
SetLines(LocalText1);
|
||||
|
||||
SetCaretAndColumnSelect(2,2, 4,1);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1);
|
||||
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1TabOver);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
RunCmdSeq([ecTab], []);
|
||||
TestIsCaretLogAndFullText('', 3, 6, LocalText1TabOver);
|
||||
// 4 extra carets + main caret
|
||||
AssertEquals(BaseTestName+'', 4, FMultiCaret.Carets.Count);
|
||||
PopBaseName;
|
||||
|
||||
PopBaseName;
|
||||
end;
|
||||
|
||||
@ -54,7 +54,7 @@ uses
|
||||
SynEditLines, SynEditStrConst, SynEditTypes, SynEdit, SynRegExpr,
|
||||
SynEditHighlighter, SynEditAutoComplete, SynEditKeyCmds, SynCompletion,
|
||||
SynEditMiscClasses, SynEditMarkupHighAll, SynEditMarks,
|
||||
SynBeautifier,
|
||||
SynBeautifier, SynPluginMultiCaret,
|
||||
SynPluginSyncronizedEditBase, SourceSynEditor,
|
||||
SynExportHTML, SynHighlighterPas, SynEditMarkup, SynEditMarkupIfDef,
|
||||
// Intf
|
||||
@ -291,6 +291,8 @@ type
|
||||
|
||||
procedure UpdateIfDefNodeStates(Force: Boolean = False);
|
||||
protected
|
||||
procedure DoMultiCaretBeforeCommand(Sender: TObject; ACommand: TSynEditorCommand;
|
||||
var AnAction: TSynMultiCaretCommandAction; var AFlags: TSynMultiCaretCommandFlags);
|
||||
procedure ProcessCommand(Sender: TObject;
|
||||
var Command: TSynEditorCommand; var AChar: TUTF8Char; {%H-}Data: pointer);
|
||||
procedure ProcessUserCommand(Sender: TObject;
|
||||
@ -3192,6 +3194,37 @@ begin
|
||||
FEditor.CaretXY := FTempCaret;
|
||||
end;
|
||||
|
||||
procedure TSourceEditor.DoMultiCaretBeforeCommand(Sender: TObject;
|
||||
ACommand: TSynEditorCommand; var AnAction: TSynMultiCaretCommandAction;
|
||||
var AFlags: TSynMultiCaretCommandFlags);
|
||||
begin
|
||||
if (FSourceNoteBook<>nil) and (snIncrementalFind in FSourceNoteBook.States) then begin
|
||||
AnAction := ccaClearCarets;
|
||||
end;
|
||||
|
||||
case ACommand of
|
||||
ecToggleComment:
|
||||
if FEditor.SelAvail then
|
||||
AnAction := ccaAdjustCarets
|
||||
else
|
||||
AnAction := ccaRepeatCommandPerLine; // one per line
|
||||
ecInsertUserName,
|
||||
ecInsertDateTime,
|
||||
ecInsertChangeLogEntry,
|
||||
ecInsertCVSAuthor,
|
||||
ecInsertCVSDate,
|
||||
ecInsertCVSHeader,
|
||||
ecInsertCVSID,
|
||||
ecInsertCVSLog,
|
||||
ecInsertCVSName,
|
||||
ecInsertCVSRevision,
|
||||
ecInsertCVSSource,
|
||||
ecInsertGUID,
|
||||
ecInsertFilename:
|
||||
AnAction := ccaRepeatCommand;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSourceEditor.ProcessCommand(Sender: TObject;
|
||||
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer);
|
||||
// these are normal commands for synedit (lower than ecUserFirst),
|
||||
@ -3264,7 +3297,7 @@ begin
|
||||
|
||||
ecSelEditorTop, ecSelEditorBottom, ecEditorTop, ecEditorBottom:
|
||||
begin
|
||||
if FaOwner<>nil then
|
||||
if (FaOwner<>nil) and (not FEditor.IsInMultiCaretRepeatExecution) then
|
||||
Manager.AddJumpPointClicked(Self);
|
||||
end;
|
||||
|
||||
@ -4529,6 +4562,7 @@ Begin
|
||||
OnPlaceBookmark := @EditorPlaceBookmark;
|
||||
OnClearBookmark := @EditorClearBookmark;
|
||||
OnChangeUpdating := @EditorChangeUpdating;
|
||||
OnMultiCaretBeforeCommand := @DoMultiCaretBeforeCommand;
|
||||
RegisterMouseActionExecHandler(@EditorHandleMouseAction);
|
||||
// IMPORTANT: when you change above, don't forget updating UnbindEditor
|
||||
Parent := AParent;
|
||||
|
||||
@ -233,9 +233,13 @@ type
|
||||
function GetHighlightUserWordCount: Integer;
|
||||
function GetHighlightUserWords(AIndex: Integer): TSourceSynEditMarkupHighlightAllMulti;
|
||||
function GetIDEGutterMarks: TIDESynGutterMarks;
|
||||
function GetIsInMultiCaretMainExecution: Boolean;
|
||||
function GetIsInMultiCaretRepeatExecution: Boolean;
|
||||
function GetOnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand;
|
||||
procedure GetTopInfoMarkupForLine(Sender: TObject; {%H-}Line: integer; var Special: boolean;
|
||||
aMarkup: TSynSelectedColor);
|
||||
procedure SetHighlightUserWordCount(AValue: Integer);
|
||||
procedure SetOnMultiCaretBeforeCommand(AValue: TSynMultiCaretBeforeCommand);
|
||||
procedure SetShowTopInfo(AValue: boolean);
|
||||
procedure SetTopInfoMarkup(AValue: TSynSelectedColor);
|
||||
procedure DoHighlightChanged(Sender: TSynEditStrings; {%H-}AIndex, {%H-}ACount : Integer);
|
||||
@ -271,6 +275,9 @@ type
|
||||
procedure SetIfdefNodeState(ALinePos, AstartPos: Integer; AState: TSynMarkupIfdefNodeState);
|
||||
property OnIfdefNodeStateRequest: TSynMarkupIfdefStateRequest read FOnIfdefNodeStateRequest write FOnIfdefNodeStateRequest;
|
||||
property MarkupIfDef: TSourceSynEditMarkupIfDef read FMarkupIfDef;
|
||||
property IsInMultiCaretMainExecution: Boolean read GetIsInMultiCaretMainExecution;
|
||||
property IsInMultiCaretRepeatExecution: Boolean read GetIsInMultiCaretRepeatExecution;
|
||||
property OnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand read GetOnMultiCaretBeforeCommand write SetOnMultiCaretBeforeCommand;
|
||||
end;
|
||||
|
||||
TIDESynHighlighterPasRangeList = class(TSynHighlighterPasRangeList)
|
||||
@ -1509,6 +1516,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIDESynEditor.SetOnMultiCaretBeforeCommand(AValue: TSynMultiCaretBeforeCommand);
|
||||
begin
|
||||
FMultiCaret.OnBeforeCommand := AValue;
|
||||
end;
|
||||
|
||||
procedure TIDESynEditor.SetShowTopInfo(AValue: boolean);
|
||||
begin
|
||||
if FShowTopInfo = AValue then Exit;
|
||||
@ -1534,6 +1546,21 @@ begin
|
||||
Result := TIDESynGutterMarks(Gutter.Parts.ByClass[TIDESynGutterMarks, 0]);
|
||||
end;
|
||||
|
||||
function TIDESynEditor.GetIsInMultiCaretMainExecution: Boolean;
|
||||
begin
|
||||
Result := FMultiCaret.IsInMainExecution;
|
||||
end;
|
||||
|
||||
function TIDESynEditor.GetIsInMultiCaretRepeatExecution: Boolean;
|
||||
begin
|
||||
Result := FMultiCaret.IsInRepeatExecution;
|
||||
end;
|
||||
|
||||
function TIDESynEditor.GetOnMultiCaretBeforeCommand: TSynMultiCaretBeforeCommand;
|
||||
begin
|
||||
Result := FMultiCaret.OnBeforeCommand;
|
||||
end;
|
||||
|
||||
function TIDESynEditor.IsIfdefMarkupActive: Boolean;
|
||||
begin
|
||||
Result := FMarkupIfDef.RealEnabled;
|
||||
@ -1610,14 +1637,12 @@ begin
|
||||
FUserWordsList := TFPList.Create;
|
||||
FTemplateEdit:=TSynPluginTemplateEdit.Create(Self);
|
||||
FSyncroEdit := TSynPluginSyncroEdit.Create(Self);
|
||||
{$IFnDEF WithoutSynMultiCaret}
|
||||
FMultiCaret := TSynPluginMultiCaret.Create(Self);
|
||||
FMultiCaret.MouseActions.Clear; // will be added to SynEdit
|
||||
FMultiCaret.KeyStrokes.Clear;
|
||||
FMultiCaret.SetCaretTypeSize(ctVerticalLine, 2, 1024, -1, 0, [ccsRelativeHeight]);
|
||||
FMultiCaret.SetCaretTypeSize(ctBlock, 1024, 1024, 0, 0, [ccsRelativeWidth, ccsRelativeHeight]);
|
||||
FMultiCaret.Color := $606060;
|
||||
{$ENDIF}
|
||||
|
||||
FMarkupForGutterMark := TSynEditMarkupGutterMark.Create(Self, FWordBreaker);
|
||||
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FMarkupForGutterMark);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user