Add support for doc doc comments:
- special highlighting - highlight jsdoc tags - special auto indent mode
This commit is contained in:
parent
80f6cd7726
commit
257d80f379
7 changed files with 103 additions and 43 deletions
|
|
@ -80,9 +80,17 @@
|
||||||
|
|
||||||
.line .comment {
|
.line .comment {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
color: rgb(76, 136, 107);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line .doc-comment {
|
||||||
color: rgb(0, 102, 255);
|
color: rgb(0, 102, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.line .doc-comment-tag {
|
||||||
|
color: rgb(128, 159, 191);
|
||||||
|
}
|
||||||
|
|
||||||
.line .number {
|
.line .number {
|
||||||
color: rgb(0, 0, 205);
|
color: rgb(0, 0, 205);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ ace.KeyBinding = function(element, editor) {
|
||||||
case keys.TAB:
|
case keys.TAB:
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
editor.blockOutdent();
|
editor.blockOutdent();
|
||||||
} else if (selection.isMultiLineSelection()) {
|
} else if (selection.isMultiLine()) {
|
||||||
editor.blockIndent();
|
editor.blockIndent();
|
||||||
} else {
|
} else {
|
||||||
editor.onTextInput("\t");
|
editor.onTextInput("\t");
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,14 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
||||||
|
|
||||||
var lastIndex = 0;
|
var lastIndex = 0;
|
||||||
|
|
||||||
|
var token = {
|
||||||
|
type: null,
|
||||||
|
value: ""
|
||||||
|
};
|
||||||
|
|
||||||
while (match = re.exec(line)) {
|
while (match = re.exec(line)) {
|
||||||
var token = {
|
var type = "text";
|
||||||
type : "text",
|
var value = match[0];
|
||||||
value : match[0]
|
|
||||||
};
|
|
||||||
|
|
||||||
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
||||||
lastIndex = re.lastIndex;
|
lastIndex = re.lastIndex;
|
||||||
|
|
@ -41,10 +44,10 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
||||||
for ( var i = 0; i < state.length; i++) {
|
for ( var i = 0; i < state.length; i++) {
|
||||||
if (match[i + 1]) {
|
if (match[i + 1]) {
|
||||||
if (typeof state[i].token == "function") {
|
if (typeof state[i].token == "function") {
|
||||||
token.type = state[i].token(match[0]);
|
type = state[i].token(match[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
token.type = state[i].token;
|
type = state[i].token;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state[i].next && state[i].next !== currentState) {
|
if (state[i].next && state[i].next !== currentState) {
|
||||||
|
|
@ -59,9 +62,23 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tokens.push(token);
|
if (token.type !== type) {
|
||||||
|
if (token.type) {
|
||||||
|
tokens.push(token);
|
||||||
|
}
|
||||||
|
token = {
|
||||||
|
type: type,
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
token.value += value;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (token.type) {
|
||||||
|
tokens.push(token);
|
||||||
|
}
|
||||||
|
|
||||||
// window.LOG && console.log(tokens, currentState);
|
// window.LOG && console.log(tokens, currentState);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,23 @@ ace.mode.JavaScript.prototype.toggleCommentLines = function(doc, range) {
|
||||||
return addedRows;
|
return addedRows;
|
||||||
};
|
};
|
||||||
|
|
||||||
ace.mode.JavaScript.prototype.increaseIndentPatterns = {
|
|
||||||
"start" : /^(\s*).*[\{\(\[]\s*$/
|
|
||||||
};
|
|
||||||
|
|
||||||
ace.mode.JavaScript.prototype.getNextLineIndent = function(line, state, tab) {
|
ace.mode.JavaScript.prototype.getNextLineIndent = function(line, state, tab) {
|
||||||
var re = this.increaseIndentPatterns[state];
|
if (state == "start") {
|
||||||
|
var re = /^(\s*).*[\{\(\[]\s*$/;
|
||||||
if (re) {
|
|
||||||
var match = line.match(re);
|
var match = line.match(re);
|
||||||
if (match) {
|
if (match) {
|
||||||
return (match[1] || "") + tab;
|
return (match[1] || "") + tab;
|
||||||
}
|
}
|
||||||
|
} else if (state == "doc-comment") {
|
||||||
|
var re = /^(\s*)(\/?)\*.*$/;
|
||||||
|
var match = line.match(re);
|
||||||
|
if (match) {
|
||||||
|
var indent = match[1];
|
||||||
|
if (match[2]) {
|
||||||
|
indent += " ";
|
||||||
|
}
|
||||||
|
return indent + "* ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var match = line.match(/^(\s+).*$/);
|
var match = line.match(/^(\s+).*$/);
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,16 @@ ace.mode.JavaScriptHighlightRules = function() {
|
||||||
// regexps are ordered -> the first match is used
|
// regexps are ordered -> the first match is used
|
||||||
|
|
||||||
this._rules = {
|
this._rules = {
|
||||||
start : [ {
|
"start" : [ {
|
||||||
token : "comment",
|
token : "comment",
|
||||||
regex : "\\/\\/.*$"
|
regex : "\\/\\/.*$"
|
||||||
}, {
|
}, {
|
||||||
token : "comment", // multi line comment in one line
|
token : "doc-comment", // doc comment
|
||||||
regex : "\\/\\*.*?\\*\\/"
|
regex : "\\/\\*\\*",
|
||||||
|
next : "doc-comment"
|
||||||
}, {
|
}, {
|
||||||
token : "comment", // multi line comment start
|
token : "comment", // multi line comment
|
||||||
regex : "\\/\\*.*$",
|
regex : "\\/\\*",
|
||||||
next : "comment"
|
next : "comment"
|
||||||
}, {
|
}, {
|
||||||
token : "string", // single line
|
token : "string", // single line
|
||||||
|
|
@ -82,6 +83,23 @@ ace.mode.JavaScriptHighlightRules = function() {
|
||||||
token : "text",
|
token : "text",
|
||||||
regex : "\\s+"
|
regex : "\\s+"
|
||||||
} ],
|
} ],
|
||||||
|
"doc-comment" : [ {
|
||||||
|
token : "doc-comment", // closing comment
|
||||||
|
regex : "\\*\\/",
|
||||||
|
next : "start"
|
||||||
|
}, {
|
||||||
|
token : "doc-comment-tag",
|
||||||
|
regex : "@[\\w\\d_]+"
|
||||||
|
}, {
|
||||||
|
token : "doc-comment",
|
||||||
|
regex : "\s+"
|
||||||
|
}, {
|
||||||
|
token : "doc-comment",
|
||||||
|
regex : "[^@\\*]+"
|
||||||
|
}, {
|
||||||
|
token : "doc-comment",
|
||||||
|
regex : "."
|
||||||
|
}],
|
||||||
"comment" : [ {
|
"comment" : [ {
|
||||||
token : "comment", // closing comment
|
token : "comment", // closing comment
|
||||||
regex : ".*?\\*\\/",
|
regex : ".*?\\*\\/",
|
||||||
|
|
|
||||||
|
|
@ -50,32 +50,23 @@ var JavaScriptTest = new TestCase("mode.JavaScriptTest", {
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: auto indent after opening brace" : function() {
|
"test: auto indent after opening brace" : function() {
|
||||||
var doc = new ace.TextDocument(["if () {"].join("\n"));
|
assertEquals(" ", this.mode.getNextLineIndent("if () {", "start", " "));
|
||||||
var editor = new ace.Editor(new MockRenderer(), doc, this.mode);
|
|
||||||
|
|
||||||
editor.navigateLineEnd();
|
|
||||||
editor.onTextInput("\n");
|
|
||||||
|
|
||||||
assertEquals(["if () {", doc.getTabString()].join("\n"), doc.toString());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: no auto indent after opening brace in multi line comment" : function() {
|
"test: no auto indent after opening brace in multi line comment" : function() {
|
||||||
var doc = new ace.TextDocument(["/*if () {"].join("\n"));
|
assertEquals("", this.mode.getNextLineIndent("/*if () {", " "));
|
||||||
var editor = new ace.Editor(new MockRenderer(), doc, this.mode);
|
|
||||||
|
|
||||||
editor.navigateLineEnd();
|
|
||||||
editor.onTextInput("\n");
|
|
||||||
|
|
||||||
assertEquals(["/*if () {", ""].join("\n"), doc.toString());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: no auto indent should add to existing indent" : function() {
|
"test: no auto indent should add to existing indent" : function() {
|
||||||
var doc = new ace.TextDocument([" if () {"].join("\n"));
|
assertEquals(" ", this.mode.getNextLineIndent(" if () {", "start", " "));
|
||||||
var editor = new ace.Editor(new MockRenderer(), doc, this.mode);
|
assertEquals(" ", this.mode.getNextLineIndent(" cde", "start", " "));
|
||||||
|
},
|
||||||
|
|
||||||
editor.navigateLineEnd();
|
"test: special indent in doc comments" : function() {
|
||||||
editor.onTextInput("\n");
|
assertEquals(" * ", this.mode.getNextLineIndent("/**", "doc-comment", " "));
|
||||||
|
assertEquals(" * ", this.mode.getNextLineIndent(" /**", "doc-comment", " "));
|
||||||
assertEquals([" if () {", " " + doc.getTabString()].join("\n"), doc.toString());
|
assertEquals(" * ", this.mode.getNextLineIndent(" *", "doc-comment", " "));
|
||||||
|
assertEquals(" * ", this.mode.getNextLineIndent(" *", "doc-comment", " "));
|
||||||
|
assertEquals(" ", this.mode.getNextLineIndent(" abc", "doc-comment", " "));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -9,12 +9,33 @@ var JavaScriptTokenizerTest = new TestCase("mode.JavaScriptTokenizerTest", {
|
||||||
|
|
||||||
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
||||||
|
|
||||||
|
assertEquals(3, tokens.length);
|
||||||
|
assertEquals("identifier", tokens[0].type);
|
||||||
|
assertEquals("text", tokens[1].type);
|
||||||
|
assertEquals("keyword", tokens[2].type);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: tokenize doc comment" : function() {
|
||||||
|
var line = "abc /** de */ fg";
|
||||||
|
|
||||||
|
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
||||||
|
|
||||||
assertEquals(5, tokens.length);
|
assertEquals(5, tokens.length);
|
||||||
assertEquals("identifier", tokens[0].type);
|
assertEquals("identifier", tokens[0].type);
|
||||||
assertEquals("text", tokens[1].type);
|
assertEquals("text", tokens[1].type);
|
||||||
assertEquals("text", tokens[2].type);
|
assertEquals("doc-comment", tokens[2].type);
|
||||||
assertEquals("text", tokens[3].type);
|
assertEquals("text", tokens[3].type);
|
||||||
assertEquals("keyword", tokens[4].type);
|
assertEquals("identifier", tokens[4].type);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
"test: tokenize doc comment with tag" : function() {
|
||||||
|
var line = "/** @param {} */";
|
||||||
|
|
||||||
|
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
||||||
|
|
||||||
|
assertEquals(3, tokens.length);
|
||||||
|
assertEquals("doc-comment", tokens[0].type);
|
||||||
|
assertEquals("doc-comment-tag", tokens[1].type);
|
||||||
|
assertEquals("doc-comment", tokens[2].type);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue