diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/autoload/health/provider.vim | 2 | ||||
-rw-r--r-- | runtime/autoload/provider/pythonx.vim | 2 | ||||
-rw-r--r-- | runtime/doc/autocmd.txt | 1 | ||||
-rw-r--r-- | runtime/doc/editing.txt | 4 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 7 | ||||
-rw-r--r-- | runtime/doc/lsp.txt | 9 | ||||
-rw-r--r-- | runtime/doc/lua.txt | 99 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 4 | ||||
-rw-r--r-- | runtime/filetype.vim | 3 | ||||
-rw-r--r-- | runtime/lua/vim/highlight.lua | 60 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 63 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/callbacks.lua | 6 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/log.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 121 | ||||
-rw-r--r-- | runtime/lua/vim/shared.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/uri.lua | 10 | ||||
-rw-r--r-- | runtime/pack/dist/opt/termdebug/plugin/termdebug.vim | 21 |
18 files changed, 330 insertions, 89 deletions
diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim index 6d481e9f49..4975dc66b8 100644 --- a/runtime/autoload/health/provider.vim +++ b/runtime/autoload/health/provider.vim @@ -581,7 +581,7 @@ function! s:check_ruby() abort endif call health#report_info('Host: '. host) - let latest_gem_cmd = has('win32') ? 'cmd /c gem list -ra ^^neovim$' : 'gem list -ra ^neovim$' + let latest_gem_cmd = has('win32') ? 'cmd /c gem list -ra "^^neovim$"' : 'gem list -ra ^neovim$' let latest_gem = s:system(split(latest_gem_cmd)) if s:shell_error || empty(latest_gem) call health#report_error('Failed to run: '. latest_gem_cmd, diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index 23e7ff8f64..ffb9bf3021 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -29,7 +29,7 @@ endfunction function! s:get_python_candidates(major_version) abort return { \ 2: ['python2', 'python2.7', 'python2.6', 'python'], - \ 3: ['python3', 'python3.8', 'python3.7', 'python3.6', 'python3.5', + \ 3: ['python3', 'python3.9', 'python3.8', 'python3.7', 'python3.6', 'python3.5', \ 'python3.4', 'python3.3', 'python'] \ }[a:major_version] endfunction diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 64ca7b6a45..f1753b75cc 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -844,6 +844,7 @@ TextYankPost Just after a |yank| or |deleting| command, but not regcontents regname regtype + visual The `inclusive` flag combined with the |'[| and |']| marks can be used to calculate the precise region of the operation. diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 23a65f16e4..ac398ec494 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1265,7 +1265,7 @@ exist, the next-higher scope in the hierarchy applies. other tabs and windows is not changed. *:tcd-* -:tcd[!] - Change to the previous current directory (before the +:tc[d][!] - Change to the previous current directory (before the previous ":tcd {path}" command). *:tch* *:tchdir* @@ -1280,7 +1280,7 @@ exist, the next-higher scope in the hierarchy applies. :lch[dir][!] Same as |:lcd|. *:lcd-* -:lcd[!] - Change to the previous current directory (before the +:lc[d][!] - Change to the previous current directory (before the previous ":lcd {path}" command). *:pw* *:pwd* *E187* diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 1992c34102..7f50769023 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1423,6 +1423,10 @@ PREDEFINED VIM VARIABLES *vim-variable* *v:var* *v:* *E963* Some variables can be set by the user, but the type cannot be changed. + *v:argv* *argv-variable* +v:argv The command line arguments Vim was invoked with. This is a + list of strings. The first item is the Vim command. + *v:beval_col* *beval_col-variable* v:beval_col The number of the column, over which the mouse pointer is. This is the byte index in the |v:beval_lnum| line. @@ -1587,6 +1591,8 @@ v:event Dictionary of event data for the current |autocommand|. Valid operation. regtype Type of register as returned by |getregtype()|. + visual Selection is visual (as opposed to, + e.g., via motion). completed_item Current selected complete item on |CompleteChanged|, Is `{}` when no complete item selected. @@ -2600,6 +2606,7 @@ argv([{nr} [, {winid}]) the whole |arglist| is returned. The {winid} argument specifies the window ID, see |argc()|. + For the Vim command line arguments see |v:argv|. assert_beeps({cmd}) *assert_beeps()* Run {cmd} and add an error message to |v:errors| if it does diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 9460e600e3..9deaf26983 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1042,15 +1042,10 @@ get_current_line_to_cursor() get_severity_highlight_name({severity}) TODO: Documentation - *vim.lsp.util.highlight_range()* -highlight_range({bufnr}, {ns}, {hiname}, {start}, {finish}) - TODO: Documentation - - *vim.lsp.util.highlight_region()* -highlight_region({ft}, {start}, {finish}) +jump_to_location({location}) *vim.lsp.util.jump_to_location()* TODO: Documentation -jump_to_location({location}) *vim.lsp.util.jump_to_location()* +preview_location({location}) *vim.lsp.util.preview_location()* TODO: Documentation locations_to_items({locations}) *vim.lsp.util.locations_to_items()* diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 09034353a3..5a49d36503 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -693,6 +693,41 @@ identical identifiers, highlighting both as |hl-WarningMsg|: > (eq? @WarningMsg.left @WarningMsg.right)) ------------------------------------------------------------------------------ +VIM.HIGHLIGHT *lua-highlight* + +Nvim includes a function for highlighting a selection on yank (see for example +https://github.com/machakann/vim-highlightedyank). To enable it, add +> + au TextYankPost * silent! lua require'vim.highlight'.on_yank() +< +to your `init.vim`. You can customize the highlight group and the duration of +the highlight via +> + au TextYankPost * silent! lua require'vim.highlight'.on_yank("IncSearch", 500) +< +If you want to exclude visual selections from highlighting on yank, use +> +au TextYankPost * silent! lua return (not vim.v.event.visual) and require'vim.highlight'.on_yank() +< + +vim.highlight.on_yank([{higroup}, {timeout}, {event}]) + *vim.highlight.on_yank()* + Highlights the yanked text. Optional arguments are the highlight group + to use ({higroup}, default `"IncSearch"`), the duration of highlighting + in milliseconds ({timeout}, default `500`), and the event structure + that is fired ({event}, default `vim.v.event`). + + +vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {rtype}, {inclusive}) + *vim.highlight.range()* + Highlights the range between {start} and {finish} (tuples of {line,col}) + in buffer {bufnr} with the highlight group {higroup} using the namespace + {ns}. Optional arguments are the type of rangeĀ (characterwise, linewise, + or blockwise, see |setreg|; default to characterwise) and whether the + range is inclusive (default false). + + +------------------------------------------------------------------------------ VIM.REGEX *lua-regex* Vim regexes can be used directly from lua. Currently they only allow @@ -758,6 +793,14 @@ vim.empty_dict() *vim.empty_dict()* Note: if numeric keys are added to the table, the metatable will be ignored and the dict converted to a list/array anyway. +vim.region({bufnr}, {pos1}, {pos2}, {type}, {inclusive}) *vim.region()* + Converts a selection specified by the buffer ({bufnr}), starting + position ({pos1}, a zero-indexed pair `{line1,column1}`), ending + position ({pos2}, same format as {pos1}), the type of the register + for the selection ({type}, see |regtype|), and a boolean indicating + whether the selection is inclusive or not, into a zero-indexed table + of linewise selections of the form `{linenr = {startcol, endcol}}` . + vim.rpcnotify({channel}, {method}[, {args}...]) *vim.rpcnotify()* Sends {event} to {channel} via |RPC| and returns immediately. If {channel} is 0, the event is broadcast to all channels. @@ -798,6 +841,62 @@ vim.schedule({callback}) *vim.schedule()* Schedules {callback} to be invoked soon by the main event-loop. Useful to avoid |textlock| or other temporary restrictions. + +vim.defer_fn({fn}, {timeout}) *vim.defer_fn* + Defers calling {fn} until {timeout} ms passes. Use to do a one-shot timer + that calls {fn}. + + Parameters: ~ + {fn} Callback to call once {timeout} expires + {timeout} Time in ms to wait before calling {fn} + + Returns: ~ + |vim.loop|.new_timer() object + +vim.wait({time}, {callback} [, {interval}]) *vim.wait()* + Wait for {time} in milliseconds until {callback} returns `true`. + + Executes {callback} immediately and at approximately {interval} + milliseconds (default 200). Nvim still processes other events during + this time. + + + Returns: ~ + If {callback} returns `true` during the {time}: + `true, nil` + + If {callback} never returns `true` during the {time}: + `false, -1` + + If {callback} is interrupted during the {time}: + `false, -2` + + If {callback} errors, the error is raised. + + Examples: > + + --- + -- Wait for 100 ms, allowing other events to process + vim.wait(100, function() end) + + --- + -- Wait for 100 ms or until global variable set. + vim.wait(100, function() return vim.g.waiting_for_var end) + + --- + -- Wait for 1 second or until global variable set, checking every ~500 ms + vim.wait(1000, function() return vim.g.waiting_for_var end, 500) + + --- + -- Schedule a function to set a value in 100ms + vim.defer_fn(function() vim.g.timer_result = true end, 100) + + -- Would wait ten seconds if results blocked. Actually only waits 100 ms + if vim.wait(10000, function() return vim.g.timer_result end) then + print('Only waiting a little bit of time!') + end +< + vim.fn.{func}({...}) *vim.fn* Invokes |vim-function| or |user-function| {func} with arguments {...}. To call autoload functions, use the syntax: > diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 376375e4ef..24b562543e 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -116,6 +116,10 @@ backwards-compatibility cost. Some examples: - Directories for 'directory' and 'undodir' are auto-created. - Terminal features such as 'guicursor' are enabled where possible. +Some features are built in that otherwise required external plugins: + +- Highlighting the yanked region, see |lua-highlight|. + ARCHITECTURE ~ External plugins run in separate processes. |remote-plugin| This improves diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 0b5003dc44..b29168984c 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -543,6 +543,9 @@ au BufNewFile,BufRead */etc/elinks.conf,*/.elinks/elinks.conf setf elinks " ERicsson LANGuage; Yaws is erlang too au BufNewFile,BufRead *.erl,*.hrl,*.yaws setf erlang +" Elm +au BufNewFile,BufRead *.elm setf elm + " Elm Filter Rules file au BufNewFile,BufRead filter-rules setf elmfilt diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua new file mode 100644 index 0000000000..69c3c8a4dc --- /dev/null +++ b/runtime/lua/vim/highlight.lua @@ -0,0 +1,60 @@ +local api = vim.api + +local highlight = {} + +--- Highlight range between two positions +--- +--@param bufnr number of buffer to apply highlighting to +--@param ns namespace to add highlight to +--@param higroup highlight group to use for highlighting +--@param rtype type of range (:help setreg, default charwise) +--@param inclusive boolean indicating whether the range is end-inclusive (default false) +function highlight.range(bufnr, ns, higroup, start, finish, rtype, inclusive) + rtype = rtype or 'v' + inclusive = inclusive or false + + -- sanity check + if start[2] < 0 or finish[2] < start[2] then return end + + local region = vim.region(bufnr, start, finish, rtype, inclusive) + for linenr, cols in pairs(region) do + api.nvim_buf_add_highlight(bufnr, ns, higroup, linenr, cols[1], cols[2]) + end + +end + +--- Highlight the yanked region +--- +--- use from init.vim via +--- au TextYankPost * lua require'vim.highlight'.on_yank() +--- customize highlight group and timeout via +--- au TextYankPost * lua require'vim.highlight'.on_yank("IncSearch", 500) +--- +-- @param higroup highlight group for yanked region +-- @param timeout time in ms before highlight is cleared +-- @param event event structure +function highlight.on_yank(higroup, timeout, event) + event = event or vim.v.event + if event.operator ~= 'y' or event.regtype == '' then return end + higroup = higroup or "IncSearch" + timeout = timeout or 500 + + local bufnr = api.nvim_get_current_buf() + local yank_ns = api.nvim_create_namespace('') + api.nvim_buf_clear_namespace(bufnr, yank_ns, 0, -1) + + local pos1 = vim.fn.getpos("'[") + local pos2 = vim.fn.getpos("']") + + pos1 = {pos1[2] - 1, pos1[3] - 1 + pos1[4]} + pos2 = {pos2[2] - 1, pos2[3] - 1 + pos2[4]} + + highlight.range(bufnr, yank_ns, higroup, pos1, pos2, event.regtype, event.inclusive) + + vim.defer_fn( + function() api.nvim_buf_clear_namespace(bufnr, yank_ns, 0, -1) end, + timeout + ) +end + +return highlight diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 61da2130c8..84812b8c64 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -46,31 +46,6 @@ local function is_dir(filename) return stat and stat.type == 'directory' or false end --- TODO Use vim.wait when that is available, but provide an alternative for now. -local wait = vim.wait or function(timeout_ms, condition, interval) - validate { - timeout_ms = { timeout_ms, 'n' }; - condition = { condition, 'f' }; - interval = { interval, 'n', true }; - } - assert(timeout_ms > 0, "timeout_ms must be > 0") - local _ = log.debug() and log.debug("wait.fallback", timeout_ms) - interval = interval or 200 - local interval_cmd = "sleep "..interval.."m" - local timeout = timeout_ms + uv.now() - -- TODO is there a better way to sync this? - while true do - uv.update_time() - if condition() then - return 0 - end - if uv.now() >= timeout then - return -1 - end - nvim_command(interval_cmd) - -- vim.loop.sleep(10) - end -end local wait_result_reason = { [-1] = "timeout"; [-2] = "interrupted"; [-3] = "error" } local valid_encodings = { @@ -122,19 +97,19 @@ local function validate_encoding(encoding) end function lsp._cmd_parts(input) - local cmd, cmd_args - if vim.tbl_islist(input) then - cmd = input[1] - cmd_args = {} - -- Don't mutate our input. - for i, v in ipairs(input) do - assert(type(v) == 'string', "input arguments must be strings") - if i > 1 then - table.insert(cmd_args, v) - end + vim.validate{cmd={ + input, + function() return vim.tbl_islist(input) end, + "list"}} + + local cmd = input[1] + local cmd_args = {} + -- Don't mutate our input. + for i, v in ipairs(input) do + vim.validate{["cmd argument"]={v, "s"}} + if i > 1 then + table.insert(cmd_args, v) end - else - error("cmd type must be list.") end return cmd, cmd_args end @@ -524,7 +499,7 @@ function lsp.start_client(config) function client.request(method, params, callback, bufnr) if not callback then callback = resolve_callback(method) - or error("not found: request callback for client "..client.name) + or error(string.format("not found: %q request callback for client %q.", method, client.name)) end local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, callback, bufnr) -- TODO keep these checks or just let it go anyway? @@ -810,8 +785,8 @@ function lsp._vim_exit_handler() for _, client in pairs(active_clients) do client.stop() end - local wait_result = wait(500, function() return tbl_isempty(active_clients) end, 50) - if wait_result ~= 0 then + + if not vim.wait(500, function() return tbl_isempty(active_clients) end, 50) then for _, client in pairs(active_clients) do client.stop(true) end @@ -889,12 +864,14 @@ function lsp.buf_request_sync(bufnr, method, params, timeout_ms) for _ in pairs(client_request_ids) do expected_result_count = expected_result_count + 1 end - local wait_result = wait(timeout_ms or 100, function() + + local wait_result, reason = vim.wait(timeout_ms or 100, function() return result_count >= expected_result_count end, 10) - if wait_result ~= 0 then + + if not wait_result then cancel() - return nil, wait_result_reason[wait_result] + return nil, wait_result_reason[reason] end return request_results end diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua index 37e9f1e5c1..7c51fc2cc2 100644 --- a/runtime/lua/vim/lsp/callbacks.lua +++ b/runtime/lua/vim/lsp/callbacks.lua @@ -242,12 +242,12 @@ end -- Add boilerplate error validation and logging for all of these. for k, fn in pairs(M) do - M[k] = function(err, method, params, client_id) - local _ = log.debug() and log.debug('default_callback', method, { params = params, client_id = client_id, err = err }) + M[k] = function(err, method, params, client_id, bufnr) + log.debug('default_callback', method, { params = params, client_id = client_id, err = err, bufnr = bufnr }) if err then error(tostring(err)) end - return fn(err, method, params, client_id) + return fn(err, method, params, client_id, bufnr) end end diff --git a/runtime/lua/vim/lsp/log.lua b/runtime/lua/vim/lsp/log.lua index 78aabf08ce..696ce43a59 100644 --- a/runtime/lua/vim/lsp/log.lua +++ b/runtime/lua/vim/lsp/log.lua @@ -24,7 +24,7 @@ do local function path_join(...) return table.concat(vim.tbl_flatten{...}, path_sep) end - local logfilename = path_join(vim.fn.stdpath('data'), 'vim-lsp.log') + local logfilename = path_join(vim.fn.stdpath('data'), 'lsp.log') --- Return the log filename. function log.get_filename() diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 877d11411b..7d5f8f5ef1 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -633,8 +633,7 @@ function protocol.make_client_capabilities() dynamicRegistration = false; completionItem = { - -- TODO(tjdevries): Is it possible to implement this in plain lua? - snippetSupport = false; + snippetSupport = true; commitCharactersSupport = false; preselectSupport = false; deprecatedSupport = false; diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 1b099fb3f4..02d233fb7b 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -3,6 +3,7 @@ local vim = vim local validate = vim.validate local api = vim.api local list_extend = vim.list_extend +local highlight = require 'vim.highlight' local M = {} @@ -199,6 +200,66 @@ function M.get_current_line_to_cursor() return line:sub(pos[2]+1) end +local function parse_snippet_rec(input, inner) + local res = "" + + local close, closeend = nil, nil + if inner then + close, closeend = input:find("}", 1, true) + while close ~= nil and input:sub(close-1,close-1) == "\\" do + close, closeend = input:find("}", closeend+1, true) + end + end + + local didx = input:find('$', 1, true) + if didx == nil and close == nil then + return input, "" + elseif close ~=nil and (didx == nil or close < didx) then + -- No inner placeholders + return input:sub(0, close-1), input:sub(closeend+1) + end + + res = res .. input:sub(0, didx-1) + input = input:sub(didx+1) + + local tabstop, tabstopend = input:find('^%d+') + local placeholder, placeholderend = input:find('^{%d+:') + local choice, choiceend = input:find('^{%d+|') + + if tabstop then + input = input:sub(tabstopend+1) + elseif choice then + input = input:sub(choiceend+1) + close, closeend = input:find("|}", 1, true) + + res = res .. input:sub(0, close-1) + input = input:sub(closeend+1) + elseif placeholder then + -- TODO: add support for variables + input = input:sub(placeholderend+1) + + -- placeholders and variables are recursive + while input ~= "" do + local r, tail = parse_snippet_rec(input, true) + r = r:gsub("\\}", "}") + + res = res .. r + input = tail + end + else + res = res .. "$" + end + + return res, input +end + +-- Parse completion entries, consuming snippet tokens +function M.parse_snippet(input) + local res, _ = parse_snippet_rec(input, false) + + return res +end + -- Sort by CompletionItem.sortText -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion local function sort_completion_items(items) @@ -213,9 +274,17 @@ end -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion local function get_completion_word(item) if item.textEdit ~= nil and item.textEdit.newText ~= nil then - return item.textEdit.newText + if protocol.InsertTextFormat[item.insertTextFormat] == "PlainText" then + return item.textEdit.newText + else + return M.parse_snippet(item.textEdit.newText) + end elseif item.insertText ~= nil then - return item.insertText + if protocol.InsertTextFormat[item.insertTextFormat] == "PlainText" then + return item.insertText + else + return M.parse_snippet(item.insertText) + end end return item.label end @@ -479,6 +548,28 @@ function M.jump_to_location(location) return true end +--- Preview a location in a floating windows +--- +--- behavior depends on type of location: +--- - for Location, range is shown (e.g., function definition) +--- - for LocationLink, targetRange is shown (e.g., body of function definition) +--- +--@param location a single Location or LocationLink +--@return bufnr,winnr buffer and window number of floating window or nil +function M.preview_location(location) + -- location may be LocationLink or Location (more useful for the former) + local uri = location.targetUri or location.uri + if uri == nil then return end + local bufnr = vim.uri_to_bufnr(uri) + if not api.nvim_buf_is_loaded(bufnr) then + vim.fn.bufload(bufnr) + end + local range = location.targetRange or location.range + local contents = api.nvim_buf_get_lines(bufnr, range.start.line, range["end"].line+1, false) + local filetype = api.nvim_buf_get_option(bufnr, 'filetype') + return M.open_floating_preview(contents, filetype) +end + local function find_window_by_var(name, value) for _, win in ipairs(api.nvim_list_wins()) do if npcall(api.nvim_win_get_var, win, name) == value then @@ -599,7 +690,7 @@ function M.fancy_floating_markdown(contents, opts) vim.cmd("ownsyntax markdown") local idx = 1 - local function highlight_region(ft, start, finish) + local function apply_syntax_to_region(ft, start, finish) if ft == '' then return end local name = ft..idx idx = idx + 1 @@ -615,8 +706,8 @@ function M.fancy_floating_markdown(contents, opts) -- make sure that regions between code blocks are definitely markdown. -- local ph = {start = 0; finish = 1;} for _, h in ipairs(highlights) do - -- highlight_region('markdown', ph.finish, h.start) - highlight_region(h.ft, h.start, h.finish) + -- apply_syntax_to_region('markdown', ph.finish, h.start) + apply_syntax_to_region(h.ft, h.start, h.finish) -- ph = h end @@ -670,19 +761,6 @@ function M.open_floating_preview(contents, filetype, opts) return floating_bufnr, floating_winnr end -local function highlight_range(bufnr, ns, hiname, start, finish) - if start[1] == finish[1] then - -- TODO care about encoding here since this is in byte index? - api.nvim_buf_add_highlight(bufnr, ns, hiname, start[1], start[2], finish[2]) - else - api.nvim_buf_add_highlight(bufnr, ns, hiname, start[1], start[2], -1) - for line = start[1] + 1, finish[1] - 1 do - api.nvim_buf_add_highlight(bufnr, ns, hiname, line, 0, -1) - end - api.nvim_buf_add_highlight(bufnr, ns, hiname, finish[1], 0, finish[2]) - end -end - do local diagnostic_ns = api.nvim_create_namespace("vim_lsp_diagnostics") local reference_ns = api.nvim_create_namespace("vim_lsp_references") @@ -755,7 +833,7 @@ do local lines = {"Diagnostics:"} local highlights = {{0, "Bold"}} local line_diagnostics = M.get_line_diagnostics() - if not line_diagnostics then return end + if vim.tbl_isempty(line_diagnostics) then return end for i, diagnostic in ipairs(line_diagnostics) do -- for i, mark in ipairs(marks) do @@ -816,8 +894,7 @@ do [protocol.DiagnosticSeverity.Hint]='Hint', } - -- TODO care about encoding here since this is in byte index? - highlight_range(bufnr, diagnostic_ns, + highlight.range(bufnr, diagnostic_ns, underline_highlight_name..hlmap[diagnostic.severity], {start.line, start.character}, {finish.line, finish.character} @@ -841,7 +918,7 @@ do [protocol.DocumentHighlightKind.Write] = "LspReferenceWrite"; } local kind = reference["kind"] or protocol.DocumentHighlightKind.Text - highlight_range(bufnr, reference_ns, document_highlight_kind[kind], start_pos, end_pos) + highlight.range(bufnr, reference_ns, document_highlight_kind[kind], start_pos, end_pos) end end diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 2135bfc837..5dc8d6dc10 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -79,7 +79,7 @@ function vim.gsplit(s, sep, plain) end return function() - if done then + if done or s == '' then return end if sep == '' then diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua index e28cc9e20f..9c3535c676 100644 --- a/runtime/lua/vim/uri.lua +++ b/runtime/lua/vim/uri.lua @@ -65,9 +65,11 @@ local function uri_from_fname(path) return table.concat(uri_parts) end +local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*)://.*' + local function uri_from_bufnr(bufnr) local fname = vim.api.nvim_buf_get_name(bufnr) - local scheme = fname:match("^([a-z]+)://.*") + local scheme = fname:match(URI_SCHEME_PATTERN) if scheme then return fname else @@ -76,6 +78,10 @@ local function uri_from_bufnr(bufnr) end local function uri_to_fname(uri) + local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri) + if scheme ~= 'file' then + return uri + end uri = uri_decode(uri) -- TODO improve this. if is_windows_file_uri(uri) then @@ -89,7 +95,7 @@ end -- Return or create a buffer for a uri. local function uri_to_bufnr(uri) - local scheme = assert(uri:match("^([a-z]+)://.*"), 'Uri must contain a scheme: ' .. uri) + local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri) if scheme == 'file' then return vim.fn.bufadd(uri_to_fname(uri)) else diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index aa2b69ad97..28dc3256c7 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -645,7 +645,7 @@ func s:InstallCommands() command Gdb call win_gotoid(s:gdbwin) command Program call win_gotoid(s:ptywin) command Source call s:GotoSourcewinOrCreateIt() - " command Winbar call s:InstallWinbar() + command Winbar call s:InstallWinbar() " TODO: can the K mapping be restored? nnoremap K :Evaluate<CR> @@ -655,6 +655,19 @@ endfunc " let s:winbar_winids = [] +" Install the window toolbar in the current window. +func s:InstallWinbar() + " if has('menu') && &mouse != '' + " nnoremenu WinBar.Step :Step<CR> + " nnoremenu WinBar.Next :Over<CR> + " nnoremenu WinBar.Finish :Finish<CR> + " nnoremenu WinBar.Cont :Continue<CR> + " nnoremenu WinBar.Stop :Stop<CR> + " nnoremenu WinBar.Eval :Evaluate<CR> + " call add(s:winbar_winids, win_getid(winnr())) + " endif +endfunc + " Delete installed debugger commands in the current window. func s:DeleteCommands() delcommand Break @@ -670,7 +683,7 @@ func s:DeleteCommands() delcommand Gdb delcommand Program delcommand Source - " delcommand Winbar + delcommand Winbar nunmap K @@ -940,7 +953,7 @@ func s:GotoSourcewinOrCreateIt() if !win_gotoid(s:sourcewin) new let s:sourcewin = win_getid(winnr()) - " call s:InstallWinbar() + call s:InstallWinbar() endif endfunc @@ -971,7 +984,7 @@ func s:HandleCursor(msg) " TODO: find existing window exe 'split ' . fnameescape(fname) let s:sourcewin = win_getid(winnr()) - " call s:InstallWinbar() + call s:InstallWinbar() else exe 'edit ' . fnameescape(fname) endif |