Page 1 of 1

Do "global-set-key" for future sessions programmatically

PostPosted: Sun Oct 28, 2012 9:58 am
by erjoalgo
I need to create a function "global-set-key-future", which does the same as "global-set-key", except that the new keybinding goes into effect in future sessions.

There are at least two ways to do this, neither of which I know how to do:

1) Define a function "global-set-key-future". First, have it execute global-set-key within it (how to run it in the 'foreground' and have it prompt the user for the key, etc?). Then, programmatically get the last command executed by the lisp interpreter as a string. Finally insert that into code snippet into .emacs. How do I retrieve the code that is being run by the interpreter? I know about the variable last-command, but that only describes the name of the last command executed; I also need its parameters, or rather the code-snippet that was run by the interpreter (since the command uses user prompts).

2) Define a function "global-set-key-future". Attempt to recreate the code-snippet by hand. This would require prompting for a key, and converting that into the vector of characters representing the desired key event. For example, the key sequence "control meta x control meta f" would have to be translated into "\C-x\C-f". What function does this translation?

3) Modify the source of global-set-key, so that whatever it does, it inserts its changes into .emacs.

Note that I am aware that it is possible to manually create these keybindings, but I am interested in creating them interactively like does global-set-key.

Re: Do "global-set-key" for future sessions programmatically

PostPosted: Mon Oct 29, 2012 7:29 am
by stackman
Please, post messages about emacs-lisp in the emacs lisp section of the forum.

When it comes to writing a global-set-key-future command,
this is hard to do if you are not fluent in emacs-lisp.
It is easy if you have a good grasp of emacs-lisp, but also pointless
since then it is faster to switch to the init-file and write manually the call to global-set-key.

Anyway, here is my version. Since the code for global-set-key is only 4 lines long, I start from there.

Code: Select all
  (defun global-set-key-future (key command)
     "A rewriting of the global-set-key command that saves the new
      binding in the init-file of the user."
     (interactive "KSet key globally: \nCSet key %s to command: ")
     (or (vectorp key) (stringp key)
         (signal 'wrong-type-argument (list 'arrayp key)))
     (define-key (current-global-map) key command)
     ;; the code that writes the binding to the init-file
     (with-current-buffer (find-file-noselect user-init-file)
       (goto-char (point-max))
       (insert (format "\n%S\n" `(global-set-key ,key ',command)))))