Re: [ace] Working with new Emmet and Snippet features

2,095 views
Skip to first unread message

Harutyun Amirjanyan

unread,
Apr 1, 2013, 3:40:50 PM4/1/13
to ace-d...@googlegroups.com
To get ace.require("ace/ext/emmet") to work in prebuilt version
include it into
https://github.com/ajaxorg/ace/blob/master/lib/ace/ace.js#L56 before
building, (same for snippets)

Ryan Griffith

unread,
Apr 2, 2013, 9:30:57 AM4/2/13
to ace-d...@googlegroups.com
Thank you for the response. I am definitely getting closer as Emmet is loading up; however, I am getting the following error within AceEmmetEditor.setupContext on the line of emmet.require('resources')...;

Uncaught TypeError: Cannot call method 'require' of undefined

I also noticed the commands are not loading either. I know this feature is still a work in progress, but wanted to see if anyone has encountered this error and what I can do to resolve it.

With regards to the snippets feature, it looks like adding the require statement loaded things; however, I do not see the SnippetManager anywhere within the editor object. Is there anything additional that I need in order to load the manager, and associated snippet files?

Harutyun Amirjanyan

unread,
Apr 2, 2013, 9:47:03 AM4/2/13
to ace-d...@googlegroups.com
you need to include emmet files separately see
https://github.com/ajaxorg/ace/blob/master/demo/kitchen-sink/demo.js#L465

snippetmanager currently doesn't add anything to the editor
and you need something like
https://github.com/ajaxorg/ace/blob/master/demo/kitchen-sink/demo.js#L474-L513
to register keybinding and add some default snippets

Ryan Griffith

unread,
Apr 2, 2013, 12:05:05 PM4/2/13
to ace-d...@googlegroups.com
This was definitely very helpful. I now have the Emmet extension up and running (chose to load the Emmet library using a script tag vs loading it within ace).

I am getting closer with the snippets. I was able to successfully create the SnippetManager and load a snippet file (javascript); however, parseSnippetFile is returning an empty array for some reason.

Harutyun Amirjanyan

unread,
Apr 2, 2013, 12:29:22 PM4/2/13
to ace-d...@googlegroups.com
snippets file is just an empty file with require("text!..."), most likely
required javascript.snippets file isn't present in your build

Ryan Griffith

unread,
Apr 2, 2013, 2:09:53 PM4/2/13
to ace-d...@googlegroups.com
I noticed that as well, but did confirm javascript.snippets does exist and is being loaded with the build (and snippetText is present).

Harutyun Amirjanyan

unread,
Apr 2, 2013, 2:28:21 PM4/2/13
to ace-d...@googlegroups.com
maybe whitespace is removed during the build,
try deleting this line
https://github.com/ajaxorg/ace/blob/master/Makefile.dryice.js#L475

Ryan Griffith

unread,
Apr 2, 2013, 2:49:56 PM4/2/13
to ace-d...@googlegroups.com
Hm, that doesn't seem to have affected things. 

I tried logging the m variable right inside of the while loop in parseSnippetFile (https://github.com/ajaxorg/ace/blob/master/lib/ace/snippets.js#L488) and it looks like the match is the entire snippetText content. I confirmed the text within the build does have line breaks in it.

Harutyun Amirjanyan

unread,
Apr 2, 2013, 3:01:13 PM4/2/13
to ace-d...@googlegroups.com
does it have tabs too?

Ryan Griffith

unread,
Apr 3, 2013, 7:24:11 AM4/3/13
to ace-d...@googlegroups.com
Yup, tabs are there as well.

Ryan Griffith

unread,
Apr 3, 2013, 9:55:34 AM4/3/13
to ace-d...@googlegroups.com
I've been playing around with the code a bit and can't seem to get the regex within parseSnippetFile to match the snippets within the text. I was also attempting to test the regex with a few external tools and also could not seem to get things to work.

Harutyun Amirjanyan

unread,
Apr 3, 2013, 10:21:38 AM4/3/13
to ace-d...@googlegroups.com
try parseSnippetFile("name 1\n\ta${0}\nsnippet 2\n\tb{1:x}2$1")
maybe it is a problem with windows line endings
try modifying the regex to /^#.*|^({[\s\S]*})\s*$|^(\S+)
(.*)$|^((?:[\r\n]*\t.*)+)/gm;

Ryan Griffith

unread,
Apr 3, 2013, 10:40:13 AM4/3/13
to ace-d...@googlegroups.com
Thank you for the response. The sample snippet did seem to work; however, the updated regex still produced the same result. The sample snippet and the new regex do work as well.

Could it be something with the way snippetText is being generated? I still have that line commented out in the builder, but did try both with and without the line with no luck.

Ryan Griffith

unread,
Apr 3, 2013, 2:00:18 PM4/3/13
to ace-d...@googlegroups.com
Still toying around with this. 

I stripped down the JavaScript snippetText that was generated within the ace build to only the proto snippet and replaced newlines (and the \) with \n and that seemed to work. It seems that the newlines present within exports.snippetText in ace.js are not being properly converted over. I confirmed this by outputting the origina snippetText within console and saw there were no new lines at all. There were; however, newlines when I replaced the newlines with \n.

Ryan Griffith

unread,
Apr 3, 2013, 3:41:21 PM4/3/13
to ace-d...@googlegroups.com
Definitely confirmed the issue is that the snippetText containing the multi-line text (using \\n I believe) does not actually generate a newline character, so the regex will fail every time. I couldn't even get the demo to work.

Although not ideal, what I chose to do is throw the snippet files somewhere public and load them dynamically using jQuery. This does bring over the newlines and generates the snippets as expected. Perhaps there is another way to load these plain text snippet files so the newlines are preserved?

Ryan Griffith

unread,
Apr 3, 2013, 4:46:13 PM4/3/13
to ace-d...@googlegroups.com
After some additional messing around with the builder script, I was able to get the snippets to work by commenting out line 475 and changing line 476 to the following:

input = '"' + input.replace(/\r?\n/g, '\\n') + '"';

This replaces the \ with newline multi-line string with simply a "\n" character, which will allow the parser to work. I'm not sure if this affects anything else within the Ace build, but things seem to be working ok. I'm still a little hesitant about having to create a JS file for each snippet I wish to load and adding an additional require statement to generate the snippetText string. 

Not sure if this is possible, but would it be more efficient to move the loading of the snippets feature into an extension and remove the extra JS dependency?

Harutyun Amirjanyan

unread,
Apr 3, 2013, 5:52:01 PM4/3/13
to ace-d...@googlegroups.com
>Not sure if this is possible, but would it be more efficient to move the loading of the snippets feature into an extension and remove the extra JS dependency?

For now there is no code for loading snippets,
there is snippetManager which isn't required from editor and bunch of
`language.snippets` files taken from snipmate
I am too, not sure how to best integrate snippetManager into rest of the ace.

How do you want to use ace snippets? do you need to add snippets
written by users or only the default ones provided by ace?

I want to add ace/ext/snippets.js file
people using require.js will need to use require() to get it
and those using prebuilt version can either include script or call
ace.config.loadModule

When loaded it will add editor.insertSnippet method and will handle
loading of default snippets from ace/snippets folder
Loading languageName.snippets file with xhr isn't always possible
because of cross origin restrictions, so they need to be wrapped in
.js file in some way, (also having js files will allow to add some
language specific logic, many textmate snippets use inline shell code
for that, but i am not sure how useful it would be)

But generally snippets are not tied to any specific format, and can be
used like this too
https://github.com/zefhemel/zed/blob/master/app/settings/mode/javascript.default.json#L41
https://github.com/zefhemel/zed/blob/master/app/js/complete/snippet.js#L4
https://github.com/zefhemel/zed/blob/master/app/js/complete.js

Ryan Griffith

unread,
Apr 4, 2013, 7:45:47 AM4/4/13
to ace-d...@googlegroups.com
> How do you want to use ace snippets? do you need to add snippets written by users or only the default ones provided by ace? 

For this project, I have a jQuery plugin that creates a sort of wrapper to Ace and a simple UI (similar to the recent Settings/Keybindings Menu pull, but with jQuery). What I think I'd like to do is load a subset of the existing snippets (and eventually some custom ones) based on an option within the jQuery plugin. So, the way snippets is loaded isn't necessarily a concern. I'd like to avoid customizing the core Ace as much as possible, moving snippets into an extension and using loadModule could be an option; however, it is also adding one more request to pull the extension in. Either way, I need to build Ace to get those snippets loaded in.

One portion I think may need some tweaking is the dependency of the additional snippets/language.js file that is used to pull in the corresponding language.snippets. Perhaps I could just have a map of the snippets I wanted, I could iterate over that and use requirejs/text! to build a map of snippet text. This would bypass the need for the extra file.

Ryan Griffith

unread,
Apr 4, 2013, 2:00:37 PM4/4/13
to ace-d...@googlegroups.com
So I think I have snippets pretty much ready to go. 

One issue I am running into is getting them to work in IE8. What ends up happening is after hitting tab the last snippet found is added after the cursor at the time of hitting tab. So the tabbing and inserting sort of works, but not quite. It looks like tabTrigger is getting lost when snippets are being recorded within parseSnippetFile, when I output the value of tabTrigger at this point it's undefined. 

Here's a screenshot of the end result:


Ryan Griffith

unread,
Apr 4, 2013, 2:35:35 PM4/4/13
to ace-d...@googlegroups.com
It looks like the issue is with the regex used to set tabTrigger at https://github.com/ajaxorg/ace/blob/master/lib/ace/snippets.js#L507, where there is a value returned in Chrome but not in IE8. I was able to fix this by using:

snippet.tabTrigger = val.split(/^(\S*)(?:\s(.*))?$/)[1] || val;

Do you know what this regex is doing by chance? I want to be sure this adjustment won't affect anything negatively.

Harutyun Amirjanyan

unread,
Apr 4, 2013, 2:44:08 PM4/4/13
to ace-d...@googlegroups.com
hmm, not sure why i used that instead of val.match(/^\S*/)[0] which
does the same, gets text before the first whitespace

Ryan Griffith

unread,
Apr 4, 2013, 2:48:28 PM4/4/13
to ace-d...@googlegroups.com
Looks like match does indeed work fine, but split doesn't. Would it be safe to use match in this case as a workaround? 

I found this article that indicates split with regex a delimiter can yield different results between browsers.

Ryan Griffith

unread,
Apr 4, 2013, 2:54:48 PM4/4/13
to ace-d...@googlegroups.com
Curious, but I wonder if https://github.com/ajaxorg/ace/blob/master/lib/ace/snippets.js#L501 should also be updated for better cross-browser support.  saw a few other instances of String.split(RegExp) within Ace, but I'm guessing more complex regex's are the main culprit.

Harutyun Amirjanyan

unread,
Apr 4, 2013, 3:21:30 PM4/4/13
to ace-d...@googlegroups.com
you are right, split with capturing regexp doesn't work on ie
fixed in https://github.com/ajaxorg/ace/pull/1346

Ryan Griffith

unread,
Apr 4, 2013, 3:22:05 PM4/4/13
to ace-d...@googlegroups.com
Ah, match would result in something completely different. I noticed the JavaScript snippets that used regex were choking in IE8, so I gave up and used the code from the article I linked above and dropped it into a string library file. Included that file and it works like a charm now.

Ryan Griffith

unread,
Apr 4, 2013, 3:57:43 PM4/4/13
to ace-d...@googlegroups.com
Great, thank you for including this fix. Looks a bit more self-contained and less complicated than including that String.split method. 

Daniel Florey

unread,
Jun 27, 2013, 9:09:32 AM6/27/13
to ace-d...@googlegroups.com
Hi,
is there a way for a numb new user to get this up and running with the pre-build versions?
Any help appreciated!
Thanks!

Am Montag, 1. April 2013 20:17:40 UTC+2 schrieb Ryan Griffith:
I saw the latest Ace source includes support for Emmet and Textmate-like Snippets; however, I can not seem to get them to work with the pre-built version of Ace (built using the latest source).

For example, with Emmet I have tried using ace.require("ace/ext/emmet") assuming I should be including the extension, but this does not seem to be doing anything. The code of the extension looks like it mimics the code within the demo, minus the loading of an extra emmet JS file. I've checked the options of the editor and do not see the registered Emmet option.

The same goes with the snippets, I have tried to mimic the demo, but can not seem to get the snippets working.

Any advice would be greatly appreciated.

Harutyun Amirjanyan

unread,
Jul 1, 2013, 6:20:29 AM7/1/13
to ace-d...@googlegroups.com
Hi Daniel

see https://groups.google.com/forum/#!topic/ace-discuss/qMWbjj53uf8
but there is no prebuilt version with autocomplete, so you'll have to
build it yourself, or wait a week or two

Daniel Florey

unread,
Jul 4, 2013, 9:07:45 AM7/4/13
to ace-d...@googlegroups.com
Hi,
thanks for your prompt reply!
I'll wait for the next release then.
Keep up the great work!
Daniel

Ryan Griffith

unread,
Dec 2, 2013, 3:19:47 PM12/2/13
to ace-d...@googlegroups.com
Don't mean to open this up again, but I am having issues again with the parseSnippetFile method not properly parsing my snippet file. I believe the issue previously was with newlines. Oddly, the current code looks pretty much the same as what I had working previously.

If I duplicate and rename an existing snippet file it works fine. I am using Sublime Text 2 for editing and default settings. Is there something I should be looking out for when editing these files, or some kind of newline setting I should look for?

Ryan Griffith

unread,
Dec 2, 2013, 4:19:14 PM12/2/13
to ace-d...@googlegroups.com
Quick update. It looks as though the issue may be related to the way tabs are handled in the regex. If I change my tab settings to tabs instead of spaces it seems to work.
Reply all
Reply to author
Forward
0 new messages