* A problem with eval-after-load
@ 2013-10-16 9:13 Marcin Borkowski
2013-10-16 17:48 ` Michael Heerdegen
0 siblings, 1 reply; 6+ messages in thread
From: Marcin Borkowski @ 2013-10-16 9:13 UTC (permalink / raw)
To: GNU Emacs users list
Hi all,
I have a problem with eval-after-load. (In fact, this is one of the
reasons I subscribed to this list;).) I have something like this in my
init.el:
(eval-after-load 'org-tree-slide '(setq org-tree-slide-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "<f1>") 'org-tree-slide-content)
(define-key map (kbd "<f5>") 'org-tree-slide-move-previous-tree)
(define-key map (kbd "<f8>") 'org-tree-slide-move-next-tree)
map)))
(load-file "~/some/path/org-tree-slide/org-tree-slide.el")
The rationale is that I did not like the default keybindings of
org-tree-slide (which is an Org-mode based simple presentation tool).
The problem is that this doesn't work: the keymap is not updated. When
I load the org-tree-slide.el *manually*, somehow it gets updated. (It
is a bit embarassing that I noticed it before I posted this blog post:
<shameless plug>
http://mbork.pl/2013-10-09_Better_keymap_for_org-tree-slide
</shameless plug>,
but I didn't notice this at first. I will update the said post as soon
as I understand what's going on here.)
Of course, I could just get rid of eval-after-load and change the order
of the loading and redefining the keymap - but I want to know what's
the problem. (Initially, I didn't want to load org-tree-slide by
default, hence the eval-after-load stuff. Then, I decided it won't
hurt to have it loaded always. I should probably learn to use
autoload.)
Am I doing something wrong?
(PS. org-mode-slide.el *does* say (provide 'org-tree-slide).)
Best,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: A problem with eval-after-load
2013-10-16 9:13 A problem with eval-after-load Marcin Borkowski
@ 2013-10-16 17:48 ` Michael Heerdegen
2013-10-16 18:31 ` Marcin Borkowski
[not found] ` <mailman.4156.1381948316.10748.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 6+ messages in thread
From: Michael Heerdegen @ 2013-10-16 17:48 UTC (permalink / raw)
To: help-gnu-emacs
Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
> Hi all,
Hi!
> I have a problem with eval-after-load. (In fact, this is one of the
> reasons I subscribed to this list;).) I have something like this in my
> init.el:
>
> (eval-after-load 'org-tree-slide '(setq org-tree-slide-mode-map
> (let ((map (make-sparse-keymap)))
> (define-key map (kbd "<f1>") 'org-tree-slide-content)
> (define-key map (kbd "<f5>") 'org-tree-slide-move-previous-tree)
> (define-key map (kbd "<f8>") 'org-tree-slide-move-next-tree)
> map)))
>
> (load-file "~/some/path/org-tree-slide/org-tree-slide.el")
>
> The rationale is that I did not like the default keybindings of
> org-tree-slide (which is an Org-mode based simple presentation tool).
>
> The problem is that this doesn't work: the keymap is not updated. When
> I load the org-tree-slide.el *manually*, somehow it gets updated. (It
> is a bit embarassing that I noticed it before I posted this blog post:
> <shameless plug>
> http://mbork.pl/2013-10-09_Better_keymap_for_org-tree-slide
> </shameless plug>,
> but I didn't notice this at first. I will update the said post as soon
> as I understand what's going on here.)
>
> Of course, I could just get rid of eval-after-load and change the order
> of the loading and redefining the keymap - but I want to know what's
> the problem. (Initially, I didn't want to load org-tree-slide by
> default, hence the eval-after-load stuff. Then, I decided it won't
> hurt to have it loaded always. I should probably learn to use
> autoload.)
>
> Am I doing something wrong?
AFAIK, when the minor mode is defined, the _value_ of the map variable
is used. The function object representing the mode doesn't refer to the
keymap variable, but only to the value (a keymap, typically a nested
list structure).
That implies that setting the variable has no effect once the mode has
been defined. So, `eval-after-load' is wrong here, you must set the map
variable _before_ loading the file.
BTW, I don't like that behavior, too, it's a bit surprising that how you
tried it doesn't work. I stumbled across this issue myself several
times.
Regards,
Michael.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: A problem with eval-after-load
2013-10-16 17:48 ` Michael Heerdegen
@ 2013-10-16 18:31 ` Marcin Borkowski
[not found] ` <mailman.4156.1381948316.10748.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 6+ messages in thread
From: Marcin Borkowski @ 2013-10-16 18:31 UTC (permalink / raw)
To: help-gnu-emacs
Dnia 2013-10-16, o godz. 19:48:46
Michael Heerdegen <michael_heerdegen@web.de> napisał(a):
> Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
>
> > Hi all,
>
> Hi!
>
> > I have a problem with eval-after-load. (In fact, this is one of the
> > reasons I subscribed to this list;).) I have something like this
> > in my init.el:
> >
> > (eval-after-load 'org-tree-slide '(setq org-tree-slide-mode-map
> > (let ((map (make-sparse-keymap)))
> > (define-key map (kbd "<f1>") 'org-tree-slide-content)
> > (define-key map (kbd "<f5>") 'org-tree-slide-move-previous-tree)
> > (define-key map (kbd "<f8>") 'org-tree-slide-move-next-tree)
> > map)))
> >
> > (load-file "~/some/path/org-tree-slide/org-tree-slide.el")
> >
> > The rationale is that I did not like the default keybindings of
> > org-tree-slide (which is an Org-mode based simple presentation
> > tool).
> >
> > The problem is that this doesn't work: the keymap is not updated.
> > When I load the org-tree-slide.el *manually*, somehow it gets
> > updated. (It is a bit embarassing that I noticed it before I
> > posted this blog post: <shameless plug>
> > http://mbork.pl/2013-10-09_Better_keymap_for_org-tree-slide
> > </shameless plug>,
> > but I didn't notice this at first. I will update the said post as
> > soon as I understand what's going on here.)
> >
> > Of course, I could just get rid of eval-after-load and change the
> > order of the loading and redefining the keymap - but I want to know
> > what's the problem. (Initially, I didn't want to load
> > org-tree-slide by default, hence the eval-after-load stuff. Then,
> > I decided it won't hurt to have it loaded always. I should
> > probably learn to use autoload.)
> >
> > Am I doing something wrong?
>
> AFAIK, when the minor mode is defined, the _value_ of the map variable
> is used. The function object representing the mode doesn't refer to
> the keymap variable, but only to the value (a keymap, typically a
> nested list structure).
>
> That implies that setting the variable has no effect once the mode has
> been defined. So, `eval-after-load' is wrong here, you must set the
> map variable _before_ loading the file.
Thanks! It's so obvious now... (I didn't see this in the manual,
though I didn't read it *very* carefully, so maybe I missed it.)
> Regards,
>
> Michael.
Best,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: A problem with eval-after-load
[not found] ` <mailman.4156.1381948316.10748.help-gnu-emacs@gnu.org>
@ 2013-10-17 2:37 ` Emanuel Berg
2013-10-17 19:52 ` Marcin Borkowski
[not found] ` <mailman.4208.1382039548.10748.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 6+ messages in thread
From: Emanuel Berg @ 2013-10-17 2:37 UTC (permalink / raw)
To: help-gnu-emacs
Can't you do simply:
(define-key emacs-lisp-mode-map (kbd "C-l d")
'eval-defun)
(For your cases, of course.)
Possibly you have to `require' or even `load' before. If
it doesn't work, test that.
Otherwise, I have all thinkable solutions. If you can
figure out how all that works you are a smarter man than
I am. (From now on: code *first*, then *comment*.)
(let ((the-map Buffer-menu-mode-map))
(define-key the-map "\C-o" nil)
(define-key the-map (kbd "i") 'previous-line)
(define-key the-map (kbd "k") 'next-line)
(define-key the-map (kbd "w") 'kill-this-buffer)
)
Compact solution but can be slow to add/update single
entries. I don't think you need "kbd" for "i", "k", and
"w" - the C-o is set to nil not to take precedence over
a global shortcut (note the different notations - no
practical difference, what I can see...).
(define-key input-decode-map [?\u0113] [S-caps])
(global-set-key (kbd "<S-caps>") 'buffer-menu)
To get weird keys to work. You have to set them up in
the ttys (or "the Linux VTs" so they will send those
Unicode chars instead of what they normally do).
(define-key (current-global-map) (kbd "C-k")
'kill-line-if-not-empty-then-delete)
Use of `current-global-map'.
(let ((the-map (current-global-map)))
(define-key the-map "\M-u" 'downcase-word)
(define-key the-map "\C-a" 'back-to-indentation) ; etc.
A combination on that.
(defun init-C-o-prefix ()
(interactive)
(define-prefix-command 'C-o-prefix)
(global-set-key "\C-o" 'C-o-prefix)
(init-C-o-keys) )
(add-hook 'after-init-hook 'init-C-o-prefix)
A new prefix key. Initialized after everything is done,
probably so not to get reset by something else, later.
(defun init-C-o-keys ()
(interactive)
(let ((the-map (current-global-map)))
(define-key the-map "\C-od" 'eval-defun)
(define-key the-map "\C-o\C-om" 'man) ; etc.
How that happens (same old).
(global-unset-key (kbd "C-x 1"))
Unset keys you don't like, so those will exit your
muscle memory.
(setq ada-mode-hook
(lambda ()
; ...
(define-key ada-mode-map (kbd "C-j") 'nil)
))
Perhaps it will be triggered more often than necessary
(not that it takes any time to set a key).
(eval-after-load 'bibtex '(define-key bibtex-mode-map
(kbd "C-j") nil))
Should be once.
(global-set-key [(control x) (k)] 'kill-this-buffer)
Yet another notation.
(global-set-key [insertchar] nil)
`global-set-key' to nil sounds like
`global-unset-key'...
(eval-after-load 'view
'(progn
(let ((the-map view-mode-map))
(define-key the-map "\C-j" nil)
(define-key the-map "k" 'scroll-down-1)
(define-key the-map "i" 'scroll-up-1)
(define-key the-map "w" 'delete-window) )))
Same old, but several keys. (The `progn' seems
redundant.)
(global-set-key (kbd "C-j") 'jump-to-register)
(set-register ?a (cons 'file "/sudo::/etc/apt/sources.list"))
(set-register ?b (cons 'file "~/News/my-kill"))
(set-register ?C (cons 'file "/sudo::/etc/default/console-setup"))
(set-register ?c (cons 'file "~/.irssi/config"))
;; etc.
Use *registers* as keys... (Note the case sensitivity,
and the sudo prefix.)
(define-key (current-global-map)
[remap save-buffers-kill-terminal] 'no-confirm-emacs-quit)
If you are happy with the *key*.
(global-set-key (kbd "M-W") 'w3m-browse-url-new-tab)
Just because it is related to a specific mode, it may
still be useful to be able to access globally with the
same shortcut.
(defun sentmail ()
"Dired the outbox directory, then focus the most recent mail."
(interactive)
(dired "~/Mail/sent")
(local-set-key (kbd "I") 'sentmail-show-prev-mail)
(local-set-key (kbd "K") 'sentmail-show-next-mail)
(revert-buffer)
(end-of-buffer)
(dotimes (i 7) (backward-word)) )
Set keys *locally*.
(defun setup-scroll-keys ()
(interactive)
(let ((map (current-global-map)))
(define-key map (kbd "C-M-j") 'scroll-left-1-or-prefix)
(define-key map (kbd "C-M-l") 'scroll-right-1-or-prefix)
(define-key map (kbd "M-i") 'scroll-up-1)
(define-key map (kbd "M-k") 'scroll-down-1) ))
(add-hook 'after-init-hook 'setup-scroll-keys)
Function to do it, on a hook. (The word "map" should
perhaps be avoided.)
(define-key the-map "\C-o\C-ow" (lambda () (interactive) (w3m)))
Lambda notation, if you don't like function
calls. Perhaps like the "inline" of C++, or macros of C,
if it has any practical significance.
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: A problem with eval-after-load
2013-10-17 2:37 ` Emanuel Berg
@ 2013-10-17 19:52 ` Marcin Borkowski
[not found] ` <mailman.4208.1382039548.10748.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 6+ messages in thread
From: Marcin Borkowski @ 2013-10-17 19:52 UTC (permalink / raw)
To: help-gnu-emacs
Wow, now I feel guilty of wasting your time on this lengthy email...
Thanks for the tips!
Dnia 2013-10-17, o godz. 04:37:07
Emanuel Berg <embe8573@student.uu.se> napisał(a):
> Can't you do simply:
>
> (define-key emacs-lisp-mode-map (kbd "C-l d")
> 'eval-defun)
>
> (For your cases, of course.)
No, since I need to *undefine* keys, too. (Now that I've read your
message, I know that I can just define them to nil - but this means two
lines of code for each function. It's faster to copy and modify the
definition of the keymap;).)
Let me comment on your comments;).
> Possibly you have to `require' or even `load' before. If
> it doesn't work, test that.
>
> Otherwise, I have all thinkable solutions. If you can
> figure out how all that works you are a smarter man than
> I am. (From now on: code *first*, then *comment*.)
>
> (let ((the-map Buffer-menu-mode-map))
> (define-key the-map "\C-o" nil)
> (define-key the-map (kbd "i") 'previous-line)
> (define-key the-map (kbd "k") 'next-line)
> (define-key the-map (kbd "w") 'kill-this-buffer)
> )
>
> Compact solution but can be slow to add/update single
> entries. I don't think you need "kbd" for "i", "k", and
> "w" - the C-o is set to nil not to take precedence over
> a global shortcut (note the different notations - no
> practical difference, what I can see...).
No need to add/update after writing my code - but my solution was
indeed a bit faster, as I mentioned.
> (define-key input-decode-map [?\u0113] [S-caps])
> (global-set-key (kbd "<S-caps>") 'buffer-menu)
>
> To get weird keys to work. You have to set them up in
> the ttys (or "the Linux VTs" so they will send those
> Unicode chars instead of what they normally do).
I'm not sure I fully understand this, but it seems to me to low-level
for me.
> (define-key (current-global-map) (kbd "C-k")
> 'kill-line-if-not-empty-then-delete)
>
> Use of `current-global-map'.
I don't want to clutter it with things needed in one specific mode.
> (let ((the-map (current-global-map)))
> (define-key the-map "\M-u" 'downcase-word)
> (define-key the-map "\C-a" 'back-to-indentation) ; etc.
>
> A combination on that.
As above.
> (defun init-C-o-prefix ()
> (interactive)
> (define-prefix-command 'C-o-prefix)
> (global-set-key "\C-o" 'C-o-prefix)
> (init-C-o-keys) )
> (add-hook 'after-init-hook 'init-C-o-prefix)
>
> A new prefix key. Initialized after everything is done,
> probably so not to get reset by something else, later.
>
> (defun init-C-o-keys ()
> (interactive)
> (let ((the-map (current-global-map)))
> (define-key the-map "\C-od" 'eval-defun)
> (define-key the-map "\C-o\C-om" 'man) ; etc.
>
> How that happens (same old).
Did not understand this. (I could RTFM, of course, but I'm too lazy
after a day's work... I'll look into this later.)
> (global-unset-key (kbd "C-x 1"))
>
> Unset keys you don't like, so those will exit your
> muscle memory.
Must remember this, might be handy some day.
> (setq ada-mode-hook
> (lambda ()
> ; ...
> (define-key ada-mode-map (kbd "C-j") 'nil)
> ))
>
> Perhaps it will be triggered more often than necessary
> (not that it takes any time to set a key).
>
> (eval-after-load 'bibtex '(define-key bibtex-mode-map
> (kbd "C-j") nil))
>
> Should be once.
This is more or less what I wanted to achieve in the first place.
> (global-set-key [(control x) (k)] 'kill-this-buffer)
>
> Yet another notation.
And an interesting one.
> (global-set-key [insertchar] nil)
>
> `global-set-key' to nil sounds like
> `global-unset-key'...
>
> (eval-after-load 'view
> '(progn
> (let ((the-map view-mode-map))
> (define-key the-map "\C-j" nil)
> (define-key the-map "k" 'scroll-down-1)
> (define-key the-map "i" 'scroll-up-1)
> (define-key the-map "w" 'delete-window) )))
>
> Same old, but several keys. (The `progn' seems
> redundant.)
>
> (global-set-key (kbd "C-j") 'jump-to-register)
> (set-register ?a (cons 'file "/sudo::/etc/apt/sources.list"))
> (set-register ?b (cons 'file "~/News/my-kill"))
> (set-register ?C (cons 'file "/sudo::/etc/default/console-setup"))
> (set-register ?c (cons 'file "~/.irssi/config"))
> ;; etc.
>
> Use *registers* as keys... (Note the case sensitivity,
> and the sudo prefix.)
Interesting idea again.
> (define-key (current-global-map)
> [remap save-buffers-kill-terminal] 'no-confirm-emacs-quit)
>
> If you are happy with the *key*.
>
> (global-set-key (kbd "M-W") 'w3m-browse-url-new-tab)
>
> Just because it is related to a specific mode, it may
> still be useful to be able to access globally with the
> same shortcut.
Indeed, though not in my case.
> (defun sentmail ()
> "Dired the outbox directory, then focus the most recent mail."
> (interactive)
> (dired "~/Mail/sent")
> (local-set-key (kbd "I") 'sentmail-show-prev-mail)
> (local-set-key (kbd "K") 'sentmail-show-next-mail)
> (revert-buffer)
> (end-of-buffer)
> (dotimes (i 7) (backward-word)) )
>
> Set keys *locally*.
"Locally" in the sense of "this mode", not "this buffer", I guess?
> (defun setup-scroll-keys ()
> (interactive)
> (let ((map (current-global-map)))
> (define-key map (kbd "C-M-j") 'scroll-left-1-or-prefix)
> (define-key map (kbd "C-M-l") 'scroll-right-1-or-prefix)
> (define-key map (kbd "M-i") 'scroll-up-1)
> (define-key map (kbd "M-k") 'scroll-down-1) ))
> (add-hook 'after-init-hook 'setup-scroll-keys)
>
> Function to do it, on a hook. (The word "map" should
> perhaps be avoided.)
>
> (define-key the-map "\C-o\C-ow" (lambda () (interactive) (w3m)))
>
> Lambda notation, if you don't like function
> calls. Perhaps like the "inline" of C++, or macros of C,
> if it has any practical significance.
Thanks again!
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: A problem with eval-after-load
[not found] ` <mailman.4208.1382039548.10748.help-gnu-emacs@gnu.org>
@ 2013-10-19 0:43 ` Emanuel Berg
0 siblings, 0 replies; 6+ messages in thread
From: Emanuel Berg @ 2013-10-19 0:43 UTC (permalink / raw)
To: help-gnu-emacs
Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
> Wow, now I feel guilty of wasting your time on this
> lengthy email... Thanks for the tips!
No, on the contrary! I love to talk about such
things. All those shortcuts were setup when I needed
them - they are from my initialization files.
If I put them at one place, as I just did, perhaps I can
detect some new things, or someone else will comment,
etc. So it is useful for me too.
I have had *a lot* of troubles with those keys, but now
everything works (and has for some time), so for this
reason I was a bit surprised there was zero consistency
how it was done.
> No need to add/update after writing my code - but my
> solution was indeed a bit faster, as I mentioned.
Did you re-write the key map in the original mode
source? Share if you like. Did you do that in root or
user space? I wonder if an update of Emacs will
overwrite those changes?
>> (define-key input-decode-map [?\u0113] [S-caps])
>> (global-set-key (kbd "<S-caps>") 'buffer-menu)
>>
>> To get weird keys to work. You have to set them up in
>> the ttys (or "the Linux VTs" so they will send those
>> Unicode chars instead of what they normally do).
> I'm not sure I fully understand this, but it seems to
> me to low-level for me.
If you use Emacs in a tty, some of the keystrokes are
undetectable in Emacs unless you have them send
something else, that *is* detectable. In the above case,
shift plus the caps lock key is made to send the Unicode
char (described by the code, whatever that is) and
*this* in turn is used to setup the shortcut. This hack
is one of the coolest and most useful I ever saw, and I
learned it on this very list. More on this, and other
remapping:
http://user.it.uu.se/~embe8573/conf/remap.inc
>> (defun init-C-o-prefix ()
>> (interactive)
>> (define-prefix-command 'C-o-prefix)
>> (global-set-key "\C-o" 'C-o-prefix)
>> (init-C-o-keys) )
>> (add-hook 'after-init-hook 'init-C-o-prefix)
>>
>> A new prefix key. Initialized after everything is done,
>> probably so not to get reset by something else, later.
>>
>> (defun init-C-o-keys ()
>> (interactive)
>> (let ((the-map (current-global-map)))
>> (define-key the-map "\C-od" 'eval-defun)
>> (define-key the-map "\C-o\C-om" 'man) ; etc.
>>
>> How that happens (same old).
>
> Did not understand this. (I could RTFM, of course,
> but I'm too lazy after a day's work... I'll look into
> this later.)
You know the M-x prefix, that is used for "long"
shortcuts. If you are running out of M-x [whatever]
shortcuts, *or* you think the M-x is located at an
un-ergonomic place, you can setup new prefixes (prefix
keys) wherever you want. Above, C-o is made such a
prefix.
> This is more or less what I wanted to achieve in the
> first place.
>
>> (global-set-key [(control x) (k)] 'kill-this-buffer)
>>
>> Yet another notation.
>
> And an interesting one.
Yeah, I don't know what separates all those
styles. Perhaps if you move around different systems
a lot, it matters. To me, they seem the same.
>> (defun sentmail ()
>> "Dired the outbox directory, then focus the most recent mail."
>> (interactive)
>> (dired "~/Mail/sent")
>> (local-set-key (kbd "I") 'sentmail-show-prev-mail)
>> (local-set-key (kbd "K") 'sentmail-show-next-mail)
>> (revert-buffer)
>> (end-of-buffer)
>> (dotimes (i 7) (backward-word)) )
>>
>> Set keys *locally*.
>
> "Locally" in the sense of "this mode", not "this
> buffer", I guess?
No, the buffer. You see, that way it won't affect
regular Dired use. That was a workaround to use Dired as
a "sent mail" archive viewer. Now, thankfully I use Gnus
so I manage without it.
--
Emanuel Berg, programmer-for-rent. CV, projects, etc at uXu
underground experts united: http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-10-19 0:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-16 9:13 A problem with eval-after-load Marcin Borkowski
2013-10-16 17:48 ` Michael Heerdegen
2013-10-16 18:31 ` Marcin Borkowski
[not found] ` <mailman.4156.1381948316.10748.help-gnu-emacs@gnu.org>
2013-10-17 2:37 ` Emanuel Berg
2013-10-17 19:52 ` Marcin Borkowski
[not found] ` <mailman.4208.1382039548.10748.help-gnu-emacs@gnu.org>
2013-10-19 0:43 ` Emanuel Berg
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).