Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
c6b09780
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
c6b09780
编写于
10月 16, 2019
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allow bracket matching to search across multiple tokens
上级
2205002a
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
236 addition
and
136 deletion
+236
-136
src/vs/editor/common/model/textModel.ts
src/vs/editor/common/model/textModel.ts
+213
-110
src/vs/editor/common/modes/supports/electricCharacter.ts
src/vs/editor/common/modes/supports/electricCharacter.ts
+1
-1
src/vs/editor/common/modes/supports/richEditBrackets.ts
src/vs/editor/common/modes/supports/richEditBrackets.ts
+7
-10
src/vs/editor/test/common/modes/supports/richEditBrackets.test.ts
...ditor/test/common/modes/supports/richEditBrackets.test.ts
+15
-15
未找到文件。
src/vs/editor/common/model/textModel.ts
浏览文件 @
c6b09780
...
...
@@ -1910,7 +1910,7 @@ export class TextModel extends Disposable implements model.ITextModel {
const
lineTokens
=
this
.
_getLineTokens
(
lineNumber
);
const
lineText
=
this
.
_buffer
.
getLineContent
(
lineNumber
);
le
t
tokenIndex
=
lineTokens
.
findTokenIndexAtOffset
(
position
.
column
-
1
);
cons
t
tokenIndex
=
lineTokens
.
findTokenIndexAtOffset
(
position
.
column
-
1
);
if
(
tokenIndex
<
0
)
{
return
null
;
}
...
...
@@ -1919,15 +1919,15 @@ export class TextModel extends Disposable implements model.ITextModel {
// check that the token is not to be ignored
if
(
currentModeBrackets
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
tokenIndex
)))
{
// limit search to not go before `maxBracketLength`
let
searchStartOffset
=
Math
.
max
(
lineTokens
.
getStartOffset
(
tokenIndex
)
,
position
.
column
-
1
-
currentModeBrackets
.
maxBracketLength
);
let
searchStartOffset
=
Math
.
max
(
0
,
position
.
column
-
1
-
currentModeBrackets
.
maxBracketLength
);
// limit search to not go after `maxBracketLength`
const
searchEndOffset
=
Math
.
min
(
lineT
okens
.
getEndOffset
(
tokenIndex
)
,
position
.
column
-
1
+
currentModeBrackets
.
maxBracketLength
);
const
searchEndOffset
=
Math
.
min
(
lineT
ext
.
length
,
position
.
column
-
1
+
currentModeBrackets
.
maxBracketLength
);
// it might be the case that [currentTokenStart -> currentTokenEnd] contains multiple brackets
// `bestResult` will contain the most right-side result
let
bestResult
:
[
Range
,
Range
]
|
null
=
null
;
while
(
true
)
{
let
foundBracket
=
BracketsUtils
.
findNextBracketInToken
(
currentModeBrackets
.
forwardRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
const
foundBracket
=
BracketsUtils
.
findNextBracketInRange
(
currentModeBrackets
.
forwardRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
!
foundBracket
)
{
// there are no more brackets in this text
break
;
...
...
@@ -1935,12 +1935,8 @@ export class TextModel extends Disposable implements model.ITextModel {
// check that we didn't hit a bracket too far away from position
if
(
foundBracket
.
startColumn
<=
position
.
column
&&
position
.
column
<=
foundBracket
.
endColumn
)
{
let
foundBracketText
=
lineText
.
substring
(
foundBracket
.
startColumn
-
1
,
foundBracket
.
endColumn
-
1
);
foundBracketText
=
foundBracketText
.
toLowerCase
();
let
r
=
this
.
_matchFoundBracket
(
foundBracket
,
currentModeBrackets
.
textIsBracket
[
foundBracketText
],
currentModeBrackets
.
textIsOpenBracket
[
foundBracketText
]);
// check that we can actually match this bracket
const
foundBracketText
=
lineText
.
substring
(
foundBracket
.
startColumn
-
1
,
foundBracket
.
endColumn
-
1
).
toLowerCase
();
const
r
=
this
.
_matchFoundBracket
(
foundBracket
,
currentModeBrackets
.
textIsBracket
[
foundBracketText
],
currentModeBrackets
.
textIsOpenBracket
[
foundBracketText
]);
if
(
r
)
{
bestResult
=
r
;
}
...
...
@@ -1956,24 +1952,20 @@ export class TextModel extends Disposable implements model.ITextModel {
// If position is in between two tokens, try also looking in the previous token
if
(
tokenIndex
>
0
&&
lineTokens
.
getStartOffset
(
tokenIndex
)
===
position
.
column
-
1
)
{
const
searchEndOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
tokenIndex
--
;
const
prevModeBrackets
=
LanguageConfigurationRegistry
.
getBracketsSupport
(
lineTokens
.
getLanguageId
(
tokenIndex
));
const
prevTokenIndex
=
tokenIndex
-
1
;
const
prevModeBrackets
=
LanguageConfigurationRegistry
.
getBracketsSupport
(
lineTokens
.
getLanguageId
(
prevTokenIndex
));
// check that previous token is not to be ignored
if
(
prevModeBrackets
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
t
okenIndex
)))
{
if
(
prevModeBrackets
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
prevT
okenIndex
)))
{
// limit search in case previous token is very large, there's no need to go beyond `maxBracketLength`
const
searchStartOffset
=
Math
.
max
(
lineTokens
.
getStartOffset
(
tokenIndex
),
position
.
column
-
1
-
prevModeBrackets
.
maxBracketLength
);
const
foundBracket
=
BracketsUtils
.
findPrevBracketInToken
(
prevModeBrackets
.
reversedRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
const
searchStartOffset
=
Math
.
max
(
0
,
position
.
column
-
1
-
prevModeBrackets
.
maxBracketLength
);
const
searchEndOffset
=
Math
.
min
(
lineText
.
length
,
position
.
column
-
1
+
prevModeBrackets
.
maxBracketLength
);
const
foundBracket
=
BracketsUtils
.
findPrevBracketInRange
(
prevModeBrackets
.
reversedRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
// check that we didn't hit a bracket too far away from position
if
(
foundBracket
&&
foundBracket
.
startColumn
<=
position
.
column
&&
position
.
column
<=
foundBracket
.
endColumn
)
{
let
foundBracketText
=
lineText
.
substring
(
foundBracket
.
startColumn
-
1
,
foundBracket
.
endColumn
-
1
);
foundBracketText
=
foundBracketText
.
toLowerCase
();
let
r
=
this
.
_matchFoundBracket
(
foundBracket
,
prevModeBrackets
.
textIsBracket
[
foundBracketText
],
prevModeBrackets
.
textIsOpenBracket
[
foundBracketText
]);
// check that we can actually match this bracket
const
foundBracketText
=
lineText
.
substring
(
foundBracket
.
startColumn
-
1
,
foundBracket
.
endColumn
-
1
).
toLowerCase
();
const
r
=
this
.
_matchFoundBracket
(
foundBracket
,
prevModeBrackets
.
textIsBracket
[
foundBracketText
],
prevModeBrackets
.
textIsOpenBracket
[
foundBracketText
]);
if
(
r
)
{
return
r
;
}
...
...
@@ -2011,54 +2003,76 @@ export class TextModel extends Disposable implements model.ITextModel {
const
reversedBracketRegex
=
bracket
.
reversedRegex
;
let
count
=
-
1
;
const
searchPrevMatchingBracketInRange
=
(
lineNumber
:
number
,
lineText
:
string
,
searchStartOffset
:
number
,
searchEndOffset
:
number
):
Range
|
null
=>
{
while
(
true
)
{
const
r
=
BracketsUtils
.
findPrevBracketInRange
(
reversedBracketRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
!
r
)
{
break
;
}
const
hitText
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
).
toLowerCase
();
if
(
hitText
===
bracket
.
open
)
{
count
++
;
}
else
if
(
hitText
===
bracket
.
close
)
{
count
--
;
}
if
(
count
===
0
)
{
return
r
;
}
searchEndOffset
=
r
.
startColumn
-
1
;
}
return
null
;
};
for
(
let
lineNumber
=
position
.
lineNumber
;
lineNumber
>=
1
;
lineNumber
--
)
{
const
lineTokens
=
this
.
_getLineTokens
(
lineNumber
);
const
tokenCount
=
lineTokens
.
getCount
();
const
lineText
=
this
.
_buffer
.
getLineContent
(
lineNumber
);
let
tokenIndex
=
tokenCount
-
1
;
let
searchStopOffset
=
-
1
;
let
searchStartOffset
=
lineText
.
length
;
let
searchEndOffset
=
lineText
.
length
;
if
(
lineNumber
===
position
.
lineNumber
)
{
tokenIndex
=
lineTokens
.
findTokenIndexAtOffset
(
position
.
column
-
1
);
searchStopOffset
=
position
.
column
-
1
;
searchStartOffset
=
position
.
column
-
1
;
searchEndOffset
=
position
.
column
-
1
;
}
let
prevSearchInToken
=
true
;
for
(;
tokenIndex
>=
0
;
tokenIndex
--
)
{
const
tokenLanguageId
=
lineTokens
.
getLanguageId
(
tokenIndex
);
const
tokenType
=
lineTokens
.
getStandardTokenType
(
tokenIndex
);
const
tokenStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
const
tokenEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
if
(
searchStopOffset
===
-
1
)
{
searchStopOffset
=
tokenEndOffset
;
}
if
(
tokenLanguageId
===
languageId
&&
!
ignoreBracketsInToken
(
tokenType
))
{
while
(
true
)
{
let
r
=
BracketsUtils
.
findPrevBracketInToken
(
reversedBracketRegex
,
lineNumber
,
lineText
,
tokenStartOffset
,
searchStopOffset
);
if
(
!
r
)
{
break
;
}
let
hitText
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
);
hitText
=
hitText
.
toLowerCase
();
if
(
hitText
===
bracket
.
open
)
{
count
++
;
}
else
if
(
hitText
===
bracket
.
close
)
{
count
--
;
}
if
(
count
===
0
)
{
const
searchInToken
=
(
lineTokens
.
getLanguageId
(
tokenIndex
)
===
languageId
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
tokenIndex
)));
if
(
searchInToken
)
{
// this token should be searched
if
(
prevSearchInToken
)
{
// the previous token should be searched, simply extend searchStartOffset
searchStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
}
else
{
// the previous token should not be searched
searchStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
searchEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
}
}
else
{
// this token should not be searched
if
(
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
searchPrevMatchingBracketInRange
(
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
r
;
}
searchStopOffset
=
r
.
startColumn
-
1
;
}
}
searchStopOffset
=
-
1
;
prevSearchInToken
=
searchInToken
;
}
if
(
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
searchPrevMatchingBracketInRange
(
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
r
;
}
}
}
...
...
@@ -2072,53 +2086,77 @@ export class TextModel extends Disposable implements model.ITextModel {
const
bracketRegex
=
bracket
.
forwardRegex
;
let
count
=
1
;
for
(
let
lineNumber
=
position
.
lineNumber
,
lineCount
=
this
.
getLineCount
();
lineNumber
<=
lineCount
;
lineNumber
++
)
{
const
searchNextMatchingBracketInRange
=
(
lineNumber
:
number
,
lineText
:
string
,
searchStartOffset
:
number
,
searchEndOffset
:
number
):
Range
|
null
=>
{
while
(
true
)
{
const
r
=
BracketsUtils
.
findNextBracketInRange
(
bracketRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
!
r
)
{
break
;
}
const
hitText
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
).
toLowerCase
();
if
(
hitText
===
bracket
.
open
)
{
count
++
;
}
else
if
(
hitText
===
bracket
.
close
)
{
count
--
;
}
if
(
count
===
0
)
{
return
r
;
}
searchStartOffset
=
r
.
endColumn
-
1
;
}
return
null
;
};
const
lineCount
=
this
.
getLineCount
();
for
(
let
lineNumber
=
position
.
lineNumber
;
lineNumber
<=
lineCount
;
lineNumber
++
)
{
const
lineTokens
=
this
.
_getLineTokens
(
lineNumber
);
const
tokenCount
=
lineTokens
.
getCount
();
const
lineText
=
this
.
_buffer
.
getLineContent
(
lineNumber
);
let
tokenIndex
=
0
;
let
searchStartOffset
=
0
;
let
searchEndOffset
=
0
;
if
(
lineNumber
===
position
.
lineNumber
)
{
tokenIndex
=
lineTokens
.
findTokenIndexAtOffset
(
position
.
column
-
1
);
searchStartOffset
=
position
.
column
-
1
;
searchEndOffset
=
position
.
column
-
1
;
}
let
prevSearchInToken
=
true
;
for
(;
tokenIndex
<
tokenCount
;
tokenIndex
++
)
{
const
tokenLanguageId
=
lineTokens
.
getLanguageId
(
tokenIndex
);
const
tokenType
=
lineTokens
.
getStandardTokenType
(
tokenIndex
);
const
tokenStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
const
tokenEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
if
(
searchStartOffset
===
0
)
{
searchStartOffset
=
tokenStartOffset
;
}
if
(
tokenLanguageId
===
languageId
&&
!
ignoreBracketsInToken
(
tokenType
))
{
while
(
true
)
{
let
r
=
BracketsUtils
.
findNextBracketInToken
(
bracketRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
tokenEndOffset
);
if
(
!
r
)
{
break
;
}
let
hitText
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
);
hitText
=
hitText
.
toLowerCase
();
if
(
hitText
===
bracket
.
open
)
{
count
++
;
}
else
if
(
hitText
===
bracket
.
close
)
{
count
--
;
}
if
(
count
===
0
)
{
const
searchInToken
=
(
lineTokens
.
getLanguageId
(
tokenIndex
)
===
languageId
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
tokenIndex
)));
if
(
searchInToken
)
{
// this token should be searched
if
(
prevSearchInToken
)
{
// the previous token should be searched, simply extend searchEndOffset
searchEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
}
else
{
// the previous token should not be searched
searchStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
searchEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
}
}
else
{
// this token should not be searched
if
(
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
searchNextMatchingBracketInRange
(
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
r
;
}
searchStartOffset
=
r
.
endColumn
-
1
;
}
}
searchStartOffset
=
0
;
prevSearchInToken
=
searchInToken
;
}
if
(
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
searchNextMatchingBracketInRange
(
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
r
;
}
}
}
...
...
@@ -2136,33 +2174,66 @@ export class TextModel extends Disposable implements model.ITextModel {
const
lineText
=
this
.
_buffer
.
getLineContent
(
lineNumber
);
let
tokenIndex
=
tokenCount
-
1
;
let
searchStopOffset
=
-
1
;
let
searchStartOffset
=
lineText
.
length
;
let
searchEndOffset
=
lineText
.
length
;
if
(
lineNumber
===
position
.
lineNumber
)
{
tokenIndex
=
lineTokens
.
findTokenIndexAtOffset
(
position
.
column
-
1
);
searchStopOffset
=
position
.
column
-
1
;
searchStartOffset
=
position
.
column
-
1
;
searchEndOffset
=
position
.
column
-
1
;
const
tokenLanguageId
=
lineTokens
.
getLanguageId
(
tokenIndex
);
if
(
languageId
!==
tokenLanguageId
)
{
languageId
=
tokenLanguageId
;
modeBrackets
=
LanguageConfigurationRegistry
.
getBracketsSupport
(
languageId
);
}
}
let
prevSearchInToken
=
true
;
for
(;
tokenIndex
>=
0
;
tokenIndex
--
)
{
const
tokenLanguageId
=
lineTokens
.
getLanguageId
(
tokenIndex
);
const
tokenType
=
lineTokens
.
getStandardTokenType
(
tokenIndex
);
const
tokenStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
const
tokenEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
if
(
searchStopOffset
===
-
1
)
{
searchStopOffset
=
tokenEndOffset
;
}
if
(
languageId
!==
tokenLanguageId
)
{
// language id change!
if
(
modeBrackets
&&
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
BracketsUtils
.
findPrevBracketInRange
(
modeBrackets
.
reversedRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
}
prevSearchInToken
=
false
;
}
languageId
=
tokenLanguageId
;
modeBrackets
=
LanguageConfigurationRegistry
.
getBracketsSupport
(
languageId
);
}
if
(
modeBrackets
&&
!
ignoreBracketsInToken
(
tokenType
))
{
let
r
=
BracketsUtils
.
findPrevBracketInToken
(
modeBrackets
.
reversedRegex
,
lineNumber
,
lineText
,
tokenStartOffset
,
searchStopOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
const
searchInToken
=
(
!!
modeBrackets
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
tokenIndex
)));
if
(
searchInToken
)
{
// this token should be searched
if
(
prevSearchInToken
)
{
// the previous token should be searched, simply extend searchStartOffset
searchStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
}
else
{
// the previous token should not be searched
searchStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
searchEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
}
}
else
{
// this token should not be searched
if
(
modeBrackets
&&
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
BracketsUtils
.
findPrevBracketInRange
(
modeBrackets
.
reversedRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
}
}
}
searchStopOffset
=
-
1
;
prevSearchInToken
=
searchInToken
;
}
if
(
modeBrackets
&&
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
BracketsUtils
.
findPrevBracketInRange
(
modeBrackets
.
reversedRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
}
}
}
...
...
@@ -2171,43 +2242,75 @@ export class TextModel extends Disposable implements model.ITextModel {
public
findNextBracket
(
_position
:
IPosition
):
model
.
IFoundBracket
|
null
{
const
position
=
this
.
validatePosition
(
_position
);
const
lineCount
=
this
.
getLineCount
();
let
languageId
:
LanguageId
=
-
1
;
let
modeBrackets
:
RichEditBrackets
|
null
=
null
;
for
(
let
lineNumber
=
position
.
lineNumber
,
lineCount
=
this
.
getLineCount
()
;
lineNumber
<=
lineCount
;
lineNumber
++
)
{
for
(
let
lineNumber
=
position
.
lineNumber
;
lineNumber
<=
lineCount
;
lineNumber
++
)
{
const
lineTokens
=
this
.
_getLineTokens
(
lineNumber
);
const
tokenCount
=
lineTokens
.
getCount
();
const
lineText
=
this
.
_buffer
.
getLineContent
(
lineNumber
);
let
tokenIndex
=
0
;
let
searchStartOffset
=
0
;
let
searchEndOffset
=
0
;
if
(
lineNumber
===
position
.
lineNumber
)
{
tokenIndex
=
lineTokens
.
findTokenIndexAtOffset
(
position
.
column
-
1
);
searchStartOffset
=
position
.
column
-
1
;
searchEndOffset
=
position
.
column
-
1
;
const
tokenLanguageId
=
lineTokens
.
getLanguageId
(
tokenIndex
);
if
(
languageId
!==
tokenLanguageId
)
{
languageId
=
tokenLanguageId
;
modeBrackets
=
LanguageConfigurationRegistry
.
getBracketsSupport
(
languageId
);
}
}
let
prevSearchInToken
=
true
;
for
(;
tokenIndex
<
tokenCount
;
tokenIndex
++
)
{
const
tokenLanguageId
=
lineTokens
.
getLanguageId
(
tokenIndex
);
const
tokenType
=
lineTokens
.
getStandardTokenType
(
tokenIndex
);
const
tokenStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
const
tokenEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
if
(
searchStartOffset
===
0
)
{
searchStartOffset
=
tokenStartOffset
;
}
if
(
languageId
!==
tokenLanguageId
)
{
// language id change!
if
(
modeBrackets
&&
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
BracketsUtils
.
findNextBracketInRange
(
modeBrackets
.
forwardRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
}
prevSearchInToken
=
false
;
}
languageId
=
tokenLanguageId
;
modeBrackets
=
LanguageConfigurationRegistry
.
getBracketsSupport
(
languageId
);
}
if
(
modeBrackets
&&
!
ignoreBracketsInToken
(
tokenType
))
{
let
r
=
BracketsUtils
.
findNextBracketInToken
(
modeBrackets
.
forwardRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
tokenEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
const
searchInToken
=
(
!!
modeBrackets
&&
!
ignoreBracketsInToken
(
lineTokens
.
getStandardTokenType
(
tokenIndex
)));
if
(
searchInToken
)
{
// this token should be searched
if
(
prevSearchInToken
)
{
// the previous token should be searched, simply extend searchEndOffset
searchEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
}
else
{
// the previous token should not be searched
searchStartOffset
=
lineTokens
.
getStartOffset
(
tokenIndex
);
searchEndOffset
=
lineTokens
.
getEndOffset
(
tokenIndex
);
}
}
else
{
// this token should not be searched
if
(
modeBrackets
&&
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
BracketsUtils
.
findNextBracketInRange
(
modeBrackets
.
forwardRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
}
}
}
searchStartOffset
=
0
;
prevSearchInToken
=
searchInToken
;
}
if
(
modeBrackets
&&
prevSearchInToken
&&
searchStartOffset
!==
searchEndOffset
)
{
const
r
=
BracketsUtils
.
findNextBracketInRange
(
modeBrackets
.
forwardRegex
,
lineNumber
,
lineText
,
searchStartOffset
,
searchEndOffset
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
modeBrackets
,
r
);
}
}
}
...
...
src/vs/editor/common/modes/supports/electricCharacter.ts
浏览文件 @
c6b09780
...
...
@@ -56,7 +56,7 @@ export class BracketElectricCharacterSupport {
let
reversedBracketRegex
=
this
.
_richEditBrackets
.
reversedRegex
;
let
text
=
context
.
getLineContent
().
substring
(
0
,
column
-
1
)
+
character
;
let
r
=
BracketsUtils
.
findPrevBracketIn
Token
(
reversedBracketRegex
,
1
,
text
,
0
,
text
.
length
);
let
r
=
BracketsUtils
.
findPrevBracketIn
Range
(
reversedBracketRegex
,
1
,
text
,
0
,
text
.
length
);
if
(
!
r
)
{
return
null
;
}
...
...
src/vs/editor/common/modes/supports/richEditBrackets.ts
浏览文件 @
c6b09780
...
...
@@ -168,12 +168,11 @@ export class BracketsUtils {
return
new
Range
(
lineNumber
,
absoluteMatchOffset
-
matchLength
+
1
,
lineNumber
,
absoluteMatchOffset
+
1
);
}
public
static
findPrevBracketIn
Token
(
reversedBracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
|
null
{
public
static
findPrevBracketIn
Range
(
reversedBracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
startOffset
:
number
,
endOffset
:
number
):
Range
|
null
{
// Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;)
let
reversedLineText
=
toReversedString
(
lineText
);
let
reversedTokenText
=
reversedLineText
.
substring
(
lineText
.
length
-
currentTokenEnd
,
lineText
.
length
-
currentTokenStart
);
return
this
.
_findPrevBracketInText
(
reversedBracketRegex
,
lineNumber
,
reversedTokenText
,
currentTokenStart
);
const
reversedLineText
=
toReversedString
(
lineText
);
const
reversedSubstr
=
reversedLineText
.
substring
(
lineText
.
length
-
endOffset
,
lineText
.
length
-
startOffset
);
return
this
.
_findPrevBracketInText
(
reversedBracketRegex
,
lineNumber
,
reversedSubstr
,
startOffset
);
}
public
static
findNextBracketInText
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
text
:
string
,
offset
:
number
):
Range
|
null
{
...
...
@@ -193,10 +192,8 @@ export class BracketsUtils {
return
new
Range
(
lineNumber
,
absoluteMatchOffset
+
1
,
lineNumber
,
absoluteMatchOffset
+
1
+
matchLength
);
}
public
static
findNextBracketInToken
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
|
null
{
let
currentTokenText
=
lineText
.
substring
(
currentTokenStart
,
currentTokenEnd
);
return
this
.
findNextBracketInText
(
bracketRegex
,
lineNumber
,
currentTokenText
,
currentTokenStart
);
public
static
findNextBracketInRange
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
startOffset
:
number
,
endOffset
:
number
):
Range
|
null
{
const
substr
=
lineText
.
substring
(
startOffset
,
endOffset
);
return
this
.
findNextBracketInText
(
bracketRegex
,
lineNumber
,
substr
,
startOffset
);
}
}
src/vs/editor/test/common/modes/supports/richEditBrackets.test.ts
浏览文件 @
c6b09780
...
...
@@ -9,71 +9,71 @@ import { BracketsUtils } from 'vs/editor/common/modes/supports/richEditBrackets'
suite
(
'
richEditBrackets
'
,
()
=>
{
function
findPrevBracketIn
Token
(
reversedBracketRegex
:
RegExp
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
|
null
{
return
BracketsUtils
.
findPrevBracketIn
Token
(
reversedBracketRegex
,
1
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
function
findPrevBracketIn
Range
(
reversedBracketRegex
:
RegExp
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
|
null
{
return
BracketsUtils
.
findPrevBracketIn
Range
(
reversedBracketRegex
,
1
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
}
function
findNextBracketIn
Token
(
forwardBracketRegex
:
RegExp
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
|
null
{
return
BracketsUtils
.
findNextBracketIn
Token
(
forwardBracketRegex
,
1
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
function
findNextBracketIn
Range
(
forwardBracketRegex
:
RegExp
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
|
null
{
return
BracketsUtils
.
findNextBracketIn
Range
(
forwardBracketRegex
,
1
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
}
test
(
'
findPrevBracketInToken one char 1
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(\{)
|
(\})
/i
,
'
{
'
,
0
,
1
);
let
result
=
findPrevBracketIn
Range
(
/
(\{)
|
(\})
/i
,
'
{
'
,
0
,
1
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
2
);
});
test
(
'
findPrevBracketInToken one char 2
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(\{)
|
(\})
/i
,
'
{{
'
,
0
,
1
);
let
result
=
findPrevBracketIn
Range
(
/
(\{)
|
(\})
/i
,
'
{{
'
,
0
,
1
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
2
);
});
test
(
'
findPrevBracketInToken one char 3
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(\{)
|
(\})
/i
,
'
{hello world!
'
,
0
,
13
);
let
result
=
findPrevBracketIn
Range
(
/
(\{)
|
(\})
/i
,
'
{hello world!
'
,
0
,
13
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
2
);
});
test
(
'
findPrevBracketInToken more chars 1
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(
olleh
)
/i
,
'
hello world!
'
,
0
,
12
);
let
result
=
findPrevBracketIn
Range
(
/
(
olleh
)
/i
,
'
hello world!
'
,
0
,
12
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
6
);
});
test
(
'
findPrevBracketInToken more chars 2
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(
olleh
)
/i
,
'
hello world!
'
,
0
,
5
);
let
result
=
findPrevBracketIn
Range
(
/
(
olleh
)
/i
,
'
hello world!
'
,
0
,
5
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
6
);
});
test
(
'
findPrevBracketInToken more chars 3
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(
olleh
)
/i
,
'
hello world!
'
,
0
,
6
);
let
result
=
findPrevBracketIn
Range
(
/
(
olleh
)
/i
,
'
hello world!
'
,
0
,
6
);
assert
.
equal
(
result
!
.
startColumn
,
2
);
assert
.
equal
(
result
!
.
endColumn
,
7
);
});
test
(
'
findNextBracketInToken one char
'
,
()
=>
{
let
result
=
findNextBracketIn
Token
(
/
(\{)
|
(\})
/i
,
'
{
'
,
0
,
1
);
let
result
=
findNextBracketIn
Range
(
/
(\{)
|
(\})
/i
,
'
{
'
,
0
,
1
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
2
);
});
test
(
'
findNextBracketInToken more chars
'
,
()
=>
{
let
result
=
findNextBracketIn
Token
(
/
(
world
)
/i
,
'
hello world!
'
,
0
,
12
);
let
result
=
findNextBracketIn
Range
(
/
(
world
)
/i
,
'
hello world!
'
,
0
,
12
);
assert
.
equal
(
result
!
.
startColumn
,
7
);
assert
.
equal
(
result
!
.
endColumn
,
12
);
});
test
(
'
findNextBracketInToken with emoty result
'
,
()
=>
{
let
result
=
findNextBracketIn
Token
(
/
(\{)
|
(\})
/i
,
''
,
0
,
0
);
let
result
=
findNextBracketIn
Range
(
/
(\{)
|
(\})
/i
,
''
,
0
,
0
);
assert
.
equal
(
result
,
null
);
});
test
(
'
issue #3894: [Handlebars] Curly braces edit issues
'
,
()
=>
{
let
result
=
findPrevBracketIn
Token
(
/
(\-\-
!<
)
|
(
>
\-\-)
|
(\{\{)
|
(\}\})
/i
,
'
{{asd}}
'
,
0
,
2
);
let
result
=
findPrevBracketIn
Range
(
/
(\-\-
!<
)
|
(
>
\-\-)
|
(\{\{)
|
(\}\})
/i
,
'
{{asd}}
'
,
0
,
2
);
assert
.
equal
(
result
!
.
startColumn
,
1
);
assert
.
equal
(
result
!
.
endColumn
,
3
);
});
});
\ No newline at end of file
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录