a ridiculously fun alternative neovim keymap for the workman keyboard layout
yneo
With unruly_kopy
and unruly_macro
when you select a register, it stays selected until you change it.
This means you don't select a register for a specific motion, instead you set
the yank or macro register, and then all future yank/paste or record/play
actions will use the selected register until you select a new register.
-- Use this setup config if you want to follow the keymap above
local unruly_worker = require('unruly-worker')
-- to setup with the defaults you can simply put
-- unruly_worker.setup()
-- example setup with the default settings
unruly_worker.setup({
-- you can use the skip_list = {} to stop unruly from creating certain mappings
-- skip_list = { "z", "Z", "<C-z>"}, skip z related mappings
skip_list = {},
unruly_options = {
-- set default unruly kopy register must be [a-z] [A-Z] 0 +
kopy_reg = "+",
-- set default unruly macro register must be [a-z] [A-Z]
macro_reg = "q",
-- set default unruly seek mode, must be unruly_worker.seek_mode.(buffer|loclist|quickfix)
seek_mode = unruly_worker.seek_mode.buffer,
-- set unruly mark mode to global or local
mark_mode_is_global = false
},
-- boosters allow you to op-in to extra keymaps
-- or opt-out of the default keymaps if you want that for some reason
booster = {
default = true,
-- easy stuff are just additional opt in keymaps
easy_swap = false,
easy_search = false,
easy_line = false,
easy_spellcheck = false,
easy_incrament = false,
easy_hlsearch = false,
easy_focus = false,
easy_window = false,
easy_jumplist = false,
easy_scroll = false,
easy_source = false,
easy_lsp = false,
easy_lsp_leader = false,
easy_diagnostic = false,
easy_diagnostic_leader = false,
-- unruly stuff change neovim's normal behavior
unruly_seek = false,
unruly_mark = false,
unruly_macro = false,
unruly_kopy = false,
unruly_quit = false,
-- plugin stuff have external dependencies
plugin_navigator = false,
plugin_comment = false,
plugin_luasnip = false,
plugin_textobject = false,
plugin_telescope_leader = false,
plugin_telescope_lsp_leader = false,
plugin_telescope_easy_jump = false,
plugin_telescope_easy_paste = false,
plugin_telescope_diagnostic_leader = false,
},
})
-- NOTE: its recommended that you require cmp before unruly_worker.external.nvim-cmp
local cmp = require("cmp")
local unruly_cmp = require('unruly-worker.external.nvim-cmp')
cmp.setup({
mapping = unruly_cmp.create_insert_mapping(),
-- optionally you can pass a config with a skip_list and mappings
-- mapping = unruly_cmp.create_insert_mapping({
-- skip_list = { "<Right>" }, -- opt out of the <Right> keymap
-- you can add your own mappings here
-- your mappings will allways overwrite the unruly_cmp default mappings
-- mapping = {
-- ["<C-u>"] = cmp.mapping.complete() -- use <c-u> to complete
-- },
-- }),
-- rest of config...
})
cmp.setup.cmdline({ "/", "?" }, {
-- you can also pass the optional config into create_cmdline_mapping
mapping = unruly_cmp.create_cmdline_mapping(),
-- rest of config...
})
cmp.setup.cmdline(":", {
mapping = unruly_cmp.create_cmdline_mapping(),
-- rest of config...
})
-- my personal nvim-cmp config file: https://github.com/slugbyte/config/blob/main/conf/config/nvim/lua/slugbyte/plugin/cmp-and-luasnip.lua
nvim-cmp
insert mode<CR>
- confirm select<C-g> or <Right>
- confirm continue<Tab> or <Down>
- next suggestion<S-Tab> or <Up>
- prev suggestion<C-x>
- abortnvim-cmp
cmdline mode<C-g> or <Right>
- confirm continue<Tab>
- next suggestion<S-Tab>
- prev suggestion<Up>
- prev history<Down>
- next history<CR>
- execute<C-x>
- abort-- NOTE: its recommended that you require telescope before unruly_worker.external.telescope
local telescope = require("telescope")
local telescope_action = require("telescope.action")
local unruly_telescope = require("unruly-worker.external.telescope")
telescope.setup({
defaults = {
mappings = unruly_telescope.create_mappings(),
-- -- optionally you can pass a config with skip_list, insert_mapping, and normal_mapping
-- mappings = unruly_telescope.create_mappings({
-- skip_list = {"<Tab>"}, -- disable <tab> map
-- -- insert_mapping will overwrite any default unruly_telescope insert mappings
-- insert_mapping = {
-- "<c-u>" = telescope_action.select_default(), -- <c-u> select default
-- },
-- -- normal_mapping will overwrite any default unruly_telescope normal mappings
-- normal_mapping = {
-- "<c-u>" = telescope_action.select_default(), -- <c-u> select default
-- },
-- }),
},
-- rest of config...
})
-- my personal telescope setup: https://github.com/slugbyte/config/blob/main/conf/config/nvim/lua/slugbyte/plugin/telescope.lua
telescope.nvim
insert mode<CR>
- select default<C-h>
- select into horizontal split<C-s>
- select into vertical split<Down> or <C-n>
- move selection down<Up> or <C-e>
- move selection up<C-k>
- telescope which key<C-x>
- abort<PageUp>
- scroll preview up<PageDown>
- scroll preview down<Tab>
- toggle selection<C-a>
- select all<C-d>
- deselect all<C-q>
- add selected to quickfix list<C-l>
- add selected to loclist listtelescope.nvim
normal mode (optional)includes everything in insert mode ^
e
- move selection upn
- move selection downN
- move to top of selection listE
- move to bottom of selection list<Esc>
- abortlocal unruly_textobjects = require("unruly-worker.external.textobjects")
require("nvim-treesitter.configs").setup({
textobjects = {
select = {
keymaps = unruly_textobjects.select_keymaps,
-- rest of config...
},
move = {
goto_next_start = unruly_textobjects.move_goto_next_start,
goto_previous_start = unruly_textobjects.move_goto_previous_start,
goto_next_end = unruly_textobjects.move_goto_next_end,
goto_previous_end = unruly_textobjects.move_goto_previous_end,
-- rest of config...
},
},
})
go{object}
goto next outer objectgi{object}
goto next inner objectge{object}
goto prev end objectGo{object}
goto prev outer objectGi{object}
goto prev inner objectGe{object}
goto prev end objectvo{object}
visual outer objectvi{object}
visual inner objectdo{object}
delete outer objectdi{object}
delete inner object{object}
a
assigmentb
blockc
calld
comment (doc)f
functioni
conditional (if)l
loopp
parameterr
returns
struct or classThis project includes a tmux config file with tmux unruly-worker style keybindings, See the unruly tmux README for installation instructions and overview.
yneo
_______ are mapped to left, down, up, rightgn
_________ visual downge
_________ visual upY
__________ goes to beginning of lineO
__________ goes to end of linew
__________ next wordW
__________ prev wordb
__________ jump to matching braceB
__________ jump cursor to the last place a change was made (back change)gg
_________ goto top of fileGG
_________ goto end of filet{char}
____ go to the [count]'th occurrence of char to the rightT{char}
____ go to the [count]'th occurrence of char to the lefth
__________ repeat the last t/T (hop)H
__________ repeat the last t/T reverse (hop reverse)(
__________ prev sentence)
__________ next sentence{
__________ prev paragraph}
__________ next paragraphi
__________ InsertI
__________ Insert at beginning of linea
__________ Appenda
__________ Append to end of liner
__________ replaceR
__________ replace model
__________ insert Line belowL
__________ insert Line abovek
__________ kopy (yank)K
__________ kopy line (yank line)p
__________ pasteP
__________ paste lined
__________ deleteD
__________ delete to end of linedd
_________ delete linesx
__________ delete under cursorX
__________ delete before cursorc
__________ changeC
__________ change to end of linecc
_________ change lines
__________ substituteS
__________ substitute lineq{reg}
_____ record a macroQ{reg}
_____ play a macrom{mark}
____ goto a markM{mark}
____ set a mark[
__________ goto previous jumplist location]
__________ goto next jumplist locationv
__________ visual modeV
__________ visual line mode<c-v>
______ visual block modeE
__________ select paragraph (envelope paragraph vip
)/
__________ search down?
__________ search upf
__________ repeat search (find)F
__________ repeat search reverse (find reverse):
or '
___ command mode~
__________ toggle case"
__________ select register!
__________ repeat change (repeat a vim motion)
&
__________ repeat substitute (repeat a :s/thing/new)
u
__________ undoU
__________ redo<<
_________ shift indent left>>
_________ shift indent rightg
__________ g commandG
__________ G commandz
__________ z commandZ
__________ Z command<c-a>
____ goto beginning of line<c-e>
____ goto end of line<c-u>
____ delete to beginning of line@
__________ align top$
__________ align middle#
__________ align bottom<ctrl>wy
___ focus left<ctrl>wn
___ focus down<ctrl>we
___ focus up<ctrl>wo
___ focus right<ctrl>wx
___ close<ctrl>wf
___ fullscreen current split<ctrl>wh
___ horizontal split<ctrl>ws
___ vertical split<ctrl>ws
___ vertical splitj
J
%
^
=
*
-
_
+
,
.
|
;
easy boosters don't dramatically alter anything, they are just additional keymaps that I didn't include in the basic setup, in order to keep it as vanilla as possible.
<C-Up>
___________ swap line/lines up<C-Down>
_________ swap line/lines down<c-y>
____________ focus left (vim)<c-n>
____________ focus down (vim)<c-e>
____________ focus up (vim)<c-o>
____________ focus right (vim)<c-x>
____________ close vim split<c-f>
____________ fullscreen current split<c-s>
____________ split verticle<c-h>
____________ split horizontalNOTE: this will auto enable the vim
hlsearch
option
<Esc>
____________ will disable the current hlsearch highlightingNOTE: this will disable the builtin
matchit
plugin
%
save and source the current lua or vimscript file<PageUp>
_________ scroll up<Home>
___________ scroll up fast<PageDown>
_______ scroll down<End>
____________ scroll down fast<c-j>
show the jumplist-
_______________ prev diagnostic_
_______________ next diagnostic<leader>dp
______ prev diagnostic<leader>dn
______ next diagnostic<C-d>
__________ lsp goto definition<C-r>
__________ lsp rename;
______________ lsp hover=
______________ lsp code action<leader>la
______ lsp code action<leader>lh
______ lsp hover<leader>ld
______ lsp goto definition<leader>lD
______ lsp goto Declaration<leader>lf
______ lsp format<leader>lr
______ lsp rename<leader><leader>c
________ check spelling suggestions for word<leader><leader>l
________ add blank line blow (stay in normal mode)<leader><leader>L
________ add blank line above (stay in normal mode)<leader><leader>/
________ find word under cursor<leader><leader>?
________ find word under cursor reverse<leader><leader>i
________ create a column of incrementing numbers# select the colomn of 0s and then <leader><leader>i
0 -(will become)-> 1
0 -(will become)-> 2
0 -(will become)-> 3
0 -(will become)-> 4
0 -(will become)-> 5
unruly boosters change the way that neovim typically works, they are probably not most vim users cup of tea
kopy_reg
(default: +
)0
k
______________ kopy (yank)K
______________ kopy line (yank line)p
______________ paste kopy belowP
______________ paste kopy above"
______________ will prompt you to select a new kopy_register
[a-z][A-X] and 0 +
<enter>
or <space>
reset to the default +
registerthe kopy prompt does not limit register selection or track history
<C-k>
__________ prompt to kopy selected text into any register<C-p>
__________ prompt to paste from any registerd
______________ deletedd
_____________ delete lineD
______________ delete to end of lines
______________ substitute S
______________ substitute linex
______________ delete under cursorX
______________ delete before cursorc
______________ delete then enter insert modecc
_____________ delete line then enter insert modeC
______________ delete to end of line then enter insert mode.
______________ paste register 0 below,
______________ paste register 0 aboveThe unruly idea behind marks is that you only need two marks, for everything else just use telescope. Unruly marks can be in local buffer mode or global mode, by default it will be in local mode.
<leader>a
_____ set mark a<leader>b
_____ set mark b<C-a>
_________ goto mark a<C-b>
_________ goto mark bm
_____________ toggle between local and global mark modeM
_____________ clear current mark mode marksunruly seek allows you to quickly navigate through quickfix list, loclist, and currently open buffers. Seek keymaps only target one type of seekable list at a time, by default the seek type will be buffers.
<leader>sn
_____ goto next seek item<leader>sp
____ goto prev seek item<leader>ss
____ goto first item in seek list (start)<leader>se
____ goto last item in seek list (end)<leader>sq
____ seek the quickfix list<leader>sl
____ seek the loclist<leader>sb
____ seek open buffersunruly macros use the preselected register macro_reg
(default: z
)
q
______________ record macroQ
______________ play macro<C-q>
__________ select the macro register[a-z][A-Z]
<leader>qv
_____ pretty print the current macro content (view)<leader>qp
_____ pretty paste the current macro content into the current buffer<leader>qi
_____ import select text as a macro<cr>
<esc>
into the register correctly<leader>ql
_____ toggle macro recording/import lockthis is maby a bad idea, but I love it
z
_____________ write all buffers, and print a random emoticon (:wall
)(づ ◕‿◕ )づ
Z
_____________ write the current buffer<C-z>
_________ prompt to quit (y
for yes, f
for force quit)plugin boosters have other plugin dependencies
depends on telescope.nvim
j
telescope find files (jump)J
telescope live grep (grep jump)<C-j>
telescope jumplist (jumplist jump)depends on telescope.nvim
<leader>/
telescope fuzzy find in current buffer<leader>tf
telescope files<leader>tg
telescope grep<leader>tb
telescope buffers<leader>to
telescope old files (recent files)<leader>tq
telescope quickfix<leader>tl
telescope loclist<leader>tj
telescope jumplist<leader>tm
telescope man pages<leader>th
telescope help tags<leader>tt
telescope tags<leader>tc
telescope keymaps<leader>tC
telescope colorschemes<leader>tH
telescope highlights<leader>tp
telescope paste from any register<leader>tr
telescope repeat last searchdepends on telescope.nvim
<leader>lc
telescope lsp incoming calls<leader>lC
telescope lsp outgoing calls<leader>li
telescope lsp goto implementation<leader>lr
telescope lsp references<leader>ls
telescope lsp document symbols<leader>lS
telescope lsp workspace symbols<leader>l$
telescope lsp dynamic workspace symbols<leader>lt
telescope lsp typesdepends on telescope.nvim
<leader>d?
telescope lsp diagnosticsdepends on any plugin that uses
gc
andgcc
mappings to comment toggle, like Comment.nvim
<c-c>
toggle commentdepends on Navigator.nvim
<c-y>
focus left (vim or terminal multiplexer)<c-n>
focus down (vim or terminal multiplexer)<c-e>
focus up (vim or terminal multiplexer)<c-o>
focus right (vim or terminal multiplexer)depends on nvim-treesitter and nvim-treesitter-textobject
plugin_textobject
will whatever s
and S
where previously (for example
unruly_kopy's s
)
s
skip to next textobjectS
skip to prev textobjectdepends on LuaSnip powerful snipits
<C-k> or <C-Left>
luasnip jump prev<C-l> or <C-Right>
luasnip jump nextBeing dyslexic has taught me its often easier for me to build a system for myself than it is to learn a system that works well for everyone else. This reinventing the wheel usually ends up being a bit of an accident. I usually start off trying to learn something the way it is, but when I struggle to grasp whats going on I inevitably decide to dig in and see how things work under the hood. My process for exploring the "under the hood of a thing" is kind of caveman style, I just poke and prod and modify and delete things until I have a feeling for what does what. By the time I'm done with all that I usually have my own opinions about what things should be like, and I decide its time to reinvent the wheel or at least swap out the tires. I think the creation of this keymap is a good example of how my learning style tends to unfold.
Unrelated to vim, I decided to learn the workman layout
in an attempt to address issues I was having with typing causing pain.
This decision forced me to consider how to remap a few vim keybinds, but one thing lead
to another and eventually I had created an entirely new layout, the
unruly-worker layout. The original process of creating this keymap lead to me spending about
a year reading :help
and scouring the internet for vim config gems. Which
probably seems ridiculous for many people, but for me its just how I've had to
do most things in life. The time felt well used because I had already spent a decade
writing code and I don't plan to stop for many decades to come. Unlike
my first 7 years struggling with vim, I can now remember the entire keymap well enough to
experience the sensation of manipulating text without noticing that my hands, or
keyboard keys, or even that vim itself has anything to do with it. I always felt vim
was the right tool for job, unruly-worker is just a jig
that makes the tool fit perfectly into my workflow.
Dyslexia may or may not have been what made it so hard for me to learn vim, but it has normalized the process of reinventing wheels as a way to learn for me. The unruly-worker layout, is a classic example of the type of outcomes that my somewhat accidental process of learning produces. unruly-worker is a tool that may not be useful for anyone else, but it makes a tool that is useful to many other people accessible to me.
Suggestions and Spellcheck are always appreciated :)
See the Contributing Guide
If you like this project star the GitHub repository :)
I referenced the source code in these projcects when trying to figure out how to use the nvim apis