1

The following .emacs file works as expected, so long as I invoke emacs the "normal" way (ie by launching the emacs executable directly).

(global-unset-key (kbd "C-]"))
(global-set-key (kbd "H-C-]") 'abort-recursive-edit)
(define-key local-function-key-map (kbd "C-]") 'event-apply-hyper-modifier)

But when I start emacs via emacsclient -n -c -a "", the value of local-function-key-map gets overwritten somewhere along the way. I have used print statements to make sure that my .emacs file is getting run, and that the value of local-function-key-map gets updated. But by the time I land in the *scratch* buffer, my binding is missing from local-function-key-map.

Has anyone experienced this before, or knows a reason why local-function-key-map would get clobbered when starting emacs via emacsclient?

I am running emacs-25.1 on CentOS 7

1

(n.b. Refer to nispio's answer for details of why this approach can solve the problem.)

I use after-make-frame-functions when dealing with terminal-local settings.

e.g.:

;; Per-frame/terminal configuration.
(defun my-frame-behaviours (&optional frame)
  "Make frame- and/or terminal-local changes."
  (with-selected-frame (or frame (selected-frame))
    ;; do things
    (message "new frame %S" (selected-frame))
    ))
;; Run now, for non-daemon Emacs...
(my-frame-behaviours)
;; ...and later, for new frames / emacsclient
(add-hook 'after-make-frame-functions 'my-frame-behaviours)
  • Thank you. I was really surprised that there was not a hook for that. I forgot that hooks occasionally get named -functions instead of -hook. Any idea if there is a reason for the difference? Or is it random? – nispio Mar 10 '17 at 16:58
  • Quoting (elisp) Hooks: "If the hook variable’s name does not end with -hook, that indicates it is probably an “abnormal hook”. That means the hook functions are called with arguments, or their return values are used in some way. The hook’s documentation says how the functions are called. You can use add-hook to add a function to an abnormal hook, but you must write the function to follow the hook’s calling convention. By convention, abnormal hook names end in -functions." – phils Mar 10 '17 at 20:33
2

tl;dr

local-function-key-map is a terminal-local version of function-key-map, so defining my binding in function-key-map fixed the problem

Why?

The reason for the behavior seems to be that local-function-key-map is a terminal-local variable. When using emacsclient, two distinct terminals are created: one in the tty, and one for the X-windows. Calling (list-terminals) after starting emacs via emacsclient returns this:

(#<terminal 0 on initial_terminal> #<terminal 1 on :0>)

So local-function-key-map in "terminal 0" (the tty) has my binding defined, but the one in "terminal 1" (the graphical frames) does not.

None of the following hooks seemed to run after the new terminal-local definition of local-function-key-map had been created.

after-init-hook
before-make-frame-hook
tty-setup-hook
term-setup-hook
emacs-startup-hook

So finally, I ended up using local-function-key-map's parent map, function-key-map, because it is not terminal-local. I still find it strange that I cannot find a way to automatically modify local-function-key-map after a new terminal is created.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.