diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /runtime/doc/lua-guide.txt | |
parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-usermarks.tar.gz rneovim-usermarks.tar.bz2 rneovim-usermarks.zip |
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'runtime/doc/lua-guide.txt')
-rw-r--r-- | runtime/doc/lua-guide.txt | 757 |
1 files changed, 757 insertions, 0 deletions
diff --git a/runtime/doc/lua-guide.txt b/runtime/doc/lua-guide.txt new file mode 100644 index 0000000000..b971a7d2ad --- /dev/null +++ b/runtime/doc/lua-guide.txt @@ -0,0 +1,757 @@ +*lua-guide.txt* Nvim + + NVIM REFERENCE MANUAL + + Guide to using Lua in Nvim + + + Type |gO| to see the table of contents. + +============================================================================== +Introduction *lua-guide* + +This guide will go through the basics of using Lua in Neovim. It is not meant +to be a comprehensive encyclopedia of all available features, nor will it +detail all intricacies. Think of it as a survival kit -- the bare minimum +needed to know to comfortably get started on using Lua in Neovim. + +An important thing to note is that this isn't a guide to the Lua language +itself. Rather, this is a guide on how to configure and modify Neovim through +the Lua language and the functions we provide to help with this. Take a look +at |luaref| and |lua-concepts| if you'd like to learn more about Lua itself. +Similarly, this guide assumes some familiarity with the basics of Neovim +(commands, options, mappings, autocommands), which are covered in the +|user-manual|. + +------------------------------------------------------------------------------ +Some words on the API *lua-guide-api* + +The purpose of this guide is to introduce the different ways of interacting +with Neovim through Lua (the "API"). This API consists of three different +layers: + +1. The "Vim API" inherited from Vim: |ex-commands| and |builtin-functions| as +well as |user-function|s in Vimscript. These are accessed through |vim.cmd()| +and |vim.fn| respectively, which are discussed under |lua-guide-vimscript| +below. + +2. The "Neovim API" written in C for use in remote plugins and GUIs; see |api|. +These functions are accessed through |vim.api|. + +3. The "Lua API" written in and specifically for Lua. These are any other +functions accessible through `vim.*` not mentioned already; see |lua-stdlib|. + +This distinction is important, as API functions inherit behavior from their +original layer: For example, Neovim API functions always need all arguments to +be specified even if Lua itself allows omitting arguments (which are then +passed as `nil`); and Vim API functions can use 0-based indexing even if Lua +arrays are 1-indexed by default. + +Through this, any possible interaction can be done through Lua without writing +a complete new API from scratch. For this reason, functions are usually not +duplicated between layers unless there is a significant benefit in +functionality or performance (e.g., you can map Lua functions directly through +|nvim_create_autocmd()| but not through |:autocmd|). In case there are multiple +ways of achieving the same thing, this guide will only cover what is most +convenient to use from Lua. + +============================================================================== +Using Lua *lua-guide-using-Lua* + +To run Lua code from the Neovim command line, use the |:lua| command: +>vim + :lua print("Hello!") +< +Note: each |:lua| command has its own scope and variables declared with the +local keyword are not accessible outside of the command. This won't work: +>vim + :lua local foo = 1 + :lua print(foo) + " prints "nil" instead of "1" +< +You can also use `:lua=`, which is the same as `:lua vim.pretty_print(...)`, +to conveniently check the value of a variable or a table: +>lua + :lua=package +< +To run a Lua script in an external file, you can use the |:source| command +exactly like for a Vimscript file: +>vim + :source ~/programs/baz/myluafile.lua +< +Finally, you can include Lua code in a Vimscript file by putting it inside a +|lua-heredoc| block: +>vim + lua << EOF + local tbl = {1, 2, 3} + for k, v in ipairs(tbl) do + print(v) + end + EOF +< +------------------------------------------------------------------------------ +Using Lua files on startup *lua-guide-config* + +Neovim supports using `init.vim` or `init.lua` as the configuration file, but +not both at the same time. This should be placed in your |config| directory, +which is typically `~/.config/nvim` for Linux, BSD, or macOS, and +`~/AppData/Local/nvim/` for Windows. Note that you can use Lua in `init.vim` +and Vimscript in `init.lua`, which will be covered below. + +If you'd like to run any other Lua script on |startup| automatically, then you +can simply put it in `plugin/` in your |'runtimepath'|. + +------------------------------------------------------------------------------ +Lua modules *lua-guide-modules* + +If you want to load Lua files on demand, you can place them in the `lua/` +directory in your |'runtimepath'| and load them with `require`. (This is the +Lua equivalent of Vimscript's |autoload| mechanism.) + +Let's assume you have the following directory structure: +> + ~/.config/nvim + |-- after/ + |-- ftplugin/ + |-- lua/ + | |-- myluamodule.lua + | |-- other_modules/ + | |-- anothermodule.lua + | |-- init.lua + |-- plugin/ + |-- syntax/ + |-- init.vim +< + +Then the following Lua code will load `myluamodule.lua`: +>lua + require("myluamodule") +< +Note the absence of a `.lua` extension. + +Similarly, loading `other_modules/anothermodule.lua` is done via +>lua + require('other_modules/anothermodule') + -- or + require('other_modules.anothermodule') +< + +Note how "submodules" are just subdirectories; the `.` is equivalent to the +path separator `/` (even on Windows). + +A folder containing an |init.lua| file can be required directly, without +having to specify the name of the file: +>lua + require('other_modules') -- loads other_modules/init.lua +< +Requiring a nonexistent module or a module which contains syntax errors aborts +the currently executing script. `pcall()` may be used to catch such errors. The +following example tries to load the `module_with_error` and only calls one of +its functions if this succeeds and prints an error message otherwise: +>lua + local ok, mymod = pcall(require, 'module_with_error') + if not ok then + print("Module had an error") + else + mymod.function() + end +< +In contrast to |:source|, |require()| not only searches through all `lua/` directories +under |'runtimepath'|, it also cache the module on first use. Calling +`require()` a second time will therefore _not_ execute the script again and +instead return the cached file. To rerun the file, you need to remove it from +the cache manually first: +>lua + package.loaded['myluamodule'] = nil + require('myluamodule') -- read and execute the module again from disk +< +------------------------------------------------------------------------------ +See also: +• |lua-require| +• |luaref-pcall()| + +============================================================================== +Using Vim commands and functions from Lua *lua-guide-vimscript* + +All Vim commands and functions are accessible from Lua. + +------------------------------------------------------------------------------ +Vim commands *lua-guide-vim-commands* + +To run an arbitrary Vim command from Lua, pass it as a string to |vim.cmd()|: +>lua + vim.cmd("colorscheme habamax") +< +Note that special characters will need to be escaped with backslashes: +>lua + vim.cmd("%s/\\Vfoo/bar/g") +< +An alternative is to use a literal string (see |luaref-literal|) delimited by +double brackets `[[ ]]` as in +>lua + vim.cmd([[%s/\Vfoo/bar/g]]) +< +Another benefit of using literal strings is that they can be multiple lines; +this allows you to pass multiple commands to a single call of |vim.cmd()|: +>lua + vim.cmd([[ + highlight Error guibg=red + highlight link Warning Error + ]]) +< +This is the converse of |lua-heredoc| and allows you to include Vimscript code in +your `init.lua`. + +If you want to build your Vim command programmatically, the following form can +be useful (all these are equivalent to the corresponding line above): +>lua + vim.cmd.colorscheme("habamax") + vim.cmd.highlight({ "Error", "guibg=red" }) + vim.cmd.highlight({ "link", "Warning", "Error" }) +< +------------------------------------------------------------------------------ +Vimscript functions *lua-guide-vim-functions* + +Use |vim.fn| to call Vimscript functions from Lua. Data types between Lua and +Vimscript are automatically converted: +>lua + print(vim.fn.printf('Hello from %s', 'Lua')) + + local reversed_list = vim.fn.reverse({ 'a', 'b', 'c' }) + print(vim.inspect(reversed_list)) -- { "c", "b", "a" } + + local function print_stdout(chan_id, data, name) + print(data[1]) + end + + vim.fn.jobstart('ls', { on_stdout = print_stdout }) + print(vim.fn.printf('Hello from %s', 'Lua')) +< +This works for both |builtin-functions| and |user-function|s. + +Note that hashes (`#`) are not valid characters for identifiers in Lua, so, +e.g., |autoload| functions have to be called with this syntax: +>lua + vim.fn['my#autoload#function']() +< +------------------------------------------------------------------------------ +See also: +• |builtin-functions|: alphabetic list of all Vimscript functions +• |function-list|: list of all Vimscript functions grouped by topic +• |:runtime|: run all Lua scripts matching a pattern in |'runtimepath'| +• |package.path|: list of all paths searched by `require()` + +============================================================================== +Variables *lua-guide-variables* + +Variables can be set and read using the following wrappers, which directly +correspond to their |variable-scope|: + +• |vim.g|: global variables (|g:|) +• |vim.b|: variables for the current buffer (|b:|) +• |vim.w|: variables for the current window (|w:|) +• |vim.t|: variables for the current tabpage (|t:|) +• |vim.v|: predefined Vim variables (|v:|) +• |vim.env|: environment variables defined in the editor session + +Data types are converted automatically. For example: +>lua + vim.g.some_global_variable = { + key1 = "value", + key2 = 300 + } + + print(vim.inspect(vim.g.some_global_variable)) + --> { key1 = "value", key2 = 300 } +< +You can target specific buffers (via number), windows (via |window-ID|), or +tabpages by indexing the wrappers: +>lua + vim.b[2].myvar = 1 -- set myvar for buffer number 2 + vim.w[1005].myothervar = true -- set myothervar for window ID 1005 +< +Some variable names may contain characters that cannot be used for identifiers +in Lua. You can still manipulate these variables by using the syntax +>lua + vim.g['my#variable'] = 1 +< +Note that you cannot directly change fields of array variables. This won't +work: +>lua + vim.g.some_global_variable.key2 = 400 + vim.pretty_print(vim.g.some_global_variable) + --> { key1 = "value", key2 = 300 } +< +Instead, you need to create an intermediate Lua table and change this: +>lua + local temp_table = vim.g.some_global_variable + temp_table.key2 = 400 + vim.g.some_global_variable = temp_table + vim.pretty_print(vim.g.some_global_variable) + --> { key1 = "value", key2 = 400 } +< +To delete a variable, simply set it to `nil`: +>lua + vim.g.myvar = nil +< +------------------------------------------------------------------------------ +See also: +• |lua-vim-variables| + +============================================================================== +Options *lua-guide-options* + +There are two complementary ways of setting |options| via Lua. + +------------------------------------------------------------------------------ +vim.opt + +The most convenient way for setting global and local options, e.g., in `init.lua`, +is through `vim.opt` and friends: + +• |vim.opt|: behaves like |:set| +• |vim.opt_global|: behaves like |:setglobal| +• |vim.opt_local|: behaves like |:setlocal| + +For example, the Vimscript commands +>vim + set smarttab + set nosmarttab +< +are equivalent to +>lua + vim.opt.smarttab = true + vim.opt.smarttab = false +< +In particular, they allow an easy way to working with list-like, map-like, and +set-like options through Lua tables: Instead of +>vim + set wildignore=*.o,*.a,__pycache__ + set listchars=space:_,tab:>~ + set formatoptions=njt +< +you can use +>lua + vim.opt.wildignore = { '*.o', '*.a', '__pycache__' } + vim.opt.listchars = { space = '_', tab = '>~' } + vim.opt.formatoptions = { n = true, j = true, t = true } +< +These wrappers also come with methods that work similarly to their |:set+=|, +|:set^=| and |:set-=| counterparts in Vimscript: +>lua + vim.opt.shortmess:append({ I = true }) + vim.opt.wildignore:prepend('*.o') + vim.opt.whichwrap:remove({ 'b', 's' }) +< +The price to pay is that you cannot access the option values directly but must +use |vim.opt:get()|: +>lua + print(vim.opt.smarttab) + --> {...} (big table) + print(vim.opt.smarttab:get()) + --> false + vim.pretty_print(vim.opt.listchars:get()) + --> { space = '_', tab = '>~' } +< +------------------------------------------------------------------------------ +vim.o + +For this reason, there exists a more direct variable-like access using `vim.o` +and friends, similarly to how you can get and set options via `:echo &number` +and `:let &listchars='space:_,tab:>~'`: + +• |vim.o|: behaves like |:set| +• |vim.go|: behaves like |:setglobal| +• |vim.bo|: for buffer-scoped options +• |vim.wo|: for window-scoped options + +For example: +>lua + vim.o.smarttab = false -- :set nosmarttab + print(vim.o.smarttab) + --> false + vim.o.listchars = 'space:_,tab:>~' -- :set listchars='space:_,tab:>~' + print(vim.o.listchars) + --> 'space:_,tab:>~' + vim.o.isfname = vim.o.isfname .. ',@-@' -- :set isfname+=@-@ + print(vim.o.isfname) + --> '@,48-57,/,.,-,_,+,,,#,$,%,~,=,@-@' + vim.bo.shiftwidth = 4 -- :setlocal shiftwidth=4 + print(vim.bo.shiftwidth) + --> 4 +< +Just like variables, you can specify a buffer number or |window-ID| for buffer +and window options, respectively. If no number is given, the current buffer or +window is used: +>lua + vim.bo[4].expandtab = true -- sets expandtab to true in buffer 4 + vim.wo.number = true -- sets number to true in current window + print(vim.wo[0].number) --> true +< +------------------------------------------------------------------------------ +See also: +• |lua-options| + +============================================================================== +Mappings *lua-guide-mappings* + +You can map either Vim commands or Lua functions to key sequences. + +------------------------------------------------------------------------------ +Creating mappings *lua-guide-mappings-set* + +Mappings can be created using |vim.keymap.set()|. This function takes three +mandatory arguments: +• {mode} is a string or a table of strings containing the mode + prefix for which the mapping will take effect. The prefixes are the ones + listed in |:map-modes|, or "!" for |:map!|, or empty string for |:map|. +• {lhs} is a string with the key sequences that should trigger the mapping. +• {rhs} is either a string with a Vim command or a Lua function that should + be executed when the {lhs} is entered. + An empty string is equivalent to |<Nop>|, which disables a key. + +Examples: +>lua + -- Normal mode mapping for Vim command + vim.keymap.set('n', '<Leader>ex1', '<cmd>echo "Example 1"<cr>') + -- Normal and Command-line mode mapping for Vim command + vim.keymap.set({'n', 'c'}, '<Leader>ex2', '<cmd>echo "Example 2"<cr>') + -- Normal mode mapping for Lua function + vim.keymap.set('n', '<Leader>ex3', vim.treesitter.start) + -- Normal mode mapping for Lua function with arguments + vim.keymap.set('n', '<Leader>ex4', function() print('Example 4') end) +< +You can map functions from Lua modules via +>lua + vim.keymap.set('n', '<Leader>pl1', require('plugin').action) +< +Note that this loads the plugin at the time the mapping is defined. If you +want to defer the loading to the time when the mapping is executed (as for +|autoload| functions), wrap it in `function() end`: +>lua + vim.keymap.set('n', '<Leader>pl2', function() require('plugin').action() end) +< +The fourth, optional, argument is a table with keys that modify the behavior +of the mapping such as those from |:map-arguments|. The following are the most +useful options: +• `buffer`: If given, only set the mapping for the buffer with the specified + number; `0` or `true` means the current buffer. >lua + -- set mapping for the current buffer + vim.keymap.set('n', '<Leader>pl1', require('plugin').action, { buffer = true }) + -- set mapping for the buffer number 4 + vim.keymap.set('n', '<Leader>pl1', require('plugin').action, { buffer = 4 }) +< +• `silent`: If set to `true`, suppress output such as error messages. >lua + vim.keymap.set('n', '<Leader>pl1', require('plugin').action, { silent = true }) +< +• `expr`: If set to `true`, do not execute the {rhs} but use the return value + as input. Special |keycodes| are converted automatically. For example, the following + mapping replaces <down> with <c-n> in the popupmenu only: >lua + vim.keymap.set('c', '<down>', function() + if vim.fn.pumvisible() == 1 then return '<c-n>' end + return '<down>' + end, { expr = true }) +< +• `desc`: A string that is shown when listing mappings with, e.g., |:map|. + This is useful since Lua functions as {rhs} are otherwise only listed as + `Lua: <number> <source file>:<line>`. Plugins should therefore always use this + for mappings they create. >lua + vim.keymap.set('n', '<Leader>pl1', require('plugin').action, + { desc = 'Execute action from plugin' }) +< +• `remap`: By default, all mappings are nonrecursive by default (i.e., + |vim.keymap.set()| behaves like |:noremap|). If the {rhs} is itself a mapping + that should be executed, set `remap = true`: >lua + vim.keymap.set('n', '<Leader>ex1', '<cmd>echo "Example 1"<cr>') + -- add a shorter mapping + vim.keymap.set('n', 'e', '<Leader>ex1', { remap = true }) +< + Note: |<Plug>| mappings are always expanded even with the default `remap = false`: >lua + vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)') +< +------------------------------------------------------------------------------ +Removing mappings *lua-guide-mappings-del* + +A specific mapping can be removed with |vim.keymap.del()|: +>lua + vim.keymap.del('n', '<Leader>ex1') + vim.keymap.del({'n', 'c'}, '<Leader>ex2', {buffer = true}) +< +------------------------------------------------------------------------------ +See also: +• `vim.api.`|nvim_get_keymap()|: return all global mapping +• `vim.api.`|nvim_buf_get_keymap()|: return all mappings for buffer + +============================================================================== +Autocommands *lua-guide-autocommands* + +An |autocommand| is a Vim command or a Lua function that is automatically +executed whenever one or more |events| are triggered, e.g., when a file is +read or written, or when a window is created. These are accessible from Lua +through the Neovim API. + +------------------------------------------------------------------------------ +Creating autocommands *lua-guide-autocommand-create* + +Autocommands are created using `vim.api.`|nvim_create_autocmd()|, which takes +two mandatory arguments: +• {event}: a string or table of strings containing the event(s) which should + trigger the command or function. +• {opts}: a table with keys that control what should happen when the event(s) + are triggered. + +The most important options are: + +• `pattern`: A string or table of strings containing the |autocmd-pattern|. + Note: Environment variable like `$HOME` and `~` are not automatically + expanded; you need to explicitly use `vim.fn.`|expand()| for this. +• `command`: A string containing a Vim command. +• `callback`: A Lua function. + +You must specify one and only one of `command` and `callback`. If `pattern` is +omitted, it defaults to `pattern = '*'`. +Examples: +>lua + vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, { + pattern = {"*.c", "*.h"}, + command = "echo 'Entering a C or C++ file'", + }) + + -- Same autocommand written with a Lua function instead + vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, { + pattern = {"*.c", "*.h"}, + callback = function() print("Entering a C or C++ file") end, + }) + + -- User event triggered by MyPlugin + vim.api.nvim_create_autocmd("User", { + pattern = "MyPlugin", + callback = function() print("My Plugin Works!") end, + }) +< + +Neovim will always call a Lua function with a single table containing information +about the triggered autocommand. The most useful keys are +• `match`: a string that matched the `pattern` (see |<amatch>|) +• `buf`: the number of the buffer the event was triggered in (see |<abuf>|) +• `file`: the file name of the buffer the event was triggered in (see |<afile>|) +• `data`: a table with other relevant data that is passed for some events + +For example, this allows you to set buffer-local mappings for some filetypes: +>lua + vim.api.nvim.create_autocmd("FileType", { + pattern = "lua", + callback = function(args) + vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = args.buf }) + end + }) +< +This means that if your callback itself takes an (even optional) argument, you +must wrap it in `function() end` to avoid an error: +>lua + vim.api.nvim_create_autocmd('TextYankPost', { + callback = function() vim.highlight.on_yank() end + }) +< +(Since unused arguments can be omitted in Lua function definitions, this is +equivalent to `function(args) ... end`.) + +Instead of using a pattern, you can create a buffer-local autocommand (see +|autocmd-buflocal|) with `buffer`; in this case, `pattern` cannot be used: +>lua + -- set autocommand for current buffer + vim.api.nvim_create_autocmd("CursorHold", { + buffer = 0, + callback = function() print("hold") end, + }) + + -- set autocommand for buffer number 33 + vim.api.nvim_create_autocmd("CursorHold", { + buffer = 33, + callback = function() print("hold") end, + }) +< +Similarly to mappings, you can (and should) add a description using `desc`: +>lua + vim.api.nvim_create_autocmd('TextYankPost', { + callback = function() vim.highlight.on_yank() end, + desc = "Briefly highlight yanked text" + }) +< +Finally, you can group autocommands using the `group` key; this will be +covered in detail in the next section. + +------------------------------------------------------------------------------ +Grouping autocommands *lua-guide-autocommands-group* + +Autocommand groups can be used to group related autocommands together; see +|autocmd-groups|. This is useful for organizing autocommands and especially +for preventing autocommands to be set multiple times. + +Groups can be created with `vim.api.`|nvim_create_augroup()|. This function +takes two mandatory arguments: a string with the name of a group and a table +determining whether the group should be cleared (i.e., all grouped +autocommands removed) if it already exists. The function returns a number that +is the internal identifier of the group. Groups can be specified either by +this identifier or by the name (but only if the group has been created first). + +For example, a common Vimscript pattern for autocommands defined in files that +may be reloaded is +>vim + augroup vimrc + " Remove all vimrc autocommands + autocmd! + au BufNewFile,BufRead *.html set shiftwidth=4 + au BufNewFile,BufRead *.html set expandtab + augroup END +< +This is equivalent to the following Lua code: +>lua + local mygroup = vim.api.nvim_create_augroup('vimrc', { clear = true }) + vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, { + pattern = '*.html', + group = mygroup, + command = 'set shiftwidth=4', + }) + vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, { + pattern = '*.html', + group = 'vimrc', -- equivalent to group=mygroup + command = 'set expandtab', + }) +< +Autocommand groups are unique for a given name, so you can reuse them, e.g., +in a different file: +>lua + local mygroup = vim.api.nvim_create_augroup('vimrc', { clear = false }) + vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, { + pattern = '*.html', + group = mygroup, + command = 'set shiftwidth=4', + }) +< +------------------------------------------------------------------------------ +Deleting autocommands *lua-guide-autocommands-delete* + +You can use `vim.api.`|nvim_clear_autocmds()| to remove autocommands. This +function takes a single mandatory argument that is a table of keys describing +the autocommands that are to be removed: +>lua + -- Delete all BufEnter and InsertLeave autocommands + vim.api.nvim_clear_autocmds({event = {"BufEnter", "InsertLeave"}}) + + -- Delete all autocommands that uses "*.py" pattern + vim.api.nvim_clear_autocmds({pattern = "*.py"}) + + -- Delete all autocommands in group "scala" + vim.api.nvim_clear_autocmds({group = "scala"}) + + -- Delete all ColorScheme autocommands in current buffer + vim.api.nvim_clear_autocmds({event = "ColorScheme", buffer = 0 }) +< +Note: Autocommands in groups will only be removed if the `group` key is +specified, even if another option matches it. + +------------------------------------------------------------------------------ +See also +• |nvim_get_autocmds()|: return all matching autocommands +• |nvim_exec_autocmds()|: execute all matching autocommands + +============================================================================== +User commands *lua-guide-usercommands* + +|user-commands| are custom Vim commands that call a Vimscript or Lua function. +Just like built-in commands, they can have arguments, act on ranges, or have +custom completion of arguments. As these are most useful for plugins, we will +cover only the basics of this advanced topic. + +------------------------------------------------------------------------------ +Creating user commands *lua-guide-usercommands-create* + +User commands can be created through the Neovim API with +`vim.api.`|nvim_create_user_command()|. This function takes three mandatory +arguments: +• a string that is the name of the command (which must start with an uppercase + letter to distinguish it from builtin commands); +• a string containing Vim commands or a Lua function that is executed when the + command is invoked; +• a table with |command-attributes|; in addition, it can contain the keys + `desc` (a string describing the command); `force` (set to `false` to avoid + replacing an already existing command with the same name), and `preview` (a + Lua function that is used for |:command-preview|). + +Example: +>lua + vim.api.nvim_create_user_command('Test', 'echo "It works!"', {}) + vim.cmd.Test() + --> It works! +< +(Note that the third argument is mandatory even if no attributes are given.) + +Lua functions are called with a single table argument containing arguments and +modifiers. The most important are: +• `name`: a string with the command name +• `fargs`: a table containing the command arguments split by whitespace (see |<f-args>|) +• `bang`: `true` if the command was executed with a `!` modifier (see |<bang>|) +• `line1`: the starting line number of the command range (see |<line1>|) +• `line2`: the final line number of the command range (see |<line2>|) +• `range`: the number of items in the command range: 0, 1, or 2 (see |<range>|) +• `count`: any count supplied (see |<count>|) +• `smods`: a table containing the command modifiers (see |<mods>|) + +For example: +>lua + vim.api.nvim_create_user_command('Upper', + function(opts) + print(string.upper(opts.fargs[1])) + end, + { nargs = 1 }) + + vim.cmd.Upper('foo') + --> FOO +< +The `complete` attribute can take a Lua function in addition to the +attributes listed in |:command-complete|. >lua + + vim.api.nvim_create_user_command('Upper', + function(opts) + print(string.upper(opts.fargs[1])) + end, + { nargs = 1, + complete = function(ArgLead, CmdLine, CursorPos) + -- return completion candidates as a list-like table + return { "foo", "bar", "baz" } + end, + }) +< +Buffer-local user commands are created with `vim.api.`|nvim_buf_create_user_command()|. +Here the first argument is the buffer number (`0` being the current buffer); +the remaining arguments are the same as for |nvim_create_user_command()|: +>lua + vim.api.nvim_buf_create_user_command(0, 'Upper', + function(opts) + print(string.upper(opts.fargs[1])) + end, + { nargs = 1 }) +< +------------------------------------------------------------------------------ +Deleting user commands *lua-guide-usercommands-delete* + +User commands can be deleted with `vim.api.`|nvim_del_user_command()|. The only +argument is the name of the command: +>lua + vim.api.nvim_del_user_command('Upper') +< +To delete buffer-local user commands use `vim.api.`|nvim_buf_del_user_command()|. +Here the first argument is the buffer number (`0` being the current buffer), +and second is command name: +>lua + vim.api.nvim_buf_del_user_command(4, 'Upper') +< +============================================================================== +Credits *lua-guide-credits* +This guide is in large part taken from nanotee's Lua guide: +https://github.com/nanotee/nvim-lua-guide + +Thank you @nanotee! + +vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl: |