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

View File

@ -1049,6 +1049,7 @@ function beautify(event) {
if (cm.beautifyChange && cm.beautifyChange[cm.changeGeneration()]) { if (cm.beautifyChange && cm.beautifyChange[cm.changeGeneration()]) {
delete cm.beautifyChange[cm.changeGeneration()]; delete cm.beautifyChange[cm.changeGeneration()];
cm.undo(); cm.undo();
cm.scrollIntoView(cm.getCursor());
undoable |= cm.beautifyChange[cm.changeGeneration()]; undoable |= cm.beautifyChange[cm.changeGeneration()];
} }
}); });
@ -1057,6 +1058,9 @@ function beautify(event) {
scope.forEach(function(cm) { scope.forEach(function(cm) {
setTimeout(function() { 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 text = cm.getValue();
var newText = exports.css_beautify(text, options); var newText = exports.css_beautify(text, options);
if (newText != text) { if (newText != text) {
@ -1065,6 +1069,11 @@ function beautify(event) {
cm.beautifyChange = {}; cm.beautifyChange = {};
} }
cm.setValue(newText); 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; cm.beautifyChange[cm.changeGeneration()] = true;
undoButton.disabled = false; undoButton.disabled = false;
} }