diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js
index 81d7c024..a4ba5c53 100644
--- a/demo/kitchen-sink/demo.js
+++ b/demo/kitchen-sink/demo.js
@@ -120,14 +120,14 @@ env.editor.commands.addCommands([{
name: "snippet",
bindKey: {win: "Alt-C", mac: "Command-Alt-C"},
exec: function(editor, needle) {
- if (typeof needle == "object") {
+ if (typeof needle == "object") {
editor.cmdLine.setValue("snippet ", 1);
editor.cmdLine.focus();
return;
}
- var s = SnippetManager.getSnippetByName(needle, editor);
- if (s)
- SnippetManager.insertSnippet(editor, s.content);
+ var s = SnippetManager.getSnippetByName(needle, editor);
+ if (s)
+ SnippetManager.insertSnippet(editor, s.content);
},
readOnly: true
}, {
@@ -169,7 +169,7 @@ commands.addCommand({
exec: function() {alert("Fake Save File");}
});
-var keybindings = {
+var keybindings = {
ace: null, // Null = use "default" keymapping
vim: require("ace/keyboard/vim").handler,
emacs: "ace/keyboard/emacs",
@@ -375,7 +375,7 @@ bindDropdown("split", function(value) {
sp.setSplits(1);
} else {
var newEditor = (sp.getSplits() == 1);
- sp.setOrientation(value == "below" ? sp.BELOW : sp.BESIDE);
+ sp.setOrientation(value == "below" ? sp.BELOW : sp.BESIDE);
sp.setSplits(2);
if (newEditor) {
@@ -449,22 +449,33 @@ require("ace/placeholder").PlaceHolder;
var SnippetManager = require("ace/snippets").SnippetManager
var jsSnippets = require("ace/snippets/javascript");
-var testSnippet = "\
-\\begin{${1:document}}\n\
- ${2:$TM_SELECTED_TEXT:some ${3:latex}}\n\
- ${3:$TM_SELECTED_TEXT/a/b/c}\n\
- ${4:${TM_SELECTED_TEXT/(.)/\\u$1/c:7}}\n\
-\\end{$1}\n\
-$0";
-SnippetManager.register({
- content: testSnippet,
- tabTrigger: "t",
- name: "testSnippet"
-})
-jsSnippets.snippets = SnippetManager.parseSnippetFile(jsSnippets.snippetText)
-SnippetManager.register(jsSnippets.snippets, "javascript")
window.SnippetManager = SnippetManager
+function saveSnippets() {
+ jsSnippets.snippets = SnippetManager.parseSnippetFile(jsSnippets.snippetText);
+ SnippetManager.register(jsSnippets.snippets, "javascript")
+}
+
+env.editSnippets = function() {
+ var sp = env.split;
+ sp.setSplits(1);
+ sp.setSplits(2);
+ sp.setOrientation(sp.BESIDE);
+ var editor = sp.$editors[1]
+ if (!env.snippetSession) {
+ var file = jsSnippets.snippetText;
+ env.snippetSession = doclist.initDoc(file, "", {});
+ env.snippetSession.setMode("ace/mode/tmsnippet");
+ env.snippetSession.setUseSoftTabs(false);
+ }
+ editor.on("blur", function() {
+ jsSnippets.snippetText = editor.getValue();
+ saveSnippets();
+ })
+ editor.setSession(env.snippetSession, 1);
+ editor.focus();
+}
+
ace.commands.bindKey("Tab", function(editor) {
var success = SnippetManager.expandWithTab(editor);
if (!success)
diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js
index 414acce0..eaf29275 100644
--- a/demo/kitchen-sink/doclist.js
+++ b/demo/kitchen-sink/doclist.js
@@ -54,6 +54,7 @@ function initDoc(file, path, doc) {
var mode = modelist.getModeFromPath(path);
session.modeName = mode.name;
session.setMode(mode.mode);
+ return session;
}
diff --git a/demo/kitchen-sink/docs/tmSnippet.tmSnippet b/demo/kitchen-sink/docs/tmSnippet.tmSnippet
index 6ea4117f..78282d18 100644
--- a/demo/kitchen-sink/docs/tmSnippet.tmSnippet
+++ b/demo/kitchen-sink/docs/tmSnippet.tmSnippet
@@ -1,19 +1,26 @@
-$$------------------------------------
-tabTrigger: t
-name: Heading 3
-scope: language
-content: -----------------------------
-\begin{${1:documnet}}
- ${2:$TM_SELECTED_TEXT:some latex}
- ${3:$TM_SELECTED_TEXT/a/b/c}
- ${4:${TM_SELECTED_TEXT/(.)/\\u$1/g:7}}
-\end{$1}
-$0\\$$
-$$------------------------------------
-tabTrigger: ^3
-name: Heading 3
-scope: language
-content: -----------------------------
-
-${TM_CURRENT_LINE/./^/g}
-$$------------------------------------
\ No newline at end of file
+# Function
+snippet fun
+ function ${1?:function_name}(${2:argument}) {
+ ${3:// body...}
+ }
+# Anonymous Function
+regex /((=)\s*|(:)\s*|(\()|\b)/f/(\))?/
+name f
+ function${M1?: ${1:functionName}}($2) {
+ ${0:$TM_SELECTED_TEXT}
+ }${M2?;}${M3?,}${M4?)}
+# Immediate function
+trigger \(?f\(
+endTrigger \)?
+snippet f(
+ (function(${1}) {
+ ${0:${TM_SELECTED_TEXT:/* code */}}
+ }(${1}));
+# if
+snippet if
+ if (${1:true}) {
+ ${0}
+ }
+
+
+
\ No newline at end of file
diff --git a/demo/kitchen-sink/modelist.js b/demo/kitchen-sink/modelist.js
index f35354dd..b3c686ef 100644
--- a/demo/kitchen-sink/modelist.js
+++ b/demo/kitchen-sink/modelist.js
@@ -98,7 +98,7 @@ var modesByName = {
tex: ["Tex" , "tex"],
text: ["Text" , "txt"],
textile: ["Textile" , "textile"],
- tmsnippet: ["tmSnippet" , "tmSnippet"],
+ tmsnippet: ["tmSnippet" , "tmSnippet"],
toml: ["toml" , "toml"],
typescript: ["Typescript" , "typescript|ts|str"],
vbscript: ["VBScript" , "vbs"],
diff --git a/kitchen-sink.html b/kitchen-sink.html
index 33bc19a7..7068e779 100644
--- a/kitchen-sink.html
+++ b/kitchen-sink.html
@@ -13,20 +13,20 @@
-
+
-
+
@@ -151,7 +151,7 @@
-
+
|
|
-
+
diff --git a/lib/ace/mode/_test/tokens_tmsnippet.json b/lib/ace/mode/_test/tokens_tmsnippet.json
index 17eaeb47..f695403d 100644
--- a/lib/ace/mode/_test/tokens_tmsnippet.json
+++ b/lib/ace/mode/_test/tokens_tmsnippet.json
@@ -1,132 +1,209 @@
[[
"start",
- ["doc,comment","$$------------------------------------"]
+ ["comment","# Function"]
],[
"start"
],[
"start",
- ["text","tabTrigger: t"]
+ ["constant.language.escape","snippet"],
+ ["text"," fun"]
],[
"start"
],[
- "start",
- ["text","name: Heading 3"]
-],[
- "start"
-],[
- "start",
- ["text","scope: language"]
-],[
- "start"
-],[
- "start",
- ["text","content: -----------------------------"]
-],[
- "start"
-],[
- "start",
- ["text","\\begin{"],
+ "sn-start",
+ ["text","\tfunction "],
["markup.list","${"],
["constant.numeric","1"],
- ["punctuation.operator",":"],
- ["text","documnet"],
+ ["text","?:function_name"],
["markup.list","}"],
- ["text","}"]
-],[
- "start"
-],[
- "start",
- ["text"," "],
+ ["text","("],
["markup.list","${"],
["constant.numeric","2"],
["punctuation.operator",":"],
- ["keyword","$TM_SELECTED_TEXT"],
- ["text",":some latex"],
- ["markup.list","}"]
+ ["text","argument"],
+ ["markup.list","}"],
+ ["text",") {"]
],[
"start"
],[
- "start",
- ["text"," "],
+ "sn-start",
+ ["text","\t\t"],
["markup.list","${"],
["constant.numeric","3"],
["punctuation.operator",":"],
+ ["text","// body..."],
+ ["markup.list","}"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t}"]
+],[
+ "start"
+],[
+ "start",
+ ["comment","# Anonymous Function"]
+],[
+ "start"
+],[
+ "start",
+ ["constant.language.escape","regex "],
+ ["keyword","/"],
+ ["text","((=)\\s*|(:)\\s*|(\\()|\\b)"],
+ ["keyword","/"],
+ ["text","f"],
+ ["keyword","/"],
+ ["text","(\\))?"],
+ ["keyword","/"]
+],[
+ "start"
+],[
+ "start",
+ ["constant.language.escape","name"],
+ ["text"," f"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\tfunction"],
+ ["markup.list","${"],
+ ["variable","M1"],
+ ["text","?: "],
+ ["markup.list","${"],
+ ["constant.numeric","1"],
+ ["punctuation.operator",":"],
+ ["text","functionName"],
+ ["markup.list","}}"],
+ ["text","("],
+ ["variable","$2"],
+ ["text",") {"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t\t"],
+ ["markup.list","${"],
+ ["constant.numeric","0"],
+ ["punctuation.operator",":"],
["keyword","$TM_SELECTED_TEXT"],
- ["text","/a/b/c"],
+ ["markup.list","}"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t}"],
+ ["markup.list","${"],
+ ["variable","M2"],
+ ["text","?;"],
+ ["markup.list","}${"],
+ ["variable","M3"],
+ ["text","?,"],
+ ["markup.list","}${"],
+ ["variable","M4"],
+ ["text","?)"],
["markup.list","}"]
],[
"start"
],[
"start",
- ["text"," "],
+ ["comment","# Immediate function"]
+],[
+ "start"
+],[
+ "start",
+ ["constant.language.escape","trigger"],
+ ["text"," \\(?f\\("]
+],[
+ "start"
+],[
+ "start",
+ ["constant.language.escape","endTrigger"],
+ ["text"," \\)?"]
+],[
+ "start"
+],[
+ "start",
+ ["constant.language.escape","snippet"],
+ ["text"," f("]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t(function("],
["markup.list","${"],
- ["constant.numeric","4"],
+ ["constant.numeric","1"],
+ ["markup.list","}"],
+ ["text",") {"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t\t"],
+ ["markup.list","${"],
+ ["constant.numeric","0"],
["punctuation.operator",":"],
["markup.list","${"],
["keyword","TM_SELECTED_TEXT"],
- ["string.regex","/(.)/"],
- ["string","\\"],
- ["keyword","\\u"],
- ["variable","$1"],
- ["string.regex","/g:"],
- ["text","7"],
+ ["punctuation.operator",":"],
+ ["text","/* code */"],
["markup.list","}}"]
],[
"start"
],[
- "start",
- ["text","\\end{"],
- ["variable","$1"],
- ["text","}"]
-],[
- "start"
-],[
- "start",
- ["variable","$0"],
- ["constant.language.escape","\\\\"],
- ["text","$$"]
-],[
- "start"
-],[
- "start",
- ["doc,comment","$$------------------------------------"]
-],[
- "start"
-],[
- "start",
- ["text","tabTrigger: ^3"]
-],[
- "start"
-],[
- "start",
- ["text","name: Heading 3"]
-],[
- "start"
-],[
- "start",
- ["text","scope: language"]
-],[
- "start"
-],[
- "start",
- ["text","content: -----------------------------"]
-],[
- "start"
-],[
- "start"
-],[
- "start"
-],[
- "start",
+ "sn-start",
+ ["text","\t}("],
["markup.list","${"],
- ["keyword","TM_CURRENT_LINE"],
- ["string.regex","/./"],
- ["string","^"],
- ["string.regex","/g"],
+ ["constant.numeric","1"],
+ ["markup.list","}"],
+ ["text","));"]
+],[
+ "start"
+],[
+ "start",
+ ["comment","# if"]
+],[
+ "start"
+],[
+ "start",
+ ["constant.language.escape","snippet"],
+ ["text"," if"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\tif ("],
+ ["markup.list","${"],
+ ["constant.numeric","1"],
+ ["punctuation.operator",":"],
+ ["text","true"],
+ ["markup.list","}"],
+ ["text",") {"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t\t"],
+ ["markup.list","${"],
+ ["constant.numeric","0"],
["markup.list","}"]
],[
"start"
],[
- "start",
- ["doc,comment","$$------------------------------------"]
+ "sn-start",
+ ["text","\t}"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t"]
+],[
+ "start"
+],[
+ "sn-start",
+ ["text","\t"]
]]
\ No newline at end of file
diff --git a/lib/ace/mode/tmsnippet.js b/lib/ace/mode/tmsnippet.js
index 8f777719..d3e51863 100644
--- a/lib/ace/mode/tmsnippet.js
+++ b/lib/ace/mode/tmsnippet.js
@@ -20,7 +20,7 @@ var SnippetHighlightRules = function() {
if (stack[1])
stack[1]++;
else
- stack.unshift("start", 1);
+ stack.unshift(state, 1);
return this.tokenName;
}, tokenName: "markup.list", regex: "\\${", next: "varDecl"},
{onMatch: function(value, state, stack) {
@@ -31,7 +31,7 @@ var SnippetHighlightRules = function() {
stack.splice(0,2);
return this.tokenName;
}, tokenName: "markup.list", regex: "}"},
- {token: "doc,comment", regex:/^\${2}-{5,}$/}
+ {token: "doc.comment", regex:/^\${2}-{5,}$/}
],
"varDecl" : [
{regex: /\d+\b/, token: "constant.numeric"},
@@ -62,15 +62,44 @@ var SnippetHighlightRules = function() {
]
};
};
-
oop.inherits(SnippetHighlightRules, TextHighlightRules);
exports.SnippetHighlightRules = SnippetHighlightRules;
+var SnippetGroupHighlightRules = function() {
+ this.$rules = {
+ "start" : [
+ {token: "text", regex: "^\\t", next: "sn-start"},
+ {token:"invalid", regex: /^ \s*/},
+ {token:"comment", regex: /^#.*/},
+ {token:"constant.language.escape", regex: "^regex ", next: "regex"},
+ {token:"constant.language.escape", regex: "^(trigger|endTrigger|name|snippet|guard|endGuard|tabTrigger|key)\\b"}
+ ],
+ "regex" : [
+ {token:"text", regex: "\\."},
+ {token:"keyword", regex: "/"},
+ {token:"empty", regex: "$", next: "start"}
+ ]
+ };
+ this.embedRules(SnippetHighlightRules, "sn-", [
+ {token: "text", regex: "^\\t", next: "sn-start"},
+ {onMatch: function(value, state, stack) {
+ stack.splice(stack.length);
+ return this.tokenName;
+ }, tokenName: "text", regex: "^(?!\t)", next: "start"},
+ ])
+
+};
+
+oop.inherits(SnippetGroupHighlightRules, TextHighlightRules);
+
+exports.SnippetGroupHighlightRules = SnippetGroupHighlightRules;
+
+var FoldMode = require("./folding/coffee").FoldMode;
var Mode = function() {
- var highlighter = new SnippetHighlightRules();
-
+ var highlighter = new SnippetGroupHighlightRules();
+ this.foldingRules = new FoldMode();
this.$tokenizer = new Tokenizer(highlighter.getRules());
};
oop.inherits(Mode, TextMode);
diff --git a/lib/ace/snippets.js b/lib/ace/snippets.js
index 3f227fe5..5b41f078 100644
--- a/lib/ace/snippets.js
+++ b/lib/ace/snippets.js
@@ -619,6 +619,8 @@ var TabstopManager = function(editor) {
var anchor = this.editor.selection.anchor;
var isEmpty = this.editor.selection.isEmpty();
for (var i = this.ranges.length; i--;) {
+ if (this.ranges[i].linked)
+ continue;
var containsLead = this.ranges[i].contains(lead.row, lead.column);
var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
if (containsLead && containsAnchor)
diff --git a/lib/ace/snippets/javascript.snippets b/lib/ace/snippets/javascript.snippets
index 313e6119..813876e2 100644
--- a/lib/ace/snippets/javascript.snippets
+++ b/lib/ace/snippets/javascript.snippets
@@ -1,6 +1,6 @@
# Prototype
snippet proto
- ${1:class_name}.prototype.${2:method_name} = function(${3irst_argument}) {
+ ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {
${4:// body...}
};
# Function