📦

今更ながら、Ansibleでvim-bootstrapベースの設定管理をする自作ロールの紹介をする

2021/12/16に公開

自分はローカルの開発軽作業の基盤としてLinuxを割と多用しており、初期セットアップ向けのIaCとしてAnsibleを採用しています。
単純なPlaybookだけでなく、 dotfiles などを始めとした「どの環境でも大体使う」ものも含めて、まとめて GitHub上で管理しています。 [1]

さて、そんな基盤の上のエディターとして確実に入れているのがVisual Studio Code・Vim・NeoVim [2] で、規模感とか環境に合わせて行ったり来たりしています。
現時点でのVimを使う際のスタンスとしては、「思いっきりカスタマイズする」というよりも、「それなりに便利そうなプラグインだけセットアップ」するスタイルです。
そのため、細かく考えずともそこそこ便利使い出来るように、Vim Bootstrapを利用しています。

これらを踏まえてなのですが、3年ほど前にAnsible Galaxyで vim_bootstrapというロールを公開しています。

https://github.com/attakei/ansible-vim-bootstrap/

このロールを今年になって手直ししてたので、現在の実装でどんなことをやっているかを簡単に整理・解説します。

Vim Bootstrapのファイル生成の仕組み

WebサイトとしてのVim Bootstrapは、以下のような流れでファイルを生成します。

  • 「プログラミング言語」を選択する(複数可)
  • 「フレームワーク」を選択する(複数可)
  • 「カラーテーマ」を選択する
  • 「Vim or NeoVim」を選択する
  • Generate! というボタンを押す

ここで、最後に登場するボタンが何をやっているかというと、単純に**「選択した設定内容をフォームとしてPOSTリクエストする」**だけだったりします。[4]

そのため、ロール上では以下のような振る舞いで実現しています。

  • default/main.yml を初期値としてユーザーに設定内容を定義してもらう。
  • uri モジュールで、POSTリクエストを行い、内容を保持する。
  • copy モジュールで、ファイルを出力する。
tasks/main.yml
- name: Fetch new vimrc
  uri:
    url: https://vim-bootstrap.com/generate.vim
    method: POST
    body: '{{ lookup("vim_bootstrap_post", vim_langs, vim_frameworks, vim_theme, vim_command)|urlencode }}'
    return_content: yes
  register: vim_bootstrap_resp
- name: Write out vimrc
  copy:
    dest: '{{ vim_config_path }}'
    content: '{{ vim_bootstrap_resp.content }}'
    backup: yes
-

ただし、Ansible上の変数からフォーム用のクエリボディーを生成するのはJinjaテンプレート上だと手間なため、
ロール内部で自作のPluginを用意しています。

ユーザー固有設定の管理

Vim Bootstrapを使っている場合にも、ユーザーが独自に設定を追加したり、プラグインを追加するということはあります。[5]

これらのファイルは、もちろんAnsibleを用いない独自管理でも構わないのですが、やはり明らかに同じ設定はどの環境でも使いまわしたいですね。
とはいえ、 template モジュールだと中身に編集の余地がなくなり、「ユーザーとしては共通させたいが端末依存で変えたい」設定の置き場が大変です。[6]

思いつく対応法としては2個存在し、今回は後者を選んでいます。

  • template モジュールを使いつつ、生成されたファイルで更にインクルードさせる。
  • blockinfile モジュールを用いて、Ansibleでは特定領域しか触らないようにする。
tasks/main.yml
- name: Write custom plugins
  blockinfile:
    path: '{{ vim_localbundles_path }}'
    create: yes
    backup: '{{ vim_bootstrap_backup }}'
    marker: '" {mark} Generated by attakei.vim_bootstrap'
    block: |
      {% for plugin in vim_additional_plugins -%}
      Plug '{{ plugin }}'
      {% endfor %}
  when: 'vim_additional_plugins|length > 0'

こちらは、プラグイン用のファイルに関する部分の抜粋です。
blockinfile で出力されるマーカーの範囲外を編集することで、「Ansibleでの編集」「ユーザーによる編集」がバッティングしないようになっています。

余談

色々必要そうな更新を済ませて、現在は比較的安定した状態にはなっています。
とはいえ言語用の設定に関しては、最近になってVimのLSPプラグイン5人衆を導入しはじめた関係で、一切指定しなかったりします。 [7]
そのせいで、徐々にVim Bootstrapである必要性が薄くなってきている感じは否めません。

いつかVim Bootstrapでは不満が出ることもあるでしょうが、それは未来のお話ということで。

脚注
  1. メンテナンス頻度があまり高くないことには目をつぶる感じで。 ↩︎

  2. NeoVimは、Vimに多少プラグインを入れて使っている関係上、「手っ取り早く起動するまっさらなVim」の代用としています。 [3] ↩︎

  3. vim --cleanあたりを使ってない理由は特にないです。 ↩︎

  4. DevToolなどで見ると確認できます。 ↩︎

  5. Vim向けの設定では、独自プラグイン用に ~/.vimrc.local.bundles を、 設定用に ~/.vimrc.local を参照するようになてちます。 ↩︎

  6. 画面幅に関係するものは端末のサイズにも影響するので、「標準設定は共通化」して「個別設定で上書き」が望ましいです。 ↩︎

  7. prabirshrestha/async.vim, prabirshrestha/vim-lsp, prabirshrestha/asyncomplete.vim, prabirshrestha/asyncomplete-lsp.vim, mattn/vim-lsp-settings` ↩︎

GitHubで編集を提案

Discussion