diff options
Diffstat (limited to 'runtime')
28 files changed, 736 insertions, 145 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/compiler/zsh.vim b/runtime/compiler/zsh.vim new file mode 100644 index 0000000000..5703c1fc44 --- /dev/null +++ b/runtime/compiler/zsh.vim @@ -0,0 +1,23 @@ +" Vim compiler file +" Compiler: Zsh +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Last Change: 2020 Sep 6 + +if exists("current_compiler") + finish +endif +let current_compiler = "zsh" + +if exists(":CompilerSet") != 2 " older Vim always used :setlocal + command -nargs=* CompilerSet setlocal <args> +endif + +let s:cpo_save = &cpo +set cpo&vim + +CompilerSet makeprg=zsh\ -n\ --\ %:S +CompilerSet errorformat=%f:\ line\ %l:\ %m, + \%-G%.%# + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 485c93b0dd..dd3469372e 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 @@ -1937,8 +1948,7 @@ nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}, {opts}) {ns_id} Namespace id from |nvim_create_namespace()| {id} Extmark id {opts} Optional parameters. Keys: - • limit: Maximum number of marks to return - • details Whether to include the details dict + • details: Whether to include the details dict Return: ~ (row, col) tuple or empty list () if extmark id was absent @@ -2153,6 +2163,15 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) mark will only be used for the current redraw cycle, and not be permantently stored in the buffer. + • right_gravity : boolean that indicates the + direction the extmark will be shifted in when + new text is inserted (true for right, false + for left). defaults to true. + • end_right_gravity : boolean that indicates the + direction the extmark end position (if it + exists) will be shifted in when new text is + inserted (true for right, false for left). + Defaults to false. Return: ~ Id of the created/updated extmark diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index 17de1d8533..172821ac28 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1543,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 6ca7b52fff..06666c3a27 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, + }, }, } }, @@ -620,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. @@ -659,6 +679,14 @@ get_active_clients() *vim.lsp.get_active_clients()* Return: ~ Table of |vim.lsp.client| objects + *vim.lsp.get_buffers_by_client_id()* +get_buffers_by_client_id({client_id}) + Parameters: ~ + {client_id} client id + + Return: ~ + list of buffer ids + get_client_by_id({client_id}) *vim.lsp.get_client_by_id()* Gets a client by id, or nil if the id is invalid. The returned client may not yet be fully initialized. @@ -757,8 +785,9 @@ start_client({config}) *vim.lsp.start_client()* {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 + 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` . @@ -796,7 +825,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 @@ -1323,6 +1359,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}) @@ -1340,10 +1380,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}) @@ -1370,6 +1414,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}) @@ -1393,16 +1441,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 @@ -1582,6 +1645,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. @@ -1603,6 +1669,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 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 2e9f1847d2..98e2d50f1d 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) @@ -5533,6 +5536,12 @@ A jump table for the options with a short description can be found at |Q_op|. "auto" only when there is a sign to display "auto:[1-9]" resize to accommodate multiple signs up to the given number (maximum 9), e.g. "auto:4" + "auto:[1-8]-[2-9]" + resize to accommodate multiple signs up to the + given maximum number (maximum 9) while keeping + at least the given minimum (maximum 8) fixed + space. The minimum number should always be less + than the maximum number, e.g. "auto:2-5" "no" never "yes" always "yes:[1-9]" always, with fixed space for signs up to the given @@ -6280,6 +6289,29 @@ A jump table for the options with a short description can be found at |Q_op|. attributes instead of "cterm" attributes. |highlight-guifg| Requires an ISO-8613-3 compatible terminal. + *'termpastefilter'* *'tpf'* +'termpastefilter' 'tpf' string (default: "BS,HT,ESC,DEL") + global + A comma separated list of options for specifying control characters + to be removed from the text pasted into the terminal window. The + supported values are: + + BS Backspace + + HT TAB + + FF Form feed + + ESC Escape + + DEL DEL + + C0 Other control characters, excluding Line feed and + Carriage return < ' ' + + C1 Control characters 0x80...0x9F + + *'terse'* *'noterse'* 'terse' boolean (default off) global 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/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/various.txt b/runtime/doc/various.txt index b6885d6e25..5fb7c4ce50 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -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/filetype.vim b/runtime/filetype.vim index 959fe35662..53fd66c4df 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -585,6 +585,9 @@ au BufNewFile,BufRead *.fan,*.fwt setf fan " Factor au BufNewFile,BufRead *.factor setf factor +" Fennel +autocmd BufRead,BufNewFile *.fnl setf fennel + " Fetchmail RC file au BufNewFile,BufRead .fetchmailrc setf fetchmail @@ -1169,8 +1172,11 @@ au BufNewFile,BufRead *.papp,*.pxml,*.pxsl setf papp " Password file 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 +" Pascal (also *.p, *.pp, *.inc) +au BufNewFile,BufRead *.pas setf pascal + +" Pascal or Puppet manifest +au BufNewFile,BufRead *.pp call dist#ft#FTpp() " Delphi or Lazarus program file au BufNewFile,BufRead *.dpr,*.lpr setf pascal @@ -1260,7 +1266,7 @@ au BufNewFile,BufRead *.pov setf pov " Povray configuration au BufNewFile,BufRead .povrayrc setf povini -" Povray, PHP or assembly +" Povray, Pascal, PHP or assembly au BufNewFile,BufRead *.inc call dist#ft#FTinc() " Printcap and Termcap @@ -1269,13 +1275,19 @@ au BufNewFile,BufRead *printcap au BufNewFile,BufRead *termcap \ let b:ptcap_type = "term" | setf ptcap -" PCCTS / ANTRL -"au BufNewFile,BufRead *.g setf antrl +" PCCTS / ANTLR +"au BufNewFile,BufRead *.g setf antlr au BufNewFile,BufRead *.g setf pccts " PPWizard au BufNewFile,BufRead *.it,*.ih setf ppwiz +" Puppet +au BufNewFile,BufRead Puppetfile setf ruby + +" Embedded Puppet +au BufNewFile,BufRead *.epp setf epuppet + " Obj 3D file format " TODO: is there a way to avoid MS-Windows Object files? au BufNewFile,BufRead *.obj setf obj @@ -1425,8 +1437,8 @@ au BufNewFile,BufRead *.rb,*.rbw setf ruby " RubyGems au BufNewFile,BufRead *.gemspec setf ruby -" Rust -au BufNewFile,BufRead *.rs setf rust +" RBS (Ruby Signature) +au BufNewFile,BufRead *.rbs setf rbs " Rackup au BufNewFile,BufRead *.ru setf ruby @@ -1440,6 +1452,9 @@ au BufNewFile,BufRead *.builder,*.rxml,*.rjs setf ruby " Rantfile and Rakefile is like Ruby au BufNewFile,BufRead [rR]antfile,*.rant,[rR]akefile,*.rake setf ruby +" Rust +au BufNewFile,BufRead *.rs setf rust + " S-lang (or shader language, or SmallLisp) au BufNewFile,BufRead *.sl setf slang @@ -1618,6 +1633,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 @@ -1728,8 +1746,13 @@ au BufNewFile,BufRead *.tli setf tli " Telix Salt au BufNewFile,BufRead *.slt setf tsalt -" Tera Term Language -au BufRead,BufNewFile *.ttl setf teraterm +" Tera Term Language or Turtle +au BufRead,BufNewFile *.ttl + \ if getline(1) =~ '^@\?\(prefix\|base\)' | + \ setf turtle | + \ else | + \ setf teraterm | + \ endif " Terminfo au BufNewFile,BufRead *.ti setf terminfo 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/ftplugin/zsh.vim b/runtime/ftplugin/zsh.vim index fe8efc59ab..53ce1417dd 100644 --- a/runtime/ftplugin/zsh.vim +++ b/runtime/ftplugin/zsh.vim @@ -2,7 +2,7 @@ " Language: Zsh shell script " Maintainer: Christian Brabandt <cb@256bit.org> " Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2017-11-22 +" Latest Revision: 2020-09-01 " License: Vim (see :h license) " Repository: https://github.com/chrisbra/vim-zsh @@ -14,11 +14,26 @@ let b:did_ftplugin = 1 let s:cpo_save = &cpo set cpo&vim -let b:undo_ftplugin = "setl com< cms< fo<" - setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql -let b:match_words = ',\<if\>:\<elif\>:\<else\>:\<fi\>' +let b:undo_ftplugin = "setl com< cms< fo< " + +if executable('zsh') + if !has('gui_running') && executable('less') + command! -buffer -nargs=1 RunHelp silent exe '!MANPAGER= zsh -ic "autoload -Uz run-help; run-help <args> 2>/dev/null | LESS= less"' | redraw! + elseif has('terminal') + command! -buffer -nargs=1 RunHelp silent exe ':term zsh -ic "autoload -Uz run-help; run-help <args>"' + else + command! -buffer -nargs=1 RunHelp echo system('zsh -ic "autoload -Uz run-help; run-help <args> 2>/dev/null"') + endif + if !exists('current_compiler') + compiler zsh + endif + setlocal keywordprg=:RunHelp + let b:undo_ftplugin .= 'keywordprg<' +endif + +let b:match_words = '\<if\>:\<elif\>:\<else\>:\<fi\>' \ . ',\<case\>:^\s*([^)]*):\<esac\>' \ . ',\<\%(select\|while\|until\|repeat\|for\%(each\)\=\)\>:\<done\>' let b:match_skip = 's:comment\|string\|heredoc\|subst' 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..a6f118abde 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -121,6 +121,9 @@ local active_clients = {} local all_buffer_active_clients = {} local uninitialized_clients = {} +-- Tracks all buffers attached to a client. +local all_client_active_buffers = {} + --@private --- Invokes a function for each LSP client attached to the buffer {bufnr}. --- @@ -226,6 +229,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 +331,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 +403,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 +433,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 +469,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 +594,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. @@ -871,9 +891,7 @@ end function lsp._text_document_did_save_handler(bufnr) bufnr = resolve_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr) - local text = once(function() - return table.concat(nvim_buf_get_lines(bufnr, 0, -1, false), '\n') - end) + local text = once(buf_get_full_text) for_each_buffer_client(bufnr, function(client, _client_id) if client.resolved_capabilities.text_document_save then local included_text @@ -916,7 +934,7 @@ function lsp.buf_attach_client(bufnr, client_id) on_lines = text_document_did_change_handler; on_detach = function() local params = { textDocument = { uri = uri; } } - for_each_buffer_client(bufnr, function(client, _client_id) + for_each_buffer_client(bufnr, function(client, _) if client.resolved_capabilities.text_document_open_close then client.notify('textDocument/didClose', params) end @@ -930,6 +948,13 @@ function lsp.buf_attach_client(bufnr, client_id) utf_sizes = true; }) end + + if not all_client_active_buffers[client_id] then + all_client_active_buffers[client_id] = {} + end + + table.insert(all_client_active_buffers[client_id], bufnr) + if buffer_client_ids[client_id] then return end -- This is our first time attaching this client to this buffer. buffer_client_ids[client_id] = true @@ -961,6 +986,19 @@ function lsp.get_client_by_id(client_id) return active_clients[client_id] or uninitialized_clients[client_id] end +--- Returns list of buffers attached to client_id. +-- +--@param client_id client id +--@returns list of buffer ids +function lsp.get_buffers_by_client_id(client_id) + local active_client_buffers = all_client_active_buffers[client_id] + if active_client_buffers then + return active_client_buffers + else + return {} + end +end + --- Stops a client(s). --- --- You can also use the `stop()` function on a |vim.lsp.client| object. @@ -978,12 +1016,23 @@ end function lsp.stop_client(client_id, force) local ids = type(client_id) == 'table' and client_id or {client_id} for _, id in ipairs(ids) do + local resolved_client_id if type(id) == 'table' and id.stop ~= nil then id.stop(force) + resolved_client_id = id.id elseif active_clients[id] then active_clients[id].stop(force) + resolved_client_id = id elseif uninitialized_clients[id] then uninitialized_clients[id].stop(true) + resolved_client_id = id + end + if resolved_client_id then + local client_buffers = lsp.get_buffers_by_client_id(resolved_client_id) + for idx = 1, #client_buffers do + lsp.diagnostic.clear(client_buffers[idx], resolved_client_id) + end + all_client_active_buffers[resolved_client_id] = nil end end end 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 87f35363b1..7eac3febd9 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -97,6 +97,18 @@ M['window/showMessageRequest'] = function(_, _, params) 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 @@ -150,6 +162,7 @@ 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 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/util.lua b/runtime/lua/vim/lsp/util.lua index ecff95f61e..00bdeecef3 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 @@ -718,7 +726,7 @@ function M.focusable_float(unique_name, fn) local bufnr = api.nvim_get_current_buf() do local win = find_window_by_var(unique_name, bufnr) - if win and api.nvim_win_is_valid(win) and not vim.fn.pumvisible() then + if win and api.nvim_win_is_valid(win) and vim.fn.pumvisible() == 0 then api.nvim_set_current_win(win) api.nvim_command("stopinsert") return 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 5a27d740a2..e49f54681d 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -340,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 @@ -353,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() @@ -385,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..3b3409bf4b 100644 --- a/runtime/scripts.vim +++ b/runtime/scripts.vim @@ -182,6 +182,14 @@ if s:line1 =~# "^#!" elseif s:name =~# 'clojure' set ft=clojure + " Free Pascal + elseif s:name =~# 'instantfpc\>' + set ft=pascal + + " Fennel + elseif s:name =~# 'fennel\>' + set ft=fennel + 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' diff --git a/runtime/syntax/zsh.vim b/runtime/syntax/zsh.vim index 3eba438aa7..819c419228 100644 --- a/runtime/syntax/zsh.vim +++ b/runtime/syntax/zsh.vim @@ -2,7 +2,7 @@ " Language: Zsh shell script " Maintainer: Christian Brabandt <cb@256bit.org> " Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2018-05-12 +" Latest Revision: 2020-11-21 " License: Vim (see :h license) " Repository: https://github.com/chrisbra/vim-zsh @@ -13,32 +13,44 @@ endif let s:cpo_save = &cpo set cpo&vim -if v:version > 704 || (v:version == 704 && has("patch1142")) - syn iskeyword @,48-57,_,192-255,#,- -else - setlocal iskeyword+=- -endif +function! s:ContainedGroup() + " needs 7.4.2008 for execute() function + let result='TOP' + " vim-pandoc syntax defines the @langname cluster for embedded syntax languages + " However, if no syntax is defined yet, `syn list @zsh` will return + " "No syntax items defined", so make sure the result is actually a valid syn cluster + for cluster in ['markdownHighlightzsh', 'zsh'] + try + " markdown syntax defines embedded clusters as @markdownhighlight<lang>, + " pandoc just uses @<lang>, so check both for both clusters + let a=split(execute('syn list @'. cluster), "\n") + if len(a) == 2 && a[0] =~# '^---' && a[1] =~? cluster + return '@'. cluster + endif + catch /E392/ + " ignore + endtry + endfor + return result +endfunction + +let s:contained=s:ContainedGroup() + +syn iskeyword @,48-57,_,192-255,#,- if get(g:, 'zsh_fold_enable', 0) setlocal foldmethod=syntax endif -syn keyword zshTodo contained TODO FIXME XXX NOTE - -syn region zshComment oneline start='\%(^\|\s\+\)#' end='$' - \ contains=zshTodo,@Spell fold - -syn region zshComment start='^\s*#' end='^\%(\s*#\)\@!' - \ contains=zshTodo,@Spell fold - -syn match zshPreProc '^\%1l#\%(!\|compdef\|autoload\).*$' - +syn match zshPOSIXQuoted '\\[xX][0-9a-fA-F]\{1,2}' +syn match zshPOSIXQuoted '\\[0-7]\{1,3}' +syn match zshPOSIXQuoted '\\u[0-9a-fA-F]\{1,4}' +syn match zshPOSIXQuoted '\\U[1-9a-fA-F]\{1,8}' syn match zshQuoted '\\.' syn region zshString matchgroup=zshStringDelimiter start=+"+ end=+"+ \ contains=zshQuoted,@zshDerefs,@zshSubst fold syn region zshString matchgroup=zshStringDelimiter start=+'+ end=+'+ fold -" XXX: This should probably be more precise, but Zsh seems a bit confused about it itself syn region zshPOSIXString matchgroup=zshStringDelimiter start=+\$'+ - \ end=+'+ contains=zshQuoted + \ skip=+\\[\\']+ end=+'+ contains=zshPOSIXQuoted,zshQuoted syn match zshJobSpec '%\(\d\+\|?\=\w\+\|[%+-]\)' syn keyword zshPrecommand noglob nocorrect exec command builtin - time @@ -112,7 +124,7 @@ syn keyword zshCommands alias autoload bg bindkey break bye cap cd \ enable eval exec exit export false fc fg \ functions getcap getln getopts hash history \ jobs kill let limit log logout popd print - \ printf pushd pushln pwd r read readonly + \ printf pushd pushln pwd r read \ rehash return sched set setcap shift \ source stat suspend test times trap true \ ttyctl type ulimit umask unalias unfunction @@ -125,7 +137,7 @@ syn keyword zshCommands alias autoload bg bindkey break bye cap cd " Create a list of option names from zsh source dir: " #!/bin/zsh " topdir=/path/to/zsh-xxx -" grep '^pindex([A-Za-z_]*)$' $topdir/Src/Doc/Zsh/optionsyo | +" grep '^pindex([A-Za-z_]*)$' $topdir/Doc/Zsh/options.yo | " while read opt " do " echo ${${(L)opt#pindex\(}%\)} @@ -136,6 +148,7 @@ syn case ignore syn match zshOptStart /^\s*\%(\%(\%(un\)\?setopt\)\|set\s+[-+]o\)/ nextgroup=zshOption skipwhite syn match zshOption / \ \%(\%(\<no_\?\)\?aliases\>\)\| + \ \%(\%(\<no_\?\)\?aliasfuncdef\>\)\|\%(\%(no_\?\)\?alias_func_def\>\)\| \ \%(\%(\<no_\?\)\?allexport\>\)\|\%(\%(no_\?\)\?all_export\>\)\| \ \%(\%(\<no_\?\)\?alwayslastprompt\>\)\|\%(\%(no_\?\)\?always_last_prompt\>\)\|\%(\%(no_\?\)\?always_lastprompt\>\)\| \ \%(\%(\<no_\?\)\?alwaystoend\>\)\|\%(\%(no_\?\)\?always_to_end\>\)\| @@ -165,10 +178,13 @@ syn match zshOption / \ \%(\%(\<no_\?\)\?casematch\>\)\|\%(\%(no_\?\)\?case_match\>\)\| \ \%(\%(\<no_\?\)\?cbases\>\)\|\%(\%(no_\?\)\?c_bases\>\)\| \ \%(\%(\<no_\?\)\?cdablevars\>\)\|\%(\%(no_\?\)\?cdable_vars\>\)\|\%(\%(no_\?\)\?cd_able_vars\>\)\| + \ \%(\%(\<no_\?\)\?cdsilent\>\)\|\%(\%(no_\?\)\?cd_silent\>\)\|\%(\%(no_\?\)\?cd_silent\>\)\| \ \%(\%(\<no_\?\)\?chasedots\>\)\|\%(\%(no_\?\)\?chase_dots\>\)\| \ \%(\%(\<no_\?\)\?chaselinks\>\)\|\%(\%(no_\?\)\?chase_links\>\)\| \ \%(\%(\<no_\?\)\?checkjobs\>\)\|\%(\%(no_\?\)\?check_jobs\>\)\| + \ \%(\%(\<no_\?\)\?checkrunningjobs\>\)\|\%(\%(no_\?\)\?check_running_jobs\>\)\| \ \%(\%(\<no_\?\)\?clobber\>\)\| + \ \%(\%(\<no_\?\)\?clobberempty\>\)\|\%(\%(no_\?\)\?clobber_empty\>\)\| \ \%(\%(\<no_\?\)\?combiningchars\>\)\|\%(\%(no_\?\)\?combining_chars\>\)\| \ \%(\%(\<no_\?\)\?completealiases\>\)\|\%(\%(no_\?\)\?complete_aliases\>\)\| \ \%(\%(\<no_\?\)\?completeinword\>\)\|\%(\%(no_\?\)\?complete_in_word\>\)\| @@ -188,7 +204,7 @@ syn match zshOption / \ \%(\%(\<no_\?\)\?equals\>\)\| \ \%(\%(\<no_\?\)\?errexit\>\)\|\%(\%(no_\?\)\?err_exit\>\)\| \ \%(\%(\<no_\?\)\?errreturn\>\)\|\%(\%(no_\?\)\?err_return\>\)\| - \ \%(\%(\<no_\?\)\?evallineno_\?\)\|\%(\%(no_\?\)\?eval_lineno_\?\)\| + \ \%(\%(\<no_\?\)\?evallineno\>\)\|\%(\%(no_\?\)\?eval_lineno\>\)\| \ \%(\%(\<no_\?\)\?exec\>\)\| \ \%(\%(\<no_\?\)\?extendedglob\>\)\|\%(\%(no_\?\)\?extended_glob\>\)\| \ \%(\%(\<no_\?\)\?extendedhistory\>\)\|\%(\%(no_\?\)\?extended_history\>\)\| @@ -309,6 +325,7 @@ syn match zshOption / \ \%(\%(\<no_\?\)\?shnullcmd\>\)\|\%(\%(no_\?\)\?sh_nullcmd\>\)\| \ \%(\%(\<no_\?\)\?shoptionletters\>\)\|\%(\%(no_\?\)\?sh_option_letters\>\)\| \ \%(\%(\<no_\?\)\?shortloops\>\)\|\%(\%(no_\?\)\?short_loops\>\)\| + \ \%(\%(\<no_\?\)\?shortrepeat\>\)\|\%(\%(no_\?\)\?short_repeat\>\)\| \ \%(\%(\<no_\?\)\?shwordsplit\>\)\|\%(\%(no_\?\)\?sh_word_split\>\)\| \ \%(\%(\<no_\?\)\?singlecommand\>\)\|\%(\%(no_\?\)\?single_command\>\)\| \ \%(\%(\<no_\?\)\?singlelinezle\>\)\|\%(\%(no_\?\)\?single_line_zle\>\)\| @@ -322,10 +339,13 @@ syn match zshOption / \ \%(\%(\<no_\?\)\?unset\>\)\| \ \%(\%(\<no_\?\)\?verbose\>\)\| \ \%(\%(\<no_\?\)\?vi\>\)\| + \ \%(\%(\<no_\?\)\?warnnestedvar\>\)\|\%(\%(no_\?\)\?warn_nested_var\>\)\| \ \%(\%(\<no_\?\)\?warncreateglobal\>\)\|\%(\%(no_\?\)\?warn_create_global\>\)\| \ \%(\%(\<no_\?\)\?xtrace\>\)\| \ \%(\%(\<no_\?\)\?zle\>\)/ nextgroup=zshOption,zshComment skipwhite contained +syn case match + syn keyword zshTypes float integer local typeset declare private readonly " XXX: this may be too much @@ -339,31 +359,42 @@ syn match zshNumber '[+-]\=\d\+\.\d\+\>' " TODO: $[...] is the same as $((...)), so add that as well. syn cluster zshSubst contains=zshSubst,zshOldSubst,zshMathSubst -syn region zshSubst matchgroup=zshSubstDelim transparent - \ start='\$(' skip='\\)' end=')' contains=TOP fold +exe 'syn region zshSubst matchgroup=zshSubstDelim transparent start=/\$(/ skip=/\\)/ end=/)/ contains='.s:contained. ' fold' syn region zshParentheses transparent start='(' skip='\\)' end=')' fold syn region zshGlob start='(#' end=')' syn region zshMathSubst matchgroup=zshSubstDelim transparent - \ start='\$((' skip='\\)' end='))' + \ start='\%(\$\?\)[<=>]\@<!((' skip='\\)' end='))' \ contains=zshParentheses,@zshSubst,zshNumber, \ @zshDerefs,zshString keepend fold -syn region zshBrackets contained transparent start='{' skip='\\}' +" The ms=s+1 prevents matching zshBrackets several times on opening brackets +" (see https://github.com/chrisbra/vim-zsh/issues/21#issuecomment-576330348) +syn region zshBrackets contained transparent start='{'ms=s+1 skip='\\}' \ end='}' fold -syn region zshBrackets transparent start='{' skip='\\}' - \ end='}' contains=TOP fold +exe 'syn region zshBrackets transparent start=/{/ms=s+1 skip=/\\}/ end=/}/ contains='.s:contained. ' fold' + syn region zshSubst matchgroup=zshSubstDelim start='\${' skip='\\}' \ end='}' contains=@zshSubst,zshBrackets,zshQuoted,zshString fold -syn region zshOldSubst matchgroup=zshSubstDelim start=+`+ skip=+\\`+ - \ end=+`+ contains=TOP,zshOldSubst fold +exe 'syn region zshOldSubst matchgroup=zshSubstDelim start=/`/ skip=/\\[\\`]/ end=/`/ contains='.s:contained. ',zshOldSubst fold' syn sync minlines=50 maxlines=90 syn sync match zshHereDocSync grouphere NONE '<<-\=\s*\%(\\\=\S\+\|\(["']\)\S\+\1\)' syn sync match zshHereDocEndSync groupthere NONE '^\s*EO\a\+\>' +syn keyword zshTodo contained TODO FIXME XXX NOTE + +syn region zshComment oneline start='\%(^\|\s\+\)#' end='$' + \ contains=zshTodo,@Spell fold + +syn region zshComment start='^\s*#' end='^\%(\s*#\)\@!' + \ contains=zshTodo,@Spell fold + +syn match zshPreProc '^\%1l#\%(!\|compdef\|autoload\).*$' + hi def link zshTodo Todo hi def link zshComment Comment hi def link zshPreProc PreProc hi def link zshQuoted SpecialChar +hi def link zshPOSIXQuoted SpecialChar hi def link zshString String hi def link zshStringDelimiter zshString hi def link zshPOSIXString zshString |