diff options
-rw-r--r-- | runtime/doc/motion.txt | 5 | ||||
-rw-r--r-- | runtime/doc/terminal.txt | 38 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 11 | ||||
-rw-r--r-- | src/nvim/terminal.c | 3 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 54 |
5 files changed, 69 insertions, 42 deletions
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/terminal.txt b/runtime/doc/terminal.txt index 99761c9c80..ea8a1c2565 100644 --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -187,26 +187,48 @@ event. The event is handled directly by Nvim and is not forwarded to plugins. OSC 133: shell integration *terminal-osc133* -Some shells will emit semantic escape sequences (OSC 133) to mark the -beginning and end of a prompt. The start of a prompt is marked with the -sequence `OSC 133 ; A`. Nvim can be configured to create signs in terminal -buffers marking shell prompts. Example: >lua +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('terminal_prompt_markers') + 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, { - -- Replace with sign text and highlight group of choice sign_text = '▶', sign_hl_group = 'SpecialChar', }) end end, }) - - -- Enable signcolumn in terminal buffers + -- Enable signcolumn in terminal buffers. vim.api.nvim_create_autocmd('TermOpen', { command = 'setlocal signcolumn=auto', }) diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index d1b83a6b4d..724a3d77e6 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -125,12 +125,11 @@ lua_State *get_global_lstate(void) return global_lstate; } -/// get error on top of stack as a string +/// Gets the Lua error at top of stack as a string, possibly modifying it in-place (but doesn't +/// change stack height). /// -/// Might alter the top value on stack in place (but doesn't change stack height) -/// -/// "error" points to memory on the lua stack, use -/// or duplicate the string before using "lstate" again +/// The returned string points to memory on the Lua stack. Use or duplicate it before using +/// `lstate` again. /// /// @param[out] len length of error (can be NULL) static const char *nlua_get_error(lua_State *lstate, size_t *len) @@ -147,7 +146,7 @@ static const char *nlua_get_error(lua_State *lstate, size_t *len) return lua_tolstring(lstate, -1, len); } -/// Convert lua error into a Vim error message +/// Converts a Lua error into a Vim error message. /// /// @param lstate Lua interpreter state. /// @param[in] msg Message base, must contain one `%.*s`. diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index ed757a63f9..2ca71e6dde 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -170,7 +170,8 @@ struct terminal { struct { int row, col; int shape; - bool visible; + bool visible; ///< Terminal wants to show cursor. + ///< `TerminalState.cursor_visible` indicates whether it is actually shown. bool blink; } cursor; diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 33dfae6b12..22c9e4658f 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -2526,7 +2526,7 @@ describe('LSP', function() ) end) - it('Supports file creation with CreateFile payload', function() + it('supports file creation with CreateFile payload', function() local tmpfile = tmpname(false) local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) local edit = { @@ -2544,7 +2544,7 @@ describe('LSP', function() end) it( - 'Supports file creation in folder that needs to be created with CreateFile payload', + 'supports file creation in folder that needs to be created with CreateFile payload', function() local tmpfile = tmpname(false) .. '/dummy/x/' local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) @@ -2647,7 +2647,7 @@ describe('LSP', function() describe('lsp.util.rename', function() local pathsep = n.get_pathsep() - it('Can rename an existing file', function() + it('can rename an existing file', function() local old = tmpname() write_file(old, 'Test content') local new = tmpname(false) @@ -2668,7 +2668,7 @@ describe('LSP', function() os.remove(new) end) - it('Can rename a directory', function() + it('can rename a directory', function() -- only reserve the name, file must not exist for the test scenario local old_dir = tmpname(false) local new_dir = tmpname(false) @@ -2695,7 +2695,7 @@ describe('LSP', function() os.remove(new_dir) end) - it('Does not touch buffers that do not match path prefix', function() + it('does not touch buffers that do not match path prefix', function() local old = tmpname(false) local new = tmpname(false) n.mkdir_p(old) @@ -2730,7 +2730,7 @@ describe('LSP', function() end) it( - 'Does not rename file if target exists and ignoreIfExists is set or overwrite is false', + 'does not rename file if target exists and ignoreIfExists is set or overwrite is false', function() local old = tmpname() write_file(old, 'Old File') @@ -2753,7 +2753,7 @@ describe('LSP', function() end ) - it('Maintains undo information for loaded buffer', function() + it('maintains undo information for loaded buffer', function() local old = tmpname() write_file(old, 'line') local new = tmpname(false) @@ -2777,7 +2777,7 @@ describe('LSP', function() eq(true, undo_kept) end) - it('Maintains undo information for unloaded buffer', function() + it('maintains undo information for unloaded buffer', function() local old = tmpname() write_file(old, 'line') local new = tmpname(false) @@ -2798,7 +2798,7 @@ describe('LSP', function() eq(true, undo_kept) end) - it('Does not rename file when it conflicts with a buffer without file', function() + it('does not rename file when it conflicts with a buffer without file', function() local old = tmpname() write_file(old, 'Old File') local new = tmpname(false) @@ -2817,7 +2817,7 @@ describe('LSP', function() eq('Old File', read_file(old)) end) - it('Does override target if overwrite is true', function() + it('does override target if overwrite is true', function() local old = tmpname() write_file(old, 'Old file') local new = tmpname() @@ -2833,7 +2833,7 @@ describe('LSP', function() end) describe('lsp.util.locations_to_items', function() - it('Convert Location[] to items', function() + it('convert Location[] to items', function() local expected_template = { { filename = '/fake/uri', @@ -2879,7 +2879,7 @@ describe('LSP', function() end end) - it('Convert LocationLink[] to items', function() + it('convert LocationLink[] to items', function() local expected = { { filename = '/fake/uri', @@ -2926,7 +2926,7 @@ describe('LSP', function() describe('lsp.util.symbols_to_items', function() describe('convert DocumentSymbol[] to items', function() - it('DocumentSymbol has children', function() + it('documentSymbol has children', function() local expected = { { col = 1, @@ -3047,7 +3047,7 @@ describe('LSP', function() ) end) - it('DocumentSymbol has no children', function() + it('documentSymbol has no children', function() local expected = { { col = 1, @@ -4387,7 +4387,7 @@ describe('LSP', function() end) describe('vim.lsp.buf.code_action', function() - it('Calls client side command if available', function() + it('calls client side command if available', function() local client --- @type vim.lsp.Client local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, @@ -4431,7 +4431,7 @@ describe('LSP', function() } end) - it('Calls workspace/executeCommand if no client side command', function() + it('calls workspace/executeCommand if no client side command', function() local client --- @type vim.lsp.Client local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, @@ -4472,7 +4472,7 @@ describe('LSP', function() }) end) - it('Filters and automatically applies action if requested', function() + it('filters and automatically applies action if requested', function() local client --- @type vim.lsp.Client local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, @@ -4547,7 +4547,7 @@ describe('LSP', function() } end) - it('Fallback to command execution on resolve error', function() + it('fallback to command execution on resolve error', function() clear() exec_lua(create_server_definition) local result = exec_lua(function() @@ -4592,7 +4592,7 @@ describe('LSP', function() eq('command:1', result[5].params.command) end) - it('Resolves command property', function() + it('resolves command property', function() clear() exec_lua(create_server_definition) local result = exec_lua(function() @@ -4639,14 +4639,14 @@ describe('LSP', function() end) describe('vim.lsp.commands', function() - it('Accepts only string keys', function() + it('accepts only string keys', function() matches( '.*The key for commands in `vim.lsp.commands` must be a string', pcall_err(exec_lua, 'vim.lsp.commands[1] = function() end') ) end) - it('Accepts only function values', function() + it('accepts only function values', function() matches( '.*Command added to `vim.lsp.commands` must be a function', pcall_err(exec_lua, 'vim.lsp.commands.dummy = 10') @@ -4880,7 +4880,7 @@ describe('LSP', function() end) describe('vim.lsp.buf.format', function() - it('Aborts with notify if no client matches filter', function() + it('aborts with notify if no client matches filter', function() local client --- @type vim.lsp.Client test_rpc_server { test_name = 'basic_init', @@ -4906,7 +4906,7 @@ describe('LSP', function() } end) - it('Sends textDocument/formatting request to format buffer', function() + it('sends textDocument/formatting request to format buffer', function() local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, { NIL, {}, { method = 'start', client_id = 1 } }, @@ -4940,7 +4940,7 @@ describe('LSP', function() } end) - it('Sends textDocument/rangeFormatting request to format a range', function() + it('sends textDocument/rangeFormatting request to format a range', function() local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, { NIL, {}, { method = 'start', client_id = 1 } }, @@ -4981,7 +4981,7 @@ describe('LSP', function() } end) - it('Sends textDocument/rangesFormatting request to format multiple ranges', function() + it('sends textDocument/rangesFormatting request to format multiple ranges', function() local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, { NIL, {}, { method = 'start', client_id = 1 } }, @@ -5028,7 +5028,7 @@ describe('LSP', function() } end) - it('Can format async', function() + it('can format async', function() local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, { NIL, {}, { method = 'start', client_id = 1 } }, @@ -5157,7 +5157,7 @@ describe('LSP', function() eq(expected_range, result[5].params.range) end) - it('Aborts with notify if no clients support requested method', function() + it('aborts with notify if no clients support requested method', function() exec_lua(create_server_definition) exec_lua(function() vim.notify = function(msg, _) |