August 2, 2020

Emmet 2 for Sublime Text

After a few month of active development, I’d like to announce a new version of Emmet plugin for Sublime Text!

tl;dr: new Emmet is much faster, smaller and better. It doesn’t hijack Tab key, provides interactive preview of expanded abbreviation and has improved JSX support. New plugin is in beta stage and must be installed from external repository. And if you like Emmet, please support it via GitHub Sponsors: it helps me maintain and support project further.

8 years ago, a first version of Emmet was released and became one of most downloaded package for Sublime Text editor. Back these days, when Emmet was a new kid on the block, I’ve tried to support as much editors as possible. Since most editors are extended with JavaScript, I wanted to re-use existing JS code base for Sublime Text, which is extended with Python.

While this solution allowed me to implement Sublime Text plugin rather quickly and (theoretically) ease further plugin support, it had too much downsides:

  • it required large PyV8 binary to be downloaded separately;
  • running JS inside Python caused major performance and stability degradation;
  • it doesn’t allow deeper integration with Sublime Text features.

A new Emmet code base is a complete rethink of architecture and how users should interact with extension.

Play nice with Tab key

Almost all users want to expand Emmet abbreviations with Tab key, just like regular snippets. The problem is that simply binding Tab key to Expand Emmet Abbreviation action prevents users from using native snippets. Moreover, it breaks another essential editor features like indent, move to next tabstop etc.

In Emmet 2 plugin, a new paradigm called abbreviation capturing is used. When you start typing a word (basically, any word can be an abbreviation!), Emmet begins to track it (displayed as subtle underline). So, an underlined word means Emmet is able to expand it as abbreviation: just hit Tab to do so!

If you just typing a regular text, most likely you’ll enter some invalid abbreviation character like space or comma: doing so at the end of captured abbreviation will automatically reset it like nothing happens. Or you can just hit Esc key to forcibly reset abbreviation and use Tab key to expand native snippets or insert indentation.

But the coolest thing is that when abbreviation becomes complex (contains more that one element), you’ll see an expanded abbreviation preview, which is updated live as you edit abbreviation:

Remember that Emmet expands abbreviation by Tab key only if it’s captured (has subtle underline)! Otherwise, Tab key acts normally.

Autocomplete provider

Emmet also acts as autocomplete provider: if you already have abbreviation in you editor and want to expand it, move caret at the end of abbreviation and invoke autocomplete popup (Ctrl-Space by default):

Note that by default Sublime Text inserts a single completion (e.g. will immediately expand abbreviation). If you want to capture abbreviation and continue it’s editing with interactive preview, run new Emmet: Capture Abbreviation action.

Improved JSX support

Make sure your document syntax in Sublime Text is set to JSX, not JavaScript.

Since any word can be an Emmet abbreviation, capturing it that same way as in HTML would cause too much distraction when you write regular JavaScript. To overcome this problem, in JSX you must explicitly prefix abbreviation with < character:

Also, Emmet has some internal improvements for JSX:

  • Detect camel-cased module notation: Foo.Bar will be expanded to <Foo.Bar></Foo.Bar> instead of <Foo className="Bar"></Foo>;
  • Expression attributes: div[class={getClass('foo')}].

CSS support

In CSS, Sublime Text uses slightly different autocomplete behaviour: it displays completions by default and doesn’t re-populate completions list as you type further, which prevents Emmet from building proper dynamic completion. To overcome this issue, Emmet displays abbreviation preview right after caret as phantom:

In Emmet 2, CSS abbreviations are enhanced with dynamic color snippets: you can type, for example, #f.5 to quickly get rgba(255, 255, 255, 0.5).

Tag preview

Another new feature of Emmet 2 is inline preview of opening tag. When you move caret inside name of closing tag and its matching open tag is not visible on screen you’ll see an inline tag preview:

Click on this preview to jump to opening tag.

More actions

All the rest actions like Wrap with Abbreviation, Balance, Select Item etc. are also supported but doesn’t have default key bindings: it caused too much trouble for new users when Emmet overrides actions from other plugins. You should either invoke these actions via Command Palette or create your own keyboard shortcuts (see Default.sublime-commands file for list of available actions).

A final Sublime Text plugin will provide web-based UI for fine-tuning Emmet options and key bindings.

Installation

You can install Emmet from Package Control:

  1. From Command Palette, run Package Control: Install Package command.
  2. In opened packages list, find Emmet package and install it.

If you’re unable to find Emmet package on last step or installed package doesn’t work as expected, restart Sublime Text and try again.


Emmet needs your support! 🎉

Emmet is free and open-source project, developed by a single person on my spare time. It’s very hard for me to maintain project of such scale and popularity yet pay my bills.

If you find Emmet useful for you or your company or you want to support new editor or future, please consider project sponsorship via GitHub Sponsors! Every donation makes me worry less about money and focus on Emmet features and improvements.