Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2020-04

Tab/Shift tab and block indentation

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Florian Klämpfl

When completing code, lazarus takes the Block indent value from the editor options for indentions, so for proper indention one sets this value to two spaces normally. However, this has the effect that tab/shift+tab also un/indents by two spaces. This is often not useful when reorganizing code. Is there any way to decouple these two behaviors: so that code completion idents by 2, tab/shift+tab by 1? Or do I need to adapt lazarus sources?

Reply by email

Martin Frb
to Florian Klämpfl
Florian Klämpfl wrote 7 lines
When completing code, lazarus takes the Block indent value from the editor options for indentions, so for proper indention one sets this value to two spaces normally. However, this has the effect that tab/shift+tab also un/indents by two spaces. This is often not useful when reorganizing code. Is there any way to decouple these two behaviors: so that code completion idents by 2, tab/shift+tab by 1? Or do I need to adapt lazarus sources?

I don't think there is a 2nd setting for codetools.

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.

Of course for un-indent that does not work, if there is a line with no spaces at the front. You can over-unindent it (block + shift tab), then shift-ctrl left click at the end of a line in the selection, to convert the selection into multi carets, hit home-key to get the carets to the front of lines, and insert a space.

The un-indent will work with empty lines in the range. "del" on multicaret will not remove line-ends. (backspace will remove line ends).

Reply by email

Florian Klämpfl
to Martin Frb
Martin Frb wrote 9 lines
On 19/04/2020 23:22, Florian Klämpfl via lazarus wrote: > When completing code, lazarus takes the Block indent value from the > editor options for indentions, so for proper indention one sets this > value to two spaces normally. However, this has the effect that > tab/shift+tab also un/indents by two spaces. This is often not useful > when reorganizing code. Is there any way to decouple these two > behaviors: so that code completion idents by 2, tab/shift+tab by 1? Or > do I need to adapt lazarus sources? I don't think there is a 2nd setting for codetools.

Would be great to have :)

Show quoted text 6 lines
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.

Reply by email

Martin Frb
to Florian Klämpfl
Florian Klämpfl wrote 12 lines
> > 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.
     Foo();
// comment at x=0
     Bar();

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
https://wiki.lazarus.freepascal.org/Editor_Macros_PascalScript

function IsIdent(c: Char): Boolean;
begin
   Result := ((c >= 'a') and (c <= 'z')) or
             ((c >= 'A') and (c <= 'Z')) or
             ((c >= '0') and (c <= '9')) or
             (c = '_');
end;
var
   p1, p2: TPoint;
   s1, s2: string;
   i, j, k: Integer;
begin
   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;
   end;
   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)
     else
       while (i <= length(s1)) and not(IsIdent(s1[i]) or (s1[i] in [#9,
' '])) do inc(i);
   end;
   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;
   end;
   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(' ');
         inc(k);
       end;
     end;
   end;
end.

Reply by email