diff options
Diffstat (limited to 'runtime/lua')
-rw-r--r-- | runtime/lua/tohtml.lua | 18 | ||||
-rw-r--r-- | runtime/lua/vim/_defaults.lua | 56 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/options.lua | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/inlay_hint.lua | 7 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/semantic_tokens.lua | 7 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 40 | ||||
-rw-r--r-- | runtime/lua/vim/shared.lua | 13 | ||||
-rw-r--r-- | runtime/lua/vim/ui.lua | 8 |
8 files changed, 101 insertions, 52 deletions
diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 6a5bd6de9d..ed42b28725 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -1293,9 +1293,25 @@ local function opt_to_global_state(opt, title) local fonts = {} if opt.font then fonts = type(opt.font) == 'string' and { opt.font } or opt.font --[[@as (string[])]] + for i, v in pairs(fonts) do + fonts[i] = ('"%s"'):format(v) + end elseif vim.o.guifont:match('^[^:]+') then - table.insert(fonts, vim.o.guifont:match('^[^:]+')) + -- Example: + -- Input: "Font,Escape\,comma, Ignore space after comma" + -- Output: { "Font","Escape,comma","Ignore space after comma" } + local prev = '' + for name in vim.gsplit(vim.o.guifont:match('^[^:]+'), ',', { trimempty = true }) do + if vim.endswith(name, '\\') then + prev = prev .. vim.trim(name:sub(1, -2) .. ',') + elseif vim.trim(name) ~= '' then + table.insert(fonts, ('"%s%s"'):format(prev, vim.trim(name))) + prev = '' + end + end end + -- Generic family names (monospace here) must not be quoted + -- because the browser recognizes them as font families. table.insert(fonts, 'monospace') --- @type vim.tohtml.state.global local state = { diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua index 38cfdbdd32..911cc13e74 100644 --- a/runtime/lua/vim/_defaults.lua +++ b/runtime/lua/vim/_defaults.lua @@ -213,20 +213,48 @@ end --- Default menus do --- Right click popup menu - -- TODO VimScript, no l10n - vim.cmd([[ - vnoremenu PopUp.Cut "+x - vnoremenu PopUp.Copy "+y - anoremenu PopUp.Paste "+gP - vnoremenu PopUp.Paste "+P - vnoremenu PopUp.Delete "_x - nnoremenu PopUp.Select\ All ggVG - vnoremenu PopUp.Select\ All gg0oG$ - inoremenu PopUp.Select\ All <C-Home><C-O>VG - anoremenu PopUp.Inspect <Cmd>Inspect<CR> - anoremenu PopUp.-1- <Nop> - anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR> - ]]) + local function def_menu(ctx) + vim.cmd([[ + anoremenu PopUp.Go\ to\ definition <Cmd>lua vim.lsp.buf.definition()<CR> + amenu PopUp.Open\ in\ web\ browser gx + anoremenu PopUp.Inspect <Cmd>Inspect<CR> + anoremenu PopUp.-1- <Nop> + vnoremenu PopUp.Cut "+x + vnoremenu PopUp.Copy "+y + anoremenu PopUp.Paste "+gP + vnoremenu PopUp.Paste "+P + vnoremenu PopUp.Delete "_x + nnoremenu PopUp.Select\ All ggVG + vnoremenu PopUp.Select\ All gg0oG$ + inoremenu PopUp.Select\ All <C-Home><C-O>VG + anoremenu PopUp.-2- <Nop> + anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR> + + amenu disable PopUp.Go\ to\ definition + amenu disable PopUp.Open\ in\ web\ browser + ]]) + + if ctx == 'url' then + vim.cmd([[amenu enable PopUp.Open\ in\ web\ browser]]) + elseif ctx == 'lsp' then + vim.cmd([[anoremenu enable PopUp.Go\ to\ definition]]) + end + end + def_menu() + + local nvim_popupmenu_augroup = vim.api.nvim_create_augroup('nvim_popupmenu', {}) + vim.api.nvim_create_autocmd('MenuPopup', { + pattern = '*', + group = nvim_popupmenu_augroup, + desc = 'Mouse popup menu', + -- nested = true, + callback = function() + local urls = require('vim.ui')._get_urls() + local url = vim.startswith(urls[1], 'http') + local ctx = url and 'url' or (vim.lsp.get_clients({ bufnr = 0 })[1] and 'lsp' or nil) + def_menu(ctx) + end, + }) end --- Default autocommands. See |default-autocmds| diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 05c9b89d77..787e661402 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -558,9 +558,9 @@ vim.wo.bri = vim.wo.breakindent --- list:{n} Adds an additional indent for lines that match a --- numbered or bulleted list (using the --- 'formatlistpat' setting). ---- list:-1 Uses the length of a match with 'formatlistpat' ---- for indentation. --- (default: 0) +--- list:-1 Uses the width of a match with 'formatlistpat' for +--- indentation. --- column:{n} Indent at column {n}. Will overrule the other --- sub-options. Note: an additional indent may be --- added for the 'showbreak' setting. diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 1e224d1bef..4483b083de 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -77,12 +77,7 @@ function M.on_inlayhint(err, result, ctx, _) local col = position.character if col > 0 then local line = lines[position.line + 1] or '' - local ok, convert_result - ok, convert_result = pcall(util._str_byteindex_enc, line, col, client.offset_encoding) - if ok then - return convert_result - end - return math.min(#line, col) + return util._str_byteindex_enc(line, col, client.offset_encoding) end return col end diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua index 2ae86851d1..8182457dd0 100644 --- a/runtime/lua/vim/lsp/semantic_tokens.lua +++ b/runtime/lua/vim/lsp/semantic_tokens.lua @@ -140,12 +140,7 @@ local function tokens_to_ranges(data, bufnr, client, request) local function _get_byte_pos(col) if col > 0 then local buf_line = lines[line + 1] or '' - local ok, result - ok, result = pcall(util._str_byteindex_enc, buf_line, col, client.offset_encoding) - if ok then - return result - end - return math.min(#buf_line, col) + return util._str_byteindex_enc(buf_line, col, client.offset_encoding) end return col end diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index cbbe3a66b7..09b97ac861 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -119,6 +119,7 @@ end ---@param encoding string|nil utf-8|utf-16|utf-32|nil defaults to utf-16 ---@return integer `encoding` index of `index` in `line` function M._str_utfindex_enc(line, index, encoding) + local len32, len16 = vim.str_utfindex(line) if not encoding then encoding = 'utf-16' end @@ -129,9 +130,15 @@ function M._str_utfindex_enc(line, index, encoding) return #line end elseif encoding == 'utf-16' then + if not index or index > len16 then + return len16 + end local _, col16 = vim.str_utfindex(line, index) return col16 elseif encoding == 'utf-32' then + if not index or index > len32 then + return len32 + end local col32, _ = vim.str_utfindex(line, index) return col32 else @@ -147,6 +154,12 @@ end ---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16 ---@return integer byte (utf-8) index of `encoding` index `index` in `line` function M._str_byteindex_enc(line, index, encoding) + local len = vim.fn.strlen(line) + if index > len then + -- LSP spec: if character > line length, default to the line length. + -- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position + return len + end if not encoding then encoding = 'utf-16' end @@ -165,9 +178,6 @@ function M._str_byteindex_enc(line, index, encoding) end end -local _str_utfindex_enc = M._str_utfindex_enc -local _str_byteindex_enc = M._str_byteindex_enc - --- Replaces text in a range with new text. --- --- CAUTION: Changes in-place! @@ -334,12 +344,7 @@ local function get_line_byte_from_position(bufnr, position, offset_encoding) -- character if col > 0 then local line = get_line(bufnr, position.line) or '' - local ok, result - ok, result = pcall(_str_byteindex_enc, line, col, offset_encoding) - if ok then - return result - end - return math.min(#line, col) + return M._str_byteindex_enc(line, col, offset_encoding or 'utf-16') end return col end @@ -436,14 +441,15 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding) e.end_col = last_line_len has_eol_text_edit = true else - -- If the replacement is over the end of a line (i.e. e.end_col is out of bounds and the + -- If the replacement is over the end of a line (i.e. e.end_col is equal to the line length and the -- replacement text ends with a newline We can likely assume that the replacement is assumed -- to be meant to replace the newline with another newline and we need to make sure this -- doesn't add an extra empty line. E.g. when the last line to be replaced contains a '\r' -- in the file some servers (clangd on windows) will include that character in the line -- while nvim_buf_set_text doesn't count it as part of the line. if - e.end_col > last_line_len + e.end_col >= last_line_len + and text_edit.range['end'].character > e.end_col and #text_edit.newText > 0 and string.sub(text_edit.newText, -1) == '\n' then @@ -1795,8 +1801,10 @@ function M.locations_to_items(locations, offset_encoding) local row = pos.line local end_row = end_pos.line local line = lines[row] or '' + local end_line = lines[end_row] or '' local col = M._str_byteindex_enc(line, pos.character, offset_encoding) - local end_col = M._str_byteindex_enc(lines[end_row] or '', end_pos.character, offset_encoding) + local end_col = M._str_byteindex_enc(end_line, end_pos.character, offset_encoding) + table.insert(items, { filename = filename, lnum = row + 1, @@ -1925,7 +1933,7 @@ local function make_position_param(window, offset_encoding) return { line = 0, character = 0 } end - col = _str_utfindex_enc(line, col, offset_encoding) + col = M._str_utfindex_enc(line, col, offset_encoding) return { line = row, character = col } end @@ -2107,11 +2115,7 @@ function M.character_offset(buf, row, col, offset_encoding) ) offset_encoding = vim.lsp.get_clients({ bufnr = buf })[1].offset_encoding end - -- If the col is past the EOL, use the line length. - if col > #line then - return _str_utfindex_enc(line, nil, offset_encoding) - end - return _str_utfindex_enc(line, col, offset_encoding) + return M._str_utfindex_enc(line, col, offset_encoding) end --- Helper function to return nested values in language server settings diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 2f10380bad..4d06cdd77d 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -354,6 +354,12 @@ function vim.tbl_isempty(t) return next(t) == nil end +--- We only merge empty tables or tables that are not list-like (indexed by consecutive integers +--- starting from 1) +local function can_merge(v) + return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.islist(v)) +end + --- Recursive worker for tbl_extend --- @param behavior 'error'|'keep'|'force' --- @param deep_extend boolean @@ -368,7 +374,7 @@ local function tbl_extend_rec(behavior, deep_extend, ...) local tbl = select(i, ...) --[[@as table<any,any>]] if tbl then for k, v in pairs(tbl) do - if deep_extend and type(v) == 'table' and type(ret[k]) == 'table' then + if deep_extend and can_merge(v) and can_merge(ret[k]) then ret[k] = tbl_extend_rec(behavior, true, ret[k], v) elseif behavior ~= 'force' and ret[k] ~= nil then if behavior == 'error' then @@ -421,6 +427,11 @@ end --- Merges recursively two or more tables. --- +--- Only values that are empty tables or tables that are not |lua-list|s (indexed by consecutive +--- integers starting from 1) are merged recursively. This is useful for merging nested tables +--- like default and user configurations where lists should be treated as literals (i.e., are +--- overwritten instead of merged). +--- ---@see |vim.tbl_extend()| --- ---@generic T1: table diff --git a/runtime/lua/vim/ui.lua b/runtime/lua/vim/ui.lua index 2d3b828ea1..3617e1d702 100644 --- a/runtime/lua/vim/ui.lua +++ b/runtime/lua/vim/ui.lua @@ -152,14 +152,14 @@ function M.open(path) else return nil, 'vim.ui.open: rundll32 not found' end - elseif vim.fn.executable('wslview') == 1 then - cmd = { 'wslview', path } - elseif vim.fn.executable('explorer.exe') == 1 then - cmd = { 'explorer.exe', path } elseif vim.fn.executable('xdg-open') == 1 then cmd = { 'xdg-open', path } opts.stdout = false opts.stderr = false + elseif vim.fn.executable('wslview') == 1 then + cmd = { 'wslview', path } + elseif vim.fn.executable('explorer.exe') == 1 then + cmd = { 'explorer.exe', path } else return nil, 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)' end |