ace里面有没有returns我匹配括号位置的函数?
Is there any function in ace which returns me matching bracket position?
我试过 jumpToMatching() 函数,它带我到匹配括号的位置,但我需要一个函数 returns 我到匹配括号的位置。有什么方法可以帮助我吗?
翻了翻default_commands.js没有这个功能
有 jumptomatching
、selecttomatching
和 expandToMatching
。
他们三个都使用带有不同参数的函数editor.jumpToMatching()
。
深入研究代码,我在 editor.js / ace.js
中找到了该函数
通过一些调整,我能够创建以下工作函数:
this.returnMatchingPos = function() {
var cursor = this.getCursorPosition();
var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
var prevToken = iterator.getCurrentToken();
var token = prevToken || iterator.stepForward();
if (!token) return;
//get next closing tag or bracket
var matchType;
var found = false;
var depth = {};
var i = cursor.column - token.start;
var bracketType;
var brackets = {
")": "(",
"(": "(",
"]": "[",
"[": "[",
"{": "{",
"}": "{"
};
do {
if (token.value.match(/[{}()\[\]]/g)) {
for (; i < token.value.length && !found; i++) {
if (!brackets[token.value[i]]) {
continue;
}
bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
if (isNaN(depth[bracketType])) {
depth[bracketType] = 0;
}
switch (token.value[i]) {
case '(':
case '[':
case '{':
depth[bracketType]++;
break;
case ')':
case ']':
case '}':
depth[bracketType]--;
if (depth[bracketType] === -1) {
matchType = 'bracket';
found = true;
}
break;
}
}
}
else if (token && token.type.indexOf('tag-name') !== -1) {
if (isNaN(depth[token.value])) {
depth[token.value] = 0;
}
if (prevToken.value === '<') {
depth[token.value]++;
}
else if (prevToken.value === '</') {
depth[token.value]--;
}
if (depth[token.value] === -1) {
matchType = 'tag';
found = true;
}
}
if (!found) {
prevToken = token;
token = iterator.stepForward();
i = 0;
}
} while (token && !found);
//no match found
if (!matchType)
return;
var range, pos;
if (matchType === 'bracket') {
range = this.session.getBracketRange(cursor);
if (!range) {
range = new Range(
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() + i - 1,
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() + i - 1
);
pos = range.start;
}
}
else if (matchType === 'tag') {
if (token && token.type.indexOf('tag-name') !== -1)
var tag = token.value;
else
return;
range = new Range(
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() - 2,
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() - 2
);
//find matching tag
if (range.compare(cursor.row, cursor.column) === 0) {
found = false;
do {
token = prevToken;
prevToken = iterator.stepBackward();
if (prevToken) {
if (prevToken.type.indexOf('tag-close') !== -1) {
range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);
}
if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
if (prevToken.value === '<') {
depth[tag]++;
}
else if (prevToken.value === '</') {
depth[tag]--;
}
if (depth[tag] === 0)
found = true;
}
}
} while (prevToken && !found);
}
//we found it
if (token && token.type.indexOf('tag-name')) {
pos = range.start;
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
pos = range.end;
}
}
pos = range && range.cursor || pos;
if (pos) {
return pos;
}
};
open/edit ace.js
并找到这一行: this.jumpToMatching = function(select, expand) {
现在将我在上面提供的函数粘贴到您刚刚找到的行之前。保存更改并关闭。
之后你可以使用 editor.returnMatchingPos()
调用它,它应该 return 一个带有 row
和 column
的对象,就像 editor.getCursorPosition()
为什么不将它包含在我自己的代码中?
现有函数使用在文件中定义的TokenIterator
。如果您可以在自己的代码中找到 var TokenIterator = require("./token_iterator").TokenIterator;
的方法,然后在我提供的函数中将 this
的所有实例更改为 editor
,则可以在编辑器对象之外使用该函数。
我试过 jumpToMatching() 函数,它带我到匹配括号的位置,但我需要一个函数 returns 我到匹配括号的位置。有什么方法可以帮助我吗?
翻了翻default_commands.js没有这个功能
有 jumptomatching
、selecttomatching
和 expandToMatching
。
他们三个都使用带有不同参数的函数editor.jumpToMatching()
。
深入研究代码,我在 editor.js / ace.js
中找到了该函数通过一些调整,我能够创建以下工作函数:
this.returnMatchingPos = function() {
var cursor = this.getCursorPosition();
var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
var prevToken = iterator.getCurrentToken();
var token = prevToken || iterator.stepForward();
if (!token) return;
//get next closing tag or bracket
var matchType;
var found = false;
var depth = {};
var i = cursor.column - token.start;
var bracketType;
var brackets = {
")": "(",
"(": "(",
"]": "[",
"[": "[",
"{": "{",
"}": "{"
};
do {
if (token.value.match(/[{}()\[\]]/g)) {
for (; i < token.value.length && !found; i++) {
if (!brackets[token.value[i]]) {
continue;
}
bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen");
if (isNaN(depth[bracketType])) {
depth[bracketType] = 0;
}
switch (token.value[i]) {
case '(':
case '[':
case '{':
depth[bracketType]++;
break;
case ')':
case ']':
case '}':
depth[bracketType]--;
if (depth[bracketType] === -1) {
matchType = 'bracket';
found = true;
}
break;
}
}
}
else if (token && token.type.indexOf('tag-name') !== -1) {
if (isNaN(depth[token.value])) {
depth[token.value] = 0;
}
if (prevToken.value === '<') {
depth[token.value]++;
}
else if (prevToken.value === '</') {
depth[token.value]--;
}
if (depth[token.value] === -1) {
matchType = 'tag';
found = true;
}
}
if (!found) {
prevToken = token;
token = iterator.stepForward();
i = 0;
}
} while (token && !found);
//no match found
if (!matchType)
return;
var range, pos;
if (matchType === 'bracket') {
range = this.session.getBracketRange(cursor);
if (!range) {
range = new Range(
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() + i - 1,
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() + i - 1
);
pos = range.start;
}
}
else if (matchType === 'tag') {
if (token && token.type.indexOf('tag-name') !== -1)
var tag = token.value;
else
return;
range = new Range(
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() - 2,
iterator.getCurrentTokenRow(),
iterator.getCurrentTokenColumn() - 2
);
//find matching tag
if (range.compare(cursor.row, cursor.column) === 0) {
found = false;
do {
token = prevToken;
prevToken = iterator.stepBackward();
if (prevToken) {
if (prevToken.type.indexOf('tag-close') !== -1) {
range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn() + 1);
}
if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
if (prevToken.value === '<') {
depth[tag]++;
}
else if (prevToken.value === '</') {
depth[tag]--;
}
if (depth[tag] === 0)
found = true;
}
}
} while (prevToken && !found);
}
//we found it
if (token && token.type.indexOf('tag-name')) {
pos = range.start;
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
pos = range.end;
}
}
pos = range && range.cursor || pos;
if (pos) {
return pos;
}
};
open/edit ace.js
并找到这一行: this.jumpToMatching = function(select, expand) {
现在将我在上面提供的函数粘贴到您刚刚找到的行之前。保存更改并关闭。
之后你可以使用 editor.returnMatchingPos()
调用它,它应该 return 一个带有 row
和 column
的对象,就像 editor.getCursorPosition()
为什么不将它包含在我自己的代码中?
现有函数使用在文件中定义的TokenIterator
。如果您可以在自己的代码中找到 var TokenIterator = require("./token_iterator").TokenIterator;
的方法,然后在我提供的函数中将 this
的所有实例更改为 editor
,则可以在编辑器对象之外使用该函数。