かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ

iTerm2+NeoVimに定住するためにやったこと

最近ようやくNeoVim環境がいいかんじにまとまってきたので、振り返りついでに記事を書いてみます。 ターミナル開発環境を整えるためのTips集として読んで頂けると幸いです。

GitHubリポジトリでdotfilesも公開しているので、記事の中で「この設定どうやってやるの?」という部分があれば参照してみてください。

github.com

あと「もっといいツールとかおすすめ設定あるよ!」というのがあればぜひ教えて下さい!!

開発環境の概要

この記事では、Macを使うことを前提としています。 紹介する環境の概要は以下のとおりです。

  • よく書くコード : コンピュータビジョン系, 画像処理系, 数値計算
  • メインの開発言語 : C++ (CMake), CUDA, Python
  • マシン : MacBookPro (US配列) + GPU搭載のUbuntuサーバー
  • ターミナル : iTerm2
  • Shell : zsh + bash

紹介する内容は、全て2019年8月現在の最新リリースに従って書いています。

f:id:kamino-dev:20190812125041p:plain
大体こんな見た目

スポンサーリンク

もくじ

1. Mac本体

1.1. 英字配列キーボードのMacBookを買う

まずは、英字配列のキーボードにするところからスタートです。

個人的には、コーディングをするならJIS配列よりUS配列のほうが有利だと思っています。 US配列はJIS配列に比べて"が押しやすいこと、[, ]が横並びになっていること、右手小指からEnterまでの距離が近いことなどが理由です。

実は、日本国内で購入できるUS配列のノートパソコンはあまり多くないのですが、ありがたいことにMacBookは購入時にキーボード配列を指定できます。

また次の節で説明しますが、Macではスペースの左右にあるcommandキーを日本語/英数入力の切り替えキーにカスタムできるので、US配列でも日本語入力時のストレスはほとんどありません。

私の場合は、Windowsの外付けキーボードから徐々にUS配列に慣れていき、MacBookを買い換えるタイミングでUS配列に完全移行しました。 Elecomが1000円くらいでUS配列のキーボードを販売していたりするので、気になる方は一度試してみるのがいいと思います。

1.2. キーボード配列をカスタマイズする

世のほとんどのプログラマcaps lockcontrol/commandを入れ替えて使っていることと思いますが(偏見)、私も多分にもれずcaps lock, control, commandを三つ巴で入れ替えています。

2019年現在、Macでキーボード配列をいじるならKarabiner-Elements一択だと思います。 公式サイトはこちら

Karabiner-Elementsでは、単純なキースワップを設定できるSimple Modificationsと、複雑な条件や複数キー入力に関する変換ルールを設定できるComplex Modificationsの2種類の設定があります。

私は、Complex Modificationsを使って以下のような設定を組んでいます。

  1. ターミナルやVimキーバインドを利用するアプリ(Terminal, iTerm2, VSCodeなど)ではcaps lockcontrolを入れ替える
  2. それ以外のアプリではcaps lockキーをcommandに、両方のcommandキーをcontrolに、controlキーをcaps lockにする
  3. 右のcommandキーが単体で押されて放されたら日本語入力に、左のcommandキーが単体で押されて放されたら英数入力に(英字配列キーボード向けの設定)

Macでは主にcommandキーがWindowsでいうところのControlキーの役割を果たしているので、Aの左隣にはcommandを配置しています。

ただし、ターミナルのショートカットやVimコマンドで使うのはcontrolの方なので、ターミナルやVimキーバインドを有効にしたアプリを開いているときはcaps lockcontrolだけ入れ替えて、Aの左隣をcontrolにしています。

この設定だと、コピー&ペーストやアクティブウィンドウの切り替えのときに

  • ターミナルソフト : スペースの隣のキー + c, v, tab
  • その他(ブラウザやFinder): Aの左隣のキー + c, v, tab

という使い分けが生じますが、慣れでカバーしています。 そもそも、ターミナル上ではVimのヤンク機能やpbcopyを使うのでコピペする機会はそんなに多くないですし、アクティブウィンドウの切り替えはMission Control(F3 or 3本指で上にスワップするやつ)から行っているので不便は感じていません。

スポンサーリンク

2. shell関連

次に、shellに関連する設定です。 自分が使っているのはzshですが、以下で紹介する設定についてはbashでもだいたい同じことができます。

2.1. shellのショートカットを覚える

shellにはカーソル移動などに使えるショートカットがあります。 このショートカットは、EmacsがベースになっているのでVim派の人間としては覚えにくい代物なのですが、一度覚えればターミナル入力のストレスがかなり軽減されます。

自分がよく使うのは、以下のショートカットです。

  • Ctrl + a : カーソルを先頭に
  • Ctrl + e : カーソルを行末に [End]
  • Ctrl + f : カーソルを1つ右に [Forward]
  • Ctrl + b : カーソルを1つ左に [Back]
  • Ctrl + c : コマンド入力を中断(打ちかけたコマンドを無視して改行)
  • Ctrl + h : Backspaceと同じ
  • Ctrl + d : カーソルが当たっている文字を消す [Delete]
    • 何も入力していない状態で押すとshellを終了する
  • Ctrl + p : コマンド履歴を戻る [Previous]
  • Ctrl + n : コマンド履歴を進む [Next]
  • Ctrl + r : 過去に実行したコマンドから検索する
    • デフォルトの検索機能は使いにくいので、後述のpeco+historyに置き換えるのがおすすめ
  • Ctrl + l : 現在の行が一番上に来るようにスクロール
  • Ctrl + u : 打ちかけたコマンドを切り取り
  • Ctrl + w : カーソル位置より前の単語を切り取り [Word]
  • Ctrl + k : カーソル位置より後を切り取り
  • Ctrl + y : 切り取った文字列を貼り付け [Yank]

一応、これらのショートカットは~/.zshrc~/.bashrcで変更することもできますが、他の環境を触るときに混乱するのが嫌なので、デフォルトのまま使っています。

2.2. プロンプトをカスタマイズする

プロンプトとは、シェルの入力前に表示されるuser@user-ubuntu:Documents$とかのことです。

zshでは、設定ファイル~/.zshrcの中でPROMPT環境変数を上書きすることで変更できます。

PROMPT='%n@%m %d %?$ '

%nはログイン中のユーザー名、%mはホスト名、%dはカレントディレクトリのフルパス、%?は直前のコマンドの終了コードを意味します。上の設定ではuser@users-MacBook-Pro /Users/user 0$みたいなプロンプトが表示されるはずです。

個人的には、%?で直前のコマンドの終了コードを表示しておくのがおすすめです。 長々とメッセージが表示されるコマンドを実行したとき、結局成功したのか失敗したのかをひと目で判別できるからです。

他にもいくつかの特殊記号があるので、気になる方は公式ドキュメントを読んでみてください。

ちなみにbashの例はこちらです。

export PS1="\u@\h \w $ "

詳細はbash公式ドキュメントを確認してください。 残念ながらbashでは特殊記号で終了コードを取ることができません。 どうしてもという場合は自前で処理を書く必要があるので、こちらのstackoverflowの回答を参照してみてください。

2.3. ビープ音を消す

shellには、無効なキー操作をしたときや何らかの通知を行うためにビープ音を鳴らす機能がありますが、邪魔なので無効にしています。 zshの場合は~/.zshrcに以下のコマンドを追加すればいいです。

setopt no_beep

bashの場合は~/.inputrcに以下のコマンドを追加すればいいです。

set bell-style none

2.4. peco+historyを構築する

先ほどCtrl + rはコマンド履歴の検索のショートカットだと書きましたが、デフォルトの検索機能は割と使いづらいです。

そこで、pecoというツールを利用して独自に検索機能を作ります。 pecoはコマンドラインで検索・選択ができるようにするツールですが、これと履歴を表示するhistoryコマンドを組み合わせることで見栄えの良い履歴検索機能が作れます。

brewを使っているならpecoは以下のコマンドでインストールできます。 また、公式リポジトリからビルド済みバイナリをインストールする方法もあります。

brew install peco

pecoをインストールした上で~/.zshrcに以下のコマンドを追加すると、Ctrl + rで履歴検索機能が起動するようになります。

function peco-history-selection() {
    BUFFER=`history -n 1 | tail -r  | awk '!a[$0]++' | peco`
    CURSOR=$#BUFFER
    zle reset-prompt
}

zle -N peco-history-selection
bindkey '^R' peco-history-selection

f:id:kamino-dev:20190812124611p:plain
peco+historyのコマンド履歴検索

コマンドの一部を打って検索、Ctrl + n, Ctrl + pで候補の中から選択、Enterで決定、Ctrl + cで中断できます。

bashの場合は以下のコマンドを~/.bashrcに追加しましょう。 こちらは拾い物なので、たぶん上のコマンドと若干挙動が違うのですが、私は気にせず使っています()。

peco-select-history() {
    declare l=$(HISTTIMEFORMAT= history | sort -k1,1nr | perl -ne 'BEGIN { my @lines = (); } s/^\s*\d+\s*//; $in=$_; if (!(grep {$in eq $_} @lines)) { push(@lines, $in); print $in; }' | peco --query "$READLINE_LINE")
    READLINE_LINE="$l"
    READLINE_POINT=${#l}
}
bind -x '"\C-r": peco-select-history'

また、pecoはMac以外のOSでも動くので、リモートのLinuxサーバーでも同じ要領で履歴検索機能を組むことができます。

スポンサーリンク

3. iTerm2関連

MacにはデフォルトでTerminalというターミナルソフトが入っていますが、それ以上にiTerm2というオープンソースのターミナルソフトがかなり優秀なのでこれを導入しています。 iTerm2はこちらの公式サイトからインストールできます。

3.1. iTerm2のショートカットを設定する

iTerm2のショートカットはPreferences > Keysからカスタマイズできます。 私は、ほぼデフォルトのまま、Window/Tab/Pane関係のショートカットだけを以下のように変更しています。

f:id:kamino-dev:20190812122358p:plain
iTerm2のショートカット設定

よく使うショートカットは以下のとおりです。

  • command + n : 新しいwindowを作る
  • command + t : 新しいtabを作る
  • command + w : 今のtabを閉じる
  • command + Enter : フルスクリーンを切り替える
  • command + q : iTerm2を終了する
  • command + (Number) : tabを切り替える(ヘッダに番号が表示されているはず)
  • option + command + (Number) : windowを切り替える(ヘッダに番号が表示されているはず)

細かい画面分割はNeoVim側の役目と割り切っているので、iTerm2のPane機能は使っていません。

また、optionのdouble-tapでHotkey Windowが出てくるように設定しています。 Preferences > Keys > HotkeyからCreate a Dedicated Hotkey WindowでHotkey Windowのプロファイルを作成します。 以降の設定変更はPreferences > Profiles > Hotkey Windowから行えます。

この設定をしておけば、optionのダブルタップでいつでもHotkey Windowが上から降りてくるようになります。

f:id:kamino-dev:20190812123159p:plain
Hotkey Window

Hotkey Windowはちょっとしたファイル操作やpingを打つときなどに使っています。

3.2. ビープ音を消す

zshで消音設定をしていても、sshでリモートのbashを起動したときなどはビープ音が鳴ってしまうので、これを消すためにiTerm2側でも消音設定をしています。 Preferences > Profiles > TerminalのSilence bellにチェックを入れればOKです。 音の代わりに視覚的に知らせてくれる機能としてFlash visual bellShow bell icon in tabsがありますが、私はどちらも必要ないのでOFFにしています。

3.3. Status Barの設定

Status BarはiTerm2 ver.3.3から追加された機能です。 tmuxには各種情報を表示できるStatus Barがあるのですが、これと同じ機能がiTerm2に移植されたものです。

Status Barの設定はPreferences > Profiles > Default > Session > Configure Status Barから変更できます。

私の場合はホスト名, カレントディレクトリのフルパス, Gitブランチ, CPU使用率, メモリ使用率の5つを表示させています。

f:id:kamino-dev:20190812123433p:plain
Status Bar

さらに最近のアップデートで、各コンポーネントをクリックするとGUIから色々操作できるようになったようですね。 たとえばカレントディレクトリのコンポーネントをクリックすると、最近訪れたディレクトリへのcdコマンドが発行できます。 またGitのコンポーネントをクリックすると、CommitやLogなどの操作ができるようになっています。

3.4. Shell Integrationを使いこなす

iTerm2 Shell Integrationは、iTerm2上のshellに拡張機能を追加するためのパッケージです。 手元のMacの他にも、sshログイン先のサーバーでも利用できます。

インストールは簡単で、iTerm2でインストール先のshellを開いた状態で画面左上のiTerm2 > Install Shell Integrationをクリックするとインストールコマンドを実行してくれます。 このときにUtilitiesもインストールするかどうか聞かれるので、一緒にインストールしておきます。

基本機能

Shell Integrationの機能の詳細は公式ドキュメントで紹介されています。

私がよく使っているのは以下の機能です。

  • 過去のコマンド入力の行を辿ってスクロールする
    • command + shift + Up/Down
  • コマンド終了時にデスクトップ通知を出す
    • option + command + a
  • 過去に実行したコマンドの終了コードや実行時間を確認する
    • プロンプトの左に出る矢印を右クリック
  • 動的にプロファイル(iTerm2の設定)を切り替える
  • リモートのホスト名, ユーザー名, カレントディレクトリの情報をiTerm2のStatus Barなどに反映させる

他にもコマンド履歴を表示したりディレクトリ履歴を表示したりできるのですが、先ほど紹介したpeco+historyの方が便利なのであまり使っていません。

Utilities

一方、Shell Integration Utilitiesでは~/.iterm2以下にいくつかの便利なコマンドが追加されます。 各コマンドの機能の詳細はこちらの公式ドキュメントを参照してください。

自分がよく使うのは以下のコマンドです。

  • imgcat <filename> : ターミナル上に画像を表示する
  • imgls <filenames> : 指定されたファイルの一覧をサムネイル付きで表示する
  • it2copy : パイプで渡された情報をMacクリップボードにコピーする
    • つまりリモートでも使えるpbcopy
    • Preferences > General > Selection > Applications in terminal may access clipboardにチェックを入れておく必要がある
  • it2dl <filenames> : (リモートで実行)指定されたファイルをMacにダウンロードする
  • it2ul : (リモートで実行)Finderを開き、そこで指定されたファイルをアップロードする

f:id:kamino-dev:20190812123701p:plain
imgcat, it2dlを実行した様子

スポンサーリンク

4. NeoVim関連

NeoVimは従来のVimの拡張性や使いやすさを向上させるために新たに開発されているエディタです。 公式ページはこちら

Vimを現役で使っている人もいるとは思うのですが、私はNeoVimでしか動かないプラグインや、後述のTerminal emulatorとneovim-remoteを使う目的でNeoVimを選びました。

4.1. 基本設定を決める

Vimの設定ファイルは~/.vimrcですが、NeoVimの設定ファイルは~/.config/nvim/init.vimです。 設定ファイルの文法はほとんど一緒ですが、細かい設定項目が変わっているので調べながら書いていく必要があります。

私が使っている基本的な設定は以下のとおりです。

" 行番号を表示する
set number
" タブはスペース4つ分の幅で表示
set tabstop=4
" 空白部分でtabキーやbackspaceを押したときにカーソル移動する幅
set softtabstop=4
" 自動インデントの幅
set shiftwidth=4
" タブを入力したときスペース×Nに置き換える
set expandtab
" 改行時に前の行のインデントを継承する
set autoindent
" C系の文法に従って自動インデント、{}とかに反応する
set smartindent
" tabと行末の余計な空白を可視化する
set list
set listchars=tab:»-,trail:-
" ビープ音を鳴らさない、可視化もしない
set visualbell
set t_vb=

4.2. キーバインドをカスタマイズする

次に、Vimキーバインドのカスタマイズです。 私はデフォルトからかけ離れた設定をするのも嫌なので、よく使うものだけ既存のコマンドを邪魔しないように置き換えています。

まず、Vimではノーマルモード:を打つとコマンドモードになるわけですが、英字配列キーボードでは:を入力するためにshiftを押す必要があります。 :wとか:qとか打つ度にshiftキーを押すのは面倒です。 そこで;でコマンドモードに入るようにしています。

" [ノーマルモード] ;でコマンド入力
noremap ; :

ノーマルモードf <letter>shift+f <letter>を入力すると、その行内で文字を検索してカーソルを移動させることができ、複数ヒットしたときは続けて,:を入力すれば左右に移動できます。 この左右移動は,.にしたほうが直観的にわかりやすいと思い、.;に置換しています。

" [ノーマルモード] .でfやFで検索を繰り返し
noremap . ;

そして、上記の変更であぶれた.(直前の動作を繰り返す)の機能を;に割り当てています。

" [ノーマルモード] :で前の操作を繰り返し
noremap : .

次に、NeoVim内部のタブを左右に移動するためのコマンドはgT, gtなのですが、この操作はよく使うのでCtrl + h, Ctrl + lでも移動できるようにしています。

" [ノーマルモード] Ctrl + hで左のタブに移動
nnoremap <C-h> gT
" [ノーマルモード] Ctrl + lで右のタブに移動
nnoremap <C-l> gt

また、行頭, 行末に移動するためのコマンドは^, $ですが、これもshiftキーが必要な上、一番上の段のキーを押す必要があるので使いづらいです。 そこでspace, h, space, lでも移動できるようにしています。

" [ノーマルモード] space, hで行頭にカーソル移動
noremap <Space>h ^
" [ノーマルモード] space, lで行末にカーソル移動
noremap <Space>l $

NeoVimにはタブの中でshellを起動するTerminal emulatorが搭載されているのですが、新しいタブを開くには:tabnewを、そこでターミナルを起動するには:teを入力する必要があります。 これを一発で実行するためにspace, tを新しいターミナルタブを開くためのショートカットとして登録しています。

" [ノーマルモード] space, tで新しいターミナルタブを開く
noremap <Space>t :tabnew<CR>:te<CR>

最後に、ターミナルからノーマルモードに戻るときのコマンドはデフォルトではなぜかCtrl + \, Ctrl + nもしくはescapeになっているのですが、普段ノーマルモードに戻るときにCtrl + [を使っているので、これに合わせるための設定をしています。

" [ターミナルモード] Ctrl + [でノーマルモードに戻る
tnoremap <C-[> <C-\><C-n>

以上のキー設定で今のところは平和に暮らせています。

4.3. Vimキーバインドを覚える

自分なりのキーバインドを決めたら、あとはひたすら使い込んで覚えていくだけだと思います。壁紙をチート表にしてみたりもしましたが結局見ることはなかったので、毎日Vimを使って少しずつ新しいコマンドにチャレンジするのがいいと思います。

自分の場合はなんとなく以下の順番で覚えていったような気がします。

  • i, I, a, A, o, O, s, S(インサートモードに)
  • escape, Ctrl + [ノーマルモードに)
  • k, j, h, l(上下左右) , gg, G(先頭・末尾) , <number>G(N行目へ移動)
  • 0, ^, $(行頭・インデントの行頭・行末)
  • Ctrl + u, Ctrl + d(半ページスクロール), Ctrl + e, Ctrl + y(1行スクロール)
  • x, dd, yy, p, P(1文字カット・カット・コピー・ペースト)
  • <number>j, d<number>jなど(複数行移動・複数行カット)
  • u, Ctrl + R(Undo, Redo
  • >>, <<(インデント操作)
  • v(範囲選択)からのd, y, s(カット・コピー・削除してインサートモードに)
  • Ctrl + v(矩形選択)からのd, y, I, A, s(複数行に同じ編集を施せる)
  • b, B, w, W, e, E(単語区切りでカーソル移動)
  • /<string>(文字列検索)からのn, N(検索結果を移動)
  • f<letter>, F<letter>(行内でその文字が見つかった場所へ移動)からの,, ;(さらに移動)
  • :%s/<before>/<after>/gl(文字列置換)
  • H, M, L(画面内の上段・中段・下段へ移動), zt, zz, zb(現在行が上段・中段・下段に来るようにスクロール)
  • q<letter>, @<letter>(マクロ)

4.4. プラグインを入れる

Vimの醍醐味と言えばプラグインですよね。 デフォルトのままでは色々と不便なのでプラグインを追加していきます。 Vimプラグイン関係の記事はたくさんあるので、この記事ではざっくりした説明だけしておきます。

Vimプラグインをインストールするための補助ツールにはいくつか種類がありますが、私はdein.vimを利用しています。 導入しているプラグインは以下のとおりです。

  • tomasr/molokai
  • vim-airline/vim-airline
  • myusuf3/numbers.vim
    • ノーマルモードで相対行番号、インサートモードではそのままの行番号を表示するプラグイン
    • 相対行番号の方がd<number>jとかが使いやすいので
  • scrooloose/nerdtree
  • jistr/vim-nerdtree-tabs
    • NERDTreeをタブ間で(擬似的に)単一のものにするためのプラグイン
  • Shougo/deoplete.nvim
  • autozimu/LanguageClient-neovim
    • Language Server Protocolに則った言語開発サポートを入れるためのフレームワーク
    • 使用する言語に応じたLanguage Serverの実行ファイル(C++clangdPythonpyls、Rustはrls)を指定すれば勝手に連動してくれる
  • rhysd/vim-clang-format
  • tell-k/vim-autopep8

まだ調整不足感はありますが、とりあえずこの構成で運用しています。

言語開発関係はLanguage Server Protocolを利用するのが鉄板だと思います。 Language Serverの実行ファイルをインストールしてLanguageClient-neovimに情報を登録しておけば、エラー表示・コード補完などをやってくれます。 ただしコードのリフォーマットはやってくれないものが多いので、言語別にオートフォーマット用のプラグインを入れています。

以上のプラグインのうちvim起動時に必ずロードするものの情報を~/.config/dein/plugins.tomlに書いておき、指定した条件(on_fton_ifなど)を満たしたときに遅延ロードさせたいプラグインの情報は~/.config/dein/plugins_lazy.tomlに書いておきます。 プラグインファイルの文法の詳細は:help deinを読むか、他の記事を参照してください。 一応、私が使っているプラグインファイルはGitHubにアップロードしてあります(https://github.com/kamino410/dotfiles/tree/master/.config/dein)。

あとはinit.vimに以下のようなスクリプトを書いてからNeoVimを起動すれば、dein.vim自体のインストールの後に他のプラグインをインストールしてくれます。 以下のスクリプトでは、インストール先は~/.cache/dein/になっています。

let g:cache_home = empty($XDG_CACHE_HOME) ? expand('$HOME/.cache') : $XDG_CACHE_HOME
let g:config_home = empty($XDG_CONFIG_HOME) ? expand('$HOME/.config') : $XDG_CONFIG_HOME
let s:dein_cache_dir = g:cache_home . '/dein'

if &runtimepath !~# '/dein.vim'
    let s:dein_repo_dir = s:dein_cache_dir . '/repos/github.com/Shougo/dein.vim'
    if !isdirectory(s:dein_repo_dir)
        call system('git clone https://github.com/Shougo/dein.vim ' . shellescape(s:dein_repo_dir))
    endif
    execute 'set runtimepath^=' . s:dein_repo_dir
endif

let g:dein#install_max_processes = 16
let g:dein#install_progress_type = 'title'
let g:dein#enable_notification = 1

if dein#load_state(s:dein_cache_dir)
    call dein#begin(s:dein_cache_dir)
    let s:toml_dir = g:config_home . '/dein'
    call dein#load_toml(s:toml_dir . '/plugins.toml' , {'lazy': 0})
    call dein#load_toml(s:toml_dir . '/plugins_lazy.toml' , {'lazy': 1})
    call dein#end()
    call dein#save_state()
endif

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

4.5. neovim-remoteを入れる

NeoVim内でターミナルを開いてファイル操作をしていると、そこからファイルを開きたくなることがありますが、nvim <filename>と打ってしまうとNeoVim内で別のNeoVimが起動してしまいます。 そこでneovim-remoteというツールを使います(公式リポジトリ)。

neovim-remoteをインストールするとnvrというコマンドが使えるようになります。 これを打つとNeoVimが自動で立てているサーバーにリクエストが投げられ、それを受けたNeoVimが指定されたファイルを開いてくれます。

私は新しいタブで開くためにnvr --remote-tabと打つことが多いので、~/.zshrcエイリアスnvrrを登録しています。

alias nvrr='nvr --remote-tab'

またNeoVim内のターミナルからgit commitしたときにコミットメッセージを入力するウィンドウをpaneとして開かせるため、~/.config/nvim/init.vimに以下の設定も追加しています。

let $GIT_EDITOR = 'nvr -cc split --remote-wait'
autocmd FileType gitcommit set bufhidden=delete

4.6. インストール用スクリプトを作る

新しくサーバーを組んだときやDockerでコンテナを作成したときに毎回ShellやNeoVimの環境を構築するのは面倒です。 そこで、ある程度自分の納得できる設定が決まったら環境構築用のスクリプトを書いてしまうことをおすすめします。

私はUbuntu18.04用に以下のようなスクリプトを使っています。

cat <<EOF2 >> install.sh
apt update
apt install -y software-properties-common
add-apt-repository -y ppa:neovim-ppa/unstable
apt update
apt install -y python3 neovim python3-pip git clang clang-tools curl clang-format peco
python3 -m pip install pynvim neovim neovim-remote autopep8
mkdir -p ~/.config
mkdir -p ~/.config/dein
mkdir -p ~/.config/nvim
mkdir -p ~/.config/nvim/ftplugin
mkdir -p ~/github
cd ~/github
git clone https://github.com/kamino410/dotfiles.git
cd ./dotfiles
git pull
cp ./.config/nvim/init.vim ~/.config/nvim
cp ./.config/nvim/ftplugin/cpp.vim ~/.config/nvim/ftplugin
cp ./.config/dein/plugins.toml ~/.config/dein
cd ~
cat <<EOF >> ~/.bashrc
export LC_ALL=en_US.UTF-8
alias nvrr='nvr --remote-tab'
peco-select-history() {
 declare l=
 READLINE_LINE=""
 READLINE_POINT=0
}
bind -x '"\C-r": peco-select-history'
EOF
EOF2
sh install.sh

スポンサーリンク

5. その他

5.1. Gitの設定

git statusはよく使うのでgit stエイリアスを登録しています。 またコミットログをネットワーク図で確認するためのコマンドをgit glogとして登録しています。 普通のターミナルからコミットするときのために、gitのエディタもNeoVimに変更してあります。

git config --global alias.st status
git config --global alias.glog "log --all --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset%cd %Cblue%cn %Creset%s'"
git config --global core.editor nvim

5.2. Dockerコンテナ内でCtrl+pを使えるようにする

Dockerではコンテナを離脱するためのショートカットとしてCtrl + p, Ctrl + qが設けられているのですが、これがshellのショートカットCtrl + pと一部重複しているせいで、Dockerコンテナ内のshellでCtrl + pがうまく動作しないという事態が起こります。

これを回避するためショートカットをCtrl + \に変更する設定を~/.docker/config.jsonに追加しています。 ちなみに設定の反映にはdockerデーモンの再起動が必要です。

{
  "auths" : {
    "https://index.docker.io/v1/" : {
    }
  },
  "detachKeys" : "ctrl-\\"
}

5.3. CMakeとclangdを連動させる

NeoVim上でC/C++を書くときはLanguageClient-neovimでclangdから情報を受け取るわけですが、clangdはデフォルトでは標準ライブラリの情報しか読み取らないのでライブラリのコードの補完などはできません。

そこで、CMakeがfind_packageで読み込んだライブラリの情報をclangdに読み込ませます。 LanguageClient-neovimにclangdの情報を登録するときに以下のようにオプションが追加されるようにしておきます。

let g:LanguageClient_serverCommands = {
    'cpp': ['clangd', '-compile-commands-dir=' . getcwd() . '/build']
}

その上でCMakeLists.txtを書くときに以下の行を追加するようにしています。

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

すると./build/compile_commands.jsonというファイルにコンパイルコマンドの情報が記録されます。これをclangdが勝手に読み取り、ライブラリの情報なども反映してくれるようになります。


以上、ただただ自分の環境について語るポエム記事をお届けしました。