mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 16:19:13 +02:00
IDE, SynEdit: Add indent for column mode selection
This commit is contained in:
parent
3c2da22f52
commit
c07ae4c10e
@ -645,8 +645,10 @@ type
|
|||||||
procedure SetVisibleSpecialChars(AValue: TSynVisibleSpecialChars);
|
procedure SetVisibleSpecialChars(AValue: TSynVisibleSpecialChars);
|
||||||
procedure SurrenderPrimarySelection;
|
procedure SurrenderPrimarySelection;
|
||||||
procedure ComputeCaret(X, Y: Integer);
|
procedure ComputeCaret(X, Y: Integer);
|
||||||
procedure DoBlockIndent;
|
procedure DoBlockIndent(AColumnIndentOutside: Boolean = False);
|
||||||
procedure DoBlockUnindent;
|
procedure DoBlockIndentColSel(AnIndentOutside: Boolean = False);
|
||||||
|
procedure DoBlockUnindent(AColumnIndentOutside: Boolean = False);
|
||||||
|
procedure DoBlockUnindentColSel(AnIndentOutside: Boolean = False);
|
||||||
procedure DoHomeKey(aMode: TSynHomeMode = synhmDefault);
|
procedure DoHomeKey(aMode: TSynHomeMode = synhmDefault);
|
||||||
procedure DoEndKey;
|
procedure DoEndKey;
|
||||||
procedure DoTabKey;
|
procedure DoTabKey;
|
||||||
@ -7718,10 +7720,10 @@ begin
|
|||||||
FCaret.LineBytePos := FBlockSelection.LastLineBytePos;
|
FCaret.LineBytePos := FBlockSelection.LastLineBytePos;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ecBlockIndent:
|
ecBlockIndent, ecBlockIndentMove:
|
||||||
if not ReadOnly then DoBlockIndent;
|
if not ReadOnly then DoBlockIndent(Command = ecBlockIndentMove);
|
||||||
ecBlockUnindent:
|
ecBlockUnindent, ecBlockUnindentMove:
|
||||||
if not ReadOnly then DoBlockUnindent;
|
if not ReadOnly then DoBlockUnindent(Command = ecBlockUnindentMove);
|
||||||
ecNormalSelect,
|
ecNormalSelect,
|
||||||
ecColumnSelect,
|
ecColumnSelect,
|
||||||
ecLineSelect:
|
ecLineSelect:
|
||||||
@ -9086,13 +9088,18 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSynEdit.DoBlockIndent;
|
procedure TCustomSynEdit.DoBlockIndent(AColumnIndentOutside: Boolean);
|
||||||
var
|
var
|
||||||
BB,BE : TPoint;
|
BB,BE : TPoint;
|
||||||
Line : PChar;
|
Line : PChar;
|
||||||
Len, e, y: integer;
|
Len, e, y: integer;
|
||||||
Spaces, Tabs: String;
|
Spaces, Tabs: String;
|
||||||
begin
|
begin
|
||||||
|
if SelAvail and (SelectionMode = smColumn) then begin
|
||||||
|
DoBlockIndentColSel(AColumnIndentOutside);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
IncPaintLock;
|
IncPaintLock;
|
||||||
FBlockSelection.IncPersistentLock;
|
FBlockSelection.IncPersistentLock;
|
||||||
try
|
try
|
||||||
@ -9135,7 +9142,88 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSynEdit.DoBlockUnindent;
|
procedure TCustomSynEdit.DoBlockIndentColSel(AnIndentOutside: Boolean);
|
||||||
|
var
|
||||||
|
BB,BE, BB2, BE2: TPoint;
|
||||||
|
Len, y, LeftBytePos, RightBytePos: integer;
|
||||||
|
LineStr, TabStr, SpaceStr: String;
|
||||||
|
Bounds: array of record
|
||||||
|
LeftByte, RightByte: integer;
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
if not (SelAvail and (SelectionMode = smColumn)) then
|
||||||
|
exit;
|
||||||
|
if (FBlockIndent <= 0) and (FBlockTabIndent <= 0) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
IncPaintLock;
|
||||||
|
try
|
||||||
|
// build text to insert
|
||||||
|
BB := BlockBegin;
|
||||||
|
BE := BlockEnd;
|
||||||
|
BB2 := FBlockSelection.StartLineBytePos;
|
||||||
|
BE2 := FBlockSelection.EndLineBytePos;
|
||||||
|
|
||||||
|
SetLength(Bounds, BE.Y - BB.Y + 1);
|
||||||
|
for y := BB.Y to BE.y do begin
|
||||||
|
Bounds[y-BB.y].LeftByte := FBlockSelection.ColumnStartBytePos[y];
|
||||||
|
Bounds[y-BB.y].RightByte := FBlockSelection.ColumnEndBytePos[y];
|
||||||
|
end;
|
||||||
|
FBlockSelection.Clear;
|
||||||
|
|
||||||
|
SpaceStr := StringOfChar(#32, FBlockIndent);
|
||||||
|
TabStr := StringOfChar( #9, FBlockTabIndent);
|
||||||
|
for y := BB.Y to BE.y do begin
|
||||||
|
LineStr := FTheLinesView[y - 1];
|
||||||
|
LeftBytePos := Bounds[y-BB.y].LeftByte;
|
||||||
|
if AnIndentOutside then begin
|
||||||
|
Len := CountBackwardWhiteSpace(PChar(LineStr), LeftBytePos-1);
|
||||||
|
RightBytePos := LeftBytePos;
|
||||||
|
LeftBytePos := LeftBytePos - Len;
|
||||||
|
if FBlockIndent = 0 then
|
||||||
|
Len := 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if FBlockIndent > 0
|
||||||
|
then Len := CountLeadWhiteSpace(PChar(LineStr)+LeftBytePos-1)
|
||||||
|
else Len := 0;
|
||||||
|
if (Len > 0) then
|
||||||
|
RightBytePos := Bounds[y-BB.y].RightByte;
|
||||||
|
if (Len > 0) and (LeftBytePos + Len > RightBytePos) then
|
||||||
|
Len := Max(0, RightBytePos - LeftBytePos);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Len = 0 then begin
|
||||||
|
FTheLinesView.EditInsert(LeftBytePos, y, TabStr+SpaceStr);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
FTheLinesView.EditInsert(LeftBytePos + Len, y, SpaceStr);
|
||||||
|
if TabStr <> '' then
|
||||||
|
FTheLinesView.EditInsert(LeftBytePos, y, TabStr);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FTrimmedLinesView.ForceTrim; // Otherwise it may reset the block
|
||||||
|
|
||||||
|
if AnIndentOutside then begin
|
||||||
|
BB2.X := BB2.X + Length(TabStr) + Length(SpaceStr);
|
||||||
|
BE2.X := BE2.X + Length(TabStr) + Length(SpaceStr);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if BB2.X > BE2.X then
|
||||||
|
BB2.X := BB2.X + Length(TabStr) + Length(SpaceStr)
|
||||||
|
else
|
||||||
|
BE2.X := BE2.X + Length(TabStr) + Length(SpaceStr);
|
||||||
|
end;
|
||||||
|
FBlockSelection.StartLineBytePos := BB2;
|
||||||
|
FBlockSelection.EndLineBytePos := BE2;
|
||||||
|
FBlockSelection.ActiveSelectionMode := smColumn;
|
||||||
|
FCaret.LineBytePos := BE2;
|
||||||
|
DecPaintLock;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCustomSynEdit.DoBlockUnindent(AColumnIndentOutside: Boolean);
|
||||||
const
|
const
|
||||||
LineEnd = #10;
|
LineEnd = #10;
|
||||||
var
|
var
|
||||||
@ -9147,6 +9235,11 @@ var
|
|||||||
SomethingDeleted : Boolean;
|
SomethingDeleted : Boolean;
|
||||||
HasTab: Boolean;
|
HasTab: Boolean;
|
||||||
begin
|
begin
|
||||||
|
if SelAvail and (SelectionMode = smColumn) then begin
|
||||||
|
DoBlockUnindentColSel(AColumnIndentOutside);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
if not SelAvail then begin
|
if not SelAvail then begin
|
||||||
BB := CaretXY;
|
BB := CaretXY;
|
||||||
BE := CaretXY;
|
BE := CaretXY;
|
||||||
@ -9257,6 +9350,165 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomSynEdit.DoBlockUnindentColSel(AnIndentOutside: Boolean);
|
||||||
|
var
|
||||||
|
BB,BE, BB2, BE2: TPoint;
|
||||||
|
Len, y, LeftBytePos, TabW, TabDel, CurTabDel, CurTabSpaceAdd,
|
||||||
|
SpaceStartCharPos, CurSpaceSpaceAdd, CurSpaceDel, CurSpaceDelPos: integer;
|
||||||
|
LineStr: String;
|
||||||
|
LeftCharPos, RightBytePos, TabEndBytePos: LongInt;
|
||||||
|
Bounds: array of record
|
||||||
|
LeftByte, RightByte: integer;
|
||||||
|
// LeftChar, RightchByte: integer;
|
||||||
|
end;
|
||||||
|
LPC: TSynLogicalPhysicalConvertor;
|
||||||
|
BbIsRight: Boolean;
|
||||||
|
|
||||||
|
function LogToPhys(X: Integer): integer; inline;
|
||||||
|
begin
|
||||||
|
Result := LPC.LogicalToPhysical(ToIdx(y), X);
|
||||||
|
end;
|
||||||
|
function PhysToLog(X: Integer): integer; inline;
|
||||||
|
begin
|
||||||
|
Result := LPC.PhysicalToLogical(ToIdx(y), X);
|
||||||
|
end;
|
||||||
|
function PhysToLog(X: Integer; out Offs: integer): integer; inline;
|
||||||
|
begin
|
||||||
|
Result := LPC.PhysicalToLogical(ToIdx(y), X, Offs, cspDefault, []);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if not (SelAvail and (SelectionMode = smColumn)) then
|
||||||
|
exit;
|
||||||
|
if (FBlockIndent <= 0) and (FBlockTabIndent <= 0) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
IncPaintLock;
|
||||||
|
try
|
||||||
|
TabW := TabWidth;
|
||||||
|
TabDel := TabW * FBlockTabIndent;
|
||||||
|
BB := BlockBegin;
|
||||||
|
BE := BlockEnd;
|
||||||
|
BB2 := FBlockSelection.StartLineBytePos;
|
||||||
|
BE2 := FBlockSelection.EndLineBytePos;
|
||||||
|
BbIsRight := BB2.X > BE2.X;
|
||||||
|
|
||||||
|
SetLength(Bounds, BE.Y - BB.Y + 1);
|
||||||
|
for y := BB.Y to BE.y do begin
|
||||||
|
Bounds[y-BB.y].LeftByte := FBlockSelection.ColumnStartBytePos[y];
|
||||||
|
Bounds[y-BB.y].RightByte := FBlockSelection.ColumnEndBytePos[y];
|
||||||
|
end;
|
||||||
|
FBlockSelection.Clear;
|
||||||
|
|
||||||
|
|
||||||
|
LPC := FTheLinesView.LogPhysConvertor;
|
||||||
|
for y := BB.Y to BE.y do begin
|
||||||
|
LineStr := FTheLinesView[y - 1];
|
||||||
|
LeftBytePos := Bounds[y-BB.y].LeftByte;
|
||||||
|
RightBytePos := Bounds[y-BB.y].RightByte;
|
||||||
|
|
||||||
|
if AnIndentOutside then begin
|
||||||
|
Len := CountBackwardWhiteSpace(PChar(LineStr), LeftBytePos-1);
|
||||||
|
RightBytePos := LeftBytePos;
|
||||||
|
LeftBytePos := LeftBytePos - Len;
|
||||||
|
//if FBlockIndent = 0 then
|
||||||
|
// Len := 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
Len := Min(CountLeadWhiteSpace(PChar(LineStr)+LeftBytePos-1), RightBytePos - LeftBytePos);
|
||||||
|
if Len > Length(LineStr) - LeftBytePos then
|
||||||
|
Len := Length(LineStr) - LeftBytePos;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Len = 0 then
|
||||||
|
Continue;
|
||||||
|
|
||||||
|
CurSpaceDel := 0;
|
||||||
|
CurSpaceDelPos := LeftBytePos + Len; // used as end for tab // pretend zero spaces
|
||||||
|
CurSpaceSpaceAdd := 0;
|
||||||
|
CurTabDel := 0;
|
||||||
|
CurTabSpaceAdd := 0;
|
||||||
|
|
||||||
|
if FBlockIndent > 0 then begin
|
||||||
|
//SpaceStartCharPos := LogToPhys(Max(LeftBytePos, CurSpaceDelPos - FBlockIndent));
|
||||||
|
SpaceStartCharPos := Max( LogToPhys(CurSpaceDelPos) - FBlockIndent,
|
||||||
|
LogToPhys(LeftBytePos)
|
||||||
|
);
|
||||||
|
CurSpaceDelPos := PhysToLog(SpaceStartCharPos, CurSpaceSpaceAdd);
|
||||||
|
CurSpaceDel := LeftBytePos + Len - CurSpaceDelPos;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (CurSpaceDel > Len) or
|
||||||
|
( (CurSpaceDel = Len) and (CurSpaceSpaceAdd = 0) )
|
||||||
|
then begin
|
||||||
|
CurSpaceDelPos := LeftBytePos;
|
||||||
|
CurSpaceDel := Len;
|
||||||
|
CurSpaceSpaceAdd := 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Len := CurSpaceDelPos - LeftBytePos;
|
||||||
|
if TabDel > 0 then begin
|
||||||
|
LeftCharPos := LogToPhys(LeftBytePos);
|
||||||
|
CurTabDel := TabDel - (LeftCharPos-1) mod TabW;
|
||||||
|
if CurTabDel > 0 then begin
|
||||||
|
TabEndBytePos := PhysToLog(LeftCharPos+CurTabDel, CurTabSpaceAdd);
|
||||||
|
CurTabDel := TabEndBytePos - LeftBytePos;
|
||||||
|
if CurTabSpaceAdd > 0 then
|
||||||
|
inc(CurTabDel);
|
||||||
|
|
||||||
|
if (CurTabDel > Len) or
|
||||||
|
( (CurTabDel=Len) and (CurTabSpaceAdd >= CurSpaceSpaceAdd) )
|
||||||
|
then begin
|
||||||
|
CurTabDel := 0;
|
||||||
|
CurTabSpaceAdd := 0;
|
||||||
|
CurSpaceDelPos := LeftBytePos;
|
||||||
|
CurSpaceDel := Len;
|
||||||
|
CurSpaceSpaceAdd := 0;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
CurTabDel := 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if CurSpaceDel > 0 then begin
|
||||||
|
FTheLinesView.EditDelete(CurSpaceDelPos, y, CurSpaceDel);
|
||||||
|
if CurSpaceSpaceAdd > 0 then
|
||||||
|
FTheLinesView.EditInsert(CurSpaceDelPos, y, StringOfChar(' ', CurSpaceSpaceAdd));
|
||||||
|
end;
|
||||||
|
if CurTabDel > 0 then begin
|
||||||
|
FTheLinesView.EditDelete(LeftBytePos, y, CurTabDel);
|
||||||
|
if CurTabSpaceAdd > 0 then
|
||||||
|
FTheLinesView.EditInsert(LeftBytePos, y, StringOfChar(' ', CurTabSpaceAdd));
|
||||||
|
end;
|
||||||
|
|
||||||
|
if AnIndentOutside then begin
|
||||||
|
if (y = BB2.y) then
|
||||||
|
BB2.X := BB2.X + CurSpaceSpaceAdd + CurTabSpaceAdd - CurSpaceDel - CurTabDel;
|
||||||
|
if (y = BE2.y) then
|
||||||
|
BE2.X := BE2.X + CurSpaceSpaceAdd + CurTabSpaceAdd - CurSpaceDel - CurTabDel;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (y = BB2.y) and (BbIsRight) then
|
||||||
|
BB2.X := BB2.X + CurSpaceSpaceAdd + CurTabSpaceAdd - CurSpaceDel - CurTabDel;
|
||||||
|
if (y = BE2.y) and (not BbIsRight) then
|
||||||
|
BE2.X := BE2.X + CurSpaceSpaceAdd + CurTabSpaceAdd - CurSpaceDel - CurTabDel;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FTrimmedLinesView.ForceTrim; // Otherwise it may reset the block
|
||||||
|
|
||||||
|
FBlockSelection.StartLineBytePos := BB2;
|
||||||
|
FBlockSelection.EndLineBytePos := BE2;
|
||||||
|
FBlockSelection.ActiveSelectionMode := smColumn;
|
||||||
|
FCaret.LineBytePos := BE2;
|
||||||
|
DecPaintLock;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomSynEdit.DoHomeKey(aMode: TSynHomeMode = synhmDefault);
|
procedure TCustomSynEdit.DoHomeKey(aMode: TSynHomeMode = synhmDefault);
|
||||||
// jump to start of line (x=1),
|
// jump to start of line (x=1),
|
||||||
// or if already there, jump to first non blank char
|
// or if already there, jump to first non blank char
|
||||||
|
@ -294,6 +294,8 @@ const
|
|||||||
ecString = 640; //Insert a whole string
|
ecString = 640; //Insert a whole string
|
||||||
|
|
||||||
ecAutoCompletion = 650;
|
ecAutoCompletion = 650;
|
||||||
|
ecBlockIndentMove = 651; // Indent selection (indent before column-sel, therefore moving the column-sel)
|
||||||
|
ecBlockUnindentMove = 652; // Unindent selection (indent before column-sel, therefore moving the column-sel)
|
||||||
|
|
||||||
ecGotFocus = 700;
|
ecGotFocus = 700;
|
||||||
ecLostFocus = 701;
|
ecLostFocus = 701;
|
||||||
@ -514,7 +516,7 @@ end;
|
|||||||
{ Command mapping routines }
|
{ Command mapping routines }
|
||||||
|
|
||||||
const
|
const
|
||||||
EditorCommandStrs: array[0..172] of TIdentMapEntry = (
|
EditorCommandStrs: array[0..174] of TIdentMapEntry = (
|
||||||
(Value: ecNone; Name: 'ecNone'),
|
(Value: ecNone; Name: 'ecNone'),
|
||||||
(Value: ecLeft; Name: 'ecLeft'),
|
(Value: ecLeft; Name: 'ecLeft'),
|
||||||
(Value: ecRight; Name: 'ecRight'),
|
(Value: ecRight; Name: 'ecRight'),
|
||||||
@ -627,6 +629,8 @@ const
|
|||||||
(Value: ecToggleMode; Name: 'ecToggleMode'),
|
(Value: ecToggleMode; Name: 'ecToggleMode'),
|
||||||
(Value: ecBlockIndent; Name: 'ecBlockIndent'),
|
(Value: ecBlockIndent; Name: 'ecBlockIndent'),
|
||||||
(Value: ecBlockUnindent; Name: 'ecBlockUnindent'),
|
(Value: ecBlockUnindent; Name: 'ecBlockUnindent'),
|
||||||
|
(Value: ecBlockIndentMove; Name: 'ecBlockIndentMove'),
|
||||||
|
(Value: ecBlockUnindentMove; Name: 'ecBlockUnindentMove'),
|
||||||
(Value: ecTab; Name: 'ecTab'),
|
(Value: ecTab; Name: 'ecTab'),
|
||||||
(Value: ecShiftTab; Name: 'ecShiftTab'),
|
(Value: ecShiftTab; Name: 'ecShiftTab'),
|
||||||
(Value: ecMatchBracket; Name: 'ecMatchBracket'),
|
(Value: ecMatchBracket; Name: 'ecMatchBracket'),
|
||||||
|
@ -83,6 +83,7 @@ function YToIdx(APointWithYPos: TPoint): TPoint; inline;
|
|||||||
function YToPos(APointWithYIdx: TPoint): TPoint; inline;
|
function YToPos(APointWithYIdx: TPoint): TPoint; inline;
|
||||||
|
|
||||||
function CountLeadWhiteSpace(AText: PChar): integer; inline;
|
function CountLeadWhiteSpace(AText: PChar): integer; inline;
|
||||||
|
function CountBackwardWhiteSpace(AText: PChar; AStart: Integer): integer; inline;
|
||||||
function CountLeadWhiteSpace(AText: PChar; out AnHasTab: boolean): integer; inline;
|
function CountLeadWhiteSpace(AText: PChar; out AnHasTab: boolean): integer; inline;
|
||||||
|
|
||||||
|
|
||||||
@ -120,6 +121,16 @@ begin
|
|||||||
Result := Run - AText;
|
Result := Run - AText;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CountBackwardWhiteSpace(AText: PChar; AStart: Integer): integer;
|
||||||
|
var
|
||||||
|
Run : PChar;
|
||||||
|
begin
|
||||||
|
Run := AText+AStart-1;
|
||||||
|
while (Run >=AText) and (Run^ in [' ', #9]) do
|
||||||
|
Dec(Run);
|
||||||
|
Result := AText + AStart - 1 - Run;
|
||||||
|
end;
|
||||||
|
|
||||||
function CountLeadWhiteSpace(AText: PChar; out AnHasTab: boolean): integer;
|
function CountLeadWhiteSpace(AText: PChar; out AnHasTab: boolean): integer;
|
||||||
var
|
var
|
||||||
Run : PChar;
|
Run : PChar;
|
||||||
|
@ -165,6 +165,7 @@ type
|
|||||||
property MainCaretIndex: Integer read GetMainCaretIndex;
|
property MainCaretIndex: Integer read GetMainCaretIndex;
|
||||||
|
|
||||||
private
|
private
|
||||||
|
FAdjustOnlyAfterInsertColumn: Boolean;
|
||||||
FCurrenCaret, FBeforeNextCaret: PCaretData;
|
FCurrenCaret, FBeforeNextCaret: PCaretData;
|
||||||
FIterationDoneCount: Integer;
|
FIterationDoneCount: Integer;
|
||||||
FLowCaret, FHighCaret: PCaretData; // used in AdjustAfterChange
|
FLowCaret, FHighCaret: PCaretData; // used in AdjustAfterChange
|
||||||
@ -186,6 +187,7 @@ type
|
|||||||
function PeekCaretY(AIndexOffset: Integer): Integer; inline;
|
function PeekCaretY(AIndexOffset: Integer): Integer; inline;
|
||||||
function PeekCaretFull(AIndexOffset: Integer): TLogCaretPoint; inline;
|
function PeekCaretFull(AIndexOffset: Integer): TLogCaretPoint; inline;
|
||||||
//procedure AbortIterator;
|
//procedure AbortIterator;
|
||||||
|
property AdjustOnlyAfterInsertColumn: Boolean read FAdjustOnlyAfterInsertColumn write FAdjustOnlyAfterInsertColumn;
|
||||||
|
|
||||||
property CurrentCaretFull: TLogCaretPoint read GetCurrentCaretFull write SetCurrentCaretFull;
|
property CurrentCaretFull: TLogCaretPoint read GetCurrentCaretFull write SetCurrentCaretFull;
|
||||||
property CurrentCaretKeepX: Integer read GetCurrentCaretKeepX write SetCurrentCaretKeepX;
|
property CurrentCaretKeepX: Integer read GetCurrentCaretKeepX write SetCurrentCaretKeepX;
|
||||||
@ -1028,7 +1030,9 @@ begin
|
|||||||
end
|
end
|
||||||
else begin // aCount >= 0
|
else begin // aCount >= 0
|
||||||
for i := lowest to FHighIndex do begin
|
for i := lowest to FHighIndex do begin
|
||||||
if (FCarets[i].y = aLinePos) and (FCarets[i].x >= aBytePos) then
|
if (FCarets[i].y = aLinePos) and (FCarets[i].x >= aBytePos) and
|
||||||
|
((not FAdjustOnlyAfterInsertColumn) or (FCarets[i].x > aBytePos))
|
||||||
|
then
|
||||||
FCarets[i].x := FCarets[i].x + aCount
|
FCarets[i].x := FCarets[i].x + aCount
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -2572,6 +2576,18 @@ var
|
|||||||
begin
|
begin
|
||||||
// hcfFinish
|
// hcfFinish
|
||||||
if AfterProcessing then begin
|
if AfterProcessing then begin
|
||||||
|
case Command of
|
||||||
|
ecTab..ecShiftTab:
|
||||||
|
if (not Editor.ReadOnly) and Editor.SelAvail and (eoTabIndent in Editor.Options) and
|
||||||
|
(SelectionObj.ActiveSelectionMode = smColumn)
|
||||||
|
then
|
||||||
|
ClearCarets;
|
||||||
|
ecBlockIndent, ecBlockUnindent, ecBlockIndentMove, ecBlockUnindentMove:
|
||||||
|
if (not Editor.ReadOnly) and Editor.SelAvail and (SelectionObj.ActiveSelectionMode = smColumn)
|
||||||
|
then
|
||||||
|
ClearCarets;
|
||||||
|
end;
|
||||||
|
|
||||||
if (FNestedCommandProcessor > 0) then begin
|
if (FNestedCommandProcessor > 0) then begin
|
||||||
dec(FNestedCommandProcessor);
|
dec(FNestedCommandProcessor);
|
||||||
exit;
|
exit;
|
||||||
@ -2682,25 +2698,21 @@ begin
|
|||||||
StartEditing;
|
StartEditing;
|
||||||
if Editor.ReadOnly then exit;
|
if Editor.ReadOnly then exit;
|
||||||
if (eoTabIndent in Editor.Options) and Editor.SelAvail then begin
|
if (eoTabIndent in Editor.Options) and Editor.SelAvail then begin
|
||||||
if (SelectionObj.ActiveSelectionMode = smColumn) then begin
|
if (SelectionObj.ActiveSelectionMode = smColumn) then
|
||||||
// no indent for column mode, when multicaret
|
ClearCarets;
|
||||||
Editor.BeginUpdate(True);
|
exit;
|
||||||
try
|
end
|
||||||
AddCaret(Editor.LogicalCaretXY.x, Editor.CaretY, CaretObj.BytePosOffset, [cfMainCaret, cfNoneVisual, cfAddDuplicate]);
|
else
|
||||||
Editor.SelText := '';
|
ExecCommandRepeated;
|
||||||
if Carets.MainCaretIndex >= 0 then begin
|
end;
|
||||||
Editor.LogicalCaretXY := Carets.Caret[Carets.MainCaretIndex];
|
ecBlockIndent, ecBlockUnindent, ecBlockIndentMove, ecBlockUnindentMove:
|
||||||
RemoveCaret(Carets.MainCaretIndex);
|
begin
|
||||||
end
|
StartEditing;
|
||||||
else
|
if Editor.ReadOnly then exit;
|
||||||
assert(False, 'TSynCustomPluginMultiCaret.ProcessAllSynCommand: Maincaret index not found');
|
if Editor.SelAvail then begin
|
||||||
ExecCommandRepeated;
|
if (SelectionObj.ActiveSelectionMode = smColumn) then
|
||||||
finally
|
ClearCarets;
|
||||||
Editor.EndUpdate;
|
exit;
|
||||||
end;
|
|
||||||
end
|
|
||||||
else // exec once and adjust
|
|
||||||
exit;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ExecCommandRepeated;
|
ExecCommandRepeated;
|
||||||
|
@ -149,15 +149,17 @@ type
|
|||||||
procedure TestIsCaretLogAndFullText(Name: String; X, Y, Offs: Integer; Lines: Array of String; Repl: Array of const); // logical caret
|
procedure TestIsCaretLogAndFullText(Name: String; X, Y, Offs: Integer; Lines: Array of String; Repl: Array of const); // logical caret
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function MyDbg(t: String): String;
|
function MyDbg(t: String; AnEsc: Boolean = false): String;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function MyDbg(t: String): String;
|
function MyDbg(t: String; AnEsc: Boolean): String;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
while(pos(LineEnding, t) > 0) do begin
|
while(pos(LineEnding, t) > 0) do begin
|
||||||
Result := Result + '"' + copy(t, 1, pos(LineEnding, t)-1) + '" Len='+IntTostr(pos(LineEnding, t)-1) + DbgStr(copy(t, 1, pos(LineEnding, t)-1)) + LineEnding;
|
if AnEsc
|
||||||
|
then Result := Result + DbgStr(copy(t, 1, pos(LineEnding, t)-1)) + ' // Len='+IntTostr(pos(LineEnding, t)-1) + DbgStr(copy(t, 1, pos(LineEnding, t)-1)) + LineEnding
|
||||||
|
else Result := Result + '"' + copy(t, 1, pos(LineEnding, t)-1) + '" Len='+IntTostr(pos(LineEnding, t)-1) + DbgStr(copy(t, 1, pos(LineEnding, t)-1)) + LineEnding;
|
||||||
system.Delete(t, 1, pos(LineEnding, t)-1+length(LineEnding));
|
system.Delete(t, 1, pos(LineEnding, t)-1+length(LineEnding));
|
||||||
end;
|
end;
|
||||||
Result := Result + '"' + t + '" Len='+IntTostr(length(t)) + DbgStr(t);
|
Result := Result + '"' + t + '" Len='+IntTostr(length(t)) + DbgStr(t);
|
||||||
|
@ -5,7 +5,7 @@ unit TestBlockIndent;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, testregistry, TestBase, math,
|
SysUtils, testregistry, TestBase, math, Types,
|
||||||
SynEdit, SynEditKeyCmds, SynEditTypes;
|
SynEdit, SynEditKeyCmds, SynEditTypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -16,13 +16,22 @@ type
|
|||||||
protected
|
protected
|
||||||
function TestTextSpace: TStringArray;
|
function TestTextSpace: TStringArray;
|
||||||
function TestTextTabs: TStringArray;
|
function TestTextTabs: TStringArray;
|
||||||
|
function TestTextColumn: TStringArray;
|
||||||
|
function TestTextColumn2: TStringArray;
|
||||||
|
|
||||||
function ReplaceIndent(AText: TStringArray; AFirstLine: Integer;
|
function ReplaceIndent(AText: TStringArray; AFirstLine: Integer;
|
||||||
ANewIndents: Array of String): TStringArray;
|
ANewIndents: Array of String): TStringArray;
|
||||||
function AddIndent(AText: TStringArray; AFirstLine, ALastLine, ASpaceCount: Integer): TStringArray;
|
function AddIndent(AText: TStringArray; AFirstLine, ALastLine, ASpaceCount: Integer): TStringArray;
|
||||||
function DelIndent(AText: TStringArray; AFirstLine, ALastLine, ASpaceCount: Integer): TStringArray;
|
function DelIndent(AText: TStringArray; AFirstLine, ALastLine, ASpaceCount: Integer): TStringArray;
|
||||||
|
function InsertIntoText(AText: TStringArray; AnInsText: String; AnXPos: array of integer): TStringArray;
|
||||||
|
function DelFromText(AText: TStringArray; AnXPosAndLen: array of integer): TStringArray;
|
||||||
|
|
||||||
procedure TestSelAndText(Name: String; LogX1, LogY1, LogX2, LogY2: Integer;
|
procedure TestSelAndText(Name: String; LogX1, LogY1, LogX2, LogY2: Integer;
|
||||||
ExpLines: Array of String;
|
ExpLines: Array of String;
|
||||||
SelIsForward: Boolean = True);
|
SelIsForward: Boolean = True);
|
||||||
|
procedure TestColSelAndText(Name: String; LogX1, LogY1, LogX2, LogY2: Integer;
|
||||||
|
ExpLines: Array of String;
|
||||||
|
SelIsForward: Boolean = True);
|
||||||
//procedure DoTest(X1,Y1, X2,Y2: Boolean; CountIndent: Integer;
|
//procedure DoTest(X1,Y1, X2,Y2: Boolean; CountIndent: Integer;
|
||||||
// ExpX1, ExpY1, ExpX2, ExpY2: Integer;
|
// ExpX1, ExpY1, ExpX2, ExpY2: Integer;
|
||||||
// ExpText: A
|
// ExpText: A
|
||||||
@ -31,6 +40,8 @@ type
|
|||||||
procedure TestUnIndent;
|
procedure TestUnIndent;
|
||||||
procedure TestIndentWithTab;
|
procedure TestIndentWithTab;
|
||||||
procedure TestUnIndentWithTab;
|
procedure TestUnIndentWithTab;
|
||||||
|
procedure TestIndentColSel;
|
||||||
|
procedure TestUnindentColSel;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -70,6 +81,29 @@ begin
|
|||||||
Result[12] := '';
|
Result[12] := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TTestBlockIndent.TestTextColumn: TStringArray;
|
||||||
|
begin
|
||||||
|
SetLength(Result, 8);
|
||||||
|
Result[0] := 'abc def ghi mno pqr';
|
||||||
|
Result[1] := 'abc de'#9#9'123456789';
|
||||||
|
Result[2] := 'äbc ÄÖÜ 123 456 789'; // ä/Ä takes 2 bytes (logical pos)
|
||||||
|
Result[3] := 'ab mef ghi mno pqr'; // m takes 3 bytes (logical pos), but also takes 1 extra phys pos
|
||||||
|
Result[4] := 'ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
Result[5] := ' abd '#9#9' xyz';
|
||||||
|
Result[6] := 'ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
Result[7] := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTestBlockIndent.TestTextColumn2: TStringArray;
|
||||||
|
begin
|
||||||
|
SetLength(Result, 5);
|
||||||
|
Result[0] := 'ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
Result[1] := 'abc def';
|
||||||
|
Result[2] := 'abc '#9#9' def';
|
||||||
|
Result[3] := 'ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
Result[4] := '';
|
||||||
|
end;
|
||||||
|
|
||||||
function GetLeadWSLen(s: String): integer;
|
function GetLeadWSLen(s: String): integer;
|
||||||
var
|
var
|
||||||
Run : PChar;
|
Run : PChar;
|
||||||
@ -81,7 +115,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TTestBlockIndent.ReplaceIndent(AText: TStringArray; AFirstLine: Integer;
|
function TTestBlockIndent.ReplaceIndent(AText: TStringArray; AFirstLine: Integer;
|
||||||
ANewIndents: Array of String): TStringArray;
|
ANewIndents: array of String): TStringArray;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
@ -123,6 +157,35 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TTestBlockIndent.InsertIntoText(AText: TStringArray; AnInsText: String;
|
||||||
|
AnXPos: array of integer): TStringArray;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
SetLength(Result, Length(AText));
|
||||||
|
for i := 0 to Length(AText) - 1 do begin
|
||||||
|
if (i < Length(AnXPos)) and (AnXPos[i] > 0) then
|
||||||
|
Result[i] := copy(AText[i], 1, AnXPos[i]-1) + AnInsText + copy(AText[i], AnXPos[i], Length(AText[i]))
|
||||||
|
else
|
||||||
|
Result[i] := AText[i];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTestBlockIndent.DelFromText(AText: TStringArray; AnXPosAndLen: array of integer
|
||||||
|
): TStringArray;
|
||||||
|
var
|
||||||
|
i, x: Integer;
|
||||||
|
begin
|
||||||
|
SetLength(Result, Length(AText));
|
||||||
|
for i := 0 to Length(AText) - 1 do begin
|
||||||
|
x := i * 2;
|
||||||
|
if (x < Length(AnXPosAndLen)) and (AnXPosAndLen[x] > 0) then
|
||||||
|
Result[i] := copy(AText[i], 1, AnXPosAndLen[x]-1) + copy(AText[i], AnXPosAndLen[x] + AnXPosAndLen[x+1], Length(AText[i]))
|
||||||
|
else
|
||||||
|
Result[i] := AText[i];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestBlockIndent.TestSelAndText(Name: String; LogX1, LogY1, LogX2, LogY2: Integer;
|
procedure TTestBlockIndent.TestSelAndText(Name: String; LogX1, LogY1, LogX2, LogY2: Integer;
|
||||||
ExpLines: array of String; SelIsForward: Boolean);
|
ExpLines: array of String; SelIsForward: Boolean);
|
||||||
begin
|
begin
|
||||||
@ -133,6 +196,33 @@ begin
|
|||||||
TestIsFullText(Name, ExpLines);
|
TestIsFullText(Name, ExpLines);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestBlockIndent.TestColSelAndText(Name: String; LogX1, LogY1, LogX2, LogY2: Integer;
|
||||||
|
ExpLines: array of String; SelIsForward: Boolean);
|
||||||
|
var
|
||||||
|
BB, BE: TPoint;
|
||||||
|
begin
|
||||||
|
TestIsCaret(Name, LogX2, LogY2);
|
||||||
|
if SynEdit.IsBackwardSel then begin
|
||||||
|
BB := SynEdit.BlockEnd;
|
||||||
|
BE := SynEdit.BlockBegin;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
BB := SynEdit.BlockBegin;
|
||||||
|
BE := SynEdit.BlockEnd;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (BB.X <> LogX1) or (BB.Y <> LogY1) then
|
||||||
|
TestFail(Name, 'IsBlockBegin(Log)',
|
||||||
|
Format('X/Y=(%d, %d)', [LogX1, LogY1]),
|
||||||
|
Format('X/Y=(%d, %d)', [BB.X, BB.Y]));
|
||||||
|
if (BE.X <> LogX2) or (BE.Y <> LogY2) then
|
||||||
|
TestFail(Name, 'IsBlockEnd(Log)',
|
||||||
|
Format('X/Y=(%d, %d)', [LogX1, LogY1]),
|
||||||
|
Format('X/Y=(%d, %d)', [BE.X, BE.Y]));
|
||||||
|
|
||||||
|
TestIsFullText(Name, ExpLines);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestBlockIndent.TestIndent;
|
procedure TTestBlockIndent.TestIndent;
|
||||||
var
|
var
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
@ -566,6 +656,403 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestBlockIndent.TestIndentColSel;
|
||||||
|
var
|
||||||
|
TheCommand: integer;
|
||||||
|
|
||||||
|
procedure SetSelect(x1,y1, x2,y2: integer);
|
||||||
|
begin
|
||||||
|
SynEdit.LogicalCaretXY := Point(x2, y2);
|
||||||
|
SynEdit.BlockBegin := Point(x1, y1);
|
||||||
|
SynEdit.BlockEnd := Point(x2, y2);
|
||||||
|
SynEdit.SelectionMode := smColumn;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoTest(AName: String; x1,y1, x2,y2: integer;
|
||||||
|
ExpectSelStartX, ExpCaretX: integer;
|
||||||
|
AnInsText: String; AnXPos: array of integer;
|
||||||
|
ATestUndoRedo: Integer = 2
|
||||||
|
);
|
||||||
|
var
|
||||||
|
TestTextSub: TStringArray;
|
||||||
|
begin
|
||||||
|
TestTextSub := InsertIntoText(TestTextColumn, AnInsText, AnXPos);
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
PushBaseName('');
|
||||||
|
|
||||||
|
SetSelect(x1,y1, x2,y2);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', ExpectSelStartX,y1, ExpCaretX,y2, TestTextSub );
|
||||||
|
if ATestUndoRedo = 0 then exit;
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
TestColSelAndText('undo 1', x1,y1, x2,y2, TestTextColumn );
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
TestColSelAndText('redo 1', ExpectSelStartX,y1, ExpCaretX,y2, TestTextSub );
|
||||||
|
if ATestUndoRedo = 1 then exit;
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
TestColSelAndText('undo 2', x1,y1, x2,y2, TestTextColumn );
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
TestColSelAndText('redo 2', ExpectSelStartX,y1, ExpCaretX,y2, TestTextSub );
|
||||||
|
|
||||||
|
PopBaseName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure DoTest2(AName: String; x1,y1, x2,y2: integer;
|
||||||
|
ExpectSelStartX1, ExpCaretX1, ExpectSelStartX2, ExpCaretX2: integer;
|
||||||
|
AnInsText: String; AnXPos1, AnXPos2: array of integer;
|
||||||
|
ExpGroupUndo: boolean
|
||||||
|
);
|
||||||
|
var
|
||||||
|
TestTextSub1, TestTextSub2: TStringArray;
|
||||||
|
undo: Integer;
|
||||||
|
begin
|
||||||
|
TestTextSub1 := InsertIntoText(TestTextColumn, AnInsText, AnXPos1);
|
||||||
|
TestTextSub2 := InsertIntoText(TestTextSub1, AnInsText, AnXPos2);
|
||||||
|
for undo := 0 to 2 do begin
|
||||||
|
DoTest(AName, x1, y1, x2, y2, ExpectSelStartX1, ExpCaretX1, AnInsText, AnXPos1, undo);
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend 2', ExpectSelStartX2,y1, ExpCaretX2,y2, TestTextSub2 );
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
if ExpGroupUndo then
|
||||||
|
TestColSelAndText('undo 2-1', x1,y1, x2,y2, TestTextColumn )
|
||||||
|
else
|
||||||
|
TestColSelAndText('undo 2-1', ExpectSelStartX1,y1, ExpCaretX1,y2, TestTextSub1 );
|
||||||
|
//
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
TestColSelAndText('redo 2-1', ExpectSelStartX2,y1, ExpCaretX2,y2, TestTextSub2 );
|
||||||
|
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
if not ExpGroupUndo then begin
|
||||||
|
TestColSelAndText('undo 2-2a', ExpectSelStartX1,y1, ExpCaretX1,y2, TestTextSub1 );
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
end;
|
||||||
|
TestColSelAndText('undo 2-2b', x1,y1, x2,y2, TestTextColumn );
|
||||||
|
//
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
if not ExpGroupUndo then begin
|
||||||
|
TestColSelAndText('redo 2-2b', ExpectSelStartX1,y1, ExpCaretX1,y2, TestTextSub1 );
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
end;
|
||||||
|
TestColSelAndText('redo 2-2a', ExpectSelStartX2,y1, ExpCaretX2,y2, TestTextSub2 );
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
ReCreateEdit;
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
PushBaseName('');
|
||||||
|
|
||||||
|
SynEdit.Options := SynEdit.Options - [eoGroupUndo] + [eoShowSpecialChars];
|
||||||
|
SynEdit.TabWidth := 5;
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
TheCommand := ecBlockIndent;
|
||||||
|
|
||||||
|
|
||||||
|
(* Line 1 Log = Phys
|
||||||
|
Line 2 Tabs
|
||||||
|
Line 3 Log = Phys // +1 for each äÄÖÜ
|
||||||
|
Line 4 Log = Phys // +1 after m
|
||||||
|
1 5 9 12
|
||||||
|
abc def ghi mno pqr'
|
||||||
|
1 5 7 8 9
|
||||||
|
abc de'#9 #9 '123456789'
|
||||||
|
abc de 123456789'
|
||||||
|
1 6 13 17
|
||||||
|
äbc ÄÖÜ 123 456 789'; // ä/Ä takes 2 bytes (logical pos)
|
||||||
|
1 4 7 10 14
|
||||||
|
ab mef ghi mno pqr'; // m takes 3 bytes (logical pos), but also takes 1 extra phys pos
|
||||||
|
1 5 9 12
|
||||||
|
ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
1 5 8 9 11
|
||||||
|
abd '#9#9 ' xyz';
|
||||||
|
ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
DoTest2('', 5,1, 12,4, 5, 14, 5, 16, ' ', [5,5,6,4], [5,5,6,4], False);
|
||||||
|
DoTest2('', 6,3, 12,1, 6, 14, 6, 16, ' ', [5,5,6], [5,5,6], False); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,1, 6,3, 14, 6, 16, 6, ' ', [5,5,6], [5,5,6], False); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,4, 5,1, 14, 5, 16, 5, ' ', [5,5,6,4], [5,5,6,4], False);
|
||||||
|
|
||||||
|
//abc def ghi mno pqr
|
||||||
|
//abc de___>____>123456
|
||||||
|
// check the inserted spaces are AFTER the tab(s), but in the selection (incl at the end of)
|
||||||
|
DoTest2('half tab - only 1 tab', 8,1, 11,4, 8, 13, 8, 15, ' ', [8,7,12,9], [8,10,12,9], False);
|
||||||
|
DoTest2('half tab - only 1 tab', 8,1, 12,4, 8, 14, 8, 16, ' ', [8,8,12,9], [8,8,12,9], False);
|
||||||
|
|
||||||
|
DoTest2('half tab - only 1 tab', 9,1, 12,4, 9, 14, 9, 16, ' ', [9,8,13,10], [9,8,13,10], False);
|
||||||
|
// NEXT: the 2nd indent goes after the 2nd tab, as the selection grew
|
||||||
|
DoTest2('half tab - both tab', 9,1, 16,4, 9, 18, 9, 20, ' ', [9,8,13,10], [9,11,13,10], False);
|
||||||
|
DoTest2('half tab - both tab', 9,1, 17,4, 9, 19, 9, 21, ' ', [9,9,13,10], [9,9,13,10], False);
|
||||||
|
|
||||||
|
DoTest2('start tab - only 1 tab', 7,1, 12,4, 7, 14, 7, 16, ' ', [7,8,10,8], [7,8,10,8], False);
|
||||||
|
DoTest2('start tab - both tab', 7,1, 17,4, 7, 19, 7, 21, ' ', [7,9,10,8], [7,9,10,8], False);
|
||||||
|
|
||||||
|
DoTest2('before tab - only 1 tab', 6,1, 12,4, 6, 14, 6, 16, ' ', [6,6,8,7], [6,6,8,7], False);
|
||||||
|
|
||||||
|
// space go after tabs
|
||||||
|
// tabs go at start
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 1;
|
||||||
|
|
||||||
|
// sel to short insert space before tabs
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
SetSelect(6,5, 10,7);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', 6,5, 13,7,
|
||||||
|
InsertIntoText(InsertIntoText(TestTextColumn, ' ', [0,0,0,0, 6,6,6]), #9, [0,0,0,0, 6,6,6])
|
||||||
|
);
|
||||||
|
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
SetSelect(6,5, 11,7);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', 6,5, 14,7,
|
||||||
|
InsertIntoText(InsertIntoText(TestTextColumn, ' ', [0,0,0,0, 6,9,6]), #9, [0,0,0,0, 6,6,6])
|
||||||
|
);
|
||||||
|
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
SetSelect(6,5, 20,7);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', 6,5, 23,7,
|
||||||
|
InsertIntoText(InsertIntoText(TestTextColumn, ' ', [0,0,0,0, 6,10,6]), #9, [0,0,0,0, 6,6,6])
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
SynEdit.Options := SynEdit.Options + [eoGroupUndo] + [eoShowSpecialChars];
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
|
||||||
|
DoTest2('', 5,1, 12,4, 5, 14, 5, 16, ' ', [5,5,6,4], [5,5,6,4], True);
|
||||||
|
DoTest2('', 6,3, 12,1, 6, 14, 6, 16, ' ', [5,5,6], [5,5,6], True); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,1, 6,3, 14, 6, 16, 6, ' ', [5,5,6], [5,5,6], True); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,4, 5,1, 14, 5, 16, 5, ' ', [5,5,6,4], [5,5,6,4], True);
|
||||||
|
|
||||||
|
(* **************************************************************************** *)
|
||||||
|
|
||||||
|
SynEdit.Options := SynEdit.Options - [eoGroupUndo];
|
||||||
|
SynEdit.TabWidth := 5;
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
TheCommand := ecBlockIndentMove;
|
||||||
|
|
||||||
|
|
||||||
|
DoTest2('', 5,1, 12,4, 7, 14, 9, 16, ' ', [4,4,5,3], [4,4,5,3], False);
|
||||||
|
DoTest2('', 6,3, 12,1, 8, 14, 10, 16, ' ', [4,4,5], [4,4,5], False); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,1, 6,3, 14, 8, 16, 10, ' ', [4,4,5], [4,4,5], False); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,4, 5,1, 14, 7, 16, 9, ' ', [4,4,5,3], [4,4,5,3], False);
|
||||||
|
|
||||||
|
// check the inserted spaces are AFTER the tab(s), but in the selection (incl at the end of)
|
||||||
|
DoTest2('half tab - only 1 tab', 8,1, 10,4, 10, 12, 12, 14, ' ', [8,7,12,9], [8,7,12,9], False);
|
||||||
|
// NEXT: the 2nd indent goes after the 2nd tab, as the selection moves
|
||||||
|
DoTest2('half tab - only 1 tab', 9,1, 12,4, 11, 14, 13, 16, ' ', [8,7,12,9], [8,10,12,9], False);
|
||||||
|
DoTest2('half tab - both tab', 9,1, 16,4, 11, 18, 13, 20, ' ', [8,7,12,9], [8,10,12,10], False);
|
||||||
|
DoTest2('half tab - both tab', 9,1, 17,4, 11, 19, 13, 21, ' ', [8,7,12,9], [8,10,12,10], False);
|
||||||
|
|
||||||
|
DoTest2('start tab - only 1 tab', 7,1, 12,4, 9, 14, 11, 16, ' ', [7,7,10,8], [7,7,10,8], False);
|
||||||
|
DoTest2('start tab - both tab', 7,1, 17,4, 9, 19, 11, 21, ' ', [7,7,10,8], [7,7,10,8], False);
|
||||||
|
|
||||||
|
// space go after tabs
|
||||||
|
// tabs go at start
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 1;
|
||||||
|
|
||||||
|
// sel to short insert space before tabs
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
SetSelect(6,5, 10,7);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', 9,5, 13,7,
|
||||||
|
InsertIntoText(InsertIntoText(TestTextColumn, ' ', [0,0,0,0, 6,6,6]), #9, [0,0,0,0, 6,5,6])
|
||||||
|
);
|
||||||
|
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
SetSelect(6,5, 11,7);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', 9,5, 14,7,
|
||||||
|
InsertIntoText(InsertIntoText(TestTextColumn, ' ', [0,0,0,0, 6,6,6]), #9, [0,0,0,0, 6,5,6])
|
||||||
|
);
|
||||||
|
|
||||||
|
SetLines(TestTextColumn);
|
||||||
|
SetSelect(11,5, 20,7);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('indend', 14,5, 23,7,
|
||||||
|
InsertIntoText(InsertIntoText(TestTextColumn, ' ', [0,0,0,0, 11,9,11]), #9, [0,0,0,0, 11,5,11])
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
SynEdit.Options := SynEdit.Options + [eoGroupUndo];
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
|
||||||
|
DoTest2('', 5,1, 12,4, 7, 14, 9, 16, ' ', [4,4,5,3], [4,4,5,3], True);
|
||||||
|
DoTest2('', 5,3, 12,1, 7, 14, 9, 16, ' ', [4,4,5], [4,4,5], True); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,1, 5,3, 14, 7, 16, 9, ' ', [4,4,5], [4,4,5], True); // only 3 lines, can't select half m
|
||||||
|
DoTest2('', 12,4, 5,1, 14, 7, 16, 9, ' ', [4,4,5,3], [4,4,5,3], True);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestBlockIndent.TestUnindentColSel;
|
||||||
|
var
|
||||||
|
TheCommand: integer;
|
||||||
|
|
||||||
|
procedure SetSelect(x1,y1, x2,y2: integer);
|
||||||
|
begin
|
||||||
|
SynEdit.LogicalCaretXY := Point(x2, y2);
|
||||||
|
SynEdit.BlockBegin := Point(x1, y1);
|
||||||
|
SynEdit.BlockEnd := Point(x2, y2);
|
||||||
|
SynEdit.SelectionMode := smColumn;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoTest(AName: String; x1,y1, x2,y2: integer;
|
||||||
|
ExpectSelStartX, ExpCaretX: integer;
|
||||||
|
AnXDelPos: array of integer;
|
||||||
|
AnInsText: String; AnXPos: array of integer;
|
||||||
|
ATestUndoRedo: Integer = 2
|
||||||
|
);
|
||||||
|
var
|
||||||
|
TestTextSub: TStringArray;
|
||||||
|
begin
|
||||||
|
TestTextSub := DelFromText(TestTextColumn2, AnXDelPos);
|
||||||
|
TestTextSub := InsertIntoText(TestTextSub, AnInsText, AnXPos);
|
||||||
|
|
||||||
|
SetLines(TestTextColumn2);
|
||||||
|
PushBaseName('');
|
||||||
|
|
||||||
|
SetSelect(x1,y1, x2,y2);
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('unindend', ExpectSelStartX,y1, ExpCaretX,y2, TestTextSub );
|
||||||
|
if ATestUndoRedo = 0 then exit;
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
TestColSelAndText('undo 1', x1,y1, x2,y2, TestTextColumn2 );
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
TestColSelAndText('redo 1', ExpectSelStartX,y1, ExpCaretX,y2, TestTextSub );
|
||||||
|
if ATestUndoRedo = 1 then exit;
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
TestColSelAndText('undo 2', x1,y1, x2,y2, TestTextColumn2 );
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
TestColSelAndText('redo 2', ExpectSelStartX,y1, ExpCaretX,y2, TestTextSub );
|
||||||
|
|
||||||
|
PopBaseName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure DoTest2(AName: String; x1,y1, x2,y2: integer;
|
||||||
|
ExpectSelStartX1, ExpCaretX1, ExpectSelStartX2, ExpCaretX2: integer;
|
||||||
|
AnXDelPos1, AnXDelPos2: array of integer;
|
||||||
|
AnInsText1: String; AnXPos1: array of integer;
|
||||||
|
AnInsText2: String; AnXPos2: array of integer;
|
||||||
|
ExpGroupUndo: boolean;
|
||||||
|
SkipRedo: boolean = False // in case the selection gets 0 column width / undo does not store that
|
||||||
|
);
|
||||||
|
var
|
||||||
|
TestTextSub1, TestTextSub2: TStringArray;
|
||||||
|
undo: Integer;
|
||||||
|
begin
|
||||||
|
TestTextSub1 := DelFromText(TestTextColumn2, AnXDelPos1);
|
||||||
|
TestTextSub1 := InsertIntoText(TestTextSub1, AnInsText1, AnXPos1);
|
||||||
|
TestTextSub2 := DelFromText(TestTextSub1, AnXDelPos2);
|
||||||
|
TestTextSub2 := InsertIntoText(TestTextSub2, AnInsText2, AnXPos2);
|
||||||
|
|
||||||
|
for undo := 0 to 2 do begin
|
||||||
|
DoTest(AName, x1, y1, x2, y2, ExpectSelStartX1, ExpCaretX1, AnXDelPos1, AnInsText1, AnXPos1, undo);
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(TheCommand, '', nil);
|
||||||
|
TestColSelAndText('unindend 2', ExpectSelStartX2,y1, ExpCaretX2,y2, TestTextSub2 );
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
if ExpGroupUndo then
|
||||||
|
TestColSelAndText('undo 2-1', x1,y1, x2,y2, TestTextColumn2 )
|
||||||
|
else
|
||||||
|
TestColSelAndText('undo 2-1', ExpectSelStartX1,y1, ExpCaretX1,y2, TestTextSub1 );
|
||||||
|
//
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
if not SkipRedo then
|
||||||
|
TestColSelAndText('redo 2-1', ExpectSelStartX2,y1, ExpCaretX2,y2, TestTextSub2 );
|
||||||
|
|
||||||
|
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
if not ExpGroupUndo then begin
|
||||||
|
TestColSelAndText('undo 2-2a', ExpectSelStartX1,y1, ExpCaretX1,y2, TestTextSub1 );
|
||||||
|
SynEdit.CommandProcessor(ecUndo, '', nil);
|
||||||
|
end;
|
||||||
|
TestColSelAndText('undo 2-2b', x1,y1, x2,y2, TestTextColumn2 );
|
||||||
|
//
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
if not ExpGroupUndo then begin
|
||||||
|
TestColSelAndText('redo 2-2b', ExpectSelStartX1,y1, ExpCaretX1,y2, TestTextSub1 );
|
||||||
|
SynEdit.CommandProcessor(ecRedo, '', nil);
|
||||||
|
end;
|
||||||
|
if not SkipRedo then
|
||||||
|
TestColSelAndText('redo 2-2a', ExpectSelStartX2,y1, ExpCaretX2,y2, TestTextSub2 );
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
(*
|
||||||
|
1 5 10
|
||||||
|
ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
1 14
|
||||||
|
abc def';
|
||||||
|
1 5 6 10
|
||||||
|
abc '#9#9' def;
|
||||||
|
abc >____> def;
|
||||||
|
ABCDEFGHIJKLMNOPQRSTUABCDEFGHIJKLMNOPQRSTU';
|
||||||
|
*)
|
||||||
|
SynEdit.Options := SynEdit.Options - [eoGroupUndo] + [eoShowSpecialChars];
|
||||||
|
SynEdit.TabWidth := 5;
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
TheCommand := ecBlockUnindent;
|
||||||
|
|
||||||
|
DoTest2('', 4,1, 15,4, 4, 15, 4, 15, [0,0, 12,2, 8,2], [0,0, 10,2, 6,2], '',[], ' ',[0,0,6], False); // no unindent in last row / no shrink sel
|
||||||
|
// 12 as 4 spaces where added
|
||||||
|
DoTest2('', 4,1, 12,3, 4, 10, 4, 12, [0,0, 12,2, 8,2], [0,0, 10,2, 6,2], '',[], ' ',[0,0,6], False);
|
||||||
|
|
||||||
|
// at end of tab / don't del outside select
|
||||||
|
DoTest2('', 4,1, 7,3, 4, 9, 4, 7, [0,0, 9,2, 6,1], [0,0, 7,2, 7,2], ' ',[0,0,6], '',[], False);
|
||||||
|
DoTest2('', 11,2, 4,3, 9, 4, 7, 4, [0,0, 9,2, 6,1], [0,0, 7,2, 7,2], ' ',[0,0,6], '',[], False);
|
||||||
|
|
||||||
|
SynEdit.BlockIndent := 8;
|
||||||
|
DoTest2('', 15,2, 4,3, 7, 4, 5, 4, [0,0, 6,8, 6,4], [0,0, 4,2, 4,2], '',[], '',[], False);
|
||||||
|
// at end of tab / don't del outside select
|
||||||
|
DoTest2('', 13,2, 4,3, 5, 4, 4, 4, [0,0, 5,8, 5,4], [0,0, 4,1, 4,1], '',[], '',[], False, True);
|
||||||
|
|
||||||
|
|
||||||
|
SynEdit.BlockIndent := 1;
|
||||||
|
SynEdit.BlockTabIndent := 1;
|
||||||
|
DoTest2('', 15,2, 4,3, 12, 4, 9, 4, [0,0, 11,3, 4,4], [0,0, 8,3, 4,2], #9'',[0,0,4], '',[], False);
|
||||||
|
|
||||||
|
|
||||||
|
SynEdit.Options := SynEdit.Options + [eoGroupUndo] + [eoShowSpecialChars];
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
|
||||||
|
DoTest2('', 4,1, 12,3, 4, 10, 4, 12, [0,0, 12,2, 8,2], [0,0, 10,2, 6,2], '',[], ' ',[0,0,6], True);
|
||||||
|
|
||||||
|
(* **************************************************************************** *)
|
||||||
|
|
||||||
|
SynEdit.Options := SynEdit.Options - [eoGroupUndo] + [eoShowSpecialChars];
|
||||||
|
SynEdit.TabWidth := 5;
|
||||||
|
SynEdit.BlockIndent := 2;
|
||||||
|
SynEdit.BlockTabIndent := 0;
|
||||||
|
TheCommand := ecBlockUnindentMove;
|
||||||
|
|
||||||
|
DoTest2('', 12,2, 11,3, 10,13, 8,11, [0,0, 10,2, 6,2], [0,0, 8,2, 8,2], ' ',[0,0,6], '',[], False);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
RegisterTest(TTestBlockIndent);
|
RegisterTest(TTestBlockIndent);
|
||||||
|
@ -555,6 +555,8 @@ begin
|
|||||||
ecToggleMode : Result:= srkmecToggleMode;
|
ecToggleMode : Result:= srkmecToggleMode;
|
||||||
ecBlockIndent : Result:= srkmecBlockIndent;
|
ecBlockIndent : Result:= srkmecBlockIndent;
|
||||||
ecBlockUnindent : Result:= srkmecBlockUnindent;
|
ecBlockUnindent : Result:= srkmecBlockUnindent;
|
||||||
|
ecBlockIndentMove : Result:= srkmecBlockIndentMove;
|
||||||
|
ecBlockUnindentMove : Result:= srkmecBlockUnindentMove;
|
||||||
ecTab : Result:= lisTab;
|
ecTab : Result:= lisTab;
|
||||||
ecShiftTab : Result:= srkmecShiftTab;
|
ecShiftTab : Result:= srkmecShiftTab;
|
||||||
ecMatchBracket : Result:= srkmecMatchBracket;
|
ecMatchBracket : Result:= srkmecMatchBracket;
|
||||||
@ -1264,6 +1266,8 @@ begin
|
|||||||
// editing
|
// editing
|
||||||
ecBlockIndent: SetCombo(VK_I,[XCtrl],VK_UNKNOWN,[], VK_K,[XCtrl],VK_I,[]);
|
ecBlockIndent: SetCombo(VK_I,[XCtrl],VK_UNKNOWN,[], VK_K,[XCtrl],VK_I,[]);
|
||||||
ecBlockUnindent: SetCombo(VK_U,[XCtrl],VK_UNKNOWN,[], VK_K,[XCtrl],VK_U,[]);
|
ecBlockUnindent: SetCombo(VK_U,[XCtrl],VK_UNKNOWN,[], VK_K,[XCtrl],VK_U,[]);
|
||||||
|
ecBlockIndentMove: SetSingle(VK_I,[XCtrl, ssShift]);
|
||||||
|
ecBlockUnindentMove: SetSingle(VK_U,[XCtrl, ssShift]);
|
||||||
ecDeleteLastChar: SetSingle(VK_BACK,[], VK_BACK,[ssShift]); // ctrl H used for scroll window.
|
ecDeleteLastChar: SetSingle(VK_BACK,[], VK_BACK,[ssShift]); // ctrl H used for scroll window.
|
||||||
ecDeleteChar: SetSingle(VK_DELETE,[]); // ctrl G conflicts with GO
|
ecDeleteChar: SetSingle(VK_DELETE,[]); // ctrl G conflicts with GO
|
||||||
ecDeleteWord: SetSingle(VK_T,[XCtrl], VK_DELETE,[XCtrl]);
|
ecDeleteWord: SetSingle(VK_T,[XCtrl], VK_DELETE,[XCtrl]);
|
||||||
@ -2916,6 +2920,8 @@ begin
|
|||||||
AddDefault(C, 'Line selection mode', srkmecLineSelect, ecLineSelect);
|
AddDefault(C, 'Line selection mode', srkmecLineSelect, ecLineSelect);
|
||||||
AddDefault(C, 'Indent block', srkmecBlockIndent, ecBlockIndent);
|
AddDefault(C, 'Indent block', srkmecBlockIndent, ecBlockIndent);
|
||||||
AddDefault(C, 'Unindent block', srkmecBlockUnindent, ecBlockUnindent);
|
AddDefault(C, 'Unindent block', srkmecBlockUnindent, ecBlockUnindent);
|
||||||
|
AddDefault(C, 'Indent block move', srkmecBlockIndentMove, ecBlockIndentMove);
|
||||||
|
AddDefault(C, 'Unindent block move', srkmecBlockUnindentMove, ecBlockUnindentMove);
|
||||||
AddDefault(C, 'Uppercase selection', lisMenuUpperCaseSelection, ecSelectionUpperCase);
|
AddDefault(C, 'Uppercase selection', lisMenuUpperCaseSelection, ecSelectionUpperCase);
|
||||||
AddDefault(C, 'Lowercase selection', lisMenuLowerCaseSelection, ecSelectionLowerCase);
|
AddDefault(C, 'Lowercase selection', lisMenuLowerCaseSelection, ecSelectionLowerCase);
|
||||||
AddDefault(C, 'Swap case in selection', lisMenuSwapCaseSelection, ecSelectionSwapCase);
|
AddDefault(C, 'Swap case in selection', lisMenuSwapCaseSelection, ecSelectionSwapCase);
|
||||||
|
@ -3104,6 +3104,8 @@ resourcestring
|
|||||||
srkmecToggleMode = 'Toggle Mode';
|
srkmecToggleMode = 'Toggle Mode';
|
||||||
srkmecBlockIndent = 'Indent block';
|
srkmecBlockIndent = 'Indent block';
|
||||||
srkmecBlockUnindent = 'Unindent block';
|
srkmecBlockUnindent = 'Unindent block';
|
||||||
|
srkmecBlockIndentMove = 'Indent (move) block';
|
||||||
|
srkmecBlockUnindentMove = 'Unindent (move) block';
|
||||||
srkmecPluginMultiCaretSetCaret = 'Add extra caret';
|
srkmecPluginMultiCaretSetCaret = 'Add extra caret';
|
||||||
srkmecPluginMultiCaretUnsetCaret = 'Remove extra caret';
|
srkmecPluginMultiCaretUnsetCaret = 'Remove extra caret';
|
||||||
srkmecPluginMultiCaretToggleCaret = 'Toggle extra caret';
|
srkmecPluginMultiCaretToggleCaret = 'Toggle extra caret';
|
||||||
|
Loading…
Reference in New Issue
Block a user