Vim Tips Wiki
(Move categories to tip template)
(Fix bug from old editing that put the map in one line; tweak)
Line 11: Line 11:
 
|category2=Searching
 
|category2=Searching
 
}}
 
}}
When searching with /, it would sometimes be nice to fold everything except for matches to your search. The following code does this, providing 2 levels of folding to allow you to show some context around each search match as well.
+
When searching with <tt>/</tt>, it would sometimes be nice to fold everything except for matches to your search. The following code does this, providing two levels of folding to allow you to show some context around each search match as well.
   
 
===Using a '/' search and key mapping===
 
===Using a '/' search and key mapping===
Add the following to a vimrc file to provide a mapping to fold on an already-performed search:
+
Add the following to your [[vimrc]] to provide a mapping to fold on an already-performed search:
   
 
<pre>
 
<pre>
map \z :setlocal foldexpr=(getline(v:lnum)=~@/)?0:(getline(v:lnum-1)=~@/)\|\|(getline(v:lnum+1)=~@/)?1:2 foldmethod=expr foldlevel=0 foldcolumn=2&lt;CR&gt;
+
nnoremap \z :setlocal foldexpr=(getline(v:lnum)=~@/)?0:(getline(v:lnum-1)=~@/)\\|\\|(getline(v:lnum+1)=~@/)?1:2 foldmethod=expr foldlevel=0 foldcolumn=2<CR>
 
</pre>
 
</pre>
   
*The first line is an extension of <pre>foldexpr=(getline(v:lnum)=~@/)?0:1</pre>
+
*The <tt>foldexpr</tt> is an extension of <tt>foldexpr=(getline(v:lnum)=~@/)?0:1</tt>
*The second line (re)sets the foldmethod to expr(ession) plus.
+
*The following options set the <tt>foldmethod</tt> to use the fold expression, and some other convenient values.
   
First search for /regexp/, then fold everything else with \z
+
First search for a pattern, then fold everything else with <tt>\z</tt><br />
Use zr to display more context, use zm to display less context.
+
Use <tt>zr</tt> to display more context, or <tt>zm</tt> to display less context.
   
 
===Using a user-defined command===
 
===Using a user-defined command===
 
If you want to search and fold with a single command, either add the following as well:
 
If you want to search and fold with a single command, either add the following as well:
 
 
<pre>
 
<pre>
 
command! -nargs=+ Foldsearch exe "normal /".<q-args>."^M\z"
 
command! -nargs=+ Foldsearch exe "normal /".<q-args>."^M\z"
 
</pre>
 
</pre>
   
Or get rid of the \z entirely:
+
Or get rid of the <tt>\z</tt> entirely:
   
 
<pre>
 
<pre>
Line 39: Line 38:
 
</pre>
 
</pre>
   
In these last two code segments, be sure to replace the "^M" with an actual CTRL-M (carriage return) character. Type :Folds[earch] &lt;search string&gt;[ENTER] to use this command. Use zr to display more context, use zm to display less context as before.
+
In these last two code segments, be sure to replace the "^M" with an actual CTRL-M (carriage return) character. Type :Folds[earch] <search string>[ENTER] to use this command. Use zr to display more context, use zm to display less context as before.
   
 
===Customizing===
 
===Customizing===
Line 60: Line 59:
 
</pre>
 
</pre>
   
Note that a better way to do this for languages that support it would be to use syntax highlighting. [[Check your syntax files for configurable options|Check the syntax file]] for the language in question to determine if this is an option. Many syntax files such as those for C, Perl, and [[Syntax folding of Vim scripts|VimL]] all define rules for at least some syntax-based folding, using <tt><nowiki>:set foldmethod=syntax</nowiki></tt>. Other languages such as Java do not currently have this functionality built in, so keep this idea around just in case you need it!
+
Note that a better way to do this for languages that support it would be to use syntax highlighting. [[Check your syntax files for configurable options|Check the syntax file]] for the language in question to determine if this is an option. Many syntax files such as those for C, Perl, and [[Syntax folding of Vim scripts|VimL]] all define rules for at least some syntax-based folding, using <tt>:set foldmethod=syntax</tt>. Other languages such as Java do not currently have this functionality built in, so keep this idea around just in case you need it!
   
 
==See also==
 
==See also==
This tip combines well with [[VimTip108]] (space bar in normal mode toggles a fold).
+
*[[VimTip108|Toggle a fold with a single keystroke]] press space bar in normal mode to toggle fold
 
*{{script|id=158}} script that does the same thing and more
 
  +
*[[VimTip213|Delete all lines containing a pattern]] to delete matching or non-matching lines, rather than folding them
This script does the same thing and more: {{script|id=158}}
 
   
 
==Comments==
 
==Comments==
  +
{{Todo}}
{{todo}} Explain better how the foldexpr string works.
+
*Explain better how the foldexpr string works.
  +
*Check if the comments in the original tip should be added (have they been taken into account?).
  +
*Is an actual ^M really needed?

Revision as of 05:41, 15 June 2008

Tip 282 Printable Monobook Previous Next

created July 11, 2002 · complexity basic · author Chris Butler · version 6.0


When searching with /, it would sometimes be nice to fold everything except for matches to your search. The following code does this, providing two levels of folding to allow you to show some context around each search match as well.

Using a '/' search and key mapping

Add the following to your vimrc to provide a mapping to fold on an already-performed search:

nnoremap \z :setlocal foldexpr=(getline(v:lnum)=~@/)?0:(getline(v:lnum-1)=~@/)\\|\\|(getline(v:lnum+1)=~@/)?1:2 foldmethod=expr foldlevel=0 foldcolumn=2<CR>
  • The foldexpr is an extension of foldexpr=(getline(v:lnum)=~@/)?0:1
  • The following options set the foldmethod to use the fold expression, and some other convenient values.

First search for a pattern, then fold everything else with \z
Use zr to display more context, or zm to display less context.

Using a user-defined command

If you want to search and fold with a single command, either add the following as well:

command! -nargs=+ Foldsearch exe "normal /".<q-args>."^M\z"

Or get rid of the \z entirely:

command! -nargs=+ Foldsearch exe "normal /".<q-args>."^M" | setlocal foldexpr=(getline(v:lnum)=~@/)?0:(getline(v:lnum-1)=~@/)\|\|(getline(v:lnum+1)=~@/)?1:2 foldmethod=expr foldlevel=0 foldcolumn=2

In these last two code segments, be sure to replace the "^M" with an actual CTRL-M (carriage return) character. Type :Folds[earch] <search string>[ENTER] to use this command. Use zr to display more context, use zm to display less context as before.

Customizing

To add a second level of context, you could add this to the end of foldexpr:

(getline(v:lnum-2)=~@/)\|\|(getline(v:lnum+2)=~@/)?2:3

but it will take longer as folded lines (the majority) evaluate the full expression.

If no context is desired at all, you can do the following instead:

foldexpr=(getline(v:lnum)=~@/)?0:(getline(v:lnum)=~@/)\|\|(getline(v:lnum)=~@/)?0:1

Uses

Aside from the possible convenience of seeing only the search terms and their immediate context, this method of folding can be used for practical purposes as well. For example, viewing a "quick and dirty" api of a source code file.

To make a command to do a quick Java API for example, use:

" View the methods and variables in a java source file."
command! Japi Foldsearch public\s\|protected\s\|private\s

Note that a better way to do this for languages that support it would be to use syntax highlighting. Check the syntax file for the language in question to determine if this is an option. Many syntax files such as those for C, Perl, and VimL all define rules for at least some syntax-based folding, using :set foldmethod=syntax. Other languages such as Java do not currently have this functionality built in, so keep this idea around just in case you need it!

See also

Comments

 TO DO 

  • Explain better how the foldexpr string works.
  • Check if the comments in the original tip should be added (have they been taken into account?).
  • Is an actual ^M really needed?