[Geany-Devel] Some comments on b4n regex-indent

Lex Trotman elextr at gmail.com
Wed Jan 30 23:28:21 UTC 2013


On 31 January 2013 09:55, Colomban Wendling <lists.ban at herbesfolles.org> wrote:
> Le 26/01/2013 03:49, Lex Trotman a écrit :
>> Hi Colomban,
>
> Hey,
>
>> Here are some comments on the subject branch.
>
> Thanks.  I'll answer the points here, but note that I have updated a few
> things recently, so they may not apply anymore.  See at the bottom of
> the mail.
>
>>  Solutions left as an
>> exercise for the reader since I don't have any ;)
>
> No no, I told you *you* were supposed to give me the solutions ;)

Well, as I said on IRC, I am thinking about it, but it is adding more regexen :)

>
>> C language, which I assume represents all {} languages
>>
>> 1. Indents relative to the previous line, that means that (tabs, width=4):
>>
>> if(long &&
>>    more){
>>        blah;
>>
>> is wrong, blah is indented too far, and hard to fix because unindent
>> remains offset (by the extra indent of "more") until the start of the
>> line.  Maybe calculate new indent relative to the previous indent
>> level, not the alignment?
>>
>> This is the same as current, and just as annoying :)
>
> Yeah.  I think for this we need clever parenthesis matching.  I even
> have some hard-coded logic locally, made a long time ago because I found
> this annoying, but not yet polished... I probably could make it a plugin
> one day -- and it'd give the "plugin for filtypes" idea to a test.
>

Yeah, alignment needs to be considered (or ignored, but that means
looking further back).

>> Can't find the gedit plugin
>
> Neither do I.  @the person who mentioned it: would we have a link?
>
>> , so tried emacs 23.4, it indented
>> correctly (including indenting "more") without any help from me, but
>> didn't indent at all until the ) after "more" and the ; after "blah"
>> which is really disconcerting but understandable.
>
> Yeah that's waht I remembered it did.  But on the matter of correctness,
> emacs cheats: it has a mod written in elisp for each language :)
>

Filetype plugin for indentation, they stole our idea :) but IIUC there
is a lot of shared common code.


>>  I guess it has a
>> "brace match" type thing for the () and indents next line by { level
>> at ;.
>>
>> 2. Can't see brace matching problem?  Maybe define better.
>
> Well, the problem is that since autoindent code is triggered after a
> newline, it would have "fixed" what brace matching did.  If brace
> matching did the same as the autoindent, of course it's fine, but if it
> was actually useful it would have been "undone".
>

Oh, ok.

>> 3. Typing } anywhere (outside comment) causes a fluctuating indent,
>> annoying whilst editing.  Not really sure what is going on here, seems
>> very dependent on whats on this and the last line, can't find a
>> pattern.
>
> I guess what you see is "normal".  "}" is declared as a "trigger
> character" in the configuration, so chat it does it… triggering
> autoindent for the current line.  And the algorithm is:
>
> line indent = prev_line_indent + indent_after_prev_line -
> unindent_after_prev_line + indent_current_line - unindent_current_line
>
> so since the current line indentation is re-computed using the previous
> line indentation as a basis and applying the rules on it, the
> indentation may change even if it doesn't match (in which case the
> indentation would be the same as the one on the prev line).
>
> Maybe I should add an "only update if a rule for the current line
> matched" check?  Not sure if it would go against something...
>

Ah, yeah, one of the principles in my thinking is *stability*, ie you
get the same answer so things don't move about like this.


>> 4. probably part of the above:
>>
>> if(long &&
>>    more){ do; it; }
>>
>> removes the alignment of "more" when } is typed.  But as I read the
>> unindent regex, it shouldn't work unless the } is only preceded by
>> whitespace?
>
> As you guessed, same as 3.
>

Which begs the question for 3 as well, if unindent regex is ^\\s*} how
does that match? Where does it get the unindentation from?

>> Python, seems ok, but as I said on IRC, I don't expect it to autoexdent.
>
> Yeah the problem with Python is that we can't guess where a block is
> supposed to be closed.  Even unindenting "else:" and "elif .*:" isn't
> really possible because you can't know to which level the else was
> supposed to apply.  Eg.
>
> def foo():
>   if a:
>     if b:
>       pass
>     else:
>       pass
>   else:
>     pass
>
> It'd be possible to get the first "else" correctly (just unindent
> current line if it matches "else:" and indent nest after ":"); but it
> would try to "fix" the second one the same way which isn't correct.  So
> we'll probably forget about Python unindentation.
>

Agree, even harder is the else in:

def foo():
    if bar:
        if bletch:
            pass
    else:
        pass

No automatic indenter is ever likely to get that right, and we don't
want one accidently changing it

>> Can't see anything new wrong with Ruby, but I don't know much what it needs.
>
> new or wrong?   if should work, apart that it unindents after "end" but
> don't indent back.

s/new// :)

>
>> You havn't done lisp or haskell yet :D
>
> Have somebody ever told you you was a funny guy? ;)
>
>
> All this said, I changed a 2 things lately:
>
> 1) I made it so a newline only automatically triggers autoindent if the
> line has the same indent as the previous one, so hopefully it won't lose
> manual or brace matched indent.  Actually I'm not sure we should really
> automagically reindent upon newline insertion; but it's convenient in
> the way it allows not to have any character triggers, in which case the
> indentation is performed on newline only and probably won't ever get
> annoying (beside the fact it's annoying for the indent not to be fixed
> on the fly).

Well, don't we have to calculate the indent of the new line every
time? (notice the space after new:) How will:

if(a){
    blah

get the indent for blah?  Triggering on { won't help, "blah" hasn't
been typed yet, in fact that line doesn't yet exist.

>
> 2) Since now \n don't really trigger auto-indent, I fixed handling of
> \n and \r as character triggers, so one can configure the thing to force
> reindentation upon newline.
>

So might as well do it on newline anyway, and also now windows line
ends will do reindentation twice (\r and \n), sure hope your algorithm
is stable :)

>
> Voila.  testing and clever ideas still welcome :)
>
> Regards,
> Colomban
> _______________________________________________
> Devel mailing list
> Devel at lists.geany.org
> https://lists.geany.org/cgi-bin/mailman/listinfo/devel


More information about the Devel mailing list