mirror of
https://github.com/neovim/neovim.git
synced 2026-05-24 05:40:08 +00:00
feat(vimfn): use Lua for more excmds/vimfns
Problem: Too much boilerplate needed to use Lua to impl an excmd or f_xx function. Solution: - Add `nlua_call_vimfn` which takes the args typval, executes Lua, and returns a typval. - refactor(excmd): lua impl for :log, :lsp
This commit is contained in:
@@ -2,6 +2,10 @@ local api = vim.api
|
||||
local fs = vim.fs
|
||||
local util = require('vim._core.util')
|
||||
|
||||
--- Parsed ex command arguments for builtin commands, passed from C via `nlua_call_excmd`.
|
||||
--- Inherits fields from user command args: args, bang, line1, line2, range, count, reg, smods.
|
||||
--- @class vim._core.ExCmdArgs : vim.api.keyset.create_user_command.command_args
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @param msg string
|
||||
@@ -151,9 +155,9 @@ local actions = {
|
||||
local available_subcmds = vim.tbl_keys(actions)
|
||||
|
||||
--- Implements command: `:lsp {subcmd} {name}?`.
|
||||
--- @param args string
|
||||
M.ex_lsp = function(args)
|
||||
local fargs = api.nvim_parse_cmd('lsp ' .. args, {}).args
|
||||
--- @param eap vim._core.ExCmdArgs
|
||||
M.ex_lsp = function(eap)
|
||||
local fargs = api.nvim_parse_cmd('lsp ' .. eap.args, {}).args
|
||||
if not fargs then
|
||||
return
|
||||
end
|
||||
@@ -192,11 +196,11 @@ end
|
||||
local log_dir = vim.fn.stdpath('log')
|
||||
|
||||
--- Implements command: `:log {file}`.
|
||||
--- @param filename string
|
||||
--- @param mods string
|
||||
M.ex_log = function(filename, mods)
|
||||
--- @param eap vim._core.ExCmdArgs
|
||||
M.ex_log = function(eap)
|
||||
local filename = eap.args
|
||||
if filename == '' then
|
||||
util.wrapped_edit(log_dir, mods)
|
||||
util.wrapped_edit(log_dir, eap.smods)
|
||||
else
|
||||
local path --- @type string
|
||||
-- Special case for NVIM_LOG_FILE
|
||||
@@ -210,7 +214,7 @@ M.ex_log = function(filename, mods)
|
||||
echo_err(("No such log file: '%s'"):format(path))
|
||||
return
|
||||
end
|
||||
util.wrapped_edit(path, mods)
|
||||
util.wrapped_edit(path, eap.smods)
|
||||
vim.cmd.normal { 'G', bang = true }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,36 +2,40 @@
|
||||
|
||||
local M = {}
|
||||
|
||||
--- Called by builtin serverlist(). Returns all running servers in stdpath("run").
|
||||
--- Called by builtin serverlist(). Returns the combined server list (own + peers).
|
||||
---
|
||||
--- - TODO: track TCP servers, somehow.
|
||||
--- - TODO: support Windows named pipes.
|
||||
---
|
||||
--- @param listed string[] Already listed servers
|
||||
--- @return string[] # List of servers found on the current machine in stdpath("run").
|
||||
function M.serverlist(listed)
|
||||
--- @param opts? table Options:
|
||||
--- - opts.peer is true, also discover peer servers.
|
||||
--- @param addrs string[] Internal ("own") addresses, from `server_address_list`.
|
||||
--- @return string[] # Combined list of servers (own + peers).
|
||||
function M.serverlist(opts, addrs)
|
||||
if type(opts) ~= 'table' or not opts.peer then
|
||||
return addrs
|
||||
end
|
||||
|
||||
-- Discover peer servers in stdpath("run").
|
||||
-- TODO: track TCP servers, somehow.
|
||||
-- TODO: support Windows named pipes.
|
||||
local root = vim.fs.normalize(vim.fn.stdpath('run') .. '/..')
|
||||
local socket_paths = vim.fs.find(function(name, _)
|
||||
return name:match('nvim.*')
|
||||
end, { path = root, type = 'socket', limit = math.huge })
|
||||
|
||||
local found = {} ---@type string[]
|
||||
for _, socket in ipairs(socket_paths) do
|
||||
-- Don't list servers twice
|
||||
if not vim.list_contains(listed, socket) then
|
||||
if not vim.list_contains(addrs, socket) then
|
||||
local ok, chan = pcall(vim.fn.sockconnect, 'pipe', socket, { rpc = true })
|
||||
if ok and chan then
|
||||
-- Check that the server is responding
|
||||
-- TODO: do we need a timeout or error handling here?
|
||||
if vim.fn.rpcrequest(chan, 'nvim_get_chan_info', 0).id then
|
||||
table.insert(found, socket)
|
||||
table.insert(addrs, socket)
|
||||
end
|
||||
vim.fn.chanclose(chan)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return found
|
||||
return addrs
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -62,12 +62,14 @@ end
|
||||
|
||||
--- :edit, but it respects commands like :hor, :vert, :tab, etc.
|
||||
--- @param file string
|
||||
--- @param mods_str string
|
||||
function M.wrapped_edit(file, mods_str)
|
||||
local cmdline = table.concat({ mods_str, 'edit' }, ' ')
|
||||
local mods = vim.api.nvim_parse_cmd(cmdline, {}).mods
|
||||
--- @diagnostic disable-next-line: need-check-nil
|
||||
if mods.tab > 0 or mods.split ~= '' or mods.horizontal or mods.vertical then
|
||||
--- @param mods string|vim.api.keyset.cmd_mods Modifier string ("vertical") or structured mods table.
|
||||
function M.wrapped_edit(file, mods)
|
||||
assert(mods)
|
||||
if type(mods) == 'string' then
|
||||
mods = vim.api.nvim_parse_cmd(mods .. ' edit', {}).mods --[[@as vim.api.keyset.cmd_mods]]
|
||||
end
|
||||
--- @cast mods vim.api.keyset.cmd_mods
|
||||
if (mods.tab or 0) > 0 or (mods.split or '') ~= '' or mods.horizontal or mods.vertical then
|
||||
local buf = M.get_buf_by_name(file)
|
||||
if buf == nil then
|
||||
buf = vim.api.nvim_create_buf(true, false)
|
||||
|
||||
@@ -111,7 +111,7 @@ error('Cannot require a meta file')
|
||||
---
|
||||
--- Command modifiers in a structured format. Has the same structure as the
|
||||
--- "mods" key of |nvim_parse_cmd()|.
|
||||
--- @field smods table
|
||||
--- @field smods vim.api.keyset.cmd_mods
|
||||
|
||||
--- @class vim.api.keyset.command_info
|
||||
--- @field name string
|
||||
|
||||
Reference in New Issue
Block a user