有馬総一郎のブログ

(彼氏の事情)

2018年11月09日 20:18:53 JST - 4 minute read - Vim

手遅れながらvimplenote-vimを使いやすくする(範囲指定とソートする)

Simplenoteをvimから使うやりかたとしては Big Sky :: VimからSimpleNoteを使う方法は何個かありますよという宣伝。が詳しい。

Pure Vim scriptだけで書かれた mattn/vimplenote-vimは、 mrtazz/simplenote.vimと比べると、以下の点で不満があった。

  • 一覧を取得する速度が遅い
  • 全件取得できない1
  • ソートされていない2
  • 上部に固定できない
  • <>&といった記号が実体参照変換されて保存される
  • VimpleNote -sで全文検索できる。しかし、そこからノートを開いて参照は出来るけれども、更新ができない
  • 削除した後も一覧が更新されないので、タイトルと開くノートがズレる

結局、simplenote.vim を使っていた。しかし、最近、どうにもエラーを吐くようになって安定せず、 vimplenote-vim をどうにか改善して使えないかと調べてみた。

どうもSimpleNote API3は公開されなくなってしまったらしいが、 SimpleNote-API-v2.1.3を見るとsinceというURLクエリパラメータとして、1970年からの秒を渡すと、それ以降のノートだけ取得できる。

--- a/autoload/vimplenote.vim
+++ b/autoload/vimplenote.vim
@@ -107,7 +107,11 @@ function! s:interface.list_note_index_in_scratch_buffer() dict
     return
   endif
 
-  let url = printf('https://simple-note.appspot.com/api2/index?auth=%s&email=%s&length=%d&offset=%d', self.token, webapi#http#encodeURI(self.email), 100, get(b:, "offset"))
+  let days = 60 * 60 * 24 * get(g:, 'VimplenoteSinceDays', 0)
+  if days > 0
+    let extra = printf('&since=%d', localtime() - days)
+  endif
+  let url = printf('https://simple-note.appspot.com/api2/index?auth=%s&email=%s&length=%d&offset=%d%s', self.token, webapi#http#encodeURI(self.email), 100, get(b:, "offset"), get(l:, 'extra', ''))
   let res = webapi#http#get(url)
   if res.status !~ '^2'
     echohl ErrorMsg | echomsg "VimpleNote: " res.message | echohl None

そして、取得したノートを"title""tags""key""modifydate""deleted"の5つの要素を持つ辞書型(dict)のデートとして、リストに詰めている。なので、 sort() 関数の注意点などを参考に辞書型データのソートをさせる。

diff --git a/autoload/vimplenote.vim b/autoload/vimplenote.vim
index ce5f14b..2371d0c 100755
--- a/autoload/vimplenote.vim
+++ b/autoload/vimplenote.vim
@@ -11,6 +11,7 @@ if !exists('s:interface')
   \ "token": "",
   \ "email": "",
   \ "notes": [],
+  \ "sort": -1,
   \}
 endif
 
@@ -102,6 +103,10 @@ function! s:GetNoteToCurrentBuffer(flag)
   call s:interface.display_note_in_scratch_buffer(a:flag)
 endfunction
 
+function! s:interface.compare(lhs, rhs) dict
+  return self.sort ? a:rhs.modifydate - a:lhs.modifydate : a:lhs.modifydate - a:rhs.modifydate
+endfunction
+
 function! s:interface.list_note_index_in_scratch_buffer() dict
   if len(self.authorization())
     return
@@ -142,6 +147,10 @@ function! s:interface.list_note_index_in_scratch_buffer() dict
     endif
   endfor
 
+  let self.sort = get(g:, 'VimplenoteSortByModifydateDesc', -1)
+  if self.sort >= 0
+    call sort(self.notes, self.compare)
+  endif
   call self.open_scratch_buffer("==VimpleNote==")
   silent %d _
   call setline(1, map(filter(copy(self.notes), 'v:val["deleted"] == 0'), 'printf("%s [%s]", strftime("%Y/%m/%d %H:%M:%S", v:val.modifydate), matchstr(v:val.title, "^.*\\%<60c"))'))

そして、以下のグローバル変数を設定することで、範囲を絞ったノート取得4、一覧の更新日付によるソートができるようになった。

let g:VimplenoteSinceDays = 10 "指定した日数分前から今日までノートを取得する
let g:VimplenoteSortByModifydateDesc = 1 " 更新日付の降順でソートする

しかし、調べていて今日知ったけど、古いAPI(https://simple-note.appspot.com)は廃止されていて、2018年10月1日以後はそのうち使えなくなのか…

Developers | Simplenote

Some older applications may still be using the legacy Simplenote API at https://simple-note.appspot.com. Note that this API has been deprecated and will no longer function after October 1, 2018.

それで simplenote.vim の方は Simperiumに対応させようと最近、コミットが多いのか。ちょうど過渡期で調子悪くなったのかも。

やったこと無駄だったかも。Vim scriptの勉強になったからいいけど。Vim scriptでもインスタンスメソッドやラムダ式で記述できるんだね。知らなかった。


追記: 2018-11-17
こんな拙いコードですが、mattnさんに取り込んでもらいました。
add option `VimplenoteSinceDays` , `VimplenoteSortByModifydateDesc` by arimasou16 · Pull Request #7 · mattn/vimplenote-vim · GitHub
オプションを追加しなければそれまでの機能には影響はないはず。
追記ここまで


  1. URLクエリパラメータlengthの制限として、削除したノート含め100件までしか取得できない ↩︎

  2. simplenote.vimではlet g:SimplenoteSortOrder = "pinned, modifydate, tags"とソート条件を指定できる。 ↩︎

  3. 本文にも書いたとおり、廃止された古いAPIとして2018年10月1日以後は近いうちに使えなくなる ↩︎

  4. 追記: 2018-11-17
    現在が2018/11/17 19:00の場合、g:VimplenoteSinceDays = 10とした場合、更新日が10日まえの2018/11/07 19:00以降のノートが一覧表示される
    追記ここまで ↩︎