LoginSignup
0
0

Neovimのinit.luaで特定の言語だけタブ幅を変える

Posted at

背景

プログラムを読みやすくするために必須なインデントですが、「字下げを何文字分すべきか」はプログラミング言語によって異なります。
今回はNeovimをLua言語を用いてinit.luaで設定する場合に、特定のプログラミング言語の場合だけインデント幅を変える方法を紹介します。

基礎知識:LuaでNeovimのインデント幅を設定する方法

NeovimをLua言語で設定する場合、インデント幅を調整する設定は主に次の3つです。

vim.o.expandtab = true
vim.o.tabstop = 4
vim.o.shiftwidth = 4

それぞれの設定項目は

  • vim.o.expandtab - trueならtabキー入力時にtab文字の代わりに同じ幅の半角スペースを入力する。
  • vim.o.tabstop - tab文字の幅を指定
  • vim.o.shiftwidth - Neovimがインデントを入力する際(例えばnormalモードでの>>)の幅を指定

です。
ここでvim.oの「o」は「option」のことです。
init.luaにてvim.oで指定した設定はすべてのバッファで有効になります。

本題:特定の言語だけインデント幅を変える

ソースコード

以下のコードをinit.luaに記載することで、プログラミング言語ごとにインデント幅を変更できます。
1行目のfiletype_tabstopテーブルの定義だけ調整してください。

local filetype_tabstop = {lua=2, markdown=2} -- filetype毎のインデント幅
local usrftcfg = vim.api.nvim_create_augroup("UserFileTypeConfig", { clear = true})
vim.api.nvim_create_autocmd("FileType", {
  group = usrftcfg,
  callback = function (args)
    local ftts = filetype_tabstop[args.match]
    if ftts then
      vim.bo.tabstop = ftts
      vim.bo.shiftwidth = ftts
    end
  end
})

解説

1行目のfiletype_tabstopにてプログラミング言語ごとにインデント幅をfiletype名=インデント幅で列挙します(vim.o.tabstop等で定義した幅をそのまま用いる言語については、わざわざ記述する必要はありません)。
この部分については利用する言語にあわせて変更してください。

プログラミング言語に応じて設定を変更するためにautocmdを利用します(一応セットでaugroupも設定しておきます)。
vim.api.nvim_create_autocmdの第1引数にFileTypeすなわち「バッファのfiletypeが設定されたとき」を指定することで、既存ファイルを開いた場合およびfiletypeを手動で設定した場合に処理を実行させます。

条件を満たした場合に実行する処理をcallback =で定義します。
つまり

function (args)
  local ftts = filetype_tabstop[args.match]
  if ftts then
    vim.bo.tabstop = ftts
    vim.bo.shiftwidth = ftts
  end
end

が実際の処理内容です。

まずargs.matchはVim Scriptの<amatch>に該当する変数で、FileTypeの場合にはバッファに設定されたfiletypeが格納されます。
よってfiletype_tabstop[args.mathc]とすることで、1行目にて定義したインデント幅を得ることができます。
その値を一旦ftts変数に格納した後、vim.bo.tabstopおよびvim.bo.shiftwidthに設定します。
ここでvim.boの「bo」は「buffer option」のことであり、指定したバッファでのみ有効になる設定です。
当該バッファにおけるtabstopshiftwidthを上書きすることで、そのプログラミング言語に合わせたインデント幅を利用できます。

以上の説明はfiletype_tabstopにて当該filetypeのインデント幅が指定されている場合の動作です。
もしfiletype_tabstopに指定のないプログラミング言語を用いた場合はどうなるでしょうか?

Lua言語では、テーブルに含まれないインデックスが指定された場合はnilを返します。
したがって、バッファのfiletypefiletype_tabstopに含まれていない場合はftts = nilとなります。
そしてif文は条件がnilであればthen以降の処理を実行しないため、if ftts then ~ endの内側はスキップされます。
この場合は、vim.o.tabstopおよびvim.o.shiftwidthの値がそのまま利用されます。

このようにして、プログラミング言語ごとにインデント幅を変更できます。

補足

今回説明した設定はinit.luaに書き込むことを想定し、比較的コンパクトな記述で済むよう心がけたものです。
filetype毎により込み入った設定をしたい場合は、以下の記事が参考になります。
[Neovim]filetype毎の設定をluaの関数単位で分ける

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0