lua: Add vim.opt and fix scopes of vim.o (#13479)

* lua: Add vim.opt

* fixup: cleaning

* fixup: comments

* ty clason

* fixup: comments

* this is the last commit. period.
This commit is contained in:
TJ DeVries
2021-05-28 08:24:48 -07:00
committed by GitHub
parent 192ea01edd
commit 43956dea55
7 changed files with 1354 additions and 178 deletions

View File

@@ -39,6 +39,75 @@ assert(vim)
vim.inspect = package.loaded['vim.inspect']
assert(vim.inspect)
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
local f, err = loadfile(found[1])
return f or error(err)
end
end
for _,trail in ipairs(vim._so_trails) do
local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
local found = vim.api.nvim_get_runtime_file(path, false)
if #found > 0 then
-- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
-- a) strip prefix up to and including the first dash, if any
-- b) replace all dots by underscores
-- c) prepend "luaopen_"
-- So "foo-bar.baz" should result in "luaopen_bar_baz"
local dash = name:find("-", 1, true)
local modname = dash and name:sub(dash + 1) or name
local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
return f or error(err)
end
end
return nil
end
table.insert(package.loaders, 1, vim._load_package)
-- These are for loading runtime modules lazily since they aren't available in
-- the nvim binary as specified in executor.c
setmetatable(vim, {
__index = function(t, key)
if key == 'treesitter' then
t.treesitter = require('vim.treesitter')
return t.treesitter
elseif key == 'F' then
t.F = require('vim.F')
return t.F
elseif require('vim.uri')[key] ~= nil then
-- Expose all `vim.uri` functions on the `vim` module.
t[key] = require('vim.uri')[key]
return t[key]
elseif key == 'lsp' then
t.lsp = require('vim.lsp')
return t.lsp
elseif key == 'highlight' then
t.highlight = require('vim.highlight')
return t.highlight
end
end
})
vim.log = {
levels = {
TRACE = 0;
@@ -105,51 +174,6 @@ function vim._os_proc_children(ppid)
return children
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
local f, err = loadfile(found[1])
return f or error(err)
end
end
for _,trail in ipairs(vim._so_trails) do
local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
local found = vim.api.nvim_get_runtime_file(path, false)
if #found > 0 then
-- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
-- a) strip prefix up to and including the first dash, if any
-- b) replace all dots by underscores
-- c) prepend "luaopen_"
-- So "foo-bar.baz" should result in "luaopen_bar_baz"
local dash = name:find("-", 1, true)
local modname = dash and name:sub(dash + 1) or name
local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
return f or error(err)
end
end
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.
@@ -282,32 +306,6 @@ vim.funcref = function(viml_func_name)
return vim.fn[viml_func_name]
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 == 'treesitter' then
t.treesitter = require('vim.treesitter')
return t.treesitter
elseif require('vim.uri')[key] ~= nil then
-- Expose all `vim.uri` functions on the `vim` module.
t[key] = require('vim.uri')[key]
return t[key]
elseif key == 'lsp' then
t.lsp = require('vim.lsp')
return t.lsp
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
setmetatable(vim, {
__index = __index
})
-- An easier alias for commands.
vim.cmd = function(command)
return vim.api.nvim_exec(command, false)
@@ -315,32 +313,8 @@ end
-- These are the vim.env/v/g/o/bo/wo variable magic accessors.
do
local a = vim.api
local validate = vim.validate
local function make_meta_accessor(get, set, del)
validate {
get = {get, 'f'};
set = {set, 'f'};
del = {del, 'f', true};
}
local mt = {}
if del then
function mt:__newindex(k, v)
if v == nil then
return del(k)
end
return set(k, v)
end
else
function mt:__newindex(k, v)
return set(k, v)
end
end
function mt:__index(k)
return get(k)
end
return setmetatable({}, mt)
end
local function make_dict_accessor(scope)
validate {
scope = {scope, 's'};
@@ -354,88 +328,12 @@ do
end
return setmetatable({}, mt)
end
vim.g = make_dict_accessor('g')
vim.v = make_dict_accessor('v')
vim.b = make_dict_accessor('b')
vim.w = make_dict_accessor('w')
vim.t = make_dict_accessor('t')
vim.o = make_meta_accessor(a.nvim_get_option, a.nvim_set_option)
local function getenv(k)
local v = vim.fn.getenv(k)
if v == vim.NIL then
return nil
end
return v
end
vim.env = make_meta_accessor(getenv, vim.fn.setenv)
-- TODO(ashkan) if/when these are available from an API, generate them
-- instead of hardcoding.
local window_options = {
arab = true; arabic = true; breakindent = true; breakindentopt = true;
bri = true; briopt = true; cc = true; cocu = true;
cole = true; colorcolumn = true; concealcursor = true; conceallevel = true;
crb = true; cuc = true; cul = true; cursorbind = true;
cursorcolumn = true; cursorline = true; diff = true; fcs = true;
fdc = true; fde = true; fdi = true; fdl = true;
fdm = true; fdn = true; fdt = true; fen = true;
fillchars = true; fml = true; fmr = true; foldcolumn = true;
foldenable = true; foldexpr = true; foldignore = true; foldlevel = true;
foldmarker = true; foldmethod = true; foldminlines = true; foldnestmax = true;
foldtext = true; lbr = true; lcs = true; linebreak = true;
list = true; listchars = true; nu = true; number = true;
numberwidth = true; nuw = true; previewwindow = true; pvw = true;
relativenumber = true; rightleft = true; rightleftcmd = true; rl = true;
rlc = true; rnu = true; scb = true; scl = true;
scr = true; scroll = true; scrollbind = true; signcolumn = true;
spell = true; statusline = true; stl = true; wfh = true;
wfw = true; winbl = true; winblend = true; winfixheight = true;
winfixwidth = true; winhighlight = true; winhl = true; wrap = true;
}
--@private
local function new_buf_opt_accessor(bufnr)
--@private
local function get(k)
if window_options[k] then
return a.nvim_err_writeln(k.." is a window option, not a buffer option")
end
if bufnr == nil and type(k) == "number" then
return new_buf_opt_accessor(k)
end
return a.nvim_buf_get_option(bufnr or 0, k)
end
--@private
local function set(k, v)
if window_options[k] then
return a.nvim_err_writeln(k.." is a window option, not a buffer option")
end
return a.nvim_buf_set_option(bufnr or 0, k, v)
end
return make_meta_accessor(get, set)
end
vim.bo = new_buf_opt_accessor(nil)
--@private
local function new_win_opt_accessor(winnr)
--@private
local function get(k)
if winnr == nil and type(k) == "number" then
return new_win_opt_accessor(k)
end
return a.nvim_win_get_option(winnr or 0, k)
end
--@private
local function set(k, v)
return a.nvim_win_set_option(winnr or 0, k, v)
end
return make_meta_accessor(get, set)
end
vim.wo = new_win_opt_accessor(nil)
end
--- Get a table of lines with start, end columns for a region marked by two points
@@ -738,4 +636,6 @@ vim._expand_pat_get_parts = function(lua_string)
return parts, search_index
end
pcall(require, 'vim._meta')
return module