aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua/vim.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua/vim.lua')
-rw-r--r--src/nvim/lua/vim.lua156
1 files changed, 96 insertions, 60 deletions
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index 820b237c4f..2c7ab46ffe 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -36,6 +36,9 @@
local vim = vim
assert(vim)
+vim.inspect = package.loaded['vim.inspect']
+assert(vim.inspect)
+
-- Internal-only until comments in #8107 are addressed.
-- Returns:
-- {errcode}, {output}
@@ -92,67 +95,44 @@ function vim._os_proc_children(ppid)
return children
end
--- TODO(ZyX-I): Create compatibility layer.
---{{{1 package.path updater function
--- Last inserted paths. Used to clear out items from package.[c]path when they
--- are no longer in &runtimepath.
-local last_nvim_paths = {}
-function vim._update_package_paths()
- local cur_nvim_paths = {}
- local rtps = vim.api.nvim_list_runtime_paths()
- local sep = package.config:sub(1, 1)
- for _, key in ipairs({'path', 'cpath'}) do
- local orig_str = package[key] .. ';'
- local pathtrails_ordered = {}
- local orig = {}
- -- Note: ignores trailing item without trailing `;`. Not using something
- -- simpler in order to preserve empty items (stand for default path).
- for s in orig_str:gmatch('[^;]*;') do
- s = s:sub(1, -2) -- Strip trailing semicolon
- orig[#orig + 1] = s
- end
- if key == 'path' then
- -- /?.lua and /?/init.lua
- pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}
- else
- local pathtrails = {}
- for _, s in ipairs(orig) do
- -- Find out path patterns. pathtrail should contain something like
- -- /?.so, \?.dll. This allows not to bother determining what correct
- -- suffixes are.
- local pathtrail = s:match('[/\\][^/\\]*%?.*$')
- if pathtrail and not pathtrails[pathtrail] then
- pathtrails[pathtrail] = true
- pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail
- end
- end
- end
- local new = {}
- for _, rtp in ipairs(rtps) do
- if not rtp:match(';') then
- for _, pathtrail in pairs(pathtrails_ordered) do
- local new_path = rtp .. sep .. 'lua' .. pathtrail
- -- Always keep paths from &runtimepath at the start:
- -- append them here disregarding orig possibly containing one of them.
- new[#new + 1] = new_path
- cur_nvim_paths[new_path] = true
- end
- end
+local pathtrails = {}
+vim._so_trails = {}
+for s in (package.cpath..';'):gmatch('[^;]*;') do
+ s = s:sub(1, -2) -- Strip trailing semicolon
+ -- Find out path patterns. pathtrail should contain something like
+ -- /?.so, \?.dll. This allows not to bother determining what correct
+ -- suffixes are.
+ local pathtrail = s:match('[/\\][^/\\]*%?.*$')
+ if pathtrail and not pathtrails[pathtrail] then
+ pathtrails[pathtrail] = true
+ table.insert(vim._so_trails, pathtrail)
+ end
+end
+
+function vim._load_package(name)
+ local basename = name:gsub('%.', '/')
+ local paths = {"lua/"..basename..".lua", "lua/"..basename.."/init.lua"}
+ for _,path in ipairs(paths) do
+ local found = vim.api.nvim_get_runtime_file(path, false)
+ if #found > 0 then
+ return loadfile(found[1])
end
- for _, orig_path in ipairs(orig) do
- -- Handle removing obsolete paths originating from &runtimepath: such
- -- paths either belong to cur_nvim_paths and were already added above or
- -- to last_nvim_paths and should not be added at all if corresponding
- -- entry was removed from &runtimepath list.
- if not (cur_nvim_paths[orig_path] or last_nvim_paths[orig_path]) then
- new[#new + 1] = orig_path
- end
+ end
+
+ for _,trail in ipairs(vim._so_trails) do
+ local path = "lua/"..trail:gsub('?',basename)
+ local found = vim.api.nvim_get_runtime_file(path, false)
+ if #found > 0 then
+ return package.loadlib(found[1])
end
- package[key] = table.concat(new, ';')
end
- last_nvim_paths = cur_nvim_paths
+ return nil
end
+table.insert(package.loaders, 1, vim._load_package)
+
+-- TODO(ZyX-I): Create compatibility layer.
+
--- Return a human-readable representation of the given object.
---
--@see https://github.com/kikito/inspect.lua
@@ -279,10 +259,7 @@ end
-- These are for loading runtime modules lazily since they aren't available in
-- the nvim binary as specified in executor.c
local function __index(t, key)
- if key == 'inspect' then
- t.inspect = require('vim.inspect')
- return t.inspect
- elseif key == 'treesitter' then
+ if key == 'treesitter' then
t.treesitter = require('vim.treesitter')
return t.treesitter
elseif require('vim.uri')[key] ~= nil then
@@ -295,6 +272,9 @@ local function __index(t, key)
elseif key == 'highlight' then
t.highlight = require('vim.highlight')
return t.highlight
+ elseif key == 'F' then
+ t.F = require('vim.F')
+ return t.F
end
end
@@ -489,4 +469,60 @@ function vim.defer_fn(fn, timeout)
return timer
end
+local on_keystroke_callbacks = {}
+
+--- Register a lua {fn} with an {id} to be run after every keystroke.
+---
+--@param fn function: Function to call. It should take one argument, which is a string.
+--- The string will contain the literal keys typed.
+--- See |i_CTRL-V|
+---
+--- If {fn} is nil, it removes the callback for the associated {ns_id}
+--@param ns_id number? Namespace ID. If not passed or 0, will generate and return a new
+--- namespace ID from |nvim_create_namesapce()|
+---
+--@return number Namespace ID associated with {fn}
+---
+--@note {fn} will be automatically removed if an error occurs while calling.
+--- This is to prevent the annoying situation of every keystroke erroring
+--- while trying to remove a broken callback.
+--@note {fn} will not be cleared from |nvim_buf_clear_namespace()|
+--@note {fn} will receive the keystrokes after mappings have been evaluated
+function vim.register_keystroke_callback(fn, ns_id)
+ vim.validate {
+ fn = { fn, 'c', true},
+ ns_id = { ns_id, 'n', true }
+ }
+
+ if ns_id == nil or ns_id == 0 then
+ ns_id = vim.api.nvim_create_namespace('')
+ end
+
+ on_keystroke_callbacks[ns_id] = fn
+ return ns_id
+end
+
+--- Function that executes the keystroke callbacks.
+--@private
+function vim._log_keystroke(char)
+ local failed_ns_ids = {}
+ local failed_messages = {}
+ for k, v in pairs(on_keystroke_callbacks) do
+ local ok, err_msg = pcall(v, char)
+ if not ok then
+ vim.register_keystroke_callback(nil, k)
+
+ table.insert(failed_ns_ids, k)
+ table.insert(failed_messages, err_msg)
+ end
+ end
+
+ if failed_ns_ids[1] then
+ error(string.format(
+ "Error executing 'on_keystroke' with ns_ids of '%s'\n With messages: %s",
+ table.concat(failed_ns_ids, ", "),
+ table.concat(failed_messages, "\n")))
+ end
+end
+
return module