[Lazarus] Tab/Shift tab and block indentation

Martin Frb lazarus at mfriebe.de
Wed Aug 19 00:24:12 CEST 2020

On 20/04/2020 21:59, Florian Klämpfl via lazarus wrote:
>> But instead of using tab to (un-)indent selected lines, you can use 
>> the multi-caret feature.
>> Go to the left most column, on the first line. Then shift-alt-down 
>> until you have a caret in front of each line you wish to change. Now 
>> either delete spaces, or insert spaces.
> Problem is, that backspace behaves really uncontrollable in this case: 
> lines get one char removes others more, I think it does some unindent 
> operation as well instead of just removing chars.
Sounds strange.
Maybe you have some tabs/#9 chars? Then "del" removes the entire #9.

But, multicaret  would eat into the text if you deleted from this.
// comment at x=0

So, yes 2nd option would be good...

Btw, when indenting for alinment, I use an editor-macro (assigned to a 
key) for aligning tokens  in the middle of a line.
For example bring all // to the same x pos
It only goes for the first occurrence of the token, but it can be adjusted.
You can in a similar way write a macro to do your indent.

The macro is actually the example on 

function IsIdent(c: Char): Boolean;
   Result := ((c >= 'a') and (c <= 'z')) or
             ((c >= 'A') and (c <= 'Z')) or
             ((c >= '0') and (c <= '9')) or
             (c = '_');

   p1, p2: TPoint;
   s1, s2: string;
   i, j, k: Integer;
   if not Caller.SelAvail then exit;
   p1 := Caller.BlockBegin;
   p2 := Caller.BlockEnd;
   if (p1.y > p2.y) or ((p1.y = p2.y) and (p1.x > p2.x)) then begin
     p1 := Caller.BlockEnd;
     p2 := Caller.BlockBegin;
   s1 := Caller.Lines[p1.y - 1];
   s2 := '';
   i := p1.x
   while (i <= length(s1)) and (s1[i] in [#9, ' ']) do inc(i);
   j := i;
   if i <= length(s1) then begin
     if IsIdent(s1[i]) then // pascal identifier
       while (i <= length(s1)) and IsIdent(s1[i]) do inc(i)
       while (i <= length(s1)) and not(IsIdent(s1[i]) or (s1[i] in [#9, 
' '])) do inc(i);
   if i > j then s2 := copy(s1, j, i-j);

   if not InputQuery( 'Align', 'Token', s2) then exit;

   j := 0;
   for i := p1.y to p2.y do begin
     s1 := Caller.Lines[i - 1];
     k := pos(s2, s1);
     if (k > j) then j := k;
   if j < 1 then exit;

   for i := p1.y to p2.y do begin
     s1 := Caller.Lines[i - 1];
     k := pos(s2, s1);
     if (k > 0) and (k < j) then begin
       Caller.LogicalCaretXY := Point(k, i);
       while k < j do begin
         ecChar(' ');


More information about the lazarus mailing list