Vimで快適に記事を書くため環境

初めに

こんにちは、Neovimを使い初めたゴリラです。

普段zenn.devに載せる記事をVimで書いています。 しかしVimで記事を書くとどうしても画像アップロードとリンク挿入の手間がかかってしまったり、 誤字脱字があったり、文章表現がバラバラになったりという問題があります。

こういった問題を長らく放置してきましたが、重い腰を上げて対策しました。 本記事は、Vim/Neovimで快適に記事を書くためにどんなことをしたのかについて解説していきます。

環境

筆者の環境は次になっています。Node.jsnpmGoは必要です。

EnvironmentsVersion
OSUbuntu 20.04 TLS
Vim8.2.1992
Neovimv0.5.0-834-g7c4f34966
Node.jsv14.15.0
npm6.14.8
Gogo version go1.15.3 linux/amd64

要件

まず、記事を書くにあたり次の要件があります。

  1. 誤字脱字を可能な限りなくす
  2. 文章の表現を統一
  3. クリップボードや画像ファイルを選択してアップロードして、そのリンクを本文に挿入

これらはmustと考えています。特に3は記事を書いていると画像やgifとを貼ったりするのでそれを毎度ブラウザを使ってアップロードするのは非常に手間です。 エディタで記事を書きながら、シームレスに画像をアップロードできたらこれだけで少なくとも5秒くらいは短縮できるでしょう。

この要件をもとに、対策をしていきます。

誤字脱字、表記ゆれ対策

1と2に関してはいわゆる校正作業ですが、こちらはtextlintを使います。

  • zenn.devは記事をリポジトリと連携できる
  • Node.jsを使っている

ということで、zenn.devと相性も良いです。(インストールして設定するだけ)

合わせて、校正ルールのプリセットもインストールします。

# textlint のインストール
$ npm install textlint

# ルールセット
$ npm install textlint-rule-prh textlint-rule-preset-jtf-style textlint-rule-preset-ja-technical-writing

使用しているルールは次の通りです。詳細はリンク先を参照ください。ひとまずこれらがあれば問題ないでしょう。

ルール説明
textlint-rule-preset-jtf-styleJTF日本語標準スタイルガイド
textlint-rule-preset-ja-technical-writing技術文章向けのルールプリセット
textlint-rule-prhprhという校正ツールのtextlintルールプリセット

インストール完了後.textlintrcに次の設定をします。(preset-ja-technical-writingでいくつかルールを無効にしています)

{
  "filters": {},
  "rules": {
    "preset-ja-technical-writing": {
      "ja-no-weak-phrase": false,
      "ja-no-mixed-period": false,
      "no-exclamation-question-mark": false
    },
    "preset-jtf-style": true,
    "prh": {
      "rulePaths": [
        "node_modules/prh/prh-rules/media/WEB+DB_PRESS.yml",
        "node_modules/prh/prh-rules/media/techbooster.yml"
      ]
    }
  }
}

設定完了したら、試しにエラーが起きる文章にtextlintをかけてみると、次のように修正すべき箇所が出てきます。

これらをまとめて修正するにはtextlint --fix [file]すればよいです。 Vim上で実行する場合は:terminal npx textlint --fix [file]もしくは:!npx textlint --fix [file]すればよいです。 これでひとまず校正すべき箇所を検出してくれる環境を用意できました。次はVim/Neovimの設定を行っていきます。

Vim/NeovimではLSP(Language Server Protocol)を使って、動的にtextlintで校正箇所を検出します。 次のプラグインをインストールことで、Vim/NeovimでもLSPを使えます。

プラグインをインストール後、:LspInstallServer efm-langserverefm-langserverをインストールします。efm-langservertextlintをLSPサーバとして動かすのに必要です。

プラグインの用意ができたら、プラグインの設定をします。vimrcまたはinit.vimに次の設定を書きます。

" lsp settings {{{
let g:lsp_signs_error = {'text': 'ウホ'}
let g:lsp_signs_warning = {'text': '🍌'}
if !has('nvim')
  let g:lsp_diagnostics_float_cursor = 1
endif
let g:lsp_log_file = ''

let g:lsp_settings = {
      \ 'efm-langserver': {
      \   'disabled': 0,
      \   'allowlist': ['markdown'],
      \  }
      \ }

function! s:on_lsp_buffer_enabled() abort
  setlocal completeopt=menu
  setlocal omnifunc=lsp#complete
endfunction

augroup lsp_install
  au!
  au User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END
" }}}

最後にtextlintをLSPとして動かすためにefm-langserverの設定を行います。 ~/.config/efm-langserver/config.yamlに次の設定をします。

version: 2
tools:
  markdown-textlint: &markdown-textlint
    lint-command: 'npx --no-install textlint -f unix --stdin --stdin-filename ${INPUT}'
    lint-ignore-exit-code: true
    lint-stdin: true
    lint-formats:
      - '%f:%l:%c: %m [%trror/%r]'
    root-markers:
      - .textlintrc
languages:
  markdown:
    - <<: *markdown-textlint

これで設定は終わりです。Vim/NeovimでMarkdownのファイルを開くと次のようにtextlintの指摘が表示されます。 編集、保存するたびにefm-langservertextlintを実行しその結果を返してくれるので記事を書きながら校正できます。

画像アップロード

zenn.devやQiitaはそれぞれ、Webエディタ上でCtrl(Cmd)+vを使うとクリップボードから画像をアップロード&リンクを挿入してくれます。 これはすばらしい機能と体験ですが、残念ながらVim/Neovimはそのような機能を持っていません。

そこで、Vim/Neovimでクリップボードから画像をアップロード&リンクを挿入してくれるプラグインgyazo.vimを作りました。 画像のアップロード先はGyazoになるので別途アカウント&トークンを取得する必要はありますが、次のようにスクショを撮ってそのままアップロードできるので要件を満たせます。

終わりに

これらの設定でだいぶ執筆環境が整って捗りました。今回はMarkdownだけ動くようにしていますが、ほかの拡張子でも動かせます。 少し手間がかかりますが、Vimmerで同じように不便を感じている方はぜひ試してみてください。


Vim

2020/11/16 00:00