diff options
Diffstat (limited to 'runtime')
39 files changed, 526 insertions, 157 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 413802eea1..3a579ab194 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -352,10 +352,14 @@ BufWritePost After writing the whole buffer to a file *ChanInfo* ChanInfo State of channel changed, for instance the client of a RPC channel described itself. + This is triggered even when inside an + autocommand defined without |autocmd-nested|. Sets these |v:event| keys: info as from |nvim_get_chan_info()| *ChanOpen* ChanOpen Just after a channel was opened. + This is triggered even when inside an + autocommand defined without |autocmd-nested|. Sets these |v:event| keys: info as from |nvim_get_chan_info()| *CmdUndefined* @@ -364,6 +368,8 @@ CmdUndefined When a user command is used but it isn't when it's used. The pattern is matched against the command name. Both <amatch> and <afile> expand to the command name. + This is triggered even when inside an + autocommand defined without |autocmd-nested|. NOTE: Autocompletion won't work until the command is defined. An alternative is to always define the user command and have it @@ -689,6 +695,8 @@ FuncUndefined When a user function is used but it isn't when it's used. The pattern is matched against the function name. Both <amatch> and <afile> are set to the name of the function. + This is triggered even when inside an + autocommand defined without |autocmd-nested|. NOTE: When writing Vim scripts a better alternative is to use an autoloaded function. See |autoload-functions|. @@ -910,7 +918,10 @@ ShellCmdPost After executing a shell command with |:!cmd|, *Signal* Signal After Nvim receives a signal. The pattern is matched against the signal name. Only - "SIGUSR1" and "SIGWINCH" are supported. Example: > + "SIGUSR1" and "SIGWINCH" are supported. + This is triggered even when inside an + autocommand defined without |autocmd-nested|. + Example: >vim autocmd Signal SIGUSR1 call some#func() < *ShellFilterPost* ShellFilterPost After executing a shell command with @@ -1004,22 +1015,40 @@ TermClose When a |terminal| job ends. status *TermRequest* TermRequest When a |:terminal| child process emits an OSC, - DCS or APC sequence. Sets |v:termrequest|. The - |event-data| is the request string. + DCS, or APC sequence. Sets |v:termrequest|. The + |event-data| is a table with the following + fields: + + - sequence: the received sequence + - cursor: (1,0)-indexed, buffer-relative + position of the cursor when the sequence was + received + + This is triggered even when inside an + autocommand defined without |autocmd-nested|. + *TermResponse* TermResponse When Nvim receives an OSC or DCS response from the host terminal. Sets |v:termresponse|. The - |event-data| is the response string. May be - triggered during another event (file I/O, - a shell command, or anything else that takes - time). Example: >lua + |event-data| is a table with the following fields: + + - sequence: the received sequence + + This is triggered even when inside an + autocommand defined without |autocmd-nested|. + + May be triggered during another event (file + I/O, a shell command, or anything else that + takes time). + + Example: >lua -- Query the terminal palette for the RGB value of color 1 -- (red) using OSC 4 vim.api.nvim_create_autocmd('TermResponse', { once = true, callback = function(args) - local resp = args.data + local resp = args.data.sequence local r, g, b = resp:match("\027%]4;1;rgb:(%w+)/(%w+)/(%w+)") end, }) @@ -1391,8 +1420,8 @@ vimrc file again). *FileExplorer* There is one group that is recognized by Vim: FileExplorer. If this group exists Vim assumes that editing a directory is possible and will trigger a -plugin that lists the files in that directory. This is used by the |netrw| -plugin. This allows you to do: > +plugin that lists the files in that directory. This is used by directory +browser plugins. This allows you to do: > browse edit ============================================================================== @@ -1666,7 +1695,7 @@ and "++ff=" argument that are effective. These should be used for the command that reads/writes the file. The |v:cmdbang| variable is one when "!" was used, zero otherwise. -See the $VIMRUNTIME/plugin/netrwPlugin.vim for examples. +See the $VIMRUNTIME/pack/dist/opt/netrw/plugin/netrwPlugin.vim for examples. ============================================================================== 11. Disabling autocommands *autocmd-disable* diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 3fc17af185..45a95e439a 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -83,6 +83,10 @@ CTRL-Q Same as CTRL-V. But with some terminals it is used for CTRL-SHIFT-V *c_CTRL-SHIFT-V* *c_CTRL-SHIFT-Q* CTRL-SHIFT-Q Works just like CTRL-V, but do not try to include the CTRL modifier into the key. + Note: When CTRL-SHIFT-V is intercepted by your system (e.g., + to paste text) you can often use CTRL-SHIFT-Q instead. + However, in some terminals (e.g. GNOME Terminal), CTRL-SHIFT-Q + quits the terminal without confirmation. *c_<Left>* *c_Left* <Left> cursor left. See 'wildmenu' for behavior during wildmenu diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt index d3170f114f..8d60d2c868 100644 --- a/runtime/doc/develop.txt +++ b/runtime/doc/develop.txt @@ -376,10 +376,10 @@ Where possible, these patterns apply to _both_ Lua and the API: - See |vim.lsp.inlay_hint.enable()| and |vim.lsp.inlay_hint.is_enabled()| for a reference implementation of these "best practices". - NOTE: open questions: https://github.com/neovim/neovim/issues/28603 -- Transformation functions should also have a filter functionality when - appropriate. That is, when the function returns a nil value it "filters" its - input, otherwise the transformed value is used. - - Example: |vim.diagnostic.config.format()| +- Transformation functions should also have "filter" functionality (when + appropriate): when the function returns a nil value it excludes (filters + out) its input, else the transformed value is used. + - Example: See the format() field of |vim.diagnostic.Opts.Float|. API DESIGN GUIDELINES *dev-api* diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 4224709a39..c275bf863d 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1496,9 +1496,8 @@ Or, when starting gvim from a shell: > Note that if a FileChangedShell autocommand is defined you will not get a warning message or prompt. The autocommand is expected to handle this. -There is no warning for a directory (e.g., with |netrw-browse|). But you do -get warned if you started editing a new file and it was created as a directory -later. +There is no warning for a directory. But you do get warned if you started +editing a new file and it was created as a directory later. When Vim notices the timestamp of a file has changed, and the file is being edited in a buffer but has not changed, Vim checks if the contents of the file diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt index 914dc64c0a..991b3d02c8 100644 --- a/runtime/doc/help.txt +++ b/runtime/doc/help.txt @@ -180,11 +180,11 @@ Standard plugins ~ *standard-plugin-list* |pi_gzip.txt| Reading and writing compressed files |pi_msgpack.txt| msgpack utilities -|pi_netrw.txt| Reading and writing files over a network |pi_paren.txt| Highlight matching parens |pi_spec.txt| Filetype plugin to work with rpm spec files |pi_tar.txt| Tar file explorer |pi_zip.txt| Zip archive explorer +|netrw| Reading and writing files over a network Local additions ~ *local-additions* diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index 0256707420..b814b3be78 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -786,8 +786,7 @@ tag char note action in Normal mode ~ |gu| gu{motion} 2 make Nmove text lowercase |gv| gv reselect the previous Visual area |gw| gw{motion} 2 format Nmove text and keep cursor -|netrw-gx| gx execute application for file name under the - cursor (only with |netrw| plugin) +|gx| gx execute application for filepath at cursor |g@| g@{motion} call 'operatorfunc' |g~| g~{motion} 2 swap case for Nmove text |g<Down>| g<Down> 1 same as "gj" diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 06f1a4e73d..b77339a325 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -212,6 +212,10 @@ CTRL-Q Same as CTRL-V. CTRL-SHIFT-V *i_CTRL-SHIFT-V* *i_CTRL-SHIFT-Q* CTRL-SHIFT-Q Works just like CTRL-V, but do not try to include the CTRL modifier into the key. + Note: When CTRL-SHIFT-V is intercepted by your system (e.g., + to paste text) you can often use CTRL-SHIFT-Q instead. + However, in some terminals (e.g. GNOME Terminal), CTRL-SHIFT-Q + quits the terminal without confirmation. CTRL-X Enter CTRL-X mode. This is a sub-mode where commands can be given to complete words or scroll the window. See @@ -639,8 +643,8 @@ Also see the 'infercase' option if you want to adjust the case of the match. When inserting a selected candidate word from the |popup-menu|, the part of the candidate word that does not match the query is highlighted using -|hl-ComplMatchIns|. If fuzzy is enabled in 'completopt', highlighting will not -be applied. +|hl-ComplMatchIns|. If fuzzy is enabled in 'completeopt', highlighting will +not be applied. *complete_CTRL-E* When completion is active you can use CTRL-E to stop it and go back to the diff --git a/runtime/doc/lua-bit.txt b/runtime/doc/lua-bit.txt index 4c47010113..dde235d141 100644 --- a/runtime/doc/lua-bit.txt +++ b/runtime/doc/lua-bit.txt @@ -86,19 +86,17 @@ Bit operations y = bit.tobit(x) *bit.tobit()* Normalizes a number to the numeric range for bit operations and returns it. This function is usually not needed since all bit operations already - normalize all of their input arguments. Check the |luabit-semantics| for - details. + normalize all of their input arguments. See |lua-bit-semantics|. Example: >lua - print(0xffffffff) --> 4294967295 (*) + print(0xffffffff) --> 4294967295 (see Note) print(bit.tobit(0xffffffff)) --> -1 printx(bit.tobit(0xffffffff)) --> 0xffffffff print(bit.tobit(0xffffffff + 1)) --> 0 print(bit.tobit(2^40 + 1234)) --> 1234 < - (*) See the treatment of |lua-bit-hex-literals| for an explanation why the - printed numbers in the first two lines differ (if your Lua installation - uses a double number type). + Note: |lua-bit-hex-literals| explains why the numbers printed in the first + two lines differ (if your Lua installation uses a double number type). y = bit.tohex(x [,n]) *bit.tohex()* Converts its first argument to a hex string. The number of hex digits is @@ -369,7 +367,7 @@ strongly advised not to rely on undefined or implementation-defined behavior. - Non-integral numbers may be rounded or truncated in an implementation-defined way. This means the result could differ between different BitOp versions, different Lua VMs, on different platforms or - even between interpreted vs. compiled code (as in |LuaJIT|). Avoid + even between interpreted vs. compiled code (as in LuaJIT). Avoid passing fractional numbers to bitwise functions. Use `math.floor()` or `math.ceil()` to get defined behavior. - Lua provides auto-coercion of string arguments to numbers by default. This diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index c184e4792d..fa3367602d 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -289,7 +289,7 @@ arguments separated by " " (space) instead of "\t" (tab). :lua {chunk} Executes Lua chunk {chunk}. If {chunk} starts with "=" the rest of the chunk is evaluated as an expression and printed. `:lua =expr` and `:=expr` - are equivalent to `:lua vim.print(expr)`. + are equivalent to `:lua print(vim.inspect(expr))`. Examples: >vim :lua vim.api.nvim_command('echo "Hello, Nvim!"') diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt index 284be09121..48fa723800 100644 --- a/runtime/doc/motion.txt +++ b/runtime/doc/motion.txt @@ -455,6 +455,8 @@ between Vi and Vim. first column. When used after an operator, then also stops below a "}" in the first column. |exclusive| Note that |exclusive-linewise| often applies. + In a :terminal buffer each shell prompt is treated as + a section. |terminal_]]| *][* ][ [count] |section|s forward or to the next '}' in the @@ -465,6 +467,8 @@ between Vi and Vim. [[ [count] |section|s backward or to the previous "{" in the first column. |exclusive| Note that |exclusive-linewise| often applies. + In a :terminal buffer each shell prompt is treated as + a section. |terminal_]]| *[]* [] [count] |section|s backward or to the previous "}" in @@ -498,6 +502,7 @@ A section begins after a form-feed (<C-L>) in the first column and at each of a set of section macros, specified by the pairs of characters in the 'sections' option. The default is "SHNHH HUnhsh", which defines a section to start at the nroff macros ".SH", ".NH", ".H", ".HU", ".nh" and ".sh". +In a :terminal buffer each shell prompt is treated as a section. |terminal_]]| The "]]" and "[[" commands stop at the '{' in the first column. This is useful to find the start of a function in a C program. To search for a '}' in diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index a131934a8e..5a3e35a3dd 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -111,6 +111,9 @@ EVENTS • `history` argument indicating if the message was added to the history. • new message kinds: "bufwrite", "completion", "list_cmd", "lua_print", "search_cmd", "shell_out/err/ret", "undo", "verbose", wildlist". +• |TermRequest| and |TermResponse| |event-data| is now a table. The "sequence" + field contains the received sequence. |TermRequest| also contains a "cursor" + field indicating the cursor's position when the sequence was received. HIGHLIGHTS @@ -241,6 +244,8 @@ DEFAULTS • |[a|, |]a|, |[A|, |]A| navigate through the |argument-list| • |[b|, |]b|, |[B|, |]B| navigate through the |buffer-list| • |[<Space>|, |]<Space>| add an empty line above and below the cursor + • |[[| and |]]| in Normal mode jump between shell prompts for shells which emit + OSC 133 sequences ("shell integration" or "semantic prompts"). • Snippet: • `<Tab>` in Insert and Select mode maps to `vim.snippet.jump({ direction = 1 })` @@ -306,6 +311,8 @@ LSP • |vim.lsp.config()| has been added to define default configurations for servers. In addition, configurations can be specified in `lsp/<name>.lua`. • |vim.lsp.enable()| has been added to enable servers. +• |vim.lsp.buf.code_action()| resolves the `command` property during the + `codeAction/resolve` request. LUA @@ -329,6 +336,7 @@ OPTIONS • 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|. • 'completeopt' flag "preinsert" highlights text to be inserted. +• 'wildmode' flag "noselect" shows 'wildmenu' without selecting an entry. • 'messagesopt' configures |:messages| and |hit-enter| prompt. • 'tabclose' controls which tab page to focus when closing a tab page. • 'eventignorewin' to persistently ignore events in a window. @@ -395,6 +403,8 @@ TERMINAL codes" mode is currently supported. • The |terminal| emits a |TermRequest| autocommand event when the child process emits an APC control sequence. +• |TermRequest| has a "cursor" field in its |event-data| indicating the + cursor position when the sequence was received. TREESITTER diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index a6f5f85d37..e42fb4f9e4 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1556,15 +1556,15 @@ A jump table for the options with a short description can be found at |Q_op|. match, e.g., what file it comes from. noinsert Do not insert any text for a match until the user selects - a match from the menu. Only works in combination with + a match from the menu. Only works in combination with "menu" or "menuone". No effect if "longest" is present. noselect Same as "noinsert", except that no menu item is - pre-selected. If both "noinsert" and "noselect" are + pre-selected. If both "noinsert" and "noselect" are present, "noselect" has precedence. nosort Disable sorting of completion candidates based on fuzzy - scores when "fuzzy" is enabled. Candidates will appear + scores when "fuzzy" is enabled. Candidates will appear in their original order. popup Show extra information about the currently selected @@ -1575,7 +1575,7 @@ A jump table for the options with a short description can be found at |Q_op|. Preinsert the portion of the first candidate word that is not part of the current completion leader and using the |hl-ComplMatchIns| highlight group. In order for it to - work, "fuzzy" must not bet set and "menuone" must be set. + work, "fuzzy" must not be set and "menuone" must be set. preview Show extra information about the currently selected completion in the preview window. Only works in @@ -4505,7 +4505,7 @@ A jump table for the options with a short description can be found at |Q_op|. set path=,, < - A directory name may end in a ':' or '/'. - Environment variables are expanded |:set_env|. - - When using |netrw.vim| URLs can be used. For example, adding + - When using |netrw| URLs can be used. For example, adding "https://www.vim.org" will make ":find index.html" work. - Search upwards and downwards in a directory tree using "*", "**" and ";". See |file-searching| for info and syntax. @@ -7050,7 +7050,10 @@ A jump table for the options with a short description can be found at |Q_op|. "lastused" When completing buffer names and more than one buffer matches, sort buffers by time last used (other than the current buffer). - When there is only a single match, it is fully completed in all cases. + "noselect" Do not pre-select first menu item and start 'wildmenu' + if it is enabled. + When there is only a single match, it is fully completed in all cases + except when "noselect" is present. Examples of useful colon-separated values: "longest:full" Like "longest", but also start 'wildmenu' if it is @@ -7073,7 +7076,11 @@ A jump table for the options with a short description can be found at |Q_op|. set wildmode=list,full < List all matches without completing, then each full match >vim set wildmode=longest,list -< Complete longest common string, then list alternatives. +< Complete longest common string, then list alternatives >vim + set wildmode=noselect:full +< Display 'wildmenu' without completing, then each full match >vim + set wildmode=noselect:lastused,full +< Same as above, but sort buffers by time last used. More info here: |cmdline-completion|. *'wildoptions'* *'wop'* diff --git a/runtime/doc/pi_gzip.txt b/runtime/doc/pi_gzip.txt index e8a1de9cef..65e7942562 100644 --- a/runtime/doc/pi_gzip.txt +++ b/runtime/doc/pi_gzip.txt @@ -29,6 +29,7 @@ with these extensions: extension compression > *.bz2 bzip2 + *.bz3 bzip3 *.gz gzip *.lz lzip *.lz4 lz4 diff --git a/runtime/doc/provider.txt b/runtime/doc/provider.txt index 69ae0f20d1..24ec170319 100644 --- a/runtime/doc/provider.txt +++ b/runtime/doc/provider.txt @@ -264,7 +264,8 @@ causes the terminal emulator to write to or read from the system clipboard. When Nvim is running in the |TUI|, it will automatically attempt to determine if the host terminal emulator supports OSC 52. If it does, then Nvim will use OSC 52 for copying and pasting if no other |clipboard-tool| is found and when -'clipboard' is unset. +'clipboard' is unset. NOTE: Using a terminal multiplexer (e.g. tmux) may +inhibit automatic OSC 52 support detection. *g:termfeatures* To disable the automatic detection, set the "osc52" key of |g:termfeatures| to diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 3a19ee55c3..00486a49db 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -246,12 +246,6 @@ Added added line in a diff Changed changed line in a diff Removed removed line in a diff -The names marked with * are the preferred groups; the others are minor groups. -For the preferred groups, the "syntax.vim" file contains default highlighting. -The minor groups are linked to the preferred groups, so they get the same -highlighting. You can override these defaults by using ":highlight" commands -after sourcing the "syntax.vim" file. - Note that highlight group names are not case sensitive. "String" and "string" can be used for the same group. @@ -4816,16 +4810,20 @@ is mostly used, because it looks better. ============================================================================== 13. Highlight command *:highlight* *:hi* *E28* *E411* *E415* -There are two types of highlight groups: -- The built-in |highlight-groups|. -- The ones used for specific languages. For these the name starts with the - name of the language. Many of these don't have any attributes, but are - linked to a group of the second type. - *hitest.vim* -You can see all the groups currently active with this command: > - :so $VIMRUNTIME/syntax/hitest.vim -This will open a new window containing all highlight group names, displayed -in their own color. +Nvim uses a range of highlight groups which fall into two categories: Editor +interface and syntax highlighting. In rough order of importance, these are +- basic editor |highlight-groups| +- standard syntax |group-name|s (in addition, syntax files can define + language-specific groups, which are prefixed with the language name) +- |diagnostic-highlights| +- |treesitter-highlight-groups| +- |lsp-semantic-highlight| groups +- |lsp-highlight| of symbols and references + +Where appropriate, highlight groups are linked by default to one of the more basic +groups, but colorschemes are expected to cover all of them. Under each tag, +the corresponding highlight groups are highlighted using the current +colorscheme. *:colo* *:colorscheme* *E185* :colo[rscheme] Output the name of the currently active color scheme. diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt index 0ab7151728..ea8a1c2565 100644 --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -144,8 +144,8 @@ directory indicated in the request. >lua vim.api.nvim_create_autocmd({ 'TermRequest' }, { desc = 'Handles OSC 7 dir change requests', callback = function(ev) - if string.sub(vim.v.termrequest, 1, 4) == '\x1b]7;' then - local dir = string.gsub(vim.v.termrequest, '\x1b]7;file://[^/]*', '') + if string.sub(ev.data.sequence, 1, 4) == '\x1b]7;' then + local dir = string.gsub(ev.data.sequence, '\x1b]7;file://[^/]*', '') if vim.fn.isdirectory(dir) == 0 then vim.notify('invalid dir: '..dir) return @@ -185,6 +185,54 @@ clipboard. OSC 52 sequences sent from the :terminal buffer do not emit a |TermRequest| event. The event is handled directly by Nvim and is not forwarded to plugins. +OSC 133: shell integration *terminal-osc133* + +Shells can emit semantic escape sequences (OSC 133) to mark where each prompt +starts and ends. The start of a prompt is marked by sequence `OSC 133 ; A ST`, +and the end by `OSC 133 ; B ST`. + + *shell-prompt-config* +You can configure your shell "rc" (e.g. ~/.bashrc) to emit OSC 133 sequences, +or your terminal may attempt to do it for you (assuming your shell config +doesn't interfere). + +- fish: https://fishshell.com/docs/current/relnotes.html#improved-terminal-support +- kitty: https://sw.kovidgoyal.net/kitty/shell-integration/ +- vscode: https://code.visualstudio.com/docs/terminal/shell-integration + +To configure bash to mark the start/end of each prompt, set $PROMPT_COMMAND +and $PS1 as follows: >bash + + # Prompt start: + PROMPT_COMMAND='printf "\033]133;A\007"' + # Prompt end: + PS1="$PS1"'\033]133;B\007' +< + *terminal_]]* *terminal_[[* +The |]]| and |[[| motions jump to the next/previous prompts, if your shell +emits OSC 133 as described above. + + *terminal-shell-prompt-signs* +To annotate each terminal prompt with a sign, call |nvim_buf_set_extmark()| +from a |TermRequest| handler: >lua + + local ns = vim.api.nvim_create_namespace('my.terminal.prompt') + vim.api.nvim_create_autocmd('TermRequest', { + callback = function(args) + if string.match(args.data.sequence, '^\027]133;A') then + local lnum = args.data.cursor[1] + vim.api.nvim_buf_set_extmark(args.buf, ns, lnum - 1, 0, { + sign_text = '▶', + sign_hl_group = 'SpecialChar', + }) + end + end, + }) + -- Enable signcolumn in terminal buffers. + vim.api.nvim_create_autocmd('TermOpen', { + command = 'setlocal signcolumn=auto', + }) +< ============================================================================== Status Variables *terminal-status* diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index f0172c36e5..31335b4fbb 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -789,7 +789,7 @@ must handle. "" (empty) Unknown (consider a |feature-request|) "bufwrite" |:write| message "confirm" Message preceding a prompt (|:confirm|, - |confirm()|, |inputlist()|, |z=,|, …) + |confirm()|, |inputlist()|, |z=|, …) "emsg" Error (|errors|, internal error, |:throw|, …) "echo" |:echo| message "echomsg" |:echomsg| message diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 1e1f6c4db7..8d8b97fe31 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -34,7 +34,8 @@ Defaults *defaults* *nvim-defaults* looking differently due to them relying on how highlight groups are defined by default. Add ":colorscheme vim" to |init.vim| or ":source $VIMRUNTIME/colors/vim.lua" to your color scheme file to restore - the old default links and colors. + the old default links and colors. See |:highlight| for a list of highlight + groups colorschemes should set. - 'autoindent' is enabled - 'autoread' is enabled (works in all UIs, including terminal) @@ -181,7 +182,10 @@ nvim.terminal: when 'background' is "light". While this may not reflect the actual foreground/background color, it permits 'background' to be retained for a nested Nvim instance running in the terminal emulator. -- TermOpen: Sets default options for |terminal| buffers: +- TermRequest: Nvim will create extmarks for shells which + annotate their prompts with OSC 133 escape sequences, enabling users to + quickly navigate between prompts using |[[| and |]]|. +- TermOpen: Sets default options and mappings for |terminal| buffers: - 'nomodifiable' - 'undolevels' set to -1 - 'textwidth' set to 0 @@ -193,6 +197,7 @@ nvim.terminal: - 'foldcolumn' set to "0" - 'winhighlight' uses |hl-StatusLineTerm| and |hl-StatusLineTermNC| in place of |hl-StatusLine| and |hl-StatusLineNC| + - |[[| and |]]| to navigate between shell prompts nvim.cmdwin: - CmdwinEnter: Limits syntax sync to maxlines=1 in the |cmdwin|. diff --git a/runtime/ftplugin/go.vim b/runtime/ftplugin/go.vim index 75f78cfa4b..b83db424bd 100644 --- a/runtime/ftplugin/go.vim +++ b/runtime/ftplugin/go.vim @@ -3,6 +3,7 @@ " Maintainer: David Barnett (https://github.com/google/vim-ft-go) " Last Change: 2014 Aug 16 " 2024 Jul 16 by Vim Project (add recommended indent style) +" 2025 Mar 07 by Vim Project (add formatprg and keywordprg option #16804) if exists('b:did_ftplugin') finish @@ -10,15 +11,39 @@ endif let b:did_ftplugin = 1 setlocal formatoptions-=t +setlocal formatprg=gofmt setlocal comments=s1:/*,mb:*,ex:*/,:// setlocal commentstring=//\ %s +setlocal keywordprg=:GoKeywordPrg -let b:undo_ftplugin = 'setl fo< com< cms<' +command! -buffer -nargs=* GoKeywordPrg call s:GoKeywordPrg() + +let b:undo_ftplugin = 'setl fo< com< cms< fp< kp<' + \ . '| delcommand -buffer GoKeywordPrg' if get(g:, 'go_recommended_style', 1) setlocal noexpandtab softtabstop=0 shiftwidth=0 let b:undo_ftplugin ..= ' | setl et< sts< sw<' endif +if !exists('*' .. expand('<SID>') .. 'GoKeywordPrg') + func! s:GoKeywordPrg() + let temp_isk = &l:iskeyword + setl iskeyword+=. + try + let cmd = 'go doc -C ' . shellescape(expand('%:h')) . ' ' . shellescape(expand('<cword>')) + if has('nvim') + exe "term" cmd + startinsert + tmap <buffer> <Esc> <Cmd>call jobstop(&channel) <Bar> bdelete<CR> + else + exe '!' . cmd + endif + finally + let &l:iskeyword = temp_isk + endtry + endfunc +endif + " vim: sw=2 sts=2 et diff --git a/runtime/ftplugin/tera.vim b/runtime/ftplugin/tera.vim new file mode 100644 index 0000000000..65bae70048 --- /dev/null +++ b/runtime/ftplugin/tera.vim @@ -0,0 +1,30 @@ +" Vim filetype plugin file +" Language: Tera +" Maintainer: Muntasir Mahmud <muntasir.joypurhat@gmail.com> +" Last Change: 2025 Mar 08 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +setlocal autoindent + +setlocal commentstring={#\ %s\ #} +setlocal comments=s:{#,e:#} + +if exists("loaded_matchit") + let b:match_ignorecase = 0 + let b:match_words = '{#:##\|#},{% *if:{% *else\>:{% *elif\>:{% *endif %},{% *for\>:{% *endfor %},{% *macro\>:{% *endmacro %},{% *block\>:{% *endblock %},{% *filter\>:{% *endfilter %},{% *set\>:{% *endset %},{% *raw\>:{% *endraw %},{% *with\>:{% *endwith %}' +endif + +setlocal includeexpr=substitute(v:fname,'\\([^.]*\\)$','\\1','g') +setlocal suffixesadd=.tera + +setlocal expandtab +setlocal shiftwidth=2 +setlocal softtabstop=2 + +let b:undo_ftplugin = "setlocal autoindent< commentstring< comments< " .. + \ "includeexpr< suffixesadd< expandtab< shiftwidth< softtabstop<" +let b:undo_ftplugin .= "|unlet! b:match_ignorecase b:match_words" diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim index 16730185c7..4772683ee8 100644 --- a/runtime/ftplugin/vim.vim +++ b/runtime/ftplugin/vim.vim @@ -1,7 +1,7 @@ " Vim filetype plugin " Language: Vim " Maintainer: Doug Kearns <dougkearns@gmail.com> -" Last Change: 2025 Feb 25 +" Last Change: 2025 Mar 05 " Former Maintainer: Bram Moolenaar <Bram@vim.org> " Contributors: Riley Bruins <ribru17@gmail.com> ('commentstring'), " @Konfekt @@ -85,6 +85,8 @@ if !exists("*" .. expand("<SID>") .. "Help") return ':'.topic elseif pre =~# '\<v:$' return 'v:'.topic + elseif pre =~# '<$' + return '<'.topic.'>' elseif pre =~# '\\$' return '/\'.topic elseif topic ==# 'v' && post =~# ':\w\+' diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index 4415a8cdca..6b8daab2c5 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -205,7 +205,9 @@ local function try_query_terminal_color(color) once = true, callback = function(args) hex = '#' - .. table.concat({ args.data:match('\027%]%d+;%d*;?rgb:(%w%w)%w%w/(%w%w)%w%w/(%w%w)%w%w') }) + .. table.concat({ + args.data.sequence:match('\027%]%d+;%d*;?rgb:(%w%w)%w%w/(%w%w)%w%w/(%w%w)%w%w'), + }) end, }) if type(color) == 'number' then diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua index c2e4e76dd6..c709f0a308 100644 --- a/runtime/lua/vim/_defaults.lua +++ b/runtime/lua/vim/_defaults.lua @@ -515,8 +515,8 @@ do if channel == 0 then return end - local fg_request = args.data == '\027]10;?' - local bg_request = args.data == '\027]11;?' + local fg_request = args.data.sequence == '\027]10;?' + local bg_request = args.data.sequence == '\027]11;?' if fg_request or bg_request then -- WARN: This does not return the actual foreground/background color, -- but rather returns: @@ -534,14 +534,59 @@ do end, }) + local nvim_terminal_prompt_ns = vim.api.nvim_create_namespace('nvim.terminal.prompt') + vim.api.nvim_create_autocmd('TermRequest', { + group = nvim_terminal_augroup, + desc = 'Mark shell prompts indicated by OSC 133 sequences for navigation', + callback = function(args) + if string.match(args.data.sequence, '^\027]133;A') then + local lnum = args.data.cursor[1] ---@type integer + vim.api.nvim_buf_set_extmark(args.buf, nvim_terminal_prompt_ns, lnum - 1, 0, {}) + end + end, + }) + + ---@param ns integer + ---@param buf integer + ---@param count integer + local function jump_to_prompt(ns, win, buf, count) + local row, col = unpack(vim.api.nvim_win_get_cursor(win)) + local start = -1 + local end_ ---@type 0|-1 + if count > 0 then + start = row + end_ = -1 + elseif count < 0 then + -- Subtract 2 because row is 1-based, but extmarks are 0-based + start = row - 2 + end_ = 0 + end + + if start < 0 then + return + end + + local extmarks = vim.api.nvim_buf_get_extmarks( + buf, + ns, + { start, col }, + end_, + { limit = math.abs(count) } + ) + if #extmarks > 0 then + local extmark = extmarks[math.min(#extmarks, math.abs(count))] + vim.api.nvim_win_set_cursor(win, { extmark[2] + 1, extmark[3] }) + end + end + vim.api.nvim_create_autocmd('TermOpen', { group = nvim_terminal_augroup, desc = 'Default settings for :terminal buffers', - callback = function() - vim.bo.modifiable = false - vim.bo.undolevels = -1 - vim.bo.scrollback = vim.o.scrollback < 0 and 10000 or math.max(1, vim.o.scrollback) - vim.bo.textwidth = 0 + callback = function(args) + vim.bo[args.buf].modifiable = false + vim.bo[args.buf].undolevels = -1 + vim.bo[args.buf].scrollback = vim.o.scrollback < 0 and 10000 or math.max(1, vim.o.scrollback) + vim.bo[args.buf].textwidth = 0 vim.wo[0][0].wrap = false vim.wo[0][0].list = false vim.wo[0][0].number = false @@ -555,6 +600,13 @@ do winhl = winhl .. ',' end vim.wo[0][0].winhighlight = winhl .. 'StatusLine:StatusLineTerm,StatusLineNC:StatusLineTermNC' + + vim.keymap.set('n', '[[', function() + jump_to_prompt(nvim_terminal_prompt_ns, 0, args.buf, -vim.v.count1) + end, { buffer = args.buf, desc = 'Jump [count] shell prompts backward' }) + vim.keymap.set('n', ']]', function() + jump_to_prompt(nvim_terminal_prompt_ns, 0, args.buf, vim.v.count1) + end, { buffer = args.buf, desc = 'Jump [count] shell prompts forward' }) end, }) @@ -712,7 +764,7 @@ do nested = true, desc = "Update the value of 'background' automatically based on the terminal emulator's background color", callback = function(args) - local resp = args.data ---@type string + local resp = args.data.sequence ---@type string local r, g, b = parseosc11(resp) if r and g and b then local rr = parsecolor(r) @@ -788,7 +840,7 @@ do group = group, nested = true, callback = function(args) - local resp = args.data ---@type string + local resp = args.data.sequence ---@type string local decrqss = resp:match('^\027P1%$r([%d;:]+)m$') if decrqss then @@ -834,9 +886,7 @@ do -- terminal responds to the DECRQSS with the same SGR sequence that we -- sent then the terminal supports truecolor. local decrqss = '\027P$qm\027\\' - if os.getenv('TMUX') then - decrqss = string.format('\027Ptmux;%s\027\\', decrqss:gsub('\027', '\027\027')) - end + -- Reset attributes first, as other code may have set attributes. io.stdout:write(string.format('\027[0m\027[48;2;%d;%d;%dm%s', r, g, b, decrqss)) diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 975f3fea4a..e29d8f1c30 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1142,6 +1142,21 @@ do end end +--- @param inspect_strings boolean use vim.inspect() for strings +function vim._print(inspect_strings, ...) + local msg = {} + for i = 1, select('#', ...) do + local o = select(i, ...) + if not inspect_strings and type(o) == 'string' then + table.insert(msg, o) + else + table.insert(msg, vim.inspect(o, { newline = '\n', indent = ' ' })) + end + end + print(table.concat(msg, '\n')) + return ... +end + --- "Pretty prints" the given arguments and returns them unmodified. --- --- Example: @@ -1155,17 +1170,7 @@ end --- @param ... any --- @return any # given arguments. function vim.print(...) - local msg = {} - for i = 1, select('#', ...) do - local o = select(i, ...) - if type(o) == 'string' then - table.insert(msg, o) - else - table.insert(msg, vim.inspect(o, { newline = '\n', indent = ' ' })) - end - end - print(table.concat(msg, '\n')) - return ... + return vim._print(false, ...) end --- Translates keycodes. diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua index 15cdd8fc79..b890b64174 100644 --- a/runtime/lua/vim/_meta/api.lua +++ b/runtime/lua/vim/_meta/api.lua @@ -9,19 +9,16 @@ error('Cannot require a meta file') vim.api = {} ---- @private --- @param buffer integer --- @param keys boolean --- @param dot boolean --- @return string function vim.api.nvim__buf_debug_extmarks(buffer, keys, dot) end ---- @private --- @param buffer integer --- @return table<string,any> function vim.api.nvim__buf_stats(buffer) end ---- @private --- EXPERIMENTAL: this API may change in the future. --- --- Sets info for the completion item at the given index. If the info text was shown in a window, @@ -35,11 +32,9 @@ function vim.api.nvim__buf_stats(buffer) end --- - bufnr: (number) buffer id in floating window function vim.api.nvim__complete_set(index, opts) end ---- @private --- @return string function vim.api.nvim__get_lib_dir() end ---- @private --- Find files in runtime directories --- --- @param pat any[] pattern of files to search for @@ -48,7 +43,6 @@ function vim.api.nvim__get_lib_dir() end --- @return string[] # list of absolute paths to the found files function vim.api.nvim__get_runtime(pat, all, opts) end ---- @private --- Returns object given as argument. --- --- This API function is used for testing. One should not rely on its presence @@ -58,7 +52,6 @@ function vim.api.nvim__get_runtime(pat, all, opts) end --- @return any # its argument. function vim.api.nvim__id(obj) end ---- @private --- Returns array given as argument. --- --- This API function is used for testing. One should not rely on its presence @@ -68,7 +61,6 @@ function vim.api.nvim__id(obj) end --- @return any[] # its argument. function vim.api.nvim__id_array(arr) end ---- @private --- Returns dict given as argument. --- --- This API function is used for testing. One should not rely on its presence @@ -78,7 +70,6 @@ function vim.api.nvim__id_array(arr) end --- @return table<string,any> # its argument. function vim.api.nvim__id_dict(dct) end ---- @private --- Returns floating-point value given as argument. --- --- This API function is used for testing. One should not rely on its presence @@ -88,7 +79,6 @@ function vim.api.nvim__id_dict(dct) end --- @return number # its argument. function vim.api.nvim__id_float(flt) end ---- @private --- NB: if your UI doesn't use hlstate, this will not return hlstate first time. --- @param grid integer --- @param row integer @@ -96,12 +86,10 @@ function vim.api.nvim__id_float(flt) end --- @return any[] function vim.api.nvim__inspect_cell(grid, row, col) end ---- @private --- For testing. The condition in schar_cache_clear_if_full is hard to --- reach, so this function can be used to force a cache clear in a test. function vim.api.nvim__invalidate_glyph_cache() end ---- @private --- EXPERIMENTAL: this API will change in the future. --- --- Get the properties for namespace @@ -110,7 +98,6 @@ function vim.api.nvim__invalidate_glyph_cache() end --- @return vim.api.keyset.ns_opts # Map defining the namespace properties, see |nvim__ns_set()| function vim.api.nvim__ns_get(ns_id) end ---- @private --- EXPERIMENTAL: this API will change in the future. --- --- Set some properties for namespace @@ -120,7 +107,6 @@ function vim.api.nvim__ns_get(ns_id) end --- - wins: a list of windows to be scoped in function vim.api.nvim__ns_set(ns_id, opts) end ---- @private --- EXPERIMENTAL: this API may change in the future. --- --- Instruct Nvim to redraw various components. @@ -148,21 +134,17 @@ function vim.api.nvim__ns_set(ns_id, opts) end --- - tabline: Redraw the 'tabline'. function vim.api.nvim__redraw(opts) end ---- @private --- @return any[] function vim.api.nvim__runtime_inspect() end ---- @private --- @param path string function vim.api.nvim__screenshot(path) end ---- @private --- Gets internal stats. --- --- @return table<string,any> # Map of various internal stats. function vim.api.nvim__stats() end ---- @private --- @param str string --- @return any function vim.api.nvim__unpack(str) end diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 8df174a838..59e65b0585 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -1083,15 +1083,15 @@ vim.go.cia = vim.go.completeitemalign --- match, e.g., what file it comes from. --- --- noinsert Do not insert any text for a match until the user selects ---- a match from the menu. Only works in combination with +--- a match from the menu. Only works in combination with --- "menu" or "menuone". No effect if "longest" is present. --- --- noselect Same as "noinsert", except that no menu item is ---- pre-selected. If both "noinsert" and "noselect" are +--- pre-selected. If both "noinsert" and "noselect" are --- present, "noselect" has precedence. --- --- nosort Disable sorting of completion candidates based on fuzzy ---- scores when "fuzzy" is enabled. Candidates will appear +--- scores when "fuzzy" is enabled. Candidates will appear --- in their original order. --- --- popup Show extra information about the currently selected @@ -1102,7 +1102,7 @@ vim.go.cia = vim.go.completeitemalign --- Preinsert the portion of the first candidate word that is --- not part of the current completion leader and using the --- `hl-ComplMatchIns` highlight group. In order for it to ---- work, "fuzzy" must not bet set and "menuone" must be set. +--- work, "fuzzy" must not be set and "menuone" must be set. --- --- preview Show extra information about the currently selected --- completion in the preview window. Only works in @@ -4640,7 +4640,7 @@ vim.go.pm = vim.go.patchmode --- ``` --- - A directory name may end in a ':' or '/'. --- - Environment variables are expanded `:set_env`. ---- - When using `netrw.vim` URLs can be used. For example, adding +--- - When using `netrw` URLs can be used. For example, adding --- "https://www.vim.org" will make ":find index.html" work. --- - Search upwards and downwards in a directory tree using "*", "**" and --- ";". See `file-searching` for info and syntax. @@ -7691,7 +7691,10 @@ vim.go.wmnu = vim.go.wildmenu --- "lastused" When completing buffer names and more than one buffer --- matches, sort buffers by time last used (other than --- the current buffer). ---- When there is only a single match, it is fully completed in all cases. +--- "noselect" Do not pre-select first menu item and start 'wildmenu' +--- if it is enabled. +--- When there is only a single match, it is fully completed in all cases +--- except when "noselect" is present. --- --- Examples of useful colon-separated values: --- "longest:full" Like "longest", but also start 'wildmenu' if it is @@ -7729,7 +7732,17 @@ vim.go.wmnu = vim.go.wildmenu --- ```vim --- set wildmode=longest,list --- ``` ---- Complete longest common string, then list alternatives. +--- Complete longest common string, then list alternatives +--- +--- ```vim +--- set wildmode=noselect:full +--- ``` +--- Display 'wildmenu' without completing, then each full match +--- +--- ```vim +--- set wildmode=noselect:lastused,full +--- ``` +--- Same as above, but sort buffers by time last used. --- More info here: `cmdline-completion`. --- --- @type string diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 26f0011e82..4749f94b1b 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1757,8 +1757,7 @@ local function render_virtual_lines(namespace, bufnr, diagnostics) string.rep( ' ', -- +1 because indexing starts at 0 in one API but at 1 in the other. - -- -1 for non-first lines, since the previous column was already drawn. - distance_between_cols(bufnr, diag.lnum, prev_col + 1, diag.col) - 1 + distance_between_cols(bufnr, diag.lnum, prev_col + 1, diag.col) ), }) else diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index c47ce5e761..2c058bc6bf 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -198,6 +198,7 @@ local extension = { abap = 'abap', abc = 'abc', abl = 'abel', + abnf = 'abnf', wrm = 'acedb', ads = 'ada', ada = 'ada', @@ -1206,6 +1207,7 @@ local extension = { tl = 'teal', templ = 'templ', tmpl = 'template', + tera = 'tera', ti = 'terminfo', dtx = 'tex', ltx = 'tex', diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 47f41b43aa..2da591e9bb 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1129,6 +1129,7 @@ local function on_code_action_results(results, opts) if not choice then return end + -- textDocument/codeAction can return either Command[] or CodeAction[] -- -- CodeAction @@ -1140,15 +1141,22 @@ local function on_code_action_results(results, opts) -- title: string -- command: string -- arguments?: any[] - -- + local client = assert(lsp.get_client_by_id(choice.ctx.client_id)) local action = choice.action local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number') - if not action.edit and client:supports_method(ms.codeAction_resolve) then + -- Only code actions are resolved, so if we have a command, just apply it. + if type(action.title) == 'string' and type(action.command) == 'string' then + apply_action(action, client, choice.ctx) + return + end + + if not action.edit or not action.command and client:supports_method(ms.codeAction_resolve) then client:request(ms.codeAction_resolve, action, function(err, resolved_action) if err then - if action.command then + -- If resolve fails, try to apply the edit/command from the original code action. + if action.edit or action.command then apply_action(action, client, choice.ctx) else vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR) diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 7975006f9d..feff9adbd0 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -424,7 +424,7 @@ function protocol.make_client_capabilities() isPreferredSupport = true, dataSupport = true, resolveSupport = { - properties = { 'edit' }, + properties = { 'edit', 'command' }, }, }, codeLens = { diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 1219f71427..ef177e903f 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1656,7 +1656,9 @@ function M.open_floating_preview(contents, syntax, opts) if not opts.height then -- Reduce window height if TS highlighter conceals code block backticks. local conceal_height = api.nvim_win_text_height(floating_winnr, {}).all - api.nvim_win_set_height(floating_winnr, conceal_height) + if conceal_height < api.nvim_win_get_height(floating_winnr) then + api.nvim_win_set_height(floating_winnr, conceal_height) + end end end diff --git a/runtime/lua/vim/termcap.lua b/runtime/lua/vim/termcap.lua index 4aa41bba9b..2789aacb90 100644 --- a/runtime/lua/vim/termcap.lua +++ b/runtime/lua/vim/termcap.lua @@ -34,7 +34,7 @@ function M.query(caps, cb) local id = vim.api.nvim_create_autocmd('TermResponse', { nested = true, callback = function(args) - local resp = args.data ---@type string + local resp = args.data.sequence ---@type string local k, rest = resp:match('^\027P1%+r(%x+)(.*)$') if k and rest then local cap = vim.text.hexdecode(k) @@ -71,11 +71,6 @@ function M.query(caps, cb) local query = string.format('\027P+q%s\027\\', table.concat(encoded, ';')) - -- If running in tmux, wrap with the passthrough sequence - if os.getenv('TMUX') then - query = string.format('\027Ptmux;%s\027\\', query:gsub('\027', '\027\027')) - end - io.stdout:write(query) timer:start(1000, 0, function() diff --git a/runtime/lua/vim/ui/clipboard/osc52.lua b/runtime/lua/vim/ui/clipboard/osc52.lua index 50afbe63a5..73f64c9743 100644 --- a/runtime/lua/vim/ui/clipboard/osc52.lua +++ b/runtime/lua/vim/ui/clipboard/osc52.lua @@ -25,7 +25,7 @@ function M.paste(reg) local contents = nil local id = vim.api.nvim_create_autocmd('TermResponse', { callback = function(args) - local resp = args.data ---@type string + local resp = args.data.sequence ---@type string local encoded = resp:match('\027%]52;%w?;([A-Za-z0-9+/=]*)') if encoded then contents = vim.base64.decode(encoded) diff --git a/runtime/makemenu.vim b/runtime/makemenu.vim index 01f214cfa0..3d27bfc551 100644 --- a/runtime/makemenu.vim +++ b/runtime/makemenu.vim @@ -1,6 +1,6 @@ " Script to define the syntax menu in synmenu.vim " Maintainer: The Vim Project <https://github.com/vim/vim> -" Last Change: 2023 Aug 10 +" Last Change: 2025 Mar 09 " Former Maintainer: Bram Moolenaar <Bram@vim.org> " This is used by "make menu" in the src directory. @@ -602,6 +602,7 @@ SynMenu T.Tcl/Tk:tcl SynMenu T.TealInfo:tli SynMenu T.Telix\ Salt:tsalt SynMenu T.Termcap/Printcap:ptcap +SynMenu T.Tera:tera SynMenu T.Terminfo:terminfo SynMenu T.Tera\ Term:teraterm SynMenu T.TeX.TeX/LaTeX:tex diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim index 13d1b6824f..079cc668f0 100644 --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -1,6 +1,6 @@ " Vim plugin for showing matching parens " Maintainer: The Vim Project <https://github.com/vim/vim> -" Last Change: 2024 May 18 +" Last Change: 2025 Mar 08 " Former Maintainer: Bram Moolenaar <Bram@vim.org> " Exit quickly when: @@ -114,6 +114,17 @@ func s:Highlight_Matching_Pair() \ .. 'string\|character\|singlequote\|escape\|symbol\|comment' \ .. "') != -1" else + " do not attempt to match when the syntax item where the cursor is + " indicates there does not exist a matching parenthesis, e.g. for shells + " case statement: "case $var in foobar)" + " + " add the check behind a filetype check, so it only needs to be + " evaluated for certain filetypes + if ['sh']->index(&filetype) >= 0 && + \ synstack(".", col("."))->indexof({_, id -> synIDattr(id, "name") + \ =~? "shSnglCase"}) >= 0 + return + endif " Build an expression that detects whether the current cursor position is " in certain syntax types (string, comment, etc.), for use as " searchpairpos()'s skip argument. diff --git a/runtime/synmenu.vim b/runtime/synmenu.vim index edc6eabd1d..6a3bb8eaf4 100644 --- a/runtime/synmenu.vim +++ b/runtime/synmenu.vim @@ -582,26 +582,27 @@ an 50.150.190 &Syntax.T.TealInfo :cal SetSyn("tli")<CR> an 50.150.200 &Syntax.T.Telix\ Salt :cal SetSyn("tsalt")<CR> an 50.150.210 &Syntax.T.Termcap/Printcap :cal SetSyn("ptcap")<CR> an 50.150.220 &Syntax.T.Terminfo :cal SetSyn("terminfo")<CR> -an 50.150.230 &Syntax.T.Tera\ Term :cal SetSyn("teraterm")<CR> -an 50.150.240 &Syntax.T.TeX.TeX/LaTeX :cal SetSyn("tex")<CR> -an 50.150.250 &Syntax.T.TeX.plain\ TeX :cal SetSyn("plaintex")<CR> -an 50.150.260 &Syntax.T.TeX.Initex :cal SetSyn("initex")<CR> -an 50.150.270 &Syntax.T.TeX.ConTeXt :cal SetSyn("context")<CR> -an 50.150.280 &Syntax.T.TeX.TeX\ configuration :cal SetSyn("texmf")<CR> -an 50.150.290 &Syntax.T.TeX.Texinfo :cal SetSyn("texinfo")<CR> -an 50.150.300 &Syntax.T.TF\ mud\ client :cal SetSyn("tf")<CR> -an 50.150.310 &Syntax.T.Tidy\ configuration :cal SetSyn("tidy")<CR> -an 50.150.320 &Syntax.T.Tilde :cal SetSyn("tilde")<CR> -an 50.150.330 &Syntax.T.Tmux\ configuration :cal SetSyn("tmux")<CR> -an 50.150.340 &Syntax.T.TPP :cal SetSyn("tpp")<CR> -an 50.150.350 &Syntax.T.Trasys\ input :cal SetSyn("trasys")<CR> -an 50.150.360 &Syntax.T.Treetop :cal SetSyn("treetop")<CR> -an 50.150.370 &Syntax.T.Trustees :cal SetSyn("trustees")<CR> -an 50.150.380 &Syntax.T.TSS.Command\ Line :cal SetSyn("tsscl")<CR> -an 50.150.390 &Syntax.T.TSS.Geometry :cal SetSyn("tssgm")<CR> -an 50.150.400 &Syntax.T.TSS.Optics :cal SetSyn("tssop")<CR> -an 50.150.410 &Syntax.T.Typescript :cal SetSyn("typescript")<CR> -an 50.150.420 &Syntax.T.TypescriptReact :cal SetSyn("typescriptreact")<CR> +an 50.150.230 &Syntax.T.Tera :cal SetSyn("tera")<CR> +an 50.150.240 &Syntax.T.Tera\ Term :cal SetSyn("teraterm")<CR> +an 50.150.250 &Syntax.T.TeX.TeX/LaTeX :cal SetSyn("tex")<CR> +an 50.150.260 &Syntax.T.TeX.plain\ TeX :cal SetSyn("plaintex")<CR> +an 50.150.270 &Syntax.T.TeX.Initex :cal SetSyn("initex")<CR> +an 50.150.280 &Syntax.T.TeX.ConTeXt :cal SetSyn("context")<CR> +an 50.150.290 &Syntax.T.TeX.TeX\ configuration :cal SetSyn("texmf")<CR> +an 50.150.300 &Syntax.T.TeX.Texinfo :cal SetSyn("texinfo")<CR> +an 50.150.310 &Syntax.T.TF\ mud\ client :cal SetSyn("tf")<CR> +an 50.150.320 &Syntax.T.Tidy\ configuration :cal SetSyn("tidy")<CR> +an 50.150.330 &Syntax.T.Tilde :cal SetSyn("tilde")<CR> +an 50.150.340 &Syntax.T.Tmux\ configuration :cal SetSyn("tmux")<CR> +an 50.150.350 &Syntax.T.TPP :cal SetSyn("tpp")<CR> +an 50.150.360 &Syntax.T.Trasys\ input :cal SetSyn("trasys")<CR> +an 50.150.370 &Syntax.T.Treetop :cal SetSyn("treetop")<CR> +an 50.150.380 &Syntax.T.Trustees :cal SetSyn("trustees")<CR> +an 50.150.390 &Syntax.T.TSS.Command\ Line :cal SetSyn("tsscl")<CR> +an 50.150.400 &Syntax.T.TSS.Geometry :cal SetSyn("tssgm")<CR> +an 50.150.410 &Syntax.T.TSS.Optics :cal SetSyn("tssop")<CR> +an 50.150.420 &Syntax.T.Typescript :cal SetSyn("typescript")<CR> +an 50.150.430 &Syntax.T.TypescriptReact :cal SetSyn("typescriptreact")<CR> an 50.160.100 &Syntax.UV.Udev\ config :cal SetSyn("udevconf")<CR> an 50.160.110 &Syntax.UV.Udev\ permissions :cal SetSyn("udevperm")<CR> an 50.160.120 &Syntax.UV.Udev\ rules :cal SetSyn("udevrules")<CR> diff --git a/runtime/syntax/abnf.vim b/runtime/syntax/abnf.vim new file mode 100644 index 0000000000..13459eb9f8 --- /dev/null +++ b/runtime/syntax/abnf.vim @@ -0,0 +1,33 @@ +" Vim compiler file +" Language: abnf +" Maintainer: A4-Tacks <wdsjxhno1001@163.com> +" Last Change: 2025 Mar 05 +" Upstream: https://github.com/A4-Tacks/abnf.vim + +" Implementing RFC-5234, RFC-7405 + +if exists('b:current_syntax') + finish +endif + +syn case ignore + +syn match abnfError /[<>"]/ +syn match abnfComment /;.*/ +syn match abnfOption /[[/\]]/ +syn region abnfString start=/\(%[si]\)\="/ end=/"/ oneline +syn region abnfProse start=/</ end=/>/ oneline +syn match abnfNumVal /\v\%b[01]+%(%(\.[01]+)+|-[01]+)=>/ +syn match abnfNumVal /\v\%d\d+%(%(\.\d+)+|-\d+)=>/ +syn match abnfNumVal /\v\%x[0-9a-f]+%(%(\.[0-9a-f]+)+|-[0-9a-f]+)=>/ +syn match abnfRepeat /\v%(%(<\d+)=\*\d*|<\d+ =)\ze[^ \t\r\n0-9*/)\]]/ + +hi def link abnfError Error +hi def link abnfComment Comment +hi def link abnfOption PreProc +hi def link abnfString String +hi def link abnfProse String +hi def link abnfNumVal Number +hi def link abnfRepeat Repeat + +" vim:noet:ts=8:sts=8:nowrap diff --git a/runtime/syntax/tera.vim b/runtime/syntax/tera.vim new file mode 100644 index 0000000000..922b9c9752 --- /dev/null +++ b/runtime/syntax/tera.vim @@ -0,0 +1,96 @@ +" Vim syntax file +" Language: Tera +" Maintainer: Muntasir Mahmud <muntasir.joypurhat@gmail.com> +" Last Change: 2025 Mar 09 + +if exists("b:current_syntax") + finish +endif + +" Detect the underlying language based on filename pattern +" For files like file.html.tera, we want to load html syntax +let s:filename = expand("%:t") +let s:dotpos = strridx(s:filename, '.', strridx(s:filename, '.tera') - 1) +let s:underlying_filetype = "" + +if s:dotpos != -1 + let s:underlying_ext = s:filename[s:dotpos+1:strridx(s:filename, '.tera')-1] + if s:underlying_ext != "" && s:underlying_ext != "tera" + let s:underlying_filetype = s:underlying_ext + endif +endif + +" Load the underlying language syntax if detected +if s:underlying_filetype != "" + execute "runtime! syntax/" . s:underlying_filetype . ".vim" + unlet! b:current_syntax +else + " Default to HTML if no specific language detected + runtime! syntax/html.vim + unlet! b:current_syntax +endif + +" Tera comment blocks: {# comment #} +syn region teraCommentBlock start="{#" end="#}" contains=@Spell containedin=cssDefinition,cssStyle,htmlHead,htmlTitle + +" Tera statements: {% if condition %} +syn region teraStatement start="{%" end="%}" contains=teraKeyword,teraString,teraNumber,teraFunction,teraBoolean,teraFilter,teraOperator containedin=cssDefinition,cssStyle,htmlHead,htmlTitle + +" Tera expressions: {{ variable }} +syn region teraExpression start="{{" end="}}" contains=teraString,teraNumber,teraFunction,teraBoolean,teraFilter,teraOperator,teraIdentifier containedin=cssDefinition,cssStyle,htmlHead,htmlTitle + +" Special handling for raw blocks - content inside shouldn't be processed +syn region teraRawBlock start="{% raw %}" end="{% endraw %}" contains=TOP,teraCommentBlock,teraStatement,teraExpression + +" Control structure keywords +syn keyword teraKeyword contained if else elif endif for endfor in macro endmacro +syn keyword teraKeyword contained block endblock extends include import set endset +syn keyword teraKeyword contained break continue filter endfilter raw endraw with endwith + +" Identifiers - define before operators for correct priority +syn match teraIdentifier contained "\<\w\+\>" + +" Operators used in expressions and statements +syn match teraOperator contained "==\|!=\|>=\|<=\|>\|<\|+\|-\|*\|/" +syn match teraOperator contained "{\@<!%}\@!" " Match % but not when part of {% or %} +syn keyword teraOperator contained and or not is as + +" Functions and filters +syn match teraFunction contained "\<\w\+\ze(" +syn match teraFilter contained "|\_s*\w\+" + +" String literals - both single and double quoted +syn region teraString contained start=+"+ skip=+\\"+ end=+"+ contains=@Spell +syn region teraString contained start=+'+ skip=+\\'+ end=+'+ contains=@Spell + +" Numeric literals - both integer and float +syn match teraNumber contained "\<\d\+\>" +syn match teraNumber contained "\<\d\+\.\d\+\>" + +" Boolean values +syn keyword teraBoolean contained true false + +" Highlighting links +hi def link teraCommentBlock Comment +hi def link teraKeyword Statement +hi def link teraOperator Operator +hi def link teraFunction Function +hi def link teraIdentifier Identifier +hi def link teraString String +hi def link teraNumber Number +hi def link teraBoolean Boolean +hi def link teraFilter PreProc + +" Special highlighting for blocks and expressions +hi def link teraStatement PreProc +hi def link teraExpression PreProc + +" Clean up script-local variables +unlet s:filename +unlet s:dotpos +if exists("s:underlying_ext") + unlet s:underlying_ext +endif +unlet s:underlying_filetype + +let b:current_syntax = "tera" diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index de0a1228e2..7fe22190b7 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -711,9 +711,9 @@ syn match vimCmplxRepeat '[^a-zA-Z_/\\()]q[0-9a-zA-Z"]\>'lc=1 syn match vimCmplxRepeat '@[0-9a-z".=@:]\ze\($\|[^a-zA-Z]\>\)' " Set command and associated set-options (vimOptions) with comment {{{2 -syn match vimSet "\<\%(setl\%[ocal]\|setg\%[lobal]\|se\%[t]\)\>" skipwhite nextgroup=vimSetBang,vimSetRegion -syn region vimSetRegion contained start="\S" skip=+\\\\\|\\|\|\n\s*\\\|\n\s*["#]\\ + matchgroup=vimCmdSep end="|" end="$" matchgroup=vimNotation end="<[cC][rR]>" keepend contains=@vimComment,@vimContinue,vimErrSetting,vimOption,vimSetAll,vimSetTermcap -syn region vimSetEqual contained matchgroup=vimOper start="[=:]\|[-+^]=" skip=+\\\\\|\\|\|\\\s\|\n\s*\\\|\n\s*["#]\\ \|^\s*\\\|^\s*["#]\\ + matchgroup=vimCmdSep end="|" end="\ze\s" end="$" contains=@vimContinue,vimCtrlChar,vimEnvvar,vimNotation,vimSetSep +syn match vimSet "\<\%(setl\%[ocal]\|setg\%[lobal]\|se\%[t]\)\>" skipwhite nextgroup=vimSetBang,vimSetArgs +syn region vimSetArgs contained start="\S" skip=+\\|\|\n\s*\\\|\n\s*["#]\\ + matchgroup=vimCmdSep end="|" end="$" matchgroup=vimNotation end="<[cC][rR]>" keepend contains=@vimComment,@vimContinue,vimErrSetting,vimOption,vimSetAll,vimSetTermcap +syn region vimSetEqual contained matchgroup=vimOper start="[=:]\|[-+^]=" skip=+\\|\|\\\s\|\n\s*\\\|\n\s*["#]\\ \|^\s*\\\|^\s*["#]\\ + matchgroup=vimCmdSep end="|" end="\ze\s" end="$" contains=@vimContinue,vimCtrlChar,vimEnvvar,vimNotation,vimSetSep syn match vimSetBang contained "\a\@1<=!" skipwhite nextgroup=vimSetAll,vimSetTermcap syn keyword vimSetAll contained all nextgroup=vimSetMod syn keyword vimSetTermcap contained termcap @@ -835,15 +835,17 @@ syn keyword vimMap mapc[lear] skipwhite nextgroup=vimMapBang,vimMapMod syn keyword vimUnmap cu[nmap] iu[nmap] lu[nmap] nun[map] ou[nmap] sunm[ap] tunma[p] vu[nmap] xu[nmap] skipwhite nextgroup=vimMapMod,vimMapLhs syn keyword vimUnmap unm[ap] skipwhite nextgroup=vimMapBang,vimMapMod,vimMapLhs -syn match vimMapLhs contained "\%(.\|\S\)\+" contains=vimCtrlChar,vimNotation skipwhite nextgroup=vimMapRhs -syn match vimMapLhs contained "\%(.\|\S\)\+\ze\s*$" contains=vimCtrlChar,vimNotation skipwhite skipnl nextgroup=vimMapRhsContinue +syn match vimMapLhs contained "\%(.\|\S\)\+" contains=vimCtrlChar,vimNotation,vimMapLeader skipwhite nextgroup=vimMapRhs +syn match vimMapLhs contained "\%(.\|\S\)\+\ze\s*$" contains=vimCtrlChar,vimNotation,vimMapLeader skipwhite skipnl nextgroup=vimMapRhsContinue syn match vimMapBang contained "\a\@1<=!" skipwhite nextgroup=vimMapMod,vimMapLhs -syn match vimMapMod contained "\%#=1\c<\(buffer\|expr\|\(local\)\=leader\|nowait\|plug\|script\|sid\|unique\|silent\)\+>" contains=vimMapModKey,vimMapModErr skipwhite nextgroup=vimMapMod,vimMapLhs -syn region vimMapRhs contained start="\S" skip=+\\|\|\@1<=|\|\n\s*\\\|\n\s*"\\ + end="|" end="$" contains=@vimContinue,vimCtrlChar,vimNotation skipnl nextgroup=vimMapRhsContinue +syn match vimMapMod contained "\%#=1<\%(buffer\|expr\|nowait\|script\|silent\|special\|unique\)\+>" contains=vimMapModKey,vimMapModErr skipwhite nextgroup=vimMapMod,vimMapLhs +syn region vimMapRhs contained start="\S" skip=+\\|\|\@1<=|\|\n\s*\\\|\n\s*"\\ + end="|" end="$" contains=@vimContinue,vimCtrlChar,vimNotation,vimMapLeader skipnl nextgroup=vimMapRhsContinue " assume a continuation comment introduces the RHS -syn region vimMapRhsContinue contained start=+^\s*\%(\\\|"\\ \)+ skip=+\\|\|\@1<=|\|\n\s*\\\|\n\s*"\\ + end="|" end="$" contains=@vimContinue,vimCtrlChar,vimNotation +syn region vimMapRhsContinue contained start=+^\s*\%(\\\|"\\ \)+ skip=+\\|\|\@1<=|\|\n\s*\\\|\n\s*"\\ + end="|" end="$" contains=@vimContinue,vimCtrlChar,vimNotation,vimMapLeader +syn match vimMapLeader contained "\%#=1\c<\%(local\)\=leader>" contains=vimMapLeaderKey +syn keyword vimMapModKey contained buffer expr nowait script silent special unique syn case ignore -syn keyword vimMapModKey contained buffer expr leader localleader nowait plug script sid silent unique +syn keyword vimMapLeaderKey contained leader localleader syn case match " Menus: {{{2 @@ -909,7 +911,7 @@ syn match vimUsrCmd '^\s*\zs\u\%(\w*\)\@>\%([(#[]\|\s\+\%([-+*/%]\=\|\.\.\)=\)\@ " Vim user commands " Compiler plugins -syn match vimCompilerSet "\<CompilerSet\>" skipwhite nextgroup=vimSetRegion +syn match vimCompilerSet "\<CompilerSet\>" skipwhite nextgroup=vimSetArgs " runtime/makemenu.vim syn match vimSynMenu "\<SynMenu\>" skipwhite nextgroup=vimSynMenuPath @@ -1494,6 +1496,8 @@ if !exists("skip_vim_syntax_inits") hi def link vimLetRegister Special hi def link vimLineComment vimComment hi def link vimMapBang vimBang + hi def link vimMapLeader vimBracket + hi def link vimMapLeaderKey vimNotation hi def link vimMapModKey vimFuncSID hi def link vimMapMod vimBracket hi def link vimMap vimCommand |