Vim optionの設定/参照方法いろいろ

 　　
この記事は [Vim Advent Calendar 2017](https://qiita.com/advent-calendar/2017/vim)、22日目の記事です。

Vimには様々なoptionがありますが、
本記事ではoptionの設定/参照方法についてご紹介していきます。

## **optionの種類毎の設定方法**

optionにはいくつかの種類があります。

1. **切替(boolean)**
2. **数値**
3. **文字列**

対象のオプションが何に該当するかは`:h 'option_name'`で確認できます。
以下ではそれぞれの設定方法について記載していきます。
## 切替(boolean)

number, wrap, equalalwaysなどが該当します。
切替オプションの場合には`:set option_name`という形でオンに変更できます。

``` vim
:set number " 行番号を表示
```

切替オプションをオフにするにはprefixとして**no**を指定します。

``` vim
:set nonumber " 行番号を表示しない
```

prefixに**inv**, またはsuffixにbang(**!**)を指定すると対象オプションの
オン/オフを切り替えるができます

``` vim
" 行番号の表示/非表示を切り替え
:set invnumber
:set number!
```

## 数値

cmdheight, tabstop, synmaxcolなどが該当します。
数値オプションの場合には`:set option_name=value` or `:set option_name:value`で数値を指定できます。

``` vim
" コマンドラインの行数を2行に設定
:set cmdheight=2
:set cmdheight:2
```

+=, -=, ^=を使用すると数値オプションの値を計算式のように修正できます。

``` vim
:set cmdheight=2  " コマンドラインの行数を2行に設定
:set cmdheight+=4 " コマンドラインの行数を2 + 4 = 6行に設定
:set cmdheight-=3 " コマンドラインの行数を6 - 3 = 3行に設定
:set cmdheight^=3 " コマンドラインの行数を3 * 3 = 9行に設定
```



## 文字列
文字列オプションの場合にも数値オプションと同様に`:set option_name=value` or `:set option_name:value`という形で文字列を指定できます。

``` vim
" grepprgにjvgrepを指定
:set grepprg=jvgrep
:set grepprg:jvgrep
```


ここから少しややこしいのですが、文字列オプションはさらに
以下3つに分類されています。

1. ただの文字列
2. カンマ区切りのリスト
3. フラグのリスト


上記3つの種類毎、`+=`, `-=`, `^=`の使われ方が少しずつ異なってきます。
(この分類も`:h ‘option_name’`で確認できます。~~というかヘルプ見る以外に確認方法はありません~~)

###### 文字列(***ただの文字列***)
***

grepprg, foldmethod, ambiwidthなどが該当します。
`+=`で後ろに文字追加, `^=`で前に文字追加, `-=`で文字の削除が行えます。


``` vim
" 以下で'grepprg'がgrep -> jvgrep -> j -> javaの順に変化
:set grepprg=grep
:set grepprg^=jv
:set grepprg-=vgrep
:set grepprg+=ava
```


###### 文字列(***カンマ区切りのリスト***)
***

tags, path, backspace, viminfoなどが該当します。
`+=`で後ろにカンマと文字追加, `^=`で先頭に文字とカンマ追加, `-=`でカンマと文字を削除します。
(※リストが単一か否かでカンマの追加, 削除は自動的に調整されます)

``` vim
" 以下で'tags'が tags,./../tags -> tags -> ./tags,tags -> ./tags,tags,TAGSの順に変化
:set tags=tags,./../tags
:set tags-=./../tags
:set tags^=./tags
:set tags+=TAGS
```

###### 文字列(***フラグのリスト***)
***

shortmess, guioptions, formatoptions,などが該当します。
`+=`でフラグの追加, `-=`でフラグを削除します。

``` vim
" 以下で'shortmess'が filn -> filnoO -> flnoO の順に変化
" NOTE: -= を使用してフラグを取り除く場合には1つずつ指定することが推奨されています
:set shortmess=filn
:set shortmess+=oO
:set shortmess-=i
```

## **オプションを規定値に戻す**

規定値に戻したいoption名に`&`を指定するだけで、
対象のoptionが規定値に戻ります

``` vim
" grepprgを規定値に戻す
:set grepprg&
" ほぼ全てのオプションを規定値に戻す(※若干例外がるので、詳細は:h :setで確認してください)
:set all&
```

また`:set option_name&vi`でViの規定値に、
`:set option_name&vim`でVimの規定値に戻すこともできます。


## **式を使用したoptionの設定方法**

式を使用してoptionに値を設定することもできます。
これもoption名に&を付けて実現できます。

式で使用する場合にはoption名の頭に`&`を指定します。

``` vim
" $VIM(Windowsだとvim.exeがあるディレクトリ)のviminfoを使用するよう修正
" viminfoの場所を動かして利便性があるかは無視してく(ry

" 最初に既定値に戻す
set viminfo&

" nフラグを指定, その後にviminfoのファイルパスを指定する
let &viminfo .= ',n' . expand('$VIM') . '\_viminfo'

" viminfoに設定されている値をecho
echo &viminfo
```


## **optionの参照方法 1**

option名に`?`を付ければoptionに設定されている値を見ることができます。

``` vim
" grepprgに設定されている値を確認
:set grepprg?
```

また`exist()`関数を使用して`exist('&option_name')`とすればそのオプションを設定可能かチェックすることもできます。

``` vim
" 透明度のトグル
" 参考:https://qiita.com/tekkoc/items/de25bbf595de8c5f73ec 
function! s:toggle_transparency() abort
  " transparencyオプションが設定可能かチェック
  if exists('&transparency')
    if &transparency == 255
      set transparency=100
    else
      set transparency=255
    endif
  endif
endfunction
nnoremap <F12> :<C-u>call <SID>toggle_transparency()<CR>
```

## **optionの参照方法 2**

`:set`と`:set all`で設定値の一覧を見ることができます

``` vim
" 既定値と異なるoptionについて全て表示
:set
" optionをほぼ全て表示(一部表示されないのもあります)
:set all
```

既定値通りのoptionの一覧を確認するには`:set`と`:set all`のdiffをとれば可能だと思います。
[こちらを参考に](http://webtech-walker.com/archive/2010/04/27173007.html)コマンド結果をキャプチャするとset1に`:set`の結果, set2に`:set all`の結果が格納されますので、
少し整形して好きなdiffツール(~~私の場合はVim~~)で比較してみてください。

``` vim
:redir => set1
:set
:redir END

:redir => set2
:set all
:redir END

" キャプチャした内容(set1 or set2)をテキストで編集したい場合には
" Insertモードで<C-r>=set1<CR>を実行してください。カーソル位置に張り付けられます。
```

## **OptionSet**

Vimにはoption設定時に使用されるOptionSetというイベントが存在します。
OptionSetをつかえばPlugin等でどのoptionが書き換えられているか確認することもできます。

``` vim
" 値が変更されたoption名, 変更前の値、変更後の値、変更されたオプションのスコープ(global or local)をecho
augroup option_set
  autocmd!
  autocmd OptionSet * echo expand('<amatch>') . ',' 'old value:' . v:option_old 'new value:' . v:option_new 'type:' v:option_type
augroup END

```


## **おまけ: 'showmatch'について**

helpで開いてみてください(`:h 'showmatch'@en` or `:h 'showmatch'@ja`)。
しょーもないイースターエッグを見ることができます(笑)


## **まとめ**

こんな感じで色々な方法でoptionの設定/参照がができます。
ただ、設定方法、参照方法は分かってもVimにどんなoptionが存在するか知らないと
意味がありませんよね。

便利なoption(よく使われているoption)を知るには他人のvimrcを見るのが一番だと思いますので、
おすすめは[vimrc読書会](http://vim-jp.org/reading-vimrc/)に参加することですかねー。
(私は過去ログ参照(or ROM専)しかしておらず未参加ですが、、、、)

そして気になったoptionを見つけたらhelpで詳細を確認するのが良いのかと思います。
`showmatch`の様に新しい発見があるかもしれないですしね。

あとは、optionの`ローカル`、`グローバル`という話や
それに関連して`setlocal`、`setglobal`というものについても紹介したかったのですが、
余り理解できていないので省きました。
[こちら](http://whileimautomaton.net/2008/01/14011600)のリンクか`:h local-options`で確認してください。

色んなoptionを使って素晴らしいVim Lifeを送りましょー。

**Happy Vim Life !!**



``` vim
" 参考
:h options
:h let-&
:h exist()
:h 'showmatch'

" その他
" NOTE: Vim イースターエッグのまとめ(http://postd.cc/vim-galore-5/)
```