Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
3703614f
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,发现更多精彩内容 >>
提交
3703614f
编写于
5月 12, 2017
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
better support for nested placeholders
上级
9a0567a6
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
84 addition
and
26 deletion
+84
-26
src/vs/editor/contrib/snippet/browser/snippetSession.ts
src/vs/editor/contrib/snippet/browser/snippetSession.ts
+24
-13
src/vs/editor/contrib/snippet/common/snippetParser.ts
src/vs/editor/contrib/snippet/common/snippetParser.ts
+20
-0
src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts
...editor/contrib/snippet/test/browser/snippetParser.test.ts
+27
-0
src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts
...ditor/contrib/snippet/test/browser/snippetSession.test.ts
+13
-13
未找到文件。
src/vs/editor/contrib/snippet/browser/snippetSession.ts
浏览文件 @
3703614f
...
...
@@ -89,31 +89,26 @@ class OneSnippet {
this
.
_init
();
let
prevGroupsIdx
=
-
1
;
if
(
fwd
&&
this
.
_placeholderGroupsIdx
<
this
.
_placeholderGroups
.
length
-
1
)
{
prevGroupsIdx
=
this
.
_placeholderGroupsIdx
;
this
.
_placeholderGroupsIdx
+=
1
;
}
else
if
(
!
fwd
&&
this
.
_placeholderGroupsIdx
>
0
)
{
prevGroupsIdx
=
this
.
_placeholderGroupsIdx
;
this
.
_placeholderGroupsIdx
-=
1
;
}
else
{
// the selection of the current placeholder might
// not acurate any more -> simply restore it
}
return
this
.
_editor
.
getModel
().
changeDecorations
(
accessor
=>
{
// change stickness to never grow when typing at its edges
// so that in-active tabstops never grow
if
(
prevGroupsIdx
!==
-
1
)
{
for
(
const
placeholder
of
this
.
_placeholderGroups
[
prevGroupsIdx
])
{
const
id
=
this
.
_placeholderDecorations
.
get
(
placeholder
);
accessor
.
changeDecorationOptions
(
id
,
OneSnippet
.
_decor
.
inactive
);
}
}
const
activePlaceholders
=
new
Set
<
Placeholder
>
();
// change stickiness to always grow when typing at its edges
// because these decorations represent the currently active
// tabstop. Special case: reaching the final tab stop
// tabstop.
// Special case #1: reaching the final tabstop
// Special case #2: placeholders enclosing active placeholders
const
selections
:
Selection
[]
=
[];
for
(
const
placeholder
of
this
.
_placeholderGroups
[
this
.
_placeholderGroupsIdx
])
{
const
id
=
this
.
_placeholderDecorations
.
get
(
placeholder
);
...
...
@@ -121,7 +116,23 @@ class OneSnippet {
selections
.
push
(
new
Selection
(
range
.
startLineNumber
,
range
.
startColumn
,
range
.
endLineNumber
,
range
.
endColumn
));
accessor
.
changeDecorationOptions
(
id
,
placeholder
.
isFinalTabstop
?
OneSnippet
.
_decor
.
activeFinal
:
OneSnippet
.
_decor
.
active
);
activePlaceholders
.
add
(
placeholder
);
for
(
const
enclosingPlaceholder
of
this
.
_snippet
.
enclosingPlaceholders
(
placeholder
))
{
const
id
=
this
.
_placeholderDecorations
.
get
(
enclosingPlaceholder
);
accessor
.
changeDecorationOptions
(
id
,
enclosingPlaceholder
.
isFinalTabstop
?
OneSnippet
.
_decor
.
activeFinal
:
OneSnippet
.
_decor
.
active
);
activePlaceholders
.
add
(
enclosingPlaceholder
);
}
}
// change stickness to never grow when typing at its edges
// so that in-active tabstops never grow
this
.
_placeholderDecorations
.
forEach
((
id
,
placeholder
)
=>
{
if
(
!
activePlaceholders
.
has
(
placeholder
))
{
accessor
.
changeDecorationOptions
(
id
,
OneSnippet
.
_decor
.
inactive
);
}
});
return
selections
;
});
}
...
...
src/vs/editor/contrib/snippet/common/snippetParser.ts
浏览文件 @
3703614f
...
...
@@ -132,6 +132,12 @@ export abstract class Marker {
return
result
;
}
parent
:
Marker
;
protected
_adopt
(
child
:
Marker
):
void
{
child
.
parent
=
this
;
}
toString
()
{
return
''
;
}
...
...
@@ -179,6 +185,7 @@ export class Placeholder extends Marker {
constructor
(
public
index
:
string
=
''
,
public
defaultValue
:
Marker
[])
{
super
();
defaultValue
.
forEach
(
this
.
_adopt
,
this
);
}
get
isFinalTabstop
()
{
return
this
.
index
===
'
0
'
;
...
...
@@ -194,6 +201,7 @@ export class Variable extends Marker {
constructor
(
public
name
:
string
=
''
,
public
defaultValue
:
Marker
[])
{
super
();
defaultValue
.
forEach
(
this
.
_adopt
,
this
);
}
get
isDefined
():
boolean
{
return
this
.
resolvedValue
!==
undefined
;
...
...
@@ -271,6 +279,18 @@ export class TextmateSnippet {
return
ret
;
}
enclosingPlaceholders
(
placeholder
:
Placeholder
):
Placeholder
[]
{
let
ret
:
Placeholder
[]
=
[];
let
{
parent
}
=
placeholder
;
while
(
parent
)
{
if
(
parent
instanceof
Placeholder
)
{
ret
.
push
(
parent
);
}
parent
=
parent
.
parent
;
}
return
ret
;
}
get
text
()
{
return
Marker
.
toString
(
this
.
marker
);
}
...
...
src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts
浏览文件 @
3703614f
...
...
@@ -327,6 +327,33 @@ suite('SnippetParser', () => {
assertLen
(
'
${TM_SELECTED_TEXT:def}$0
'
,
0
,
3
,
0
);
});
test
(
'
parser, parent node
'
,
function
()
{
let
snippet
=
SnippetParser
.
parse
(
'
This ${1:is ${2:nested}}$0
'
);
assert
.
equal
(
snippet
.
placeholders
.
length
,
3
);
let
[
first
,
second
]
=
snippet
.
placeholders
;
assert
.
equal
(
first
.
index
,
'
1
'
);
assert
.
equal
(
second
.
index
,
'
2
'
);
assert
.
ok
(
second
.
parent
===
first
);
assert
.
ok
(
first
.
parent
===
undefined
);
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
]);
});
test
(
'
TextmateSnippet#enclosingPlaceholders
'
,
function
()
{
let
snippet
=
SnippetParser
.
parse
(
'
This ${1:is ${2:nested}}$0
'
);
let
[
first
,
second
]
=
snippet
.
placeholders
;
assert
.
deepEqual
(
snippet
.
enclosingPlaceholders
(
first
),
[]);
assert
.
deepEqual
(
snippet
.
enclosingPlaceholders
(
second
),
[
first
]);
});
test
(
'
TextmateSnippet#offset
'
,
()
=>
{
let
snippet
=
SnippetParser
.
parse
(
'
te$1xt
'
);
assert
.
equal
(
snippet
.
offset
(
snippet
.
marker
[
0
]),
0
);
...
...
src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts
浏览文件 @
3703614f
...
...
@@ -378,23 +378,23 @@ suite('SnippetSession', function () {
assertSelections
(
editor
,
new
Selection
(
1
,
11
,
1
,
11
));
});
//
test('snippets, typing with nested placeholder', function () {
test
(
'
snippets, typing with nested placeholder
'
,
function
()
{
//
editor.setSelection(new Selection(1, 1, 1, 1));
//
const session = new SnippetSession(editor, 'This ${1:is ${2:nested}}.$0');
//
session.insert();
//
assertSelections(editor, new Selection(1, 6, 1, 15));
editor
.
setSelection
(
new
Selection
(
1
,
1
,
1
,
1
));
const
session
=
new
SnippetSession
(
editor
,
'
This ${1:is ${2:nested}}.$0
'
);
session
.
insert
();
assertSelections
(
editor
,
new
Selection
(
1
,
6
,
1
,
15
));
//
session.next();
//
assertSelections(editor, new Selection(1, 9, 1, 15));
session
.
next
();
assertSelections
(
editor
,
new
Selection
(
1
,
9
,
1
,
15
));
//
editor.trigger('test', 'deleteLeft', {});
//
assertSelections(editor, new Selection(1, 9, 1, 9));
editor
.
trigger
(
'
test
'
,
'
deleteLeft
'
,
{});
assertSelections
(
editor
,
new
Selection
(
1
,
9
,
1
,
9
));
//
editor.trigger('test', 'type', { text: 'XXX' });
//
session.prev();
//
assertSelections(editor, new Selection(1, 6, 1, 12));
//
});
editor
.
trigger
(
'
test
'
,
'
type
'
,
{
text
:
'
XXX
'
});
session
.
prev
();
assertSelections
(
editor
,
new
Selection
(
1
,
6
,
1
,
12
));
});
test
(
'
snippets, snippet with variables
'
,
function
()
{
const
session
=
new
SnippetSession
(
editor
,
'
@line=$TM_LINE_NUMBER$0
'
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录