add folding for xml style modes. Also refactor
html, svg and xml modes to reuse code
This commit is contained in:
parent
9a612cd2e5
commit
71d5f359fb
9 changed files with 234 additions and 181 deletions
|
|
@ -391,7 +391,7 @@ function Folding() {
|
|||
this.removeFold(fold);
|
||||
}, this);
|
||||
this.$modified = true;
|
||||
}
|
||||
};
|
||||
|
||||
this.expandFold = function(fold) {
|
||||
this.removeFold(fold);
|
||||
|
|
@ -399,13 +399,13 @@ function Folding() {
|
|||
this.addFold(fold);
|
||||
}, this);
|
||||
fold.subFolds = [];
|
||||
}
|
||||
};
|
||||
|
||||
this.expandFolds = function(folds) {
|
||||
folds.forEach(function(fold) {
|
||||
this.expandFold(fold);
|
||||
}, this);
|
||||
}
|
||||
};
|
||||
|
||||
this.unfold = function(location, expandInner) {
|
||||
var range, folds;
|
||||
|
|
@ -418,7 +418,7 @@ function Folding() {
|
|||
else
|
||||
range = location;
|
||||
|
||||
var folds = this.getFoldsInRange(range);
|
||||
folds = this.getFoldsInRange(range);
|
||||
if (expandInner) {
|
||||
this.removeFolds(folds);
|
||||
} else {
|
||||
|
|
@ -429,7 +429,7 @@ function Folding() {
|
|||
folds = this.getFoldsInRange(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a given documentRow is folded. This is true if there are some
|
||||
|
|
@ -458,7 +458,6 @@ function Folding() {
|
|||
}
|
||||
|
||||
// Build the textline using the FoldLine walker.
|
||||
var line = "";
|
||||
var doc = this.doc;
|
||||
var textLine = "";
|
||||
|
||||
|
|
@ -494,7 +493,6 @@ function Folding() {
|
|||
};
|
||||
|
||||
this.$cloneFoldData = function() {
|
||||
var foldData = this.$foldData;
|
||||
var fd = [];
|
||||
fd = this.$foldData.map(function(foldLine) {
|
||||
var folds = foldLine.folds.map(function(fold) {
|
||||
|
|
@ -511,9 +509,9 @@ function Folding() {
|
|||
var range = selection.getRange();
|
||||
|
||||
if (range.isEmpty()) {
|
||||
var cursor = range.start
|
||||
var cursor = range.start;
|
||||
var fold = this.getFoldAt(cursor.row, cursor.column);
|
||||
var bracketPos, column;
|
||||
var bracketPos;
|
||||
|
||||
if (fold) {
|
||||
this.expandFold(fold);
|
||||
|
|
@ -601,7 +599,6 @@ function Folding() {
|
|||
continue
|
||||
|
||||
var range = this.getFoldWidgetRange(row);
|
||||
console.log(row, range)
|
||||
if (range)
|
||||
this.addFold("...", range)
|
||||
}
|
||||
|
|
@ -771,7 +768,98 @@ Folding.commonFoldingRules = {
|
|||
}
|
||||
},
|
||||
// TODO: folding based only on indentation
|
||||
"indentation": null
|
||||
"indentation": null,
|
||||
|
||||
"xml": {
|
||||
getFoldWidget: function(row) {
|
||||
var tags = this.getTokens(row, row)[0].tokens
|
||||
.filter(function(token) {
|
||||
return token.type === "meta.tag"
|
||||
})
|
||||
.map(function(token) {
|
||||
return token.value;
|
||||
}).
|
||||
join("")
|
||||
.trim()
|
||||
.replace(/^<|>$|\s+/g, "")
|
||||
.split("><")
|
||||
|
||||
var fold = tags[0];
|
||||
|
||||
if (!fold)
|
||||
return;
|
||||
if (fold.charAt(0) == "/")
|
||||
return "end";
|
||||
|
||||
if (tags.indexOf("/" + fold) !== -1)
|
||||
return;
|
||||
|
||||
return "start";
|
||||
},
|
||||
|
||||
getFoldWidgetRange: function(row) {
|
||||
var start, end;
|
||||
var stack = [];
|
||||
|
||||
var iterator = new TokenIterator(this, row, 0);
|
||||
var step = "stepForward";
|
||||
var isBack = false;
|
||||
|
||||
do {
|
||||
var token = iterator.getCurrentToken();
|
||||
|
||||
var value = token.value.trim();
|
||||
if (token && token.type == "meta.tag" && token.value !== ">") {
|
||||
var tagName = value.replace(/^[<\s]*|[\s*>]$/g, "");
|
||||
if (!start) {
|
||||
if (tagName.charAt(0) == "/") {
|
||||
tagName = tagName.slice(1);
|
||||
step = "stepBackward";
|
||||
isBack = true;
|
||||
}
|
||||
|
||||
start = {
|
||||
row: row,
|
||||
column: iterator.getCurrentTokenColumn() + (isBack ? 0 : value.length + 1)
|
||||
};
|
||||
|
||||
stack.push(tagName);
|
||||
}
|
||||
else {
|
||||
if (tagName.charAt(0) == "/") {
|
||||
tagName = tagName.slice(1);
|
||||
var close = !isBack;
|
||||
}
|
||||
else
|
||||
close = isBack;
|
||||
|
||||
if (close) {
|
||||
if (stack[stack.length-1] == tagName) {
|
||||
stack.pop();
|
||||
if (stack.length == 0) {
|
||||
end = {
|
||||
row: iterator.getCurrentTokenRow(),
|
||||
column: iterator.getCurrentTokenColumn() + (isBack ? value.length : 0)
|
||||
};
|
||||
if (isBack)
|
||||
return Range.fromPoints(end, start);
|
||||
else
|
||||
return Range.fromPoints(start, end);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error("unmatched tags!", tagName, stack)
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack.push(tagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while(token = iterator[step]());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.Folding = Folding;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue