more work on snippet manager
This commit is contained in:
parent
d16daddc5e
commit
3d43f42f8a
10 changed files with 316 additions and 199 deletions
|
|
@ -447,7 +447,7 @@ new StatusBar(env.editor, cmdLine.container);
|
||||||
require("ace/placeholder").PlaceHolder;
|
require("ace/placeholder").PlaceHolder;
|
||||||
|
|
||||||
var SnippetManager = require("ace/snippets").SnippetManager
|
var SnippetManager = require("ace/snippets").SnippetManager
|
||||||
var jsSnippets = require("ace/requirejs/text!./snippets/js.json")
|
var jsSnippets = require("ace/snippets/javascript");
|
||||||
var testSnippet = "\
|
var testSnippet = "\
|
||||||
\\begin{${1:document}}\n\
|
\\begin{${1:document}}\n\
|
||||||
${2:$TM_SELECTED_TEXT:some ${3:latex}}\n\
|
${2:$TM_SELECTED_TEXT:some ${3:latex}}\n\
|
||||||
|
|
@ -460,7 +460,8 @@ SnippetManager.register({
|
||||||
tabTrigger: "t",
|
tabTrigger: "t",
|
||||||
name: "testSnippet"
|
name: "testSnippet"
|
||||||
})
|
})
|
||||||
SnippetManager.register(JSON.parse(jsSnippets).snippets)
|
jsSnippets.snippets = SnippetManager.parseSnippetFile(jsSnippets.snippetText)
|
||||||
|
SnippetManager.register(jsSnippets.snippets)
|
||||||
|
|
||||||
|
|
||||||
ace.commands.bindKey("Tab", function(editor) {
|
ace.commands.bindKey("Tab", function(editor) {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"main": "./demo.js",
|
|
||||||
"mappings": {
|
|
||||||
"ace": "../.."
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"github.com/sourcemint/bundler-js/0/-meta/config/0": {
|
|
||||||
"adapter": "github.com/sourcemint/sdk-requirejs/0",
|
|
||||||
"resources": [
|
|
||||||
"./icons/*",
|
|
||||||
"./logo.png",
|
|
||||||
"./styles.css"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
{"snippets":[{
|
|
||||||
"content": "var ${1:class} = function(${20}) {\n\t$40$0\n};\n\n(function() {\n\t${60:this.prop = \"\"}\n}).call(${1:class}.prototype);",
|
|
||||||
"name": "class",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "class"
|
|
||||||
}, {
|
|
||||||
"content": "for (var ${20:i} = ${1:Things}.length; ${20:i} --; ) {\n\t${100:${1:Things}[${20:i}]}$0\n};",
|
|
||||||
"name": "backwards for loop",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "for-"
|
|
||||||
}, {
|
|
||||||
"content": "for (var ${20:i} = ${1:Things}.length - 1; ${20:i} >= 0; ${20:i}--) {\n\t${100:${1:Things}[${20:i}]}$0\n};",
|
|
||||||
"name": "for (…) {…} (Improved Native For-Loop)",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "for"
|
|
||||||
}, {
|
|
||||||
"content": "for (var ${20:i}=0; ${20:i} < ${1:Things}.length; ${20:i}++) {\n\t${100:${1:Things}[${20:i}]}$0\n};",
|
|
||||||
"name": "for (…) {…}",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "for"
|
|
||||||
}, {
|
|
||||||
"content":"function ${1:function_name} (${2:argument}) {\n\t${0:// body...}\n}",
|
|
||||||
"name": "Function",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "fun"
|
|
||||||
}, {
|
|
||||||
"content": "function($1) {${0:$TM_SELECTED_TEXT}};",
|
|
||||||
"name": "Anonymous Function",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "f"
|
|
||||||
}, {
|
|
||||||
"content": "getElement${1/(T)|.*/(?1:s)/}By${1:T}${1/(T)|(I)|.*/(?1:agName)(?2:d)/}('$2')",
|
|
||||||
"name": "Get Elements",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "get"
|
|
||||||
}, {
|
|
||||||
"content": "if (${1:true}) {\n\t${0:$TM_SELECTED_TEXT}\n} else {\n\t\n}",
|
|
||||||
"name": "if … else",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "ife"
|
|
||||||
}, {
|
|
||||||
"content": "if (${1:true}) {${0:$TM_SELECTED_TEXT}}",
|
|
||||||
"name": "if",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "if"
|
|
||||||
}, {
|
|
||||||
"content": "'${1:${2:#thing}:${3:click}}': function(element){\n\t$0\n}${10:,}",
|
|
||||||
"name": "Object Method String",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "'':f"
|
|
||||||
}, {
|
|
||||||
"content": "${1:method_name}: function(${3:attribute}){\n\t$0\n}${10:,}",
|
|
||||||
"name": "Object Method",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": ":f"
|
|
||||||
}, {
|
|
||||||
"content": "${1:value_name}:${0:value},",
|
|
||||||
"name": "Object Value JS",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": ":,"
|
|
||||||
}, {
|
|
||||||
"content": "${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n\t${0:// body...}\n};\n",
|
|
||||||
"name": "Prototype",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "proto"
|
|
||||||
}, {
|
|
||||||
"content": "setTimeout(function() {$0}${2:}, ${1:10});",
|
|
||||||
"name": "setTimeout function",
|
|
||||||
"scope": "js",
|
|
||||||
"tabTrigger": "timeout"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
@ -540,5 +540,10 @@ Range.fromPoints = function(start, end) {
|
||||||
};
|
};
|
||||||
Range.comparePoints = comparePoints;
|
Range.comparePoints = comparePoints;
|
||||||
|
|
||||||
|
Range.comparePoints = function(p1, p2) {
|
||||||
|
return p1.row - p2.row || p1.column - p2.column;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.Range = Range;
|
exports.Range = Range;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var Range = require("ace/range").Range
|
var Range = require("./range").Range
|
||||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
var lang = require("./lib/lang")
|
||||||
var RangeList = require("ace/range_list").RangeList;
|
var HashHandler = require("./keyboard/hash_handler").HashHandler;
|
||||||
|
|
||||||
var SnippetManager = function() {
|
var SnippetManager = function() {
|
||||||
this.snippets = [];
|
this.snippets = [];
|
||||||
|
|
@ -59,7 +59,7 @@ var SnippetManager = function() {
|
||||||
// m[3] = \$(\w+) variables or tabstops
|
// m[3] = \$(\w+) variables or tabstops
|
||||||
// m[4] = \$\{([\dA-Z_]+)
|
// m[4] = \$\{([\dA-Z_]+)
|
||||||
// m[5] = format string
|
// m[5] = format string
|
||||||
var re = /\\([\$}`\\])|(})|\n|\$(\w+)|\$\{([\dA-Z_]+)([\/|`])?(\:?)/g;
|
var re = /\\([\$}`\\])|(})|\n|\$(\d+|\w+)|\$\{([\dA-Z_]+)([\/|`])?(\:?)/g;
|
||||||
var formatters = {
|
var formatters = {
|
||||||
"/": /((\/(?:\\.|[^\/])+){1,20})\/\w*/g, // replace or guard
|
"/": /((\/(?:\\.|[^\/])+){1,20})\/\w*/g, // replace or guard
|
||||||
"|": /|[^|}]+|/g, // choice list
|
"|": /|[^|}]+|/g, // choice list
|
||||||
|
|
@ -91,7 +91,7 @@ var SnippetManager = function() {
|
||||||
} else if (m[4]) { // variable
|
} else if (m[4]) { // variable
|
||||||
var placeholder = addVar(m[4], {});
|
var placeholder = addVar(m[4], {});
|
||||||
if (m[5])
|
if (m[5])
|
||||||
readFormatString(placeholder, m[5]);
|
readFormatString(m[5], placeholder);
|
||||||
if (stack[0])
|
if (stack[0])
|
||||||
stack[0].child = placeholder;
|
stack[0].child = placeholder;
|
||||||
stack.unshift(placeholder);
|
stack.unshift(placeholder);
|
||||||
|
|
@ -140,8 +140,7 @@ var SnippetManager = function() {
|
||||||
return this.$getDefaultValue(editor, varName);
|
return this.$getDefaultValue(editor, varName);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
// returns string formatted according to http://manual.macromates.com/en/regular_expressions#replacement_string_syntax_format_strings
|
||||||
// TODO: support \U \L \E
|
|
||||||
this.tmStrFormat = function(str, fmt) {
|
this.tmStrFormat = function(str, fmt) {
|
||||||
fmt = fmt.split("/");
|
fmt = fmt.split("/");
|
||||||
fmt.shift();
|
fmt.shift();
|
||||||
|
|
@ -153,17 +152,24 @@ var SnippetManager = function() {
|
||||||
search += "/" + fmt.shift();
|
search += "/" + fmt.shift();
|
||||||
fmt = fmt.join("/");
|
fmt = fmt.join("/");
|
||||||
var re = new RegExp(search, flags);
|
var re = new RegExp(search, flags);
|
||||||
|
|
||||||
|
var parseRe = /\\.|\\([ulULE])|\$(\d+)|\${(\d+)}|\(?(\d+):|\)/
|
||||||
|
var fmtParts = [];
|
||||||
|
while (m = parseRe.exec(fmt)) {
|
||||||
|
if (m[1]) {
|
||||||
|
|
||||||
|
} else if (m[2] || m[3]) {
|
||||||
|
|
||||||
|
} else if (m[4]) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return str.replace(re, function() {
|
return str.replace(re, function() {
|
||||||
var matches = arguments;
|
var matches = arguments;
|
||||||
var result = fmt.replace(/(\\[ul])?\$(\d)/g, function(_, flag, index) {
|
for (var i = 0; i < fmtParts; i++) {
|
||||||
var $ = matches[index] || "";
|
|
||||||
if (flag == "\\u") {
|
}
|
||||||
$ = $[0].toUpperCase() + $.substr(1);
|
|
||||||
} else if (flag == "\\l") {
|
|
||||||
$ = $[0].toLowerCase() + $.substr(1);
|
|
||||||
}
|
|
||||||
return $;
|
|
||||||
});
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -234,16 +240,14 @@ var SnippetManager = function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
tabstops.forEach(function(ts) {
|
tabstops.forEach(function(ts) {
|
||||||
if (ts.value) {
|
ts.value && ts.forEach(function(p) {
|
||||||
ts.forEach(function(p) {
|
var i = tokens.indexOf(p);
|
||||||
var i = tokens.indexOf(p);
|
var i1 = tokens.indexOf(p, i + 1);
|
||||||
var i1 = tokens.indexOf(p, i + 1);
|
if (i1 == -1)
|
||||||
if (i1 == -1)
|
tokens.splice(i + 1, 0, ts.value, p);
|
||||||
tokens.splice(i + 1, 0, ts.value, p);
|
else if (i1 == i + 1)
|
||||||
else if (i1 == i + 1)
|
tokens.splice(i + 1, 0, ts.value);
|
||||||
tokens.splice(i + 1, 0, ts.value);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// convert to plain text
|
// convert to plain text
|
||||||
var row = 0, column = 0;
|
var row = 0, column = 0;
|
||||||
|
|
@ -271,63 +275,135 @@ var SnippetManager = function() {
|
||||||
tabstopManager.tabNext();
|
tabstopManager.tabNext();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.$getScope = function(editor) {
|
||||||
|
var scope = editor.session.$mode.$id || "";
|
||||||
|
scope = scope.split("/").pop();
|
||||||
|
if (editor.session.$mode.$modes) {
|
||||||
|
var c = editor.getCursorPosition()
|
||||||
|
var state = editor.session.getState(c.row);
|
||||||
|
if (state.substring) {
|
||||||
|
if (state.substring(0, 3) == "js-")
|
||||||
|
scope = "javascript";
|
||||||
|
else if (state.substring(0, 4) == "css-")
|
||||||
|
scope = "css";
|
||||||
|
else if (state.substring(0, 4) == "php-")
|
||||||
|
scope = "php";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scope;
|
||||||
|
};
|
||||||
|
|
||||||
this.expandWithTab = function(editor) {
|
this.expandWithTab = function(editor) {
|
||||||
var cursor = editor.getCursorPosition();
|
var cursor = editor.getCursorPosition();
|
||||||
var line = editor.session.getLine(cursor.row);
|
var line = editor.session.getLine(cursor.row);
|
||||||
var before = line.substring(0, cursor.column);
|
var before = line.substring(0, cursor.column);
|
||||||
var after = line.substr(cursor.column);
|
var after = line.substr(cursor.column);
|
||||||
var s = this.snippets;
|
|
||||||
for (var i = this.snippets.length; i--;) {
|
var scope = this.$getScope(editor);
|
||||||
var s = this.snippets[i];
|
var snippetMap = this.snippetMap;
|
||||||
if (!s.trigger || !s.trigger.test(before))
|
var snippet;
|
||||||
return;
|
[scope, "_"].some(function(scope) {
|
||||||
|
var snippets = snippetMap[scope];
|
||||||
replacedText
|
if (snippets)
|
||||||
var trigger = this.snippets[i].tabTrigger;
|
snippet = this.findMatchingSnippet(snippets, before, after);
|
||||||
if (tabTrigger && before.slice(-tabTrigger.length) == tabTrigger) {
|
return !!snippet;
|
||||||
var matchedSnippet = this.snippets[i];
|
}, this);
|
||||||
break;
|
if (!snippet)
|
||||||
}
|
return false;
|
||||||
}
|
|
||||||
if (matchedSnippet) {
|
editor.session.doc.removeInLine(
|
||||||
ace.session.doc.removeInLine(cursor.row, cursor.column - tabTrigger.length, cursor.column);
|
cursor.row,
|
||||||
this.insertSnippet(editor, matchedSnippet.content, replacedText);
|
cursor.column - snippet.matchBefore[0].length,
|
||||||
return true;
|
cursor.column - snippet.matchAfter[0].length
|
||||||
}
|
);
|
||||||
|
this.insertSnippet(editor, snippet.content, snippet.matchBefore, snippet.matchAfter);
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
this.register = function(snippets) {
|
|
||||||
if (snippets.content) {
|
this.findMatchingSnippet = function(snippetList, before, after) {
|
||||||
this.snippets.push(snippets)
|
for (var i = snippetList.length; i--;) {
|
||||||
} else {
|
var s = snippetList[i];
|
||||||
this.snippets.push.apply(this.snippets, snippets)
|
if (s.startRe && !s.startRe.test(before))
|
||||||
|
continue;
|
||||||
|
if (s.endRe && !s.endRe.test(after))
|
||||||
|
continue;
|
||||||
|
if (!s.startRe && !s.endRe)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s.matchBefore = s.startRe ? s.startRe.exec(before) : [""];
|
||||||
|
s.matchAfter = s.endRe ? s.endRe.exec(after) : [""];
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.snippetMap = {};
|
||||||
|
this.register = function(snippets, scope) {
|
||||||
|
var snippetMap = this.snippetMap;
|
||||||
|
function addSnippet(s) {
|
||||||
|
if (!s.scope)
|
||||||
|
s.scope = scope || "_";
|
||||||
|
if (!snippetMap[s.scope])
|
||||||
|
snippetMap[s.scope] = [];
|
||||||
|
snippetMap[s.scope].push(s);
|
||||||
|
|
||||||
|
if (s.tabTrigger) {
|
||||||
|
if (/^\w/.test(s.tabTrigger))
|
||||||
|
s.guard = "\\b";
|
||||||
|
s.trigger = lang.escapeRegExp(s.tabTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
s.startRe = (s.guard || "") + (s.trigger || "");
|
||||||
|
if (s.startRe && s.startRe[s.startRe - 1] != "$")
|
||||||
|
s.startRe += "$";
|
||||||
|
if (s.startRe)
|
||||||
|
s.startRe = new RegExp(s.startRe);
|
||||||
|
s.endRe = (s.endGuard || "") + (s.endTrigger || "");
|
||||||
|
if (s.endRe && s.endRe[0] != "^")
|
||||||
|
s.endRe = "^" + s.endRe;
|
||||||
|
if (s.endRe)
|
||||||
|
s.endRe = new RegExp(s.endRe);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (snippets.content)
|
||||||
|
addSnippet(snippets);
|
||||||
|
else if (Array.isArray(snippets))
|
||||||
|
snippets.forEach(addSnippet);
|
||||||
|
};
|
||||||
this.parseSnippetFile = function(str) {
|
this.parseSnippetFile = function(str) {
|
||||||
var list = [], snippet = {};
|
var list = [], snippet = {};
|
||||||
var re = /^(\S+) (.*)$|^((?:\n?\t.*)+)/gm;
|
var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
|
||||||
while(m = re.exec(str)){
|
var m;
|
||||||
if (m[3]) {
|
while (m = re.exec(str)) {
|
||||||
snippet.content = m[3].replace(/^\t/gm, "");
|
if (m[1]) {
|
||||||
|
try {
|
||||||
|
snippet = JSON.parse(m[1])
|
||||||
|
list.push(snippet);
|
||||||
|
} catch (e) {}
|
||||||
|
} if (m[4]) {
|
||||||
|
snippet.content = m[4].replace(/^\t/gm, "");
|
||||||
list.push(snippet);
|
list.push(snippet);
|
||||||
snippet = {};
|
snippet = {};
|
||||||
} else {
|
} else {
|
||||||
var key = m[1], val = m[2];
|
var key = m[2], val = m[3];
|
||||||
if (key == "snippet") {
|
if (key == "regex") {
|
||||||
if (!val.indexOf(" ")) {
|
val = val.split(/\/((?:[^\/\\]|\\.)*)\/?/);
|
||||||
snippet.trigger = val;
|
snippet.guard = val[1];
|
||||||
} else {
|
snippet.trigger = val[2];
|
||||||
snippet.trigger = val;
|
snippet.endTrigger = val[3];
|
||||||
}
|
snippet.endGuard = val[3];
|
||||||
} else if (key == "#") {
|
} else if (key == "snippet") {
|
||||||
snippet.name = val;
|
val = val.split(/^(\S*)(?:\s(.*))?$/);
|
||||||
|
snippet.tabTrigger = val[1];
|
||||||
|
if (!snippet.name)
|
||||||
|
snippet.name = val[2];
|
||||||
} else {
|
} else {
|
||||||
snippet[key] = val;
|
snippet[key] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return snippets;
|
return list;
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(SnippetManager.prototype);
|
}).call(SnippetManager.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -346,6 +422,7 @@ var TabstopManager = function(editor) {
|
||||||
this.index = -1;
|
this.index = -1;
|
||||||
this.ranges = [];
|
this.ranges = [];
|
||||||
this.tabstops = [];
|
this.tabstops = [];
|
||||||
|
this.selectedTabstop = null;
|
||||||
|
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
this.editor.on("change", this.$onChange);
|
this.editor.on("change", this.$onChange);
|
||||||
|
|
@ -357,6 +434,7 @@ var TabstopManager = function(editor) {
|
||||||
this.tabstops.forEach(this.removeTabstopMarkers, this);
|
this.tabstops.forEach(this.removeTabstopMarkers, this);
|
||||||
this.ranges = null;
|
this.ranges = null;
|
||||||
this.tabstops = null;
|
this.tabstops = null;
|
||||||
|
this.selectedTabstop = null;
|
||||||
this.editor.removeListener("change", this.$onChange);
|
this.editor.removeListener("change", this.$onChange);
|
||||||
this.editor.removeListener("changeSelection", this.$onChangeSelection);
|
this.editor.removeListener("changeSelection", this.$onChangeSelection);
|
||||||
this.editor.removeListener("changeSession", this.$onChangeSession);
|
this.editor.removeListener("changeSession", this.$onChangeSession);
|
||||||
|
|
@ -381,11 +459,18 @@ var TabstopManager = function(editor) {
|
||||||
var colDiff = end.column - start.column;
|
var colDiff = end.column - start.column;
|
||||||
var ranges = this.ranges;
|
var ranges = this.ranges;
|
||||||
|
|
||||||
for (var i = 0, n = ranges.length; i < n; i++) {
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
var r = ranges[i];
|
var r = ranges[i];
|
||||||
if (r.end.row < startRow)
|
if (r.end.row < startRow)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (Range.comparePoints(changeRange.start, r.start) < 0
|
||||||
|
&& Range.comparePoints(changeRange.end, r.end) > 0) {
|
||||||
|
this.removeRange(r);
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (r.start.row == startRow && r.start.column > start.column) {
|
if (r.start.row == startRow && r.start.column > start.column) {
|
||||||
r.start.column += colDiff;
|
r.start.column += colDiff;
|
||||||
}
|
}
|
||||||
|
|
@ -405,9 +490,12 @@ var TabstopManager = function(editor) {
|
||||||
if (!this.editor)
|
if (!this.editor)
|
||||||
return
|
return
|
||||||
var lead = this.editor.selection.lead;
|
var lead = this.editor.selection.lead;
|
||||||
var row = lead.row, column = lead.column;
|
var anchor = this.editor.selection.anchor;
|
||||||
|
var isEmpty = this.editor.selection.isEmpty();
|
||||||
for (var i = this.ranges.length; i--;) {
|
for (var i = this.ranges.length; i--;) {
|
||||||
if (this.ranges[i].contains(row, column))
|
var containsLead = this.ranges[i].contains(lead.row, lead.column);
|
||||||
|
var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
|
||||||
|
if (containsLead && containsAnchor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.detach();
|
this.detach();
|
||||||
|
|
@ -433,12 +521,12 @@ var TabstopManager = function(editor) {
|
||||||
ts = this.tabstops[this.index];
|
ts = this.tabstops[this.index];
|
||||||
if (!ts)
|
if (!ts)
|
||||||
return;
|
return;
|
||||||
// this.removeTabstopMarkers(ts);
|
|
||||||
|
|
||||||
|
this.selectedTabstop = ts;
|
||||||
var sel = this.editor.multiSelect;
|
var sel = this.editor.multiSelect;
|
||||||
sel.toSingleRange(ts[0].range.clone());
|
sel.toSingleRange(ts[0].clone());
|
||||||
for (var i = ts.length; i--;)
|
for (var i = ts.length; i--;)
|
||||||
sel.addRange(ts[i].range.clone(), true);
|
sel.addRange(ts[i].clone(), true);
|
||||||
this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
||||||
};
|
};
|
||||||
this.addTabstops = function(tabstops, start, end) {
|
this.addTabstops = function(tabstops, start, end) {
|
||||||
|
|
@ -447,8 +535,8 @@ var TabstopManager = function(editor) {
|
||||||
var p = Range.fromPoints(end, end);
|
var p = Range.fromPoints(end, end);
|
||||||
moveRelative(p.start, start);
|
moveRelative(p.start, start);
|
||||||
moveRelative(p.end, start);
|
moveRelative(p.end, start);
|
||||||
this.tabstops[0] = [p];
|
tabstops[0] = [p];
|
||||||
this.tabstops[0].index = 0;
|
tabstops[0].index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = this.index;
|
var i = this.index;
|
||||||
|
|
@ -456,13 +544,16 @@ var TabstopManager = function(editor) {
|
||||||
var ranges = this.ranges;
|
var ranges = this.ranges;
|
||||||
var editor = this.editor;
|
var editor = this.editor;
|
||||||
tabstops.forEach(function(ts) {
|
tabstops.forEach(function(ts) {
|
||||||
ts.forEach(function(p) {
|
for (var i = ts.length; i--;) {
|
||||||
|
var p = ts[i];
|
||||||
var range = Range.fromPoints(p.start, p.end || p.start);
|
var range = Range.fromPoints(p.start, p.end || p.start);
|
||||||
movePoint(range.start, start);
|
movePoint(range.start, start);
|
||||||
movePoint(range.end, start);
|
movePoint(range.end, start);
|
||||||
p.range = range;
|
range.original = p;
|
||||||
|
range.tabstop = ts;
|
||||||
ranges.push(range);
|
ranges.push(range);
|
||||||
});
|
ts[i] = range;
|
||||||
|
}
|
||||||
arg.push(ts);
|
arg.push(ts);
|
||||||
this.addTabstopMarkers(ts);
|
this.addTabstopMarkers(ts);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
@ -473,18 +564,25 @@ var TabstopManager = function(editor) {
|
||||||
|
|
||||||
this.addTabstopMarkers = function(ts) {
|
this.addTabstopMarkers = function(ts) {
|
||||||
var session = this.editor.session;
|
var session = this.editor.session;
|
||||||
ts.forEach(function(p) {
|
ts.forEach(function(range) {
|
||||||
if (!p.markerId)
|
if (!range.markerId)
|
||||||
p.markerId = session.addMarker(p.range, "ace_snippet-marker", "text");
|
range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.removeTabstopMarkers = function(ts) {
|
this.removeTabstopMarkers = function(ts) {
|
||||||
var session = this.editor.session;
|
var session = this.editor.session;
|
||||||
ts.forEach(function(p) {
|
ts.forEach(function(range) {
|
||||||
session.removeMarker(p.markerId);
|
session.removeMarker(range.markerId);
|
||||||
p.markerId = null
|
range.markerId = null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
this.removeRange = function(range) {
|
||||||
|
var i = range.tabstop.indexOf(range);
|
||||||
|
range.tabstop.splice(i, 1);
|
||||||
|
i = this.ranges.indexOf(range);
|
||||||
|
this.ranges.splice(i, 1);
|
||||||
|
this.editor.session.removeMarker(range.markerId);
|
||||||
|
};
|
||||||
|
|
||||||
this.keyboardHandler = new HashHandler();
|
this.keyboardHandler = new HashHandler();
|
||||||
this.keyboardHandler.bindKeys({
|
this.keyboardHandler.bindKeys({
|
||||||
|
|
|
||||||
7
lib/ace/snippets/javascript.js
Normal file
7
lib/ace/snippets/javascript.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.snippetText = require("../requirejs/text!./javascript.snippets");
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -11,12 +11,13 @@ snippet fun
|
||||||
}
|
}
|
||||||
# Anonymous Function
|
# Anonymous Function
|
||||||
snippet f
|
snippet f
|
||||||
function (${1}) {
|
function(${1}) {
|
||||||
${3}
|
${3}
|
||||||
}${2:;}
|
}${2:;}
|
||||||
# Immediate function
|
# Immediate function
|
||||||
snippet (f
|
regex //f\(/\)?/
|
||||||
(function (${1}) {
|
snippet f(
|
||||||
|
(function(${1}) {
|
||||||
${3:/* code */}
|
${3:/* code */}
|
||||||
}(${2}));
|
}(${2}));
|
||||||
# if
|
# if
|
||||||
|
|
@ -50,16 +51,7 @@ snippet case
|
||||||
${2:// code}
|
${2:// code}
|
||||||
break;
|
break;
|
||||||
${3}
|
${3}
|
||||||
# for (...) {...}
|
|
||||||
snippet for
|
|
||||||
for (var ${2:i} = 0; $2 < ${1:Things}.length; $2${3: += 1}) {
|
|
||||||
${4:$1[$2]}
|
|
||||||
}
|
|
||||||
# for (...) {...} (Improved Native For-Loop)
|
|
||||||
snippet forr
|
|
||||||
for (var ${2:i} = ${1:Things}.length - 1; $2 >= 0; $2${3: -= 1}) {
|
|
||||||
${4:$1[$2]}
|
|
||||||
}
|
|
||||||
# while (...) {...}
|
# while (...) {...}
|
||||||
snippet wh
|
snippet wh
|
||||||
while (${1:/* condition */}) {
|
while (${1:/* condition */}) {
|
||||||
|
|
@ -79,17 +71,17 @@ snippet do
|
||||||
} while (${1:/* condition */});
|
} while (${1:/* condition */});
|
||||||
# Object Method
|
# Object Method
|
||||||
snippet :f
|
snippet :f
|
||||||
${1:method_name}: function (${2:attribute}) {
|
${1:method_name}: function(${2:attribute}) {
|
||||||
${4}
|
${4}
|
||||||
}${3:,}
|
}${3:,}
|
||||||
# setTimeout function
|
# setTimeout function
|
||||||
snippet timeout
|
snippet timeout
|
||||||
setTimeout(function () {${3}}${2}, ${1:10});
|
setTimeout(function() {${3}}${2}, ${1:10});
|
||||||
# Get Elements
|
# Get Elements
|
||||||
snippet get
|
snippet gett
|
||||||
getElementsBy${1:TagName}('${2}')${3}
|
getElementsBy${1:TagName}('${2}')${3}
|
||||||
# Get Element
|
# Get Element
|
||||||
snippet gett
|
snippet get
|
||||||
getElementBy${1:Id}('${2}')${3}
|
getElementBy${1:Id}('${2}')${3}
|
||||||
# console.log (Firebug)
|
# console.log (Firebug)
|
||||||
snippet cl
|
snippet cl
|
||||||
|
|
@ -123,10 +115,10 @@ snippet jsons
|
||||||
JSON.stringify(${1:object});
|
JSON.stringify(${1:object});
|
||||||
# self-defining function
|
# self-defining function
|
||||||
snippet sdf
|
snippet sdf
|
||||||
var ${1:function_name} = function (${2:argument}) {
|
var ${1:function_name} = function(${2:argument}) {
|
||||||
${3:// initial code ...}
|
${3:// initial code ...}
|
||||||
|
|
||||||
$1 = function ($2) {
|
$1 = function($2) {
|
||||||
${4:// main code}
|
${4:// main code}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -154,3 +146,33 @@ snippet sing
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
# class
|
||||||
|
regex /^\s*/clas{0,2}/
|
||||||
|
var ${1:class} = function(${20}) {
|
||||||
|
$40$0\n
|
||||||
|
};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
${60:this.prop = ""}
|
||||||
|
}).call(${1:class}.prototype);
|
||||||
|
#
|
||||||
|
snippet for-
|
||||||
|
for (var ${20:i} = ${1:Things}.length; ${20:i}--; ) {
|
||||||
|
${100:${1:Things}[${20:i}];
|
||||||
|
}
|
||||||
|
$0
|
||||||
|
|
||||||
|
|
||||||
|
# for (...) {...}
|
||||||
|
snippet for
|
||||||
|
for (var ${2:i} = 0; $2 < ${1:Things}.length; $2${3:++}) {
|
||||||
|
${4:$1[$2]}
|
||||||
|
}
|
||||||
|
# for (...) {...} (Improved Native For-Loop)
|
||||||
|
snippet forr
|
||||||
|
for (var ${2:i} = ${1:Things}.length - 1; $2 >= 0; $2${3:--}) {
|
||||||
|
${4:$1[$2]}
|
||||||
|
}
|
||||||
|
snippet for-
|
||||||
|
|
||||||
|
snippet for ?in
|
||||||
|
|
|
||||||
56
lib/ace/snippets_test.js
Normal file
56
lib/ace/snippets_test.js
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Distributed under the BSD license:
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Ajax.org B.V.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Ajax.org B.V. nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
if (typeof process !== "undefined") {
|
||||||
|
require("amd-loader");
|
||||||
|
}
|
||||||
|
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var SnippetManager = require("./snippets").SnippetManager;
|
||||||
|
var assert = require("./test/assertions");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"!test: textmate style format strings" : function() {
|
||||||
|
var fmt = SnippetManager.tmStrFormat;
|
||||||
|
assert.equal(fmt("abc", "/(.)(.)/$1/g"), "ac");
|
||||||
|
assert.equal(fmt("abc", "/(.)(.)/$1(?2:Hello(1)2)/g"), "aHello(12)c2)");
|
||||||
|
assert.equal(fmt("abc", "/(.)(.)/\u$1+lL+\u$2e|/g"), "A+lL+be|C+lL+e|");
|
||||||
|
assert.equal(fmt("aBCD", "/(.)(.)/\U$1+lL+\l$2e/g"), "A+LL+be");
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof module !== "undefined" && module === require.main) {
|
||||||
|
require("asyncjs").test.testcase(module.exports).exec()
|
||||||
|
}
|
||||||
|
|
@ -46,6 +46,7 @@ var testNames = [
|
||||||
"ace/range_list_test",
|
"ace/range_list_test",
|
||||||
"ace/search_test",
|
"ace/search_test",
|
||||||
"ace/selection_test",
|
"ace/selection_test",
|
||||||
|
"ace/snippets_test",
|
||||||
"ace/token_iterator_test",
|
"ace/token_iterator_test",
|
||||||
"ace/virtual_renderer_test"
|
"ace/virtual_renderer_test"
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ var path = process.argv[2] || process.cwd();
|
||||||
function readSnippet(path, name) {
|
function readSnippet(path, name) {
|
||||||
if (name)
|
if (name)
|
||||||
path += name
|
path += name
|
||||||
if (!/\.tmSnippet$/i.test(path))
|
console.log(name)
|
||||||
|
if (!/\.(tmSnippet|sublime-snippet|plist)$/i.test(path))
|
||||||
return
|
return
|
||||||
console.log(name)
|
console.log(name)
|
||||||
var plistString = fs.readFileSync(path, "utf8");
|
var plistString = fs.readFileSync(path, "utf8");
|
||||||
|
|
@ -16,15 +17,29 @@ function readSnippet(path, name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// read
|
// read
|
||||||
if (fs.statSync(path).isDirectory()) {
|
function readDir(path) {
|
||||||
path += "/"
|
if (fs.statSync(path).isDirectory()) {
|
||||||
fs.readdirSync(path).forEach(function(name) {
|
path += "/"
|
||||||
readSnippet(path, name)
|
fs.readdirSync(path).forEach(function(name) {
|
||||||
})
|
if (/snippets/i.test(name))
|
||||||
} else {
|
readSnippetsInDir(path + name)
|
||||||
readSnippet(path)
|
else
|
||||||
|
readDir(path + name)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
function readSnippetsInDir(path) {
|
||||||
|
if (fs.statSync(path).isDirectory()) {
|
||||||
|
path += "/"
|
||||||
|
snippets.push(path)
|
||||||
|
fs.readdirSync(path).forEach(function(name) {
|
||||||
|
readSnippet(path, name)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
readSnippet(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readDir(path)
|
||||||
// transform
|
// transform
|
||||||
snippets = snippets.map(function(s) {
|
snippets = snippets.map(function(s) {
|
||||||
if (s.length == 1)
|
if (s.length == 1)
|
||||||
|
|
@ -62,6 +77,6 @@ var text = JSON.stringify(snippets, null, 1)
|
||||||
return "\\n"+"\\" + "\n"
|
return "\\n"+"\\" + "\n"
|
||||||
})
|
})
|
||||||
|
|
||||||
fs.writeFileSync(path += "./ace.snippets.js", text)
|
fs.writeFileSync(path += "/./ace.snippets.js", text)
|
||||||
|
|
||||||
console.log(path)
|
console.log(path)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue