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?
Mailing lists / lazarus / 2020-04
Tab/Shift tab and block indentation
4 messages · 2 people · –
- FFlorian Klämpfl 2
- MMartin Frb 2
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Florian Klämpfl wrote 7 lines
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).
Martin Frb wrote 9 lines
Would be great to have :)
Show quoted text 6 lines
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.
Florian Klämpfl wrote 12 lines
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.