This article was originally written for my personal blog.
I am republishing it here for the DEV community.
I use VS Code every day. I use it exclusively since February 2018, both personally and professionally. I like it a lot.
But I am frustrated.
I am frustrated because I miss a great tool to perform automated refactorings for me. And neither VS Code, neither existing extensions provide the experience I'm looking for!
Thus, 2 months ago, I decided to follow my own advice and hack my own problem. I started creating the VS Code extension I was looking for. This extension analyzes my code, suggests refactorings and executes them with the minimal amount of keystrokes needed.
It helps me focus on my intention instead of manually following the scripted mechanics of a refactoring.
I called this extension: Abracadabra ✨
It's true that VS Code ships with basic refactoring operations. So what's wrong?
Well, speaking from a personal point of view, few things aren't great:
- I need more than that. There are a lot of automated refactorings that I know and aren't proposed.
- I can't just have the cursor on a variable and trigger an extraction. To get an appropriate suggestion requires selecting exactly the code to refactor. I need to select the whole extracted statement first, which is slowing me down.
- I don't like the UX much. Talking about extraction, I often feel confused in front of all the suggested options. I need to play the computer in my head and decipher what "enclosing scope" vs. "module scope" means in terms of the resulting code. I know that there is a better way.
Before using VS Code exclusively, I used Webstorm professionally for a few years. And I prefer VS Code: it's free, feels lighter to use and has a very active community.
But there is one thing Webstorm nailed that VS Code doesn't provide: many, intuitive, automated refactorings.
This made me so productive back in the days. I relied on my editor to move fast 🏇
And I think it matters. If refactoring code takes 2 keystrokes I'm very likely to do it. If I have to find the correct combination of 5 keystrokes to make it work, I'm less likely. If I have to do it by hand… You get the idea.
Great automated refactorings are a productivity boost for every developer.
Yes! And I used it for some time. Well… I tried to.
I appreciate the good efforts that were put in it. At least someone worked to provide more refactorings, shared that for free and maintained it 👏👏
But it's not exactly what I'm looking for, for a few reasons:
- It still misses a lot of refactorings I'm looking for. In fact, it doesn't have many. The way it performs operations like "Add Export", "Negate Expression" or "Wrap Selection", even if they're handy, is not refactoring because they modify code behavior.
- It often tended to just not work. Until very recently, it would fail if I had a JS class in the file. Still today, it doesn't work on TypeScript code.
- It provides features I'm not looking for (I don't want code snippets, I want refactorings)
- Selection doesn't have to be as precise as VS Code. It understands what you want to do with a partial selection. Though I still can't "just have the cursor inside" and make it work.
- The UX is still not the one I expect. It requires too many keystrokes for me to extract a variable.
At that point, I thought:
OK, maybe I can contribute and improve it!
Heading to the repository, I was really happy to see it seemed well tested 👍
But I felt the architecture was not quite what I'd have in mind:
I think abstractions are great, as long as "[their purpose] is not to be vague, but to create a new semantic level in which one can be absolutely precise" as Dijkstra said. To me, too many "factories" adds a lot of indirection for which I can't figure out the added value.
// add-export-factory.js function addExportFactory( coordsHelper, editActionsFactory, // => OK, what's this? logger, parser, selectionExportHelper, selectionExpressionHelper, templateHelper, vsCodeHelperFactory )
// edit-actions-factory.js function editActionsFactory( editFactory, // => and this? vscodeFactory )
// edit-factory.js function editFactory(editApiFactory)
// edit-api-factory.js function editApiFactory(vscodeFactory)
Abstracting VS Code API so we isolate our domain logic from the actual platform brings a lot of value. But, in my opinion, all of the intermediate factories make the code more difficult to reason about.
So, I was not really satisfied with the extension, neither aligned with the overall design of the code—but I respect the choice of the author, whatever works best for him! That's when popped up in my head the idea of scratching my personal itch and build my own extension.
That's why, 2 months ago, I started to build this extension.
My goal is essentially to build the tool I'm missing.
There is a very cool side-effect of this: the learning part. Digging into Abstract Syntax Trees manipulations is super interesting. Also, I'm discovering how to build a VS Code extension for the first time. Finally, it's a playground for me to test architectural decisions and practices, like documenting architectural decisions through ADRs.
I implemented a couple of refactorings across these 2 months. I published the extension a few days ago on the Marketplace.
Now I'm waiting for feedback to improve these first refactorings, fix edge cases and improve the UX to match what I'd expect from a great extension!
Our goal is to provide you with easy-to-use, intuitive refactorings. They help you clean the code and understand what's going on.
- Click on the Extensions icon (usually on the left-hand side of your editor).
- Search for "Abracadabra".
- Find the extension in the list and click the install button.
All refactorings are available through the Command Palette.
Some refactorings have default keybindings configured, but you can change that.
Refactorings that don't have default keybindings are available through VS Code Quick Fixes. You usually access them by clicking on the lightbulb that appear next to the code
We recommend you to use the official shortcut (e.g.
⌘ . on Mac), or to define a custom one (like
Alt + ↵).
Then, if you want to help me, you can:
- Give me your feedbacks on what you like and what you'd like to improve. Whether you find a bug, have a suggestion or just want to share something, have a look at existing issues or open a new one.
- If you'd like to contribute, you can start with the "Good First Issues" I've listed. Any kind of contribution is welcomed 🙂
- Spread the word so I can get more use-cases and more feedbacks to improve the extension!
That's it. I'm really excited about this and happy to start spreading the word.
Now, I feel better.