Sometimes I use Sublime Text for writing reminders.
I always use the same layout for this task which looks like this :
>Title
>>Subtitle
>>>Comment
> Title
>> ...
Where a >
represent a tab character
So I'm wondering if it's possible to create my own syntax highlighting for this kinds of files, with one color for the title, another one for the subtitle and the regular color for the comment.
Syntax highlighting is performed using .tmLanguage
syntax definitions. They are formatted in Apple's XML-based PLIST format, although thanks to the excellent Sublime plugin PackageDev
they can be written in JSON or in YAML, which I chose for its compactness, and the fact that I get sweet syntax highlighting with it using my theme*.
So, your syntax is very straightforward. You'll have three rules:
- Matching lines beginning with a single tab as "Title" lines
- Matching lines beginning with two tabs as "Subtitle" lines
- Matching lines beginning with three tabs as "Comment" lines.
Everything else will be displayed by Sublime as plain text.
Here it is, in YAML:
# [PackageDev] target_format: plist, ext: tmLanguage
---
name: Reminders
comment: Written for http://stackoverflow.com/q/25689365/1426065 by @MattDMo
scopeName: text.reminders
fileTypes: [todo]
uuid: 6B548E74-5E01-497A-B030-9D31131B7A70
patterns:
- name: text.title.reminders
match: ^\t(?!\t+)(.*)
- name: text.subtitle.reminders
match: ^\t\t(?!\t+)(.*)
- name: text.comment.reminders
match: ^\t\t\t(.*)
Everything is pretty straightforward. The name is what shows up in the bottom right corner of Sublime, it was written by me, its base scope name is text.reminders
, opening a file with the .todo
extension will automatically apply this syntax, and the UUID is just a unique identifier. As I mentioned above, there are three patterns. One thing to keep in mind: this will only match if the line begins with a literal tab character, not space characters being inserted as a tab! That means you'll need to select
View -> Indentation
and make sure Indent Using Spaces
is NOT checked. Just for good measure, select View -> Indentation -> Convert Indentation to Tabs
as well. These settings can be applied just to "Reminders" views, I'll cover that later.
So we have our YAML, which is useless if you don't have PackageDev
. However, translated to a PLIST it works much better:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>comment</key>
<string>Written for http://stackoverflow.com/q/25689365/1426065 by @MattDMo</string>
<key>fileTypes</key>
<array>
<string>todo</string>
</array>
<key>name</key>
<string>Reminders</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>^\t(?!\t+)(.*)</string>
<key>name</key>
<string>text.title.reminders</string>
</dict>
<dict>
<key>match</key>
<string>^\t\t(?!\t+)(.*)</string>
<key>name</key>
<string>text.subtitle.reminders</string>
</dict>
<dict>
<key>match</key>
<string>^\t\t\t(.*)</string>
<key>name</key>
<string>text.comment.reminders</string>
</dict>
</array>
<key>scopeName</key>
<string>text.reminders</string>
<key>uuid</key>
<string>6B548E74-5E01-497A-B030-9D31131B7A70</string>
</dict>
</plist>
In Sublime, create a new file with XML syntax and copy the above XML into it. Find your Packages
directory by selecting Preferences -> Browse Packages...
then save this new file as Packages/User/Reminders.tmLanguage
(make sure the L
in tmLanguage
is capitalized). There should now be a "Users -> Reminders" option in the language list in the bottom right of Sublime, or through the View -> Syntax
menu option.
However, there's one more thing to do - get coloring. To do this you'll need to modify your .tmTheme
color scheme file. Since you're using Sublime Text 2 (I assume), it's pretty easy. Open Preferences -> Settings-User
and check the value of "color_scheme"
. Open the color scheme file by selecting File -> Open...
, navigating to the Packages
directory you found earlier with Preferences -> Browse Packages...
, and opening the file in whatever subdirectory it's in. For example, if your settings file says "color_scheme": "Packages/Color Scheme - Default/Monokai.tmTheme"
you'll navigate to the Packages/Color Scheme - Default
directory in the open file dialog and open Monokai.tmTheme
. Super easy.
Now that you have your color scheme file open, you can set the syntax to XML if you want, then scroll all the way down to the bottom. You'll want to insert your new colors (I'll get to that in a minute) above the lines that say:
</array>
<key>uuid</key>
<string>06CD1FB2-A00A-4F8C-97B2-60E131912345</string>
</dict>
</plist>
The UUID may not even be there, it might just say:
</array>
</dict>
</plist>
Regardless, whichever is there should always be the last lines in the file, or things will break. At any rate, above these lines, insert the following dicts:
<dict>
<key>name</key>
<string>Reminders - Title</string>
<key>scope</key>
<string>text.reminders text.title.reminders</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>bold italic</string>
<key>foreground</key>
<string>#00FF00</string>
<key>background</key>
<string></string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Reminders - Subtitle</string>
<key>scope</key>
<string>text.reminders text.subtitle.reminders</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#FF0080</string>
<key>background</key>
<string></string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Reminders - Comment</string>
<key>scope</key>
<string>text.reminders text.comment.reminders</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string></string>
<key>background</key>
<string></string>
</dict>
</dict>
Feel free to customize the foreground
and background
colors and the fontStyle
attributes ("bold" and "italic" are the only working values) however you like.
One more thing, if you'll remember - setting Sublime to use tabs just in Reminders views. Create a new file using JSON syntax, or if you installed PackageDev
, with "Sublime Settings" syntax. Add to it the following:
{
"translate_tabs_to_spaces": false,
"extensions":
[
"todo"
]
}
(Yes, I know "todo" is already in the language definition, I just like to be safe). You can add any other option here that's used in the Preferences -> Settings-Default
and ... -> Settings-User
files, just make sure the file is valid JSON. Save the file as Packages/User/Reminders.sublime-settings
.
And that's it! You may need to restart Sublime for the changes to kick in, but then you're all set. To recap, the steps to making a new syntax definition are as follows:
- Get
PackageDev
, your life will be a lot easier.
- Write highlighting regexes in JSON or YAML format using the Oniguruma regex language, testing online with tools like Rubular (using Ruby 1.9.2 option).
- Compile to PLIST/XML.
- Modify color scheme for new scopes.
- Create a
.sublime-settings
file for syntax-specific settings like tabs.
- ???
- Profit!
* linked in my user profile if you're interested...