Create a messagebox-like interface in vim
This commit is contained in:
parent
810946a1c1
commit
4fbafaa462
4 changed files with 87 additions and 16 deletions
|
|
@ -72,11 +72,7 @@ function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
|
|||
\ 'mapping': 0
|
||||
\ }
|
||||
|
||||
" When ambiwidth is single, use prettier characters for the border. This
|
||||
" would look silly when ambiwidth is double.
|
||||
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
|
||||
let config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
|
||||
endif
|
||||
let config = vimspector#internal#popup#SetBorderChars( config )
|
||||
|
||||
if a:is_hover
|
||||
let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter'
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ endfunction
|
|||
function! vimspector#internal#neopopup#Confirm( confirm_id,
|
||||
\ text,
|
||||
\ default_value ) abort
|
||||
|
||||
" Neovim doesn't have an equivalent of popup_dialog, and it's way too much
|
||||
" effort to write one, so we just use confirm().
|
||||
let result = confirm( a:text, '&Yes &No &Default', 3 )
|
||||
|
||||
" Map the results to what popup_menu_filter would return (ok s:ConfirmCallback
|
||||
|
|
|
|||
|
|
@ -32,9 +32,32 @@ function! vimspector#internal#popup#HideSplash( id ) abort
|
|||
call popup_hide( a:id )
|
||||
endfunction
|
||||
|
||||
let s:current_selection = 0
|
||||
let s:selections = []
|
||||
let s:text = []
|
||||
|
||||
function! s:UpdatePopup( id )
|
||||
let buf = copy( s:text )
|
||||
call extend( buf, s:DrawButtons() )
|
||||
call popup_settext( a:id, buf )
|
||||
endfunction
|
||||
|
||||
function! s:YesNoDefaultFilter( default_value, id, key ) abort
|
||||
if a:key ==# "\<CR>" || a:key ==# 'D' || a:key ==# 'd'
|
||||
if a:key ==# "\<CR>"
|
||||
call popup_close( a:id, s:current_selection + 1 )
|
||||
return 1
|
||||
elseif a:key ==# 'D' || a:key ==# 'd'
|
||||
call popup_close( a:id, a:default_value )
|
||||
return 1
|
||||
elseif index( [ "\<Tab>", "\<Right>" ], a:key ) >= 0
|
||||
let s:current_selection = ( s:current_selection + 1 ) % len( s:selections )
|
||||
call s:UpdatePopup( a:id )
|
||||
return 1
|
||||
elseif index( [ "\<S-Tab>", "\<Left>" ], a:key ) >= 0
|
||||
let s:current_selection = s:current_selection == 0
|
||||
\ ? len( s:selections ) - 1: s:current_selection - 1
|
||||
call s:UpdatePopup( a:id )
|
||||
return 1
|
||||
endif
|
||||
|
||||
return popup_filter_yesno( a:id, a:key )
|
||||
|
|
@ -46,23 +69,68 @@ function! s:ConfirmCallback( confirm_id, id, result ) abort
|
|||
\ int( vim.eval( 'a:result' ) ) )
|
||||
endfunction
|
||||
|
||||
function! s:SelectionPosition( idx ) abort
|
||||
return a:idx == 0 ? 0 : len( join( s:selections[ : a:idx - 1 ], ' ' ) ) + 1
|
||||
endfunction
|
||||
|
||||
function! s:DrawButtons() abort
|
||||
return [ {
|
||||
\ 'text': join( s:selections, ' ' ),
|
||||
\ 'props': [
|
||||
\ {
|
||||
\ 'col': s:SelectionPosition( s:current_selection ) + 1,
|
||||
\ 'length': len( s:selections[ s:current_selection ] ),
|
||||
\ 'type': 'VimspectorSelectedItem'
|
||||
\ },
|
||||
\ ]
|
||||
\ } ]
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#popup#Confirm(
|
||||
\ confirm_id,
|
||||
\ text,
|
||||
\ options,
|
||||
\ default_value ) abort
|
||||
let text = a:text
|
||||
if type( a:text ) != v:t_list
|
||||
let text = [ a:text ]
|
||||
|
||||
silent! call prop_type_add( 'VimspectorSelectedItem', {
|
||||
\ 'highlight': 'PMenuSel'
|
||||
\ } )
|
||||
|
||||
let lines = split( a:text, "\n", v:true )
|
||||
let buf = []
|
||||
for line in lines
|
||||
call add( buf, { 'text': line, 'props': [] } )
|
||||
endfor
|
||||
|
||||
call add( buf, { 'text': '', 'props': [] } )
|
||||
|
||||
let s:selections = a:options
|
||||
let s:current_selection = ( a:default_value - 1 )
|
||||
|
||||
let s:text = copy( buf )
|
||||
call extend( buf, s:DrawButtons() )
|
||||
|
||||
let config = {
|
||||
\ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ),
|
||||
\ 'filter': function( 's:YesNoDefaultFilter', [ a:default_value ] ),
|
||||
\ 'mapping': v:false,
|
||||
\ }
|
||||
let config = vimspector#internal#popup#SetBorderChars( config )
|
||||
|
||||
return popup_dialog( buf, config )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#popup#SetBorderChars( config )
|
||||
" When ambiwidth is single, use prettier characters for the border. This
|
||||
" would look silly when ambiwidth is double.
|
||||
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
|
||||
let a:config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
|
||||
endif
|
||||
|
||||
call extend( text, [ '', '(Y)es (N)o (D)efault' ] )
|
||||
|
||||
return popup_dialog( text, {
|
||||
\ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ),
|
||||
\ 'filter': function( 's:YesNoDefaultFilter', [ a:default_value ] )
|
||||
\ } )
|
||||
return a:config
|
||||
endfunction
|
||||
|
||||
|
||||
" Boilerplate {{{
|
||||
let &cpoptions=s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
|
|
|||
|
|
@ -390,13 +390,17 @@ def ConfirmCallback( confirm_id, result ):
|
|||
handler( result )
|
||||
|
||||
|
||||
def Confirm( api_prefix, prompt, handler, default_value = 1 ):
|
||||
def Confirm( api_prefix, prompt, handler, default_value = 3, options = None ):
|
||||
global CONFIRM_ID
|
||||
if not options:
|
||||
options = [ '(Y)es', '(N)o', '(D)efault' ]
|
||||
|
||||
CONFIRM_ID += 1
|
||||
CONFIRM[ CONFIRM_ID ] = handler
|
||||
Call( f'vimspector#internal#{ api_prefix }popup#Confirm',
|
||||
CONFIRM_ID,
|
||||
prompt,
|
||||
options,
|
||||
default_value )
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue