Itemizers
Languages
Itemizers group syntax zones into hierarchical blocks and allow Espresso to provide code folding and a hierarchical representation of the document in the Navigator.
XML syntax
The XML files in your Itemizers folder define your plug-in's itemizer definitions. Files can be named anything you like, although by convention they are usually named after the syntax they are itemizing (PHP.xml, CSS.xml, etc.).
Itemizers define what syntax zones make up which items:
<?xml version="1.0"?>
<itemizer language-context="js">
<!-- Targeting a single zone is the simplest type of itemizer possible -->
<item name="js.comment">
<class>ESCommentItem</class>
<zone>js comment</zone>
</item>
<!-- You can also construct more complicated itemizers with start and end zones -->
<item name="js.function.anonymous">
<class>ESJSAnonymousFunctionItem</class>
<start-zone>js function.definition.anonymous + brace.round.open ~ brace.round.close + brace.curly.open</start-zone>
<end-zone>js brace.curly.close</end-zone>
<subitems>
<include-root-itemizers/>
</subitems>
</item>
</itemizer>
Defining a language-context
attribute on your root-level itemizer element is typically a good idea, as it vastly improves performance by limiting the itemizers Espresso has to parse for a given language.
The <class>
element is optional, and specifies the name of the compiled code classname that will control how your item is displayed in the Navigator (see below).
For a simple item, the <zone>
element is where you specify the syntax zone that represents the item's content.
For more complicated recipes, <start-zone>
and <end-zone>
specify the syntax zones that delimit the item. This allows you to construct itemizer definitions for things like groups, tag hierarchies, and similar.
Code folding automatically folds everything except for the start-zone and end-zone to continue to provide context in the code about what is folded.
The <subitems>
element specifies what items will be interpreted inside of this item. The special <include-root-itemizers/>
element will include all items or you can define additional item elements here that will only be active inside of this item.
Selectors within items
You can use :has-child()
and other niceties of selectors to get very fine-grained control over your items.
Additionally, itemizers provide a special ~(balanced)
selector that can be used within a <start-zones>
tag to ensure that braces are balanced properly (otherwise you sometimes get itemizers that will improperly capture most of the document). For instance:
<item name="js.function.named">
<start-zones>function.definition:has-child(name:capture(name)) + brace.round.open ~(balanced) brace.round.close + brace.curly.open</start-zones>
<end-zone>brace.curly.close</end-zone>
<subitems>
<include-root-itemizers/>
</subitems>
</item>
There are some important caveats for the ~(balanced)
combinator, however:
- It can only be used once per
<start-zones>
tag - All other selectors must be adjacent using the
+
combinator - The zones immediately surrounding the
~(balanced)
combinator must be simple selectors (in other words, no using things like:not()
,:has-child()
, or[text='']
;:capture()
is allowed, however)
Built-in Itemizer classes
Espresso includes the following classes:
- default (no class specified): basic styling; use
:capture(name)
to explicitly set the text output to the Navigator to the contents of a particular syntax zone ESCommentItem
: styles the item as a comment in the Navigator; automatically outputs the text of the comment (minus leading punctuation)ESCodeBlockItem
: styles the item as a generic code block, with the text "{ ... }" and no iconESCodeClassItem
: styles the item as a class with the icon ; use:capture(name)
to explicitly choose the zone to be used as the class name
Item name keywords
There are certain keywords that when included in your item name will trigger specific icons in the Navigator automatically. For instance, the following item will be styled like a function definition:
<item name="php.function">
<start-zones>function.definition:has-child(name:capture(name)) + brace.round.open ~ brace.round.close + brace.curly.open</start-zones>
<end-zone>brace.curly.close</end-zone>
<subitems>
<include-root-itemizers/>
</subitems>
</item>
Keywords include:
function
:comment
:collection
: prepends a folder icon to the texttag
: styles the text like an HTML tagprocessing-instruction
: styles the text like an HTML tag with a gear icon prepended
Non-generic classes
These classes are available, but are rarely useful for third-party plug-ins:
ESStyleItem
: styles the item as a CSS selectorESStyleImportItem
: styles the item as a CSS import statement with the iconESTagItem
: generic tag styling; automatically outputs any attributes included on the tagESXHTMLTagItem
: styles the item as an HTML tag, and outputs the ID and any classes (if available)