help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Adding and running a major mode hook


From: Eric Abrahamsen
Subject: Re: Adding and running a major mode hook
Date: Sun, 27 Apr 2014 13:15:33 +0800
User-agent: Gnus/5.13001 (Ma Gnus v0.10) Emacs/24.3 (gnu/linux)

Jacob Gerlach <address@hidden> writes:

> I think that a hook is the right way for me to allow users some customization 
> in my major mode.
>
> I have a list that is used to create font lock constructs, and I'd like to 
> allow users to add to that list before my code processes it into font lock 
> constructs.
>
> What I have now is basically:
>
> (setq content-list...)
>
> (mapc 'create-constructs content-list)
>
> What I've tried to do is
>
>  (setq content-list ...)
>
>  (defvar add-user-content-hook nil)
>  (defun add-user-content (input)
>    (add-hook 'add-user-content-hook
>      (lambda () (add-to-list 'content-list input))))
>
>  (run-hooks 'add-user-content-hook)
>
>  (mapc 'create-constructs content-list)
>
> With the intention that users put something like 
>
>   (add-user-content '("my content"))
>
> in their .emacs
>
> This code doesn't generate any errors, but it doesn't work either.
>
> Reading about hooks in the documentation makes me think that I have a 
> conceptual misunderstanding about the manner and sequence in which code in 
> mymode.el is executed. Specifically, what is the difference between putting 
> (run-hooks... in (define-derived-mode ... vs putting (run-hooks... somewhere 
> in the mode's code (as I have done above)?

If you've got the run-hooks inside the mode declaration, then the hooks
won't run until the user activates the mode in some particular buffer.
They will then run *every* time your mode is activated.

If you've got it at the top level of the file, the hooks will run once,
*while* the file is being loaded for the first time: ie quite likely
during emacs startup, possibly before the user's relevant customization
is loaded.

They won't run again later, when the user calls `add-user-content',
because all `add-user-content' does is add to the hook, it doesn't run
the hook again.

>From what I can see from your examples above, it might be enough just to
have:

(defvar content-list '(default values))

(define-derived-mode 'your-mode
  ....
  (mapc 'create-constructs content-list)

(defun add-user-content (input)
  (add-to-list 'content-list input))

Without any hooks at all.

When the file is loaded, these functions are defined, but no constructs
are created. After the file is loaded, the user's customizations are
loaded, including possible calls to `add-user-content', which put new
values into `content-list'. Then, *every time* the user activates this
mode, constructs are created out of whatever's in `content-list'.

Now your new problem is, do you want new constructs created every time
the mode is activated? Will that create duplicate/extraneous constructs?
Perhaps you could use a buffer-local variable to store the constructs,
so that each buffer has its own list.

Anyway, if you do go the hook route, remember that it won't make much
sense to call `run-hooks' at the top level of the file. That's pretty
much always done in the mode declaration. Hooks are meant to store
functions to be run later, when something else happens. If you put it at
the top level of the file, it will only happen on load, in which case
you might as well just call whatever the function is directly.

Hope that didn't make it worse,
Eric




reply via email to

[Prev in Thread] Current Thread [Next in Thread]