Merge pull request #20593 from lewis6991/fix/man_macos13

This commit is contained in:
Lewis Russell 2022-10-11 16:18:18 +01:00 committed by GitHub
commit 760b399f6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,6 @@
local api, fn = vim.api, vim.fn
local find_arg = '-w'
local FIND_ARG = '-w'
local localfile_arg = true -- Always use -l if possible. #6683
local buf_hls = {}
@ -12,7 +12,7 @@ local function man_error(msg)
end
-- Run a system command and timeout after 30 seconds.
local function man_system(args, silent, env)
local function system(cmd, silent, env)
local stdout_data = {}
local stderr_data = {}
local stdout = vim.loop.new_pipe(false)
@ -22,8 +22,8 @@ local function man_system(args, silent, env)
local exit_code
local handle
handle = vim.loop.spawn('man', {
args = args,
handle = vim.loop.spawn(cmd[1], {
args = vim.list_slice(cmd, 2),
stdio = { nil, stdout, stderr },
env = env,
}, function(code)
@ -45,8 +45,8 @@ local function man_system(args, silent, env)
stdout:close()
stderr:close()
if not silent then
local cmd = table.concat({ 'man', unpack(args) }, ' ')
man_error(string.format('command error: %s', cmd))
local cmd_str = table.concat(cmd, ' ')
man_error(string.format('command error: %s', cmd_str))
end
end
@ -60,13 +60,13 @@ local function man_system(args, silent, env)
stdout:close()
stderr:close()
end
local cmd = table.concat({ 'man', unpack(args) }, ' ')
man_error(string.format('command timed out: %s', cmd))
local cmd_str = table.concat(cmd, ' ')
man_error(string.format('command timed out: %s', cmd_str))
end
if exit_code ~= 0 and not silent then
local cmd = table.concat({ 'man', unpack(args) }, ' ')
man_error(string.format("command error '%s': %s", cmd, table.concat(stderr_data)))
local cmd_str = table.concat(cmd, ' ')
man_error(string.format("command error '%s': %s", cmd_str, table.concat(stderr_data)))
end
return table.concat(stdout_data)
@ -269,14 +269,14 @@ local function get_path(sect, name, silent)
--
-- Finally, we can avoid relying on -S or -s here since they are very
-- inconsistently supported. Instead, call -w with a section and a name.
local args
local cmd
if sect == '' then
args = { find_arg, name }
cmd = { 'man', FIND_ARG, name }
else
args = { find_arg, sect, name }
cmd = { 'man', FIND_ARG, sect, name }
end
local lines = man_system(args, silent)
local lines = system(cmd, silent)
local results = vim.split(lines or {}, '\n', { trimempty = true })
if #results == 0 then
@ -342,7 +342,7 @@ end
-- 2. If it still could not be found, then we try again without a section.
-- 3. If still not found but $MANSECT is set, then we try again with $MANSECT
-- unset.
local function verify_exists(sect, name)
local function verify_exists(sect, name, silent)
if sect and sect ~= '' then
local ret = get_path(sect, name, true)
if ret then
@ -378,8 +378,10 @@ local function verify_exists(sect, name)
end
end
-- finally, if that didn't work, there is no hope
man_error('no manual entry for ' .. name)
if not silent then
-- finally, if that didn't work, there is no hope
man_error('no manual entry for ' .. name)
end
end
local EXT_RE = vim.regex([[\.\%([glx]z\|bz2\|lzma\|Z\)$]])
@ -434,12 +436,12 @@ local function get_page(path, silent)
manwidth = api.nvim_win_get_width(0)
end
local args = localfile_arg and { '-l', path } or { path }
local cmd = localfile_arg and { 'man', '-l', path } or { 'man', path }
-- Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).
-- http://comments.gmane.org/gmane.editors.vim.devel/29085
-- Set MAN_KEEP_FORMATTING so Debian man doesn't discard backspaces.
return man_system(args, silent, {
return system(cmd, silent, {
'MANPAGER=cat',
'MANWIDTH=' .. manwidth,
'MAN_KEEP_FORMATTING=1',
@ -480,38 +482,40 @@ local function format_candidate(path, psect)
return ''
end
local function get_paths(sect, name, do_fallback)
-- callers must try-catch this, as some `man` implementations don't support `s:find_arg`
local ok, ret = pcall(function()
local mandirs =
table.concat(vim.split(man_system({ find_arg }), '[:\n]', { trimempty = true }), ',')
local paths = fn.globpath(mandirs, 'man?/' .. name .. '*.' .. sect .. '*', false, true)
pcall(function()
-- Prioritize the result from verify_exists as it obeys b:man_default_sects.
local first = verify_exists(sect, name)
paths = vim.tbl_filter(function(v)
return v ~= first
end, paths)
paths = { first, unpack(paths) }
end)
return paths
end)
local function move_elem_to_head(list, elem)
local list1 = vim.tbl_filter(function(v)
return v ~= elem
end, list)
return { elem, unpack(list1) }
end
if not ok then
if not do_fallback then
error(ret)
end
local function get_paths(sect, name)
-- Try several sources for getting the list man directories:
-- 1. `man -w` (works on most systems)
-- 2. `manpath`
-- 3. $MANPATH
local mandirs_raw = vim.F.npcall(system, { 'man', FIND_ARG })
or vim.F.npcall(system, { 'manpath', '-q' })
or vim.env.MANPATH
-- Fallback to a single path, with the page we're trying to find.
ok, ret = pcall(verify_exists, sect, name)
return { ok and ret or nil }
if not mandirs_raw then
man_error("Could not determine man directories from: 'man -w', 'manpath' or $MANPATH")
end
return ret or {}
local mandirs = table.concat(vim.split(mandirs_raw, '[:\n]', { trimempty = true }), ',')
local paths = fn.globpath(mandirs, 'man?/' .. name .. '*.' .. sect .. '*', false, true)
-- Prioritize the result from verify_exists as it obeys b:man_default_sects.
local first = verify_exists(sect, name, true)
if first then
paths = move_elem_to_head(paths, first)
end
return paths
end
local function complete(sect, psect, name)
local pages = get_paths(sect, name, false)
local pages = get_paths(sect, name)
-- We remove duplicates in case the same manpage in different languages was found.
return fn.uniq(fn.sort(vim.tbl_map(function(v)
return format_candidate(v, psect)
@ -587,7 +591,7 @@ end
function M.goto_tag(pattern, _, _)
local sect, name = extract_sect_and_name_ref(pattern)
local paths = get_paths(sect, name, true)
local paths = get_paths(sect, name)
local structured = {}
for _, path in ipairs(paths) do