Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
b7ae720d
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,发现更多精彩内容 >>
提交
b7ae720d
编写于
5月 10, 2017
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wire up variable resolver, resolve variables per selection
上级
47c0398d
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
145 addition
and
94 deletion
+145
-94
src/vs/editor/contrib/snippet/browser/editorSnippets.ts
src/vs/editor/contrib/snippet/browser/editorSnippets.ts
+14
-8
src/vs/editor/contrib/snippet/common/snippetParser.ts
src/vs/editor/contrib/snippet/common/snippetParser.ts
+9
-4
src/vs/editor/contrib/snippet/common/snippetVariables.ts
src/vs/editor/contrib/snippet/common/snippetVariables.ts
+50
-3
src/vs/editor/contrib/snippet/test/browser/editorSnippets.test.ts
...ditor/contrib/snippet/test/browser/editorSnippets.test.ts
+13
-5
src/vs/editor/contrib/snippet/test/browser/snippetVariables.test.ts
...tor/contrib/snippet/test/browser/snippetVariables.test.ts
+59
-74
未找到文件。
src/vs/editor/contrib/snippet/browser/editorSnippets.ts
浏览文件 @
b7ae720d
...
...
@@ -13,6 +13,7 @@ import { Selection } from 'vs/editor/common/core/selection';
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
IPosition
}
from
'
vs/editor/common/core/position
'
;
import
{
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
EditorSnippetVariableResolver
}
from
"
vs/editor/contrib/snippet/common/snippetVariables
"
;
class
OneSnippet
{
...
...
@@ -172,21 +173,26 @@ export class SnippetSession {
return
templateLines
.
join
(
model
.
getEOL
());
}
static
adjust
Range
(
model
:
IModel
,
range
:
Range
,
overwriteBefore
:
number
,
overwriteAfter
:
number
):
Range
{
static
adjust
Selection
(
model
:
IModel
,
selection
:
Selection
,
overwriteBefore
:
number
,
overwriteAfter
:
number
):
Selection
{
if
(
overwriteBefore
!==
0
||
overwriteAfter
!==
0
)
{
let
{
startLineNumber
,
startColumn
,
endLineNumber
,
endColumn
}
=
range
;
let
{
startLineNumber
,
startColumn
,
endLineNumber
,
endColumn
}
=
selection
;
startColumn
-=
overwriteBefore
;
endColumn
+=
overwriteAfter
;
range
=
Range
.
plusRange
(
range
,
{
const
range
=
model
.
validateRange
(
Range
.
plusRange
(
selection
,
{
startLineNumber
,
startColumn
,
endLineNumber
,
endColumn
,
});
range
=
model
.
validateRange
(
range
);
}));
selection
=
Selection
.
createWithDirection
(
range
.
startLineNumber
,
range
.
startColumn
,
range
.
endLineNumber
,
range
.
endColumn
,
selection
.
getDirection
()
);
}
return
range
;
return
selection
;
}
private
readonly
_editor
:
ICommonCodeEditor
;
...
...
@@ -222,11 +228,11 @@ export class SnippetSession {
.
sort
((
a
,
b
)
=>
Range
.
compareRangesUsingStarts
(
a
.
selection
,
b
.
selection
));
for
(
const
{
selection
,
idx
}
of
indexedSelection
)
{
const
range
=
SnippetSession
.
adjust
Range
(
model
,
selection
,
this
.
_overwriteBefore
,
this
.
_overwriteAfter
);
const
range
=
SnippetSession
.
adjust
Selection
(
model
,
selection
,
this
.
_overwriteBefore
,
this
.
_overwriteAfter
);
const
start
=
range
.
getStartPosition
();
const
adjustedTemplate
=
SnippetSession
.
normalizeWhitespace
(
model
,
start
,
this
.
_template
);
const
snippet
=
SnippetParser
.
parse
(
adjustedTemplate
);
const
snippet
=
SnippetParser
.
parse
(
adjustedTemplate
)
.
resolveVariables
(
new
EditorSnippetVariableResolver
(
model
,
range
))
;
const
offset
=
model
.
getOffsetAt
(
start
)
+
delta
;
edits
[
idx
]
=
EditOperation
.
replaceMove
(
range
,
snippet
.
text
);
...
...
src/vs/editor/contrib/snippet/common/snippetParser.ts
浏览文件 @
b7ae720d
...
...
@@ -183,9 +183,6 @@ export class Placeholder extends Marker {
get
isFinalTabstop
()
{
return
this
.
index
===
'
0
'
;
}
with
(
defaultValue
:
Marker
[]):
Placeholder
{
return
new
Placeholder
(
this
.
index
,
defaultValue
);
}
toString
()
{
return
Marker
.
toString
(
this
.
defaultValue
);
}
...
...
@@ -201,6 +198,13 @@ export class Variable extends Marker {
get
isDefined
():
boolean
{
return
this
.
resolvedValue
!==
undefined
;
}
len
():
number
{
if
(
this
.
isDefined
)
{
return
this
.
resolvedValue
.
length
;
}
else
{
return
super
.
len
();
}
}
toString
()
{
return
this
.
isDefined
?
this
.
resolvedValue
:
Marker
.
toString
(
this
.
defaultValue
);
}
...
...
@@ -271,7 +275,7 @@ export class TextmateSnippet {
return
Marker
.
toString
(
this
.
marker
);
}
resolveVariables
(
resolver
:
{
resolve
(
name
:
string
):
string
}):
void
{
resolveVariables
(
resolver
:
{
resolve
(
name
:
string
):
string
}):
this
{
walk
(
this
.
marker
,
candidate
=>
{
if
(
candidate
instanceof
Variable
)
{
candidate
.
resolvedValue
=
resolver
.
resolve
(
candidate
.
name
);
...
...
@@ -282,6 +286,7 @@ export class TextmateSnippet {
}
return
true
;
});
return
this
;
}
}
...
...
src/vs/editor/contrib/snippet/common/snippetVariables.ts
浏览文件 @
b7ae720d
...
...
@@ -6,14 +6,61 @@
'
use strict
'
;
import
{
basename
,
dirname
,
normalize
}
from
'
vs/base/common/paths
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
import
{
ICommonCodeEditor
,
IModel
}
from
'
vs/editor/common/editorCommon
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
ISnippetVariableResolver
}
from
'
./snippet
'
;
export
class
EditorSnippetVariableResolver
{
constructor
(
private
readonly
_model
:
IModel
,
private
readonly
_selection
:
Selection
)
{
//
}
resolve
(
name
:
string
):
string
{
if
(
name
===
'
SELECTION
'
||
name
===
'
TM_SELECTED_TEXT
'
)
{
return
this
.
_model
.
getValueInRange
(
this
.
_selection
);
}
else
if
(
name
===
'
TM_CURRENT_LINE
'
)
{
return
this
.
_model
.
getLineContent
(
this
.
_selection
.
positionLineNumber
);
}
else
if
(
name
===
'
TM_CURRENT_WORD
'
)
{
const
info
=
this
.
_model
.
getWordAtPosition
({
lineNumber
:
this
.
_selection
.
positionLineNumber
,
column
:
this
.
_selection
.
positionColumn
});
return
info
?
info
.
word
:
''
;
}
else
if
(
name
===
'
TM_LINE_INDEX
'
)
{
return
String
(
this
.
_selection
.
positionLineNumber
-
1
);
}
else
if
(
name
===
'
TM_LINE_NUMBER
'
)
{
return
String
(
this
.
_selection
.
positionLineNumber
);
}
else
if
(
name
===
'
TM_FILENAME
'
)
{
return
basename
(
this
.
_model
.
uri
.
fsPath
);
}
else
if
(
name
===
'
TM_DIRECTORY
'
)
{
const
dir
=
dirname
(
this
.
_model
.
uri
.
fsPath
);
return
dir
!==
'
.
'
?
dir
:
''
;
}
else
if
(
name
===
'
TM_FILEPATH
'
)
{
return
this
.
_model
.
uri
.
fsPath
;
}
else
{
return
undefined
;
}
}
}
export
class
SnippetVariablesResolver
implements
ISnippetVariableResolver
{
private
_editor
:
editorCommon
.
ICommonCodeEditor
;
private
readonly
_editor
:
ICommonCodeEditor
;
constructor
(
editor
:
editorCommon
.
ICommonCodeEditor
)
{
constructor
(
editor
:
ICommonCodeEditor
)
{
this
.
_editor
=
editor
;
}
...
...
src/vs/editor/contrib/snippet/test/browser/editorSnippets.test.ts
浏览文件 @
b7ae720d
...
...
@@ -52,15 +52,15 @@ suite('SnippetSession', function () {
assertNormalized
(
new
Position
(
2
,
3
),
'
foo
\r\t
bar
'
,
'
foo
\n
bar
'
);
});
test
(
'
adjust selection (overwrite[Before|After]
'
,
function
()
{
test
(
'
adjust selection (overwrite[Before|After]
)
'
,
function
()
{
let
range
=
SnippetSession
.
adjust
Range
(
model
,
new
Range
(
1
,
2
,
1
,
2
),
1
,
0
);
let
range
=
SnippetSession
.
adjust
Selection
(
model
,
new
Selection
(
1
,
2
,
1
,
2
),
1
,
0
);
assert
.
ok
(
range
.
equalsRange
(
new
Range
(
1
,
1
,
1
,
2
)));
range
=
SnippetSession
.
adjust
Range
(
model
,
new
Range
(
1
,
2
,
1
,
2
),
1111
,
0
);
range
=
SnippetSession
.
adjust
Selection
(
model
,
new
Selection
(
1
,
2
,
1
,
2
),
1111
,
0
);
assert
.
ok
(
range
.
equalsRange
(
new
Range
(
1
,
1
,
1
,
2
)));
range
=
SnippetSession
.
adjust
Range
(
model
,
new
Range
(
1
,
2
,
1
,
2
),
0
,
10
);
range
=
SnippetSession
.
adjust
Selection
(
model
,
new
Selection
(
1
,
2
,
1
,
2
),
0
,
10
);
assert
.
ok
(
range
.
equalsRange
(
new
Range
(
1
,
2
,
1
,
12
)));
range
=
SnippetSession
.
adjust
Range
(
model
,
new
Range
(
1
,
2
,
1
,
2
),
0
,
10111
);
range
=
SnippetSession
.
adjust
Selection
(
model
,
new
Selection
(
1
,
2
,
1
,
2
),
0
,
10111
);
assert
.
ok
(
range
.
equalsRange
(
new
Range
(
1
,
2
,
1
,
17
)));
});
...
...
@@ -377,5 +377,13 @@ suite('SnippetSession', function () {
assertSelections
(
editor
,
new
Selection
(
1
,
11
,
1
,
11
));
});
test
(
'
snippets, snippet with variables
'
,
function
()
{
const
session
=
new
SnippetSession
(
editor
,
'
@line=$TM_LINE_NUMBER$0
'
);
session
.
insert
();
assert
.
equal
(
model
.
getValue
(),
'
@line=1function foo() {
\n
@line=2console.log(a);
\n
}
'
);
assertSelections
(
editor
,
new
Selection
(
1
,
8
,
1
,
8
),
new
Selection
(
2
,
12
,
2
,
12
));
});
});
src/vs/editor/contrib/snippet/test/browser/snippetVariables.test.ts
浏览文件 @
b7ae720d
...
...
@@ -8,112 +8,97 @@ import * as assert from 'assert';
import
{
isWindows
}
from
'
vs/base/common/platform
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
SnippetVariables
Resolver
}
from
'
vs/editor/contrib/snippet/common/snippetVariables
'
;
import
{
EditorSnippetVariable
Resolver
}
from
'
vs/editor/contrib/snippet/common/snippetVariables
'
;
import
{
SnippetParser
}
from
'
vs/editor/contrib/snippet/common/snippetParser
'
;
import
{
MockCodeEditor
,
withMockCodeEditor
}
from
'
vs/editor/test/common/mocks/mockCodeEditor
'
;
import
{
Model
}
from
'
vs/editor/common/model/model
'
;
suite
(
'
Snippet Variables Resolver
'
,
function
()
{
const
model
=
Model
.
createFromString
(
''
,
undefined
,
undefined
,
URI
.
parse
(
'
file:///foo/files/text.txt
'
));
let
model
:
Model
;
let
resolver
:
EditorSnippetVariableResolver
;
function
variablesTest
(
callback
:
(
editor
:
MockCodeEditor
,
resolver
:
SnippetVariablesResolver
)
=>
any
)
{
const
lines
:
string
[]
=
[
setup
(
function
()
{
model
=
Model
.
createFromString
([
'
this is line one
'
,
'
this is line two
'
,
'
this is line three
'
];
]
.
join
(
'
\n
'
),
undefined
,
undefined
,
URI
.
parse
(
'
file:///foo/files/text.txt
'
))
;
model
.
setValue
(
lines
.
join
(
'
\n
'
));
resolver
=
new
EditorSnippetVariableResolver
(
model
,
new
Selection
(
1
,
1
,
1
,
1
));
});
withMockCodeEditor
(
lines
,
{
model
},
editor
=>
{
callback
(
editor
,
new
SnippetVariablesResolver
(
editor
));
});
}
teardown
(
function
()
{
model
.
dispose
();
});
test
(
'
editor variables, basics
'
,
function
()
{
variablesTest
((
editor
,
resolver
)
=>
{
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILENAME
'
),
'
text.txt
'
);
assert
.
equal
(
resolver
.
resolve
(
'
something
'
),
undefined
);
editor
.
setModel
(
null
);
assert
.
throws
(()
=>
resolver
.
resolve
(
'
TM_FILENAME
'
));
});
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILENAME
'
),
'
text.txt
'
);
assert
.
equal
(
resolver
.
resolve
(
'
something
'
),
undefined
);
});
test
(
'
editor variables, file/dir
'
,
function
()
{
variablesTest
((
editor
,
resolver
)
=>
{
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILENAME
'
),
'
text.txt
'
);
if
(
!
isWindows
)
{
assert
.
equal
(
resolver
.
resolve
(
'
TM_DIRECTORY
'
),
'
/foo/files
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILEPATH
'
),
'
/foo/files/text.txt
'
);
}
editor
.
setModel
(
Model
.
createFromString
(
''
,
undefined
,
undefined
,
URI
.
parse
(
'
http://www.pb.o/abc/def/ghi
'
)));
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILENAME
'
),
'
ghi
'
);
if
(
!
isWindows
)
{
assert
.
equal
(
resolver
.
resolve
(
'
TM_DIRECTORY
'
),
'
/abc/def
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILEPATH
'
),
'
/abc/def/ghi
'
);
}
editor
.
setModel
(
Model
.
createFromString
(
''
,
undefined
,
undefined
,
URI
.
parse
(
'
mem:fff.ts
'
)));
assert
.
equal
(
resolver
.
resolve
(
'
TM_DIRECTORY
'
),
''
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILEPATH
'
),
'
fff.ts
'
);
});
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILENAME
'
),
'
text.txt
'
);
if
(
!
isWindows
)
{
assert
.
equal
(
resolver
.
resolve
(
'
TM_DIRECTORY
'
),
'
/foo/files
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILEPATH
'
),
'
/foo/files/text.txt
'
);
}
resolver
=
new
EditorSnippetVariableResolver
(
Model
.
createFromString
(
''
,
undefined
,
undefined
,
URI
.
parse
(
'
http://www.pb.o/abc/def/ghi
'
)),
new
Selection
(
1
,
1
,
1
,
1
)
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILENAME
'
),
'
ghi
'
);
if
(
!
isWindows
)
{
assert
.
equal
(
resolver
.
resolve
(
'
TM_DIRECTORY
'
),
'
/abc/def
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILEPATH
'
),
'
/abc/def/ghi
'
);
}
resolver
=
new
EditorSnippetVariableResolver
(
Model
.
createFromString
(
''
,
undefined
,
undefined
,
URI
.
parse
(
'
mem:fff.ts
'
)),
new
Selection
(
1
,
1
,
1
,
1
)
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_DIRECTORY
'
),
''
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_FILEPATH
'
),
'
fff.ts
'
);
});
test
(
'
editor variables, selection
'
,
function
()
{
variablesTest
((
editor
,
resolver
)
=>
{
resolver
=
new
EditorSnippetVariableResolver
(
model
,
new
Selection
(
1
,
2
,
2
,
3
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_SELECTED_TEXT
'
),
'
his is line one
\n
th
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_LINE
'
),
'
this is line two
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_INDEX
'
),
'
1
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_NUMBER
'
),
'
2
'
);
editor
.
setSelection
(
new
Selection
(
1
,
2
,
2
,
3
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_SELECTED_TEXT
'
),
'
his is line one
\n
th
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_LINE
'
),
'
this is line two
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_INDEX
'
),
'
1
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_NUMBER
'
),
'
2
'
);
resolver
=
new
EditorSnippetVariableResolver
(
model
,
new
Selection
(
2
,
3
,
1
,
2
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_SELECTED_TEXT
'
),
'
his is line one
\n
th
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_LINE
'
),
'
this is line one
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_INDEX
'
),
'
0
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_NUMBER
'
),
'
1
'
);
editor
.
setSelection
(
new
Selection
(
2
,
3
,
1
,
2
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_SELECTED_TEXT
'
),
'
his is line one
\n
th
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_LINE
'
),
'
this is line one
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_INDEX
'
),
'
0
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_LINE_NUMBER
'
),
'
1
'
);
resolver
=
new
EditorSnippetVariableResolver
(
model
,
new
Selection
(
1
,
2
,
1
,
2
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_SELECTED_TEXT
'
),
''
);
editor
.
setSelection
(
new
Selection
(
1
,
2
,
1
,
2
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_SELECTED_TEXT
'
),
''
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_WORD
'
),
'
this
'
);
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_WORD
'
),
'
this
'
);
resolver
=
new
EditorSnippetVariableResolver
(
model
,
new
Selection
(
3
,
1
,
3
,
1
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_WORD
'
),
''
);
editor
.
setSelection
(
new
Selection
(
3
,
1
,
3
,
1
));
assert
.
equal
(
resolver
.
resolve
(
'
TM_CURRENT_WORD
'
),
''
);
});
});
test
(
'
TextmateSnippet, resolve variable
'
,
function
()
{
const
snippet
=
SnippetParser
.
parse
(
'
"$TM_CURRENT_WORD"
'
);
assert
.
equal
(
snippet
.
text
,
'
""
'
);
snippet
.
resolveVariables
(
resolver
);
assert
.
equal
(
snippet
.
text
,
'
"this"
'
);
const
snippet
=
SnippetParser
.
parse
(
'
"$TM_SELECTED_TEXT"
'
);
variablesTest
((
editor
,
resolver
)
=>
{
assert
.
equal
(
snippet
.
text
,
'
""
'
);
editor
.
setSelection
(
new
Selection
(
1
,
1
,
1
,
5
));
snippet
.
resolveVariables
(
resolver
);
assert
.
equal
(
snippet
.
text
,
'
"this"
'
);
});
});
test
(
'
TextmateSnippet, resolve variable with default
'
,
function
()
{
const
snippet
=
SnippetParser
.
parse
(
'
"${TM_SELECTED_TEXT:foo}"
'
);
variablesTest
((
editor
,
resolver
)
=>
{
assert
.
equal
(
snippet
.
text
,
'
"foo"
'
);
editor
.
setSelection
(
new
Selection
(
1
,
1
,
1
,
5
));
snippet
.
resolveVariables
(
resolver
);
assert
.
equal
(
snippet
.
text
,
'
"this"
'
);
});
const
snippet
=
SnippetParser
.
parse
(
'
"${TM_CURRENT_WORD:foo}"
'
);
assert
.
equal
(
snippet
.
text
,
'
"foo"
'
);
snippet
.
resolveVariables
(
resolver
);
assert
.
equal
(
snippet
.
text
,
'
"this"
'
);
});
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录