dotfiles/nvim/.config/nvim/lua/core/mappings.lua

137 lines
5.0 KiB
Lua

local map = vim.keymap.set
local is_available = require("util").is_available
if is_available("which-key") then
local prefix = require("which-key").register
prefix({ ["<leader>v"] = { name = "+vim" } })
prefix({ ["<leader>s"] = { name = "+show" } })
prefix({ ["<localleader>s"] = { name = "+set" } })
prefix({ ["<localleader>Z"] = { name = "+spelling" } })
end
-- The general ideas behind these mappings:
--
-- * Leader prefix is the generally preferred way to map new things, however
-- only for those that affect all of vim or work in a supra-buffer way.
--
-- * Localleader prefix is used for mappings which only affect single buffers.
-- In other words mostly filetype specific mappings
-- backspace to switch to alternate (last) buffer
map("n", "<BS>", "<C-^>")
-- since u undoes, would it not make sense that U redoes?
map("n", "U", "<C-r>")
-- d-motion puts the last 'deleted' thing into the default register to paste;
-- use D-motion to truly delete something into nothingness and keep whatever
-- you want in your register, ready to paste
map("n", "D", '"_d')
-- I don't particularly need ex mode (at least, yet) but faster macro access is nice
map("n", "Q", "@")
-- stronger versions of left,right - move all the way to beginning/end of line
map("n", "H", "^")
map("n", "L", "$")
-- when in softwrapped files, allow moving through the visible lines with j/k
-- but when prepending a number jump *exactly* as many lines, wrapped or not
-- This makes relative linenumbers much more useful in prose docs since they
-- are always exactly correct
local function wrap_up()
if vim.v.count == 0 then
return "gk"
end
return "k"
end
local function wrap_down()
if vim.v.count == 0 then
return "gj"
end
return "j"
end
map("n", "k", wrap_up, { expr = true })
map("n", "j", wrap_down, { expr = true })
-- move around between matching brackets with tab
map("n", "<Tab>", "%")
-- when in insertion mode, C-u uppercases the current word, C-l lowercases it,
map("i", "<C-u>", "<esc>gUiw`]a")
map("i", "<C-y>", "<esc>guiw`]a")
-- Add undo break-points at punctuations for plaintext editing
for _, char in pairs({ ",", ".", ";", "?", "!" }) do
map("i", char, string.format("%s<c-g>u", char))
end
-- yank current filename/filepath to f buffer
map("n", "yp", ':let @p = expand("%")<Cr>', { desc = "yank filename" })
map("n", "yP", ':let @p = expand("%:p")<Cr>', { desc = "yank filepath" })
-- repeat the last substitute command with all its flags preserved
map("n", "&", ":&&<cr>")
-- bracket pairings to go to the next/previous of:
-- (works with count prefixes)
-- Argument list
map("n", "[a", ":previous<cr>")
map("n", "]a", ":next<cr>")
-- Buffers
map("n", "[b", ":bprevious<cr>")
map("n", "]b", ":bnext<cr>")
-- Quickfix list
map("n", "[q", ":cprevious<cr>")
map("n", "]q", ":cnext<cr>")
-- Location list
map("n", "[l", ":lprevious<cr>")
map("n", "]l", ":lnext<cr>")
-- maps the leader for buffer local mappings
-- since we are (atm) using sneak to go fwd/bwd in fFtT searches, comma does
-- not do too many useful things and can be taken up as localleader
vim.g.maplocalleader = ","
-- If we mapped localleader to comma, we can still get to its original function
-- by douple-tapping it.
-- FIXME does this work still (and is it necessary)?
if vim.g.maplocalleader == "," then
map("", ",,", ",")
vim.keymap.del("", ",,", { silent = true })
end
-- get out of terminal mode a little easier by double tapping backslash
map("t", "\\\\", [[<C-\><C-n>]], { desc = "exit terminal mode" })
-- remove search highlights by pressing space+/
map("n", "<leader>/", ":noh<cr>", { desc = "remove highlights" })
-- split buffers vertically/horizontally with the leader \ or - (mirrors my
-- tmux setup)
map("n", "<leader>-", ":sp<cr>", { desc = "open horiz split" })
map("n", "<leader>\\", ":vsp<cr>", { desc = "open vert split" })
-- open actual new tab with leader-T
map("n", "<leader>T", ":tabedit | Vifm<cr>", { desc = "open tab" })
-- select the whole buffer with <leader>-a
map("n", "<leader>a", "ggVG", { desc = "select all" })
-- Format current Paragraph (esp useful in prose writing)
map("n", "<localleader>q", "gqap", { silent = true, desc = "Format current paragraph" })
map("x", "<localleader>q", "gq", { silent = true, desc = "Format {motion}" })
map("n", "<localleader>Q", "vapJgqap", { silent = true, desc = "Unformat then format paragraph" })
-- SPELL CHECKING
-- Move to the prev/next spelling error with [S ]S
-- Move to the prev/next spelling error or suggestion with [s ]s
map("n", "<localleader>ZZ", ":setlocal spell! spelllang=en_us,en_gb,de_de<cr>", { desc = "Toggle spellcheck" })
map("n", "<localleader>ZE", ":setlocal spell! spelllang=en_us<cr>", { desc = "Toggle EN_US spellcheck" })
map("n", "<localleader>ZB", ":setlocal spell! spelllang=en_gb<cr>", { desc = "Toggle EN_GB spellcheck" })
map("n", "<localleader>ZD", ":setlocal spell! spelllang=de_de<cr>", { desc = "Toggle DE_DE spellcheck" })
-- undo last spelling mistake from insert and normal mode
map("i", "<c-z>", "<C-G>u<Esc>e[s1z=`]a<C-G>u")
map("n", "<localleader>z", "mse[s1z=`s", { desc = "Fix last spell error" })