vendor/assets/javascripts/ace/ext-language_tools.js in ace-rails-ap-4.2 vs vendor/assets/javascripts/ace/ext-language_tools.js in ace-rails-ap-4.3
- old
+ new
@@ -1,169 +1,254 @@
-define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/anchor","ace/keyboard/hash_handler","ace/tokenizer","ace/lib/dom","ace/editor"], function(require, exports, module) {
+define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/lib/dom","ace/editor"], function(require, exports, module) {
"use strict";
var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
var lang = require("./lib/lang");
var Range = require("./range").Range;
-var Anchor = require("./anchor").Anchor;
+var RangeList = require("./range_list").RangeList;
var HashHandler = require("./keyboard/hash_handler").HashHandler;
var Tokenizer = require("./tokenizer").Tokenizer;
-var comparePoints = Range.comparePoints;
+var clipboard = require("./clipboard");
+var VARIABLES = {
+ CURRENT_WORD: function(editor) {
+ return editor.session.getTextRange(editor.session.getWordRange());
+ },
+ SELECTION: function(editor, name, indentation) {
+ var text = editor.session.getTextRange();
+ if (indentation)
+ return text.replace(/\n\r?([ \t]*\S)/g, "\n" + indentation + "$1");
+ return text;
+ },
+ CURRENT_LINE: function(editor) {
+ return editor.session.getLine(editor.getCursorPosition().row);
+ },
+ PREV_LINE: function(editor) {
+ return editor.session.getLine(editor.getCursorPosition().row - 1);
+ },
+ LINE_INDEX: function(editor) {
+ return editor.getCursorPosition().row;
+ },
+ LINE_NUMBER: function(editor) {
+ return editor.getCursorPosition().row + 1;
+ },
+ SOFT_TABS: function(editor) {
+ return editor.session.getUseSoftTabs() ? "YES" : "NO";
+ },
+ TAB_SIZE: function(editor) {
+ return editor.session.getTabSize();
+ },
+ CLIPBOARD: function(editor) {
+ return clipboard.getText && clipboard.getText();
+ },
+ FILENAME: function(editor) {
+ return /[^/\\]*$/.exec(this.FILEPATH(editor))[0];
+ },
+ FILENAME_BASE: function(editor) {
+ return /[^/\\]*$/.exec(this.FILEPATH(editor))[0].replace(/\.[^.]*$/, "");
+ },
+ DIRECTORY: function(editor) {
+ return this.FILEPATH(editor).replace(/[^/\\]*$/, "");
+ },
+ FILEPATH: function(editor) { return "/not implemented.txt"; },
+ WORKSPACE_NAME: function() { return "Unknown"; },
+ FULLNAME: function() { return "Unknown"; },
+ BLOCK_COMMENT_START: function(editor) {
+ var mode = editor.session.$mode || {};
+ return mode.blockComment && mode.blockComment.start || "";
+ },
+ BLOCK_COMMENT_END: function(editor) {
+ var mode = editor.session.$mode || {};
+ return mode.blockComment && mode.blockComment.end || "";
+ },
+ LINE_COMMENT: function(editor) {
+ var mode = editor.session.$mode || {};
+ return mode.lineCommentStart || "";
+ },
+ CURRENT_YEAR: date.bind(null, {year: "numeric"}),
+ CURRENT_YEAR_SHORT: date.bind(null, {year: "2-digit"}),
+ CURRENT_MONTH: date.bind(null, {month: "numeric"}),
+ CURRENT_MONTH_NAME: date.bind(null, {month: "long"}),
+ CURRENT_MONTH_NAME_SHORT: date.bind(null, {month: "short"}),
+ CURRENT_DATE: date.bind(null, {day: "2-digit"}),
+ CURRENT_DAY_NAME: date.bind(null, {weekday: "long"}),
+ CURRENT_DAY_NAME_SHORT: date.bind(null, {weekday: "short"}),
+ CURRENT_HOUR: date.bind(null, {hour: "2-digit", hour12: false}),
+ CURRENT_MINUTE: date.bind(null, {minute: "2-digit"}),
+ CURRENT_SECOND: date.bind(null, {second: "2-digit"})
+};
+
+VARIABLES.SELECTED_TEXT = VARIABLES.SELECTION;
+
+function date(dateFormat) {
+ var str = new Date().toLocaleString("en-us", dateFormat);
+ return str.length == 1 ? "0" + str : str;
+}
+
var SnippetManager = function() {
this.snippetMap = {};
this.snippetNameMap = {};
};
(function() {
oop.implement(this, EventEmitter);
this.getTokenizer = function() {
- function TabstopToken(str, _, stack) {
+ return SnippetManager.$tokenizer || this.createTokenizer();
+ };
+
+ this.createTokenizer = function() {
+ function TabstopToken(str) {
str = str.substr(1);
- if (/^\d+$/.test(str) && !stack.inFormatString)
+ if (/^\d+$/.test(str))
return [{tabstopId: parseInt(str, 10)}];
return [{text: str}];
}
function escape(ch) {
return "(?:[^\\\\" + ch + "]|\\\\.)";
}
+ var formatMatcher = {
+ regex: "/(" + escape("/") + "+)/",
+ onMatch: function(val, state, stack) {
+ var ts = stack[0];
+ ts.fmtString = true;
+ ts.guard = val.slice(1, -1);
+ ts.flag = "";
+ return "";
+ },
+ next: "formatString"
+ };
+
SnippetManager.$tokenizer = new Tokenizer({
start: [
- {regex: /:/, onMatch: function(val, state, stack) {
- if (stack.length && stack[0].expectIf) {
- stack[0].expectIf = false;
- stack[0].elseBranch = stack[0];
- return [stack[0]];
- }
- return ":";
- }},
{regex: /\\./, onMatch: function(val, state, stack) {
var ch = val[1];
if (ch == "}" && stack.length) {
val = ch;
- }else if ("`$\\".indexOf(ch) != -1) {
+ } else if ("`$\\".indexOf(ch) != -1) {
val = ch;
- } else if (stack.inFormatString) {
- if (ch == "n")
- val = "\n";
- else if (ch == "t")
- val = "\n";
- else if ("ulULE".indexOf(ch) != -1) {
- val = {changeCase: ch, local: ch > "a"};
- }
}
-
return [val];
}},
{regex: /}/, onMatch: function(val, state, stack) {
return [stack.length ? stack.shift() : val];
}},
{regex: /\$(?:\d+|\w+)/, onMatch: TabstopToken},
{regex: /\$\{[\dA-Z_a-z]+/, onMatch: function(str, state, stack) {
- var t = TabstopToken(str.substr(1), state, stack);
+ var t = TabstopToken(str.substr(1));
stack.unshift(t[0]);
return t;
}, next: "snippetVar"},
{regex: /\n/, token: "newline", merge: false}
],
snippetVar: [
{regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) {
- stack[0].choices = val.slice(1, -1).split(",");
+ var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function(operator) {
+ return operator.length == 2 ? operator[1] : "\x00";
+ }).split("\x00");
+ stack[0].choices = choices;
+ return [choices[0]];
}, next: "start"},
- {regex: "/(" + escape("/") + "+)/(?:(" + escape("/") + "*)/)(\\w*):?",
- onMatch: function(val, state, stack) {
- var ts = stack[0];
- ts.fmtString = val;
-
- val = this.splitRegex.exec(val);
- ts.guard = val[1];
- ts.fmt = val[2];
- ts.flag = val[3];
- return "";
- }, next: "start"},
- {regex: "`" + escape("`") + "*`", onMatch: function(val, state, stack) {
- stack[0].code = val.splice(1, -1);
- return "";
- }, next: "start"},
- {regex: "\\?", onMatch: function(val, state, stack) {
- if (stack[0])
- stack[0].expectIf = true;
- }, next: "start"},
+ formatMatcher,
{regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "start"}
],
formatString: [
- {regex: "/(" + escape("/") + "+)/", token: "regex"},
- {regex: "", onMatch: function(val, state, stack) {
- stack.inFormatString = true;
+ {regex: /:/, onMatch: function(val, state, stack) {
+ if (stack.length && stack[0].expectElse) {
+ stack[0].expectElse = false;
+ stack[0].ifEnd = {elseEnd: stack[0]};
+ return [stack[0].ifEnd];
+ }
+ return ":";
+ }},
+ {regex: /\\./, onMatch: function(val, state, stack) {
+ var ch = val[1];
+ if (ch == "}" && stack.length)
+ val = ch;
+ else if ("`$\\".indexOf(ch) != -1)
+ val = ch;
+ else if (ch == "n")
+ val = "\n";
+ else if (ch == "t")
+ val = "\t";
+ else if ("ulULE".indexOf(ch) != -1)
+ val = {changeCase: ch, local: ch > "a"};
+ return [val];
+ }},
+ {regex: "/\\w*}", onMatch: function(val, state, stack) {
+ var next = stack.shift();
+ if (next)
+ next.flag = val.slice(1, -1);
+ this.next = next && next.tabstopId ? "start" : "";
+ return [next || val];
+ }, next: "start"},
+ {regex: /\$(?:\d+|\w+)/, onMatch: function(val, state, stack) {
+ return [{text: val.slice(1)}];
+ }},
+ {regex: /\${\w+/, onMatch: function(val, state, stack) {
+ var token = {text: val.slice(2)};
+ stack.unshift(token);
+ return [token];
+ }, next: "formatStringVar"},
+ {regex: /\n/, token: "newline", merge: false},
+ {regex: /}/, onMatch: function(val, state, stack) {
+ var next = stack.shift();
+ this.next = next && next.tabstopId ? "start" : "";
+ return [next || val];
}, next: "start"}
+ ],
+ formatStringVar: [
+ {regex: /:\/\w+}/, onMatch: function(val, state, stack) {
+ var ts = stack[0];
+ ts.formatFunction = val.slice(2, -1);
+ return [stack.shift()];
+ }, next: "formatString"},
+ formatMatcher,
+ {regex: /:[\?\-+]?/, onMatch: function(val, state, stack) {
+ if (val[1] == "+")
+ stack[0].ifEnd = stack[0];
+ if (val[1] == "?")
+ stack[0].expectElse = true;
+ }, next: "formatString"},
+ {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "formatString"}
]
});
- SnippetManager.prototype.getTokenizer = function() {
- return SnippetManager.$tokenizer;
- };
return SnippetManager.$tokenizer;
};
this.tokenizeTmSnippet = function(str, startState) {
return this.getTokenizer().getLineTokens(str, startState).tokens.map(function(x) {
return x.value || x;
});
};
-
- this.$getDefaultValue = function(editor, name) {
- if (/^[A-Z]\d+$/.test(name)) {
- var i = name.substr(1);
- return (this.variables[name[0] + "__"] || {})[i];
- }
- if (/^\d+$/.test(name)) {
- return (this.variables.__ || {})[name];
- }
+
+ this.getVariableValue = function(editor, name, indentation) {
+ if (/^\d+$/.test(name))
+ return (this.variables.__ || {})[name] || "";
+ if (/^[A-Z]\d+$/.test(name))
+ return (this.variables[name[0] + "__"] || {})[name.substr(1)] || "";
+
name = name.replace(/^TM_/, "");
-
- if (!editor)
- return;
- var s = editor.session;
- switch(name) {
- case "CURRENT_WORD":
- var r = s.getWordRange();
- case "SELECTION":
- case "SELECTED_TEXT":
- return s.getTextRange(r);
- case "CURRENT_LINE":
- return s.getLine(editor.getCursorPosition().row);
- case "PREV_LINE": // not possible in textmate
- return s.getLine(editor.getCursorPosition().row - 1);
- case "LINE_INDEX":
- return editor.getCursorPosition().column;
- case "LINE_NUMBER":
- return editor.getCursorPosition().row + 1;
- case "SOFT_TABS":
- return s.getUseSoftTabs() ? "YES" : "NO";
- case "TAB_SIZE":
- return s.getTabSize();
- case "FILENAME":
- case "FILEPATH":
- return "";
- case "FULLNAME":
- return "Ace";
- }
+ if (!this.variables.hasOwnProperty(name))
+ return "";
+ var value = this.variables[name];
+ if (typeof value == "function")
+ value = this.variables[name](editor, name, indentation);
+ return value == null ? "" : value;
};
- this.variables = {};
- this.getVariableValue = function(editor, varName) {
- if (this.variables.hasOwnProperty(varName))
- return this.variables[varName](editor, varName) || "";
- return this.$getDefaultValue(editor, varName) || "";
- };
+
+ this.variables = VARIABLES;
this.tmStrFormat = function(str, ch, editor) {
+ if (!ch.fmt) return str;
var flag = ch.flag || "";
var re = ch.guard;
- re = new RegExp(re, flag.replace(/[^gi]/, ""));
- var fmtTokens = this.tokenizeTmSnippet(ch.fmt, "formatString");
+ re = new RegExp(re, flag.replace(/[^gim]/g, ""));
+ var fmtTokens = typeof ch.fmt == "string" ? this.tokenizeTmSnippet(ch.fmt, "formatString") : ch.fmt;
var _self = this;
var formatted = str.replace(re, function() {
- _self.variables.__ = arguments;
+ var oldArgs = _self.variables.__;
+ _self.variables.__ = [].slice.call(arguments);
var fmtParts = _self.resolveVariables(fmtTokens, editor);
var gChangeCase = "E";
for (var i = 0; i < fmtParts.length; i++) {
var ch = fmtParts[i];
if (typeof ch == "object") {
@@ -184,44 +269,67 @@
fmtParts[i] = ch.toUpperCase();
} else if (gChangeCase == "L") {
fmtParts[i] = ch.toLowerCase();
}
}
+ _self.variables.__ = oldArgs;
return fmtParts.join("");
});
- this.variables.__ = null;
return formatted;
};
+
+ this.tmFormatFunction = function(str, ch, editor) {
+ if (ch.formatFunction == "upcase")
+ return str.toUpperCase();
+ if (ch.formatFunction == "downcase")
+ return str.toLowerCase();
+ return str;
+ };
this.resolveVariables = function(snippet, editor) {
var result = [];
+ var indentation = "";
+ var afterNewLine = true;
for (var i = 0; i < snippet.length; i++) {
var ch = snippet[i];
if (typeof ch == "string") {
result.push(ch);
- } else if (typeof ch != "object") {
+ if (ch == "\n") {
+ afterNewLine = true;
+ indentation = "";
+ }
+ else if (afterNewLine) {
+ indentation = /^\t*/.exec(ch)[0];
+ afterNewLine = /\S/.test(ch);
+ }
continue;
- } else if (ch.skip) {
- gotoNext(ch);
- } else if (ch.processed < i) {
- continue;
- } else if (ch.text) {
- var value = this.getVariableValue(editor, ch.text);
- if (value && ch.fmtString)
- value = this.tmStrFormat(value, ch);
- ch.processed = i;
- if (ch.expectIf == null) {
- if (value) {
- result.push(value);
- gotoNext(ch);
- }
- } else {
- if (value) {
- ch.skip = ch.elseBranch;
- } else
- gotoNext(ch);
+ }
+ if (!ch) continue;
+ afterNewLine = false;
+
+ if (ch.fmtString) {
+ var j = snippet.indexOf(ch, i + 1);
+ if (j == -1) j = snippet.length;
+ ch.fmt = snippet.slice(i + 1, j);
+ i = j;
+ }
+
+ if (ch.text) {
+ var value = this.getVariableValue(editor, ch.text, indentation) + "";
+ if (ch.fmtString)
+ value = this.tmStrFormat(value, ch, editor);
+ if (ch.formatFunction)
+ value = this.tmFormatFunction(value, ch, editor);
+
+ if (value && !ch.ifEnd) {
+ result.push(value);
+ gotoNext(ch);
+ } else if (!value && ch.ifEnd) {
+ gotoNext(ch.ifEnd);
}
+ } else if (ch.elseEnd) {
+ gotoNext(ch.elseEnd);
} else if (ch.tabstopId != null) {
result.push(ch);
} else if (ch.changeCase != null) {
result.push(ch);
}
@@ -261,13 +369,16 @@
var ts = tabstops[id];
if (!ts) {
ts = tabstops[id] = [];
ts.index = id;
ts.value = "";
+ ts.parents = {};
}
if (ts.indexOf(p) !== -1)
return;
+ if (p.choices && !ts.choices)
+ ts.choices = p.choices;
ts.push(p);
var i1 = tokens.indexOf(p, i + 1);
if (i1 === -1)
return;
@@ -298,23 +409,28 @@
for (var i = 0; i < tokens.length; i++) {
var p = tokens[i];
if (typeof p != "object")
continue;
var id = p.tabstopId;
+ var ts = tabstops[id];
var i1 = tokens.indexOf(p, i + 1);
if (expanding[id]) {
- if (expanding[id] === p)
- expanding[id] = null;
+ if (expanding[id] === p) {
+ delete expanding[id];
+ Object.keys(expanding).forEach(function(parentId) {
+ ts.parents[parentId] = true;
+ });
+ }
continue;
}
-
- var ts = tabstops[id];
- var arg = typeof ts.value == "string" ? [ts.value] : copyValue(ts.value);
- arg.unshift(i + 1, Math.max(0, i1 - i));
- arg.push(p);
expanding[id] = p;
- tokens.splice.apply(tokens, arg);
+ var value = ts.value;
+ if (typeof value !== "string")
+ value = copyValue(value);
+ else if (p.fmt)
+ value = this.tmStrFormat(value, p, editor);
+ tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));
if (ts.indexOf(p) === -1)
ts.push(p);
}
var row = 0, column = 0;
@@ -326,11 +442,11 @@
column = lines[lines.length - 1].length;
row += lines.length - 1;
} else
column += t.length;
text += t;
- } else {
+ } else if (t) {
if (!t.start)
t.start = {row: row, column: column};
else
t.end = {row: row, column: column};
}
@@ -628,70 +744,47 @@
this.editor.tabstopManager = null;
this.editor = null;
};
this.onChange = function(delta) {
- var changeRange = delta;
var isRemove = delta.action[0] == "r";
- var start = delta.start;
- var end = delta.end;
- var startRow = start.row;
- var endRow = end.row;
- var lineDif = endRow - startRow;
- var colDiff = end.column - start.column;
-
- if (isRemove) {
- lineDif = -lineDif;
- colDiff = -colDiff;
- }
- if (!this.$inChange && isRemove) {
- var ts = this.selectedTabstop;
- var changedOutside = ts && !ts.some(function(r) {
- return comparePoints(r.start, start) <= 0 && comparePoints(r.end, end) >= 0;
- });
- if (changedOutside)
- return this.detach();
- }
- var ranges = this.ranges;
- for (var i = 0; i < ranges.length; i++) {
- var r = ranges[i];
- if (r.end.row < start.row)
- continue;
-
- if (isRemove && comparePoints(start, r.start) < 0 && comparePoints(end, r.end) > 0) {
- this.removeRange(r);
- i--;
- continue;
+ var parents = this.selectedTabstop && this.selectedTabstop.parents || {};
+ var tabstops = (this.tabstops || []).slice();
+ for (var i = 0; i < tabstops.length; i++) {
+ var ts = tabstops[i];
+ var active = ts == this.selectedTabstop || parents[ts.index];
+ ts.rangeList.$bias = active ? 0 : 1;
+
+ if (delta.action == "remove" && ts !== this.selectedTabstop) {
+ var parentActive = ts.parents && ts.parents[this.selectedTabstop.index];
+ var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
+ startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
+ var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
+ endIndex = endIndex < 0 ? -endIndex - 1 : endIndex - 1;
+ var toRemove = ts.rangeList.ranges.slice(startIndex, endIndex);
+ for (var j = 0; j < toRemove.length; j++)
+ this.removeRange(toRemove[j]);
}
-
- if (r.start.row == startRow && r.start.column > start.column)
- r.start.column += colDiff;
- if (r.end.row == startRow && r.end.column >= start.column)
- r.end.column += colDiff;
- if (r.start.row >= startRow)
- r.start.row += lineDif;
- if (r.end.row >= startRow)
- r.end.row += lineDif;
-
- if (comparePoints(r.start, r.end) > 0)
- this.removeRange(r);
+ ts.rangeList.$onChange(delta);
}
- if (!ranges.length)
+ var session = this.editor.session;
+ if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())
this.detach();
};
this.updateLinkedFields = function() {
var ts = this.selectedTabstop;
- if (!ts || !ts.hasLinkedRanges)
+ if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)
return;
this.$inChange = true;
var session = this.editor.session;
var text = session.getTextRange(ts.firstNonLinked);
- for (var i = ts.length; i--;) {
+ for (var i = 0; i < ts.length; i++) {
var range = ts[i];
if (!range.linked)
continue;
- var fmt = exports.snippetManager.tmStrFormat(text, range.original);
+ var original = range.original;
+ var fmt = exports.snippetManager.tmStrFormat(text, original, this.editor);
session.replace(range, fmt);
}
this.$inChange = false;
};
this.onAfterExec = function(e) {
@@ -702,11 +795,11 @@
if (!this.editor)
return;
var lead = this.editor.selection.lead;
var anchor = this.editor.selection.anchor;
var isEmpty = this.editor.selection.isEmpty();
- for (var i = this.ranges.length; i--;) {
+ for (var i = 0; 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)
@@ -736,27 +829,32 @@
ts = this.tabstops[this.index];
if (!ts || !ts.length)
return;
this.selectedTabstop = ts;
- if (!this.editor.inVirtualSelectionMode) {
+ var range = ts.firstNonLinked || ts;
+ if (!this.editor.inVirtualSelectionMode) {
var sel = this.editor.multiSelect;
- sel.toSingleRange(ts.firstNonLinked.clone());
- for (var i = ts.length; i--;) {
+ sel.toSingleRange(range.clone());
+ for (var i = 0; i < ts.length; i++) {
if (ts.hasLinkedRanges && ts[i].linked)
continue;
sel.addRange(ts[i].clone(), true);
}
if (sel.ranges[0])
sel.addRange(sel.ranges[0].clone());
} else {
- this.editor.selection.setRange(ts.firstNonLinked);
+ this.editor.selection.setRange(range);
}
this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
+ if (this.selectedTabstop && this.selectedTabstop.choices)
+ this.editor.execCommand("startAutocomplete", {matches: this.selectedTabstop.choices});
};
this.addTabstops = function(tabstops, start, end) {
+ var useLink = this.useLink || !this.editor.getOption("enableMultiselect");
+
if (!this.$openTabstops)
this.$openTabstops = [];
if (!tabstops[0]) {
var p = Range.fromPoints(end, end);
moveRelative(p.start, start);
@@ -768,24 +866,27 @@
var i = this.index;
var arg = [i + 1, 0];
var ranges = this.ranges;
tabstops.forEach(function(ts, index) {
var dest = this.$openTabstops[index] || ts;
-
- for (var i = ts.length; i--;) {
+ ts.rangeList = new RangeList();
+ ts.rangeList.$bias = 0;
+
+ for (var i = 0; i < ts.length; i++) {
var p = ts[i];
var range = Range.fromPoints(p.start, p.end || p.start);
movePoint(range.start, start);
movePoint(range.end, start);
range.original = p;
range.tabstop = dest;
ranges.push(range);
+ ts.rangeList.ranges.push(range);
if (dest != ts)
dest.unshift(range);
else
dest[i] = range;
- if (p.fmtString) {
+ if (p.fmtString || (dest.firstNonLinked && useLink)) {
range.linked = true;
dest.hasLinkedRanges = true;
} else if (!dest.firstNonLinked)
dest.firstNonLinked = range;
}
@@ -819,13 +920,15 @@
range.markerId = null;
});
};
this.removeRange = function(range) {
var i = range.tabstop.indexOf(range);
- range.tabstop.splice(i, 1);
+ if (i != -1) range.tabstop.splice(i, 1);
i = this.ranges.indexOf(range);
- this.ranges.splice(i, 1);
+ if (i != -1) this.ranges.splice(i, 1);
+ i = range.tabstop.rangeList.ranges.indexOf(range);
+ if (i != -1) range.tabstop.splice(i, 1);
this.editor.session.removeMarker(range.markerId);
if (!range.tabstop.length) {
i = this.tabstops.indexOf(range.tabstop);
if (i != -1)
this.tabstops.splice(i, 1);
@@ -855,22 +958,10 @@
});
}).call(TabstopManager.prototype);
-var changeTracker = {};
-changeTracker.onChange = Anchor.prototype.onChange;
-changeTracker.setPosition = function(row, column) {
- this.pos.row = row;
- this.pos.column = column;
-};
-changeTracker.update = function(pos, delta, $insertRight) {
- this.$insertRight = $insertRight;
- this.pos = pos;
- this.onChange(delta);
-};
-
var movePoint = function(point, diff) {
if (point.row == 0)
point.column += diff.column;
point.row += diff.row;
};
@@ -1079,10 +1170,12 @@
}
addToken(caption.slice(lastIndex, caption.length), "");
if (data.meta)
tokens.push({type: "completion-meta", value: data.meta});
+ if (data.message)
+ tokens.push({type: "completion-message", value: data.message});
return tokens;
};
bgTokenizer.$updateOnChange = noop;
bgTokenizer.start = noop;
@@ -1164,10 +1257,25 @@
this._signal("show");
lastMouseEvent = null;
popup.isOpen = true;
};
+ popup.goTo = function(where) {
+ var row = this.getRow();
+ var max = this.session.getLength() - 1;
+
+ switch(where) {
+ case "up": row = row <= 0 ? max : row - 1; break;
+ case "down": row = row >= max ? -1 : row + 1; break;
+ case "start": row = 0; break;
+ case "end": row = max; break;
+ }
+
+ this.setRow(row);
+ };
+
+
popup.getTextLeftOffset = function() {
return this.$borderSize + this.renderer.$padding + this.$imageSize;
};
popup.$imageSize = 0;
@@ -1197,10 +1305,13 @@
}\
.ace_completion-meta {\
opacity: 0.5;\
margin: 0.9em;\
}\
+.ace_completion-message {\
+ color: blue;\
+}\
.ace_editor.ace_autocomplete .ace_completion-highlight{\
color: #2d69c7;\
}\
.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\
color: #93ca12;\
@@ -1222,11 +1333,11 @@
background: #25282c;\
color: #c1c1c1;\
}", "autocompletion.css");
exports.AcePopup = AcePopup;
-
+exports.$singleLineEditor = $singleLineEditor;
});
define("ace/autocomplete/util",["require","exports","module"], function(require, exports, module) {
"use strict";
@@ -1285,20 +1396,20 @@
return prefix || this.retrievePrecedingIdentifier(line, pos.column);
};
});
-define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/event","ace/lib/lang","ace/lib/dom","ace/snippets"], function(require, exports, module) {
+define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/lang","ace/lib/dom","ace/snippets","ace/config"], function(require, exports, module) {
"use strict";
var HashHandler = require("./keyboard/hash_handler").HashHandler;
var AcePopup = require("./autocomplete/popup").AcePopup;
var util = require("./autocomplete/util");
-var event = require("./lib/event");
var lang = require("./lib/lang");
var dom = require("./lib/dom");
var snippetManager = require("./snippets").snippetManager;
+var config = require("./config");
var Autocomplete = function() {
this.autoInsert = false;
this.autoSelect = true;
this.exactMatch = false;
@@ -1418,21 +1529,11 @@
this.mousewheelListener = function(e) {
this.detach();
};
this.goTo = function(where) {
- var row = this.popup.getRow();
- var max = this.popup.session.getLength() - 1;
-
- switch(where) {
- case "up": row = row <= 0 ? max : row - 1; break;
- case "down": row = row >= max ? -1 : row + 1; break;
- case "start": row = 0; break;
- case "end": row = max; break;
- }
-
- this.popup.setRow(row);
+ this.popup.goTo(where);
};
this.insertMatch = function(data, options) {
if (!data)
data = this.popup.getData(this.popup.getRow());
@@ -1502,11 +1603,11 @@
});
});
return true;
};
- this.showPopup = function(editor) {
+ this.showPopup = function(editor, options) {
if (this.editor)
this.detach();
this.activated = true;
@@ -1520,14 +1621,14 @@
editor.on("changeSelection", this.changeListener);
editor.on("blur", this.blurListener);
editor.on("mousedown", this.mousedownListener);
editor.on("mousewheel", this.mousewheelListener);
- this.updateCompletions();
+ this.updateCompletions(false, options);
};
- this.updateCompletions = function(keepPopupPosition) {
+ this.updateCompletions = function(keepPopupPosition, options) {
if (keepPopupPosition && this.base && this.completions) {
var pos = this.editor.getCursorPosition();
var prefix = this.editor.session.getTextRange({start: this.base, end: pos});
if (prefix == this.completions.filterText)
return;
@@ -1539,10 +1640,18 @@
&& !this.completions.filtered[0].snippet)
return this.detach();
this.openPopup(this.editor, prefix, keepPopupPosition);
return;
}
+
+ if (options && options.matches) {
+ var pos = this.editor.getSelectionRange().start;
+ this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);
+ this.base.$insertRight = true;
+ this.completions = new FilteredList(options.matches);
+ return this.openPopup(this.editor, "", keepPopupPosition);
+ }
var _id = this.gatherCompletionsId;
this.gatherCompletions(this.editor, function(err, results) {
var detachIfFinished = function() {
if (!results.finished) return;
return this.detach();
@@ -1588,11 +1697,11 @@
this.editor.completers.some(function(completer) {
if (completer.getDocTooltip)
doc = completer.getDocTooltip(selected);
return doc;
});
- if (!doc)
+ if (!doc && typeof selected != "string")
doc = selected;
if (typeof doc == "string")
doc = {docText: doc};
if (!doc || !(doc.docHTML || doc.docText))
@@ -1670,21 +1779,51 @@
}
a = a.parentNode;
}
};
+ this.destroy = function() {
+ this.detach();
+ if (this.popup) {
+ this.popup.destroy();
+ var el = this.popup.container;
+ if (el && el.parentNode)
+ el.parentNode.removeChild(el);
+ }
+ if (this.editor && this.editor.completer == this)
+ this.editor.completer == null;
+ this.popup = null;
+ };
+
}).call(Autocomplete.prototype);
+
+Autocomplete.for = function(editor) {
+ if (editor.completer) {
+ return editor.completer;
+ }
+ if (config.get("sharedPopups")) {
+ if (!Autocomplete.$shared)
+ Autocomplete.$sharedInstance = new Autocomplete();
+ editor.completer = Autocomplete.$sharedInstance;
+ } else {
+ editor.completer = new Autocomplete();
+ editor.once("destroy", function(e, editor) {
+ editor.completer.destroy();
+ });
+ }
+ return editor.completer;
+};
+
Autocomplete.startCommand = {
name: "startAutocomplete",
- exec: function(editor) {
- if (!editor.completer)
- editor.completer = new Autocomplete();
- editor.completer.autoInsert = false;
- editor.completer.autoSelect = true;
- editor.completer.showPopup(editor);
- editor.completer.cancelContextMenu();
+ exec: function(editor, options) {
+ var completer = Autocomplete.for(editor);
+ completer.autoInsert = false;
+ completer.autoSelect = true;
+ completer.showPopup(editor, options);
+ completer.cancelContextMenu();
},
bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
};
var FilteredList = function(array, filterText) {
@@ -1702,11 +1841,11 @@
this.filterText = str;
matches = this.filterCompletions(matches, this.filterText);
matches = matches.sort(function(a, b) {
return b.exactMatch - a.exactMatch || b.$score - a.$score
- || (a.caption || a.value) < (b.caption || b.value);
+ || (a.caption || a.value).localeCompare(b.caption || b.value);
});
var prev = null;
matches = matches.filter(function(item){
var caption = item.snippet || item.caption || item.value;
if (caption === prev) return false;
@@ -1932,14 +2071,12 @@
editor.completer.detach();
}
else if (e.command.name === "insertstring") {
var prefix = util.getCompletionPrefix(editor);
if (prefix && !hasCompleter) {
- if (!editor.completer) {
- editor.completer = new Autocomplete();
- }
- editor.completer.autoInsert = false;
- editor.completer.showPopup(editor);
+ var completer = Autocomplete.for(editor);
+ completer.autoInsert = false;
+ completer.showPopup(editor);
}
}
};
var Editor = require("../editor").Editor;
\ No newline at end of file