reddit / emacs

How to actually define key binds in Emacs?

JeykeyLP · 2022-08-08 19:06
I'm struggling a bit with the key binds system in Emacs. I'm aware, that my setup is probably pretty unique, but I hope someone might have at least some answers for me: Because I'm not using a standard QWERTY layout but instead a Dvorak layout, I have to rebind most of the normal binds. I'm doing this with evil-mode and a custom minor mode, through which I declare all navigation keys. This `evil-dvorak-mode` is turned on globally. The basic motion keys for me look like this: (evil-define-key 'visual evil-dvorak-mode-map "h" 'evil-next-line "t" 'evil-previous-line "d" 'evil-backward-char "n" 'evil-forward-char ) I'm also redefining most commands through a system of leader keys with the package `evil-leader`, which is also turned on globally. For example: (evil-leader/set-leader "SPC") (evil-leader/set-key "bs" 'save-buffer "bb" 'consult-buffer ) Both of these systems work under normal conditions reliably, but they tend to break under any special circumstances, and I have no idea how to guarantee all key binds are working as intended. Some of the issues I have encountered: \- Certain buffers can override the navigation keys, especially the org-mode \*Agenda\* buffer. Even if I specifically bind `org-agenda-next-line` for the `org-agenda-mode-map` nothing seems to happen. \- For certain mini-buffers and selections, I want to define `C-h` and `C-t` for motion. I'm doing this by simply calling `define-key` for the specific map. This approach has worked for both `Selectrum` and `Company`, but when I was trying out `Corfu` today, pressing the keys simply triggered their normal Emacs behavior. \- In the standard \*Messages\* buffer the navigation keys are working without problems, but the leader keys aren't available, the same happens in the org-mode Agenda. Currently, the space bar is my main leader key, and it appears in these modes that key gets overwritten somehow. If anybody has a setup even remotely similar to mine, some input would be appreciated. I would especially like to know how I can define key bindings without having them overwritten by some other mode or package. For more context, my entire key binds setup can be found [here](https://github.com/jakobklemm/dots/blob/master/emacs/.emacs.d/modules/input.el). Any help would be appreciated, thanks.
MitchellMarquez42 · 2022-08-08 19:21
You might benefit from doing everything through [General](https://github.com/noctuid/general.el)
TrepidTurtle · 2022-08-08 19:30
+1 to this. Here’s my configuration, might help you. Go to the keyboard section. https://github.com/jakebox/jake-emacs
codefake · 2022-08-08 19:32
Absolutely this. I depend on general in my config as I rely heavily on leader key configuration, which I love. General makes all this a breeze. Highly recommended for your binding needs.
tom_dl · 2022-08-08 20:11
I'd recommend reading [noctuid's evil guide](https://github.com/noctuid/evil-guide), particularly the link to the [spacemacs keymap guide](https://github.com/syl20bnr/spacemacs/wiki/Keymaps-guide) and the mention of the commentary on `evil-core.el`
thetemp_ · 2022-08-08 21:34
As another Dvorak user who tried customizing `evil-mode` some time ago, my advice would be to either move away from using Evil (as I eventually did) or just get used to using Evil's default keybindings as they are in the Dvorak layout. Dvorak actually isn't bad at all with Vim bindings. The "j" and "k" keys are still next to each other and reasonably easy to reach. "b" and "w" are also close to each other. The only real negative is the "l" key being up in the corner. But if you can get in the habit of using "t" for character navigation, that's faster anyway. If I recall correctly, the `evil-collection` package has a way for you to automatically rearrange keys for different major modes. And there is a similar feature in the `general` package. Unfortunately, I was never able to fully grasp how those worked and just got more and more frustrated over time with unfortunate surprises that popped up whenever I installed a new package. The nice thing about default keybindings (and keybinding conventions) is that every mode already has consistent bindings, so you don't have to redefine them to match your way of doing things. This is true of Emacs bindings, but it's also true for the most part in `evil-mode` if you use packages like `evil-collection` and `evil-org`.
todo-anonymize-self · 2022-08-09 05:13
Get `helpful` (and possibly `which-key`?). This will show you what all a command is bound to in the help for it. Then take away all your keybinds and restart Emacs. Then `C-h k <key-sequence> RET` or `C-h f <function-name> RET` to open the help buffer about the command and you'll see a section about what all keys in what all keymaps the command is bound to. I had to bind movement keys to `visual`, `normal`, and `movement` Evil states to get a fully-working-(almost)-everywhere rebind. The other thing is try `general`, like u/MitchellMarquez42 said. Don't know how to do it in `evil` but `general` gives you an `override` keymap that will ensure your binds win over everyone else's. Third thing third, sometimes I've had to unbind commands before I could get an `evil` leader key working, but that was before I discovered `general` so the `override` thing may or may not make this moot. Oh, and stick this in your `use-package` for `general`: ;; We want SPC as a leader key, probably. So do this. It just affects what ;; keybinds are overridden by the `override' keymap functionality that ;; `general' provides. ;; ;; https://github.com/emacs-evil/evil-collection#making-spc-work-similarly-to-spacemacs ;; ;; NOTE: `evil-collection' binds over SPC in many packages. To use SPC as a ;; leader key with `general', first set these override states: (setq general-override-states '(insert emacs hybrid normal visual motion operator replace)) And at this point you should be able to do something like this for movement: (general-define-key :states '(motion visual normal) :keymaps 'override ;; ──┬──────────────── ;; │ ↑ ↓ ← → ;; ──┴──────────────── "." #'evil-previous-line "e" #'evil-next-line "o" #'evil-backward-char "u" #'evil-forward-char)