fix expansion of snippets with nested tabstops

This commit is contained in:
nightwing 2013-09-05 18:45:51 +04:00
commit 1fa691693e
2 changed files with 92 additions and 22 deletions

View file

@ -282,38 +282,73 @@ var SnippetManager = function() {
if (typeof p != "object") if (typeof p != "object")
return; return;
var id = p.tabstopId; var id = p.tabstopId;
if (!tabstops[id]) { var ts = tabstops[id];
tabstops[id] = []; if (!ts) {
tabstops[id].index = id; ts = tabstops[id] = [];
tabstops[id].value = ""; ts.index = id;
ts.value = "";
} }
if (tabstops[id].indexOf(p) != -1) if (ts.indexOf(p) !== -1)
return; return;
tabstops[id].push(p); ts.push(p);
var i1 = tokens.indexOf(p, i + 1); var i1 = tokens.indexOf(p, i + 1);
if (i1 == -1) if (i1 === -1)
return; return;
var value = tokens.slice(i + 1, i1).join("");
if (value) var value = tokens.slice(i + 1, i1);
tabstops[id].value = value; var isNested = value.some(function(t) {return typeof t === "object"});
if (isNested && !ts.value) {
ts.value = value;
} else if (value.length && (!ts.value || typeof ts.value !== "string")) {
ts.value = value.join("");
}
}); });
tabstops.forEach(function(ts) { // expand tabstop values
ts.value && ts.forEach(function(p) { tabstops.forEach(function(ts) {ts.length = 0});
var i = tokens.indexOf(p); var expanding = {};
function copyValue(val) {
var copy = []
for (var i = 0; i < val.length; i++) {
var p = val[i];
if (typeof p == "object") {
if (expanding[p.tabstopId])
continue;
var j = val.lastIndexOf(p, i - 1);
p = copy[j] || {tabstopId: p.tabstopId};
}
copy[i] = p;
}
return copy;
}
for (var i = 0; i < tokens.length; i++) {
var p = tokens[i];
if (typeof p != "object")
continue;
var id = p.tabstopId;
var i1 = tokens.indexOf(p, i + 1); var i1 = tokens.indexOf(p, i + 1);
if (i1 == -1) if (expanding[id] == p) {
tokens.splice(i + 1, 0, ts.value, p); expanding[id] = null;
else if (i1 == i + 1) continue;
tokens.splice(i + 1, 0, ts.value); }
});
}); 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);
if (ts.indexOf(p) === -1)
ts.push(p);
};
// convert to plain text // convert to plain text
var row = 0, column = 0; var row = 0, column = 0;
var text = ""; var text = "";
tokens.forEach(function(t) { tokens.forEach(function(t) {
if (typeof t == "string") { if (typeof t === "string") {
if (t[0] == "\n"){ if (t[0] === "\n"){
column = t.length - 1; column = t.length - 1;
row ++; row ++;
} else } else

View file

@ -34,11 +34,20 @@ if (typeof process !== "undefined") {
define(function(require, exports, module) { define(function(require, exports, module) {
"use strict"; "use strict";
var EditSession = require("./edit_session").EditSession;
var Editor = require("./editor").Editor;
var MockRenderer = require("./test/mockrenderer").MockRenderer;
var MultiSelect = require("./multi_select").MultiSelect;
var snippetManager = require("./snippets").snippetManager; var snippetManager = require("./snippets").snippetManager;
var assert = require("./test/assertions"); var assert = require("./test/assertions");
module.exports = { module.exports = {
setUp : function(next) {
this.editor = new Editor(new MockRenderer());
next();
},
"test: textmate style format strings" : function() { "test: textmate style format strings" : function() {
var fmt = snippetManager.tmStrFormat; var fmt = snippetManager.tmStrFormat;
snippetManager.tmStrFormat("hello", { snippetManager.tmStrFormat("hello", {
@ -86,6 +95,32 @@ module.exports = {
assert.equal(tokens[1].fmt, "\\ul\\/"); assert.equal(tokens[1].fmt, "\\ul\\/");
assert.equal(tokens[1].guard, "as\\/d"); assert.equal(tokens[1].guard, "as\\/d");
assert.equal(tokens[1].flag, "g"); assert.equal(tokens[1].flag, "g");
},
"test: expand snippet with nested tabstops": function() {
var content = "-${1}-${1:1}--${2:2 ${3} 2}-${3:3 $1 3}-${4:4 $2 4}";
this.editor.setValue("");
snippetManager.insertSnippet(this.editor, content);
assert.equal(this.editor.getValue(), "-1-1--2 3 1 3 2-3 1 3-4 2 3 1 3 2 4");
assert.equal(this.editor.getSelectedText(), "1\n1\n1\n1\n1");
this.editor.tabstopManager.tabNext();
assert.equal(this.editor.getSelectedText(), "2 3 1 3 2\n2 3 1 3 2");
this.editor.tabstopManager.tabNext();
assert.equal(this.editor.getSelectedText(), "3 1 3\n3 1 3\n3 1 3");
this.editor.tabstopManager.tabNext();
assert.equal(this.editor.getSelectedText(), "4 2 3 1 3 2 4");
this.editor.tabstopManager.tabNext();
assert.equal(this.editor.getSelectedText(), "");
this.editor.setValue("");
snippetManager.insertSnippet(this.editor, "-${1:a$2}-${2:b$1}");
assert.equal(this.editor.getValue(), "-ab-ba");
assert.equal(this.editor.getSelectedText(), "ab\na");
this.editor.tabstopManager.tabNext();
assert.equal(this.editor.getSelectedText(), "b\nba");
this.editor.tabstopManager.tabNext();
assert.equal(this.editor.getSelectedText(), "");
} }
}; };