Sublime Text is a fast cross-platform editor with thousands of user-contributed packages implemented in its Python API. It is not free or open-source, although most of the user-contributed packages are both. Development is active as of June 2016.
Here, we outline several of the most important Sublime Text features that will help you to minimize your typing overhead and work more efficiently with your MathBook XML project. We also introduce the MBXTools package designed to help MathBook XML authors work more efficiently.
Sublime Text 2 and 3 are both available for an unlimited evaluation period, but a licence must be purchased for continued use. I have found the additional features of Sublime Text 3 to be well worth the cost of the license.
Sublime Text settings are stored and managed in a collection of JSON files as key-value pairs, in files that have a .sublime-settings extension. You change the settings by visiting these files and editing the values away from their defaults.
To edit your Sublime Text settings, you can use the Preferences/Settings — User menu (Sublime Text/Preferences… on OS X). Make sure that when you go to edit Settings, you always choose the User option. Changes to Default settings files will be overwritten when Sublime Text updates. It is recommended to use the Default files to see what settings are available to change. There are a lot, and not all are documented.
All Sublime Text users should be aware that a particular view (buffer) may receive settings in several different ways, e.g., from global default settings, from global OS-specific settings, from package-provided settings, from user-provided settings, and so on.
Key bindings are also stored in files with a similar format. There are only so many keyboard shortcuts available, although Sublime Text does support multistep shortcuts like Emacs. If you find that you wish to reassign shortcuts, this is certainly possible through the Preferences/Key Bindings — User menu (Sublime Text/Preferences… on OS X).
Sublime Text's Python API exposes a lot of the Sublime Text internals to plugin and package authors. Packages extend Sublime Text's functionality, much like Emacs major modes. A package usually consists of some Python scripts that define Sublime Text events and actions, some text-based configuration files (XML/JSON/YAML files defining language syntax, symbol recognition, custom snippet insertion triggers and contexts, keybindings for new and old commands, etc.), and perhaps some other stuff too. These typically get bundled into a .zip archive that is disguised with the unusual extension .sublime-package. These archives live in the Packages directory, accessible via the Preferences menu (the Sublime Text/Preferences menu on OS X). Sublime Text monitors the Packages directory for changes and reloads all affected plugins on the fly.
The first thing you should do after installing Sublime Text is install the Package Control package. This package manager operates within Sublime Text to automatically fetch updates for packages you have installed (unless you disable this feature). You can also list currently installed packages, find new packages to investigate, remove packages, etc.
Thousands of user-contributed packages are available for easy installation via Package Control. It is possible to maintain packages by hand, since most package authors publish via GitHub, but Package Control is the universally recommended method of obtaining, managing, and removing packages for your installation.
Visit the Package Control download site.
Find the Sublime Text console command (make sure the correct version of Sublime Text is selected) and copy it to the clipboard.
Open the Sublime Text console (Ctrl-`) and paste the command into the window that appears, then press Enter.
Having installed Package Control, you can use the command palette to deploy its commands, such as Install Package, List Packages, and Remove Package. See the documentation for more. A few packages that are especially useful are recommended throughout this section, and summarized in Subsection B.1.9.
Like many modern editors, Sublime Text has good project management features. These allow files that are part of a larger project to work together. For example, Sublime's Goto Anything command allows quick access to any file in a project. The Find in Project command permits users to search and replace (with or without regular expressions) across an entire project. Matches are displayed in a text buffer and double-clicking opens the relevant file at the appropriate position.
The sidebar provides a convenient view of all of the files and directories in a project—or, if you like, a filtered view, where files of your choice are excluded. The MBXTools package (Subsection B.1.7) also makes some use of project-specific settings in order to provide some of its functionality.
The easiest way to make use of the project management functionality is to store related files in a single directory and its subdirectories. If you then use the File/Open Folder… command, the entire directory is opened and all its subdirectories and files are shown in the sidebar. You can toggle the sidebar with either the command palette or directly with Ctrl+K, Ctrl+B (Cmd+K, Cmd+B on OS X).
By making use of this command you are already using project management, even if you never save your project. Sublime Text always has an implicit project open if you don't open an explicit one. This is good enough for many users a lot of the time, since it provides the most useful feature (Find/Find in Project). The Goto/Go To Symbol in Project command is also useful, but not fully implemented in MBXTools (Subsection B.1.7). Some of the benefits of explicit project management are outlined below.
To save your project explicitly, use the Project menu to choose Save As Project… and choose an appropriate name and location. For a MathBook XML project, this would probably be the same name and location as the document root file. Use the Project menu commands to open and close your project.
There are a few benefits to using an explicit project to group files.
You can group together files and folders in different parts of the filesystem, instead of being restricted to subtrees.
You can have project-specific settings that are different from Sublime Text's defaults and different from your user preferences (<<subsection-settings>>).
Sublime's project workspaces will remember which files you had open when you last closed the project, and at which positions.
If you get very fancy, you can have multiple workspaces for the same project, with different filters and views for different purposes.
It is fine to include .sublime-project files in Git repositories, but .sublime-workspace files should never be so included (according to the Sublime Text documentation).
Multiple selections are the single most useful and irreplaceable feature of Sublime Text, the one that will keep you coming back. From the documentation:
Any praise about multiple selections is an understatement.
The base functionality of multiple selections is simple. Hold down the Ctrl key (Cmd on OS X), and click somewhere in the open view to get a second cursor. Continue to add more cursors. All of them will behave together when you type: text will be inserted, most snippets or other text commands function as usual, etc. Even mouse commands work in an intuitive way with multiple selections.
It is hard to explain exactly what makes multiple selections so powerful. You just have to try it for yourself. Here is a typical example. In a structured document, many bits of text occur quite frequently—element and attribute names, for example. You may want to update several occurrences of a fragment at once—making several identical changes. Sublime's Quick Add Next command (Ctrl+D/Cmd+D) makes this a snap.
Place the caret somewhere in the word you'd like to modify.
Use Quick Add Next to expand your (empty) selection to the current word.
Use Quick Add Next again to add the next instance to the selection, which will then typically be disconnected.
Continue to Quick Add Next as many times as you like. Use Quick Skip Next (Ctrl+K, Ctrl+D/Cmd+K, Cmd+D) to jump over instances you would like to leave alone. If you go too far and select in error, hit Ctrl+U/Cmd+U to undo.
Make your modification, only one time.
Another example that occurs frequently when authoring XML is when you use the Wrap with Tag snippet (Alt+Shift+W/Ctrl+Shift+W). This snippet wraps the selection(s) in a <p> tag, with the tag name highlighted in both the start and end tags. If the p element is not what you wanted, just type. Both tags are replaced. This is a huge benefit to the XML author that makes essential use of multiple selections, even though you are barely aware of this as you use the feature.
Column selection allows you to select a rectangular area of a file. This is unbelievably useful when editing a structured document. There are lots of ways to do it (see the Sublime Text documentation for a mostly exhaustive list), but the most frequently used is to hold down Shift while clicking and dragging with the right mouse button (on OS X, hold down Option while dragging with the right mouse button). See the documentation for keyboard-based shortcuts.
Column selection becomes even more useful when used in combination with the keyboard shortcuts for moving and selecting, such as Ctrl+Shift+Right (select to end of word) and Shift+End (select to end of line).
Yet another example of the appallingly great utility of multiple selection comes when copying and pasting from a different file format. Suppose you have copied some lines of text and wish each such line to become a list item in your MathBook XML source.
Use column selection, as described above, to select each line individually.
Use Wrap with Tag to wrap each of the selected lines with matched begin/end <li> tags, all at once.
Now you have to select the lines again, to wrap them with matched begin/end <p> tags. First, hit Shift+End to select to end of line.
If your lines are wrapped, you may need to hit Shift+End again to get to the end of the wrapped lines.
Now you've selected too far: the </li> are selected as well. Hold down Ctrl+Shift and hit the left arrow twice (unselect by word). (After a little practice, steps like this seem automatic.)
Use Wrap with Tag to wrap each of the selected lines with matched begin/end <p> tags, all at once.
This does take a little mouse-work, but the keystroke savings can be considerable. (The Emmet package, described in Subsection B.1.6, provides an even quicker way to do this task and much more complicated ones.)
There are so many incredibly handy ways to use multiple selections that we will forgo any further examples to leave the reader the pleasure of discovering her own favorites. One particularly helpful package is Text Pastry, which provides some autonumbering and text insertion commands that work nicely with multiple selections. There are also a handful of packages that extend multiple selection functionality, such as PowerCursors and MultiEditUtils. PowerCursors allows you to add cursors and manipulate them without using the mouse. MultiEditUtils provides additional text processing commands designed to work with multiple selections.
Emmet is the most downloaded plugin for Sublime Text (1.82 million installs via Package Control). It is mostly used by HTML and CSS authors and provides a lot of functionality for them. It is also useful for writing XML, as we see below. The main benefits of working with Emmet are ease of tag creation, manipulation, and removal.
Emmet by default overrides Sublime's binding for the Tab key, endowing it with new behavior (the command Expand Abbreviation). This new behavior is to create a matching XML tag pair for whatever word is to the left of the caret, or with whatever words are selected. For example, if you were to type “ol” and press the Tab key, the resulting text would be
<ol></ol>with the caret positioned between the two newly created tags. Pressing Tab a further time moves the caret to the right of the end tag.
Emmet will produce any word it does not recognize into a matched tag pair when the Expand Abbreviation command is run. Some XML elements are empty, though. Within a matched tag pair, the command Split/Join Tag (Ctrl+Shift+`/Cmd+Shift+`) will contract it into an empty tag, removing any text between the existing begin and end tags. (If the caret is inside a tag for an empty element, this command replaces the empty element with a matching begin/end tag pair.)
The default behavior (creating tag pairs whenever Tab is pressed) interferes with Sublime Text's usual Tab-completion, which may be undesirable. It may be disabled by setting
"disabled_keymap_actions": "expand_abbreviation_by_tab"in the Preferences/Package Settings/Emmet/Settings — User file. The functionality of Expand Abbreviation will still be available through Ctrl+E.
For a more involved example of abbreviations, suppose you have pasted the items of an ordered list. Now you need to structure it with ol, li, and so on.
Lists are often good.
You can provide list items with <c>@xml:id</c>.
You probably don't want to number them, though.
The desired output is:
<li xml:id="item1">Lists are often good.</li>
<li xml:id="item2">You can provide list items with <c>@xml:id</c>.</li>
<li xml:id="item3">You probably don't want to number them, though.</li>
Using Emmet, one produces it by executing the Wrap as you Type command (Ctrl+Shift+G/Ctrl+W) and entering the following expression in the minibuffer.
The > symbol denotes a child element, the square brackets (with or without assignment) denote an attribute list, the $ provides the line-based numbering, and the * specifies wrapping each selected line with the indicated subtree (so each line is wrapped with <li><p>, instead of the entire selection).
Emmet can produce a large hierarchy of nested XML tags at various levels using this abbreviation syntax. For example, suppose you know that you will need to produce a tag structure of the following form.
Admittedly, this is a bit much, but it makes the point. The Emmet “abbreviation” for this structure is:
Upon typing this string and placing the caret to the right of it, hit Ctrl+E (or Tab, if you didn't disable the Emmet default). The entire tree structure is created immediately, with tab stops for the missing attribute values and for each matching begin/end pair.
The Expand Abbreviation As You Type command allows you to tweak such abbreviations interactively. Hit Ctrl+Alt+Enter and type the expression above into the minibuffer at the bottom of the window, watching the tree appear as you type.
Emmet is a very powerful package that can do much more than is outlined here. However, it is by default mostly adapted to writing CSS and HTML. Customizing it to work more directly with MathBook XML is an ongoing project. You can discover more about Emmet by examining the Emmet documentation or poking around in the Settings and Keymap files.
Git or SublimeGit