This spring, I tasked myself with exploring the possible integrations Prismic could offer with Integrated Development Environments (IDEs, a.k.a. code editors). This was a topic I was interested in and aligned with our current goal of providing you with the best integration and experience. I also felt like it could come with the opportunity for me to learn more about the anatomy of IDE extensions.
“Who knows?” I thought, “Might be helpful for a hypothetic Philips Hue (yes, the light bulbs) integration… Nevermind! Someone beat me to it.”
This Prismic extension project led to Prismic Snippets being released for VS Code, as well as Vim, Sublime Text, and IntelliJ, hopefully providing most of you with snippets to template content quickly. But that’s not all! While working on these 4 extensions I also had the opportunity to create Schnipsel, an open-source tool I created to solve a multiple extensions problem…
A multiple extensions problem…
One of the first questions I asked myself when starting this project was: which IDE should we target? I suspected VS Code to be the one, but doing some research is always great to get rid of biases, right? While there are no precise data on IDE market shares, surveys are regularly run by third parties asking about IDE usage (e.g. Stack Overflow’s Developer Survey).
Long story short, numbers fluctuate, but IDE usage among web developers in 2022 can “roughly” be summed up like so:
So VS Code is the winner, yay! But 70% is only about two-thirds of developers, so there are clearly opportunities with other IDEs, too. In that regard, each IDE comes with its own extension framework or even language: VS Code wants its extensions to be written in TypeScript, so does Vim (via Coc), but IntelliJ is all about Java and Sublime Text whistles Python, and… as we now wanted to cover multiple IDEs, that was our problem!
Each IDE requires extensions to be written very differently (they all have their own reasons for that). This kills any opportunity to share code if we were to write an extension for each of them. It would be all about duplication, or would it be?
Maybe there’s hope after all
As I was doing research for this project and learning about extensions’ capabilities, I stumbled across Snippet Generator:
Snippet Generator is an application developed by Pawel Grzybek. It allows you to write a snippet in a simple format (the left section of the GIF above) and convert it to different IDE snippet formats (the right section with the cryptic syntax).
This clicked for me! I could just define a convenient format for writing snippets like Pawel did, and then have some kind of process to render that snippet to different IDE formats. All that would remain would be to figure out some boilerplate for each IDE to load those snippets through an extension. Then it would be Winner Winner, Chicken Dinner!
I started working on that idea and that idea eventually got a name: Schnipsel.
Introducing Schnipsel
Schnipsel — German for “fragment or snippet” — is available for anyone to use on GitHub. It is a CLI tool that reads some input snippet files, then renders them to desired IDE formats. Let’s highlight how it works by first talking about snippet files!
Snippet files
Snippet files are what I came up with for an easy-to-write, read, and parse format to write snippets in. Basically, they’re Markdown files with some front matter and a code block. The code block can be highlighted with any language you fancy, just like regular Markdown, and tab stops with placeholders can be declared inside it with an à-la-VS Code syntax. Considering all of that, a snippet file can look like this for example:
---
name: "Prismic Link"
description: "Yields a ready-to-use `<PrismicLink />` component"
scopes: ["vue-html", "html"]
prefix: "prismicLink"
---
```html
<PrismicLink :field="${1:doc.data.field}">
${2}
</PrismicLink>
```
What I find extra cool about it is that it even displays nicely over on GitHub.
Snippet files are what we used and what potential Schnipsel users would use to define their snippets before rendering them through the available renderers …
Rendering snippets
To render snippets, Schnipsel works with an array of renderers. I wrote one for each IDE we decided to target for now (namely, VS Code, Vim, Sublime Text, and IntelliJ), but we can always add more should we want to.
The role of a renderer is to take in parsed snippet files, some metadata, and the code inside the code block, and render them to the desired format at a specific location.
A CLI to bridge the two
Schnipsel is able to work thanks to these first two notions. A CLI then allows you to render your snippet files once or in watch mode.
# renders snippets once
schnipsel
# renders snippets in watch mode
schnipsel --watch
From my experience, building a CLI is always quite fun and refreshing compared to my usual projects. This time it was also for me the opportunity to work with some cool (new) tools:
For example, Schnipsel CLI works by reading its configuration from the user’s schnipsel.config.ts
file. Reading a TypeScript file from a CLI is not trivial (because the CLI by design is a Node.js script). For that purpose, this was the perfect opportunity to use c12. It’s a smart configuration loader developed by the Nuxt team that handles TypeScript configuration files.
Another great tool I had the opportunity to use again for this project is CAC. It’s a simple CLI framework that I find pleasant to use. It is nicely typed, and its output is minimal but well-formatted.
That’s all folks!
One of the things I cherish about working at Prismic is that we get time to work on open-source projects like Schnipsel. This comes with a lot of learning opportunities while also allowing us to give back to the community.
In fact, earlier this year I had the chance to work on another open-source project as I implemented <NuxtLink>
, the new link component for Nuxt 3. You can read more about this experience right here!
Finally, if you’re a Prismic user feel free to give Prismic Snippets a try! Find how to install it on your IDE and what you can do with it on GitHub!
Cheers!