Subject: bug#23565: 24.5; tcl-end-of-defun and tcl-eval-defun doesn't work reliable

From: Rolf Ade <[email-masked]>
Date: Sat, 28 Sep 2019 02:20:54 +0200

Rolf Ade <[email-masked]> writes:
> Tom Tromey <[email-masked]> writes:
>>>>>>> "Rolf" == Rolf Ade <[email-masked]> writes:
>>
>> Rolf> Indent the second line ("foo") with <Tab> and you get
>> Rolf> do {
>> Rolf>     foo
>>
>> Thanks for trying this.
>> I suppose instead of the fix for the "namespace" thing, tcl-mode should
>> maybe just looking at brace depth for indentation.  I will take a deeper
>> look.
>
> Despite #32035 this is still open with master of today (but not with
> 26.2). Completely legal and commen code at the beginning befor the first
> word out of tcl-proc-list are not indented as expected. Examples:
>
> do {
> something
> }
>
> if {$argc != 0} {
> puts stderr "usage: $argv0"
> }
>
> set options {
> -foo "default"
> -bar "bardefault"
> }
>
>
> Expected indentation would be of course something like:
>
> do {
>     something
> }
>
> if {$argc != 0} {
>     puts stderr "usage: $argv0"
> }
>
> set options {
>     -foo "default"
>     -bar "bardefault"
> }
>
>
> After the first word out of tcl-proc-list in the buffer all that
> examples above will be indented as expected, no misbehaviour any more.
>
> I happily confirm again, that master hasn't the original problem of this
> bug report. And I'd really love to see that fixed, after it has plagued
> me for 20 years.
>
> But I'm afraid that the cure (current behavior of master) is worse than
> the problem (26.2).

(I'm getting nervous - emacs-dev already talks about cutting an emacs-27
branch ... I'd really love to see this long standing bug to be fixed.
Let me recapitulate.)

The original bug of this report was fixed by

commit cd5bb4bf3dbad8941d25823f398b595b8f0edbb9
Author: Tom Tromey <[email-masked]>
Date:   Sun Jun 24 11:18:19 2018 -0600

This fix introduced a new unwanted indentation behaviour. Any code at
the beginning of a buffer in tcl-mode before the first word that match
an element out of tcl-proc-list (or so it looks like, I haven't really
understand all details but I've provided some examples earlier in the
thread) will not be indented as typically expected.

I'm afraid the behaviour of current master is more worse than it was
before of cd5bb4bf3dbad8941d25823f398b595b8f0edbb9. E.g. work with a
notable fraction of the tcl files included in the tcl core distribution
(https://core.tcl-lang.org/tcl/download) would suffer from this.

So before release of emacs 27 this commit should be reverted. Or, much
better, because the commit fixes the original problem (which I really
love to see fixed), it should be improved.

I came up with the following. The simple idea is to keep the new
behaviour where it shines and fall back to the old way otherwise.

Commit message:

Fix tcl-mode indentation after fix of bug#23565

* lisp/progmodes/tcl.el (tcl-calculate-indent) Fall back to old
  indentation method for tcl code at the start of the buffer before the
  first word matching an element out of tcl-proc-list.

Copyright-paperwork-exempt: yes

diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index 0fd3d6d1bf..db97230480 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -817,7 +817,9 @@ tcl-calculate-indent
           found-next-line)
       (if parse-start
          (goto-char parse-start)
-       (beginning-of-defun))
+       (if (not (beginning-of-defun))
+            (let ((beginning-of-defun-function nil))
+              (beginning-of-defun))))
       (while (< (point) indent-point)
        (setq parse-start (point))
        (setq state (parse-partial-sexp (point) indent-point 0))