Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
038703dc
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,发现更多精彩内容 >>
提交
038703dc
编写于
6月 01, 2017
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
renamed and make TextSnippet extend Marker, #27543
上级
b28e0e34
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
113 addition
and
77 deletion
+113
-77
src/vs/editor/contrib/snippet/browser/snippetParser.ts
src/vs/editor/contrib/snippet/browser/snippetParser.ts
+57
-35
src/vs/editor/contrib/snippet/browser/snippetSession.ts
src/vs/editor/contrib/snippet/browser/snippetSession.ts
+1
-1
src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts
...editor/contrib/snippet/test/browser/snippetParser.test.ts
+46
-32
src/vs/workbench/parts/emmet/electron-browser/editorAccessor.ts
.../workbench/parts/emmet/electron-browser/editorAccessor.ts
+4
-4
src/vs/workbench/parts/snippets/electron-browser/TMSnippets.ts
...s/workbench/parts/snippets/electron-browser/TMSnippets.ts
+5
-5
未找到文件。
src/vs/editor/contrib/snippet/browser/snippetParser.ts
浏览文件 @
038703dc
...
...
@@ -134,8 +134,19 @@ export abstract class Marker {
parent
:
Marker
;
protected
_adopt
(
child
:
Marker
):
void
{
child
.
parent
=
this
;
private
_children
:
Marker
[]
=
[];
set
children
(
marker
:
Marker
[])
{
this
.
_children
=
[];
for
(
const
m
of
marker
)
{
m
.
parent
=
this
;
this
.
_children
.
push
(
m
);
}
// Object.freeze(this._children);
}
get
children
():
Marker
[]
{
return
this
.
_children
;
}
toString
()
{
...
...
@@ -176,15 +187,15 @@ export class Placeholder extends Marker {
}
}
constructor
(
public
index
:
string
=
''
,
public
defaultValue
:
Marker
[])
{
constructor
(
public
index
:
string
=
''
,
children
:
Marker
[])
{
super
();
defaultValue
.
forEach
(
this
.
_adopt
,
this
)
;
this
.
children
=
children
;
}
get
isFinalTabstop
()
{
return
this
.
index
===
'
0
'
;
}
toString
()
{
return
Marker
.
toString
(
this
.
defaultValue
);
return
Marker
.
toString
(
this
.
children
);
}
}
...
...
@@ -192,9 +203,9 @@ export class Variable extends Marker {
resolvedValue
:
string
;
constructor
(
public
name
:
string
=
''
,
public
defaultValue
:
Marker
[])
{
constructor
(
public
name
:
string
=
''
,
children
:
Marker
[])
{
super
();
defaultValue
.
forEach
(
this
.
_adopt
,
this
)
;
this
.
children
=
children
;
}
get
isDefined
():
boolean
{
return
this
.
resolvedValue
!==
undefined
;
...
...
@@ -207,7 +218,7 @@ export class Variable extends Marker {
}
}
toString
()
{
return
this
.
isDefined
?
this
.
resolvedValue
:
Marker
.
toString
(
this
.
defaultValue
);
return
this
.
isDefined
?
this
.
resolvedValue
:
Marker
.
toString
(
this
.
children
);
}
}
export
function
walk
(
marker
:
Marker
[],
visitor
:
(
marker
:
Marker
)
=>
boolean
):
void
{
...
...
@@ -219,36 +230,38 @@ export function walk(marker: Marker[], visitor: (marker: Marker) => boolean): vo
break
;
}
if
(
marker
instanceof
Placeholder
||
marker
instanceof
Variable
)
{
stack
.
unshift
(...
marker
.
defaultValue
);
stack
.
unshift
(...
marker
.
children
);
}
}
}
export
class
TextmateSnippet
{
export
class
TextmateSnippet
extends
Marker
{
readonly
marker
:
Marker
[];
readonly
placeholders
:
Placeholder
[];
private
_placeholders
:
Placeholder
[];
constructor
(
marker
:
Marker
[])
{
this
.
marker
=
marker
;
this
.
placeholders
=
[];
// fill in placeholders
walk
(
marker
,
candidate
=>
{
if
(
candidate
instanceof
Placeholder
)
{
this
.
placeholders
.
push
(
candidate
);
}
return
true
;
});
super
();
this
.
children
=
marker
;
}
Object
.
freeze
(
this
.
marker
);
Object
.
freeze
(
this
.
placeholders
);
get
placeholders
():
Placeholder
[]
{
if
(
!
this
.
_placeholders
)
{
// fill in placeholders
this
.
_placeholders
=
[];
walk
(
this
.
children
,
candidate
=>
{
if
(
candidate
instanceof
Placeholder
)
{
this
.
placeholders
.
push
(
candidate
);
}
return
true
;
});
}
return
this
.
_placeholders
;
}
offset
(
marker
:
Marker
):
number
{
let
pos
=
0
;
let
found
=
false
;
walk
(
this
.
marker
,
candidate
=>
{
walk
(
this
.
children
,
candidate
=>
{
if
(
candidate
===
marker
)
{
found
=
true
;
return
false
;
...
...
@@ -263,7 +276,7 @@ export class TextmateSnippet {
return
pos
;
}
l
en
(
marker
:
Marker
):
number
{
fullL
en
(
marker
:
Marker
):
number
{
let
ret
=
0
;
walk
([
marker
],
marker
=>
{
ret
+=
marker
.
len
();
...
...
@@ -285,22 +298,31 @@ export class TextmateSnippet {
}
get
text
()
{
return
Marker
.
toString
(
this
.
marker
);
return
Marker
.
toString
(
this
.
children
);
}
resolveVariables
(
resolver
:
{
resolve
(
name
:
string
):
string
}):
this
{
walk
(
this
.
marker
,
candidate
=>
{
walk
(
this
.
children
,
candidate
=>
{
if
(
candidate
instanceof
Variable
)
{
candidate
.
resolvedValue
=
resolver
.
resolve
(
candidate
.
name
);
if
(
candidate
.
isDefined
)
{
// remove default value from resolved variable
candidate
.
defaultValue
.
length
=
0
;
candidate
.
children
=
[]
;
}
}
return
true
;
});
return
this
;
}
replace
(
marker
:
Marker
,
others
:
Marker
[]):
void
{
const
{
parent
}
=
marker
;
const
idx
=
parent
.
children
.
indexOf
(
marker
);
const
newChildren
=
parent
.
children
.
slice
(
0
);
newChildren
.
splice
(
idx
,
1
,
...
others
);
parent
.
children
=
newChildren
;
this
.
_placeholders
=
undefined
;
}
}
export
class
SnippetParser
{
...
...
@@ -349,17 +371,17 @@ export class SnippetParser {
// fill in default values for repeated placeholders
// like `${1:foo}and$1` becomes ${1:foo}and${1:foo}
if
(
!
placeholderDefaultValues
.
has
(
thisMarker
.
index
))
{
placeholderDefaultValues
.
set
(
thisMarker
.
index
,
thisMarker
.
defaultValue
);
}
else
if
(
thisMarker
.
defaultValue
.
length
===
0
)
{
thisMarker
.
defaultValue
=
placeholderDefaultValues
.
get
(
thisMarker
.
index
).
slice
(
0
);
placeholderDefaultValues
.
set
(
thisMarker
.
index
,
thisMarker
.
children
);
}
else
if
(
thisMarker
.
children
.
length
===
0
)
{
thisMarker
.
children
=
placeholderDefaultValues
.
get
(
thisMarker
.
index
).
slice
(
0
);
}
if
(
thisMarker
.
defaultValue
.
length
>
0
)
{
walk
(
thisMarker
.
defaultValue
,
placeholderDefaultValues
);
if
(
thisMarker
.
children
.
length
>
0
)
{
walk
(
thisMarker
.
children
,
placeholderDefaultValues
);
}
}
else
if
(
thisMarker
instanceof
Variable
)
{
walk
(
thisMarker
.
defaultValue
,
placeholderDefaultValues
);
walk
(
thisMarker
.
children
,
placeholderDefaultValues
);
}
else
if
(
i
>
0
&&
thisMarker
instanceof
Text
&&
marker
[
i
-
1
]
instanceof
Text
)
{
(
<
Text
>
marker
[
i
-
1
]).
string
+=
(
<
Text
>
marker
[
i
]).
string
;
...
...
src/vs/editor/contrib/snippet/browser/snippetSession.ts
浏览文件 @
038703dc
...
...
@@ -65,7 +65,7 @@ export class OneSnippet {
// create a decoration for each placeholder
for
(
const
placeholder
of
this
.
_snippet
.
placeholders
)
{
const
placeholderOffset
=
this
.
_snippet
.
offset
(
placeholder
);
const
placeholderLen
=
this
.
_snippet
.
l
en
(
placeholder
);
const
placeholderLen
=
this
.
_snippet
.
fullL
en
(
placeholder
);
const
range
=
Range
.
fromPositions
(
model
.
getPositionAt
(
this
.
_offset
+
placeholderOffset
),
model
.
getPositionAt
(
this
.
_offset
+
placeholderOffset
+
placeholderLen
)
...
...
src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts
浏览文件 @
038703dc
...
...
@@ -153,13 +153,13 @@ suite('SnippetParser', () => {
assertTextAndMarker
(
'
foo${1:bar
\\
}${2:foo}}
'
,
'
foobar}foo
'
,
Text
,
Placeholder
);
let
[,
placeholder
]
=
new
SnippetParser
(
true
,
false
).
parse
(
'
foo${1:bar
\\
}${2:foo}}
'
);
let
{
defaultValue
}
=
(
<
Placeholder
>
placeholder
);
let
{
children
}
=
(
<
Placeholder
>
placeholder
);
assert
.
equal
((
<
Placeholder
>
placeholder
).
index
,
'
1
'
);
assert
.
ok
(
defaultValue
[
0
]
instanceof
Text
);
assert
.
equal
(
defaultValue
[
0
].
toString
(),
'
bar}
'
);
assert
.
ok
(
defaultValue
[
1
]
instanceof
Placeholder
);
assert
.
equal
(
defaultValue
[
1
].
toString
(),
'
foo
'
);
assert
.
ok
(
children
[
0
]
instanceof
Text
);
assert
.
equal
(
children
[
0
].
toString
(),
'
bar}
'
);
assert
.
ok
(
children
[
1
]
instanceof
Placeholder
);
assert
.
equal
(
children
[
1
].
toString
(),
'
foo
'
);
});
test
(
'
Parser, placeholder
'
,
()
=>
{
...
...
@@ -225,17 +225,17 @@ suite('SnippetParser', () => {
const
placeholder
=
<
Placeholder
>
marker
[
1
];
assert
.
equal
(
placeholder
,
false
);
assert
.
equal
(
placeholder
.
index
,
'
1
'
);
assert
.
equal
(
placeholder
.
defaultValue
.
length
,
3
);
assert
.
ok
(
placeholder
.
defaultValue
[
0
]
instanceof
Text
);
assert
.
ok
(
placeholder
.
defaultValue
[
1
]
instanceof
Variable
);
assert
.
ok
(
placeholder
.
defaultValue
[
2
]
instanceof
Text
);
assert
.
equal
(
placeholder
.
defaultValue
[
0
].
toString
(),
'
'
);
assert
.
equal
(
placeholder
.
defaultValue
[
1
].
toString
(),
''
);
assert
.
equal
(
placeholder
.
defaultValue
[
2
].
toString
(),
'
'
);
const
nestedVariable
=
<
Variable
>
placeholder
.
defaultValue
[
1
];
assert
.
equal
(
placeholder
.
children
.
length
,
3
);
assert
.
ok
(
placeholder
.
children
[
0
]
instanceof
Text
);
assert
.
ok
(
placeholder
.
children
[
1
]
instanceof
Variable
);
assert
.
ok
(
placeholder
.
children
[
2
]
instanceof
Text
);
assert
.
equal
(
placeholder
.
children
[
0
].
toString
(),
'
'
);
assert
.
equal
(
placeholder
.
children
[
1
].
toString
(),
''
);
assert
.
equal
(
placeholder
.
children
[
2
].
toString
(),
'
'
);
const
nestedVariable
=
<
Variable
>
placeholder
.
children
[
1
];
assert
.
equal
(
nestedVariable
.
name
,
'
TM_SELECTED_TEXT
'
);
assert
.
equal
(
nestedVariable
.
defaultValue
.
length
,
0
);
assert
.
equal
(
nestedVariable
.
children
.
length
,
0
);
marker
=
new
SnippetParser
().
parse
(
'
$TM_SELECTED_TEXT
'
);
assert
.
equal
(
marker
.
length
,
1
);
...
...
@@ -268,13 +268,13 @@ suite('SnippetParser', () => {
const
[
p1
,
,
p2
,
,
p3
]
=
new
SnippetParser
().
parse
(
'
{{first}}-{{2:}}-{{second}}-{{1:}}
'
);
assert
.
equal
((
<
Placeholder
>
p1
).
index
,
'
first
'
);
assert
.
equal
(
Marker
.
toString
((
<
Placeholder
>
p1
).
defaultValue
),
'
first
'
);
assert
.
equal
(
Marker
.
toString
((
<
Placeholder
>
p1
).
children
),
'
first
'
);
assert
.
equal
((
<
Placeholder
>
p2
).
index
,
'
2
'
);
assert
.
equal
(
Marker
.
toString
((
<
Placeholder
>
p2
).
defaultValue
),
''
);
assert
.
equal
(
Marker
.
toString
((
<
Placeholder
>
p2
).
children
),
''
);
assert
.
equal
((
<
Placeholder
>
p3
).
index
,
'
second
'
);
assert
.
equal
(
Marker
.
toString
((
<
Placeholder
>
p3
).
defaultValue
),
'
second
'
);
assert
.
equal
(
Marker
.
toString
((
<
Placeholder
>
p3
).
children
),
'
second
'
);
});
test
(
'
Parser, default placeholder values
'
,
()
=>
{
...
...
@@ -284,12 +284,12 @@ suite('SnippetParser', () => {
const
[,
p1
,
,
p2
]
=
new
SnippetParser
().
parse
(
'
errorContext: `${1:err}`, error:$1
'
);
assert
.
equal
((
<
Placeholder
>
p1
).
index
,
'
1
'
);
assert
.
equal
((
<
Placeholder
>
p1
).
defaultValue
.
length
,
'
1
'
);
assert
.
equal
((
<
Text
>
(
<
Placeholder
>
p1
).
defaultValue
[
0
]),
'
err
'
);
assert
.
equal
((
<
Placeholder
>
p1
).
children
.
length
,
'
1
'
);
assert
.
equal
((
<
Text
>
(
<
Placeholder
>
p1
).
children
[
0
]),
'
err
'
);
assert
.
equal
((
<
Placeholder
>
p2
).
index
,
'
1
'
);
assert
.
equal
((
<
Placeholder
>
p2
).
defaultValue
.
length
,
'
1
'
);
assert
.
equal
((
<
Text
>
(
<
Placeholder
>
p2
).
defaultValue
[
0
]),
'
err
'
);
assert
.
equal
((
<
Placeholder
>
p2
).
children
.
length
,
'
1
'
);
assert
.
equal
((
<
Text
>
(
<
Placeholder
>
p2
).
children
[
0
]),
'
err
'
);
});
...
...
@@ -309,8 +309,8 @@ suite('SnippetParser', () => {
test
(
'
marker#len
'
,
()
=>
{
function
assertLen
(
template
:
string
,
...
lengths
:
number
[]):
void
{
const
{
marker
}
=
SnippetParser
.
parse
(
template
);
walk
(
marker
,
m
=>
{
const
{
children
}
=
SnippetParser
.
parse
(
template
);
walk
(
children
,
m
=>
{
const
expected
=
lengths
.
shift
();
assert
.
equal
(
m
.
len
(),
expected
);
return
true
;
...
...
@@ -335,15 +335,15 @@ suite('SnippetParser', () => {
assert
.
equal
(
first
.
index
,
'
1
'
);
assert
.
equal
(
second
.
index
,
'
2
'
);
assert
.
ok
(
second
.
parent
===
first
);
assert
.
ok
(
first
.
parent
===
undefined
);
assert
.
ok
(
first
.
parent
===
snippet
);
snippet
=
SnippetParser
.
parse
(
'
${VAR:default${1:value}}$0
'
);
assert
.
equal
(
snippet
.
placeholders
.
length
,
2
);
[
first
]
=
snippet
.
placeholders
;
assert
.
equal
(
first
.
index
,
'
1
'
);
assert
.
ok
(
snippet
.
marker
[
0
]
instanceof
Variable
);
assert
.
ok
(
first
.
parent
===
snippet
.
marker
[
0
]);
assert
.
ok
(
snippet
.
children
[
0
]
instanceof
Variable
);
assert
.
ok
(
first
.
parent
===
snippet
.
children
[
0
]);
});
test
(
'
TextmateSnippet#enclosingPlaceholders
'
,
function
()
{
...
...
@@ -356,13 +356,13 @@ suite('SnippetParser', () => {
test
(
'
TextmateSnippet#offset
'
,
()
=>
{
let
snippet
=
SnippetParser
.
parse
(
'
te$1xt
'
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
marker
[
0
]),
0
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
marker
[
1
]),
2
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
marker
[
2
]),
2
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
children
[
0
]),
0
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
children
[
1
]),
2
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
children
[
2
]),
2
);
snippet
=
SnippetParser
.
parse
(
'
${TM_SELECTED_TEXT:def}
'
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
marker
[
0
]),
0
);
assert
.
equal
(
snippet
.
offset
((
<
Variable
>
snippet
.
marker
[
0
]).
defaultValue
[
0
]),
0
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
children
[
0
]),
0
);
assert
.
equal
(
snippet
.
offset
((
<
Variable
>
snippet
.
children
[
0
]).
children
[
0
]),
0
);
// forgein marker
assert
.
equal
(
snippet
.
offset
(
new
Text
(
'
foo
'
)),
-
1
);
...
...
@@ -386,4 +386,18 @@ suite('SnippetParser', () => {
placeholders
=
snippet
.
placeholders
;
assert
.
equal
(
placeholders
.
length
,
3
);
});
test
(
'
TextmateSnippet#replace
'
,
function
()
{
let
snippet
=
SnippetParser
.
parse
(
'
aaa${1:bbb${2:ccc}}$0
'
);
assert
.
equal
(
snippet
.
placeholders
.
length
,
3
);
const
[,
second
]
=
snippet
.
placeholders
;
assert
.
equal
(
second
.
index
,
'
2
'
);
let
nested
=
SnippetParser
.
parse
(
'
ddd$1eee$0
'
);
snippet
.
replace
(
second
,
nested
.
children
);
assert
.
equal
(
snippet
.
text
,
'
aaabbbdddeee
'
);
assert
.
equal
(
snippet
.
placeholders
.
length
,
4
);
});
});
src/vs/workbench/parts/emmet/electron-browser/editorAccessor.ts
浏览文件 @
038703dc
...
...
@@ -144,14 +144,14 @@ export class EditorAccessor implements emmet.Editor {
return
SnippetParser
.
escape
(
marker
.
string
);
}
else
if
(
marker
instanceof
Placeholder
)
{
if
(
marker
.
defaultValue
.
length
>
0
)
{
return
`
\$
{
${
marker
.
index
}
:
${
marker
.
defaultValue
.
map
(
toSnippetString
).
join
(
''
)}
}`
;
if
(
marker
.
children
.
length
>
0
)
{
return
`
\$
{
${
marker
.
index
}
:
${
marker
.
children
.
map
(
toSnippetString
).
join
(
''
)}
}`
;
}
else
{
return
`
\$
${
marker
.
index
}
`
;
}
}
else
if
(
marker
instanceof
Variable
)
{
if
(
marker
.
defaultValue
.
length
>
0
)
{
return
`
\$
{
${
marker
.
name
}
:
${
marker
.
defaultValue
.
map
(
toSnippetString
).
join
(
''
)}
}`
;
if
(
marker
.
children
.
length
>
0
)
{
return
`
\$
{
${
marker
.
name
}
:
${
marker
.
children
.
map
(
toSnippetString
).
join
(
''
)}
}`
;
}
else
{
return
`
\$
${
marker
.
name
}
`
;
}
...
...
src/vs/workbench/parts/snippets/electron-browser/TMSnippets.ts
浏览文件 @
038703dc
...
...
@@ -169,13 +169,13 @@ function _rewriteBogousVariables(snippet: ISnippet): boolean {
return
SnippetParser
.
escape
(
marker
.
string
);
}
else
if
(
marker
instanceof
Placeholder
)
{
if
(
marker
.
defaultValue
.
length
>
0
)
{
return
`
\$
{
${
marker
.
index
}
:
${
marker
.
defaultValue
.
map
(
fixBogousVariables
).
join
(
''
)}
}`
;
if
(
marker
.
children
.
length
>
0
)
{
return
`
\$
{
${
marker
.
index
}
:
${
marker
.
children
.
map
(
fixBogousVariables
).
join
(
''
)}
}`
;
}
else
{
return
`
\$
${
marker
.
index
}
`
;
}
}
else
if
(
marker
instanceof
Variable
)
{
if
(
marker
.
defaultValue
.
length
===
0
&&
!
EditorSnippetVariableResolver
.
VariableNames
[
marker
.
name
])
{
if
(
marker
.
children
.
length
===
0
&&
!
EditorSnippetVariableResolver
.
VariableNames
[
marker
.
name
])
{
// a 'variable' without a default value and not being one of our supported
// variables is automatically turing into a placeholder. This is to restore
// a bug we had before. So `${foo}` becomes `${N:foo}`
...
...
@@ -183,8 +183,8 @@ function _rewriteBogousVariables(snippet: ISnippet): boolean {
placeholders
.
set
(
marker
.
name
,
index
);
return
`
\$
{
${
index
++
}
:
${
marker
.
name
}
}`
;
}
else
if
(
marker
.
defaultValue
.
length
>
0
)
{
return
`
\$
{
${
marker
.
name
}
:
${
marker
.
defaultValue
.
map
(
fixBogousVariables
).
join
(
''
)}
}`
;
}
else
if
(
marker
.
children
.
length
>
0
)
{
return
`
\$
{
${
marker
.
name
}
:
${
marker
.
children
.
map
(
fixBogousVariables
).
join
(
''
)}
}`
;
}
else
{
return
`
\$
${
marker
.
name
}
`
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录