Why can't I change paredit keybindings

I am trying to use only a few functions from paredit without loading all the key bindings. Looking at paredit.el, the only map I found was paredit-mode-map, so I tried this.

(setq paredit-mode-map (make-sparse-keymap)) (define-key paredit-mode-map (kbd "<CM-left>") 'paredit-backward) 

It did not change the key binding (as noted with Ch k), but the paredit-mode-map variable was changed.

I also tried

 (eval-after-load "paredit" '(progn (setq paredit-mode-map (make-sparse-keymap)) (define-key paredit-mode-map (kbd "<CM-left>") 'paredit-backward))) 

and then turn paredit on and off with the same result.

Before, making changes to the key card directly always worked for me. What's going on here?

Edit:

I managed to change the keyboard layout by doing the following:

 ; Remove old paredit bindings (defun take-from-list (condp list) "Returns elements in list satisfying condp" (delq nil (mapcar (lambda (x) (and (funcall condp x) x)) list))) (setq minor-mode-map-alist (take-from-list (lambda (x) (not (eq (car x) 'paredit-mode))) minor-mode-map-alist)) ; Create new paredit-mode-map (setq paredit-mode-map (make-sparse-keymap)) (define-key paredit-mode-map (kbd "<C-kp-enter>") 'paredit-backward) ; Add the new paredit-mode-map to minor-mode-map-alist (setq minor-mode-map-alist (append (list (append (list 'paredit-mode) paredit-mode-map)) minor-mode-map-alist)) 

So it looks like minor-mode-map-alist is the variable used for the search. I'm sure there are more elegant ways to change key bindings, but I wanted to understand how keys work in emacs.

+6
source share
3 answers

Paredit uses a different key card identification method. While most minor modes define a key card in a variable definition, Paredit calls paredit-define-keys at the top level and thus forces the layout to be initialized.

In other words, you cannot prevent Paredit from setting bindings. You need to remove all the key bindings in the keyboard layout using (define-key paredit-mode-map … nil) to get rid of them.

Edit: You cannot use "reset" by assigning a new layout to this variable. (setq paredit-mode-map …) will change the paredit-mode-map variable, it will not change the actual layout used in Paredit mode.

The binding of this variable is evaluated only once during the definition , that is, during the evaluation of define-minor-mode . This macro internally calls add-minor-mode and passes the current value to this function. keyboard variable. All future use of the mode applies only to this layout. The keymap variable is never evaluated by minor mode again , so changing the binding has no effect.

If you want to change the keyboard layout, you need to re-bind the variable to define-minor-mode , that is, before loading the corresponding library. Changing it in the form of eval-after-load is therefore completely useless.

Normally changing the keymap variable before loading the library works well, because most modes define a keyboard map in the body of defvar . defvar however will not change the value of a variable if it already has a value. Thus, if a variable already has a key card, it will not be affected.

However, as I said, Paredit does not respect this template and instead forcibly adds bindings to the layout. So changing it is pointless because Paredit will add its bindings anyway.

As I said, you need to manually clear the existing layout without defining each of its keys.

TL DR: Use Smartparens, really! It covers all of Paredit, it is flexible, it is powerful, it is extensible, in short, it is just good. And it allows you to choose any key combinations you want.

+4
source

Read the answer of lunaryorn first. This is just an explanation.

what exactly is broken with your code

 (setq paredit-mode-map (make-sparse-keymap)) 

This will not work with any mode already loaded. paredit not special.

Paredit disrespect for defvar means that it is very difficult to untie all keys as you wish.

+3
source

Why don't you just create your own minor mode? All Paredit Mode does is provide key bindings, so if you clobber its keymap, it does nothing for you. Paredit commands are available whether you use Paredit mode or not. (No one is imposing key bindings on you!)

 (defvar snowape-mode-map (make-sparse-keymap)) (define-minor-mode snowape-mode "Minor mode for snowape favorite pareditoid key bindings. \\<snowape-mode-map>" :lighter " Snowape") (define-key snowape-mode-map (kbd "CM-<left>") 'paredit-backward) ... 

Alternatively, you can simply use local-set-key in your favorite modes:

 (add-hook 'lisp-mode-hook (defun lisp-mode-snowape-setup () (local-set-key (kbd "CM-<left>") 'paredit-backward))) 
+3
source

Source: https://habr.com/ru/post/945249/


All Articles