diff options
Diffstat (limited to 'runtime')
33 files changed, 726 insertions, 188 deletions
diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim index b6297472c3..cf26bc3172 100644 --- a/runtime/autoload/dist/ft.vim +++ b/runtime/autoload/dist/ft.vim @@ -362,6 +362,10 @@ func dist#ft#FTinc() setf aspvbs elseif lines =~ "<?" setf php + " Pascal supports // comments but they're vary rarely used for file + " headers so assume POV-Ray + elseif lines =~ '^\s*\%({\|(\*\)' || lines =~? s:ft_pascal_keywords + setf pascal else call dist#ft#FTasmsyntax() if exists("b:asmsyntax") @@ -408,6 +412,9 @@ func dist#ft#FTprogress_asm() setf progress endfunc +let s:ft_pascal_comments = '^\s*\%({\|(\*\|//\)' +let s:ft_pascal_keywords = '^\s*\%(program\|unit\|library\|uses\|begin\|procedure\|function\|const\|type\|var\)\>' + func dist#ft#FTprogress_pascal() if exists("g:filetype_p") exe "setf " . g:filetype_p @@ -419,8 +426,7 @@ func dist#ft#FTprogress_pascal() let lnum = 1 while lnum <= 10 && lnum < line('$') let line = getline(lnum) - if line =~ '^\s*\(program\|unit\|procedure\|function\|const\|type\|var\)\>' - \ || line =~ '^\s*{' || line =~ '^\s*(\*' + if line =~ s:ft_pascal_comments || line =~? s:ft_pascal_keywords setf pascal return elseif line !~ '^\s*$' || line =~ '^/\*' @@ -433,6 +439,19 @@ func dist#ft#FTprogress_pascal() setf progress endfunc +func dist#ft#FTpp() + if exists("g:filetype_pp") + exe "setf " . g:filetype_pp + else + let line = getline(nextnonblank(1)) + if line =~ s:ft_pascal_comments || line =~? s:ft_pascal_keywords + setf pascal + else + setf puppet + endif + endif +endfunc + func dist#ft#FTr() let max = line("$") > 50 ? 50 : line("$") diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index 99d8c41dba..78a86315a3 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -137,8 +137,6 @@ function! s:put_page(page) abort setlocal modifiable setlocal noreadonly setlocal noswapfile - " git-ls-files(1) is all one keyword/tag-target - setlocal iskeyword+=(,) silent keepjumps %delete _ silent put =a:page while getline(1) =~# '^\s*$' diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 485c93b0dd..a810bef8f6 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -663,6 +663,17 @@ nvim_del_var({name}) *nvim_del_var()* Parameters: ~ {name} Variable name +nvim_echo({chunks}, {history}, {opts}) *nvim_echo()* + Echo a message. + + Parameters: ~ + {chunks} A list of [text, hl_group] arrays, each + representing a text chunk with specified + highlight. `hl_group` element can be omitted + for no highlight. + {history} if true, add to |message-history|. + {opts} Optional parameters. Reserved for future use. + nvim_err_write({str}) *nvim_err_write()* Writes a message to the Vim error buffer. Does not append "\n", the message is buffered (won't display) until a linefeed diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index d04f52de0b..384bdd63a4 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1600,7 +1600,7 @@ v:event Dictionary of event data for the current |autocommand|. Valid regtype Type of register as returned by |getregtype()|. visual Selection is visual (as opposed to, - e.g., via motion). + e.g., via motion). completed_item Current selected complete item on |CompleteChanged|, Is `{}` when no complete item selected. @@ -1783,7 +1783,7 @@ v:msgpack_types Dictionary containing msgpack types used by |msgpackparse()| of msgpack types, use |is| operator. *v:null* *null-variable* -v:null Special value used to put "null" in JSON and NIL in msgpack. +v:null Special value used to put "null" in JSON and NIL in msgpack. See |json_encode()|. This value is converted to "v:null" when used as a String (e.g. in |expr5| with string concatenation operator) and to zero when used as a Number (e.g. in |expr5| @@ -2184,6 +2184,7 @@ getjumplist([{winnr} [, {tabnr}]]) getline({lnum}) String line {lnum} of current buffer getline({lnum}, {end}) List lines {lnum} to {end} of current buffer getloclist({nr} [, {what}]) List list of location list items +getmarklist([{expr}]) List list of global/local marks getmatches([{win}]) List list of current matches getpid() Number process ID of Vim getpos({expr}) List position of cursor, mark, etc. @@ -4149,7 +4150,7 @@ function({name} [, {arglist}] [, {dict}]) garbagecollect([{atexit}]) *garbagecollect()* Cleanup unused |Lists| and |Dictionaries| that have circular references. - + There is hardly ever a need to invoke this function, as it is automatically done when Vim runs out of memory or is waiting for the user to press a key after 'updatetime'. Items without @@ -4649,6 +4650,24 @@ getloclist({nr},[, {what}]) *getloclist()* field is applicable only when called from a location list window. See |location-list-file-window| for more details. +getmarklist([{expr}] *getmarklist()* + Without the {expr} argument returns a |List| with information + about all the global marks. |mark| + + If the optional {expr} argument is specified, returns the + local marks defined in buffer {expr}. For the use of {expr}, + see |bufname()|. + + Each item in the retuned List is a |Dict| with the following: + name - name of the mark prefixed by "'" + pos - a |List| with the position of the mark: + [bufnum, lnum, col, off] + Refer to |getpos()| for more information. + file - file name + + Refer to |getpos()| for getting information about a specific + mark. + getmatches([{win}]) *getmatches()* Returns a |List| with all matches previously defined for the current window by |matchadd()| and the |:match| commands. @@ -4915,7 +4934,7 @@ getwininfo([{winid}]) *getwininfo()* quickfix 1 if quickfix or location list window terminal 1 if a terminal window tabnr tab page number - topline first displayed buffer line + topline first displayed buffer line variables a reference to the dictionary with window-local variables width window width @@ -5055,7 +5074,7 @@ has({feature}) Returns 1 if {feature} is supported, 0 otherwise. The Vim's compile-time feature-names (prefixed with "+") are not recognized because Nvim is always compiled with all possible - features. |feature-compile| + features. |feature-compile| Feature names can be: 1. Nvim version. For example the "nvim-0.2.1" feature means @@ -5080,7 +5099,7 @@ has({feature}) Returns 1 if {feature} is supported, 0 otherwise. The ttyin input is a terminal (tty) ttyout output is a terminal (tty) unix Unix system. - *vim_starting* True during |startup|. + *vim_starting* True during |startup|. win32 Windows system (32 or 64 bit). win64 Windows system (64 bit). wsl WSL (Windows Subsystem for Linux) system @@ -5665,7 +5684,7 @@ json_encode({expr}) *json_encode()* |msgpack-special-dict|), values with self-referencing containers, strings which contain non-UTF-8 characters, pseudo-UTF-8 strings which contain codepoints reserved for - surrogate pairs (such strings are not valid UTF-8 strings). + surrogate pairs (such strings are not valid UTF-8 strings). Non-printable characters are converted into "\u1234" escapes or special escapes like "\t", other are dumped as-is. @@ -5828,7 +5847,7 @@ map({expr1}, {expr2}) *map()* {expr1} must be a |List| or a |Dictionary|. Replace each item in {expr1} with the result of evaluating {expr2}. {expr2} must be a |string| or |Funcref|. - + If {expr2} is a |string|, inside {expr2} |v:val| has the value of the current item. For a |Dictionary| |v:key| has the key of the current item and for a |List| |v:key| has the index of @@ -6095,8 +6114,8 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]]) - A list with three numbers, e.g., [23, 11, 3]. As above, but the third number gives the length of the highlight in bytes. - Entries with zero and negative line numbers are silently - ignored, as well as entries with negative column numbers and + Entries with zero and negative line numbers are silently + ignored, as well as entries with negative column numbers and lengths. The maximum number of positions is 8. @@ -7589,7 +7608,7 @@ setpos({expr}, {list}) setqflist({list} [, {action}[, {what}]]) *setqflist()* Create or replace or add to the quickfix list. - + When {what} is not present, use the items in {list}. Each item must be a dictionary. Non-dictionary items in {list} are ignored. Each dictionary item can contain the following @@ -7630,12 +7649,12 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()* 'a' The items from {list} are added to the existing quickfix list. If there is no existing list, then a new list is created. - + 'r' The items from the current quickfix list are replaced with the items from {list}. This can also be used to clear the list: > :call setqflist([], 'r') -< +< 'f' All the quickfix lists in the quickfix stack are freed. @@ -8004,7 +8023,7 @@ sign_place({id}, {group}, {name}, {expr} [, {dict}]) empty string. {group} functions as a namespace for {id}, thus two groups can use the same IDs. Refer to |sign-identifier| for more information. - + {name} refers to a defined sign. {expr} refers to a buffer name or number. For the accepted values, see |bufname()|. @@ -8784,7 +8803,7 @@ system({cmd} [, {input}]) *system()* *E677* Note: Use |shellescape()| or |::S| with |expand()| or |fnamemodify()| to escape special characters in a command - argument. Newlines in {cmd} may cause the command to fail. + argument. Newlines in {cmd} may cause the command to fail. The characters in 'shellquote' and 'shellxquote' may also cause trouble. diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index afcacad460..172821ac28 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1173,9 +1173,11 @@ tag command action ~ |:caddbuffer| :cad[dbuffer] add errors from buffer |:caddexpr| :cadde[xpr] add errors from expr |:caddfile| :caddf[ile] add error message to current quickfix list +|:cafter| :caf[ter] go to error after current cursor |:call| :cal[l] call a function |:catch| :cat[ch] part of a :try command -|:cbelow| :cbe[low] go to error below current line +|:cbefore| :cbef[ore] go to error before current cursor +|:cbelow| :cbel[ow] go to error below current line |:cbottom| :cbo[ttom] scroll to the bottom of the quickfix window |:cbuffer| :cb[uffer] parse error messages and jump to first error |:cc| :cc go to specific error @@ -1336,10 +1338,12 @@ tag command action ~ |:laddexpr| :lad[dexpr] add locations from expr |:laddbuffer| :laddb[uffer] add locations from buffer |:laddfile| :laddf[ile] add locations to current location list +|:lafter| :laf[ter] go to location after current cursor |:last| :la[st] go to the last file in the argument list |:language| :lan[guage] set the language (locale) |:later| :lat[er] go to newer change, redo -|:lbelow| :lbe[low] go to location below current line +|:lbefore| :lbef[ore] go to location before current cursor +|:lbelow| :lbel[ow] go to location below current line |:lbottom| :lbo[ttom] scroll to the bottom of the location window |:lbuffer| :lb[uffer] parse locations and jump to first location |:lcd| :lc[d] change directory locally @@ -1539,6 +1543,8 @@ tag command action ~ |:sign| :sig[n] manipulate signs |:silent| :sil[ent] run a command silently |:sleep| :sl[eep] do nothing for a few seconds +|:sleep!| :sl[eep]! do nothing for a few seconds, without the + cursor visible |:slast| :sla[st] split window and go to last file in the argument list |:smagic| :sm[agic] :substitute with 'magic' diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 8e93b188e9..772afdcc1a 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -27,9 +27,9 @@ Follow these steps to get LSP features: 1. Install the nvim-lspconfig plugin. It provides common configuration for various servers so you can get started quickly. https://github.com/neovim/nvim-lspconfig - 2. Install a language server. Try ":LspInstall <tab>" or use your system - package manager to install the relevant language server: + 2. Install a language server. A list of language servers can be found here: https://microsoft.github.io/language-server-protocol/implementors/servers/ + See individual server documentation for installation instructions. 3. Add `lua require('lspconfig').xx.setup{…}` to your init.vim, where "xx" is the name of the relevant config. See the nvim-lspconfig README for details. NOTE: Make sure to restart nvim after installing and configuring. @@ -62,20 +62,39 @@ Example config (in init.vim): > vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.vim.lsp.omnifunc') -- For plugins with an `on_attach` callback, call them here. For example: - -- require('completion').on_attach(client) + -- require('completion').on_attach() end -- An example of configuring for `sumneko_lua`, -- a language server for Lua. - -- First, you must run `:LspInstall sumneko_lua` for this to work. + + -- set the path to the sumneko installation + local system_name = "Linux" -- (Linux, macOS, or Windows) + local sumneko_root_path = '/path/to/lua-language-server' + local sumneko_binary = sumneko_root_path.."/bin/"..system_name.."/lua-language-server" + require('lspconfig').sumneko_lua.setup({ + cmd = {sumneko_binary, "-E", sumneko_root_path .. "/main.lua"}; -- An example of settings for an LSP server. -- For more options, see nvim-lspconfig settings = { Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) + version = 'LuaJIT', + -- Setup your lua path + path = vim.split(package.path, ';'), + }, diagnostics = { - enable = true, - globals = { "vim" }, + -- Get the language server to recognize the `vim` global + globals = {'vim'}, + }, + workspace = { + -- Make the server aware of Neovim runtime files + library = { + [vim.fn.expand('$VIMRUNTIME/lua')] = true, + [vim.fn.expand('$VIMRUNTIME/lua/vim/lsp')] = true, + }, }, } }, @@ -176,6 +195,7 @@ specification. These LSP requests/notifications are defined by default: textDocument/typeDefinition* window/logMessage window/showMessage + window/showMessageRequest workspace/applyEdit workspace/symbol @@ -619,8 +639,9 @@ client() *vim.lsp.client* automatically escalate and force shutdown. • is_stopped() Checks whether a client is stopped. Returns: true if the client is fully stopped. - • on_attach(bufnr) Runs the on_attach function from the - client's config if it was defined. + • on_attach(client, bufnr) Runs the on_attach function from + the client's config if it was defined. Useful for + buffer-local setup. • Members • {id} (number): The id allocated to the client. @@ -755,6 +776,11 @@ start_client({config}) *vim.lsp.start_client()* array. {handlers} Map of language server method names to |lsp-handler| + {settings} Map with language server specific + settings. These are returned to the + language server if requested via + `workspace/configuration` . Keys are + case-sensitive. {init_options} Values to pass in the initialization request as `initializationOptions` . See `initialize` in the LSP spec. @@ -791,7 +817,14 @@ start_client({config}) *vim.lsp.start_client()* `capabilities.offsetEncoding` was sent to it. You can only modify the `client.offset_encoding` here before - any notifications are sent. + any notifications are sent. Most + language servers expect to be sent + client specified settings after + initialization. Neovim does not make + this assumption. A + `workspace/didChangeConfiguration` + notification should be sent to the + server during on_init. {on_exit} Callback (code, signal, client_id) invoked on client exit. • code: exit code of the process @@ -1318,6 +1351,10 @@ set_signs({diagnostics}, {bufnr}, {client_id}, {sign_ns}, {opts}) {sign_ns} number|nil {opts} table Configuration for signs. Keys: • priority: Set the priority of the signs. + • severity_limit (DiagnosticSeverity): + • Limit severity of diagnostics found. + E.g. "Warning" means { "Error", + "Warning" } will be valid. *vim.lsp.diagnostic.set_underline()* set_underline({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts}) @@ -1335,10 +1372,14 @@ set_underline({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts}) Parameters: ~ {diagnostics} Diagnostic [] - {bufnr} number The buffer number - {client_id} number the client id - {diagnostic_ns} number|nil - {opts} table Currently unused. + {bufnr} number: The buffer number + {client_id} number: The client id + {diagnostic_ns} number|nil: The namespace + {opts} table: Configuration table: + • severity_limit (DiagnosticSeverity): + • Limit severity of diagnostics found. + E.g. "Warning" means { "Error", + "Warning" } will be valid. *vim.lsp.diagnostic.set_virtual_text()* set_virtual_text({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts}) @@ -1365,6 +1406,10 @@ set_virtual_text({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts}) before virtual text on line • spacing (number): Number of spaces to insert before virtual text + • severity_limit (DiagnosticSeverity): + • Limit severity of diagnostics found. + E.g. "Warning" means { "Error", + "Warning" } will be valid. *vim.lsp.diagnostic.show_line_diagnostics()* show_line_diagnostics({opts}, {bufnr}, {line_nr}, {client_id}) @@ -1388,16 +1433,31 @@ show_line_diagnostics({opts}, {bufnr}, {line_nr}, {client_id}) {client_id} number|nil the client id Return: ~ - {popup_bufnr, win_id} + table {popup_bufnr, win_id} + + +============================================================================== +Lua module: vim.lsp.handlers *lsp-handlers* + + *vim.lsp.handlers.progress_callback()* +progress_callback({_}, {_}, {params}, {client_id}) + See also: ~ + https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand ============================================================================== Lua module: vim.lsp.util *lsp-util* *vim.lsp.util.apply_text_document_edit()* -apply_text_document_edit({text_document_edit}) +apply_text_document_edit({text_document_edit}, {index}) + Applies a `TextDocumentEdit` , which is a list of changes to a + single document. + Parameters: ~ - {text_document_edit} (table) a `TextDocumentEdit` object + {text_document_edit} table: a `TextDocumentEdit` object + {index} number: Optional index of the edit, + if from a list of edits (or nil, if + not from a list) See also: ~ https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit @@ -1577,6 +1637,9 @@ get_effective_tabstop({bufnr}) *vim.lsp.util.get_effective_tabstop()* See also: ~ |softtabstop| +get_progress_messages() *vim.lsp.util.get_progress_messages()* + TODO: Documentation + jump_to_location({location}) *vim.lsp.util.jump_to_location()* Jumps to a location. @@ -1598,6 +1661,19 @@ locations_to_items({locations}) *vim.lsp.util.locations_to_items()* Return: ~ (table) list of items +lookup_section({settings}, {section}) *vim.lsp.util.lookup_section()* + Helper function to return nested values in language server + settings + + Parameters: ~ + {settings} a table of language server settings + {section} a string indicating the field of the settings + table + + Return: ~ + (table or string) The value of settings accessed via + section + *vim.lsp.util.make_floating_popup_options()* make_floating_popup_options({width}, {height}, {opts}) Creates a table with sensible default options for a floating @@ -1678,7 +1754,7 @@ make_workspace_params({added}, {removed}) Create the workspace params Parameters: ~ - {added} + {added} {removed} *vim.lsp.util.open_floating_preview()* diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index a03de10a17..0bbed56662 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -622,6 +622,9 @@ vim.api.{func}({...}) *vim.api* Example: call the "nvim_get_current_line()" API function: > print(tostring(vim.api.nvim_get_current_line())) +vim.version() *vim.version* + Returns the version of the current neovim build. + vim.in_fast_event() *vim.in_fast_event()* Returns true if the code is executing as part of a "fast" event handler, where most of the API is disabled. These are low-level events @@ -1262,14 +1265,12 @@ validate({opt}) *vim.validate()* vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}} => NOP (success) -< -> - vim.validate{arg1={1, 'table'}} - => error('arg1: expected table, got number') -< -> - vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} - => error('arg1: expected even number, got 3') + + vim.validate{arg1={1, 'table'}} + => error('arg1: expected table, got number') + + vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} + => error('arg1: expected even number, got 3') < Parameters: ~ diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index e740a45bec..2a757bbed9 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -734,6 +734,8 @@ A jump table for the options with a short description can be found at |Q_op|. eol allow backspacing over line breaks (join lines) start allow backspacing over the start of insert; CTRL-W and CTRL-U stop once at the start of insert. + nostop like start, except CTRL-W and CTRL-U do not stop at the start of + insert. When the value is empty, Vi compatible backspacing is used. @@ -742,6 +744,7 @@ A jump table for the options with a short description can be found at |Q_op|. 0 same as ":set backspace=" (Vi compatible) 1 same as ":set backspace=indent,eol" 2 same as ":set backspace=indent,eol,start" + 3 same as ":set backspace=indent,eol,nostop" *'backup'* *'bk'* *'nobackup'* *'nobk'* 'backup' 'bk' boolean (default off) @@ -2609,7 +2612,7 @@ A jump table for the options with a short description can be found at |Q_op|. when internal formatting is used. Make sure the cursor is kept in the same spot relative to the text then! The |mode()| function will return "i" or "R" in this situation. - + When the expression evaluates to non-zero Vim will fall back to using the internal format mechanism. @@ -3184,7 +3187,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'inccommand'* *'icm'* 'inccommand' 'icm' string (default "") global - + "nosplit": Shows the effects of a command incrementally, as you type. "split" : Also shows partial off-screen results in a preview window. @@ -6838,7 +6841,7 @@ A jump table for the options with a short description can be found at |Q_op|. a built-in |highlight-groups| item to be overridden by {hl} group in the window. Only built-in |highlight-groups| are supported, not syntax highlighting (use |:ownsyntax| for that). - + Highlights of vertical separators are determined by the window to the left of the separator. The 'tabline' highlight of a tabpage is decided by the last-focused window of the tabpage. Highlights of diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index d6ff3ea9ea..fab3b11430 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -74,7 +74,7 @@ processing a quickfix or location list command, it will be aborted. *:cc* :cc[!] [nr] Display error [nr]. If [nr] is omitted, the same - error is displayed again. Without [!] this doesn't +:[nr]cc[!] error is displayed again. Without [!] this doesn't work when jumping to another buffer, the current buffer has been changed, there is the only window for the buffer and both 'hidden' and 'autowrite' are off. @@ -83,10 +83,13 @@ processing a quickfix or location list command, it will be aborted. there is another window for this buffer. The 'switchbuf' settings are respected when jumping to a buffer. + When used in the quickfix window the line number can + be used, including "." for the current line and "$" + for the last line. *:ll* :ll[!] [nr] Same as ":cc", except the location list for the - current window is used instead of the quickfix list. +:[nr]ll[!] current window is used instead of the quickfix list. *:cn* *:cne* *:cnext* *E553* :[count]cn[ext][!] Display the [count] next error in the list that @@ -125,8 +128,8 @@ processing a quickfix or location list command, it will be aborted. :[count]lab[ove] Same as ":cabove", except the location list for the current window is used instead of the quickfix list. - *:cbe* *:cbelow* -:[count]cbe[low] Go to the [count] error below the current line in the + *:cbel* *:cbelow* +:[count]cbel[ow] Go to the [count] error below the current line in the current buffer. If [count] is omitted, then 1 is used. If there are no errors, then an error message is displayed. Assumes that the entries in a quickfix @@ -136,8 +139,36 @@ processing a quickfix or location list command, it will be aborted. exceeds the number of entries below the current line, then the last error in the file is selected. - *:lbe* *:lbelow* -:[count]lbe[low] Same as ":cbelow", except the location list for the + *:lbel* *:lbelow* +:[count]lbel[ow] Same as ":cbelow", except the location list for the + current window is used instead of the quickfix list. + + *:cbe* *:cbefore* +:[count]cbe[fore] Go to the [count] error before the current cursor + position in the current buffer. If [count] is + omitted, then 1 is used. If there are no errors, then + an error message is displayed. Assumes that the + entries in a quickfix list are sorted by their buffer, + line and column numbers. If [count] exceeds the + number of entries before the current position, then + the first error in the file is selected. + + *:lbe* *:lbefore* +:[count]lbe[fore] Same as ":cbefore", except the location list for the + current window is used instead of the quickfix list. + + *:caf* *:cafter* +:[count]caf[ter] Go to the [count] error after the current cursor + position in the current buffer. If [count] is + omitted, then 1 is used. If there are no errors, then + an error message is displayed. Assumes that the + entries in a quickfix list are sorted by their buffer, + line and column numbers. If [count] exceeds the + number of entries after the current position, then + the last error in the file is selected. + + *:laf* *:lafter* +:[count]laf[ter] Same as ":cafter", except the location list for the current window is used instead of the quickfix list. *:cnf* *:cnfile* @@ -805,14 +836,19 @@ lists. They set one of the existing error lists as the current one. the current window instead of the quickfix list. *:chistory* *:chi* -:chi[story] Show the list of error lists. The current list is +:[count]chi[story] Show the list of error lists. The current list is marked with ">". The output looks like: error list 1 of 3; 43 errors ~ > error list 2 of 3; 0 errors ~ error list 3 of 3; 15 errors ~ + When [count] is given, then the count'th quickfix + list is made the current list. Example: > + " Make the 4th quickfix list current + :4chistory +< *:lhistory* *:lhi* -:lhi[story] Show the list of location lists, otherwise like +:[count]lhi[story] Show the list of location lists, otherwise like `:chistory`. When adding a new error list, it becomes the current list. @@ -1294,7 +1330,11 @@ Basic items %v virtual column number (finds a number representing screen column of the error (1 <tab> == 8 screen columns)) - %t error type (finds a single character) + %t error type (finds a single character): + e - error message + w - warning message + i - info message + n - note message %n error number (finds a number) %m error message (finds a string) %r matches the "rest" of a single-line file message %O/P/Q @@ -1365,6 +1405,7 @@ prefixes are: %E start of a multi-line error message %W start of a multi-line warning message %I start of a multi-line informational message + %N start of a multi-line note message %A start of a multi-line message (unspecified type) %> for next line start with current pattern again |efm-%>| %C continuation of a multi-line message diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index d4b6324bc3..604c969c64 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -180,7 +180,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. Read Ex commands from {file} in each directory given by 'runtimepath' and/or 'packpath'. There is no error for non-existing files. - + Example: > :runtime syntax/c.vim @@ -254,7 +254,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. *:packl* *:packloadall* :packl[oadall][!] Load all packages in the "start" directory under each entry in 'packpath'. - + First all the directories found are added to 'runtimepath', then the plugins found in the directories are sourced. This allows for a plugin to diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 160995b440..4a99aa47bf 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1316,8 +1316,9 @@ file when reading and include: ============================================================================== Standard Paths *standard-path* -Nvim stores configuration and data in standard locations. Plugins are strongly -encouraged to follow this pattern also. Use |stdpath()| to get the paths. +Nvim stores configuration, data, and logs in standard locations. Plugins are +strongly encouraged to follow this pattern also. Use |stdpath()| to get the +paths. *base-directories* *xdg* The "base" (root) directories conform to the XDG Base Directory Specification. @@ -1342,8 +1343,8 @@ LOG FILE *$NVIM_LOG_FILE* Besides 'debug' and 'verbose', Nvim keeps a general log file for internal debugging, plugins and RPC clients. > :echo $NVIM_LOG_FILE -Usually the file is ~/.local/share/nvim/log unless that path is inaccessible -or if $NVIM_LOG_FILE was set before |startup|. +By default, the file is located at stdpath('cache')/log unless that path +is inaccessible or if $NVIM_LOG_FILE was set before |startup|. vim:noet:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index b011db3dd3..23db809543 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -544,7 +544,7 @@ only supported by new versions of ctags (such as Exuberant ctags). the bar) and ;" is used to have Vi ignore the rest of the line. Example: APP file.c call cursor(3, 4)|;" v - + {field} .. A list of optional fields. Each field has the form: <Tab>{fieldname}:{value} diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index 911e7b8b47..1696d3b9ba 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -195,7 +195,8 @@ query:iter_captures({node}, {bufnr}, {start_row}, {end_row}) text of the buffer. {start_row} and {end_row} can be used to limit matches inside a row range (this is typically used with root node as the node, i e to get syntax highlight matches in the current - viewport) + viewport). When omitted the start and end row values are used from + the given node. The iterator returns three values, a numeric id identifying the capture, the captured node, and metadata from any directives processing the match. diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index 0a8584927e..82406898c8 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -170,7 +170,7 @@ the editor. `mouse_shape`: (To be implemented.) Some keys are missing in some modes. - + The following keys are deprecated: `hl_id`: Use `attr_id` instead. @@ -460,7 +460,7 @@ is not active. New UIs should implement |ui-linegrid| instead. ["set_scroll_region", top, bot, left, right] Define the scroll region used by `scroll` below. - + Note: ranges are end-inclusive, which is inconsistent with API conventions. diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 31da51bfbe..e92e464c6a 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -723,6 +723,7 @@ Cursor and mark position: *cursor-functions* *mark-functions* getcurpos() get position of the cursor getpos() get position of cursor, mark, etc. setpos() set position of cursor, mark, etc. + getmarklist() list of global/local marks byte2line() get line number at a specific byte count line2byte() byte count at a specific line diff_filler() get the number of filler lines above a line diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 32551815b0..5fb7c4ce50 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -46,26 +46,26 @@ CTRL-L Clears and redraws the screen. The redraw may happen ga Print the ascii value of the character under the cursor in decimal, hexadecimal and octal. Mnemonic: Get Ascii value. - + For example, when the cursor is on a 'R': <R> 82, Hex 52, Octal 122 ~ When the character is a non-standard ASCII character, but printable according to the 'isprint' option, the non-printable version is also given. - + When the character is larger than 127, the <M-x> form is also printed. For example: <~A> <M-^A> 129, Hex 81, Octal 201 ~ <p> <|~> <M-~> 254, Hex fe, Octal 376 ~ (where <p> is a special character) - + The <Nul> character in a file is stored internally as <NL>, but it will be shown as: <^@> 0, Hex 00, Octal 000 ~ - + If the character has composing characters these are also shown. The value of 'maxcombine' doesn't matter. - + If the character can be inserted as a digraph, also output the two characters that can be used to create the character: @@ -317,11 +317,11 @@ g8 Print the hex values of the bytes used in the optional. :redi[r] @{a-z}>> Append messages to register {a-z}. -:redi[r] @*> +:redi[r] @*> :redi[r] @+> Redirect messages to the selection or clipboard. For backward compatibility, the ">" after the register name can be omitted. See |quotestar| and |quoteplus|. -:redi[r] @*>> +:redi[r] @*>> :redi[r] @+>> Append messages to the selection or clipboard. :redi[r] @"> Redirect messages to the unnamed register. For @@ -489,12 +489,12 @@ gO Show a filetype-specific, navigable "outline" of the Currently works in |help| and |:Man| buffers. [N]gs *gs* *:sl* *:sleep* -:[N]sl[eep] [N] [m] Do nothing for [N] seconds, or [N] milliseconds if [m] +:[N]sl[eep] [N][m] Do nothing for [N] seconds, or [N] milliseconds if [m] was given. "gs" always uses seconds. Default is one second. > :sleep "sleep for one second :5sleep "sleep for five seconds - :sleep 100m "sleep for a hundred milliseconds + :sleep 100m "sleep for 100 milliseconds 10gs "sleep for ten seconds < Can be interrupted with CTRL-C. "gs" stands for "goto sleep". diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index b5623f4ea4..2c3ffcbe9a 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -124,7 +124,7 @@ CTRL-W CTRL-S *CTRL-W_CTRL-S* :[N]sp[lit] [++opt] [+cmd] [file] *:sp* *:split* Split current window in two. The result is two viewports on the same file. - + Make the new window N high (default is to use half the height of the current window). Reduces the current window height to create room (and others, if the 'equalalways' option is set, diff --git a/runtime/filetype.vim b/runtime/filetype.vim index d2083b23d3..9104519451 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -495,6 +495,9 @@ au BufNewFile,BufRead *.com call dist#ft#BindzoneCheck('dcl') " DOT au BufNewFile,BufRead *.dot,*.gv setf dot +" Dune +au BufNewFile,BufRead jbuild,dune,dune-project,dune-workspace setf dune + " Dylan - lid files au BufNewFile,BufRead *.lid setf dylanlid @@ -1121,8 +1124,8 @@ au BufNewFile,BufRead *.nse setf lua " NSIS au BufNewFile,BufRead *.nsi,*.nsh setf nsis -" OCAML -au BufNewFile,BufRead *.ml,*.mli,*.mll,*.mly,.ocamlinit setf ocaml +" OCaml +au BufNewFile,BufRead *.ml,*.mli,*.mll,*.mly,.ocamlinit,*.mlt,*.mlp,*.mlip,*.mli.cppo,*.ml.cppo setf ocaml " Occam au BufNewFile,BufRead *.occ setf occam @@ -1130,6 +1133,9 @@ au BufNewFile,BufRead *.occ setf occam " Omnimark au BufNewFile,BufRead *.xom,*.xin setf omnimark +" OPAM +au BufNewFile,BufRead opam,*.opam,*.opam.template setf opam + " OpenROAD au BufNewFile,BufRead *.or setf openroad @@ -1164,7 +1170,9 @@ au BufNewFile,BufRead *.papp,*.pxml,*.pxsl setf papp au BufNewFile,BufRead */etc/passwd,*/etc/passwd-,*/etc/passwd.edit,*/etc/shadow,*/etc/shadow-,*/etc/shadow.edit,*/var/backups/passwd.bak,*/var/backups/shadow.bak setf passwd " Pascal (also *.p) -au BufNewFile,BufRead *.pas,*.pp setf pascal +au BufNewFile,BufRead *.pas setf pascal + +au BufNewFile,BufRead *.pp call dist#ft#FTpp() " Delphi or Lazarus program file au BufNewFile,BufRead *.dpr,*.lpr setf pascal @@ -1549,6 +1557,9 @@ au BufNewFile,BufRead *.scm,*.ss,*.rkt setf scheme " Screen RC au BufNewFile,BufRead .screenrc,screenrc setf screen +" Sexplib +au BufNewFile,BufRead *.sexp setf sexplib + " Simula au BufNewFile,BufRead *.sim setf simula @@ -1609,6 +1620,9 @@ au BufNewFile,BufRead *.mib,*.my setf mib au BufNewFile,BufRead *.hog,snort.conf,vision.conf setf hog au BufNewFile,BufRead *.rules call dist#ft#FTRules() +" SPARQL queries +au BufNewFile,BufRead *.rq,*.sparql setf sparql + " Spec (Linux RPM) au BufNewFile,BufRead *.spec setf spec diff --git a/runtime/ftplugin/elm.vim b/runtime/ftplugin/elm.vim new file mode 100644 index 0000000000..1e10346186 --- /dev/null +++ b/runtime/ftplugin/elm.vim @@ -0,0 +1,18 @@ +" Elm filetype plugin file +" Language: Elm +" Maintainer: Andreas Scharf <as@99n.de> +" Latest Revision: 2020-05-29 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +setlocal comments=s1fl:{-,mb:\ ,ex:-},:-- +setlocal commentstring=--\ %s + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/ftplugin/man.vim b/runtime/ftplugin/man.vim index 74225a558c..5d3e00d033 100644 --- a/runtime/ftplugin/man.vim +++ b/runtime/ftplugin/man.vim @@ -16,7 +16,11 @@ setlocal noswapfile buftype=nofile bufhidden=hide setlocal nomodified readonly nomodifiable setlocal noexpandtab tabstop=8 softtabstop=8 shiftwidth=8 setlocal wrap breakindent linebreak -setlocal iskeyword+=- + +" Parentheses and '-' for references like `git-ls-files(1)`; '@' for systemd +" pages; ':' for Perl and C++ pages. Here, I intentionally omit the locale +" specific characters matched by `@`. +setlocal iskeyword=@-@,:,a-z,A-Z,48-57,_,.,-,(,) setlocal nonumber norelativenumber setlocal foldcolumn=0 colorcolumn=0 nolist nofoldenable @@ -24,9 +28,10 @@ setlocal foldcolumn=0 colorcolumn=0 nolist nofoldenable setlocal tagfunc=man#goto_tag if !exists('g:no_plugin_maps') && !exists('g:no_man_maps') - nnoremap <silent> <buffer> j gj - nnoremap <silent> <buffer> k gk - nnoremap <silent> <buffer> gO :call man#show_toc()<CR> + nnoremap <silent> <buffer> j gj + nnoremap <silent> <buffer> k gk + nnoremap <silent> <buffer> gO :call man#show_toc()<CR> + nnoremap <silent> <buffer> <2-LeftMouse> :Man<CR> if s:pager nnoremap <silent> <buffer> <nowait> q :lclose<CR>:q<CR> else diff --git a/runtime/indent/elm.vim b/runtime/indent/elm.vim new file mode 100644 index 0000000000..232c347c66 --- /dev/null +++ b/runtime/indent/elm.vim @@ -0,0 +1,114 @@ +" Elm indent plugin file +" Language: Elm +" Maintainer: Andreas Scharf <as@99n.de> +" Original Author: Joseph Hager <ajhager@gmail.com> +" Copyright: Joseph Hager <ajhager@gmail.com> +" License: BSD3 +" Latest Revision: 2020-05-29 + +" Only load this indent file when no other was loaded. +if exists('b:did_indent') + finish +endif +let b:did_indent = 1 + +" Local defaults +setlocal expandtab +setlocal indentexpr=GetElmIndent() +setlocal indentkeys+=0=else,0=if,0=of,0=import,0=then,0=type,0\|,0},0\],0),=-},0=in +setlocal nolisp +setlocal nosmartindent + +" Only define the function once. +if exists('*GetElmIndent') + finish +endif + +" Indent pairs +function! s:FindPair(pstart, pmid, pend) + "call search(a:pend, 'bW') + return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) +endfunction + +function! GetElmIndent() + let l:lnum = v:lnum - 1 + + " Ident 0 if the first line of the file: + if l:lnum == 0 + return 0 + endif + + let l:ind = indent(l:lnum) + let l:lline = getline(l:lnum) + let l:line = getline(v:lnum) + + " Indent if current line begins with '}': + if l:line =~? '^\s*}' + return s:FindPair('{', '', '}') + + " Indent if current line begins with 'else': + elseif l:line =~# '^\s*else\>' + if l:lline !~# '^\s*\(if\|then\)\>' + return s:FindPair('\<if\>', '', '\<else\>') + endif + + " Indent if current line begins with 'then': + elseif l:line =~# '^\s*then\>' + if l:lline !~# '^\s*\(if\|else\)\>' + return s:FindPair('\<if\>', '', '\<then\>') + endif + + " HACK: Indent lines in case with nearest case clause: + elseif l:line =~# '->' && l:line !~# ':' && l:line !~# '\\' + return indent(search('^\s*case', 'bWn')) + &shiftwidth + + " HACK: Don't change the indentation if the last line is a comment. + elseif l:lline =~# '^\s*--' + return l:ind + + " Align the end of block comments with the start + elseif l:line =~# '^\s*-}' + return indent(search('{-', 'bWn')) + + " Indent double shift after let with an empty rhs + elseif l:lline =~# '\<let\>.*\s=$' + return l:ind + 4 + &shiftwidth + + " Align 'in' with the parent let. + elseif l:line =~# '^\s*in\>' + return indent(search('^\s*let', 'bWn')) + + " Align bindings with the parent let. + elseif l:lline =~# '\<let\>' + return l:ind + 4 + + " Align bindings with the parent in. + elseif l:lline =~# '^\s*in\>' + return l:ind + + endif + + " Add a 'shiftwidth' after lines ending with: + if l:lline =~# '\(|\|=\|->\|<-\|(\|\[\|{\|\<\(of\|else\|if\|then\)\)\s*$' + let l:ind = l:ind + &shiftwidth + + " Add a 'shiftwidth' after lines starting with type ending with '=': + elseif l:lline =~# '^\s*type' && l:line =~# '^\s*=' + let l:ind = l:ind + &shiftwidth + + " Back to normal indent after comments: + elseif l:lline =~# '-}\s*$' + call search('-}', 'bW') + let l:ind = indent(searchpair('{-', '', '-}', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"')) + + " Ident some operators if there aren't any starting the last line. + elseif l:line =~# '^\s*\(!\|&\|(\|`\|+\||\|{\|[\|,\)=' && l:lline !~# '^\s*\(!\|&\|(\|`\|+\||\|{\|[\|,\)=' && l:lline !~# '^\s*$' + let l:ind = l:ind + &shiftwidth + + elseif l:lline ==# '' && getline(l:lnum - 1) !=# '' + let l:ind = indent(search('^\s*\S+', 'bWn')) + + endif + + return l:ind +endfunc diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 0326550245..64d08e9733 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -226,6 +226,7 @@ local function validate_client_config(config) on_error = { config.on_error, "f", true }; on_exit = { config.on_exit, "f", true }; on_init = { config.on_init, "f", true }; + settings = { config.settings, "t", true }; before_init = { config.before_init, "f", true }; offset_encoding = { config.offset_encoding, "s", true }; flags = { config.flags, "t", true }; @@ -327,8 +328,9 @@ end --- Checks whether a client is stopped. --- Returns: true if the client is fully stopped. --- ---- - on_attach(bufnr) +--- - on_attach(client, bufnr) --- Runs the on_attach function from the client's config if it was defined. +--- Useful for buffer-local setup. --- --- - Members --- - {id} (number): The id allocated to the client. @@ -398,6 +400,10 @@ end --- --@param handlers Map of language server method names to |lsp-handler| --- +--@param settings Map with language server specific settings. These are +--- returned to the language server if requested via `workspace/configuration`. +--- Keys are case-sensitive. +--- --@param init_options Values to pass in the initialization request --- as `initializationOptions`. See `initialize` in the LSP spec. --- @@ -424,7 +430,10 @@ end --- the server may send. For example, clangd sends --- `initialize_result.offsetEncoding` if `capabilities.offsetEncoding` was --- sent to it. You can only modify the `client.offset_encoding` here before ---- any notifications are sent. +--- any notifications are sent. Most language servers expect to be sent client specified settings after +--- initialization. Neovim does not make this assumption. A +--- `workspace/didChangeConfiguration` notification should be sent +--- to the server during on_init. --- --@param on_exit Callback (code, signal, client_id) invoked on client --- exit. @@ -457,6 +466,7 @@ function lsp.start_client(config) local cmd, cmd_args, offset_encoding = cleaned_config.cmd, cleaned_config.cmd_args, cleaned_config.offset_encoding config.flags = config.flags or {} + config.settings = config.settings or {} local client_id = next_client_id() @@ -581,12 +591,19 @@ function lsp.start_client(config) local valid_traces = { off = 'off'; messages = 'messages'; verbose = 'verbose'; } + local version = vim.version() local initialize_params = { -- The process Id of the parent process that started the server. Is null if -- the process has not been started by another process. If the parent -- process is not alive then the server should exit (see exit notification) -- its process. processId = uv.getpid(); + -- Information about the client + -- since 3.15.0 + clientInfo = { + name = "Neovim", + version = string.format("%s.%s.%s", version.major, version.minor, version.patch) + }; -- The rootPath of the workspace. Is null if no folder is open. -- -- @deprecated in favour of rootUri. diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 072349b226..a625098bab 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -16,6 +16,24 @@ local to_severity = function(severity) return type(severity) == 'string' and DiagnosticSeverity[severity] or severity end +local filter_to_severity_limit = function(severity, diagnostics) + local filter_level = to_severity(severity) + if not filter_level then + return diagnostics + end + + return vim.tbl_filter(function(t) return t.severity == filter_level end, diagnostics) +end + +local filter_by_severity_limit = function(severity_limit, diagnostics) + local filter_level = to_severity(severity_limit) + if not filter_level then + return diagnostics + end + + return vim.tbl_filter(function(t) return t.severity <= filter_level end, diagnostics) +end + local to_position = function(position, bufnr) vim.validate { position = {position, 't'} } @@ -377,11 +395,9 @@ function M.get_line_diagnostics(bufnr, line_nr, opts, client_id) end if opts.severity then - local filter_level = to_severity(opts.severity) - line_diagnostics = vim.tbl_filter(function(t) return t.severity == filter_level end, line_diagnostics) + line_diagnostics = filter_to_severity_limit(opts.severity, line_diagnostics) elseif opts.severity_limit then - local filter_level = to_severity(opts.severity_limit) - line_diagnostics = vim.tbl_filter(function(t) return t.severity <= filter_level end, line_diagnostics) + line_diagnostics = filter_by_severity_limit(opts.severity_limit, line_diagnostics) end if opts.severity_sort then @@ -542,7 +558,7 @@ function M.goto_prev(opts) ) end ---- Get the previous diagnostic closest to the cursor_position +--- Get the next diagnostic closest to the cursor_position ---@param opts table See |vim.lsp.diagnostic.goto_next()| ---@return table Next diagnostic function M.get_next(opts) @@ -609,6 +625,8 @@ end ---@param sign_ns number|nil ---@param opts table Configuration for signs. Keys: --- - priority: Set the priority of the signs. +--- - severity_limit (DiagnosticSeverity): +--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. function M.set_signs(diagnostics, bufnr, client_id, sign_ns, opts) opts = opts or {} sign_ns = sign_ns or M._get_sign_namespace(client_id) @@ -622,9 +640,11 @@ function M.set_signs(diagnostics, bufnr, client_id, sign_ns, opts) end bufnr = get_bufnr(bufnr) + diagnostics = filter_by_severity_limit(opts.severity_limit, diagnostics) local ok = true for _, diagnostic in ipairs(diagnostics) do + ok = ok and pcall(vim.fn.sign_place, 0, sign_ns, @@ -654,15 +674,17 @@ end --- </pre> --- ---@param diagnostics Diagnostic[] ----@param bufnr number The buffer number ----@param client_id number the client id ----@param diagnostic_ns number|nil ----@param opts table Currently unused. +---@param bufnr number: The buffer number +---@param client_id number: The client id +---@param diagnostic_ns number|nil: The namespace +---@param opts table: Configuration table: +--- - severity_limit (DiagnosticSeverity): +--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. function M.set_underline(diagnostics, bufnr, client_id, diagnostic_ns, opts) opts = opts or {} - assert(opts) -- lint diagnostic_ns = diagnostic_ns or M._get_diagnostic_namespace(client_id) + diagnostics = filter_by_severity_limit(opts.severity_limit, diagnostics) for _, diagnostic in ipairs(diagnostics) do local start = diagnostic.range["start"] @@ -703,6 +725,8 @@ end ---@param opts table Options on how to display virtual text. Keys: --- - prefix (string): Prefix to display before virtual text on line --- - spacing (number): Number of spaces to insert before virtual text +--- - severity_limit (DiagnosticSeverity): +--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. function M.set_virtual_text(diagnostics, bufnr, client_id, diagnostic_ns, opts) opts = opts or {} @@ -721,6 +745,7 @@ function M.set_virtual_text(diagnostics, bufnr, client_id, diagnostic_ns, opts) end for line, line_diagnostics in pairs(buffer_line_diagnostics) do + line_diagnostics = filter_by_severity_limit(opts.severity_limit, line_diagnostics) local virt_texts = M.get_virtual_text_chunks_for_line(bufnr, line, line_diagnostics, opts) if virt_texts then @@ -1082,7 +1107,7 @@ end ---@param bufnr number The buffer number ---@param line_nr number The line number ---@param client_id number|nil the client id ----@return {popup_bufnr, win_id} +---@return table {popup_bufnr, win_id} function M.show_line_diagnostics(opts, bufnr, line_nr, client_id) opts = opts or {} opts.severity_sort = if_nil(opts.severity_sort, true) @@ -1151,30 +1176,14 @@ function M.set_loclist(opts) local bufnr = vim.api.nvim_get_current_buf() local buffer_diags = M.get(bufnr, opts.client_id) - local severity = to_severity(opts.severity) - local severity_limit = to_severity(opts.severity_limit) + if opts.severity then + buffer_diags = filter_to_severity_limit(opts.severity, buffer_diags) + elseif opts.severity_limit then + buffer_diags = filter_by_severity_limit(opts.severity_limit, buffer_diags) + end local items = {} local insert_diag = function(diag) - if severity then - -- Handle missing severities - if not diag.severity then - return - end - - if severity ~= diag.severity then - return - end - elseif severity_limit then - if not diag.severity then - return - end - - if severity_limit < diag.severity then - return - end - end - local pos = diag.range.start local row = pos.line local col = util.character_offset(bufnr, row, pos.character) diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index fd23a6a547..7eac3febd9 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -28,8 +28,9 @@ end -- Basically a token of type number/string local function progress_callback(_, _, params, client_id) local client = vim.lsp.get_client_by_id(client_id) + local client_name = client and client.name or string.format("id=%d", client_id) if not client then - err_message("LSP[", client_id, "] client has shut down after sending the message") + err_message("LSP[", client_name, "] client has shut down after sending the message") end local val = params.value -- unspecified yet local token = params.token -- string or number @@ -43,14 +44,11 @@ local function progress_callback(_, _, params, client_id) percentage = val.percentage, } elseif val.kind == 'report' then - client.messages.progress[token] = { - message = val.message, - percentage = val.percentage, - } + client.messages.progress[token].message = val.message; + client.messages.progress[token].percentage = val.percentage; elseif val.kind == 'end' then if client.messages.progress[token] == nil then - err_message( - 'echom "[lsp-status] Received `end` message with no corresponding `begin` from "') + err_message("LSP[", client_name, "] received `end` message with no corresponding `begin`") else client.messages.progress[token].message = val.message client.messages.progress[token].done = true @@ -70,8 +68,9 @@ M['$/progress'] = progress_callback M['window/workDoneProgress/create'] = function(_, _, params, client_id) local client = vim.lsp.get_client_by_id(client_id) local token = params.token -- string or number + local client_name = client and client.name or string.format("id=%d", client_id) if not client then - err_message("LSP[", client_id, "] client has shut down after sending the message") + err_message("LSP[", client_name, "] client has shut down after sending the message") end client.messages.progress[token] = {} return vim.NIL @@ -94,13 +93,22 @@ M['window/showMessageRequest'] = function(_, _, params) if choice < 1 or choice > #actions then return vim.NIL else - local action_chosen = actions[choice] - return { - title = action_chosen; - } + return actions[choice] end end +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability +M['client/registerCapability'] = function(_, _, _, client_id) + local warning_tpl = "The language server %s triggers a registerCapability ".. + "handler despite dynamicRegistration set to false. ".. + "Report upstream, this warning is harmless" + local client = vim.lsp.get_client_by_id(client_id) + local client_name = client and client.name or string.format("id=%d", client_id) + local warning = string.format(warning_tpl, client_name) + log.warn(warning) + return vim.NIL +end + --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction M['textDocument/codeAction'] = function(_, _, actions) if actions == nil or vim.tbl_isempty(actions) then @@ -149,6 +157,32 @@ M['workspace/applyEdit'] = function(_, _, workspace_edit) } end +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_configuration +M['workspace/configuration'] = function(err, _, params, client_id) + local client = vim.lsp.get_client_by_id(client_id) + if not client then + err_message("LSP[id=", client_id, "] client has shut down after sending the message") + return + end + if err then error(vim.inspect(err)) end + if not params.items then + return {} + end + + local result = {} + for _, item in ipairs(params.items) do + if item.section then + local value = util.lookup_section(client.config.settings, item.section) or vim.NIL + -- For empty sections with no explicit '' key, return settings as is + if value == vim.NIL and item.section == '' then + value = client.config.settings or vim.NIL + end + table.insert(result, value) + end + end + return result +end + M['textDocument/publishDiagnostics'] = function(...) return require('vim.lsp.diagnostic').on_publish_diagnostics(...) end diff --git a/runtime/lua/vim/lsp/log.lua b/runtime/lua/vim/lsp/log.lua index 587a65cd96..b6e91e37b9 100644 --- a/runtime/lua/vim/lsp/log.lua +++ b/runtime/lua/vim/lsp/log.lua @@ -28,7 +28,7 @@ do local function path_join(...) return table.concat(vim.tbl_flatten{...}, path_sep) end - local logfilename = path_join(vim.fn.stdpath('data'), 'lsp.log') + local logfilename = path_join(vim.fn.stdpath('cache'), 'lsp.log') --- Returns the log filename. --@returns (string) log filename @@ -36,7 +36,7 @@ do return logfilename end - vim.fn.mkdir(vim.fn.stdpath('data'), "p") + vim.fn.mkdir(vim.fn.stdpath('cache'), "p") local logfile = assert(io.open(logfilename, "a+")) for level, levelnr in pairs(log.levels) do -- Also export the log level on the root object. diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index b2d3d0641c..3e111c154a 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -34,6 +34,13 @@ local constants = { Hint = 4; }; + DiagnosticTag = { + -- Unused or unnecessary code + Unnecessary = 1; + -- Deprecated or obsolete code + Deprecated = 2; + }; + MessageType = { -- An error message. Error = 1; @@ -521,6 +528,13 @@ export interface TextDocumentClientCapabilities { publishDiagnostics?: { --Whether the clients accepts diagnostics with related information. relatedInformation?: boolean; + --Client supports the tag property to provide meta data about a diagnostic. + --Clients supporting tags have to handle unknown tags gracefully. + --Since 3.15.0 + tagSupport?: { + --The tags supported by this client + valueSet: DiagnosticTag[]; + }; }; --Capabilities specific to `textDocument/foldingRange` requests. -- @@ -706,6 +720,18 @@ function protocol.make_client_capabilities() dynamicRegistration = false; prepareSupport = true; }; + publishDiagnostics = { + relatedInformation = true; + tagSupport = { + valueSet = (function() + local res = {} + for k in ipairs(protocol.DiagnosticTag) do + if type(k) == 'number' then table.insert(res, k) end + end + return res + end)(); + }; + }; }; workspace = { symbol = { diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 0972ea83c4..e33e0109b6 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -254,19 +254,27 @@ function M.extract_completion_items(result) end --- Applies a `TextDocumentEdit`, which is a list of changes to a single --- document. +--- document. --- ---@param text_document_edit (table) a `TextDocumentEdit` object ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit -function M.apply_text_document_edit(text_document_edit) +---@param text_document_edit table: a `TextDocumentEdit` object +---@param index number: Optional index of the edit, if from a list of edits (or nil, if not from a list) +---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit +function M.apply_text_document_edit(text_document_edit, index) local text_document = text_document_edit.textDocument local bufnr = vim.uri_to_bufnr(text_document.uri) + -- For lists of text document edits, + -- do not check the version after the first edit. + local should_check_version = true + if index and index > 1 then + should_check_version = false + end + -- `VersionedTextDocumentIdentifier`s version may be null -- https://microsoft.github.io/language-server-protocol/specification#versionedTextDocumentIdentifier - if text_document.version + if should_check_version and (text_document.version and M.buf_versions[bufnr] - and M.buf_versions[bufnr] > text_document.version then + and M.buf_versions[bufnr] > text_document.version) then print("Buffer ", text_document.uri, " newer than edits.") return end @@ -459,12 +467,12 @@ end -- @see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit function M.apply_workspace_edit(workspace_edit) if workspace_edit.documentChanges then - for _, change in ipairs(workspace_edit.documentChanges) do + for idx, change in ipairs(workspace_edit.documentChanges) do if change.kind then -- TODO(ashkan) handle CreateFile/RenameFile/DeleteFile error(string.format("Unsupported change: %q", vim.inspect(change))) else - M.apply_text_document_edit(change) + M.apply_text_document_edit(change, idx) end end return @@ -1422,6 +1430,21 @@ function M.character_offset(buf, row, col) return str_utfindex(line, col) end +--- Helper function to return nested values in language server settings +--- +--@param settings a table of language server settings +--@param section a string indicating the field of the settings table +--@returns (table or string) The value of settings accessed via section +function M.lookup_section(settings, section) + for part in vim.gsplit(section, '.', true) do + settings = settings[part] + if not settings then + return + end + end + return settings +end + M._get_line_byte_from_position = get_line_byte_from_position M._warn_once = warn_once diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index 79dcf77f9e..38ac182e32 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -50,7 +50,7 @@ function M._create_parser(bufnr, lang, opts) end end - a.nvim_buf_attach(self.bufnr, false, {on_bytes=bytes_cb, on_detach=detach_cb, preview=true}) + a.nvim_buf_attach(self:source(), false, {on_bytes=bytes_cb, on_detach=detach_cb, preview=true}) self:parse() diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 9c620c422c..c864fe5878 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -425,23 +425,21 @@ function LanguageTree:register_cbs(cbs) end end -local function region_contains(region, range) - for _, node in ipairs(region) do - local start_row, start_col, end_row, end_col = node:range() - local start_fits = start_row < range[1] or (start_row == range[1] and start_col <= range[2]) - local end_fits = end_row > range[3] or (end_row == range[3] and end_col >= range[4]) +local function tree_contains(tree, range) + local start_row, start_col, end_row, end_col = tree:root():range() + local start_fits = start_row < range[1] or (start_row == range[1] and start_col <= range[2]) + local end_fits = end_row > range[3] or (end_row == range[3] and end_col >= range[4]) - if start_fits and end_fits then - return true - end + if start_fits and end_fits then + return true end return false end function LanguageTree:contains(range) - for _, region in pairs(self._regions) do - if region_contains(region, range) then + for _, tree in pairs(self._trees) do + if tree_contains(tree, range) then return true end end diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 682f981fbc..e49f54681d 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -8,36 +8,10 @@ Query.__index = Query local M = {} --- Filter the runtime query files, the spec is like regular runtime files but in the new `queries` --- directory. They resemble ftplugins, that is that you can override queries by adding things in the --- `queries` directory, and extend using the `after/queries` directory. -local function filter_files(file_list) - local main = nil - local after = {} - - for _, fname in ipairs(file_list) do - -- Only get the name of the directory containing the queries directory - if vim.fn.fnamemodify(fname, ":p:h:h:h:t") == "after" then - table.insert(after, fname) - -- The first one is the one with most priority - elseif not main then - main = fname - end - end - return main and { main, unpack(after) } or after -end - -local function runtime_query_path(lang, query_name) - return string.format('queries/%s/%s.scm', lang, query_name) -end - -local function filtered_runtime_queries(lang, query_name) - return filter_files(a.nvim_get_runtime_file(runtime_query_path(lang, query_name), true) or {}) -end - -local function get_query_files(lang, query_name, is_included) - local lang_files = filtered_runtime_queries(lang, query_name) +function M.get_query_files(lang, query_name, is_included) + local query_path = string.format('queries/%s/%s.scm', lang, query_name) + local lang_files = a.nvim_get_runtime_file(query_path, true) if #lang_files == 0 then return {} end @@ -51,10 +25,10 @@ local function get_query_files(lang, query_name, is_included) local MODELINE_FORMAT = "^;+%s*inherits%s*:?%s*([a-z_,()]+)%s*$" for _, file in ipairs(lang_files) do - local modeline = vim.fn.readfile(file, "", 1) + local modeline = io.open(file, 'r'):read('*l') - if #modeline == 1 then - local langlist = modeline[1]:match(MODELINE_FORMAT) + if modeline then + local langlist = modeline:match(MODELINE_FORMAT) if langlist then for _, incllang in ipairs(vim.split(langlist, ',', true)) do @@ -74,7 +48,7 @@ local function get_query_files(lang, query_name, is_included) local query_files = {} for _, base_lang in ipairs(base_langs) do - local base_files = get_query_files(base_lang, query_name, true) + local base_files = M.get_query_files(base_lang, query_name, true) vim.list_extend(query_files, base_files) end vim.list_extend(query_files, lang_files) @@ -86,10 +60,10 @@ local function read_query_files(filenames) local contents = {} for _,filename in ipairs(filenames) do - vim.list_extend(contents, vim.fn.readfile(filename)) + table.insert(contents, io.open(filename, 'r'):read('*a')) end - return table.concat(contents, '\n') + return table.concat(contents, '') end local match_metatable = { @@ -110,7 +84,7 @@ end -- -- @return The corresponding query, parsed. function M.get_query(lang, query_name) - local query_files = get_query_files(lang, query_name) + local query_files = M.get_query_files(lang, query_name) local query_string = read_query_files(query_files) if #query_string > 0 then @@ -366,6 +340,19 @@ function Query:apply_directives(match, pattern, source, metadata) end end + +--- Returns the start and stop value if set else the node's range. +-- When the node's range is used, the stop is incremented by 1 +-- to make the search inclusive. +local function value_or_node_range(start, stop, node) + if start == nil and stop == nil then + local node_start, _, node_stop, _ = node:range() + return node_start, node_stop + 1 -- Make stop inclusive + end + + return start, stop +end + --- Iterates of the captures of self on a given range. -- -- @param node The node under witch the search will occur @@ -379,6 +366,9 @@ function Query:iter_captures(node, source, start, stop) if type(source) == "number" and source == 0 then source = vim.api.nvim_get_current_buf() end + + start, stop = value_or_node_range(start, stop, node) + local raw_iter = node:_rawquery(self.query, true, start, stop) local function iter() local capture, captured_node, match = raw_iter() @@ -411,6 +401,9 @@ function Query:iter_matches(node, source, start, stop) if type(source) == "number" and source == 0 then source = vim.api.nvim_get_current_buf() end + + start, stop = value_or_node_range(start, stop, node) + local raw_iter = node:_rawquery(self.query, false, start, stop) local function iter() local pattern, match = raw_iter() diff --git a/runtime/nvim.appdata.xml b/runtime/nvim.appdata.xml index 025de1b5a9..e99c76a930 100644 --- a/runtime/nvim.appdata.xml +++ b/runtime/nvim.appdata.xml @@ -26,6 +26,7 @@ </screenshots> <releases> + <release date="2020-08-04" version="0.4.4"/> <release date="2019-11-06" version="0.4.3"/> <release date="2019-09-15" version="0.4.2"/> <release date="2019-09-15" version="0.4.1"/> diff --git a/runtime/scripts.vim b/runtime/scripts.vim index 6aae2b1ec3..536993d485 100644 --- a/runtime/scripts.vim +++ b/runtime/scripts.vim @@ -182,6 +182,10 @@ if s:line1 =~# "^#!" elseif s:name =~# 'clojure' set ft=clojure + " Free Pascal + elseif s:name =~# 'instantfpc\>' + set ft=pascal + endif unlet s:name diff --git a/runtime/syntax/elm.vim b/runtime/syntax/elm.vim new file mode 100644 index 0000000000..1277827f57 --- /dev/null +++ b/runtime/syntax/elm.vim @@ -0,0 +1,105 @@ +" Vim syntax file +" Language: Elm +" Maintainer: Andreas Scharf <as@99n.de> +" Original Author: Joseph Hager <ajhager@gmail.com> +" Copyright: Joseph Hager <ajhager@gmail.com> +" License: BSD3 +" Latest Revision: 2020-05-29 + +if exists('b:current_syntax') + finish +endif + +" Keywords +syn keyword elmConditional else if of then case +syn keyword elmAlias alias +syn keyword elmTypedef contained type port +syn keyword elmImport exposing as import module where + +" Operators +" elm/core +syn match elmOperator contained "\(<|\||>\|||\|&&\|==\|/=\|<=\|>=\|++\|::\|+\|-\|*\|/\|//\|^\|<>\|>>\|<<\|<\|>\|%\)" +" elm/parser +syn match elmOperator contained "\(|.\||=\)" +" elm/url +syn match elmOperator contained "\(</>\|<?>\)" + +" Types +syn match elmType "\<[A-Z][0-9A-Za-z_-]*" +syn keyword elmNumberType number + +" Modules +syn match elmModule "\<\([A-Z][0-9A-Za-z_'-\.]*\)\+\.[A-Za-z]"me=e-2 +syn match elmModule "^\(module\|import\)\s\+[A-Z][0-9A-Za-z_'-\.]*\(\s\+as\s\+[A-Z][0-9A-Za-z_'-\.]*\)\?\(\s\+exposing\)\?" contains=elmImport + +" Delimiters +syn match elmDelimiter "[,;]" +syn match elmBraces "[()[\]{}]" + +" Functions +syn match elmTupleFunction "\((,\+)\)" + +" Comments +syn keyword elmTodo TODO FIXME XXX contained +syn match elmLineComment "--.*" contains=elmTodo,@spell +syn region elmComment matchgroup=elmComment start="{-|\=" end="-}" contains=elmTodo,elmComment,@spell fold + +" Strings +syn match elmStringEscape "\\u[0-9a-fA-F]\{4}" contained +syn match elmStringEscape "\\[nrfvbt\\\"]" contained +syn region elmString start="\"" skip="\\\"" end="\"" contains=elmStringEscape,@spell +syn region elmTripleString start="\"\"\"" skip="\\\"" end="\"\"\"" contains=elmStringEscape,@spell +syn match elmChar "'[^'\\]'\|'\\.'\|'\\u[0-9a-fA-F]\{4}'" + +" Lambda +syn region elmLambdaFunc start="\\"hs=s+1 end="->"he=e-2 + +" Debug +syn match elmDebug "Debug.\(log\|todo\|toString\)" + +" Numbers +syn match elmInt "-\?\<\d\+\>" +syn match elmFloat "-\?\(\<\d\+\.\d\+\>\)" + +" Identifiers +syn match elmTopLevelDecl "^\s*[a-zA-Z][a-zA-z0-9_]*\('\)*\s\+:\(\r\n\|\r\|\n\|\s\)\+" contains=elmOperator +syn match elmFuncName /^\l\w*/ + +" Folding +syn region elmTopLevelTypedef start="type" end="\n\(\n\n\)\@=" contains=ALL fold +syn region elmTopLevelFunction start="^[a-zA-Z].\+\n[a-zA-Z].\+=" end="^\(\n\+\)\@=" contains=ALL fold +syn region elmCaseBlock matchgroup=elmCaseBlockDefinition start="^\z\(\s\+\)\<case\>" end="^\z1\@!\W\@=" end="\(\n\n\z1\@!\)\@=" end="\n\z1\@!\(\n\n\)\@=" contains=ALL fold +syn region elmCaseItemBlock start="^\z\(\s\+\).\+->$" end="^\z1\@!\W\@=" end="\(\n\n\z1\@!\)\@=" end="\(\n\z1\S\)\@=" contains=ALL fold +syn region elmLetBlock matchgroup=elmLetBlockDefinition start="\<let\>" end="\<in\>" contains=ALL fold + +hi def link elmFuncName Function +hi def link elmCaseBlockDefinition Conditional +hi def link elmCaseBlockItemDefinition Conditional +hi def link elmLetBlockDefinition TypeDef +hi def link elmTopLevelDecl Function +hi def link elmTupleFunction Normal +hi def link elmTodo Todo +hi def link elmComment Comment +hi def link elmLineComment Comment +hi def link elmString String +hi def link elmTripleString String +hi def link elmChar String +hi def link elmStringEscape Special +hi def link elmInt Number +hi def link elmFloat Float +hi def link elmDelimiter Delimiter +hi def link elmBraces Delimiter +hi def link elmTypedef TypeDef +hi def link elmImport Include +hi def link elmConditional Conditional +hi def link elmAlias Delimiter +hi def link elmOperator Operator +hi def link elmType Type +hi def link elmNumberType Identifier +hi def link elmLambdaFunc Function +hi def link elmDebug Debug +hi def link elmModule Type + +syn sync minlines=500 + +let b:current_syntax = 'elm' |