8000 mini.nvim/lua/mini/keymap.lua at main · figofigueiroa/mini.nvim · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
868 lines (781 loc) · 41.8 KB

keymap.lua

File metadata and controls

868 lines (781 loc) · 41.8 KB
-- - For "before" direction exact left end is needed. This will be used
-- in Insert mode and cursor will be between target and its left cell.
-- - For "after" direction the one cell to right (after normalization) is
-- needed because cursor in Insert mode will be just after the node.
local from_row, from_col, to_row, to_col = vim.treesitter.get_node_range(node)
local row = side == 'before' and from_row or to_row
local col = side == 'before' and from_col or to_col
new_pos = H.normalize_pos(row, col)
-- Iterate up the tree until different position is found. This is useful
-- for "before" direction and non-Insert mode.
if not (new_pos[1] == pos[1] and new_pos[2] == pos[2]) then
H.hide_completion()
pcall(vim.api.nvim_win_set_cursor, 0, new_pos)
new_pos = vim.api.nvim_win_get_cursor(0)
end
if not (new_pos[1] == pos[1] and new_pos[2] == pos[2]) then break end
node = node:parent()
end
end
-- Return callable which is wrapped to be executed after expression mapping
return function() return act end
end
H.steps_builtin.jump_after_tsnode = { condition = H.can_jump_tsnode, action = H.make_jump_tsnode('after') }
H.steps_builtin.jump_before_tsnode = { condition = H.can_jump_tsnode, action = H.make_jump_tsnode('before') }
H.steps_builtin.jump_after_close = {
condition = function() return vim.fn.mode() == 'i' end,
-- NOTE: In Insert mode 'c' flag (accept at cursor) with 'after' adjust are
-- needed for working "chaining". In other modes it is no flag and no adjust,
-- which is why these steps only work in Insert mode.
action = MiniKeymap.gen_step.search_pattern([=[[)\]}"'`]]=], 'cW', { side = 'after' }).action,
}
H.steps_builtin.jump_before_open = {
condition = function() return vim.fn.mode() == 'i' end,
action = MiniKeymap.gen_step.search_pattern([=[[(\[{"'`]]=], 'bW', { side = 'before' }).action,
}
H.is_in_indent = function()
local line, col = vim.api.nvim_get_current_line(), vim.fn.col('.')
local offset = vim.fn.mode() == 'i' and 1 or 0
return line:sub(1, col - offset):find('^%s*$') ~= nil
end
H.increase_indent_keys = { i = '<C-t>', v = '>', V = '>', ['\22'] = '>' }
H.decrease_indent_keys = { i = '<C-d>', v = '<', V = '<', ['\22'] = '<' }
H.steps_builtin.increase_indent = { condition = H.is_in_indent, action = function() return H.increase_indent_keys[vim.fn.mode()] or '>>' end }
H.steps_builtin.decrease_indent = { condition = H.is_in_indent, action = function() return H.decrease_indent_keys[vim.fn.mode()] or '<<' end }
H.hungry_bs_condition = function()
local line, col = vim.api.nvim_get_current_line(), vim.fn.col('.')
local offset = vim.fn.mode() == 'i' and 1 or 0
return line:sub(1, col - offset):find('%s+$') ~= nil
end
H.hungry_bs_action = function()
return function()
local line, lnum, col = vim.api.nvim_get_current_line(), vim.fn.line('.'), vim.fn.col('.')
local offset = vim.fn.mode() == 'i' and 1 or 0
local from_col = line:sub(1, col - offset):match('()%s+$')
vim.api.nvim_buf_set_text(0, lnum - 1, from_col - 1, lnum - 1, col - offset, {})
vim.api.nvim_win_set_cursor(0, { lnum, from_col - 1 })
end
end
H.steps_builtin.hungry_bs = { condition = H.hungry_bs_condition, action = H.hungry_bs_action }
H.make_vimsnippet_condition = function(dir) return function() return vim.snippet.active({ direction = dir }) end end
H.make_vimsnippet_action = function(dir) return H.make_cmd_lua_action('vim.snippet.jump(' .. dir .. ')') end
H.steps_builtin.vimsnippet_next = { condition = H.make_vimsnippet_condition(1), action = H.make_vimsnippet_action(1) }
H.steps_builtin.vimsnippet_prev = { condition = H.make_vimsnippet_condition(-1), action = H.make_vimsnippet_action(-1) }
H.is_visible_cmp = function() return H.has_module('cmp') and require('cmp').visible() end
H.is_selected_cmp = function() return H.has_module('cmp') and require('cmp').get_selected_entry() ~= nil end
H.make_cmp_action = function(action) return H.make_cmd_lua_action('require("cmp").' .. action .. '()') end
H.steps_builtin.cmp_next = { condition = H.is_visible_cmp, action = H.make_cmp_action('select_next_item') }
H.steps_builtin.cmp_prev = { condition = H.is_visible_cmp, action = H.make_cmp_action('select_prev_item') }
H.steps_builtin.cmp_accept = { condition = H.is_selected_cmp, action = H.make_cmp_action('confirm') }
H.is_visible_blink = function() return H.has_module('blink.cmp') and require('blink.cmp').is_menu_visible() end
H.is_selected_blink = function() return H.is_visible_blink() and require('blink.cmp').get_selected_item() ~= nil end
H.make_blink_action = function(action) return H.make_cmd_lua_action('require("blink.cmp").' .. action .. '()') end
H.steps_builtin.blink_next = { condition = H.is_visible_blink, action = H.make_blink_action('select_next') }
H.steps_builtin.blink_prev = { condition = H.is_visible_blink, action = H.make_blink_action('select_prev') }
H.steps_builtin.blink_accept = { condition = H.is_selected_blink, action = H.make_blink_action('accept') }
H.make_luasnip_condition = function(dir) return function() return H.has_module('luasnip') and require('luasnip').jumpable(dir) end end
H.is_luasnip_expandable = function() return H.has_module('luasnip') and require('luasnip').expandable() end
H.make_luasnip_action = function(dir) return H.make_cmd_lua_action('require("luasnip").jump(' .. dir .. ')') end
H.steps_builtin.luasnip_next = { condition = H.make_luasnip_condition(1), action = H.make_luasnip_action(1) }
H.steps_builtin.luasnip_prev = { condition = H.make_luasnip_condition(-1), action = H.make_luasnip_action(-1) }
H.steps_builtin.luasnip_expand = { condition = H.is_luasnip_expandable, action = H.make_cmd_lua_action('require("luasnip").expand()') }
H.has_nvimautopairs = function() return H.has_module('nvim-autopairs') end
H.make_nvimautopairs_action = function(method) return function() return vim.fn.keytrans(require('nvim-autopairs')[method]()) end end
H.steps_builtin.nvimautopairs_cr = { condition = H.has_nvimautopairs, action = H.make_nvimautopairs_action('autopairs_cr') }
H.steps_builtin.nvimautopairs_bs = { condition = H.has_nvimautopairs, action = H.make_nvimautopairs_action('autopairs_bs') }
--stylua: ignore end
-- Validators -----------------------------------------------------------------
H.is_string = function(x) return type(x) == 'string' end
H.is_array_of = function(x, predicate)
if not vim.islist(x) then return false end
for i = 1, #x do
if not predicate(x[i]) then return false end
end
return true
end
-- Utilities ------------------------------------------------------------------
H.error = function(msg) error('(mini.keymap) ' .. msg, 0) end
H.check_type = function(name, val, ref, allow_nil)
if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end
H.error(string.format('`%s` should be %s, not %s', name, ref, type(val)))
end
H.notify = function(msg, level_name, silent)
if not silent then vim.notify('(mini.keymap) ' .. msg, vim.log.levels[level_name]) end
end
H.normalize_pos = function(row, col)
-- Input is {0,0} indexed, output is {1,0} indexed
if row < 0 or (row == 0 and col < 0) then return { 1, 0 } end
local last_row = vim.api.nvim_buf_line_count(0) - 1
local n_col_last_row = H.get_row_cols(last_row)
-- Assume this is used in Insert node, so placing just after EOL can be done
if row > last_row or (row == last_row and col > n_col_last_row) then return { last_row + 1, n_col_last_row } end
if col < 0 then return { row, H.get_row_cols(row - 1) } end
if col > H.get_row_cols(row) then return { row + 2, 0 } end
return { row + 1, col }
end
H.get_row_cols = function(row) return vim.fn.getline(row + 1):len() end
H.get_tsnode = function() return vim.treesitter.get_node() end
H.hide_completion = function()
-- NOTE: `complete()` instead of emulating <C-y> works immediately (without
-- the need to `vim.schedule()`). See 'mini.snippets' for more details.
-- NOTE: Checking 'pumvisible() == 1' should not lead to edge cases from
-- 'mini.snippets' (as there is no extmarks involved).
if vim.fn.mode() == 'i' and vim.fn.pumvisible() == 1 then vim.cmd('silent noautocmd call complete(col("."), [])') end
end
return MiniKeymap
0