Preserve selection/cursor after beautify-css

This commit is contained in:
tophf 2017-03-29 08:30:14 +03:00
parent 668e3a7b56
commit 3876ffc671
2 changed files with 96 additions and 19 deletions

View File

@ -114,6 +114,12 @@
var newline_before_open_brace = defaultOption(options.newline_before_open_brace, false);
var newline_after_open_brace = defaultOption(options.newline_after_open_brace, true);
var newline_before_close_brace = defaultOption(options.newline_before_close_brace, true);
var translatePos = (options.translate_positions || [])[0];
var translatePosIndex = 0;
var translatePosLine = translatePos && translatePos.line;
var translatePosCol = translatePos && translatePos.ch;
var inputPosLine = 0, inputPosCol = 0;
var outputPosLine = 0, outputPosCol = 0;
/* STYLUS: hack end */
if (options.indent_with_tabs) {
@ -140,20 +146,46 @@
ch;
var parenLevel = 0;
function next() {
function next(resetLine, resetCol) {
if (resetLine !== undefined) {
inputPosLine = resetLine;
inputPosCol = resetCol;
if (inputPosCol < 0) {
inputPosLine--;
inputPosCol = pos - source_text.lastIndexOf('\n', pos);
}
}
ch = source_text.charAt(++pos);
if (translatePos) {
inputPosCol++;
if (ch == '\n') {
inputPosLine++;
inputPosCol = 0;
}
if (inputPosLine == translatePosLine && inputPosCol >= translatePosCol
|| inputPosLine > translatePosLine) {
translatePos.line = outputPosLine - (inputPosLine - translatePosLine);
translatePos.ch = outputPosCol - (inputPosCol - translatePosCol);
translatePos.ch += translatePos.ch ? 1 : 0;
translatePos = options.translate_positions[++translatePosIndex];
translatePosLine = translatePos && translatePos.line;
translatePosCol = translatePos && translatePos.ch;
}
}
return ch || '';
}
function peek(skipWhitespace) {
var result = '';
var prev_pos = pos;
var prevInputPosLine = inputPosLine;
var prevInputPosCol = inputPosCol;
if (skipWhitespace) {
eatWhitespace();
}
result = source_text.charAt(pos + 1) || '';
pos = prev_pos - 1;
next();
next(prevInputPosLine, prevInputPosCol - 1);
return result;
}
@ -173,9 +205,11 @@
function peekString(endChar) {
var prev_pos = pos;
var prevInputPosLine = inputPosLine;
var prevInputPosCol = inputPosCol;
var str = eatString(endChar);
pos = prev_pos - 1;
next();
next(prevInputPosLine, prevInputPosCol - 1);
return str;
}
@ -267,23 +301,19 @@
var print = {};
print["{"] = function(ch) {
/* STYLUS: hack start */
newline_before_open_brace ? print.newLine() : print.singleSpace();
/* STYLUS: hack end */
output.push(ch);
outputPosCol++;
if (!eatWhitespace(true)) {
/* STYLUS: hack start */
newline_after_open_brace ? print.newLine() : print.singleSpace();
/* STYLUS: hack end */
}
};
print["}"] = function(newline) {
if (newline) {
/* STYLUS: hack start */
newline_before_close_brace ? print.newLine() : (print.trim(), print.singleSpace());
/* STYLUS: hack end */
}
output.push('}');
outputPosCol++;
if (!eatWhitespace(true)) {
print.newLine();
}
@ -299,17 +329,22 @@
print.trim();
} else if (output[output.length - 1] === basebaseIndentString) {
output.pop();
outputPosCol -= basebaseIndentString.length;
}
output.push('\n');
outputPosLine++;
outputPosCol = 0;
if (basebaseIndentString) {
output.push(basebaseIndentString);
outputPosCol += basebaseIndentString.length;
}
}
};
print.singleSpace = function() {
if (output.length && !print._lastCharWhitespace()) {
output.push(' ');
outputPosCol++;
}
};
@ -321,7 +356,25 @@
print.trim = function() {
while (print._lastCharWhitespace()) {
output.pop();
const text = output.pop();
if (text.indexOf('\n') >= 0) {
outputPosLine -= text.match(/\n/g).length;
}
}
outputPosCol = 0;
let i = output.length, token;
while (--i >= 0 && (token = output[i]) != '\n') {
outputPosCol += token.length;
}
};
print.text = function(text) {
output.push(text);
if (text.indexOf('\n') < 0) {
outputPosCol += text.length;
} else {
outputPosLine += text.match(/\n/g).length;
outputPosCol = text.length - text.lastIndexOf('\n') - 1;
}
};
@ -351,7 +404,7 @@
print.newLine();
}
output.push(eatComment());
print.text(eatComment());
print.newLine();
if (header) {
print.newLine(true);
@ -361,16 +414,17 @@
print.trim();
}
print.singleSpace();
output.push(eatComment());
print.text(eatComment());
print.newLine();
} else if (ch === '@') {
print.preserveSingleSpace();
// deal with less propery mixins @{...}
if (peek() === '{') {
output.push(eatString('}'));
print.text(eatString('}'));
} else {
output.push(ch);
outputPosCol++;
// strip trailing space, if present, for hash property checks
var variableOrRule = peekString(": ,;{}()[]/='\"");
@ -379,7 +433,7 @@
// we have a variable or pseudo-class, add it and insert one space before continuing
next();
variableOrRule = eatString(": ").replace(/\s$/, '');
output.push(variableOrRule);
print.text(variableOrRule);
print.singleSpace();
}
@ -395,13 +449,14 @@
}
} else if (ch === '#' && peek() === '{') {
print.preserveSingleSpace();
output.push(eatString('}'));
print.text(eatString('}'));
} else if (ch === '{') {
if (peek(true) === '}') {
eatWhitespace();
next();
print.singleSpace();
output.push("{");
outputPosCol++;
print['}'](false);
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
print.newLine(true);
@ -437,6 +492,7 @@
// 'property: value' delimiter
// which could be in a conditional group query
output.push(':');
outputPosCol++;
if (!insidePropertyValue) {
insidePropertyValue = true;
print.singleSpace();
@ -448,34 +504,37 @@
// preserve space before pseudoclasses/pseudoelements, as it means "in any child"
if (lookBack(" ") && output[output.length - 1] !== " ") {
output.push(" ");
outputPosCol++;
}
if (peek() === ":") {
// pseudo-element
next();
output.push("::");
outputPosCol += 2;
} else {
// pseudo-class
output.push(':');
outputPosCol++;
}
}
} else if (ch === '"' || ch === '\'') {
print.preserveSingleSpace();
output.push(eatString(ch));
print.text(eatString(ch));
} else if (ch === ';') {
insidePropertyValue = false;
output.push(ch);
outputPosCol++;
if (!eatWhitespace(true)) {
/* STYLUS: hack start */
newline_between_properties ? print.newLine() : print.singleSpace();
/* STYLUS: hack end */
}
} else if (ch === '(') { // may be a url
if (lookBack("url")) {
output.push(ch);
outputPosCol++;
eatWhitespace();
if (next()) {
if (ch !== ')' && ch !== '"' && ch !== '\'') {
output.push(eatString(')'));
print.text(eatString(')'));
} else {
pos--;
}
@ -484,13 +543,16 @@
parenLevel++;
print.preserveSingleSpace();
output.push(ch);
outputPosCol++;
eatWhitespace();
}
} else if (ch === ')') {
output.push(ch);
outputPosCol++;
parenLevel--;
} else if (ch === ',') {
output.push(ch);
outputPosCol++;
if (!eatWhitespace(true) && selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
print.newLine();
} else {
@ -502,9 +564,11 @@
if (space_around_combinator) {
print.singleSpace();
output.push(ch);
outputPosCol++;
print.singleSpace();
} else {
output.push(ch);
outputPosCol++;
eatWhitespace();
// squash extra whitespace
if (ch && whiteRe.test(ch)) {
@ -513,18 +577,22 @@
}
} else if (ch === ']') {
output.push(ch);
outputPosCol++;
} else if (ch === '[') {
print.preserveSingleSpace();
output.push(ch);
outputPosCol++;
} else if (ch === '=') { // no whitespace before or after
eatWhitespace();
output.push('=');
outputPosCol++;
if (whiteRe.test(ch)) {
ch = '';
}
} else {
print.preserveSingleSpace();
output.push(ch);
outputPosCol++;
}
}

View File

@ -1049,6 +1049,7 @@ function beautify(event) {
if (cm.beautifyChange && cm.beautifyChange[cm.changeGeneration()]) {
delete cm.beautifyChange[cm.changeGeneration()];
cm.undo();
cm.scrollIntoView(cm.getCursor());
undoable |= cm.beautifyChange[cm.changeGeneration()];
}
});
@ -1057,6 +1058,9 @@ function beautify(event) {
scope.forEach(function(cm) {
setTimeout(function() {
const pos = options.translate_positions =
[].concat.apply([], cm.doc.sel.ranges.map(r =>
[Object.assign({}, r.anchor), Object.assign({}, r.head)]));
var text = cm.getValue();
var newText = exports.css_beautify(text, options);
if (newText != text) {
@ -1065,6 +1069,11 @@ function beautify(event) {
cm.beautifyChange = {};
}
cm.setValue(newText);
const selections = [];
for (let i = 0; i < pos.length; i += 2) {
selections.push({anchor: pos[i], head: pos[i + 1]});
}
cm.setSelections(selections);
cm.beautifyChange[cm.changeGeneration()] = true;
undoButton.disabled = false;
}