unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Feature request: permanent-local values in hooks buffer local values
@ 2007-12-03 17:15 Lennart Borgman (gmail)
  2007-12-03 18:22 ` Juanma Barranquero
  2007-12-04  4:56 ` Richard Stallman
  0 siblings, 2 replies; 12+ messages in thread
From: Lennart Borgman (gmail) @ 2007-12-03 17:15 UTC (permalink / raw)
  To: Emacs Devel

For variables there is a property (permanent-local) you can set on them 
to make their buffer local value survive when changing major mode.

For buffer local values of hooks you can perhaps use that, but it 
probably does not do what you want. Some functions in a hook should 
survive changing major mode (for the same reasons that variables should 
do it), but other should not.

Could somehow a feature be added to hooks that fulfills the need I have 
sketched above?

Maybe the functions in the hook could have the property permanent-local? 
   kill-local-variable should then of course have to check if a variable 
is a hook. (To implement something like that add-hook could set a 
property on a hook variable saying it is a hook.)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-03 17:15 Feature request: permanent-local values in hooks buffer local values Lennart Borgman (gmail)
@ 2007-12-03 18:22 ` Juanma Barranquero
  2007-12-04  4:56 ` Richard Stallman
  1 sibling, 0 replies; 12+ messages in thread
From: Juanma Barranquero @ 2007-12-03 18:22 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: Emacs Devel

On Dec 3, 2007 6:15 PM, Lennart Borgman (gmail)
<lennart.borgman@gmail.com> wrote:

> (To implement something like that add-hook could set a
> property on a hook variable saying it is a hook.)

http://article.gmane.org/gmane.emacs.devel/82069

             Juanma

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-03 17:15 Feature request: permanent-local values in hooks buffer local values Lennart Borgman (gmail)
  2007-12-03 18:22 ` Juanma Barranquero
@ 2007-12-04  4:56 ` Richard Stallman
  2007-12-04 18:13   ` Lennart Borgman (gmail)
  1 sibling, 1 reply; 12+ messages in thread
From: Richard Stallman @ 2007-12-04  4:56 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: emacs-devel

    For buffer local values of hooks you can perhaps use that, but it 
    probably does not do what you want. Some functions in a hook should 
    survive changing major mode (for the same reasons that variables should 
    do it), but other should not.

    Could somehow a feature be added to hooks that fulfills the need I have 
    sketched above?

Isn't change-major-mode-hook sufficient to take care of this need?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-04  4:56 ` Richard Stallman
@ 2007-12-04 18:13   ` Lennart Borgman (gmail)
  2007-12-05  6:05     ` Richard Stallman
  0 siblings, 1 reply; 12+ messages in thread
From: Lennart Borgman (gmail) @ 2007-12-04 18:13 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

Richard Stallman wrote:
>     For buffer local values of hooks you can perhaps use that, but it 
>     probably does not do what you want. Some functions in a hook should 
>     survive changing major mode (for the same reasons that variables should 
>     do it), but other should not.
> 
>     Could somehow a feature be added to hooks that fulfills the need I have 
>     sketched above?
> 
> Isn't change-major-mode-hook sufficient to take care of this need?

Perhaps you meant after-change-major-mode-hook? Yes, minor modes can add 
them selves to after-change-major-mode-hook to re-add their buffer local 
hook functions if that fits.

Perhaps that is better. It could look something like below where I have 
used flymake as an example. (flymake-mode is a minor mode that is buffer 
local, but that does not really care about major mode. It depends on the 
buffer file name instead.):

   (put 'flymake-mode 'permanent-local t)

   (defun flymake-add-to-local-hooks ()
     (when flymake-mode
       (add-hook 'after-change-functions 'flymake-after-change-function
                  nil t)
       (add-hook 'after-save-hook 'flymake-after-save-hook nil t)
       (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t)))

   (add-hook 'after-change-major-mode-hook 'flymake-add-to-local-hooks)

What disturbs me about a solution like this is that the global value of 
after-change-major-mode-hook must be used. (Am I missing something 
there?) It does not mean any performance penalty, of course. It just 
that it feels a bit strange.

Is this the way to go for such minor modes as flymake-mode? I think we 
need some guidelines here for minor mode authors.

The reason I am asking this is mainly because it has to be solved in 
some way for mumamo-mode. (For those who do not know about it see 
http://www.emacswiki.org/cgi-bin/wiki/MuMaMo )

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-04 18:13   ` Lennart Borgman (gmail)
@ 2007-12-05  6:05     ` Richard Stallman
  2007-12-05  7:21       ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 12+ messages in thread
From: Richard Stallman @ 2007-12-05  6:05 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: emacs-devel

    > Isn't change-major-mode-hook sufficient to take care of this need?

    Perhaps you meant after-change-major-mode-hook?

Isn't this about cleaning up something after you exit a major mode?
`change-major-mode-hook' is the feature for that.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-05  6:05     ` Richard Stallman
@ 2007-12-05  7:21       ` Lennart Borgman (gmail)
  2007-12-06  2:11         ` Richard Stallman
  0 siblings, 1 reply; 12+ messages in thread
From: Lennart Borgman (gmail) @ 2007-12-05  7:21 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

Richard Stallman wrote:
>     > Isn't change-major-mode-hook sufficient to take care of this need?
> 
>     Perhaps you meant after-change-major-mode-hook?
> 
> Isn't this about cleaning up something after you exit a major mode?
> `change-major-mode-hook' is the feature for that.

In a way, yes. But remember the goal. It is to let a minor mode that is 
turned on in the buffer survive changing major mode.

There are two kind of things to survive:

1) buffer local variable values, which are survived by using (put 
'VARIABLE 'permanent-local t)

2) buffer local entries in hooks. Those are what I am asking about here.

We have now mentioned three ways of achieving 2:

a) my original proposition in this thread

b) my (mis)interpretetion of your previous answer, where I suggested 
using a global entry in after-change-major-mode-hook

c) your suggestion to use change-major-mode-hook.

Using change-major-mode-hook would require something like this AFAICS:

- The minor mode that want to survive puts a function in the buffer 
local value of change-major-mode-hook.

- This function when called puts another function in the global value of 
after-change-major-mode-hook. This function should then restore the 
buffer local entries for the minor mode in the hooks. After this the 
function removes itself from the global value of 
after-change-major-mode-hook.

Is this the solution you would like?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-05  7:21       ` Lennart Borgman (gmail)
@ 2007-12-06  2:11         ` Richard Stallman
  2007-12-07  0:25           ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 12+ messages in thread
From: Richard Stallman @ 2007-12-06  2:11 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: emacs-devel

    In a way, yes. But remember the goal. It is to let a minor mode that is 
    turned on in the buffer survive changing major mode.

    There are two kind of things to survive:

    1) buffer local variable values, which are survived by using (put 
    'VARIABLE 'permanent-local t)

    2) buffer local entries in hooks. Those are what I am asking about here.

I see.  I did not understand your aim before.
Here's a possible implementation.

1. Put a property on hook variables to identify them for this
special processing.

2. Put another property (as you suggested) on hook functions
to indicate they should be preserved.

3. Now it is possible for kill-all-local-variables
to identify hook variables, scan their local values,
and preserve specific hooks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-06  2:11         ` Richard Stallman
@ 2007-12-07  0:25           ` Lennart Borgman (gmail)
  2007-12-09 12:36             ` Richard Stallman
  0 siblings, 1 reply; 12+ messages in thread
From: Lennart Borgman (gmail) @ 2007-12-07  0:25 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

Richard Stallman wrote:
>     In a way, yes. But remember the goal. It is to let a minor mode that is 
>     turned on in the buffer survive changing major mode.
> 
>     There are two kind of things to survive:
> 
>     1) buffer local variable values, which are survived by using (put 
>     'VARIABLE 'permanent-local t)
> 
>     2) buffer local entries in hooks. Those are what I am asking about here.
> 
> I see.  I did not understand your aim before.
> Here's a possible implementation.
> 
> 1. Put a property on hook variables to identify them for this
> special processing.
> 
> 2. Put another property (as you suggested) on hook functions
> to indicate they should be preserved.
> 
> 3. Now it is possible for kill-all-local-variables
> to identify hook variables, scan their local values,
> and preserve specific hooks.


I have tested another solution, defining a macro instead for minor mode 
authors to use if they want their minor mode to survive changes in major 
mode. The advantage of that is that it makes it very clear what is 
needed. And I do not think there is any big performance penalty. A 
disadvantage is however that the minor mode initialization will be a bit 
different whether this macro is available or not. Therefore it would be 
good if the macro were added to Emacs.

Here is the macro:


(defmacro mumamo-make-change-major-survivor (name hook-fun-list var-list)
   "Define functions for major mode change survival.
Minor mode authors that want their buffer local
minor mode to survive when the major mode in the buffer is
changed can use this macro.

An example of such a minor mode may be flymake minor mode. For
flymake this call can be used:

   (eval-after-load 'mumamo
     (mumamo-make-change-major-survivor
      flymake
      '((after-change-functions flymake-after-change-function)
        (after-save-hook flymake-after-save-hook)
        (kill-buffer-hook flymake-kill-buffer-hook))
      '(flymake-mode
        flymake-is-running
        flymake-timer
        flymake-last-change-time
        flymake-check-start-time
        flymake-check-was-interrupted
        flymake-err-info
        flymake-new-err-info
        flymake-output-residual
        flymake-mode-line
        flymake-mode-line-e-w
        flymake-mode-line-status
        flymake-temp-source-file-name
        flymake-master-file-name
        flymake-temp-master-file-name
        flymake-base-dir
        )))

Then in `flymake-mode' a call to the functions
`flymake-add-survivor' and `flymake-remove-survivor \(which was defined 
by the macro called above) must be done.

The macro defines two functions for the user of this macro to
call, NAME-add-survivor and NAME-remove-survivor. A typical use
is for a minor mode to use the first when turning on and the
second when turning off.

NAME-add-survivor will add to local hooks according to the list
HOOK-FUN-LIST and arrange so that those additions to the local
hooks will be setup again after a major mode change. Also make
sure that the local values of the variables in VAR-LIST survives
a major mode change.

NAME-remove-survivor does the opposite of this.

NAME should be a symbol. HOOK-FUN-LIST should be a list where
each record has the format

   \(HOOK-NAME HOOK-FUNCTION)

where HOOK-NAME is the name of the hook to which HOOK-FUNCTION
should be added locally.

VAR-LIST should be a list of variable symbols."
   (let* ((sname (symbol-name name))
          (NAME-add-survivor    (intern (concat sname "-add-survivor")))
          (NAME-remove-survivor (intern (concat sname "-remove-survivor")))
          (NAME-acmmh-f         (intern (concat sname "-acmmh-f")))
          (NAME-cmmh-f          (intern (concat sname "-cmmh-f"))))

     `(progn

        (defun ,NAME-add-survivor ()
          "Add major mode change surviving.
This function should be called by the code that calls the macro
`make-change-major-survivor'."
          (dolist (rec ,hook-fun-list)
            (let ((hook (nth 0 rec))
                  (func (nth 1 rec)))
              (add-hook hook func nil t)))
          ;; Set up to survive major mode change
          (add-hook 'change-major-mode-hook ',NAME-cmmh-f nil t)
          ;;(lwarn t :warning "add survivor, cmmh=%S" 
change-major-mode-hook)
          )

        (defun ,NAME-remove-survivor ()
          "Remove major mode change surviving.
This function should be called by the code that calls the macro
`make-change-major-survivor'."
          (dolist (rec ,hook-fun-list)
            (let ((hook (nth 0 rec))
                  (func (nth 1 rec)))
              (remove-hook hook func t)))
          ;; Set up to survive major mode change
          (remove-hook 'change-major-mode-hook ',NAME-cmmh-f t)
          ;;(lwarn t :warning "rem survivor, cmmh=%S" 
change-major-mode-hook)
          )

        (defun ,NAME-acmmh-f ()
          "Restore after changing major mode.
This function is added locally to `after-change-major-mode-hook'."
          ;;(remove-hook 'after-change-major-mode-hook ',NAME-acmmh-f t)
          (,NAME-add-survivor)
          ;; Remove 'permanent-local t
          (dolist (sym ,var-list)
            (put sym 'permanent-local nil)))

        (defun ,NAME-cmmh-f ()
          "Set up to restore after changing major mode.
This function is added locally to `change-major-mode-hook'."
          (add-hook 'after-change-major-mode-hook ',NAME-acmmh-f nil t)
          ;;(lwarn t :warning "cmmh-f, acmmh=%S" 
after-change-major-mode-hook)
          (put 'after-change-major-mode-hook 'permanent-local t)
          ;; Note: I can see no way to later remove the
          ;; 'permanent-local property that is set here without
          ;; getting potential problems.
          ;;
          ;; Add 'permanent-local t
          (dolist (sym ,var-list)
            (put sym 'permanent-local t))))))

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-07  0:25           ` Lennart Borgman (gmail)
@ 2007-12-09 12:36             ` Richard Stallman
  2007-12-09 14:21               ` Lennart Borgman (gmail)
  0 siblings, 1 reply; 12+ messages in thread
From: Richard Stallman @ 2007-12-09 12:36 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: emacs-devel

    Then in `flymake-mode' a call to the functions
    `flymake-add-survivor' and `flymake-remove-survivor \(which was defined 
    by the macro called above) must be done.

This seems like a very cumbersome interface.  I think it is very
unclean to dynamically change `permanent-local' properties.  That's
the sort of thing that we are sure to regret.

We should use my mechanism instead.  It is simple and clean.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-09 12:36             ` Richard Stallman
@ 2007-12-09 14:21               ` Lennart Borgman (gmail)
  2007-12-09 15:24                 ` Lennart Borgman (gmail)
  2007-12-09 23:19                 ` Richard Stallman
  0 siblings, 2 replies; 12+ messages in thread
From: Lennart Borgman (gmail) @ 2007-12-09 14:21 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

Richard Stallman wrote:
>     Then in `flymake-mode' a call to the functions
>     `flymake-add-survivor' and `flymake-remove-survivor \(which was defined 
>     by the macro called above) must be done.
> 
> This seems like a very cumbersome interface.  I think it is very
> unclean to dynamically change `permanent-local' properties.  That's
> the sort of thing that we are sure to regret.
> 
> We should use my mechanism instead.  It is simple and clean.

That is very fine with me.

I suggest then adding something like this to the end of add-hook:

     (when (and local
                (get function 'permanent-local-in-hooks))
       (put hook 'permanent-local-hook t)

Then in kill-local-variables check for the property 
'permanent-local-hook and handle the hook accordingly.

I can see no reasonable way to remove the property 'permanent-local-hook 
from the hook variable. (The problem is that properties do not have 
buffer local values. It could be simulated by having a buffer local 
variable carrying the propery, but I see no reason to make it that 
complicated.)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-09 14:21               ` Lennart Borgman (gmail)
@ 2007-12-09 15:24                 ` Lennart Borgman (gmail)
  2007-12-09 23:19                 ` Richard Stallman
  1 sibling, 0 replies; 12+ messages in thread
From: Lennart Borgman (gmail) @ 2007-12-09 15:24 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

Lennart Borgman (gmail) wrote:
> Richard Stallman wrote:
>>     Then in `flymake-mode' a call to the functions
>>     `flymake-add-survivor' and `flymake-remove-survivor \(which was 
>> defined     by the macro called above) must be done.
>>
>> This seems like a very cumbersome interface.  I think it is very
>> unclean to dynamically change `permanent-local' properties.  That's
>> the sort of thing that we are sure to regret.
>>
>> We should use my mechanism instead.  It is simple and clean.
> 
> That is very fine with me.
> 
> I suggest then adding something like this to the end of add-hook:
> 
>     (when (and local
>                (get function 'permanent-local-in-hooks))
>       (put hook 'permanent-local-hook t)
> 
> Then in kill-local-variables check for the property 
> 'permanent-local-hook and handle the hook accordingly.
> 
> I can see no reasonable way to remove the property 'permanent-local-hook 
> from the hook variable. (The problem is that properties do not have 
> buffer local values. It could be simulated by having a buffer local 
> variable carrying the propery, but I see no reason to make it that 
> complicated.)

     (when (and local
                (and (symbolp function))
                (get function 'permanent-local-in-hooks))
       (put hook 'permanent-local-hook t)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Feature request: permanent-local values in hooks buffer local values
  2007-12-09 14:21               ` Lennart Borgman (gmail)
  2007-12-09 15:24                 ` Lennart Borgman (gmail)
@ 2007-12-09 23:19                 ` Richard Stallman
  1 sibling, 0 replies; 12+ messages in thread
From: Richard Stallman @ 2007-12-09 23:19 UTC (permalink / raw)
  To: Lennart Borgman (gmail); +Cc: emacs-devel

    I can see no reasonable way to remove the property 'permanent-local-hook 
    from the hook variable. 

Removing that property would be only an optimization.
It's not crucial.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2007-12-09 23:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-03 17:15 Feature request: permanent-local values in hooks buffer local values Lennart Borgman (gmail)
2007-12-03 18:22 ` Juanma Barranquero
2007-12-04  4:56 ` Richard Stallman
2007-12-04 18:13   ` Lennart Borgman (gmail)
2007-12-05  6:05     ` Richard Stallman
2007-12-05  7:21       ` Lennart Borgman (gmail)
2007-12-06  2:11         ` Richard Stallman
2007-12-07  0:25           ` Lennart Borgman (gmail)
2007-12-09 12:36             ` Richard Stallman
2007-12-09 14:21               ` Lennart Borgman (gmail)
2007-12-09 15:24                 ` Lennart Borgman (gmail)
2007-12-09 23:19                 ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).