jyp / boon

Ergonomic Command Mode for Emacs
GNU General Public License v3.0
331 stars 35 forks source link

Add 1 set of alternative mappings #108

Open srcreigh opened 3 years ago

srcreigh commented 3 years ago

Hi, thank you so much for Boon. I have been using it for about a year. I have a great love for it.

This code adds an ACMD alternate command state, 3 alt keymaps, and a global var to toggle between the default set and the alternate set. This is my fix for wanting to switch between Qwerty and Dvorak mappings seamlessly. The changes also automatically put you in CMD / SPC / ACMD (alternate command) automatically whenever you switch to a buffer. this will clobber your INS buffers, which is actually by preference, but that's besides the point.

I don't necessarily think this is a best solution to my problem nor fit for general use, I just wanted to share some code, share the problem I was facing, and start a discussion. Maybe there is a code contribution somewhere here but that's not up to me :)

As alternatives before doing this, I tried adjusting the keymaps after boon-mode is initialized. But I had some issues. Ex in qwerty c calls boon-c-god but in Dvorak I wanted it to be previous-line. When I deleted "c" from boon-command-map and then mapped "c" in boon-moves-map, I would get "c" is undefined. I didn't look into the root cause of this :) It seemed like the alist of maps which power boon-local-mode was getting out of sync with the keymap vars, but I'm not sure why.

I also tried making it easy to restart emacs with desktop.el. This did work but it was not seamless. There is some friction to switch as I would have to change my config using the wrong keymaps, then restart emacs. I usually got mixed up too, I would restart emacs without change the config the first time and have to try again. And desktop.el I found a bit tricky to use as well.

Here is my current config which lets me call simple M-x boon-toggle-alt to switch between Qwerty and Dvorak.

(use-package boon
  :load-path "~/.emacs.d/boon/"
  :bind (:map boon-moves-map
          ("i" . next-line)
          ("o" . previous-line)
          ("k" . backward-char)
          ("l" . forward-char)
          ("u" . boon-beginning-of-line)
          ("p" . boon-end-of-line)
          ("j" . boon-smarter-backward)
          (":" . boon-smarter-forward)
          ("<" . beginning-of-buffer)
          (">" . end-of-buffer)
          ("I" . forward-paragraph)
          ("O" . backward-paragraph)
         :map boon-command-map
              ("a" . sc/duplicate-line)
              ("s" . boon-substitute-region)
              ("d" . boon-take-region)
              ("D" . boon-treasure-region)
              ("f" . boon-splice)
          ("F" . yank-pop)
              ("v" . boon-set-insert-like-state)
              ("V" . boon-open-next-line-and-insert)
              ("C-v" . boon-open-line-and-insert)
              ("x" . boon-x-map)
              ("c" . boon-c-god)
              ("m" . xref-find-definitions)
              ("M" . xref-find-references)
              ("n" . xref-pop-marker-stack)
              ("<RET>" . newline)
     :map boon-alt-moves-map
          ("c" . next-line)
          ("r" . previous-line)
          ("t" . backward-char)
          ("n" . forward-char)
          ("g" . boon-beginning-of-line)
          ("l" . boon-end-of-line)
          ("h" . boon-smarter-backward)
          ("s" . boon-smarter-forward)
          ("W" . beginning-of-buffer)
          ("V" . end-of-buffer)
          ("C" . forward-paragraph)
          ("R" . backward-paragraph)
         :map boon-alt-command-map
              ("a" . sc/duplicate-line)
              ("o" . boon-substitute-region)
              ("e" . boon-take-region)
              ("E" . boon-treasure-region)
              ("u" . boon-splice)
          ("U" . yank-pop)
              ("k" . boon-set-insert-like-state)
              ("K" . boon-open-next-line-and-insert)
              ("C-k" . boon-open-line-and-insert)
              ("q" . boon-x-map)
              ("j" . boon-c-god)
              ("m" . xref-find-definitions)
              ("M" . xref-find-references)
              ("b" . xref-pop-marker-stack)
              ("<RET>" . newline)
     :map boon-insert-map
              ([remap newline] . nil)
     :map boon-select-map
          ("s" . boon-select-wim)
          ("b" . boon-select-blanks)
     :map boon-alt-select-map
          ("o" . boon-select-wim)
          ("x" . boon-select-blanks))
  :init
  (boon-mode)
  (boon-toggle-alt))
jyp commented 3 years ago

I am not sure what you're trying to achieve. You should be able to manipulate boon keymaps as any other keymap in elisp code to switch between configurations. The only pitfall I can think of is that certain keymaps inherit from others: don't change the keybinding in a derived map, but in the parent directly.