Adding an Emoji-Log Picker With Native VS Code Snippets

  • report
    Disclaimer
    Click for Disclaimer
    This Post is over a year old (first published about 3 years ago). As such, please keep in mind that some of the information may no longer be accurate, best practice, or a reflection of how I would approach the same thing today.
  • infoFull Post Details
    info_outlineClick for Full Post Details
    Date Posted:
    Sep. 22, 2020
    Last Updated:
    Sep. 22, 2020
  • classTags
    classClick for Tags

Intro

This is a quick guide on how to add an Emoji-Log picker macro to your VSCode setup, with a custom snippet that is just a few lines of code.

Emoji Log Picker, implemented through a custom VSCode Snippet

What is Emoji-Log?

If you haven’t heard of the Emoji-Log project / standard (by Ahmad Awais), you should go check it out. If you look at a lot of open-source repos, chances are you have actually come across its use in the wild at least once or twice. The TLDR is that it is a proposed standard / philosophy for writing the headline of commit messages, and using emoji prefixes to easily convey the type of change made. For example:

πŸ› FIX: Broken redirect pattern

There is already a VSCode extension for Emoji-Log, but I wanted to share how I added an Emoji-Log picker / macro to my VSCode configuration, with just a few lines of code and the support of VSCode Snippets. It serves as a good example of how simple, yet capable, VSCode snippets can be.

VSCode Snippets

VSCode snippets are an incredibly powerful, yet underutilized part of VSCode. With enough manipulation, they can essentially act as text-expanders, macros, and formatters (and this isn’t my first promoting them).

Picking a predefined text choice and inserting it is an excellent use-case for snippets, and the impetus for this post.

Solution: Emoji-Log VSCode Snippet

Here is the snippet code:

{
    "Emoji Log Picker": {
        "prefix": "Emoji Log Picker",
        "description": "Pick an Emoji Log Emoji to use as a prefix",
        "body": "${1|πŸ“¦ NEW,πŸ‘Œ IMPROVE,πŸ› FIX,πŸ“– DOC,πŸš€ RELEASE,πŸ€– TEST,‼️ BREAKING|}: ${2:IMPERATIVE_MESSAGE_GOES_HERE}"
    }
}

Click to see version that defaults to clipboard contents first

{
    "Emoji Log Picker": {
        "prefix": "Emoji Log Picker",
        "description": "Pick an Emoji Log Emoji to use as a prefix",
        "body": "${1|πŸ“¦ NEW,πŸ‘Œ IMPROVE,πŸ› FIX,πŸ“– DOC,πŸš€ RELEASE,πŸ€– TEST,‼️ BREAKING|}: ${2:${CLIPBOARD:IMPERATIVE_MESSAGE_GOES_HERE}}"
    }
}

Adding the Snippet to VSCode

To add this to your VSCode environment:

  1. Bring up the command palette (CTRL + SHIFT + P)
  2. Start typing snippets, and then select Preferences: Configure User Snippets
  3. If you already have a global snippets file, select it, otherwise create a new one with New Global Snippets file
  4. In the snippets file that opens, paste the above snippet
  5. You are done! Now, in almost anywhere in VSCode, you can press CTRL + SPACE to bring up snippets, and then start typing Emoji to bring up the log picker.

If you are looking for a more generic guide on VSCode snippets, this one looks good. And don’t forget the official docs!

Breaking Down How It Works

Since this snippet is pretty simple, it serves as a good example for learning how VSCode Snippets work.

First, let’s break down the main properties:

  • prefix: Serves as the main text string to be used for β€œtriggering” the snippet; a better name for this might actually be keywords. This can be an array of strings, but a single string seems to work just was well (since VS uses sub-string matching)
  • description: Optional. Gets displayed by IntelliSense, in that little popup window as it shows snippets to pick from
  • body: The main thing that is inserted when the snippet is run
    • πŸ’‘ TIP: The main way that snippets work is by inserting content, but through some tricky syntax, you can use them for formatting, replacement, etc.

πŸ’‘ Another helpful optional field is scope. We could add that to our snippet with a value of "plaintext,markdown", if we only wanted our snippet to be suggested in those contexts. Without a scope field, the snippet will appear everywhere (unless the snippet file itself is scoped by language).

Next, let’s break down the body, the crucial part of the snippet. For the purposes of explanation, we can simply from this:

${1|πŸ“¦ NEW,πŸ‘Œ IMPROVE,πŸ› FIX,πŸ“– DOC,πŸš€ RELEASE,πŸ€– TEST,‼️ BREAKING|}: ${2:IMPERATIVE_MESSAGE_GOES_HERE}

to this:

${ 1 | CHOICE_A,CHOICE_B | }: ${ 2: IMPERATIVE_MESSAGE_GOES_HERE }}
 |             |                 |                 |
 |-> Placeholder wrapper         |                 |
               |                 |                 |
               |-> Choice        |-> Tabstop       |-> Plain text

To break it down another way

  • ${} are placeholder wrappers
  • The number prefixes ({$1}, ${2:}) inside the placeholders are tabstops.
    • Unfortunately, they are mandatory with choice elements, which is why I have tab stop with the choice section, even though there should be nothing for the user to type in that spot
  • To offer choices, you need to use a special syntax with pipe wrappers:
    • | CHOICE_A,CHOICE_B |
  • The : between placeholder wrappers is plain text that will be output
  • The benefits to using a placeholder wrapper in the second part instead of just using $2IMPERATIVE_MESSAGE_GOES_HERE are:
    • When we tab to the second part, anything we type will replace the entire placeholder text
    • The placeholder syntax is easier to read
    • It makes it easier to upgrade our snippet later and expand with variables, nested placeholders, etc.

Adding the Clipboard

If we want the imperative message section to default to clipboard text, while still allowing the user to customize it, we can use the placeholder + variable syntax.

We simply replace this:

${2:IMPERATIVE_MESSAGE_GOES_HERE}

… with this:

${2:${CLIPBOARD:IMPERATIVE_MESSAGE_GOES_HERE}}

We now have a nested placeholder element, where it will fill with the value of the CLIPBOARD value, defaulting to IMPERATIVE_MESSAGE_GOES_HERE if the value does not exist. And since it is at a tabstop, it is easy for the user (aka you!) to customize the message.

Wrap Up

Even if you are not interested in using Emoji-Log, I hope you still learned something about VSCode snippets and maybe got some inspiration for your own workflow improvements!

Leave a Reply

Your email address will not be published.