Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/lua/std/map.lua

Raw
local available_modes = {
	normal_visual_select_operator_pending = '',
	N = '',

	normal = 'n',
	n = 'n',

	insert = 'i',
	i = 'i',

	visual = 'x',
	x = 'x',

	visual_select = 'v',
	v = 'v',

	select = 's',
	s = 's',

	operator_pending = 'o',
	o = 'o',

	['!'] = '!',
	insert_command_line = '!',

	command_line = 'c',
	c = 'c',

	terminal = 't',
	t = 't',
}

local bind = function ( self, map )
	vim.validate( 'map',         map,         'table' )
	vim.validate( 'map.keys',    map.keys,    { 'string', 'table' } )
	vim.validate( 'map.command', map.command, { 'function', 'string' } )

	local keys = map.keys
	local command = map.command

	map.options = map.options or {}

	if map.category and map.description then
		map.description = map.category .. ': ' .. map.description
	end

	local options = vim.tbl_extend( 'keep', map.options, {
		silent = true,
		desc = map.description,
		buf = map.buffer,
		remap = map.remap,
	} )

	if vim.tbl_isempty( self.modes ) then
		self.modes[1] = available_modes.normal_visual_select_operator_pending
	end

	local modes = self.modes

	if type( keys ) == 'table' then
		for _, key in ipairs( keys ) do
			vim.keymap.set( modes, key, command, options )
		end
	else
		vim.keymap.set( modes, keys, command, options )
	end

	self.modes = {}

	return function ()
		local delete_options = options.buf and { buf = options.buf } or {}
		if type( keys ) == 'table' then
			for _, key in ipairs( keys ) do
				vim.keymap.del( modes, key, delete_options )
			end
		else
			vim.keymap.del( modes, keys, delete_options )
		end
	end
end

local add_mode = function ( self, key )
	local new_mode = available_modes[key]
	if new_mode == nil then
		error( 'unknown keymap mode requested: ' .. key )
	end
	if not vim.tbl_contains( self.modes, new_mode ) then
		table.insert( self.modes, new_mode )
	end
	return self
end

--- @overload fun(map:table): function
local map = setmetatable(
	{
		modes = {},
	},
	{
		__index = add_mode,
		__newindex = function ( ... ) error( 'Assignments are not supported for std.map.\n' .. vim.inspect( ... ), 2 ) end,
		__call = bind,
	}
)

return map