Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
51ea3ac8
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,发现更多精彩内容 >>
提交
51ea3ac8
编写于
9月 11, 2018
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixes #51869
上级
603e7457
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
117 addition
and
49 deletion
+117
-49
src/vs/editor/contrib/multicursor/multicursor.ts
src/vs/editor/contrib/multicursor/multicursor.ts
+5
-18
src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts
src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts
+112
-31
未找到文件。
src/vs/editor/contrib/multicursor/multicursor.ts
浏览文件 @
51ea3ac8
...
...
@@ -663,13 +663,11 @@ export class CompatChangeAll extends MultiCursorSelectionControllerAction {
}
class
SelectionHighlighterState
{
public
readonly
lastWordUnderCursor
:
Selection
;
public
readonly
searchText
:
string
;
public
readonly
matchCase
:
boolean
;
public
readonly
wordSeparators
:
string
;
constructor
(
lastWordUnderCursor
:
Selection
,
searchText
:
string
,
matchCase
:
boolean
,
wordSeparators
:
string
)
{
this
.
lastWordUnderCursor
=
lastWordUnderCursor
;
constructor
(
searchText
:
string
,
matchCase
:
boolean
,
wordSeparators
:
string
)
{
this
.
searchText
=
searchText
;
this
.
matchCase
=
matchCase
;
this
.
wordSeparators
=
wordSeparators
;
...
...
@@ -723,7 +721,7 @@ export class SelectionHighlighter extends Disposable implements IEditorContribut
if
(
e
.
selection
.
isEmpty
())
{
if
(
e
.
reason
===
CursorChangeReason
.
Explicit
)
{
if
(
this
.
state
&&
(
!
this
.
state
.
lastWordUnderCursor
||
!
this
.
state
.
lastWordUnderCursor
.
containsPosition
(
e
.
selection
.
getStartPosition
()))
)
{
if
(
this
.
state
)
{
// no longer valid
this
.
_setState
(
null
);
}
...
...
@@ -791,21 +789,10 @@ export class SelectionHighlighter extends Disposable implements IEditorContribut
return
null
;
}
let
lastWordUnderCursor
:
Selection
=
null
;
const
hasFindOccurrences
=
DocumentHighlightProviderRegistry
.
has
(
model
);
if
(
r
.
currentMatch
)
{
// This is an empty selection
if
(
hasFindOccurrences
)
{
// Do not interfere with semantic word highlighting in the no selection case
return
null
;
}
const
config
=
editor
.
getConfiguration
();
if
(
!
config
.
contribInfo
.
occurrencesHighlight
)
{
return
null
;
}
lastWordUnderCursor
=
r
.
currentMatch
;
// Do not interfere with semantic word highlighting in the no selection case
return
null
;
}
if
(
/^
[
\t]
+$/
.
test
(
r
.
searchText
))
{
// whitespace only selection
...
...
@@ -837,7 +824,7 @@ export class SelectionHighlighter extends Disposable implements IEditorContribut
}
}
return
new
SelectionHighlighterState
(
lastWordUnderCursor
,
r
.
searchText
,
r
.
matchCase
,
r
.
wholeWord
?
editor
.
getConfiguration
().
wordSeparators
:
null
);
return
new
SelectionHighlighterState
(
r
.
searchText
,
r
.
matchCase
,
r
.
wholeWord
?
editor
.
getConfiguration
().
wordSeparators
:
null
);
}
private
_setState
(
state
:
SelectionHighlighterState
):
void
{
...
...
src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts
浏览文件 @
51ea3ac8
...
...
@@ -5,7 +5,7 @@
import
*
as
nls
from
'
vs/nls
'
;
import
{
first2
,
createCancelablePromise
,
CancelablePromise
}
from
'
vs/base/common/async
'
;
import
{
first2
,
createCancelablePromise
,
CancelablePromise
,
timeout
}
from
'
vs/base/common/async
'
;
import
{
onUnexpectedExternalError
,
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
*
as
editorCommon
from
'
vs/editor/common/editorCommon
'
;
...
...
@@ -13,6 +13,7 @@ import { registerEditorContribution, EditorAction, IActionOptions, registerEdito
import
{
DocumentHighlight
,
DocumentHighlightKind
,
DocumentHighlightProviderRegistry
}
from
'
vs/editor/common/modes
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
registerColor
,
editorSelectionHighlight
,
overviewRulerSelectionHighlightForeground
,
activeContrastBorder
,
editorSelectionHighlightBorder
}
from
'
vs/platform/theme/common/colorRegistry
'
;
import
{
registerThemingParticipant
,
themeColorFromId
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
CursorChangeReason
,
ICursorPositionChangedEvent
}
from
'
vs/editor/common/controller/cursorEvents
'
;
...
...
@@ -50,6 +51,112 @@ export function getOccurrencesAtPosition(model: ITextModel, position: Position,
}),
result
=>
!
isFalsyOrEmpty
(
result
));
}
interface
IOccurenceAtPositionRequest
{
readonly
result
:
Promise
<
DocumentHighlight
[]
>
;
isValid
(
model
:
ITextModel
,
selection
:
Selection
,
decorationIds
:
string
[]):
boolean
;
cancel
():
void
;
}
abstract
class
OccurenceAtPositionRequest
implements
IOccurenceAtPositionRequest
{
private
readonly
_wordRange
:
Range
;
public
readonly
result
:
CancelablePromise
<
DocumentHighlight
[]
>
;
constructor
(
model
:
ITextModel
,
selection
:
Selection
,
wordSeparators
:
string
)
{
this
.
_wordRange
=
this
.
_getCurrentWordRange
(
model
,
selection
);
this
.
result
=
createCancelablePromise
(
token
=>
this
.
_compute
(
model
,
selection
,
wordSeparators
,
token
));
}
protected
abstract
_compute
(
model
:
ITextModel
,
selection
:
Selection
,
wordSeparators
:
string
,
token
:
CancellationToken
):
Thenable
<
DocumentHighlight
[]
>
;
private
_getCurrentWordRange
(
model
:
ITextModel
,
selection
:
Selection
):
Range
{
const
word
=
model
.
getWordAtPosition
(
selection
.
getPosition
());
if
(
word
)
{
return
new
Range
(
selection
.
startLineNumber
,
word
.
startColumn
,
selection
.
startLineNumber
,
word
.
endColumn
);
}
return
null
;
}
public
isValid
(
model
:
ITextModel
,
selection
:
Selection
,
decorationIds
:
string
[]):
boolean
{
const
lineNumber
=
selection
.
startLineNumber
;
const
startColumn
=
selection
.
startColumn
;
const
endColumn
=
selection
.
endColumn
;
const
currentWordRange
=
this
.
_getCurrentWordRange
(
model
,
selection
);
let
requestIsValid
=
(
this
.
_wordRange
&&
this
.
_wordRange
.
equalsRange
(
currentWordRange
));
// Even if we are on a different word, if that word is in the decorations ranges, the request is still valid
// (Same symbol)
for
(
let
i
=
0
,
len
=
decorationIds
.
length
;
!
requestIsValid
&&
i
<
len
;
i
++
)
{
let
range
=
model
.
getDecorationRange
(
decorationIds
[
i
]);
if
(
range
&&
range
.
startLineNumber
===
lineNumber
)
{
if
(
range
.
startColumn
<=
startColumn
&&
range
.
endColumn
>=
endColumn
)
{
requestIsValid
=
true
;
}
}
}
return
requestIsValid
;
}
public
cancel
():
void
{
this
.
result
.
cancel
();
}
}
class
SemanticOccurenceAtPositionRequest
extends
OccurenceAtPositionRequest
{
protected
_compute
(
model
:
ITextModel
,
selection
:
Selection
,
wordSeparators
:
string
,
token
:
CancellationToken
):
Thenable
<
DocumentHighlight
[]
>
{
return
getOccurrencesAtPosition
(
model
,
selection
.
getPosition
(),
token
);
}
}
class
TextualOccurenceAtPositionRequest
extends
OccurenceAtPositionRequest
{
private
_selectionIsEmpty
:
boolean
;
constructor
(
model
:
ITextModel
,
selection
:
Selection
,
wordSeparators
:
string
)
{
super
(
model
,
selection
,
wordSeparators
);
this
.
_selectionIsEmpty
=
selection
.
isEmpty
();
}
protected
_compute
(
model
:
ITextModel
,
selection
:
Selection
,
wordSeparators
:
string
,
token
:
CancellationToken
):
Thenable
<
DocumentHighlight
[]
>
{
return
timeout
(
250
,
token
).
then
(()
=>
{
if
(
!
selection
.
isEmpty
())
{
return
[];
}
const
word
=
model
.
getWordAtPosition
(
selection
.
getPosition
());
if
(
!
word
)
{
return
[];
}
const
matches
=
model
.
findMatches
(
word
.
word
,
true
,
false
,
true
,
wordSeparators
,
false
);
return
matches
.
map
(
m
=>
{
return
{
range
:
m
.
range
,
kind
:
DocumentHighlightKind
.
Text
};
});
});
}
public
isValid
(
model
:
ITextModel
,
selection
:
Selection
,
decorationIds
:
string
[]):
boolean
{
const
currentSelectionIsEmpty
=
selection
.
isEmpty
();
if
(
this
.
_selectionIsEmpty
!==
currentSelectionIsEmpty
)
{
return
false
;
}
return
super
.
isValid
(
model
,
selection
,
decorationIds
);
}
}
function
computeOccurencesAtPosition
(
model
:
ITextModel
,
selection
:
Selection
,
wordSeparators
:
string
):
IOccurenceAtPositionRequest
{
if
(
DocumentHighlightProviderRegistry
.
has
(
model
))
{
return
new
SemanticOccurenceAtPositionRequest
(
model
,
selection
,
wordSeparators
);
}
return
new
TextualOccurenceAtPositionRequest
(
model
,
selection
,
wordSeparators
);
}
registerDefaultLanguageCommand
(
'
_executeDocumentHighlights
'
,
(
model
,
position
)
=>
getOccurrencesAtPosition
(
model
,
position
,
CancellationToken
.
None
));
class
WordHighlighter
{
...
...
@@ -57,12 +164,11 @@ class WordHighlighter {
private
editor
:
ICodeEditor
;
private
occurrencesHighlight
:
boolean
;
private
model
:
ITextModel
;
private
_lastWordRange
:
Range
;
private
_decorationIds
:
string
[];
private
toUnhook
:
IDisposable
[];
private
workerRequestTokenId
:
number
=
0
;
private
workerRequest
:
CancelablePromise
<
DocumentHighlight
[]
>
=
null
;
private
workerRequest
:
IOccurenceAtPositionRequest
;
private
workerRequestCompleted
:
boolean
=
false
;
private
workerRequestValue
:
DocumentHighlight
[]
=
[];
...
...
@@ -109,7 +215,6 @@ class WordHighlighter {
}
}));
this
.
_lastWordRange
=
null
;
this
.
_decorationIds
=
[];
this
.
workerRequestTokenId
=
0
;
this
.
workerRequest
=
null
;
...
...
@@ -173,8 +278,6 @@ class WordHighlighter {
}
private
_stopAll
():
void
{
this
.
_lastWordRange
=
null
;
// Remove any existing decorations
this
.
_removeDecorations
();
...
...
@@ -215,12 +318,6 @@ class WordHighlighter {
}
private
_run
():
void
{
// no providers for this model
if
(
!
DocumentHighlightProviderRegistry
.
has
(
this
.
model
))
{
this
.
_stopAll
();
return
;
}
let
editorSelection
=
this
.
editor
.
getSelection
();
// ignore multiline selection
...
...
@@ -249,21 +346,7 @@ class WordHighlighter {
// - 250ms later after the last cursor move event, render the occurrences
// - no flickering!
let
currentWordRange
=
new
Range
(
lineNumber
,
word
.
startColumn
,
lineNumber
,
word
.
endColumn
);
let
workerRequestIsValid
=
this
.
_lastWordRange
&&
this
.
_lastWordRange
.
equalsRange
(
currentWordRange
);
// Even if we are on a different word, if that word is in the decorations ranges, the request is still valid
// (Same symbol)
for
(
let
i
=
0
,
len
=
this
.
_decorationIds
.
length
;
!
workerRequestIsValid
&&
i
<
len
;
i
++
)
{
let
range
=
this
.
model
.
getDecorationRange
(
this
.
_decorationIds
[
i
]);
if
(
range
&&
range
.
startLineNumber
===
lineNumber
)
{
if
(
range
.
startColumn
<=
startColumn
&&
range
.
endColumn
>=
endColumn
)
{
workerRequestIsValid
=
true
;
}
}
}
const
workerRequestIsValid
=
(
this
.
workerRequest
&&
this
.
workerRequest
.
isValid
(
this
.
model
,
editorSelection
,
this
.
_decorationIds
));
// There are 4 cases:
// a) old workerRequest is valid & completed, renderDecorationsTimer fired
...
...
@@ -292,9 +375,9 @@ class WordHighlighter {
let
myRequestId
=
++
this
.
workerRequestTokenId
;
this
.
workerRequestCompleted
=
false
;
this
.
workerRequest
=
c
reateCancelablePromise
(
token
=>
getOccurrencesAtPosition
(
this
.
model
,
this
.
editor
.
getPosition
(),
token
)
);
this
.
workerRequest
=
c
omputeOccurencesAtPosition
(
this
.
model
,
this
.
editor
.
getSelection
(),
this
.
editor
.
getConfiguration
().
wordSeparators
);
this
.
workerRequest
.
then
(
data
=>
{
this
.
workerRequest
.
result
.
then
(
data
=>
{
if
(
myRequestId
===
this
.
workerRequestTokenId
)
{
this
.
workerRequestCompleted
=
true
;
this
.
workerRequestValue
=
data
||
[];
...
...
@@ -302,8 +385,6 @@ class WordHighlighter {
}
},
onUnexpectedError
);
}
this
.
_lastWordRange
=
currentWordRange
;
}
private
_beginRenderDecorations
():
void
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录