diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
| commit | 9be89f131f87608f224f0ee06d199fcd09d32176 (patch) | |
| tree | 11022dcfa9e08cb4ac5581b16734196128688d48 /runtime/lua | |
| parent | ff7ed8f586589d620a806c3758fac4a47a8e7e15 (diff) | |
| parent | 88085c2e80a7e3ac29aabb6b5420377eed99b8b6 (diff) | |
| download | rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.gz rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.bz2 rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.zip | |
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'runtime/lua')
74 files changed, 7378 insertions, 4589 deletions
diff --git a/runtime/lua/editorconfig.lua b/runtime/lua/editorconfig.lua index dcd7425c29..e65d267a70 100644 --- a/runtime/lua/editorconfig.lua +++ b/runtime/lua/editorconfig.lua @@ -190,6 +190,27 @@ function properties.insert_final_newline(bufnr, val) end end +--- A code of the format ss or ss-TT, where ss is an ISO 639 language code and TT is an ISO 3166 territory identifier. +--- Sets the 'spelllang' option. +function properties.spelling_language(bufnr, val) + local error_msg = + 'spelling_language must be of the format ss or ss-TT, where ss is an ISO 639 language code and TT is an ISO 3166 territory identifier.' + + assert(val:len() == 2 or val:len() == 5, error_msg) + + local language_code = val:sub(1, 2):lower() + assert(language_code:match('%l%l'), error_msg) + if val:len() == 2 then + vim.bo[bufnr].spelllang = language_code + else + assert(val:sub(3, 3) == '-', error_msg) + + local territory_code = val:sub(4, 5):lower() + assert(territory_code:match('%l%l'), error_msg) + vim.bo[bufnr].spelllang = language_code .. '_' .. territory_code + end +end + --- @private --- Modified version of [glob2regpat()] that does not match path separators on `*`. --- diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua index 02e841030f..fce8f89be8 100644 --- a/runtime/lua/man.lua +++ b/runtime/lua/man.lua @@ -35,7 +35,7 @@ local function highlight_line(line, linenr) ---@type string[] local chars = {} local prev_char = '' - local overstrike, escape = false, false + local overstrike, escape, osc8 = false, false, false ---@type table<integer,{attr:integer,start:integer,final:integer}> local hls = {} -- Store highlight groups as { attr, start, final } @@ -139,6 +139,12 @@ local function highlight_line(line, linenr) prev_char = '' byte = byte + #char chars[#chars + 1] = char + elseif osc8 then + -- eat characters until String Terminator or bell + if (prev_char == '\027' and char == '\\') or char == '\a' then + osc8 = false + end + prev_char = char elseif escape then -- Use prev_char to store the escape sequence prev_char = prev_char .. char @@ -157,8 +163,11 @@ local function highlight_line(line, linenr) add_attr_hl(match + 0) -- coerce to number end escape = false - elseif not prev_char:match('^%[[\032-\063]*$') then - -- Stop looking if this isn't a partial CSI sequence + elseif prev_char == ']8;' then + osc8 = true + escape = false + elseif not prev_char:match('^[][][\032-\063]*$') then + -- Stop looking if this isn't a partial CSI or OSC sequence escape = false end elseif char == '\027' then @@ -470,7 +479,13 @@ local function put_page(page) -- XXX: nroff justifies text by filling it with whitespace. That interacts -- badly with our use of $MANWIDTH=999. Hack around this by using a fixed -- size for those whitespace regions. - vim.cmd([[silent! keeppatterns keepjumps %s/\s\{199,}/\=repeat(' ', 10)/g]]) + -- Use try/catch to avoid setting v:errmsg. + vim.cmd([[ + try + keeppatterns keepjumps %s/\s\{199,}/\=repeat(' ', 10)/g + catch + endtry + ]]) vim.cmd('1') -- Move cursor to first line highlight_man_page() set_options() @@ -708,7 +723,7 @@ function M.open_page(count, smods, args) end sect, name = extract_sect_and_name_path(path) - local buf = fn.bufnr() + local buf = api.nvim_get_current_buf() local save_tfu = vim.bo[buf].tagfunc vim.bo[buf].tagfunc = "v:lua.require'man'.goto_tag" @@ -724,7 +739,9 @@ function M.open_page(count, smods, args) end end) - vim.bo[buf].tagfunc = save_tfu + if api.nvim_buf_is_valid(buf) then + vim.bo[buf].tagfunc = save_tfu + end if not ok then error(ret) diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 505de720ba..ed42b28725 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -1,6 +1,6 @@ --- @brief ---<pre>help ----:TOhtml {file} *:TOhtml* +---:[range]TOhtml {file} *:TOhtml* ---Converts the buffer shown in the current window to HTML, opens the generated ---HTML in a new split window, and saves its contents to {file}. If {file} is not ---given, a temporary file (created by |tempname()|) is used. @@ -40,13 +40,14 @@ --- @field winid integer --- @field bufnr integer --- @field width integer ---- @field buflen integer +--- @field start integer +--- @field end_ integer --- @class (private) vim.tohtml.styletable --- @field [integer] vim.tohtml.line (integer: (1-index, exclusive)) --- @class (private) vim.tohtml.line ---- @field virt_lines {[integer]:{[1]:string,[2]:integer}[]} +--- @field virt_lines {[integer]:[string,integer][]} --- @field pre_text string[][] --- @field hide? boolean --- @field [integer] vim.tohtml.cell? (integer: (1-index, exclusive)) @@ -57,6 +58,24 @@ --- @field [3] any[][] virt_text --- @field [4] any[][] overlay_text +--- @type string[] +local notifications = {} + +---@param msg string +local function notify(msg) + if #notifications == 0 then + vim.schedule(function() + if #notifications > 1 then + vim.notify(('TOhtml: %s (+ %d more warnings)'):format(notifications[1], #notifications - 1)) + elseif #notifications == 1 then + vim.notify('TOhtml: ' .. notifications[1]) + end + notifications = {} + end) + end + table.insert(notifications, msg) +end + local HIDE_ID = -1 -- stylua: ignore start local cterm_8_to_hex={ @@ -168,6 +187,8 @@ local background_color_cache = nil --- @type string? local foreground_color_cache = nil +local len = vim.api.nvim_strwidth + --- @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands --- @param color "background"|"foreground"|integer --- @return string? @@ -215,7 +236,7 @@ local function cterm_to_hex(colorstr) if hex then cterm_color_cache[color] = hex else - vim.notify_once("Info(TOhtml): Couldn't get terminal colors, using fallback") + notify("Couldn't get terminal colors, using fallback") local t_Co = tonumber(vim.api.nvim_eval('&t_Co')) if t_Co <= 8 then cterm_color_cache = cterm_8_to_hex @@ -241,7 +262,7 @@ local function get_background_color() end local hex = try_query_terminal_color('background') if not hex or not hex:match('#%x%x%x%x%x%x') then - vim.notify_once("Info(TOhtml): Couldn't get terminal background colors, using fallback") + notify("Couldn't get terminal background colors, using fallback") hex = vim.o.background == 'light' and '#ffffff' or '#000000' end background_color_cache = hex @@ -259,7 +280,7 @@ local function get_foreground_color() end local hex = try_query_terminal_color('foreground') if not hex or not hex:match('#%x%x%x%x%x%x') then - vim.notify_once("Info(TOhtml): Couldn't get terminal foreground colors, using fallback") + notify("Couldn't get terminal foreground colors, using fallback") hex = vim.o.background == 'light' and '#000000' or '#ffffff' end foreground_color_cache = hex @@ -292,9 +313,12 @@ local function style_line_insert_virt_text(style_line, col, val) end --- @param state vim.tohtml.state ---- @param hl string|integer|nil +--- @param hl string|integer|string[]|integer[]? --- @return nil|integer local function register_hl(state, hl) + if type(hl) == 'table' then + hl = hl[#hl] + end if type(hl) == 'nil' then return elseif type(hl) == 'string' then @@ -370,7 +394,7 @@ end --- @param state vim.tohtml.state local function styletable_syntax(state) - for row = 1, state.buflen do + for row = state.start, state.end_ do local prev_id = 0 local prev_col = nil for col = 1, #vim.fn.getline(row) + 1 do @@ -390,7 +414,7 @@ end --- @param state vim.tohtml.state local function styletable_diff(state) local styletable = state.style - for row = 1, state.buflen do + for row = state.start, state.end_ do local style_line = styletable[row] local filler = vim.fn.diff_filler(row) if filler ~= 0 then @@ -400,7 +424,7 @@ local function styletable_diff(state) { { fill:rep(state.width), register_hl(state, 'DiffDelete') } } ) end - if row == state.buflen + 1 then + if row == state.end_ + 1 then break end local prev_id = 0 @@ -442,7 +466,9 @@ local function styletable_treesitter(state) if not query then return end - for capture, node, metadata in query:iter_captures(root, buf_highlighter.bufnr, 0, state.buflen) do + for capture, node, metadata in + query:iter_captures(root, buf_highlighter.bufnr, state.start - 1, state.end_) + do local srow, scol, erow, ecol = node:range() --- @diagnostic disable-next-line: invisible local c = q._query.captures[capture] @@ -458,7 +484,7 @@ local function styletable_treesitter(state) end --- @param state vim.tohtml.state ---- @param extmark {[1]:integer,[2]:integer,[3]:integer,[4]:vim.api.keyset.set_extmark|any} +--- @param extmark [integer, integer, integer, vim.api.keyset.set_extmark|any] --- @param namespaces table<integer,string> local function _styletable_extmarks_highlight(state, extmark, namespaces) if not extmark[4].hl_group then @@ -467,7 +493,7 @@ local function _styletable_extmarks_highlight(state, extmark, namespaces) ---TODO(altermo) LSP semantic tokens (and some other extmarks) are only ---generated in visible lines, and not in the whole buffer. if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_semantic_tokens') then - vim.notify_once('Info(TOhtml): lsp semantic tokens are not supported, HTML may be incorrect') + notify('lsp semantic tokens are not supported, HTML may be incorrect') return end local srow, scol, erow, ecol = @@ -480,18 +506,28 @@ local function _styletable_extmarks_highlight(state, extmark, namespaces) end --- @param state vim.tohtml.state ---- @param extmark {[1]:integer,[2]:integer,[3]:integer,[4]:vim.api.keyset.set_extmark|any} -local function _styletable_extmarks_virt_text(state, extmark) +--- @param extmark [integer, integer, integer, vim.api.keyset.set_extmark|any] +--- @param namespaces table<integer,string> +local function _styletable_extmarks_virt_text(state, extmark, namespaces) if not extmark[4].virt_text then return end + ---TODO(altermo) LSP semantic tokens (and some other extmarks) are only + ---generated in visible lines, and not in the whole buffer. + if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_inlayhint') then + notify('lsp inlay hints are not supported, HTML may be incorrect') + return + end local styletable = state.style --- @type integer,integer local row, col = extmark[2], extmark[3] if - extmark[4].virt_text_pos == 'inline' - or extmark[4].virt_text_pos == 'eol' - or extmark[4].virt_text_pos == 'overlay' + row < vim.api.nvim_buf_line_count(state.bufnr) + and ( + extmark[4].virt_text_pos == 'inline' + or extmark[4].virt_text_pos == 'eol' + or extmark[4].virt_text_pos == 'overlay' + ) then if extmark[4].virt_text_pos == 'eol' then style_line_insert_virt_text(styletable[row + 1], #vim.fn.getline(row + 1) + 1, { ' ' }) @@ -510,7 +546,7 @@ local function _styletable_extmarks_virt_text(state, extmark) else style_line_insert_virt_text(styletable[row + 1], col + 1, { i[1], hlid }) end - virt_text_len = virt_text_len + #i[1] + virt_text_len = virt_text_len + len(i[1]) end if extmark[4].virt_text_pos == 'overlay' then styletable_insert_range(state, row + 1, col + 1, row + 1, col + virt_text_len + 1, HIDE_ID) @@ -521,17 +557,15 @@ local function _styletable_extmarks_virt_text(state, extmark) hl_mode = 'blend', hl_group = 'combine', } - for opt, val in ipairs(not_supported) do + for opt, val in pairs(not_supported) do if extmark[4][opt] == val then - vim.notify_once( - ('Info(TOhtml): extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val) - ) + notify(('extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val)) end end end --- @param state vim.tohtml.state ---- @param extmark {[1]:integer,[2]:integer,[3]:integer,[4]:vim.api.keyset.set_extmark|any} +--- @param extmark [integer, integer, integer, vim.api.keyset.set_extmark|any] local function _styletable_extmarks_virt_lines(state, extmark) ---TODO(altermo) if the fold start is equal to virt_line start then the fold hides the virt_line if not extmark[4].virt_lines then @@ -552,7 +586,7 @@ local function _styletable_extmarks_virt_lines(state, extmark) end --- @param state vim.tohtml.state ---- @param extmark {[1]:integer,[2]:integer,[3]:integer,[4]:vim.api.keyset.set_extmark|any} +--- @param extmark [integer, integer, integer, vim.api.keyset.set_extmark|any] local function _styletable_extmarks_conceal(state, extmark) if not extmark[4].conceal or state.opt.conceallevel == 0 then return @@ -586,7 +620,7 @@ local function styletable_extmarks(state) _styletable_extmarks_conceal(state, v) end for _, v in ipairs(extmarks) do - _styletable_extmarks_virt_text(state, v) + _styletable_extmarks_virt_text(state, v, namespaces) end for _, v in ipairs(extmarks) do _styletable_extmarks_virt_lines(state, v) @@ -597,7 +631,7 @@ end local function styletable_folds(state) local styletable = state.style local has_folded = false - for row = 1, state.buflen do + for row = state.start, state.end_ do if vim.fn.foldclosed(row) > 0 then has_folded = true styletable[row].hide = true @@ -611,18 +645,16 @@ local function styletable_folds(state) end end if has_folded and type(({ pcall(vim.api.nvim_eval, vim.o.foldtext) })[2]) == 'table' then - vim.notify_once( - 'Info(TOhtml): foldtext returning a table is half supported, HTML may be incorrect' - ) + notify('foldtext returning a table with highlights is not supported, HTML may be incorrect') end end --- @param state vim.tohtml.state local function styletable_conceal(state) local bufnr = state.bufnr - vim.api.nvim_buf_call(bufnr, function() - for row = 1, state.buflen do - --- @type table<integer,{[1]:integer,[2]:integer,[3]:string}> + vim._with({ buf = bufnr }, function() + for row = state.start, state.end_ do + --- @type table<integer,[integer,integer,string]> local conceals = {} local line_len_exclusive = #vim.fn.getline(row) + 1 for col = 1, line_len_exclusive do @@ -738,8 +770,8 @@ local function styletable_statuscolumn(state) if foldcolumn:match('^auto') then local max = tonumber(foldcolumn:match('^%w-:(%d)')) or 1 local maxfold = 0 - vim.api.nvim_buf_call(state.bufnr, function() - for row = 1, vim.api.nvim_buf_line_count(state.bufnr) do + vim._with({ buf = state.bufnr }, function() + for row = state.start, state.end_ do local foldlevel = vim.fn.foldlevel(row) if foldlevel > maxfold then maxfold = foldlevel @@ -754,12 +786,12 @@ local function styletable_statuscolumn(state) --- @type table<integer,any> local statuses = {} - for row = 1, state.buflen do + for row = state.start, state.end_ do local status = vim.api.nvim_eval_statusline( statuscolumn, { winid = state.winid, use_statuscol_lnum = row, highlights = true } ) - local width = vim.api.nvim_strwidth(status.str) + local width = len(status.str) if width > minwidth then minwidth = width end @@ -774,7 +806,7 @@ local function styletable_statuscolumn(state) for k, v in ipairs(hls) do local text = str:sub(v.start + 1, hls[k + 1] and hls[k + 1].start or nil) if k == #hls then - text = text .. (' '):rep(minwidth - vim.api.nvim_strwidth(str)) + text = text .. (' '):rep(minwidth - len(str)) end if text ~= '' then local hlid = register_hl(state, v.group) @@ -794,7 +826,6 @@ local function styletable_listchars(state) local function utf8_sub(str, i, j) return vim.fn.strcharpart(str, i - 1, j and j - i + 1 or nil) end - local len = vim.api.nvim_strwidth --- @ |