diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 2dfcb75451..52ad4313bf 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -382,9 +382,10 @@ CmdUndefined When a user command is used but it isn't always define the user command and have it invoke an autoloaded function. See |autoload|. *CmdlineChanged* -CmdlineChanged After a change was made to the text inside - command line. Be careful not to mess up the - command line, it may cause Vim to lock up. +CmdlineChanged After EVERY change inside command line. Also + triggered during mappings! Use || instead + of ":" in mappings, to avoid that. + expands to the |cmdline-char|. *CmdlineEnter* CmdlineEnter After entering the command-line (including diff --git a/runtime/doc/dev_arch.txt b/runtime/doc/dev_arch.txt index 3fe50ddb7e..3391736b5f 100644 --- a/runtime/doc/dev_arch.txt +++ b/runtime/doc/dev_arch.txt @@ -144,19 +144,17 @@ asynchronous events, which can include: Nvim implements this functionality by entering another event loop while waiting for characters, so instead of: >py - def state_enter(state_callback, data): + def state_enter(on_state, data): do - key = readkey() # read a key from the user - while state_callback(data, key) # invoke the callback for the current state -< + key = readkey() # Read a key from the user + while on_state(data, key) # Invoke callback for the current state -The Nvim program loop is more like: >py +the Nvim program loop is more like: >py - def state_enter(state_callback, data): + def state_enter(on_state, data): do - event = read_next_event() # read an event from the operating system - while state_callback(data, event) # invoke the callback for the current state -< + event = read_next_event() # Read an event from the OS + while on_state(data, event) # Invoke callback for current state where `event` is something the operating system delivers to us, including (but not limited to) user input. The `read_next_event()` part is internally diff --git a/runtime/doc/dev_test.txt b/runtime/doc/dev_test.txt index 48e7e56ccd..8b2d76d38c 100644 --- a/runtime/doc/dev_test.txt +++ b/runtime/doc/dev_test.txt @@ -33,7 +33,7 @@ Tests are broadly divided into unit tests (`test/unit/`), functional tests opposed to Lua). They are essentially "integration" tests, they test the full system. But they are fast. -You can learn the [Lua concepts 15 minutes](https://learnxinyminutes.com/docs/lua/), +You can learn [Lua concepts 15 minutes](https://learnxinyminutes.com/docs/lua/), see also |lua-guide|. Use any existing test as a template to start writing new tests, or see |dev-quickstart|. diff --git a/runtime/doc/dev_tools.txt b/runtime/doc/dev_tools.txt index ffa874012a..4883ddea82 100644 --- a/runtime/doc/dev_tools.txt +++ b/runtime/doc/dev_tools.txt @@ -93,6 +93,8 @@ TUI INSPECT Use the Ghostty https://ghostty.org/ inspector tool to observe and query the output and events from any terminal application such as Nvim. +From the Ghostty inspector you can click the "Terminal IO" tab to get a trace. + TERMINFO LOGGING At 'verbose' level 3, Nvim logs its internal terminfo state, so you can see @@ -139,9 +141,10 @@ region is repainted internally. To also highlight excess internal redraws, use > TUI TRACE -In the rare case that you want to collect a trace of terminal output, the -ancient `script` command is still the "state of the art". The libvterm -`vterm-dump` utility formats the result for human-readability. +From the Ghostty inspector you can click the "Terminal IO" tab to get a trace. + +Alternatively, the ancient `script` command is the "state of the art". The +libvterm `vterm-dump` utility formats the result for human-readability. Record a Nvim terminal session and format it with `vterm-dump`: >sh diff --git a/runtime/doc/faq.txt b/runtime/doc/faq.txt index 35348fe0ac..4844cf7997 100644 --- a/runtime/doc/faq.txt +++ b/runtime/doc/faq.txt @@ -120,7 +120,6 @@ manage the cursor style: Alternatively, consider setting the desired cursor shape in your shell (e.g. with PROMPT_COMMAND in bash). -< ------------------------------------------------------------------------------ CURSOR SHAPE DOESN'T CHANGE IN TMUX diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index b992de5090..75cc055f3a 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -73,20 +73,21 @@ listed below, if (1) the language server supports the functionality and (2) the options are empty or were set by the builtin runtime (ftplugin) files. The options are not restored when the LSP client is stopped or detached. -GLOBAL DEFAULTS - *gra* *gri* *grn* *grr* *grt* *i_CTRL-S* *v_an* *v_in* +GLOBAL DEFAULTS *gra* *gri* *grn* *grr* *grt* *i_CTRL-S* *v_an* *v_in* + These GLOBAL keymaps are created unconditionally when Nvim starts: -- "gra" is mapped in Normal and Visual mode to |vim.lsp.buf.code_action()| -- "gri" is mapped in Normal mode to |vim.lsp.buf.implementation()| -- "grn" is mapped in Normal mode to |vim.lsp.buf.rename()| -- "grr" is mapped in Normal mode to |vim.lsp.buf.references()| -- "grt" is mapped in Normal mode to |vim.lsp.buf.type_definition()| -- "gO" is mapped in Normal mode to |vim.lsp.buf.document_symbol()| -- CTRL-S is mapped in Insert mode to |vim.lsp.buf.signature_help()| -- "an" and "in" are mapped in Visual mode to outer and inner incremental +- "gra" (Normal and Visual mode) is mapped to |vim.lsp.buf.code_action()| +- "gri" is mapped to |vim.lsp.buf.implementation()| +- "grn" is mapped to |vim.lsp.buf.rename()| +- "grr" is mapped to |vim.lsp.buf.references()| +- "grt" is mapped to |vim.lsp.buf.type_definition()| +- "gO" is mapped to |vim.lsp.buf.document_symbol()| +- CTRL-S (Insert mode) is mapped to |vim.lsp.buf.signature_help()| +- "an" and "in" (Visual mode) are mapped to outer and inner incremental selections, respectively, using |vim.lsp.buf.selection_range()| BUFFER-LOCAL DEFAULTS + - 'omnifunc' is set to |vim.lsp.omnifunc()|, use |i_CTRL-X_CTRL-O| to trigger completion. - 'tagfunc' is set to |vim.lsp.tagfunc()|. This enables features like @@ -101,6 +102,7 @@ BUFFER-LOCAL DEFAULTS - To opt out call `vim.lsp.document_color.enable(false, args.buf)` on |LspAttach|. DISABLING DEFAULTS *lsp-defaults-disable* + You can remove GLOBAL keymaps at any time using |vim.keymap.del()| or |:unmap|. See also |gr-default|. @@ -130,7 +132,7 @@ Use |vim.lsp.config()| to define or modify LSP configurations, and |vim.lsp.start()| which allows you to share and merge configs (provided by Nvim, plugins, and your local config). - *lsp-new-config* +NEW CONFIG *lsp-new-config* To create a new config you can either use `vim.lsp.config()` or create a `lsp/.lua` file. @@ -155,7 +157,7 @@ EXAMPLE: DEFINE A CONFIG AS A FILE ~ :lua vim.lsp.enable('foo') 5. Run `:checkhealth vim.lsp`, check "Enabled Configurations". 🌈 - *lsp-config-merge* +HOW CONFIGS ARE MERGED *lsp-config-merge* When an LSP client starts, it resolves its configuration by merging the following sources (merge semantics defined by |vim.tbl_deep_extend()| with "force" behavior), in order of increasing priority: @@ -166,6 +168,7 @@ following sources (merge semantics defined by |vim.tbl_deep_extend()| with 3. Configurations defined anywhere else. Example: given the following configs... >lua + -- Defined in init.lua vim.lsp.config('*', { capabilities = { @@ -177,20 +180,19 @@ Example: given the following configs... >lua }, root_markers = { '.git' }, }) - -- Defined in /lsp/clangd.lua return { cmd = { 'clangd' }, root_markers = { '.clangd', 'compile_commands.json' }, filetypes = { 'c', 'cpp' }, } - -- Defined in init.lua vim.lsp.config('clangd', { filetypes = { 'c' }, }) < ...the merged result is: >lua + { -- From the clangd configuration in /lsp/clangd.lua cmd = { 'clangd' }, @@ -213,7 +215,7 @@ Example: given the following configs... >lua } } < - *lsp-attach* +CONFIGURE ON ATTACH *lsp-attach* To use LSP features beyond those provided by Nvim (see |lsp-buf|), you can set keymaps and options on |Client:on_attach()| or |LspAttach|. Not all language servers provide the same capabilities; check `supports_method()` in your diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 35c0353fce..4c361f30f3 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2410,15 +2410,13 @@ vim.filetype.match({args}) *vim.filetype.match()* Mutually exclusive with {buf}. Return (multiple): ~ - (`string?`) If a match was found, the matched filetype. - (`function?`) A function that modifies buffer state when called (for - example, to set some filetype specific buffer variables). The function - accepts a buffer number as its only argument. - (`boolean?`) Return true if a match was found by falling back to a - generic configuration file (i.e., ".conf"). If true, the filetype - should be set with `:setf FALLBACK conf`, which enables a later - |:setf| command to override the filetype. See `:help setf` for more - information. + (`string?`) The matched filetype, if any. + (`function?`) A function `fun(buf: integer)` that modifies buffer + state when called (for example, to set some filetype specific buffer + variables). + (`boolean?`) true if a match was found by falling back to a generic + filetype (i.e., ".conf"), which indicates the filetype should be set + with `:setf FALLBACK conf`. See |:setfiletype|. ============================================================================== @@ -2434,6 +2432,13 @@ Example: >lua end < + *vim.fs.read()* +You can use |readblob()| to get a file's contents without explicitly opening/closing it. + +Example: >lua + vim.print(vim.fn.readblob('.git/config')) +< + vim.fs.abspath({path}) *vim.fs.abspath()* Convert path to an absolute path. A tilde (~) character at the beginning @@ -3438,6 +3443,18 @@ vim.keymap.set({mode}, {lhs}, {rhs}, {opts}) *vim.keymap.set()* end, { expr = true }) -- Map "[%%" to a mapping: vim.keymap.set('n', '[%%', '(MatchitNormalMultiBackward)') + + -- Use `getregionpos(getpos('v'))` to get the "current visual selection": + vim.keymap.set('x', 'M', function() + local region = vim.fn.getregionpos(vim.fn.getpos('v'), vim.fn.getpos('.'), { + type = 'v', + exclusive = false, + eol = false, + }) + local line1 = region[1][1][2] + local line2 = region[#region][1][2] + vim.print({ line1, line2 }) + end) < Parameters: ~ diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index 81457800a6..8080d8245b 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -326,9 +326,8 @@ be seen as a special key. ** *:map-cmd* The pseudokey begins a "command mapping", which executes the command -directly without changing modes. Where you might use ":..." in the -{rhs} of a mapping, you can instead use "...". -Example: > +directly without changing modes. Where you might use ":…" in the {rhs} of +a mapping, you can instead use "…". Example: > noremap x echo mode(1) < This is more flexible than `:` in Visual and Operator-pending mode, or @@ -348,7 +347,7 @@ Note: |CmdlineEnter| and |CmdlineLeave| events. This helps performance. - For the same reason, |keycodes| like are interpreted as plain, unmapped keys. -- The command is not echo'ed, no need for . +- The command is not echo'd, no need for . - The {rhs} is not subject to abbreviations nor to other mappings, even if the mapping is recursive. - In Visual mode you can use `line('v')` and `col('v')` to get one end of the @@ -357,7 +356,7 @@ Note: *E1255* *E1136* commands must terminate, that is, they must be followed by in the {rhs} of the mapping definition. |Command-line| mode is never entered. To use -a literal in the {rhs}, use ||. +a literal "<" in the {rhs}, use ||. 1.3 MAPPING AND MODES *:map-modes* diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 3c790674e9..5b5c1f78d1 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -71,8 +71,8 @@ EDITOR - |i_CTRL-R| inserts named/clipboard registers (A-Z,a-z,0-9+) literally, like pasting instead of like user input. Improves performance, avoids broken formatting. To get the old behavior you can use `=@x`. -- Buffer names now follow RFC3986 for detecting a scheme, meaning - "svn+ssh", "ed2k", and "iris.xpc" are now treated as URI schemes +- Buffer name URI scheme parsing more closely follows RFC3986, so for example + "svn+ssh:", "ed2k:", and "iris.xpc:" are recognized as URI schemes. EVENTS diff --git a/runtime/doc/vimfn.txt b/runtime/doc/vimfn.txt index 3c9ae4d9fd..3eaa88b62d 100644 --- a/runtime/doc/vimfn.txt +++ b/runtime/doc/vimfn.txt @@ -3931,33 +3931,30 @@ getpid() *getpid()* (`integer`) getpos({expr}) *getpos()* - Get the position for String {expr}. - The accepted values for {expr} are: - . The cursor position. - $ The last line in the current buffer. + Gets a position, where {expr} is one of: + . Cursor position. + $ Last line in the current buffer. 'x Position of mark x (if the mark is not set, 0 is returned for all values). w0 First line visible in current window (one if the display isn't updated, e.g. in silent Ex mode). w$ Last line visible in current window (this is one less than "w0" if no lines are visible). - v When not in Visual mode, returns the cursor - position. In Visual mode, returns the other end - of the Visual area. A good way to think about - this is that in Visual mode "v" and "." complement - each other. While "." refers to the cursor - position, "v" refers to where |v_o| would move the - cursor. As a result, you can use "v" and "." - together to work on all of a selection in - characterwise Visual mode. If the cursor is at - the end of a characterwise Visual area, "v" refers - to the start of the same Visual area. And if the - cursor is at the start of a characterwise Visual - area, "v" refers to the end of the same Visual - area. "v" differs from |'<| and |'>| in that it's - updated right away. - Note that a mark in another file can be used. The line number - then applies to another buffer. + v End of the current Visual selection (unlike |'<| + |'>| which give the previous, not current, Visual + selection), or the cursor position if not in Visual + mode. + + To get the current selected region: >vim + let region = getregionpos(getpos('v'), getpos('.')) +< + Explanation: in Visual mode "v" and "." complement each + other. While "." refers to the cursor position, "v" + refers to where |v_o| would move the cursor. So you can + use "v" and "." together to get the selected region. + + Note that if a mark in another file is used, the line number + applies to that buffer. The result is a |List| with four numbers: [bufnum, lnum, col, off] @@ -4249,8 +4246,14 @@ getregionpos({pos1}, {pos2} [, {opts}]) *getregionpos()* the offset of the character's first cell not included in the selection, otherwise all its cells are included. - Apart from the options supported by |getregion()|, {opts} also - supports the following: + To get the current visual selection: >vim + let region = getregionpos(getpos('v'), getpos('.')) +< + The {opts} Dict supports the following items: + + type See |getregion()|. + + exclusive See |getregion()|. eol If |TRUE|, indicate positions beyond the end of a line with "col" values diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 9ffdfe1961..3528388f11 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -3530,33 +3530,30 @@ function vim.fn.getmousepos() end --- @return integer function vim.fn.getpid() end ---- Get the position for String {expr}. ---- The accepted values for {expr} are: ---- . The cursor position. ---- $ The last line in the current buffer. +--- Gets a position, where {expr} is one of: +--- . Cursor position. +--- $ Last line in the current buffer. --- 'x Position of mark x (if the mark is not set, 0 is --- returned for all values). --- w0 First line visible in current window (one if the --- display isn't updated, e.g. in silent Ex mode). --- w$ Last line visible in current window (this is one --- less than "w0" if no lines are visible). ---- v When not in Visual mode, returns the cursor ---- position. In Visual mode, returns the other end ---- of the Visual area. A good way to think about ---- this is that in Visual mode "v" and "." complement ---- each other. While "." refers to the cursor ---- position, "v" refers to where |v_o| would move the ---- cursor. As a result, you can use "v" and "." ---- together to work on all of a selection in ---- characterwise Visual mode. If the cursor is at ---- the end of a characterwise Visual area, "v" refers ---- to the start of the same Visual area. And if the ---- cursor is at the start of a characterwise Visual ---- area, "v" refers to the end of the same Visual ---- area. "v" differs from |'<| and |'>| in that it's ---- updated right away. ---- Note that a mark in another file can be used. The line number ---- then applies to another buffer. +--- v End of the current Visual selection (unlike |'<| +--- |'>| which give the previous, not current, Visual +--- selection), or the cursor position if not in Visual +--- mode. +--- +--- To get the current selected region: >vim +--- let region = getregionpos(getpos('v'), getpos('.')) +--- < +--- Explanation: in Visual mode "v" and "." complement each +--- other. While "." refers to the cursor position, "v" +--- refers to where |v_o| would move the cursor. So you can +--- use "v" and "." together to get the selected region. +--- +--- Note that if a mark in another file is used, the line number +--- applies to that buffer. --- --- The result is a |List| with four numbers: --- [bufnum, lnum, col, off] @@ -3839,8 +3836,14 @@ function vim.fn.getregion(pos1, pos2, opts) end --- the offset of the character's first cell not included in the --- selection, otherwise all its cells are included. --- ---- Apart from the options supported by |getregion()|, {opts} also ---- supports the following: +--- To get the current visual selection: >vim +--- let region = getregionpos(getpos('v'), getpos('.')) +--- < +--- The {opts} Dict supports the following items: +--- +--- type See |getregion()|. +--- +--- exclusive See |getregion()|. --- --- eol If |TRUE|, indicate positions beyond --- the end of a line with "col" values diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 6fad0abde7..3e250b238e 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -3101,14 +3101,12 @@ end --- ---@param args vim.filetype.match.args Table specifying which matching strategy to use. --- Accepted keys are: ----@return string|nil # If a match was found, the matched filetype. ----@return function|nil # A function that modifies buffer state when called (for example, to set some ---- filetype specific buffer variables). The function accepts a buffer number as ---- its only argument. ----@return boolean|nil # Return true if a match was found by falling back to a generic configuration ---- file (i.e., ".conf"). If true, the filetype should be set with ---- `:setf FALLBACK conf`, which enables a later |:setf| command to override the ---- filetype. See `:help setf` for more information. +---@return string|nil # The matched filetype, if any. +---@return function|nil # A function `fun(buf: integer)` that modifies buffer state when called (for +--- example, to set some filetype specific buffer variables). +---@return boolean|nil # true if a match was found by falling back to a generic filetype +--- (i.e., ".conf"), which indicates the filetype should be set with +--- `:setf FALLBACK conf`. See |:setfiletype|. function M.match(args) vim.validate('arg', args, 'table') diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 1a3011e495..6773bb00ff 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -9,6 +9,15 @@ --- vim.print('file exists') --- end --- < +--- +--- *vim.fs.read()* +--- You can use |readblob()| to get a file's contents without explicitly opening/closing it. +--- +--- Example: +--- +--- >lua +--- vim.print(vim.fn.readblob('.git/config')) +--- < local uv = vim.uv diff --git a/runtime/lua/vim/keymap.lua b/runtime/lua/vim/keymap.lua index 2afb628267..0c40abadfc 100644 --- a/runtime/lua/vim/keymap.lua +++ b/runtime/lua/vim/keymap.lua @@ -30,6 +30,18 @@ local keymap = {} --- end, { expr = true }) --- -- Map "[%%" to a mapping: --- vim.keymap.set('n', '[%%', '(MatchitNormalMultiBackward)') +--- +--- -- Use `getregionpos(getpos('v'))` to get the "current visual selection": +--- vim.keymap.set('x', 'M', function() +--- local region = vim.fn.getregionpos(vim.fn.getpos('v'), vim.fn.getpos('.'), { +--- type = 'v', +--- exclusive = false, +--- eol = false, +--- }) +--- local line1 = region[1][1][2] +--- local line2 = region[#region][1][2] +--- vim.print({ line1, line2 }) +--- end) --- ``` --- ---@param mode string|string[] Mode "short-name" (see |nvim_set_keymap()|), or a list thereof. diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 47c41fc055..2583ab132f 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -4410,33 +4410,30 @@ M.funcs = { args = 1, base = 1, desc = [=[ - Get the position for String {expr}. - The accepted values for {expr} are: - . The cursor position. - $ The last line in the current buffer. + Gets a position, where {expr} is one of: + . Cursor position. + $ Last line in the current buffer. 'x Position of mark x (if the mark is not set, 0 is returned for all values). w0 First line visible in current window (one if the display isn't updated, e.g. in silent Ex mode). w$ Last line visible in current window (this is one less than "w0" if no lines are visible). - v When not in Visual mode, returns the cursor - position. In Visual mode, returns the other end - of the Visual area. A good way to think about - this is that in Visual mode "v" and "." complement - each other. While "." refers to the cursor - position, "v" refers to where |v_o| would move the - cursor. As a result, you can use "v" and "." - together to work on all of a selection in - characterwise Visual mode. If the cursor is at - the end of a characterwise Visual area, "v" refers - to the start of the same Visual area. And if the - cursor is at the start of a characterwise Visual - area, "v" refers to the end of the same Visual - area. "v" differs from |'<| and |'>| in that it's - updated right away. - Note that a mark in another file can be used. The line number - then applies to another buffer. + v End of the current Visual selection (unlike |'<| + |'>| which give the previous, not current, Visual + selection), or the cursor position if not in Visual + mode. + + To get the current selected region: >vim + let region = getregionpos(getpos('v'), getpos('.')) + < + Explanation: in Visual mode "v" and "." complement each + other. While "." refers to the cursor position, "v" + refers to where |v_o| would move the cursor. So you can + use "v" and "." together to get the selected region. + + Note that if a mark in another file is used, the line number + applies to that buffer. The result is a |List| with four numbers: [bufnum, lnum, col, off] @@ -4746,8 +4743,14 @@ M.funcs = { the offset of the character's first cell not included in the selection, otherwise all its cells are included. - Apart from the options supported by |getregion()|, {opts} also - supports the following: + To get the current visual selection: >vim + let region = getregionpos(getpos('v'), getpos('.')) + < + The {opts} Dict supports the following items: + + type See |getregion()|. + + exclusive See |getregion()|. eol If |TRUE|, indicate positions beyond the end of a line with "col" values diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 48e13ffc08..06edf4730d 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1153,7 +1153,7 @@ void ex_changes(exarg_T *eap) } \ } -// don't delete the line, just put at first deleted line +// "NO DELete": don't delete the line, just put at first deleted line. #define ONE_ADJUST_NODEL(add) \ { \ lp = add; \ diff --git a/test/functional/testnvim.lua b/test/functional/testnvim.lua index abb2ffd86c..58a76d8d06 100644 --- a/test/functional/testnvim.lua +++ b/test/functional/testnvim.lua @@ -1014,6 +1014,9 @@ function M.add_builddir_to_rtp() end --- Create folder with non existing parents +--- +--- TODO(justinmk): lift this and `t.mkdir()` into vim.fs. +--- --- @param path string --- @return boolean? function M.mkdir_p(path)