Sublime Forum

How to create a new language?

#1

Jon, can you give me some guidance on creating a new language?

Basically, I want to make a variant of Markdown which has it’s own settings and file extension, and later it’ll have it’s own language file. I’ve tried creating a package, but it doesn’t add anything to the list of file types in the bottom-right corner. Is this master-list of languages extensible?

Steve

0 Likes

Soda Theme - New Sublime Text 2 UI theme
Soda Theme - New Sublime Text 2 UI theme
Development Status - July 2014
Language auto-loading?
New logo discussion?
#2

These days Sublime Text uses TextMate style syntax definitions in *.tmLanguage files. There’s an introduction at http://macromates.com/textmate/manual/language_grammars.

You can download existing ones from code.google.com/p/tmbundles4win/, the only caveat being that the files must have a .tmLanguage extension. Some already do, others have to be renamed from .plist to .tmLanguage to be recognised.

It’s worth noting that sublime uses Apple’s byzantine propertly-list-in-xml format, which is equivalent to what you see in the above documentation, but more verbose.

Any syntax definition that has file extensions associated with it appears as a selectable option, so if you make sure you have:

...
<key>fileTypes</key>
<array>
	<string>some-extension</string>
</array>
...

then it’ll be an available choice.

Note that tmLanguage files are not presently auto reloaded, which I realise isn’t ideal.

wrt the settings, just make a *.sublime-options file with the same base name as the .tmLanguage file, and it’ll get picked up.

Below is a simple example of a definition that marks up *.sublime-options files, which will be included in the next beta:

<?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>fileTypes</key>
	<array>
		<string>sublime-options</string>
		<string>sublime-build</string>
	</array>
	<key>name</key>
	<string>Sublime Options</string>
	<key>patterns</key>
	<array>
		<dict>
			<key>captures</key>
			<dict>
				<key>1</key>
				<dict>
					<key>name</key>
					<string>punctuation.definition.comment.sublime-options</string>
				</dict>
			</dict>
			<key>match</key>
			<string>(#).*$\n?</string>
			<key>name</key>
			<string>comment.line.number-sign.sublime-options</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(:?[1-9]+[0-9]*|0)\b</string>
			<key>name</key>
			<string>constant.numeric.integer.decimal.sublime-options</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(:?true|false)\b</string>
			<key>name</key>
			<string>constant.language.sublime-options</string>
		</dict>
	</array>
	<key>scopeName</key>
	<string>source.sublime-options</string>
</dict>
</plist>

Ctrl+Alt+P is a handy key binding to keep in mind as you’re developing a syntax definition, it shows you the name assigned to the character that’s just to the right of the cursor.

0 Likes

#3

OK, great! I’ve got a project I’m working on with a fiction author, and I should be able to develop, basically, a custom fiction-writing IDE for him entirely in Sublime. Sweet.

(BTW, I noticed that the .package-menu files aren’t registered as being XML files, so they don’t syntax highlight yet.)

0 Likes

#4

I’ve added this info to the wiki at sublimetextwiki.com/cgi-bin/ … wnLanguage

0 Likes

#5

Anyone out there trying this, you’ll find yourself restarting sublime A LOT. If you have python installed, you can run this script; it’ll create a new instance of Sublime every time you close. Very useful for reloading those .tmLanguage files.

# endlessly sublime
#
# reloads sublime text over and over and over... 
# useful if you need to restart A LOT, for example
# while developing languages

import os, sys, subprocess

sublimePath = "c:\\program files\\sublime text\\sublimetext.exe"

i = 0
while i < 100: # limited just in case it starts spawning forever...
  os.spawnl(os.P_WAIT, sublimePath)
  i = i + 1
0 Likes

#6

Well, that’s it – I’ve got a package written with a very basic markup language, and it’s all highlighing beautifully. Thanks, Jon.

0 Likes

#7

Excellent! I’ll take a look at getting tmLanguage files auto reloading, it’s unduly painful atm.

0 Likes

#8

Heh. You knew I couldn’t go ten minutes without requesting an API feature…

So, I’m liking the way that the lexer is giving me syntax highlighting. I’ve invented a mini-markup language. Neat!

Now, of course, I want to write a program that parses the markup using the same rules as the syntax highlighter.

Ie, if I’m using this syntax for creating emphasis;

here is an important message

I’d love to get a hierarchical version of the output, something like;

{
doc =
{
text = "here is an ",
markup.italic.script = “important”,
text = “message”
}
}

If, by some stroke of luck, such a thing is available in ST, is it possible to get hold of it?

0 Likes

#9

There’s the API function extractScope, which will return the extents of a given region. However, in terms of extracting an AST of the buffer, it’s not great - it doesn’t descend into children. e.g, if you give it a point in a string, it’ll give you the extents of the string, but it won’t notify you of any escaped characters, interpolated code etc contained within the string.

There’s no reason the full tree structure of the buffer couldn’t be exposed though.

There’s also a stand alone TM syntax parser, which may be of interest:

ultraviolet.rubyforge.org/

0 Likes

#10

Hi, Jon. Cheers. I’m getting the regions at start-and-end tuples. Is there any way to get the text that you’d see if you press ctrl-alt-p? I think with that, I can probably create the AST.

Also, the markup language isn’t that complex, so I can recreate the lexer; it’s not a biggie.

0 Likes

#11

There’s no way to get that yet, I’ll add a couple of functions for the next beta:

view.syntaxName(point): Get the name at the given point
view.matchSelector(point, selector): Evaluate the selector vs. the name at the given point, returning True iff it matches

0 Likes

#12

That sounds great. Then I can scan through the file, building up an index of (position, syntax names). That’ll give me enough to build a hierarchy. Thanks.

0 Likes

#13

Hi,

I’ve made a reStructuredText package for Sublime here http://kib2.free.fr/Sublime/reStructuredText.sublime-package,
no problem for the syntax highlighting but I’ve got some with the only snippet inside (I don’t know why exactly, and don’t have much time yet).

All files are utf-8 encoded because I’m currently working with Sublime under Linux+wine (the only thing annoying is that I can’t launch my Python scripts from wine).

See you, hoping to see a Linux version soon :smile:

0 Likes

#14

Nice stuff!

The key binding should be using “text.restructedtext” rather than “source.restructuredtext” for the context, as that’s what reStructuredText.tmLanguage declares (You can see it when you’ve got a file open using that syntax highlighting, and press Ctrl+Alt+P)

0 Likes

#15

Thanks for the tip Jon,

I will try to add some snippets now.
Do you know how to launch a Python script from Sublime under Wine ?

0 Likes

#16

As in, to have Tools/Build System/Python work?

It relies on python.exe being in the system path, perhaps that’s what’s not working for you under Wine.

0 Likes

#17

[quote=“jps”]As in, to have Tools/Build System/Python work?

It relies on python.exe being in the system path, perhaps that’s what’s not working for you under Wine.[/quote]

That’s the problem indeed : can I set it to my own Python’s executable under Linux ?

0 Likes

#18

If you edit the file Packages/Python/Python.sublime-build (Normally found under C:\Documents and Settings<username>\Application data\Sublime Text on XP), then you can try changing ‘python.exe’ to /usr/bin/python, and see if that works.

0 Likes

#19

Hi Jon,

I’ve tried without success.

My build command is not set to this one :

buildCommand exec ' *File "(...*?)", line ([0-9]*)' usr/bin/python'"$File"'

(What’s the ‘line ([0-9]*’ ? I suspect in the future I could choose some part of code to run, that’s it ? )

Here’s the message Sublime send me :

running command /usr/bin/python'"Z:\home\kib\Bureau\Programmation\Python\RecupBases\recup.py"' Spawn: trying c:\windows\system32\cmd.exe /A /S /C "/usr/bin/python'"Z:\home\kib\Bureau\Programmation\Python\RecupBases\recup.py"'"

A few questions now:

  • How can I set the console output by default ? I haven’t seen any option in configuration files for it.
  • Can snippets be nested inside each other ?
  • Does code folding is on your todo list ?

Thanks again.

0 Likes

#20

I’m not quite sure what you mean here, could you elaborate a bit?

Do you mean, some directive inside the *.sublime-snippet file to include another snippet? There’s no functionality for that yet, I can add it to the todo list though.

It sure is! It’s behind things like the project manager and symbol list in priority though.

0 Likes