From: Eric Abrahamsen <eric@ericabrahamsen.net>
To: help-gnu-emacs@gnu.org
Subject: Re: Adding and running a major mode hook
Date: Sun, 27 Apr 2014 13:15:33 +0800 [thread overview]
Message-ID: <87y4yruzd6.fsf@ericabrahamsen.net> (raw)
In-Reply-To: <ed13f213-3af4-4f7e-b3d8-90543fc5b4b9@googlegroups.com> (Jacob Gerlach's message of "Sat, 26 Apr 2014 10:25:52 -0700 (PDT)")
Jacob Gerlach <jacobgerlach@gmail.com> 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
next prev parent reply other threads:[~2014-04-27 5:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-26 17:25 Adding and running a major mode hook Jacob Gerlach
2014-04-27 3:12 ` Eric Abrahamsen
2014-04-27 5:15 ` Eric Abrahamsen [this message]
[not found] ` <mailman.107.1398568207.1147.help-gnu-emacs@gnu.org>
2014-04-27 11:56 ` Jacob Gerlach
2014-04-27 12:10 ` Jacob Gerlach
2014-04-29 0:45 ` Eric Abrahamsen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y4yruzd6.fsf@ericabrahamsen.net \
--to=eric@ericabrahamsen.net \
--cc=help-gnu-emacs@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).