<まえがき> Vimはこわくない。
つい最近までVimといえば強いエンジニアが使うこわいエディターだという勝手なイメージが私の中にありました。
しかし、いざvimrcを自分でカスタマイズし始めると楽しくなってしまい、いつの間にかメインエディターがVimになりました。Vimmerの数だけVimがあり、使い方に正解のないというVimの魅力に気づいてしまったのです。
この記事ではこれまでに私が行ったVimを使いやすくするための設定とその手順を紹介します。
あくまでカスタマイズの一例として誰かの役に立てると嬉しいです。Vimはこわくありません!
目次
この記事では筆者がVimを(そこそこ)使いこなせるようになった設定とその導入手順をご紹介します。
手順に沿って設定を進めれば誰でもVimを(そこそこ)使えるようになるはずです
ダラダラと書いていたら長くなったので気になるところだけ読んでくださいmm
1. .vimrc をdotfilesで管理しよう
基本的にVimの設定は~/.vimrc
に記述します。(.vimrc
がない場合は作成します)
Vimの使い心地に大きく影響する.vimrc
をコンピュータごとにカスタマイズするのは大変です。
そこでdotfilesの出番です。dotfilesを利用して.vimrc
を効率的に管理しましょう。
この章の続きを読む
dotfilesは.zshrc
や.vimrc
といった設定ファイルを一つにまとめたディレクトリの総称です。
dotfilesをGit管理下におき、Gitホスティングサービス(GitHubなど)で管理することで、複数のコンピュータで同じ設定ファイルを簡単に用意することができます。
さっそくdotfilesを作成し、Git管理を始めましょう。
$ mkdir dotfiles
$ cd dotfiles
$ git init
次にdotfilesへバージョン管理したい設定ファイルを追加していきます。
例えば、ホームディレクトリ直下の何らかの設定ファイル.hogerc
をdotfilesで管理する流れは以下のようになります。
① ホームディレクトリ直下の.hogerc
を~/dotfiles/
へ移動させる。
② ホームディレクトリ直下に~/dotfiles/.hogerc
へのシンボリックリンクを作成する。
$ mv ~/.hogerc ~/dotfiles/
$ ln -s ~/dotfiles/.hogerc ~/.hogerc
シンボリックリンクの作成とは簡単に言えば「このファイルを参照したい時はこっちを見てね!」という目印ファイルを作成しておくことです。これによってこれまで通り設定ファイル~/.hogerc
への参照が解決されます(ハッピー)。
それでは上記の基本的な流れに沿って.vimrc
をdotfilesで管理しましょう。
$ mv ~/.vimrc ~/dotfiles/
$ ln -s ~/dotfiles/.vimrc ~/.vimrc
これでdotfilesで.vimrc
管理を始めることができました
ついでにホームディクレクトリ直下の.vim
.zshrc
.zprofile
といった設定ファイルも ~/dotfiles/ へ移動させ、シンボリックリンクを作成しておきましょう。
ここからは余談ですが、dotfilesにはinstall.sh
などの名前で、シンボリックリンク作成やパッケージインストールのコマンドをまとめたシェルスクリプトを用意しておくことが多いようです。dotfilesをgit clone
してinstall.sh
を実行するだけで環境設定が終わればとってもスマートです
GitHubで公開されている様々なdotfilesを参考に、オリジナルのdotfilesを育てていくと良さそうです。
2. Vimの基本設定をしよう
この章では、筆者の.vimrc
を紹介します。
すでに.vimrc
を自分でカスタマイズしている方はスキップしていただいて大丈夫です。
以下の.vimrc
から必要な設定があればコピーしましょう。
この章の続きを読む
" シェルを指定してください
set shell=/bin/zsh
" encoding
set encoding=utf8
scriptencoding utf8
set fileencoding=utf-8
set termencoding=utf8
set fileencodings=utf-8,ucs-boms,euc-jp,ep932
set fileformats=unix,dos,mac
set ambiwidth=double
set nobomb
set t_Co=256
" スワップファイルの作成先を変更
set noswapfile
" ヤンクをクリップボードへ繋ぐ
set clipboard=unnamed
" ビープ音を消す
set belloff=all
" 行番号系
set number
" タイトル系
set title
" インデント系
filetype plugin indent on
set expandtab
set tabstop=2
set softtabstop=2
set autoindent
set smartindent
set shiftwidth=2
au FileType go setlocal sw=4 ts=4 sts=4 noet
set list listchars=tab:»-,trail:-,eol:↲,extends:»,precedes:«,nbsp:%
" 挿入モードでバックスペース削除を有効
set backspace=indent,eol,start
" 検索するときに大文字小文字を区別しない
set ignorecase
" 検索した時にハイライト
set hlsearch
" キーバインド------------------------------------------------------------------
" xで削除した時はヤンクしない
vnoremap x "_x
nnoremap x "_x
" 現在のバッファ削除
nnoremap bd :bd<CR>
" 括弧の補完
inoremap {<Enter> {}<Left><CR><ESC><S-o>
inoremap [<Enter> []<Left><CR><ESC><S-o>
inoremap (<Enter> ()<Left><CR><ESC><S-o>
" クオーテーションの補完
inoremap ' ''<LEFT>
inoremap " ""<LEFT>
" insertモードでemacsのキーバインドを使えるようにする
imap <C-p> <Up>
imap <C-n> <Down>
imap <C-b> <Left>
imap <C-f> <Right>
" visulaモードでインデント調整後に選択範囲を開放しない
vnoremap > >gv
vnoremap < <gv
" 画面分割系
nnoremap sj <C-w>j
nnoremap sk <C-w>k
nnoremap sl <C-w>l
nnoremap sh <C-w>h
nnoremap ss :<C-u>sp<CR><C-w>j
nnoremap sv :<C-u>vs<CR><C-w>l
" plugin manager ---------------------------------------------
" 4章で紹介
" ------------------------------------------------------------
" カラースキーム(任意です)
if (empty($TMUX))
if (has("nvim"))
let $NVIM_TUI_ENABLE_TRUE_COLOR=1
endif
if (has("termguicolors"))
set termguicolors
endif
endif
syntax on
上記の.vimrc
をコピーするとデフォルトのVimに行番号表示、括弧補完などの機能が追加されます。
Vimが少しだけリッチになりましたね
(なお、筆者の.vimrc
をそのままコピーした方はこれ以降の章の.vimrc
への追記の項目はスキップして大丈夫です)
ちなみに筆者の最新の.vimrc
はこちらです。
3. VimとEmacsのキーバインドと仲良くなろう
Vimの独特なキーバインドは慣れるまでは苦行のように感じるかもしれません。さらにVimに登場するモードという概念が他のエディターから移ってきた人を混乱させます。しかし、一度慣れてしまえばその強力なキーバインドに病みつきになってしまうでしょう。
Vimのキーバインドを使いこなすためには練習あるのみです。
筆者の場合は1週間Vim以外のエディターを使わないという縛りを課すことでVimに対する気持ち悪さを消すことができました。
(Vimのキーバインドを紹介する記事は広いインターネットの世界にたくさん転がっているため、ここでは細かいキーバインドの説明は割愛します)
この章の続きを読む
はじめてVimの操作を学ぶにはチュートリアルが最適です。
$ vimtutor
コマンドを実行すると以下の画面が立ち上がり、Vimの操作方法を順序よく学ぶことができます。
ちなみに$ vimtutor en
とコマンドを実行すると言語を切り替えることができます(できました)。
さて、この章のタイトルは**「VimとEmacsのキーバインドと仲良くなろう」**でした。
なぜEmacs???と疑問に思われた方もいるのではないでしょうか。
実はMacOSはデフォルトでEmacsライクなキーバインドが使えます。
試しにGoogle documentのファイルの中でEmacsキーバインドを使ってカーソルを移動させると上手く動作することが確認できます。
覚えると便利なEmacsカーソル操作のキーバインドは以下です。(C-p: コントロールキーを押しながらpを押すという意味)
Emacsキーバインド | 説明 | 単語の意味 | Vimキーバインドでは |
---|---|---|---|
C-p | 1 行上に移動 | previous | k |
C-n | 1 行下に移動 | next | j |
C-f | 1 文字前に移動 | forward | h |
C-b | 1 文字後に移動 | back | l |
C-a | 行の先頭に移動 | - | ^ |
C-e | 行の末尾に移動 | - | $ |
一見するとキーが散らばっていて難しく感じますが、単語の意味を考えると覚えやすいと思います。 |
.vimrc
に以下の設定を追加した時、上記のEmacsキーバインドがVimで威力を発揮します
" InsertモードでEmacsのキーバインドを使えるようにする
imap <C-p> <Up>
imap <C-n> <Down>
imap <C-b> <Left>
imap <C-f> <Right>
imap <C-a> <C-o>:call <SID>home()<CR>
imap <C-e> <End>
imap <C-d> <Del>
imap <C-h> <BS>
imap <C-k> <C-r>=<SID>kill()<CR>
コメントアウトの通りですが、上記の設定を追加するとInsertモードでEmacsキーバインドを利用したカーソル移動が可能になります。
地味ですが、Normalモードに戻らずカーソルを操作できるのは便利です。
ちょっとした編集の際にぜひ使ってみてください
4. dein.vimでプラグインを管理しよう
幸せなことにインターネットの世界では私たちのVimを強化するプラグインを公開してくれている方々がいます。
その恩恵を最大限に受けるためにもプラグインマネージャを使ってプラグインを効率的に管理しましょう。
公開されているプラグインマネージャーにも様々なものがありますが、筆者はShougoさんが開発されている dein.vim を使っています。
この章ではdein.vimの基本的な使い方を解説します。さっそくdein.vimを使ってプラグイン管理をはじめてみましょう。
Quick startに記載されている通りの手順を踏めばdein.vimの導入は簡単です。
しかし、ここでは一歩踏み込んだ設定としてプラグインの設定をtomlファイルとして切り出す方法を紹介します。
この章の続きを読む
まずは以下のコマンドを実行してdein.vimをインストールしましょう。
2つ目のコマンドではdein本体をインストールするディレクトリを自由に指定することができます。
ここでは~/.vim/bundles
としていますが ~/.cache/dein
や ~/.local/share/dein
など他のディレクトリを指定することもできます。もし他のディレクトリを指定した場合はこれ以降の~/.vim/bundles
を自分の指定ディレクトリに合わせて変更してください。
$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.vim/bundles
次に、.vimrc
に以下の設定を追加しましょう。
" plugin manager ---------------------------------------------
if &compatible
set nocompatible
endif
" プラグインがインストールされるディレクトリ
let s:dein_dir = expand('~/.vim/bundles')
" dein.vim本体
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'
if &runtimepath !~# '/dein.vim'
if !isdirectory(s:dein_repo_dir)
execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
endif
execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir, ':p')
endif
" tomlセット
let s:toml_dir=expand('~/.dein/')
let s:toml=s:toml_dir . 'dein.toml'
let s:toml_lazy=s:toml_dir . 'dein-lazy.toml'
" プラグインのロード
if dein#load_state(s:dein_dir)
call dein#begin(s:dein_dir)
call dein#load_toml(s:toml)
call dein#load_toml(s:toml_lazy, {'lazy': 1})
call dein#end()
call dein#save_state()
endif
" インストールしていないプラグインがあればインストールを実行
if dein#check_install()
call dein#install()
endif
" ------------------------------------------------------------
ここでは.dein
配下のdein.toml
とdein-lazy.toml
という2つのtomlファイルを読み込む設定をしています。
したがって、.dein
ディレクトリをdotfiles直下に作り、ホームディレクトリ直下にシンボリックリンクを作成しておくと良さそうです。
$ cd ~/dotfiles
$ mkdir .dein
$ ln -s ~/dotfiles/.dein ~/.dein
$ cd .dein
$ touch dein.toml dein-lazy.toml
シンボリックリンクはファイルだけでなく、ディレクトリでも作成することが可能です。
dein-lazy.toml
は読み込み時に {'lazy': 1}
を指定してます。これによりdein-lazy.toml
には遅延読み込みが適用されます。
プラグインをたくさん追加するとVimの起動は遅くなりがちですが、起動時に必要のないプラグインはdein-lazy.toml
で遅延読み込みさせることでこの問題を解決することができます
またプラグインごとの設定をhookで管理できるため.vimrc
を散らかすことがなくなります。
hookについてはこちらの記事が参考になります。
[dein.vim] hook の便利な使い方
tomlファイルは基本的に以下のように記述します。
[[plugins]]
repo = 'インストールしたいプラグインのリポジトリ'
hook_add = 'Vim起動時に読み込む設定'
tomlファイルにプラグインを追記しておけば先ほど.vimrc
に記述した以下のスクリプトによってVimを起動するだけで新たなプラグインをインストールしてくれます
" インストールしていないプラグインがあればインストールを実行
if dein#check_install()
call dein#install()
endif
これでプラグインを効率的に管理できる環境が整いました
5. おすすめのプラグインを紹介します
この章では開発効率をUPさせるVimのおすすめプラグインを幾つかピックアップして紹介します。
プラグインを使用する上で必要なパッケージやツールのインストール方法と筆者のtomlファイルでの設定をまとめています。
この章の続きを読む
① preservim/nerdtree
GitHubのリポジトリ: https://github.com/preservim/nerdtree
NERDTreeを利用するとVim上で視認性の高いディレクトリツリーを表示することができます
使用方法
1. dein.tomlに設定を追記する。
[[plugins]]
repo = 'scrooloose/nerdtree'
hook_add = '''
let NERDTreeShowHidden=1
nnoremap <silent><C-a> :NERDTreeFind<CR>:vertical res 30<CR>
'''
筆者の設定では<C-a>
でディレクトリツリーを表示、:q
でディレクトリツリーを閉じます。
また、NERDTreeにはメニューモード(ディレクトリツリー上でm
を押す)で、子要素の追加や削除、リネームを簡単に行う機能があります。
▽NERDTreeの操作方法についてはこちらの記事が参考になります。
vim-plugin NERDTree で開発効率をアップする!
ちなみにデフォルトのVimでは:e .
でカレントディレクトリのファイル一覧を表示できます。
② vim-airline/vim-airline
GitHubのリポジトリ: https://github.com/vim-airline/vim-airline
vim-airlineを使うとグラフィカルで見た目がカッコいいステータスバーを手軽に利用することができます
使用方法
1. Power Line fontsをインストールする。
$ git clone https://github.com/powerline/fonts.git --depth=1
$ ./install.sh
$ cd ..
$ rm -rf fonts
2. dein.tomlに設定を追記する。
[[plugins]]
repo = 'vim-airline/vim-airline'
[[plugins]]
repo = 'vim-airline/vim-airline-themes'
depends = 'vim-airline'
hook_add = '''
let g:airline_theme = 'onedark'
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_idx_mode = 1
let g:airline#extensions#tabline#fnamemod = ':t'
'''
3. .vimrcに以下の設定を追記する。
" , キーで次タブのバッファを表示
nnoremap <silent> , :bprev<CR>
" . キーで前タブのバッファを表示
nnoremap <silent> . :bnext<CR>
" bdで現在のバッファを削除
nnoremap bd :bd<CR>
vim-airlineには様々なテーマが用意されています。
> vim-airlineのテーマ一覧
dein.tomlのlet g:airline_theme = 'onedark'
を書き換えて好みテーマを指定しましょう。
筆者の設定ではバッファタブを有効にしており、,
を押すと次にタブ、.
を押すと前のタブに移動することができます。
また、不要になったタブはbd
で削除できます。
Vimにはデフォルトのタブ機能がありますが、筆者はvim-airlineのバッファタブを利用しているため使用していません。
混乱を避けるためにデフォルトのタブ機能を使うかvim-airlineのバッファタブを使うか、どちらかを選んで利用するのが良いでしょう。
③ airblade/vim-gitgutter
GitHubのリポジトリ: https://github.com/airblade/vim-gitgutter
vim-gitgutterはGitの差分を行番号横のsignで分かりやすく示してくれます
使用方法
1. dein.tomlに設定を追記する。
[[plugins]]
repo = 'airblade/vim-gitgutter'
hook_add = '''
set signcolumn=yes
let g:gitgutter_async = 1
let g:gitgutter_sign_modified = 'rw'
highlight GitGutterAdd ctermfg=green
highlight GitGutterChange ctermfg=yellow
highlight GitGutterDelete ctermfg=red
highlight GitGutterChangeDelete ctermfg=yellow
'''
行番号横に表示されるsignのおかげでどこを編集したのかすぐに確認することができます。
④ tomtom/tcomment_vim
GitHubのリポジトリ: https://github.com/tomtom/tcomment_vim
tomtom/tcomment_vimを使うとVimでコメントアウト操作を手軽に行えるようになります
使用方法
1. dein.tomlに設定を追記する。
[[plugins]]
repo = 'tomtom/tcomment_vim'
hook_add = '''
vnoremap ? :'<,'>TComment<CR>
'''
筆者の設定ではVisualモードで?
(= Shift + /)を押すと選択した範囲をコメントアウトします。
ちなみに?
をキーバインドとして利用しているのはVSCodeで Cmd + /
キーでコメントアウトしていた名残です。
⑤ luochen1990/rainbow
GitHubのリポジトリ: https://github.com/luochen1990/rainbow
luochen1990/rainbowはVim上でカラフルな括弧を表示してくれます
使用方法
1. dein.tomlに設定を追記する。
[[plugins]]
repo = 'luochen1990/rainbow'
hook_add = '''
let g:rainbow_active = 1
'''
対応する括弧が色付けされて視認性が上がります。
⑥ alvan/vim-closetag
GitHubのリポジトリ: https://github.com/alvan/vim-closetag
alvan/vim-closetagを利用すると閉じタグを自動で補完してくれます
使用方法
1. dein-lazy.tomlに設定を追記する。
[[plugins]]
repo = 'alvan/vim-closetag'
on_ft = ['html', 'xhtml', 'javascript', 'typescript', 'javascript.jsx', 'typescript.tsx']
hook_add = '''
let g:closetag_filenames='*.html'
let g:closetag_xhtml_filenames='*.jsx,*.tsx,*.vue'
let g:closetag_filetypes='html'
let g:closetag_xhtml_filetypes='jsx,tsx,javascript.jsx,typescript.tsx,vue'
let g:closetag_emptyTags_caseSensitive=1
let g:closetag_shortcut='>'
'''
閉じタグの補完で地味に開発効率UPします
⑦ ryanoasis/vim-devicons
GitHubのリポジトリ: https://github.com/ryanoasis/vim-devicons
vimの中でアイコンを表示してくれるプラグインです。使用方法
①dein.tomlに設定を追記する。
[[plugins]]
repo = 'ryanoasis/vim-devicons'
②ターミナルとフォントの設定をする
↓ ターミナルとフォントの設定についてはスクラップボックスに書いたのでこちらをご覧ください。
vimにアイコンを表示するプラグインを入れた
アイコンが表示されるだけで一気にリッチなエディターに様変わりしましたね
⑧ easymotion/vim-easymotion
GitHubのリポジトリ: https://github.com/easymotion/vim-easymotion
高速なカーソル移動を実現するプラグインです。
使用方法
①vimrcにLeaderキーを設定する。
" <Leader>キー
let mapleader = " "
Leaderキーはキーのマッピング定義で使用できるプレフィックスキーです。キーマップを設定する時に<Leader>
として使用することができます。
簡単にいうとオリジナルのキーマッピングを利用する際にはじめに押すキーのことです。
筆者はスペースキー
をLeaderキーとして指定しています。
②dein.tomlに設定を追記する。
[[plugins]]
repo = 'easymotion/vim-easymotion'
hook_add = '''
nmap <Leader> <Plug>(easymotion-prefix)
let g:EasyMotion_do_mapping = 0 # デフォルトキーマッピングの無効化
nmap <Leader>w <Plug>(easymotion-jumptoanywhere) # 全画面移動
nmap <Leader>jk <Plug>(easymotion-sol-bd-jk) # 行頭移動
nmap <Leader>s <Plug>(easymotion-s2) # 全画面検索移動
'''
筆者はデフォルトのキーマッピングを無効化して、nmap
でキーを再帰マップしています。
スペース + w
で全画面移動。
スペース + jk
で行頭移動。
スペース + s
で全画面検索移動ができます。
6. 画面分割をビシバシっ!とキメよう
キーボードでの画面分割、画面移動の操作に慣れるとVimでの開発効率は格段にUPします。
この章では画面分割をビシバシっ!と決めれられるよう、便利なプラグインとキーバインドの設定を行います。
この章の続きを読む
デフォルトのVimではコマンドモードで:sp
や:vs
といったコマンドを実行することで画面分割ができます。
しかし毎回コマンドを実行するのはすこし面倒なので、画面分割を簡単にするキーバインドを設定しましょう。
nnoremap sj <C-w>j
nnoremap sk <C-w>k
nnoremap sl <C-w>l
nnoremap sh <C-w>h
nnoremap ss :<C-u>sp<CR><C-w>j
nnoremap sv :<C-u>vs<CR><C-w>l
上記のキーバインドはPrefixとしてs
キーを使用します。
垂直方向へ画面を分割したい時はまずs
を押してv
を押します。
水平方向へ画面を分割したい時はまずs
を押してs
を押します。
そして画面の移動はs
を押したあとにVimお馴染みの方向キーh
j
k
l
で行います。
オリジナルのキーバインドを設定することで画面分割がとても簡単になりました
▽ 画面分割については以下の記事が参考になります。
Vimの便利な画面分割&タブページと、それを更に便利にする方法
画面の分割と移動が簡単にできるようになったので、次は画面サイズの変更も簡単に行いたくなってきました。
そこで画面サイズの変更を簡単に行えるプラグインを導入します。
simeji/winresizer
GitHubのリポジトリ: https://github.com/simeji/winresizer
simeji/winresizerは画面サイズの変更を簡単にするプラグインです
使用方法
- dein.tomlに設定を追記する。
[[plugins]]
repo = 'simeji/winresizer'
simeji/winresizerの使い方は以下のようになります。
① サイズを変更したい画面にカーソルを持ってきて<C-e>
(Ctr + e)を押す。
② 画面がwindow resize modeに切り替わるのでh
j
k
l
で画面サイズを自由に変更する。
③ エンターキーで画面サイズを確定させる。
とても簡単ですね
この章では画面の分割と移動、サイズの変更を簡単に行うための設定を紹介しました。
これからは息をはくように画面を分割してVimを使いこなしましょう
7. tmux導入してターミナル環境を整えよう
(※ tmuxは次章で紹介するtigと合わせて使うと便利です)
強いエディター代表のVSCodeにはcommand+j
で簡単にターミナルを起動できる機能があります。
やはりVSCodeは最強のエディターなのでしょうか?(心の声<はい、そうです。))
いえ、必ずしもそうとは言えません。もちろんVimでも同じようなことができます
この章の続きを読む
Vimを使い始めたころ、VSCodeが恋しくて仕方ありませんでした。
特にターミナル機能をVimで実現するにはどうすれば良いのかと悩んでいました。
しかし、気づいたのです。
**Vimをカスタマイズするのではなく、実行環境であるターミナルを使いやすくすれば良いのだ!**と。
tmuxで複数のターミナルを操作しよう
tmuxを使えば1つのウィンドウ(tmuxセッション)の中で複数のターミナル(独立した疑似端末/ペイン)を起動することができます。
簡単に言えば「今まで別々のタブやウィンドウで起動していたターミナルを一つにまとめられるぞっ!」ということです。
使用方法
1. tmuxをインストールする。
$ brew install tmux
$ brew install reattach-to-user-namespace (← こちらはtmuxのコピーモードをクリップボードと連携させるために必要です)
2. 設定ファイル.tmux.conf
をdotfiles直下に用意し、ホームディクトリにシンボリックリンクを作成する。
$ cd ~/dotfiles
$ touch .tmux.conf
$ ln -s ~/dotfiles/.tmux.conf ~/.tmux.conf
-
.tmux.conf
に設定を記述する。
特にこだわりがなければ以下の設定をコピペしてください。
.tmux.confを表示
# シェルを設定してください
set-option -g default-shell /bin/zsh
# set prefix key
set -g prefix C-s
unbind C-b
set-option -g history-limit 100000
# enable mouse
set-option -g mouse on
# fix remaining word
set -s set-clipboard off
# color
set -g default-terminal "screen-256color"
set-option -ga terminal-overrides ",xterm-256color:Tc"
# reduce delay
set -sg escape-time 10
set-option -g repeat-time 500
# index number
set -g base-index 1
set -g pane-base-index 1
setw -g monitor-activity on
# create new window
bind c new-window -c '#{pane_current_path}'
# split window
bind v split-window -h -c '#{pane_current_path}'
bind s split-window -v -c '#{pane_current_path}'
# select pane
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# resize pane
bind -r H resize-pane -L 3
bind -r J resize-pane -D 3
bind -r K resize-pane -U 3
bind -r L resize-pane -R 3
# remove pane
bind q kill-pane
# copy mode settings
# start copy mode <C-s> + y
bind y copy-mode
setw -g mode-keys vi
# required: brew install reattach-to-user-namespace
set-option -g default-command "exec reattach-to-user-namespace -l $SHELL"
# USAGE) v: start select, y: yank, i: back to normal mode
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy" \; send-keys -X clear-selection
bind-key -T copy-mode-vi i send-keys -X cancel
- tmux起動のエイリアスを
.zshrc
に設定しておく。(任意です)
alias t='tmux'
シェルログインとともにtmuxを起動した人はこちら
# SHELL LOGIN WITH TMUX / If not running interactively, do not do anything
[[ $- != *i* ]] && return
[[ -z "$TMUX" ]] && exec tmux
tmuxの使い方は簡単です。
まずはターミナルでtmux
(エイリアスを使う場合はt
)とコマンドを入力しましょう。
すると以下のように新規のtmuxセッションが作成されます。
筆者の.tmux.conf
設定ではPrefixキーとして<C-s>
(Ctr + s)を使用しています。
tmuxでは一つの画面のことをペインと呼びますが、新たなペインを立ち上げる場合は以下のように操作します。
- 画面を垂直分割してペインを立ち上げる場合:
<C-s>
を押したあとにv
- 画面を水平分割してペインを立ち上げる場合:
<C-s>
を押したあとにs
そして、ペインの移動は<C-s>
を押したあとにh
j
k
l
キーで行うことができます。
この操作は1つの前の章で紹介したVim内の画面分割と似ていますね!
tmuxの画面分割はPrefixが<C-s>
、Vim内での画面分割はPrefixがs
で、コントロールキーを押すかどうかの違いだけです
そして分割したペインはexit
することで閉じることができます。
次に、ペインのサイズを変更してみましょう。
ペインのサイズは同じくPrefixキーである<C-s>
を押したあとにH
J
K
L
キーで行うことができます。
ペインの移動にshiftキーを加えただけです。
Vim内での画面サイズ変更とは少し違いますが、使っていくうちにすぐに慣れるので大丈夫です
ここまででtmuxでのペイン操作がスムーズにできるようになりました
これからはtmuxセッションの中でVimを使った開発を行い、ターミナル操作をしたくなれば新たなペインを立ち上げ簡単にコマンドを実行できます。もうVSCodeのターミナル機能が恋しくなることはありません
※ちなみに別ペインで操作した変更をVimで読み込む場合は:e!
コマンド(再読み込み)で対応できます。
tmuxについての余談
8. tigを使ってターミナルからGitを高速で操作しよう
Vimを使い始めてすぐに恋しくなったVSCodeの機能がありました。
それはGitの差分をグラフィカルなUIで確認でき、直感的操作でステージングやコミットできる機能です。
同じような操作性をVimに求めるのは難しいのでしょうか?
実はtigを使ってターミナル環境を整えれば全て解決します。しかも、VSCodeよりも高速にGitの操作が可能です。
この章の続きを読む
tmuxの章でも書いたようにVimをカスタマイズするのではなく、実行環境であるターミナルを使いやすくすることが重要です。
tigを導入してGitを操ろう
tigはターミナル上でGitの差分をカラフルに表示したり、操作することができるツールです。
使用方法
1. tigをインストールする。
$ brew install tig
2. 設定ファイル.tigrc
をdotfiles直下に用意し、ホームディクトリにシンボリックリンクを作成する。
$ cd ~/dotfiles
$ touch .tigrc
$ ln -s ~/dotfiles/.tigrc ~/.tigrc
-
.tigrc
に設定を記述する。
特にこだわりがなければ以下の設定をコピペしてください。
#--------------------------------------------------------------#
## tig settings ##
#--------------------------------------------------------------#
set main-view = id:yes date:default,local=yes author commit-title:graph=yes,refs=yes,overflow=false
set blame-view = date:default id:yes,color line-number:yes,interval=1 text
set pager-view = text
set stage-view = text
set log-view = text
set blob-view = text
set diff-view = text:yes,commit-title-overflow=no
set tab-size = 2
set ignore-case = true
set split-view-width = 80%
set split-view-height = 80%
set diff-options = -m --first-parent
set refresh-mode = auto
#--------------------------------------------------------------#
## key bind ##
#--------------------------------------------------------------#
# Pで現在のブランチへpush
bind generic P ?@!git push origin %(repo:head)
# Dでstatus viewのuntracked fileを削除できるようにする
# https://github.com/jonas/tig/issues/31 見るとおもしろい
# https://github.com/jonas/tig/issues/393 見るとおもしろい
bind status D ?@rm %(file)
# そのほかのGitコマンド
bind generic F ?@!git fetch %(remote)
bind generic U ?@!git pull %(remote)
color cursor black white bold
tigはターミナル上でtig
コマンドを実行することで起動します。
tigにはいくつかのviewがあり、起動したあとに以下のキーでviewを切り替えることができます。
キー | 表示されるview |
---|---|
m | Main view |
s | Status |
t | Tree (files) |
y | Stash view |
g | Grep |
h | Help |
ここでは主に利用することになるであろうStatus viewでのコミットからリモートへのpushまでの操作を簡単に説明します。
① tig
でtigを起動しs
を押す or tig status
を実行する
以下のようなStatus viewが表示されます。git status
した時と同じような表示で違和感ないと思います。
② u
でステージとアンステージを行う
ファイルをまるごとステージング、アンステージする場合はカーソルをファイルに合わせてu
を押します。
ファイル内のhunk(変更単位)ごとにステージング、アンステージする場合はファイルをエンターキーで選択し、hunk単位でu
を押します。
1行ずつステージ、アンステージする場合は1
を押します。
③ C
でコミットする
Status viewでC
(大文字)を押すとお馴染みのgit commit画面になりステージした内容をコミットできます。
③ P
でリモートリポジトリへpushする
最後に大文字のP
でHEADをリモートリポジトリへpushします。
tigの終了はq
です。
tigはとても便利なツールですね
具体的な使い方として前の章で紹介したtmuxと合わせ技をよく使います。
tmuxで分割ペインを立ち上げる → tigでコミット という流れです。
ちなみにStatus Viewで変更を取り消すときはu
ではなく!
を使います。
Untracked filesの変更を取り消す場合はD
を使います。
(Untracked filesの変更を取り消しコマンドD
はtig本体の機能ではなく.tigrc
のオリジナル設定です。なぜデフォルトでUntracked filesの変更を取り消し機能がないのかはこちらのIssueが参考になります。)
便利なtigとtmuxを使いこなしてVimとターミナルの環境を最強にしましょう
9. fzfで高速な単語検索とファイル検索を実現しよう
fzfを使えばカレントディレクトリから高速でファイルや単語をあいまい検索することができます。
さらにfzf.vimにはファイルの編集履歴から簡単にファイルを開くことができる機能もあります。
fzfの高速で強力な検索機能を使ってVimをもっと使いやすくしましょう
この章の続きを読む
まずはfzfをVimで使えるように設定しましょう。
使用方法
1. fzf本体のインストール
$ brew install fzf
2. ripgrepをインストール
ripgrepはgrepやAgより高速な検索ツールです。
$ brew install ripgrep
3. .zshrcに設定を追加
# Settings for fzf
export PATH="$PATH:$HOME/.fzf/bin"
export FZF_DEFAULT_COMMAND='rg --files --hidden --glob "!.git"'
export FZF_DEFAULT_OPTS='--height 30% --border'
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
4. Vim用のプラグインをインストール
dein.tomlに以下の設定を追加してください。
# fzf
[[plugins]]
repo = 'junegunn/fzf'
hook_post_update = './install --all'
merged = 0
# fzf.vim
[[plugins]]
repo = 'junegunn/fzf.vim'
depends = 'fzf'
hook_add = '''
command! -bang -nargs=* Rg
\ call fzf#vim#grep(
\ 'rg --column --line-number --hidden --ignore-case --no-heading --color=always '.shellescape(<q-args>), 1,
\ <bang>0 ? fzf#vim#with_preview({'options': '--delimiter : --nth 4..'}, 'up:60%')
\ : fzf#vim#with_preview({'options': '--delimiter : --nth 4..'}, 'right:50%:hidden', '?'),
\ <bang>0)
nnoremap <C-g> :Rg<Space>
nnoremap <C-p> :GFiles<CR>
nnoremap <C-h> :History<CR>
'''
以上でfzfの曖昧検索がVimで使えるようになりました
次に具体的な使い方をご紹介します。
カレントディレクトリ配下からファイル検索
例えばディレクトリをvim .
で開き、作業していたとします。
ファイルを検索したい時は<C-p>
(コントロール押しながらp)を押します。
すると以下のようにQuickfixでファイルのあいまい検索ができます。
カーソルの移動にはTAB
shift + TAB
か前の章で紹介したEmacsのキーバインドを使います。
ちなみになぜp
をバインドしているかというと以前にctrlp.vim
というプラグインを使っていた名残です。
しかし、実は<C-p>
には:GFiles
をバインドしているためGit管理下のファイルしか検索できません。
ほとんどの場合は:GFiles
で問題ないのですが、未だGitでtrackingしていないファイルを検索したい場合はコマンドモードで:Files
を実行してください。
するとGit管理していないファイルも検索することができます。コマンドを打つのが面倒な方はキーバインドを設定しても良いかもしれません。
バッファの編集履歴からファイルを開く
さっきまで開いていたファイルをもう一度開きたいということは良くあります。
そんな時は<C-h>
を使うとバッファの編集履歴(≒ファイルの編集履歴)からファイルを開くことができます。
h
は:History
のh
で覚えやすいと思います。
(ちなみに簡単なファイルバックの場合はVimデフォルトの<C-o>
でも可能です。)
カレントディレクトリ配下から単語を検索
例えばディレクトリをvim .
で開き、作業していたとします。
カレントディレクトリ以下のfzf
という単語を検索したくなった時は<C-g>
を押して、引数に検索したい単語を渡します。
すると上のGIFのようにカレントディレクトリ以下の単語を検索することができます。
ちなみに、?
を押すとカーソルで選択中のファイルの中身を見ることができます。
以上がfzfの簡単な使い方です。
ここで紹介した検索以外にもfzf.vimには様々な検索方法があります。詳しくはコマンド一覧をご覧ください。
私の友人はfzfがあればNERDTREEやタブなんて要らないと言っていましたが本当にそうだと思います。
これからはfzfでバシバシと検索を使いましょう
10. 強力なLanguage Serverの恩恵を受けよう
VimにLanguage Server(言語サーバー)との通信(LSP)をサポートするプラグインを追加すれば、非常に強力で便利な言語サーバーの恩恵を受けることができます。
言語サーバーの恩恵によって実現できる機能には以下のようなものが挙げられます。
① コードジャンプ(定義元ジャンプ)
② リアルタイムの入力補完
③ エラー警告やインフォメーションの表示
この章ではLanguage Server Protocol(LSP)をサポートしているVimのプラグイン「coc.nvim」の導入手順と基本的な使い方を紹介します。
この章の続きを読む
はじめに言語サーバーとその通信プロトコルであるLSP(Language Server Protocol)について簡単に説明します。
言語サーバーはエディターとは別のプロセスで独立して立ち上がります。
エディターから言語サーバーに対してリクエストが送られると、言語サーバーはそれに応じたレスポンスを返します。このリクエストとレスポンスの通信方式の決まりがLSP(Language Server Protocol)です。
決まった通信プロトコルを利用する言語サーバーを用意しておけば、クライアント(エディター側)は言語サーバーとのやりとりだけで仕様の異なる言語ごとの機能を実装できるようになります。つまり、エディターは言語ごとの実装を言語サーバーに任せられてハッピー!というわけです
言語サーバーとLSPについてはマイクロソフトの以下のページが参考になります。
言語サーバー プロトコル
次にLSPをサポートしているプラグイン「coc.nvim」をインストールしましょう。
coc.nvim
GitHubリポジトリ: https://github.com/neoclide/coc.nvim
使用方法
1. Node.jsをインストール(既にNode.jsをインストール済みの場合はスキップ)
$ curl -sL install-node.now.sh/lts | zsh
2. dein.tomlに設定を追加
[[plugins]]
repo = 'neoclide/coc.nvim'
rev = 'release'
build = '''
git checkout release
'''
hook_add = '''
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
'''
coc.nvimはLSPクライアント以外にも様々な機能をcoc extensions(拡張機能)として提供しています。(拡張機能一覧)
拡張機能はVimのコマンドモードで:CocInstall 拡張機能名
と実行することでインストールすることができます。拡張機能の本体は~/.config/coc/extensions
にインストールされます。
例えば、coc-emojiをインストールしたい時は:CocInstall coc-emoji
とコマンドを実行します。インストール完了後、マークダウンファイルで:
を打つとたくさんの絵文字が補完で表示されるようになりました。
他にもcoc.nvimには様々な拡張機能が提供されているので、拡張機能一覧から欲しいものを見つけてインストールしましょう
続いてcoc.nvimで言語サーバーの恩恵を受けてみましょう。
coc.nvimはLSPクライアントであるため、言語サーバーは別で用意する必要があります。
言語サーバーはcoc.nvimの拡張機能として提供されているものと各自でインストールする必要があるものに分けられます。拡張機能が存在する場合は拡張機能を利用するのが良いでしょう。
例えばTypeScriptの言語サーバーは拡張機能(coc-tsserver)として用意されているため、:CocInstall coc-tsserver
を実行するだけで言語サーバーを用意することができます。
言語サーバーが拡張機能として提供されていない場合は、言語サーバーをインストールした後に~/.vim/coc-settings.json
に以下のように設定を追記します。
{
"languageserver": {
"golang": {
"command": "gopls",
"rootPatterns": [
"go.mod"
],
"filetypes": [
"go"
]
},
"bash": {
"command": "bash-language-server",
"args": [
"start"
],
"filetypes": [
"sh"
],
"ignoredRootPaths": [
"~"
]
}
}
言語サーバー一覧とcoc-settings.json
の記述例はこちらから確認できます。
言語サーバーの用意ができればいよいよコードジャンプ(定義元ジャンプ)
入力補完
警告やインフォメーションの表示
といった便利な機能が利用できるようになります
例えばTypeScriptの場合。
① コードジャンプ
関数や変数、型の定義元へオリジナルのキーバインドgd
で簡単にジャンプすることができます。
ちなみにジャンプ元のファイルへ戻るには<C-o>
が便利です。
② 入力補完
<tab>
またはEmacsキーバインドで候補を選択します。
③ 警告やインフォメーションの表示
こちらの例ではReactコンポーネントの引数の型が違うよ!とエラーを警告してくれました。
このように言語サーバーのパワーは非常に強力です
coc.nvimで言語サーバーの恩恵を受けてVimを最強の開発環境にしましょう!
ちなみにcoc.nvimにはfzfライクなあいまい検索を実現する拡張機能などもあります。好きなようにカスタマイズすると楽しそうです
<あとがき> Vimは楽しい!
この記事では私がVimをそこそこ使えるようになるまでに行った設定とその手順を紹介してみました。
ここで紹介したこと以外にもターミナル、tmux、Vimのカラースキームを統一する、高速なターミナルエミュレーターを導入するなどVimをもっと使いやすくする方法を考えると楽しいはずです。(わたしの使っているカラースキームはatom-one-dark-terminal、onedark.vimです。おすすめのターミナルエミュレーターはalacrittyです。)
Vimを使い始めてもうすぐ1ヶ月が経ちますが、今でも私のdotfilesはスクスクと成長中です。
きっとまた1ヶ月後にこの記事を読むとリライトしたくなる箇所がたくさんあるんだろうなと思っています
しかし、Vimが楽しいことはこれからも変わらない気がしています。
Vimの不満点が1つずつ消える度に「あ〜、、Vim最高!!」ってなるのすごいな。Vim scriptでも書けたらもっと楽しくなりそう。どうやら沼にハマってしまったようだ。
— jiroshin (@jiroshin_) November 25, 2019
今後もVimライフを楽しみましょう
2020.1.8 追記)
思ったより多くの方にこの記事を読んで頂けているようです。ありがとうございます
記事中の設定に改善点を発見した場合はできるだけ更新していますが、もしエラーが出ることがあれば変更リクエストまたはコメントでお知らせ頂けますと幸いです。