-- WASD-style layout (ported from Vim). Uses same keys as your vimrc; 'x' = visual (vnoremap). local function n(lhs, rhs, opts) vim.keymap.set('n', lhs, rhs, opts or {}) end local function x(lhs, rhs) vim.keymap.set('x', lhs, rhs) end local function o(lhs, rhs, opts) vim.keymap.set('o', lhs, rhs, opts or {}) end -- Movement (normal, visual, operator-pending) for _, lhs in ipairs({ 'w', 's', 'a', 'd' }) do local rhs = ({ w = 'k', s = 'j', a = 'h', d = 'l' })[lhs] n(lhs, rhs) x(lhs, rhs) o(lhs, rhs) end -- Word motions (normal + operator; visual keeps native w/W/e/E on i,I,j,J now remapped) for _, mode in ipairs({ 'n', 'o' }) do local opts = mode == 'o' and { nowait = true } or {} vim.keymap.set(mode, 'i', 'w', opts) vim.keymap.set(mode, 'I', 'W', opts) vim.keymap.set(mode, 'j', 'e', opts) vim.keymap.set(mode, 'J', 'E', opts) end -- Operator-pending fixes so combos behave as expected: -- cw -> ci, ce -> cj, and rk does nothing. o('w', 'i', { nowait = true }) o('e', 'j', { nowait = true }) o('k', '', { nowait = true }) -- Insert / append n('e', 'i') n('E', 'a') n('D', 'A') n('A', 'I') -- Operators n('r', 'd', { nowait = true }) n('R', 'D') o('r', 'd', { nowait = true }) n('c', 'c') o('c', 'c') n('f', 's') n('F', 'S') n('t', 'r') n('T', 'R') -- Open lines n('W', 'O') n('S', 'o') -- Visual mode entry from normal n('H', 'V') n('h', '') -- Find / motion n('l', 'f') n('L', 'F') n('p', 't') n('P', 'T') o('l', 'f', { nowait = true }) o('L', 'F', { nowait = true }) o('p', 't', { nowait = true }) o('P', 'T', { nowait = true }) -- Paste n('v', 'p') n('V', 'P') n('o', 'p') n('K', '') n('k', '') n('O', '') x('O', '') o('O', '')