I would like to use search in file with folded functions to search only in functions titles. But common vim search searches inside folding and unfolds any hidden text. Is there a way to search only in open text ignoring the rest?
2 Answers
You could use :folddoopen
to capture the addresses of the lines which are not in open folds, then build a sub-expression describing those lines (see :h \%l
, :h \%>l
, :h \%<l
).
As an example:
cno <c-o> <c-r>=<sid>limit_search_to_open_folds(1)<cr><c-c>
fu s:limit_search_to_open_folds(step) abort
if a:step == 1
let s:pat = getcmdline()
call timer_start(0, {-> s:limit_search_to_open_folds(2)})
else
let s:pat = get(s:, 'pat', '')..'\m\%('
folddoopen let s:pat ..= '\%'..line('.')..'l\|'
let s:pat = substitute(s:pat, '\\|$', '\\)', '')
call feedkeys('/'..s:pat, 'in')
endif
return ''
endfu
Write your pattern, then press C-o
. It should append a sub-expression which limits the search to the lines which are not in closed folds.
If the sub-expression is too long, try this:
cno <c-o> <c-r>=<sid>limit_search_to_open_folds(1)<cr><c-c>
fu s:limit_search_to_open_folds(step) abort
if a:step == 1
let s:cmdline = getcmdline()
call timer_start(0, {-> s:limit_search_to_open_folds(2)})
else
let lnums = []
folddoopen let lnums += [line('.')]
let ranges = []
for i in range(len(lnums))
if i > 0 && lnums[i] == lnums[i-1] + 1
if type(ranges[-1]) == type(0)
let ranges[-1] = [ranges[-1], ranges[-1]+1]
else
let ranges[-1][1] += 1
endif
else
let ranges += [lnums[i]]
endif
endfor
call map(ranges, {_,v -> type(v) == type(0) ? '\%'..v..'l' : '\%>'..(v[0]-1)..'l\%<'..(v[1]+1)..'l'})
let pat = get(s:, 'cmdline', '')
\ ..'\m\%('
\ ..join(ranges, '\|')
\ ..'\)'
call feedkeys('/'..pat, 'in')
endif
return ''
endfu
While this solution is not as powerful as @user938271's one, it is far more simple and I find it sufficient for basic navigation:
:set fdo-=search
Setting this will make your search only find at most one result by fold and prevents unfolding them even when moving to them by cycling through search results with n
/N
, while working normally for unfolded text. This effectively make you find results in unfolded text quickly by being minimally bothered by folded text, and still getting the info of folds that contain the search pattern, secondarily.
:set foldopen-=search
, then Vim will still search within the folds, but at least it won't unfold them.