-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Statistically ergonomic keybinds for all keyboard layouts #506
Comments
fixes #23 |
@udayvir-singh Hey, it looks cool. I saw there are lot reasonable points, I also like your idea about protecting the pinky finger, by leaving them for some other usages or putting a non-repeatable commands. The overall feeling of the command looks great. I just found some tricky combinations when I went through it. For example, |
|
The keyboard layout also takes into account normal english word usage, that was insert mode is |
The layout tries to minimize bad combinations, which there are very few. The first iterations tried to maximize good combinations but that ended up being way worse, here is a example:
I choose the later, as over a long coding session those bad combinations add up and start hurting your fingers really bad. |
I prefer a smother experience over a fast and jerky one:
fast meh meh fast meh meh ...
fast fast bad fast bad fast ... All those |
This is a good point I've never thought about. And there are some DWIM style commands I won't go with.
|
@DogLooksGood You could just use the global keybinds in those edge cases, like |
I just fixed it, so it doesn't pollute the history: (defun meow-word ()
"Expand word/symbol under cursor."
(interactive)
(if (and (use-region-p)
(equal (car (region-bounds))
(bounds-of-thing-at-point 'word)))
(progn
(when (string-match-p
(or (car regexp-search-ring) "")
(buffer-substring (region-beginning) (region-end)))
(pop regexp-search-ring))
(meow-mark-symbol 1))
(progn
(when (and (mark)
(equal (car (region-bounds))
(bounds-of-thing-at-point 'symbol)))
(meow-pop-selection))
(meow-mark-word 1)))) It can still just optionally included with the default suggestion being |
I can understand reverse/negative-argument dwim. It was just a experimental command. Just replace it will normal |
However, you can't replace |
To summarize:
The goal of the keyboard layout was to be good 90% of the time and be consistent in quality, after 8 iterations this is the final layout I came up with which fully exploits the weakness of a traditional stagger layout, Thus was never meant to be perfect in ideological sense but was made with real world data in mind. |
In this case
How you delete the |
@DogLooksGood |
Now that I think about it, You could also swap |
Here is the final layout that I suggest: ;; -------------------- ;;
;; UTILS ;;
;; -------------------- ;;
(defun meow-change-line ()
"Kill till end of line and switch to INSERT state."
(interactive)
(let ((beg (point)))
(end-of-line)
(delete-region beg (point))
(meow-insert-mode)))
(defun meow-save-clipboard ()
"Copy in clipboard."
(interactive)
(let ((meow-use-clipboard t))
(meow-save)))
(defun meow-kmacro ()
"Toggle recording of kmacro."
(interactive)
(if defining-kbd-macro
(meow-end-kmacro)
(meow-start-kmacro)))
;; -------------------- ;;
;; VARIABLES ;;
;; -------------------- ;;
(meow-thing-register 'angle
'(pair ("<") (">"))
'(pair ("<") (">")))
(setq meow-char-thing-table
'((?f . round)
(?d . square)
(?s . curly)
(?a . angle)
(?r . string)
(?v . paragraph)
(?c . line)
(?x . buffer)))
;; -------------------- ;;
;; MAPPINGS ;;
;; -------------------- ;;
(meow-define-keys 'normal
; expansion
'("0" . meow-expand-0)
'("1" . meow-expand-1)
'("2" . meow-expand-2)
'("3" . meow-expand-3)
'("4" . meow-expand-4)
'("5" . meow-expand-5)
'("6" . meow-expand-6)
'("7" . meow-expand-7)
'("8" . meow-expand-8)
'("9" . meow-expand-9)
; movement
'("i" . meow-prev)
'("k" . meow-next)
'("j" . meow-left)
'("l" . meow-right)
'("y" . meow-search)
'("/" . meow-visit)
; expansion
'("I" . meow-prev-expand)
'("K" . meow-next-expand)
'("J" . meow-left-expand)
'("L" . meow-right-expand)
'("u" . meow-back-word)
'("U" . meow-back-symbol)
'("o" . meow-next-word)
'("O" . meow-next-symbol)
'("a" . meow-mark-word)
'("A" . meow-mark-symbol)
'("s" . meow-line)
'("w" . meow-block)
'("q" . meow-join)
'("g" . meow-grab)
'("G" . meow-pop-grab)
'("p" . meow-cancel-selection)
'("P" . meow-pop-selection)
'("t" . meow-till)
'("T" . meow-find)
'("," . meow-beginning-of-thing)
'("." . meow-end-of-thing)
'("<" . meow-inner-of-thing)
'(">" . meow-bounds-of-thing)
'("[" . indent-rigidly-left-to-tab-stop)
'("]" . indent-rigidly-right-to-tab-stop)
; editing
'("b" . open-line)
'("B" . split-line)
'("d" . meow-kill)
'("f" . meow-change)
'("F" . meow-change-line)
'("x" . meow-delete)
'("c" . meow-save)
'("C" . meow-save-clipboard)
'("v" . meow-yank-dwim)
'("V" . meow-yank-pop-dwim)
'("e" . meow-insert)
'("E" . meow-open-above)
'("r" . meow-append)
'("R" . meow-open-below)
'("z" . query-replace-regexp)
'("h" . undo-only)
'("H" . undo-redo)
'("m" . meow-kmacro)
'("M" . kmacro-call-macro)
; prefix n
'("nm" . kmacro-edit-macro)
'("nf" . meow-comment)
; prefix ;
'(";f" . save-buffer)
'(";F" . save-some-buffers)
; ignore escape
'("<escape>" . ignore)) |
I think we should add I think we don't really have a way to define the key for arbitrary keyboard layout with one command. So I will add it as an option in README for an ergonomic layout for QWERTY. |
@DogLooksGood What do you think about adding |
@DogLooksGood After some more modifications, I found a extra improvement by replacing ;; -------------------- ;;
;; UTILS ;;
;; -------------------- ;;
(defun meow-change-line ()
"Kill till end of line and switch to INSERT state."
(interactive)
(let ((beg (point)))
(end-of-line)
(delete-region beg (point))
(meow-insert-mode)))
(defun meow-kmacro ()
"Toggle recording of kmacro."
(interactive)
(if defining-kbd-macro
(meow-end-kmacro)
(meow-start-kmacro)))
;; -------------------- ;;
;; VARIABLES ;;
;; -------------------- ;;
(meow-thing-register 'angle
'(pair ("<") (">"))
'(pair ("<") (">")))
(setq meow-char-thing-table
'((?f . round)
(?d . square)
(?s . curly)
(?a . angle)
(?r . string)
(?v . paragraph)
(?c . line)
(?x . buffer)))
;; -------------------- ;;
;; MAPPINGS ;;
;; -------------------- ;;
(meow-define-keys 'normal
; expansion
'("0" . meow-expand-0)
'("1" . meow-expand-1)
'("2" . meow-expand-2)
'("3" . meow-expand-3)
'("4" . meow-expand-4)
'("5" . meow-expand-5)
'("6" . meow-expand-6)
'("7" . meow-expand-7)
'("8" . meow-expand-8)
'("9" . meow-expand-9)
'("'" . meow-reverse)
; movement
'("i" . meow-prev)
'("k" . meow-next)
'("j" . meow-left)
'("l" . meow-right)
'("y" . meow-search)
'("/" . meow-visit)
; expansion
'("I" . meow-prev-expand)
'("K" . meow-next-expand)
'("J" . meow-left-expand)
'("L" . meow-right-expand)
'("u" . meow-back-word)
'("U" . meow-back-symbol)
'("o" . meow-next-word)
'("O" . meow-next-symbol)
'("a" . meow-mark-word)
'("A" . meow-mark-symbol)
'("s" . meow-line)
'("S" . meow-goto-line)
'("w" . meow-block)
'("q" . meow-join)
'("g" . meow-grab)
'("G" . meow-pop-grab)
'("p" . meow-cancel-selection)
'("P" . meow-pop-selection)
'("x" . meow-till)
'("z" . meow-find)
'("," . meow-beginning-of-thing)
'("." . meow-end-of-thing)
'("<" . meow-inner-of-thing)
'(">" . meow-bounds-of-thing)
'("[" . indent-rigidly-left-to-tab-stop)
'("]" . indent-rigidly-right-to-tab-stop)
; editing
'("b" . open-line)
'("B" . split-line)
'("d" . meow-kill)
'("f" . meow-change)
'("F" . meow-change-line)
'("t" . meow-delete)
'("c" . meow-save)
'("v" . meow-yank)
'("V" . meow-yank-pop)
'("e" . meow-insert)
'("E" . meow-open-above)
'("r" . meow-append)
'("R" . meow-open-below)
'("h" . undo-only)
'("H" . undo-redo)
'("m" . meow-kmacro)
'("M" . kmacro-call-macro)
; prefix n
'("nm" . kmacro-edit-macro)
'("nf" . meow-comment)
'("nd" . meow-swap-grab)
'("ns" . meow-sync-grab)
;; .. etc
; prefix ;
'(";f" . save-buffer)
'(";F" . save-some-buffers)
'(";d" . meow-query-replace-regexp)
;; .. etc
; ignore escape
'("<escape>" . ignore)) |
Hey, @udayvir-singh sorry for the late reply. I'm considering some minor modifications when merging into the doc. I personally don't think As for How do you think? |
@DogLooksGood No problem, the layout is meant as a guideline anyways for people to create there own layout that fits there editing style, I just wanted to add better starting keybinds for beginners. |
Also I wanted to ask, what do you think about moving all the
Or without capitalization:
|
@DogLooksGood Here is the final final revision of the layout with no extra bells-and-whistles: ;; -------------------- ;;
;; THING TABLE ;;
;; -------------------- ;;
(meow-thing-register 'angle
'(pair ("<") (">"))
'(pair ("<") (">")))
(setq meow-char-thing-table
'((?f . round)
(?d . square)
(?s . curly)
(?a . angle)
(?r . string)
(?v . paragraph)
(?c . line)
(?x . buffer)))
;; -------------------- ;;
;; MAPPINGS ;;
;; -------------------- ;;
(meow-define-keys 'normal
; expansion
'("0" . meow-expand-0)
'("1" . meow-expand-1)
'("2" . meow-expand-2)
'("3" . meow-expand-3)
'("4" . meow-expand-4)
'("5" . meow-expand-5)
'("6" . meow-expand-6)
'("7" . meow-expand-7)
'("8" . meow-expand-8)
'("9" . meow-expand-9)
'("'" . meow-reverse)
; movement
'("i" . meow-prev)
'("k" . meow-next)
'("j" . meow-left)
'("l" . meow-right)
'("y" . meow-search)
'("/" . meow-visit)
; expansion
'("I" . meow-prev-expand)
'("K" . meow-next-expand)
'("J" . meow-left-expand)
'("L" . meow-right-expand)
'("u" . meow-back-word)
'("U" . meow-back-symbol)
'("o" . meow-next-word)
'("O" . meow-next-symbol)
'("a" . meow-mark-word)
'("A" . meow-mark-symbol)
'("s" . meow-line)
'("S" . meow-goto-line)
'("w" . meow-block)
'("q" . meow-join)
'("g" . meow-grab)
'("G" . meow-pop-grab)
'("m" . meow-swap-grab)
'("M" . meow-sync-grab)
'("p" . meow-cancel-selection)
'("P" . meow-pop-selection)
'("x" . meow-till)
'("z" . meow-find)
'("," . meow-beginning-of-thing)
'("." . meow-end-of-thing)
'("<" . meow-inner-of-thing)
'(">" . meow-bounds-of-thing)
; editing
'("d" . meow-kill)
'("f" . meow-change)
'("t" . meow-delete)
'("c" . meow-save)
'("v" . meow-yank)
'("V" . meow-yank-pop)
'("e" . meow-insert)
'("E" . meow-open-above)
'("r" . meow-append)
'("R" . meow-open-below)
'("h" . undo-only)
'("H" . undo-redo)
'("b" . open-line)
'("B" . split-line)
'("[" . indent-rigidly-left-to-tab-stop)
'("]" . indent-rigidly-right-to-tab-stop)
; prefix n
'("nf" . meow-comment)
'("nt" . meow-start-kmacro-or-insert-counter)
'("nr" . meow-start-kmacro)
'("ne" . meow-end-or-call-kmacro)
;; ...etc
; prefix ;
'(";f" . save-buffer)
'(";F" . save-some-buffers)
'(";d" . meow-query-replace-regexp)
;; ... etc
; ignore escape
'("<escape>" . ignore)) |
After 6 months of research, testing and multiple revisions, here is the most ergonomic layout I could create for meow:
Some notable features:
The layout is keyboard layout agnostic, although it may seem like it was created for qwerty layout due to
c
andv
being copy and paste, the position ofc
andv
was determined by command statistics and not due to mnemonics.Uses
ijkl
instead ofhjkl
as it offers three benefits:;
, which allows you to set;
as a prefix key.u
ando
above for word-wise movement and selection, instead of the awkward vim styleb
,w
.The layout is designed to maximize alternation and rolling, which increases the amount of actions/minute.
[uo][df]
: delete/change forward/backward word[uo][er]
: enter insert mode before/after forward/backward wordqp
: start of linesp
: end of linewp
: start of blockay
: search wordx<space>
: select space delimited word;f
: save buffer [one of the most used commands]a[er]
: enter insert mode before/after worda[df]
: delete/change words[er]
: enter insert mode before/after lines[df]
: delete/change lineqr
: enter insert mode at start of lineqd
: join linew[er]
: enter insert mode before after blockw[df]
: delete/change blockMost used commands are placed in the order of home row -> top row -> bottom row.
Has 2 extra prefix keys
n
and;
, that only contain commands that can be used in a editable buffer.n
prefix is for editing commands liketranspose-chars
,sp-forward-barf-sexp
,meow-comment
, etc.;
prefix is for non-editing/general-use commands likesave-buffer
,eglot-format
, etc.save-buffer
ortranspose-chars
in a non-editable buffer, hence, they end up as dead keys in other modes with leader map, wasting valuable keyboard space.Adds many additions commands:
meow-word
: a single command that combinesmeow-expand-word
andmeow-expand-symbol
. it works as follows [|
is the cursor]:|hello-word
and pressa
, it expands tohello
, if you pressa
again it expands tohello-world
.aa
instead of having a separate keybind and doing<shift>a
.meow-kill-line
: kills till end of line respectingmeow-use-clipboard
variable.meow-change-line
: kills till end of line and switches to INSERT state.meow-save-clipboard
: explicitly save to clipboard.meow-yank-dwim
andmeow-yank-pop-dwim
: adds vim-like behavior for yanking lines.meow-smart-reverse
: Reverses selection or begins negative argument.meow-kmacro
: Combines meow-kmacro-start and meow-kmacro end, behaves like vim'sq
.meow-eldoc
: Just a simple function that toggles eldoc buffer.Source code
This source code here is different from my actual dotfiles, as it uses some other plugins like expand-region, undo-tree, smartparens. Here are my actual config files which contain much more keybinds:
init-meow.el
init-mappings.el
Further improvements:
meow-block
can be replaced wither/expand-region
for more selection range. Here is config for expand-region that I use:The text was updated successfully, but these errors were encountered: