diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/doc/autocmd.txt | 3 | ||||
-rw-r--r-- | runtime/doc/cmdline.txt | 8 | ||||
-rw-r--r-- | runtime/doc/diagnostic.txt | 3 | ||||
-rw-r--r-- | runtime/doc/hebrew.txt | 41 | ||||
-rw-r--r-- | runtime/doc/index.txt | 5 | ||||
-rw-r--r-- | runtime/doc/insert.txt | 6 | ||||
-rw-r--r-- | runtime/doc/lsp.txt | 6 | ||||
-rw-r--r-- | runtime/doc/news.txt | 3 | ||||
-rw-r--r-- | runtime/doc/options.txt | 9 | ||||
-rw-r--r-- | runtime/doc/quickref.txt | 7 | ||||
-rw-r--r-- | runtime/doc/starting.txt | 3 | ||||
-rw-r--r-- | runtime/doc/tabpage.txt | 15 | ||||
-rw-r--r-- | runtime/indent/json5.vim | 11 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/options.lua | 9 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 21 | ||||
-rw-r--r-- | runtime/lua/vim/filetype.lua | 5 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 343 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/client.lua | 24 | ||||
-rw-r--r-- | runtime/syntax/java.vim | 51 |
19 files changed, 275 insertions, 298 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 8890872e1a..b3974e3246 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -884,6 +884,9 @@ SafeState When nothing is pending, going to wait for the *SessionLoadPost* SessionLoadPost After loading the session file created using the |:mksession| command. + *SessionWritePost* +SessionWritePost After writing a session file by calling + the |:mksession| command. *ShellCmdPost* ShellCmdPost After executing a shell command with |:!cmd|, |:make| and |:grep|. Can be used to check for diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 57a4223c53..f306067a9c 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -274,14 +274,6 @@ CTRL-P command-line completion (see |cmdline-completion|) CTRL-A command-line completion (see |cmdline-completion|) CTRL-L command-line completion (see |cmdline-completion|) - *c_CTRL-_* -CTRL-_ Switch between Hebrew and English keyboard mode, which is - private to the command-line and not related to hkmap. - This is useful when Hebrew text entry is required in the - command-line, searches, abbreviations, etc. Applies only if - the 'allowrevins' option is set. - See |rileft.txt|. - *c_CTRL-^* CTRL-^ Toggle the use of language |:lmap| mappings and/or Input Method. diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index c9e783ca62..a9172119d0 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -371,7 +371,8 @@ Lua module: vim.diagnostic *diagnostic-api* A table with the following keys: Fields: ~ - • {namespace}? (`integer`) Limit diagnostics to the given namespace. + • {namespace}? (`integer[]|integer`) Limit diagnostics to one or more + namespaces. • {lnum}? (`integer`) Limit diagnostics to the given line number. • {severity}? (`vim.diagnostic.SeverityFilter`) See |diagnostic-severity|. diff --git a/runtime/doc/hebrew.txt b/runtime/doc/hebrew.txt index e38385e13a..c19b4b9835 100644 --- a/runtime/doc/hebrew.txt +++ b/runtime/doc/hebrew.txt @@ -14,7 +14,7 @@ currently helping support these features. ------------------------------------------------------------------------------ Introduction -Hebrew-specific options are 'hkmap', 'hkmapp' 'keymap'=hebrew and 'aleph'. +Hebrew-specific 'keymap' values are "hebrew" and "hebrewp". Hebrew-useful options are 'delcombine', 'allowrevins', 'revins', 'rightleft' and 'rightleftcmd'. @@ -30,7 +30,7 @@ Details + 'rightleft' ('rl') sets window orientation to right-to-left. This means that the logical text 'ABC' will be displayed as 'CBA', and will start drawing at the right edge of the window, not the left edge. - + 'keymap' ('kmp') sets keyboard mapping. use values "hebrew" or "heprewp" + + 'keymap' ('kmp') sets keyboard mapping. use values "hebrew" or "hebrewp" (the latter option enables phonetic mapping) + 'delcombine' ('deco'), boolean, allows one to remove the niqud or te`amim by pressing 'x' on a character (with associated niqud). @@ -41,35 +41,23 @@ Details + Encoding: + Under Unix, ISO 8859-8 encoding (Hebrew letters codes: 224-250). + Under MS DOS, PC encoding (Hebrew letters codes: 128-154). - These are defaults, that can be overridden using the 'aleph' option. + You should prefer using UTF8, as it supports the combining-characters ('deco' does nothing if UTF8 encoding is not active). + Vim arguments: - + `vim -H file` starts editing a Hebrew file, i.e. 'rightleft' and 'hkmap' - are set. + + `vim -H file` starts editing a Hebrew file, i.e. 'rightleft' is set and + 'keymap' is set to "hebrew". + Keyboard: - + The 'allowrevins' option enables the CTRL-_ command in Insert mode and - in Command-line mode. + + The 'allowrevins' option enables the CTRL-_ command in Insert mode. - + CTRL-_ in insert/replace modes toggles 'revins' and 'hkmap' as follows: - - When in rightleft window, 'revins' is toggled, since - English will likely be inserted in this case. - - When in norightleft window, 'revins' is toggled, since Hebrew - will likely be inserted in this case. + + CTRL-_ in Insert mode toggles 'revins'. CTRL-_ moves the cursor to the end of the typed text. - + CTRL-_ in command mode only toggles keyboard mapping (see Bugs below). - This setting is independent of 'hkmap' option, which only applies to - insert/replace mode. - Note: On some keyboards, CTRL-_ is mapped to CTRL-?. - + Keyboard mapping while 'hkmap' is set (standard Israeli keyboard): + + Keyboard mapping while 'keymap' is "hebrew" (standard Israeli keyboard): q w e r t y u i o p / ' ק ר א ט ו ן ם פ @@ -80,11 +68,8 @@ Details z x c v b n m , . / ז ס ב ה נ מ צ ת ץ . - This is also the keymap when 'keymap=hebrew' is set. The advantage of - 'keymap' is that it works properly when using UTF8, e.g. it inserts the - correct characters; 'hkmap' does not. The 'keymap' keyboard can also - insert niqud and te`amim. To see what those mappings are, look at the - keymap file 'hebrew.vim' etc. + The 'keymap' keyboard can also insert niqud and te`amim. To see what + those mappings are, look at the keymap file hebrew.vim etc. Typing backwards @@ -102,13 +87,7 @@ If the 'showmode' option is set, "-- REVERSE INSERT --" will be shown in the status line when reverse Insert mode is active. When the 'allowrevins' option is set, reverse Insert mode can be also entered -via CTRL-_, which has some extra functionality: First, keyboard mapping is -changed according to the window orientation -- if in a left-to-right window, -'revins' is used to enter Hebrew text, so the keyboard changes to Hebrew -('hkmap' is set); if in a right-to-left window, 'revins' is used to enter -English text, so the keyboard changes to English ('hkmap' is reset). Second, -when exiting 'revins' via CTRL-_, the cursor moves to the end of the typed -text (if possible). +and exited via CTRL-_. ------------------------------------------------------------------------------ diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index 969346c4c7..79f10b33f1 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -92,8 +92,7 @@ tag char action in Insert mode ~ CTRL-\ others not used |i_CTRL-]| CTRL-] trigger abbreviation |i_CTRL-^| CTRL-^ toggle use of |:lmap| mappings -|i_CTRL-_| CTRL-_ When 'allowrevins' set: change language - (Hebrew) +|i_CTRL-_| CTRL-_ When 'allowrevins' set: toggle 'revins' <Space> to '~' not used, except '0' and '^' followed by CTRL-D @@ -1072,8 +1071,6 @@ tag command action in Command-line editing mode ~ CTRL-\ others not used |c_CTRL-]| CTRL-] trigger abbreviation |c_CTRL-^| CTRL-^ toggle use of |:lmap| mappings -|c_CTRL-_| CTRL-_ when 'allowrevins' set: change language - (Hebrew) |c_<Del>| <Del> delete the character under the cursor |c_<Left>| <Left> cursor left diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 34affb22e9..91b0d41f1c 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -225,11 +225,7 @@ CTRL-Y Insert the character which is above the cursor. able to copy characters from a long line. *i_CTRL-_* -CTRL-_ Switch between insert direction, by toggling 'revins', as follows: - - When in a rightleft window, 'revins' is toggled, - since English will likely be inserted in this case. - - When in a norightleft window, 'revins' is toggled, - since a rightleft language will likely be inserted in this case. +CTRL-_ Switch between insert direction, by toggling 'revins'. CTRL-_ moves the cursor to the end of the typed text. diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index ed5e3b63f9..70b8878837 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -907,8 +907,8 @@ stop_client({client_id}, {force}) *vim.lsp.stop_client()* for this client, then force-shutdown is attempted. Parameters: ~ - • {client_id} (`integer|vim.lsp.Client`) id or |vim.lsp.Client| object, - or list thereof + • {client_id} (`integer|integer[]|vim.lsp.Client[]`) id, list of id's, + or list of |vim.lsp.Client| objects • {force} (`boolean?`) shutdown forcefully tagfunc({pattern}, {flags}) *vim.lsp.tagfunc()* @@ -1016,7 +1016,7 @@ Lua module: vim.lsp.client *lsp-client* • {capabilities} (`lsp.ClientCapabilities`) The capabilities provided by the client (editor or tool) • {dynamic_capabilities} (`lsp.DynamicCapabilities`) - • {request} (`fun(method: string, params: table?, handler: lsp.Handler?, bufnr: integer): boolean, integer?`) + • {request} (`fun(method: string, params: table?, handler: lsp.Handler?, bufnr: integer?): boolean, integer?`) Sends a request to the server. This is a thin wrapper around {client.rpc.request} with some additional checking. If {handler} is not diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 0222d547b0..1aee5c656b 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -408,6 +408,9 @@ The following changes to existing APIs or features add new behavior. "virtual_text" table, which gives users more control over how diagnostic virtual text is displayed. +• |vim.diagnostic.get()| and |vim.diagnostic.count()| accept multiple + namespaces rather than just a single namespace. + • Extmarks now fully support multi-line ranges, and a single extmark can be used to highlight a range of arbitrary length. The |nvim_buf_set_extmark()| API function already allowed you to define such ranges, but highlight regions diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index dd3b60b7b8..3cc5b6af64 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -639,10 +639,9 @@ A jump table for the options with a short description can be found at |Q_op|. *'allowrevins'* *'ari'* *'noallowrevins'* *'noari'* 'allowrevins' 'ari' boolean (default off) global - Allow CTRL-_ in Insert and Command-line mode. This is default off, to - avoid that users that accidentally type CTRL-_ instead of SHIFT-_ get - into reverse Insert mode, and don't know how to get out. See - 'revins'. + Allow CTRL-_ in Insert mode. This is default off, to avoid that users + that accidentally type CTRL-_ instead of SHIFT-_ get into reverse + Insert mode, and don't know how to get out. See 'revins'. *'ambiwidth'* *'ambw'* 'ambiwidth' 'ambw' string (default "single") @@ -6349,7 +6348,7 @@ A jump table for the options with a short description can be found at |Q_op|. appear wrong in many places. The value must be more than 0 and less than 10000. - There are four main ways to use tabs in Vim: + There are five main ways to use tabs in Vim: 1. Always keep 'tabstop' at 8, set 'softtabstop' and 'shiftwidth' to 4 (or 3 or whatever you prefer) and use 'noexpandtab'. Then Vim will use a mix of tabs and spaces, but typing <Tab> and <BS> will diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 4ef4392f92..c0d00d16cb 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -620,8 +620,7 @@ In Insert or Command-line mode: the help Short explanation of each option: *option-list* -'aleph' 'al' ASCII code of the letter Aleph (Hebrew) -'allowrevins' 'ari' allow CTRL-_ in Insert and Command-line mode +'allowrevins' 'ari' allow CTRL-_ in Insert mode 'ambiwidth' 'ambw' what to do with Unicode chars of ambiguous width 'arabic' 'arab' for Arabic as a default second language 'arabicshape' 'arshape' do shaping for Arabic characters @@ -739,8 +738,6 @@ Short explanation of each option: *option-list* 'helplang' 'hlg' preferred help languages 'hidden' 'hid' don't unload buffer when it is |abandon|ed 'history' 'hi' number of command-lines that are remembered -'hkmap' 'hk' Hebrew keyboard mapping -'hkmapp' 'hkp' phonetic Hebrew keyboard mapping 'hlsearch' 'hls' highlight matches with last search pattern 'icon' let Vim set the text of the window icon 'iconstring' string to use for the Vim icon text @@ -1141,7 +1138,7 @@ Context-sensitive completion on the command-line: |-b| -b binary mode |-l| -l lisp mode |-A| -A Arabic mode ('arabic' is set) -|-H| -H Hebrew mode ('hkmap' and 'rightleft' are set) +|-H| -H Hebrew mode (Hebrew keymap & 'rightleft' are set) |-V| -V Verbose, give informative messages |-r| -r give list of swap files |-r| -r {file} .. recover aborted edit session diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index b2b5568ee6..fb8ed0344b 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -260,7 +260,8 @@ argument. -A Arabic mode. Sets the 'arabic' option on. *-H* --H Hebrew mode. Sets the 'rightleft' option on and 'keymap' to "hebrew" +-H Hebrew mode. Sets the 'rightleft' option on and the 'keymap' + option to "hebrew". *-V* *verbose* -V[N] Verbose. Sets the 'verbose' option to [N] (default: 10). diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt index 49b2773253..649af628d6 100644 --- a/runtime/doc/tabpage.txt +++ b/runtime/doc/tabpage.txt @@ -187,7 +187,7 @@ gt *i_CTRL-<PageDown>* *i_<C-PageDown>* :1tabnext " go to the first tab page :$tabnext " go to the last tab page :tabnext $ " as above - :tabnext # " go to the last accessed tab page + :tabnext # " go to the last accessed tab page :tabnext - " go to the previous tab page :tabnext -1 " as above :tabnext + " go to the next tab page @@ -239,18 +239,17 @@ REORDERING TAB PAGES: Move the current tab page to after tab page N. Use zero to make the current tab page the first one. N is counted before the move, thus if the second tab is the current one, - `:tabmove 1` and `:tabmove 2` have no effect. + `:tabmove 1` and `:tabmove 2` have no effect. Without N the tab page is made the last one. > - :.tabmove " do nothing - :-tabmove " move the tab page to the left - :+tabmove " move the tab page to the right - :0tabmove " move the tab page to the beginning of the tab - " list + :.tabmove " do nothing + :-tabmove " move the tab page to the left + :+tabmove " move the tab page to the right + :0tabmove " move the tab page to the first :tabmove 0 " as above :tabmove " move the tab page to the last :$tabmove " as above :tabmove $ " as above - :tabmove # " move the tab page after the last accessed + :tabmove # " move the tab page after the last accessed " tab page :tabm[ove] +[N] diff --git a/runtime/indent/json5.vim b/runtime/indent/json5.vim new file mode 100644 index 0000000000..5977a4b912 --- /dev/null +++ b/runtime/indent/json5.vim @@ -0,0 +1,11 @@ +" Vim indent file +" Language: JSON5 +" Maintainer: The Vim Project <https://github.com/vim/vim> +" Last Change: 2024-03-26 + +if exists("b:did_indent") + finish +endif + +" Same as jsonc indenting for now +runtime! indent/jsonc.vim diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index ac366197cc..e8e56e86b2 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -11,10 +11,9 @@ vim.bo = vim.bo ---@field [integer] vim.wo vim.wo = vim.wo ---- Allow CTRL-_ in Insert and Command-line mode. This is default off, to ---- avoid that users that accidentally type CTRL-_ instead of SHIFT-_ get ---- into reverse Insert mode, and don't know how to get out. See ---- 'revins'. +--- Allow CTRL-_ in Insert mode. This is default off, to avoid that users +--- that accidentally type CTRL-_ instead of SHIFT-_ get into reverse +--- Insert mode, and don't know how to get out. See 'revins'. --- --- @type boolean vim.o.allowrevins = false @@ -6846,7 +6845,7 @@ vim.go.tpm = vim.go.tabpagemax --- appear wrong in many places. --- The value must be more than 0 and less than 10000. --- ---- There are four main ways to use tabs in Vim: +--- There are five main ways to use tabs in Vim: --- 1. Always keep 'tabstop' at 8, set 'softtabstop' and 'shiftwidth' to 4 --- (or 3 or whatever you prefer) and use 'noexpandtab'. Then Vim --- will use a mix of tabs and spaces, but typing <Tab> and <BS> will diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index d5075d7d3d..57491d155d 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -682,6 +682,13 @@ local function get_diagnostics(bufnr, opts, clamp) opts = opts or {} local namespace = opts.namespace + + if type(namespace) == 'number' then + namespace = { namespace } + end + + ---@cast namespace integer[] + local diagnostics = {} -- Memoized results of buf_line_count per bufnr @@ -742,11 +749,15 @@ local function get_diagnostics(bufnr, opts, clamp) end elseif bufnr == nil then for b, t in pairs(diagnostic_cache) do - add_all_diags(b, t[namespace] or {}) + for _, iter_namespace in ipairs(namespace) do + add_all_diags(b, t[iter_namespace] or {}) + end end else bufnr = get_bufnr(bufnr) - add_all_diags(bufnr, diagnostic_cache[bufnr][namespace] or {}) + for _, iter_namespace in ipairs(namespace) do + add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace] or {}) + end end if opts.severity then @@ -785,7 +796,7 @@ end --- @param search_forward boolean --- @param bufnr integer --- @param opts vim.diagnostic.GotoOpts ---- @param namespace integer +--- @param namespace integer[]|integer --- @return vim.Diagnostic? local function next_diagnostic(position, search_forward, bufnr, opts, namespace) position[1] = position[1] - 1 @@ -1115,8 +1126,8 @@ end --- A table with the following keys: --- @class vim.diagnostic.GetOpts --- ---- Limit diagnostics to the given namespace. ---- @field namespace? integer +--- Limit diagnostics to one or more namespaces. +--- @field namespace? integer[]|integer --- --- Limit diagnostics to the given line number. --- @field lnum? integer diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index af5636a32d..a69391be18 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1472,7 +1472,6 @@ local filename = { ['bash.bashrc'] = detect.bash, bashrc = detect.bash, ['.bashrc'] = detect.bash, - ['.env'] = detect.sh, ['.kshrc'] = detect.ksh, ['.profile'] = detect.sh, ['/etc/profile'] = detect.sh, @@ -2387,7 +2386,9 @@ function M.match(args) end -- Next, check file extension - local ext = fn.fnamemodify(name, ':e') + -- Don't use fnamemodify() with :e modifier here, + -- as that's empty when there is only an extension. + local ext = name:match('%.([^.]-)$') or '' ft, on_detect = dispatch(extension[ext], path, bufnr) if ft then return ft, on_detect diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index d5c376ba44..0c9de607fe 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1,7 +1,5 @@ local api = vim.api -local tbl_isempty, tbl_extend = vim.tbl_isempty, vim.tbl_extend local validate = vim.validate -local if_nil = vim.F.if_nil local lsp = vim._defer_require('vim.lsp', { _changetracking = ..., --- @module 'vim.lsp._changetracking' @@ -108,40 +106,7 @@ function lsp._buf_get_line_ending(bufnr) end -- Tracks all clients created via lsp.start_client -local active_clients = {} --- @type table<integer,vim.lsp.Client> -local all_buffer_active_clients = {} --- @type table<integer,table<integer,true>> -local uninitialized_clients = {} --- @type table<integer,vim.lsp.Client> - ----@param bufnr? integer ----@param fn fun(client: vim.lsp.Client, client_id: integer, bufnr: integer) -local function for_each_buffer_client(bufnr, fn, restrict_client_ids) - validate({ - fn = { fn, 'f' }, - restrict_client_ids = { restrict_client_ids, 't', true }, - }) - bufnr = resolve_bufnr(bufnr) - local client_ids = all_buffer_active_clients[bufnr] - if not client_ids or tbl_isempty(client_ids) then - return - end - - if restrict_client_ids and #restrict_client_ids > 0 then - local filtered_client_ids = {} --- @type table<integer,true> - for client_id in pairs(client_ids) do - if vim.list_contains(restrict_client_ids, client_id) then - filtered_client_ids[client_id] = true - end - end - client_ids = filtered_client_ids - end - - for client_id in pairs(client_ids) do - local client = active_clients[client_id] - if client then - fn(client, client_id, bufnr) - end - end -end +local all_clients = {} --- @type table<integer,vim.lsp.Client> local client_errors_base = table.maxn(lsp.rpc.client_errors) local client_errors_offset = 0 @@ -156,7 +121,7 @@ end --- Can be used to look up the string from a the number or the number --- from the string. --- @nodoc -lsp.client_errors = tbl_extend( +lsp.client_errors = vim.tbl_extend( 'error', lsp.rpc.client_errors, client_error('BEFORE_INIT_CALLBACK_ERROR'), @@ -258,12 +223,10 @@ function lsp.start(config, opts) local bufnr = resolve_bufnr(opts.bufnr) - for _, clients in ipairs({ uninitialized_clients, lsp.get_clients() }) do - for _, client in pairs(clients) do - if reuse_client(client, config) then - lsp.buf_attach_client(bufnr, client.id) - return client.id - end + for _, client in pairs(all_clients) do + if reuse_client(client, config) then + lsp.buf_attach_client(bufnr, client.id) + return client.id end end @@ -383,48 +346,30 @@ local function reset_defaults(bufnr) end) end ---- @param client vim.lsp.Client -local function on_client_init(client) - local id = client.id - uninitialized_clients[id] = nil - -- Only assign after initialized. - active_clients[id] = client - -- If we had been registered before we start, then send didOpen This can - -- happen if we attach to buffers before initialize finishes or if - -- someone restarts a client. - for bufnr, client_ids in pairs(all_buffer_active_clients) do - if client_ids[id] then - client.on_attach(bufnr) - end - end -end - --- @param code integer --- @param signal integer --- @param client_id integer local function on_client_exit(code, signal, client_id) - local client = active_clients[client_id] or uninitialized_clients[client_id] - - for bufnr, client_ids in pairs(all_buffer_active_clients) do - if client_ids[client_id] then - vim.schedule(function() - if client and client.attached_buffers[bufnr] then - api.nvim_exec_autocmds('LspDetach', { - buffer = bufnr, - modeline = false, - data = { client_id = client_id }, - }) - end + local client = all_clients[client_id] + + for bufnr in pairs(client.attached_buffers) do + vim.schedule(function() + if client and client.attached_buffers[bufnr] then + api.nvim_exec_autocmds('LspDetach', { + buffer = bufnr, + modeline = false, + data = { client_id = client_id }, + }) + end - local namespace = vim.lsp.diagnostic.get_namespace(client_id) - vim.diagnostic.reset(namespace, bufnr) + local namespace = vim.lsp.diagnostic.get_namespace(client_id) + vim.diagnostic.reset(namespace, bufnr) + client.attached_buffers[bufnr] = nil - client_ids[client_id] = nil - if vim.tbl_isempty(client_ids) then - reset_defaults(bufnr) - end - end) - end + if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then + reset_defaults(bufnr) + end + end) end local name = client.name or 'unknown' @@ -432,8 +377,7 @@ local function on_client_exit(code, signal, client_id) -- Schedule the deletion of the client object so that it exists in the execution of LspDetach -- autocommands vim.schedule(function() - active_clients[client_id] = nil - uninitialized_clients[client_id] = nil + all_clients[client_id] = nil -- Client can be absent if executable starts, but initialize fails -- init/attach won't have happened @@ -466,12 +410,9 @@ function lsp.start_client(config) end --- @diagnostic disable-next-line: invisible - table.insert(client._on_init_cbs, on_client_init) - --- @diagnostic disable-next-line: invisible table.insert(client._on_exit_cbs, on_client_exit) - -- Store the uninitialized_clients for cleanup in case we exit before initialize finishes. - uninitialized_clients[client.id] = client + all_clients[client.id] = client client:initialize() @@ -495,7 +436,7 @@ local function text_document_did_change_handler( new_lastline ) -- Detach (nvim_buf_attach) via returning True to on_lines if no clients are attached - if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then + if #lsp.get_clients({ bufnr = bufnr }) == 0 then return true end util.buf_versions[bufnr] = changedtick @@ -543,6 +484,80 @@ local function text_document_did_save_handler(bufnr) end end +--- @param bufnr integer +--- @param client_id integer +local function buf_attach(bufnr, client_id) + local uri = vim.uri_from_bufnr(bufnr) + local augroup = ('lsp_c_%d_b_%d_save'):format(client_id, bufnr) + local group = api.nvim_create_augroup(augroup, { clear = true }) + api.nvim_create_autocmd('BufWritePre', { + group = group, + buffer = bufnr, + desc = 'vim.lsp: textDocument/willSave', + callback = function(ctx) + for _, client in ipairs(lsp.get_clients({ bufnr = ctx.buf })) do + local params = { + textDocument = { + uri = uri, + }, + reason = protocol.TextDocumentSaveReason.Manual, + } + if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'willSave') then + client.notify(ms.textDocument_willSave, params) + end + if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'willSaveWaitUntil') then + local result, err = + client.request_sync(ms.textDocument_willSaveWaitUntil, params, 1000, ctx.buf) + if result and result.result then + util.apply_text_edits(result.result, ctx.buf, client.offset_encoding) + elseif err then + log.error(vim.inspect(err)) + end + end + end + end, + }) + api.nvim_create_autocmd('BufWritePost', { + group = group, + buffer = bufnr, + desc = 'vim.lsp: textDocument/didSave handler', + callback = function(ctx) + text_document_did_save_handler(ctx.buf) + end, + }) + -- First time, so attach and set up stuff. + api.nvim_buf_attach(bufnr, false, { + on_lines = text_document_did_change_handler, + on_reload = function() + local params = { textDocument = { uri = uri } } + for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do + changetracking.reset_buf(client, bufnr) + if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then + client.notify(ms.textDocument_didClose, params) + end + client:_text_document_did_open_handler(bufnr) + end + end, + on_detach = function() + local params = { textDocument = { uri = uri } } + for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do + changetracking.reset_buf(client, bufnr) + if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then + client.notify(ms.textDocument_didClose, params) + end + end + for _, client in ipairs(all_clients) do + client.attached_buffers[bufnr] = nil + end + util.buf_versions[bufnr] = nil + end, + -- TODO if we know all of the potential clients ahead of time, then we + -- could conditionally set this. + -- utf_sizes = size_index > 1; + utf_sizes = true, + }) +end + --- Implements the `textDocument/did…` notifications required to track a buffer --- for any language server. --- @@ -561,92 +576,26 @@ function lsp.buf_attach_client(bufnr, client_id) log.warn(string.format('buf_attach_client called on unloaded buffer (id: %d): ', bufnr)) return false end - local buffer_client_ids = all_buffer_active_clients[bufnr] -- This is our first time attaching to this buffer. - if not buffer_client_ids then - buffer_client_ids = {} - all_buffer_active_clients[bufnr] = buffer_client_ids + if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then + buf_attach(bufnr, client_id) + end - local uri = vim.uri_from_bufnr(bufnr) - local augroup = ('lsp_c_%d_b_%d_save'):format(client_id, bufnr) - local group = api.nvim_create_augroup(augroup, { clear = true }) - api.nvim_create_autocmd('BufWritePre', { - group = group, - buffer = bufnr, - desc = 'vim.lsp: textDocument/willSave', - callback = function(ctx) - for _, client in ipairs(lsp.get_clients({ bufnr = ctx.buf })) do - local params = { - textDocument = { - uri = uri, - }, - reason = protocol.TextDocumentSaveReason.Manual, - } - if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'willSave') then - client.notify(ms.textDocument_willSave, params) - end - if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'willSaveWaitUntil') then - local result, err = - client.request_sync(ms.textDocument_willSaveWaitUntil, params, 1000, ctx.buf) - if result and result.result then - util.apply_text_edits(result.result, ctx.buf, client.offset_encoding) - elseif err then - log.error(vim.inspect(err)) - end - end - end - end, - }) - api.nvim_create_autocmd('BufWritePost', { - group = group, - buffer = bufnr, - desc = 'vim.lsp: textDocument/didSave handler', - callback = function(ctx) - text_document_did_save_handler(ctx.buf) - end, - }) - -- First time, so attach and set up stuff. - api.nvim_buf_attach(bufnr, false, { - on_lines = text_document_did_change_handler, - on_reload = function() - local params = { textDocument = { uri = uri } } - for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do - changetracking.reset_buf(client, bufnr) - if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then - client.notify(ms.textDocument_didClose, params) - end - client:_text_document_did_open_handler(bufnr) - end - end, - on_detach = function() - local params = { textDocument = { uri = uri } } - for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do - changetracking.reset_buf(client, bufnr) - if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then - client.notify(ms.textDocument_didClose, params) - end - client.attached_buffers[bufnr] = nil - end - util.buf_versions[bufnr] = nil - all_buffer_active_clients[bufnr] = nil - end, - -- TODO if we know all of the potential clients ahead of time, then we - -- could conditionally set this. - -- utf_sizes = size_index > 1; - utf_sizes = true, - }) + local client = lsp.get_client_by_id(client_id) + if not client then + return false end - if buffer_client_ids[client_id] then + if client.attached_buffers[bufnr] then return true end - -- This is our first time attaching this client to this buffer. - buffer_client_ids[client_id] = true - local client = active_clients[client_id] + client.attached_buffers[bufnr] = true + + -- This is our first time attaching this client to this buffer. -- Send didOpen for the client if it is initialized. If it isn't initialized -- then it will send didOpen on initialize. - if client then + if client.initialized then client:_on_attach(bufnr) end return true @@ -665,7 +614,7 @@ function lsp.buf_detach_client(bufnr, client_id) }) bufnr = resolve_bufnr(bufnr) - local client = lsp.get_client_by_id(client_id) + local client = all_clients[client_id] if not client or not client.attached_buffers[bufnr] then vim.notify( string.format( @@ -694,11 +643,6 @@ function lsp.buf_detach_client(bufnr, client_id) client.attached_buffers[bufnr] = nil util.buf_versions[bufnr] = nil - all_buffer_active_clients[bufnr][client_id] = nil - if #vim.tbl_keys(all_buffer_active_clients[bufnr]) == 0 then - all_buffer_active_clients[bufnr] = nil - end - local namespace = lsp.diagnostic.get_namespace(client_id) vim.diagnostic.reset(namespace, bufnr) end @@ -708,7 +652,7 @@ end ---@param bufnr (integer) Buffer handle, or 0 for current ---@param client_id (integer) the client id function lsp.buf_is_attached(bufnr, client_id) - return (all_buffer_active_clients[resolve_bufnr(bufnr)] or {})[client_id] == true + return lsp.get_clients({ bufnr = bufnr, id = client_id, _uninitialized = true })[1] ~= nil end --- Gets a client by id, or nil if the id is invalid. @@ -718,7 +662,7 @@ end --- ---@return (nil|vim.lsp.Client) client rpc object function lsp.get_client_by_id(client_id) - return active_clients[client_id] or uninitialized_clients[client_id] + return all_clients[client_id] end --- Returns list of buffers attached to client_id. @@ -726,7 +670,7 @@ end ---@param client_id integer client id ---@return integer[] buffers list of buffer ids function lsp.get_buffers_by_client_id(client_id) - local client = lsp.get_client_by_id(client_id) + local client = all_clients[client_id] return client and vim.tbl_keys(client.attached_buffers) or {} end @@ -742,17 +686,22 @@ end --- By default asks the server to shutdown, unless stop was requested --- already for this client, then force-shutdown is attempted. --- ----@param client_id integer|vim.lsp.Client id or |vim.lsp.Client| object, or list thereof ----@param force boolean|nil shutdown forcefully +---@param client_id integer|integer[]|vim.lsp.Client[] id, list of id's, or list of |vim.lsp.Client| objects +---@param force? boolean shutdown forcefully function lsp.stop_client(client_id, force) + --- @type integer[]|vim.lsp.Client[] local ids = type(client_id) == 'table' and client_id or { client_id } for _, id in ipairs(ids) do - if type(id) == 'table' and id.stop ~= nil then - id.stop(force) - elseif active_clients[id] then - active_clients[id].stop(force) - elseif uninitialized_clients[id] then - uninitialized_clients[id].stop(true) + if type(id) == 'table' then + if id.stop then + id.stop(force) + end + else + --- @cast id -vim.lsp.Client + local client = all_clients[id] + if client then + client.stop(force) + end end end end @@ -772,6 +721,9 @@ end --- --- Only return clients supporting the given method --- @field method? string +--- +--- Also return uninitialized clients. +--- @field package _uninitialized? boolean --- Get active clients. --- @@ -784,15 +736,16 @@ function lsp.get_clients(filter) local clients = {} --- @type vim.lsp.Client[] - local t = filter.bufnr and (all_buffer_active_clients[resolve_bufnr(filter.bufnr)] or {}) - or active_clients - for client_id in pairs(t) do - local client = active_clients[client_id] + local bufnr = filter.bufnr and resolve_bufnr(filter.bufnr) + + for _, client in pairs(all_clients) do if client and (filter.id == nil or client.id == filter.id) + and (filter.bufnr == nil or client.attached_buffers[bufnr]) and (filter.name == nil or client.name == filter.name) and (filter.method == nil or client.supports_method(filter.method, { bufnr = filter.bufnr })) + and (filter._uninitialized or client.initialized) then clients[#clients + 1] = client end @@ -810,15 +763,9 @@ end api.nvim_create_autocmd('VimLeavePre', { desc = 'vim.lsp: exit handler', callback = function() + local active_clients = lsp.get_clients() log.info('exit_handler', active_clients) - for _, client in pairs(uninitialized_clients) do - client.stop(true) - end - -- TODO handle v:dying differently? - if tbl_isempty(active_clients) then - return - end - for _, client in pairs(active_clients) do + for _, client in pairs(all_clients) do client.stop() end @@ -827,7 +774,7 @@ api.nvim_create_autocmd('VimLeavePre', { local send_kill = false for client_id, client in pairs(active_clients) do - local timeout = if_nil(client.flags.exit_timeout, false) + local timeout = client.flags.exit_timeout if timeout then send_kill = true timeouts[client_id] = timeout @@ -910,7 +857,7 @@ function lsp.buf_request(bufnr, method, params, handler) local function _cancel_all_requests() for client_id, request_id in pairs(client_request_ids) do - local client = active_clients[client_id] + local client = all_clients[client_id] client.cancel_request(request_id) end end @@ -1106,7 +1053,7 @@ end ---@return boolean stopped true if client is stopped, false otherwise. function lsp.client_is_stopped(client_id) assert(client_id, 'missing client_id param') - return active_clients[client_id] == nil and not uninitialized_clients[client_id] + return not all_clients[client_id] end --- Gets a map of client_id:client pairs for the given buffer, where each value @@ -1172,7 +1119,11 @@ function lsp.for_each_buffer_client(bufnr, fn) 'lsp.get_clients({ bufnr = bufnr }) with regular loop', '0.12' ) - return for_each_buffer_client(bufnr, fn) + bufnr = resolve_bufnr(bufnr) + + for _, client in pairs(lsp.get_clients({ bufnr = bufnr })) do + fn(client, client.id, bufnr) + end end --- Function to manage overriding defaults for LSP handlers. diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index b06fab7319..303fc55982 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -185,6 +185,10 @@ local validate = vim.validate --- @field root_dir string --- --- @field attached_buffers table<integer,true> +--- +--- Buffers that should be attached to upon initialize() +--- @field package _buffers_to_attach table<integer,true> +--- --- @field private _log_prefix string --- --- Track this so that we can escalate automatically if we've already tried a @@ -225,7 +229,7 @@ local validate = vim.validate --- If {status} is `true`, the function returns {request_id} as the second --- result. You can use this with `client.cancel_request(request_id)` to cancel --- the request. ---- @field request fun(method: string, params: table?, handler: lsp.Handler?, bufnr: integer): boolean, integer? +--- @field request fun(method: string, params: table?, handler: lsp.Handler?, bufnr: integer?): boolean, integer? --- --- Sends a request to the server and synchronously waits for the response. --- This is a wrapper around {client.request} @@ -608,8 +612,16 @@ function Client:initialize() self:_notify(ms.workspace_didChangeConfiguration, { settings = self.settings }) end + -- If server is being restarted, make sure to re-attach to any previously attached buffers. + -- Save which buffers before on_init in case new buffers are attached. + local reattach_bufs = vim.deepcopy(self.attached_buffers) + self:_run_callbacks(self._on_init_cbs, lsp.client_errors.ON_INIT_CALLBACK_ERROR, self, result) + for buf in pairs(reattach_bufs) do + self:_on_attach(buf) + end + log.info( self._log_prefix, 'server_capabilities', @@ -647,10 +659,10 @@ end --- checks for capabilities and handler availability. --- --- @param method string LSP method name. ---- @param params table|nil LSP request params. ---- @param handler lsp.Handler|nil Response |lsp-handler| for this method. ---- @param bufnr integer Buffer handle (0 for current). ---- @return boolean status, integer|nil request_id {status} is a bool indicating +--- @param params? table LSP request params. +--- @param handler? lsp.Handler Response |lsp-handler| for this method. +--- @param bufnr? integer Buffer handle (0 for current). +--- @return boolean status, integer? request_id {status} is a bool indicating --- whether the request was successful. If it is `false`, then it will --- always be `false` (the client has shutdown). If it was --- successful, then it will return {request_id} as the @@ -761,7 +773,7 @@ function Client:_request_sync(method, params, timeout_ms, bufnr) return request_result end ---- @private +--- @package --- Sends a notification to an LSP server. --- --- @param method string LSP method name. diff --git a/runtime/syntax/java.vim b/runtime/syntax/java.vim index c059de603c..1f0c158031 100644 --- a/runtime/syntax/java.vim +++ b/runtime/syntax/java.vim @@ -2,7 +2,7 @@ " Language: Java " Maintainer: Claudio Fleiner <claudio@fleiner.com> " URL: https://github.com/fleiner/vim/blob/master/runtime/syntax/java.vim -" Last Change: 2024 Mar 06 +" Last Change: 2024 Mar 25 " Please check :help java.vim for comments on some of the options available. @@ -91,7 +91,7 @@ if exists("java_highlight_all") || exists("java_highlight_java") || exists("ja " keywords can be pre-sorted and appended without disturbing " the current keyword placement. The below _match_es follow suit. - syn keyword javaR_JavaLang ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException ClassCastException IllegalArgumentException IllegalMonitorStateException IllegalThreadStateException IndexOutOfBoundsException NegativeArraySizeException NullPointerException NumberFormatException RuntimeException SecurityException StringIndexOutOfBoundsException IllegalStateException UnsupportedOperationException EnumConstantNotPresentException TypeNotPresentException IllegalCallerException LayerInstantiationException + syn keyword javaR_JavaLang ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException ClassCastException IllegalArgumentException IllegalMonitorStateException IllegalThreadStateException IndexOutOfBoundsException NegativeArraySizeException NullPointerException NumberFormatException RuntimeException SecurityException StringIndexOutOfBoundsException IllegalStateException UnsupportedOperationException EnumConstantNotPresentException TypeNotPresentException IllegalCallerException LayerInstantiationException WrongThreadException MatchException syn cluster javaTop add=javaR_JavaLang syn cluster javaClasses add=javaR_JavaLang hi def link javaR_JavaLang javaR_Java @@ -111,6 +111,8 @@ if exists("java_highlight_all") || exists("java_highlight_java") || exists("ja syn match javaC_JavaLang "\%(\<Enum\.\)\@<=\<EnumDesc\>" syn keyword javaC_JavaLang Boolean Character Class ClassLoader Compiler Double Float Integer Long Math Number Object Process Runtime SecurityManager String StringBuffer Thread ThreadGroup Byte Short Void InheritableThreadLocal Package RuntimePermission ThreadLocal StrictMath StackTraceElement Enum ProcessBuilder StringBuilder ClassValue Module ModuleLayer StackWalker Record syn match javaC_JavaLang "\<System\>" " See javaDebug. + " As of Java 21, java.lang.Compiler is no more (deprecated in Java 9). + syn keyword javaLangDeprecated Compiler syn cluster javaTop add=javaC_JavaLang syn cluster javaClasses add=javaC_JavaLang hi def link javaC_JavaLang javaC_Java @@ -191,13 +193,20 @@ if exists("java_comment_strings") syn cluster javaCommentSpecial2 add=javaComment2String,javaCommentCharacter,javaNumber,javaStrTempl endif -syn region javaComment start="/\*" end="\*/" contains=@javaCommentSpecial,javaTodo,@Spell +syn region javaComment matchgroup=javaCommentStart start="/\*" end="\*/" contains=@javaCommentSpecial,javaTodo,javaCommentError,javaSpaceError,@Spell syn match javaCommentStar contained "^\s*\*[^/]"me=e-1 syn match javaCommentStar contained "^\s*\*$" -syn match javaLineComment "//.*" contains=@javaCommentSpecial2,javaTodo,@Spell +syn match javaLineComment "//.*" contains=@javaCommentSpecial2,javaTodo,javaCommentMarkupTag,javaSpaceError,@Spell +syn match javaCommentMarkupTag contained "@\%(end\|highlight\|link\|replace\|start\)\>" nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite +syn match javaCommentMarkupTagAttr contained "\<region\>" nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite +syn region javaCommentMarkupTagAttr contained transparent matchgroup=htmlArg start=/\<\%(re\%(gex\|gion\|placement\)\|substring\|t\%(arget\|ype\)\)\%(\s*=\)\@=/ matchgroup=htmlString end=/\%(=\s*\)\@<=\%("[^"]\+"\|'[^']\+'\|\%([.-]\|\k\)\+\)/ nextgroup=javaCommentMarkupTagAttr,javaSpaceError skipwhite oneline +hi def link javaCommentMarkupTagAttr htmlArg hi def link javaCommentString javaString hi def link javaComment2String javaString hi def link javaCommentCharacter javaCharacter +syn match javaCommentError contained "/\*"me=e-1 display +hi def link javaCommentError javaError +hi def link javaCommentStart javaComment syn cluster javaTop add=javaComment,javaLineComment @@ -211,15 +220,20 @@ if !exists("java_ignore_javadoc") && main_syntax != 'jsp' " here. syntax spell default - syn region javaDocComment start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaTodo,@Spell - syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*" matchgroup=javaCommentTitle keepend end="\.$" end="\.[ \t\r<&]"me=e-1 end="[^{]@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@javaHtml,javaCommentStar,javaTodo,@Spell,javaDocTags,javaDocSeeTag - - syn region javaDocTags contained start="{@\(code\|link\|linkplain\|inherit[Dd]oc\|doc[rR]oot\|value\)" end="}" - syn match javaDocTags contained "@\(param\|exception\|throws\|since\)\s\+\S\+" contains=javaDocParam - syn match javaDocParam contained "\s\S\+" - syn match javaDocTags contained "@\(version\|author\|return\|deprecated\|serial\|serialField\|serialData\)\>" - syn region javaDocSeeTag contained matchgroup=javaDocTags start="@see\s\+" matchgroup=NONE end="\_."re=e-1 contains=javaDocSeeTagParam - syn match javaDocSeeTagParam contained @"\_[^"]\+"\|<a\s\+\_.\{-}</a>\|\(\k\|\.\)*\(#\k\+\((\_[^)]\+)\)\=\)\=@ extend + syn region javaDocComment start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag,javaTodo,javaCommentError,javaSpaceError,@Spell + syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*" matchgroup=javaCommentTitle end="\.$" end="\.[ \t\r]\@=" end="\%(^\s*\**\s*\)\@<=@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag + syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*\s*\r\=\n\=\s*\**\s*\%({@return\>\)\@=" matchgroup=javaCommentTitle end="}\%(\s*\.*\)*" contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag + syn region javaDocTags contained start="{@\%(li\%(teral\|nk\%(plain\)\=\)\|inherit[Dd]oc\|doc[rR]oot\|value\)\>" end="}" + syn match javaDocTags contained "@\%(param\|exception\|throws\|since\)\s\+\S\+" contains=javaDocParam + syn match javaDocParam contained "\s\S\+" + syn match javaDocTags contained "@\%(version\|author\|return\|deprecated\|serial\%(Field\|Data\)\=\)\>" + syn region javaDocSeeTag contained matchgroup=javaDocTags start="@see\s\+" matchgroup=NONE end="\_."re=e-1 contains=javaDocSeeTagParam + syn match javaDocSeeTagParam contained @"\_[^"]\+"\|<a\s\+\_.\{-}</a>\|\%(\k\|\.\)*\%(#\k\+\%((\_[^)]*)\)\=\)\=@ contains=@javaHtml extend + syn region javaCodeSkipBlock contained transparent start="{\%(@code\>\)\@!" end="}" contains=javaCodeSkipBlock,javaDocCodeTag + syn region javaDocCodeTag contained start="{@code\>" end="}" contains=javaDocCodeTag,javaCodeSkipBlock + syn region javaDocSnippetTagAttr contained transparent matchgroup=htmlArg start=/\<\%(class\|file\|id\|lang\|region\)\%(\s*=\)\@=/ matchgroup=htmlString end=/:$/ end=/\%(=\s*\)\@<=\%("[^"]\+"\|'[^']\+'\|\%([.\\/-]\|\k\)\+\)/ nextgroup=javaDocSnippetTagAttr skipwhite skipnl + syn region javaSnippetSkipBlock contained transparent start="{\%(@snippet\>\)\@!" end="}" contains=javaSnippetSkipBlock,javaDocSnippetTag,javaCommentMarkupTag + syn region javaDocSnippetTag contained start="{@snippet\>" end="}" contains=javaDocSnippetTag,javaSnippetSkipBlock,javaDocSnippetTagAttr,javaCommentMarkupTag syntax case match endif @@ -359,6 +373,13 @@ endif if !exists("java_minlines") let java_minlines = 10 endif + +" Note that variations of a /*/ balanced comment, e.g., /*/*/, /*//*/, +" /* /*/, /* /*/, etc., may have their rightmost /*/ part accepted +" as a comment start by ':syntax sync ccomment'; consider alternatives +" to make synchronisation start further towards file's beginning by +" bumping up g:java_minlines or issuing ':syntax sync fromstart' or +" preferring &foldmethod set to 'syntax'. exec "syn sync ccomment javaComment minlines=" . java_minlines " The default highlighting. @@ -404,6 +425,8 @@ hi def link javaAnnotation PreProc hi def link javaCommentTitle SpecialComment hi def link javaDocTags Special +hi def link javaDocCodeTag Special +hi def link javaDocSnippetTag Special hi def link javaDocParam Function hi def link javaDocSeeTagParam Function hi def link javaCommentStar javaComment @@ -413,6 +436,8 @@ hi def link javaExternal Include hi def link htmlComment Special hi def link htmlCommentPart Special +hi def link htmlArg Type +hi def link htmlString String hi def link javaSpaceError Error if s:isModuleInfoDeclarationCurrentBuffer() |