Photoruction工事中!

Photoructionの開発ブログです!

VIMで開発する

 

開発者の中でも黒魔道士しか使わないツールがあります。

Linuxサーバーのcrontabを更新する必要がある時または、設定ファイルを修正する時など、必ずどんなマシンにでも入っているエディターを使わなければなりません。しかしよくあることはWimしか入ってないことがあります。

Vimはエディターの中で使いづらいことや、小さなスクリプトだけならなんとか修正可能などと言われていますが、実際やろうとすると、結構効率よく開発もできます。

まずは、基本のVimで何ができるのかを紹介してから、プラグインを入れてみるとどこまでモダーンなIDEにできるのかお見せしましょう。

免責:これはあくまで個人的に「ほぉ、これは便利だね」と思った機能とプラグインだけです。

 

基本操作と知識

モーダルエディタ

Vimはモーダルエディタです。モードを切り替えて、ファイルの編集やコードの操作を行います。

デフォルトは Normal モードです。キーを打つとコマンドが実行されます。

一番よく知られているのは i キーを押すと Insert モードに切り替えます。

このモードで打つ字が入力されます。つまり、通常のエディタと変わりません。

Insert モードから Normal モードに戻るために Esc を打ちます。

: キーを打つとコマンドを打つことができます。

基本操作は vimtutor で勉強でき、これは日本語に翻訳されています。シェルで vimtutor ja を実行してみてください。

 

検索

検索はアクティブウィンドウの中で行います。

/ を打つと検索できます。つまり、 function getHolidays() 文字列を探すために /getHoli でマッチできます。打てば打つほど完全一致できます。

そして、コードを読む際に、カーソルオーバーして、 * を打つと文字列の検索となります。 ? を打つと、さかのぼり検索になります。検索の結果は n で次のマッチに飛び、 p で前のマッチに戻ります。

検索が終わったら、 :noh で検索ハイライトを解除できます。

 

バッファ、ウィンドウ、タブ

Vimのレイアウトアイテムの名前は普段のアプリケーションとちょっと違います。

バッファは基本的にファイルです。

ウィンドウはバッファを閲覧するGUIスペース。複数ウィンドウが同じバッファを違う箇所で開くことができます。

タブは簡単に言うと、ウィンドウのセットまたワークスペースと考えられます。

バッファを閉じると、このバッファを使うウィンドウが全て閉じます。

 

Vanilla VIMプラグイン無し)で開発

このセクションで、一般のVimと.vimrcで開発用のTipsを紹介します。

プラグインがなくても、ある程度効率よくコーディングができます。個人的パソコンまたはよく使うサーバーであれば、ちょっとぐらい設定ファイルを更新して、Vimの機能を開放できます。

設定ファイルは通常 $HOME/.vimrc です。

早速ですが、下記の設定を追加します。

 

""""" あった方がいい設定 """""
" これでいろいろな言語のハイライト機能をオンにする
syntax on
" ファイルタイプに応じてオート設定
filetype on
filetype indent on
" vimの反応速度を上げる(screen redraw)
set ttyfast
" いつもステータスを表示する
set laststatus=2
" backups フォルダを作成する
silent !mkdir -p ~/.vim/backups
" swap ファイルフォルダ
set directory=~/.vim/backups//
" バックアップフォルダ
set backupdir=~/.vim/backups//
" 編集されたファイルを保存しなくても、他のファイルを開ける
set hidden

" タブをスペースに
set expandtab
" タブのサイズと自動インデント幅を4文字に
set tabstop=4
set shiftwidth=4
set softtabstop=4

""""" エディター """""
" 長い行をwrapしない
set nowrap
" 行数を表示する
set number
" オートインデントを有効に
set smartindent
set autoindent

" 打っている最中検索を行う
set incsearch
" 小文字のみで検索すれば、ケースに関わらず検索する。大文字を使えば、ケースマッチを有効に
set smartcase
" 検索マッチをハイライトする
set hlsearch

" 貼り付けモード切り替えキー(勝手にインデントをしないモード)
set pastetoggle=<F2>
" diffを縦で開く
set diffopt+=vertical

" 保存する際に末尾のスペースを消す
augroup Cleanup
	autocmd!
	autocmd BufWritePre * :%s/\\s\\+$//e
augroup END

""""" レイアウト """""
" 縦スプリットを下に開く
set splitbelow
" 横スプリットを右に開く
set splitright

""""" netrw (ファイルブラウザ)"""""
" バナーメッセージを非表示
let g:netrw_banner=0
" スプリットファイルブラウザを開くとウィンドーのサイズ設定(%)
let g:netrw_winsize=50
" プレビユーを縦スプリットで開く
let g:netrw_preview=1
" ツリー表示
let g:netrw_liststyle=3

Netrw:ファイルブラウザ

Vimはすでにファイルブラウザがついています。

全画面で開く: :Ex

スプリットして、下に開く: :Hex

スプリットして、左に開く: :Vex

タブで開く: :Tex

操作はかなり単純で、通常の移動+エンターキーでフォルダを展開またはファイルを開きます。

f:id:photoruction_tech_blog:20211220094501j:plain

p を打つとプレビューウィンドウを開きます。

Ctrl+w z でプレビューを閉じます。

R でファイルまたはフォルダの名前編集ができます。

v を打つとファイルをスピリットで開きます。

 

画面スプリット

新しいウィンドウを右に開く: Ctrl+w v

新しいウィンドウを下に開く: Ctrl+w s

カーソルを別のウィンドウに移動: Ctrl+w [移動キー]例えば、右のウィンドウに移動する: Ctrl+w l

アクティブウィンドウを拡大する(他のウィンドウを閉じる): Ctrl+w o

アクテイブウィンドウを閉じる: Ctrl+w q

もちろんスプリットの中にさらにスプリットもできます。どんどん読みづらくなりますけどね。

f:id:photoruction_tech_blog:20211220094737j:plain

 

タブ機能

新しいタブを作成する: :tabnew

次のタブに移動する: g t

前のタブに移動する: g T

他のタブを閉じる: :tabonly

タブを閉じる: :tabclose

タブの使い方は色々有るのですが、個人的にタブ毎にアプリケーションコードとのファイルに対するテストファイルを開くことが多いです。

タブ1:
- BookingController
- BookingControllerTest
タブ2:
- BookingLogic
- BookingLogicTest

オートコンプリート

はい、一応単純なオートコンプリートが付いています。

非常にスマートというわけではないが、一応開いているバッファのなかを分析して、合いそうな文字列で推奨するような機能です。

ようするに、複雑な変数名があれば、問題なくこれで入力できます。

Insert モードで Ctrl+n を打つとオートコンプリートが表示されます。選択1つしかなければ、表示せず自動入力されます。 Ctrl+n で次の選択(下)に移動して、 Ctrl+p で前の選択(上)に戻ります。

f:id:photoruction_tech_blog:20211220094828j:plain

f:id:photoruction_tech_blog:20211220094841j:plain

 

タグでナビゲーション

tags ファイルが存在したら、vimがそのタグファイルを読み込んで、それぞれの箇所に飛ぶことが可能です。カーソルを文字列にオーバーして、 Ctrl+]でタグの定義箇所に飛べます。 Ctrl+t で元のファイルに戻れます。たまに同じタグに複数定義箇所が存在します。その時、 g] を打って、どのファイルを開くのを選択できます。 :tags <タグ名> でも使えます。

f:id:photoruction_tech_blog:20211220095106j:plain

タグファイルを生成するために ctags と言うツールをインストールする必要があります。コードが変わるとまた生成する必要があるので、ちょっと使いにくいです。ただし、プラグインを使うと自動化できます。そして、あまり変わらないコードだったら、一応手動でもタグファイルを生成する価値があります。

そして、タグナビゲーション機能をVimのヘルプで使えます。 :help でアクセスでき、リンクを Ctrl+] または g] で開けます。

 

ターミナル

Vim 8 以降だと、ターミナルが付いています!

:terminal で起動できます。ターミナルはデフォルトで Insert モードです。

Normal モードに切り替えIMはエディターの中で使いづらいやるために Ctrl+w N を打つ必要があります。

また Insert モードに戻るには、通常通り i を打てば良いです。

Normal モードでは通常の動き、コピーなど、すべての機能を使えるので、便利です。

ターミナルを専用タブで開いても便利です。

もちろん、 vim 自体を Ctrl+z でバックグランドに落としてもいいです。

そしてシェルから fg を実行するだけで復活できます。

 

セッション

例えばVSCodeを開く時、最後閉じた状態のままでまた開きます。

vimでも似たような機能が存在します。

:mksession! を実行すると同じフォルダに Session.vimファイルが作成されます。

このファイルをロードするとファイル作成時の状態に戻ります。 :source Session.vim で実行できます。

またはシェルでエディタを実行する際に、 -S パラメタを追加すると自動的に Session.vim をロードします。

このコマンドの弱点は手動で実行する必要があることです。 .vimrc でキーマッピングを追加したら、自動コマンドを追加するのが便利です。

個人的に、専用プラグインに任します。

 

プラグインを入れましょう!

プラグインを使うと、機能は爆発的に広がります。

プラグイン管理

vim 8 が既にプラグイン管理ができるのですが、個人的には VimPlug を気に入り使用しています。

プラットフォームによってやり方がちょっと異なりますが、基本的に、プラグインのコードを autoload フォルダに入れればOKです。

そして、 .vimrc の中で

call plug#begin()
call plug#end()

のブロックを作って、欲しいプラグインをここに入れれば簡単に管理できます。

流れは:

  1. Plug 'xxxx/xxxx' の行を .vimrcbegin...end の中入れて
  2. vim を起動して(またはリロードする)
  3. :PlugInstall を実行する

たまに :PlugUpdate を実行するだけで更新できます。

 

基本設定とUI

デフォルト設定の見直し

まずはVimのデフォルト設定を軽く変えた方がいいです。

これは tpope/vim-sensible に任せます。

ステータスバーのレベルアップ!

VimのデフォルトUIは静かで邪魔にならないのですが、たまにちょっとスパルタ過ぎます。

ステータスバーを vim-airline/vim-airline で拡張します。

そして、より格好よくするために vim-airline/vim-airline-themes も入れます。

vim-airlineでいろいろな情報が目の前に現れます。モード名、ブランチ名+ファイル変更まとめ(インサート、変更、削除の行数)、ファイルタイプとエンコード、ファイルタイプ等。

スクショや機能の詳細と設定はGithubで確認するのはおすすめです。

カラースキーム

あくまで好みの問題ですが、自分は sainnhe/sonokai のダークカラースキームが好きです。

VimPlugでの管理も簡単です!

そして、微調整のため(カラースキームのオプションなど)のため、設定ファイルに下記を追加します。

" ダークモードは正義!
set background=dark

" フルカラーターミナルだとOKです
set termguicolors
" カラースキームオプション
let g:sonokai_style = 'shusia'
let g:sonokai_enable_italic = 1 
let g:sonokai_transparent_background = 0 
let g:sonokai_diagnostic_text_highlight = 0 
let g:sonokai_diagnostic_line_highlight = 0 

" カラースキーム選択
colorscheme sonokai
" 更にオプション(他のプラグインと連携)
let g:airline_theme = 'sonokai'
let g:airline#extensions#coc#enabled = 1 

 

共通コードツール

このカテゴリは通常のIDE機能をVimで再現できるプラグインについてです。

Ctrl+P

それぞれのIDECtrl+pでファイルを開いたりができます。もちろん、Vimでもできます!

そのために ctrlpvim/ctrlp.vim を入れましょう。

そして、興味のないファイルを省く設定を追加します

" CtrlP
set wildignore+=*/tmp/*,*.so,*.swp,*.zip     " MacOSX/Linux
set wildignore+=*\\\\tmp\\\\*,*.swp,*.zip,*.exe  " Windows

let g:ctrlp_custom_ignore = {
  \\ 'dir':  '\\v[\\/](\\.(git|hg|svn)|node_modules|vendor)$',
  \\ 'file': '\\v\\.(exe|so|dll)$',
  \\ 'link': 'some_bad_symbolic_links',
  \\ }

 

ワードハイライト

カーソルがオーバーしているワードをハイライトするプラグインも個人的に好きです。

それは RRethy/vim-illuminate で解決します。デフォルトはアンダーラインでマッチを表示するのですが、ブロックハイライトが好みです。

" ハイライト
hi link illuminatedWord Visual

 

セッション管理自動化

さすがに毎回 :mksession!を実行するのは手間がかかります。もちろんそのためのプラグインがあります!早速入れましょう: tpope/vim-obsession

Tim Popeのプラグインが必要なパラメタのみを保存しています。

そして、セッションのトラッキングを開始したい時: :Obsess を実行するだけです。 -S フラグを使ってセッションをロードしたら、 :Obsess を実行する必要はありません。

注意:バッファを開く・閉じる際に Session.vim ファイルが更新されます。したがって、ステートを保存するために全てのバッファを一括で閉じる必要があります。すなわち、 :q ではなく :qa で終了しましょう。

タグファイル生成

ctagsを自動的に実行してくれるプラグインの登場です!

では ludovicchabant/vim-gutentags も入れましょう。プロジェクトが大きかったら、タグ生成は時間がかかる場合あります。

ローカルvimrc

プロジェクト毎設定を変えて欲しい時がある場合、 embear/vim-localvimrc で設定の微調整ができます。

このプラグインを入れると 各プロジェクトに .lvimrc ファイルを作って、設定を入れて、この環境だけで適用します。

デフォルトは毎回「 .lvimrc の設定をロードしていい?」と聞かれてしまうので、下記の設定で、ファイルが変わらない限り、承認を覚えてくれます。

" lvimrc
let g:localvimrc_persistent = 1

 

特にデバッガの設定や、ソースコードフォルダマッピングのためにこのプラグインは非常に便利です。

ソース管理対応(Git)

もちろんターミナルでいちいち実行して、何が変わったのを確認できますが、流石に大変ですね。

エディタで一目で分かるようにしたほうが良いに間違いありません。

Vim-GitGutter

airblade/vim-gitgutter は左側の行目のさらに左にファイル変更の印を入れてくれます。

f:id:photoruction_tech_blog:20211220095336p:plain



上記のサイドバーでは - は削除、 ~ は編集、 + は追加と明確に変更の内容と箇所を示します。変更の内容は \ h p で確認できます。

もちろん印、色など、全てカスタムできます。他の機能もたくさん有ります。

詳細はvim-gitgutterのGithubで確認するおすすめします。

" vim-gitgutter
if exists('&signcolumn')  " Vim 7.4.2201
  set signcolumn=yes
else
  let g:gitgutter_sign_column_always = 1 
endif
set updatetime=200
let g:gitgutter_override_sign_column_highlight = 1

 

Vim-Fugitive:いろいろなツール

tpope/vim-fugitive からインストールできます。

このプラグインはいろいろなGit機能をWrapしています。全部説明する余裕はないですが、例えばgit blameをvim内で確認できたり、ファイルの古いバージョンと比較したりできます。

詳細はGithubページで確認ください。

ViMagit

Magit( jreybert/vimagit )パネルを開くとワークスペースの様子を確認や、変更をステージングスペースに追加するもしくは捨てるやコミットもできます。

VSCodeのGitタブみたいな感じです。ファイル単位だけではなく、ハンク(変更ブロック)単位と行単位も対応します。

https://user-images.githubusercontent.com/533068/28827790-ee0ec640-76ce-11e7-840b-10a4f5e4eae4.gif

下記の追加設定で \ g sマッピングします。

" vimagitパネルを開く
nnoremap <leader>gs :Magit<CR>       " git status

 

スマートコードコンプレッション

VimVSCodeみたいにスマートにできますか?もちろんですとも!

このゴールを達成するためにLS(Language Server:言語サーバー)を使います。

LSとは何でしょうか?まぁ、簡単に説明すると、裏で動いている特定言語サーバープロセスとやり取りして、コードの様子を確認し、オートコンプリート選択肢を計算などします。

このLSとやり取りをするために、LSP(LSのプロトコル)を扱うプラグインが必要です。

インストール

このプラグインの名は neoclide/coc.nvim です。

プラグインをインストールするだけでは足りません。使いやすくするために、設定も更新しないといけません。

おすすめの設定はこちら:https://github.com/neoclide/coc.nvim#example-vim-configuration

全部必要と言うわけではないですが、デフォルトとして安定で使いやすいです。

運用になれてから設定変更するのがおすすめです。

言語サーバー登録

CoCプラグインを入れるだけで、なにもできません。言語サーバーが必要です!

そのためにそれぞれのCoC拡張をインストールする必要があります。

基本的に、https://github.com/neoclide/coc.nvim/wiki/Language-servers に参考しながら、インストールすべきです。

その他、おすすめのやり方は vimrc で登録するのではなく :CocInstall で管理することです。

例えば、Javascript/TypeScriptサーバーをインストールするには

:CocInstall coc-tsserver でできます。

念の為、一旦vimを閉じて、開いたら、シンタックスチェックやオートコンプリートが使えるはずです。

f:id:photoruction_tech_blog:20211220095429p:plain

f:id:photoruction_tech_blog:20211220095444p:plain

 

まとめ

ここまで読んでいただけたら、「よく頑張ったね!」と感謝致します。

Vimは間違いなくちょっと変わったツールで、だいぶ古いイメージがあるのですが、モダーンな開発ツールとしても使えます。

もちろんVSCodeや他のIDEVimっぽい動きはできますが、中途半端なできで使い物になりません。これで満足できませんでした。

Vimでないエディタを毎日使って涙を流している皆様のために、この(かなり雑な)ガイドを作りました。自分に合う開発環境を作る踏み台になれば幸いです。

 

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com

www.wantedly.com