On my podcast and other outlets, I have been talking a lot lately about Black, the Python Autoformatter. I am a huge fan and I've often wished LabVIEW had something similar. I've been inspired by Darren's Nattifier. and some work by Felipe to start working on my own autoformatter.
You can find the results here:
The first question to ask is why would anyone want or even need an autoformatter? Code quality is important. To be maintainable your code must be well-organized and easy to read. However, there is a tradeoff. Making all the wires straight actually takes a fair amount of time and effort. It can be tedious. I've spent many hours moving wires one pixel at a time so they line up perfectly. I've also spent a lot of time going through VI Analyzer results clicking on them one at a time and fixing them. That is a lot of time and effort that could be devoted to solving my customer's problems. I've often thought "Why can't VI analyzer just fix that for me? And why can't it just run automatically?" There has to be a better way.
I found the answer in Python. I started using PyCharm with the BlackConnect plugin. It was so freeing. I didn't have to worry about how long my lines were, or the best way to indent a dictionary definition, or where I was supposed to use spaces around an equals and where not to. As long as I got the syntax correct when I hit enter, Pycharm would automatically save the file and run Black on it. If I had a long dictionary definition that needed to be split, it just magically reappeared with the correct white space. Black Magic.
One of Black's charms is in its slogan (stolen from Henry Ford) - "You can have any color you want as long as it is Black." There are lots of competing ideas about what makes for good style. Black takes all the decision-making out of it. Giving up control to Black brings the freedom of not having to worry about those details. All of that mental bandwidth can be used for more important things.
An Added Benefit
An added benefit of using something like Black is that it cuts down on noise in your repository. If you aren't using an autoformatter and you are relying on code reviews (or even a tool like VI analyzer - used after the fact) to catch style issues, then you end up with a lot of commits that just fix style issues. At the end of the day, having all those separate commits is just not that important. They don't represent changes in the functionality of the code. I'd rather not have to sort through them when I am looking for a bug or doing a review. I want the style of the code to fade into the background, so I can actually focus on the functionality of the code.
Black is Actually Two Parts
Black itself comes in 2 parts. There is a command line tool called black. You can run this from a shell, simply by pointing it at a directory. It will find all the relevant files and reformat them. This is a manual step. The second part is blackd, which is a daemon. It runs in the background and an IDE like PyCharm or VSCode can communicate with it to let it know when files have been updated so that it can format them. If enabled this happens automatically. You edit a file. You press enter. PyCharm automatically saves the file and notifies blackd, which runs black. Black formats the file and PyCharm automatically reloads the changed file. Simple. Easy.
The First Half of Blue
What I have just released on VIPM is the CLI part. This is the first step towards creating an autoformatter that can run automatically in the background like blackd. I put a lot of effort into making it usable as a standalone tool. I wanted to make sure that even if I couldn't get the autoformatting part to work correctly, I had at least built something useful.
The Second Half
I'm working on a second half of the project called BlueMon. It is a file system monitor written in Python that monitors a directory and when it detects a VI being saved launches Blue from the command line. It currently works, but it is very much a work in progress and it has some caveats I am trying to figure out how to work around.
As a Git Commit Hook
I mentioned this project to Darren. He liked the formatting part and disliked the automatic formatting when saving idea. He suggested setting it up as a Git Hook so that it ran on changed files when you committed. That is totally doable. I just haven't gotten around to it yet. If you are ambitious, I am sure you can figure it out on your own. If I get around to it first, I will make it available.
What is included
I mentioned being inspired by the "Nattifier" so the first set of formattings I implemented were those. I knew Darren wrote them and they've been used quite heavily. I figured they would be pretty performant and well-tested. I also figured since Nattifier was very popular it might help me build an audience for Blue as well. Currently, if you run Blue on a directory of files, it is basically the equivalent of opening them all and running Nattify on each one. Now you can do it programmatically on an entire folder, instead of one at a time.
The CLI also has support for running subsets of the Nattify steps. The readme has a ton of information on all the various options. I tried to make it rather flexible to support a wide variety of workflows. It is possible to run it on a folder or an individual file. It is possible to run only certain tests or exclude tests for specific VIs or folders. The other major feature that is important is auto-detecting GUIs. Blue will detect a VI as a GUI if it has splitter bars, subpanels, tabs, or if it has changed any of the default window settings. That catches 90% of the cases. If blue detects a VI as a GUI it will skip rearranging the front panel for that VI, which was probably the most asked for feature.
To get started, simply install the package from VIPM. Since it autodetects GUIs, it should be fairly safe to run on just about any code you have. The changes are almost all cosmetic (it does turn off auto-error handling and turns on separate compiled code). To be safe you should be using Git or some other Source Code Control (you should be using that anyway).
You can easily run the tool by opening your favorite shell and entering
g-cli blue –-. to run blue on the current directory. Then you should run your unit tests to make sure they still pass. If you have LVCompare setup, then you can use
git difftool to see the changes. If you don't like the changes you can always roll it back. If you don't like the results for one of the particular steps, you can always ignore that step - see the readme for various ways to do that.
I've created a platform to add more reformatting steps. Here are a few future reformattings I was thinking of adding:
- Removing Class Mutation History
- Hiding unused Iteration Terminals
- Hiding Unused Event Data Nodes
- Shrinking Event Data Nodes by getting removing unused terminals.
Do you like this tool? Do you find it useful? Is there some formatting step that you'd like to see added? Please add your comments below.