Neovimはじめました & 2016年vimrc大掃除
  • Date:2016-12-27 火 (午前 04:36:50)
  • Updated:2016-12-27 火 (午前 04:44:54)
  • Tags:neovim vim
  • Category:Programming

11月あたりからvim環境を見直して概ねまとまってきたのでメモとして残しておきます。

概要は

  • Neovim導入
  • プラグイン整理(neobundle => dein.vim)
  • Neovim/Vim/Nyaovim対応

になります。

設定ファイルはGitHubの.dotfilesにあるのでこちらを見ればこの記事は読まなくてもいいかもしれません。

embed.ly


Neovimはじめました

Home - Neovim

Neovimのterminal modeに感動してNeovimをはじめてみることにしました。

あとVimよりサクサク動いていて、思考の速度に近づいてる気がします。

Neovimのインストールはパッケージマネージャーから

OSXとUbuntuでの開発が多いのでパッケージマネージャーを使ってインストールすることにします。

しかもNeovimの場合パッケージマネージャーを使用して新しいNeovimをインストールすることが可能なので手元でビルドしなくていいのもメリットだと感じています。

あとPython拡張を使うのでインストールと一緒に有効にしておきます。

OSXの場合(homebrew-neovim/README.md at master · neovim/homebrew-neovim)

brew tap neovim/neovim
brew install --HEAD neovim
brew install python
brew install python3
pip2 install --user --upgrade neovim
pip3 install --user --upgrade neovim

Ubuntuの場合(Installing Neovim · neovim/neovim Wiki)

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:neovim-ppa/unstable
sudo apt-get update
sudo apt-get install neovim
sudo apt-get install python-dev python-pip python3-dev python3-pip
sudo pip2 install --user --upgrade neovim
sudo pip3 install --user --upgrade neovim

手元でビルドする場合、CentOS6以前などではビルドに必要なツールをビルドする必要があったりするので、自分の場合は環境によってはNeovimは諦めてVimも併用で使うようにしています。

設定ファイルの場所

デフォルトでは"~/.config/nvim/init.vim"がVimで言う"~/.vimrc"になります。

環境変数"$XDG_CONFIG_HOME"を変更することで、デフォルトの"~/.config"部分を変更できます。

今後Neovimメインで使っていくような気がしているので、.vimrcへのシンボリックリンクを作成することでVimも同じ設定で使えるようにしています。

Nyaovimもはじめました

MiniBrowserプラグインを使って、Web開発のプレビューを横に出しながらプログラミングできて楽しいです。

Markdownプレビューも最高です。

設定ファイル(~/.config/nyaovim/nyaovimrc.html)

<dom-module id="nyaovim-app">
  <template>
    <style>
      /* CSS configurations here */
      .horizontal {
         display: flex;
         width: 100%;
         height: 100%;
       }
       neovim-editor {
         width: 100%;
         height: 100%;
       }
    </style>

    <!-- Component tags here -->
    <div class="horizontal">
      <neovim-editor
        id="nyaovim-editor"
        argv="[[argv]]"
        font-size="16"
        font="Meslo LG M DZ for Powerline">
      </neovim-editor>
      <markdown-preview editor="[[editor]]"></markdown-preview>
      <mini-browser url="https://google.com" editor="[[editor]]"></mini-browser>
    </div>
    <popup-tooltip editor="[[editor]]"></popup-tooltip>
  </template>
</dom-module>

Nyaovimプラグインもdein.vimで読み込むのですが、"if exists('g:nyaovim_version')"を使うことでNyaovim固有の設定を記述します。

プラグイン整理

今までの構成を大幅に変更してみました。dein.vimによる影響が大きいですが以下の点が今までと大きく変わりました。

  • cacheの利用
  • プラグイン遅延ロード
  • tomlファイルでプラグイン管理
  • NeovimとVimとNyaovimで設定を分ける
  • NeovimとVimとNyaovimで使用するプラグインも使い分かる

Neovimをメインに据えていくのでルートディレクトリは"~/.config/nvim"で、ディレクトリ構成は以下のようになっています。

~/.config/nvim
├── dein.toml
├── deinlazy.toml
├── init.vim
├── keymap.rc.vim
├── options.rc.vim
└── plugins
    ├── airline.rc.vim
    ├── anzu.rc.vim
    ├── deoplete.rc.vim
    ├── iceberg.rc.vim
    ├── neocomplete.rc.vim
    ├── neomake.rc.vim
    ├── neoterm.rc.vim
    ├── nerdcomenter.rc.vim
    ├── syntastic.rc.vim
    ├── vimfiler.rc.vim
    ├── vimshell.rc.vim
    └── yankround.rc.vim

dein.vim

Shougo氏がdein.vimという新しいプラグインマネージャを作っていたのでそちらに移行しました。

基本的にShougo氏のvimrcを参考にして作ってみました。

このあたりを参考にして以下のようなinit.vimになりました。

if &compatible
  set nocompatible
endif

augroup MyAutoCmd
  autocmd!
augroup END

if exists('g:nyaovim_version')
  let s:dein_cache_path = expand('~/.cache/nyaovim/dein')
elseif has('nvim')
  let s:dein_cache_path = expand('~/.cache/nvim/dein')
else
  let s:dein_cache_path = expand('~/.cache/vim/dein')
endif

let s:dein_dir = s:dein_cache_path
                 \ .'/repos/github.com/Shougo/dein.vim'

if &runtimepath !~ '/dein.vim'
  if !isdirectory(s:dein_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_dir
  endif
  execute 'set runtimepath+=' . fnamemodify(s:dein_dir, ':p')
endif

if dein#load_state(s:dein_cache_path)
  call dein#begin(s:dein_cache_path)

  call dein#load_toml('~/.config/nvim/dein.toml', {'lazy' : 0})
  call dein#load_toml('~/.config/nvim/deinlazy.toml', {'lazy' : 1})

  if exists('g:nyaovim_version')
    call dein#add('rhysd/nyaovim-popup-tooltip')
    call dein#add('rhysd/nyaovim-markdown-preview')
    call dein#add('rhysd/nyaovim-mini-browser')
  endif

  call dein#end()
  call dein#save_state()
endif

if dein#check_install()
  call dein#install()
endif

filetype plugin indent on
syntax enable

runtime! options.rc.vim
runtime! keymap.rc.vim

ポイントは、Neovim/Vim/Nyaovimでcacheのパスを使い分けて各々のプラグインを使用できるようにしています。

Vim本体の設定とKeymapは別ファイルとして最後に読み込んでいます。

Neovimも開発中なので、プラグインに関しても日々更新されていくものが多いので、動作がおかしいときや数日に一度は":call dein#update()"してプラグインを更新すると良いです。

管理するプラグインについてはdein.toml(遅延ロードするプラグインはdeinlazy.toml)に書きます。

[[plugins]]
repo = 'xxx/yyy'

基本的には上の書き方で、設定がある場合はhook_*を使って設定を読み込みます。

  • hook_addはプラグイン追加後
  • hook_sourceはプラグイン読み込み前
  • hook_post_sourceはプラグイン読み込み後

(ドキュメント => dein.vim/dein.txt at master · Shougo/dein.vim)

hookのスクリプトに"source .vim"と書いて外部のVim scriptを読み込むようにするとtomlファイルがすっきりするので、設定が長くなるプラグインなどはそうしています。

ifというキーを使ってNeovimやVimの切り替えができます。

以下はneocompleteとdeoplete.nvim、neotermとvimshellの例です。

[[plugins]]
repo = 'Shougo/neocomplete.vim'
depends = 'context_filetype.vim'
if = "has('lua')"
on_i = 1
hook_source = '''
source ~/.config/nvim/plugins/neocomplete.rc.vim
'''

[[plugins]]
repo = 'Shougo/deoplete.nvim'
depends = 'context_filetype.vim'
if = "has('nvim')"
on_i = 1
hook_source = '''
source ~/.config/nvim/plugins/deoplete.rc.vim
'''

[[plugins]]
repo = 'kassio/neoterm'
if = "has('nvim')"
hook_add = '''
source ~/.config/nvim/plugins/neoterm.rc.vim
'''

[[plugins]]
repo = 'Shougo/vimshell'
if = "!has('nvim')"
hook_add = '''
source ~/.config/nvim/plugins/vimshell.rc.vim
'''

これを書くまでに参考にして勉強したりした情報集です、ありがとうございました。

Vimの文法はこちら


残りは気になった個別のプラグインについて書いていきます。

iceberg

Iceberg - dark color scheme for Vim

目に優しそうでカッコいいカラースキームです。

visual modeを結構多用するのですが、モニターのブルーライトカットが効きすぎているのか色が分かりづらかったのでオレンジ色に変えてあります。

au MyAutoCmd VimEnter * nested colorscheme iceberg
" Visual mode
au MyAutoCmd VimEnter * highlight Visual ctermbg=216
" backgroung transparency
"au MyAutoCmd VimEnter * highlight Normal ctermbg=none
"au MyAutoCmd VimEnter * highlight NonText ctermbg=none
"au MyAutoCmd VimEnter * highlight TablineSel ctermbg=none
"au MyAutoCmd VimEnter * highlight LineNr ctermbg=none
"au MyAutoCmd VimEnter * highlight CursorLineNr ctermbg=none

カラースキームを使う場合、一行目の記述は必須のようです。

neoterm

neovimのterminal modeが便利すぎてやばいです。

とりあえずいつもどおりにノーマルモードを使用するために以下の設定をします。

if has('nvim')
  tnoremap <silent> <ESC> <C-\><C-n>
endif

もっと便利に使うためにneotermを導入します。

kassio/neoterm: Wrapper of some neovim's :terminal functions.

neotermはneovimのterminalラッパープラグインです。手軽に分割ターミナルとかが使えます。

さらに、ファイルや行、選択範囲をreplに突っ込んでterminalで実行したりテスト連携があったりと便利機能満載です。

以下のように設定しました。

  • Quickrunの代用ぽい設定
  • toggleする設定
  • vimshellの代用ぽい設定
[[plugins]]
repo = 'kassio/neoterm'
if = "has('nvim')"
hook_add = '''
nnoremap <silent> ,rc :TREPLSendFile<cr>
nnoremap <silent> ,rl :TREPLSendLine<cr>
vnoremap <silent> ,rl :TREPLSendSelection<cr>
nnoremap <silent> vt :Ttoggle<cr>
nnoremap <silent> vs :terminal<cr>
'''

shellを指定している方を多く見ましたが、自分の環境では$SHELLが開いている感じがしたので設定していません。

embed.ly

とは言いましたが、Vimではterminal modeは使えないのでVimShellを使うように設定しています。

[[plugins]]
repo = 'kassio/neoterm'
if = "has('nvim')"
hook_add = '''
source ~/.config/nvim/plugins/neoterm.rc.vim
'''

[[plugins]]
repo = 'Shougo/vimshell'
if = "!has('nvim')"
hook_add = '''
source ~/.config/nvim/plugins/vimshell.rc.vim
'''

[[plugins]]
repo = 'Shougo/vimproc.vim'
if = "!has('nvim')"
build = 'make'

neomake

非同期でmakeやlintを実行するsyntasticの非同期版のようなプラグインです。

READMEは最低限の内容のみとなっているので、helpを読みながら設定していきます。

まず、見た目の設定です。

" color
autocmd! BufWritePost * Neomake
au MyAutoCmd ColorScheme * hi NeomakeErrorSign cterm=bold ctermfg=7 ctermbg=9
au MyAutoCmd ColorScheme * hi NeomakeWarningSign cterm=bold ctermfg=8 ctermbg=216
au MyAutoCmd ColorScheme * hi NeomakeMessageSign cterm=bold ctermfg=8 ctermbg=150
au MyAutoCmd ColorScheme * hi NeomakeInfoSign cterm=bold ctermfg=8 ctermbg=110
" text
let g:neomake_error_sign = {'text': 'E✖', 'texthl': 'NeomakeErrorSign'}
let g:neomake_warning_sign = {
    \   'text': 'W➤',
    \   'texthl': 'NeomakeWarningSign',
    \ }
let g:neomake_message_sign = {
     \   'text': 'M➤',
     \   'texthl': 'NeomakeMessageSign',
     \ }
let g:neomake_info_sign = {'text': 'ℹ➤', 'texthl': 'NeomakeInfoSign'}

基本的にここにあるmakerは使えます。有効にする際は以下のように書きます。

let g:neomake_<lang>_enabled_makers = ['<maker>', '<maker>']

maker名は末尾の名前です、例えばneomake/cpp.vim at master · neomake/neomakeにある"function! neomake#makers#ft#cpp#gcc()"の場合は"gcc"になります。

複数指定すると複数個makerが動くことになるので動作が被ってる場合、同じメッセージが複数出ます。

makerは自作することもできるようです。

g:neomake_{ filetype }_{ makername }_maker

ディレクトリmakerという機能もあるようなので気になります。

Vim7.4.503からneomakeは使用可能ですが、syntasticに慣れていたのもありVimを使う時はsyntasticを使うようにしています。

[[plugins]]
repo = 'neomake/neomake'
if = "has('nvim')"
hook_add = '''
source ~/.config/nvim/plugins/neomake.rc.vim
'''

[[plugins]]
repo = 'vim-syntastic/syntastic'
if = "!has('nvim')"
hook_add = '''
source ~/.config/nvim/plugins/syntastic.rc.vim
'''

ちなみにSyntasticもneomakeと同じような見た目になるように設定しています。

" ColorScheme
au MyAutoCmd VimEnter * highlight SignColumn ctermbg=237
au MyAutoCmd VimEnter * highlight SyntasticErrorSign cterm=bold ctermfg=255 ctermbg=203
au MyAutoCmd VimEnter * highlight SyntasticWarningSign cterm=bold ctermfg=233 ctermbg=150
let g:syntastic_error_symbol = 'E➤'
let g:syntastic_warning_symbol = 'W➤'
" Basic setting
let g:syntastic_always_populate_loc_list = 1
"let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0
" for javascript
let g:syntastic_javascript_checkers = ['eslint']
" for c/cpp
let g:syntastic_cpp_compiler_options = '-Wall'

deoplete.nvim

neocompleteに次ぐ補完プラグインです。

deinlazyに追加します。

[[plugins]]
repo = 'Shougo/deoplete.nvim'
depends = 'context_filetype.vim'
if = "has('nvim')"
on_i = 1
hook_source = '''
source ~/.config/nvim/plugins/deoplete.rc.vim
'''

deoplete.rc.vim

let g:deoplete#enable_at_startup = 1
" <TAB>: completion.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ deoplete#manual_complete()
function! s:check_back_space() abort "{{{
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~ '\s'
endfunction"}}}

" <S-TAB>: completion back.
inoremap <expr><S-TAB>  pumvisible() ? "\<C-p>" : "\<C-h>"

" <BS>: close popup and delete backword char.
inoremap <expr><BS> deoplete#smart_close_popup()."\<C-h>"

" Use auto delimiter
call deoplete#custom#set('_', 'converters', [
      \ 'converter_remove_paren',
      \ 'converter_remove_overlap',
      \ 'converter_truncate_abbr',
      \ 'converter_truncate_menu',
      \ 'converter_auto_delimiter',
\ ])

let g:deoplete#enable_camel_case = 1

deoplete.nvim/deoplete.txt at master · Shougo/deoplete.nvim

ドキュメントを見ると言語ごとにEXTERNAL SOURCESがあるので、開発する言語を中心にプラグインを適宜追加していけば良さそうです。

vim-airline

airlineは対応しているプラグインも多く設定も少なくて済むので、とても好きなpowerlineです。

dein.vimは依存関係を書けるので設定ファイルがわかりやすくなって良いです。

[[plugins]]
repo = 'majutsushi/tagbar'

[[plugins]]
repo = 'tpope/vim-fugitive'

[[plugins]]
repo = 'vim-airline/vim-airline'
depends = ['tagbar', 'vim-fugitive']
hook_add = '''
source ~/.config/nvim/plugins/airline.rc.vim
'''

[[plugins]]
repo = 'vim-airline/vim-airline-themes'
depends = 'vim-airline'
hook_add = '''
let g:airline_theme='luna'
'''

airline.rc.vim

if exists('g:nyaovim_version')
  let g:airline_powerline_fonts = 0
  let g:airline_left_sep = ''
  let g:airline_right_sep = ''
else
  let g:airline_powerline_fonts = 1
endif
let g:airline#extensions#tabline#enabled = 1
if !has('nvim')
  let g:airline#extensions#whitespace#mixed_indent_algo = 2 " see :help airline-whitespace@en
endif

NyaovimでPowerlineFontが崩れてしまったのでNyaovimでは無効にしています。

mixed_indentがうざかったりしますがドキュメントを読むとアルゴリズムを変更できるので賢めのアルゴリズムに変更しています。

Vimfiler

Shougo/vimfiler.vim: Powerful file explorer implemented by Vim script

便利すぎて手放せないプラグインです。

[[plugins]]
repo = 'Shougo/unite.vim'
hook_add = '''
nnoremap <silent> fb :<C-u>Unite buffer<CR>
'''

[[plugins]]
repo = 'Shougo/vimfiler.vim'
depends = 'unite.vim'
hook_add = '''
source ~/.config/nvim/plugins/vimfiler.rc.vim
'''

vimfiler.rc.vim

call vimfiler#custom#profile('default', 'context', {
     \ 'safe' : 0,
     \ 'auto_expand' : 1,
     \ 'parent' : 0,
     \ })
"default explore -> vimfiler
let g:vimfiler_as_default_explorer = 1
"buffer directory
nnoremap <silent> fe :<C-u>VimFilerBufferDir -quit<CR>
" Nerdtree like
nnoremap <C-e> :<C-u>VimFilerBufferDir -split -winwidth=120 -toggle -no-quit<CR>
"key mapping
autocmd MyAutoCmd FileType vimfiler call s:vimfiler_my_settings()
function! s:vimfiler_my_settings()
  nnoremap <silent><buffer><expr> s vimfiler#do_switch_action('vsplit')
  nnoremap <silent><buffer><expr> v vimfiler#do_switch_action('split')
  nnoremap <silent><buffer><expr> t vimfiler#do_action('tabopen')
endfunction
" Textmate icons
let g:vimfiler_tree_leaf_icon = ' '
let g:vimfiler_tree_opened_icon = '▾'
let g:vimfiler_tree_closed_icon = '▸'
let g:vimfiler_file_icon = '-'
let g:vimfiler_marked_file_icon = '*'

関数内検索

1000行くらいの長い関数がひしめき合ってるコードと向かい合うとき関数内検索があるとかなり便利なので下記の情報を元にできるようにしました。かなり便利です。

[[plugins]]
repo = 'kana/vim-operator-user'

[[plugins]]
repo = 'kana/vim-textobj-user'

[[plugins]]
repo = 'kana/vim-textobj-function'

[[plugins]]
repo = 'osyo-manga/vim-operator-search'
depends = ['vim-operator-user', 'vim-textobj-function', 'vim-textobj-user']
hook_add = '''
nmap <Space>/ <Plug>(operator-search)if
'''

/で検索できます。

Show comments

Adsense

Share

  • このエントリーをはてなブックマークに追加

About

どこにでもいる平凡なプログラムを書く人間のログ。

Recently

Tags

Pages

-->