錆びついたinit.vimをLuaで書き換えてピカピカにする

本記事は[Vim駅伝](https://vim-jp.org/ekiden/)`2023-03-22`枠の記事です。

# 環境

Ubuntu 20.04.5 LTS
Neovim v0.9.0-dev

# Neovimのバージョンを上げる

普通にaptでインストールすると古いバージョン（v0.4.3）が入ってきてしまうので、以下のコマンドで入れ直します。

```
sudo add-apt-repository ppa:neovim-ppa/unstable
sudo apt-get update
sudo apt-get install neovim
```

※注意※
開発版（-dev）が入ってきます！安定版を使いたい方は気をつけて🐈

# 古い`init.vim`

こちらが、かれこれ2年以上更新していない古い`init.vim`です([GitHub](https://github.com/matoruru/dotfiles/blob/master/.nvimrc))。

<details><summary>クリックでソースコードを表示</summary><div>

```vimscript
" Plugins
call plug#begin('~/.vim/plugged')

"  Theme
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'altercation/vim-colors-solarized'

"  Move
Plug 'unblevable/quick-scope'

"  Input
Plug 'cohama/lexima.vim'
Plug 'gyim/vim-boxdraw'

"  IDE
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'prettier/vim-prettier', {
  \ 'do': 'yarn install',
  \ 'branch': 'release/0.x'
  \ }

" HTML
Plug 'mattn/emmet-vim'

" JavaScript
Plug 'pangloss/vim-javascript'

"  Haskell
Plug 'neovimhaskell/haskell-vim'

"  PureScript
Plug 'purescript-contrib/purescript-vim'

" --- --- TypeScript
Plug 'leafgarland/typescript-vim'
Plug 'peitalin/vim-jsx-typescript'

"  Fish
Plug 'dag/vim-fish'

"  Utility
Plug 'simeji/winresizer'
Plug 'bronson/vim-trailing-whitespace'
Plug 'moll/vim-bbye'
Plug 'machakann/vim-highlightedyank'
Plug 'vim-scripts/vim-auto-save'

"  Git
Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'airblade/vim-gitgutter'

"  File explorer
Plug 'preservim/nerdtree'

call plug#end()


" Set leader key
let mapleader = "\<Space>"


" Theme
let g:airline_theme='solarized'
let g:airline#extensions#tabline#enabled=1
let g:airline#extensions#fugitiveline#enabled=1
let g:airline_powerline_fonts=1
let base16colorspace=256

syntax enable
set background=dark
colorscheme solarized


" Lexima.vim
let g:lexima_enable_basic_rules = 1


" quick-scope
let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']


" vim-auto-save
let g:auto_save = 1
let g:auto_save_silent = 1
let g:auto_save_in_insert_mode = 0


" coc
nmap <silent> <leader>sd :call <SID>show_documentation()<CR>
nmap <silent> <leader>ca :CocAction<CR>
nmap <silent> <leader>gd <Plug>(coc-definition)
nmap <silent> <leader>gy <Plug>(coc-type-definition)
nmap <silent> <leader>gi <Plug>(coc-implementation)
nmap <silent> <leader>gr <Plug>(coc-references)

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  elseif (coc#rpc#ready())
    call CocActionAsync('doHover')
  else
    execute '!' . &keywordprg . " " . expand('<cword>')
  endif
endfunction


" Haskell
let g:haskell_enable_quantification = 1
let g:haskell_enable_recursivedo = 1
let g:haskell_enable_arrowsyntax = 1
let g:haskell_enable_pattern_synonyms = 1
let g:haskell_enable_typeroles = 1
let g:haskell_enable_static_pointers = 1
let g:haskell_backpack = 1

let g:haskell_indent_if = 2
let g:haskell_indent_case = 2
let g:haskell_indent_let = 2
let g:haskell_indent_where = 2
let g:haskell_indent_before_where = 2
let g:haskell_indent_after_bare_where = 2
let g:haskell_indent_do = 2
let g:haskell_indent_in = 2
let g:haskell_indent_guard = 2


" PureScript
let purescript_indent_if = 2
let purescript_indent_case = 2
let purescript_indent_let = 2
let purescript_indent_where = 2
let purescript_indent_do = 2


" --- NERDTree
function IsInNERDTreeBuf()
  return exists('t:NERDTreeBufName') && bufname("%") == t:NERDTreeBufName
endfunction


" --- Nt
command! Nt :tabnew|term


" --- Bbye
noremap <silent> <leader><C-w> :Bdelete<CR>


" --- vim-highlightedyank
let g:highlightedyank_highlight_duration = 500

" Remap keys
set backspace=0
noremap  <BackSpace> <nop>
noremap! <BackSpace> <nop>
inoremap <BackSpace> <nop>
noremap  <Delete>    <nop>
noremap! <Delete>    <nop>

noremap  <Up>    <nop>
noremap! <Up>    <nop>
noremap  <Down>    <nop>
noremap! <Down>    <nop>
noremap  <Left>    <nop>
noremap! <Left>    <nop>
noremap  <Right>    <nop>
noremap! <Right>    <nop>

noremap <silent> <C-h> <C-w>h
noremap <silent> <C-l> <C-w>l
noremap <silent> <C-j> <C-w>j
noremap <silent> <C-k> <C-w>k

nnoremap Q <nop>

map <C-n> :NERDTreeToggle<CR>

nnoremap <F6> :<C-u>tabnew ~/.nvimrc<CR>
nnoremap <F7> :<C-u>source ~/.nvimrc<CR>
nnoremap <F8> :set relativenumber! number!<CR>

nnoremap <F10> :!code %<CR>

nnoremap <silent> <Esc> :noh<CR><Esc>

nnoremap cp "+p
nnoremap cy "+y
vnoremap cy "+y

nnoremap + <C-a>
nnoremap - <C-x>

tnoremap <ESC> <C-\><C-n>

" Use the pattern to serach the history
cnoremap <C-p> <Up>
cnoremap <C-n> <Down>

" Use the command-line mode with emacs keybindings
cnoremap <C-b> <Left>
cnoremap <C-f> <Right>
cnoremap <C-e> <End>
cnoremap <C-a> <Home>

" Open the command line window
cnoremap <C-g> <C-f>

" Highlight without jumping
noremap * *``
noremap # #``

nnoremap <silent> <expr> ]b IsInNERDTreeBuf() ? '<C-w>l:bn<CR>' : ':bn<CR>'
nnoremap <silent> <expr> [b IsInNERDTreeBuf() ? '<C-w>l:bp<CR>' : ':bp<CR>'
nnoremap <silent> <expr> ]B IsInNERDTreeBuf() ? '<C-w>l:bl<CR>' : ':bl<CR>'
nnoremap <silent> <expr> [B IsInNERDTreeBuf() ? '<C-w>l:bf<CR>' : ':bf<CR>'

nnoremap <silent> ]a :next<CR>
nnoremap <silent> [a :prev<CR>
nnoremap <silent> ]A :last<CR>
nnoremap <silent> [A :first<CR>

nnoremap <silent> ]c :cnext<CR>
nnoremap <silent> [c :cprev<CR>
nnoremap <silent> ]C :clast<CR>
nnoremap <silent> [C :cfirst<CR>

nnoremap <silent> ]e :call CocAction('diagnosticNext')<CR>
nnoremap <silent> [e :call CocAction('diagnosticPrevious')<CR>
nnoremap <silent> ]E :<CR>
nnoremap <silent> [E :<CR>

nnoremap <silent> ]t gt
nnoremap <silent> [t gT
nnoremap <silent> ]T :tabl<CR>
nnoremap <silent> [T :tabfir<CR>

cnoremap <silent> <C-t>h :vs\|term<CR>
cnoremap <silent> <C-t>j :sp<CR><C-w>j:term<CR>
cnoremap <silent> <C-t>k :sp\|term<CR>
cnoremap <silent> <C-t>l :vs<CR><C-w>l:term<CR>


" Basic settings
set cursorline
set relativenumber number

highlight Comment cterm=italic gui=italic

set mouse=
set nowrapscan
set hlsearch
set ai
set showmatch
set ruler
set tabstop=2
set shiftwidth=2
set expandtab

set incsearch
set inccommand=split

let &t_SI .= "\e[6 q"
let &t_EI .= "\e[2 q"
let &t_SR .= "\e[4 q"

set nobackup
set nowritebackup
set noundofile
set noswapfile

set hidden

augroup termopen-startinsert
  autocmd!
  autocmd TermOpen * startinsert
augroup END
```

</div></details>

# Luaに書き換えていく

まずは`init.lua`が読み込まれることを確認するために`init.lua`から何かしら出力させてみます。

ファイルの場所は`~/.config/nvim/init.lua`です。

```lua:init.lua
print('hi')
```

Neovimを再起動すると、エディタ下部に`hi`と出力されました。ちゃんと読み込まれているようです。

では、ここから順番にLuaへと書き換えていきます。

## プラグインマネージャをplug.nvimからpacker.nvimに変える

```lua:init.lua
vim.cmd [[packadd packer.nvim]]

return require('packer').startup(function(use)
  use 'wbthomason/packer.nvim'

  -- Theme
  use 'vim-airline/vim-airline'
  use 'vim-airline/vim-airline-themes'
  use 'altercation/vim-colors-solarized'

  -- Move
  use 'unblevable/quick-scope'

  -- Input
  use 'cohama/lexima.vim'
  use 'gyim/vim-boxdraw'

  -- IDE
  use {
    'neoclide/coc.nvim',
    branch = 'release',
  }
  use {
    'prettier/vim-prettier',
    branch = 'release/0.x',
    run = 'yarn install',
  }

  -- HTML
  use 'mattn/emmet-vim'

  -- JavaScript
  use 'pangloss/vim-javascript'

  -- Haskell
  use 'neovimhaskell/haskell-vim'

  -- PureScript
  use 'purescript-contrib/purescript-vim'

  -- TypeScript
  use 'leafgarland/typescript-vim'
  use 'peitalin/vim-jsx-typescript'

  -- Fish
  use 'dag/vim-fish'

  -- Utility
  use 'simeji/winresizer'
  use 'bronson/vim-trailing-whitespace'
  use 'moll/vim-bbye'
  use 'machakann/vim-highlightedyank'
  use 'vim-scripts/vim-auto-save'

  -- Git
  use 'Xuyuanp/nerdtree-git-plugin'
  use 'airblade/vim-gitgutter'

  -- File explorer
  use 'preservim/nerdtree'
end)
```

書きやすくていい感じです。Vim scriptの時にはエスケープする必要のあった改行部分などもLuaのテーブルで綺麗になりました。

## `#`付きの変数にアクセスする際の注意点

例えば、Vim scriptの

```vimscript
let g:airline#extensions#tabline#enabled=1
```

は、単純に

```lua
vim.g.airline#extensions#tabline#enabled=1
```

と書き換えるとエラーになるため、以下のようにする必要があります。

```lua
vim.g['airline#extensions#tabline#enabled']=1
```

## 残りの部分を書き換える

あとはほとんど変数の設定とキーマッピングだけです・・・が、面倒で気が進まないので徐々に書き換えていきます（終了次第、記事更新します！）

# 参考

https://github.com/willelz/nvim-lua-guide-ja/blob/master/README.ja.md

# 最後に

記事を読んでくださってありがとうございます！

Twitterフォローしていただけると記事を書き続けるモチベーションになります😺
https://twitter.com/_matoruru