diff --git a/src/sphinxnotes/snippet/integration/binding.nvim b/src/sphinxnotes/snippet/integration/binding.nvim index 0414214..25f0f34 100644 --- a/src/sphinxnotes/snippet/integration/binding.nvim +++ b/src/sphinxnotes/snippet/integration/binding.nvim @@ -8,10 +8,10 @@ " TODO: Support vim? function! g:SphinxNotesSnippetListAndView() - function! s:CallView(selection) - call g:SphinxNotesSnippetView(s:SplitID(a:selection)) + function! ListAndView_CB(id) + call g:SphinxNotesSnippetView(a:id) endfunction - call g:SphinxNotesSnippetList(function('s:CallView'), '*') + call g:SphinxNotesSnippetList('"*"', function('ListAndView_CB')) endfunction " https://github.com/anhmv/vim-float-window/blob/master/plugin/float-window.vim diff --git a/src/sphinxnotes/snippet/integration/binding.vim b/src/sphinxnotes/snippet/integration/binding.vim index 5919f0b..6225080 100644 --- a/src/sphinxnotes/snippet/integration/binding.vim +++ b/src/sphinxnotes/snippet/integration/binding.vim @@ -6,9 +6,9 @@ " :Version: 20211114 " -function! g:SphinxNotesSnippetEdit(id) - let file = system(join([s:snippet, 'get', '--file', a:id, '2>/dev/null'], ' ')) - let line = system(join([s:snippet, 'get', '--line-start', a:id, '2>/dev/null'], ' ')) +function g:SphinxNotesSnippetEdit(id) + let file = g:SphinxNotesSnippetGet(a:id, 'file')[0] + let line = g:SphinxNotesSnippetGet(a:id, 'line-start')[0] if &modified execute 'vsplit ' . file else @@ -17,48 +17,29 @@ function! g:SphinxNotesSnippetEdit(id) execute line endfunction -function! g:SphinxNotesSnippetListAndEdit() - function! s:CallEdit(selection) - call g:SphinxNotesSnippetEdit(s:SplitID(a:selection)) +function g:SphinxNotesSnippetListAndEdit() + function! ListAndEdit_CB(id) + call g:SphinxNotesSnippetEdit(a:id) endfunction - call g:SphinxNotesSnippetList(function('s:CallEdit'), 'ds') + call g:SphinxNotesSnippetList('ds', function('ListAndEdit_CB')) endfunction -function! g:SphinxNotesSnippetUrl(id) - let url_list = systemlist(join([s:snippet, 'get', '--url', a:id, '2>/dev/null'], ' ')) +function g:SphinxNotesSnippetUrl(id) + let url_list = g:SphinxNotesSnippetGet(a:id, 'url') for url in url_list echo system('xdg-open ' . shellescape(url)) endfor endfunction -function! g:SphinxNotesSnippetListAndUrl() - function! s:CallUrl(selection) - call g:SphinxNotesSnippetUrl(s:SplitID(a:selection)) +function g:SphinxNotesSnippetListAndUrl() + function! ListAndUrl_CB(id) + call g:SphinxNotesSnippetUrl(a:id) endfunction - call g:SphinxNotesSnippetList(function('s:CallUrl'), 'ds') -endfunction - -function! g:SphinxNotesSnippetInput(id, item) - let content = system(join([s:snippet, 'get', '--' . a:item, a:id, '2>/dev/null'], ' ')) - let content = substitute(content, '\n\+$', '', '') " skip trailing \n - if a:item == 'docname' - " Create doc reference. - let content = ':doc:`/' . content . '`' - endif - execute 'normal! i' . content -endfunction - -function! g:SphinxNotesSnippetListAndInputDocname() - function! s:InputDocname(selection) - call g:SphinxNotesSnippetInput(s:SplitID(a:selection), 'docname') - endfunction - call g:SphinxNotesSnippetList(function('s:InputDocname'), 'd') + call g:SphinxNotesSnippetList('ds', function('ListAndUrl_CB')) endfunction nmap e :call g:SphinxNotesSnippetListAndEdit() nmap u :call g:SphinxNotesSnippetListAndUrl() -nmap d :call g:SphinxNotesSnippetListAndInputDocname() -" FIXME: can't return to insert mode even use a/startinsert!/C-o -imap d :call g:SphinxNotesSnippetListAndInputDocname() +nmap i :call g:SphinxNotesSnippetListAndInput() " vim: set shiftwidth=2: diff --git a/src/sphinxnotes/snippet/integration/plugin.vim b/src/sphinxnotes/snippet/integration/plugin.vim index da79b48..3cf01c5 100644 --- a/src/sphinxnotes/snippet/integration/plugin.vim +++ b/src/sphinxnotes/snippet/integration/plugin.vim @@ -8,25 +8,102 @@ " NOTE: junegunn/fzf.vim is required let s:snippet = 'snippet' +let s:width = 0.9 +let s:height = 0.6 -function! s:SplitID(row) - return split(a:row, ' ')[0] -endfunction - -" TODO: extra opts -function! g:SphinxNotesSnippetList(callback, tags) - let l:width = 0.9 +" Use fzf to list all snippets, callback with argument id. +function g:SphinxNotesSnippetList(tags, callback) let cmd = [s:snippet, 'list', \ '--tags', a:tags, - \ '--width', float2nr(&columns * l:width) - 2, + \ '--width', float2nr(&columns * s:width) - 2, \ ] + + " Use closure keyword so that inner function can access outer one's + " localvars (l:) and arguments (a:). + " https://vi.stackexchange.com/a/21807 + function! List_CB(selection) closure + let id = split(a:selection, ' ')[0] + call a:callback(id) + endfunction + " https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzfrun call fzf#run({ \ 'source': join(cmd, ' '), - \ 'sink': a:callback, + \ 'sink': function('List_CB'), \ 'options': ['--with-nth', '2..', '--no-hscroll', '--header-lines', '1'], - \ 'window': {'width': l:width, 'height': 0.6}, + \ 'window': {'width': s:width, 'height': s:height}, \ }) endfunction -" vim: set shiftwidth=2: +" Return the attribute value of specific snippet. +function g:SphinxNotesSnippetGet(id, attr) + let cmd = [s:snippet, 'get', a:id, '--' . a:attr] + return systemlist(join(cmd, ' ')) +endfunction + +" Use fzf to list all attr of specific snippet, +" callback with arguments (attr_name, attr_value). +function g:SphinxNotesSnippetListSnippetAttrs(id, callback) + " Display attr -> Identify attr (also used as CLI option) + let attrs = { + \ 'Source': 'src', + \ 'URL': 'url', + \ 'Docname': 'docname', + \ 'Dependent files': 'deps', + \ 'Text': 'text', + \ 'Title': 'title', + \ } + let delim = ' ' + let table = ['OPTION' . delim . 'ATTRIBUTE'] + for name in keys(attrs) + call add(table, attrs[name] . delim . name) + endfor + + function! ListSnippetAttrs_CB(selection) closure + let opt = split(a:selection, ' ')[0] + let val = g:SphinxNotesSnippetGet(a:id, opt) + call a:callback(opt, val) " finally call user's cb + endfunction + + let preview_cmd = [s:snippet, 'get', a:id, '--$(echo {} | cut -d " " -f1)'] + let info_cmd = ['echo', 'Index ID:', a:id] + call fzf#run({ + \ 'source': table, + \ 'sink': function('ListSnippetAttrs_CB'), + \ 'options': [ + \ '--header-lines', '1', + \ '--with-nth', '2..', + \ '--preview', join(preview_cmd, ' '), + \ '--preview-window', ',wrap', + \ '--info-command', join(info_cmd, ' '), + \ ], + \ 'window': {'width': s:width, 'height': s:height}, + \ }) +endfunction + +function g:SphinxNotesSnippetInput(id) + function! Input_CB(attr, val) " TODO: became g:func. + if a:attr == 'docname' + " Create doc reference. + let content = ':doc:`/' . a:val[0] . '`' + elseif a:attr == 'title' + " Create local section reference. + let content = '`' . a:val[0] . '`_' + else + let content = join(a:val, '') + endif + execute 'normal! i' . content + endfunction + + call g:SphinxNotesSnippetListSnippetAttrs(a:id, function('Input_CB')) +endfunction + +function g:SphinxNotesSnippetListAndInput() + function! ListAndInput_CB(id) + call g:SphinxNotesSnippetInput(a:id) + endfunction + + call g:SphinxNotesSnippetList('"*"', function('ListAndInput_CB')) +endfunction + + " vim: set shiftwidth=2: