fix expansion of snippets with nested tabstops
This commit is contained in:
parent
62c514135d
commit
1fa691693e
2 changed files with 92 additions and 22 deletions
|
|
@ -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 = {};
|
||||||
var i1 = tokens.indexOf(p, i + 1);
|
function copyValue(val) {
|
||||||
if (i1 == -1)
|
var copy = []
|
||||||
tokens.splice(i + 1, 0, ts.value, p);
|
for (var i = 0; i < val.length; i++) {
|
||||||
else if (i1 == i + 1)
|
var p = val[i];
|
||||||
tokens.splice(i + 1, 0, ts.value);
|
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);
|
||||||
|
if (expanding[id] == p) {
|
||||||
|
expanding[id] = null;
|
||||||
|
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);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -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(), "");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue