Recently, I was working on my competitive-coding skills to land a job. But like a developer I was pushing each and every program that I made to GitHub. I wanted a way to list down all the files I made in my README.md file in a readable format.
The tree command is a very useful utility to list out the hierarchy inside a project. My aim was to convert this hierarchial structure into a markdown list:
To see what we are going to make in detail, check this video out:
The How
Working with the hierarchy that we have, we need to perform a series of find and replace operations to get our output. The only challenge is that our symbols | |-- -- are not utf-8 encoded. Which means that we cannot type them using our standard keyboard. So to search for these tags, we need to copy paste them.
Removing the left-most pipe
Now let us perform our first operation:
:%s/│//
This will search for all │ (which are in the left side of the hierarchy) and delete them. Now to type this command, you can copy paste the │ character from your file, or you can directly go into the vim command line with │ in your cursor and press Ctrl + r + " to paste it there, which is a more intuitive way of approaching the problem. We get this as our output:
To convert our hierarchy to a list, every sub-element needs to remain in the same position and have a * next to it. This can be achieved by replacing the ├── character by a *:
Notice that the last sub-element still has the pipe character in front of it. It can be replaced by the following and subsequent output is given below:
Are we done? Not quite. If you look at the produced output in a markdown previewer, you will notice that it does not render properly. Why?
That is because there are hidden unicode characters in this file which we need to replace by a space character. To show all whitespaces, you can run the following commands:
:setlistchars=eol:$,tab:>-,trail:~,extends:>,precedes:<,space:␣
:setlist" to see unicode characters in the statusline:setstatusline=%b\ %B
This will yield the following output:
Notice that in the statusline we can view the invisible character as A0. We need to replace it by space, which can be easily done by:
:%s/\%u00a0/ /g
And voila, we have our output!
Combining everything
In vim, the pipe (|) character can be used to pipe multiple find and replace commands. So everything we did here can be condensed to the following command:
:%s/│//|%s/├──/*/|%s/└──/*/|%s/\%u00a0/ /g
What lies ahead
I have made a plugin called treemd which maps some very easy keybindings for converting your tree buffer to a markdown list. There is a bonus keybinding for running the tree command with a specified depth, in the current directory and using it as a markdown list: