有馬総一郎のブログ

(彼氏の事情)

手遅れながらvimplenote-vimを使いやすくする(検索したノートを更新できるようにする)

今度は、折角のmattn/vimplenote-vimのアドバンテージとしてノートの検索ができるのだから、検索したノートを参照だけでなく、更新できるようにしたい。

何故、検索したノートを更新できないか、調べてみたところ、リストから開いてノート更新のする場合は、authorizationのファンクションが呼ばれているけど、検索してノートを開いて更新しようとした場合は、authorizationのファンクションが呼ばれていない

ノート一覧:Vimplenote -l ノート検索:Vimplenote -s
list_note_index_in_scratch_buffer

authorization

open_scratch_buffer
search_notes_with_tags

authorization

open_scratch_buffer
ノートを開く<cr> ノートを開く<cr>
GetNoteToCurrentBuffer

display_note_in_scratch_buffer

authorization

open_scratch_buffer
GetNoteToCurrentBuffer

display_note_in_scratch_buffer

authorization

open_scratch_buffer
更新:w 更新:w
update_note_from_current_buffer

get_current_note

authorization
update_note_from_current_buffer

get_current_note

つまりget_current_note()でemptyとなって更新できない。

vimplenote-vim/autoload/vimplenote.vim
1
2
3
4
5
6
7
function! s:interface.update_note_from_current_buffer() dict
  let note = self.get_current_note()
  if empty(note)
    return
  endif

if len(self.authorization())

検索した場合は notes リストが空なので、更新できないということだった。

vimplenote-vim/autoload/vimplenote.vim
1
2
3
4
5
6
7
8
9
10
function! s:interface.get_current_note()
  let mx = '^VimpleNote:\zs\w\+'
  let key = matchstr(bufname('%'), mx)
  if len(key) == 0
    return {}
  endif
  let found = filter(copy(self.notes), 'v:val.key == key')
  if len(found) == 0
   return
endif

なら、検索したときに notes リストに結果を詰めようと思ったが、検索結果としては更新日付やタグといった情報が足りていない。0でとりあえず埋めとこうとしたが、そうすると更新するときにタグが空になってしまったりするので宜しくない。

また、リスト取得時に検索したノートが混じってしまい、更新日付が1970年のノートとして表示される。

じゃあ、更新するときに、検索したノートの場合は一覧取得の時とは別の実装で次の処理に行くようにしようと思ったが、更新に限らず、ノートに対する処理は notes に詰めこまれている前提なので全ての処理に改修を加えるのは一苦労。

パフォーマンスが劣化するけど、検索結果取得の時も、一覧取得と同様に各ノートを一つずつ取得して必要な情報を取ることにした。それでも、一覧表示時に検索したノートが混じるのは宜しくないので、検索したノートは削除するかたちで実装してみた。

vimplenote.vim検索したノートも更新可能に
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
--- a/autoload/vimplenote.vim
+++ b/autoload/vimplenote.vim
@@ -122,6 +122,10 @@ function! s:interface.list_note_index_in_scratch_buffer() dict
     echohl ErrorMsg | echomsg "VimpleNote: " res.message | echohl None
     return
   endif
+  let found = filter(copy(self.notes), 'v:val.search == 1')
+  if len(found) > 0
+    let self.notes = []
+  endif
   let datas = webapi#json#decode(res.content)
   for note in datas.data
     if !note.deleted
@@ -143,6 +147,7 @@ function! s:interface.list_note_index_in_scratch_buffer() dict
       \  "key": note.key,
       \  "modifydate": note.modifydate,
       \  "deleted": note.deleted,
+      \  "search": 0,
       \})
     endif
   endfor
@@ -170,9 +175,27 @@ function! s:interface.search_notes_with_tags(...) dict
     return
   endif
   let datas = webapi#json#decode(res.content)
+  for result in datas.Response.Results
+    let url = printf('https://simple-note.appspot.com/api2/data/%s?auth=%s&email=%s', result.key, self.token, webapi#http#encodeURI(self.email))
+    let res = webapi#http#get(url)
+    if res.status !~ '^2'
+      echohl ErrorMsg | echomsg "VimpleNote: " res.message | echohl None
+      return
+    endif
+    let data = webapi#json#decode(res.content)
+    let lines = split(data.content, "\n")
+    call add(self.notes, {
+    \  "title": len(lines) > 0 ? lines[0] : '',
+    \  "tags": data.tags,
+    \  "key": result.key,
+    \  "modifydate": data.modifydate,
+    \  "deleted": data.deleted,
+    \  "search": 1,
+    \})
+  endfor
   call self.open_scratch_buffer("==VimpleNote==")
   silent %d _
-  call setline(1, map(datas.Response.Results, 'printf("%s | [%s]", v:val.key, matchstr(substitute(v:val.content, "\n", " ", "g"), "^.*\\%<60c"))'))
+  call setline(1, map(copy(self.notes), 'printf("%s [%s]", strftime("%Y/%m/%d %H:%M:%S", v:val.modifydate), matchstr(v:val.title, "^.*\\%<60c"))'))
   nnoremap <buffer> <cr> :call <SID>GetNoteToCurrentBuffer(0)<cr>
   setlocal nomodified
 endfunction
@@ -188,11 +211,7 @@ function! s:interface.display_note_in_scratch_buffer(flag) dict
   if line('.') == 0 || getline('.') == ''
     return
   endif
-  if a:flag
-    let note = self.notes[line('.')-1]
-  else
-    let note = { "key" : matchstr(getline('.'), '^[^ ]\+\ze') }
-  endif
+  let note = self.notes[line('.')-1]
   let url = printf('https://simple-note.appspot.com/api2/data/%s?auth=%s&email=%s', note.key, self.token, webapi#http#encodeURI(self.email))
   let res = webapi#http#get(url)
   if res.status !~ '^2'
vimplenote.vim検索結果が残り続けるのを修正
1
2
3
4
5
6
7
8
@@ -174,6 +174,7 @@ function! s:interface.search_notes_with_tags(...) dict
     echohl ErrorMsg | echomsg "VimpleNote: " res.message | echohl None
     return
   endif
+  let self.notes = []
   let datas = webapi#json#decode(res.content)
   for result in datas.Response.Results
     let url = printf('https://simple-note.appspot.com/api2/data/%s?auth=%s&email=%s', result.key, self.token, webapi#http#encodeURI(self.email))

とりあえず、これで様子見だ。

それにしても、call setline(1, map([1,2,3], 'printf("%s | [%s]", "ddddd cccccc", "xxxxx")'))で、

ddddd cccccc | [xxxxx]
ddddd cccccc | [xxxxx]
ddddd cccccc | [xxxxx]

こうなるんだね…他filterとかなかなか、個人的に直感的に理解しにくいメソッドだ。

Comments