mirror of
https://github.com/inkarkat/vim-ingo-library.git
synced 2026-05-29 11:18:51 +02:00
174 lines
6.7 KiB
VimL
174 lines
6.7 KiB
VimL
" ingo/window/locate.vim: Functions to locate a window.
|
|
"
|
|
" DEPENDENCIES:
|
|
" - ingo/actions.vim autoload script
|
|
"
|
|
" Copyright: (C) 2016 Ingo Karkat
|
|
" The VIM LICENSE applies to this script; see ':help copyright'.
|
|
"
|
|
" Maintainer: Ingo Karkat <ingo@karkat.de>
|
|
"
|
|
" REVISION DATE REMARKS
|
|
" 1.028.001 25-Nov-2016 file creation
|
|
|
|
function! s:Match( winVarName, Predicate, winNr, ... )
|
|
if a:0 >= 2 && a:winNr == a:2
|
|
return 0
|
|
endif
|
|
let l:tabNr = (a:0 ? a:1 : tabpagenr())
|
|
|
|
let l:value = gettabwinvar(l:tabNr, a:winNr, a:winVarName)
|
|
return !! ingo#actions#EvaluateWithValOrFunc(a:Predicate, l:value)
|
|
endfunction
|
|
|
|
function! s:CheckTabPageNearest( tabNr, winVarName, Predicate, ... )
|
|
let l:skipWinNr = (a:0 ? a:1 : 0)
|
|
let [l:currentWinNr, l:previousWinNr, l:lastWinNr] = [tabpagewinnr(a:tabNr), tabpagewinnr(a:tabNr, '#'), tabpagewinnr(a:tabNr, '$')]
|
|
if s:Match(a:winVarName, a:Predicate, l:currentWinNr, a:tabNr, l:skipWinNr)
|
|
return [a:tabNr, l:currentWinNr]
|
|
elseif s:Match(a:winVarName, a:Predicate, l:previousWinNr, a:tabNr, l:skipWinNr)
|
|
return [a:tabNr, l:previousWinNr]
|
|
endif
|
|
|
|
let l:offset = 1
|
|
while l:currentWinNr - l:offset > 0 || l:currentWinNr + l:offset <= l:lastWinNr
|
|
if s:Match(a:winVarName, a:Predicate, l:currentWinNr - l:offset, a:tabNr, l:skipWinNr)
|
|
return [a:tabNr, l:currentWinNr - l:offset]
|
|
elseif s:Match(a:winVarName, a:Predicate, l:currentWinNr + l:offset, a:tabNr, l:skipWinNr)
|
|
return [a:tabNr, l:currentWinNr + l:offset]
|
|
endif
|
|
let l:offset += 1
|
|
endwhile
|
|
return [0, 0]
|
|
endfunction
|
|
|
|
function! ingo#window#locate#NearestByPredicate( isSearchOtherTabPages, winVarName, Predicate )
|
|
"******************************************************************************
|
|
"* PURPOSE:
|
|
" Locate the window closest to the current one where the window variable a:winVarName makes
|
|
" a:Predicate (passed in as argument or v:val) true.
|
|
"* ASSUMPTIONS / PRECONDITIONS:
|
|
" None.
|
|
"* EFFECTS / POSTCONDITIONS:
|
|
" None.
|
|
"* INPUTS:
|
|
" a:isSearchOtherTabPages Flag whether windows in other tab pages should also
|
|
" be considered.
|
|
" a:winVarName Name of the window-local variable, like in
|
|
" |gettabwinvar()|
|
|
" a:Predicate Either a Funcref or an expression to be eval()ed.
|
|
" Gets the value of a:winVarName passed, should return
|
|
" a boolean value.
|
|
"* RETURN VALUES:
|
|
" [tabpagenr, winnr] if a:isSearchOtherTabPages and the found window is on a
|
|
" different tab page
|
|
" [0, winnr] if the window is on the current tab page
|
|
" [0, 0] if a:Predicate did not yield true in any other window
|
|
"******************************************************************************
|
|
let l:lastWinNr = winnr('#')
|
|
if l:lastWinNr != 0 && s:Match(a:winVarName, a:Predicate, l:lastWinNr)
|
|
return [tabpagenr(), l:lastWinNr]
|
|
endif
|
|
|
|
let l:result = s:CheckTabPageNearest(tabpagenr(), a:winVarName, a:Predicate, winnr())
|
|
if l:result != [0, 0] || ! a:isSearchOtherTabPages
|
|
return l:result
|
|
endif
|
|
|
|
|
|
let [l:currentTabPageNr, l:lastTabPageNr] = [tabpagenr(), tabpagenr('$')]
|
|
let l:offset = 1
|
|
while l:currentTabPageNr - l:offset > 0 || l:currentTabPageNr + l:offset <= l:lastTabPageNr
|
|
let l:result = s:CheckTabPageNearest(l:currentTabPageNr - l:offset, a:winVarName, a:Predicate)
|
|
if l:result != [0, 0] | return l:result | endif
|
|
|
|
let l:result = s:CheckTabPageNearest(l:currentTabPageNr + l:offset, a:winVarName, a:Predicate)
|
|
if l:result != [0, 0] | return l:result | endif
|
|
|
|
let l:offset += 1
|
|
endwhile
|
|
|
|
return [0, 0]
|
|
endfunction
|
|
|
|
function! ingo#window#locate#FirstByPredicate( isSearchOtherTabPages, winVarName, Predicate )
|
|
"******************************************************************************
|
|
"* PURPOSE:
|
|
" Locate the first window (in this tab page, or with a:isSearchOtherTabPages
|
|
" in other tabs) where the window variable a:winVarName makes a:Predicate
|
|
" (passed in as argument or v:val) true.
|
|
"* ASSUMPTIONS / PRECONDITIONS:
|
|
" None.
|
|
"* EFFECTS / POSTCONDITIONS:
|
|
" None.
|
|
"* INPUTS:
|
|
" a:isSearchOtherTabPages Flag whether windows in other tab pages should also
|
|
" be considered.
|
|
" a:winVarName Name of the window-local variable, like in
|
|
" |gettabwinvar()|
|
|
" a:Predicate Either a Funcref or an expression to be eval()ed.
|
|
" Gets the value of a:winVarName passed, should return
|
|
" a boolean value.
|
|
"* RETURN VALUES:
|
|
" [tabpagenr, winnr] if a:isSearchOtherTabPages and the found window is on a
|
|
" different tab page
|
|
" [0, winnr] if the window is on the current tab page
|
|
" [0, 0] if a:Predicate did not yield true in any other window
|
|
"******************************************************************************
|
|
for l:winNr in range(1, winnr('$'))
|
|
if s:Match(a:winVarName, a:Predicate, l:winNr)
|
|
return [0, l:winNr]
|
|
endif
|
|
endfor
|
|
if ! a:isSearchOtherTabPages
|
|
return [0, 0]
|
|
endif
|
|
|
|
for l:tabPageNr in filter(range(1, tabpagenr('$')), 'v:val != ' . tabpagenr())
|
|
let l:lastWinNr = tabpagewinnr(l:tabPageNr, '$')
|
|
for l:winNr in range(1, l:lastWinNr)
|
|
if s:Match(a:winVarName, a:Predicate, l:winNr, l:tabPageNr)
|
|
return [l:tabPageNr, l:winNr]
|
|
endif
|
|
endfor
|
|
endfor
|
|
|
|
return [0, 0]
|
|
endfunction
|
|
|
|
function! ingo#window#locate#ByPredicate( strategy, isSearchOtherTabPages, winVarName, Predicate )
|
|
"******************************************************************************
|
|
"* PURPOSE:
|
|
" Locate a window (in this tab page, or with a:isSearchOtherTabPages in other
|
|
" tabs), with a:strategy to determine precedences, where the window variable
|
|
" a:winVarName makes a:Predicate (passed in as argument or v:val) true.
|
|
"* ASSUMPTIONS / PRECONDITIONS:
|
|
" None.
|
|
"* EFFECTS / POSTCONDITIONS:
|
|
" None.
|
|
"* INPUTS:
|
|
" a:strategy One of "first" or "nearest".
|
|
" a:isSearchOtherTabPages Flag whether windows in other tab pages should also
|
|
" be considered.
|
|
" a:winVarName Name of the window-local variable, like in
|
|
" |gettabwinvar()|
|
|
" a:Predicate Either a Funcref or an expression to be eval()ed.
|
|
" Gets the value of a:winVarName passed, should return
|
|
" a boolean value.
|
|
"* RETURN VALUES:
|
|
" [tabpagenr, winnr] if a:isSearchOtherTabPages and the found window is on a
|
|
" different tab page
|
|
" [0, winnr] if the window is on the current tab page
|
|
" [0, 0] if a:Predicate did not yield true in any other window
|
|
"******************************************************************************
|
|
if a:strategy ==# 'first'
|
|
return ingo#window#locate#FirstByPredicate(a:isSearchOtherTabPages, a:winVarName, a:Predicate)
|
|
elseif a:strategy ==# 'nearest'
|
|
return ingo#window#locate#NearestByPredicate(a:isSearchOtherTabPages, a:winVarName, a:Predicate)
|
|
else
|
|
throw 'ASSERT: Unknown strategy ' . string(a:strategy)
|
|
endif
|
|
endfunction
|
|
|
|
" vism: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
|