Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
nightwing
84a0246e2c highlight matching tag 2013-09-23 12:14:19 +04:00
nightwing
528e760dcd do not add fold widget for doctype 2013-09-22 02:46:19 +04:00
nightwing
10a759feb7 do not include tag attributes in the fold 2013-09-22 02:46:18 +04:00
nightwing
127270a7aa fix mixed folding misses folds on lines drawn before tokenization is finished 2013-09-22 02:46:18 +04:00
nightwing
04a308e00d make findMatchingBracket faster 2013-09-22 02:46:17 +04:00
9 changed files with 112 additions and 41 deletions

View file

@ -102,7 +102,7 @@ function BracketMatch() {
"}": "{"
};
this.$findOpeningBracket = function(bracket, position, typeRe) {
this.$findOpeningBracket = function(bracket, position, type) {
var openBracket = this.$brackets[bracket];
var depth = 1;
@ -113,20 +113,14 @@ function BracketMatch() {
if (!token)
return;
if (!typeRe){
typeRe = new RegExp(
"(\\.?" +
token.type.replace(".", "\\.").replace("rparen", ".paren")
+ ")+"
);
}
if (!type)
type = token.type.replace(/\.(?:rparen|lparen|start|end)$/, "");
// Start searching in token, just before the character at position.column
var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
var value = token.value;
while (true) {
while (true) {
while (valueIndex >= 0) {
var chr = value.charAt(valueIndex);
if (chr == openBracket) {
@ -146,7 +140,7 @@ function BracketMatch() {
// whose type matches typeRe
do {
token = iterator.stepBackward();
} while (token && !typeRe.test(token.type));
} while (token && token.type.lastIndexOf(type, 0));
if (token == null)
break;
@ -155,10 +149,10 @@ function BracketMatch() {
valueIndex = value.length - 1;
}
return null;
return false;
};
this.$findClosingBracket = function(bracket, position, typeRe) {
this.$findClosingBracket = function(bracket, position, type) {
var closingBracket = this.$brackets[bracket];
var depth = 1;
@ -169,19 +163,13 @@ function BracketMatch() {
if (!token)
return;
if (!typeRe){
typeRe = new RegExp(
"(\\.?" +
token.type.replace(".", "\\.").replace("lparen", ".paren")
+ ")+"
);
}
if (!type)
type = token.type.replace(/\.(?:rparen|lparen|start|end)$/, "");
// Start searching in token, after the character at position.column
var valueIndex = position.column - iterator.getCurrentTokenColumn();
while (true) {
var value = token.value;
var valueLength = value.length;
while (valueIndex < valueLength) {
@ -203,7 +191,7 @@ function BracketMatch() {
// whose type matches typeRe
do {
token = iterator.stepForward();
} while (token && !typeRe.test(token.type));
} while (token && token.type.lastIndexOf(type, 0));
if (token == null)
break;
@ -211,7 +199,7 @@ function BracketMatch() {
valueIndex = 0;
}
return null;
return false;
};
}
exports.BracketMatch = BracketMatch;

View file

@ -355,10 +355,10 @@ module.exports = {
case "{":
case "[":
var cursor = editor.getCursorPosition();
var end = editor.session.$findClosingBracket(param, cursor, /paren/);
var end = editor.session.$findClosingBracket(param, cursor, "paren");
if (!end)
return;
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/);
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, "paren");
if (!start)
return;
end.column ++;

View file

@ -59,6 +59,8 @@ oop.inherits(FoldMode, BaseFoldMode);
};
this.getFoldWidget = function(session, foldStyle, row) {
if (session.bgTokenizer.currentLine < row)
return;
return (
this.$tryMode(session.getState(row-1), session, foldStyle, row) ||
this.$tryMode(session.getState(row), session, foldStyle, row) ||

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
@ -14,7 +14,7 @@
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -113,7 +113,7 @@ oop.inherits(FoldMode, BaseFoldMode);
};
}
value += token.value;
if (value.indexOf(">") !== -1) {
if (token.type.slice(-4) === ".end") {
var tag = this._parseTag(value);
tag.start = start;
tag.end = {
@ -164,7 +164,6 @@ oop.inherits(FoldMode, BaseFoldMode);
this._pop = function(stack, tag) {
while (stack.length) {
var top = stack[stack.length-1];
if (!tag || top.tagName == tag.tagName) {
return stack.pop();
@ -195,7 +194,7 @@ oop.inherits(FoldMode, BaseFoldMode);
var iterator = new TokenIterator(session, row, firstTag.column);
var start = {
row: row,
column: firstTag.column + firstTag.tagName.length + 2
column: firstTag.column + firstTag.match.length
};
while (tag = this._readTagForward(iterator)) {
if (tag.selfClosing) {
@ -209,8 +208,9 @@ oop.inherits(FoldMode, BaseFoldMode);
if (tag.closing) {
this._pop(stack, tag);
if (stack.length == 0)
if (!stack.length)
return Range.fromPoints(start, tag.start);
}
else {
stack.push(tag)
@ -236,9 +236,12 @@ oop.inherits(FoldMode, BaseFoldMode);
if (!tag.closing) {
this._pop(stack, tag);
if (stack.length == 0) {
tag.start.column += tag.tagName.length + 2;
return Range.fromPoints(tag.start, end);
if (!stack.length) {
if (tag.start.row != tag.end.row) {
tag.end = tag.start;
tag.end.column += session.getLine(tag.end.row).length;
}
return Range.fromPoints(tag.end, end);
}
}
else {
@ -246,9 +249,81 @@ oop.inherits(FoldMode, BaseFoldMode);
}
}
}
};
this.getMatching = function(session, row, column) {
if (row == undefined)
row = session.selection.lead
if (typeof row == "object") {
column = row.column;
row = row.row;
}
var TAG_NAME = "meta.tag.name";
var iterator = new TokenIterator(session, row, column);
var startToken = iterator.getCurrentToken();
if (!startToken)
return;
if (startToken.type.lastIndexOf(TAG_NAME, 0) == 0) {
startToken = iterator.stepBackward();
} else
return;
var isBackward = startToken.value == "</";
var stack = [];
var tag;
if (!isBackward) {
while (tag = this._readTagForward(iterator)) {
if (tag.selfClosing) {
if (!stack.length) {
return Range.fromPoints(tag.start, tag.end);
} else
continue;
}
if (tag.closing) {
this._pop(stack, tag);
if (!stack.length) {
var row = tag.start.row;
var col = tag.start.column + 2;
return new Range(row, col, row, col + tag.tagName.length)
}
}
else {
stack.push(tag)
}
}
}
else {
tag = this._readTagForward(iterator);
iterator.stepBackward();
while (tag = this._readTagBackward(iterator)) {
if (tag.selfClosing) {
if (!stack.length) {
tag.start.column += tag.tagName.length + 2;
tag.end.column -= 2;
return Range.fromPoints(tag.start, tag.end);
} else
continue;
}
if (!tag.closing) {
this._pop(stack, tag);
if (!stack.length) {
var row = tag.start.row;
var col = tag.start.column + 1;
return new Range(row, col, row, col + tag.tagName.length)
}
}
else {
stack.push(tag)
}
}
}
};
}).call(FoldMode.prototype);
});

View file

@ -69,6 +69,10 @@ oop.inherits(Mode, TextMode);
return false;
};
this.getMatching = function(session, row, column) {
return this.foldingRules.defaultMode.getMatching(session, row, column);
};
this.getCompletions = function(state, session, pos, prefix) {
return this.$completer.getCompletions(state, session, pos, prefix);
};

View file

@ -50,6 +50,9 @@ oop.inherits(Mode, TextMode);
this.blockComment = {start: "<!--", end: "-->"};
this.getMatching = function(session, row, column) {
return this.foldingRules.getMatching(session, row, column);
}
}).call(Mode.prototype);
exports.Mode = Mode;

View file

@ -49,7 +49,7 @@ var XmlHighlightRules = function(normalize) {
},
{token : "comment", regex : "<\\!--", next : "comment"},
{
token : ["punctuation.doctype.begin", "meta.tag.doctype"],
token : ["punctuation.doctype.begin", "meta.doctype.tag"],
regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype"
},
{include : "tag"},

View file

@ -60,13 +60,12 @@ exports.tag = function(states, name, nextState, tagMap) {
regex : "\\s+"
}, {
//token : "meta.tag",
token : !tagMap ? "meta.tag.tag-name" : function(value) {
token : tagMap ? function(value) {
if (tagMap[value])
return "meta.tag.tag-name." + tagMap[value];
else
return "meta.tag.tag-name";
},
} : "meta.tag.tag-name",
regex : "[-_a-zA-Z0-9:]+",
next : name + "_embed_attribute_list"
}, {

View file

@ -131,7 +131,7 @@ var TokenIterator = function(session, initialRow, initialColumn) {
var tokenIndex = this.$tokenIndex;
// If a column was cached by EditSession.getTokenAt, then use it
var column = rowTokens[tokenIndex].start;
var column = rowTokens[tokenIndex] && rowTokens[tokenIndex].start;
if (column !== undefined)
return column;
@ -141,7 +141,7 @@ var TokenIterator = function(session, initialRow, initialColumn) {
column += rowTokens[tokenIndex].value.length;
}
return column;
return column;
};
}).call(TokenIterator.prototype);