aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2021-11-13 22:28:44 +0900
committernsfisis <nsfisis@gmail.com>2021-11-13 23:02:07 +0900
commitafe70ab33d918165afa92da2557968e2a27d9a4f (patch)
treeb66853b432f7c381ba1135d29bfedbcb8dc27998
parent95529f0684458af774b75afa1b3b565248be6b6d (diff)
downloaddotfiles-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--.vimrc104
1 files changed, 104 insertions, 0 deletions
diff --git a/.vimrc b/.vimrc
index 815fcff..86f7d4b 100644
--- a/.vimrc
+++ b/.vimrc
@@ -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