Skip to content

Commit

Permalink
Support floating_win based action menu (#655)
Browse files Browse the repository at this point in the history
* Support floating_win based action menu

Close #478

* .

* Fix vint

* Commit ftplugin/clap_action.vim

* .

* Force the cursor move in action window

* .

* Update CHANGELOG.md
  • Loading branch information
liuchengxu committed Mar 7, 2021
1 parent 995b814 commit c50ad95
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [unreleased]

### Added

- Support neovim floating_win based action menu. #655

### Improved

- Truncate the lines of `grep` provider. #650
Expand Down
3 changes: 2 additions & 1 deletion autoload/clap/action.vim
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set cpoptions&vim

let s:ACTIONS_TITLE_KEY = 'title'

" `confirm()` based action menu, this is deprecated now.
function! s:invoke_action() abort
let provider_action = g:clap.provider._().action
if has_key(provider_action, s:ACTIONS_TITLE_KEY)
Expand Down Expand Up @@ -34,7 +35,7 @@ function! clap#action#invoke() abort
return ''
endif
if has('nvim')
call s:invoke_action()
call clap#floating_win#action#create()
else
call clap#popup#action#invoke()
endif
Expand Down
90 changes: 90 additions & 0 deletions autoload/clap/floating_win/action.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
" Author: liuchengxu <xuliuchengxlc@gmail.com>
" Description: Action dialog based on floating win.
scriptencoding utf-8

let s:save_cpo = &cpoptions
set cpoptions&vim

function! clap#floating_win#action#create() abort
let buf = nvim_create_buf(v:false, v:true)

let provider_action = g:clap.provider._().action
if has_key(provider_action, 'title')
let title = provider_action['title']()
else
let title = 'Choose action:'
endif
let choices = filter(keys(provider_action), 'v:val !~# "title"')
let lines = []

let s:lnum2key = {}
let idx = 2
let max_line_len = 0
for choice in choices
let s:lnum2key[idx] = choice
let str = substitute(choice, '&', '', '')
let line = join(split(str, '\ze\u'), ' ')
if strlen(line) > max_line_len
let max_line_len = strlen(line)
endif
call add(lines, line)
let idx += 1
endfor

let choices = map(lines, '" [". (str2nr(v:key) + 1)."] ".v:val')

let lines = [title] + choices
call nvim_buf_set_lines(buf, 0, -1, v:true, lines)

call setbufvar(buf, '&filetype', 'clap_action')

let opts = nvim_win_get_config(g:clap.display.winid)
let opts.row += opts.height / 3
let opts.col += opts.width / 5
let opts.style = 'minimal'
let opts.relative = 'editor'
let opts.height = len(lines)
let opts.width = max([opts.width * 3 / 5, max_line_len + 5])
silent let s:action_winid = nvim_open_win(buf, v:true, opts)

call cursor(2, 6)

let w:action_header_id = matchaddpos('Title', [1])
endfunction

function! clap#floating_win#action#close() abort
call clap#util#nvim_win_close_safe(s:action_winid)
noautocmd call win_gotoid(g:clap.input.winid)
endfunction

function! clap#floating_win#action#apply_choice() abort
if has_key(s:lnum2key, line('.'))
let provider_action = g:clap.provider._().action
let action_key = s:lnum2key[line('.')]
call clap#util#nvim_win_close_safe(s:action_winid)
" TODO: add `action*` for performing actions against multi-selected entries?
call clap#floating_win#action#close()
call provider_action[action_key]()
else
call clap#helper#echo_error('Invalid action choice: '.getline('.'))
endif
endfunction

function! clap#floating_win#action#next_item() abort
if line('.') == line('$')
noautocmd call cursor(2, 6)
else
noautocmd call cursor(line('.') + 1, 6)
endif
endfunction

function! clap#floating_win#action#prev_item() abort
if line('.') == 2
noautocmd call cursor(line('$'), 6)
else
noautocmd call cursor(line('.') - 1, 6)
endif
endfunction

let &cpoptions = s:save_cpo
unlet s:save_cpo
5 changes: 5 additions & 0 deletions ftplugin/clap_action.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
nnoremap <silent> <buffer> <CR> :<c-u>call clap#floating_win#action#apply_choice()<CR>
nnoremap <silent> <buffer> <Esc> :<c-u>call clap#floating_win#action#close()<CR>
nnoremap <silent> <buffer> q :<c-u>call clap#floating_win#action#close()<CR>
nnoremap <silent> <buffer> j :<c-u>call clap#floating_win#action#next_item()<CR>
nnoremap <silent> <buffer> k :<c-u>call clap#floating_win#action#prev_item()<CR>

0 comments on commit c50ad95

Please sign in to comment.