Help us understand the problem. What is going on with this article?

[更新中] ぼくのVimさばきを支える設定とその導入手順を紹介する

<まえがき> Vimはこわくない。 :sunflower:

つい最近までVimといえば強いエンジニアが使うこわいエディターだという勝手なイメージが私の中にありました。
しかし、いざvimrcを自分でカスタマイズし始めると楽しくなってしまい、いつの間にかメインエディターがVimになりました。Vimmerの数だけVimがあり、使い方に正解のないというVimの魅力に気づいてしまったのです。
この記事ではこれまでに私が行ったVimを使いやすくするための設定とその手順を紹介します。
あくまでカスタマイズの一例として誰かの役に立てると嬉しいです。Vimはこわくありません!:sunny:
d1d05424d7ca11326ac2686ce07e69c2.gif

目次 :book:

この記事では筆者がVimを(そこそこ)使いこなせるようになった設定とその導入手順をご紹介します。
手順に沿って設定を進めれば誰でもVimを(そこそこ)使えるようになるはずです:fire:

章番号 タイトル
1章 .vimrc をdotfilesで管理しよう :gear:
2章 Vimの基本設定をしよう:pick:
3章 VimとEmacsのキーバインドと仲良くなろう :open_hands:
4章 dein.vimでプラグインを管理しよう :zap:
5章 おすすめのプラグインを紹介します :doughnut:
6章 画面分割をビシバシっ!とキメよう :waning_gibbous_moon:
7章 tmux導入してターミナル環境を整えよう :family_wwbb:
8章 tigを使ってターミナルからgitを高速で操作しよう :pencil:
9章 fzfで高速な単語検索とファイル検索を実現しよう :mag:
10章 強力なLanguage Serverの恩恵を受けよう :muscle:

ダラダラと書いていたら長くなったので気になるところだけ読んでくださいmm

1. .vimrc をdotfilesで管理しよう :gear:

基本的にVimの設定は~/.vimrcに記述します。(.vimrcがない場合は作成します)
Vimの使い心地に大きく影響する.vimrcをコンピュータごとにカスタマイズするのは大変です。
そこでdotfilesの出番です。dotfilesを利用して.vimrcを効率的に管理しましょう。

この章の続きを読む

dotfilesは.zshrc.vimrcといった設定ファイルを一つにまとめたディレクトリの総称です。
dotfilesをGit管理下におき、Gitホスティングサービス(GitHubなど)で管理することで、複数のコンピュータで同じ設定ファイルを簡単に用意することができます。

さっそくdotfilesを作成し、Git管理を始めましょう。

dotfilesを作成する
$ mkdir dotfiles
$ cd dotfiles
$ git init

次にdotfilesへバージョン管理したい設定ファイルを追加していきます。
例えば、ホームディレクトリ直下の何らかの設定ファイル.hogercをdotfilesで管理する流れは以下のようになります。
① ホームディレクトリ直下の.hogerc~/dotfiles/へ移動させる。
② ホームディレクトリ直下に~/dotfiles/.hogercへのシンボリックリンクを作成する。

具体的なコマンド
$ mv ~/.hogerc ~/dotfiles/
$ ln -s ~/dotfiles/.hogerc ~/.hogerc

シンボリックリンクの作成とは簡単に言えば「このファイルを参照したい時はこっちを見てね!」という目印ファイルを作成しておくことです。これによってこれまで通り設定ファイル~/.hogercへの参照が解決されます(ハッピー)。

それでは上記の基本的な流れに沿って.vimrcをdotfilesで管理しましょう。

.vimrcをdotfilesで管理する
$ mv ~/.vimrc ~/dotfiles/
$ ln -s ~/dotfiles/.vimrc ~/.vimrc

これでdotfilesで.vimrc管理を始めることができました:star2:
ついでにホームディクレクトリ直下の.vim .zshrc .zprofileといった設定ファイルも ~/dotfiles/ へ移動させ、シンボリックリンクを作成しておきましょう。

ここからは余談ですが、dotfilesにはinstall.shなどの名前で、シンボリックリンク作成やパッケージインストールのコマンドをまとめたシェルスクリプトを用意しておくことが多いようです。dotfilesをgit cloneしてinstall.shを実行するだけで環境設定が終わればとってもスマートです:sparkles:

GitHubで公開されている様々なdotfilesを参考に、オリジナルのdotfilesを育てていくと良さそうです。

2. Vimの基本設定をしよう :pick:

この章では、筆者の.vimrcを紹介します。
すでに.vimrcを自分でカスタマイズしている方はスキップしていただいて大丈夫です。

以下の.vimrcから必要な設定があればコピーしましょう。

この章の続きを読む

そのままコピーすると筆者と同じVim設定(2019/11/25現在)となります(:skull::beginner::warning:)。
.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 backspace=indent,eol,start

" 検索するときに大文字小文字を区別しない
set ignorecase

" 検索した時にハイライト
set hlsearch

" キーバインド------------------------------------------------------------------

" xで削除した時はヤンクしない
vnoremap x "_x
nnoremap x "_x

" 1 で行頭に移動
nnoremap 1 ^

" 2で行末に移動
nnoremap 2 $

" 9 で前のバッファタブへ
nnoremap <silent> 9 :bprev<CR>

" 0 で次のバッファタブへ
nnoremap <silent> 0 :bnext<CR>

" Option + | でファイル内の文字置換
nnoremap \ :%s/old/new/g<LEFT><LEFT><LEFT><LEFT><LEFT><LEFT><LEFT><LEFT>

" 現在のバッファ削除
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>
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>

" 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が少しだけリッチになりましたね:sparkles:
(なお、筆者の.vimrcをそのままコピーした方はこれ以降の章の.vimrcへの追記の項目はスキップして大丈夫です)


ちなみに筆者の最新の.vimrcこちらです。

3. VimとEmacsのキーバインドと仲良くなろう :open_hands:

Vimの独特なキーバインドは慣れるまでは苦行のように感じるかもしれません。さらにVimに登場するモードという概念が他のエディターから移ってきた人を混乱させます。しかし、一度慣れてしまえばその強力なキーバインドに病みつきになってしまうでしょう。

Vimのキーバインドを使いこなすためには練習あるのみです。
筆者の場合は1週間Vim以外のエディターを使わないという縛りを課すことでVimに対する気持ち悪さを消すことができました。
(Vimのキーバインドを紹介する記事は広いインターネットの世界にたくさん転がっているため、ここでは細かいキーバインドの説明は割愛します:scissors:)

この章の続きを読む

はじめてVimの操作を学ぶにはチュートリアルが最適です。

terminal
$ vimtutor

コマンドを実行すると以下の画面が立ち上がり、Vimの操作方法を順序よく学ぶことができます。
スクリーンショット 2019-11-24 21.20.57.png
ちなみに$ vimtutor enとコマンドを実行すると言語を切り替えることができます(できました)。


さて、この章のタイトルは「VimとEmacsのキーバインドと仲良くなろう」でした。
なぜEmacs???と疑問に思われた方もいるのではないでしょうか。

実はMacOSはデフォルトでEmacsライクなキーバインドが使えます。
試しにGoogle documentのファイルの中でEmacsキーバインドを使ってカーソルを移動させると上手く動作することが確認できます。
dfdc51754d1c8051da2e22dd07c8cbf0.gif

覚えると便利な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で威力を発揮します:japanese_ogre:

.vimrc
" 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キーバインドを利用したカーソル移動が可能になります。
35b85e2c58f590e865294d97fca25728.gif
地味ですが、Normalモードに戻らずカーソルを操作できるのは便利です。

ちょっとした編集の際にぜひ使ってみてください:relieved:

4. dein.vimでプラグインを管理しよう :zap:

幸せなことにインターネットの世界では私たちの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を自分の指定ディレクトリに合わせて変更してください。

terminal
$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.vim/bundles

次に、.vimrcに以下の設定を追加しましょう。

.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.tomldein-lazy.tomlという2つのtomlファイルを読み込む設定をしています。
したがって、.deinディレクトリをdotfiles直下に作り、ホームディレクトリ直下にシンボリックリンクを作成しておくと良さそうです。

terminal
$ 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で遅延読み込みさせることでこの問題を解決することができます:sparkles:

またプラグインごとの設定をhookで管理できるため.vimrcを散らかすことがなくなります。

hookについてはこちらの記事が参考になります。
[dein.vim] hook の便利な使い方

tomlファイルは基本的に以下のように記述します。

tomlファイルの基本的な書き方
[[plugins]]
repo = 'インストールしたいプラグインのリポジトリ'
hook_add = 'Vim起動時に読み込む設定'

tomlファイルにプラグインを追記しておけば先ほど.vimrcに記述した以下のスクリプトによってVimを起動するだけで新たなプラグインをインストールしてくれます:sparkles:

自動インストールのスクリプト
" インストールしていないプラグインがあればインストールを実行
if dein#check_install()
  call dein#install()
endif

これでプラグインを効率的に管理できる環境が整いました:sunny:


5. おすすめのプラグインを紹介します :doughnut:

この章では開発効率をUPさせるVimのおすすめプラグインを幾つかピックアップして紹介します。
プラグインを使用する上で必要なパッケージやツールのインストール方法と筆者のtomlファイルでの設定をまとめています。

この章の続きを読む

① preservim/nerdtree

GitHubのリポジトリ: https://github.com/preservim/nerdtree

NERDTreeを利用するとVim上で視認性の高いディレクトリツリーを表示することができます:sparkles:
dc3bffe119dcac3a6c7d0b2d0404afd2.gif

使用方法
1. dein.tomlに設定を追記する。

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を使うとグラフィカルで見た目がカッコいいステータスバーを手軽に利用することができます:sparkles:
スクリーンショット 2019-11-25 1.52.47.png

使用方法
1. Power Line fontsをインストールする。

teminal
$ git clone https://github.com/powerline/fonts.git --depth=1
$ ./install.sh
$ cd ..
$ rm -rf fonts

2. dein.tomlに設定を追記する。

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に以下の設定を追記する。

.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で削除できます。
4f82fcf14064b1cf933bf5423e837b0f.gif

Vimにはデフォルトのタブ機能がありますが、筆者はvim-airlineのバッファタブを利用しているため使用していません。
混乱を避けるためにデフォルトのタブ機能を使うかvim-airlineのバッファタブを使うか、どちらかを選んで利用するのが良いでしょう。


③ nathanaelkane/vim-indent-guides

GitHubのリポジトリ: https://github.com/nathanaelkane/vim-indent-guides

vim-indent-guidesを使うとインデントがカラフルに色付けされます:sparkles:
スクリーンショット 2019-11-25 2.43.42.png

使用方法
1. dein.tomlに設定を追記する。

dein.tomlの設定
[[plugins]]
repo = 'nathanaelkane/vim-indent-guides'
hook_add = '''
    let g:indent_guides_enable_on_vim_startup = 1
    let g:indent_guides_exclude_filetypes = ['help', 'nerdtree']
    let g:indent_guides_auto_colors = 0
    autocmd VimEnter,Colorscheme * :hi IndentGuidesOdd ctermbg=237
    autocmd VimEnter,Colorscheme * :hi IndentGuidesEven ctermbg=240
'''

Vimのインデント可視化系のプラグインといえばvim-indent-guidesかindentLineがよく使われています。筆者はvim-indent-guideを落ち着いたカラーで利用するのが好きです。


④ airblade/vim-gitgutter

GitHubのリポジトリ: https://github.com/airblade/vim-gitgutter

vim-gitgutterはGitの差分を行番号横のsignで分かりやすく示してくれます:sparkles:
スクリーンショット 2019-11-25 3.02.25.png

使用方法
1. dein.tomlに設定を追記する。

dein.tomlの設定
[[plugins]]
repo = 'nathanaelkane/vim-indent-guides'
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のおかげでどこを編集したのかすぐに確認することができます。


⑤ dense-analysis/ale

GitHubのリポジトリ: https://github.com/dense-analysis/ale

dense-analysis/aleを利用するとVim上でLinterを走らせることができます:sparkles:

使用方法
1. 利用したい言語のLinterをインストールし、設定ファイルなどの用意を済ませておく。

2. dein.tomlに設定を追記する。設定は参考例です。

dein.tomlの設定(参考例)
[[plugins]]
repo = 'dense-analysis/ale'
hook_add = '''
  let g:ale_set_highlights = 0
  let g:ale_lint_on_enter=1
  let g:ale_lint_on_save=1
  let g:ale_lint_on_text_changed=0
  let g:ale_sign_column_always=1
  let g:ale_linters = {
    \ 'css': ['stylelint', 'prettier'],
    \ 'dockerfile': ['hadolint'],
    \ 'erb': ['erb'],
    \ 'html': ['HTMLHint'],
    \ 'haml': ['haml-lint'],
    \ 'javascript': ['eslint'],
    \ 'json': ['jq'],
    \ 'ruby': ['rubocop', 'solargraph'],
    \ 'typescript': ['eslint'],
    \ 'vim': ['vint'],
    \ 'yaml': ['yamllint'],
    \ }
  let g:ale_sign_error='E'
  let g:ale_sign_warning='W'
  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_statusline_format=['E %d', 'W %d', '']
  let g:ale_open_list=1
  let g:ale_set_loclist=0
  let g:ale_keep_list_window_open=0
  let g:ale_javascript_prettier_use_local_config=1
'''

VimでもLinterを積極的に利用して綺麗なコードを書きましょう:star2:


⑥ tomtom/tcomment_vim

GitHubのリポジトリ: https://github.com/tomtom/tcomment_vim

tomtom/tcomment_vimを使うとVimでコメントアウト操作を手軽に行えるようになります:sparkles:
4d533d3cc77984b5ab779bb4ab4b6546.gif

使用方法
1. dein.tomlに設定を追記する。

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上でカラフルな括弧を表示してくれます:sparkles:
スクリーンショット 2019-11-25 3.40.17.png

使用方法
1. dein.tomlに設定を追記する。

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を利用すると閉じタグを自動で補完してくれます:sparkles:

使用方法
1. dein-lazy.tomlに設定を追記する。

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します:sun_with_face:

⑨ ryanoasis/vim-devicons

GitHubのリポジトリ: https://github.com/ryanoasis/vim-devicons

Screen Shot 2020-02-11 at 14.36.02.png
vimの中でアイコンを表示してくれるプラグインです。

使用方法
1. dein.tomlに設定を追記する。

dein.tomlの設定
[[plugins]]
repo = 'ryanoasis/vim-devicons'
  1. ターミナルとフォントの設定をする ↓ ターミナルとフォントの設定についてはスクラップボックスに書いたのでこちらをご覧ください。 vimにアイコンを表示するプラグインを入れた

アイコンが表示されるだけで一気にリッチなエディターに様変わりしましたね:sushi:


6. 画面分割をビシバシっ!とキメよう :waning_gibbous_moon:

65406c1504f07faa515eafe4643b14c4.gif
キーボードでの画面分割、画面移動の操作に慣れるとVimでの開発効率は格段にUPします。
この章では画面分割をビシバシっ!と決めれられるよう、便利なプラグインとキーバインドの設定を行います。

この章の続きを読む

デフォルトのVimではコマンドモードで:sp:vsといったコマンドを実行することで画面分割ができます。
しかし毎回コマンドを実行するのはすこし面倒なので、画面分割を簡単にするキーバインドを設定しましょう。

.vimrc
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を押します。
2d3dd7ba6c52b261b65547eef9de39ec.gif

そして画面の移動はsを押したあとにVimお馴染みの方向キーh j k lで行います。
05ee291f4b8ae81cb1b83100bc94a6c0.gif

オリジナルのキーバインドを設定することで画面分割がとても簡単になりました:star:

▽ 画面分割については以下の記事が参考になります。
Vimの便利な画面分割&タブページと、それを更に便利にする方法


画面の分割と移動が簡単にできるようになったので、次は画面サイズの変更も簡単に行いたくなってきました。
そこで画面サイズの変更を簡単に行えるプラグインを導入します。

simeji/winresizer

GitHubのリポジトリ: https://github.com/simeji/winresizer

simeji/winresizerは画面サイズの変更を簡単にするプラグインです:sparkles:

使用方法
1. dein.tomlに設定を追記する。

dein.tomlの設定
[[plugins]]
repo = 'simeji/winresizer'

simeji/winresizerの使い方は以下のようになります。
① サイズを変更したい画面にカーソルを持ってきて<C-e>(Ctr + e)を押す。
② 画面がwindow resize modeに切り替わるのでh j k lで画面サイズを自由に変更する。
③ エンターキーで画面サイズを確定させる。

d8b78e9f5fa8019dbd7a169cc0515009.gif

とても簡単ですね:sunny:

この章では画面の分割と移動、サイズの変更を簡単に行うための設定を紹介しました。
これからは息をはくように画面を分割してVimを使いこなしましょう:fire:

7. tmux導入してターミナル環境を整えよう :family_wwbb:

aa69b7488c40841e212ef17769220b2c.gif

(※ tmuxは次章で紹介するtigと合わせて使うと便利です)

強いエディター代表のVSCodeにはcommand+jで簡単にターミナルを起動できる機能があります。

やはりVSCodeは最強のエディターなのでしょうか?(心の声<はい、そうです。))
いえ、必ずしもそうとは言えません。もちろんVimでも同じようなことができます:beers:

この章の続きを読む

Vimを使い始めたころ、VSCodeが恋しくて仕方ありませんでした。
特にターミナル機能をVimで実現するにはどうすれば良いのかと悩んでいました。

しかし、気づいたのです。
Vimをカスタマイズするのではなく、実行環境であるターミナルを使いやすくすれば良いのだ!と。

tmuxで複数のターミナルを操作しよう

tmuxを使えば1つのウィンドウ(tmuxセッション)の中で複数のターミナル(独立した疑似端末/ペイン)を起動することができます。
簡単に言えば「今まで別々のタブやウィンドウで起動していたターミナルを一つにまとめられるぞっ!」ということです。

92576171f7554033c701dfeb4af057fe.gif

使用方法
1. tmuxをインストールする。

terminal
$ brew install tmux
$ brew install reattach-to-user-namespace (← こちらはtmuxのコピーモードをクリップボードと連携させるために必要です)

2. 設定ファイル.tmux.confをdotfiles直下に用意し、ホームディクトリにシンボリックリンクを作成する。

terminal
$ cd ~/dotfiles
$ touch .tmux.conf
$ ln -s ~/dotfiles/.tmux.conf ~/.tmux.conf
  1. .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

  1. tmux起動のエイリアスを.zshrcに設定しておく。(任意です)
.zshrcなど
alias t='tmux'

シェルログインとともにtmuxを起動した人はこちら
.zshrcなど
# SHELL LOGIN WITH TMUX / If not running interactively, do not do anything
[[ $- != *i* ]] && return
[[ -z "$TMUX" ]] && exec tmux

tmuxの使い方は簡単です。
まずはターミナルでtmux(エイリアスを使う場合はt)とコマンドを入力しましょう。
すると以下のように新規のtmuxセッションが作成されます。
4565267c1efb5efbed642b7bb4896c6f.gif

筆者の.tmux.conf設定ではPrefixキーとして<C-s>(Ctr + s)を使用しています。

tmuxでは一つの画面のことをペインと呼びますが、新たなペインを立ち上げる場合は以下のように操作します。
- 画面を垂直分割してペインを立ち上げる場合: <C-s>を押したあとにv
- 画面を水平分割してペインを立ち上げる場合: <C-s>を押したあとにs

そして、ペインの移動は<C-s>を押したあとにh j k lキーで行うことができます。

この操作は1つの前の章で紹介したVim内の画面分割と似ていますね!:eyes:
tmuxの画面分割はPrefixが<C-s>、Vim内での画面分割はPrefixがsで、コントロールキーを押すかどうかの違いだけです:star:

そして分割したペインはexitすることで閉じることができます。
6d1e581f36345a737398ee081002998c.gif

次に、ペインのサイズを変更してみましょう。
ペインのサイズは同じくPrefixキーである<C-s>を押したあとにH J K Lキーで行うことができます。
ペインの移動にshiftキーを加えただけです。
Vim内での画面サイズ変更とは少し違いますが、使っていくうちにすぐに慣れるので大丈夫です:star:

24c19144e206270195722fc7d49539af.gif

ここまででtmuxでのペイン操作がスムーズにできるようになりました:family_mwgb:

これからはtmuxセッションの中でVimを使った開発を行い、ターミナル操作をしたくなれば新たなペインを立ち上げ簡単にコマンドを実行できます。もうVSCodeのターミナル機能が恋しくなることはありません:fire:

※ちなみに別ペインで操作した変更をVimで読み込む場合は:e!コマンド(再読み込み)で対応できます。

tmuxについての余談

:page_with_curl:
Vim8からは:termでVimターミナルモードが使えるようになりました。
筆者も素早くシェルを叩きたいときはたまにVimのターミナルモードを利用しています。
しかし、Prefixがめんどくさかったりでやはりtmuxを利用する方が好きです:family_mmgb:
好きな方を使うと良いと思います:yum:

8. tigを使ってターミナルからGitを高速で操作しよう :pencil:

9be1e7c280ea5f7d6839c3a9c3b5af97.gif

Vimを使い始めてすぐに恋しくなったVSCodeの機能がありました。
それはGitの差分をグラフィカルなUIで確認でき、直感的操作でステージングやコミットできる機能です。

同じような操作性をVimに求めるのは難しいのでしょうか?
実はtigを使ってターミナル環境を整えれば全て解決します。しかも、VSCodeよりも高速にGitの操作が可能です。

この章の続きを読む

tmuxの章でも書いたようにVimをカスタマイズするのではなく、実行環境であるターミナルを使いやすくすることが重要です。

tigを導入してGitを操ろう

tigはターミナル上でGitの差分をカラフルに表示したり、操作することができるツールです。
3dfb047ebd97a6d8b08e1f02a304cee5.gif

使用方法
1. tigをインストールする。

terminal
$ brew install tig

2. 設定ファイル.tigrcをdotfiles直下に用意し、ホームディクトリにシンボリックリンクを作成する。

terminal
$ cd ~/dotfiles
$ touch .tigrc
$ ln -s ~/dotfiles/.tigrc ~/.tigrc
  1. .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した時と同じような表示で違和感ないと思います。
スクリーンショット 2019-11-26 1.46.09.png

uでステージとアンステージを行う

ファイルをまるごとステージング、アンステージする場合はカーソルをファイルに合わせてuを押します。
b6fec6021baa020a58f04d6129300fb5.gif

ファイル内のhunk(変更単位)ごとにステージング、アンステージする場合はファイルをエンターキーで選択し、hunk単位でuを押します。
e2ec9a172032e70c2ad9bd5bb526f6c1.gif
1行ずつステージ、アンステージする場合は1を押します。

Cでコミットする
Status viewでC(大文字)を押すとお馴染みのgit commit画面になりステージした内容をコミットできます。
982c9aff7af572197367de2324c2be25.gif

Pでリモートリポジトリへpushする
最後に大文字のPで現在のブランチのコミットをリモートリポジトリへpushします。

tigの終了はqです。

tigはとても便利なツールですね:star:
具体的な使い方として前の章で紹介したtmuxと合わせ技をよく使います。
Vimで作業中、理解できるでしょう。理解できるでしょう。 tmuxで分割ペインを立ち上げる → tigでコミット という流れです。
9f2d55c684a9e6d3945b4ab7548f6c3b.gif

ちなみにStatus Viewで変更を取り消すときはuではなく!を使います。
Untracked filesの変更を取り消す場合はDを使います。

(Untracked filesの変更を取り消しコマンドDはtig本体の機能ではなく.tigrcのオリジナル設定です。なぜデフォルトでUntracked filesの変更を取り消し機能がないのかはこちらのIssueが参考になります。)

便利なtigとtmuxを使いこなしてVimとターミナルの環境を最強にしましょう:fire:

9. fzfで高速な単語検索とファイル検索を実現しよう :mag:

fzfを使えばカレントディレクトリから高速でファイルや単語をあいまい検索することができます。
さらにfzf.vimにはファイルの編集履歴から簡単にファイルを開くことができる機能もあります。
5b1d9305751f677f7bba6411508a8f63.gif

fzfの高速で強力な検索機能を使ってVimをもっと使いやすくしましょう:sunny:

この章の続きを読む

まずはfzfをVimで使えるように設定しましょう。

使用方法
1. fzf本体のインストール

terminal
$ brew install fzf

2. ripgrepをインストール
ripgrepはgrepやAgより高速な検索ツールです。

terminal
$ brew install ripgrep

3. .zshrcに設定を追加

.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に以下の設定を追加してください。

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で使えるようになりました:star:
次に具体的な使い方をご紹介します。

カレントディレクトリ配下からファイル検索

例えばディレクトリをvim .で開き、作業していたとします。
ファイルを検索したい時は<C-p>(コントロール押しながらp)を押します。
すると以下のようにQuickfixでファイルのあいまい検索ができます。
スクリーンショット 2019-11-27 12.03.42.png
カーソルの移動にはTAB shift + TABか前の章で紹介したEmacsのキーバインドを使います。
ちなみになぜpをバインドしているかというと以前にctrlp.vimというプラグインを使っていた名残です。

しかし、実は<C-p>には:GFilesをバインドしているためGit管理下のファイルしか検索できません。
ほとんどの場合は:GFilesで問題ないのですが、未だGitでtrackingしていないファイルを検索したい場合はコマンドモードで:Filesを実行してください。
スクリーンショット 2019-11-27 12.10.25.png
するとGit管理していないファイルも検索することができます。コマンドを打つのが面倒な方はキーバインドを設定しても良いかもしれません。

バッファの編集履歴からファイルを開く

さっきまで開いていたファイルをもう一度開きたいということは良くあります。
そんな時は<C-h>を使うとバッファの編集履歴(≒ファイルの編集履歴)からファイルを開くことができます。
366aa648eb84e4536d8ab5e6c2d24f5c.gif
h:Historyhで覚えやすいと思います。

(ちなみに簡単なファイルバックの場合はVimデフォルトの<C-o>でも可能です。)

カレントディレクトリ配下から単語を検索

例えばディレクトリをvim .で開き、作業していたとします。
カレントディレクトリ以下のfzfという単語を検索したくなった時は<C-g>を押して、引数に検索したい単語を渡します。
e8eec2bd6184871fc28d588c12282fdd.gif
すると上のGIFのようにカレントディレクトリ以下の単語を検索することができます。
ちなみに、?を押すとカーソルで選択中のファイルの中身を見ることができます。


以上がfzfの簡単な使い方です。

ここで紹介した検索以外にもfzf.vimには様々な検索方法があります。詳しくはコマンド一覧をご覧ください。

私の友人はfzfがあればNERDTREEやタブなんて要らないと言っていましたが本当にそうだと思います。
これからはfzfでバシバシと検索を使いましょう:fire:

10. 強力なLanguage Serverの恩恵を受けよう :muscle:

VimにLanguage Server(言語サーバー)との通信(LSP)をサポートするプラグインを追加すれば、非常に強力で便利な言語サーバーの恩恵を受けることができます。
137734a038aa4cb5b3e830c0b8772483.gif

言語サーバーの恩恵によって実現できる機能には以下のようなものが挙げられます。
① コードジャンプ(定義元ジャンプ)
② リアルタイムの入力補完
③ エラー警告やインフォメーションの表示

この章ではLanguage Server Protocol(LSP)をサポートしているVimのプラグイン「coc.nvim」の導入手順と基本的な使い方を紹介します。

この章の続きを読む

はじめに言語サーバーとその通信プロトコルであるLSP(Language Server Protocol)について簡単に説明します。
languageserver.png
言語サーバーはエディターとは別のプロセスで独立して立ち上がります。
エディターから言語サーバーに対してリクエストが送られると、言語サーバーはそれに応じたレスポンスを返します。このリクエストとレスポンスの通信方式の決まりがLSP(Language Server Protocol)です。
決まった通信プロトコルを利用する言語サーバーを用意しておけば、クライアント(エディター側)は言語サーバーとのやりとりだけで仕様の異なる言語ごとの機能を実装できるようになります。つまり、エディターは言語ごとの実装を言語サーバーに任せられてハッピー!というわけです:sunny:

言語サーバーとLSPについてはマイクロソフトの以下のページが参考になります。
言語サーバー プロトコル

次にLSPをサポートしているプラグイン「coc.nvim」をインストールしましょう。

coc.nvim

GitHubリポジトリ: https://github.com/neoclide/coc.nvim

使用方法
1. Node.jsをインストール(既にNode.jsをインストール済みの場合はスキップ)

terminal
$ curl -sL install-node.now.sh/lts | zsh

2. dein.tomlに設定を追加

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とコマンドを実行します。インストール完了後、マークダウンファイルで:を打つとたくさんの絵文字が補完で表示されるようになりました。
スクリーンショット 2019-11-29 20.36.15.png

他にもcoc.nvimには様々な拡張機能が提供されているので、拡張機能一覧から欲しいものを見つけてインストールしましょう:ramen:


続いてcoc.nvimで言語サーバーの恩恵を受けてみましょう。
coc.nvimはLSPクライアントであるため、言語サーバーは別で用意する必要があります。
言語サーバーはcoc.nvimの拡張機能として提供されているものと各自でインストールする必要があるものに分けられます。拡張機能が存在する場合は拡張機能を利用するのが良いでしょう。

例えばTypeScriptの言語サーバーは拡張機能(coc-tsserver)として用意されているため、:CocInstall coc-tsserverを実行するだけで言語サーバーを用意することができます。

言語サーバーが拡張機能として提供されていない場合は、言語サーバーをインストールした後に~/.vim/coc-settings.jsonに以下のように設定を追記します。

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の記述例はこちらから確認できます。

言語サーバーの用意ができればいよいよコードジャンプ(定義元ジャンプ) 入力補完 警告やインフォメーションの表示といった便利な機能が利用できるようになります:star2:

例えばTypeScriptの場合。
① コードジャンプ
4572f7b9e208cdc75ce357f01fbb3e96.gif
関数や変数、型の定義元へオリジナルのキーバインドgdで簡単にジャンプすることができます。
ちなみにジャンプ元のファイルへ戻るには<C-o>が便利です。

② 入力補完
5c3dd9e830a830fe618f8d3f6e0c1fbb.gif
<tab>またはEmacsキーバインドで候補を選択します。

③ 警告やインフォメーションの表示
17416dbeb333a0f4bdccb4d56a16fedd.gif
こちらの例ではReactコンポーネントの引数の型が違うよ!とエラーを警告してくれました。

このように言語サーバーのパワーは非常に強力です:muscle:
coc.nvimで言語サーバーの恩恵を受けてVimを最強の開発環境にしましょう!

ちなみにcoc.nvimにはfzfライクなあいまい検索を実現する拡張機能などもあります。好きなようにカスタマイズすると楽しそうです:sparkles:

<あとがき> Vimは楽しい! :star2:

この記事では私がVimをそこそこ使えるようになるまでに行った設定とその手順を紹介してみました。
ここで紹介したこと以外にもターミナル、tmux、Vimのカラースキームを統一する、高速なターミナルエミュレーターを導入するなどVimをもっと使いやすくする方法を考えると楽しいはずです。(わたしの使っているカラースキームはatom-one-dark-terminalonedark.vimです。おすすめのターミナルエミュレーターはalacrittyです。)
Vimを使い始めてもうすぐ1ヶ月が経ちますが、今でも私のdotfilesはスクスクと成長中です。
きっとまた1ヶ月後にこの記事を読むとリライトしたくなる箇所がたくさんあるんだろうなと思っています:sweat:
しかし、Vimが楽しいことはこれからも変わらない気がしています。

今後もVimライフを楽しみましょう:fire:


最後に筆者の最新設定(dotfiles)を貼っておきます。

2020.1.8 追記)
思ったより多くの方にこの記事を読んで頂けているようです。ありがとうございます:crocodile:
記事中の設定に改善点を発見した場合はできるだけ更新していますが、もしエラーが出ることがあれば変更リクエストまたはコメントでお知らせ頂けますと幸いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした