Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Snapshot of a part of a file in Vim: hide comments and blank lines

Tags:

c++

c

comments

vim

How to temporary show a snapshot of a file, while hiding comments and blank line?

The purpose would be to get a catch of a C++ function (for example), in a dense page formating.

A manner to do that is to use the global command to filter out lines of comments

:g!/\/\/

but then the syntax highlighting and move controls disappear.

The folding feature of Vim is a way to do the job, but it does only reduce several consecutive comments to a single line that is visually intrusive.

Anyway, folding is still useful to hide long C-like comments, for example with:

:set foldmethod=marker
:set foldmarker=/*,*/

But I did not manage to easily fold both C (/.../) and C++ (//...) comments in a single command.

The ideal trick would:

  • hide (not just fold in a single line) comments and blank lines,
  • perhaps indicate hidden lines with a character on the first column,
  • handle both C and C++ comments,
  • while preserving the syntax highlighting,
  • and, ideally, the ability to browse the code,
  • permits an easy revert to come back to the "commented" view.

So as to transform the following code:

/** Let say hello
* and do not forget anybody
*/
void hello( int arg )
{
  // OMG an hello world!
  std::cout << "hello" << std::endl;

} // where is the world?

Into the following buffer:

void hello( int arg )
{
  std::cout << "hello" << std::endl;
}
like image 641
nojhan Avatar asked Feb 05 '11 16:02

nojhan


1 Answers

All comments can be removed from the source with the following command:
:%s/\/\*\_.\{-}\*\/\n\{,1}\|^\s*\/\/.*\n\|\s*\/\/.*//

This can then be undone with the u command, assuming no other actions are there to be undone.

Since vi regexes can be extremely cryptic, below is an explanation of each part. The entire regex is split into three parts separated by an OR operator (\|).

\/\*\_.\{-}\*\/\n\{,1}
This is to match block comments of the form /* ... */. It matches the string '/*' (\/\*) followed by zero or more of any character, including new line, but matching as few as possible (\_.\{-}), followed by zero or one newline (\n\{,1}). The reason it matches zero or one new line is to handle both the case where there is code on the same line as the comment and the case when the comment is on a line by itself.

^\s*\/\/.*\n This is to match comments of the form //... where the comment is on a line by itself. It matches zero or more whitespace characters that start with the beginning of the line (^\s*) followed by the string '//' (\/\/), then zero or more of any character (.*), ending with a new line (\n).

\s*\/\/.* This matches comments of the form //... where the comment follows code. It matches any amount of whitespace (\s*) followed by the string // (\/\/) and then any number of characters that are not newline (.*).

This is the best I can come up with at the moment, if I can think of a way to hide instead of delete the comments, I'll update this post.

Update: A possible way to simply "hide" the comments might be to color them the same as the background. This would render them invisible. However, I currently don't know how feasible that idea might be or how well it would generalize. I don't know enough about colors in vim to be able to write a script to accomplish this.

like image 135
cledoux Avatar answered Sep 28 '22 10:09

cledoux