この記事は Vim (その 2) Advent Calendar 2016 の 9 日目の記事です。
Vim に関する記事 + Advent Calendar 初投稿です。よろしくお願いします。


昨年末、仕事が凄く詰まっている時期に突然 Vim を使い始めて、丁度 1 年が経とうとしています。

それまではターミナルを開くのも、Gulp や npm scripts を走らせるときくらいで、それ程使用頻度としては高くありませんでした。
しかし、Vim と出会ってからは一変、黒い画面の中に篭もるようになりました。

そうなってくると Vim でなんでも完結させたい 欲が出てきました。

皆さん、メモの管理はどうしてますか?

Vim で作業中、さくっとメモ書きを残しておきたいことがあります。例を挙げると、

  • 備忘録を残しながら作業したい
  • コードの設計を文書化して思案したい
  • TODO の管理
  • 突如ポエムを書きたくなった
  • 別件の作業指示があった
  • メールの下書きをしたい
  • etc…

などなど、メモを残したくなるシチュエーションは多くあると思います。


先輩 Vimmer の方々がどうしているのかと探してみると幾つか記事が見つかります。

どれも良さそうです。ただ、作成したメモを様々な環境で参照しようとすると Dropbox あたりを使うことになりそうです。

Dropbox でも問題無いのですが、出先や休憩中にスマホでメモを見返したい時に、やや見づらいのが難点です。

改善の余地が無いかなぁとぼんやり考えていたら、それを解決するのにうってつけなものが見つかりました。

Slack で管理したらよさそう

Slack の提供するアプリは使い勝手もよく見やすいと思います。他サービスとの連携も非常に柔軟に行えます。そして、デフォルトで優秀な検索機能が付いています。

#memo みたいなメモ書き専用のチャンネルに Vim からサクッと挙げることが出来れば、先述した悩みを解消できそうです。

というわけで、

Slack! Memo! Vim!

Slack をメモ代わりに使うためのプラグインを作ってみました。

スクリーンショット

上記では新規バッファを開き、メモを書いて Slack に投稿したりしてます。

極力シンプルに使えることを目指し、オプションや API を一つでも減らすことで、複数チャンネルやユーザには対応していません。

プラグインのリポジトリは以下です。

wadackel/slack-memo-vim
https://github.com/wadackel/slack-memo-vim

Windows 環境が手元に無いため未確認です。すみません。

導入方法

他プラグインと同様にインストールします。内部的にmattnさんのwebapi-vimを使用しているので、別途インストールする必要があります。

dein

.vimrc
call dein#add('mattn/webapi-vim')
call dein#add('wadackel/slack-memo-vim', {'depends': 'mattn/webapi-vim'})

NeoBundle

.vimrc
NeoBundle 'mattn/webapi-vim'
NeoBundle 'wadackel/slack-memo-vim', {'depends': 'mattn/webapi-vim'}

Slack のトークン、メモ用チャンネルの設定

Slack の API を叩く必要があるので、以下のように API トークンの設定が必要です。

.vimrc
let g:slack_memo_token = '<YOUR_TOKEN>'
let g:slack_memo_channel = '<YOUR_MEMO_CHANNEL_ID>'

これらの設定後は、すぐに使い始めることができます。

トークンの取得方法はググればすぐに出ると思うので割愛します。
g:slack_memo_channelにはチャンネル名ではなく、チャンネルのIDが必要です。
API > Methods > channels.listのテスターを使うことで ID の確認が簡単にできます。

余談ですが、トークンは基本的に非公開とするのが良いので、dotfiles などで.vimrc を管理している際は別ファイルとして管理するのが良いと思います。

.vimrc
if filereadable(expand('~/.vimrc.local'))
  source ~/.vimrc.local
endif
.vimrc.local
let g:slack_memo_token = '<YOUR_TOKEN>'
let g:slack_memo_channel = '<YOUR_MEMO_CHANNEL_ID>'

以上で導入完了です。

できること

できることはそれほど多くありませんが簡単にご紹介します。

新規メモ

何かしらのバッファを開きメモを書いたあと、以下のコマンドを実行します。

:SlackMemoPost

メモの投稿デモ

メモの投稿後は通常のファイルと同様に:wなどで保存すると、そのまま Slack 上のメモが更新されるようになっています。

また、1 行目は後述するメモ一覧時にタイトルとして扱われます。そのため、分かりやすいものにしておくと良いと思います。$ git log --onelineなんかと同じ感じです。

メモの一覧

以下のコマンドを実行するとメモを一覧し、<CR>又はoでバッファにカーソル上のメモを展開します。

:SlackMemoList

メモの一覧デモ

一覧を閉じるときは<Esc>qをタイプします。勿論:qでも OK です。

本筋とは少しずれますが、新規メモ追加時に Slack の API でタイムスタンプを返してくれるので、投稿した日時をメモの本文に入れなくても自動で残せるのが地味に便利です。

一覧中に使用できるキーマップは以下の通りです。

キー 概要
Enter or o カーソル上のメモを開く.
Esc or q 一覧を閉じる.
d カーソル上のメモを削除.
y カーソル上のメモ本文を Yank.
r 一覧を更新します. (Slack 上の変更を取り込み)

メモの削除

キーマップの一覧でも示しましたが、削除したいメモにカーソルを合わせ、dをタイプすると確認が出るのでyで削除します。

メモの削除デモ

複数選択で削除したいのですが未実装です…。

GFM の TODO リストをサポート

GFM の TODO リストはそのままでも充分に見やすいですが、Slack 上ではやや見づらく感じたので emoji として表示するようになっています。

GFMのTODOリストデモ

Bot のユーザ名やアイコンを変更

アイコンには画像、又は emoji が使用可能です。デフォルトではアイコンは未指定になります。

デフォルトの設定
let g:slack_memo_bot_username = 'Vim (bot)'
let g:slack_memo_bot_icon_url = ''
" 又は
let g:slack_memo_bot_icon_emoji = ''

キーマップなど

デフォルトではキーマップは当ててません。必要に応じて各自設定する必要があります。
以下、設定例です。

.vimrc
nnoremap smp :SlackMemoPost<CR>
nnoremap sml :SlackMemoList<CR>

CtrlP で一覧する

以下コマンドを使用すると CtrlP でメモを一覧することもできます。CtrlP がインストール済みの場合にのみ動作します。

:SlackMemoCtrlP

ただ、今のところ先述した削除などのアクションが出来ないので、使い勝手はそれほど良くないかもしれません…。

できないこと

正直なところ、できないことがまだまだ多くあります…。(是非 PR ください!!)

検索できないです…

僕自身の Vim script 力が足らなすぎて、まだ検索機能がありません。かなり致命的な感じがするので、そのうち気が向いた時に実装する予定です。

カテゴリ、タグなどはありません

良い実装が浮かばなかったのと、タイトル(1 行目)を工夫することで概ね問題無いように思うので多分対応しないと思います。

カテゴリごとに投稿する Bot のユーザ名を変えれば分かりやすいかもと思ったのですが、投稿者は後から変更出来なそうだったので諦めました。

最大で 1000 件までしかリストできません

Slack の API で各チャンネルの履歴を一度に取得出来るのが、1000 件が限界です。 ページネーション的な実装がまだなので、現状 1000 件のメモが限界です…。

一つのメモに対する文字数制限

しっかりと確認しているわけではないのですが、Real Time Messaging APIの Limits の項によると、4,000 文字(マルチバイト関連未確認です…)が送信出来ないみたいです。
試しに手元にあった長めのコードをそのままポストしてみると、分割された状態で保存されました。

そのため、あくまで簡易的なメモに向きそうです。

おわりに

まだまだエラー処理が雑だったり、至らないところばかりですが、なんとかぎりぎりプラグインとして動くところまで出来ました。
これを作るまで、10 行以上の Vim Script を書いたことが無いくらいだったのでご容赦いただければ幸いです。

機能要望やバグなどありましたらIssuesTwitterまでご連絡いただければ嬉しいです。


最後に、実装に関して mattn さんのgist-vimをもの凄く参考にさせていただきました。
有難うございます。

次の Advent Calendar は wordijp さんで「exepath でスーパーサイヤ人か判定する」です。
気になります。