SynEdit/IDE: Basic Multi-Caret mode

git-svn-id: trunk@48123 -
This commit is contained in:
martin 2015-03-03 23:51:11 +00:00
parent c303b4f6c3
commit b87c34ebfb
31 changed files with 637 additions and 79 deletions

View File

@ -487,6 +487,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -487,6 +487,10 @@ msgstr "Žádná akce"
msgid "Quick Paste Selection"
msgstr "Rychle vložit výběr"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Režim,Začít,Pokračovat"

View File

@ -490,6 +490,10 @@ msgstr "Keine Aktion"
msgid "Quick Paste Selection"
msgstr "Ausgewählten Text einfügen"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Modus,Beginn,Weiter"

View File

@ -485,6 +485,10 @@ msgstr "Ninguna acción"
msgid "Quick Paste Selection"
msgstr "Pegado Rapido de Selección"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -480,6 +480,10 @@ msgstr "Ei toimintoa"
msgid "Quick Paste Selection"
msgstr "Pika-liitä valinta"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Moodi,Ala,Jatka"

View File

@ -486,6 +486,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -485,6 +485,10 @@ msgstr "ללא פעולה"
msgid "Quick Paste Selection"
msgstr "העתקה מהירה של הבחירה"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "מצב, התחלה, המשך"

View File

@ -487,6 +487,10 @@ msgstr "Nincs művelet"
msgid "Quick Paste Selection"
msgstr "Kijelölés gyors beillesztése"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Mód,Kezdés,Folytatás"

View File

@ -490,6 +490,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -488,6 +488,10 @@ msgstr "Nessuna azione"
msgid "Quick Paste Selection"
msgstr "Selezione incolla veloce"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Modo,inizia,continua"

View File

@ -488,6 +488,10 @@ msgstr "Jokio veiksmo"
msgid "Quick Paste Selection"
msgstr "Spartusis atrankos įdėjimas"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Veiksena,Pradėti,Tęsti"

View File

@ -487,6 +487,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -491,6 +491,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -477,6 +477,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -486,6 +486,10 @@ msgstr "Sem Ação"
msgid "Quick Paste Selection"
msgstr "Colar Seleção Rapidamente"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Modo,Iniciar,Continuar"

View File

@ -486,6 +486,10 @@ msgstr "Нет действия"
msgid "Quick Paste Selection"
msgstr "Быстрая вставка выделенного"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Режим,Начать,Продолжить"

View File

@ -488,6 +488,10 @@ msgstr "Без Дії"
msgid "Quick Paste Selection"
msgstr "Швидкий Вибір Вставки"
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr "Режим,Почати,Продовжити"

View File

@ -490,6 +490,10 @@ msgstr ""
msgid "Quick Paste Selection"
msgstr ""
#: syneditstrconst.syns_emcpluginmulticarettogglecaret
msgid "Toggle extra caret"
msgstr ""
#: syneditstrconst.syns_emcselection_opt
msgid "Mode,Begin,Continue"
msgstr ""

View File

@ -277,6 +277,7 @@ const
ecPluginFirstCompletion = 19000;
ecPluginFirstSyncro = 19010;
ecPluginFirstTemplEdit = 19030;
ecPluginFirstMultiCaret = 19050;
ecPluginFirst = 20000;
@ -1253,6 +1254,7 @@ initialization
finalization
ExtraIdentToIntFn := nil;
ExtraIntToIdentFn := nil;
ExtraGetEditorCommandValues := nil;
end.

View File

@ -35,8 +35,8 @@ unit SynEditMouseCmds;
interface
uses
LazSynEditMouseCmdsTypes, Classes, Controls, SysUtils, SynEditStrConst, SynEditPointClasses, Dialogs,
LCLProc, Menus;
LazSynEditMouseCmdsTypes, Classes, Controls, SysUtils, SynEditStrConst, SynEditPointClasses,
SynEditKeyCmds, Dialogs, LCLProc, Menus;
type
@ -306,6 +306,9 @@ const
emcoWheelScrollPages = TSynEditorMouseCommandOpt(2); // Opt2 > 0 ==> percentage
emcoWheelScrollPagesLessOne = TSynEditorMouseCommandOpt(3); // Opt2 > 0 ==> percentage
type
TMouseCmdNameAndOptProcs = function(emc: TSynEditorMouseCommand): String;
// Plugins don't know of other plugins, so they need to map the codes
// Plugins all start at ecPluginFirst (overlapping)
// If ask by SynEdit they add an offset
@ -316,8 +319,14 @@ function AllocatePluginMouseRange(Count: Integer; OffsetOnly: Boolean = False):
function MouseCommandName(emc: TSynEditorMouseCommand): String;
function MouseCommandConfigName(emc: TSynEditorMouseCommand): String;
function SynMouseCmdToIdent(SynMouseCmd: Longint; out Ident: String): Boolean;
function IdentToSynMouseCmd(const Ident: string; out SynMouseCmd: Longint): Boolean;
function SynMouseCmdToIdent(SynMouseCmd: Longint; var Ident: String): Boolean;
function IdentToSynMouseCmd(const Ident: string; var SynMouseCmd: Longint): Boolean;
procedure GetEditorMouseCommandValues(Proc: TGetStrProc);
procedure RegisterMouseCmdIdentProcs(IdentToIntFn: TIdentToInt; IntToIdentFn: TIntToIdent);
procedure RegisterExtraGetEditorMouseCommandValues(AProc: TGetEditorCommandValuesProc);
procedure RegisterMouseCmdNameAndOptProcs(ANamesProc: TMouseCmdNameAndOptProcs; AOptProc: TMouseCmdNameAndOptProcs = nil);
const
SYNEDIT_LINK_MODIFIER = {$IFDEF LCLcarbon}ssMeta{$ELSE}ssCtrl{$ENDIF};
@ -326,28 +335,28 @@ implementation
const
SynMouseCommandNames: array [0..27] of TIdentMapEntry = (
(Value: emcNone; Name: 'emcNone'),
(Value: emcStartSelections; Name: 'emcStartSelections'),
(Value: emcNone; Name: 'emcNone'),
(Value: emcStartSelections; Name: 'emcStartSelections'),
(Value: emcStartColumnSelections; Name: 'emcStartColumnSelections'),
(Value: emcStartLineSelections; Name: 'emcStartLineSelections'),
(Value: emcStartLineSelections; Name: 'emcStartLineSelections'),
(Value: emcSelectWord; Name: 'emcSelectWord'),
(Value: emcSelectLine; Name: 'emcSelectLine'),
(Value: emcSelectPara; Name: 'emcSelectPara'),
(Value: emcSelectWord; Name: 'emcSelectWord'),
(Value: emcSelectLine; Name: 'emcSelectLine'),
(Value: emcSelectPara; Name: 'emcSelectPara'),
(Value: emcStartDragMove; Name: 'emcStartDragMove'),
(Value: emcPasteSelection; Name: 'emcPasteSelection'),
(Value: emcMouseLink; Name: 'emcMouseLink'),
(Value: emcStartDragMove; Name: 'emcStartDragMove'),
(Value: emcPasteSelection; Name: 'emcPasteSelection'),
(Value: emcMouseLink; Name: 'emcMouseLink'),
(Value: emcContextMenu; Name: 'emcContextMenu'),
(Value: emcContextMenu; Name: 'emcContextMenu'),
(Value: emcOnMainGutterClick; Name: 'emcOnMainGutterClick'),
(Value: emcOnMainGutterClick; Name: 'emcOnMainGutterClick'),
(Value: emcCodeFoldCollaps; Name: 'emcCodeFoldCollaps'),
(Value: emcCodeFoldExpand; Name: 'emcCodeFoldExpand'),
(Value: emcCodeFoldContextMenu; Name: 'emcCodeFoldContextMenu'),
(Value: emcCodeFoldCollaps; Name: 'emcCodeFoldCollaps'),
(Value: emcCodeFoldExpand; Name: 'emcCodeFoldExpand'),
(Value: emcCodeFoldContextMenu; Name: 'emcCodeFoldContextMenu'),
(Value: emcSynEditCommand; Name: 'emcSynEditCommand'),
(Value: emcSynEditCommand; Name: 'emcSynEditCommand'),
(Value: emcWheelScrollDown; Name: 'emcWheelScrollDown'),
(Value: emcWheelScrollUp; Name: 'emcWheelScrollUp'),
@ -356,16 +365,23 @@ const
(Value: emcWheelHorizScrollDown; Name: 'emcWheelHorizScrollDown'),
(Value: emcWheelHorizScrollUp; Name: 'emcWheelHorizScrollUp'),
(Value: emcWheelZoomOut; Name: 'emcWheelZoomOut'),
(Value: emcWheelZoomIn; Name: 'emcWheelZoomIn'),
(Value: emcWheelZoomNorm; Name: 'emcWheelZoomNorm'),
(Value: emcWheelZoomOut; Name: 'emcWheelZoomOut'),
(Value: emcWheelZoomIn; Name: 'emcWheelZoomIn'),
(Value: emcWheelZoomNorm; Name: 'emcWheelZoomNorm'),
(Value: emcStartSelectTokens; Name: 'emcStartSelectTokens'),
(Value: emcStartSelectWords; Name: 'emcStartSelectWords'),
(Value: emcStartSelectLines; Name: 'emcStartSelectLines')
(Value: emcStartSelectTokens; Name: 'emcStartSelectTokens'),
(Value: emcStartSelectWords; Name: 'emcStartSelectWords'),
(Value: emcStartSelectLines; Name: 'emcStartSelectLines')
);
var
ExtraIdentToIntFn: Array of TIdentToInt = nil;
ExtraIntToIdentFn: Array of TIntToIdent = nil;
ExtraGetEditorCommandValues: Array of TGetEditorCommandValuesProc = nil;
ExtraMouseCmdNameFn: Array of TMouseCmdNameAndOptProcs = nil;
ExtraMouseCmdOptFn: Array of TMouseCmdNameAndOptProcs = nil;
function AllocatePluginMouseRange(Count: Integer; OffsetOnly: Boolean = False): integer;
const
CurOffset : integer = 0;
@ -377,6 +393,8 @@ begin
end;
function MouseCommandName(emc: TSynEditorMouseCommand): String;
var
i: Integer;
begin
case emc of
emcNone: Result := SYNS_emcNone;
@ -414,11 +432,20 @@ begin
emcStartSelectWords: Result := SYNS_emcStartSelectWords;
emcStartSelectLines: Result := SYNS_emcStartSelectLines;
else Result := ''
else begin
Result := '';
i := 0;
while (i < length(ExtraMouseCmdNameFn)) and (Result = '') do begin
Result := ExtraMouseCmdNameFn[i](emc);
inc(i);
end;
end;
end;
end;
function MouseCommandConfigName(emc: TSynEditorMouseCommand): String;
var
i: Integer;
begin
case emc of
emcStartSelections,
@ -431,20 +458,90 @@ begin
emcContextMenu: Result := SYNS_emcContextMenuCaretMove_opt;
emcWheelScrollDown..emcWheelVertScrollUp:
Result := SYNS_emcWheelScroll_opt;
else Result := ''
else begin
Result := '';
i := 0;
while (i < length(ExtraMouseCmdOptFn)) and (Result = '') do begin
Result := ExtraMouseCmdOptFn[i](emc);
inc(i);
end;
end;
end;
end;
function SynMouseCmdToIdent(SynMouseCmd: Longint; out Ident: String): Boolean;
function SynMouseCmdToIdent(SynMouseCmd: Longint; var Ident: String): Boolean;
var
i: Integer;
begin
Ident := '';
Result := IntToIdent(SynMouseCmd, Ident, SynMouseCommandNames);
i := 0;
while (i < length(ExtraIntToIdentFn)) and (not Result) do begin
Result := ExtraIntToIdentFn[i](SynMouseCmd, Ident);
inc(i);
end;
end;
function IdentToSynMouseCmd(const Ident: string; out SynMouseCmd: Longint): Boolean;
function IdentToSynMouseCmd(const Ident: string; var SynMouseCmd: Longint): Boolean;
var
i: Integer;
begin
SynMouseCmd := 0;
Result := IdentToInt(Ident, SynMouseCmd, SynMouseCommandNames);
i := 0;
while (i < length(ExtraIdentToIntFn)) and (not Result) do begin
Result := ExtraIdentToIntFn[i](Ident, SynMouseCmd);
inc(i);
end;
end;
procedure GetEditorMouseCommandValues(Proc: TGetStrProc);
var
i: Integer;
begin
for i := Low(SynMouseCommandNames) to High(SynMouseCommandNames) do
Proc(SynMouseCommandNames[I].Name);
i := 0;
while (i < length(ExtraGetEditorCommandValues)) do begin
ExtraGetEditorCommandValues[i](Proc);
inc(i);
end;
end;
procedure RegisterMouseCmdIdentProcs(IdentToIntFn: TIdentToInt; IntToIdentFn: TIntToIdent);
var
i: Integer;
begin
i := length(ExtraIdentToIntFn);
SetLength(ExtraIdentToIntFn, i + 1);
ExtraIdentToIntFn[i] := IdentToIntFn;
i := length(ExtraIntToIdentFn);
SetLength(ExtraIntToIdentFn, i + 1);
ExtraIntToIdentFn[i] := IntToIdentFn;
end;
procedure RegisterExtraGetEditorMouseCommandValues(AProc: TGetEditorCommandValuesProc);
var
i: Integer;
begin
i := length(ExtraGetEditorCommandValues);
SetLength(ExtraGetEditorCommandValues, i + 1);
ExtraGetEditorCommandValues[i] := AProc;
end;
procedure RegisterMouseCmdNameAndOptProcs(ANamesProc: TMouseCmdNameAndOptProcs;
AOptProc: TMouseCmdNameAndOptProcs);
var
i: Integer;
begin
i := length(ExtraMouseCmdNameFn);
SetLength(ExtraMouseCmdNameFn, i + 1);
ExtraMouseCmdNameFn[i] := ANamesProc;
if AOptProc = nil then
exit;
i := length(ExtraMouseCmdOptFn);
SetLength(ExtraMouseCmdOptFn, i + 1);
ExtraMouseCmdOptFn[i] := AOptProc;
end;
{ TSynEditMouseInternalActions }
@ -928,7 +1025,14 @@ begin
end;
initialization
RegisterIntegerConsts(TypeInfo(TSynEditorMouseCommand), TIdentToInt(@IdentToSynMouseCmd), TIntToIdent(@SynMouseCmdToIdent));
RegisterIntegerConsts(TypeInfo(TSynEditorMouseCommand), @IdentToSynMouseCmd, @SynMouseCmdToIdent);
finalization
ExtraIdentToIntFn := nil;
ExtraIntToIdentFn := nil;
ExtraGetEditorCommandValues := nil;
ExtraMouseCmdNameFn := nil;
ExtraMouseCmdOptFn := nil;
end.

View File

@ -2836,6 +2836,10 @@ end;
procedure TSynEditScreenCaretPainterInternal.BeginScroll(dx, dy: Integer; const rcScroll,
rcClip: TRect);
{$IFDEF SynCaretNoHideInSroll}
var
rs: TIsInRectState;
{$ENDIF}
begin
assert(not((FInPaint or FInScroll)), 'TSynEditScreenCaretPainterInternal.BeginScroll: not((FInPaint or FInScroll))');
if (FState <> []) then
@ -2847,7 +2851,11 @@ begin
inherited SetCaretPosEx(-1,-1);
end;
{$ELSE}
if ((IsInRect(rcClip) = irPartInside) or (IsInRect(rcScroll) = irPartInside)) and FIsDrawn then begin
rs := IsInRect(rcScroll);
if not( ((IsInRect(rcClip) = irOutside) and (rs = irOutside)) or
((IsInRect(rcClip, Left+dx, Top+dy, Width, Height) = irInside) and (rs = irInside))
)
then begin
HideCaret;
inherited SetCaretPosEx(-1,-1);
end;

View File

@ -434,6 +434,7 @@ resourcestring
SYNS_emcContextMenuCaretMove_opt = '"Move caret, when selection exists", Never, "Click outside", Always';
SYNS_emcWheelScroll_opt = 'Speed,"System settings",Lines,Pages,"Pages (less one line)"';
SYNS_emcPluginMultiCaretToggleCaret = 'Toggle extra caret';
implementation
end.

View File

@ -14,6 +14,7 @@ interface
uses
Classes, SysUtils, SynEdit, SynEditPointClasses, SynEditKeyCmds, SynEditTypes,
LazSynTextArea, SynEditMiscProcs, LazSynEditText, SynEditMiscClasses, SynEditMouseCmds,
SynEditStrConst,
{$IfDef SynMultiCaretDebug} LazLoggerBase, {$ELSE} LazLoggerDummy, {$ENDIF}
LCLType, Controls, Graphics, Clipbrd;
@ -21,6 +22,11 @@ const
emcPluginMultiCaretToggleCaret = emcPluginFirstMultiCaret;
//ecPluginMultiCaretSetCaret = ecPluginFirstMultiCaret + 0;
//ecPluginMultiCaretUnsetCaret = ecPluginFirstMultiCaret + 1;
//ecPluginMultiCaretToggleCaret = ecPluginFirstMultiCaret + 2;
//ecPluginMultiCaretClearAll = ecPluginFirstMultiCaret + 3;
type
TSynPluginMultiCaretVisualList = class;
@ -177,18 +183,30 @@ type
procedure ResetDefaults; override;
end;
{ TSynPluginMultiCaret }
{ TSynPluginMultiCaretKeyStrokes }
TSynPluginMultiCaretKeyStrokes = class(TSynEditKeyStrokes)
public
procedure ResetDefaults; override;
end;
{ TSynCustomPluginMultiCaret }
TSynPluginMultiCaretStateFlag = (
sfProcessingCmd, sfProcessingMain,
sfExtendingColumnSel
sfExtendingColumnSel, sfSkipCaretsAtSelection
);
TSynPluginMultiCaretStateFlags = set of TSynPluginMultiCaretStateFlag;
TSynPluginMultiCaret = class(TSynPluginMultiCaretBase)
TSynCustomPluginMultiCaret = class(TSynPluginMultiCaretBase)
private
FEnableWithColumnSelection: Boolean;
FStateFlags: TSynPluginMultiCaretStateFlags;
FMouseActions: TSynPluginMultiCaretMouseActions;
FSelY1, FSElY2, FSelX: Integer;
procedure RemoveCaretsInSelection;
procedure SetSkipCaretAtSel;
protected
procedure DoEditorRemoving(AValue: TCustomSynEdit); override;
procedure DoEditorAdded(AValue: TCustomSynEdit); override;
@ -210,7 +228,15 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function AddCaretAt(X, Y: Integer): Integer;
property MouseActions: TSynPluginMultiCaretMouseActions read FMouseActions;
property EnableWithColumnSelection: Boolean read FEnableWithColumnSelection write FEnableWithColumnSelection default True;
end;
TSynPluginMultiCaret = class(TSynCustomPluginMultiCaret)
published
property MouseActions;
property EnableWithColumnSelection;
end;
implementation
@ -223,6 +249,48 @@ var
const
EMPTY_LIST_LEN = 8;
SynMouseCommandNames: array [0..0] of TIdentMapEntry = (
(Value: emcPluginMultiCaretToggleCaret; Name: 'emcPluginMultiCaretToggleCaret')
);
function SynMouseCmdToIdent(SynMouseCmd: Longint; var Ident: String): Boolean;
begin
Ident := '';
Result := IntToIdent(SynMouseCmd, Ident, SynMouseCommandNames);
end;
function IdentToSynMouseCmd(const Ident: string; var SynMouseCmd: Longint): Boolean;
begin
SynMouseCmd := 0;
Result := IdentToInt(Ident, SynMouseCmd, SynMouseCommandNames);
end;
procedure GetEditorMouseCommandValues(Proc: TGetStrProc);
var
i: Integer;
begin
for i := Low(SynMouseCommandNames) to High(SynMouseCommandNames) do
Proc(SynMouseCommandNames[I].Name);
end;
function MouseCommandName(emc: TSynEditorMouseCommand): String;
begin
case emc of
emcPluginMultiCaretToggleCaret: Result := SYNS_emcPluginMultiCaretToggleCaret;
else
Result := '';
end;
end;
function MouseCommandConfigName(emc: TSynEditorMouseCommand): String;
begin
case emc of
emcPluginMultiCaretToggleCaret: Result := '';
else
Result := '';
end;
end;
{ TSynPluginMultiCaretVisual }
constructor TSynPluginMultiCaretVisual.Create(AHandleOwner: TWinControl;
@ -1135,9 +1203,60 @@ begin
AddCommand(emcPluginMultiCaretToggleCaret, False, mbXMiddle, ccAny, cdDown, [ssShift], [ssShift,ssCtrl,ssAlt]);
end;
{ TSynPluginMultiCaret }
{ TSynPluginMultiCaretKeyStrokes }
procedure TSynPluginMultiCaret.DoEditorRemoving(AValue: TCustomSynEdit);
procedure TSynPluginMultiCaretKeyStrokes.ResetDefaults;
begin
inherited ResetDefaults;
end;
{ TSynCustomPluginMultiCaret }
procedure TSynCustomPluginMultiCaret.RemoveCaretsInSelection;
var
i, x, y: Integer;
bb, be: TPoint;
sm: TSynSelectionMode;
begin
bb := SelectionObj.FirstLineBytePos;
be := SelectionObj.LastLineBytePos;
sm := SelectionObj.ActiveSelectionMode;
if sm = smLine then begin
bb.x := 0;
be.x := MaxInt;
end;
if (sm = smColumn) and (bb.x > be.x) then begin
if bb.x = be.x then
exit;
i := bb.x;
bb.x := be.x;
be.x := i;
end;
i := CaretsCount;
while i > 0 do begin
dec(i);
x := Carets.Caret[i].x;
y := Carets.Caret[i].y;
if (y < bb.y) or
(y > be.y) or
( ((y = bb.y) or (sm = smColumn)) and (x <= bb.x) ) or
( ((y = be.y) or (sm = smColumn)) and (x >= be.x) )
then
Continue;
Carets.RemoveCaret(i);
end;
end;
procedure TSynCustomPluginMultiCaret.SetSkipCaretAtSel;
begin
Include(FStateFlags, sfSkipCaretsAtSelection);
FSelY1 := SelectionObj.FirstLineBytePos.y;
FSElY2 := SelectionObj.LastLineBytePos.y;
FSelX := SelectionObj.FirstLineBytePos.x;
end;
procedure TSynCustomPluginMultiCaret.DoEditorRemoving(AValue: TCustomSynEdit);
begin
if Editor <> nil then begin
CaretObj.RemoveChangeHandler(@DoCaretChanged);
@ -1150,7 +1269,7 @@ begin
inherited DoEditorRemoving(AValue);
end;
procedure TSynPluginMultiCaret.DoEditorAdded(AValue: TCustomSynEdit);
procedure TSynCustomPluginMultiCaret.DoEditorAdded(AValue: TCustomSynEdit);
begin
inherited DoEditorAdded(AValue);
if Editor <> nil then begin
@ -1163,7 +1282,7 @@ begin
end;
end;
procedure TSynPluginMultiCaret.DoAfterDecPaintLock(Sender: TObject);
procedure TSynCustomPluginMultiCaret.DoAfterDecPaintLock(Sender: TObject);
begin
if FPaintLock > 1 then begin
inherited DoAfterDecPaintLock(Sender);
@ -1175,14 +1294,14 @@ begin
FStateFlags := FStateFlags - [sfProcessingCmd, sfExtendingColumnSel];
end;
procedure TSynPluginMultiCaret.DoCaretChanged(Sender: TObject);
procedure TSynCustomPluginMultiCaret.DoCaretChanged(Sender: TObject);
begin
if (FStateFlags * [sfProcessingCmd, sfExtendingColumnSel] <> []) then
exit;
ClearCarets;
end;
procedure TSynPluginMultiCaret.DoSelectionChanged(Sender: TObject);
procedure TSynCustomPluginMultiCaret.DoSelectionChanged(Sender: TObject);
var
i, x, y1, y2, y3: Integer;
c: TPoint;
@ -1190,7 +1309,7 @@ begin
if (sfProcessingCmd in FStateFlags) then exit;
y1 := Editor.BlockBegin.y;
y2 := Editor.BlockEnd.y;
If not ((y1 <> y2) and (Editor.SelectionMode = smColumn)) then begin
If not ((y1 <> y2) and (Editor.SelectionMode = smColumn) and EnableWithColumnSelection) then begin
ClearCarets;
exit;
end;
@ -1214,31 +1333,34 @@ begin
end;
procedure TSynPluginMultiCaret.DoBeforeSetSelText(Sender: TObject; AMode: TSynSelectionMode;
procedure TSynCustomPluginMultiCaret.DoBeforeSetSelText(Sender: TObject; AMode: TSynSelectionMode;
ANewText: PChar);
begin
SelectionObj.RemoveBeforeSetSelTextHandler(@DoBeforeSetSelText);
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, 'TSynPluginMultiCaret.ProcessSynCommand: Maincaret index not found');
assert(False, 'TSynCustomPluginMultiCaret.ProcessSynCommand: Maincaret index not found');
end;
procedure TSynPluginMultiCaret.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
procedure TSynCustomPluginMultiCaret.ProcessSynCommand(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
procedure ExecCommandRepeated;
var
c, i: Integer;
c, i, y: Integer;
p: TPoint;
begin
Handled := True;
Editor.BeginUpdate(True);
try
c := AddCaret(Editor.LogicalCaretXY.x, Editor.CaretY, [cfMainCaret, cfNoneVisual, cfAddDuplicate]);
c := AddCaret(Editor.LogicalCaretXY.x, Editor.CaretY, [cfMainCaret, cfNoneVisual {, cfAddDuplicate}]);
// Execute Command at current caret pos
Include(FStateFlags, sfProcessingMain);
@ -1251,9 +1373,20 @@ procedure TSynPluginMultiCaret.ProcessSynCommand(Sender: TObject; AfterProcessin
// Repeat command
CaretObj.IncForcePastEOL;
for i := 0 to CaretsCount - 1 do begin
i := CaretsCount;
y := FSElY2;
while i > 0 do begin
dec(i);
if i = c then continue;
Editor.LogicalCaretXY := Carets.Caret[i];
p := Carets.Caret[i];
if y > p.y then y := p.y;
if (sfSkipCaretsAtSelection in FStateFlags) and (y >= FSElY1) and
(y = p.y) and (FSelX = p.x)
then begin
dec(y);
continue;
end;
Editor.LogicalCaretXY := p;
Editor.CommandProcessor(Command, AChar, nil, [hcfInit, hcfFinish]);
end;
CaretObj.DecForcePastEOL;
@ -1264,7 +1397,7 @@ procedure TSynPluginMultiCaret.ProcessSynCommand(Sender: TObject; AfterProcessin
RemoveCaret(Carets.MainCaretIndex);
end
else
assert(False, 'TSynPluginMultiCaret.ProcessSynCommand: Maincaret index not found');
assert(False, 'TSynCustomPluginMultiCaret.ProcessSynCommand: Maincaret index not found');
finally
Editor.EndUpdate;
end;
@ -1298,6 +1431,11 @@ begin
ecLineBreak..ecChar:
begin
Include(FStateFlags, sfProcessingCmd);
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;
@ -1341,7 +1479,7 @@ begin
RemoveCaret(Carets.MainCaretIndex);
end
else
assert(False, 'TSynPluginMultiCaret.ProcessSynCommand: Maincaret index not found');
assert(False, 'TSynCustomPluginMultiCaret.ProcessSynCommand: Maincaret index not found');
ExecCommandRepeated;
finally
Editor.EndUpdate;
@ -1370,13 +1508,13 @@ begin
end;
function TSynPluginMultiCaret.MaybeHandleMouseAction(var AnInfo: TSynEditMouseActionInfo;
function TSynCustomPluginMultiCaret.MaybeHandleMouseAction(var AnInfo: TSynEditMouseActionInfo;
HandleActionProc: TSynEditMouseActionHandler): Boolean;
begin
Result := HandleActionProc(FMouseActions, AnInfo);
end;
function TSynPluginMultiCaret.DoHandleMouseAction(AnAction: TSynEditMouseAction;
function TSynCustomPluginMultiCaret.DoHandleMouseAction(AnAction: TSynEditMouseAction;
var AnInfo: TSynEditMouseActionInfo): Boolean;
var
i: Integer;
@ -1388,32 +1526,43 @@ begin
if i >= 0 then
RemoveCaret(i)
else
if (AnInfo.NewCaret.BytePos <> CaretObj.BytePos) or (AnInfo.NewCaret.LinePos <> CaretObj.LinePos) then
AddCaret(AnInfo.NewCaret.BytePos, AnInfo.NewCaret.LinePos);
end;
end;
function TSynPluginMultiCaret.CreateVisual: TSynPluginMultiCaretVisual;
function TSynCustomPluginMultiCaret.CreateVisual: TSynPluginMultiCaretVisual;
begin
Result := inherited CreateVisual;
if FInPaint then
Result.BeginPaint(FPaintClip);
end;
constructor TSynPluginMultiCaret.Create(AOwner: TComponent);
constructor TSynCustomPluginMultiCaret.Create(AOwner: TComponent);
begin
FMouseActions := TSynPluginMultiCaretMouseActions.Create(Self);
FMouseActions.ResetDefaults;
FEnableWithColumnSelection := True;
inherited Create(AOwner);
end;
destructor TSynPluginMultiCaret.Destroy;
destructor TSynCustomPluginMultiCaret.Destroy;
begin
inherited Destroy;
FreeAndNil(FMouseActions);
end;
{$IfDef SynMultiCaretDebug}
function TSynCustomPluginMultiCaret.AddCaretAt(X, Y: Integer): Integer;
begin
AddCaret(x, y);
end;
initialization
RegisterMouseCmdIdentProcs(@IdentToSynMouseCmd, @SynMouseCmdToIdent);
RegisterExtraGetEditorMouseCommandValues(@GetEditorMouseCommandValues);
RegisterMouseCmdNameAndOptProcs(@MouseCommandName, @MouseCommandConfigName);
{$IfDef SynMultiCaretDebug}
SynMCaretDebug := DebugLogger.FindOrRegisterLogGroup('SynMultiCaretDebug' {$IFDEF SynMultiCaretDebug} , True {$ENDIF} );
{$ENDIF}
end.

View File

@ -22,10 +22,13 @@ type
FMultiCaret: TSynPluginMultiCaretTest;
public
procedure ReCreateEdit; reintroduce;
procedure ReCreateEdit(ALines: TStringArray; AOpt: TSynEditorOptions2 = [];
AOptRemove: TSynEditorOptions2 = []);
procedure RunCmdSeq(cmds: Array of TSynEditorCommand; chars: array of String);
published
procedure CaretList;
procedure Edit;
procedure Delete;
procedure ReplaceColSel;
procedure TabKey;
procedure Paste;
@ -44,6 +47,14 @@ begin
SynEdit.TabWidth := 4;
end;
procedure TTestMultiCaret.ReCreateEdit(ALines: TStringArray; AOpt: TSynEditorOptions2;
AOptRemove: TSynEditorOptions2);
begin
ReCreateEdit;
SynEdit.Options2 := SynEdit.Options2 - AOptRemove + AOpt;
SetLines(ALines);
end;
procedure TTestMultiCaret.RunCmdSeq(cmds: array of TSynEditorCommand; chars: array of String);
var
i, j: Integer;
@ -231,6 +242,182 @@ begin
end;
procedure TTestMultiCaret.Delete;
function TestText1: TStringArray;
begin
SetLength(Result, 8);
Result[0] := '1aA';
Result[1] := '2bB';
Result[2] := '3cC';
Result[3] := '4dD';
Result[4] := '5eE';
Result[5] := '6fF';
Result[6] := '7gG';
Result[7] := '';
end;
function TestText1Del: TStringArray;
begin
SetLength(Result, 8);
Result[0] := '1aA';
Result[1] := '2B';
Result[2] := '3C';
Result[3] := '4D';
Result[4] := '5E';
Result[5] := '6F';
Result[6] := '7gG';
Result[7] := '';
end;
function TestText1Del2: TStringArray;
begin
SetLength(Result, 8);
Result[0] := '1aA';
Result[1] := 'B';
Result[2] := 'C';
Result[3] := 'D';
Result[4] := 'E';
Result[5] := 'F';
Result[6] := '7gG';
Result[7] := '';
end;
function TestText1DelExtra: TStringArray;
begin
SetLength(Result, 8);
Result[0] := '1aA';
Result[1] := '2B';
Result[2] := '3';
Result[3] := 'D';
Result[4] := '5E';
Result[5] := '6F';
Result[6] := '7gG';
Result[7] := '';
end;
var
Opt, OptRemove: TSynEditorOptions2;
begin
PushBaseName('NO eoPersistentBlock, HAS eoOverwriteBlock');
Opt := [eoOverwriteBlock];
OptRemove := [eoPersistentBlock];
PushBaseName('ecDeleteLastChar');
PushBaseName('ecDeleteLastChar - zero width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(3,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown], []);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteLastChar - ONE width backward sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(3,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelLeft], []);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteLastChar - ONE width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(2,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight], []);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteLastChar - Two width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(1,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight, ecColSelRight], []);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1Del2);
TestIsCaret('', 1, 6);
PopPushBaseName('ecDeleteLastChar - ONE width sel / extra caret');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(2,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight], []);
FMultiCaret.AddCaretAt(4,3);
FMultiCaret.AddCaretAt(2,4);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1DelExtra);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteChar');
PushBaseName('ecDeleteChar - zero width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(2,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown], []);
RunCmdSeq([ecDeleteChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteChar - ONE width backward sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(3,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelLeft], []);
RunCmdSeq([ecDeleteChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteChar - ONE width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(2,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight], []);
RunCmdSeq([ecDeleteChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteChar - Two width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(1,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight, ecColSelRight], []);
RunCmdSeq([ecDeleteChar], []);
TestIsFullText('', TestText1Del2);
TestIsCaret('', 1, 6);
PopBaseName;
PopBaseName;
PopPushBaseName('NO eoPersistentBlock, NO eoOverwriteBlock');
Opt := [];
OptRemove := [eoOverwriteBlock, eoPersistentBlock];
PushBaseName('ecDeleteLastChar');
PopPushBaseName('ecDeleteLastChar - Two width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(1,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight, ecColSelRight], []);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopPushBaseName('ecDeleteChar');
PopPushBaseName('ecDeleteChar - Two width backward sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(4,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelLeft, ecColSelLeft], []);
RunCmdSeq([ecDeleteChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopBaseName;
PopBaseName;
PopPushBaseName('NO eoPersistentBlock, NO eoOverwriteBlock');
Opt := [eoPersistentBlock];
OptRemove := [eoOverwriteBlock];
PopPushBaseName('ecDeleteLastChar - Two width sel');
ReCreateEdit(TestText1, Opt, OptRemove);
SetCaret(1,2);
RunCmdSeq([ecColSelDown, ecColSelDown, ecColSelDown, ecColSelDown, ecColSelRight, ecColSelRight], []);
RunCmdSeq([ecDeleteLastChar], []);
TestIsFullText('', TestText1Del);
TestIsCaret('', 2, 6);
PopBaseName;
end;
procedure TTestMultiCaret.ReplaceColSel;
function TestText1: TStringArray;
begin

View File

@ -59,7 +59,7 @@ uses
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP, SynHighlighterSQL,
SynHighlighterPython, SynHighlighterUNIXShellScript, SynHighlighterXML,
SynHighlighterJScript, SynHighlighterDiff, SynHighlighterBat, SynHighlighterIni,
SynHighlighterPo,
SynHighlighterPo, SynPluginMultiCaret,
// codetools
LinkScanner, CodeToolManager,
// IDEIntf
@ -736,6 +736,8 @@ type
mbaContextMenuDebug,
mbaContextMenuTab,
mbaMultiCaretToggle,
// Old values, needed to load old config
moTCLNone, moTMIgnore,
moTMPaste,
@ -743,7 +745,7 @@ type
moTCLJumpOrBlock
);
TMouseOptButtonAction = mbaNone..mbaContextMenuTab;
TMouseOptButtonAction = mbaNone..mbaMultiCaretToggle;
const
MouseOptButtonActionOld: Array [moTCLNone..moTCLJumpOrBlock] of TMouseOptButtonActionOld = (
@ -913,7 +915,7 @@ type
property TextAltLeftClick: TMouseOptButtonAction read FTextAltLeftClick write FTextAltLeftClick
default mbaSelectColumn;
property TextShiftCtrlLeftClick: TMouseOptButtonAction read FTextShiftCtrlLeftClick write FTextShiftCtrlLeftClick
default mbaNone; // continue selection
default mbaMultiCaretToggle; // continue selection
property TextShiftAltLeftClick: TMouseOptButtonAction read FTextShiftAltLeftClick write FTextShiftAltLeftClick
default mbaNone; // continue selection
property TextAltCtrlLeftClick: TMouseOptButtonAction read FTextAltCtrlLeftClick write FTextAltCtrlLeftClick
@ -1312,6 +1314,7 @@ type
fUndoLimit: Integer;
fTabWidth: Integer;
FBracketHighlightStyle: TSynEditBracketHighlightStyle;
FMultiCaretOnColumnSelect: Boolean;
// Display options
fVisibleRightMargin: Boolean;
@ -1586,6 +1589,8 @@ type
property ReverseFoldPopUpOrder: Boolean
read FReverseFoldPopUpOrder write FReverseFoldPopUpOrder default True;
property UseTabHistory: Boolean read fUseTabHistory write fUseTabHistory;
property MultiCaretOnColumnSelect: Boolean
read FMultiCaretOnColumnSelect write FMultiCaretOnColumnSelect default True;
// Highlighter Pas
property PasExtendedKeywordsMode: Boolean
@ -3260,7 +3265,7 @@ begin
FTextAltCtrlLeftClick := mbaNone;
FTextShiftLeftClick := mbaNone;
FTextShiftAltLeftClick := mbaNone;
FTextShiftCtrlLeftClick := mbaNone;
FTextShiftCtrlLeftClick := mbaMultiCaretToggle;
FTextShiftAltCtrlLeftClick := mbaNone;
// middle
FTextMiddleClick := mbaPaste;
@ -3431,6 +3436,8 @@ procedure TEditorMouseOptions.ResetTextToDefault;
AddCommand(emcContextMenu, True, AButton, AClickCount, ADir, AShift, AShiftMask, emcoSelectionCaretMoveOutside, 0, 1);
mbaContextMenuTab:
AddCommand(emcContextMenu, True, AButton, AClickCount, ADir, AShift, AShiftMask, emcoSelectionCaretMoveOutside, 0, 2);
mbaMultiCaretToggle:
AddCommand(emcPluginMultiCaretToggleCaret, True, AButton, AClickCount, ADir, AShift, AShiftMask, 0, 0, 0);
end;
end;
end;
@ -3505,8 +3512,8 @@ begin
if FTextShiftCtrlLeftClick = mbaNone
then SelKey := [ssShift]
else SelKey := [];
AddBtnClick(FTextCtrlLeftClick, mbXLeft, [SYNEDIT_LINK_MODIFIER], ModKeys, False, SelKey);
AddBtnClick(FTextShiftCtrlLeftClick, mbXLeft, [ssShift, SYNEDIT_LINK_MODIFIER], ModKeys, False, SelKey);
AddBtnClick(FTextCtrlLeftClick, mbXLeft, [SYNEDIT_LINK_MODIFIER], ModKeys, False, SelKey);
AddBtnClick(FTextShiftCtrlLeftClick, mbXLeft, [ssShift, SYNEDIT_LINK_MODIFIER], ModKeys, False, SelKey);
if FTextShiftAltLeftClick = mbaNone
then SelKey := [ssShift]
@ -4387,6 +4394,7 @@ begin
FGutterSeparatorIndex := 3;
fSynEditOptions := SynEditDefaultOptions;
fSynEditOptions2 := SynEditDefaultOptions2;
FMultiCaretOnColumnSelect := True;
// Display options
fEditorFont := SynDefaultFontName;
@ -5539,6 +5547,10 @@ begin
end;
end;
{$IFnDEF WithoutSynMultiCaret}
if ASynEdit is TIDESynEditor then
TIDESynEditor(ASynEdit).MultiCaret.EnableWithColumnSelection := MultiCaretOnColumnSelect;
{$ENDIF}
// Display options
ASynEdit.Gutter.Visible := fVisibleGutter;

View File

@ -200,7 +200,7 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
AnchorSideTop.Side = asrBottom
Left = 6
Height = 19
Top = 254
Top = 273
Width = 152
BorderSpacing.Left = 6
BorderSpacing.Top = 6
@ -214,7 +214,7 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
AnchorSideTop.Side = asrBottom
Left = 218
Height = 19
Top = 254
Top = 273
Width = 152
BorderSpacing.Top = 6
Caption = 'OverwriteBlockCheckBox'
@ -251,7 +251,6 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
Top = 0
Width = 434
Caption = 'UndoGroupDivider'
Autosize = True
Anchors = [akTop, akLeft, akRight]
Font.Style = [fsBold]
ParentFont = False
@ -267,7 +266,6 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
Top = 65
Width = 434
Caption = 'ScrollGroupDivider'
Autosize = True
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
Font.Style = [fsBold]
@ -284,7 +282,6 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
Top = 130
Width = 434
Caption = 'CaretGroupDivider'
Autosize = True
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
Font.Style = [fsBold]
@ -292,16 +289,15 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
end
object BlockGroupDivider: TDividerBevel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = ScrollPastEndLineCheckBox
AnchorSideTop.Control = MultiCaretOnColumnSelection
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 0
Height = 15
Top = 233
Top = 252
Width = 434
Caption = 'BlockGroupDivider'
Autosize = True
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
Font.Style = [fsBold]
@ -318,4 +314,16 @@ object EditorGeneralOptionsFrame: TEditorGeneralOptionsFrame
Caption = 'Scroll Hint'
TabOrder = 16
end
object MultiCaretOnColumnSelection: TCheckBox
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = ScrollPastEndLineCheckBox
AnchorSideTop.Side = asrBottom
Left = 6
Height = 19
Top = 227
Width = 183
BorderSpacing.Left = 6
Caption = 'MultiCaretOnColumnSelection'
TabOrder = 17
end
end

View File

@ -34,6 +34,7 @@ type
{ TEditorGeneralOptionsFrame }
TEditorGeneralOptionsFrame = class(TAbstractIDEOptionsEditor)
MultiCaretOnColumnSelection: TCheckBox;
CursorSkipsTabCheckBox: TCheckBox;
CaretGroupDivider: TDividerBevel;
BlockGroupDivider: TDividerBevel;
@ -138,6 +139,7 @@ begin
CursorSkipsTabCheckBox.Caption := dlgCursorSkipsTab;
HomeKeyJumpsToNearestStartCheckBox.Caption := dlgHomeKeyJumpsToNearestStart;
EndKeyJumpsToNearestStartCheckBox.Caption := dlgEndKeyJumpsToNearestStart;
MultiCaretOnColumnSelection.Caption := dlgMultiCaretOnColumnSelection;
// Block
BlockGroupDivider.Caption := dlgBlockGroupOptions;
@ -171,6 +173,7 @@ begin
CursorSkipsTabCheckBox.Checked := eoCaretSkipTab in SynEditOptions2;
HomeKeyJumpsToNearestStartCheckBox.Checked := eoEnhanceHomeKey in SynEditOptions;
EndKeyJumpsToNearestStartCheckBox.Checked := eoEnhanceEndKey in SynEditOptions2;
MultiCaretOnColumnSelection.Checked := MultiCaretOnColumnSelect;
// block
PersistentBlockCheckBox.Checked := eoPersistentBlock in SynEditOptions2;
@ -230,6 +233,7 @@ begin
UpdateOptionFromBool(CursorSkipsTabCheckBox.Checked, eoCaretSkipTab);
UpdateOptionFromBool(HomeKeyJumpsToNearestStartCheckBox.Checked, eoEnhanceHomeKey);
UpdateOptionFromBool(EndKeyJumpsToNearestStartCheckBox.Checked, eoEnhanceEndKey);
MultiCaretOnColumnSelect := MultiCaretOnColumnSelection.Checked;
// block
UpdateOptionFromBool(PersistentBlockCheckBox.Checked, eoPersistentBlock);

View File

@ -577,6 +577,7 @@ procedure TEditorMouseOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
ACombo.Items.Add(dlfMouseSimpleButtonContextMenu); // mbaContextMenu
ACombo.Items.Add(dlfMouseSimpleButtonContextMenuDbg); // mbaContextMenuDebug;
ACombo.Items.Add(dlfMouseSimpleButtonContextMenuTab); // mbaContextMenuTab;
ACombo.Items.Add(dlfMouseSimpleButtonMultiCaretToggle); // mbaMultiCaretToggle;
end;
procedure SetupWheelCombo(ACombo: TComboBox);

View File

@ -1604,6 +1604,7 @@ resourcestring
dlfMouseSimpleButtonContextMenu = 'Context Menu';
dlfMouseSimpleButtonContextMenuDbg = 'Context Menu (debug)';
dlfMouseSimpleButtonContextMenuTab = 'Context Menu (tab)';
dlfMouseSimpleButtonMultiCaretToggle = 'Toggle extra Caret';
dlfMouseSimpleWheelNothing = 'Nothing/Default';
dlfMouseSimpleWheelSrollDef = 'Scroll (System speed)';
@ -1687,6 +1688,7 @@ resourcestring
dlgCopyWordAtCursorOnCopyNone = 'Copy word on copy none';
dlgHomeKeyJumpsToNearestStart = 'Home key jumps to nearest start';
dlgEndKeyJumpsToNearestStart = 'End key jumps to nearest end';
dlgMultiCaretOnColumnSelection = 'Enable multi caret for column selection';
dlgColorLink = '(Edit Color)';
dlgKeyLink = '(Edit Key)';
dlgBracketHighlight = 'Bracket highlight';

View File

@ -48,6 +48,7 @@ type
MousePos: TPoint; var Handled: Boolean);
private
FKeyMap: TKeyCommandRelationList;
procedure AddMouseCmd(const S: string);
public
{ public declarations }
Procedure ResetInputs;
@ -80,10 +81,20 @@ end;
{ MouseaActionDialog }
procedure TMouseaActionDialog.FormCreate(Sender: TObject);
procedure TMouseaActionDialog.AddMouseCmd(const S: string);
var
i: Integer;
CName: String;
s2: String;
begin
if IdentToSynMouseCmd(S, i) then begin
s2 := MouseCommandName(i);
if s2 = '' then s2 := s;
ActionBox.Items.AddObject(s2, TObject(ptrint(i)));
end;
end;
procedure TMouseaActionDialog.FormCreate(Sender: TObject);
var
mb: TSynMouseButton;
cc: TSynMAClickCount;
begin
@ -109,11 +120,7 @@ begin
CapturePanel.ControlStyle := ControlStyle + [csTripleClicks, csQuadClicks];
CaretCheck.Caption := dlgMouseOptCaretMove;
ActionBox.Clear;
for i:= 0 to emcMax do begin
CName := MouseCommandName(i);
if CName <> '' then
ActionBox.Items.AddObject(CName, TObject(ptrint(i)));
end;
GetEditorMouseCommandValues(@AddMouseCmd);
ButtonBox.Clear;
for mb := low(TSynMouseButton) to high(TSynMouseButton) do
ButtonBox.Items.add(ButtonName[mb]);

View File

@ -56,7 +56,7 @@ uses
SynEditTextBuffer, SynEditFoldedView, SynTextDrawer, SynEditTextBase, LazSynEditText,
SynPluginTemplateEdit, SynPluginSyncroEdit, LazSynTextArea, SynEditHighlighter,
SynEditHighlighterFoldBase, SynHighlighterPas, SynEditMarkupHighAll, SynEditKeyCmds,
SynEditMarkupIfDef, SynEditMiscProcs, SynPluginMultiCaret,
SynEditMarkupIfDef, SynEditMiscProcs, SynPluginMultiCaret, SynEditPointClasses,
etSrcEditMarks, LazarusIDEStrConsts;
type
@ -1610,8 +1610,9 @@ begin
FUserWordsList := TFPList.Create;
FTemplateEdit:=TSynPluginTemplateEdit.Create(Self);
FSyncroEdit := TSynPluginSyncroEdit.Create(Self);
{$IFDEF WithSynMultiCaret}
{$IFnDEF WithoutSynMultiCaret}
FMultiCaret := TSynPluginMultiCaret.Create(Self);
FMultiCaret.MouseActions.Clear; // will be added to SynEdit
FMultiCaret.SetCaretTypeSize(ctVerticalLine, 2, 1024, -1, 0, [ccsRelativeHeight]);
FMultiCaret.SetCaretTypeSize(ctBlock, 1024, 1024, 0, 0, [ccsRelativeWidth, ccsRelativeHeight]);
FMultiCaret.Color := $606060;