Vim Tips Wiki
Register
(Move categories to tip template)
(Replace tip using fdo/folddoopen suggestions from comment and newsgroup)
Line 3: Line 3:
 
|previous=388
 
|previous=388
 
|next=390
 
|next=390
|created=December 17, 2002
+
|created=2002
 
|complexity=basic
 
|complexity=basic
|author=Demai Ni
+
|author=
 
|version=6.0
 
|version=6.0
 
|rating=0/0
 
|rating=0/0
|category1=Searching
+
|category1=Folding
|category2=
+
|category2=Searching
 
}}
 
}}
  +
Folds are useful to temporarily hide text that you don't currently need to see. By default, when you search for text, each fold containing a search hit automatically opens when you find the hit. This behavior is controlled with the <tt>'foldopen'</tt> option (abbreviated to <tt>'fdo'</tt>).
{{Deprecated|the folddoopen and folddoclosed commands accomplish this}}
 
If you like to [[Use folds in your program|use folds]], or if you are viewing a diff between two files, much of the file contents may be folded away. You probably don't care much about what is inside the folds, but a simple search or substitute will act upon text inside them anyway.
 
   
  +
To search only in open folds (unfolded text):
The following function allows you to search and replace only within unfolded content. Use it to fold away all functions except the one you're working on and act only upon the one you're working on, fold away unchanged content in a diff and act on the new content, etc.
 
  +
<pre>
  +
:set fdo-=search
  +
</pre>
   
  +
With the above, a search shows one hit per fold that contains the search target. The fold is not opened, and is only found once, even if it contains several instances of the search target.
  +
  +
You can also perform commands only on lines in open folds. For example, the following command will change every 'old' to 'new', but only in lines that are not folded:
 
<pre>
 
<pre>
  +
:folddoopen s/old/new/ge
function! Foldrepl(spattern, tpattern)
 
"go to top of the file
 
normal! gg
 
let diffopt_sav = &diffopt
 
"need to change fold option for diff
 
if &diff
 
exec "set diffopt+=context:0"
 
endif
 
let mycount =0
 
"find the search pattern
 
while search(a:spattern, "W") > 0
 
"search pattern found, check if the line is folded
 
if foldclosed(line(".")) < 0
 
"line is not folded, execute replace
 
exec "s/".a:spattern."/".a:tpattern."/g"
 
let mycount = mycount + 1
 
endif
 
endwhile
 
"need to restore fold option
 
if &diff
 
let &diffopt = diffopt_sav
 
endif
 
echo mycount "lines are changed"
 
endfunction
 
 
</pre>
 
</pre>
  +
  +
With <tt>:folddoopen</tt>, each unfolded line is marked. Then the command (<tt>s/old/new/ge</tt>) is executed on each marked line. Therefore the <tt>s///</tt> command has no range (it operates on the current line), and it has the <tt>e</tt> flag so no error is shown if a line does not contain 'old'.
   
 
==References==
 
==References==
*{{help|foldclosed()}}
+
*{{help|folding}}
*{{help|search()}}
+
*{{help|'foldopen'}}
  +
*{{help|:folddoopen}}
  +
*{{help|:folddoclosed}}
   
 
==Comments==
 
==Comments==
  +
I'm seeing some weird messages from Vim 7.2 when using the above to s/old/new/ in text with several closed folds. The command works, but it shows a spurious "x substitutions on n lines" message (x and n are too big). Any thoughts? --[[User:JohnBeckett|JohnBeckett]] 00:05, 14 October 2008 (UTC)
{{todo}}
 
  +
Use built-in commands for this tip: {{help|:folddoopen}} {{help|:folddoclosed}}
 
 
----
 
----

Revision as of 00:05, 14 October 2008

Tip 389 Printable Monobook Previous Next

created 2002 · complexity basic · version 6.0


Folds are useful to temporarily hide text that you don't currently need to see. By default, when you search for text, each fold containing a search hit automatically opens when you find the hit. This behavior is controlled with the 'foldopen' option (abbreviated to 'fdo').

To search only in open folds (unfolded text):

:set fdo-=search

With the above, a search shows one hit per fold that contains the search target. The fold is not opened, and is only found once, even if it contains several instances of the search target.

You can also perform commands only on lines in open folds. For example, the following command will change every 'old' to 'new', but only in lines that are not folded:

:folddoopen s/old/new/ge

With :folddoopen, each unfolded line is marked. Then the command (s/old/new/ge) is executed on each marked line. Therefore the s/// command has no range (it operates on the current line), and it has the e flag so no error is shown if a line does not contain 'old'.

References

Comments

I'm seeing some weird messages from Vim 7.2 when using the above to s/old/new/ in text with several closed folds. The command works, but it shows a spurious "x substitutions on n lines" message (x and n are too big). Any thoughts? --JohnBeckett 00:05, 14 October 2008 (UTC)