简体   繁体   中英

Comment / uncomment multiple fixed lines in vim

In my code I have multiple scattered lines which help me to debug my program and show me what is going on during execution. Is there an easy and fast way to comment and uncomment (toggle) these fixed lines in vim? I thought about marking these lines with a special sign (eg //) like this in python:

print "Debug!" # //   

and everytime a sepcific shortcut is pressed all lines which end with a "# 'some optional descriptive text' //" are commented or uncommented, respectively.

I've looked at NERD Commenter, but from what I read the lines to be commented / uncommented have to be selected each time?

First, find a pattern that selects the right lines. If you have :set hls , it will help spot the matches. I think something like /#.*\\/\\/$ is what you want.

Next, comment out the selected lines with

:g/<pattern>/s/^/# /

if # will comment out the line, and un-comment them with

:g/<pattern>/s/^# //

Now, you want a single command to toggle. You can either use a variable to keep track of the toggle state, or you can try to figure out the current state by examining the lines that match. Using a variable seems simpler.

The variable could be global, local to the buffer, or local to the script. I like using script-local variables in order to avoid cluttering the namespace. In this case, using a script-local variable might mean that vim will get confused when you switch buffers, so let's use a buffer-local variable, say b:commentToggle .

The first time the function is called, it notices that the variable is not set, so use search() to look for a line that starts with # (There is a space there!) and ends with the pattern we already have. The n flag means not to move the cursor, and w means to wrap around the end of the file (like searching with 'wrapscan' set). The search() function returns the line number (1-based!) if the pattern is found, 0 if not. See :help search() .

This seems to work in a small test:

fun! CommentToggle()
  if !exists('b:commentToggle')
    let b:commentToggle = !search('^# .*#.*\/\/$', 'nw')
  endif
  if b:commentToggle == 1
    g/#.*\/\/$/s/^/# /
  else
    g/#.*\/\/$/s/^# //e
  endif
  let b:commentToggle = !b:commentToggle
endfun
nnoremap <F4> :call CommentToggle()<CR>

If you want to put # in front of the first non-blank, then use ^\\s*# in the search() command; s/\\ze\\S/# / or s/\\S/\\1# / in the first :g line; and s/^\\s*\\zs# // in the second :g line. See :help /\\zs , :help /\\ze , and :help sub-replace-special .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM