diff options
| author | nsfisis <nsfisis@gmail.com> | 2021-11-13 22:28:44 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2021-11-13 23:02:07 +0900 |
| commit | afe70ab33d918165afa92da2557968e2a27d9a4f (patch) | |
| tree | b66853b432f7c381ba1135d29bfedbcb8dc27998 | |
| parent | 95529f0684458af774b75afa1b3b565248be6b6d (diff) | |
| download | dotfiles-afe70ab33d918165afa92da2557968e2a27d9a4f.tar.gz dotfiles-afe70ab33d918165afa92da2557968e2a27d9a4f.tar.zst dotfiles-afe70ab33d918165afa92da2557968e2a27d9a4f.zip | |
vim: add new keybinding "tg" to interactively choose windows by using popupwin
| -rw-r--r-- | .vimrc | 104 |
1 files changed, 104 insertions, 0 deletions
@@ -872,6 +872,92 @@ function! s:bdelete_bang_with_confirm() abort endfunction +let g:choose_window_indicators = [ + \ 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', + \ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + \ ] + + +function! s:choose_window_filter(popups, winid, key) abort + let jump_target = -1 + for popup in a:popups + if a:key ==? popup.indicator + let jump_target = popup.target_winid + endif + endfor + if jump_target !=# -1 + call win_gotoid(jump_target) + endif + + call popup_close(a:winid) + return v:true +endfunction + + +function s:choose_window_close_popups(popups, winid, result) abort + for popup in a:popups + call popup_close(popup.winid) + endfor +endfunction + + +function! s:choose_window_interactively() abort + " List normal windows up to 20. + let wins = [] + for winnr in range(1, winnr('$')) + if winnr !=# winnr() && win_gettype(winnr) ==# '' + call add(wins, win_getid(winnr)) + endif + endfor + if len(g:choose_window_indicators) < len(wins) + unlet wins[len(g:choose_window_indicators):] + endif + + if len(wins) ==# 0 + return + endif + if len(wins) ==# 1 + if wins[0] ==# win_getid() + call win_gotoid(wins[1]) + else + call win_gotoid(wins[0]) + endif + return + endif + + " Show popups. + let popups = [] + for i in range(len(wins)) + let winid = wins[i] + let indicator = g:choose_window_indicators[i] + let [winy, winx, winh, winw] = s:win_getrect(winid) + let popup = popup_create(indicator, #{ + \ line: winy + (winh - 5) / 2, + \ col: winx + (winw - 9) / 2, + \ drag: v:false, + \ resize: v:false, + \ padding: [1, 3, 1, 3], + \ border: [], + \ }) + call add(popups, #{ + \ winid: popup, + \ indicator: indicator, + \ target_winid: winid, + \ }) + endfor + + " Show dialog. + let [winy, winx, winh, winw] = s:win_getrect(0) + let popup = popup_dialog('Select window', #{ + \ pos: 'topleft', + \ line: winy + (winh - 3) / 2, + \ col: winx + (winw - len('Select window') - 4) / 2, + \ filter: function(s:SNR .. 'choose_window_filter', [popups]), + \ callback: function(s:SNR .. 'choose_window_close_popups', [popups]), + \ }) +endfunction + + nnoremap <silent> tt :<C-u>tabnew<CR> nnoremap <silent> tT :<C-u>call <SID>move_current_window_to_tabpage()<CR> @@ -929,6 +1015,10 @@ nnoremap tc <C-w>c nnoremap to <C-w>o nnoremap <silent> tO :<C-u>tabonly<CR> +if has('popupwin') + nnoremap <silent> tg :<C-u>call <SID>choose_window_interactively()<CR> +endif + function! s:smart_open(command) abort @@ -1024,6 +1114,8 @@ nnoremap <silent> XF :<C-u>function {<C-r>=v:count<CR>}<CR> nnoremap <silent> XM :<C-u>messages<CR> +nnoremap <silent> XP :<C-u>call popup_clear(1)<CR> + @@ -1785,6 +1877,18 @@ endfunction +"" Wrapper of |win_screenpos()|, |winheight()| and |winwidth()|. +"" Returns quadruple consisting of y, x, width and height. +function! s:win_getrect(...) abort + let win = get(a:000, 0, 0) + let [y, x] = win_screenpos(win) + let h = winheight(win) + let w = winwidth(win) + return [y, x, h, w] +endfunction + + + " They are not used any longer. {{{2 if 0 |
