Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
d50b568d
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,发现更多精彩内容 >>
提交
d50b568d
编写于
2月 11, 2019
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
multiple cursor in internal api of smart select, #41838
上级
8bbe6acd
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
138 addition
and
128 deletion
+138
-128
src/vs/editor/common/modes.ts
src/vs/editor/common/modes.ts
+1
-1
src/vs/editor/contrib/smartSelect/bracketSelections.ts
src/vs/editor/contrib/smartSelect/bracketSelections.ts
+13
-6
src/vs/editor/contrib/smartSelect/smartSelect.ts
src/vs/editor/contrib/smartSelect/smartSelect.ts
+67
-73
src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts
src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts
+4
-2
src/vs/editor/contrib/smartSelect/wordSelections.ts
src/vs/editor/contrib/smartSelect/wordSelections.ts
+10
-6
src/vs/editor/contrib/suggest/wordDistance.ts
src/vs/editor/contrib/suggest/wordDistance.ts
+4
-4
src/vs/monaco.d.ts
src/vs/monaco.d.ts
+1
-1
src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts
...kbench/api/electron-browser/mainThreadLanguageFeatures.ts
+2
-2
src/vs/workbench/api/node/extHost.protocol.ts
src/vs/workbench/api/node/extHost.protocol.ts
+1
-1
src/vs/workbench/api/node/extHostApiCommands.ts
src/vs/workbench/api/node/extHostApiCommands.ts
+8
-9
src/vs/workbench/api/node/extHostLanguageFeatures.ts
src/vs/workbench/api/node/extHostLanguageFeatures.ts
+20
-18
src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts
...ench/test/electron-browser/api/extHostApiCommands.test.ts
+4
-3
src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts
...test/electron-browser/api/extHostLanguageFeatures.test.ts
+3
-2
未找到文件。
src/vs/editor/common/modes.ts
浏览文件 @
d50b568d
...
...
@@ -1064,7 +1064,7 @@ export interface SelectionRangeProvider {
/**
* Provide ranges that should be selected from the given position.
*/
provideSelectionRanges
(
model
:
model
.
ITextModel
,
position
:
Position
,
token
:
CancellationToken
):
ProviderResult
<
SelectionRange
[]
>
;
provideSelectionRanges
(
model
:
model
.
ITextModel
,
position
s
:
Position
[],
token
:
CancellationToken
):
ProviderResult
<
SelectionRange
[]
[]
>
;
}
export
interface
FoldingContext
{
...
...
src/vs/editor/contrib/smartSelect/bracketSelections.ts
浏览文件 @
d50b568d
...
...
@@ -11,12 +11,19 @@ import { LinkedList } from 'vs/base/common/linkedList';
export
class
BracketSelectionRangeProvider
implements
SelectionRangeProvider
{
provideSelectionRanges
(
model
:
ITextModel
,
position
:
Position
):
Promise
<
SelectionRange
[]
>
{
const
bucket
:
SelectionRange
[]
=
[];
const
ranges
=
new
Map
<
string
,
LinkedList
<
Range
>>
();
return
new
Promise
(
resolve
=>
BracketSelectionRangeProvider
.
_bracketsRightYield
(
resolve
,
0
,
model
,
position
,
ranges
))
.
then
(()
=>
new
Promise
(
resolve
=>
BracketSelectionRangeProvider
.
_bracketsLeftYield
(
resolve
,
0
,
model
,
position
,
ranges
,
bucket
)))
.
then
(()
=>
bucket
);
async
provideSelectionRanges
(
model
:
ITextModel
,
positions
:
Position
[]):
Promise
<
SelectionRange
[][]
>
{
const
result
:
SelectionRange
[][]
=
[];
for
(
const
position
of
positions
)
{
const
bucket
:
SelectionRange
[]
=
[];
result
.
push
(
bucket
);
const
ranges
=
new
Map
<
string
,
LinkedList
<
Range
>>
();
await
new
Promise
(
resolve
=>
BracketSelectionRangeProvider
.
_bracketsRightYield
(
resolve
,
0
,
model
,
position
,
ranges
));
await
new
Promise
(
resolve
=>
BracketSelectionRangeProvider
.
_bracketsLeftYield
(
resolve
,
0
,
model
,
position
,
ranges
,
bucket
));
}
return
result
;
}
private
static
readonly
_maxDuration
=
30
;
...
...
src/vs/editor/contrib/smartSelect/smartSelect.ts
浏览文件 @
d50b568d
...
...
@@ -86,7 +86,7 @@ class SmartSelectController implements IEditorContribution {
let
promise
:
Promise
<
void
>
=
Promise
.
resolve
(
undefined
);
if
(
!
this
.
_state
)
{
promise
=
provideSelectionRanges
N
(
model
,
selections
.
map
(
s
=>
s
.
getPosition
()),
CancellationToken
.
None
).
then
(
ranges
=>
{
promise
=
provideSelectionRanges
(
model
,
selections
.
map
(
s
=>
s
.
getPosition
()),
CancellationToken
.
None
).
then
(
ranges
=>
{
if
(
!
arrays
.
isNonEmptyArray
(
ranges
)
||
ranges
.
length
!==
selections
.
length
)
{
// invalid result
return
;
...
...
@@ -210,99 +210,93 @@ registerEditorAction(ShrinkSelectionAction);
// word selection
modes
.
SelectionRangeRegistry
.
register
(
'
*
'
,
new
WordSelectionRangeProvider
());
export
function
provideSelectionRanges
(
model
:
ITextModel
,
position
:
Position
,
token
:
CancellationToken
):
Promise
<
Range
[]
|
undefined
|
null
>
{
export
function
provideSelectionRanges
(
model
:
ITextModel
,
position
s
:
Position
[],
token
:
CancellationToken
):
Promise
<
Range
[][]
>
{
const
provider
=
modes
.
SelectionRangeRegistry
.
orderedGroups
(
model
);
const
provider
s
=
modes
.
SelectionRangeRegistry
.
all
(
model
);
if
(
provider
.
length
===
1
)
{
if
(
provider
s
.
length
===
1
)
{
// add word selection and bracket selection when no provider exists
provider
.
unshift
([
new
BracketSelectionRangeProvider
()]);
}
interface
RankedRange
{
rank
:
number
;
range
:
Range
;
providers
.
unshift
(
new
BracketSelectionRangeProvider
());
}
let
work
:
Promise
<
any
>
[]
=
[];
let
ranges
:
RankedRange
[]
=
[];
let
rank
=
0
;
for
(
const
group
of
provider
)
{
rank
+=
1
;
for
(
const
prov
of
group
)
{
work
.
push
(
Promise
.
resolve
(
prov
.
provideSelectionRanges
(
model
,
position
,
token
)).
then
(
selectionRanges
=>
{
if
(
arrays
.
isNonEmptyArray
(
selectionRanges
)
)
{
for
(
const
sel
of
selectionRanges
)
{
if
(
Range
.
isIRange
(
sel
.
range
)
&&
Range
.
containsPosition
(
sel
.
range
,
position
))
{
ranges
.
push
({
range
:
Range
.
lift
(
sel
.
range
),
rank
}
);
let
allRawRanges
:
Range
[]
[]
=
[];
arrays
.
fill
(
positions
.
length
,
[],
allRawRanges
)
;
for
(
const
provider
of
providers
)
{
work
.
push
(
Promise
.
resolve
(
provider
.
provideSelectionRanges
(
model
,
positions
,
token
)).
then
(
allProviderRanges
=>
{
if
(
arrays
.
isNonEmptyArray
(
allProviderRanges
)
&&
allProviderRanges
.
length
===
positions
.
length
)
{
for
(
let
i
=
0
;
i
<
positions
.
length
;
i
++
)
{
for
(
const
oneProviderRanges
of
allProviderRanges
[
i
]
)
{
if
(
Range
.
isIRange
(
oneProviderRanges
.
range
)
&&
Range
.
containsPosition
(
oneProviderRanges
.
range
,
positions
[
i
]
))
{
allRawRanges
[
i
].
push
(
Range
.
lift
(
oneProviderRanges
.
range
)
);
}
}
}
}
));
}
}
}
));
}
return
Promise
.
all
(
work
).
then
(()
=>
{
if
(
ranges
.
length
===
0
)
{
return
[];
}
return
allRawRanges
.
map
(
oneRawRanges
=>
{
ranges
.
sort
((
a
,
b
)
=>
{
if
(
Position
.
isBefore
(
a
.
range
.
getStartPosition
(),
b
.
range
.
getStartPosition
()))
{
return
1
;
}
else
if
(
Position
.
isBefore
(
b
.
range
.
getStartPosition
(),
a
.
range
.
getStartPosition
()))
{
return
-
1
;
}
else
if
(
Position
.
isBefore
(
a
.
range
.
getEndPosition
(),
b
.
range
.
getEndPosition
()))
{
return
-
1
;
}
else
if
(
Position
.
isBefore
(
b
.
range
.
getEndPosition
(),
a
.
range
.
getEndPosition
()))
{
return
1
;
}
else
{
return
b
.
rank
-
a
.
rank
;
if
(
oneRawRanges
.
length
===
0
)
{
return
[];
}
});
let
result
:
Range
[]
=
[];
let
last
:
Range
|
undefined
;
for
(
const
{
range
}
of
ranges
)
{
if
(
!
last
||
(
Range
.
containsRange
(
range
,
last
)
&&
!
Range
.
equalsRange
(
range
,
last
)))
{
result
.
push
(
range
);
last
=
range
;
}
}
let
result2
:
Range
[]
=
[
result
[
0
]];
for
(
let
i
=
1
;
i
<
result
.
length
;
i
++
)
{
const
prev
=
result
[
i
-
1
];
const
cur
=
result
[
i
];
if
(
cur
.
startLineNumber
!==
prev
.
startLineNumber
||
cur
.
endLineNumber
!==
prev
.
endLineNumber
)
{
// add line/block range without leading/failing whitespace
const
rangeNoWhitespace
=
new
Range
(
prev
.
startLineNumber
,
model
.
getLineFirstNonWhitespaceColumn
(
prev
.
startLineNumber
),
prev
.
endLineNumber
,
model
.
getLineLastNonWhitespaceColumn
(
prev
.
endLineNumber
));
if
(
rangeNoWhitespace
.
containsRange
(
prev
)
&&
!
rangeNoWhitespace
.
equalsRange
(
prev
))
{
result2
.
push
(
rangeNoWhitespace
);
// sort all by start/end position
oneRawRanges
.
sort
((
a
,
b
)
=>
{
if
(
Position
.
isBefore
(
a
.
getStartPosition
(),
b
.
getStartPosition
()))
{
return
1
;
}
else
if
(
Position
.
isBefore
(
b
.
getStartPosition
(),
a
.
getStartPosition
()))
{
return
-
1
;
}
else
if
(
Position
.
isBefore
(
a
.
getEndPosition
(),
b
.
getEndPosition
()))
{
return
-
1
;
}
else
if
(
Position
.
isBefore
(
b
.
getEndPosition
(),
a
.
getEndPosition
()))
{
return
1
;
}
else
{
return
0
;
}
// add line/block range
const
rangeFull
=
new
Range
(
prev
.
startLineNumber
,
1
,
prev
.
endLineNumber
,
model
.
getLineMaxColumn
(
prev
.
endLineNumber
));
if
(
rangeFull
.
containsRange
(
prev
)
&&
!
rangeFull
.
equalsRange
(
rangeNoWhitespace
))
{
result2
.
push
(
rangeFull
);
});
// remove ranges that don't contain the former range or that are equal to the
// former range
let
oneRanges
:
Range
[]
=
[];
let
last
:
Range
|
undefined
;
for
(
const
range
of
oneRawRanges
)
{
if
(
!
last
||
(
Range
.
containsRange
(
range
,
last
)
&&
!
Range
.
equalsRange
(
range
,
last
)))
{
oneRanges
.
push
(
range
);
last
=
range
;
}
}
result2
.
push
(
cur
);
}
return
result2
;
});
}
export
function
provideSelectionRangesN
(
model
:
ITextModel
,
position
:
Position
[],
token
:
CancellationToken
):
Promise
<
Range
[][]
>
{
return
Promise
.
all
(
position
.
map
(
pos
=>
{
return
provideSelectionRanges
(
model
,
pos
,
token
).
then
(
value
=>
{
return
value
||
[];
// add ranges that expand trivia at line starts and ends whenever a range
// wraps onto the a new line
let
oneRangesWithTrivia
:
Range
[]
=
[
oneRanges
[
0
]];
for
(
let
i
=
1
;
i
<
oneRanges
.
length
;
i
++
)
{
const
prev
=
oneRanges
[
i
-
1
];
const
cur
=
oneRanges
[
i
];
if
(
cur
.
startLineNumber
!==
prev
.
startLineNumber
||
cur
.
endLineNumber
!==
prev
.
endLineNumber
)
{
// add line/block range without leading/failing whitespace
const
rangeNoWhitespace
=
new
Range
(
prev
.
startLineNumber
,
model
.
getLineFirstNonWhitespaceColumn
(
prev
.
startLineNumber
),
prev
.
endLineNumber
,
model
.
getLineLastNonWhitespaceColumn
(
prev
.
endLineNumber
));
if
(
rangeNoWhitespace
.
containsRange
(
prev
)
&&
!
rangeNoWhitespace
.
equalsRange
(
prev
))
{
oneRangesWithTrivia
.
push
(
rangeNoWhitespace
);
}
// add line/block range
const
rangeFull
=
new
Range
(
prev
.
startLineNumber
,
1
,
prev
.
endLineNumber
,
model
.
getLineMaxColumn
(
prev
.
endLineNumber
));
if
(
rangeFull
.
containsRange
(
prev
)
&&
!
rangeFull
.
equalsRange
(
rangeNoWhitespace
))
{
oneRangesWithTrivia
.
push
(
rangeFull
);
}
}
oneRangesWithTrivia
.
push
(
cur
);
}
return
oneRangesWithTrivia
;
});
})
)
;
});
}
registerDefaultLanguageCommand
(
'
_executeSelectionRangeProvider
'
,
function
(
model
,
position
)
{
return
provideSelectionRanges
(
model
,
position
,
CancellationToken
.
None
);
registerDefaultLanguageCommand
(
'
_executeSelectionRangeProvider
'
,
function
(
model
,
_position
,
args
)
{
return
provideSelectionRanges
(
model
,
args
.
positions
,
CancellationToken
.
None
);
});
src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts
浏览文件 @
d50b568d
...
...
@@ -79,7 +79,7 @@ suite('SmartSelect', () => {
async
function
assertGetRangesToPosition
(
text
:
string
[],
lineNumber
:
number
,
column
:
number
,
ranges
:
Range
[]):
Promise
<
void
>
{
let
uri
=
URI
.
file
(
'
test.js
'
);
let
model
=
modelService
.
createModel
(
text
.
join
(
'
\n
'
),
new
StaticLanguageSelector
(
mode
.
getLanguageIdentifier
()),
uri
);
let
actual
=
await
provideSelectionRanges
(
model
,
new
Position
(
lineNumber
,
column
)
,
CancellationToken
.
None
);
let
[
actual
]
=
await
provideSelectionRanges
(
model
,
[
new
Position
(
lineNumber
,
column
)]
,
CancellationToken
.
None
);
let
actualStr
=
actual
!
.
map
(
r
=>
new
Range
(
r
.
startLineNumber
,
r
.
startColumn
,
r
.
endLineNumber
,
r
.
endColumn
).
toString
());
let
desiredStr
=
ranges
.
reverse
().
map
(
r
=>
String
(
r
));
...
...
@@ -203,7 +203,9 @@ suite('SmartSelect', () => {
let
model
=
modelService
.
createModel
(
value
,
new
StaticLanguageSelector
(
mode
.
getLanguageIdentifier
()),
URI
.
parse
(
'
fake:lang
'
));
let
pos
=
model
.
getPositionAt
(
value
.
indexOf
(
'
|
'
));
let
ranges
=
await
provider
.
provideSelectionRanges
(
model
,
pos
,
CancellationToken
.
None
);
let
all
=
await
provider
.
provideSelectionRanges
(
model
,
[
pos
],
CancellationToken
.
None
);
let
ranges
=
all
!
[
0
];
modelService
.
destroyModel
(
model
.
uri
);
assert
.
equal
(
expected
.
length
,
ranges
!
.
length
);
...
...
src/vs/editor/contrib/smartSelect/wordSelections.ts
浏览文件 @
d50b568d
...
...
@@ -12,12 +12,16 @@ import { isUpperAsciiLetter, isLowerAsciiLetter } from 'vs/base/common/strings';
export
class
WordSelectionRangeProvider
implements
SelectionRangeProvider
{
provideSelectionRanges
(
model
:
ITextModel
,
position
:
Position
):
SelectionRange
[]
{
let
result
:
SelectionRange
[]
=
[];
this
.
_addInWordRanges
(
result
,
model
,
position
);
this
.
_addWordRanges
(
result
,
model
,
position
);
this
.
_addWhitespaceLine
(
result
,
model
,
position
);
result
.
push
({
range
:
model
.
getFullModelRange
(),
kind
:
'
statement.all
'
});
provideSelectionRanges
(
model
:
ITextModel
,
positions
:
Position
[]):
SelectionRange
[][]
{
const
result
:
SelectionRange
[][]
=
[];
for
(
const
position
of
positions
)
{
const
bucket
:
SelectionRange
[]
=
[];
result
.
push
(
bucket
);
this
.
_addInWordRanges
(
bucket
,
model
,
position
);
this
.
_addWordRanges
(
bucket
,
model
,
position
);
this
.
_addWhitespaceLine
(
bucket
,
model
,
position
);
bucket
.
push
({
range
:
model
.
getFullModelRange
(),
kind
:
'
statement.all
'
});
}
return
result
;
}
...
...
src/vs/editor/contrib/suggest/wordDistance.ts
浏览文件 @
d50b568d
...
...
@@ -34,11 +34,11 @@ export abstract class WordDistance {
return
Promise
.
resolve
(
WordDistance
.
None
);
}
return
new
BracketSelectionRangeProvider
().
provideSelectionRanges
(
model
,
position
).
then
(
ranges
=>
{
if
(
!
ranges
||
ranges
.
length
===
0
)
{
return
new
BracketSelectionRangeProvider
().
provideSelectionRanges
(
model
,
[
position
]
).
then
(
ranges
=>
{
if
(
!
ranges
||
ranges
.
length
===
0
||
ranges
[
0
].
length
===
0
)
{
return
WordDistance
.
None
;
}
return
service
.
computeWordRanges
(
model
.
uri
,
ranges
[
0
].
range
).
then
(
wordRanges
=>
{
return
service
.
computeWordRanges
(
model
.
uri
,
ranges
[
0
]
[
0
]
.
range
).
then
(
wordRanges
=>
{
return
new
class
extends
WordDistance
{
distance
(
anchor
:
IPosition
,
suggestion
:
CompletionItem
)
{
if
(
!
wordRanges
||
!
position
.
equals
(
editor
.
getPosition
()))
{
...
...
@@ -55,7 +55,7 @@ export abstract class WordDistance {
let
idx
=
binarySearch
(
wordLines
,
Range
.
fromPositions
(
anchor
),
Range
.
compareRangesUsingStarts
);
let
bestWordRange
=
idx
>=
0
?
wordLines
[
idx
]
:
wordLines
[
Math
.
max
(
0
,
~
idx
-
1
)];
let
blockDistance
=
ranges
.
length
;
for
(
const
range
of
ranges
)
{
for
(
const
range
of
ranges
[
0
]
)
{
if
(
!
Range
.
containsRange
(
range
.
range
,
bestWordRange
))
{
break
;
}
...
...
src/vs/monaco.d.ts
浏览文件 @
d50b568d
...
...
@@ -5303,7 +5303,7 @@ declare namespace monaco.languages {
/**
* Provide ranges that should be selected from the given position.
*/
provideSelectionRanges
(
model
:
editor
.
ITextModel
,
position
:
Position
,
token
:
CancellationToken
):
ProviderResult
<
SelectionRange
[]
>
;
provideSelectionRanges
(
model
:
editor
.
ITextModel
,
position
s
:
Position
[],
token
:
CancellationToken
):
ProviderResult
<
SelectionRange
[]
[]
>
;
}
export
interface
FoldingContext
{
...
...
src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts
浏览文件 @
d50b568d
...
...
@@ -408,8 +408,8 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
$registerSelectionRangeProvider
(
handle
:
number
,
selector
:
ISerializedDocumentFilter
[]):
void
{
this
.
_registrations
[
handle
]
=
modes
.
SelectionRangeRegistry
.
register
(
typeConverters
.
LanguageSelector
.
from
(
selector
),
{
provideSelectionRanges
:
(
model
,
position
,
token
)
=>
{
return
this
.
_proxy
.
$provideSelectionRanges
(
handle
,
model
.
uri
,
position
,
token
);
provideSelectionRanges
:
(
model
,
position
s
,
token
)
=>
{
return
this
.
_proxy
.
$provideSelectionRanges
(
handle
,
model
.
uri
,
position
s
,
token
);
}
});
}
...
...
src/vs/workbench/api/node/extHost.protocol.ts
浏览文件 @
d50b568d
...
...
@@ -921,7 +921,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideDocumentColors
(
handle
:
number
,
resource
:
UriComponents
,
token
:
CancellationToken
):
Promise
<
IRawColorInfo
[]
>
;
$provideColorPresentations
(
handle
:
number
,
resource
:
UriComponents
,
colorInfo
:
IRawColorInfo
,
token
:
CancellationToken
):
Promise
<
modes
.
IColorPresentation
[]
>
;
$provideFoldingRanges
(
handle
:
number
,
resource
:
UriComponents
,
context
:
modes
.
FoldingContext
,
token
:
CancellationToken
):
Promise
<
modes
.
FoldingRange
[]
>
;
$provideSelectionRanges
(
handle
:
number
,
resource
:
UriComponents
,
position
:
IPosition
,
token
:
CancellationToken
):
Promise
<
modes
.
SelectionRange
[]
>
;
$provideSelectionRanges
(
handle
:
number
,
resource
:
UriComponents
,
position
s
:
IPosition
[],
token
:
CancellationToken
):
Promise
<
modes
.
SelectionRange
[]
[]
>
;
}
export
interface
ExtHostQuickOpenShape
{
...
...
src/vs/workbench/api/node/extHostApiCommands.ts
浏览文件 @
d50b568d
...
...
@@ -17,7 +17,7 @@ import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
import
{
CustomCodeAction
}
from
'
vs/workbench/api/node/extHostLanguageFeatures
'
;
import
{
ICommandsExecutor
,
PreviewHTMLAPICommand
,
OpenFolderAPICommand
,
DiffAPICommand
,
OpenAPICommand
,
RemoveFromRecentlyOpenedAPICommand
,
SetEditorLayoutAPICommand
}
from
'
./apiCommands
'
;
import
{
EditorGroupLayout
}
from
'
vs/workbench/services/editor/common/editorGroupsService
'
;
import
{
isFalsyOrEmpty
,
isNonEmptyArray
}
from
'
vs/base/common/arrays
'
;
import
{
isFalsyOrEmpty
}
from
'
vs/base/common/arrays
'
;
export
class
ExtHostApiCommands
{
...
...
@@ -199,7 +199,7 @@ export class ExtHostApiCommands {
description
:
'
Execute selection range provider.
'
,
args
:
[
{
name
:
'
uri
'
,
description
:
'
Uri of a text document
'
,
constraint
:
URI
},
{
name
:
'
position
'
,
description
:
'
Position in a text document
'
,
constraint
:
types
.
Position
}
{
name
:
'
position
s
'
,
description
:
'
Positions in a text document
'
,
constraint
:
a
=>
Array
.
isArray
(
a
)
}
],
returns
:
'
A promise that resolves to an array of ranges.
'
});
...
...
@@ -420,16 +420,15 @@ export class ExtHostApiCommands {
});
}
private
_executeSelectionRangeProvider
(
resource
:
URI
,
position
:
types
.
Position
):
Promise
<
vscode
.
SelectionRange
[]
>
{
private
_executeSelectionRangeProvider
(
resource
:
URI
,
positions
:
types
.
Position
[]):
Promise
<
vscode
.
SelectionRange
[][]
>
{
let
pos
=
positions
.
map
(
typeConverters
.
Position
.
from
);
const
args
=
{
resource
,
position
:
position
&&
typeConverters
.
Position
.
from
(
position
)
position
:
pos
[
0
],
positions
:
pos
};
return
this
.
_commands
.
executeCommand
<
modes
.
SelectionRange
[]
>
(
'
_executeSelectionRangeProvider
'
,
args
).
then
(
result
=>
{
if
(
isNonEmptyArray
(
result
))
{
return
result
.
map
(
typeConverters
.
SelectionRange
.
to
);
}
return
[];
return
this
.
_commands
.
executeCommand
<
modes
.
SelectionRange
[][]
>
(
'
_executeSelectionRangeProvider
'
,
args
).
then
(
result
=>
{
return
result
.
map
(
oneResult
=>
oneResult
.
map
(
typeConverters
.
SelectionRange
.
to
));
});
}
...
...
src/vs/workbench/api/node/extHostLanguageFeatures.ts
浏览文件 @
d50b568d
...
...
@@ -876,24 +876,26 @@ class SelectionRangeAdapter {
private
readonly
_provider
:
vscode
.
SelectionRangeProvider
)
{
}
provideSelectionRanges
(
resource
:
URI
,
position
:
IPosition
,
token
:
CancellationToken
):
Promise
<
modes
.
SelectionRange
[]
>
{
provideSelectionRanges
(
resource
:
URI
,
position
s
:
IPosition
[],
token
:
CancellationToken
):
Promise
<
modes
.
SelectionRange
[]
[]
>
{
const
{
document
}
=
this
.
_documents
.
getDocumentData
(
resource
);
const
pos
=
typeConvert
.
Position
.
to
(
position
);
return
asPromise
(()
=>
this
.
_provider
.
provideSelectionRanges
(
document
,
pos
,
token
)).
then
(
selectionRanges
=>
{
if
(
isFalsyOrEmpty
(
selectionRanges
))
{
return
undefined
;
}
let
result
:
modes
.
SelectionRange
[]
=
[];
let
last
:
vscode
.
Position
|
vscode
.
Range
=
pos
;
for
(
const
sel
of
selectionRanges
)
{
if
(
!
sel
.
range
.
contains
(
last
))
{
throw
new
Error
(
'
INVALID selection range, must contain the previous range
'
);
return
Promise
.
all
(
positions
.
map
(
position
=>
{
const
pos
=
typeConvert
.
Position
.
to
(
position
);
return
asPromise
(()
=>
this
.
_provider
.
provideSelectionRanges
(
document
,
pos
,
token
)).
then
(
selectionRanges
=>
{
if
(
isFalsyOrEmpty
(
selectionRanges
))
{
return
undefined
;
}
result
.
push
(
typeConvert
.
SelectionRange
.
from
(
sel
));
last
=
sel
.
range
;
}
return
result
;
});
let
oneResult
:
modes
.
SelectionRange
[]
=
[];
let
last
:
vscode
.
Position
|
vscode
.
Range
=
pos
;
for
(
const
sel
of
selectionRanges
)
{
if
(
!
sel
.
range
.
contains
(
last
))
{
throw
new
Error
(
'
INVALID selection range, must contain the previous range
'
);
}
oneResult
.
push
(
typeConvert
.
SelectionRange
.
from
(
sel
));
last
=
sel
.
range
;
}
return
oneResult
;
});
}));
}
}
...
...
@@ -1307,8 +1309,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return
this
.
_createDisposable
(
handle
);
}
$provideSelectionRanges
(
handle
:
number
,
resource
:
UriComponents
,
position
:
IPosition
,
token
:
CancellationToken
):
Promise
<
modes
.
SelectionRange
[]
>
{
return
this
.
_withAdapter
(
handle
,
SelectionRangeAdapter
,
adapter
=>
adapter
.
provideSelectionRanges
(
URI
.
revive
(
resource
),
position
,
token
));
$provideSelectionRanges
(
handle
:
number
,
resource
:
UriComponents
,
position
s
:
IPosition
[],
token
:
CancellationToken
):
Promise
<
modes
.
SelectionRange
[]
[]
>
{
return
this
.
_withAdapter
(
handle
,
SelectionRangeAdapter
,
adapter
=>
adapter
.
provideSelectionRanges
(
URI
.
revive
(
resource
),
position
s
,
token
));
}
// --- configuration
...
...
src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts
浏览文件 @
d50b568d
...
...
@@ -796,7 +796,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
// --- selection ranges
test
(
'
Links
, back and forth
'
,
async
function
()
{
test
(
'
Selection Range
, back and forth
'
,
async
function
()
{
disposables
.
push
(
extHost
.
registerSelectionRangeProvider
(
nullExtensionDescription
,
defaultSelector
,
<
vscode
.
SelectionRangeProvider
>
{
provideSelectionRanges
()
{
...
...
@@ -808,8 +808,9 @@ suite('ExtHostLanguageFeatureCommands', function () {
}));
await
rpcProtocol
.
sync
();
let
value
=
await
commands
.
executeCommand
<
vscode
.
DocumentLink
[]
>
(
'
vscode.executeSelectionRangeProvider
'
,
model
.
uri
,
new
types
.
Position
(
0
,
10
));
assert
.
ok
(
value
.
length
>=
2
);
let
value
=
await
commands
.
executeCommand
<
vscode
.
SelectionRange
[][]
>
(
'
vscode.executeSelectionRangeProvider
'
,
model
.
uri
,
[
new
types
.
Position
(
0
,
10
)]);
assert
.
equal
(
value
.
length
,
1
);
assert
.
ok
(
value
[
0
].
length
>=
2
);
});
});
src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts
浏览文件 @
d50b568d
...
...
@@ -1103,8 +1103,9 @@ suite('ExtHostLanguageFeatures', function () {
await
rpcProtocol
.
sync
();
provideSelectionRanges
(
model
,
new
Position
(
1
,
17
),
CancellationToken
.
None
).
then
(
ranges
=>
{
assert
.
ok
(
ranges
.
length
>=
2
);
provideSelectionRanges
(
model
,
[
new
Position
(
1
,
17
)],
CancellationToken
.
None
).
then
(
ranges
=>
{
assert
.
equal
(
ranges
.
length
,
1
);
assert
.
ok
(
ranges
[
0
].
length
>=
2
);
});
});
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录