Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
徽霖
Vscode
提交
4ae7d630
V
Vscode
项目概览
徽霖
/
Vscode
通知
9
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
Vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4ae7d630
编写于
7月 10, 2019
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
know when a snippet needs clipboard access, #76847
上级
6505977f
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
85 addition
and
64 deletion
+85
-64
src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts
...nch/contrib/snippets/browser/snippetCompletionProvider.ts
+1
-2
src/vs/workbench/contrib/snippets/browser/snippetsFile.ts
src/vs/workbench/contrib/snippets/browser/snippetsFile.ts
+63
-60
src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts
...rkbench/contrib/snippets/test/browser/snippetFile.test.ts
+15
-0
src/vs/workbench/contrib/snippets/test/browser/snippetsRewrite.test.ts
...nch/contrib/snippets/test/browser/snippetsRewrite.test.ts
+6
-2
未找到文件。
src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts
浏览文件 @
4ae7d630
...
...
@@ -32,7 +32,7 @@ export class SnippetCompletion implements CompletionItem {
)
{
this
.
label
=
snippet
.
prefix
;
this
.
detail
=
localize
(
'
detail.snippet
'
,
"
{0} ({1})
"
,
snippet
.
description
||
snippet
.
name
,
snippet
.
source
);
this
.
insertText
=
snippet
.
body
;
this
.
insertText
=
snippet
.
codeSnippet
;
this
.
range
=
range
;
this
.
sortText
=
`
${
snippet
.
snippetSource
===
SnippetSource
.
Extension
?
'
z
'
:
'
a
'
}
-
${
snippet
.
prefix
}
`
;
this
.
kind
=
CompletionItemKind
.
Snippet
;
...
...
@@ -41,7 +41,6 @@ export class SnippetCompletion implements CompletionItem {
resolve
():
this
{
this
.
documentation
=
new
MarkdownString
().
appendCodeblock
(
''
,
new
SnippetParser
().
text
(
this
.
snippet
.
codeSnippet
));
this
.
insertText
=
this
.
snippet
.
codeSnippet
;
return
this
;
}
...
...
src/vs/workbench/contrib/snippets/browser/snippetsFile.ts
浏览文件 @
4ae7d630
...
...
@@ -13,11 +13,67 @@ import { isFalsyOrWhitespace } from 'vs/base/common/strings';
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
IExtensionDescription
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IdleValue
}
from
'
vs/base/common/async
'
;
class
SnippetBodyInsights
{
readonly
codeSnippet
:
string
;
readonly
isBogous
:
boolean
;
readonly
needsClipboard
:
boolean
;
constructor
(
body
:
string
)
{
// init with defaults
this
.
isBogous
=
false
;
this
.
needsClipboard
=
false
;
this
.
codeSnippet
=
body
;
// check snippet...
const
textmateSnippet
=
new
SnippetParser
().
parse
(
body
,
false
);
let
placeholders
=
new
Map
<
string
,
number
>
();
let
placeholderMax
=
0
;
for
(
const
placeholder
of
textmateSnippet
.
placeholders
)
{
placeholderMax
=
Math
.
max
(
placeholderMax
,
placeholder
.
index
);
}
let
stack
=
[...
textmateSnippet
.
children
];
while
(
stack
.
length
>
0
)
{
const
marker
=
stack
.
shift
()
!
;
if
(
marker
instanceof
Variable
)
{
if
(
marker
.
children
.
length
===
0
&&
!
KnownSnippetVariableNames
[
marker
.
name
])
{
// a 'variable' without a default value and not being one of our supported
// variables is automatically turned into a placeholder. This is to restore
// a bug we had before. So `${foo}` becomes `${N:foo}`
const
index
=
placeholders
.
has
(
marker
.
name
)
?
placeholders
.
get
(
marker
.
name
)
!
:
++
placeholderMax
;
placeholders
.
set
(
marker
.
name
,
index
);
const
synthetic
=
new
Placeholder
(
index
).
appendChild
(
new
Text
(
marker
.
name
));
textmateSnippet
.
replace
(
marker
,
[
synthetic
]);
this
.
isBogous
=
true
;
}
if
(
marker
.
name
===
'
CLIPBOARD
'
)
{
this
.
needsClipboard
=
true
;
}
}
else
{
// recurse
stack
.
push
(...
marker
.
children
);
}
}
if
(
this
.
isBogous
)
{
this
.
codeSnippet
=
textmateSnippet
.
toTextmateString
();
}
}
}
export
class
Snippet
{
private
_codeSnippet
:
string
;
private
_isBogous
:
boolean
;
private
readonly
_bodyInsights
:
IdleValue
<
SnippetBodyInsights
>
;
readonly
prefixLow
:
string
;
...
...
@@ -32,29 +88,19 @@ export class Snippet {
)
{
//
this
.
prefixLow
=
prefix
?
prefix
.
toLowerCase
()
:
prefix
;
this
.
_bodyInsights
=
new
IdleValue
(()
=>
new
SnippetBodyInsights
(
this
.
body
));
}
get
codeSnippet
():
string
{
this
.
_ensureCodeSnippet
();
return
this
.
_codeSnippet
;
return
this
.
_bodyInsights
.
getValue
().
codeSnippet
;
}
get
isBogous
():
boolean
{
this
.
_ensureCodeSnippet
();
return
this
.
_isBogous
;
return
this
.
_bodyInsights
.
getValue
().
isBogous
;
}
private
_ensureCodeSnippet
()
{
if
(
!
this
.
_codeSnippet
)
{
const
rewrite
=
Snippet
.
_rewriteBogousVariables
(
this
.
body
);
if
(
typeof
rewrite
===
'
string
'
)
{
this
.
_codeSnippet
=
rewrite
;
this
.
_isBogous
=
true
;
}
else
{
this
.
_codeSnippet
=
this
.
body
;
this
.
_isBogous
=
false
;
}
}
get
needsClipboard
():
boolean
{
return
this
.
_bodyInsights
.
getValue
().
needsClipboard
;
}
static
compare
(
a
:
Snippet
,
b
:
Snippet
):
number
{
...
...
@@ -70,49 +116,6 @@ export class Snippet {
return
0
;
}
}
static
_rewriteBogousVariables
(
template
:
string
):
false
|
string
{
const
textmateSnippet
=
new
SnippetParser
().
parse
(
template
,
false
);
let
placeholders
=
new
Map
<
string
,
number
>
();
let
placeholderMax
=
0
;
for
(
const
placeholder
of
textmateSnippet
.
placeholders
)
{
placeholderMax
=
Math
.
max
(
placeholderMax
,
placeholder
.
index
);
}
let
didChange
=
false
;
let
stack
=
[...
textmateSnippet
.
children
];
while
(
stack
.
length
>
0
)
{
const
marker
=
stack
.
shift
()
!
;
if
(
marker
instanceof
Variable
&&
marker
.
children
.
length
===
0
&&
!
KnownSnippetVariableNames
[
marker
.
name
]
)
{
// a 'variable' without a default value and not being one of our supported
// variables is automatically turned into a placeholder. This is to restore
// a bug we had before. So `${foo}` becomes `${N:foo}`
const
index
=
placeholders
.
has
(
marker
.
name
)
?
placeholders
.
get
(
marker
.
name
)
!
:
++
placeholderMax
;
placeholders
.
set
(
marker
.
name
,
index
);
const
synthetic
=
new
Placeholder
(
index
).
appendChild
(
new
Text
(
marker
.
name
));
textmateSnippet
.
replace
(
marker
,
[
synthetic
]);
didChange
=
true
;
}
else
{
// recurse
stack
.
push
(...
marker
.
children
);
}
}
if
(
!
didChange
)
{
return
false
;
}
else
{
return
textmateSnippet
.
toTextmateString
();
}
}
}
...
...
src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts
浏览文件 @
4ae7d630
...
...
@@ -65,4 +65,19 @@ suite('Snippets', function () {
});
test
(
'
Snippet#needsClipboard
'
,
function
()
{
function
assertNeedsClipboard
(
body
:
string
,
expected
:
boolean
):
void
{
let
snippet
=
new
Snippet
([
'
foo
'
],
'
FooSnippet1
'
,
'
foo
'
,
''
,
body
,
'
test
'
,
SnippetSource
.
User
);
assert
.
equal
(
snippet
.
needsClipboard
,
expected
);
}
assertNeedsClipboard
(
'
foo$CLIPBOARD
'
,
true
);
assertNeedsClipboard
(
'
${CLIPBOARD}
'
,
true
);
assertNeedsClipboard
(
'
foo${CLIPBOARD}bar
'
,
true
);
assertNeedsClipboard
(
'
foo$clipboard
'
,
false
);
assertNeedsClipboard
(
'
foo${clipboard}
'
,
false
);
assertNeedsClipboard
(
'
baba
'
,
false
);
});
});
src/vs/workbench/contrib/snippets/test/browser/snippetsRewrite.test.ts
浏览文件 @
4ae7d630
...
...
@@ -9,8 +9,12 @@ import { Snippet, SnippetSource } from 'vs/workbench/contrib/snippets/browser/sn
suite
(
'
SnippetRewrite
'
,
function
()
{
function
assertRewrite
(
input
:
string
,
expected
:
string
|
boolean
):
void
{
const
actual
=
Snippet
.
_rewriteBogousVariables
(
input
);
assert
.
equal
(
actual
,
expected
);
const
actual
=
new
Snippet
([
'
foo
'
],
'
foo
'
,
'
foo
'
,
'
foo
'
,
input
,
'
foo
'
,
SnippetSource
.
User
);
if
(
typeof
expected
===
'
boolean
'
)
{
assert
.
equal
(
actual
.
codeSnippet
,
input
);
}
else
{
assert
.
equal
(
actual
.
codeSnippet
,
expected
);
}
}
test
(
'
bogous variable rewrite
'
,
function
()
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录