Adding Keyboard Bindings to Existing Emacs Mode

I am trying to complete the first modification of Emacs. I recorded a small keyboard macro and Emacs spat it out as elisp, resulting in:

(setq add-docstring "\C-rdef\Cn\Ca\Cm\Cp\Ci\C-u6\"\C-u3\Cb") (global-set-key "\Cc\Cd" 'add-docstring) 

However, a search for the Emacs link showed that Cc Cd is already bound in diff mode. I do not plan to use diff mode, but the future is unknowable, and I would not want to catch a trap for myself. So I would like this keybinding to work only in python mode, where it is trying to help me add docstrings.

In my /usr/share/emacs/23.whatever/list/progmodes I found python.elc and python.el.gz . I unpacked python.el.gz and got a readable version of the elisp file. Now, however, the documentation is becoming opaque to me.

How can I add key binding to python mode, and not globally?

Is it possible, for bonus points, to apply changes in python mode without restarting emacs or closing open files? This is a self-modifying editor, I see there is a good chance that this is possible.

+7
python emacs elisp keyboard-shortcuts
source share
2 answers

It turns out that Cc Cd is already bound to python-mode (to 'python-pdbtrack-toggle-stack-tracking ), so you might want to reconsider your choice of key bindings.

Note: if you just want to cut / paste the solution, skip to the end of the answer. Read on to find out how to get there - if you want to do it again.

A macro is a good start, but what you have will not work. To get something that you can bind to a key, try Mx insert-kbd-macro for this macro, and you will get:

 (fset 'add-docstring (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("def ...unprintable characters...6\"3" 0 "%d")) arg))) 

(hm .... non-printable characters, I cannot cut / paste in SO, but you can do it yourself to get the right thing). With a little change, what you get is equivalent to this:

 (fset 'add-docstring (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item `(,(kbd "Cr def Cn Ca Cm Cp Ci Cu 6 \" Cu 3 Cb") 0 "%d") arg))) 

This is the first step. Using the above, you can do Mx add-docstring and get the desired behavior.

The next step is what you asked - how to communicate locally with keys. The documentation for keybindings starts here , and Local Keymaps is interesting for you, which leads to the following:

 (add-hook 'python-mode-hook (lambda () (define-key python-mode-map (kbd "Cc Cd") 'add-docstring))) 

This sets up an anonymous function that will be called when python-mode turned on, and this function does one thing - it sets up the key binding that you want in the key map specifically for python mode.

If you carefully read the Key Card section , you will see that Emacs follows the agreement that only users should associate combat machines with Cc a , where a is any lower or upper letter (for example, Cc d Cc T Cc p are all available) , and packets limit bindings to a specific mode to Cc% , where % is any punctuation character or (for example, Cc Cc Cc [ Cc Cz ).

So, if you change the binding to Cc d , then you will almost certainly not come across any package. python.el shipped with Emacs complies with these conventions, like most (all?) packages shipped with Emacs.

You will notice that I use kbd to read in key sequences. It is portable, and it’s much easier for me to read it.

There is something else you can do to clear this:

Here is what I would do for # 1, which would give you a convenient place to set other options:

 (add-hook 'python-mode-hook 'my-python-customizations) (defun my-python-customizations () "set up my personal customizations for python mode" ;; put other customizations in here (define-key python-mode-map (kbd "Cc Cd") 'add-docstring)) (defun add-docstring (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item `(,(kbd "Cr def Cn Ca Cm Cp Ci Cu 6 \" Cu 3 Cb") 0 "%d") arg)) 

Using a named function is a bit cleaner because you can do (remove-hook 'python-mode-hook 'my-python-customizations) if you want. In addition, if you look at the value for the hook ( Ch v python-mode-hook RET ), then it will become clear what is called (an anonymous function is longer and harder to read).

For bonus points after pasting the code in .emacs do Mx eval-region , which Emacs will indicate to evaluate the code in the region. To see the changes in existing python buffers, you just need to open a new python file / buffer that will trigger a keybinding change, which is common to all python buffers.

Happy hack.

+15
source share

First, do not confuse with python.el. What you want to do is create your own custom binding for python mode. This is usually done in your .emacs file in your home directory.

In this file, add something like the following (I have not tested this - so there might be some syntax error, and I don't use python myself)

 (add-hook 'python-mode-hook '(lambda () (define-key python-mode-map "\Cc\Cd" 'add-doc-string))) 

The hook mechanism is used. This is a function that is called every time you call python mode. This function binds Cc Cd to your add-doc-string function.

This answer is very brief. Check out the .emacs file, settings, and hooks in the emacs documentation.

+4
source share

All Articles