天狗会議録
Posts Pages About
LunarVimに移行
2024/10/26

Visual Studio Codeへの不満点

Visual Studio Codeは非常に優れたテキストエディタである。 軽快な動作、高速な検索、豊富な拡張機能、Git機能、等々。 何より、Visual StudioやXCodeのようなIDEとは異なり、プロジェクトの構成には一切干渉しない点は、とにかくCLI信者にとって嬉しい。

しかし、ぼんやりとした不満があった。 恐らく、ある程度のマウス操作を要求されることが引っかかっているのだろう。 せっかく編集画面とターミナルの切替え用ショートカットを用意したのに、ついぞ使うことはなかった。 特にMacBookを使い始めてからは、一単語移動のためのOptionキーが押しにくく、トラックパッドを多用するはめになった。

あるいは、Vimの仕様経験があるからだろう。 Visual Studioでコーディングしていると、どうしても「Vimならもっと楽に編集できるのに」と思うことがある。 実際、vscodevimを入れたこともあった。 しかし、すぐにアンインストールした。 使いにくかったからだ。 合わなかったからだ。

今も尚、Visual Studio Codeを悪く言うつもりは毛頭ないが、しかし、Vimに完全移行しようと決意した。

Vimの不満点

単体ファイルの編集においては非常に優れたテキストエディタである。 一方、複数ファイルの編集においては使いにくくて仕方がなかった。 また、言語サーバを使うことができず、すべて自力で書かなければならないのが時折億劫だった。

勿論、あらゆる不満もプラグインを入れれば解決したのだろう。 しかし、プラグインの追加自体が面倒くさかった。 結局、ぼくの.vimrcは次に示す通り、小さいものに納まっていた。

" dein begin
let s:dein_base = '~/.cache/dein/'
let s:dein_src = '~/.cache/dein/repos/github.com/Shougo/dein.vim'
execute 'set runtimepath+=' .. s:dein_src
call dein#begin(s:dein_base)
call dein#add(s:dein_src)

" add plugins
call dein#add('jacoborus/tender.vim')
call dein#add('itchyny/lightline.vim')
call dein#add('lambdalisue/fern.vim')

" dein end
call dein#end()

" dein auto install
if dein#check_install()
  call dein#install()
endif

" tender configuration
if (has("termguicolors"))
  set termguicolors
endif
syntax enable
colorscheme tender
let g:lightline = { 'colorscheme': 'tender' }

" lightline configuration
set laststatus=2

" define a function to reset plugins
function! Reset_dein() abort
  call map(dein#check_clean(), "delete(v:val, 'rf')")
  call dein#recache_runtimepath()
endfunction

" default indent
set expandtab
set tabstop=8
set softtabstop=4
set shiftwidth=4

" set default fileformat unix
set fileformats=unix

" show line numbers
set number

" enable backspace
set backspace=indent,eol,start

" enable clipboard
set clipboard=unnamed,autoselect

" configure visual
set guioptions-=m
set guioptions-=T
set guioptions-=r
set guioptions-=R
set guioptions-=l
set guioptions-=L
set guioptions-=b

" Tab controls
nnoremap <C-T> :tabnew<CR>
nnoremap <C-Space> gt

とはいえ、これからVimを使っていこうと決めたからには面倒だとか億劫だとか言っていられない。 ちゃんと調べて環境構築するかと重い腰を上げた。 そこで、まず、Neovimに当たった。 Neovimは使ったことがあった。 当時は「なんかなういな」と思って嫌煙していたが、この際だからNeovimを使うかと決めた。 そして、すぐ、LunarVimが見つかった。 どうやら最初から色々なものが揃っているらしい。 昔なら嫌煙していたろうが、Visual Studio Codeを許せてLunarVimを許せない道理はない。 ということで、LunarVimを採用するに至った。

LunarVim

LunarVimの概要説明は 公式ページ に任せる。

最も重要なこととして、動作が軽快である。 そして、標準でLSPなりプラグインマネージャなりターミナルなり、恐らく自力で構築するのは面倒であろうものが色々入っている。 さくっと使い始められて嬉しい。

一方、インストールが面倒である。 特に、WindowsではPowerShell 7系が必要である。 そのインストールはさることながら、今までNative Tools Command Prompt for VS 2022を使っていたために、そもそもPowerShellに移行する必要があった。 PowerShellではvcvarsall.batを簡単に適用できない。 記事違になるので書かないが、これを解決するのも面倒であった。

現状のconfig.luaを次に示す。

-- すべてのファイルに共通する設定
vim.api.nvim_create_autocmd("BufEnter", {
  pattern = "*",
  callback = function()
    if vim.b.first_opened == nil then
      vim.b.first_opened = true

      vim.opt_local.list = true
      vim.opt_local.listchars = "tab:->,trail:~,nbsp:+"

      vim.opt_local.tabstop = 16
      vim.opt_local.softtabstop = 16

      vim.opt_local.autoindent = false
      vim.opt_local.smartindent = false
      vim.opt_local.smarttab = false
      vim.opt_local.indentexpr = ""
      vim.opt_local.indentkeys = ""

      local ftplugin_file = vim.env.LUNARVIM_CONFIG_DIR .. "/ftplugin/" .. vim.bo.filetype .. ".lua"
      if vim.fn.filereadable(ftplugin_file) == 1 then
        dofile(ftplugin_file)
      end
    end
  end,
})

-- 便利なキーバインド
lvim.keys.insert_mode["jj"] = "<ESC>"
lvim.keys.normal_mode["<Leader><Leader>"] = ":HopWord<CR>"
-- 分割画面の移動
lvim.keys.normal_mode["<C-h>"] = "<C-w>h"
lvim.keys.normal_mode["<C-j>"] = "<C-w>j"
lvim.keys.normal_mode["<C-k>"] = "<C-w>k"
lvim.keys.normal_mode["<C-l>"] = "<C-w>l"
-- バッファの移動
lvim.keys.normal_mode["<C-n>"] = ":bp<CR>"
lvim.keys.normal_mode["<C-m>"] = ":bn<CR>"
-- 現在のバッファを、前のバッファに移動してから、閉じる
lvim.keys.normal_mode["<Leader>bw"] = ":let bnum = bufnr('%')<CR>:bp<CR>:execute 'bw' bnum<CR>"

-- 自動で""や{}やが閉じられる機能を無効化
lvim.builtin.autopairs.active = false

-- プラグイン
lvim.plugins = {
  {
    "phaazon/hop.nvim",
    event = "BufRead",
    config = function()
      require("hop").setup()
    end,
  },
}

LunarVimの不満点

早速ではあるが、LunarVimあるいはVimに対する不満を記す。

日本語に弱い

文字がずれるずれる。 Vimで日本語入力をするときは、殆どはコメントを書いているときだろうが。 今、まさに、この記事をLunarVimで書いているわけだが、煩わしくて仕方ない。

また、日本語ばかりの文章を編集するときはhopが活きづらい。 まあ、仕方ないか……。

タブページを簡単に閉じれない

nvim-treeでEnterキーを押してファイルを開くと、新しいタブページとして編集画面が現れる。

このタブを削除するには:tabcなり:bdなり:bwなりすれば良いと言われている。 しかし、これでは上手くいかない。 :tabcでは「Cannot close last tab page」と怒られる。 :bd:bwではVim自体が終了することがある。

そのため、削除したいタブを、前のタブに移ってから、削除することで解決した。 それが次のキーバインドである。

lvim.keys.normal_mode["<Leader>bw"] = ":let bnum = bufnr('%')<CR>:bp<CR>:execute 'bw' bnum<CR>"

ftpluginに上書きされる

config.luaに次のように書いても、ftpluginの設定に上書きされてしまう。

-- optであろうが
vim.opt.tabstop = 4
-- opt_localであろうが
vim.opt_local.tabstop = 4
-- cmdであろうが
vim.cmd("set tabstop=4")

これを回避するために、次のように書かなければならない。

vim.api.nvim_create_autocmd("BufEnter", {
  pattern = "*",
  callback = function()
    if vim.b.first_opened == nil then
      vim.b.first_opened = true
      vim.opt_local.tabstop = 4
    end
  end,
})

また、$LUNARVIM_CONFIG_DIRつまりconfig.luaのあるディレクトリにftplugin/<FILETYPE>.luaを作成することで、言語ごとの設定が行える。 が、この設定もftpluginによって上書きされてしまう。 これを回避するために、矢張り次のように書かなければならない。

vim.api.nvim_create_autocmd("BufEnter", {
  pattern = "*",
  callback = function()
    if vim.b.first_opened == nil then
      vim.b.first_opened = true
      local ftplugin_file = vim.env.LUNARVIM_CONFIG_DIR .. "/ftplugin/" .. vim.bo.filetype .. ".lua"
      if vim.fn.filereadable(ftplugin_file) == 1 then
        dofile(ftplugin_file)
      end
    end
  end,
})

ちなみに、ftpluginを次のように無効化できるが、LSPが使えなくなるので採用できない。

vim.cmd("filetype off")

未解決問題

listcharsをtab:->,trail:~のように設定しているが、 >>> ~~~のようにshiftwidthの境界で一文字目が消える。 macOS+iTerm2でもWindows10+PowerShell7でも起こる。 HackGen Console NFでもMS ゴシックでも起こる。 純粋なneovimでは起こらない。

プロジェクト内検索の方法がわからない。 Visual Studio Codeの最大の強みがそれであるので、これがないとそれだけで使わない理由になってしまう。 良い感じのpluginがあるのだろうか。 見当たらなかったが。