Movatterモバイル変換


[0]ホーム

URL:


Lua-guide

Nvim:help pages,generated fromsource using thetree-sitter-vimdoc parser.


Guide to using Lua in Nvim

Introduction

This guide introduces the basics of everyday Lua usage for configuring andcontrolling Nvim. It assumes some familiarity with the (non-Lua) basics ofNvim (commands, options, mappings, autocommands), which are covered in theuser-manual.
This is not a comprehensive encyclopedia of all available features. Think ofit as a survival kit: the bare minimum needed to comfortably get started onusing Lua in Nvim.
Seelua-plugin for guidance on developing Lua plugins.Seeluaref andlua-concepts for details on the Lua programming language.

Some words on the APIlua-guide-api

The purpose of this guide is to introduce the different ways of interactingwith Nvim through Lua (the "API"). This API consists of three differentlayers:
1. The "Vim API" inherited from Vim:Ex-commands andvimscript-functions as well asuser-functions in Vimscript. These are accessed throughvim.cmd() andvim.fn respectively, which are discussed underlua-guide-vimscript below.
2. The "Nvim API" written in C for use in remote plugins and GUIs; seeapi. These functions are accessed throughvim.api.
3. The "Lua API" written in and specifically for Lua. These are any other functions accessible throughvim.* not mentioned already; seelua-stdlib.
This distinction is important, as API functions inherit behavior from theiroriginal layer: For example, Nvim API functions always need all arguments tobe specified even if Lua itself allows omitting arguments (which are thenpassed asnil); and Vim API functions can use 0-based indexing even if Luaarrays are 1-indexed by default.
Through this, any possible interaction can be done through Lua without writinga complete new API from scratch. For this reason, functions are usually notduplicated between layers unless there is a significant benefit infunctionality or performance (e.g., you can map Lua functions directly throughnvim_create_autocmd() but not through:autocmd). In case there are multipleways of achieving the same thing, this guide will only cover what is mostconvenient to use from Lua.

Using Lualua-guide-using-Lua

To run Lua code from the Nvim command line, use the:lua command:
:lua print("Hello!")
Note: each:lua command has its own scope and variables declared with thelocal keyword are not accessible outside of the command. This won't work:
:lua local foo = 1:lua print(foo)" prints "nil" instead of "1"
You can also use:lua=, which is equivalent to:lua vim.print(...), toconveniently check the value of a variable or a table:
:lua =package
To run a Lua script in an external file, you can use the:source commandexactly like for a Vimscript file:
:source ~/programs/baz/myluafile.lua
Finally, you can include Lua code in a Vimscript file by putting it inside a:lua-heredoc block:
lua << EOF  local tbl = {1, 2, 3}  for k, v in ipairs(tbl) do    print(v)  endEOF

Using Lua files on startuplua-guide-config

Nvim supports usinginit.vim orinit.lua as the configuration file, butnot both at the same time. This should be placed in yourconfig directory(run:echo stdpath('config') to see where it is). Note that you can also useLua ininit.vim and Vimscript ininit.lua, which will be covered below.
If you'd like to run any other Lua script onstartup automatically, then youcan simply put it inplugin/ in your'runtimepath'.

Lua moduleslua-guide-modules

If you want to load Lua files on demand, you can place them in thelua/directory in your'runtimepath' and load them withrequire. (This is theLua equivalent of Vimscript'sautoload 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 loadmyluamodule.lua:
require("myluamodule")
Note the absence of a.lua extension.
Similarly, loadingother_modules/anothermodule.lua is done via
require('other_modules/anothermodule')-- orrequire('other_modules.anothermodule')
Note how "submodules" are just subdirectories; the. is equivalent to thepath separator/ (even on Windows).
A folder containing aninit.lua file can be required directly, withouthaving to specify the name of the file:
require('other_modules') -- loads other_modules/init.lua
Requiring a nonexistent module or a module which contains syntax errors abortsthe currently executing script.pcall() may be used to catch such errors. Thefollowing example tries to load themodule_with_error and only calls one ofits functions if this succeeds and prints an error message otherwise:
local ok, mymod = pcall(require, 'module_with_error')if not ok then  print("Module had an error")else  mymod.func()end
In contrast to:source,require() not only searches through alllua/ directoriesunder'runtimepath', it also caches the module on first use. Callingrequire() a second time will therefore _not_ execute the script again andinstead return the cached file. To rerun the file, you need to remove it fromthe cache manually first:
package.loaded['myluamodule'] = nilrequire('myluamodule')    -- read and execute the module again from disk

See also:

lua-module-load: howrequire() finds modules
pcall()

Using Vim commands and functions from Lualua-guide-vimscript

All Vim commands and functions are accessible from Lua.

Vim commandslua-guide-vim-commands

To run an arbitrary Vim command from Lua, pass it as a string tovim.cmd():
vim.cmd("colorscheme habamax")
Note that special characters will need to be escaped with backslashes:
vim.cmd("%s/\\Vfoo/bar/g")
An alternative is to use a literal string (seelua-literal) delimited bydouble brackets[[ ]] as in
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 ofvim.cmd():
vim.cmd([[  highlight Error guibg=red  highlight link Warning Error]])
This is the converse of:lua-heredoc and allows you to include Vimscriptcode in yourinit.lua.
If you want to build your Vim command programmatically, the following form canbe useful (all these are equivalent to the corresponding line above):
vim.cmd.colorscheme("habamax")vim.cmd.highlight({ "Error", "guibg=red" })vim.cmd.highlight({ "link", "Warning", "Error" })

Vimscript functionslua-guide-vim-functions

Usevim.fn to call Vimscript functions from Lua. Data types between Lua andVimscript are automatically converted:
print(vim.fn.printf('Hello from %s', 'Lua'))local reversed_list = vim.fn.reverse({ 'a', 'b', 'c' })vim.print(reversed_list) -- { "c", "b", "a" }local function print_stdout(chan_id, data, name)  print(data[1])endvim.fn.jobstart('ls', { on_stdout = print_stdout })
This works for bothvimscript-functions anduser-functions.
Note that hashes (#) are not valid characters for identifiers in Lua, so,e.g.,autoload functions have to be called with this syntax:
vim.fn['my#autoload#function']()

See also:

vimscript-functions: descriptions of all Vimscript functions
function-list: Vimscript functions grouped by topic
:runtime: run all Lua scripts matching a pattern in'runtimepath'

Variableslua-guide-variables

Variables can be set and read using the following wrappers, which directlycorrespond to theirvariable-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:
vim.g.some_global_variable = {  key1 = "value",  key2 = 300}vim.print(vim.g.some_global_variable)--> { key1 = "value", key2 = 300 }
You can target specific buffers (via number), windows (viawindow-ID), ortabpages by indexing the wrappers:
vim.b[2].myvar = 1               -- set myvar for buffer number 2vim.w[1005].myothervar = true    -- set myothervar for window ID 1005
Some variable names may contain characters that cannot be used for identifiersin Lua. You can still manipulate these variables by using the syntax
vim.g['my#variable'] = 1
Note that you cannot directly change fields of array variables. This won'twork:
vim.g.some_global_variable.key2 = 400vim.print(vim.g.some_global_variable)--> { key1 = "value", key2 = 300 }
Instead, you need to create an intermediate Lua table and change this:
local temp_table = vim.g.some_global_variabletemp_table.key2 = 400vim.g.some_global_variable = temp_tablevim.print(vim.g.some_global_variable)--> { key1 = "value", key2 = 400 }
To delete a variable, simply set it tonil:
vim.g.myvar = nil

See also:

lua-vim-variables

Optionslua-guide-options

There are two complementary ways of settingoptions via Lua.

vim.opt

The most convenient way for setting global and local options, e.g., ininit.lua,is throughvim.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
set smarttabset nosmarttab
are equivalent to
vim.opt.smarttab = truevim.opt.smarttab = false
In particular, they allow an easy way to working with list-like, map-like, andset-like options through Lua tables: Instead of
set wildignore=*.o,*.a,__pycache__set listchars=space:_,tab:>~set formatoptions=njt
you can use
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:
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 mustusevim.opt:get():
print(vim.opt.smarttab)--> {...} (big table)print(vim.opt.smarttab:get())--> falsevim.print(vim.opt.listchars:get())--> { space = '_', tab = '>~' }

vim.o

For this reason, there exists a more direct variable-like access usingvim.oand friends, similarly to how you can get and set options via:echo &numberand: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 (can be double indexed)
For example:
vim.o.smarttab = false -- :set nosmarttabprint(vim.o.smarttab)--> falsevim.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=4print(vim.bo.shiftwidth)--> 4
Just like variables, you can specify a buffer number orwindow-ID for bufferand window options, respectively. If no number is given, the current buffer orwindow is used:
vim.bo[4].expandtab = true -- sets expandtab to true in buffer 4vim.wo.number = true       -- sets number to true in current windowvim.wo[0].number = true    -- same as abovevim.wo[0][0].number = true -- sets number to true in current buffer                           -- in current window onlyprint(vim.wo[0].number)    --> true

See also:

lua-options

Mappingslua-guide-mappings

You can map either Vim commands or Lua functions to key sequences.

Creating mappingslua-guide-mappings-set

Mappings can be created usingvim.keymap.set(). This function takes threemandatory 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:
-- Normal mode mapping for Vim commandvim.keymap.set('n', '<Leader>ex1', '<cmd>echo "Example 1"<cr>')-- Normal and Command-line mode mapping for Vim commandvim.keymap.set({'n', 'c'}, '<Leader>ex2', '<cmd>echo "Example 2"<cr>')-- Normal mode mapping for Lua functionvim.keymap.set('n', '<Leader>ex3', vim.treesitter.start)-- Normal mode mapping for Lua function with argumentsvim.keymap.set('n', '<Leader>ex4', function() print('Example 4') end)
You can map functions from Lua modules via
vim.keymap.set('n', '<Leader>pl1', require('plugin').action)
Note that this loads the plugin at the time the mapping is defined. If youwant to defer the loading to the time when the mapping is executed (as forautoload functions), wrap it infunction() end:
vim.keymap.set('n', '<Leader>pl2', function() require('plugin').action() end)
The fourth, optional, argument is a table with keys that modify the behaviorof the mapping such as those from:map-arguments. The following are the mostuseful options:
buffer: If given, only set the mapping for the buffer with the specified number;0 ortrue means the current buffer.
-- set mapping for the current buffervim.keymap.set('n', '<Leader>pl1', require('plugin').action, { buffer = true })-- set mapping for the buffer number 4vim.keymap.set('n', '<Leader>pl1', require('plugin').action, { buffer = 4 })
silent: If set totrue, suppress output such as error messages.
vim.keymap.set('n', '<Leader>pl1', require('plugin').action, { silent = true })
expr: If set totrue, do not execute the{rhs} but use the return value as input. Specialkeycodes are converted automatically. For example, the following mapping replaces<down> with<c-n> in the popupmenu only:
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 asLua: <number> <source file>:<line>. Plugins should therefore always use this for mappings they create.
vim.keymap.set('n', '<Leader>pl1', require('plugin').action,  { desc = 'Execute action from plugin' })
remap: By default, all mappings are nonrecursive (i.e.,vim.keymap.set() behaves like:noremap). If the{rhs} is itself a mapping that should be executed, setremap = true:
vim.keymap.set('n', '<Leader>ex1', '<cmd>echo "Example 1"<cr>')-- add a shorter mappingvim.keymap.set('n', 'e', '<Leader>ex1', { remap = true })
Note:<Plug> mappings are always expanded even with the defaultremap = false:
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')

Removing mappingslua-guide-mappings-del

A specific mapping can be removed withvim.keymap.del():
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

Autocommandslua-guide-autocommands

Anautocommand is a Vim command or a Lua function that is automaticallyexecuted whenever one or moreevents are triggered, e.g., when a file isread or written, or when a window is created. These are accessible from Luathrough the Nvim API.

Creating autocommandslua-guide-autocommand-create

Autocommands are created usingvim.api.nvim_create_autocmd(), which takestwo 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 theautocmd-pattern. Note: Environment variable like$HOME and~ are not automatically expanded; you need to explicitly usevim.fn.expand() for this.
command: A string containing a Vim command.
callback: A Lua function.
You must specify one and only one ofcommand andcallback. Ifpattern isomitted, it defaults topattern = '*'.Examples:
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 insteadvim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {  pattern = {"*.c", "*.h"},  callback = function() print("Entering a C or C++ file") end,})-- User event triggered by MyPluginvim.api.nvim_create_autocmd("User", {  pattern = "MyPlugin",  callback = function() print("My Plugin Works!") end,})
Nvim will always call a Lua function with a single table containing informationabout the triggered autocommand. The most useful keys are
match: a string that matched thepattern (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:
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, youmust wrap it infunction() end to avoid an error:
vim.api.nvim_create_autocmd('TextYankPost', {  callback = function() vim.hl.on_yank() end})
(Since unused arguments can be omitted in Lua function definitions, this isequivalent tofunction(args) ... end.)
Instead of using a pattern, you can create a buffer-local autocommand (seeautocmd-buflocal) withbuffer; in this case,pattern cannot be used:
-- set autocommand for current buffervim.api.nvim_create_autocmd("CursorHold", {  buffer = 0,  callback = function() print("hold") end,})-- set autocommand for buffer number 33vim.api.nvim_create_autocmd("CursorHold", {  buffer = 33,  callback = function() print("hold") end,})
Similarly to mappings, you can (and should) add a description usingdesc:
vim.api.nvim_create_autocmd('TextYankPost', {  callback = function() vim.hl.on_yank() end,  desc = "Briefly highlight yanked text"})
Finally, you can group autocommands using thegroup key; this will becovered in detail in the next section.

Grouping autocommandslua-guide-autocommands-group

Autocommand groups can be used to group related autocommands together; seeautocmd-groups. This is useful for organizing autocommands and especiallyfor preventing autocommands to be set multiple times.
Groups can be created withvim.api.nvim_create_augroup(). This functiontakes two mandatory arguments: a string with the name of a group and a tabledetermining whether the group should be cleared (i.e., all groupedautocommands removed) if it already exists. The function returns a number thatis the internal identifier of the group. Groups can be specified either bythis 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 thatmay be reloaded is
augroup vimrc  " Remove all vimrc autocommands  autocmd!  au BufNewFile,BufRead *.html set shiftwidth=4  au BufNewFile,BufRead *.html set expandtabaugroup END
This is equivalent to the following Lua code:
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:
local mygroup = vim.api.nvim_create_augroup('vimrc', { clear = false })vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, {  pattern = '*.c',  group = mygroup,  command = 'set noexpandtab',})

Deleting autocommandslua-guide-autocommands-delete

You can usevim.api.nvim_clear_autocmds() to remove autocommands. Thisfunction takes a single mandatory argument that is a table of keys describingthe autocommands that are to be removed:
-- Delete all BufEnter and InsertLeave autocommandsvim.api.nvim_clear_autocmds({event = {"BufEnter", "InsertLeave"}})-- Delete all autocommands that uses "*.py" patternvim.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 buffervim.api.nvim_clear_autocmds({event = "ColorScheme", buffer = 0 })
Note: Autocommands in groups will only be removed if thegroup key isspecified, even if another option matches it.

See also

nvim_get_autocmds(): return all matching autocommands
nvim_exec_autocmds(): execute all matching autocommands

User commandslua-guide-commands

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 havecustom completion of arguments. As these are most useful for plugins, we willcover only the basics of this advanced topic.

Creating user commandslua-guide-commands-create

User commands can be created vianvim_create_user_command(). This functiontakes 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 withcommand-attributes; in addition, it can contain the keysdesc (a string describing the command);force (set tofalse to avoid replacing an already existing command with the same name), andpreview (a Lua function that is used for:command-preview).
Example:
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 andmodifiers. 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:
vim.api.nvim_create_user_command('Upper',  function(opts)    print(string.upper(opts.fargs[1]))  end,  { nargs = 1 })vim.cmd.Upper('foo')--> FOO
Thecomplete attribute can take a Lua function in addition to theattributes listed in:command-complete.
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 withvim.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 fornvim_create_user_command():
vim.api.nvim_buf_create_user_command(0, 'Upper',  function(opts)    print(string.upper(opts.fargs[1]))  end,  { nargs = 1 })

Deleting user commandslua-guide-commands-delete

User commands can be deleted withvim.api.nvim_del_user_command(). The onlyargument is the name of the command:
vim.api.nvim_del_user_command('Upper')
To delete buffer-local user commands usevim.api.nvim_buf_del_user_command().Here the first argument is the buffer number (0 being the current buffer),and second is command name:
vim.api.nvim_buf_del_user_command(4, 'Upper')

Creditslua-guide-credits

This guide is in large part taken from nanotee's Lua guide:https://github.com/nanotee/nvim-lua-guide
Thank you @nanotee!
Main
Commands index
Quick reference

Introduction
Some words on the API
Using Lua
Using Lua files on startup
Lua modules
See also:
Using Vim commands and functions from Lua
Vim commands
Vimscript functions
See also:
Variables
See also:
Options
vim.opt
vim.o
See also:
Mappings
Creating mappings
Removing mappings
See also:
Autocommands
Creating autocommands
Grouping autocommands
Deleting autocommands
See also
User commands
Creating user commands
Deleting user commands
Credits

[8]ページ先頭

©2009-2025 Movatter.jp