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:
. ├── arrays │ ├── k-smallest-fastest.cpp │ ├── k-smallest-using-set.cpp │ └── rotate.cpp
* arrays * k-smallest-fastest.cpp * k-smallest-using-set.cpp * rotate.cpp
To see what we are going to make in detail, check this video out:
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:
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:
. |── arrays ├── k-smallest-fastest.cpp ├── k-smallest-using-set.cpp └── rotate.cpp
Replacing the sub-element pipe with a star
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
Our output now look like this:
. * arrays * k-smallest-fastest.cpp * k-smallest-using-set.cpp └── rotate.cpp
Replacing the last sub-element pipe with a star
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:
. * arrays * k-smallest-fastest.cpp * k-smallest-using-set.cpp * rotate.cpp
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:
:set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<,space:␣ :set list " to see unicode characters in the statusline :set statusline=%b\ %B
This will yield the following output:
Notice that in the statusline we can view the invisible character as
. We need to replace it by space, which can be easily done by:
And voila, we have our output!
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:
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: