Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
7f438ed3
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,发现更多精彩内容 >>
提交
7f438ed3
编写于
11月 01, 2016
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Eliminate ILineContext
上级
89f732b2
变更
20
隐藏空白更改
内联
并排
Showing
20 changed file
with
390 addition
and
524 deletion
+390
-524
src/vs/editor/common/controller/cursorCollection.ts
src/vs/editor/common/controller/cursorCollection.ts
+33
-39
src/vs/editor/common/controller/oneCursor.ts
src/vs/editor/common/controller/oneCursor.ts
+7
-16
src/vs/editor/common/core/lineTokens.ts
src/vs/editor/common/core/lineTokens.ts
+39
-19
src/vs/editor/common/core/modeTransition.ts
src/vs/editor/common/core/modeTransition.ts
+19
-0
src/vs/editor/common/editorCommon.ts
src/vs/editor/common/editorCommon.ts
+1
-7
src/vs/editor/common/model/modelLine.ts
src/vs/editor/common/model/modelLine.ts
+1
-3
src/vs/editor/common/model/textModelWithTokens.ts
src/vs/editor/common/model/textModelWithTokens.ts
+37
-57
src/vs/editor/common/model/textModelWithTokensHelpers.ts
src/vs/editor/common/model/textModelWithTokensHelpers.ts
+0
-49
src/vs/editor/common/modes.ts
src/vs/editor/common/modes.ts
+0
-66
src/vs/editor/common/modes/languageConfigurationRegistry.ts
src/vs/editor/common/modes/languageConfigurationRegistry.ts
+98
-23
src/vs/editor/common/modes/supports.ts
src/vs/editor/common/modes/supports.ts
+41
-37
src/vs/editor/common/modes/supports/characterPair.ts
src/vs/editor/common/modes/supports/characterPair.ts
+22
-39
src/vs/editor/common/modes/supports/electricCharacter.ts
src/vs/editor/common/modes/supports/electricCharacter.ts
+16
-34
src/vs/editor/common/modes/supports/onEnter.ts
src/vs/editor/common/modes/supports/onEnter.ts
+7
-41
src/vs/editor/common/services/editorWorkerServiceImpl.ts
src/vs/editor/common/services/editorWorkerServiceImpl.ts
+3
-3
src/vs/editor/test/common/controller/cursor.test.ts
src/vs/editor/test/common/controller/cursor.test.ts
+2
-2
src/vs/editor/test/common/modes/autoIndentation.test.ts
src/vs/editor/test/common/modes/autoIndentation.test.ts
+31
-4
src/vs/editor/test/common/modes/supports/onEnter.test.ts
src/vs/editor/test/common/modes/supports/onEnter.test.ts
+6
-6
src/vs/editor/test/common/modes/tokenization.test.ts
src/vs/editor/test/common/modes/tokenization.test.ts
+21
-23
src/vs/editor/test/common/modesTestUtils.ts
src/vs/editor/test/common/modesTestUtils.ts
+6
-56
未找到文件。
src/vs/editor/common/controller/cursorCollection.ts
浏览文件 @
7f438ed3
...
...
@@ -328,52 +328,46 @@ export class CursorCollection {
};
let
electricCharSupport
=
LanguageConfigurationRegistry
.
getElectricCharacterSupport
(
this
.
model
.
getMode
().
getId
());
if
(
electricCharSupport
)
{
let
electricChars
:
string
[]
=
null
;
try
{
electricChars
=
electricCharSupport
.
getElectricCharacters
();
}
catch
(
e
)
{
onUnexpectedError
(
e
);
electricChars
=
null
;
}
if
(
electricChars
)
{
for
(
i
=
0
;
i
<
electricChars
.
length
;
i
++
)
{
result
.
electricChars
[
electricChars
[
i
]]
=
true
;
}
let
electricChars
:
string
[]
=
null
;
try
{
electricChars
=
LanguageConfigurationRegistry
.
getElectricCharacters
(
this
.
model
.
getMode
().
getId
());
}
catch
(
e
)
{
onUnexpectedError
(
e
);
electricChars
=
null
;
}
if
(
electricChars
)
{
for
(
i
=
0
;
i
<
electricChars
.
length
;
i
++
)
{
result
.
electricChars
[
electricChars
[
i
]]
=
true
;
}
}
let
characterPairSupport
=
LanguageConfigurationRegistry
.
getCharacterPairSupport
(
this
.
model
.
getMode
().
getId
());
if
(
characterPairSupport
)
{
let
autoClosingPairs
:
IAutoClosingPair
[];
try
{
autoClosingPairs
=
characterPairSupport
.
getAutoClosingPairs
();
}
catch
(
e
)
{
onUnexpectedError
(
e
);
autoClosingPairs
=
null
;
}
if
(
autoClosingPairs
)
{
for
(
i
=
0
;
i
<
autoClosingPairs
.
length
;
i
++
)
{
result
.
autoClosingPairsOpen
[
autoClosingPairs
[
i
].
open
]
=
autoClosingPairs
[
i
].
close
;
result
.
autoClosingPairsClose
[
autoClosingPairs
[
i
].
close
]
=
autoClosingPairs
[
i
].
open
;
}
let
autoClosingPairs
:
IAutoClosingPair
[];
try
{
autoClosingPairs
=
LanguageConfigurationRegistry
.
getAutoClosingPairs
(
this
.
model
.
getMode
().
getId
());
}
catch
(
e
)
{
onUnexpectedError
(
e
);
autoClosingPairs
=
null
;
}
if
(
autoClosingPairs
)
{
for
(
i
=
0
;
i
<
autoClosingPairs
.
length
;
i
++
)
{
result
.
autoClosingPairsOpen
[
autoClosingPairs
[
i
].
open
]
=
autoClosingPairs
[
i
].
close
;
result
.
autoClosingPairsClose
[
autoClosingPairs
[
i
].
close
]
=
autoClosingPairs
[
i
].
open
;
}
}
let
surroundingPairs
:
IAutoClosingPair
[];
try
{
surroundingPairs
=
characterPairSupport
.
getSurroundingPairs
();
}
catch
(
e
)
{
onUnexpectedError
(
e
);
surroundingPairs
=
null
;
}
if
(
surroundingPairs
)
{
for
(
i
=
0
;
i
<
surroundingPairs
.
length
;
i
++
)
{
result
.
surroundingPairs
[
surroundingPairs
[
i
].
open
]
=
surroundingPairs
[
i
].
close
;
}
let
surroundingPairs
:
IAutoClosingPair
[];
try
{
surroundingPairs
=
LanguageConfigurationRegistry
.
getSurroundingPairs
(
this
.
model
.
getMode
().
getId
());
}
catch
(
e
)
{
onUnexpectedError
(
e
);
surroundingPairs
=
null
;
}
if
(
surroundingPairs
)
{
for
(
i
=
0
;
i
<
surroundingPairs
.
length
;
i
++
)
{
result
.
surroundingPairs
[
surroundingPairs
[
i
].
open
]
=
surroundingPairs
[
i
].
close
;
}
}
return
result
;
}
}
\ No newline at end of file
}
src/vs/editor/common/controller/oneCursor.ts
浏览文件 @
7f438ed3
...
...
@@ -1471,12 +1471,6 @@ export class OneCursorOp {
return
false
;
}
let
characterPairSupport
=
LanguageConfigurationRegistry
.
getCharacterPairSupport
(
cursor
.
model
.
getMode
().
getId
());
if
(
!
characterPairSupport
)
{
return
false
;
}
let
position
=
cursor
.
getPosition
();
let
lineText
=
cursor
.
model
.
getLineContent
(
position
.
lineNumber
);
let
beforeCharacter
=
lineText
[
position
.
column
-
1
];
...
...
@@ -1495,11 +1489,11 @@ export class OneCursorOp {
}
}
let
line
Context
=
cursor
.
model
.
getLineContext
(
position
.
lineNumber
);
let
line
Tokens
=
cursor
.
model
.
getLineTokens
(
position
.
lineNumber
,
false
);
let
shouldAutoClosePair
=
false
;
try
{
shouldAutoClosePair
=
characterPairSupport
.
shouldAutoClosePair
(
ch
,
lineContext
,
position
.
column
-
1
);
shouldAutoClosePair
=
LanguageConfigurationRegistry
.
shouldAutoClosePair
(
ch
,
lineTokens
,
position
.
column
-
1
);
}
catch
(
e
)
{
onUnexpectedError
(
e
);
}
...
...
@@ -1571,16 +1565,13 @@ export class OneCursorOp {
let
position
=
cursor
.
getPosition
();
let
lineText
=
cursor
.
model
.
getLineContent
(
position
.
lineNumber
);
let
line
Context
=
cursor
.
model
.
getLineContext
(
position
.
lineNumber
);
let
line
Tokens
=
cursor
.
model
.
getLineTokens
(
position
.
lineNumber
,
false
);
let
electricAction
:
IElectricAction
;
let
electricCharSupport
=
LanguageConfigurationRegistry
.
getElectricCharacterSupport
(
cursor
.
model
.
getMode
().
getId
());
if
(
electricCharSupport
)
{
try
{
electricAction
=
electricCharSupport
.
onElectricCharacter
(
lineContext
,
position
.
column
-
2
);
}
catch
(
e
)
{
onUnexpectedError
(
e
);
}
try
{
electricAction
=
LanguageConfigurationRegistry
.
onElectricCharacter
(
lineTokens
,
position
.
column
-
2
);
}
catch
(
e
)
{
onUnexpectedError
(
e
);
}
if
(
electricAction
)
{
...
...
src/vs/editor/common/core/lineTokens.ts
浏览文件 @
7f438ed3
...
...
@@ -75,23 +75,29 @@ export class LineToken {
export
class
LineTokens
{
_lineTokensBrand
:
void
;
private
_map
:
TokensInflatorMap
;
private
_tokens
:
number
[];
private
_textLength
:
number
;
private
readonly
_map
:
TokensInflatorMap
;
private
readonly
_tokens
:
number
[];
private
readonly
_text
:
string
;
private
readonly
_textLength
:
number
;
readonly
modeTransitions
:
ModeTransition
[];
constructor
(
map
:
TokensInflatorMap
,
tokens
:
number
[],
modeTransitions
:
ModeTransition
[],
text
Length
:
number
)
{
constructor
(
map
:
TokensInflatorMap
,
tokens
:
number
[],
modeTransitions
:
ModeTransition
[],
text
:
string
)
{
this
.
_map
=
map
;
this
.
_tokens
=
tokens
;
this
.
modeTransitions
=
modeTransitions
;
this
.
_textLength
=
textLength
;
this
.
_text
=
text
;
this
.
_textLength
=
this
.
_text
.
length
;
}
public
getTokenCount
():
number
{
return
this
.
_tokens
.
length
;
}
public
getLineContent
():
string
{
return
this
.
_text
;
}
public
getTokenStartOffset
(
tokenIndex
:
number
):
number
{
return
TokensBinaryEncoding
.
getStartIndex
(
this
.
_tokens
[
tokenIndex
]);
}
...
...
@@ -108,25 +114,39 @@ export class LineTokens {
}
public
equals
(
other
:
LineTokens
):
boolean
{
if
(
other
instanceof
LineTokens
)
{
if
(
this
.
_map
!==
other
.
_map
)
{
return
false
;
}
if
(
this
.
_tokens
.
length
!==
other
.
_tokens
.
length
)
{
return
false
;
}
for
(
let
i
=
0
,
len
=
this
.
_tokens
.
length
;
i
<
len
;
i
++
)
{
if
(
this
.
_tokens
[
i
]
!==
other
.
_tokens
[
i
])
{
return
false
;
}
}
return
true
;
}
if
(
!
(
other
instanceof
LineTokens
))
{
return
false
;
}
if
(
this
.
_text
!==
other
.
_text
)
{
return
false
;
}
if
(
this
.
_map
!==
other
.
_map
)
{
return
false
;
}
if
(
!
ModeTransition
.
equals
(
this
.
modeTransitions
,
other
.
modeTransitions
))
{
return
false
;
}
if
(
this
.
_tokens
.
length
!==
other
.
_tokens
.
length
)
{
return
false
;
}
for
(
let
i
=
0
,
len
=
this
.
_tokens
.
length
;
i
<
len
;
i
++
)
{
if
(
this
.
_tokens
[
i
]
!==
other
.
_tokens
[
i
])
{
return
false
;
}
}
return
true
;
}
/**
* Find the token containing offset `offset`.
* For example, with the following tokens [0, 5), [5, 9), [9, infinity)
* Searching for 0, 1, 2, 3 or 4 will return 0.
* Searching for 5, 6, 7 or 8 will return 1.
* Searching for 9, 10, 11, ... will return 2.
* @param offset The search offset
* @return The index of the token containing the offset.
*/
public
findTokenIndexAtOffset
(
offset
:
number
):
number
{
return
TokensBinaryEncoding
.
findIndexOfOffset
(
this
.
_tokens
,
offset
);
}
...
...
src/vs/editor/common/core/modeTransition.ts
浏览文件 @
7f438ed3
...
...
@@ -20,4 +20,23 @@ export class ModeTransition {
public
static
findIndexInSegmentsArray
(
arr
:
ModeTransition
[],
desiredIndex
:
number
):
number
{
return
Arrays
.
findIndexInSegmentsArray
(
arr
,
desiredIndex
);
}
public
static
equals
(
a
:
ModeTransition
[],
b
:
ModeTransition
[]):
boolean
{
let
aLen
=
a
.
length
;
let
bLen
=
b
.
length
;
if
(
aLen
!==
bLen
)
{
return
false
;
}
for
(
let
i
=
0
;
i
<
aLen
;
i
++
)
{
let
aModeTransition
=
a
[
i
];
let
bModeTransition
=
b
[
i
];
if
(
aModeTransition
.
startIndex
!==
bModeTransition
.
startIndex
)
{
return
false
;
}
if
(
aModeTransition
.
modeId
!==
bModeTransition
.
modeId
)
{
return
false
;
}
}
return
true
;
}
}
src/vs/editor/common/editorCommon.ts
浏览文件 @
7f438ed3
...
...
@@ -10,7 +10,7 @@ import * as types from 'vs/base/common/types';
import
URI
from
'
vs/base/common/uri
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
ServicesAccessor
,
IConstructorSignature1
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
I
LineContext
,
I
Mode
}
from
'
vs/editor/common/modes
'
;
import
{
IMode
}
from
'
vs/editor/common/modes
'
;
import
{
LineTokens
}
from
'
vs/editor/common/core/lineTokens
'
;
import
{
ScrollbarVisibility
}
from
'
vs/base/common/scrollable
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
...
...
@@ -1882,12 +1882,6 @@ export interface ITokenizedModel extends ITextModel {
*/
getLineTokens
(
lineNumber
:
number
,
inaccurateTokensAcceptable
?:
boolean
):
LineTokens
;
/**
* Tokenize if necessary and get the tokenization result for the line `lineNumber`, as returned by the language mode.
* @internal
*/
getLineContext
(
lineNumber
:
number
):
ILineContext
;
/**
* Get the current language mode associated with the model.
*/
...
...
src/vs/editor/common/model/modelLine.ts
浏览文件 @
7f438ed3
...
...
@@ -195,8 +195,6 @@ export class ModelLine {
}
public
getTokens
(
map
:
TokensInflatorMap
):
LineTokens
{
const
textLength
=
this
.
_text
.
length
;
let
lineTokens
=
this
.
_lineTokens
;
if
(
!
lineTokens
)
{
if
(
this
.
_text
.
length
===
0
)
{
...
...
@@ -206,7 +204,7 @@ export class ModelLine {
}
}
return
new
LineTokens
(
map
,
lineTokens
,
this
.
getModeTransitions
(
map
.
topLevelModeId
),
t
extLength
);
return
new
LineTokens
(
map
,
lineTokens
,
this
.
getModeTransitions
(
map
.
topLevelModeId
),
t
his
.
_text
);
}
// --- END TOKENS
...
...
src/vs/editor/common/model/textModelWithTokens.ts
浏览文件 @
7f438ed3
...
...
@@ -11,11 +11,9 @@ import { StopWatch } from 'vs/base/common/stopwatch';
import
*
as
timer
from
'
vs/base/common/timer
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
import
{
ModelLine
}
from
'
vs/editor/common/model/modelLine
'
;
import
{
TextModel
}
from
'
vs/editor/common/model/textModel
'
;
import
{
WordHelper
}
from
'
vs/editor/common/model/textModelWithTokensHelpers
'
;
import
{
TokenIterator
}
from
'
vs/editor/common/model/tokenIterator
'
;
import
{
ITokenizationSupport
,
ILine
Context
,
ILine
Tokens
,
IMode
,
IState
,
TokenizationRegistry
,
IRichEditBrackets
}
from
'
vs/editor/common/modes
'
;
import
{
ITokenizationSupport
,
ILineTokens
,
IMode
,
IState
,
TokenizationRegistry
,
IRichEditBrackets
}
from
'
vs/editor/common/modes
'
;
import
{
NULL_MODE_ID
,
nullTokenize
}
from
'
vs/editor/common/modes/nullMode
'
;
import
{
ignoreBracketsInToken
}
from
'
vs/editor/common/modes/supports
'
;
import
{
BracketsUtils
}
from
'
vs/editor/common/modes/supports/richEditBrackets
'
;
...
...
@@ -25,6 +23,7 @@ import { Position } from 'vs/editor/common/core/position';
import
{
LanguageConfigurationRegistry
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
import
{
Token
}
from
'
vs/editor/common/core/token
'
;
import
{
LineTokens
,
LineToken
}
from
'
vs/editor/common/core/lineTokens
'
;
import
{
getWordAtText
}
from
'
vs/editor/common/model/wordHelper
'
;
class
Mode
implements
IMode
{
...
...
@@ -74,42 +73,6 @@ class ModelTokensChangedEventBuilder {
}
}
/**
* TODO@Alex: remove this wrapper
*/
class
LineContext
implements
ILineContext
{
public
modeTransitions
:
ModeTransition
[];
private
_text
:
string
;
private
_lineTokens
:
LineTokens
;
constructor
(
topLevelModeId
:
string
,
line
:
ModelLine
,
map
:
TokensInflatorMap
)
{
this
.
modeTransitions
=
line
.
getModeTransitions
(
topLevelModeId
);
this
.
_text
=
line
.
text
;
this
.
_lineTokens
=
line
.
getTokens
(
map
);
}
public
getLineContent
():
string
{
return
this
.
_text
;
}
public
getTokenCount
():
number
{
return
this
.
_lineTokens
.
getTokenCount
();
}
public
getTokenStartOffset
(
tokenIndex
:
number
):
number
{
return
this
.
_lineTokens
.
getTokenStartOffset
(
tokenIndex
);
}
public
getTokenType
(
tokenIndex
:
number
):
string
{
return
this
.
_lineTokens
.
getTokenType
(
tokenIndex
);
}
public
findIndexOfOffset
(
offset
:
number
):
number
{
return
this
.
_lineTokens
.
findTokenIndexAtOffset
(
offset
);
}
}
export
class
TextModelWithTokens
extends
TextModel
implements
editorCommon
.
ITokenizedModel
{
private
static
MODE_TOKENIZATION_FAILED_MSG
=
nls
.
localize
(
'
mode.tokenizationSupportFailed
'
,
"
The mode has failed while tokenizing the input.
"
);
...
...
@@ -239,18 +202,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
return
this
.
_lines
[
lineNumber
-
1
].
getTokens
(
this
.
_tokensInflatorMap
);
}
public
getLineContext
(
lineNumber
:
number
):
ILineContext
{
if
(
lineNumber
<
1
||
lineNumber
>
this
.
getLineCount
())
{
throw
new
Error
(
'
Illegal value
'
+
lineNumber
+
'
for `lineNumber`
'
);
}
this
.
_withModelTokensChangedEventBuilder
((
eventBuilder
)
=>
{
this
.
_updateTokensUntilLine
(
eventBuilder
,
lineNumber
,
true
);
});
return
new
LineContext
(
this
.
getModeId
(),
this
.
_lines
[
lineNumber
-
1
],
this
.
_tokensInflatorMap
);
}
public
getMode
():
IMode
{
return
new
Mode
(
this
.
_languageId
);
}
...
...
@@ -489,10 +440,6 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
// Having tokens allows implementing additional helper methods
protected
_getWordDefinition
():
RegExp
{
return
WordHelper
.
massageWordDefinitionOf
(
this
.
getModeId
());
}
public
getWordAtPosition
(
_position
:
editorCommon
.
IPosition
):
editorCommon
.
IWordAtPosition
{
this
.
_assertNotDisposed
();
let
position
=
this
.
validatePosition
(
_position
);
...
...
@@ -500,11 +447,44 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
if
(
this
.
_invalidLineStartIndex
<=
position
.
lineNumber
)
{
// this line is not tokenized
return
WordHelper
.
getWordAtPosition
(
lineContent
,
position
.
column
,
this
.
getModeId
(),
null
);
return
getWordAtText
(
position
.
column
,
LanguageConfigurationRegistry
.
getWordDefinition
(
this
.
getModeId
()),
lineContent
,
0
);
}
let
modeTransitions
=
this
.
_lines
[
position
.
lineNumber
-
1
].
getModeTransitions
(
this
.
getModeId
());
return
WordHelper
.
getWordAtPosition
(
lineContent
,
position
.
column
,
this
.
getModeId
(),
modeTransitions
);
let
offset
=
position
.
column
-
1
;
let
modeIndex
=
ModeTransition
.
findIndexInSegmentsArray
(
modeTransitions
,
offset
);
let
modeStartOffset
=
modeTransitions
[
modeIndex
].
startIndex
;
let
modeEndOffset
=
(
modeIndex
+
1
<
modeTransitions
.
length
?
modeTransitions
[
modeIndex
+
1
].
startIndex
:
lineContent
.
length
);
let
modeId
=
modeTransitions
[
modeIndex
].
modeId
;
let
result
=
getWordAtText
(
position
.
column
,
LanguageConfigurationRegistry
.
getWordDefinition
(
modeId
),
lineContent
.
substring
(
modeStartOffset
,
modeEndOffset
),
modeStartOffset
);
if
(
!
result
&&
modeIndex
>
0
&&
modeTransitions
[
modeIndex
].
startIndex
===
offset
)
{
// The position is right at the beginning of `modeIndex`, so try looking at `modeIndex` - 1 too
let
prevModeStartOffset
=
modeTransitions
[
modeIndex
-
1
].
startIndex
;
let
prevModeId
=
modeTransitions
[
modeIndex
-
1
].
modeId
;
result
=
getWordAtText
(
position
.
column
,
LanguageConfigurationRegistry
.
getWordDefinition
(
prevModeId
),
lineContent
.
substring
(
prevModeStartOffset
,
modeStartOffset
),
prevModeStartOffset
);
}
return
result
;
}
public
getWordUntilPosition
(
position
:
editorCommon
.
IPosition
):
editorCommon
.
IWordAtPosition
{
...
...
src/vs/editor/common/model/textModelWithTokensHelpers.ts
已删除
100644 → 0
浏览文件 @
89f732b2
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
IWordAtPosition
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ModeTransition
}
from
'
vs/editor/common/core/modeTransition
'
;
import
{
LanguageConfigurationRegistry
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
import
{
getWordAtText
,
ensureValidWordDefinition
}
from
'
vs/editor/common/model/wordHelper
'
;
export
class
WordHelper
{
public
static
massageWordDefinitionOf
(
modeId
:
string
):
RegExp
{
let
wordDefinition
=
LanguageConfigurationRegistry
.
getWordDefinition
(
modeId
);
return
ensureValidWordDefinition
(
wordDefinition
);
}
private
static
_getWordAtColumn
(
txt
:
string
,
column
:
number
,
modeIndex
:
number
,
modeTransitions
:
ModeTransition
[]):
IWordAtPosition
{
let
modeStartIndex
=
modeTransitions
[
modeIndex
].
startIndex
;
let
modeEndIndex
=
(
modeIndex
+
1
<
modeTransitions
.
length
?
modeTransitions
[
modeIndex
+
1
].
startIndex
:
txt
.
length
);
let
modeId
=
modeTransitions
[
modeIndex
].
modeId
;
return
getWordAtText
(
column
,
WordHelper
.
massageWordDefinitionOf
(
modeId
),
txt
.
substring
(
modeStartIndex
,
modeEndIndex
),
modeStartIndex
);
}
public
static
getWordAtPosition
(
lineContent
:
string
,
column
:
number
,
topModeId
:
string
,
modeTransitions
:
ModeTransition
[]):
IWordAtPosition
{
if
(
!
modeTransitions
||
modeTransitions
.
length
===
0
)
{
return
getWordAtText
(
column
,
WordHelper
.
massageWordDefinitionOf
(
topModeId
),
lineContent
,
0
);
}
let
result
:
IWordAtPosition
=
null
;
let
columnIndex
=
column
-
1
;
let
modeIndex
=
ModeTransition
.
findIndexInSegmentsArray
(
modeTransitions
,
columnIndex
);
result
=
WordHelper
.
_getWordAtColumn
(
lineContent
,
column
,
modeIndex
,
modeTransitions
);
if
(
!
result
&&
modeIndex
>
0
&&
modeTransitions
[
modeIndex
].
startIndex
===
columnIndex
)
{
// The position is right at the beginning of `modeIndex`, so try looking at `modeIndex` - 1 too
result
=
WordHelper
.
_getWordAtColumn
(
lineContent
,
column
,
modeIndex
-
1
,
modeTransitions
);
}
return
result
;
}
}
src/vs/editor/common/modes.ts
浏览文件 @
7f438ed3
...
...
@@ -36,47 +36,6 @@ export interface IModeDescriptor {
id
:
string
;
}
/**
* @internal
*/
export
interface
ILineContext
{
/**
* Get the content of the line.
*/
getLineContent
():
string
;
/**
* The mode transitions on this line.
*/
modeTransitions
:
ModeTransition
[];
/**
* Get the number of tokens on this line.
*/
getTokenCount
():
number
;
/**
* Get the start offset of the token at `tokenIndex`.
*/
getTokenStartOffset
(
tokenIndex
:
number
):
number
;
/**
* Get the type of the token at `tokenIndex`.
*/
getTokenType
(
tokenIndex
:
number
):
string
;
/**
* Find the token containing offset `offset`.
* For example, with the following tokens [0, 5), [5, 9), [9, infinity)
* Searching for 0, 1, 2, 3 or 4 will return 0.
* Searching for 5, 6, 7 or 8 will return 1.
* Searching for 9, 10, 11, ... will return 2.
* @param offset The search offset
* @return The index of the token containing the offset.
*/
findIndexOfOffset
(
offset
:
number
):
number
;
}
/**
* A mode. Will soon be obsolete.
*/
...
...
@@ -773,22 +732,6 @@ export interface EnterAction {
removeText
?:
number
;
}
/**
* @internal
*/
export
interface
IRichEditElectricCharacter
{
getElectricCharacters
():
string
[];
// Should return opening bracket type to match indentation with
onElectricCharacter
(
context
:
ILineContext
,
offset
:
number
):
IElectricAction
;
}
/**
* @internal
*/
export
interface
IRichEditOnEnter
{
onEnter
(
model
:
editorCommon
.
ITokenizedModel
,
position
:
editorCommon
.
IPosition
):
EnterAction
;
}
/**
* Interface used to support insertion of mode specific comments.
* @internal
...
...
@@ -804,15 +747,6 @@ export interface IAutoClosingPair {
close
:
string
;
}
/**
* @internal
*/
export
interface
IRichEditCharacterPair
{
getAutoClosingPairs
():
IAutoClosingPairConditional
[];
shouldAutoClosePair
(
character
:
string
,
context
:
ILineContext
,
offset
:
number
):
boolean
;
getSurroundingPairs
():
IAutoClosingPair
[];
}
/**
* @internal
*/
...
...
src/vs/editor/common/modes/languageConfigurationRegistry.ts
浏览文件 @
7f438ed3
...
...
@@ -5,9 +5,9 @@
'
use strict
'
;
import
{
ICommentsConfiguration
,
IRichEditBrackets
,
I
RichEditCharacterPair
,
I
AutoClosingPair
,
IAutoClosingPairConditional
,
IRichEditOnEnter
,
CharacterPair
,
IRichEditElectricCharacter
,
EnterAction
,
Indent
Action
ICommentsConfiguration
,
IRichEditBrackets
,
IAutoClosingPair
,
IAutoClosingPairConditional
,
CharacterPair
,
EnterAction
,
IndentAction
,
IElectric
Action
}
from
'
vs/editor/common/modes
'
;
import
{
CharacterPairSupport
}
from
'
vs/editor/common/modes/supports/characterPair
'
;
import
{
BracketElectricCharacterSupport
,
IBracketElectricCharacterContribution
}
from
'
vs/editor/common/modes/supports/electricCharacter
'
;
...
...
@@ -16,10 +16,11 @@ import { RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBracke
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
ITokenizedModel
}
from
'
vs/editor/common/editorCommon
'
;
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
DEFAULT_WORD_REGEXP
}
from
'
vs/editor/common/model/wordHelper
'
;
import
{
DEFAULT_WORD_REGEXP
,
ensureValidWordDefinition
}
from
'
vs/editor/common/model/wordHelper
'
;
import
{
createScopedLineTokens
}
from
'
vs/editor/common/modes/supports
'
;
import
{
LineTokens
}
from
'
vs/editor/common/core/lineTokens
'
;
/**
* Describes how comments for a language work.
...
...
@@ -90,9 +91,9 @@ export class RichEditSupport {
public
electricCharacter
:
BracketElectricCharacterSupport
;
public
comments
:
ICommentsConfiguration
;
public
characterPair
:
IRichEditCharacterPair
;
public
characterPair
:
CharacterPairSupport
;
public
wordDefinition
:
RegExp
;
public
onEnter
:
IRichEditOnEnter
;
public
onEnter
:
OnEnterSupport
;
public
brackets
:
IRichEditBrackets
;
constructor
(
modeId
:
string
,
previous
:
RichEditSupport
,
rawConf
:
LanguageConfiguration
)
{
...
...
@@ -112,8 +113,8 @@ export class RichEditSupport {
this
.
_handleComments
(
modeId
,
this
.
_conf
);
this
.
characterPair
=
new
CharacterPairSupport
(
LanguageConfigurationRegistry
,
modeId
,
this
.
_conf
);
this
.
electricCharacter
=
new
BracketElectricCharacterSupport
(
LanguageConfigurationRegistry
,
modeId
,
this
.
brackets
,
this
.
characterPair
.
getAutoClosingPairs
(),
this
.
_conf
.
__electricCharacterSupport
);
this
.
characterPair
=
new
CharacterPairSupport
(
this
.
_conf
);
this
.
electricCharacter
=
new
BracketElectricCharacterSupport
(
this
.
brackets
,
this
.
characterPair
.
getAutoClosingPairs
(),
this
.
_conf
.
__electricCharacterSupport
);
this
.
wordDefinition
=
this
.
_conf
.
wordPattern
||
DEFAULT_WORD_REGEXP
;
}
...
...
@@ -150,7 +151,7 @@ export class RichEditSupport {
}
if
(
!
empty
)
{
this
.
onEnter
=
new
OnEnterSupport
(
LanguageConfigurationRegistry
,
modeId
,
onEnter
);
this
.
onEnter
=
new
OnEnterSupport
(
onEnter
);
}
}
...
...
@@ -198,7 +199,9 @@ export class LanguageConfigurationRegistryImpl {
return
this
.
_entries
[
modeId
];
}
public
getElectricCharacterSupport
(
modeId
:
string
):
IRichEditElectricCharacter
{
// begin electricCharacter
private
_getElectricCharacterSupport
(
modeId
:
string
):
BracketElectricCharacterSupport
{
let
value
=
this
.
_getRichEditSupport
(
modeId
);
if
(
!
value
)
{
return
null
;
...
...
@@ -206,6 +209,28 @@ export class LanguageConfigurationRegistryImpl {
return
value
.
electricCharacter
||
null
;
}
public
getElectricCharacters
(
modeId
:
string
):
string
[]
{
let
electricCharacterSupport
=
this
.
_getElectricCharacterSupport
(
modeId
);
if
(
!
electricCharacterSupport
)
{
return
[];
}
return
electricCharacterSupport
.
getElectricCharacters
();
}
/**
* Should return opening bracket type to match indentation with
*/
public
onElectricCharacter
(
context
:
LineTokens
,
offset
:
number
):
IElectricAction
{
let
scopedLineTokens
=
createScopedLineTokens
(
context
,
offset
);
let
electricCharacterSupport
=
this
.
_getElectricCharacterSupport
(
scopedLineTokens
.
modeId
);
if
(
!
electricCharacterSupport
)
{
return
null
;
}
return
electricCharacterSupport
.
onElectricCharacter
(
scopedLineTokens
,
offset
-
scopedLineTokens
.
firstCharOffset
);
}
// end electricCharacter
public
getComments
(
modeId
:
string
):
ICommentsConfiguration
{
let
value
=
this
.
_getRichEditSupport
(
modeId
);
if
(
!
value
)
{
...
...
@@ -214,7 +239,9 @@ export class LanguageConfigurationRegistryImpl {
return
value
.
comments
||
null
;
}
public
getCharacterPairSupport
(
modeId
:
string
):
IRichEditCharacterPair
{
// begin characterPair
private
_getCharacterPairSupport
(
modeId
:
string
):
CharacterPairSupport
{
let
value
=
this
.
_getRichEditSupport
(
modeId
);
if
(
!
value
)
{
return
null
;
...
...
@@ -222,15 +249,44 @@ export class LanguageConfigurationRegistryImpl {
return
value
.
characterPair
||
null
;
}
public
getAutoClosingPairs
(
modeId
:
string
):
IAutoClosingPairConditional
[]
{
let
characterPairSupport
=
this
.
_getCharacterPairSupport
(
modeId
);
if
(
!
characterPairSupport
)
{
return
[];
}
return
characterPairSupport
.
getAutoClosingPairs
();
}
public
getSurroundingPairs
(
modeId
:
string
):
IAutoClosingPair
[]
{
let
characterPairSupport
=
this
.
_getCharacterPairSupport
(
modeId
);
if
(
!
characterPairSupport
)
{
return
[];
}
return
characterPairSupport
.
getSurroundingPairs
();
}
public
shouldAutoClosePair
(
character
:
string
,
context
:
LineTokens
,
offset
:
number
):
boolean
{
let
scopedLineTokens
=
createScopedLineTokens
(
context
,
offset
);
let
characterPairSupport
=
this
.
_getCharacterPairSupport
(
scopedLineTokens
.
modeId
);
if
(
!
characterPairSupport
)
{
return
false
;
}
return
characterPairSupport
.
shouldAutoClosePair
(
character
,
scopedLineTokens
,
offset
-
scopedLineTokens
.
firstCharOffset
);
}
// end characterPair
public
getWordDefinition
(
modeId
:
string
):
RegExp
{
let
value
=
this
.
_getRichEditSupport
(
modeId
);
if
(
!
value
)
{
return
null
;
return
ensureValidWordDefinition
(
null
)
;
}
return
value
.
wordDefinition
||
null
;
return
ensureValidWordDefinition
(
value
.
wordDefinition
||
null
)
;
}
public
getOnEnterSupport
(
modeId
:
string
):
IRichEditOnEnter
{
// begin onEnter
private
_getOnEnterSupport
(
modeId
:
string
):
OnEnterSupport
{
let
value
=
this
.
_getRichEditSupport
(
modeId
);
if
(
!
value
)
{
return
null
;
...
...
@@ -239,18 +295,35 @@ export class LanguageConfigurationRegistryImpl {
}
public
getRawEnterActionAtPosition
(
model
:
ITokenizedModel
,
lineNumber
:
number
,
column
:
number
):
EnterAction
{
let
result
:
EnterAction
;
let
onEnterSupport
=
this
.
getOnEnterSupport
(
model
.
getMode
().
getId
());
let
lineTokens
=
model
.
getLineTokens
(
lineNumber
,
false
);
let
scopedLineTokens
=
createScopedLineTokens
(
lineTokens
,
column
-
1
);
let
onEnterSupport
=
this
.
_getOnEnterSupport
(
scopedLineTokens
.
modeId
);
if
(
!
onEnterSupport
)
{
return
null
;
}
if
(
onEnterSupport
)
{
try
{
result
=
onEnterSupport
.
onEnter
(
model
,
new
Position
(
lineNumber
,
column
));
}
catch
(
e
)
{
onUnexpectedError
(
e
);
let
scopedLineText
=
scopedLineTokens
.
getLineContent
();
let
beforeEnterText
=
scopedLineText
.
substr
(
0
,
column
-
1
-
scopedLineTokens
.
firstCharOffset
);
let
afterEnterText
=
scopedLineText
.
substr
(
column
-
1
-
scopedLineTokens
.
firstCharOffset
);
let
oneLineAboveText
=
''
;
if
(
lineNumber
>
1
&&
scopedLineTokens
.
firstCharOffset
===
0
)
{
// This is not the first line and the entire line belongs to this mode
let
oneLineAboveLineTokens
=
model
.
getLineTokens
(
lineNumber
-
1
,
false
);
let
oneLineAboveMaxColumn
=
model
.
getLineMaxColumn
(
lineNumber
-
1
);
let
oneLineAboveScopedLineTokens
=
createScopedLineTokens
(
oneLineAboveLineTokens
,
oneLineAboveMaxColumn
-
1
);
if
(
oneLineAboveScopedLineTokens
.
modeId
===
scopedLineTokens
.
modeId
)
{
// The line above ends with text belonging to the same mode
oneLineAboveText
=
oneLineAboveScopedLineTokens
.
getLineContent
();
}
}
let
result
:
EnterAction
=
null
;
try
{
result
=
onEnterSupport
.
onEnter
(
oneLineAboveText
,
beforeEnterText
,
afterEnterText
);
}
catch
(
e
)
{
onUnexpectedError
(
e
);
}
return
result
;
}
...
...
@@ -290,6 +363,8 @@ export class LanguageConfigurationRegistryImpl {
};
}
// end onEnter
public
getBracketsSupport
(
modeId
:
string
):
IRichEditBrackets
{
let
value
=
this
.
_getRichEditSupport
(
modeId
);
if
(
!
value
)
{
...
...
src/vs/editor/common/modes/supports.ts
浏览文件 @
7f438ed3
...
...
@@ -8,6 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
ModeTransition
}
from
'
vs/editor/common/core/modeTransition
'
;
import
{
Token
}
from
'
vs/editor/common/core/token
'
;
import
{
LineTokens
}
from
'
vs/editor/common/core/lineTokens
'
;
export
class
RawLineTokens
implements
modes
.
ILineTokens
{
_lineTokensBrand
:
void
;
...
...
@@ -27,73 +28,76 @@ export class RawLineTokens implements modes.ILineTokens {
}
}
export
function
handleEvent
<
T
>
(
context
:
modes
.
ILineContext
,
offset
:
number
,
runner
:
(
modeId
:
string
,
newContext
:
modes
.
ILineContext
,
offset
:
number
)
=>
T
):
T
{
export
function
createScopedLineTokens
(
context
:
LineTokens
,
offset
:
number
):
ScopedLineTokens
{
let
modeTransitions
=
context
.
modeTransitions
;
if
(
modeTransitions
.
length
===
1
)
{
return
runner
(
modeTransitions
[
0
].
modeId
,
context
,
offset
);
return
new
ScopedLineTokens
(
context
,
modeTransitions
[
0
].
modeId
,
0
,
context
.
getTokenCount
(),
0
,
context
.
getLineContent
().
length
);
}
let
modeIndex
=
ModeTransition
.
findIndexInSegmentsArray
(
modeTransitions
,
offset
);
let
nestedModeId
=
modeTransitions
[
modeIndex
].
modeId
;
let
modeStartIndex
=
modeTransitions
[
modeIndex
].
startIndex
;
let
firstTokenIn
ModeIndex
=
context
.
findIndexOf
Offset
(
modeStartIndex
);
let
nextCharacterAfterModeIndex
=
-
1
;
let
nextTokenAfterMode
=
-
1
;
let
firstTokenIn
dex
=
context
.
findTokenIndexAt
Offset
(
modeStartIndex
);
let
lastCharOffset
=
-
1
;
let
lastTokenIndex
=
-
1
;
if
(
modeIndex
+
1
<
modeTransitions
.
length
)
{
nextTokenAfterMode
=
context
.
findIndexOf
Offset
(
modeTransitions
[
modeIndex
+
1
].
startIndex
);
nextCharacterAfterModeIndex
=
context
.
getTokenStartOffset
(
nextTokenAfterMode
);
lastTokenIndex
=
context
.
findTokenIndexAt
Offset
(
modeTransitions
[
modeIndex
+
1
].
startIndex
);
lastCharOffset
=
context
.
getTokenStartOffset
(
lastTokenIndex
);
}
else
{
nextTokenAfterMode
=
context
.
getTokenCount
();
nextCharacterAfterModeIndex
=
context
.
getLineContent
().
length
;
lastTokenIndex
=
context
.
getTokenCount
();
lastCharOffset
=
context
.
getLineContent
().
length
;
}
let
firstTokenCharacterOffset
=
context
.
getTokenStartOffset
(
firstTokenInModeIndex
);
let
newCtx
=
new
FilteredLineContext
(
context
,
nestedModeId
,
firstTokenInModeIndex
,
nextTokenAfterMode
,
firstTokenCharacterOffset
,
nextCharacterAfterModeIndex
);
return
runner
(
nestedModeId
,
newCtx
,
offset
-
firstTokenCharacterOffset
);
let
firstCharOffset
=
context
.
getTokenStartOffset
(
firstTokenIndex
);
return
new
ScopedLineTokens
(
context
,
nestedModeId
,
firstTokenIndex
,
lastTokenIndex
,
firstCharOffset
,
lastCharOffset
);
}
export
class
FilteredLineContext
implements
modes
.
ILineContext
{
public
modeTransitions
:
ModeTransition
[];
private
_actual
:
modes
.
ILineContext
;
private
_firstTokenInModeIndex
:
number
;
private
_nextTokenAfterMode
:
number
;
private
_firstTokenCharacterOffset
:
number
;
private
_nextCharacterAfterModeIndex
:
number
;
constructor
(
actual
:
modes
.
ILineContext
,
modeId
:
string
,
firstTokenInModeIndex
:
number
,
nextTokenAfterMode
:
number
,
firstTokenCharacterOffset
:
number
,
nextCharacterAfterModeIndex
:
number
)
{
this
.
modeTransitions
=
[
new
ModeTransition
(
0
,
modeId
)];
export
class
ScopedLineTokens
{
_scopedLineTokensBrand
:
void
;
public
readonly
modeId
:
string
;
private
readonly
_actual
:
LineTokens
;
private
readonly
_firstTokenIndex
:
number
;
private
readonly
_lastTokenIndex
:
number
;
public
readonly
firstCharOffset
:
number
;
private
readonly
_lastCharOffset
:
number
;
constructor
(
actual
:
LineTokens
,
modeId
:
string
,
firstTokenIndex
:
number
,
lastTokenIndex
:
number
,
firstCharOffset
:
number
,
lastCharOffset
:
number
)
{
this
.
_actual
=
actual
;
this
.
_firstTokenInModeIndex
=
firstTokenInModeIndex
;
this
.
_nextTokenAfterMode
=
nextTokenAfterMode
;
this
.
_firstTokenCharacterOffset
=
firstTokenCharacterOffset
;
this
.
_nextCharacterAfterModeIndex
=
nextCharacterAfterModeIndex
;
this
.
modeId
=
modeId
;
this
.
_firstTokenIndex
=
firstTokenIndex
;
this
.
_lastTokenIndex
=
lastTokenIndex
;
this
.
firstCharOffset
=
firstCharOffset
;
this
.
_lastCharOffset
=
lastCharOffset
;
}
public
getLineContent
():
string
{
var
actualLineContent
=
this
.
_actual
.
getLineContent
();
return
actualLineContent
.
substring
(
this
.
_firstTokenCharacterOffset
,
this
.
_nextCharacterAfterModeIndex
);
return
actualLineContent
.
substring
(
this
.
firstCharOffset
,
this
.
_lastCharOffset
);
}
public
getTokenCount
():
number
{
return
this
.
_
nextTokenAfterMode
-
this
.
_firstTokenInMode
Index
;
return
this
.
_
lastTokenIndex
-
this
.
_firstToken
Index
;
}
public
find
IndexOf
Offset
(
offset
:
number
):
number
{
return
this
.
_actual
.
find
IndexOfOffset
(
offset
+
this
.
_firstTokenCharacterOffset
)
-
this
.
_firstTokenInMode
Index
;
public
find
TokenIndexAt
Offset
(
offset
:
number
):
number
{
return
this
.
_actual
.
find
TokenIndexAtOffset
(
offset
+
this
.
firstCharOffset
)
-
this
.
_firstToken
Index
;
}
public
getTokenStartOffset
(
tokenIndex
:
number
):
number
{
return
this
.
_actual
.
getTokenStartOffset
(
tokenIndex
+
this
.
_firstTokenIn
ModeIndex
)
-
this
.
_firstTokenCharacte
rOffset
;
return
this
.
_actual
.
getTokenStartOffset
(
tokenIndex
+
this
.
_firstTokenIn
dex
)
-
this
.
firstCha
rOffset
;
}
public
getTokenType
(
tokenIndex
:
number
):
string
{
return
this
.
_actual
.
getTokenType
(
tokenIndex
+
this
.
_firstTokenIn
ModeIn
dex
);
return
this
.
_actual
.
getTokenType
(
tokenIndex
+
this
.
_firstTokenIndex
);
}
}
...
...
src/vs/editor/common/modes/supports/characterPair.ts
浏览文件 @
7f438ed3
...
...
@@ -4,20 +4,15 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
IAutoClosingPair
,
IAutoClosingPairConditional
,
ILineContext
,
IRichEditCharacterPair
,
CharacterPair
}
from
'
vs/editor/common/modes
'
;
import
{
handleEvent
}
from
'
vs/editor/common/modes/supports
'
;
import
{
LanguageConfigurationRegistryImpl
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
import
{
IAutoClosingPair
,
IAutoClosingPairConditional
,
CharacterPair
}
from
'
vs/editor/common/modes
'
;
import
{
ScopedLineTokens
}
from
'
vs/editor/common/modes/supports
'
;
export
class
CharacterPairSupport
implements
IRichEditCharacterPair
{
export
class
CharacterPairSupport
{
private
_registry
:
LanguageConfigurationRegistryImpl
;
private
_modeId
:
string
;
private
_autoClosingPairs
:
IAutoClosingPairConditional
[];
private
_surroundingPairs
:
IAutoClosingPair
[];
private
readonly
_autoClosingPairs
:
IAutoClosingPairConditional
[];
private
readonly
_surroundingPairs
:
IAutoClosingPair
[];
constructor
(
registry
:
LanguageConfigurationRegistryImpl
,
modeId
:
string
,
config
:
{
brackets
?:
CharacterPair
[];
autoClosingPairs
?:
IAutoClosingPairConditional
[],
surroundingPairs
?:
IAutoClosingPair
[]
})
{
this
.
_registry
=
registry
;
this
.
_modeId
=
modeId
;
constructor
(
config
:
{
brackets
?:
CharacterPair
[];
autoClosingPairs
?:
IAutoClosingPairConditional
[],
surroundingPairs
?:
IAutoClosingPair
[]
})
{
this
.
_autoClosingPairs
=
config
.
autoClosingPairs
;
if
(
!
this
.
_autoClosingPairs
)
{
this
.
_autoClosingPairs
=
config
.
brackets
?
config
.
brackets
.
map
(
b
=>
({
open
:
b
[
0
],
close
:
b
[
1
]
}))
:
[];
...
...
@@ -29,41 +24,29 @@ export class CharacterPairSupport implements IRichEditCharacterPair {
return
this
.
_autoClosingPairs
;
}
public
shouldAutoClosePair
(
character
:
string
,
context
:
ILineContext
,
offset
:
number
):
boolean
{
return
handleEvent
(
context
,
offset
,
(
nestedModeId
:
string
,
context
:
ILineContext
,
offset
:
number
)
=>
{
if
(
this
.
_modeId
===
nestedModeId
)
{
// Always complete on empty line
if
(
context
.
getTokenCount
()
===
0
)
{
return
true
;
}
public
shouldAutoClosePair
(
character
:
string
,
context
:
ScopedLineTokens
,
offset
:
number
):
boolean
{
// Always complete on empty line
if
(
context
.
getTokenCount
()
===
0
)
{
return
true
;
}
var
tokenIndex
=
context
.
findIndexOf
Offset
(
offset
-
1
);
var
tokenType
=
context
.
getTokenType
(
tokenIndex
);
var
tokenIndex
=
context
.
findTokenIndexAt
Offset
(
offset
-
1
);
var
tokenType
=
context
.
getTokenType
(
tokenIndex
);
for
(
var
i
=
0
;
i
<
this
.
_autoClosingPairs
.
length
;
++
i
)
{
if
(
this
.
_autoClosingPairs
[
i
].
open
===
character
)
{
if
(
this
.
_autoClosingPairs
[
i
].
notIn
)
{
for
(
var
notInIndex
=
0
;
notInIndex
<
this
.
_autoClosingPairs
[
i
].
notIn
.
length
;
++
notInIndex
)
{
if
(
tokenType
.
indexOf
(
this
.
_autoClosingPairs
[
i
].
notIn
[
notInIndex
])
>
-
1
)
{
return
false
;
}
}
for
(
var
i
=
0
;
i
<
this
.
_autoClosingPairs
.
length
;
++
i
)
{
if
(
this
.
_autoClosingPairs
[
i
].
open
===
character
)
{
if
(
this
.
_autoClosingPairs
[
i
].
notIn
)
{
for
(
var
notInIndex
=
0
;
notInIndex
<
this
.
_autoClosingPairs
[
i
].
notIn
.
length
;
++
notInIndex
)
{
if
(
tokenType
.
indexOf
(
this
.
_autoClosingPairs
[
i
].
notIn
[
notInIndex
])
>
-
1
)
{
return
false
;
}
break
;
}
}
return
true
;
}
let
characterPairSupport
=
this
.
_registry
.
getCharacterPairSupport
(
nestedModeId
);
if
(
characterPairSupport
)
{
return
characterPairSupport
.
shouldAutoClosePair
(
character
,
context
,
offset
);
break
;
}
}
return
null
;
});
return
true
;
}
public
getSurroundingPairs
():
IAutoClosingPair
[]
{
...
...
src/vs/editor/common/modes/supports/electricCharacter.ts
浏览文件 @
7f438ed3
...
...
@@ -6,9 +6,8 @@
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
handleEvent
,
ignoreBracketsInToken
}
from
'
vs/editor/common/modes/supports
'
;
import
{
ScopedLineTokens
,
ignoreBracketsInToken
}
from
'
vs/editor/common/modes/supports
'
;
import
{
BracketsUtils
}
from
'
vs/editor/common/modes/supports/richEditBrackets
'
;
import
{
LanguageConfigurationRegistryImpl
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
/**
* Definition of documentation comments (e.g. Javadoc/JSdoc)
...
...
@@ -25,18 +24,14 @@ export interface IBracketElectricCharacterContribution {
embeddedElectricCharacters
?:
string
[];
}
export
class
BracketElectricCharacterSupport
implements
modes
.
IRichEditElectricCharacter
{
export
class
BracketElectricCharacterSupport
{
private
_registry
:
LanguageConfigurationRegistryImpl
;
private
_modeId
:
string
;
private
contribution
:
IBracketElectricCharacterContribution
;
private
brackets
:
Brackets
;
private
readonly
contribution
:
IBracketElectricCharacterContribution
;
private
readonly
brackets
:
Brackets
;
constructor
(
registry
:
LanguageConfigurationRegistryImpl
,
modeId
:
string
,
brackets
:
modes
.
IRichEditBrackets
,
autoClosePairs
:
modes
.
IAutoClosingPairConditional
[],
contribution
:
IBracketElectricCharacterContribution
)
{
this
.
_registry
=
registry
;
this
.
_modeId
=
modeId
;
constructor
(
brackets
:
modes
.
IRichEditBrackets
,
autoClosePairs
:
modes
.
IAutoClosingPairConditional
[],
contribution
:
IBracketElectricCharacterContribution
)
{
this
.
contribution
=
contribution
||
{};
this
.
brackets
=
new
Brackets
(
modeId
,
brackets
,
autoClosePairs
,
this
.
contribution
.
docComment
);
this
.
brackets
=
new
Brackets
(
brackets
,
autoClosePairs
,
this
.
contribution
.
docComment
);
}
public
getElectricCharacters
():
string
[]
{
...
...
@@ -46,30 +41,17 @@ export class BracketElectricCharacterSupport implements modes.IRichEditElectricC
return
this
.
brackets
.
getElectricCharacters
();
}
public
onElectricCharacter
(
context
:
modes
.
ILineContext
,
offset
:
number
):
modes
.
IElectricAction
{
return
handleEvent
(
context
,
offset
,
(
nestedModeId
:
string
,
context
:
modes
.
ILineContext
,
offset
:
number
)
=>
{
if
(
this
.
_modeId
===
nestedModeId
)
{
return
this
.
brackets
.
onElectricCharacter
(
context
,
offset
);
}
let
electricCharacterSupport
=
this
.
_registry
.
getElectricCharacterSupport
(
nestedModeId
);
if
(
electricCharacterSupport
)
{
return
electricCharacterSupport
.
onElectricCharacter
(
context
,
offset
);
}
return
null
;
});
public
onElectricCharacter
(
context
:
ScopedLineTokens
,
offset
:
number
):
modes
.
IElectricAction
{
return
this
.
brackets
.
onElectricCharacter
(
context
,
offset
);
}
}
export
class
Brackets
{
private
_modeId
:
string
;
private
_richEditBrackets
:
modes
.
IRichEditBrackets
;
private
_complexAutoClosePairs
:
modes
.
IAutoClosingPairConditional
[];
private
readonly
_richEditBrackets
:
modes
.
IRichEditBrackets
;
private
readonly
_complexAutoClosePairs
:
modes
.
IAutoClosingPairConditional
[];
constructor
(
modeId
:
string
,
richEditBrackets
:
modes
.
IRichEditBrackets
,
autoClosePairs
:
modes
.
IAutoClosingPairConditional
[],
docComment
?:
IDocComment
)
{
this
.
_modeId
=
modeId
;
constructor
(
richEditBrackets
:
modes
.
IRichEditBrackets
,
autoClosePairs
:
modes
.
IAutoClosingPairConditional
[],
docComment
?:
IDocComment
)
{
this
.
_richEditBrackets
=
richEditBrackets
;
this
.
_complexAutoClosePairs
=
autoClosePairs
.
filter
(
pair
=>
pair
.
open
.
length
>
1
&&
!!
pair
.
close
);
if
(
docComment
)
{
...
...
@@ -102,7 +84,7 @@ export class Brackets {
return
result
;
}
public
onElectricCharacter
(
context
:
modes
.
ILineContext
,
offset
:
number
):
modes
.
IElectricAction
{
public
onElectricCharacter
(
context
:
ScopedLineTokens
,
offset
:
number
):
modes
.
IElectricAction
{
if
(
context
.
getTokenCount
()
===
0
)
{
return
null
;
}
...
...
@@ -121,7 +103,7 @@ export class Brackets {
return
true
;
}
private
_onElectricAutoIndent
(
context
:
modes
.
ILineContext
,
offset
:
number
):
modes
.
IElectricAction
{
private
_onElectricAutoIndent
(
context
:
ScopedLineTokens
,
offset
:
number
):
modes
.
IElectricAction
{
if
(
!
this
.
_richEditBrackets
||
this
.
_richEditBrackets
.
brackets
.
length
===
0
)
{
return
null
;
...
...
@@ -130,7 +112,7 @@ export class Brackets {
let
reversedBracketRegex
=
this
.
_richEditBrackets
.
reversedRegex
;
let
lineText
=
context
.
getLineContent
();
let
tokenIndex
=
context
.
find
IndexOf
Offset
(
offset
);
let
tokenIndex
=
context
.
find
TokenIndexAt
Offset
(
offset
);
let
tokenStart
=
context
.
getTokenStartOffset
(
tokenIndex
);
let
tokenEnd
=
offset
+
1
;
...
...
@@ -157,7 +139,7 @@ export class Brackets {
return
null
;
}
private
_onElectricAutoClose
(
context
:
modes
.
ILineContext
,
offset
:
number
):
modes
.
IElectricAction
{
private
_onElectricAutoClose
(
context
:
ScopedLineTokens
,
offset
:
number
):
modes
.
IElectricAction
{
if
(
!
this
.
_complexAutoClosePairs
.
length
)
{
return
null
;
...
...
@@ -180,7 +162,7 @@ export class Brackets {
}
// check if the full open bracket matches
let
lastTokenIndex
=
context
.
find
IndexOf
Offset
(
offset
);
let
lastTokenIndex
=
context
.
find
TokenIndexAt
Offset
(
offset
);
if
(
line
.
substring
(
context
.
getTokenStartOffset
(
lastTokenIndex
),
offset
+
1
/* include electric char*/
)
!==
pair
.
open
)
{
continue
;
}
...
...
src/vs/editor/common/modes/supports/onEnter.ts
浏览文件 @
7f438ed3
...
...
@@ -6,10 +6,7 @@
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
IPosition
,
ITextModel
,
ITokenizedModel
}
from
'
vs/editor/common/editorCommon
'
;
import
{
EnterAction
,
ILineContext
,
IRichEditOnEnter
,
IndentAction
,
CharacterPair
}
from
'
vs/editor/common/modes
'
;
import
{
handleEvent
}
from
'
vs/editor/common/modes/supports
'
;
import
{
LanguageConfigurationRegistryImpl
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
import
{
EnterAction
,
IndentAction
,
CharacterPair
}
from
'
vs/editor/common/modes
'
;
/**
* Describes indentation rules for a language.
...
...
@@ -64,20 +61,17 @@ interface IProcessedBracketPair {
closeRegExp
:
RegExp
;
}
export
class
OnEnterSupport
implements
IRichEditOnEnter
{
export
class
OnEnterSupport
{
private
static
_INDENT
:
EnterAction
=
{
indentAction
:
IndentAction
.
Indent
};
private
static
_INDENT_OUTDENT
:
EnterAction
=
{
indentAction
:
IndentAction
.
IndentOutdent
};
private
static
_OUTDENT
:
EnterAction
=
{
indentAction
:
IndentAction
.
Outdent
};
private
_registry
:
LanguageConfigurationRegistryImpl
;
private
_modeId
:
string
;
private
_brackets
:
IProcessedBracketPair
[];
private
_indentationRules
:
IndentationRule
;
private
_regExpRules
:
OnEnterRule
[];
private
readonly
_brackets
:
IProcessedBracketPair
[];
private
readonly
_indentationRules
:
IndentationRule
;
private
readonly
_regExpRules
:
OnEnterRule
[];
constructor
(
registry
:
LanguageConfigurationRegistryImpl
,
modeId
:
string
,
opts
?:
IOnEnterSupportOptions
)
{
this
.
_registry
=
registry
;
constructor
(
opts
?:
IOnEnterSupportOptions
)
{
opts
=
opts
||
{};
opts
.
brackets
=
opts
.
brackets
||
[
[
'
(
'
,
'
)
'
],
...
...
@@ -85,7 +79,6 @@ export class OnEnterSupport implements IRichEditOnEnter {
[
'
[
'
,
'
]
'
]
];
this
.
_modeId
=
modeId
;
this
.
_brackets
=
opts
.
brackets
.
map
((
bracket
)
=>
{
return
{
open
:
bracket
[
0
],
...
...
@@ -98,34 +91,7 @@ export class OnEnterSupport implements IRichEditOnEnter {
this
.
_indentationRules
=
opts
.
indentationRules
;
}
public
onEnter
(
model
:
ITokenizedModel
,
position
:
IPosition
):
EnterAction
{
var
context
=
model
.
getLineContext
(
position
.
lineNumber
);
return
handleEvent
(
context
,
position
.
column
-
1
,
(
nestedModeId
:
string
,
context
:
ILineContext
,
offset
:
number
)
=>
{
if
(
this
.
_modeId
===
nestedModeId
)
{
return
this
.
_onEnter
(
model
,
position
);
}
let
onEnterSupport
=
this
.
_registry
.
getOnEnterSupport
(
nestedModeId
);
if
(
onEnterSupport
)
{
return
onEnterSupport
.
onEnter
(
model
,
position
);
}
return
null
;
});
}
private
_onEnter
(
model
:
ITextModel
,
position
:
IPosition
):
EnterAction
{
let
lineText
=
model
.
getLineContent
(
position
.
lineNumber
);
let
beforeEnterText
=
lineText
.
substr
(
0
,
position
.
column
-
1
);
let
afterEnterText
=
lineText
.
substr
(
position
.
column
-
1
);
let
oneLineAboveText
=
position
.
lineNumber
===
1
?
''
:
model
.
getLineContent
(
position
.
lineNumber
-
1
);
return
this
.
_actualOnEnter
(
oneLineAboveText
,
beforeEnterText
,
afterEnterText
);
}
_actualOnEnter
(
oneLineAboveText
:
string
,
beforeEnterText
:
string
,
afterEnterText
:
string
):
EnterAction
{
public
onEnter
(
oneLineAboveText
:
string
,
beforeEnterText
:
string
,
afterEnterText
:
string
):
EnterAction
{
// (1): `regExpRules`
for
(
let
i
=
0
,
len
=
this
.
_regExpRules
.
length
;
i
<
len
;
i
++
)
{
let
rule
=
this
.
_regExpRules
[
i
];
...
...
src/vs/editor/common/services/editorWorkerServiceImpl.ts
浏览文件 @
7f438ed3
...
...
@@ -11,11 +11,11 @@ import { TPromise } from 'vs/base/common/winjs.base';
import
{
SimpleWorkerClient
,
logOnceWebWorkerWarning
}
from
'
vs/base/common/worker/simpleWorker
'
;
import
{
DefaultWorkerFactory
}
from
'
vs/base/worker/defaultWorkerFactory
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
import
{
WordHelper
}
from
'
vs/editor/common/model/textModelWithTokensHelpers
'
;
import
{
IInplaceReplaceSupportResult
,
ILink
,
ISuggestResult
,
LinkProviderRegistry
,
LinkProvider
}
from
'
vs/editor/common/modes
'
;
import
{
IEditorWorkerService
}
from
'
vs/editor/common/services/editorWorkerService
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
EditorSimpleWorkerImpl
}
from
'
vs/editor/common/services/editorSimpleWorker
'
;
import
{
LanguageConfigurationRegistry
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
/**
* Stop syncing a model to the worker if it was not needed for 1 min.
...
...
@@ -321,7 +321,7 @@ export class EditorWorkerClient extends Disposable {
if
(
!
model
)
{
return
null
;
}
let
wordDefRegExp
=
WordHelper
.
massageWordDefinitionOf
(
model
.
getModeId
());
let
wordDefRegExp
=
LanguageConfigurationRegistry
.
getWordDefinition
(
model
.
getModeId
());
let
wordDef
=
wordDefRegExp
.
source
;
let
wordDefFlags
=
(
wordDefRegExp
.
global
?
'
g
'
:
''
)
+
(
wordDefRegExp
.
ignoreCase
?
'
i
'
:
''
)
+
(
wordDefRegExp
.
multiline
?
'
m
'
:
''
);
return
proxy
.
textualSuggest
(
resource
.
toString
(),
position
,
wordDef
,
wordDefFlags
);
...
...
@@ -334,7 +334,7 @@ export class EditorWorkerClient extends Disposable {
if
(
!
model
)
{
return
null
;
}
let
wordDefRegExp
=
WordHelper
.
massageWordDefinitionOf
(
model
.
getModeId
());
let
wordDefRegExp
=
LanguageConfigurationRegistry
.
getWordDefinition
(
model
.
getModeId
());
let
wordDef
=
wordDefRegExp
.
source
;
let
wordDefFlags
=
(
wordDefRegExp
.
global
?
'
g
'
:
''
)
+
(
wordDefRegExp
.
ignoreCase
?
'
i
'
:
''
)
+
(
wordDefRegExp
.
multiline
?
'
m
'
:
''
);
return
proxy
.
navigateValueSet
(
resource
.
toString
(),
range
,
up
,
wordDef
,
wordDefFlags
);
...
...
src/vs/editor/test/common/controller/cursor.test.ts
浏览文件 @
7f438ed3
...
...
@@ -17,7 +17,7 @@ import {
ICursorPositionChangedEvent
,
ICursorSelectionChangedEvent
}
from
'
vs/editor/common/editorCommon
'
;
import
{
Model
}
from
'
vs/editor/common/model/model
'
;
import
{
I
Mode
,
I
ndentAction
}
from
'
vs/editor/common/modes
'
;
import
{
IndentAction
}
from
'
vs/editor/common/modes
'
;
import
{
LanguageConfigurationRegistry
}
from
'
vs/editor/common/modes/languageConfigurationRegistry
'
;
import
{
MockConfiguration
}
from
'
vs/editor/test/common/mocks/mockConfiguration
'
;
import
{
MockMode
}
from
'
vs/editor/test/common/mocks/mockMode
'
;
...
...
@@ -1148,7 +1148,7 @@ suite('Editor Controller - Regression tests', () => {
modeId
:
new
BracketMode
().
getId
()
},
(
model
,
cursor
)
=>
{
// ensure is tokenized
model
.
getLine
Context
(
1
);
model
.
getLine
Tokens
(
1
,
false
);
moveTo
(
cursor
,
1
,
20
);
...
...
src/vs/editor/test/common/modes/autoIndentation.test.ts
浏览文件 @
7f438ed3
...
...
@@ -6,16 +6,43 @@
import
*
as
assert
from
'
assert
'
;
import
{
Brackets
}
from
'
vs/editor/common/modes/supports/electricCharacter
'
;
import
{
createLineContextFromTokenText
}
from
'
vs/editor/test/common/modesTestUtils
'
;
import
{
createFakeLineTokens
}
from
'
vs/editor/test/common/modesTestUtils
'
;
import
{
LineTokens
}
from
'
vs/editor/common/core/lineTokens
'
;
import
{
Token
}
from
'
vs/editor/common/core/token
'
;
import
{
ModeTransition
}
from
'
vs/editor/common/core/modeTransition
'
;
import
{
createScopedLineTokens
,
ScopedLineTokens
}
from
'
vs/editor/common/modes/supports
'
;
interface
TokenText
{
text
:
string
;
type
:
string
;
}
function
createLineContextFromTokenText
(
modeId
:
string
,
tokens
:
TokenText
[]):
LineTokens
{
let
line
=
''
;
let
processedTokens
:
Token
[]
=
[];
let
indexSoFar
=
0
;
for
(
let
i
=
0
;
i
<
tokens
.
length
;
++
i
)
{
processedTokens
.
push
(
new
Token
(
indexSoFar
,
tokens
[
i
].
type
));
line
+=
tokens
[
i
].
text
;
indexSoFar
+=
tokens
[
i
].
text
.
length
;
}
return
createFakeLineTokens
(
line
,
modeId
,
processedTokens
,
[
new
ModeTransition
(
0
,
modeId
)]);
}
function
createScopedLineTokensFromTokenText
(
modeId
:
string
,
tokens
:
TokenText
[]):
ScopedLineTokens
{
return
createScopedLineTokens
(
createLineContextFromTokenText
(
modeId
,
tokens
),
0
);
}
suite
(
'
Editor Modes - Auto Indentation
'
,
()
=>
{
test
(
'
Doc comments
'
,
()
=>
{
var
brackets
=
new
Brackets
(
'
test
'
,
null
,
[{
open
:
'
/**
'
,
close
:
'
*/
'
}]);
var
brackets
=
new
Brackets
(
null
,
[{
open
:
'
/**
'
,
close
:
'
*/
'
}]);
assert
.
equal
(
brackets
.
onElectricCharacter
(
create
LineContextFromTokenText
(
[
assert
.
equal
(
brackets
.
onElectricCharacter
(
create
ScopedLineTokensFromTokenText
(
'
test
'
,
[
{
text
:
'
/**
'
,
type
:
'
doc
'
},
]),
2
).
appendText
,
'
*/
'
);
assert
.
equal
(
brackets
.
onElectricCharacter
(
create
LineContextFromTokenText
(
[
assert
.
equal
(
brackets
.
onElectricCharacter
(
create
ScopedLineTokensFromTokenText
(
'
test
'
,
[
{
text
:
'
/**
'
,
type
:
'
doc
'
},
{
text
:
'
'
,
type
:
'
doc
'
},
{
text
:
'
*/
'
,
type
:
'
doc
'
},
...
...
src/vs/editor/test/common/modes/supports/onEnter.test.ts
浏览文件 @
7f438ed3
...
...
@@ -11,7 +11,7 @@ import { OnEnterSupport } from 'vs/editor/common/modes/supports/onEnter';
suite
(
'
OnEnter
'
,
()
=>
{
test
(
'
uses indentationRules
'
,
()
=>
{
var
support
=
new
OnEnterSupport
(
null
,
null
,
{
var
support
=
new
OnEnterSupport
({
indentationRules
:
{
decreaseIndentPattern
:
/^
\s
*
((?!\S
.*
\/[
*
])
.*
[
*
]\/\s
*
)?[
})
\]]
|^
\s
*
(
case
\b
.*|default
)
:
\s
*
(\/\/
.*|
\/[
*
]
.*
[
*
]\/\s
*
)?
$/
,
increaseIndentPattern
:
/
(\{[^
}"'
]
*|
\([^
)"'
]
*|
\[[^\]
"'
]
*|^
\s
*
(\{\}
|
\(\)
|
\[\]
|
(
case
\b
.*|default
)
:
))\s
*
(\/\/
.*|
\/[
*
]
.*
[
*
]\/\s
*
)?
$/
,
...
...
@@ -21,7 +21,7 @@ suite('OnEnter', () => {
});
var
testIndentAction
=
(
oneLineAboveText
:
string
,
beforeText
:
string
,
afterText
:
string
,
expected
:
IndentAction
)
=>
{
var
actual
=
support
.
_actualO
nEnter
(
oneLineAboveText
,
beforeText
,
afterText
);
var
actual
=
support
.
o
nEnter
(
oneLineAboveText
,
beforeText
,
afterText
);
if
(
expected
===
IndentAction
.
None
)
{
assert
.
equal
(
actual
,
null
);
}
else
{
...
...
@@ -42,11 +42,11 @@ suite('OnEnter', () => {
[
'
(
'
,
'
)
'
],
[
'
begin
'
,
'
end
'
]
];
var
support
=
new
OnEnterSupport
(
null
,
null
,
{
var
support
=
new
OnEnterSupport
({
brackets
:
brackets
});
var
testIndentAction
=
(
beforeText
:
string
,
afterText
:
string
,
expected
:
IndentAction
)
=>
{
var
actual
=
support
.
_actualO
nEnter
(
''
,
beforeText
,
afterText
);
var
actual
=
support
.
o
nEnter
(
''
,
beforeText
,
afterText
);
if
(
expected
===
IndentAction
.
None
)
{
assert
.
equal
(
actual
,
null
);
}
else
{
...
...
@@ -75,7 +75,7 @@ suite('OnEnter', () => {
});
test
(
'
uses regExpRules
'
,
()
=>
{
var
support
=
new
OnEnterSupport
(
null
,
null
,
{
var
support
=
new
OnEnterSupport
({
regExpRules
:
[
{
beforeText
:
/^
\s
*
\/\*\*(?!\/)([^\*]
|
\*(?!\/))
*$/
,
...
...
@@ -101,7 +101,7 @@ suite('OnEnter', () => {
]
});
var
testIndentAction
=
(
beforeText
:
string
,
afterText
:
string
,
expectedIndentAction
:
IndentAction
,
expectedAppendText
:
string
,
removeText
:
number
=
0
)
=>
{
var
actual
=
support
.
_actualO
nEnter
(
''
,
beforeText
,
afterText
);
var
actual
=
support
.
o
nEnter
(
''
,
beforeText
,
afterText
);
if
(
expectedIndentAction
===
null
)
{
assert
.
equal
(
actual
,
null
,
'
isNull:
'
+
beforeText
);
}
else
{
...
...
src/vs/editor/test/common/modes/tokenization.test.ts
浏览文件 @
7f438ed3
...
...
@@ -7,9 +7,9 @@
import
*
as
assert
from
'
assert
'
;
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
AbstractState
,
ITokenizationResult
}
from
'
vs/editor/common/modes/abstractState
'
;
import
{
handleEvent
}
from
'
vs/editor/common/modes/supports
'
;
import
{
createScopedLineTokens
}
from
'
vs/editor/common/modes/supports
'
;
import
{
IModeLocator
,
ILeavingNestedModeData
,
TokenizationSupport
}
from
'
vs/editor/common/modes/supports/tokenizationSupport
'
;
import
{
create
MockLineContext
}
from
'
vs/editor/test/common/modesTestUtils
'
;
import
{
create
FakeLineTokens
}
from
'
vs/editor/test/common/modesTestUtils
'
;
import
{
MockMode
}
from
'
vs/editor/test/common/mocks/mockMode
'
;
import
{
ModeTransition
}
from
'
vs/editor/common/core/modeTransition
'
;
import
{
Token
}
from
'
vs/editor/common/core/token
'
;
...
...
@@ -315,27 +315,25 @@ suite('Editor Modes - Tokenization', () => {
{
startIndex
:
5
,
id
:
'
B
'
}
]);
handleEvent
(
createMockLineContext
(
'
abc (def
'
,
lineTokens
),
0
,
(
modeId
:
string
,
context
:
modes
.
ILineContext
,
offset
:
number
)
=>
{
assert
.
deepEqual
(
modeId
,
'
A
'
);
assert
.
equal
(
context
.
getTokenCount
(),
3
);
assert
.
equal
(
context
.
getTokenStartOffset
(
0
),
0
);
assert
.
equal
(
context
.
getTokenType
(
0
),
'
A.abc
'
);
assert
.
equal
(
context
.
getTokenStartOffset
(
1
),
3
);
assert
.
equal
(
context
.
getTokenType
(
1
),
''
);
assert
.
equal
(
context
.
getTokenStartOffset
(
2
),
4
);
assert
.
equal
(
context
.
getTokenType
(
2
),
'
A.(
'
);
assert
.
deepEqual
(
offset
,
0
);
assert
.
equal
(
context
.
getLineContent
(),
'
abc (
'
);
});
handleEvent
(
createMockLineContext
(
'
abc (def
'
,
lineTokens
),
6
,
(
modeId
:
string
,
context
:
modes
.
ILineContext
,
offset
:
number
)
=>
{
assert
.
deepEqual
(
modeId
,
'
B
'
);
assert
.
equal
(
context
.
getTokenCount
(),
1
);
assert
.
equal
(
context
.
getTokenStartOffset
(
0
),
0
);
assert
.
equal
(
context
.
getTokenType
(
0
),
'
B.def
'
);
assert
.
deepEqual
(
offset
,
1
);
assert
.
equal
(
context
.
getLineContent
(),
'
def
'
);
});
let
scopedLineTokens1
=
createScopedLineTokens
(
createFakeLineTokens
(
'
abc (def
'
,
switchingMode
.
getId
(),
lineTokens
.
tokens
,
lineTokens
.
modeTransitions
),
0
);
assert
.
deepEqual
(
scopedLineTokens1
.
modeId
,
'
A
'
);
assert
.
equal
(
scopedLineTokens1
.
getTokenCount
(),
3
);
assert
.
equal
(
scopedLineTokens1
.
getTokenStartOffset
(
0
),
0
);
assert
.
equal
(
scopedLineTokens1
.
getTokenType
(
0
),
'
A.abc
'
);
assert
.
equal
(
scopedLineTokens1
.
getTokenStartOffset
(
1
),
3
);
assert
.
equal
(
scopedLineTokens1
.
getTokenType
(
1
),
''
);
assert
.
equal
(
scopedLineTokens1
.
getTokenStartOffset
(
2
),
4
);
assert
.
equal
(
scopedLineTokens1
.
getTokenType
(
2
),
'
A.(
'
);
assert
.
deepEqual
(
scopedLineTokens1
.
firstCharOffset
,
0
);
assert
.
equal
(
scopedLineTokens1
.
getLineContent
(),
'
abc (
'
);
let
scopedLineTokens2
=
createScopedLineTokens
(
createFakeLineTokens
(
'
abc (def
'
,
switchingMode
.
getId
(),
lineTokens
.
tokens
,
lineTokens
.
modeTransitions
),
6
);
assert
.
deepEqual
(
scopedLineTokens2
.
modeId
,
'
B
'
);
assert
.
equal
(
scopedLineTokens2
.
getTokenCount
(),
1
);
assert
.
equal
(
scopedLineTokens2
.
getTokenStartOffset
(
0
),
0
);
assert
.
equal
(
scopedLineTokens2
.
getTokenType
(
0
),
'
B.def
'
);
assert
.
deepEqual
(
scopedLineTokens2
.
firstCharOffset
,
5
);
assert
.
equal
(
scopedLineTokens2
.
getLineContent
(),
'
def
'
);
lineTokens
=
switchingModeTokenize
(
'
ghi jkl
'
,
lineTokens
.
endState
);
assertTokens
(
lineTokens
.
tokens
,
[
...
...
src/vs/editor/test/common/modesTestUtils.ts
浏览文件 @
7f438ed3
...
...
@@ -4,63 +4,13 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Arrays
}
from
'
vs/editor/common/core/arrays
'
;
import
*
as
modes
from
'
vs/editor/common/modes
'
;
import
{
ModeTransition
}
from
'
vs/editor/common/core/modeTransition
'
;
import
{
Token
}
from
'
vs/editor/common/core/token
'
;
import
{
LineTokens
}
from
'
vs/editor/common/core/lineTokens
'
;
import
{
TokensBinaryEncoding
,
TokensInflatorMap
}
from
'
vs/editor/common/model/tokensBinaryEncoding
'
;
export
interface
TokenText
{
text
:
string
;
type
:
string
;
export
function
createFakeLineTokens
(
line
:
string
,
modeId
:
string
,
tokens
:
Token
[],
modeTransitions
:
ModeTransition
[]):
LineTokens
{
let
map
=
new
TokensInflatorMap
(
modeId
);
let
deflatedTokens
=
TokensBinaryEncoding
.
deflateArr
(
map
,
tokens
);
return
new
LineTokens
(
map
,
deflatedTokens
,
modeTransitions
,
line
);
}
export
function
createLineContextFromTokenText
(
tokens
:
TokenText
[]):
modes
.
ILineContext
{
let
line
=
''
;
let
processedTokens
:
Token
[]
=
[];
let
indexSoFar
=
0
;
for
(
let
i
=
0
;
i
<
tokens
.
length
;
++
i
)
{
processedTokens
.
push
(
new
Token
(
indexSoFar
,
tokens
[
i
].
type
));
line
+=
tokens
[
i
].
text
;
indexSoFar
+=
tokens
[
i
].
text
.
length
;
}
return
new
TestLineContext
(
line
,
processedTokens
,
null
);
}
export
function
createMockLineContext
(
line
:
string
,
tokens
:
modes
.
ILineTokens
):
modes
.
ILineContext
{
return
new
TestLineContext
(
line
,
tokens
.
tokens
,
tokens
.
modeTransitions
);
}
class
TestLineContext
implements
modes
.
ILineContext
{
public
modeTransitions
:
ModeTransition
[];
private
_line
:
string
;
private
_tokens
:
Token
[];
constructor
(
line
:
string
,
tokens
:
Token
[],
modeTransitions
:
ModeTransition
[])
{
this
.
modeTransitions
=
modeTransitions
;
this
.
_line
=
line
;
this
.
_tokens
=
tokens
;
}
public
getLineContent
():
string
{
return
this
.
_line
;
}
public
getTokenCount
():
number
{
return
this
.
_tokens
.
length
;
}
public
getTokenStartOffset
(
tokenIndex
:
number
):
number
{
return
this
.
_tokens
[
tokenIndex
].
startIndex
;
}
public
getTokenType
(
tokenIndex
:
number
):
string
{
return
this
.
_tokens
[
tokenIndex
].
type
;
}
public
findIndexOfOffset
(
offset
:
number
):
number
{
return
Arrays
.
findIndexInSegmentsArray
(
this
.
_tokens
,
offset
);
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录