commit
5fc3bbbe09
7 changed files with 328 additions and 114 deletions
|
|
@ -1655,9 +1655,7 @@ var Editor = function(renderer, session) {
|
|||
* @related EditSession.moveLinesUp
|
||||
**/
|
||||
this.moveLinesDown = function() {
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
return this.session.moveLinesDown(firstRow, lastRow);
|
||||
});
|
||||
this.$moveLines(1, false);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1666,9 +1664,7 @@ var Editor = function(renderer, session) {
|
|||
* @related EditSession.moveLinesDown
|
||||
**/
|
||||
this.moveLinesUp = function() {
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
return this.session.moveLinesUp(firstRow, lastRow);
|
||||
});
|
||||
this.$moveLines(-1, false);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1692,10 +1688,7 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
**/
|
||||
this.copyLinesUp = function() {
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
this.session.duplicateLines(firstRow, lastRow);
|
||||
return 0;
|
||||
});
|
||||
this.$moveLines(-1, true);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1705,51 +1698,61 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
**/
|
||||
this.copyLinesDown = function() {
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
return this.session.duplicateLines(firstRow, lastRow);
|
||||
});
|
||||
this.$moveLines(1, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicating them, or shifting them.
|
||||
* @param {Function} mover A method to call on each selected row
|
||||
*
|
||||
* for internal use
|
||||
* @ignore
|
||||
*
|
||||
**/
|
||||
this.$moveLines = function(mover) {
|
||||
this.$moveLines = function(dir, copy) {
|
||||
var rows, moved;
|
||||
var selection = this.selection;
|
||||
if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
|
||||
var range = selection.toOrientedRange();
|
||||
var rows = this.$getSelectedRows(range);
|
||||
var linesMoved = mover.call(this, rows.first, rows.last);
|
||||
range.moveBy(linesMoved, 0);
|
||||
rows = this.$getSelectedRows(range);
|
||||
moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir);
|
||||
if (copy && dir == -1) moved = 0;
|
||||
range.moveBy(moved, 0);
|
||||
selection.fromOrientedRange(range);
|
||||
} else {
|
||||
var ranges = selection.rangeList.ranges;
|
||||
selection.rangeList.detach(this.session);
|
||||
|
||||
for (var i = ranges.length; i--; ) {
|
||||
this.inVirtualSelectionMode = true;
|
||||
|
||||
var diff = 0;
|
||||
var totalDiff = 0;
|
||||
var l = ranges.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
var rangeIndex = i;
|
||||
var rows = ranges[i].collapseRows();
|
||||
var last = rows.end.row;
|
||||
var first = rows.start.row;
|
||||
while (i--) {
|
||||
rows = ranges[i].collapseRows();
|
||||
if (first - rows.end.row <= 1)
|
||||
first = rows.end.row;
|
||||
else
|
||||
ranges[i].moveBy(diff, 0);
|
||||
rows = this.$getSelectedRows(ranges[i]);
|
||||
var first = rows.first;
|
||||
var last = rows.last;
|
||||
while (++i < l) {
|
||||
if (totalDiff) ranges[i].moveBy(totalDiff, 0);
|
||||
var subRows = this.$getSelectedRows(ranges[i]);
|
||||
if (copy && subRows.first != last)
|
||||
break;
|
||||
else if (!copy && subRows.first > last + 1)
|
||||
break;
|
||||
last = subRows.last;
|
||||
}
|
||||
i++;
|
||||
|
||||
var linesMoved = mover.call(this, first, last);
|
||||
while (rangeIndex >= i) {
|
||||
ranges[rangeIndex].moveBy(linesMoved, 0);
|
||||
rangeIndex--;
|
||||
i--;
|
||||
diff = this.session.$moveLines(first, last, copy ? 0 : dir);
|
||||
if (copy && dir == -1) rangeIndex = i + 1;
|
||||
while (rangeIndex <= i) {
|
||||
ranges[rangeIndex].moveBy(diff, 0);
|
||||
rangeIndex++;
|
||||
}
|
||||
if (!copy) diff = 0;
|
||||
totalDiff += diff;
|
||||
}
|
||||
|
||||
selection.fromOrientedRange(selection.ranges[0]);
|
||||
selection.rangeList.attach(this.session);
|
||||
this.inVirtualSelectionMode = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1762,8 +1765,8 @@ var Editor = function(renderer, session) {
|
|||
*
|
||||
* @returns {Object}
|
||||
**/
|
||||
this.$getSelectedRows = function() {
|
||||
var range = this.getSelectionRange().collapseRows();
|
||||
this.$getSelectedRows = function(range) {
|
||||
range = (range || this.getSelectionRange()).collapseRows();
|
||||
|
||||
return {
|
||||
first: this.session.getRowFoldStart(range.start.row),
|
||||
|
|
|
|||
|
|
@ -120,6 +120,15 @@ module.exports = {
|
|||
assert.equal(editor.getValue(), "{")
|
||||
exec("insertstring", 1, "\n");
|
||||
assert.equal(editor.getValue(), "{\n \n}")
|
||||
|
||||
editor.setValue("");
|
||||
exec("insertstring", 1, "(");
|
||||
exec("insertstring", 1, '"');
|
||||
exec("insertstring", 1, '"');
|
||||
assert.equal(editor.getValue(), '("")');
|
||||
exec("backspace", 1);
|
||||
exec("insertstring", 1, '"');
|
||||
assert.equal(editor.getValue(), '("")');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -260,48 +260,40 @@ var CstyleBehaviour = function() {
|
|||
var cursor = editor.getCursorPosition();
|
||||
var line = session.doc.getLine(cursor.row);
|
||||
var leftChar = line.substring(cursor.column-1, cursor.column);
|
||||
|
||||
var rightChar = line.substring(cursor.column, cursor.column + 1);
|
||||
|
||||
var token = session.getTokenAt(cursor.row, cursor.column);
|
||||
var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);
|
||||
// We're escaped.
|
||||
if (leftChar == '\\') {
|
||||
if (leftChar == "\\" && token && /escape/.test(token.type))
|
||||
return null;
|
||||
|
||||
var stringBefore = token && /string/.test(token.type);
|
||||
var stringAfter = !rightToken || /string/.test(rightToken.type);
|
||||
|
||||
var pair;
|
||||
if (rightChar == quote) {
|
||||
pair = stringBefore !== stringAfter;
|
||||
} else {
|
||||
if (stringBefore && !stringAfter)
|
||||
return null; // wrap string with different quote
|
||||
if (stringBefore && stringAfter)
|
||||
return null; // do not pair quotes inside strings
|
||||
var wordRe = session.$mode.tokenRe;
|
||||
wordRe.lastIndex = 0;
|
||||
var isWordBefore = wordRe.test(leftChar);
|
||||
wordRe.lastIndex = 0;
|
||||
var isWordAfter = wordRe.test(leftChar);
|
||||
if (isWordBefore || isWordAfter)
|
||||
return null; // before or after alphanumeric
|
||||
if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
|
||||
return null; // there is rightChar and it isn't closing
|
||||
pair = true;
|
||||
}
|
||||
|
||||
// Find what token we're inside.
|
||||
var tokens = session.getTokens(selection.start.row);
|
||||
var col = 0, token;
|
||||
var quotepos = -1; // Track whether we're inside an open quote.
|
||||
|
||||
for (var x = 0; x < tokens.length; x++) {
|
||||
token = tokens[x];
|
||||
if (token.type == "string") {
|
||||
quotepos = -1;
|
||||
} else if (quotepos < 0) {
|
||||
quotepos = token.value.indexOf(quote);
|
||||
}
|
||||
if ((token.value.length + col) > selection.start.column) {
|
||||
break;
|
||||
}
|
||||
col += tokens[x].value.length;
|
||||
}
|
||||
|
||||
// Try and be smart about when we auto insert.
|
||||
if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) {
|
||||
if (!CstyleBehaviour.isSaneInsertion(editor, session))
|
||||
return;
|
||||
return {
|
||||
text: quote + quote,
|
||||
selection: [1,1]
|
||||
};
|
||||
} else if (token && token.type === "string") {
|
||||
// Ignore input and move right one if we're typing over the closing quote.
|
||||
var rightChar = line.substring(cursor.column, cursor.column + 1);
|
||||
if (rightChar == quote) {
|
||||
return {
|
||||
text: '',
|
||||
selection: [1, 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
text: pair ? quote + quote : "",
|
||||
selection: [1,1]
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -55,6 +55,24 @@ oop.inherits(PhpMode, TextMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.tokenRe = new RegExp("^["
|
||||
+ unicode.packages.L
|
||||
+ unicode.packages.Mn + unicode.packages.Mc
|
||||
+ unicode.packages.Nd
|
||||
+ unicode.packages.Pc + "\_]+", "g"
|
||||
);
|
||||
|
||||
this.nonTokenRe = new RegExp("^(?:[^"
|
||||
+ unicode.packages.L
|
||||
+ unicode.packages.Mn + unicode.packages.Mc
|
||||
+ unicode.packages.Nd
|
||||
+ unicode.packages.Pc + "\_]|\s])+", "g"
|
||||
);
|
||||
|
||||
|
||||
this.lineCommentStart = ["//", "#"];
|
||||
this.blockComment = {start: "/*", end: "*/"};
|
||||
|
||||
this.getNextLineIndent = function(state, line, tab) {
|
||||
var indent = this.$getIndent(line);
|
||||
|
||||
|
|
@ -100,8 +118,10 @@ oop.inherits(PhpMode, TextMode);
|
|||
|
||||
var Mode = function(opts) {
|
||||
if (opts && opts.inline) {
|
||||
PhpMode.call(this);
|
||||
return;
|
||||
var mode = new PhpMode();
|
||||
mode.createWorker = this.createWorker;
|
||||
mode.inlinePhp = true;
|
||||
return mode;
|
||||
}
|
||||
HtmlMode.call(this);
|
||||
this.HighlightRules = PhpHighlightRules;
|
||||
|
|
@ -116,24 +136,6 @@ oop.inherits(Mode, HtmlMode);
|
|||
|
||||
(function() {
|
||||
|
||||
this.tokenRe = new RegExp("^["
|
||||
+ unicode.packages.L
|
||||
+ unicode.packages.Mn + unicode.packages.Mc
|
||||
+ unicode.packages.Nd
|
||||
+ unicode.packages.Pc + "\_]+", "g"
|
||||
);
|
||||
|
||||
this.nonTokenRe = new RegExp("^(?:[^"
|
||||
+ unicode.packages.L
|
||||
+ unicode.packages.Mn + unicode.packages.Mc
|
||||
+ unicode.packages.Nd
|
||||
+ unicode.packages.Pc + "\_]|\s])+", "g"
|
||||
);
|
||||
|
||||
|
||||
this.lineCommentStart = ["//", "#"];
|
||||
this.blockComment = {start: "/*", end: "*/"};
|
||||
|
||||
this.createWorker = function(session) {
|
||||
var worker = new WorkerClient(["ace"], "ace/mode/php_worker", "PhpWorker");
|
||||
worker.attachToDocument(session.getDocument());
|
||||
|
|
|
|||
|
|
@ -51,6 +51,45 @@ var exec = function(name, times, args) {
|
|||
var testRanges = function(str) {
|
||||
assert.equal(editor.selection.getAllRanges() + "", str + "");
|
||||
};
|
||||
function getSelection(editor) {
|
||||
var data = editor.multiSelect.toJSON();
|
||||
if (!data.length) data = [data];
|
||||
data = data.map(function(x) {
|
||||
var a, c;
|
||||
if (x.isBackwards) {
|
||||
a = x.end;
|
||||
c = x.start;
|
||||
} else {
|
||||
c = x.end;
|
||||
a = x.start;
|
||||
}
|
||||
return Range.comparePoints(a, c)
|
||||
? [a.row, a.column, c.row, c.column]
|
||||
: [a.row, a.column];
|
||||
});
|
||||
return data.length > 1 ? data : data[0];
|
||||
}
|
||||
function testSelection(editor, data) {
|
||||
assert.equal(getSelection(editor) + "", data + "");
|
||||
}
|
||||
function setSelection(editor, data) {
|
||||
if (typeof data[0] == "number")
|
||||
data = [data];
|
||||
editor.selection.fromJSON(data.map(function(x) {
|
||||
var start = {row: x[0], column: x[1]};
|
||||
var end = x.length == 2 ? start : {row: x[2], column: x[3]};
|
||||
var isBackwards = Range.comparePoints(start, end) > 0;
|
||||
return isBackwards ? {
|
||||
start: end,
|
||||
end: start,
|
||||
isBackwards: true
|
||||
} : {
|
||||
start: start,
|
||||
end: end,
|
||||
isBackwards: true
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
|
|
@ -167,6 +206,37 @@ module.exports = {
|
|||
editor.execCommand('insertfoo');
|
||||
assert.equal('l1foo\nl2foo', editor.getValue());
|
||||
},
|
||||
|
||||
"test multiselect move lines": function() {
|
||||
editor = new Editor(new MockRenderer());
|
||||
|
||||
editor.setValue("l1\nl2\nl3\nl4", -1);
|
||||
setSelection(editor, [[0,2],[1,2],[2,2],[3,2]]);
|
||||
|
||||
exec("copylinesdown");
|
||||
assert.equal(editor.getValue(),"l1\nl1\nl2\nl2\nl3\nl3\nl4\nl4");
|
||||
testSelection(editor, [[1,2],[3,2],[5,2],[7,2]]);
|
||||
exec("copylinesup");
|
||||
assert.equal(editor.getValue(),"l1\nl1\nl1\nl2\nl2\nl2\nl3\nl3\nl3\nl4\nl4\nl4");
|
||||
testSelection(editor, [[1,2],[4,2],[7,2],[10,2]]);
|
||||
exec("removeline");
|
||||
assert.equal(editor.getValue(),"l1\nl1\nl2\nl2\nl3\nl3\nl4\nl4");
|
||||
testSelection(editor, [[1,0],[3,0],[5,0],[7,0]]);
|
||||
|
||||
setSelection(editor, [[1,2],[1,0,1,1],[3,0,3,1],[5,0,5,1],[7,0,7,1]]);
|
||||
exec("copylinesdown");
|
||||
exec("copylinesup");
|
||||
assert.equal(editor.getValue(),"l1\nl1\nl1\nl1\nl2\nl2\nl2\nl2\nl3\nl3\nl3\nl3\nl4\nl4\nl4\nl4");
|
||||
testSelection(editor, [[2,2],[2,0,2,1],[6,0,6,1],[10,0,10,1],[14,0,14,1]]);
|
||||
|
||||
exec("movelinesdown", 12);
|
||||
assert.equal(editor.getValue(),"l1\nl1\nl1\nl2\nl2\nl2\nl3\nl3\nl3\nl4\nl4\nl4\nl1\nl2\nl3\nl4");
|
||||
testSelection(editor, [[12,2],[12,0,12,1],[13,0,13,1],[14,0,14,1],[15,0,15,1]]);
|
||||
|
||||
exec("movelinesup", 12);
|
||||
assert.equal(editor.getValue(),"l1\nl2\nl3\nl4\nl1\nl1\nl1\nl2\nl2\nl2\nl3\nl3\nl3\nl4\nl4\nl4");
|
||||
testSelection(editor, [[0,2],[0,0,0,1],[1,0,1,1],[2,0,2,1],[3,0,3,1]]);
|
||||
},
|
||||
|
||||
"test multiselect fromJSON/toJSON": function() {
|
||||
var doc = new EditSession(["l1", "l2"]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue