From ee7752bfc783b0d8c568f0d09ffcbfdd20c0dcd3 Mon Sep 17 00:00:00 2001 From: Shengyu Zhang Date: Wed, 23 Oct 2024 23:11:51 +0800 Subject: [PATCH] feat(integration): General vim input helper --- .../snippet/integration/binding.vim | 21 +---- .../snippet/integration/plugin.vim | 79 +++++++++++++++++-- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/sphinxnotes/snippet/integration/binding.vim b/src/sphinxnotes/snippet/integration/binding.vim index 5919f0b..aa14a2f 100644 --- a/src/sphinxnotes/snippet/integration/binding.vim +++ b/src/sphinxnotes/snippet/integration/binding.vim @@ -38,27 +38,8 @@ function! g:SphinxNotesSnippetListAndUrl() 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') -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:SphinxNotesSnippetInputSnippetAttr() " vim: set shiftwidth=2: diff --git a/src/sphinxnotes/snippet/integration/plugin.vim b/src/sphinxnotes/snippet/integration/plugin.vim index da79b48..169681c 100644 --- a/src/sphinxnotes/snippet/integration/plugin.vim +++ b/src/sphinxnotes/snippet/integration/plugin.vim @@ -8,25 +8,94 @@ " NOTE: junegunn/fzf.vim is required let s:snippet = 'snippet' +let s:width = 0.9 +let s:height = 0.6 +" TODO: remove function! s:SplitID(row) return split(a:row, ' ')[0] endfunction -" TODO: extra opts +" Use fzf to list all snippets, callback with arguments (selection). function! g:SphinxNotesSnippetList(callback, tags) - let l:width = 0.9 let cmd = [s:snippet, 'list', \ '--tags', a:tags, - \ '--width', float2nr(&columns * l:width) - 2, + \ '--width', float2nr(&columns * s:width) - 2, \ ] " https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzfrun call fzf#run({ \ 'source': join(cmd, ' '), \ 'sink': a:callback, \ '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 + + " Local scope -> script scope, so vars can be access from inner function. + let s:id_for_list_snippet_attrs = a:id + let s:cb_for_list_snippet_attrs = a:callback + function! s:SphinxNotesSnippetListSnippetAttrs_CB(selection) + let opt = split(a:selection, ' ')[0] + let val = g:SphinxNotesSnippetGet(s:id_for_list_snippet_attrs, opt) + call s:cb_for_list_snippet_attrs(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('s:SphinxNotesSnippetListSnippetAttrs_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:SphinxNotesSnippetInputSnippetAttr(id) + function! s:SphinxNotesSnippetInputSnippetAttr_CB(attr, val) + if a:attr == 'docname' + " Create doc reference. + let content = ':doc:`/' . val[0] . '`' + elif a:attr == 'title' + " Create local section reference. + let content = '`' . val[0] . '`_' + else: + let content = join(val, '') + endif + + execute 'normal! i' . content + endfunction + + call g:SphinxNotesSnippetListSnippetAttrs(a:id, function('s:SphinxNotesSnippetInputSnippetAttr_CB')) +endfunction + + " vim: set shiftwidth=2: