@@ -692,6 +692,199 @@ function! quickui#context#open(textlist, opts)
692692endfunc
693693
694694
695+ " ----------------------------------------------------------------------
696+ " open the context window and wait for selection
697+ " ----------------------------------------------------------------------
698+ function ! s: context_wait (textlist, opts) abort
699+ let border = get (a: opts , ' border' , g: quickui #style#border)
700+ let ignore_case = get (a: opts , ' ignore_case' , 1 )
701+ let hwnd = quickui#context#compile (a: textlist , border)
702+ let cwnd = quickui#window#new ()
703+ let w = hwnd.width
704+ let h = hwnd.height
705+ let hwnd.index = get (a: opts , ' index' , -1 )
706+ let hwnd.opts = a: opts
707+ let opts = {' w' :w , ' h' :h , ' border' :0 }
708+ if has_key (a: opts , ' x' ) && has_key (a: opts , ' y' )
709+ let opts.x = a: opts .x
710+ let opts.y = a: opts .y
711+ else
712+ let pos = quickui#core#around_cursor (w , h )
713+ let opts.y = pos[0 ] - 1
714+ let opts.x = pos[1 ] - 1
715+ endif
716+ let opts.z = get (a: opts , ' z' , 500 )
717+ let opts.color = get (a: opts , ' color' , ' QuickBG' )
718+ let hwnd.direct = get (a: opts , ' direct' , 0 )
719+ if hwnd.direct == 0
720+ let hwnd.direct = (opts.x <= (&columns / 2 ))? 1 : -1
721+ endif
722+ call cwnd.open (hwnd.image, opts)
723+ call cwnd.show (1 )
724+ let keymap = quickui#utils#keymap ()
725+ let keymap [' J' ] = ' BOTTOM'
726+ let keymap [' K' ] = ' TOP'
727+ let hwnd.code = 0
728+ let hwnd.state = 1
729+ let hwnd.keymap = keymap
730+ let hwnd.hotkey = {}
731+ for item in hwnd.items
732+ if item.enable != 0 && item.key_pos >= 0
733+ let key = ignore_case ? tolower (item.key_char) : item.key_char
734+ if get (a: opts , ' reserve' , 0 ) == 0
735+ let hwnd.hotkey[key ] = item.index
736+ elseif get (g: , ' quickui_protect_hjkl' , 0 ) != 0
737+ let hwnd.hotkey[key ] = item.index
738+ else
739+ if key != ' h' && key != ' j' && key != ' k' && key != ' l'
740+ let hwnd.hotkey[key ] = item.index
741+ endif
742+ endif
743+ endif
744+ endfor
745+ let hwnd.winid = cwnd.winid
746+ let retval = -1
747+ while 1
748+ noautocmd call quickui#context#update (hwnd)
749+ redraw
750+ try
751+ let code = getchar ()
752+ catch /^Vim:Interrupt$/
753+ let code = " \<C-C> "
754+ endtry
755+ let ch = (type (code) == v: t_number )? nr2char (code) : code
756+ if ch == " \<ESC> " || ch == " \<c-c> "
757+ break
758+ elseif ch == " " || ch == " \<cr> "
759+ let index = hwnd.index
760+ if index >= 0 && index < len (hwnd.items )
761+ let item = hwnd.items [index ]
762+ if item.is_sep == 0 && item.enable != 0
763+ let retval = index
764+ break
765+ endif
766+ endif
767+ elseif ch == " \<LeftMouse> "
768+ let pos = cwnd.mouse_click ()
769+ if pos.x < 0
770+ break
771+ else
772+ let x1 = (hwnd.border == 0 )? 0 : 1
773+ let x2 = (hwnd.border == 0 )? w : (w - 1 )
774+ let ii = (hwnd.border == 0 )? pos.y : (pos.y - 1 )
775+ if pos.x >= x1 && pos.x < x2
776+ if ii >= 0 && ii < len (hwnd.items )
777+ let item = hwnd.items [ii]
778+ if item.is_sep == 0 && item.enable != 0
779+ let hwnd.index = ii
780+ let retval = ii
781+ noautocmd call quickui#context#update (hwnd)
782+ redraw
783+ break
784+ endif
785+ endif
786+ endif
787+ endif
788+ elseif has_key (hwnd.hotkey, ch )
789+ let hr = hwnd.hotkey[ch ]
790+ if hr >= 0
791+ let hwnd.index = hr
792+ let retval = hr
793+ break
794+ endif
795+ elseif has_key (hwnd.keymap , ch )
796+ let key = hwnd.keymap [ch ]
797+ if key == ' ESC'
798+ break
799+ elseif key == ' UP'
800+ let hwnd.index = s: cursor_move (hwnd, hwnd.index , -1 )
801+ elseif key == ' DOWN'
802+ let hwnd.index = s: cursor_move (hwnd, hwnd.index , 1 )
803+ elseif key == ' TOP'
804+ let hwnd.index = s: cursor_move (hwnd, hwnd.index , ' TOP' )
805+ elseif key == ' BOTTOM'
806+ let hwnd.index = s: cursor_move (hwnd, hwnd.index , ' BOTTOM' )
807+ endif
808+ endif
809+ endwhile
810+ noautocmd call quickui#context#update (hwnd)
811+ let hr = ' '
812+ if retval >= 0 && retval < len (hwnd.items )
813+ let item = hwnd.items [retval]
814+ if item.is_sep == 0 && item.enable != 0
815+ let hwnd.index = retval
816+ if ! has_key (item, ' child' )
817+ let hr = item.cmd
818+ else
819+ let child = item.child
820+ let cc = quickui#context#compile (child, border)
821+ let cw = cc .width
822+ let ch = cc .height
823+ unlet cc
824+ let op = {}
825+ let op .z = opts.z + 1
826+ let op .y = opts.y + retval
827+ let op .y = (op .y + ch > &lines )? (&lines - ch ) : op .y
828+ let op .y = (op .y < 0 )? 0 : op .y
829+ for i in range (5 )
830+ if hwnd.direct >= 0
831+ let tx = opts.x + opts.w
832+ if tx + cw > &columns
833+ let hwnd.direct = -1
834+ else
835+ let op .x = tx
836+ break
837+ endif
838+ elseif hwnd.direct < 0
839+ let tx = opts.x - cw
840+ if tx < 0
841+ let hwnd.direct = 1
842+ else
843+ let op .x = tx
844+ break
845+ endif
846+ endif
847+ endfor
848+ if ! has_key (op , ' x' )
849+ let op .x = 1
850+ endif
851+ let op .direct = hwnd.direct
852+ let op .border = get (a: opts , ' border' , border)
853+ let hr = s: context_wait (child, op )
854+ endif
855+ endif
856+ endif
857+ let g: quickui #context#cursor = hwnd.index
858+ let g: quickui #context#current = hwnd
859+ call cwnd.close ()
860+ unlet cwnd
861+ return hr
862+ endfunc
863+
864+
865+ " ----------------------------------------------------------------------
866+ " open the context window and wait for selection
867+ " ----------------------------------------------------------------------
868+ function ! quickui#context#wait (textlist, opts) abort
869+ return s: context_wait (a: textlist , a: opts )
870+ endfunc
871+
872+
873+ " ----------------------------------------------------------------------
874+ " open context menu and execute commands
875+ " ----------------------------------------------------------------------
876+ function ! quickui#context#open_nested (textlist, opts) abort
877+ let cmd = s: context_wait (a: textlist , a: opts )
878+ if has_key (a: opts , ' callback' )
879+ call a: opts .callback (0 )
880+ endif
881+ if cmd != ' '
882+ exec cmd
883+ endif
884+ endfunc
885+
886+
887+
695888" ----------------------------------------------------------------------
696889" testing suit
697890" ----------------------------------------------------------------------
0 commit comments