Skip to content

Commit

Permalink
feat(integration): General vim input helper (#38)
Browse files Browse the repository at this point in the history
* feat(integration): General vim input helper

* refactor(integration): Refactor vim plugin
  • Loading branch information
SilverRainZ authored Oct 27, 2024
1 parent deef7e4 commit d6db43f
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 47 deletions.
6 changes: 3 additions & 3 deletions src/sphinxnotes/snippet/integration/binding.nvim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
47 changes: 14 additions & 33 deletions src/sphinxnotes/snippet/integration/binding.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <C-k>e :call g:SphinxNotesSnippetListAndEdit()<CR>
nmap <C-k>u :call g:SphinxNotesSnippetListAndUrl()<CR>
nmap <C-k>d :call g:SphinxNotesSnippetListAndInputDocname()<CR>
" FIXME: can't return to insert mode even use a/startinsert!/C-o
imap <C-k>d <C-o>:call g:SphinxNotesSnippetListAndInputDocname()<CR>
nmap <C-k>i :call g:SphinxNotesSnippetListAndInput()<CR>
" vim: set shiftwidth=2:
99 changes: 88 additions & 11 deletions src/sphinxnotes/snippet/integration/plugin.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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, '<CR>')
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:

0 comments on commit d6db43f

Please sign in to comment.