Neovim はじめたときの初期環境構築備忘録
環境構築で行ったこと
はじめに(注意)
これは完全に個人用で作成したスクラップということを忘れないでほしい.環境依存のところもかなりあると思うので丸写しせず,必要な部分を必要なだけ切り取って使ってほしい.
環境
- システム: Windows Subsystem for Linux 2
- OS: Ubuntu 20.04
- 使用ターミナル:Windows Terminal
インストール
# Update & upgrade Ubuntu 20.04 and Install neovim
sudo apt update -y
sudo apt upgrade -y
## (Omit how to install Neovim because it is written in the official website...)
# Install Python environment for Neovim
sudo pip3 install pynvim
sudo pip3 install neovim-remote
# Omit: Install jedi for deoplete-jedi and jedi-language-server for coc-jedi
#sudo pip3 install jedi
#sudo pip3 install jedi-language-server
# Install pylint for statement check (may be preinstalled)
sudo pip3 install pylint
XDG_CONFIG_HOME
の設定
環境変数export XDG_CONFIG_HOME=~/.config/
msgpack のアップグレード(自動補完プラグイン deoplete を利用するためにはPython 用 msgpack はバージョン 1.0.0 以上が必要)
pip install --upgrade msgpack
vim-Plug のインストール
の通りにやればよいので省略
ノーマルモード時に自動的にIMEをオフにする
下記リンクを参考:
軽くまとめると,githubリポジトリ https://github.com/iuchim/zenhan からzenhan.exeを任意のディレクトリに設置する.
WSL上でホームディレクトリにある.profile
(すでに .bash_profile
または.bash_login
が存在する場合はそのどちらか)に環境変数としてzenhan
(適当な名前)を定義しておく.つまり,
export zenhan='/mnt/c/Users/[zenhan.exeを設置したフルパス]'
を追記する.
(注意:zenhan.exe を生成するためにはbuild.sh
を wsl2 から実行し、windows向けの実行ファイルを生成する必要がありため、クロスコンパイラが必要である。sudo apt install mingw-w64 g++ gcc m4
を実行するで解決する)
ターミナルを再起動しコマンドプロンプトでecho $zenhan
を実行したときに,先ほど定義したzenhan.exe
のパスが返ってくれば,正しい.また,プロンプトでコマンドzenhan 1
またはzenhan 0
を実行した時に,画面右下のIMEが「あ」「A」と切り替わっていたら正しくzenhan.exe
がWSL上で動いていることになる.
次にinit.vim
にて実際にNeovim起動中にノーマルモードに切り替わった時にzenhan 0
が実行されるように設定する.
" IME off setting
let &shell='/usr/bin/bash --login'
autocmd InsertLeave * :call system('${zenhan} 0')
autocmd CmdlineLeave * :call system('${zenhan} 0')
参考:プラグインの環境が動作条件を満たしているか確認
:checkhealth
init.vim
の設定(完全に個人用なので使用する際は取捨選択必要)
参考:Vimから移行したものをベースとしており,すべて確認できたわけでないので使用する際は注意
" ================
" Basic settings
" ================
set t_Co=256
set number
set cursorline
set guifont=Ricty\ Diminished\ Discord:h13
set autoindent
set smartindent
set ambiwidth=double " Japanese input
set showmatch
set showmode
set encoding=utf-8
set fileencodings=iso-2022-jp,euc-jp,sjis,utf-8
set fileformats=unix,dos,mac
set nobackup
set laststatus=2
set mouse=a " Enable mouse wheeling
set backspace=indent,eol,start " Enable BS
set nocursorline
autocmd InsertEnter,InsertLeave * set cursorline!
" Neovim Terminal separate
if has('nvim')
command! -nargs=* Term split | terminal <args>
command! -nargs=* Termv vsplit | terminal <args>
endif
" IME off setting when Esc
let &shell='/usr/bin/bash --login'
autocmd InsertLeave * :call system('${zenhan} 0')
autocmd CmdlineLeave * :call system('${zenhan} 0')
" ===================
" Remap key bindings
" ===================
" NORMAL mode
noremap j gj
noremap k gk
noremap <Down> gj
noremap <Up> gk
nnoremap <S-Tab> <<
" INSERT mode
"inoremap <Up> <C-O>gk
"inoremap <Down> <C-O>gj
inoremap <Tab> <C-t>
inoremap <S-Tab> <C-d>
" edita setting
set splitbelow
set splitright
set noequalalways
set wildmenu
" Spell checking "
set spell
set spelllang=en,cjk
" cursor setting
set ruler
set cursorline
" Remember the last cursor position when leave from an editing file
autocmd BufReadPost *
\ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
\ | exe "normal! g`\""
\ | endif
" tab setting
set tabstop=2
set shiftwidth=2
" Auto-completion of parenthesis
inoremap { {}<LEFT>
inoremap [ []<LEFT>
inoremap ( ()<LEFT>
"inoremap " ""<LEFT>
"inoremap ' ''<LEFT>
inoremap {<CR> {<CR>}<ESC>O
inoremap (<CR> (<CR>)<ESC>O
" Checking Auto-completion of closing parenthesis
" Check the next character after input ) or } (closing parenthesis)
" in insert mode, then if the next character is a closing, it only
" moves cursor one character, else input a closing character.
inoremap <expr> ) strpart(getline('.'), col('.')-1, 1) == ")" ? "\<Right>" : ")"
inoremap <expr> } strpart(getline('.'), col('.')-1, 1) == "}" ? "\<Right>" : "}"
inoremap <expr> ] strpart(getline('.'), col('.')-1, 1) == "]" ? "\<Right>" : "]"
"inoremap <expr> \" strpart(getline('.'), col('.')-1, 1) == \" ? "\<Right>" : "\""
"inoremap <expr> \' strpart(getline('.'), col('.')-1, 1) == \' ? "\<Right>" : "\'"
" =====================
" Begin Vim-Plug
" =====================
"
call plug#begin('~/.vim/plugged')
Plug 'lervag/vimtex'
" -- Colorscheme and theme --
Plug 'jacoborus/tender.vim'
Plug 'itchyny/lightline.vim'
Plug 'vim-airline/vim-airline'
" --- Autocompletion ---
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
Plug 'deoplete-plugins/deoplete-jedi' " for Python
"Plug 'neoclide/coc.nvim', {'branch': 'release'}
"Plug 'pappasam/coc-jedi', { 'do': 'yarn install --frozen-lockfile && yarn build' }
" --- ALE (Asynchronous Linting Engine) ---
Plug 'dense-analysis/ale'
Plug 'Vimjas/vim-python-pep8-indent'
call plug#end()
" End Vim-Plug Installation =========
"
" deoplete.nvim is enable by default
let g:deoplete#enable_at_startup = 1
" Vimtex settings
call deoplete#custom#var('omni', 'input_patterns', {
\ 'tex': g:vimtex#re#deoplete
\})
" --- ALE settings
" Setting ALE (Asyncronus Linting Engine)
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
let g:ale_lint_on_text_changed = 'always'
" Colorscheme settings
if (has("termguicolors"))
set termguicolors
let g:lightline = { 'colorscheme': 'tender' }
" lightline
Plug 'itchyny/lightline.vim'
" Airline
Plug 'vim-airline/vim-airline'
let g:airline#extensions#tabline#enabled = 1
let g:airline_theme = 'tender'
endif
colorscheme tender " Choose tender as colorscheme
syntax enable
filetype plugin indent on
coc-nvim を使いたいが,いまの環境(deopleteとの組み合わせ)ではエラーを吐くのでdeoplete.nvim
を消して補完環境をcoc-nvim
に統一すること.
補足:Tmux の基本設定&キーバインド
余談:
まだWindows Terminal は分割画面(ペイン:pane)を作成(ショートカット:Alt+Shift+- または Alt+Shift+'+'でそれぞれ横分割,縦分割)したときにどのディレクトリにいたとしてもカレントディレクトリはデフォルトの%HOME%
となってしまう.これに関してはまだ Microsoft は対応していない(ついでにクリップボードからペーストするときのフォーマット崩れとか,メモリ消費量が半端ない問題も修正してほしい).
そこで,Tmuxを使うことにした.Tmuxの利点はたくさんあるが,一番はシェルを閉じてもセッションが切断されないことだと思う.これにより,再度ターミナルを使うときに以前の編集状態やパスを保持した状態で作業を再開できる.
以下は https://tanakatarou.tech/25/ をもとに追記&修正
# prefixキーをC-oに変更する
set -g prefix C-t
# デフォルトでprefix がC-b になっているので、そのキーバインドを解除する
unbind C-b
# + でペインを縦に分割する
bind + split-window -h
# - でペインを横に分割する
bind - split-window -v
# ウィンドウの一覧を表示します.
bind w choose-tree -Zw
# 次のペインに移動
bind Tab select-pane -t :.+
# キーバインドの一覧を表示します.リストはC-n,C-pで移動できます.
bind ? list-keys
# prefix + rで設定ファイルをリロードする。.tmux.conf を変更したらリロード!
bind r source-file ~/.tmux.conf \; display "Reloaded!"
# Vimのキーバインドでペインの大きさを変える
bind -r C-h resize-pane -L 5
bind -r C-j resize-pane -D 5
bind -r C-k resize-pane -U 5
bind -r C-l resize-pane -R 5
# Enable mouse
set-option -g mouse on
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"
bind -n WheelDownPane select-pane -t= \; send-keys -M
# キーストロークのディレイを減らす
set -g escape-time 1
# ウィンドウのインデックスを1から始める
set -g base-index 1
# ペインのインデックスを1から始める
set -g pane-base-index 1
# ステータスバーを設定する
set -g status-interval 60
## ヴィジュアルノーティフィケーションを有効にする
set -g visual-activity on
## ステータスバーを上部に表示する
#set -g status-position bottom
# ステータスバーの色を設定する
set -g status-bg "colour238"
# status line の文字色を指定する。
set -g status-fg "colour255"
# Default terminal is "xterm-256color"
set -g default-terminal "xterm-256color"
# アクティブなペインのみ白っぽく変更(真っ黒は232)
set -g window-style 'bg=colour239'
set -g window-active-style 'bg=colour234'
Tmux の基本操作
上の設定をもとにまとめておく
-
tmux new -s <セッション名>
:タグ<セッション名>
のセッションを開始する -
tmux a -t <セッション名>
:タグ<セッション名>
のセッションを再開する(アタッチ) -
tmux kill-session -t <セッション名>
:タグ<セッション名>
のセッションを終了 -
<C-t>
:プレフィックス -
<C-t> d
:アクティブセッションをデタッチ,抜ける(セッションは保持される) -
<C-t>+[h/j/k/l]
:アクティブペインのサイズ変更(それぞれ,左,下,上,右に伸縮) -
<C-t> <tab>
:アクティブなペインを移動する
新たに覚えた基本操作
すべて https://neovim.io/doc/user/tabpage.html を参考にすればよい.一部記載する.
-
:tabnew [file]
:新しいタブでファイルを開く -
:tabc[lose][!]
:現在のタブを閉じる(!
を付けた場合はファイル内容に変更があっても強制的に閉じる) -
gt
または:tabn[ext]
:次のタブに移動する -
gT
:前のタブに移動する -
{番号}gt
:指定した番号のタブへジャンプする -
:tabs
:現在開いているタブの一覧を見る -
zg
:スペルチェックの辞書への登録(英文のときカーソル上の単語が登録される) -
zug
:スペルチェック辞書から削除 -
zw
:スペルチェック辞書に wrong word として登録(エディタで赤く表示される) -
zuw
:zug
と同じ要領
Deoplete の操作方法
-
<C-n>
:次の候補 -
<C-p>
:前の候補 -
<C-k>
:選択,展開(確定する場合はさらにEnter
を押す必要がある)
Vimtex の操作
lervag/vimtex
はVimでTeXファイルを編集する際に有用なプラグインである.これも開発者のリポジトリ https://github.com/lervag/vimtex#features で書かれているが,必要なものをまとめておく.
- ノーマルモード時のカーソル移動:
-
[[
,[]
,][
,]]
でそれぞれ,前のセクション
,前のセクションの一行前
,次のセクションの一行前
,次のセクション
に移動する -
[m
,[M
,]m
,]M
でそれぞれ,前の環境のbegin
,前の環境のend
,次の環境のbegin
,次の環境のend
に移動する
以下も同じ要領で移動する.移動する環境 -
[n
,[N
,]n
,]N
でそれぞれ,前の数式環境のbegin
,前の数式環境のend
,次の環境のbegin
,前の数式環境のend
に移動する -
[r
,[R
,]r
,]R
:frame
環境 -
[*
,]*
:コメント
Move between matching delimiters with % -
%
:デリミターの間を行き来する.例えば,
-
\begin{frame}{Title}
\begin{align*}
f(x) & = x^\top Ax \\
g(x) & = \| x\| - 1 = 0
\end{align*}
\end{frame}
というファイルで\begin{frame}
のどこかにカーソルがある場合,一回%
を押すと\end{frame}
に飛び,もう一回%
を押すと\begin{frame}
に戻る.
-
テキストオブジェ
-
ic ac
:コマンド -
id ad
:デリミター -
ie ae
:LaTeX 環境 -
i$ a$
:インライン数式 -
iP aP
:セクション -
im am
:箇条書き
-
-
その他キーマッピング
-
dsc
,dse
,ds$
,dsd
:囲まれたコマンド
,環境
,デリミター(機能しない)
(以下同)を削除する -
csc
,cse
,cs$
,csd
:変更 -
tsc
,tse
:コマンド,もしくは囲まれた環境に*
を付ける -
tsd
:()
で実行すると\left(\right)
に変える -
tsf
:インラインの分数(/で表記する.e.g. 3/4)を\frac{分子}{分母}
に変える - (挿入モードで)
]]
:環境もしくはデリミターを閉じる記述を直後に自動補完
例:\begin{frame}
で]]
を実行すると\begin{frame}\end{frame}
となる -
<F7>
:コマンドを作成する.e.g.<F7>
=>sqrt<CR>
=>\sqrt{}
が作成される(あまり楽にならない?)
-
締め
この二日間 Neovim の環境構築に時間を費やして思ったことは,結局手っ取り早いのは
ちゃんと DOCUMENT を読むことである.DOCUMENTの情報量は半端でないが,適宜検索などで絞り込んで効率よく欲しい情報を一次ソースから得る習慣をつけたい.
楽そうだからという理由で,こうしたまとめ記事で目に留まったものに頼ってもいいけども,割と暗に環境依存して書かれていることがあって結局調べなおすということが半分以上の時間費やしていた気がする.
Pylint のモジュールインポートエラーを解決する
Pylint を使ったリアルタイム構文チェックをNeovimで利用する場合,ユーザーが作成したモジュールが読み込まれなくてnot defined
が出て邪魔に感じるだろう(プログラムを動かすときは問題ないにもかかわらず).その対策として,.pylintrc
を作業フォルダに作成する.
参考(修正):https://blog.515hikaru.net/entry/2017/01/26/031311
pylint --generate-rcfile >> .pylintrc
作業フォルダー上で.pylintrc
を作成して開くといろいろ書き込まれているが,[MASTER]
部分にコメントアウトで#init-hook=
という行があると思う.ここをコメントを外してカレントディレクトリをpylintのパスに追加すれば問題なく作業ディレクトリ上の作成したモジュール(python プログラム)が読み込まれる.
init-hook='import sys; sys.path.append(".")'
自動補完に coc.nvim を使用する場合
はじめに
Coc.nvim で自動補完プラグインを管理する場合,先に紹介したdeoplete
と競合するため,根本的に見直さなければならないので,本スクラップでフォーカスする Python 以外にも vimtex といった類のものもcoc-vimtex
( https://github.com/neoclide/coc-vimtex )をインストールする必要がある.また,Deoplete との大きな違いとしてはほとんどメジャーな言語の自動補完はcoc-[言語名]
でパッケージが用意されているため管理しやすい.しかし,体感として補完タブの動作言語は deoplete の Python と違って,JavaScriptということもあるのか若干遅い(正直本格的に調査していないので何とも言えない).
Node.js のインストール
WSL に Node.js をインストールする(Cocの起動に必要).
Node.js最新版のWSLへのインストール方法はすでに紹介されている諸記事を参考.
coc-jedi
の構築
coc.nvim と Python 用の補完環境注意:
先述したように,既に紹介した自動補完プラグインdeoplete
と競合するので,init.vim
でPlug 'Shougo/deoplete.nvim', {'...
とPlug 'deoplete-plugins/deoplete-jedi'
の行をコメントアウトし,:PlugClean
で拡張機能を削除する
-
Plug 'neoclide/coc.nvim', {'branch': 'release'}
を追加し,:PlugInstall
でcoc.nvim
をインストールする. -
:CocInstall coc-jedi
でPython自動補完プラグイン(coc-jedi)をインストールする. -
init.vim
で以下の行を追加
autocmd FileType python let b:coc_root_patterns = ['.git', '.env']
同時にdeoplete に関する記述
let g:deoplete#enable_at_startup = 1
と
call deoplete#custom#var('omni',...
をコメントアウトする.
-
coc-settings.json
を~/.config/nvim/
に用意する.以下の設定を記述すると,MSLS (Microsoft Language Server) でリアルタイムに構文データを参照する(jsonにはコメント構文がないので#
以降は消すこと!).
{
"python.jediEnabled": true, # いらないかも
"jedi.enable": true,
"jedi.startupMessage": false,
"jedi.markupKindPreferred": "plaintext",
"jedi.trace.server": "off",
"jedi.jediSettings.autoImportModules": [],
"jedi.executable.command": "jedi-language-server",
"jedi.executable.args": [],
"jedi.completion.disableSnippets": false,
"jedi.completion.resolveEagerly": false,
"jedi.diagnostics.enable": true,
"jedi.diagnostics.didOpen": true,
"jedi.diagnostics.didChange": true,
"jedi.diagnostics.didSave": true,
"jedi.workspace.extraPaths": ["."], # 公式は`[]`だがこれだと作業フォルダ内のモジュールが読み込まれないのでカレントを追加しておく
}
PYTHONPATH
の指定
開発時の注意:.pylint の設定でも書いた理由と同じようにcoc-python
で自動補完を行う場合,以下のファイルを作業フォルダに用意することで,パーサーが作業ディレクトリのモジュールデータベースを構築するため,インポートエラーが出力されなくなる.
PYTHONPATH="[pythonx.xがあるパス]/pythonx.x/site-packages"
要するに Neovim で Python 開発環境で自動補完を実現するために別途必要なファイルは
-
.env
:PYTHONPATH
の定義 -
.pylintrc
:Python 用 linting 設定ファイル(pylint --generate-rcfile >> .pylintrc
で作成し,`init-hookを追加)