Skip to content

Commit d6db43f

Browse files
authored
feat(integration): General vim input helper (#38)
* feat(integration): General vim input helper * refactor(integration): Refactor vim plugin
1 parent deef7e4 commit d6db43f

File tree

3 files changed

+105
-47
lines changed

3 files changed

+105
-47
lines changed

src/sphinxnotes/snippet/integration/binding.nvim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
" TODO: Support vim?
99

1010
function! g:SphinxNotesSnippetListAndView()
11-
function! s:CallView(selection)
12-
call g:SphinxNotesSnippetView(s:SplitID(a:selection))
11+
function! ListAndView_CB(id)
12+
call g:SphinxNotesSnippetView(a:id)
1313
endfunction
14-
call g:SphinxNotesSnippetList(function('s:CallView'), '*')
14+
call g:SphinxNotesSnippetList('"*"', function('ListAndView_CB'))
1515
endfunction
1616

1717
" https://github.com/anhmv/vim-float-window/blob/master/plugin/float-window.vim

src/sphinxnotes/snippet/integration/binding.vim

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
" :Version: 20211114
77
"
88

9-
function! g:SphinxNotesSnippetEdit(id)
10-
let file = system(join([s:snippet, 'get', '--file', a:id, '2>/dev/null'], ' '))
11-
let line = system(join([s:snippet, 'get', '--line-start', a:id, '2>/dev/null'], ' '))
9+
function g:SphinxNotesSnippetEdit(id)
10+
let file = g:SphinxNotesSnippetGet(a:id, 'file')[0]
11+
let line = g:SphinxNotesSnippetGet(a:id, 'line-start')[0]
1212
if &modified
1313
execute 'vsplit ' . file
1414
else
@@ -17,48 +17,29 @@ function! g:SphinxNotesSnippetEdit(id)
1717
execute line
1818
endfunction
1919

20-
function! g:SphinxNotesSnippetListAndEdit()
21-
function! s:CallEdit(selection)
22-
call g:SphinxNotesSnippetEdit(s:SplitID(a:selection))
20+
function g:SphinxNotesSnippetListAndEdit()
21+
function! ListAndEdit_CB(id)
22+
call g:SphinxNotesSnippetEdit(a:id)
2323
endfunction
24-
call g:SphinxNotesSnippetList(function('s:CallEdit'), 'ds')
24+
call g:SphinxNotesSnippetList('ds', function('ListAndEdit_CB'))
2525
endfunction
2626

27-
function! g:SphinxNotesSnippetUrl(id)
28-
let url_list = systemlist(join([s:snippet, 'get', '--url', a:id, '2>/dev/null'], ' '))
27+
function g:SphinxNotesSnippetUrl(id)
28+
let url_list = g:SphinxNotesSnippetGet(a:id, 'url')
2929
for url in url_list
3030
echo system('xdg-open ' . shellescape(url))
3131
endfor
3232
endfunction
3333

34-
function! g:SphinxNotesSnippetListAndUrl()
35-
function! s:CallUrl(selection)
36-
call g:SphinxNotesSnippetUrl(s:SplitID(a:selection))
34+
function g:SphinxNotesSnippetListAndUrl()
35+
function! ListAndUrl_CB(id)
36+
call g:SphinxNotesSnippetUrl(a:id)
3737
endfunction
38-
call g:SphinxNotesSnippetList(function('s:CallUrl'), 'ds')
39-
endfunction
40-
41-
function! g:SphinxNotesSnippetInput(id, item)
42-
let content = system(join([s:snippet, 'get', '--' . a:item, a:id, '2>/dev/null'], ' '))
43-
let content = substitute(content, '\n\+$', '', '') " skip trailing \n
44-
if a:item == 'docname'
45-
" Create doc reference.
46-
let content = ':doc:`/' . content . '`'
47-
endif
48-
execute 'normal! i' . content
49-
endfunction
50-
51-
function! g:SphinxNotesSnippetListAndInputDocname()
52-
function! s:InputDocname(selection)
53-
call g:SphinxNotesSnippetInput(s:SplitID(a:selection), 'docname')
54-
endfunction
55-
call g:SphinxNotesSnippetList(function('s:InputDocname'), 'd')
38+
call g:SphinxNotesSnippetList('ds', function('ListAndUrl_CB'))
5639
endfunction
5740

5841
nmap <C-k>e :call g:SphinxNotesSnippetListAndEdit()<CR>
5942
nmap <C-k>u :call g:SphinxNotesSnippetListAndUrl()<CR>
60-
nmap <C-k>d :call g:SphinxNotesSnippetListAndInputDocname()<CR>
61-
" FIXME: can't return to insert mode even use a/startinsert!/C-o
62-
imap <C-k>d <C-o>:call g:SphinxNotesSnippetListAndInputDocname()<CR>
43+
nmap <C-k>i :call g:SphinxNotesSnippetListAndInput()<CR>
6344
6445
" vim: set shiftwidth=2:

src/sphinxnotes/snippet/integration/plugin.vim

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,102 @@
88
" NOTE: junegunn/fzf.vim is required
99

1010
let s:snippet = 'snippet'
11+
let s:width = 0.9
12+
let s:height = 0.6
1113

12-
function! s:SplitID(row)
13-
return split(a:row, ' ')[0]
14-
endfunction
15-
16-
" TODO: extra opts
17-
function! g:SphinxNotesSnippetList(callback, tags)
18-
let l:width = 0.9
14+
" Use fzf to list all snippets, callback with argument id.
15+
function g:SphinxNotesSnippetList(tags, callback)
1916
let cmd = [s:snippet, 'list',
2017
\ '--tags', a:tags,
21-
\ '--width', float2nr(&columns * l:width) - 2,
18+
\ '--width', float2nr(&columns * s:width) - 2,
2219
\ ]
20+
21+
" Use closure keyword so that inner function can access outer one's
22+
" localvars (l:) and arguments (a:).
23+
" https://vi.stackexchange.com/a/21807
24+
function! List_CB(selection) closure
25+
let id = split(a:selection, ' ')[0]
26+
call a:callback(id)
27+
endfunction
28+
2329
" https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzfrun
2430
call fzf#run({
2531
\ 'source': join(cmd, ' '),
26-
\ 'sink': a:callback,
32+
\ 'sink': function('List_CB'),
2733
\ 'options': ['--with-nth', '2..', '--no-hscroll', '--header-lines', '1'],
28-
\ 'window': {'width': l:width, 'height': 0.6},
34+
\ 'window': {'width': s:width, 'height': s:height},
2935
\ })
3036
endfunction
3137

32-
" vim: set shiftwidth=2:
38+
" Return the attribute value of specific snippet.
39+
function g:SphinxNotesSnippetGet(id, attr)
40+
let cmd = [s:snippet, 'get', a:id, '--' . a:attr]
41+
return systemlist(join(cmd, ' '))
42+
endfunction
43+
44+
" Use fzf to list all attr of specific snippet,
45+
" callback with arguments (attr_name, attr_value).
46+
function g:SphinxNotesSnippetListSnippetAttrs(id, callback)
47+
" Display attr -> Identify attr (also used as CLI option)
48+
let attrs = {
49+
\ 'Source': 'src',
50+
\ 'URL': 'url',
51+
\ 'Docname': 'docname',
52+
\ 'Dependent files': 'deps',
53+
\ 'Text': 'text',
54+
\ 'Title': 'title',
55+
\ }
56+
let delim = ' '
57+
let table = ['OPTION' . delim . 'ATTRIBUTE']
58+
for name in keys(attrs)
59+
call add(table, attrs[name] . delim . name)
60+
endfor
61+
62+
function! ListSnippetAttrs_CB(selection) closure
63+
let opt = split(a:selection, ' ')[0]
64+
let val = g:SphinxNotesSnippetGet(a:id, opt)
65+
call a:callback(opt, val) " finally call user's cb
66+
endfunction
67+
68+
let preview_cmd = [s:snippet, 'get', a:id, '--$(echo {} | cut -d " " -f1)']
69+
let info_cmd = ['echo', 'Index ID:', a:id]
70+
call fzf#run({
71+
\ 'source': table,
72+
\ 'sink': function('ListSnippetAttrs_CB'),
73+
\ 'options': [
74+
\ '--header-lines', '1',
75+
\ '--with-nth', '2..',
76+
\ '--preview', join(preview_cmd, ' '),
77+
\ '--preview-window', ',wrap',
78+
\ '--info-command', join(info_cmd, ' '),
79+
\ ],
80+
\ 'window': {'width': s:width, 'height': s:height},
81+
\ })
82+
endfunction
83+
84+
function g:SphinxNotesSnippetInput(id)
85+
function! Input_CB(attr, val) " TODO: became g:func.
86+
if a:attr == 'docname'
87+
" Create doc reference.
88+
let content = ':doc:`/' . a:val[0] . '`'
89+
elseif a:attr == 'title'
90+
" Create local section reference.
91+
let content = '`' . a:val[0] . '`_'
92+
else
93+
let content = join(a:val, '<CR>')
94+
endif
95+
execute 'normal! i' . content
96+
endfunction
97+
98+
call g:SphinxNotesSnippetListSnippetAttrs(a:id, function('Input_CB'))
99+
endfunction
100+
101+
function g:SphinxNotesSnippetListAndInput()
102+
function! ListAndInput_CB(id)
103+
call g:SphinxNotesSnippetInput(a:id)
104+
endfunction
105+
106+
call g:SphinxNotesSnippetList('"*"', function('ListAndInput_CB'))
107+
endfunction
108+
109+
" vim: set shiftwidth=2:

0 commit comments

Comments
 (0)