DEV Community

David Cantrell
David Cantrell

Posted on

GNU tree annoyed me so I fixed it

The tree utility is incredibly useful, but sometimes it can be just too verbose. Often you want to see a tree of some directory with exceptions - for example, you might have a sub-directory full of your project's dependencies that you have no interest in seeing.

To solve that problem tree has the -I option. My project's dependencies generally live in a local/ directory, so I can exclude it thus:

tree -I local
Enter fullscreen mode Exit fullscreen mode

Now, what if I want to exclude something else as well, such as hiding my tests too. You would think that you could do this:

tree -I local -I t
Enter fullscreen mode Exit fullscreen mode

But no. It only pays attention to one -I argument. Specifically, it only cares about the last one. If you want to ignore multiple directories you need to combine them into a pattern:

tree -I local|t
Enter fullscreen mode Exit fullscreen mode

Except that doesn't work, the shell will interpret that as piping the output from tree -I local into t. You need to escape the pipe character:

tree -I local\|t
Enter fullscreen mode Exit fullscreen mode

This is all a bit of a pain. Add to that that you can't set defaults in an environment variable or a configuration file, so I generally find myself forgetting to say -I at all and then having to do it again when my screen is filled with unwanted gibberish.

So I've fixed it with a shell function. That function will automatically apply any defaults that are in ~/.treerc (you can see mine here), and will combine multiple -I arguments into one.

It also lets you say -I \$FIGNORE as a special case to ignore anything mentioned in that specific environment variable. The env var is normally used to tell the shell what files to ignore when doing tab-completion, but I figure that, combined with per-project environment variables controlled by direnv it's a reasonable place to put such data. I may change that later though.

The argument processing is done in perl, as it's far easier to do in that language than in the shell, but it doesn't do a complete job because I'm lazy. In particular if you combine arguments in an invocation like this:

tree -ahI foo
Enter fullscreen mode Exit fullscreen mode

then it won't spot that and give the -I in there the correct treatment. Patches welcome!

Top comments (3)

mbeijen profile image
Michiel W. Beijen

Just to let you know, I shared your annoyance about the -I flag in tree. And after reading your post, I noticed it is not just me who wants this. 'tree' does not have a public source code repo but I contacted the author, also pointing to your website. Now there is a new version of tree, 2.0, and it has support for multiple -I flags!!

Thanks to you for confirming my annoyance and thanks to Steve Baker, the tree author, to make this happen.

A fellow tree lover

drhyde profile image
David Cantrell

And it appears to have a public repo now, so I'll see if I can patch my .treerc shenanigans into it!

dguo profile image
Danny Guo

Nice hack! You may be interested in checking out broot, an alternative to tree.