Monday, 23 January 2012

Hiding a regex with vim (aka making C comments disappear)

I use the mighty vim editor for most of my coding. I have a heavily customized setup which has evolved over quite a few years. However, it is by no means a static setup as I keep finding new scripts and tricks (and of course Bram keeps on adding extra goodness with each release).

    Recently, I was hacking through a lot of C code containing lots of debug cruft (log function calls, commented out bits and pieces, etc). The problem was I couldn't get a feel for the code as all the debug was too distracting. The question popped into my head, "can I hide all this stuff?" A number of folk have come up with ways to "hide" the data you don't want to see in Vim using folds (":help fold" in Vim). However, that wasn't what I wanted as folds also introduce their own "visual noise". I just wanted this stuff gone.

    What I came up with is a complete hack, but it suited my purpose rather well: I changed the colour of the regex's matching the data I wanted to hide to match the colour of my terminals background.

    So rather than seeing this:




    ...with a few keystrokes, I could change it to this:


    Neat huh? Note that I've removed:

    • C-style comments
    • C++-style comments
    • "#if 0" blocks
    If we cancel "hidden mode", you can see the highlighted text:


    To achieve this, we need to make a few tweaks to your ~/.vimrc. First, we need a function that enables highlight search mode and then toggles the highlight mode for the "Search" highlighting group. We also need a variable to keep track whether we're in "hidden mode" or not:

    let g:Hide_Search = 0
    
    function! JHHideSearch()
      :set hlsearch
    if g:Hide_Search == 1
        let g:Hide_Search = 0
    " XXX: you might want to tweak the colours in the line below 
    :hi search term=reverse ctermfg=0 ctermbg=3 guibg=Yellow
      else
        let g:Hide_Search = 1
        " XXX: the colours to use to make the search terms invisible
        :hi search ctermbg=black ctermfg=black guifg=black guibg=black
      endif
    endfunction
    

    This is the "hack" since as you can see, I've hard-coded the normal colours used for highlighting the "Search" highlight group and I've also hard-coded the colour to make the search terms invisible. For the latter, I've used black as that is the colour I use for my terminal background. You might want to tweak those ":hi" lines with colours of your choice.

    Now, we need a key combo that will invoke this function. I chose "\h" (where "h" is a mnemonic for "hide":

    noremap \h :call JHHideSearch()<cr>
    

    Now, try searching for a string. Let's search for "hello" using the familiar vi(m) command:

    /hello
    

    Assuming that text is found in your file, if you now type "\h", all occurrences of that string will disappear! Type "\h" to undo "hidden mode" and display the search highlight again. This works for regular expressions of course.

    Since I spent most of my time working with C code, I also added a key combination that will select the 3 types of "comment" listed above:

    noremap \c /\/\*\_.\{-}\*\/\n\{,1}\\|^\s*\/\/.*\n\|\s*\/\/.*\\|\/\/.*$\\|^\#if 0\_.\{-}\_.\{-}#endif<cr>
    

    So, to hide all comments in the code I'm reading, I simply type "\c \h". And to revert to normal Vim behaviour, I type "\h".

    For further reading, fire up Vim: and look at:


    • :help highlight
    • :help hlsearch

    1 comment:

    1. Nice Post, Thanks for your very useful information... I will bookmark for next reference.

      ReplyDelete