気を散らすノート

色々と散った気をまとめておくところ.論文読んだり自分で遊んだりする.たぶん.

ことしの vimrc 振り返り

自分 advent calendar 2019, 9日目の記事です.遅刻したので日付変わってちょっと追記しています.

タイトル通り,時々メモの形でこういうのを残しておくのも悪くないかもしれない.本当は先週から週末にかけて予定が詰まっており一旦こういうぱっと書けるのでお茶を濁すしかなくなったものです.でも明日のネタはもう決まったのでよし.現在の形は https://github.com/lesguillemets/myvim にそろっと置いてあります.

プラグイン管理には(設計思想が完全に正しいと思っている)miv を使っているので, vimrc.yaml に設定を書くことが多い.2019年に入ってからの変更をだらだら書き下しながら振り返っていきます.…実は昨年11月に多くの設定を捨て たのですが,その後1ヶ月くらいでガガッと整地が進んでおり,それが終わった後の1年くらいでの動きということになります.(ちなみに結果的には上記11月の決断は大正解で,起動もちょっと早くなって設定がだいぶスッキリしました.長らく statusline 系のプラグインは避けていた中, lightline を使い始めたのもこの頃.)

設定・マッピング

if has('patch-8.1.1270')
  set shortmess-=S
endif
  osyo-manga/vim-anzu:
+   enable: |
+     ! has('patch-8.1.1270')

shortmessS が入り,有史以来愛用していた osyo-manga/vim-anzu が必ずしも必要なくなりました.個人的にはカウント上限が少ないとか不満がいくつかあるのですが,使って本体に報告する方向で話を進めたい.

if has('terminal')
  " Try mapping gt.
  " I think I'll find it annoying only when using vim inside :terminal.
  tnoremap gt <C-w>:<C-u>tabnext<CR>
  tnoremap gT <C-w>:<C-u>tabprevious<CR>
endif

terminalが入ってそこそこ便利に使う中,開いた terminal からの脱出で引っかかることが起きて設定したマッピング.意外と( terminal 内で vim を使うようなときでなければ)誤爆しないし,そういえば複雑なことするときは :terminal じゃなくて <C-z> でふつうのターミナルに戻っているのでした.

filetypes:
  gitcommit: |
    setlocal spell

Git の commit message (rhysd/committia.vim を愛用しています) にスペルチェックを入れたもの.べんり.

プラグイン

新規

今年の一大イベントは,時々試しては消していた lsp 系のプラグインに移行し,prabirshrestha/vim-lsp + prabirshrestha/asyncomplete.vim として neocomplete/deoplete をやめたことです.一つのきっかけは ghc-mod が 開発ツールとしては deprecate された こと.以前から GHC のアップデートに手軽に入れられるバージョンが追従できておらず,GHC のバージョンをちょっと古いので使ってたのですがとうとう他に手立てがなくなりました.ただ eagletmt/ghcmod-vim のほうがやはり出来がよいという時期がしばらく続いたこと,haskell-ide-engine が割とメモリを食い,さらにちょうど僕の移行の時期にバグで数GB以上食い続ける時期があったことなどのために,結局自分が Haskell を書く機会を減らした一つの大きな原因になったのは振り返るとすこし感慨深いものがあります.出先で使ってるラップトップのメモリが 4GB しかなくて(まあ増設しろという話なんですが),xfce で動いてるのでまるまる 3GB くらいは使えるのですが,それにしても最近 Haskell の開発をやるのがしんどくなってきた.とくに stack も含めてディスク・メモリについて富豪的なのはちょっとつらいなあと思います.一方 rust は language server の出来がわるくなくて,またコンパイル時に CPU は要求してもメモリの負担が小さいので件のラップトップで開発しやすく,このプラグイン移行と同時期から haskell の代わりに使うことが増えてきました.

  prabirshrestha/asyncomplete.vim:
    after: |
      inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
      inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
      inoremap <expr> <CR> pumvisible() ? asyncomplete#close_popup() . "\<CR>" : "\<CR>"
      let g:asyncomplete_remove_duplicates = 1
      let g:asyncomplete_smart_completion = 1
      let g:asyncomplete_auto_popup = 1
      set completeopt-=preview
  prabirshrestha/asyncomplete-buffer.vim:
    dependedby:
      prabirshrestha/asyncomplete.vim
    after: |
      au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#buffer#get_source_options({
      \ 'name': 'buffer',
      \ 'whitelist': ['*'],
      \ 'blacklist': ['go'],
      \ 'completor': function('asyncomplete#sources#buffer#completor'),
      \ }))
  prabirshrestha/asyncomplete-file.vim:
    dependedby:
      prabirshrestha/asyncomplete.vim
    after: |
      au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#file#get_source_options({
      \ 'name': 'file',
      \ 'whitelist': ['*'],
      \ 'priority': 10,
      \ 'completor': function('asyncomplete#sources#file#completor')
      \ }))
  prabirshrestha/asyncomplete-omni.vim:
    dependedby:
      prabirshrestha/asyncomplete.vim
    after: |
     au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#omni#get_source_options({
      \ 'name': 'omni',
      \ 'whitelist': ['*'],
      \ 'blacklist': [],
      \ 'completor': function('asyncomplete#sources#omni#completor')
      \  }))
  prabirshrestha/asyncomplete-lsp.vim:
    dependedby:
      prabirshrestha/asyncomplete.vim

  prabirshrestha/async.vim:
    dependedby:
      - prabirshrestha/vim-lsp

  prabirshrestha/vim-lsp:
    dependon:
      - prabirshrestha/async.vim
    filetype:
      - haskell
      - rust
      - python
    before: |
      let g:lsp_diagnostics_enabled = 0
      let g:lsp_async_completion = 1
    after: |
      if executable('hie')
        autocmd FileType haskell setlocal omnifunc=lsp#complete
        autocmd FileType haskell nnoremap <buffer> <C-]> :LspDefinition<CR>
        autocmd FileType haskell nnoremap <buffer> gh :LspHover<CR>
        autocmd FileType haskell nnoremap <buffer> K :LspHover<CR>
        au User lsp_setup call lsp#register_server({
        \ 'name' : 'hie',
        \ 'cmd' : { server_info->[ 'hie', '--lsp'] },
        \ 'whitelist' : ['haskell', 'lhaskell']
        \ })
      endif
      if executable('rls')
          autocmd FileType rust setlocal omnifunc=lsp#complete
          autocmd FileType rust nnoremap <buffer> <C-]> :LspDefinition<CR>
          autocmd FileType rust nnoremap <buffer> gh :LspHover<CR>
          autocmd FileType rust nnoremap <buffer> K :LspHover<CR>
          au User lsp_setup call lsp#register_server({
              \ 'name': 'rls',
              \ 'cmd': {server_info->[ 'rustup', 'run', 'nightly', 'rls']},
              \ 'whitelist': ['rust'],
              \ 'workspace_config' : { 'rust': { 'unstable_features' : 'true' }}
              \ })
      endif
      if executable('pyls')
          autocmd FileType python setlocal omnifunc=lsp#complete
          autocmd FileType python nnoremap <buffer> <C-]> :LspDefinition<CR>
          autocmd FileType python nnoremap <buffer> gh :LspHover<CR>
          autocmd FileType python nnoremap <buffer> K :LspHover<CR>
          au User lsp_setup call lsp#register_server({
              \ 'name': 'pyls',
              \ 'cmd': {server_info->['pyls']},
              \ 'whitelist': ['python'],
              \ })
      endif

最近書く量そのものがガタ落ちしてますが,基本的に Rust, Haskell, LaTeX をこの順で書く.前2つを lsp に完全移行しました.syntax check / linter としては dense-analysis/ale を使っています.(都合2つ language server が起動することになり,ここの連携絶対なんかできるだろと思ってるのに着手できてません.)

いくつか正確に把握できてない不満があり,早いうちに問題の特定と fix を考えたいと思ってるのですが怠惰でうまく行っていません.

  • 片方が他方の部分文字列になるようなときの補完動作
  • (ALE の) linter とかの複数行にわたるメッセージをいい感じに表示する場所とかの設定
  • 後なんかいろいろ

これは advent calendar 中にうまくできれば記事にしたいです.

  wincent/terminus:
    before: |
      let g:TerminusMouse=0
      let g:TerminusFocusReporting=0
      let g:TerminusBracketedPaste=0

  majutsushi/tagbar:
    command:
      - TagbarToggle
  • wincent/terminus : insert mode でカーソルかっこよくするのにしか使ってない
  • majutsushi/tagbar: 便利だけど, lsp ベースの言語を最近触ってるので出番が少ない

乗り換え

  luochen1990/rainbow:
    before: |
      let g:rainbow_active = 1
      let g:rainbow_conf = {
      \ 'separately': {}
      \ }
      for ft in [
          \ "css", "text", "html", "javascript", "quickrun", "lua", "help",
          \ "qf", "agit", "agit_diff", "agit_stat", "diff", "gitcommit", "coq",
          \ "clojure"
          \ ]
        let g:rainbow_conf.separately[ft] = 0
      endfor

  kana/vim-operator-user:
    dependedby:
      - rhysd/vim-operator-surround
  rhysd/vim-operator-surround:
    dependon: kana/vim-operator-user
    after: |
      nnoremap <silent> s <Nop>
      map <silent>sa <Plug>(operator-surround-append)
      map <silent>sd <Plug>(operator-surround-delete)
      map <silent>sr <Plug>(operator-surround-replace)

まとめ

みたいな感じで,今年は LSP 系の導入以外はあんまり進捗ありませんでした.コード書くことも減ってるし仕方ないね.(これからちょっと当てがあり,特定の目的のためにコードを書く,と言う機会を増やしたい所存.)昨年11月の大掃除は現在まですごくいい効果をもたらしてるので,その頃に一度 write up しておけばよかったかも.定期的な振り返りも,他の人から見ると面白くなくても自分のためにはいいなという気分でした.