Adding WSL Support to a VS Code Extension
I have a few dozen projects on GitHub. I put a lot of effort into my README.md
files, making them complete with descriptions, instructions, and screenshots – the last one being the most time-consuming to manage.
Rich Editors are Easy⌗
You've Got Mail!
No more than five emails per year, all densely packed with knowledge.
I don’t mean easy for the developers (I never tried, but it sounds daunting), but for the users. All the data inside a rich file format such as .docx
is embedded inside of itself. There are no worries about hosting or broken links for your pictures, as Microsoft Word will save them the same way as your text.
Rich formats make copy-pasting images easy.
Screenshots are quick with Microsoft Word, especially if you know about Windows+Shift+S
Text Editors are Clunky⌗
IDEs will give you the world as long as you stay inside of it. VS Code makes file management a breeze in your workspace but bringing in anything from the outside world will not be frictionless. Inserting a screenshot into a markdown document within VS Code is a multi-step process:
- Take the screenshot
- Save the screenshot in a folder
- Locate the screenshot in file explorer
- Drag-drop the screenshot into VS Code
- Reference the screenshot from the markdown document
Nowhere near as seamless as Microsoft Word handles pasting images. What if there was an extension that could handle pastes directly?
Forking Forks⌗
Clocking in at over 150k installs, mushan’s Paste Image features what we want. Unfortunately, the repository appears abandoned with the last commit being over two years old.
That’s a lot of issues
For my purposes, the extension did not work at all on WSL, but its popularity made me believe that there could be a functioning fork. At the time of writing, there are 117 forks, many of them active. Additionally, there are a few forks of forks.
There are a couple dozen forks that had activity in the past year
Most of the forks were to fix one-off issues, but one, in particular, has taken on the mantle by not just stopping at bug fixes and implementing new features. I would describe them, but the README does a fine job of it.
Judging it to be worth investing my time in, I started sending in a series of pull requests. The bulk of my work revolved around adding WSL support and refactoring the code to make it more maintainable. I’m happy with the result.
Reading the Windows Clipboard from WSL-land⌗
As mentioned previously, when testing the original extension, it did not work for me due to my WSL-based setup. The extension works by accessing the clipboard through PowerShell and bash scripts, which invoke system utilities.
There are multiple scripts for Windows, Linux and Mac
The correct script gets executed based on the operating system which the extension detects. In the case of WSL, that operating system that runs the extension host is Linux, but since it is a “headless” Linux without an X11 server (though one can be installed) it doesn’t have a clipboard. Accessing the Windows clipboard requires jumping through a couple of hoops.
A feature of WSL is that any Windows-native application invoked from within WSL will run under the Window host (which is very different from WINE emulation, for example). This feature makes escaping for the WSL context as easy as launching PowerShell. Doing so, however, will break any paths generated in WSL-land such as __dirname
or any output from the fs
package. Luckily, they can be re-written back and forth between WSL and Windows formats using the wslpath
utility.
~
▶ wslpath -u C:/
/mnt/c/
~
▶ wslpath -m /home/
//wsl$/Ubuntu/home
~
▶ wslpath -w /home/
\\wsl$\Ubuntu\home
The extension can detect that it’s running in a WSL environment using the is-wsl
package. Putting the two together, it is possible to convert paths inside the NodeJS by calling out to wslpath
.
function toWindowsPath(path: string) {
if (getCurrentPlatform() != "wsl") return path;
// Path must exist for wslpath to work
await runCommand("touch", [path]);
return runCommand("wslpath", ["-m", path]);
}
Better Clipboard API⌗
The current approach of dispatching scripts to extract data from the clipboard is fundamentally broken. It will be possible to do it natively when VS Code extensions can leverage electron’s full clipboard APIs. I have filed an issue to have it supported.
Becoming a Maintainer⌗
After investing many hours into this extension, GitHub greeted me with this e-mail:
I have been noticed!