SynEdit, IDE: added ecMoveSelection...up/down/right/left, ecDuplicateSelection

git-svn-id: trunk@62575 -
This commit is contained in:
martin 2020-01-21 19:27:09 +00:00
parent 8220e396b5
commit 39650cf381
6 changed files with 110 additions and 11 deletions

View File

@ -505,6 +505,7 @@ type
FInternalCaret: TSynEditCaret;
//FScreenCaret: TSynEditScreenCaret;
FInternalBlockSelection: TSynEditSelection;
FLastCaretXForMoveSelection: Integer;
FOnChangeUpdating: TChangeUpdatingEvent;
FMouseSelectionMode: TSynSelectionMode;
FMouseSelectionCmd: TSynEditorMouseCommand;
@ -6635,6 +6636,8 @@ begin
DebugLn(['[TCustomSynEdit.CommandProcessor] ',Command
,' AChar=',AChar,' Data=',DbgS(Data)]);
{$ENDIF}
if (Command <> ecMoveSelectUp) and (Command <> ecMoveSelectDown) then
FLastCaretXForMoveSelection := -1;
// first the program event handler gets a chance to process the command
InitialCmd := Command;
if not(hcfInit in ASkipHooks) then
@ -6699,7 +6702,7 @@ var
Len: Integer;
Temp: string;
Helper: string;
moveBkm: boolean;
moveBkm, CurBack: boolean;
WP: TPoint;
Caret: TPoint;
CaretNew: TPoint;
@ -6707,6 +6710,7 @@ var
LogCounter: integer;
LogCaretXY: TPoint;
CY: Integer;
CurSm: TSynSelectionMode;
begin
IncPaintLock;
@ -6721,6 +6725,8 @@ begin
FBlockSelection.ActiveSelectionMode := smColumn;
if Command in [ecSelCmdRangeStart..ecSelCmdRangeEnd] then
FBlockSelection.ActiveSelectionMode := FBlockSelection.SelectionMode;
if (Command <> ecMoveSelectUp) and (Command <> ecMoveSelectDown) then
FLastCaretXForMoveSelection := -1;
FBlockSelection.AutoExtend := Command in [ecSelectionStart..ecSelectionEnd];
FCaret.ChangeOnTouch;
@ -7222,6 +7228,59 @@ begin
FBlockSelection.DecPersistentLock;
InternalEndUndoBlock;
end;
ecMoveSelectUp,
ecMoveSelectDown,
ecMoveSelectLeft,
ecMoveSelectRight:
if (not ReadOnly) and SelAvail then begin
InternalBeginUndoBlock;
if FLastCaretXForMoveSelection < 0 then
FLastCaretXForMoveSelection := FBlockSelection.FirstLineBytePos.x;
CurSm := FBlockSelection.ActiveSelectionMode;
CurBack := FBlockSelection.IsBackwardSel;
Temp := FBlockSelection.SelText;
if CurSm = smColumn then
FCaret.IncForcePastEOL;
SetSelTextExternal('');
FCaret.LineBytePos := FBlockSelection.StartLineBytePos;
if (Command = ecMoveSelectUp) or (Command = ecMoveSelectDown) then
FCaret.KeepCaretXPos := FLastCaretXForMoveSelection;
case Command of
ecMoveSelectUp: MoveCaretVert(-1);
ecMoveSelectDown: MoveCaretVert(1);
ecMoveSelectLeft: FCaret.MoveHoriz(-1);
ecMoveSelectRight: FCaret.MoveHoriz(1);
end;
FBlockSelection.Clear;
FBlockSelection.SetSelTextPrimitive(CurSm, PChar(Temp), False, True);
if CurBack then begin
FBlockSelection.SortSelectionPoints(True);
FCaret.LineBytePos := FBlockSelection.EndLineBytePos;
end;
if (Command = ecMoveSelectUp) or (Command = ecMoveSelectDown) then
FCaret.KeepCaretXPos := FLastCaretXForMoveSelection;
if CurSm = smColumn then
FCaret.DecForcePastEOL;
InternalEndUndoBlock;
end;
ecDuplicateSelection:
if (not ReadOnly) and SelAvail then begin
InternalBeginUndoBlock;
FCaret.IncForcePastEOL;
CurSm := FBlockSelection.ActiveSelectionMode;
CurBack := FBlockSelection.IsBackwardSel;
Temp := FBlockSelection.SelText;
FCaret.LineBytePos := FBlockSelection.FirstLineBytePos;
FBlockSelection.Clear;
FBlockSelection.SetSelTextPrimitive(CurSm, PChar(Temp), False, True);
if CurBack then
FBlockSelection.SortSelectionPoints(True);
FCaret.DecForcePastEOL;
InternalEndUndoBlock;
end;
ecScrollUp:
begin
TopView := TopView - 1;

View File

@ -282,6 +282,13 @@ const
ecMoveLineDown = 631; // Moves current line (or selection) one line down
ecDuplicateLine = 632; // Line or selection (full lines)
ecMoveSelectUp = 633; // Moves selection one line up
ecMoveSelectDown = 634; // Moves selection one line down
ecMoveSelectLeft = 635; // Moves selection one line up
ecMoveSelectRight = 636; // Moves selection one line down
ecDuplicateSelection= 637;
ecString = 640; //Insert a whole string
ecAutoCompletion = 650;
@ -506,7 +513,7 @@ end;
{ Command mapping routines }
const
EditorCommandStrs: array[0..166] of TIdentMapEntry = (
EditorCommandStrs: array[0..171] of TIdentMapEntry = (
(Value: ecNone; Name: 'ecNone'),
(Value: ecLeft; Name: 'ecLeft'),
(Value: ecRight; Name: 'ecRight'),
@ -603,7 +610,12 @@ const
(Value: ecCutAddCurrentLine; Name: 'ecCutAddCurrentLine'),
(Value: ecMoveLineUp; Name: 'ecMoveLineUp'),
(Value: ecMoveLineDown; Name: 'ecMoveLineDown'),
(Value: ecMoveSelectUp; Name: 'ecMoveSelectUp'),
(Value: ecMoveSelectDown; Name: 'ecMoveSelectDown'),
(Value: ecMoveSelectLeft; Name: 'ecMoveSelectLeft'),
(Value: ecMoveSelectRight; Name: 'ecMoveSelectRight'),
(Value: ecDuplicateLine; Name: 'ecDuplicateLine'),
(Value: ecDuplicateSelection; Name: 'ecDuplicateSelection'),
(Value: ecScrollUp; Name: 'ecScrollUp'),
(Value: ecScrollDown; Name: 'ecScrollDown'),
(Value: ecScrollLeft; Name: 'ecScrollLeft'),

View File

@ -162,12 +162,12 @@ type
constructor Create(ALines: TSynEditStrings; aActOnLineChanges: Boolean);
destructor Destroy; override;
procedure AssignFrom(Src: TSynEditSelection);
procedure SetSelTextPrimitive(PasteMode: TSynSelectionMode; Value: PChar; AReplace: Boolean = False);
procedure SetSelTextPrimitive(PasteMode: TSynSelectionMode; Value: PChar; AReplace: Boolean = False; ASetTextSelected: Boolean = False);
function SelAvail: Boolean;
function SelCanContinue(ACaret: TSynEditCaret): Boolean;
function IsBackwardSel: Boolean; // SelStart < SelEnd ?
procedure BeginMinimumSelection; // current selection will be minimum while follow caret (autoExtend) // until next setSelStart or end of follow
procedure SortSelectionPoints;
procedure SortSelectionPoints(AReverse: Boolean = False);
procedure IgnoreNextCaretMove;
// Mode can NOT be changed in nested calls
procedure IncPersistentLock(AMode: TSynBlockPersistMode = sbpDefault); // Weak: Do not extend (but rather move) block, if at start/end
@ -1881,8 +1881,8 @@ begin
end;
end;
procedure TSynEditSelection.SetSelTextPrimitive(PasteMode : TSynSelectionMode;
Value : PChar; AReplace: Boolean = False);
procedure TSynEditSelection.SetSelTextPrimitive(PasteMode: TSynSelectionMode;
Value: PChar; AReplace: Boolean; ASetTextSelected: Boolean);
var
BB, BE: TPoint;
@ -2178,7 +2178,12 @@ begin
FInternalCaret.LineBytePos := StartLineBytePos;
if (Value <> nil) and (Value[0] <> #0) then begin
InsertText;
StartLineBytePos := FInternalCaret.LineBytePos; // reset selection
if ASetTextSelected then begin
EndLineBytePos := FInternalCaret.LineBytePos;
FActiveSelectionMode := PasteMode;
end
else
StartLineBytePos := FInternalCaret.LineBytePos; // reset selection
end;
if FCaret <> nil then
FCaret.LineCharPos := FInternalCaret.LineCharPos;
@ -2205,7 +2210,7 @@ procedure TSynEditSelection.ConstrainStartLineBytePos(var Value: TPoint);
begin
Value.y := MinMax(Value.y, 1, Max(fLines.Count, 1));
if (FCaret = nil) or FCaret.AllowPastEOL then
if (FCaret = nil) or FCaret.AllowPastEOL or (FCaret.FForcePastEOL > 0) then
Value.x := Max(Value.x, 1)
else
Value.x := MinMax(Value.x, 1, length(Lines[Value.y - 1])+1);
@ -2498,9 +2503,9 @@ begin
end;
end;
procedure TSynEditSelection.SortSelectionPoints;
procedure TSynEditSelection.SortSelectionPoints(AReverse: Boolean);
begin
if IsBackwardSel then begin
if IsBackwardSel xor AReverse then begin
SwapInt(FStartLinePos, FEndLinePos);
SwapInt(FStartBytePos, FEndBytePos);
end;

View File

@ -2630,7 +2630,10 @@ begin
Action := ccaDefaultAction;
case Command of
ecCopy, ecCut,
ecCopyCurrentLine, ecCutCurrentLine: Action := ccaNoneRepeatCommand;
ecCopyCurrentLine, ecCutCurrentLine, ecDuplicateSelection:
Action := ccaNoneRepeatCommand;
ecMoveSelectUp, ecMoveSelectDown, ecMoveSelectLeft, ecMoveSelectRight:
Action := ccaClearCarets;
ecGotoMarker0..ecGotoMarker9: Action := ccaClearCarets;
ecSelectAll: Action := ccaClearCarets;
ecDeleteChar: if smcoDeleteSkipLineBreak in Options then

View File

@ -423,6 +423,11 @@ begin
ecMoveLineUp : Result:= srkmecMoveLineUp;
ecMoveLineDown : Result:= srkmecMoveLineDown;
ecDuplicateLine : Result:= srkmecDuplicateLine;
ecMoveSelectUp : Result:= srkmecMoveSelectUp;
ecMoveSelectDown : Result:= srkmecMoveSelectDown;
ecMoveSelectLeft : Result:= srkmecMoveSelectLeft;
ecMoveSelectRight : Result:= srkmecMoveSelectRight;
ecDuplicateSelection : Result:= srkmecDuplicateSelection;
ecMultiPaste : Result:= srkmecMultiPaste;
ecScrollUp : Result:= srkmecScrollUp;
ecScrollDown : Result:= srkmecScrollDown;
@ -1028,6 +1033,11 @@ begin
ecMoveLineUp: SetSingle(VK_UP,[XCtrl, ssShift, ssAlt]);
ecMoveLineDown: SetSingle(VK_DOWN,[XCtrl, ssShift, ssAlt]);
ecDuplicateLine: SetSingle(VK_INSERT,[XCtrl, ssShift, ssAlt]);
ecMoveSelectUp: SetSingle(VK_NUMPAD8,[XCtrl, ssAlt]);
ecMoveSelectDown: SetSingle(VK_NUMPAD2,[XCtrl, ssAlt]);
ecMoveSelectLeft: SetSingle(VK_NUMPAD4,[XCtrl, ssAlt]);
ecMoveSelectRight: SetSingle(VK_NUMPAD6,[XCtrl, ssAlt]);
ecDuplicateSelection: SetSingle(VK_NUMPAD0,[XCtrl, ssAlt]);
ecMultiPaste: SetSingle(VK_UNKNOWN,[]);
ecNormalSelect: SetSingle(VK_UNKNOWN,[]);
@ -2795,7 +2805,12 @@ begin
AddDefault(C, 'Break line, leave cursor', srkmecInsertLine, ecInsertLine);
AddDefault(C, 'Move one line up', srkmecMoveLineUp, ecMoveLineUp);
AddDefault(C, 'Move one line down', srkmecMoveLineDown, ecMoveLineDown);
AddDefault(C, 'Move selection up', srkmecMoveSelectUp, ecMoveSelectUp);
AddDefault(C, 'Move selection down', srkmecMoveSelectDown, ecMoveSelectDown);
AddDefault(C, 'Move selection left', srkmecMoveSelectLeft, ecMoveSelectLeft);
AddDefault(C, 'Move selection right', srkmecMoveSelectRight, ecMoveSelectRight);
AddDefault(C, 'Duplicate line or lines in selection', srkmecDuplicateLine, ecDuplicateLine);
AddDefault(C, 'Duplicate selection', srkmecDuplicateSelection, ecDuplicateSelection);
AddDefault(C, 'Enclose in $IFDEF', lisEncloseInIFDEF, ecSelectionEncloseIFDEF);
AddDefault(C, 'Insert from Character Map', lisMenuInsertCharacter, ecInsertCharacter);
AddDefault(C, 'Insert GPL notice', srkmecInsertGPLNotice, ecInsertGPLNotice);

View File

@ -3130,6 +3130,11 @@ resourcestring
srkmecMoveLineUp = 'Move line up';
srkmecMoveLineDown = 'Move line down';
srkmecDuplicateLine = 'Duplicate line (or lines in selection)';
srkmecDuplicateSelection = 'Duplicate selection';
srkmecMoveSelectUp = 'Move selection up';
srkmecMoveSelectDown = 'Move selection down';
srkmecMoveSelectLeft = 'Move selection left';
srkmecMoveSelectRight = 'Move selection right';
srkmecMultiPaste = 'MultiPaste';
srkmecScrollUp = 'Scroll up one line';