aboutsummaryrefslogtreecommitdiff
path: root/runtime/doc/lua-guide.txt
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /runtime/doc/lua-guide.txt
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-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.txt757
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: