GNU bug report logs - #31361
25.3; Issue when advising `indent-line-function'

Previous Next

Package: emacs;

Reported by: Nicolas Goaziou <mail <at> nicolasgoaziou.fr>

Date: Thu, 3 May 2018 21:17:02 UTC

Severity: normal

Found in version 25.3

To reply to this bug, email your comments to 31361 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to monnier <at> IRO.UMontreal.CA, bug-gnu-emacs <at> gnu.org:
bug#31361; Package emacs. (Thu, 03 May 2018 21:17:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Nicolas Goaziou <mail <at> nicolasgoaziou.fr>:
New bug report received and forwarded. Copy sent to monnier <at> IRO.UMontreal.CA, bug-gnu-emacs <at> gnu.org. (Thu, 03 May 2018 21:17:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Goaziou <mail <at> nicolasgoaziou.fr>
To: bug-gnu-emacs <at> gnu.org
Subject: 25.3; Issue when advising `indent-line-function'
Date: Thu, 03 May 2018 23:15:46 +0200
Hello,

When `indent-line-function' is advised, using `add-function', and the
variable contains `indent-relative', `indent-according-to-mode' has an
erratic behavior.

In the following code, from `indent-according-to-mode',

 (if (memq indent-line-function
	    '(indent-relative indent-relative-maybe))
    ...
    ;; The normal case.
    (funcall indent-line-function))

the if branch is no longer executed because `indent-line-function' is no
longer `indent-relative' but a closure around it.

You can reproduce the issue with the following recipe:

  - Open a new buffer in Fundamental mode (so `indent-line-function' is
    `indent-relative')

  - Insert : "-- Test"

  - From there, <RET> returns to column 0.  However, upon evaluating the
    following:

      M-: (add-function :before-until (local 'indent-line-function) #'ignore)

    <RET> now moves point at the same column as the "T" from "Test", in
    the new line.


Regards,

-- 
Nicolas Goaziou                                                0x80A93738




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#31361; Package emacs. (Sat, 05 May 2018 14:27:02 GMT) Full text and rfc822 format available.

Message #8 received at 31361 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Goaziou <mail <at> nicolasgoaziou.fr>
To: 31361 <at> debbugs.gnu.org
Cc: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Subject: Re: bug#31361: 25.3; Issue when advising `indent-line-function'
Date: Sat, 05 May 2018 16:26:27 +0200
Nicolas Goaziou <mail <at> nicolasgoaziou.fr> writes:

> When `indent-line-function' is advised, using `add-function', and the
> variable contains `indent-relative', `indent-according-to-mode' has an
> erratic behavior.
>
> In the following code, from `indent-according-to-mode',
>
>  (if (memq indent-line-function
> 	    '(indent-relative indent-relative-maybe))
>     ...
>     ;; The normal case.
>     (funcall indent-line-function))
>
> the if branch is no longer executed because `indent-line-function' is no
> longer `indent-relative' but a closure around it.

Thinking more about the problem, I think I can describe it differently.

When `indent-line-function' is set to `indent-relative' -- or
`indent-relative-maybe' -- the function `indent-relative' is not meant
to be actually called to handle the indentation. Instead, some ad-hoc
indentation is hard-coded into `indent-according-to-mode', which see.

However, when `indent-line-function' is advised, according to my
previous report, `indent-relative' is actually called for indentation,
which is not the intent, per above.

So basically, any call to `indent-according-to-mode', e.g., with
`reindent-then-newline-and-indent' or through Electric Indent mode, is
broken whenever `indent-relative' is advised.

One idea, suggested by Stefan, would be to write
`indent-according-to-mode' like the following:

    (if (memq (advice--cd*r indent-line-function)
             '(indent-relative indent-relative-maybe))
       ...
       ;; The normal case.
       (funcall indent-line-function))

i.e., strip advices so that the ad-hoc code is executed, as intended,
instead of ultimately calling `indent-relative'. Unfortunately, this is
insufficient because the advices are not applied, which is also wrong.

If this stripping is done, it should also ensure that advices are
applied on the ad-hoc indentation code there.

FWIW, my gut feeling is that `indent-relative' -- and
`indent-relative-maybe' -- ought to be normalized to behave like
a normal indentation function, i.e., a function actually called from
`indent-according-to-mode'. This was the case before commit
a17b712b4d812d28086ae9af02f9043b36cf3e19 (Oct 30 2001). 

Currently, `indent-relative' is two-sided. Therefore, the previous
suggestion might entail to split `indent-relative' into two parts, one
meant to be used as a value for `indent-line-function' -- maybe named
`indent-relative-function' -- and the other one to be used like current
`indent-relative', i.e., jumping from one indent point to the other.




This bug report was last modified 5 years and 356 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.