オレオレneovim環境構築&設定
オレオレneovim環境構築&設定
TSG Advent Calendar 2021の13日目の記事です。
自己紹介
教養過程1年の2lu3と申します。
WindowsとUbuntu、Linux Mintでneovimを使っているneovim初心者です。
概要
- neovimの環境構築をUbuntuで行う
- windowsの環境構築は最近やってないから覚えていない
- さらに、他に良い記事がたくさんある
- さらに、windowsのほうが導入が簡単
- なのでUbuntuのみです
- UbuntuとWindowsで設定の共有をするためのTips
キーワード
neovim
, ubuntu20.04
, dein
, coc
, c++
, python
環境構築
linuxbrew
まず、linuxbrewをインストールするとよいです。aptではインストールできない最新版を簡単にインストールできます。さらに、linuxbrewならインストールするのにsudo
権限を必要としないので、大学のサーバーの中の自分のアカウントでneovimをインストールするときも同様の手順で行なえます。
homebrewのHPに書いてあるとおり、下のようにターミナルで実行します。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
次に、pathを通したりする作業が必要になります。こちらは、Homebrew on Linuxのページに書いてあるように、下のコマンドを実行します。
test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)"
test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
test -r ~/.bash_profile && echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >>~/.bash_profile
echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >>~/.profile
もし、上のコマンドを実行した結果、~/.bash_profile
と~/.profile
が両方存在している場合、要注意です。詳しくは触れませんが、両者が存在するときの挙動をよく理解していない場合、どちらか一つに統合し、いらない方を削除すべきです。私の場合、~/.bashrc
と~/.profile
のみ存在しています。以下、私の環境を前提に書いていきます。適宜読み替えてください。
source ~/.profile
または
source ~/.bash_profile
を実行して上のコマンドで変更した内容を反映させます。
ここまできたら、
brew --version
と実行し、バージョン情報が帰ってきたらOKです。
次のステップに進みましょう。
neovim
brew
をインストールしているなら、
brew install neovim
だけでOKです。
次に、neovim
のプラグインを入れる上で必要になることが多いpython
とnodejs
をインストールしていきます。
python
pythonの環境構築で重要なのは2つあります。
一つは、pythonのバージョン(3.7.3や3.8.10など)です。pythonはバージョンによって使える文法が違います。バージョンを手軽に変更するために、pyenv, anacondaなど複数の管理システムが存在します。
もう1つは、仮想環境です。これは、同じpythonのバージョンでも、pipでインストールするパッケージの組み合わせがプロジェクトによって違う場合に便利です。こちらも、venv, virtual venv, pipenvなどが存在します。
注意点として、両方の機能を持った管理システムも存在します。anaconda
などがその例です。
私の場合、pyenvでバージョンを管理し、pipenvで仮想環境を管理しています。
それでは、まず、pyenvからインストールします。
brew install pyenv
pathを通したりするのに、下のコマンドを実行しましょう。
echo 'eval "$(pyenv init --path)"' >>~/.profile
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.profile
source ~/.bashrc
pyenv install -l
すると、pyenvがインストール可能なバージョンがたくさん出てきたと思います。
この中で、普段使いするpythonのバージョンを選びましょう。私の場合、3.8.12
にしています。
では、早速3.8.12
をインストールしてみましょう。
pyenv install 3.8.12
結構時間がかかるので気長に待ちましょう。
インストールできたら、このバージョンをデフォルトで使うよ!と宣言するために下のコマンドを実行します。
pyenv global 3.8.12
この状態で、
python --version
をすると、3.8.12
であることが確認できると思います。
次に、pipenvのインストールです。公式ドキュメントには、pip install pipenv
とすることを推奨されているのですが、私はあえてbrew
でインストールしています。
brew install pipenv
pipenvはデフォルトではある1つのフォルダにすべての仮想環境がまとめられているのですが、フォルダ名の中に乱数が入っているのでこのあとneovimにpythonのpathを伝えるのに不便です。これは、別のデバイスでは乱数の数字が変わるため、デバイスが変わるたびにpythonのpathを編集する必要があるためです。そのため、下のコマンドを実行して、仮想環境をそのフォルダの下に作るようにしましょう。
echo 'export PIPENV_VENV_IN_PROJECT=true' >> ~/.bashrc
source ~/.bashrc
ここで、適切な場所でneovim用の仮想環境を作りましょう。
私の場合、~/python_envs/nvim
というディレクトリを作って、その中で
pipenv install pynvim
とすることで、仮想環境を作り、neovimに必要なpythonパッケージであるpynvimをインストールしています。
この場合、neovimに渡すpythonのpathは、~/python_envs/nvim/.venv/bin/python
となっています。
node
brewでnodebrewをインストールしてさらにnodeをインストールします。
なぜ、こんなことをと思われた方は、何でHomebrewからじゃなくNodebrewでNode.jsのバージョン管理するのかを読まれるとよいでしょう。
インストールのやり方は、MacにNode.jsをインストールを参考にしてください。Macと書いてありますが、Ubuntuでも同じ手順でできます。
anyenv+nodenvで環境構築するやり方を記事内でおすすめされていますが、少なくともしばらくの間はnodeをバージョン管理することがないので、必要になったら環境構築をやり直すつもりです。
nodeをインストールできたら、
source ~/.bash_profile
npm install -g neovim
を実行してください。
dein
deinは、neovimのプラグインを管理することができます。
curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
# For example, we just use `~/.cache/dein` as installation directory
sh ./installer.sh ~/.cache/dein
を実行しましょう。
また、vim側の設定ファイルにも記載する必要があるのですが、それは後述します。
設定ファイル ~ .vim系 ~
上で、必要なものはインストールできました。これから、設定をいろいろ記載していきましょう。
設定ファイルは、~/.config/nvim
というディレクトリを作ってその中に入れましょう。neovimは、~/.vimrc
または~/.config/nvim/init.vim
をデフォルトで読みます。(それ以外もあると思いますが、調べていません)
~/.config/nvim/init.vim
if &compatible
set nocompatible
endif
" 外部設定ファイルの読み込み
runtime! options.vim
runtime! keymap.vim
" neovim用pythonの設定
" pip install pynvim
if has('win64')
let g:python3_dir = 'C:\Users\tlaloc\python_envs\nvim\.venv\Scripts\'
let g:python3_host_prog=g:python3_dir . 'python.exe'
elseif has("unix")
let g:python3_dir = '~/python_envs/nvim/.venv/bin/'
let g:python3_host_prog= g:python3_dir . 'python'
endif
" dein関係
"
let g:dein#auto_recache=1
set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim
let s:watch_files = ['~/.config/nvim/init.vim', '~/.config/nvim/dein.toml', '~/.config/nvim/dein_lazy.toml']
if dein#load_state('~/.cache/dein')
call dein#begin('~/.cache/dein', s:watch_files)
call dein#load_toml('~/.config/nvim/dein.toml', {'lazy': 0})
call dein#load_toml('~/.config/nvim/dein_lazy.toml', {'lazy': 1})
call dein#end()
call dein#save_state()
endif
if dein#check_install()
call dein#install()
endif
syntax enable
順番に説明していきます。
if &compatible
set nocompatible
endif
はvi互換モードを抑制するみたいな感じです。あまり良くわかっていないし、理解しないといけないほど初心者にとって重要なものでもないと思うのでのでおまじないと考えています。
" 外部設定ファイルを読み込む
runtime! options.vim
runtime! keymap.vim
init.vim
以外のファイルを読み込んでいます。これは、optiopns.rc.vim
などがinit.vim
などのデフォルトで読み込まれるファイル名ではないからです。
また、15~17行目で、不足しているプラグインがあったら、自動でインストールしています。
" neovim用pythonの設定
" pip install pynvim
if has('win64')
let g:python3_dir = 'C:\Users\tlaloc\python_envs\nvim\.venv\Scripts\'
let g:python3_host_prog=g:python3_dir . 'python.exe'
elseif has("unix")
let g:python3_dir = '~/python_envs/nvim/.venv/bin/'
let g:python3_host_prog= g:python3_dir . 'python'
endif
ここで、さきほとインストールしたpythonの場所をneovimに教えています。インストールした場所が違う場合、適宜変更してください。上がwindows用、下がlinux用です。windowsはユーザー名ベタ書きなので注意してください。
" dein関係
set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim
if dein#load_state('~/.cache/dein')
call dein#begin('~/.cache/dein')
call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim')
call dein#load_toml('~/.config/nvim/dein.toml', {'lazy': 0})
call dein#load_toml('~/.config/nvim/dein_lazy.toml', {'lazy': 1})
call dein#end()
call dein#save_state()
endif
if dein#check_install()
call dein#install()
endif
ここは、deinを使うためのおまじないと考えても良いですが、少しだけ触れておきます。8行目と9行目は、あとで説明するdein.toml
とdein_lazy.toml
をload_toml
しています。ここで、lazy
がそれぞれ0と1になっています。lazy
は読み込みするときのタイミングを指定しています。詳しくは後述します。
~/.config/nvim/options.vim
" ######################## 見た目 ########################
set termguicolors " True Color対応
set title " ターミナルのタブ名に現在編集中のファイル名を設定
set number " 行番号を表示する
set wrap " 行を折り返す
set showmatch " 括弧入力時の対応する括弧を表示
set list "不可視文字の可視化
set listchars=tab:»-,trail:-,extends:»,precedes:«,nbsp:%,eol:↲ " デフォルト不可視文字は美しくないのでUnicodeできれいに
set matchtime=3 " 対応括弧のハイライト表示を3sにする
" ######################## 検索・置換 ########################
set ignorecase " 大文字小文字の区別なく検索する
set smartcase " 検索文字列に大文字が含まれている場合は区別して検索する
set wrapscan " 検索時に最後まで行ったら最初に戻る
set hlsearch " 検索語をハイライト表示
set incsearch " 検索文字列入力時に順次対象文字列にヒットさせる
set inccommand=split " インタラクティブに変更
" ######################## インデント ########################
set smartindent " オートインデント
set expandtab " softtabstop や shiftwidth で設定されている値分のスペースが挿入されたときに、挿入されたスペース数が tabstop に達してもタブに変換されない
set tabstop=4 " スペースn個分で1つのタブとしてカウントするか
set softtabstop=4 " <tab>を押したとき、n個のスペースを挿入
set shiftwidth=4 " <Enter>や<<, >>などを押したとき、n個のスペースを挿入
" ######################## 補完 ########################
set wildmode=list:longest " コマンドラインの補完
set infercase " 補完時に大文字小文字を区別しない
set wildmenu "コマンドの補完を有効に
au FileType * setlocal formatoptions-=ro " 自動コメント挿入を回避
" ######################## 操作 ########################
set clipboard+=unnamedplus " クリップボードにコピーする
set backspace=indent,eol,start " backspaceで様々な文字を消せるようにした
set hidden
set textwidth=0 "自動改行する文字数
" ######################## ログ ########################
set history=5000 "保持するコマンド履歴の数
set noswapfile " swapファイルを保存しない
set noundofile " undoファイルを保存しない
set nobackup " backupを保存しない
set nowritebackup "writebackupを保存しない
set viminfo= " viminfoファイルに保存しない
" ######################## その他 ########################
filetype plugin indent on " ファイルタイプの検索とプラグインをONにする
set encoding=utf-8 " 文字コード
コメントに書いてあるとおりです。いろんなオプションを分類するのって難しいですよね。
~/.config/nvim/keymap.vim
" leaderを,に変更
let mapleader = "\<Space>"
" 入力モード中に素早くjjと入力した場合はESCとみなす
inoremap <silent> jj <Esc>:<C-u>w<CR>
" 同上を日本語でも打てるように
inoremap <silent> っj <Esc>:<C-u>w<CR>
" ESCを2回押すことでハイライトを消す
nmap <silent> <Esc><Esc> :nohlsearch<CR>
" ##### 日本語用 #####
nnoremap あ a
nnoremap い i
nnoremap う u
nnoremap お o
nnoremap っd dd
nnoremap っy yy
" ##### ウィンドウ操作系 #####
nnoremap <silent> <Leader>v :vs<CR>
nnoremap <silent> <Leader>s :sp<CR>
nnoremap <silent> <Leader>h <C-w>h
nnoremap <silent> <Leader>j <C-w>j
nnoremap <silent> <Leader>k <C-w>k
nnoremap <silent> <Leader>l <C-w>l
nnoremap <silent> <Leader>h <C-w>h
nnoremap <silent> <Leader>j <C-w>j
nnoremap <silent> <Leader>k <C-w>k
nnoremap <silent> <Leader>l <C-w>l
" ##### 行・列関係 #####
nnoremap j gj
nnoremap k gk
vnoremap j gj
vnoremap k gk
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-h> <Left>
inoremap <C-l> <Right>
" 補完
inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<S-TAB>"
一番上のmapleader
はneovimにおいて非常に重要なキーです。私は、押しやすいスペースキーを割り当てていますが、自分の好きな使いやすいキーを割り当てれば良いと思います。
その次の、jj
はneovimならほとんどの方が設定されています。insertモードからnormalモードに戻ります。私の場合、同時にファイルの内容を保存するようにしています。
また、使うことはあまりないのですが日本語を入力してもいくつかのキーは反応するようにしています。正直、なくても良いです。
また、ウィンドウ操作は画面分割をするときに便利です。私の場合、<Leader>
はスペースなので、<Leader>
を別のキーにされている方はspace
を適宜読み替えてください。
コマンド | 内容 |
---|---|
space +v
|
左右に画面分割 |
space +s
|
上下に画面分割 |
space +h
|
左の画面に移動 |
space +j
|
下の画面に移動 |
space +k
|
上の画面に移動 |
space +l
|
右の画面に移動 |
nnoremap j gj
nnoremap k gk
vnoremap j gj
vnoremap k gk
ここでは、本当は1行だが画面の制約上2行として表示されている場合についての動作をカスタマイズしています。もともとのhjklの設定では、このような状況では画面上では2行となっていても1行であるとしてカーソル移動を行います。しかし、それは人間が見た画面上での動きとしてわかりにくいので、折り返しで2行として表示されている場合、実際は1行でも画面上の1行目と2行目をjkで移動できるようにしています。
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-h> <Left>
inoremap <C-l> <Right>
これは設定だけして使い忘れていますが、insertモードでコントロールボタンを押しながらhjklすれば矢印キーが入力されます。
inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<S-TAB>"
この行は、補完をつかったときにtabキーで次の候補に、shift+tabで前の候補に選択を移動させるkeymapです。
設定 ~ dein系 ~
ここからは、deinの設定ファイルについて書いていきます。
細かい文法の説明は他のサイトに譲るとして、注意点をいくつか。
-
source ~
系では、追加の設定ファイルを読み込んでいる- しかし、キーマップに関する設定がほとんどで、洗練させたキーマップとは言い難いし、淡々と説明するのが苦痛すぎるので解説しません
- どうしても知りたい場合は、私の設定レポジトリを参考にしてください
- hook_addとhook_sourceどちらを使うか, deinとdein_lazyの使い分けは、私自身これがベストなのか判断が付きません(betterではあるはず)。他の詳しい方のサイトをご覧になったようが良いと思います。
~/.config/nvim/dein.toml
# [dein.toml]
[[plugins]]
repo = 'Shougo/dein.vim'
#################### ファイル検索 ####################
# fzf-preview
# ripgrepをインストールするべし
[[plugins]]
repo = 'yuki-yano/fzf-preview.vim'
rev = 'release/rpc'
depends=['junegunn/fzf']
hook_add= '''
source ~/.config/nvim/plugins/fzf-preview.vim
'''
[[plugins]]
repo = 'junegunn/fzf'
build = './install --all'
merged = 0
#################### 見た目 ####################
# インデントに線を表示する
[[plugins]]
repo = 'Yggdroot/indentLine'
# ---------- Vim Airline ----------
[[plugins]]
repo = 'vim-airline/vim-airline'
hook_add = '''
source ~/.config/nvim/plugins/vim-airline.vim
'''
# vim-airlineのテーマ
[[plugins]]
repo = 'vim-airline/vim-airline-themes'
#################### Git ####################
# Gitコマンドを使用する
[[plugins]]
repo = 'tpope/vim-fugitive'
hook_add = '''
nnoremap <silent> gs :Git status<CR>
nnoremap <silent> gps :Git push<CR>
nnoremap <silent> gpl :Git pull<CR>
nnoremap <silent> gc :Git commit<CR>
'''
# show add/delete sign to left
[[plugins]]
repo = 'airblade/vim-gitgutter'
# #################### Uncategorized ###################
# 対となる括弧を追加/削除する
[[plugins]]
repo = 'jiangmiao/auto-pairs'
# coc
[[plugins]]
repo = 'neoclide/coc.nvim'
merged = 0
rev = 'release'
hook_add = '''
source ~/.config/nvim/plugins/coc.vim
'''
#################### 画像生成 ####################
# ソースコードをいい感じの画像にしてくれる
[[plugins]]
repo = 'skanehira/denops-germanium.vim'
depends = ['denops.vim']
hook_add = '''
nnoremap <Leader>pic :Germanium<CR>
vnoremap <Leader>pic :Germanium<CR>
'''
[[plugins]]
repo = 'vim-denops/denops.vim'
インストールしているプラグインを順番に説明していきます。
dein
プラグインマネージャーです。dein
がdein
自身を管理しています。
fzf-preview
こんな感じで、ファイルをfuzzy検索して開けるようになる。このプラグインを使う場合、
brew install ripgrep
するとよい。
indentLine
インデントに縦の線を書いてくれます。
vim-airline
ステータスバーをかっこよくしてくれる。
vim-fugitive
vimのコマンドでgitの操作が出来る。
vim-gitgutter
差分(前回のcommitから追加したか削除したか)を左側に表示してくれる
auto-pairs
カッコを自動補完
coc
様々な言語の補完とかを設定してくれる。
例えば、python
なら、:CocInstall coc-pyright
とするとpython用のLanguage Serverをインストールしてくれる。
denops-germanium
ソースコードをかっこいい画像にしてくれる。
~/.config/nvim/dein_lazy.toml
# [dein_lazy.toml]
# hook_add : deinによってプラグインが認識されたとき
# hook_source : プラグインを読み込む直前に
# hook_post_source : プラグインを読み込んだ直後
# on_i : インサートモードに入ったら読み込む
# on_ft : 特定のファイルタイプで読み込む
# on_func : 関数が事項されるときにロード
# on_event : イベントが実行されるときにロード
# on_cmd :
#################### エクスプローラー ####################
# ファイルツリーを表示
[[plugins]]
repo = 'scrooloose/nerdtree'
depends = ['ryanoasis/vim-devicons']
on_event='NERDTreeToggle'
hook_add='''
nnoremap <silent> <Leader>e :NERDTreeToggle<CR>
'''
# file icon for filetree
[[plugins]]
repo = 'ryanoasis/vim-devicons'
on_source='nerdtree'
#################### 画面サイズ変更 ####################
# ウィンドウの分割サイズを変更
[[plugins]]
repo = 'simeji/winresizer'
on_event='WinResizerStartResize'
hook_add='''
nnoremap <Leader>r :WinResizerStartResize<CR>
'''
#################### Quick Run ####################
# vimを閉じずに編集中のファイルを素早く実行する
[[plugins]]
repo = 'thinca/vim-quickrun'
hook_add = '''
source ~/.config/nvim/plugins/vim-quickrun.vim
'''
# quick runに必要なライブラリ(非同期処理)
[[plugins]]
repo = 'Shougo/vimproc.vim'
#################### 言語ごとの設定 ####################
# ---------- c++ ----------
[[plugins]]
repo = 'vim-scripts/DoxygenToolkit.vim'
on_ft = ['c', 'cpp']
hook_add = '''
nmap <leader>dox :Dox<CR>
'''
# ---------- Python ----------
[[plugins]]
repo = 'heavenshell/vim-pydocstring'
build='make install'
on_ft = ['python']
hook_add= '''
source ~/.config/nvim/plugins/vim-pydocstring.vim
'''
# ---------- TOML ----------
[[plugins]]
repo = 'cespare/vim-toml'
on_ft = ['toml']
# ---------- WEB ----------
# カッコを自動で補完
[[plugins]]
repo = 'alvan/vim-closetag'
on_ft = ['js', 'html']
hook_add = '''
source ~/.config/nvim/plugins/vim-closetag.vim
'''
nerdtree
左側にエクスプローラーもどきを開くことが出来る。fzf入れてからは余り使わない。
winresizer
左右・上下分割したときに、左と右のスペースを変更することが出来る。たまに、横幅が短いソースコードと長いソースコードを左右で分割して開くときに使う。
vim-quickrun
わざわざターミナル戻ってそのソースコードを実行するのが面倒くさいときに使う。python
でやることが多い。
DoxygenToolkit
doxygen
という形式のコメントを自動挿入できる。
vim-pydocstring
上のpythonバージョン
vim-toml
tomlファイルのsyntax highlight
vim-closetag
閉じる方のタグを自動で入れてくれる。
終わりに
以上が、私の現在のneovim設定です。こうしたほうが良い等あればコメント等で教えていただけると嬉しいです。
Discussion