Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
d3e54fd2
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,发现更多精彩内容 >>
提交
d3e54fd2
编写于
8月 24, 2016
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
replace CodeSnippet-ctor with static factory method with fromTextMate, fromInternal, fromEmmet
上级
067a747b
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
325 addition
and
296 deletion
+325
-296
src/vs/editor/common/modes/snippetsRegistry.ts
src/vs/editor/common/modes/snippetsRegistry.ts
+0
-2
src/vs/editor/contrib/defineKeybinding/browser/defineKeybinding.ts
...itor/contrib/defineKeybinding/browser/defineKeybinding.ts
+1
-1
src/vs/editor/contrib/snippet/common/snippet.ts
src/vs/editor/contrib/snippet/common/snippet.ts
+211
-170
src/vs/editor/contrib/snippet/test/common/snippet.test.ts
src/vs/editor/contrib/snippet/test/common/snippet.test.ts
+99
-104
src/vs/editor/contrib/snippet/test/common/snippetController.test.ts
...tor/contrib/snippet/test/common/snippetController.test.ts
+5
-5
src/vs/editor/contrib/suggest/browser/suggestController.ts
src/vs/editor/contrib/suggest/browser/suggestController.ts
+1
-1
src/vs/editor/contrib/suggest/browser/tabCompletion.ts
src/vs/editor/contrib/suggest/browser/tabCompletion.ts
+1
-1
src/vs/editor/contrib/suggest/electron-browser/snippetCompletion.ts
...tor/contrib/suggest/electron-browser/snippetCompletion.ts
+1
-1
src/vs/editor/node/textMate/TMSnippets.ts
src/vs/editor/node/textMate/TMSnippets.ts
+5
-9
src/vs/workbench/parts/emmet/node/editorAccessor.ts
src/vs/workbench/parts/emmet/node/editorAccessor.ts
+1
-2
未找到文件。
src/vs/editor/common/modes/snippetsRegistry.ts
浏览文件 @
d3e54fd2
...
...
@@ -20,8 +20,6 @@ export interface ISnippetsRegistry {
*/
registerSnippets
(
modeId
:
string
,
snippets
:
ISnippet
[],
owner
?:
string
):
void
;
/**
* Visit all snippets
*/
...
...
src/vs/editor/contrib/defineKeybinding/browser/defineKeybinding.ts
浏览文件 @
d3e54fd2
...
...
@@ -117,7 +117,7 @@ export class DefineKeybindingController implements editorCommon.IEditorContribut
snippetText
=
smartInsertInfo
.
prepend
+
snippetText
+
smartInsertInfo
.
append
;
this
.
_editor
.
setPosition
(
smartInsertInfo
.
position
);
SnippetController
.
get
(
this
.
_editor
).
run
(
new
CodeSnippet
(
snippetText
),
0
,
0
);
SnippetController
.
get
(
this
.
_editor
).
run
(
CodeSnippet
.
fromInternal
(
snippetText
),
0
,
0
);
}
private
_onModel
():
void
{
...
...
src/vs/editor/contrib/snippet/common/snippet.ts
浏览文件 @
d3e54fd2
...
...
@@ -5,60 +5,29 @@
'
use strict
'
;
import
*
as
collections
from
'
vs/base/common/collections
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
interface
IParsedLinePlaceHolderInfo
{
id
:
string
;
value
:
string
;
startColumn
:
number
;
endColumn
:
number
;
}
interface
IParsedLine
{
line
:
string
;
placeHolders
:
IParsedLinePlaceHolderInfo
[];
}
export
interface
IPlaceHolder
{
id
:
string
;
value
:
string
;
occurences
:
editorCommon
.
IRange
[];
}
export
interface
IIndentationNormalizer
{
normalizeIndentation
(
str
:
string
):
string
;
}
export
interface
ICodeSnippet
{
lines
:
string
[];
placeHolders
:
IPlaceHolder
[];
finishPlaceHolderIndex
:
number
;
}
export
enum
ExternalSnippetType
{
TextMateSnippet
,
EmmetSnippet
}
import
*
as
collections
from
'
vs/base/common/collections
'
;
export
class
CodeSnippet
implements
ICodeSnippet
{
private
_lastGeneratedId
:
number
;
public
lines
:
string
[];
public
placeHolders
:
IPlaceHolder
[];
public
finishPlaceHolderIndex
:
number
;
static
fromTextmate
(
template
:
string
):
CodeSnippet
{
return
TextMateSnippetParser
.
parse
(
template
);
}
constructor
(
snippetTemplate
:
string
)
{
this
.
lines
=
[];
this
.
placeHolders
=
[];
this
.
_lastGeneratedId
=
0
;
this
.
finishPlaceHolderIndex
=
-
1
;
static
fromEmmet
(
template
:
string
):
CodeSnippet
{
return
EmmetSnippetParser
.
parse
(
template
);
}
this
.
parseTemplate
(
snippetTemplate
);
static
fromInternal
(
template
:
string
):
CodeSnippet
{
return
InternalFormatSnippetParser
.
parse
(
template
);
}
public
lines
:
string
[]
=
[];
public
placeHolders
:
IPlaceHolder
[]
=
[];
public
finishPlaceHolderIndex
:
number
=
-
1
;
get
isInsertOnly
():
boolean
{
return
this
.
placeHolders
.
length
===
0
;
}
...
...
@@ -80,6 +49,104 @@ export class CodeSnippet implements ICodeSnippet {
return
true
;
}
private
extractLineIndentation
(
str
:
string
,
maxColumn
:
number
=
Number
.
MAX_VALUE
):
string
{
var
fullIndentation
=
strings
.
getLeadingWhitespace
(
str
);
if
(
fullIndentation
.
length
>
maxColumn
-
1
)
{
return
fullIndentation
.
substring
(
0
,
maxColumn
-
1
);
}
return
fullIndentation
;
}
public
bind
(
referenceLine
:
string
,
deltaLine
:
number
,
firstLineDeltaColumn
:
number
,
config
:
IIndentationNormalizer
):
ICodeSnippet
{
var
resultLines
:
string
[]
=
[];
var
resultPlaceHolders
:
IPlaceHolder
[]
=
[];
var
referenceIndentation
=
this
.
extractLineIndentation
(
referenceLine
,
firstLineDeltaColumn
+
1
);
var
originalLine
:
string
,
originalLineIndentation
:
string
,
remainingLine
:
string
,
indentation
:
string
;
var
i
:
number
,
len
:
number
,
j
:
number
,
lenJ
:
number
;
// Compute resultLines & keep deltaColumns as a reference for adjusting placeholders
var
deltaColumns
:
number
[]
=
[];
for
(
i
=
0
,
len
=
this
.
lines
.
length
;
i
<
len
;
i
++
)
{
originalLine
=
this
.
lines
[
i
];
if
(
i
===
0
)
{
deltaColumns
[
i
+
1
]
=
firstLineDeltaColumn
;
resultLines
[
i
]
=
originalLine
;
}
else
{
originalLineIndentation
=
this
.
extractLineIndentation
(
originalLine
);
remainingLine
=
originalLine
.
substr
(
originalLineIndentation
.
length
);
indentation
=
config
.
normalizeIndentation
(
referenceIndentation
+
originalLineIndentation
);
deltaColumns
[
i
+
1
]
=
indentation
.
length
-
originalLineIndentation
.
length
;
resultLines
[
i
]
=
indentation
+
remainingLine
;
}
}
// Compute resultPlaceHolders
var
originalPlaceHolder
:
IPlaceHolder
,
originalOccurence
:
editorCommon
.
IRange
,
resultOccurences
:
editorCommon
.
IRange
[];
for
(
i
=
0
,
len
=
this
.
placeHolders
.
length
;
i
<
len
;
i
++
)
{
originalPlaceHolder
=
this
.
placeHolders
[
i
];
resultOccurences
=
[];
for
(
j
=
0
,
lenJ
=
originalPlaceHolder
.
occurences
.
length
;
j
<
lenJ
;
j
++
)
{
originalOccurence
=
originalPlaceHolder
.
occurences
[
j
];
resultOccurences
.
push
({
startLineNumber
:
originalOccurence
.
startLineNumber
+
deltaLine
,
startColumn
:
originalOccurence
.
startColumn
+
deltaColumns
[
originalOccurence
.
startLineNumber
],
endLineNumber
:
originalOccurence
.
endLineNumber
+
deltaLine
,
endColumn
:
originalOccurence
.
endColumn
+
deltaColumns
[
originalOccurence
.
endLineNumber
]
});
}
resultPlaceHolders
.
push
({
id
:
originalPlaceHolder
.
id
,
value
:
originalPlaceHolder
.
value
,
occurences
:
resultOccurences
});
}
return
{
lines
:
resultLines
,
placeHolders
:
resultPlaceHolders
,
finishPlaceHolderIndex
:
this
.
finishPlaceHolderIndex
};
}
}
// --- parsing
interface
ISnippetParser
{
parse
(
input
:
string
):
CodeSnippet
;
}
interface
IParsedLinePlaceHolderInfo
{
id
:
string
;
value
:
string
;
startColumn
:
number
;
endColumn
:
number
;
}
interface
IParsedLine
{
line
:
string
;
placeHolders
:
IParsedLinePlaceHolderInfo
[];
}
const
InternalFormatSnippetParser
=
new
class
implements
ISnippetParser
{
private
_lastGeneratedId
:
number
;
private
_snippet
:
CodeSnippet
;
parse
(
template
:
string
):
CodeSnippet
{
this
.
_lastGeneratedId
=
0
;
this
.
_snippet
=
new
CodeSnippet
();
this
.
parseTemplate
(
template
);
return
this
.
_snippet
;
}
private
parseTemplate
(
template
:
string
):
void
{
var
placeHoldersMap
:
collections
.
IStringDictionary
<
IPlaceHolder
>
=
{};
...
...
@@ -105,19 +172,19 @@ export class CodeSnippet implements ICodeSnippet {
value
:
linePlaceHolder
.
value
,
occurences
:
[]
};
this
.
placeHolders
.
push
(
placeHolder
);
this
.
_snippet
.
placeHolders
.
push
(
placeHolder
);
placeHoldersMap
[
linePlaceHolder
.
id
]
=
placeHolder
;
}
placeHolder
.
occurences
.
push
(
occurence
);
}
this
.
lines
.
push
(
parsedLine
.
line
);
this
.
_snippet
.
lines
.
push
(
parsedLine
.
line
);
}
// Named variables (e.g. {greeting} and {greeting:Hello}) are sorted first, followed by
// tab-stops and numeric variables (e.g. $1, $2, ${3:foo}) which are sorted in ascending order
this
.
placeHolders
.
sort
((
a
,
b
)
=>
{
this
.
_snippet
.
placeHolders
.
sort
((
a
,
b
)
=>
{
let
nonIntegerId
=
(
v
:
IPlaceHolder
)
=>
!
(
/^
\d
+$/
).
test
(
v
.
id
);
let
isFinishPlaceHolder
=
(
v
:
IPlaceHolder
)
=>
v
.
id
===
''
&&
v
.
value
===
''
;
...
...
@@ -144,8 +211,8 @@ export class CodeSnippet implements ICodeSnippet {
return
Number
(
a
.
id
)
<
Number
(
b
.
id
)
?
-
1
:
1
;
});
if
(
this
.
placeHolders
.
length
>
0
&&
this
.
placeHolders
[
this
.
placeHolders
.
length
-
1
].
value
===
''
)
{
this
.
finishPlaceHolderIndex
=
this
.
placeHolders
.
length
-
1
;
if
(
this
.
_snippet
.
placeHolders
.
length
>
0
&&
this
.
_snippet
.
placeHolders
[
this
.
_snippet
.
placeHolders
.
length
-
1
].
value
===
''
)
{
this
.
_snippet
.
finishPlaceHolderIndex
=
this
.
_snippet
.
placeHolders
.
length
-
1
;
}
}
...
...
@@ -253,147 +320,121 @@ export class CodeSnippet implements ICodeSnippet {
placeHolders
:
placeHolders
};
}
};
// This is used for both TextMate and Emmet
public
static
convertExternalSnippet
(
snippet
:
string
,
snippetType
:
ExternalSnippetType
):
string
{
var
openBraces
=
0
;
var
convertedSnippet
=
''
;
var
i
=
0
;
var
len
=
snippet
.
length
;
const
TextMateSnippetParser
=
new
class
implements
ISnippetParser
{
while
(
i
<
len
)
{
var
restOfLine
=
snippet
.
substr
(
i
);
parse
(
template
:
string
):
CodeSnippet
{
template
=
_convertExternalSnippet
(
template
,
ExternalSnippetType
.
TextMateSnippet
);
return
InternalFormatSnippetParser
.
parse
(
template
);
}
};
// Cursor tab stop
if
(
/^
\$
0/
.
test
(
restOfLine
))
{
i
+=
2
;
convertedSnippet
+=
snippetType
===
ExternalSnippetType
.
EmmetSnippet
?
'
{{_}}
'
:
'
{{}}
'
;
continue
;
}
if
(
/^
\$\{
0
\}
/
.
test
(
restOfLine
))
{
i
+=
4
;
convertedSnippet
+=
snippetType
===
ExternalSnippetType
.
EmmetSnippet
?
'
{{_}}
'
:
'
{{}}
'
;
continue
;
}
const
EmmetSnippetParser
=
new
class
implements
ISnippetParser
{
// Tab stops
var
matches
=
restOfLine
.
match
(
/^
\$(\d
+
)
/
);
if
(
Array
.
isArray
(
matches
)
&&
matches
.
length
===
2
)
{
i
+=
1
+
matches
[
1
].
length
;
convertedSnippet
+=
'
{{
'
+
matches
[
1
]
+
'
:}}
'
;
continue
;
}
matches
=
restOfLine
.
match
(
/^
\$\{(\d
+
)\}
/
);
if
(
Array
.
isArray
(
matches
)
&&
matches
.
length
===
2
)
{
i
+=
3
+
matches
[
1
].
length
;
convertedSnippet
+=
'
{{
'
+
matches
[
1
]
+
'
:}}
'
;
continue
;
}
parse
(
template
:
string
):
CodeSnippet
{
template
=
_convertExternalSnippet
(
template
,
ExternalSnippetType
.
EmmetSnippet
);
return
InternalFormatSnippetParser
.
parse
(
template
);
}
};
// Open brace patterns placeholder
if
(
/^
\$
{/
.
test
(
restOfLine
))
{
i
+=
2
;
++
openBraces
;
convertedSnippet
+=
'
{{
'
;
continue
;
}
export
enum
ExternalSnippetType
{
TextMateSnippet
,
EmmetSnippet
}
// Close brace patterns placeholder
if
(
openBraces
>
0
&&
/^}/
.
test
(
restOfLine
))
{
i
+=
1
;
--
openBraces
;
convertedSnippet
+=
'
}}
'
;
continue
;
}
// This is used for both TextMate and Emmet
function
_convertExternalSnippet
(
snippet
:
string
,
snippetType
:
ExternalSnippetType
):
string
{
var
openBraces
=
0
;
var
convertedSnippet
=
''
;
var
i
=
0
;
var
len
=
snippet
.
length
;
while
(
i
<
len
)
{
var
restOfLine
=
snippet
.
substr
(
i
);
// Cursor tab stop
if
(
/^
\$
0/
.
test
(
restOfLine
))
{
i
+=
2
;
convertedSnippet
+=
snippetType
===
ExternalSnippetType
.
EmmetSnippet
?
'
{{_}}
'
:
'
{{}}
'
;
continue
;
}
if
(
/^
\$\{
0
\}
/
.
test
(
restOfLine
))
{
i
+=
4
;
convertedSnippet
+=
snippetType
===
ExternalSnippetType
.
EmmetSnippet
?
'
{{_}}
'
:
'
{{}}
'
;
continue
;
}
// Escapes
if
(
/^
\\
./
.
test
(
restOfLine
))
{
i
+=
2
;
if
(
/^
\\\$
/
.
test
(
restOfLine
))
{
convertedSnippet
+=
'
$
'
;
}
else
{
convertedSnippet
+=
restOfLine
.
substr
(
0
,
2
);
}
continue
;
}
// Tab stops
var
matches
=
restOfLine
.
match
(
/^
\$(\d
+
)
/
);
if
(
Array
.
isArray
(
matches
)
&&
matches
.
length
===
2
)
{
i
+=
1
+
matches
[
1
].
length
;
convertedSnippet
+=
'
{{
'
+
matches
[
1
]
+
'
:}}
'
;
continue
;
}
matches
=
restOfLine
.
match
(
/^
\$\{(\d
+
)\}
/
);
if
(
Array
.
isArray
(
matches
)
&&
matches
.
length
===
2
)
{
i
+=
3
+
matches
[
1
].
length
;
convertedSnippet
+=
'
{{
'
+
matches
[
1
]
+
'
:}}
'
;
continue
;
}
// Escape braces that don't belong to a
placeholder
matches
=
restOfLine
.
match
(
/^
(
{|}
)
/
);
i
f
(
Array
.
isArray
(
matches
)
&&
matches
.
length
===
2
)
{
i
+=
1
;
convertedSnippet
+=
'
\\
'
+
matches
[
1
]
;
continue
;
}
// Open brace patterns
placeholder
if
(
/^
\$
{/
.
test
(
restOfLine
))
{
i
+=
2
;
++
openBraces
;
convertedSnippet
+=
'
{{
'
;
continue
;
}
// Close brace patterns placeholder
if
(
openBraces
>
0
&&
/^}/
.
test
(
restOfLine
))
{
i
+=
1
;
convertedSnippet
+=
restOfLine
.
charAt
(
0
);
--
openBraces
;
convertedSnippet
+=
'
}}
'
;
continue
;
}
return
convertedSnippet
;
}
private
extractLineIndentation
(
str
:
string
,
maxColumn
:
number
=
Number
.
MAX_VALUE
):
string
{
var
fullIndentation
=
strings
.
getLeadingWhitespace
(
str
);
// Escapes
if
(
/^
\\
./
.
test
(
restOfLine
))
{
i
+=
2
;
if
(
/^
\\\$
/
.
test
(
restOfLine
))
{
convertedSnippet
+=
'
$
'
;
}
else
{
convertedSnippet
+=
restOfLine
.
substr
(
0
,
2
);
}
continue
;
}
if
(
fullIndentation
.
length
>
maxColumn
-
1
)
{
return
fullIndentation
.
substring
(
0
,
maxColumn
-
1
);
// Escape braces that don't belong to a placeholder
matches
=
restOfLine
.
match
(
/^
(
{|}
)
/
);
if
(
Array
.
isArray
(
matches
)
&&
matches
.
length
===
2
)
{
i
+=
1
;
convertedSnippet
+=
'
\\
'
+
matches
[
1
];
continue
;
}
return
fullIndentation
;
i
+=
1
;
convertedSnippet
+=
restOfLine
.
charAt
(
0
);
}
public
bind
(
referenceLine
:
string
,
deltaLine
:
number
,
firstLineDeltaColumn
:
number
,
config
:
IIndentationNormalizer
):
ICodeSnippet
{
var
resultLines
:
string
[]
=
[];
var
resultPlaceHolders
:
IPlaceHolder
[]
=
[];
var
referenceIndentation
=
this
.
extractLineIndentation
(
referenceLine
,
firstLineDeltaColumn
+
1
);
var
originalLine
:
string
,
originalLineIndentation
:
string
,
remainingLine
:
string
,
indentation
:
string
;
var
i
:
number
,
len
:
number
,
j
:
number
,
lenJ
:
number
;
// Compute resultLines & keep deltaColumns as a reference for adjusting placeholders
var
deltaColumns
:
number
[]
=
[];
for
(
i
=
0
,
len
=
this
.
lines
.
length
;
i
<
len
;
i
++
)
{
originalLine
=
this
.
lines
[
i
];
if
(
i
===
0
)
{
deltaColumns
[
i
+
1
]
=
firstLineDeltaColumn
;
resultLines
[
i
]
=
originalLine
;
}
else
{
originalLineIndentation
=
this
.
extractLineIndentation
(
originalLine
);
remainingLine
=
originalLine
.
substr
(
originalLineIndentation
.
length
);
indentation
=
config
.
normalizeIndentation
(
referenceIndentation
+
originalLineIndentation
);
deltaColumns
[
i
+
1
]
=
indentation
.
length
-
originalLineIndentation
.
length
;
resultLines
[
i
]
=
indentation
+
remainingLine
;
}
}
return
convertedSnippet
;
};
// Compute resultPlaceHolders
var
originalPlaceHolder
:
IPlaceHolder
,
originalOccurence
:
editorCommon
.
IRange
,
resultOccurences
:
editorCommon
.
IRange
[];
for
(
i
=
0
,
len
=
this
.
placeHolders
.
length
;
i
<
len
;
i
++
)
{
originalPlaceHolder
=
this
.
placeHolders
[
i
];
resultOccurences
=
[];
for
(
j
=
0
,
lenJ
=
originalPlaceHolder
.
occurences
.
length
;
j
<
lenJ
;
j
++
)
{
originalOccurence
=
originalPlaceHolder
.
occurences
[
j
];
resultOccurences
.
push
({
startLineNumber
:
originalOccurence
.
startLineNumber
+
deltaLine
,
startColumn
:
originalOccurence
.
startColumn
+
deltaColumns
[
originalOccurence
.
startLineNumber
],
endLineNumber
:
originalOccurence
.
endLineNumber
+
deltaLine
,
endColumn
:
originalOccurence
.
endColumn
+
deltaColumns
[
originalOccurence
.
endLineNumber
]
});
}
export
interface
IPlaceHolder
{
id
:
string
;
value
:
string
;
occurences
:
editorCommon
.
IRange
[];
}
resultPlaceHolders
.
push
({
id
:
originalPlaceHolder
.
id
,
value
:
originalPlaceHolder
.
value
,
occurences
:
resultOccurences
});
}
export
interface
IIndentationNormalizer
{
normalizeIndentation
(
str
:
string
):
string
;
}
return
{
lines
:
resultLines
,
placeHolders
:
resultPlaceHolders
,
finishPlaceHolderIndex
:
this
.
finishPlaceHolderIndex
};
}
export
interface
ICodeSnippet
{
lines
:
string
[];
placeHolders
:
IPlaceHolder
[];
finishPlaceHolderIndex
:
number
;
}
src/vs/editor/contrib/snippet/test/common/snippet.test.ts
浏览文件 @
d3e54fd2
...
...
@@ -6,85 +6,84 @@
import
*
as
assert
from
'
assert
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
CodeSnippet
,
ExternalSnippetType
}
from
'
vs/editor/contrib/snippet/common/snippet
'
;
import
{
CodeSnippet
}
from
'
vs/editor/contrib/snippet/common/snippet
'
;
suite
(
'
Editor Contrib - Snippets
'
,
()
=>
{
test
(
'
Support tab stop order
'
,
()
=>
{
let
external
=
'
finished:$0, second:${2:name}, first:$1, third:$3
'
;
let
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
function
assertInternalAndTextmate
(
internal
:
string
,
textmate
:
string
,
callback
:
(
snippet
:
CodeSnippet
)
=>
any
)
{
assert
.
equal
(
internal
,
'
finished:{{}}, second:{{2:name}}, first:{{1:}}, third:{{3:}}
'
);
callback
(
CodeSnippet
.
fromInternal
(
internal
));
callback
(
CodeSnippet
.
fromTextmate
(
textmate
));
}
let
snippet
=
new
CodeSnippet
(
internal
);
test
(
'
Support tab stop order
'
,
()
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
finished:, second:name, first:, third:
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
4
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
value
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
2
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
value
,
'
name
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
id
,
'
3
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
value
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
3
].
id
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
3
].
value
,
''
);
assert
.
equal
(
snippet
.
finishPlaceHolderIndex
,
3
);
assertInternalAndTextmate
(
'
finished:{{}}, second:{{2:name}}, first:{{1:}}, third:{{3:}}
'
,
'
finished:$0, second:${2:name}, first:$1, third:$3
'
,
snippet
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
finished:, second:name, first:, third:
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
4
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
value
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
2
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
value
,
'
name
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
id
,
'
3
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
value
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
3
].
id
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
3
].
value
,
''
);
assert
.
equal
(
snippet
.
finishPlaceHolderIndex
,
3
);
});
});
test
(
'
Support tab stop order with implicit finish
'
,
()
=>
{
let
external
=
'
t2:$2, t1:$1
'
;
let
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
assert
.
equal
(
internal
,
'
t2:{{2:}}, t1:{{1:}}
'
);
let
snippet
=
new
CodeSnippet
(
internal
);
assert
.
deepEqual
(
snippet
.
lines
,
[
'
t2:, t1:
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
2
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
value
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
2
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
value
,
''
);
assert
.
equal
(
snippet
.
finishPlaceHolderIndex
,
1
);
assertInternalAndTextmate
(
'
t2:{{2:}}, t1:{{1:}}
'
,
'
t2:$2, t1:$1
'
,
snippet
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
t2:, t1:
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
2
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
value
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
2
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
value
,
''
);
assert
.
equal
(
snippet
.
finishPlaceHolderIndex
,
1
);
});
});
test
(
'
Support tab stop order with no finish
'
,
()
=>
{
let
external
=
'
t2:${2:second}, t3:${3:last}, t1:${1:first}
'
;
let
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
assert
.
equal
(
internal
,
'
t2:{{2:second}}, t3:{{3:last}}, t1:{{1:first}}
'
);
let
snippet
=
new
CodeSnippet
(
internal
);
assert
.
deepEqual
(
snippet
.
lines
,
[
'
t2:second, t3:last, t1:first
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
3
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
value
,
'
first
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
2
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
value
,
'
second
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
id
,
'
3
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
value
,
'
last
'
);
assert
.
equal
(
snippet
.
finishPlaceHolderIndex
,
-
1
);
assertInternalAndTextmate
(
'
t2:{{2:second}}, t3:{{3:last}}, t1:{{1:first}}
'
,
'
t2:${2:second}, t3:${3:last}, t1:${1:first}
'
,
snippet
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
t2:second, t3:last, t1:first
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
3
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
value
,
'
first
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
2
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
value
,
'
second
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
id
,
'
3
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
value
,
'
last
'
);
assert
.
equal
(
snippet
.
finishPlaceHolderIndex
,
-
1
);
});
});
test
(
'
Support tab stop order wich does not affect named variable id
\'
s
'
,
()
=>
{
let
external
=
'
${first}-${2}-${second}-${1}
'
;
let
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
assert
.
equal
(
internal
,
'
{{first}}-{{2:}}-{{second}}-{{1:}}
'
);
let
snippet
=
new
CodeSnippet
(
internal
);
assert
.
deepEqual
(
snippet
.
lines
,
[
'
first--second-
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
4
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
first
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
second
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
3
].
id
,
'
2
'
);
assertInternalAndTextmate
(
'
{{first}}-{{2:}}-{{second}}-{{1:}}
'
,
'
${first}-${2}-${second}-${1}
'
,
snippet
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
first--second-
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
4
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
first
'
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
'
second
'
);
assert
.
equal
(
snippet
.
placeHolders
[
2
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
3
].
id
,
'
2
'
);
}
);
});
test
(
'
bug #17541:[snippets] Support default text in mirrors
'
,
()
=>
{
...
...
@@ -95,29 +94,27 @@ suite('Editor Contrib - Snippets', () => {
'
end{$1}
'
].
join
(
'
\n
'
);
var
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
assert
.
equal
(
internal
,
[
var
internal
=
[
'
begin
\\
{{{1:enumerate}}
\\
}
'
,
'
\t
{{}}
'
,
'
end
\\
{{{1:}}
\\
}
'
].
join
(
'
\n
'
)
)
;
var
snippet
=
new
CodeSnippet
(
internal
);
assert
.
deepEqual
(
snippet
.
lines
,
[
'
begin{enumerate}
'
,
'
\t
'
,
'
end{enumerate}
'
]
);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
2
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
occurences
.
length
,
2
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
0
],
new
Range
(
1
,
7
,
1
,
16
));
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
1
],
new
Range
(
3
,
5
,
3
,
14
)
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
occurences
.
length
,
1
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
1
].
occurences
[
0
],
new
Range
(
2
,
2
,
2
,
2
)
);
].
join
(
'
\n
'
);
assertInternalAndTextmate
(
internal
,
external
,
snippet
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
begin{enumerate}
'
,
'
\t
'
,
'
end{enumerate}
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
2
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
occurences
.
length
,
2
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
0
],
new
Range
(
1
,
7
,
1
,
16
)
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
1
],
new
Range
(
3
,
5
,
3
,
14
));
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
occurences
.
length
,
1
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
1
].
occurences
[
0
],
new
Range
(
2
,
2
,
2
,
2
)
);
}
);
});
test
(
'
bug #17487:[snippets] four backslashes are required to get one backslash in the inserted text
'
,
()
=>
{
...
...
@@ -128,37 +125,35 @@ suite('Editor Contrib - Snippets', () => {
'
\\
end{$1}
'
].
join
(
'
\n
'
);
var
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
assert
.
equal
(
internal
,
[
var
internal
=
[
'
\\
begin
\\
{{{1:enumerate}}
\\
}
'
,
'
\t
{{}}
'
,
'
\\
end
\\
{{{1:}}
\\
}
'
].
join
(
'
\n
'
)
)
;
var
snippet
=
new
CodeSnippet
(
internal
);
assert
.
deepEqual
(
snippet
.
lines
,
[
'
\\
begin{enumerate}
'
,
'
\t
'
,
'
\\
end{enumerate}
'
]
);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
2
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
occurences
.
length
,
2
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
0
],
new
Range
(
1
,
8
,
1
,
17
));
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
1
],
new
Range
(
3
,
6
,
3
,
15
)
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
occurences
.
length
,
1
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
1
].
occurences
[
0
],
new
Range
(
2
,
2
,
2
,
2
)
);
].
join
(
'
\n
'
);
assertInternalAndTextmate
(
internal
,
external
,
snippet
=>
{
assert
.
deepEqual
(
snippet
.
lines
,
[
'
\\
begin{enumerate}
'
,
'
\t
'
,
'
\\
end{enumerate}
'
]);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
2
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
id
,
'
1
'
);
assert
.
equal
(
snippet
.
placeHolders
[
0
].
occurences
.
length
,
2
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
0
],
new
Range
(
1
,
8
,
1
,
17
)
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
0
].
occurences
[
1
],
new
Range
(
3
,
6
,
3
,
15
));
assert
.
equal
(
snippet
.
placeHolders
[
1
].
id
,
''
);
assert
.
equal
(
snippet
.
placeHolders
[
1
].
occurences
.
length
,
1
);
assert
.
deepEqual
(
snippet
.
placeHolders
[
1
].
occurences
[
0
],
new
Range
(
2
,
2
,
2
,
2
)
);
}
);
});
test
(
'
issue #3552: Snippet Converted Not Working for literal Dollar Sign
'
,
()
=>
{
let
external
=
'
\n\\
$scope.
\\
$broadcast(
\'
scroll.infiniteScrollComplete
\'
);
\n
'
;
let
internal
=
CodeSnippet
.
convertExternalSnippet
(
external
,
ExternalSnippetType
.
TextMateSnippet
);
assert
.
equal
(
internal
,
'
\n
$scope.$broadcast(
\'
scroll.infiniteScrollComplete
\'
);
\n
'
);
let
snippet
=
CodeSnippet
.
fromTextmate
(
external
);
assert
.
equal
(
snippet
.
placeHolders
.
length
,
0
);
assert
.
deepEqual
(
snippet
.
lines
,
[
''
,
'
$scope.$broadcast(
\'
scroll.infiniteScrollComplete
\'
);
'
,
''
]
);
});
});
src/vs/editor/contrib/snippet/test/common/snippetController.test.ts
浏览文件 @
d3e54fd2
...
...
@@ -35,7 +35,7 @@ suite('SnippetController', () => {
insertSpaces
:
false
});
let
snippetController
=
editor
.
registerAndInstantiateContribution
<
TestSnippetController
>
(
TestSnippetController
);
let
codeSnippet
=
new
CodeSnippet
([
let
codeSnippet
=
CodeSnippet
.
fromInternal
([
'
for (var {{index}}; {{index}} < {{array}}.length; {{index}}++) {
'
,
'
\t
var element = {{array}}[{{index}}];
'
,
'
\t
{{}}
'
,
...
...
@@ -228,7 +228,7 @@ suite('SnippetController', () => {
new
Selection
(
2
,
1
,
2
,
1
),
]);
codeSnippet
=
new
CodeSnippet
(
'
foo{{}}
'
);
codeSnippet
=
CodeSnippet
.
fromInternal
(
'
foo{{}}
'
);
snippetController
.
run
(
codeSnippet
,
0
,
0
,
false
);
assert
.
equal
(
editor
.
getSelections
().
length
,
2
);
...
...
@@ -243,7 +243,7 @@ suite('SnippetController', () => {
new
Selection
(
2
,
1
,
2
,
1
),
]);
codeSnippet
=
new
CodeSnippet
(
'
foo{{}}bar
'
);
codeSnippet
=
CodeSnippet
.
fromInternal
(
'
foo{{}}bar
'
);
snippetController
.
run
(
codeSnippet
,
0
,
0
,
false
);
assert
.
equal
(
editor
.
getSelections
().
length
,
2
);
...
...
@@ -258,7 +258,7 @@ suite('SnippetController', () => {
new
Selection
(
1
,
5
,
1
,
5
),
]);
codeSnippet
=
new
CodeSnippet
(
'
foo{{}}bar
'
);
codeSnippet
=
CodeSnippet
.
fromInternal
(
'
foo{{}}bar
'
);
snippetController
.
run
(
codeSnippet
,
0
,
0
,
false
);
assert
.
equal
(
editor
.
getSelections
().
length
,
2
);
...
...
@@ -273,7 +273,7 @@ suite('SnippetController', () => {
new
Selection
(
1
,
5
,
1
,
5
),
]);
codeSnippet
=
new
CodeSnippet
(
'
foo
\n
{{}}
\n
bar
'
);
codeSnippet
=
CodeSnippet
.
fromInternal
(
'
foo
\n
{{}}
\n
bar
'
);
snippetController
.
run
(
codeSnippet
,
0
,
0
,
false
);
assert
.
equal
(
editor
.
getSelections
().
length
,
2
);
...
...
src/vs/editor/contrib/suggest/browser/suggestController.ts
浏览文件 @
d3e54fd2
...
...
@@ -85,7 +85,7 @@ export class SuggestController implements IEditorContribution {
}
SnippetController
.
get
(
this
.
editor
).
run
(
new
CodeSnippet
(
insertText
),
CodeSnippet
.
fromInternal
(
insertText
),
overwriteBefore
+
columnDelta
,
overwriteAfter
);
...
...
src/vs/editor/contrib/suggest/browser/tabCompletion.ts
浏览文件 @
d3e54fd2
...
...
@@ -66,7 +66,7 @@ class TabCompletionController implements editorCommon.IEditorContribution {
performSnippetCompletions
():
void
{
if
(
this
.
_currentSnippets
.
length
===
1
)
{
const
snippet
=
this
.
_currentSnippets
[
0
];
const
codeSnippet
=
new
CodeSnippet
(
snippet
.
codeSnippet
);
const
codeSnippet
=
CodeSnippet
.
fromTextmate
(
snippet
.
codeSnippet
);
this
.
_snippetController
.
run
(
codeSnippet
,
snippet
.
prefix
.
length
,
0
);
// } else {
// todo@joh - show suggest widget with proposals
...
...
src/vs/editor/contrib/suggest/electron-browser/snippetCompletion.ts
浏览文件 @
d3e54fd2
...
...
@@ -49,7 +49,7 @@ class ShowSnippetsActions extends EditorAction {
return
quickOpenService
.
pick
(
picks
).
then
(
pick
=>
{
if
(
pick
)
{
SnippetController
.
get
(
editor
).
run
(
new
CodeSnippet
(
pick
.
snippet
.
codeSnippet
),
0
,
0
);
SnippetController
.
get
(
editor
).
run
(
CodeSnippet
.
fromTextmate
(
pick
.
snippet
.
codeSnippet
),
0
,
0
);
}
});
}
...
...
src/vs/editor/node/textMate/TMSnippets.ts
浏览文件 @
d3e54fd2
...
...
@@ -12,7 +12,6 @@ import {readFile} from 'vs/base/node/pfs';
import
{
IExtensionMessageCollector
,
ExtensionsRegistry
}
from
'
vs/platform/extensions/common/extensionsRegistry
'
;
import
{
ISnippetsRegistry
,
Extensions
,
ISnippet
}
from
'
vs/editor/common/modes/snippetsRegistry
'
;
import
{
IModeService
}
from
'
vs/editor/common/services/modeService
'
;
import
{
CodeSnippet
,
ExternalSnippetType
}
from
'
vs/editor/contrib/snippet/common/snippet
'
;
import
platform
=
require
(
'
vs/platform/platform
'
);
export
interface
ISnippetsExtensionPoint
{
...
...
@@ -106,14 +105,11 @@ function parseSnippetFile(snippetFileContent: string): ISnippet[] {
}
if
(
typeof
prefix
===
'
string
'
&&
typeof
bodyStringOrArray
===
'
string
'
)
{
let
codeSnippet
=
CodeSnippet
.
convertExternalSnippet
(
bodyStringOrArray
,
ExternalSnippetType
.
TextMateSnippet
);
if
(
codeSnippet
!==
null
)
{
result
.
push
({
prefix
,
description
:
snippet
[
'
description
'
]
||
description
,
codeSnippet
});
}
result
.
push
({
prefix
,
description
:
snippet
[
'
description
'
]
||
description
,
codeSnippet
:
bodyStringOrArray
});
}
};
...
...
src/vs/workbench/parts/emmet/node/editorAccessor.ts
浏览文件 @
d3e54fd2
...
...
@@ -87,8 +87,7 @@ export class EditorAccessor implements emmet.Editor {
}
let
range
=
new
Range
(
startPosition
.
lineNumber
,
startPosition
.
column
,
endPosition
.
lineNumber
,
endPosition
.
column
);
let
snippet
=
snippets
.
CodeSnippet
.
convertExternalSnippet
(
value
,
snippets
.
ExternalSnippetType
.
EmmetSnippet
);
let
codeSnippet
=
new
snippets
.
CodeSnippet
(
snippet
);
let
codeSnippet
=
snippets
.
CodeSnippet
.
fromEmmet
(
value
);
SnippetController
.
get
(
this
.
editor
).
runWithReplaceRange
(
codeSnippet
,
range
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录