Problem
Sheets has vim-style modal editing but no way to customize key bindings. Vim users expect to carry over muscle memory from their .vimrc — for example, many people remap <C-c><C-c> to quit, or remap navigation keys for their keyboard layout.
This is especially relevant now that #22 proposes removing Ctrl-C as a quit key. Without a config file, there's no way for users to bind their own quit sequence.
Proposal: ~/.sheetsrc
A minimal RC file that supports key mapping, using familiar vim syntax.
Format
" Comments start with " or #
# This is also a comment
" Map a key sequence in normal mode
nmap <C-c><C-c> :q
" Map in insert mode
imap <C-c> <Esc>
" Map in select mode
smap <C-c> <Esc>
" Map in all modes
map <C-c> <Esc>
Supported mapping commands
| Command |
Scope |
nmap / nnoremap |
Normal mode |
imap / inoremap |
Insert mode |
smap |
Select mode |
map / noremap |
All modes |
Key notation
Uses vim-style <...> notation:
| Notation |
Key |
<C-x> |
Ctrl+x |
<Esc> |
Escape |
<CR> / <Enter> |
Enter |
<Tab> |
Tab |
<Space> |
Space |
<BS> |
Backspace |
a, q, etc. |
Literal characters |
Multiple keys can be chained: <C-c><C-c> is a two-key sequence.
Supported actions
| Action |
Effect |
:q |
Quit |
:w |
Write/save |
:wq |
Write and quit |
<Esc> |
Exit current mode → normal |
<Nop> |
Do nothing (disable a key) |
Multi-key sequence handling
When the user presses a key that is a prefix of a mapped sequence:
- Buffer the key and wait for the next keypress
- If the next key completes a mapping → execute the action
- If the next key doesn't match any mapping → flush the buffer and process both keys normally
- If no key comes within 1 second → flush the buffer (process the key normally)
This matches vim's timeoutlen behavior.
Scope / non-goals
This proposal intentionally keeps the scope small:
- No
set commands (e.g., set cellwidth=20) — that can come later
- No recursive mapping —
nmap and nnoremap behave identically for now
- No
<leader> key — users can just spell out their sequences
- No runtime
:map command — config is read once at startup
Implementation sketch
- New file
config.go: RC file parser, key notation normalizer, sequence matcher
types.go: Add config, pendingSeq, pendingSeqMsgs fields to model
model.go: Check bindings before normal key dispatch in Update(); extract key dispatch into processKeyMsg() so buffered keys can be replayed on flush
I have a working implementation of this and am happy to open a PR if the design looks good. Feedback on the format, scope, or naming is welcome.
Problem
Sheets has vim-style modal editing but no way to customize key bindings. Vim users expect to carry over muscle memory from their
.vimrc— for example, many people remap<C-c><C-c>to quit, or remap navigation keys for their keyboard layout.This is especially relevant now that #22 proposes removing Ctrl-C as a quit key. Without a config file, there's no way for users to bind their own quit sequence.
Proposal:
~/.sheetsrcA minimal RC file that supports key mapping, using familiar vim syntax.
Format
Supported mapping commands
nmap/nnoremapimap/inoremapsmapmap/noremapKey notation
Uses vim-style
<...>notation:<C-x><Esc><CR>/<Enter><Tab><Space><BS>a,q, etc.Multiple keys can be chained:
<C-c><C-c>is a two-key sequence.Supported actions
:q:w:wq<Esc><Nop>Multi-key sequence handling
When the user presses a key that is a prefix of a mapped sequence:
This matches vim's
timeoutlenbehavior.Scope / non-goals
This proposal intentionally keeps the scope small:
setcommands (e.g.,set cellwidth=20) — that can come laternmapandnnoremapbehave identically for now<leader>key — users can just spell out their sequences:mapcommand — config is read once at startupImplementation sketch
config.go: RC file parser, key notation normalizer, sequence matchertypes.go: Addconfig,pendingSeq,pendingSeqMsgsfields to modelmodel.go: Check bindings before normal key dispatch inUpdate(); extract key dispatch intoprocessKeyMsg()so buffered keys can be replayed on flushI have a working implementation of this and am happy to open a PR if the design looks good. Feedback on the format, scope, or naming is welcome.