Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
568c9e51
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
568c9e51
编写于
2月 10, 2016
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Begin using mode's brackets when searching for brackets
上级
8c60e594
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
183 addition
and
179 deletion
+183
-179
src/vs/editor/common/controller/oneCursor.ts
src/vs/editor/common/controller/oneCursor.ts
+1
-1
src/vs/editor/common/editorCommon.ts
src/vs/editor/common/editorCommon.ts
+4
-3
src/vs/editor/common/model/textModelWithTokens.ts
src/vs/editor/common/model/textModelWithTokens.ts
+90
-140
src/vs/editor/common/modes.ts
src/vs/editor/common/modes.ts
+15
-1
src/vs/editor/common/modes/supports/electricCharacter.ts
src/vs/editor/common/modes/supports/electricCharacter.ts
+57
-30
src/vs/editor/common/modes/supports/richEditSupport.ts
src/vs/editor/common/modes/supports/richEditSupport.ts
+3
-1
src/vs/editor/test/common/testModes.ts
src/vs/editor/test/common/testModes.ts
+10
-0
src/vs/languages/javascript/test/common/javascript.test.ts
src/vs/languages/javascript/test/common/javascript.test.ts
+3
-3
未找到文件。
src/vs/editor/common/controller/oneCursor.ts
浏览文件 @
568c9e51
...
...
@@ -1161,7 +1161,7 @@ export class OneCursorOp {
if
(
matchOpenBracket
)
{
var
match
=
cursor
.
model
.
findMatchingBracketUp
(
matchOpenBracket
,
{
lineNumber
:
position
.
lineNumber
,
column
:
position
.
column
-
matchOpenBracket
.
close
.
length
column
:
position
.
column
-
matchOpenBracket
.
length
});
if
(
match
)
{
var
matchLineNumber
=
match
.
startLineNumber
;
...
...
src/vs/editor/common/editorCommon.ts
浏览文件 @
568c9e51
...
...
@@ -1376,10 +1376,11 @@ export interface ITextModel {
isDisposed
():
boolean
;
}
export
interface
IFindBracketRequest
{
modeId
:
string
;
export
interface
IRichEditBracket
{
open
:
string
;
close
:
string
;
forwardRegex
:
RegExp
;
reversedRegex
:
RegExp
;
}
export
interface
IFoundBracket
{
...
...
@@ -1486,7 +1487,7 @@ export interface ITokenizedModel extends ITextModel {
* @param position The position at which to start the search.
* @return The range of the matching bracket, or null if the bracket match was not found.
*/
findMatchingBracketUp
(
request
:
IFindBracketRequest
,
position
:
IPosition
):
IEditorRange
;
findMatchingBracketUp
(
bracket
:
string
,
position
:
IPosition
):
IEditorRange
;
/**
* Find the first bracket in the model before `position`.
...
...
src/vs/editor/common/model/textModelWithTokens.ts
浏览文件 @
568c9e51
...
...
@@ -24,6 +24,7 @@ import {TPromise} from 'vs/base/common/winjs.base';
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
*
as
Strings
from
'
vs/base/common/strings
'
;
import
{
ignoreBracketsInToken
}
from
'
vs/editor/common/modes/supports
'
;
import
{
BracketsUtils
}
from
'
vs/editor/common/modes/supports/electricCharacter
'
;
export
class
TokensInflatorMap
implements
EditorCommon
.
ITokensInflatorMap
{
...
...
@@ -847,12 +848,28 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
return
result
;
}
public
findMatchingBracketUp
(
request
:
EditorCommon
.
IFindBracketRequest
,
_position
:
EditorCommon
.
IPosition
):
EditorCommon
.
IEditorRange
{
public
findMatchingBracketUp
(
bracket
:
string
,
_position
:
EditorCommon
.
IPosition
):
EditorCommon
.
IEditorRange
{
if
(
this
.
_isDisposed
)
{
throw
new
Error
(
'
TextModelWithTokens.findMatchingBracketUp: Model is disposed
'
);
}
return
this
.
_findMatchingBracketUp
(
request
.
open
,
request
.
close
,
this
.
validatePosition
(
_position
));
let
position
=
this
.
validatePosition
(
_position
);
let
modeTransitions
=
this
.
_lines
[
position
.
lineNumber
-
1
].
getModeTransitions
().
toArray
(
this
.
_mode
);
let
currentModeIndex
=
Arrays
.
findIndexInSegmentsArray
(
modeTransitions
,
position
.
column
-
1
);
let
currentMode
=
modeTransitions
[
currentModeIndex
];
let
currentModeBrackets
=
currentMode
.
mode
.
richEditSupport
?
currentMode
.
mode
.
richEditSupport
.
brackets
:
null
;
if
(
!
currentModeBrackets
)
{
return
null
;
}
let
data
=
currentModeBrackets
.
textIsBracket
[
bracket
];
if
(
!
data
)
{
return
null
;
}
return
this
.
_findMatchingBracketUp
(
data
,
position
);
}
public
matchBracket
(
position
:
EditorCommon
.
IPosition
,
inaccurateResultAcceptable
:
boolean
=
false
):
EditorCommon
.
IMatchBracketResult
{
...
...
@@ -864,19 +881,20 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
}
private
_matchBracket
(
position
:
EditorCommon
.
IEditorPosition
):
EditorCommon
.
IMatchBracketResult
{
let
reversedBracketRegex
=
/
[\(\)\[\]\{\}]
/
;
// TODO@Alex: use mode's brackets
let
bracketRegex
=
/
[\(\)\[\]\{\}]
/
;
// TODO@Alex: use mode's brackets
let
maxBracketLength
=
1
;
// TODO@Alex: use mode's brackets
let
tokensMap
=
this
.
_tokensInflatorMap
;
let
lineNumber
=
position
.
lineNumber
;
let
lineTokens
=
this
.
_lines
[
lineNumber
-
1
].
getTokens
();
let
lineText
=
this
.
_lines
[
lineNumber
-
1
].
text
;
let
lineTokens
=
this
.
_lines
[
lineNumber
-
1
].
getTokens
();
let
tokens
=
lineTokens
.
getBinaryEncodedTokens
();
let
currentTokenIndex
=
lineTokens
.
findIndexOfOffset
(
position
.
column
-
1
);
let
currentTokenStart
=
getStartIndex
(
tokens
[
currentTokenIndex
]);
let
modeTransitions
=
this
.
_lines
[
lineNumber
-
1
].
getModeTransitions
().
toArray
(
this
.
_mode
);
let
currentModeIndex
=
Arrays
.
findIndexInSegmentsArray
(
modeTransitions
,
position
.
column
-
1
);
let
currentMode
=
modeTransitions
[
currentModeIndex
];
let
currentModeBrackets
=
currentMode
.
mode
.
richEditSupport
?
currentMode
.
mode
.
richEditSupport
.
brackets
:
null
;
// If position is in between two tokens, try first looking in the previous token
if
(
currentTokenIndex
>
0
&&
currentTokenStart
===
position
.
column
-
1
)
{
let
prevTokenIndex
=
currentTokenIndex
-
1
;
...
...
@@ -886,14 +904,24 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
if
(
!
ignoreBracketsInToken
(
prevTokenType
))
{
let
prevTokenStart
=
getStartIndex
(
tokens
[
prevTokenIndex
]);
let
prevMode
=
currentMode
;
let
prevModeBrackets
=
currentModeBrackets
;
// check if previous token is in a different mode
if
(
currentModeIndex
>
0
&&
currentMode
.
startIndex
===
position
.
column
-
1
)
{
prevMode
=
modeTransitions
[
currentModeIndex
-
1
];
prevModeBrackets
=
prevMode
.
mode
.
richEditSupport
?
prevMode
.
mode
.
richEditSupport
.
brackets
:
null
;
}
if
(
prevModeBrackets
)
{
// limit search in case previous token is very large, there's no need to go beyond `maxBracketLength`
prevTokenStart
=
Math
.
max
(
prevTokenStart
,
position
.
column
-
1
-
maxBracketLength
);
prevTokenStart
=
Math
.
max
(
prevTokenStart
,
position
.
column
-
1
-
prevModeBrackets
.
maxBracketLength
);
let
foundBracket
=
TextModelWithTokens
.
_findPrevBracketInToken
(
reversedBracket
Regex
,
lineNumber
,
lineText
,
prevTokenStart
,
currentTokenStart
);
let
foundBracket
=
BracketsUtils
.
findPrevBracketInToken
(
prevModeBrackets
.
reversed
Regex
,
lineNumber
,
lineText
,
prevTokenStart
,
currentTokenStart
);
// check that we didn't hit a bracket too far away from position
if
(
foundBracket
&&
foundBracket
.
startColumn
<=
position
.
column
&&
position
.
column
<=
foundBracket
.
endColumn
)
{
let
r
=
this
.
_matchFoundBracket
(
foundBracket
);
let
foundBracketText
=
lineText
.
substring
(
foundBracket
.
startColumn
-
1
,
foundBracket
.
endColumn
-
1
);
let
r
=
this
.
_matchFoundBracket
(
foundBracket
,
prevModeBrackets
.
textIsBracket
[
foundBracketText
],
prevModeBrackets
.
textIsOpenBracket
[
foundBracketText
]);
// check that we can actually match this bracket
if
(
r
)
{
...
...
@@ -902,20 +930,22 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
}
}
}
}
// check that the token is not to be ignored
if
(
!
ignoreBracketsInToken
(
getType
(
tokensMap
,
tokens
[
currentTokenIndex
])))
{
if
(
currentModeBrackets
)
{
// limit search to not go before `maxBracketLength`
currentTokenStart
=
Math
.
max
(
currentTokenStart
,
position
.
column
-
1
-
maxBracketLength
);
currentTokenStart
=
Math
.
max
(
currentTokenStart
,
position
.
column
-
1
-
currentModeBrackets
.
maxBracketLength
);
// limit search to not go after `maxBracketLength`
let
currentTokenEnd
=
(
currentTokenIndex
+
1
<
tokens
.
length
?
getStartIndex
(
tokens
[
currentTokenIndex
+
1
])
:
lineText
.
length
);
currentTokenEnd
=
Math
.
min
(
currentTokenEnd
,
position
.
column
-
1
+
maxBracketLength
);
currentTokenEnd
=
Math
.
min
(
currentTokenEnd
,
position
.
column
-
1
+
currentModeBrackets
.
maxBracketLength
);
// it might still be the case that [currentTokenStart -> currentTokenEnd] contains multiple brackets
while
(
true
)
{
let
foundBracket
=
TextModelWithTokens
.
_findNextBracketInText
(
bracket
Regex
,
lineNumber
,
lineText
.
substring
(
currentTokenStart
,
currentTokenEnd
),
currentTokenStart
);
let
foundBracket
=
BracketsUtils
.
findNextBracketInText
(
currentModeBrackets
.
forward
Regex
,
lineNumber
,
lineText
.
substring
(
currentTokenStart
,
currentTokenEnd
),
currentTokenStart
);
if
(
!
foundBracket
)
{
// there are no brackets in this text
break
;
...
...
@@ -923,7 +953,8 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
// check that we didn't hit a bracket too far away from position
if
(
foundBracket
.
startColumn
<=
position
.
column
&&
position
.
column
<=
foundBracket
.
endColumn
)
{
let
r
=
this
.
_matchFoundBracket
(
foundBracket
);
let
foundBracketText
=
lineText
.
substring
(
foundBracket
.
startColumn
-
1
,
foundBracket
.
endColumn
-
1
);
let
r
=
this
.
_matchFoundBracket
(
foundBracket
,
currentModeBrackets
.
textIsBracket
[
foundBracketText
],
currentModeBrackets
.
textIsOpenBracket
[
foundBracketText
]);
// check that we can actually match this bracket
if
(
r
)
{
...
...
@@ -934,6 +965,7 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
currentTokenStart
=
foundBracket
.
endColumn
-
1
;
}
}
}
return
{
brackets
:
null
,
...
...
@@ -941,19 +973,17 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
};
}
private
_matchFoundBracket
(
foundBracket
:
Range
):
EditorCommon
.
IMatchBracketResult
{
let
data
=
this
.
_toFoundBracket
(
foundBracket
);
if
(
data
.
isOpen
)
{
let
matched
=
this
.
_findMatchingBracketDown
(
data
.
open
,
data
.
close
,
data
.
range
.
getEndPosition
());
private
_matchFoundBracket
(
foundBracket
:
Range
,
data
:
EditorCommon
.
IRichEditBracket
,
isOpen
:
boolean
):
EditorCommon
.
IMatchBracketResult
{
if
(
isOpen
)
{
let
matched
=
this
.
_findMatchingBracketDown
(
data
,
foundBracket
.
getEndPosition
());
if
(
matched
)
{
return
{
brackets
:
[
foundBracket
,
matched
],
isAccurate
:
true
};
}
}
else
if
(
!
data
.
isOpen
)
{
let
matched
=
this
.
_findMatchingBracketUp
(
data
.
open
,
data
.
close
,
data
.
range
.
getStartPosition
());
}
else
{
let
matched
=
this
.
_findMatchingBracketUp
(
data
,
foundBracket
.
getStartPosition
());
if
(
matched
)
{
return
{
brackets
:
[
foundBracket
,
matched
],
...
...
@@ -965,50 +995,13 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
return
null
;
}
private
static
_getReversedString
(
str
:
string
):
string
{
let
reversedStr
=
''
;
for
(
let
i
=
str
.
length
-
1
;
i
>=
0
;
i
--
)
{
reversedStr
+=
str
.
charAt
(
i
);
}
return
reversedStr
;
}
private
static
_REVERSED_REGEX_BRACKET_PAIR_CACHE
:
{[
key
:
string
]:
RegExp
;}
=
{};
private
static
_getReversedRegexForBracketPair
(
open
:
string
,
close
:
string
):
RegExp
{
let
key
=
open
+
'
;
'
+
close
;
if
(
!
this
.
_REVERSED_REGEX_BRACKET_PAIR_CACHE
.
hasOwnProperty
(
key
))
{
let
reversedOpen
=
this
.
_getReversedString
(
open
);
let
reversedClose
=
this
.
_getReversedString
(
close
);
private
_findMatchingBracketUp
(
bracket
:
EditorCommon
.
IRichEditBracket
,
position
:
EditorCommon
.
IEditorPosition
):
Range
{
// console.log('_findMatchingBracketUp: ', 'bracket: ', JSON.stringify(bracket), 'startPosition: ', String(position));
let
reversedOpenEscaped
=
Strings
.
escapeRegExpCharacters
(
reversedOpen
);
let
reversedCloseEscaped
=
Strings
.
escapeRegExpCharacters
(
reversedClose
);
let
regexStr
=
`(
${
reversedOpenEscaped
}
)|(
${
reversedCloseEscaped
}
)`
;
this
.
_REVERSED_REGEX_BRACKET_PAIR_CACHE
[
key
]
=
Strings
.
createRegExp
(
regexStr
,
true
,
false
,
false
,
false
);
}
return
this
.
_REVERSED_REGEX_BRACKET_PAIR_CACHE
[
key
];
}
private
static
_REGEX_BRACKET_PAIR_CACHE
:
{[
key
:
string
]:
RegExp
;}
=
{};
private
static
_getRegexForBracketPair
(
open
:
string
,
close
:
string
):
RegExp
{
let
key
=
open
+
'
;
'
+
close
;
if
(
!
this
.
_REGEX_BRACKET_PAIR_CACHE
.
hasOwnProperty
(
key
))
{
let
openEscaped
=
Strings
.
escapeRegExpCharacters
(
open
);
let
closeEscaped
=
Strings
.
escapeRegExpCharacters
(
close
);
let
regexStr
=
`(
${
openEscaped
}
)|(
${
closeEscaped
}
)`
;
this
.
_REGEX_BRACKET_PAIR_CACHE
[
key
]
=
Strings
.
createRegExp
(
regexStr
,
true
,
false
,
false
,
false
);
}
return
this
.
_REGEX_BRACKET_PAIR_CACHE
[
key
];
}
private
_findMatchingBracketUp
(
openBracket
:
string
,
closeBracket
:
string
,
position
:
EditorCommon
.
IEditorPosition
):
Range
{
// console.log('_findMatchingBracketUp: ', 'openBracket: ', openBracket, 'closeBracket: ', closeBracket, 'startPosition: ', String(position));
let
tokensMap
=
this
.
_tokensInflatorMap
;
let
reversedBracketRegex
=
TextModelWithTokens
.
_getReversedRegexForBracketPair
(
openBracket
,
closeBracket
);
// TODO@Alex: account for mode transitions
let
reversedBracketRegex
=
bracket
.
reversedRegex
;
let
count
=
-
1
;
for
(
let
lineNumber
=
position
.
lineNumber
;
lineNumber
>=
1
;
lineNumber
--
)
{
...
...
@@ -1031,16 +1024,16 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
if
(
!
ignoreBracketsInToken
(
currentTokenType
))
{
while
(
true
)
{
let
r
=
TextModelWithTokens
.
_
findPrevBracketInToken
(
reversedBracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
let
r
=
BracketsUtils
.
findPrevBracketInToken
(
reversedBracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
if
(
!
r
)
{
break
;
}
let
hitText
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
);
if
(
hitText
===
openBracket
)
{
if
(
hitText
===
bracket
.
open
)
{
count
++
;
}
else
if
(
hitText
===
closeBracket
)
{
}
else
if
(
hitText
===
bracket
.
close
)
{
count
--
;
}
...
...
@@ -1059,11 +1052,12 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
return
null
;
}
private
_findMatchingBracketDown
(
openBracket
:
string
,
closeBracket
:
string
,
position
:
EditorCommon
.
IEditorPosition
):
Range
{
// console.log('_findMatchingBracketDown: ', '
openBracket: ', openBracket, 'closeBracket: ', closeBracket
, 'startPosition: ', String(position));
private
_findMatchingBracketDown
(
bracket
:
EditorCommon
.
IRichEditBracket
,
position
:
EditorCommon
.
IEditorPosition
):
Range
{
// console.log('_findMatchingBracketDown: ', '
bracket: ', JSON.stringify(bracket)
, 'startPosition: ', String(position));
let
tokensMap
=
this
.
_tokensInflatorMap
;
let
bracketRegex
=
TextModelWithTokens
.
_getRegexForBracketPair
(
openBracket
,
closeBracket
);
// TODO@Alex: account for mode transitions
let
bracketRegex
=
bracket
.
forwardRegex
;
let
count
=
1
;
for
(
let
lineNumber
=
position
.
lineNumber
,
lineCount
=
this
.
getLineCount
();
lineNumber
<=
lineCount
;
lineNumber
++
)
{
...
...
@@ -1086,16 +1080,16 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
if
(
!
ignoreBracketsInToken
(
currentTokenType
))
{
while
(
true
)
{
let
r
=
TextModelWithTokens
.
_
findNextBracketInToken
(
bracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
let
r
=
BracketsUtils
.
findNextBracketInToken
(
bracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
if
(
!
r
)
{
break
;
}
let
hitText
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
);
if
(
hitText
===
openBracket
)
{
if
(
hitText
===
bracket
.
open
)
{
count
++
;
}
else
if
(
hitText
===
closeBracket
)
{
}
else
if
(
hitText
===
bracket
.
close
)
{
count
--
;
}
...
...
@@ -1114,30 +1108,6 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
return
null
;
}
private
static
_findPrevBracketInText
(
reversedBracketRegex
:
RegExp
,
lineNumber
:
number
,
reversedText
:
string
,
offset
:
number
):
Range
{
let
m
=
reversedText
.
match
(
reversedBracketRegex
);
if
(
!
m
)
{
return
null
;
}
let
matchOffset
=
reversedText
.
length
-
1
-
m
.
index
;
let
matchLength
=
m
[
0
].
length
;
let
absoluteMatchOffset
=
offset
+
matchOffset
;
return
new
Range
(
lineNumber
,
absoluteMatchOffset
+
1
,
lineNumber
,
absoluteMatchOffset
+
1
+
matchLength
);
}
private
static
_findPrevBracketInToken
(
reversedBracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
{
// Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;)
let
currentTokenReversedText
=
''
;
for
(
let
index
=
currentTokenEnd
-
1
;
index
>=
currentTokenStart
;
index
--
)
{
currentTokenReversedText
+=
lineText
.
charAt
(
index
);
}
return
this
.
_findPrevBracketInText
(
reversedBracketRegex
,
lineNumber
,
currentTokenReversedText
,
currentTokenStart
);
}
public
findPrevBracket
(
_position
:
EditorCommon
.
IPosition
):
EditorCommon
.
IFoundBracket
{
if
(
this
.
_isDisposed
)
{
throw
new
Error
(
'
TextModelWithTokens.findPrevBracket: Model is disposed
'
);
...
...
@@ -1165,7 +1135,7 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
let
currentTokenStart
=
getStartIndex
(
currentToken
);
if
(
!
ignoreBracketsInToken
(
currentTokenType
))
{
let
r
=
TextModelWithTokens
.
_
findPrevBracketInToken
(
reversedBracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
let
r
=
BracketsUtils
.
findPrevBracketInToken
(
reversedBracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
r
);
}
...
...
@@ -1178,26 +1148,6 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
return
null
;
}
private
static
_findNextBracketInText
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
text
:
string
,
offset
:
number
):
Range
{
let
m
=
text
.
match
(
bracketRegex
);
if
(
!
m
)
{
return
null
;
}
let
matchOffset
=
m
.
index
;
let
matchLength
=
m
[
0
].
length
;
let
absoluteMatchOffset
=
offset
+
matchOffset
;
return
new
Range
(
lineNumber
,
absoluteMatchOffset
+
1
,
lineNumber
,
absoluteMatchOffset
+
1
+
matchLength
);
}
private
static
_findNextBracketInToken
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
{
let
currentTokenText
=
lineText
.
substring
(
currentTokenStart
,
currentTokenEnd
);
return
this
.
_findNextBracketInText
(
bracketRegex
,
lineNumber
,
currentTokenText
,
currentTokenStart
);
}
public
findNextBracket
(
_position
:
EditorCommon
.
IPosition
):
EditorCommon
.
IFoundBracket
{
if
(
this
.
_isDisposed
)
{
throw
new
Error
(
'
TextModelWithTokens.findNextBracket: Model is disposed
'
);
...
...
@@ -1225,7 +1175,7 @@ export class TextModelWithTokens extends TextModel implements EditorCommon.IToke
let
currentTokenEnd
=
tokenIndex
+
1
<
tokensLength
?
getStartIndex
(
tokens
[
tokenIndex
+
1
])
:
lineText
.
length
;
if
(
!
ignoreBracketsInToken
(
currentTokenType
))
{
let
r
=
TextModelWithTokens
.
_
findNextBracketInToken
(
bracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
let
r
=
BracketsUtils
.
findNextBracketInToken
(
bracketRegex
,
lineNumber
,
lineText
,
currentTokenStart
,
currentTokenEnd
);
if
(
r
)
{
return
this
.
_toFoundBracket
(
r
);
}
...
...
src/vs/editor/common/modes.ts
浏览文件 @
568c9e51
...
...
@@ -697,7 +697,7 @@ export interface IElectricAction {
// The line will be indented at the same level of the line
// which contains the matching given bracket type.
matchOpenBracket
?:
EditorCommon
.
IFindBracketRequest
;
matchOpenBracket
?:
string
;
// The text will be appended after the electric character.
appendText
?:
string
;
...
...
@@ -754,6 +754,15 @@ export interface IRichEditCharacterPair {
getSurroundingPairs
():
IAutoClosingPair
[];
}
export
interface
IRichEditBrackets
{
maxBracketLength
:
number
;
forwardRegex
:
RegExp
;
reversedRegex
:
RegExp
;
brackets
:
EditorCommon
.
IRichEditBracket
[];
textIsBracket
:
{[
text
:
string
]:
EditorCommon
.
IRichEditBracket
;};
textIsOpenBracket
:
{[
text
:
string
]:
boolean
;};
}
export
interface
IRichEditSupport
{
/**
* Optional adapter for electric characters.
...
...
@@ -779,4 +788,9 @@ export interface IRichEditSupport {
* Optional adapter for custom Enter handling.
*/
onEnter
?:
IRichEditOnEnter
;
/**
* Optional adapter for brackets.
*/
brackets
?:
IRichEditBrackets
;
}
src/vs/editor/common/modes/supports/electricCharacter.ts
浏览文件 @
568c9e51
...
...
@@ -8,7 +8,7 @@ import * as Modes from 'vs/editor/common/modes';
import
{
handleEvent
,
ignoreBracketsInToken
}
from
'
vs/editor/common/modes/supports
'
;
import
Strings
=
require
(
'
vs/base/common/strings
'
);
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
I
Found
Bracket
}
from
'
vs/editor/common/editorCommon
'
;
import
{
I
RichEdit
Bracket
}
from
'
vs/editor/common/editorCommon
'
;
import
{
Arrays
}
from
'
vs/editor/common/core/arrays
'
;
/**
...
...
@@ -58,31 +58,26 @@ export class BracketElectricCharacterSupport implements Modes.IRichEditElectricC
}
});
}
}
interface
ISimpleInternalBracket
{
open
:
string
;
close
:
string
;
}
interface
IInternalBrackets
extends
ISimpleInternalBracket
{
forwardRegex
:
RegExp
;
reversedRegex
:
RegExp
;
public
getRichEditBrackets
():
Modes
.
IRichEditBrackets
{
return
this
.
brackets
.
getRichEditBrackets
();
}
}
interface
I
Text
Bracket
{
interface
I
SimpleInternal
Bracket
{
open
:
string
;
close
:
string
;
isOpen
:
boolean
;
}
export
class
Brackets
{
private
_modeId
:
string
;
private
_brackets
:
I
InternalBrackets
[];
private
_brackets
:
I
RichEditBracket
[];
private
_bracketsForwardRegex
:
RegExp
;
private
_bracketsReversedRegex
:
RegExp
;
private
_text2Bracket
:
{[
text
:
string
]:
ITextBracket
;};
private
_maxBracketLength
:
number
;
private
_textIsBracket
:
{[
text
:
string
]:
IRichEditBracket
;};
private
_textIsOpenBracket
:
{[
text
:
string
]:
boolean
;};
private
_docComment
:
IDocComment
;
constructor
(
modeId
:
string
,
brackets
:
Modes
.
IBracketPair
[],
docComment
:
IDocComment
=
null
,
caseInsensitive
:
boolean
=
false
)
{
...
...
@@ -97,14 +92,35 @@ export class Brackets {
});
this
.
_bracketsForwardRegex
=
getRegexForBrackets
(
this
.
_brackets
);
this
.
_bracketsReversedRegex
=
getReversedRegexForBrackets
(
this
.
_brackets
);
this
.
_text2Bracket
=
{};
this
.
_textIsBracket
=
{};
this
.
_textIsOpenBracket
=
{};
this
.
_maxBracketLength
=
0
;
this
.
_brackets
.
forEach
((
b
)
=>
{
this
.
_text2Bracket
[
b
.
open
]
=
{
open
:
b
.
open
,
close
:
b
.
close
,
isOpen
:
true
};
this
.
_text2Bracket
[
b
.
close
]
=
{
open
:
b
.
open
,
close
:
b
.
close
,
isOpen
:
false
};
this
.
_textIsBracket
[
b
.
open
]
=
b
;
this
.
_textIsBracket
[
b
.
close
]
=
b
;
this
.
_textIsOpenBracket
[
b
.
open
]
=
true
;
this
.
_textIsOpenBracket
[
b
.
close
]
=
false
;
this
.
_maxBracketLength
=
Math
.
max
(
this
.
_maxBracketLength
,
b
.
open
.
length
);
this
.
_maxBracketLength
=
Math
.
max
(
this
.
_maxBracketLength
,
b
.
close
.
length
);
});
this
.
_docComment
=
docComment
?
docComment
:
null
;
}
public
getRichEditBrackets
():
Modes
.
IRichEditBrackets
{
if
(
this
.
_brackets
.
length
===
0
)
{
return
null
;
}
return
{
maxBracketLength
:
this
.
_maxBracketLength
,
forwardRegex
:
this
.
_bracketsForwardRegex
,
reversedRegex
:
this
.
_bracketsReversedRegex
,
brackets
:
this
.
_brackets
,
textIsBracket
:
this
.
_textIsBracket
,
textIsOpenBracket
:
this
.
_textIsOpenBracket
};
}
public
getElectricCharacters
():
string
[]
{
var
result
:
string
[]
=
[];
...
...
@@ -168,15 +184,11 @@ export class Brackets {
let
r
=
BracketsUtils
.
findPrevBracketInToken
(
reversedBracketRegex
,
1
,
lineText
,
tokenStart
,
tokenEnd
);
if
(
r
)
{
let
text
=
lineText
.
substring
(
r
.
startColumn
-
1
,
r
.
endColumn
-
1
);
let
data
=
this
.
_text2
Bracket
[
text
];
if
(
!
data
.
isOpen
)
{
let
isOpen
=
this
.
_textIsOpen
Bracket
[
text
];
if
(
!
isOpen
)
{
return
{
matchOpenBracket
:
{
modeId
:
this
.
_modeId
,
open
:
data
.
open
,
close
:
data
.
close
}
}
matchOpenBracket
:
text
};
}
}
}
...
...
@@ -228,7 +240,6 @@ function once<T, R>(keyFn:(input:T)=>string, computeFn:(input:T)=>R):(input:T)=>
}
}
// TODO: dup in textModelWithTokens
var
getRegexForBracketPair
=
once
<
ISimpleInternalBracket
,
RegExp
>
(
(
input
)
=>
`
${
input
.
open
}
;
${
input
.
close
}
`
,
(
input
)
=>
{
...
...
@@ -236,7 +247,6 @@ var getRegexForBracketPair = once<ISimpleInternalBracket,RegExp>(
}
);
// TODO: dup in textModelWithTokens
var
getReversedRegexForBracketPair
=
once
<
ISimpleInternalBracket
,
RegExp
>
(
(
input
)
=>
`
${
input
.
open
}
;
${
input
.
close
}
`
,
(
input
)
=>
{
...
...
@@ -273,7 +283,6 @@ function createOrRegex(pieces:string[]): RegExp {
return
Strings
.
createRegExp
(
regexStr
,
true
,
false
,
false
,
false
);
}
// TODO: dup in textModelWithTokens
function
toReversedString
(
str
:
string
):
string
{
let
reversedStr
=
''
;
for
(
let
i
=
str
.
length
-
1
;
i
>=
0
;
i
--
)
{
...
...
@@ -284,7 +293,6 @@ function toReversedString(str:string): string {
export
class
BracketsUtils
{
// TODO: dup in textModelWithTokens
private
static
_findPrevBracketInText
(
reversedBracketRegex
:
RegExp
,
lineNumber
:
number
,
reversedText
:
string
,
offset
:
number
):
Range
{
let
m
=
reversedText
.
match
(
reversedBracketRegex
);
...
...
@@ -299,7 +307,6 @@ export class BracketsUtils {
return
new
Range
(
lineNumber
,
absoluteMatchOffset
+
1
,
lineNumber
,
absoluteMatchOffset
+
1
+
matchLength
);
}
// TODO: dup in textModelWithTokens
public
static
findPrevBracketInToken
(
reversedBracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
{
// Because JS does not support backwards regex search, we search forwards in a reversed string with a reversed regex ;)
let
currentTokenReversedText
=
''
;
...
...
@@ -310,4 +317,24 @@ export class BracketsUtils {
return
this
.
_findPrevBracketInText
(
reversedBracketRegex
,
lineNumber
,
currentTokenReversedText
,
currentTokenStart
);
}
public
static
findNextBracketInText
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
text
:
string
,
offset
:
number
):
Range
{
let
m
=
text
.
match
(
bracketRegex
);
if
(
!
m
)
{
return
null
;
}
let
matchOffset
=
m
.
index
;
let
matchLength
=
m
[
0
].
length
;
let
absoluteMatchOffset
=
offset
+
matchOffset
;
return
new
Range
(
lineNumber
,
absoluteMatchOffset
+
1
,
lineNumber
,
absoluteMatchOffset
+
1
+
matchLength
);
}
public
static
findNextBracketInToken
(
bracketRegex
:
RegExp
,
lineNumber
:
number
,
lineText
:
string
,
currentTokenStart
:
number
,
currentTokenEnd
:
number
):
Range
{
let
currentTokenText
=
lineText
.
substring
(
currentTokenStart
,
currentTokenEnd
);
return
this
.
findNextBracketInText
(
bracketRegex
,
lineNumber
,
currentTokenText
,
currentTokenStart
);
}
}
src/vs/editor/common/modes/supports/richEditSupport.ts
浏览文件 @
568c9e51
...
...
@@ -30,11 +30,12 @@ export interface IRichEditConfiguration {
export
class
RichEditSupport
implements
Modes
.
IRichEditSupport
{
public
electricCharacter
:
Modes
.
IRichEditElectricCharacter
;
public
electricCharacter
:
BracketElectricCharacterSupport
;
public
comments
:
Modes
.
ICommentsConfiguration
;
public
characterPair
:
Modes
.
IRichEditCharacterPair
;
public
wordDefinition
:
RegExp
;
public
onEnter
:
Modes
.
IRichEditOnEnter
;
public
brackets
:
Modes
.
IRichEditBrackets
;
constructor
(
modeId
:
string
,
conf
:
IRichEditConfiguration
)
{
...
...
@@ -48,6 +49,7 @@ export class RichEditSupport implements Modes.IRichEditSupport {
if
(
conf
.
__electricCharacterSupport
)
{
this
.
electricCharacter
=
new
BracketElectricCharacterSupport
(
modeId
,
conf
.
__electricCharacterSupport
);
this
.
brackets
=
this
.
electricCharacter
.
getRichEditBrackets
();
}
this
.
wordDefinition
=
conf
.
wordPattern
||
NullMode
.
DEFAULT_WORD_REGEXP
;
...
...
src/vs/editor/test/common/testModes.ts
浏览文件 @
568c9e51
...
...
@@ -220,12 +220,22 @@ export class BracketState extends AbstractState {
export
class
BracketMode
extends
TestingMode
{
public
tokenizationSupport
:
modes
.
ITokenizationSupport
;
public
richEditSupport
:
modes
.
IRichEditSupport
;
constructor
()
{
super
();
this
.
tokenizationSupport
=
new
TokenizationSupport
(
this
,
{
getInitialState
:
()
=>
new
BracketState
(
this
)
},
false
,
false
);
this
.
richEditSupport
=
new
RichEditSupport
(
this
.
getId
(),
{
__electricCharacterSupport
:
{
brackets
:
[
{
tokenType
:
'
asd
'
,
open
:
'
{
'
,
close
:
'
}
'
,
isElectric
:
true
},
{
tokenType
:
'
qwe
'
,
open
:
'
[
'
,
close
:
'
]
'
,
isElectric
:
true
},
{
tokenType
:
'
zxc
'
,
open
:
'
(
'
,
close
:
'
)
'
,
isElectric
:
true
}
]
}
});
}
}
...
...
src/vs/languages/javascript/test/common/javascript.test.ts
浏览文件 @
568c9e51
...
...
@@ -68,9 +68,9 @@ suite('JS - Auto Indent', () => {
assert
.
deepEqual
(
actual
,
expected
,
'
LINE <<<
'
+
line
+
'
>>>, OFFSET: <<<
'
+
offset
+
'
>>>
'
);
}
const
CURLY
=
{
matchOpenBracket
:
{
modeId
:
'
javascript
'
,
open
:
'
{
'
,
close
:
'
}
'
}
};
const
ROUND
=
{
matchOpenBracket
:
{
modeId
:
'
javascript
'
,
open
:
'
(
'
,
close
:
'
)
'
}
};
const
SQUARE
=
{
matchOpenBracket
:
{
modeId
:
'
javascript
'
,
open
:
'
[
'
,
close
:
'
]
'
}
};
const
CURLY
=
{
matchOpenBracket
:
'
}
'
};
const
ROUND
=
{
matchOpenBracket
:
'
)
'
};
const
SQUARE
=
{
matchOpenBracket
:
'
]
'
};
testElectricCharacter
(
'
var f = function() {}
'
,
20
,
null
);
testElectricCharacter
(
'
}
'
,
0
,
CURLY
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录