勝手なイメージですが、Vimをメインのエディターとして使っているエンジニアはバックエンドやインフラ領域をメインでやっている方が多いような気がします。
自分のようにフロントエンドメインでやっているエンジニアで、Vimをメインのエディターにしている方はあまりいないかなと思ったので、フロントエンドを中心にやっている自分のVimの設定や入れているプラグインについてまとめた記事を執筆してみました。
Vimを使うようになったきっかけやVimを使うようになって良かったこと、しんどかったことについても書いてみたので、この辺りは暇な人は読んでくれると嬉しいです。
普段使用している言語とかライブラリとか
普段は以下の言語やライブラリ、フレームワークを使うことが多いです。
- HTML・CSS・SCSS
- JavaScript・TypeScript
- React(FWだとNext.JS)
- Vue(FWだとNuxt.js)
- PHP(たまに触る)
- WordPress(たまに触る)
上記に加えて、前の職場ではLaravelを、今の職場ではバックエンドの人手が足りなかった時にGoを書いていた時期もありました。
Vimを使うようになったきっかけ
自分にプログラミングを教えてくれた方がいるのですが、その方がVimを使っていたからというのが大きな理由の一つです。
今から2年半くらい前にプログラミング学習を始めた頃は無難にVSCodeを使っていたのですが、プログラミングを教えてもらった方に「エディター何使っているんですか?」と聞いたら、「Vim使ってるよー」って返ってきまして、その時にVimの画面を見せてもらったのが自分とVimの出会いです。
黒い画面でカタカタやるのなんかプログラマーっぽくってかっこよくね?っていう、すごく軽いノリでVimを使い始めました。
後日、Vimについて色々調べていると、VimtutorっていうVimのチュートリアルがあるらしいということを知って触ってみたのですが、、、
「文字どうやって入力するの?これ?」
「終了の仕方もわからん...:qで終了?意味わからん」
「これで開発している人やばくねっ?」
このような感じだったのですが、Vimtutorを4周くらいしたら簡単なテキスト編集ならできるようになりました。
それから、しばらくはVimとVSCode半々くらいの割合でコードを書いていたのですが、キーボードだけで操作を完結できるのって便利だなーって思い、思い切ってメインのエディターをVimに変えました。
→プログラミング学習を初めて、4〜5ヶ月目くらいの話です。
メインのエディターをVimに変えてからは、ウェブ開発(フロントエンド・バックエンド)、ウェブ制作(開発メインですが制作をやることもある)、全てVimを使用してコーディングを行なっています。
Vimの設定について
まず初めに、Vimの基本的な設定と使用しているプラグインについて書いていこうと思います。
詳しい設定に関しては、こちらのリポジトリをご覧ください。
ディレクトリ構造やファイルの分け方について
自分のVimは以下のような感じでディレクトリやファイルを分割しています。
.
├── .vim(Vimの設定を配置するディレクトリ)
│ ├── coc-settings.json(coc.nvimの設定)
│ ├── colors(テーマファイル)
│ ├── indent(インデント周りの設定)
│ ├── templates(sonictemplate-vimで読み込むテンプレート)
│ └── vim_settings(.vimrcで読み込ませる設定)
│ ├── init
│ │ ├── basic-setteing.vim(基本設定)
│ │ ├── functions.vim(自作の関数)
│ │ ├── netrw.vim(netrwの設定)
│ │ ├── plugins.vim(使用するプラグインの記述)
│ │ ├── search-setting.vim(検索周りの設定)
│ │ └── theme.vim(テーマの設定)
│ └── plugin_settings
└── .vimrc
ディレクトリ構成ですが、自分でカスタマイズしたテーマやプラグインマネージャでインストールできないテーマに関しては、colors
に、言語ごとのインデントの設定は、indent
に、sonictemplate-vimというテンプレートを管理するプラグインで使用するテンプレートは、templates
ディレクトリで管理しています。
メインの設定は、vim_settings
配下で管理していて、ディレクトリは以下のように分割しています。
- init・・・初期化時に読み込ませたい or プラグインに依存しない設定ファイルを配置
- plugin_settings・・・プラグイン固有の設定ファイルを配置
プラグインに関連する設定なのか、プラグイン以外の設定なのかとかなり雑に分けています。
色々書いた設定を.vimrc
で読み込ませるようにしています。
runtime! vim_settings/init/*.vim
runtime! vim_settings/plugin_settings/*.vim
設定ファイルを細かめの粒度で分割している理由ですが、Vimの設定を全て.vimrc
に記述してしまうと、少し手を加えたい時に編集したい箇所を探すのが面倒になるため、ディレクトリやファイルは細かめの粒度で分割するようにしています。
分割方法に関しては、下記の記事を参考にしました。
initディレクトリ配下の設定ファイルについて
文字コードや、表示周り、キーマッピングの設定を記述しているbasic-setting.vim
はこんな感じになっています。
"----------------------------------------
" 基本の設定
"----------------------------------------
set encoding=UTF-8
set t_Co=256
" 全角スペースにシンタックスハイライトをかける
augroup highlightIdegraphicSpace
autocmd!
autocmd Colorscheme * highlight IdeographicSpace term=underline ctermbg=DarkGreen guibg=DarkGreen
autocmd VimEnter,WinEnter * match IdeographicSpace / /
augroup END
" vimのヘルプ機能を日本語化
set helplang=ja,en
" タイトルを表示
set title
" 行番号を表示
" set number
set numberwidth=5
" vimを使ってくれてありがとうを非表示
set notitle
" 記号などで字が潰れるのを防ぐ
set ambiwidth=double
" カーソルの位置を表示する
set ruler
" 不可視文字を可視化 (タブが「▸-」と表示される)
set list listchars=tab:\▸\-
" インデント周りの設定
set shiftwidth=2
set softtabstop=2
set tabstop=2
set expandtab
set autoindent
set smartindent
" 入力中のコマンドを表示
set showcmd
" 検索結果をハイライトで表示
set hlsearch
" ステータスバーを表示
set laststatus=2
" 対応するかっこやプレースを表示
set showmatch matchtime=1
" 文字の削除をバックスペースでもできるようにする
set backspace=indent,eol,start
" 行末の1文字先までカーソルを移動できるようにする
set virtualedit=onemore
" スワップファイルを作成しないようにする
set noswapfile
" ヤンクしたテキストをクリップボードにもコピーできるようにする
set clipboard+=unnamed
set clipboard+=unnamed,autoselect
" コマンドの補完
set wildmenu
set history=5000
" 画面分割のキーバインドを変更
map vsplit vs
map split sp
" 行を折り返さない
set nowrap
" HTMLとXMLの閉じタグの補完
augroup MyXML
autocmd!
autocmd Filetype html inoremap <buffer> </ </<C-x><C-o>
autocmd Filetype xml inoremap <buffer> </ </<C-x><C-o>
augroup END
" インサートモード時のキーマッピング
" ()と{}と[]と引用符の補完
inoremap (<Enter> ()<Left>
inoremap {<Enter> {}<Left>
inoremap [<Enter> []<Left>
inoremap "<Enter> ""<Left>
inoremap '<Enter> ''<Left>
inoremap `<Enter> ``<Left>
inoremap {<Space> {}<Left><CR><ESC><S-o>
inoremap [<Space> []<Left><CR><ESC><S-o>
" ノーマルモード時のキーマッピング
" 折り返し時に表示してる行単位で移動できるようにする
nnoremap j gj
nnoremap k gk
" インクリメント・デクリメント
nnoremap + <C-a>
nnoremap - <C-x>
" ESC連打でハイライト解除
nnoremap <Esc><Esc> :noh<CR><Esc>
" 矢印キー無効化 (矢印使って移動するのは甘え)
noremap <Left> <Nop>
noremap <Down> <Nop>
noremap <Up> <Nop>
noremap <Right> <Nop>
" 行番号の表示切り替え
nnoremap <Space>n :set invnumber<CR>
" 外部grepで検索対象から除外するディレクトリを指定
set grepprg=grep\ -rnIH\ --exclude-dir=node_modules\ --exclude-dir=.*\ --exclude-dir=out\ --exclude-dir=build\ --exclude-dir=vendor
検索周りの設定を記述している、search-setting.vim
はこんな感じになっています。
"----------------------------------------
" 検索に関する設定
"----------------------------------------
" 1文字入力毎に検索を行う
set incsearch
" 検索結果をハイライト
set hlsearch
" 検索時に英大小文字の区別を無視する
set ignorecase
" 全て英小文字で入力した場合のみ区別を無視する
set smartcase
テーマの設定を記述している、theme.vim
はこんな感じになっています。
"----------------------------------------
" テーマ
"----------------------------------------
" floating window(上書き)
autocmd ColorScheme * highlight Pmenu ctermbg=234
autocmd ColorScheme * highlight PmenuSel ctermbg=cyan
autocmd ColorScheme * highlight PmenuThumb ctermbg=darkcyan
autocmd ColorScheme * highlight PmenuSbar ctermbg=white
" gitの差分を表示する際の色(上書き)
autocmd ColorScheme * highlight DiffAdd cterm=bold ctermfg=10 ctermbg=22
autocmd ColorScheme * highlight DiffDelete cterm=bold ctermfg=10 ctermbg=52
autocmd ColorScheme * highlight DiffChange cterm=bold ctermfg=10 ctermbg=17
autocmd ColorScheme * highlight DiffText cterm=bold ctermfg=10 ctermbg=21
" 背景色tron256用(上書き)
" autocmd ColorScheme * highlight Normal ctermbg=0
" コメントアウトの色 pablo用(上書き)
autocmd ColorScheme * highlight Comment ctermfg=250
" 行数の数字が表示されてる部分の幅
set numberwidth=6
syntax enable
" colorscheme tron256
colorscheme pablo
特に変わった設定はしていませんが、以下の点は少しこだわっています。
- ()や{}、``などをエンター連打で補完できるようにキーマップを設定している
- 行番号の表示・非表示を
Space + n
で切り替えられるようにしている
コーディングしている時は不要な情報は極力シャットアウトしたいので、行番号はあえて表示していません。
ただ、行番号自体を表示したいケースは多いので、行番号の表示・非表示を切り替えることができるキーマップを設定して、行番号は表示したい時だけ表示できるようにしています。
テーマの設定に関してはデフォルトのままだと若干見づらいと感じた部分をちょいちょい手を加えて微調整するようにしています。
使用しているテーマですが、最近はVimにデフォルトでインストールされているpabloというテーマをメインで使用しています。
テーマに設定されている色自体はデフォルトから大きく変更はしていませんが、ターミナルの設定を変更して、使用できる色の種類を増やしたり、彩度や明度などを調整したりはしています。
→pabloを使っても同じ感じにはならないと思います。
使用しているプラグインについて
使用しているプラグインに関してはこんな感じです。
"----------------------------------------
" プラグイン
"----------------------------------------
call plug#begin()
" 1, インデントの可視化
Plug 'Yggdroot/indentLine'
" 2, ウィンドウサイズの変更を簡単にする
Plug 'simeji/winresizer'
" 3, ステータスバーのカスタマイズ
Plug 'itchyny/lightline.vim'
" 4, gitの情報を表示
Plug 'tpope/vim-fugitive'
" 5, 補完
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" 6, エメット
Plug 'mattn/emmet-vim'
" 7, jsx・tsxのシンタックスハイライト
Plug 'othree/yajs.vim', { 'for': ['jsx', 'tsx'] }
Plug 'maxmellon/vim-jsx-pretty', { 'for': ['jsx', 'tsx'] }
Plug 'HerringtonDarkholme/yats.vim', { 'for': ['jsx', 'tsx'] }
" 8, vim helpを日本語化
Plug 'vim-jp/vimdoc-ja'
" 9, 各種Lintを非同期実行
Plug 'w0rp/ale'
" 10, コメントアウトを効率化
Plug 'tyru/caw.vim'
" 11, 定義元ジャンプ
Plug 'pechorin/any-jump.vim', { 'on': 'AnyJump' }
" 12, テンプレートを管理するプラグイン
Plug 'mattn/sonictemplate-vim'
" 13, Vimからagを使えるようにする
Plug 'rking/ag.vim', { 'on': ['Ag', 'AgFile'] }
" 14, 複数ファイルの一括置換
Plug 'thinca/vim-qfreplace', { 'on': 'Qfreplace' }
" 15, タブにアイコンフォントを表示するために使用
Plug 'ryanoasis/vim-devicons'
" 16, quickfixで自由にファイルを開けるようにするためのプラグイン
Plug 'skanehira/qfopen.vim'
call plug#end()
プラグイン管理はvim-plugを使用しています。
プラグインのインストールから削除まで簡単にできるので気に入っています。
プラグイン周りで意識している部分だと、シンタックスハイライト系のプラグインはforを使用して、特定の拡張子のファイルを開いた時しか読み込ませないようにしています。
特定のコマンドしか使用していないプラグインに関してはonを使用して、指定したコマンドを実行した時しかプラグインを読み込ませないようにしたりとかはしています。
今回は、普段使用させていただいているプラグインの中で特に便利なものを抜粋して紹介させていただきます。
→紹介しきれなかったプラグインも感謝して使わせていただいています!
simeji/winresizer
ウィンドウのサイズを簡単に変更することができるプラグインです。
自分の場合は、Ctrl-E(デフォルトの設定)にキーマップを割り当てています。
ウィンドウのサイズ切り替えはよく使うので、重宝しています!
neoclide/coc.nvim
言わずと知れたVimをIDE化することができるプラグインです。
正確にはVimにLSP(Language Server Protocol)を導入することができるプラグインで、導入することでLSPを使用した補完やエラーが起きてる箇所の提示などがVim上でできるようになります。
設定はこんな感じです。
" ヒントを表示
" silent・・・コマンドラインへの出力を抑制する
" <C-u>hoge<cr>・・・特殊なキーのマッピング
" https://thinca.hatenablog.com/entry/20100205/1265307642
nnoremap <silent> <space>h :<C-u>call CocAction('doHover')<cr>
" cocで表示されるフローティングウィンドウのスクロールのキーマッピング
" issues: https://github.com/neoclide/coc.nvim/issues/609
nnoremap <nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
nnoremap <nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
inoremap <nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
inoremap <nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
nnoremap <silent> <space>l :CocList<CR>
下記のコマンドをVimのコマンドモードで入力するだけで、各種LSPをインストールできるので、簡単にLSPを利用できるのもポイント高いですね!
# VueのLSPを追加したい時
:CocInstall coc-vetur
僕が普段使用しているLSPはこんな感じです。
LSPじゃないのが1つ混ざっていますね。。。
coc-explorer
ファイラーはcoc.nvim経由でインストール可能なcoc-explorerを使っています。
Vimを使い始めてから1年くらいはNERDTreeを使っていたのですが、全体的に動きがもっさりしていたり、デフォルトのキーマッピングがわかりづらかったのもあって、より新しく拡張性が高そうなcoc-explorerに乗り換えました。
NERDTreeと比較すると動作も軽く、カスタマイズ性も高いので、非常に使いやすいファイラーだと思います!
設定はこんな感じです。
nnoremap <silent><C-n> :CocCommand explorer<CR>
" キーマッピング周りの設定
" MEMO: ディレクトリアイコンにホバーした状態で、sを押すと
" ホバーしたディレクトリを起点にしてファイラーを開き直せる
call coc#config("explorer",{
\"file.showHiddenFiles":"true",
\"icon.enableNerdfont":1,
\"keyMappingMode":"none",
\"keyMappings.global":{
\"h": "collapse",
\"l": ["expandable?", "expand", "open"],
\"k": "nodePrev",
\"j": "nodeNext",
\"o": "open",
\"i":"open:split",
\"S":"open:split:plain",
\"s":"open:vsplit",
\"t":"open:tab",
\"d":"delete",
\"D":"deleteForever",
\"a":"addFile",
\"A":"addDirectory",
\"r":"rename",
\"q":"quit",
\"/":"search",
\"R": "refresh",
\"yy": "copyFile",
\"dd": "cutFile",
\"p": "pasteFile",
\"G": ["wait", "gotoParent"],
\},
\})
mattn/emmet-vim
Vimでemmetが使えるようになるプラグインです。
Vimでフロントエンド開発をするなら必須と言っても過言ではないプラグインだと思います。
展開できるテンプレートのlangをjaに上書きする設定のみ行なっています。
let g:user_emmet_leader_key='<c-e>'
let g:user_emmet_settings = {
\ 'variables' : {
\ 'lang' : "ja"
\ },
\ 'html' : {
\ 'indentation' : ' ',
\ 'snippets' : {
\ 'html:5': "<!DOCTYPE html>\n"
\ ."<html lang=\"${lang}\">\n"
\ ."<head>\n"
\ ."\t<meta charset=\"${charset}\">\n"
\ ."\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n"
\ ."\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
\ ."\t<title></title>\n"
\ ."</head>\n"
\ ."<body>\n\t${child}|\n</body>\n"
\ ."</html>",
\ }
\ }
\}
w0rp/ale
リントを非同期で実行してくれるプラグインです。
フロントエンド開発だと、prettier、eslint、stylelintあたりをよく使うので、これらのフォーマッターやリントはファイル保存時に実行されるように設定を行なっています。
" 解説記事: https://kuune.org/text/2017/07/23/how-to-lint-and-autoformat-with-ale/
" 言語ごとに有効にするLintツールを設定する
let g:ale_linters = {
\ 'javascript': ['eslint', 'prettier'],
\ 'javascriptreact': ['eslint', 'prettier'],
\ 'typescript': ['eslint', 'prettier'],
\ 'typescriptreact': ['eslint', 'prettier'],
\ 'vue': ['eslint', 'prettier'],
\ 'css': ['stylelint', 'prettier'],
\ 'scss': ['stylelint', 'prettier'],
\ 'go': ['gofmt', 'goimports', 'remove_trailing_lines', 'trim_whitespace'],
\ }
" 言語ごとの自動整形を行うリンターの設定を行う
let g:ale_fixers = {
\ 'javascript': ['eslint', 'prettier'],
\ 'json': ['eslint', 'prettier'],
\ 'javascriptreact': ['eslint', 'prettier'],
\ 'typescript': ['eslint', 'prettier'],
\ 'typescriptreact': ['eslint', 'prettier'],
\ 'vue': ['eslint', 'prettier'],
\ 'css': ['stylelint', 'prettier'],
\ 'scss': ['stylelint', 'prettier'],
\ 'go': ['gofmt', 'goimports', 'remove_trailing_lines', 'trim_whitespace'],
\ }
" ファイル保存時に実行
let g:ale_fix_on_save = 1
" ローカルの設定ファイルを考慮する
let g:ale_javascript_prettier_use_local_config = 1
pechorin/any-jump.vim
単語にホバーした状態で、:AnyJump
を実行すると、ホバーしている単語と同じ単語を含むファイルをagで検索してフローティングウィンドウ内に表示してくれるプラグインです。
関数の定義元や変数の参照先に飛ぶときに重宝します。
使用するためには、agが必要です!
検索対象から除外したいファイルをanyjump.vim
に指定しています。
" Custom ignore files
let g:any_jump_ignored_files = ['log', 'logs', 'images', 'imgs', 'img', 'node_modules', 'out', 'build', 'vendor', '.git', 'jquery-*.js', '*.bak', '*.map', '*.tmp', '*.temp']
rking/ag.vim
agをVim上で実行して、実行結果をVimのQuickfixに流し込むプラグインです。
先程紹介したany-jumpとこのag.vimは、Vimの検索能力を強化するために導入しています。
検索対象から除外したいファイルは.agignore
に指定しています。
log
logs
images
imgs
img
node_modules
out
build
vendor
.git
jquery-*.js
*.bak
*.map
*.tmp
*.temp
any-jump.vimと役割が被っていますが、以下のように使い分けたいので、2種類のプラグインを導入しています。
- any-jump・・・関数とかクラスの定義元に移動したい時
- ag.vim・・・特定のキーワードで検索かけたい時
関数とかクラスの定義元への移動はcoc.nvimでもできますが、any-jumpの方が使いやすいので、any-jumpの方を使っています。
その他、Vimと併用して使っているツールなど
Vim以外の周辺ツールですが、主に以下のようなツールを使用しています。
- iTerm2・・・ターミナル。
- tmux・・・1つのターミナルで複数ターミナルを起動させるために使用。
- tig・・・Git操作をCUI上で楽にできる。
- fish・・・メインで使ってるシェル。
- ag・・・ag.vim・any-jumpを使用するのに必要。
- ranger・・・Python製のCUIファイラー。coc-explorerと併用している。
- glow・・・CUIでマークダウンのプレビューをできるようにする。
- jq・・・Vim上でJSONを整形するときに使用。
ファイラーをcoc-explorerとrangerの2種類入れている理由は、ディレクトリの移動(プロジェクトルート外に移動したい時)はrangerを使いたいけど、開発を行うときはサイドバースタイルでコーディングしたいからです。
メインのエディターをVimに変えて良かったこと
メインのエディターをVimに変えてよかったなーと感じたことについてまとめてみました。
キーボードだけで全ての操作を完結できるので作業効率が上がった
メインのエディターをVimに変えて一番良かったなと感じたのはこの点です。
コードを書くときにマウスやトラックパッドを一切使わず、キーボード上で全ての操作を完結できるので、コードを書くスピードはかなり上がった気がします。
あくまで、体感ですがVSCodeを使っていた時の1.5〜2倍くらいは早くなった気がします。
キーボードだけで全ての操作を完結できるのって、想像以上に大きなアドバンテージだなとVimを使うようになってから、強く感じました。
公式ドキュメントやissueを読む癖がついた
Vimを使っていると、プラグインの細かい設定や機能などが公式ドキュメント以外に載っているケースは少ないので、公式ドキュメントやイシューを読む癖が身につきました。
プラグインを1つ導入するのにも公式ドキュメントやissueを読まないといけないことが多いので、Vimを使うことによって、公式ドキュメントやイシューを読む癖が身についたのは良かったと思っています。
実務だと一番役に立っているスキルかもしれないです。
CLI操作が苦じゃなくなった
CLI操作が苦じゃなくなったのも大きなメリットだと思いました。
VimはCUI上で動作するエディターなので、CLI操作は基本的には避けられません。
プログラミングを学習し始めの頃の話ですが、Vimを使うことで、CLIに早いうちから慣れることができたので、その点は良かったなと思っています。
プログラミング初学者限定ではありますが、これもかなり大きなメリットだと思いました。
カスタマイズ性が高いので、理想の開発環境を追及できる
文字の大きさや色、表示する項目などはもちろん、どんなプラグインを使うか、Vim以外のどんなCLI・CUIツールを組み合わせて使うかによって、Vimの使い勝手は大きく変わってくると思います。
「ここを変えたら使いやすくなるんじゃないか?」とか「このツールを組み合わせたらこんなことできるんじゃないか?」などを考えて試行錯誤することで、エディター使いやすさをとことん追及できるのも、Vimの魅力の1つだと思います。
メインのエディターをVimに変えてきつかったこと・困ったこと
メインのエディターをVimに変えて、逆にしんどかったことについてもまとめてみました。
学習コストが高い
これに尽きると思います。
プログラミングの学習とVimを使えるようにするための学習を同時並行でこなすのはかなりしんどかったです。
文字の入力方法すらわからなかった状態から、ある程度使えるようになるまで大体1年半位かかりました。
画像を扱うとき
エディター上でちょっと画像を確認したいなという時がフロントエンドをやっていると割とあるのですが、CUI上で画像を扱うのはなかなか難しいので、困るときがあります。
rangerで画像を扱えるようにカスタマイズして、CUIで画像見れるようにしていた時期がありましたが、tmux上でVimを立ち上げると動作が安定しないことが分かったので、泣く泣く諦めた経緯があります。
現状はエディター上で画像を確認したいときは、VSCodeを使ってます。
まとめ
フロントエンドメインでVimを使ってコードを書いていますが、今のところ特に困っていることはないです。
むしろ、Vimじゃないともう開発できないというところまではきています。
slackでメッセージを打つときに無意識に、hjklを入力してしまうことがあるくらいにはVimのキーバインドに慣れてしまったので、エンジニアを続ける間は多分Vimを使い続けるのかなーとは思ってます。
最後に、Vimはいいエディターだと思います。
読んでいただきましてありがとうございました。