Merge pull request #881 from ajaxorg/align_cursors
add command to align cursors
This commit is contained in:
commit
7966efc0df
2 changed files with 149 additions and 20 deletions
|
|
@ -74,11 +74,15 @@ exports.defaultCommands = [{
|
||||||
}, {
|
}, {
|
||||||
name: "splitIntoLines",
|
name: "splitIntoLines",
|
||||||
exec: function(editor) { editor.multiSelect.splitIntoLines(); },
|
exec: function(editor) { editor.multiSelect.splitIntoLines(); },
|
||||||
bindKey: {win: "Ctrl-Shift-L", mac: "Ctrl-Shift-L"},
|
bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
|
||||||
readonly: true
|
readonly: true
|
||||||
|
}, {
|
||||||
|
name: "alignCursors",
|
||||||
|
exec: function(editor) { editor.alignCursors(); },
|
||||||
|
bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// commands active in multiselect mode
|
// commands active only in multiselect mode
|
||||||
exports.multiSelectCommands = [{
|
exports.multiSelectCommands = [{
|
||||||
name: "singleSelection",
|
name: "singleSelection",
|
||||||
bindKey: "esc",
|
bindKey: "esc",
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ var Range = require("./range").Range;
|
||||||
var Selection = require("./selection").Selection;
|
var Selection = require("./selection").Selection;
|
||||||
var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
|
var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
|
||||||
var event = require("./lib/event");
|
var event = require("./lib/event");
|
||||||
|
var lang = require("./lib/lang");
|
||||||
var commands = require("./commands/multi_select_commands");
|
var commands = require("./commands/multi_select_commands");
|
||||||
exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
|
exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
|
||||||
|
|
||||||
|
|
@ -198,10 +199,19 @@ var EditSession = require("./edit_session").EditSession;
|
||||||
this.setSelectionRange(range, lastRange.cursor == lastRange.start);
|
this.setSelectionRange(range, lastRange.cursor == lastRange.start);
|
||||||
} else {
|
} else {
|
||||||
var range = this.getRange();
|
var range = this.getRange();
|
||||||
|
var isBackwards = this.isBackwards();
|
||||||
var startRow = range.start.row;
|
var startRow = range.start.row;
|
||||||
var endRow = range.end.row;
|
var endRow = range.end.row;
|
||||||
if (startRow == endRow)
|
if (startRow == endRow) {
|
||||||
|
if (isBackwards)
|
||||||
|
var start = range.end, end = range.start;
|
||||||
|
else
|
||||||
|
var start = range.start, end = range.end;
|
||||||
|
|
||||||
|
this.addRange(Range.fromPoints(end, end));
|
||||||
|
this.addRange(Range.fromPoints(start, start));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var rectSel = [];
|
var rectSel = [];
|
||||||
var r = this.getLineRange(startRow, true);
|
var r = this.getLineRange(startRow, true);
|
||||||
|
|
@ -645,7 +655,7 @@ var Editor = require("./editor").Editor;
|
||||||
*
|
*
|
||||||
* Finds the next occurence of text in an active selection and adds it to the selections.
|
* Finds the next occurence of text in an active selection and adds it to the selections.
|
||||||
**/
|
**/
|
||||||
this.selectMore = function (dir, skip) {
|
this.selectMore = function(dir, skip) {
|
||||||
var session = this.session;
|
var session = this.session;
|
||||||
var sel = session.multiSelect;
|
var sel = session.multiSelect;
|
||||||
|
|
||||||
|
|
@ -665,6 +675,121 @@ var Editor = require("./editor").Editor;
|
||||||
if (skip)
|
if (skip)
|
||||||
this.multiSelect.substractPoint(range.cursor);
|
this.multiSelect.substractPoint(range.cursor);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** extension
|
||||||
|
* Editor.alignCursors()
|
||||||
|
*
|
||||||
|
* aligns cursors or selected text
|
||||||
|
**/
|
||||||
|
this.alignCursors = function() {
|
||||||
|
var session = this.session;
|
||||||
|
var sel = session.multiSelect;
|
||||||
|
var ranges = sel.ranges;
|
||||||
|
|
||||||
|
if (!ranges.length) {
|
||||||
|
var range = this.selection.getRange();
|
||||||
|
var fr = range.start.row, lr = range.end.row;
|
||||||
|
var lines = this.session.doc.removeLines(fr, lr);
|
||||||
|
lines = this.$reAlignText(lines);
|
||||||
|
this.session.doc.insertLines(fr, lines);
|
||||||
|
range.start.column = 0;
|
||||||
|
range.end.column = lines[lines.length - 1].length;
|
||||||
|
this.selection.setRange(range);
|
||||||
|
} else {
|
||||||
|
// filter out ranges on same row
|
||||||
|
var row = -1;
|
||||||
|
var sameRowRanges = ranges.filter(function(r) {
|
||||||
|
if (r.cursor.row == row)
|
||||||
|
return true;
|
||||||
|
row = r.cursor.row;
|
||||||
|
});
|
||||||
|
sel.$onRemoveRange(sameRowRanges);
|
||||||
|
|
||||||
|
var maxCol = 0;
|
||||||
|
var minSpace = Infinity;
|
||||||
|
var spaceOffsets = ranges.map(function(r) {
|
||||||
|
var p = r.cursor;
|
||||||
|
var line = session.getLine(p.row);
|
||||||
|
var spaceOffset = line.substr(p.column).search(/\S/g);
|
||||||
|
if (spaceOffset == -1)
|
||||||
|
spaceOffset = 0;
|
||||||
|
|
||||||
|
if (p.column > maxCol)
|
||||||
|
maxCol = p.column;
|
||||||
|
if (spaceOffset < minSpace)
|
||||||
|
minSpace = spaceOffset;
|
||||||
|
return spaceOffset;
|
||||||
|
});
|
||||||
|
ranges.forEach(function(r, i) {
|
||||||
|
var p = r.cursor;
|
||||||
|
var l = maxCol - p.column;
|
||||||
|
var d = spaceOffsets[i] - minSpace;
|
||||||
|
if (l > d)
|
||||||
|
session.insert(p, lang.stringRepeat(" ", l - d));
|
||||||
|
else
|
||||||
|
session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
|
||||||
|
|
||||||
|
r.start.column = r.end.column = maxCol;
|
||||||
|
r.start.row = r.end.row = p.row;
|
||||||
|
r.cursor = r.end;
|
||||||
|
});
|
||||||
|
sel.fromOrientedRange(ranges[0]);
|
||||||
|
this.renderer.updateCursor();
|
||||||
|
this.renderer.updateBackMarkers();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$reAlignText = function(lines) {
|
||||||
|
var isLeftAligned = true, isRightAligned = true;
|
||||||
|
var startW, textW, endW;
|
||||||
|
|
||||||
|
return lines.map(function(line) {
|
||||||
|
var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
|
||||||
|
if (!m)
|
||||||
|
return [line];
|
||||||
|
|
||||||
|
if (startW == null) {
|
||||||
|
startW = m[1].length;
|
||||||
|
textW = m[2].length;
|
||||||
|
endW = m[3].length;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
|
||||||
|
isRightAligned = false;
|
||||||
|
if (startW != m[1].length)
|
||||||
|
isLeftAligned = false;
|
||||||
|
|
||||||
|
if (startW > m[1].length)
|
||||||
|
startW = m[1].length;
|
||||||
|
if (textW < m[2].length)
|
||||||
|
textW = m[2].length;
|
||||||
|
if (endW > m[3].length)
|
||||||
|
endW = m[3].length;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}).map(isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
|
||||||
|
|
||||||
|
function strRepeat(n, ch) {
|
||||||
|
return Array(n + 1).join(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
function alignLeft(m) {
|
||||||
|
return !m[2] ? m[0] : strRepeat(startW, " ") + m[2]
|
||||||
|
+ strRepeat(textW - m[2].length + endW, " ")
|
||||||
|
+ m[4].replace(/^([=:])\s+/, "$1 ")
|
||||||
|
}
|
||||||
|
function alignRight(m) {
|
||||||
|
return !m[2] ? m[0] : strRepeat(startW + textW - m[2].length, " ") + m[2]
|
||||||
|
+ strRepeat(endW, " ")
|
||||||
|
+ m[4].replace(/^([=:])\s+/, "$1 ")
|
||||||
|
}
|
||||||
|
function unAlign(m) {
|
||||||
|
return !m[2] ? m[0] : strRepeat(startW, " ") + m[2]
|
||||||
|
+ strRepeat(endW, " ")
|
||||||
|
+ m[4].replace(/^([=:])\s+/, "$1 ")
|
||||||
|
}
|
||||||
|
}
|
||||||
}).call(Editor.prototype);
|
}).call(Editor.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue