diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7392eaf0c..630324e289 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,10 +36,11 @@ Reporting problems - Check `$NVIM_LOG_FILE`, if it exists. - Include `cmake --system-information` for build-related issues. -Pull requests ("PRs") +Pull requests (PRs) --------------------- - To avoid duplicate work, create a `[WIP]` pull request as soon as possible. +- Your PR must include **test coverage.** See [test/README.md][run-tests]. - Avoid cosmetic changes to unrelated files in the same commit. - Use a [feature branch][git-feature-branch] instead of the master branch. - Use a **rebase workflow** for small PRs. diff --git a/MAINTAIN.md b/MAINTAIN.md index ed0df76e36..55f4e7afc2 100644 --- a/MAINTAIN.md +++ b/MAINTAIN.md @@ -5,6 +5,15 @@ Notes on maintaining the Neovim project. See also: https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt +General guidelines +------------------ + +* Decide by cost-benefit +* Write down what was decided +* Constraints are good +* Use automation to solve problems +* Never break the API + Ticket Triage ------------- @@ -19,9 +28,9 @@ The forecasting problem might be solved with an explicit priority system (like Bram's todo.txt). Meanwhile the Neovim priority system is defined by: - PRs nearing completion (RDY). -- Issue labels. E.g. the +plan label increases the ticket's priority merely for - having a plan written down: it is _closer to completion_ than tickets without - a plan. +- Issue labels. E.g. the `+plan` label increases the ticket's priority merely + for having a plan written down: it is _closer to completion_ than tickets + without a plan. - Comment activity or new information. Anything that isn't in the next milestone, and doesn't have a RDY PR ... is @@ -32,17 +41,17 @@ full :) Release Policy -------------- -The goal is "early and often". +Release "often", but not "early". -Up to now we use only one branch, the `master` branch. +The (unreleased) `master` branch is the "early" channel; it should not be +released if it's not stable. Medium-risk changes may be merged to `master` if +the next feature-release is not imminent. -- If `master` is unstable we don't release. -- If the last release has a major bug, we: - 1. Fix the bug on `master`. - 2. Disable or remove any known risks present on `master`. - 3. Cut a release from `master`. +For maintenance releases, create a `release-x.y` branch. If the current stable +release has a major bug: -This is a bit silly, but it works ok. And it keeps `master` from biting off -more feature-creep than it can chew. +1. Fix the bug on `master`. +2. Cherry-pick the fix to `release-x.y`. +3. Cut a release from `release-x.y` (run `scripts/release.sh`). See also: https://github.com/neovim/neovim/issues/862 diff --git a/README.md b/README.md index 4adb14322c..21b3a7ac6f 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,10 @@ Features -------- - Modern [GUIs](https://github.com/neovim/neovim/wiki/Related-projects#gui) -- [API](https://github.com/neovim/neovim/wiki/Related-projects#api-clients) - access from any language including Clojure, Lisp, Go, Haskell, Lua, - JavaScript, Perl, Python, Ruby, and Rust +- [API access](https://github.com/neovim/neovim/wiki/Related-projects#api-clients) + from any language including C/C++, C#, Clojure, D, Elixir, Lisp, Go, + Haskell, Java, JavaScript/Node.js, Julia, Lisp, Lua, Perl, Python, Racket, + Ruby, Rust - Embedded, scriptable [terminal emulator](https://neovim.io/doc/user/nvim_terminal_emulator.html) - Asynchronous [job control](https://github.com/neovim/neovim/pull/2247) - [Shared data (shada)](https://github.com/neovim/neovim/pull/2506) among multiple editor instances diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index cdf6a8b92b..1d2764b9ee 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -289,6 +289,11 @@ nvim_input({keys}) *nvim_input()* |keycodes| like are translated, so "<" is special. To input a literal "<", send . + Note: + For mouse events use |nvim_input_mouse()|. The pseudokey + form "" is deprecated since |api- + level| 6. + Attributes: ~ {async} @@ -299,6 +304,43 @@ nvim_input({keys}) *nvim_input()* Number of bytes actually written (can be fewer than requested if the buffer becomes full). + *nvim_input_mouse()* +nvim_input_mouse({button}, {action}, {modifier}, {grid}, {row}, {col}) + Send mouse event from GUI. + + The call is non-blocking. It doesn't wait on any resulting + action, but queues the event to be processed soon by the event + loop. + + Note: + Currently this doesn't support "scripting" multiple mouse + events by calling it multiple times in a loop: the + intermediate mouse positions will be ignored. It should be + used to implement real-time mouse input in a GUI. The + deprecated pseudokey form ("") of + |nvim_input()| has the same limitiation. + + Attributes: ~ + {async} + + Parameters: ~ + {button} Mouse button: one of "left", "right", + "middle", "wheel". + {action} For ordinary buttons, one of "press", "drag", + "release". For the wheel, one of "up", "down", + "left", "right". + {modifier} String of modifiers each represented by a + single char. The same specifiers are used as + for a key press, except that the "-" separator + is optional, so "C-A-", "c-a" and "CA" can all + be used to specify Ctrl+Alt+click. + {grid} Grid number if the client uses |ui-multigrid|, + else 0. + {row} Mouse row-position (zero-based, like redraw + events) + {col} Mouse column-position (zero-based, like redraw + events) + *nvim_replace_termcodes()* nvim_replace_termcodes({str}, {from_part}, {do_lt}, {special}) Replaces terminal codes and |keycodes| (, , ...) in a @@ -400,7 +442,7 @@ nvim_set_current_dir({dir}) *nvim_set_current_dir()* {dir} Directory path nvim_get_current_line() *nvim_get_current_line()* - Gets the current line + Gets the current line. Parameters: ~ @@ -408,18 +450,18 @@ nvim_get_current_line() *nvim_get_current_line()* Current line string nvim_set_current_line({line}) *nvim_set_current_line()* - Sets the current line + Sets the current line. Parameters: ~ {line} Line contents nvim_del_current_line() *nvim_del_current_line()* - Deletes the current line + Deletes the current line. Parameters: ~ nvim_get_var({name}) *nvim_get_var()* - Gets a global (g:) variable + Gets a global (g:) variable. Parameters: ~ {name} Variable name @@ -428,20 +470,20 @@ nvim_get_var({name}) *nvim_get_var()* Variable value nvim_set_var({name}, {value}) *nvim_set_var()* - Sets a global (g:) variable + Sets a global (g:) variable. Parameters: ~ {name} Variable name {value} Variable value nvim_del_var({name}) *nvim_del_var()* - Removes a global (g:) variable + Removes a global (g:) variable. Parameters: ~ {name} Variable name nvim_get_vvar({name}) *nvim_get_vvar()* - Gets a v: variable + Gets a v: variable. Parameters: ~ {name} Variable name @@ -449,8 +491,15 @@ nvim_get_vvar({name}) *nvim_get_vvar()* Return: ~ Variable value +nvim_set_vvar({name}, {value}) *nvim_set_vvar()* + Sets a v: variable, if it is not readonly. + + Parameters: ~ + {name} Variable name + {value} Variable value + nvim_get_option({name}) *nvim_get_option()* - Gets an option value string + Gets an option value string. Parameters: ~ {name} Option name @@ -459,7 +508,7 @@ nvim_get_option({name}) *nvim_get_option()* Option value (global) nvim_set_option({name}, {value}) *nvim_set_option()* - Sets an option value + Sets an option value. Parameters: ~ {name} Option name @@ -498,55 +547,55 @@ nvim_list_bufs() *nvim_list_bufs()* List of buffer handles nvim_get_current_buf() *nvim_get_current_buf()* - Gets the current buffer + Gets the current buffer. Return: ~ Buffer handle nvim_set_current_buf({buffer}) *nvim_set_current_buf()* - Sets the current buffer + Sets the current buffer. Parameters: ~ {buffer} Buffer handle nvim_list_wins() *nvim_list_wins()* - Gets the current list of window handles + Gets the current list of window handles. Return: ~ List of window handles nvim_get_current_win() *nvim_get_current_win()* - Gets the current window + Gets the current window. Return: ~ Window handle nvim_set_current_win({window}) *nvim_set_current_win()* - Sets the current window + Sets the current window. Parameters: ~ {window} Window handle nvim_list_tabpages() *nvim_list_tabpages()* - Gets the current list of tabpage handles + Gets the current list of tabpage handles. Return: ~ List of tabpage handles nvim_get_current_tabpage() *nvim_get_current_tabpage()* - Gets the current tabpage + Gets the current tabpage. Return: ~ Tabpage handle nvim_set_current_tabpage({tabpage}) *nvim_set_current_tabpage()* - Sets the current tabpage + Sets the current tabpage. Parameters: ~ {tabpage} Tabpage handle nvim_create_namespace({name}) *nvim_create_namespace()* - Creates a new namespace, or gets an existing one + Creates a new namespace, or gets an existing one. Namespaces are used for buffer highlights and virtual text, see |nvim_buf_add_highlight()| and @@ -563,19 +612,19 @@ nvim_create_namespace({name}) *nvim_create_namespace()* Namespace id nvim_get_namespaces() *nvim_get_namespaces()* - Gets existing, non-anonymous namespaces + Gets existing, non-anonymous namespaces. Return: ~ dict that maps from names to namespace ids. nvim_subscribe({event}) *nvim_subscribe()* - Subscribes to event broadcasts + Subscribes to event broadcasts. Parameters: ~ {event} Event type string nvim_unsubscribe({event}) *nvim_unsubscribe()* - Unsubscribes to event broadcasts + Unsubscribes to event broadcasts. Parameters: ~ {event} Event type string @@ -724,7 +773,7 @@ nvim_call_atomic({calls}) *nvim_call_atomic()* *nvim_parse_expression()* nvim_parse_expression({expr}, {flags}, {highlight}) - Parse a VimL expression + Parse a VimL expression. Attributes: ~ {async} @@ -801,7 +850,7 @@ nvim_parse_expression({expr}, {flags}, {highlight}) "SingleQuotedString" and "DoubleQuotedString" nodes. nvim__id({obj}) *nvim__id()* - Returns object given as argument + Returns object given as argument. This API function is used for testing. One should not rely on its presence in plugins. @@ -813,7 +862,7 @@ nvim__id({obj}) *nvim__id()* its argument. nvim__id_array({arr}) *nvim__id_array()* - Returns array given as argument + Returns array given as argument. This API function is used for testing. One should not rely on its presence in plugins. @@ -825,7 +874,7 @@ nvim__id_array({arr}) *nvim__id_array()* its argument. nvim__id_dictionary({dct}) *nvim__id_dictionary()* - Returns dictionary given as argument + Returns dictionary given as argument. This API function is used for testing. One should not rely on its presence in plugins. @@ -837,7 +886,7 @@ nvim__id_dictionary({dct}) *nvim__id_dictionary()* its argument. nvim__id_float({flt}) *nvim__id_float()* - Returns floating-point value given as argument + Returns floating-point value given as argument. This API function is used for testing. One should not rely on its presence in plugins. @@ -874,6 +923,26 @@ nvim_get_proc({pid}) *nvim_get_proc()* Return: ~ Map of process properties, or NIL if process not found. + *nvim_select_popupmenu_item()* +nvim_select_popupmenu_item({item}, {insert}, {finish}, {opts}) + Selects an item in the completion popupmenu. + + If |ins-completion| is not active this API call is silently + ignored. Useful for an external UI using |ui-popupmenu| to + control the popupmenu with the mouse. Can also be used in a + mapping; use |:map-cmd| to ensure the mapping doesn't + end completion mode. + + Parameters: ~ + {item} Index (zero-based) of the item to select. Value + of -1 selects nothing and restores the original + text. + {insert} Whether the selection should be inserted in the + buffer. + {finish} Finish the completion and dismiss the popupmenu. + Implies `insert`. + {opts} Optional parameters. Reserved for future use. + nvim__inspect_cell({row}, {col}) *nvim__inspect_cell()* TODO: Documentation @@ -914,7 +983,8 @@ nvim_buf_attach({buffer}, {send_buffer}, {opts}) *nvim_buf_attach()* `nvim_buf_lines_event`. Otherwise, the first notification will be a `nvim_buf_changedtick_event` - {opts} Optional parameters. Currently not used. + {opts} Optional parameters. Reserved for future + use. Return: ~ False when updates couldn't be enabled because the buffer @@ -1447,4 +1517,17 @@ nvim_ui_try_resize({width}, {height}) *nvim_ui_try_resize()* nvim_ui_set_option({name}, {value}) *nvim_ui_set_option()* TODO: Documentation + *nvim_ui_try_resize_grid()* +nvim_ui_try_resize_grid({grid}, {width}, {height}) + Tell Nvim to resize a grid. Triggers a grid_resize event with + the requested grid size or the maximum size if it exceeds size + limits. + + On invalid grid handle, fails with error. + + Parameters: ~ + {grid} The handle of the grid to be changed. + {width} The new requested width. + {height} The new requested height. + vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt index e244072c66..4b1cbe2cce 100644 --- a/runtime/doc/develop.txt +++ b/runtime/doc/develop.txt @@ -4,7 +4,7 @@ NVIM REFERENCE MANUAL -Development of Nvim *development* +Development of Nvim *development* *dev* This reference describes design constraints and guidelines, for developing Nvim applications or Nvim itself. @@ -79,7 +79,7 @@ include the kitchen sink... but it's good for plumbing." ============================================================================== -Developer guidelines *dev* +Developer guidelines *dev-guidelines* PROVIDERS *dev-provider* @@ -209,10 +209,12 @@ Examples of API-client package names: Implementation ~ -Consider using libmpack instead of the msgpack.org C/C++ library. libmpack is -small (can be inlined into your C/C++ project) and efficient (no allocations). -It also implements msgpack-RPC. -https://github.com/libmpack/libmpack/ +For C/C++ projects, consider libmpack instead of the msgpack.org library. + https://github.com/libmpack/libmpack/ +libmpack is small (no dependencies, can inline into your C/C++ project) and +efficient (no allocations). It also implements msgpack-RPC, the protocol +required by Nvim. + https://github.com/msgpack-rpc/msgpack-rpc EXTERNAL UI *dev-ui* diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt index 06609a77e1..f8c7693d45 100644 --- a/runtime/doc/gui.txt +++ b/runtime/doc/gui.txt @@ -29,25 +29,6 @@ When the GUI starts up initializations are carried out, in this order: The path names are truncated to 35 characters. You can truncate them at a different length, for example 50, like this: > :let bmenu_max_pathlen = 50 -- If the "-U {gvimrc}" command-line option has been used when starting Vim, - the {gvimrc} file will be read for initializations. The following - initializations are skipped. When {gvimrc} is "NONE" no file will be read - for initializations. -- For Unix and MS-Windows, if the system gvimrc exists, it is sourced. The - name of this file is normally "$VIM/ginit.vim". You can check this with - ":version". Also see |$VIM|. -- The following are tried, and only the first one that exists is used: - - If the GVIMINIT environment variable exists and is not empty, it is - executed as an Ex command. - - If the user gvimrc file exists, it is sourced. The name of this file is - normally "$XDG_CONFIG_HOME/nvim/ginit.vim" ($XDG_CONFIG_HOME defaults to - ~/.config). - The name of the first file found is stored in $MYGVIMRC, unless it was - already set. - -NOTE: All but the first one are not carried out if Vim was started with -"-u NONE" or "-u DEFAULTS" and no "-U" argument was given, or when started -with "-U NONE". All this happens AFTER the normal Vim initializations, like reading your vimrc file. See |initialization|. @@ -55,17 +36,7 @@ But the GUI window is only opened after all the initializations have been carried out. If you want some commands to be executed just after opening the GUI window, use the |GUIEnter| autocommand event. Example: > :autocmd GUIEnter * winpos 100 50 - -You can use the gvimrc files to set up your own customized menus (see |:menu|) -and initialize other things that you may want to set up differently from the -terminal version. - -Recommended place for your personal GUI initializations: - Unix $XDG_CONFIG_HOME/.config/nvim/ginit.vim - (default for $XDG_CONFIG_HOME is ~/.config) - -The personal initialization files are searched in the order specified above -and only the first one that is found is read. +< *:winp* *:winpos* *E188* :winp[os] diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt index 97bbb34078..c36aeffa1a 100644 --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -4,10 +4,31 @@ NVIM REFERENCE MANUAL -Lua Interface to Nvim *lua* *Lua* +Lua engine *lua* *Lua* Type |gO| to see the table of contents. +============================================================================== +Introduction *lua-intro* + +The Lua 5.1 language is builtin and always available. Try this command to get +an idea of what lurks beneath: > + + :lua print(vim.inspect(package.loaded)) + +Nvim includes a "standard library" |lua-stdlib| for Lua. This library +complements the Nvim editor |functions| and Ex commands (the editor "stdlib"), +which can also be used from Lua code. + +Nvim resolves module conflicts by "last wins". For example if both of these +are on 'runtimepath': + runtime/lua/foo.lua + ~/.config/nvim/lua/foo.lua +then `require('foo')` loads "~/.config/nvim/lua/foo.lua", and +"runtime/lua/foo.lua" is not used. See |lua-require| to understand how Nvim +finds and loads Lua modules. The conventions are similar to VimL plugins, +with some extra features. See |lua-require-example| for a walkthrough. + ============================================================================== Importing modules *lua-require* @@ -54,25 +75,27 @@ The result will look like this: = `/foo/bar/lua/?.so;/foo/bar/lua/a?d/j/g.elf;/abc/lua/?.so;/abc/lua/a?d/j/g.elf;./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` -Note: to keep up with 'runtimepath' updates paths added at previous update are -remembered and removed at the next update, while all paths derived from the -new 'runtimepath' are prepended as described above. This allows removing -paths when path is removed from 'runtimepath', adding paths when they are -added and reordering `package.path`/`package.cpath` content if 'runtimepath' -was reordered. +Note: -Note 2: even though adjustments happens automatically Nvim does not track -current values of `package.path` or `package.cpath`. If you happened to -delete some paths from there you need to reset 'runtimepath' to make them -readded. Just running `let &runtimepath = &runtimepath` should work. +- To track 'runtimepath' updates, paths added at previous update are + remembered and removed at the next update, while all paths derived from the + new 'runtimepath' are prepended as described above. This allows removing + paths when path is removed from 'runtimepath', adding paths when they are + added and reordering `package.path`/`package.cpath` content if 'runtimepath' + was reordered. -Note 3: skipping paths from 'runtimepath' which contain semicolons applies -both to `package.path` and `package.cpath`. Given that there is a number of -badly written plugins using shell which will not work with paths containing -semicolons it is better to not have them in 'runtimepath' at all. +- Although adjustments happen automatically, Nvim does not track current + values of `package.path` or `package.cpath`. If you happen to delete some + paths from there you can set 'runtimepath' to trigger an update: > + let &runtimepath = &runtimepath + +- Skipping paths from 'runtimepath' which contain semicolons applies both to + `package.path` and `package.cpath`. Given that there are some badly written + plugins using shell which will not work with paths containing semicolons it + is better to not have them in 'runtimepath' at all. ------------------------------------------------------------------------------ -Example of a plugin that uses lua modules *lua-require-example* +LUA PLUGIN EXAMPLE *lua-require-example* The following example plugin adds a command `:MakeCharBlob` which transforms current buffer into a long `unsigned char` array. Lua contains transformation @@ -83,70 +106,70 @@ this case `lua/charblob.lua` means `~/.config/nvim/lua/charblob.lua`). autoload/charblob.vim: > - function charblob#encode_buffer() - call setline(1, luaeval( - \ 'require("charblob").encode(unpack(_A))', - \ [getline(1, '$'), &textwidth, ' '])) - endfunction + function charblob#encode_buffer() + call setline(1, luaeval( + \ 'require("charblob").encode(unpack(_A))', + \ [getline(1, '$'), &textwidth, ' '])) + endfunction plugin/charblob.vim: > - if exists('g:charblob_loaded') - finish - endif - let g:charblob_loaded = 1 + if exists('g:charblob_loaded') + finish + endif + let g:charblob_loaded = 1 - command MakeCharBlob :call charblob#encode_buffer() + command MakeCharBlob :call charblob#encode_buffer() lua/charblob.lua: > - local function charblob_bytes_iter(lines) - local init_s = { - next_line_idx = 1, - next_byte_idx = 1, - lines = lines, - } - local function next(s, _) - if lines[s.next_line_idx] == nil then - return nil - end - if s.next_byte_idx > #(lines[s.next_line_idx]) then - s.next_line_idx = s.next_line_idx + 1 - s.next_byte_idx = 1 - return ('\n'):byte() - end - local ret = lines[s.next_line_idx]:byte(s.next_byte_idx) - if ret == ('\n'):byte() then - ret = 0 -- See :h NL-used-for-NUL. - end - s.next_byte_idx = s.next_byte_idx + 1 - return ret - end - return next, init_s, nil - end + local function charblob_bytes_iter(lines) + local init_s = { + next_line_idx = 1, + next_byte_idx = 1, + lines = lines, + } + local function next(s, _) + if lines[s.next_line_idx] == nil then + return nil + end + if s.next_byte_idx > #(lines[s.next_line_idx]) then + s.next_line_idx = s.next_line_idx + 1 + s.next_byte_idx = 1 + return ('\n'):byte() + end + local ret = lines[s.next_line_idx]:byte(s.next_byte_idx) + if ret == ('\n'):byte() then + ret = 0 -- See :h NL-used-for-NUL. + end + s.next_byte_idx = s.next_byte_idx + 1 + return ret + end + return next, init_s, nil + end - local function charblob_encode(lines, textwidth, indent) - local ret = { - 'const unsigned char blob[] = {', - indent, - } - for byte in charblob_bytes_iter(lines) do - -- .- space + number (width 3) + comma - if #(ret[#ret]) + 5 > textwidth then - ret[#ret + 1] = indent - else - ret[#ret] = ret[#ret] .. ' ' - end - ret[#ret] = ret[#ret] .. (('%3u,'):format(byte)) - end - ret[#ret + 1] = '};' - return ret - end + local function charblob_encode(lines, textwidth, indent) + local ret = { + 'const unsigned char blob[] = {', + indent, + } + for byte in charblob_bytes_iter(lines) do + -- .- space + number (width 3) + comma + if #(ret[#ret]) + 5 > textwidth then + ret[#ret + 1] = indent + else + ret[#ret] = ret[#ret] .. ' ' + end + ret[#ret] = ret[#ret] .. (('%3u,'):format(byte)) + end + ret[#ret + 1] = '};' + return ret + end - return { - bytes_iter = charblob_bytes_iter, - encode = charblob_encode, - } + return { + bytes_iter = charblob_bytes_iter, + encode = charblob_encode, + } ============================================================================== Commands *lua-commands* @@ -157,13 +180,13 @@ Commands *lua-commands* Examples: > - :lua vim.api.nvim_command('echo "Hello, Nvim!"') + :lua vim.api.nvim_command('echo "Hello, Nvim!"') < To see the Lua version: > - :lua print(_VERSION) + :lua print(_VERSION) To see the LuaJIT version: > - :lua print(jit.version) + :lua print(jit.version) < :[range]lua << {endmarker} @@ -179,15 +202,15 @@ in Vim scripts. Example: > - function! CurrentLineInfo() - lua << EOF - local linenr = vim.api.nvim_win_get_cursor(0)[1] - local curline = vim.api.nvim_buf_get_lines( - 0, linenr, linenr + 1, false)[1] - print(string.format("Current line [%d] has %d bytes", - linenr, #curline)) - EOF - endfunction + function! CurrentLineInfo() + lua << EOF + local linenr = vim.api.nvim_win_get_cursor(0)[1] + local curline = vim.api.nvim_buf_get_lines( + 0, linenr, linenr + 1, false)[1] + print(string.format("Current line [%d] has %d bytes", + linenr, #curline)) + EOF + endfunction Note that the `local` variables will disappear when block finishes. This is not the case for globals. @@ -203,12 +226,12 @@ not the case for globals. Examples: > - :luado return string.format("%s\t%d", line:reverse(), #line) + :luado return string.format("%s\t%d", line:reverse(), #line) - :lua require"lpeg" - :lua -- balanced parenthesis grammar: - :lua bp = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" } - :luado if bp:match(line) then return "-->\t" .. line end + :lua require"lpeg" + :lua -- balanced parenthesis grammar: + :lua bp = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" } + :luado if bp:match(line) then return "-->\t" .. line end < *:luafile* @@ -218,8 +241,8 @@ Examples: Examples: > - :luafile script.lua - :luafile % + :luafile script.lua + :luafile % < All these commands execute a Lua chunk from either the command line (:lua and @@ -235,21 +258,48 @@ position are restricted when the command is executed in the |sandbox|. ============================================================================== -The vim module *lua-vim* +vim.* *lua-vim* *lua-stdlib* -Lua interfaces Nvim through the "vim" module. Currently it has the `api` -submodule and some Nvim-specific utilities. +The "standard library" (stdlib) of Nvim Lua is the `vim` module, which exposes +various functions and sub-modules. The module is implicitly loaded, thus +require("vim") is unnecessary. + +You can peek at the module properties: > + + :lua print(vim.inspect(vim)) + +Result is something like this: > + + { + _os_proc_children = , + _os_proc_info = , + ... + api = { + nvim__id = , + nvim__id_array = , + ... + }, + deepcopy = , + gsplit = , + ... + } + +To find documentation on e.g. the "deepcopy" function: > + + :help vim.deepcopy + +Note: Underscore-prefixed functions (e.g. "_os_proc_children") are +internal/private and must not be used by plugins. ------------------------------------------------------------------------------ vim.api.* functions -`vim.api` exposes the Nvim |API| as a table of Lua functions. All functions -are available. +`vim.api` exposes the full Nvim |API| as a table of Lua functions. For example, to use the "nvim_get_current_line()" API function, call "vim.api.nvim_get_current_line()": > - print(tostring(vim.api.nvim_get_current_line())) + print(tostring(vim.api.nvim_get_current_line())) ------------------------------------------------------------------------------ vim.* builtin functions @@ -311,10 +361,10 @@ vim.type_idx *lua-vim.type_idx* vim.val_idx *lua-vim.val_idx* Value index for tables representing |Float|s. A table representing floating-point value 1.0 looks like this: > - { - [vim.type_idx] = vim.types.float, - [vim.val_idx] = 1.0, - } + { + [vim.type_idx] = vim.types.float, + [vim.val_idx] = 1.0, + } < See also |lua-vim.type_idx| and |lua-special-tbl|. vim.types *lua-vim.types* @@ -346,8 +396,9 @@ vim.inspect({object}, {options}) *vim.inspect* Return a human-readable representation of the passed object. See https://github.com/kikito/inspect.lua for details and possible options. + ============================================================================== -The luaeval function *lua-luaeval* *lua-eval* +luaeval() *lua-luaeval* *lua-eval* *luaeval()* The (dual) equivalent of "vim.eval" for passing Lua values to Nvim is @@ -355,11 +406,11 @@ The (dual) equivalent of "vim.eval" for passing Lua values to Nvim is for _A inside expression and returns the result of the expression. It is semantically equivalent in Lua to: > - local chunkheader = "local _A = select(1, ...) return " - function luaeval (expstr, arg) - local chunk = assert(loadstring(chunkheader .. expstr, "luaeval")) - return chunk(arg) -- return typval - end + local chunkheader = "local _A = select(1, ...) return " + function luaeval (expstr, arg) + local chunk = assert(loadstring(chunkheader .. expstr, "luaeval")) + return chunk(arg) -- return typval + end Lua nils, numbers, strings, tables and booleans are converted to their respective VimL types. An error is thrown if conversion of any other Lua types @@ -368,10 +419,10 @@ is attempted. The magic global "_A" contains the second argument to luaeval(). Example: > - :echo luaeval('_A[1] + _A[2]', [40, 2]) - 42 - :echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123') - foo + :echo luaeval('_A[1] + _A[2]', [40, 2]) + 42 + :echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123') + foo Lua tables are used as both dictionaries and lists, so it is impossible to determine whether empty table is meant to be empty list or empty dictionary. @@ -405,11 +456,11 @@ cases there is the following agreement: Examples: > - :echo luaeval('math.pi') - :function Rand(x,y) " random uniform between x and y - : return luaeval('(_A.y-_A.x)*math.random()+_A.x', {'x':a:x,'y':a:y}) - : endfunction - :echo Rand(1,10) + :echo luaeval('math.pi') + :function Rand(x,y) " random uniform between x and y + : return luaeval('(_A.y-_A.x)*math.random()+_A.x', {'x':a:x,'y':a:y}) + : endfunction + :echo Rand(1,10) Note that currently second argument to `luaeval` undergoes VimL to lua conversion, so changing containers in lua do not affect values in VimL. Return @@ -417,4 +468,4 @@ value is also always converted. When converting, |msgpack-special-dict|s are treated specially. ============================================================================== - vim:tw=78:ts=8:noet:ft=help:norl: + vim:tw=78:ts=8:et:ft=help:norl: diff --git a/runtime/doc/if_pyth.txt b/runtime/doc/if_pyth.txt index df4b54ef76..ac725a9b5d 100644 --- a/runtime/doc/if_pyth.txt +++ b/runtime/doc/if_pyth.txt @@ -11,7 +11,7 @@ See |provider-python| for more information. Type |gO| to see the table of contents. ============================================================================== -1. Commands *python-commands* +Commands *python-commands* *:python* *:py* *E263* *E264* *E887* :[range]py[thon] {stmt} @@ -44,10 +44,10 @@ Example: > To see what version of Python you have: > :python print(sys.version) -There is no need to import sys, it's done by default. +There is no need to "import sys", it's done by default. -Note: Python is very sensitive to the indenting. Make sure the "class" line -and "EOF" do not have any indent. +Note: Python is very sensitive to indenting. Make sure the "class" line and +"EOF" do not have any indent. *:pydo* :[range]pydo {body} Execute Python function "def _vim_pydo(line, linenr): @@ -103,8 +103,8 @@ Here are some examples *python-examples* > :python print "Hello" :python str = current.buffer[42] -(Note that changes - like the imports - persist from one command to the next, -just like in the Python interpreter.) +Note that changes (such as the "import" statements) persist from one command +to the next, just like the Python REPL. *script-here* When using a script language in-line, you might want to skip this when the @@ -130,7 +130,7 @@ Instead, put the Python command in a function and call that function: Note that "EOF" must be at the start of the line. ============================================================================== -2. The vim module *python-vim* *python2* +The vim module *python-vim* *python2* Python code gets all of its access to vim (with one exception - see |python-output| below) via the "vim" module. The vim module implements two @@ -189,11 +189,6 @@ vim.eval(str) *python-eval* # string.atoi() to convert to # a number. -vim.bindeval(str) *python-bindeval* - Like |python-eval|, but returns special objects described in - |python-bindeval-objects|. These python objects let you modify (|List| - or |Dictionary|) or call (|Funcref|) vim objects. - vim.strwidth(str) *python-strwidth* Like |strwidth()|: returns number of display cells str occupies, tab is counted as one cell. @@ -291,8 +286,7 @@ vim.current *python-current* vim.vars *python-vars* vim.vvars *python-vvars* Dictionary-like objects holding dictionaries with global (|g:|) and - vim (|v:|) variables respectively. Identical to `vim.bindeval("g:")`, - but faster. + vim (|v:|) variables respectively. vim.options *python-options* Object partly supporting mapping protocol (supports setting and @@ -407,7 +401,7 @@ vim._get_paths *python-_get_paths* {rtp}/pythonx directories for each {rtp} in 'runtimepath'. ============================================================================== -3. Buffer objects *python-buffer* +Buffer objects *python-buffer* Buffer objects represent vim buffers. You can obtain them in a number of ways: - via vim.current.buffer (|python-current|) @@ -485,7 +479,7 @@ Examples (assume b is the current buffer) > :py del b.options["ar"] # same as :set autoread< ============================================================================== -4. Range objects *python-range* +Range objects *python-range* Range objects represent a part of a vim buffer. You can obtain them in a number of ways: @@ -517,7 +511,7 @@ Example (assume r is the current range): vim.command("%d,%dhardcopy!" % (r.start+1,r.end+1)) ============================================================================== -5. Window objects *python-window* +Window objects *python-window* Window objects represent vim windows. You can obtain them in a number of ways: - via vim.current.window (|python-current|) @@ -561,7 +555,7 @@ The width attribute is writable only if the screen is split vertically. Window object type is available using "Window" attribute of vim module. ============================================================================== -6. Tab page objects *python-tabpage* +Tab page objects *python-tabpage* Tab page objects represent vim tab pages. You can obtain them in a number of ways: @@ -583,119 +577,14 @@ Tab page attributes are: TabPage object type is available using "TabPage" attribute of vim module. ============================================================================== -7. vim.bindeval objects *python-bindeval-objects* - -vim.Dictionary object *python-Dictionary* - Dictionary-like object providing access to vim |Dictionary| type. - Attributes: - Attribute Description ~ - locked One of *python-.locked* - Value Description ~ - zero Variable is not locked - vim.VAR_LOCKED Variable is locked, but can be unlocked - vim.VAR_FIXED Variable is locked and can't be unlocked - Read-write. You can unlock locked variable by assigning - `True` or `False` to this attribute. No recursive locking - is supported. - scope One of - Value Description ~ - zero Dictionary is not a scope one - vim.VAR_DEF_SCOPE |g:| or |l:| dictionary - vim.VAR_SCOPE Other scope dictionary, - see |internal-variables| - Methods (note: methods do not support keyword arguments): - Method Description ~ - keys() Returns a list with dictionary keys. - values() Returns a list with dictionary values. - items() Returns a list of 2-tuples with dictionary contents. - update(iterable), update(dictionary), update(**kwargs) - Adds keys to dictionary. - get(key[, default=None]) - Obtain key from dictionary, returning the default if it is - not present. - pop(key[, default]) - Remove specified key from dictionary and return - corresponding value. If key is not found and default is - given returns the default, otherwise raises KeyError. - popitem() - Remove random key from dictionary and return (key, value) - pair. - has_key(key) - Check whether dictionary contains specified key, similar - to `key in dict`. - - __new__(), __new__(iterable), __new__(dictionary), __new__(update) - You can use `vim.Dictionary()` to create new vim - dictionaries. `d=vim.Dictionary(arg)` is the same as - `d=vim.bindeval('{}');d.update(arg)`. Without arguments - constructs empty dictionary. - - Examples: > - d = vim.Dictionary(food="bar") # Constructor - d['a'] = 'b' # Item assignment - print d['a'] # getting item - d.update({'c': 'd'}) # .update(dictionary) - d.update(e='f') # .update(**kwargs) - d.update((('g', 'h'), ('i', 'j'))) # .update(iterable) - for key in d.keys(): # .keys() - for val in d.values(): # .values() - for key, val in d.items(): # .items() - print isinstance(d, vim.Dictionary) # True - for key in d: # Iteration over keys - class Dict(vim.Dictionary): # Subclassing -< - Note: when iterating over keys you should not modify dictionary. - -vim.List object *python-List* - Sequence-like object providing access to vim |List| type. - Supports `.locked` attribute, see |python-.locked|. Also supports the - following methods: - Method Description ~ - extend(item) Add items to the list. - - __new__(), __new__(iterable) - You can use `vim.List()` to create new vim lists. - `l=vim.List(iterable)` is the same as - `l=vim.bindeval('[]');l.extend(iterable)`. Without - arguments constructs empty list. - Examples: > - l = vim.List("abc") # Constructor, result: ['a', 'b', 'c'] - l.extend(['abc', 'def']) # .extend() method - print l[1:] # slicing - l[:0] = ['ghi', 'jkl'] # slice assignment - print l[0] # getting item - l[0] = 'mno' # assignment - for i in l: # iteration - print isinstance(l, vim.List) # True - class List(vim.List): # Subclassing - -vim.Function object *python-Function* - Function-like object, acting like vim |Funcref| object. Supports `.name` - attribute and is callable. Accepts special keyword argument `self`, see - |Dictionary-function|. You can also use `vim.Function(name)` constructor, - it is the same as `vim.bindeval('function(%s)'%json.dumps(name))`. - - Examples: > - f = vim.Function('tr') # Constructor - print f('abc', 'a', 'b') # Calls tr('abc', 'a', 'b') - vim.command(''' - function DictFun() dict - return self - endfunction - ''') - f = vim.bindeval('function("DictFun")') - print f(self={}) # Like call('DictFun', [], {}) - print isinstance(f, vim.Function) # True - -============================================================================== -8. pyeval() and py3eval() Vim functions *python-pyeval* +pyeval() and py3eval() Vim functions *python-pyeval* To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()| functions to evaluate Python expressions and pass their values to Vim script. |pyxeval()| is also available. ============================================================================== -9. Python 3 *python3* +Python 3 *python3* *:py3* *:python3* The `:py3` and `:python3` commands work similar to `:python`. A simple check @@ -724,7 +613,7 @@ You can test what Python version is available with: > endif ============================================================================== -10. Python X *python_x* *pythonx* +Python X *python_x* *pythonx* Because most python code can be written so that it works with Python 2.6+ and Python 3, the pyx* functions and commands have been written. They work the diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index bcefa1f56b..a26e8faa2c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6170,10 +6170,16 @@ A jump table for the options with a short description can be found at |Q_op|. 'ttimeout' boolean (default on) global This option and 'ttimeoutlen' determine the behavior when part of a - key code sequence has been received by the terminal UI. For example, - if the \x1b byte is received and 'ttimeout' is set, Nvim will wait - 'ttimeoutlen' milliseconds for the terminal to complete a byte - sequence that represents a key that starts with \x1b. + key code sequence has been received by the |TUI|. + + For example if (the \x1b byte) is received and 'ttimeout' is + set, Nvim waits 'ttimeoutlen' milliseconds for the terminal to + complete a key code sequence. If no input arrives before the timeout, + a single is assumed. Many TUI cursor key codes start with . + + On very slow systems this may fail, causing cursor keys not to work + sometimes. If you discover this problem you can ":set ttimeout=9999". + Nvim will wait for the next character to arrive after an . *'timeoutlen'* *'tm'* 'timeoutlen' 'tm' number (default 1000) diff --git a/runtime/doc/provider.txt b/runtime/doc/provider.txt index 6ed3c230b9..09fdc6872b 100644 --- a/runtime/doc/provider.txt +++ b/runtime/doc/provider.txt @@ -22,7 +22,9 @@ Python integration *provider-python* Nvim supports Python |remote-plugin|s and the Vim legacy |python2| and |python3| interfaces (which are implemented as remote-plugins). -Note: Only the Vim 7.3 API is supported; bindeval (Vim 7.4) is not. + +Note: Only the Vim 7.3 legacy interface is supported, not later features such +as |python-bindeval| (Vim 7.4); use the Nvim API instead. PYTHON QUICKSTART ~ diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 12794b6cc0..291f4b2086 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -409,8 +409,8 @@ accordingly. Vim proceeds in this order: useful for debugging the initializations. 3. Execute Ex commands, from environment variables and/or files - An environment variable is read as one Ex command line, where multiple - commands must be separated with '|' or . + An environment variable (e.g. $VIMINIT) is read as one Ex command + line, where multiple commands must be separated with '|' or . *config* *init.vim* *vimrc* *exrc* A file that contains initialization commands is generically called a "vimrc" or config file. Each line in a vimrc file is executed as an @@ -422,20 +422,15 @@ accordingly. Vim proceeds in this order: Or if |$XDG_CONFIG_HOME| is defined: $XDG_CONFIG_HOME/nvim/init.vim - RECOMMENDATION: Put all your Vim configuration stuff in the - $HOME/.config/nvim/ directory. That makes it easy to copy it to - another system. - - If Vim was started with "-u filename", the file "filename" is used. + If Nvim was started with "-u filename", the file "filename" is used. All following initializations until 4. are skipped. $MYVIMRC is not set. - "vim -u NORC" can be used to skip these initializations without - reading a file. "vim -u NONE" also skips plugins and syntax + "nvim -u NORC" can be used to skip these initializations without + reading a file. "nvim -u NONE" also skips plugins and syntax highlighting. |-u| - If Vim was started in Ex mode with the "-s" argument, all following - initializations until 4. are skipped. Only the "-u" option is - interpreted. + If Nvim was started with |-es|, all following initializations until 4. + are skipped. *system-vimrc* *sysinit.vim* a. The system vimrc file is read for initializations. If nvim/sysinit.vim file exists in one of $XDG_CONFIG_DIRS, it will be @@ -447,13 +442,11 @@ accordingly. Vim proceeds in this order: is used, the others are ignored. The $MYVIMRC environment variable is set to the file that was first found, unless $MYVIMRC was already set and when using VIMINIT. - - The environment variable VIMINIT - The value of $VIMINIT is used as an Ex command line. - - The user vimrc file: $XDG_CONFIG_HOME/nvim/init.vim. - - Other vimrc file: {xdg_config_dir}/nvim/init.vim where + - Environment variable $VIMINIT, used as an Ex command line. + - User |config| file: $XDG_CONFIG_HOME/nvim/init.vim. + - Other config file: {xdg_config_dir}/nvim/init.vim where {xdg_config_dir} is one of the directories in $XDG_CONFIG_DIRS. - - The environment variable EXINIT. - The value of $EXINIT is used as an Ex command line. + - Environment variable $EXINIT, used as an Ex command line. c. If the 'exrc' option is on (which is NOT the default), the current directory is searched for three files. The first that exists is used, @@ -519,18 +512,14 @@ accordingly. Vim proceeds in this order: If the "-b" flag was given to Vim, the options for binary editing will be set now. See |-b|. -10. Perform GUI initializations - Only when starting "gvim", the GUI initializations will be done. See - |gui-init|. - -11. Read the ShaDa file +10. Read the ShaDa file See |shada-file|. -12. Read the quickfix file +11. Read the quickfix file If the "-q" flag was given to Vim, the quickfix file is read. If this fails, Vim exits. -13. Open all windows +12. Open all windows When the |-o| flag was given, windows will be opened (but not displayed yet). When the |-p| flag was given, tab pages will be created (but not @@ -539,7 +528,7 @@ accordingly. Vim proceeds in this order: If the "-q" flag was given to Vim, the first error is jumped to. Buffers for all windows will be loaded. -14. Execute startup commands +13. Execute startup commands If a "-t" flag was given to Vim, the tag is jumped to. The commands given with the |-c| and |+cmd| arguments are executed. If the 'insertmode' option is set, Insert mode is entered. @@ -591,9 +580,6 @@ On Windows systems Vim assumes that all the vimrc files have pairs as line separators. This will give problems if you have a file with only s and have a line like ":map xx yy^M". The trailing ^M will be ignored. -The $MYVIMRC or $MYGVIMRC file will be set to the first found vimrc and/or -gvimrc file. - Avoiding trojan horses ~ *trojan-horse* diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt index 9de5745e92..978f50dd55 100644 --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -6,17 +6,18 @@ Terminal UI *TUI* *tui* -Nvim (except in |--headless| mode) uses information about the terminal you are -using to present a built-in UI. If that information is not correct, the -screen may be messed up or keys may not be recognized. +Nvim uses a list of terminal capabilities to display its user interface +(except in |--embed| and |--headless| modes). If that information is wrong, +the screen may be messed up or keys may not be recognized. Type |gO| to see the table of contents. ============================================================================== Startup *startup-terminal* -Nvim (except in |--headless| mode) guesses a terminal type when it starts. -|$TERM| is the primary hint that determines the terminal type. +Nvim guesses the terminal type when it starts (except in |--embed| and +|--headless| modes). The |$TERM| environment variable is the primary hint that +determines the terminal type. *terminfo* *E557* *E558* *E559* The terminfo database is used if available. @@ -37,39 +38,39 @@ The $TERM environment variable must match the terminal you are using! Otherwise Nvim cannot know what sequences your terminal expects, and weird or sub-optimal behavior will result (scrolling quirks, wrong colors, etc.). -$TERM is also important because it is mirrored by SSH to the remote session, +$TERM is also important because it is forwarded by SSH to the remote session, unlike most other environment variables. For this terminal Set $TERM to |builtin-terms| ------------------------------------------------------------------------- + anything libvte-based vte, vte-256color Y + (e.g. GNOME Terminal) (aliases: gnome, gnome-256color) iTerm (original) iterm, iTerm.app N iTerm2 (new capabilities) iterm2, iTerm2.app Y Konsole konsole-256color N - anything libvte-based vte, vte-256color Y - (e.g. GNOME Terminal) (aliases: gnome, gnome-256color) - tmux tmux, tmux-256color Y - screen screen, screen-256color Y - PuTTY putty, putty-256color Y - Terminal.app nsterm N Linux virtual terminal linux, linux-256color Y + PuTTY putty, putty-256color Y + rxvt rxvt, rxvt-256color Y + screen screen, screen-256color Y + simple terminal (st) st, st-256color Y + Terminal.app nsterm N + tmux tmux, tmux-256color Y + Windows/ConEmu conemu Y + Windows/Cygwin-built Nvim cygwin Y + Windows/Interix interix Y + Windows/VTP console vtpcon Y + Windows/legacy console win32con Y + xterm or compatible xterm, xterm-256color Y *builtin-terms* *builtin_terms* -If a |terminfo| database is not available, or no entry for the terminal type is -found in that database, Nvim will use a compiled-in mini-database of terminfo -entries for "xterm", "putty", "screen", "tmux", "rxvt", "iterm", "interix", -"linux", "st", "vte", "gnome", and "ansi". +If a |terminfo| database is not available or there is no entry for the current +terminal, Nvim will map |$TERM| to a builtin entry according to the above +table, or "ansi" if there is no match. For example "TERM=putty-256color" will +be mapped to the builtin "putty" entry. See also |tui-colors|. -The lookup matches the initial portion of the terminal type, so (for example) -"putty-256color" and "putty" will both be mapped to the built-in "putty" -entry. The built-in terminfo entries describe the terminal as 256-colour -capable if possible. See |tui-colors|. - -If no built-in terminfo record matches the terminal type, the built-in "ansi" -terminfo record is used as a final fallback. - -The built-in mini-database is not combined with an external terminfo database, -nor can it be used in preference to one. You can thus entirely override any -omissions or out-of-date information in the built-in terminfo database by +The builtin terminfo is not combined with any external terminfo database, nor +can it be used in preference to one. You can thus entirely override any +omissions or out-of-date information in the builtin terminfo database by supplying an external one with entries for the terminal type. Settings depending on terminal *term-dependent-settings* @@ -107,12 +108,6 @@ and right scroll margins as well. If Nvim detects that the terminal is Xterm, it will make use of this ability to speed up scrolling that is not the full width of the terminal. -This ability is only present in genuine Xterm, not in the many terminal -emulators that incorrectly describe themselves as xterm. Nvim's detection of -genuine Xterm will not work over an SSH connection, because the environment -variable, set by genuine Xterm, that it looks for is not automatically -replicated over an SSH login session. - *tui-colors* Nvim uses 256 colours by default, ignoring |terminfo| for most terminal types, including "linux" (whose virtual terminals have had 256-colour support since @@ -149,7 +144,7 @@ extension pioneered by dtterm. |terminfo| does not have a flag for this extension. So Nvim simply assumes that (all) "dtterm", "xterm", "teraterm", "rxvt" terminal types, and Konsole, are capable of this. - *tui-cursor-shape* + *tui-cursor-shape* Nvim will adjust the shape of the cursor from a block to a line when in insert mode (or as specified by the 'guicursor' option), on terminals that support it. It uses the same |terminfo| extensions that were pioneered by tmux for @@ -162,55 +157,22 @@ environment variables. For the "rxvt", "putty", "linux", "screen", terminal emulator, or genuine Xterm are detected, it will add constructed "Ss" and "Se" capabilities. -Note: Sometimes it will appear that Nvim when run within tmux is not changing -the cursor, but in fact it is tmux receiving instructions from Nvim to change -the cursor and not knowing what to do in turn. tmux has to translate what it -receives from Nvim into whatever control sequence is appropriate for the -terminal that it is outputting to. It shares a common mechanism with Nvim, of -using the "Ss" and "Se" capabilities from terminfo (for the output terminal) -if they are present. Unlike Nvim, if they are not present in terminfo you -must add them by setting "terminal-overrides" in ~/.tmux.conf . + *tui-cursor-tmux* +Within tmux it may appear that Nvim is not changing the cursor, but in fact it +is tmux receiving instructions from Nvim to change the cursor and not knowing +what to do in turn. tmux must translate what it receives from Nvim into +whatever control sequence is appropriate for the host terminal. It shares +a common mechanism with Nvim, of using the "Ss" and "Se" capabilities from +terminfo (for the output terminal) if they are present. Unlike Nvim, if they +are not in terminfo you must add them by setting "terminal-overrides" in +~/.tmux.conf . See the tmux(1) manual page for the details of how and what to do in the tmux configuration file. It will look something like: > set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q' - + set -ga terminal-overrides 'xterm*:\E]50;CursorShape=%?%p1%{3}%<%t%{0}%e%{1}%;%d\007' < - *cs7-problem* -Note: If the terminal settings are changed after running Vim, you might have -an illegal combination of settings. This has been reported on Solaris 2.5 -with "stty cs8 parenb", which is restored as "stty cs7 parenb". Use -"stty cs8 -parenb -istrip" instead, this is restored correctly. - -Many cursor key codes start with an . Vim must find out if this is a -single hit of the key or the start of a cursor key sequence. It waits -for a next character to arrive. If it does not arrive within one second a -single is assumed. On very slow systems this may fail, causing cursor -keys not to work sometimes. If you discover this problem reset the 'timeout' -option. Vim will wait for the next character to arrive after an . If -you want to enter a single you must type it twice. - -Some terminals have confusing codes for the cursor keys. The televideo 925 is -such a terminal. It sends a CTRL-H for cursor-left. This would make it -impossible to distinguish a backspace and cursor-left. To avoid this problem -CTRL-H is never recognized as cursor-left. - - *vt100-cursor-keys* *xterm-cursor-keys* -Other terminals (e.g., vt100 and xterm) have cursor keys that send OA, -OB, etc. Unfortunately these are valid commands in insert mode: Stop -insert, Open a new line above the new one, start inserting 'A', 'B', etc. -Instead of performing these commands Vim will erroneously recognize this typed -key sequence as a cursor key movement. To avoid this and make Vim do what you -want in either case you could use these settings: > - :set notimeout " don't timeout on mappings - :set ttimeout " do timeout on terminal key codes - :set timeoutlen=100 " timeout after 100 msec -This requires the key-codes to be sent within 100 msec in order to recognize -them as a cursor key. When you type you normally are not that fast, so they -are recognized as individual typed commands, even though Vim receives the same -sequence of bytes. - ============================================================================== Window size *window-size* diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index db856ceb65..0e6c682b5c 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -371,7 +371,7 @@ VimL (Vim script) compatibility: Some legacy Vim features are not implemented: -- |if_py|: vim.bindeval() and vim.Function() are not supported +- |if_py|: *python-bindeval* *python-Function* are not supported - |if_lua|: the `vim` object is missing some legacy methods - *if_perl* - *if_mzscheme* diff --git a/scripts/release.sh b/scripts/release.sh index fb266ad154..a51a6666f5 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -93,7 +93,7 @@ Next steps: - Double-check NVIM_VERSION_* in CMakeLists.txt - Push the tag: git push --follow-tags - - Empty-merge (if this is a maintenance release): - git checkout upstream/master - git merge -s ours upstream/release-x.y + - Update the 'stable' tag: + git push --force upstream HEAD^:refs/tags/stable + git fetch --tags - Update website: index.html" diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 5df0f0bb47..9cd178eaeb 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -104,7 +104,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) /// the whole buffer. If so, the first notification will be a /// `nvim_buf_lines_event`. Otherwise, the first notification will be /// a `nvim_buf_changedtick_event` -/// @param opts Optional parameters. Currently not used. +/// @param opts Optional parameters. Reserved for future use. /// @param[out] err Details of an error that may have occurred /// @return False when updates couldn't be enabled because the buffer isn't /// loaded or `opts` contained an invalid key; otherwise True. diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 7ba5251c60..bc8a1a941f 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -245,9 +245,8 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, name.data); } -/// Tell nvim to resize a grid. Nvim sends grid_resize event with the -/// requested grid size is within size limits and with maximum allowed size -/// otherwise. +/// Tell Nvim to resize a grid. Triggers a grid_resize event with the requested +/// grid size or the maximum size if it exceeds size limits. /// /// On invalid grid handle, fails with error. /// diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 7f62333d88..5b59ff39f4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -198,9 +198,8 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi) /// @note |keycodes| like are translated, so "<" is special. /// To input a literal "<", send . /// -/// For mouse events use |nvim_input_mouse()|. For back-compat reasons -/// this method supports mouse input as "". This -/// usage is deprecated since API level 6, use the dedicated method instead. +/// @note For mouse events use |nvim_input_mouse()|. The pseudokey form +/// "" is deprecated since |api-level| 6. /// /// @param keys to be typed /// @return Number of bytes actually written (can be fewer than @@ -211,7 +210,7 @@ Integer nvim_input(String keys) return (Integer)input_enqueue(keys); } -/// Send mouse event from GUI +/// Send mouse event from GUI. /// /// The call is non-blocking. It doesn't wait on any resulting action, but /// queues the event to be processed soon by the event loop. @@ -220,20 +219,18 @@ Integer nvim_input(String keys) /// by calling it multiple times in a loop: the intermediate mouse /// positions will be ignored. It should be used to implement real-time /// mouse input in a GUI. The deprecated pseudokey form -/// ("") in |nvim_input()| has the same limitiation. +/// ("") of |nvim_input()| has the same limitiation. /// -/// @param button Which mouse button, one of "left", "right", "middle" or -/// "wheel". -/// @param action For ordinary buttons, one of "press", "drag" and "release" -/// For the wheel, use "up", "down", "left" and "right". +/// @param button Mouse button: one of "left", "right", "middle", "wheel". +/// @param action For ordinary buttons, one of "press", "drag", "release". +/// For the wheel, one of "up", "down", "left", "right". /// @param modifier String of modifiers each represented by a single char. /// The same specifiers are used as for a key press, except /// that the "-" separator is optional, so "C-A-", "c-a" -/// and "CA" can all be used to specify Ctrl+Alt+click -/// @param grid For a client using |ui-multigrid| pass in the grid number. -/// Other clients should pass in 0 (not 1). -/// @param row row position of mouse (zero-based, like in redraw events) -/// @param col column position of mouse (zero-based, like in redraw events) +/// and "CA" can all be used to specify Ctrl+Alt+click. +/// @param grid Grid number if the client uses |ui-multigrid|, else 0. +/// @param row Mouse row-position (zero-based, like redraw events) +/// @param col Mouse column-position (zero-based, like redraw events) void nvim_input_mouse(String button, String action, String modifier, Integer grid, Integer row, Integer col, Error *err) FUNC_API_SINCE(6) FUNC_API_ASYNC @@ -694,7 +691,7 @@ void nvim_set_current_dir(String dir, Error *err) try_end(err); } -/// Gets the current line +/// Gets the current line. /// /// @param[out] err Error details, if any /// @return Current line string @@ -704,7 +701,7 @@ String nvim_get_current_line(Error *err) return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } -/// Sets the current line +/// Sets the current line. /// /// @param line Line contents /// @param[out] err Error details, if any @@ -714,7 +711,7 @@ void nvim_set_current_line(String line, Error *err) buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err); } -/// Deletes the current line +/// Deletes the current line. /// /// @param[out] err Error details, if any void nvim_del_current_line(Error *err) @@ -723,7 +720,7 @@ void nvim_del_current_line(Error *err) buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } -/// Gets a global (g:) variable +/// Gets a global (g:) variable. /// /// @param name Variable name /// @param[out] err Error details, if any @@ -734,7 +731,7 @@ Object nvim_get_var(String name, Error *err) return dict_get_value(&globvardict, name, err); } -/// Sets a global (g:) variable +/// Sets a global (g:) variable. /// /// @param name Variable name /// @param value Variable value @@ -745,7 +742,7 @@ void nvim_set_var(String name, Object value, Error *err) dict_set_var(&globvardict, name, value, false, false, err); } -/// Removes a global (g:) variable +/// Removes a global (g:) variable. /// /// @param name Variable name /// @param[out] err Error details, if any @@ -772,7 +769,7 @@ Object vim_del_var(String name, Error *err) return dict_set_var(&globvardict, name, NIL, true, true, err); } -/// Gets a v: variable +/// Gets a v: variable. /// /// @param name Variable name /// @param[out] err Error details, if any @@ -783,7 +780,7 @@ Object nvim_get_vvar(String name, Error *err) return dict_get_value(&vimvardict, name, err); } -/// Sets a v: variable, if it is not readonly +/// Sets a v: variable, if it is not readonly. /// /// @param name Variable name /// @param value Variable value @@ -794,7 +791,7 @@ void nvim_set_vvar(String name, Object value, Error *err) dict_set_var(&vimvardict, name, value, false, false, err); } -/// Gets an option value string +/// Gets an option value string. /// /// @param name Option name /// @param[out] err Error details, if any @@ -805,7 +802,7 @@ Object nvim_get_option(String name, Error *err) return get_option_from(NULL, SREQ_GLOBAL, name, err); } -/// Sets an option value +/// Sets an option value. /// /// @param name Option name /// @param value New option value @@ -873,7 +870,7 @@ ArrayOf(Buffer) nvim_list_bufs(void) return rv; } -/// Gets the current buffer +/// Gets the current buffer. /// /// @return Buffer handle Buffer nvim_get_current_buf(void) @@ -882,7 +879,7 @@ Buffer nvim_get_current_buf(void) return curbuf->handle; } -/// Sets the current buffer +/// Sets the current buffer. /// /// @param buffer Buffer handle /// @param[out] err Error details, if any @@ -905,7 +902,7 @@ void nvim_set_current_buf(Buffer buffer, Error *err) } } -/// Gets the current list of window handles +/// Gets the current list of window handles. /// /// @return List of window handles ArrayOf(Window) nvim_list_wins(void) @@ -927,7 +924,7 @@ ArrayOf(Window) nvim_list_wins(void) return rv; } -/// Gets the current window +/// Gets the current window. /// /// @return Window handle Window nvim_get_current_win(void) @@ -936,7 +933,7 @@ Window nvim_get_current_win(void) return curwin->handle; } -/// Sets the current window +/// Sets the current window. /// /// @param window Window handle void nvim_set_current_win(Window window, Error *err) @@ -958,7 +955,7 @@ void nvim_set_current_win(Window window, Error *err) } } -/// Gets the current list of tabpage handles +/// Gets the current list of tabpage handles. /// /// @return List of tabpage handles ArrayOf(Tabpage) nvim_list_tabpages(void) @@ -980,7 +977,7 @@ ArrayOf(Tabpage) nvim_list_tabpages(void) return rv; } -/// Gets the current tabpage +/// Gets the current tabpage. /// /// @return Tabpage handle Tabpage nvim_get_current_tabpage(void) @@ -989,7 +986,7 @@ Tabpage nvim_get_current_tabpage(void) return curtab->handle; } -/// Sets the current tabpage +/// Sets the current tabpage. /// /// @param tabpage Tabpage handle /// @param[out] err Error details, if any @@ -1012,7 +1009,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) } } -/// Creates a new namespace, or gets an existing one +/// Creates a new namespace, or gets an existing one. /// /// Namespaces are used for buffer highlights and virtual text, see /// |nvim_buf_add_highlight()| and |nvim_buf_set_virtual_text()|. @@ -1038,7 +1035,7 @@ Integer nvim_create_namespace(String name) return (Integer)id; } -/// Gets existing, non-anonymous namespaces +/// Gets existing, non-anonymous namespaces. /// /// @return dict that maps from names to namespace ids. Dictionary nvim_get_namespaces(void) @@ -1055,7 +1052,7 @@ Dictionary nvim_get_namespaces(void) return retval; } -/// Subscribes to event broadcasts +/// Subscribes to event broadcasts. /// /// @param channel_id Channel id (passed automatically by the dispatcher) /// @param event Event type string @@ -1069,7 +1066,7 @@ void nvim_subscribe(uint64_t channel_id, String event) rpc_subscribe(channel_id, e); } -/// Unsubscribes to event broadcasts +/// Unsubscribes to event broadcasts. /// /// @param channel_id Channel id (passed automatically by the dispatcher) /// @param event Event type string @@ -1379,7 +1376,7 @@ typedef struct { typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack; /// @endcond -/// Parse a VimL expression +/// Parse a VimL expression. /// /// @param[in] expr Expression to parse. Is always treated as a single line. /// @param[in] flags Flags: @@ -1860,7 +1857,7 @@ static void write_msg(String message, bool to_err) // Functions used for testing purposes -/// Returns object given as argument +/// Returns object given as argument. /// /// This API function is used for testing. One should not rely on its presence /// in plugins. @@ -1873,7 +1870,7 @@ Object nvim__id(Object obj) return copy_object(obj); } -/// Returns array given as argument +/// Returns array given as argument. /// /// This API function is used for testing. One should not rely on its presence /// in plugins. @@ -1886,7 +1883,7 @@ Array nvim__id_array(Array arr) return copy_object(ARRAY_OBJ(arr)).data.array; } -/// Returns dictionary given as argument +/// Returns dictionary given as argument. /// /// This API function is used for testing. One should not rely on its presence /// in plugins. @@ -1899,7 +1896,7 @@ Dictionary nvim__id_dictionary(Dictionary dct) return copy_object(DICTIONARY_OBJ(dct)).data.dictionary; } -/// Returns floating-point value given as argument +/// Returns floating-point value given as argument. /// /// This API function is used for testing. One should not rely on its presence /// in plugins. @@ -2023,19 +2020,19 @@ Object nvim_get_proc(Integer pid, Error *err) return rvobj; } -/// Selects an item in the completion popupmenu +/// Selects an item in the completion popupmenu. /// -/// When insert completion is not active, this API call is silently ignored. -/// It is mostly useful for an external UI using |ui-popupmenu| for instance -/// to control the popupmenu with the mouse. But it can also be used in an -/// insert mode mapping, use mapping |:map-cmd| to ensure the mapping -/// doesn't end completion mode. +/// If |ins-completion| is not active this API call is silently ignored. +/// Useful for an external UI using |ui-popupmenu| to control the popupmenu +/// with the mouse. Can also be used in a mapping; use |:map-cmd| to +/// ensure the mapping doesn't end completion mode. /// -/// @param item Index of the item to select, starting with zero. Pass in "-1" -/// to select no item (restore original text). +/// @param item Index (zero-based) of the item to select. Value of -1 selects +/// nothing and restores the original text. /// @param insert Whether the selection should be inserted in the buffer. -/// @param finish If true, completion will be finished with this item, and the -/// popupmenu dissmissed. Implies `insert`. +/// @param finish Finish the completion and dismiss the popupmenu. Implies +/// `insert`. +/// @param opts Optional parameters. Reserved for future use. void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts, Error *err) FUNC_API_SINCE(6) diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h index 34a002af5d..edd933b2cd 100644 --- a/src/nvim/memline_defs.h +++ b/src/nvim/memline_defs.h @@ -3,54 +3,65 @@ #include "nvim/memfile_defs.h" -/* - * When searching for a specific line, we remember what blocks in the tree - * are the branches leading to that block. This is stored in ml_stack. Each - * entry is a pointer to info in a block (may be data block or pointer block) - */ +/// +/// When searching for a specific line, we remember what blocks in the tree +/// are the branches leading to that block. This is stored in ml_stack. Each +/// entry is a pointer to info in a block (may be data block or pointer block) +/// typedef struct info_pointer { - blocknr_T ip_bnum; /* block number */ - linenr_T ip_low; /* lowest lnum in this block */ - linenr_T ip_high; /* highest lnum in this block */ - int ip_index; /* index for block with current lnum */ -} infoptr_T; /* block/index pair */ + blocknr_T ip_bnum; // block number + linenr_T ip_low; // lowest lnum in this block + linenr_T ip_high; // highest lnum in this block + int ip_index; // index for block with current lnum +} infoptr_T; // block/index pair typedef struct ml_chunksize { int mlcs_numlines; long mlcs_totalsize; } chunksize_T; -/* Flags when calling ml_updatechunk() */ - +// Flags when calling ml_updatechunk() #define ML_CHNK_ADDLINE 1 #define ML_CHNK_DELLINE 2 #define ML_CHNK_UPDLINE 3 -/* - * the memline structure holds all the information about a memline - */ +/// memline structure: the contents of a buffer. +/// Essentially a tree with a branch factor of 128. +/// Lines are stored at leaf nodes. +/// Nodes are stored on ml_mfp (memfile_T): +/// pointer_block: internal nodes +/// data_block: leaf nodes +/// +/// Memline also has "chunks" of 800 lines that are separate from the 128-tree +/// structure, primarily used to speed up line2byte() and byte2line(). +/// +/// Motivation: If you have a file that is 10000 lines long, and you insert +/// a line at linenr 1000, you don't want to move 9000 lines in +/// memory. With this structure it is roughly (N * 128) pointer +/// moves, where N is the height (typically 1-3). +/// typedef struct memline { - linenr_T ml_line_count; /* number of lines in the buffer */ + linenr_T ml_line_count; // number of lines in the buffer - memfile_T *ml_mfp; /* pointer to associated memfile */ + memfile_T *ml_mfp; // pointer to associated memfile -#define ML_EMPTY 1 /* empty buffer */ -#define ML_LINE_DIRTY 2 /* cached line was changed and allocated */ -#define ML_LOCKED_DIRTY 4 /* ml_locked was changed */ -#define ML_LOCKED_POS 8 /* ml_locked needs positive block number */ +#define ML_EMPTY 1 // empty buffer +#define ML_LINE_DIRTY 2 // cached line was changed and allocated +#define ML_LOCKED_DIRTY 4 // ml_locked was changed +#define ML_LOCKED_POS 8 // ml_locked needs positive block number int ml_flags; - infoptr_T *ml_stack; /* stack of pointer blocks (array of IPTRs) */ - int ml_stack_top; /* current top of ml_stack */ - int ml_stack_size; /* total number of entries in ml_stack */ + infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs) + int ml_stack_top; // current top of ml_stack + int ml_stack_size; // total number of entries in ml_stack - linenr_T ml_line_lnum; /* line number of cached line, 0 if not valid */ - char_u *ml_line_ptr; /* pointer to cached line */ + linenr_T ml_line_lnum; // line number of cached line, 0 if not valid + char_u *ml_line_ptr; // pointer to cached line - bhdr_T *ml_locked; /* block used by last ml_get */ - linenr_T ml_locked_low; /* first line in ml_locked */ - linenr_T ml_locked_high; /* last line in ml_locked */ - int ml_locked_lineadd; /* number of lines inserted in ml_locked */ + bhdr_T *ml_locked; // block used by last ml_get + linenr_T ml_locked_low; // first line in ml_locked + linenr_T ml_locked_high; // last line in ml_locked + int ml_locked_lineadd; // number of lines inserted in ml_locked chunksize_T *ml_chunksize; int ml_numchunks; int ml_usedchunks;