Luaガイド

Nvim :help ページは、このスクリプト によって ソース から tree-sitter-vimdoc パーサーを使用して生成されます。


NvimにおけるLuaの使い方ガイド

はじめに

このガイドでは、NvimでLuaを使用する際の基本について説明します。利用可能なすべての機能を網羅した百科事典のようなものでも、すべての詳細を説明するものでもありません。サバイバルキット、つまりNvimでLuaを使い始めるために快適に知っておくべき必要最小限のものと考えてください。
重要な注意点として、これはLua言語自体のガイドではありません。むしろ、Lua言語と、それを支援するために提供する関数を通じて、Nvimを設定および変更する方法についてのガイドです。Lua自体について詳しく知りたい場合は、luareflua-concepts を参照してください。同様に、このガイドでは、Nvimの基本(コマンド、オプション、マッピング、自動コマンド)についてある程度の知識があることを前提としています。これらについては、ユーザーマニュアルで説明されています。

APIについて lua-guide-api

このガイドの目的は、Luaを通じてNvimと対話するさまざまな方法(「API」)を紹介することです。このAPIは、3つの異なる層で構成されています。
1. Vimから継承された「Vim API」: Exコマンド組み込み関数、そしてVimscriptの ユーザー定義関数。これらは、それぞれ vim.cmd()vim.fn を通じてアクセスされます。これらについては、以下の lua-guide-vimscript で説明します。
2. リモートプラグインとGUIで使用するためにCで書かれた「Nvim API」: api を参照してください。これらの関数は、vim.api を通じてアクセスされます。
3. Luaで書かれ、Lua専用の「Lua API」。これらは、既に述べた以外の vim.* を通じてアクセス可能な他のすべての関数です。 lua-stdlib を参照してください。
この区別は重要です。API関数は元の層から動作を継承するためです。たとえば、Nvim API関数は、Lua自体が引数の省略を許可している場合でも(その場合、nil として渡されます)、常にすべての引数を指定する必要があります。また、Vim API関数は、Lua配列のデフォルトが1始まりである場合でも、0始まりのインデックスを使用できます。
これにより、まったく新しいAPIを最初から作成することなく、Luaを通じてあらゆる可能なインタラクションを実行できます。このため、機能やパフォーマンスに大きなメリットがない限り、通常、関数は層間で重複しません(たとえば、Lua関数は nvim_create_autocmd() を通じて直接マップできますが、:autocmd を通じてはマップできません)。同じことを実現する複数の方法がある場合、このガイドでは、Luaから使用するのが最も便利な方法のみを説明します。

Luaの使い方 lua-guide-using-Lua

NvimコマンドラインからLuaコードを実行するには、:lua コマンドを使用します。
:lua print("Hello!")
注意::lua コマンドは独自のスコープを持ち、localキーワードで宣言された変数はコマンドの外部からはアクセスできません。これは機能しません。
:lua local foo = 1
:lua print(foo)
" prints "nil" instead of "1"
また、:lua= を使用することもできます。これは :lua vim.print(...) と同等であり、変数またはテーブルの値を簡単に確認できます。
:lua =package
外部ファイルのLuaスクリプトを実行するには、Vimscriptファイルとまったく同じように :source コマンドを使用できます。
:source ~/programs/baz/myluafile.lua
最後に、:lua-heredoc ブロック内に配置することで、VimscriptファイルにLuaコードを含めることができます。
lua << EOF
  local tbl = {1, 2, 3}
  for k, v in ipairs(tbl) do
    print(v)
  end
EOF

起動時にLuaファイルを使用する lua-guide-config

Nvimは、設定ファイルとして init.vim または init.lua を使用することをサポートしていますが、両方を同時に使用することはできません。これは、設定 ディレクトリに配置する必要があります。これは、通常、Linux、BSD、またはmacOSの場合は ~/.config/nvim、Windowsの場合は ~/AppData/Local/nvim/ です。 init.vim でLuaを、init.lua でVimscriptを使用できます。これについては、以下で説明します。
起動 時に他のLuaスクリプトを自動的に実行する場合は、'runtimepath'plugin/ に配置するだけです。

Luaモジュール lua-guide-modules

Luaファイルをオンデマンドでロードする場合は、'runtimepath'lua/ ディレクトリに配置し、require でロードできます。(これは、Vimscriptの autoload メカニズムに相当するLuaです。)
次のディレクトリ構造があるとします。
~/.config/nvim
|-- after/
|-- ftplugin/
|-- lua/
|   |-- myluamodule.lua
|   |-- other_modules/
|       |-- anothermodule.lua
|       |-- init.lua
|-- plugin/
|-- syntax/
|-- init.vim
すると、次のLuaコードは myluamodule.lua をロードします。
require("myluamodule")
.lua 拡張子が存在しないことに注意してください。
同様に、other_modules/anothermodule.lua のロードは、次のように行います。
require('other_modules/anothermodule')
-- or
require('other_modules.anothermodule')
「サブモジュール」は単なるサブディレクトリであることに注意してください。 . は、パス区切り文字 / と同等です(Windowsでも)。
init.lua ファイルを含むフォルダは、ファイル名を指定せずに直接requireできます。
require('other_modules') -- loads other_modules/init.lua
存在しないモジュール、または構文エラーを含むモジュールをrequireすると、現在実行中のスクリプトが中止されます。 pcall() を使用して、そのようなエラーをキャッチできます。次の例では、module_with_error をロードしようとし、これが成功した場合にのみその関数の1つを呼び出し、そうでない場合はエラーメッセージを出力します。
local ok, mymod = pcall(require, 'module_with_error')
if not ok then
  print("Module had an error")
else
  mymod.function()
end
:source とは対照的に、require() は、'runtimepath' の下のすべての lua/ ディレクトリを検索するだけでなく、最初に使用したときにモジュールをキャッシュします。したがって、require() を2回目に呼び出すと、スクリプトは _再実行されず_、キャッシュされたファイルが返されます。ファイルを再実行するには、最初に手動でキャッシュから削除する必要があります。
package.loaded['myluamodule'] = nil
require('myluamodule')    -- read and execute the module again from disk

関連項目

LuaからVimコマンドと関数を使用する lua-guide-vimscript

すべてのVimコマンドと関数は、Luaからアクセスできます。

Vimコマンド lua-guide-vim-commands

Luaから任意のVimコマンドを実行するには、それを文字列として vim.cmd() に渡します。
vim.cmd("colorscheme habamax")
特殊文字はバックスラッシュでエスケープする必要があることに注意してください。
vim.cmd("%s/\\Vfoo/bar/g")
別の方法として、二重角かっこ [[ ]] で区切られたリテラル文字列(lua-literal を参照)を使用する方法があります。
vim.cmd([[%s/\Vfoo/bar/g]])
リテラル文字列を使用するもう1つの利点は、複数行にできることです。これにより、vim.cmd() の1回の呼び出しに複数のコマンドを渡すことができます。
vim.cmd([[
  highlight Error guibg=red
  highlight link Warning Error
]])
これは :lua-heredoc の逆であり、init.lua にVimscriptコードを含めることができます。
Vimコマンドをプログラムで構築する場合は、次の形式が役立ちます(これらはすべて、上記の対応する行と同等です)。
vim.cmd.colorscheme("habamax")
vim.cmd.highlight({ "Error", "guibg=red" })
vim.cmd.highlight({ "link", "Warning", "Error" })

Vimscript関数 lua-guide-vim-functions

LuaからVimscript関数を呼び出すには、vim.fn を使用します。LuaとVimscript間のデータ型は自動的に変換されます。
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])
end
vim.fn.jobstart('ls', { on_stdout = print_stdout })
これは、組み込み関数ユーザー定義関数 の両方で機能します。
ハッシュ(#)はLuaの識別子として有効な文字ではないため、たとえば、autoload 関数は、この構文で呼び出す必要があることに注意してください。
vim.fn['my#autoload#function']()

関連項目

組み込み関数: すべてのVimscript関数のアルファベット順リスト
function-list: トピック別にグループ化されたすべてのVimscript関数のリスト
:runtime: 'runtimepath' 内のパターンに一致するすべてのLuaスクリプトを実行します
package.path: require() によって検索されるすべてのパスのリスト
変数は、次のラッパーを使用して設定および読み取りできます。これらは、変数のスコープ に直接対応します。
vim.g: グローバル変数 (g:)
vim.b: 現在のバッファの変数 (b:)
vim.w: 現在のウィンドウの変数 (w:)
vim.t: 現在のタブページの変数 (t:)
vim.v: あらかじめ定義されたVim変数 (v:)
vim.env: エディターセッションで定義された環境変数
データ型は自動的に変換されます。例えば
vim.g.some_global_variable = {
  key1 = "value",
  key2 = 300
}
vim.print(vim.g.some_global_variable)
--> { key1 = "value", key2 = 300 }
ラッパーにインデックスを付けることで、特定のバッファ(番号経由)、ウィンドウ(window-ID 経由)、またはタブページをターゲットにできます。
vim.b[2].myvar = 1               -- set myvar for buffer number 2
vim.w[1005].myothervar = true    -- set myothervar for window ID 1005
一部の変数名には、Luaの識別子に使用できない文字が含まれている場合があります。これらの変数は、次の構文を使用して操作できます。
vim.g['my#variable'] = 1
配列変数のフィールドを直接変更することはできないことに注意してください。これは機能しません。
vim.g.some_global_variable.key2 = 400
vim.print(vim.g.some_global_variable)
--> { key1 = "value", key2 = 300 }
代わりに、中間Luaテーブルを作成して、これを変更する必要があります。
local temp_table = vim.g.some_global_variable
temp_table.key2 = 400
vim.g.some_global_variable = temp_table
vim.print(vim.g.some_global_variable)
--> { key1 = "value", key2 = 400 }
変数を削除するには、単に nil に設定します。
vim.g.myvar = nil

関連項目

オプション lua-guide-options

Luaを介して オプション を設定するには、2つの補完的な方法があります。

vim.opt

グローバルオプションとローカルオプションを設定するための最も便利な方法は、たとえば init.lua では、vim.opt などを使用することです。
vim.opt: :set のように動作します
vim.opt_global: :setglobal のように動作します
vim.opt_local: :setlocal のように動作します
たとえば、Vimscriptコマンド
set smarttab
set nosmarttab
は、次と同等です。
vim.opt.smarttab = true
vim.opt.smarttab = false
特に、Luaテーブルを通じてリストのような、マップのような、セットのようなオプションを簡単に操作できます。次のようにする代わりに
set wildignore=*.o,*.a,__pycache__
set listchars=space:_,tab:>~
set formatoptions=njt
次のように使用できます。
vim.opt.wildignore = { '*.o', '*.a', '__pycache__' }
vim.opt.listchars = { space = '_', tab = '>~' }
vim.opt.formatoptions = { n = true, j = true, t = true }
これらのラッパーには、Vimscriptの :set+=:set^=:set-= に相当するものと同様に機能するメソッドも用意されています。
vim.opt.shortmess:append({ I = true })
vim.opt.wildignore:prepend('*.o')
vim.opt.whichwrap:remove({ 'b', 's' })
代償として、オプション値に直接アクセスすることはできず、vim.opt:get() を使用する必要があることです。
print(vim.opt.smarttab)
--> {...} (big table)
print(vim.opt.smarttab:get())
--> false
vim.print(vim.opt.listchars:get())
--> { space = '_', tab = '>~' }

vim.o

このため、:echo &number:let &listchars='space:_,tab:>~' を介してオプションを取得および設定する方法と同様に、vim.o などを使用してより直接的な変数のようなアクセスが存在します。
vim.o: :set のように動作します
vim.go: :setglobal のように動作します
vim.bo: バッファスコープのオプション用
vim.wo: ウィンドウスコープのオプション用(二重にインデックスを付けることができます)
例えば
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
変数と同様に、バッファオプションとウィンドウオプションにそれぞれバッファ番号または window-ID を指定できます。番号が指定されていない場合は、現在のバッファまたはウィンドウが使用されます。
vim.bo[4].expandtab = true -- sets expandtab to true in buffer 4
vim.wo.number = true       -- sets number to true in current window
vim.wo[0].number = true    -- same as above
vim.wo[0][0].number = true -- sets number to true in current buffer
                           -- in current window only
print(vim.wo[0].number)    --> true

関連項目

マッピング lua-guide-mappings

VimコマンドまたはLua関数をキーシーケンスにマップできます。

マッピングの作成 lua-guide-mappings-set

マッピングは、vim.keymap.set() を使用して作成できます。この関数は、3つの必須引数を取ります。
{mode} は、マッピングが有効になるモードプレフィックスを含む文字列または文字列のテーブルです。プレフィックスは、:map-modes にリストされているもの、または :map! の場合は「!」、:map の場合は空の文字列です。
{lhs} は、マッピングをトリガーするキーシーケンスを含む文字列です。
{rhs} は、Vim コマンドを含む文字列か、{lhs}が入力されたときに実行されるべき Lua 関数のいずれかです。空の文字列は <Nop> と同等であり、キーを無効にします。
-- 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)
Lua モジュールから関数をマッピングするには、次のようにします。
vim.keymap.set('n', '<Leader>pl1', require('plugin').action)
これはマッピングが定義された時点でプラグインをロードすることに注意してください。マッピングが実行された時点までロードを遅延させたい場合(autoload 関数のように)、function() end でラップします。
vim.keymap.set('n', '<Leader>pl2', function() require('plugin').action() end)
4 番目のオプションの引数は、:map-arguments のようなマッピングの動作を変更するキーを持つテーブルです。最も有用なオプションは以下のとおりです。
buffer: 指定された番号のバッファに対してのみマッピングを設定します。0 または true は現在のバッファを意味します。
-- 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: true に設定すると、エラーメッセージなどの出力を抑制します。
vim.keymap.set('n', '<Leader>pl1', require('plugin').action, { silent = true })
expr: true に設定すると、{rhs} を実行せず、戻り値を入力として使用します。特別な キーコード は自動的に変換されます。たとえば、次のマッピングはポップアップメニューでのみ <down><c-n> に置き換えます。
vim.keymap.set('c', '<down>', function()
  if vim.fn.pumvisible() == 1 then return '<c-n>' end
  return '<down>'
end, { expr = true })
desc: 例えば :map でマッピングを一覧表示する際に表示される文字列です。{rhs} としての Lua 関数は、それ以外の場合は Lua: <number> <source file>:<line> としてのみリストされるため、これは便利です。したがって、プラグインは作成するマッピングに対して常にこれを使用する必要があります。
vim.keymap.set('n', '<Leader>pl1', require('plugin').action,
  { desc = 'Execute action from plugin' })
remap: デフォルトでは、すべてのマッピングは非再帰的です(つまり、vim.keymap.set():noremap のように動作します)。{rhs}自体が実行されるべきマッピングである場合は、remap = true を設定します。
vim.keymap.set('n', '<Leader>ex1', '<cmd>echo "Example 1"<cr>')
-- add a shorter mapping
vim.keymap.set('n', 'e', '<Leader>ex1', { remap = true })
注意: <Plug> マッピングは、デフォルトの remap = false でも常に展開されます。
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')

マッピングの削除 lua-guide-mappings-del

特定のマッピングは vim.keymap.del() で削除できます。
vim.keymap.del('n', '<Leader>ex1')
vim.keymap.del({'n', 'c'}, '<Leader>ex2', {buffer = true})

関連項目

vim.api.nvim_get_keymap(): すべてのグローバルマッピングを返します。
vim.api.nvim_buf_get_keymap(): バッファのすべてのマッピングを返します。

自動コマンド lua-guide-autocommands

自動コマンド は、1 つ以上の イベント がトリガーされるたびに自動的に実行される Vim コマンドまたは Lua 関数です。たとえば、ファイルが読み書きされたとき、またはウィンドウが作成されたときなどです。これらは Lua から Nvim API を介してアクセスできます。

自動コマンドの作成 lua-guide-autocommand-create

自動コマンドは vim.api.nvim_create_autocmd() を使用して作成されます。これは 2 つの必須引数を取ります。
{event}: コマンドまたは関数をトリガーするイベントを含む文字列または文字列のテーブル。
{opts}: イベントがトリガーされたときに何が起こるかを制御するキーを持つテーブル。
最も重要なオプションは以下のとおりです。
pattern: autocmd-pattern を含む文字列または文字列のテーブル。 注意: $HOME~ のような環境変数は自動的に展開されません。これには明示的に vim.fn.expand() を使用する必要があります。
command: Vim コマンドを含む文字列。
callback: Lua 関数。
commandcallback のいずれか 1 つを指定する必要があります。pattern が省略された場合、デフォルトは pattern = '*' です。例
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,
})
Nvim は常に、トリガーされた自動コマンドに関する情報を含む単一のテーブルを使用して Lua 関数を呼び出します。最も有用なキーは以下のとおりです。
match: pattern に一致した文字列(<amatch> を参照)
buf: イベントがトリガーされたバッファの番号(<abuf> を参照)
file: イベントがトリガーされたバッファのファイル名(<afile> を参照)
data: 一部のイベントに渡されるその他の関連データを含むテーブル
たとえば、これにより、一部のファイルタイプに対してバッファローカルマッピングを設定できます。
vim.api.nvim_create_autocmd("FileType", {
  pattern = "lua",
  callback = function(args)
    vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = args.buf })
  end
})
これは、コールバック自体が(オプションの)引数を取る場合、エラーを回避するために function() end でラップする必要があることを意味します。
vim.api.nvim_create_autocmd('TextYankPost', {
  callback = function() vim.hl.on_yank() end
})
(Lua 関数定義では未使用の引数を省略できるため、これは function(args) ... end と同等です。)
パターンを使用する代わりに、buffer を使用してバッファローカルの自動コマンド(autocmd-buflocal を参照)を作成できます。この場合、pattern は使用できません。
-- 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,
})
マッピングと同様に、desc を使用して説明を追加できます(そして追加するべきです)。
vim.api.nvim_create_autocmd('TextYankPost', {
  callback = function() vim.hl.on_yank() end,
  desc = "Briefly highlight yanked text"
})
最後に、group キーを使用して自動コマンドをグループ化できます。これは次のセクションで詳しく説明します。

自動コマンドのグループ化 lua-guide-autocommands-group

自動コマンドグループを使用して、関連する自動コマンドをまとめてグループ化できます。 autocmd-groups を参照してください。これは、自動コマンドを整理し、特に自動コマンドが複数回設定されるのを防ぐのに役立ちます。
グループは vim.api.nvim_create_augroup() で作成できます。この関数は 2 つの必須引数を取ります。グループの名前を持つ文字列と、グループが既に存在する場合にグループをクリアする必要があるかどうか(つまり、すべてのグループ化された自動コマンドを削除するかどうか)を決定するテーブルです。関数は、グループの内部識別子である数値を返します。グループはこの識別子または名前で指定できます(ただし、グループが最初に作成されている場合のみ)。
たとえば、リロードされる可能性のあるファイルで定義された自動コマンドの一般的な Vimscript パターンは次のとおりです。
augroup vimrc
  " Remove all vimrc autocommands
  autocmd!
  au BufNewFile,BufRead *.html set shiftwidth=4
  au BufNewFile,BufRead *.html set expandtab
augroup END
これは、次の 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',
})
自動コマンドグループは、特定の名前に対して一意であるため、たとえば別のファイルで再利用できます。
local mygroup = vim.api.nvim_create_augroup('vimrc', { clear = false })
vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, {
  pattern = '*.c',
  group = mygroup,
  command = 'set noexpandtab',
})

自動コマンドの削除 lua-guide-autocommands-delete

vim.api.nvim_clear_autocmds() を使用して自動コマンドを削除できます。この関数は、削除される自動コマンドを記述するキーのテーブルである単一の必須引数を取ります。
-- 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 })
注意: グループ内の自動コマンドは、別のオプションが一致する場合でも、group キーが指定されている場合にのみ削除されます。

関連項目

nvim_get_autocmds(): 一致するすべての自動コマンドを返します。
nvim_exec_autocmds(): 一致するすべての自動コマンドを実行します。

ユーザーコマンド lua-guide-commands

ユーザーコマンド は、Vimscript または Lua 関数を呼び出すカスタム Vim コマンドです。組み込みコマンドと同様に、引数を持つことができ、範囲に対して動作したり、引数のカスタム補完を持つことができます。これらはプラグインにとって最も役立つため、この高度なトピックの基本のみを説明します。

ユーザーコマンドの作成 lua-guide-commands-create

ユーザーコマンドは nvim_create_user_command() を介して作成できます。この関数は 3 つの必須引数を取ります。
コマンドの名前である文字列(組み込みコマンドと区別するために大文字で始める必要があります)。
コマンドが呼び出されたときに実行される Vim コマンドまたは Lua 関数を含む文字列。
command-attributes を持つテーブル。さらに、キー desc(コマンドを記述する文字列)、forcefalse に設定して、同じ名前の既存のコマンドの置き換えを回避します)、および preview:command-preview に使用される Lua 関数)を含めることができます。
vim.api.nvim_create_user_command('Test', 'echo "It works!"', {})
vim.cmd.Test()
--> It works!
(属性が指定されていない場合でも、3 番目の引数は必須であることに注意してください。)
Lua 関数は、引数と修飾子を含む単一のテーブル引数を使用して呼び出されます。最も重要なものは以下のとおりです。
name: コマンド名を含む文字列
fargs: 空白で分割されたコマンド引数を含むテーブル(<f-args> を参照)
bang: コマンドが ! 修飾子で実行された場合、true<bang> を参照)
line1: コマンド範囲の開始行番号(<line1> を参照)
line2: コマンド範囲の最終行番号(<line2> を参照)
range: コマンド範囲の項目数: 0、1、または 2(<range> を参照)
count: 指定されたカウント(<count> を参照)
smods: コマンド修飾子を含むテーブル(<mods> を参照)
例えば
vim.api.nvim_create_user_command('Upper',
  function(opts)
    print(string.upper(opts.fargs[1]))
  end,
  { nargs = 1 })
vim.cmd.Upper('foo')
--> FOO
complete 属性は、: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,
})
バッファローカルのユーザーコマンドは、vim.api.nvim_buf_create_user_command() で作成されます。ここで、最初の引数はバッファ番号(0 は現在のバッファ)です。残りの引数は nvim_create_user_command() と同じです。
vim.api.nvim_buf_create_user_command(0, 'Upper',
  function(opts)
    print(string.upper(opts.fargs[1]))
  end,
  { nargs = 1 })

ユーザーコマンドの削除 lua-guide-commands-delete

ユーザーコマンドは vim.api.nvim_del_user_command() で削除できます。唯一の引数はコマンドの名前です。
vim.api.nvim_del_user_command('Upper')
バッファローカルのユーザーコマンドを削除するには、vim.api.nvim_buf_del_user_command() を使用します。最初の引数はバッファ番号(0 は現在のバッファ)、2 番目はコマンド名です。
vim.api.nvim_buf_del_user_command(4, 'Upper')

クレジット lua-guide-credits

このガイドの大部分は、nanotee の Lua ガイドから引用されています: https://github.com/nanotee/nvim-lua-guide
@nanotee に感謝します!
メイン
コマンド一覧
クイックリファレンス