Your Linux Data Center Experts

I've never really considered myself to be much of a vi “power user”.I have a core of functionality that I use all the time, and most of the rest of it I just don't use. I've found this is true of many vi users, but I've recently come to understand that I do tend to us a fairly larger core set of functionality than many others I know. I've also been kind of expanding the set of vi commands I use regularly, partly because of a recent presentation I gave on neat things you can do with vi.

One of the things that I've really been using quite a lot lately is folding. This is a feature of vim, which allows you kind of zoom in and out in detail level in code. You can have vim use it's syntax highlighting to create fold marks in your code based on code blocks, which is a useful first cut. However, you can also mark areas using “{{{1” (where “1” is a fold level, allowing folds to nest).

I've really gotten into this because it allows me to mark chunks of code with comments (which are all that show when the fold is closed). I'm a pretty minimal commenter, adding a short comment on a chunk of code that does something. With the folds closed, I get a very high-level, kind of terse literate style code. For example, I might go into a file and see:

def parseConfigFile(name):  #{{{1
def main():  #{{{1

Then when I open that first fold I'd might see:

def parseConfigFile(name):  #{{{1
   '''Open the file specified by "name" and parse it.  Return a
   configuration file object.'''
   class configClass:  #{{{2
   #  set up configuration object  {{{2
   #  read configuration file  {{{2
   #  clean up loaded data  {{{2
   #  return configuration  {{{2
def main():  #{{{1

About the only problem, which I don't run into much with Python of course, is that this markup totally breaks the “brace match” vi command. I use that all the time for making sure I've got balanced parens, brackets or braces. Press “%” when on one of these symbols to see the one that matches.

vim includes all sorts of tools for managing folds. “zM” closes all folds, while “zR” opens all folds. “zm” on the other hands, closes the next fold level (zooming out on your code) while “zr” zooms in for more detail. I also use “zo” to open a particular fold and “zO” to recursively open all folds within that fold (for example, when I'm on a function and want to just see the whole thing.

Folds really do make code much easier to deal with. You can change the level that you're working at to eliminate things that you don't care about. This is something that I've found really helps my concentration, hiding things that I'm not ready to deal with.

One thing that I can never remember how to do is to do a search for the word that the cursor is on. I always want to do Control-], but that requires “tags” to have been run and only works with tag symbols. “*” and “#” just do a forward or reverse search for the text under the cursor.

In finding these, I also found “g” and “g#”, which are like “” and “#”, but they don't anchor the search to be a word, so you can find the text occurring anywhere, not just as an exact word match. Then I found there are a whole ton of useful “g” commands. “ga” will print the hex/dec/oct character code under the cursor.

However, the neatest “g” function I found was “gd” which will take you to the definition of the word under the cursor. Essentially, searches backwards for the start of a function or the beginning of the file, then searches forward for the text under your cursor. In other words, it takes you to the first mention of that string in the current function. Unfortunately this only seems to work for languages which use “{” for the function block start, and for code which has a “{” in the first column after a function. So, Python will search from the beginning of the file. It shouldn't be hard to build a routine that does this in a python-smart way, though.

For more information on other “g” commands, in vim type “:help g”.

comments powered by Disqus

Join our other satisfied clients. Contact us today.