🗓️

日付を加減算したり今日に修正するvimのプラグインを作った

2022/07/29に公開

プラグインの紹介

動作イメージ

https://github.com/utubo/vim-reformatdate

  • <C-a><C-x>で日付や曜日の加減算ができるようになります
  • <F6>(マッピングは一例)で強制的に今日の日付に更新できます
  • 日付を更新したついでに直後にある曜日も勝手に更新します!

これでvimで日記を書くのが捗りますね

インストール

README.mdに書いてありますが一応…

call dein('utubo/vim-reformatdate')

" Reformat
nnoremap <silent> <F5> :call reformatdate#reformat()<CR>

" Reset to today
nnoremap <silent> <F6> :call reformatdate#reformat(localtime())<CR>

" Increment/Decrement days
nnoremap <silent> <C-a> :<C-u>call reformatdate#inc(v:count)<CR>
nnoremap <silent> <C-x> :<C-u>call reformatdate#dec(v:count)<CR>

設定

対応フォーマット、曜日や月の名前は自由に追加できます。

let g:reformatdate_extend_formats = ['%m月%d日']
let g:reformatdate_extend_names = [{
  \ 'a': ['日', '月', '火', '水', '木', '金', '土'],
  \ 'A': ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'],
  \ }, {
  \ 'a': ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
  \}, {
  \ 'b': ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫'],
  \}]

作ってハマったところ

知見としてメモっておきます

strptime

Windowsには無いという罠
フォーマット文字列の%Y,%m...とサブマッチグループが順番通り1対1で紐づくような正規表現をつくって自前でパースするようにしました

strftime

マルチバイト文字に対応していないという罠
しょうがないので自作しました
(後で気づきましたがvital.vimにあるかも?)

カーソル位置の日付文字列を拾う仕組み

迷ったんですが以下で切り抜けました
フォーマットから作った正規表現で前方検索

search('\V' . 正規表現 . '\C', 'bc', line('.'))

結果が0でなければ、続いてカーソル位置をマッチ終端へするように検索

search('\V' . 正規表現 . '\C', 'ce', line('.'))

上記で文字列の始めと終わりを取得し、元のカーソル位置がその中に収まっていれば更新対象としています
magicignorecaseは設定で変えられている可能性があるので\V\Cを付与しています

カーソル位置の曜日名を拾う仕組み

expand('<cword>')をつかってます
なので_Wed_なんかだと前後のアンダーバーも含まれてしまって更新できなかったりします
(なにかいい手はないものか…)

実は

実は作ったのは7年前くらい前で、こっそりGithubに上げてました
最近なんとなく整理や機能追加したので取り上げてみたのでした

2022/07/30 追記

<C-a>,<C-x>についてはdps-dialがよさそうですね
https://zenn.dev/monaqa/articles/2021-12-18-vim-dps-dial

reformatdateは日付特化で%B %d等にも対応してますから
共存させる場合はreformatedateの加減算のマッピングを<Leader><C-a>などにするといいかもしれません

GitHubで編集を提案

Discussion