5

in LaTeX mode C-cC-f calls the tex-file function. I performed a litte tweak to that function and I wrote a tex-file-mod function. Now I'd like to call the tex-file-mode with the same key-binding during some scripts of mine and to restore the default behaviour when I exit these scripts.

Is there a way to do that using a let-binding way?

I hope I've been enough clear in my question.

EDIT. I tried, on a Drew's hint, this:

(let (latex-mode-map)
     (define-key latex-mode-map "\C-c\C-f" 'tex-file-mod))

But it doesn't restore the default key-binding at the script exit.

2 Answers 2

4

You can let-bind the keymap variable (presumably tex-file-mode-map) to a new keymap:

(let ((tex-file-mode-map (make-sparse-keymap)))
  ...)

Its value before binding it is restored after the let. After binding it, and within the body of the let, assign whatever different bindings you want.

Be aware, however, that, any other changes to the map (e.g. by a user or by other code) during the duration of that let will be lost when the let is finished.

If you want to start with the current bindings, you need to make a copy, so that your changes don't affect the original keymap:

(let ((tex-file-mode-map (copy-keymap tex-file-mode-map)))
  ...)

Another approach is to use unwind-protect. Save the current bindings for the keys you want to change, then change them, then have the cleanup part of the unwind-protect restore them.

4
  • let-bind the keymap variable doesn't work for me. I setted the key with (define-key latex-mode-map "\C-c\C-f" 'tex-file-mod)) and (let (latex-mod-map) ...) but the at the script exit the default key-binding is not restored. Where's my mistake? Jun 22, 2017 at 8:02
  • 1
    @GabrieleNicolardi Your example sets latex-mode-map to nil. See the Emacs Manual node on Local Variables for a description of the syntax of let.
    – Basil
    Jun 22, 2017 at 8:24
  • 2
    @GabrieleNicolardi I suspect that you wanted to copy the original keymap, see my edit. Jun 22, 2017 at 8:28
  • I'm actually surprised that let-binding a copy of the keymap (or a sparse keymap) works at all. I think the keymap symbol is not looked up unless the mode is (re)defined (for minor mode) or the mode command is (re)run (for major modes).
    – YoungFrog
    Jun 22, 2017 at 11:32
3

[This was going to be a comment to @Drew's answer, but the code will not be rendered correctly.]

I gave this a try and wrote a macro using unwind-protect.

(defmacro with-keybinding (map key command &rest body)
  `(let* ((map ,map)
          (key ,key)
          (newcommand ,command)
          (prevbinding (lookup-key map key)))
     (unwind-protect
         (progn
           (define-key map key newcommand)
           ,@body)
       (define-key map key prevbinding))))

[Small warning : the macro written above is "not hygienic".]

I tested with :

(with-keybinding LaTeX-mode-map (kbd "C-c C-c") 'ignore
                 (recursive-edit))

and checked that C-c C-c did nothing, and then did something again after exiting recursive-edit with C-M-c.

It might be nice to add a suitable generalized variable so that letf would do this work for us.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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