Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
136bbd3b
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
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,发现更多精彩内容 >>
提交
136bbd3b
编写于
5月 06, 2020
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rework gotoError logic to be fit for #96708
上级
c650757b
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
278 addition
and
320 deletion
+278
-320
src/vs/editor/contrib/gotoError/gotoError.ts
src/vs/editor/contrib/gotoError/gotoError.ts
+91
-315
src/vs/editor/contrib/gotoError/gotoErrorWidget.ts
src/vs/editor/contrib/gotoError/gotoErrorWidget.ts
+4
-2
src/vs/editor/contrib/gotoError/markerNavigationService.ts
src/vs/editor/contrib/gotoError/markerNavigationService.ts
+181
-0
src/vs/editor/contrib/gotoError/media/gotoErrorWidget.css
src/vs/editor/contrib/gotoError/media/gotoErrorWidget.css
+1
-1
src/vs/editor/contrib/hover/modesContentHover.ts
src/vs/editor/contrib/hover/modesContentHover.ts
+1
-2
未找到文件。
src/vs/editor/contrib/gotoError/gotoError.ts
浏览文件 @
136bbd3b
...
...
@@ -4,12 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import
*
as
nls
from
'
vs/nls
'
;
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
KeyCode
,
KeyMod
}
from
'
vs/base/common/keyCodes
'
;
import
{
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
RawContextKey
,
IContextKey
,
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IMarker
,
IMarkerService
,
MarkerSeverity
}
from
'
vs/platform/markers/common/markers
'
;
import
{
IMarker
}
from
'
vs/platform/markers/common/markers
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
IEditorContribution
}
from
'
vs/editor/common/editorCommon
'
;
...
...
@@ -18,194 +17,32 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import
{
EditorContextKeys
}
from
'
vs/editor/common/editorContextKeys
'
;
import
{
KeybindingWeight
}
from
'
vs/platform/keybinding/common/keybindingsRegistry
'
;
import
{
MarkerNavigationWidget
}
from
'
./gotoErrorWidget
'
;
import
{
compare
}
from
'
vs/base/common/strings
'
;
import
{
binarySearch
,
find
}
from
'
vs/base/common/arrays
'
;
import
{
ICodeEditorService
}
from
'
vs/editor/browser/services/codeEditorService
'
;
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
MenuRegistry
,
MenuId
}
from
'
vs/platform/actions/common/actions
'
;
import
{
isEqual
}
from
'
vs/base/common/resources
'
;
import
{
TextEditorSelectionRevealType
}
from
'
vs/platform/editor/common/editor
'
;
import
{
Codicon
,
registerIcon
}
from
'
vs/base/common/codicons
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
class
MarkerModel
{
private
readonly
_editor
:
ICodeEditor
;
private
_markers
:
IMarker
[];
private
_nextIdx
:
number
;
private
readonly
_toUnbind
=
new
DisposableStore
();
private
_ignoreSelectionChange
:
boolean
;
private
readonly
_onCurrentMarkerChanged
:
Emitter
<
IMarker
|
undefined
>
;
private
readonly
_onMarkerSetChanged
:
Emitter
<
MarkerModel
>
;
constructor
(
editor
:
ICodeEditor
,
markers
:
IMarker
[])
{
this
.
_editor
=
editor
;
this
.
_markers
=
[];
this
.
_nextIdx
=
-
1
;
this
.
_ignoreSelectionChange
=
false
;
this
.
_onCurrentMarkerChanged
=
new
Emitter
<
IMarker
|
undefined
>
();
this
.
_onMarkerSetChanged
=
new
Emitter
<
MarkerModel
>
();
this
.
setMarkers
(
markers
);
// listen on editor
this
.
_toUnbind
.
add
(
this
.
_editor
.
onDidDispose
(()
=>
this
.
dispose
()));
this
.
_toUnbind
.
add
(
this
.
_editor
.
onDidChangeCursorPosition
(()
=>
{
if
(
this
.
_ignoreSelectionChange
)
{
return
;
}
if
(
this
.
currentMarker
&&
this
.
_editor
.
getPosition
()
&&
Range
.
containsPosition
(
this
.
currentMarker
,
this
.
_editor
.
getPosition
()
!
))
{
return
;
}
this
.
_nextIdx
=
-
1
;
}));
}
public
get
onCurrentMarkerChanged
()
{
return
this
.
_onCurrentMarkerChanged
.
event
;
}
public
get
onMarkerSetChanged
()
{
return
this
.
_onMarkerSetChanged
.
event
;
}
public
setMarkers
(
markers
:
IMarker
[]):
void
{
let
oldMarker
=
this
.
_nextIdx
>=
0
?
this
.
_markers
[
this
.
_nextIdx
]
:
undefined
;
this
.
_markers
=
markers
||
[];
this
.
_markers
.
sort
(
MarkerNavigationAction
.
compareMarker
);
if
(
!
oldMarker
)
{
this
.
_nextIdx
=
-
1
;
}
else
{
this
.
_nextIdx
=
Math
.
max
(
-
1
,
binarySearch
(
this
.
_markers
,
oldMarker
,
MarkerNavigationAction
.
compareMarker
));
}
this
.
_onMarkerSetChanged
.
fire
(
this
);
}
public
withoutWatchingEditorPosition
(
callback
:
()
=>
void
):
void
{
this
.
_ignoreSelectionChange
=
true
;
try
{
callback
();
}
finally
{
this
.
_ignoreSelectionChange
=
false
;
}
}
private
_initIdx
(
fwd
:
boolean
):
void
{
let
found
=
false
;
const
position
=
this
.
_editor
.
getPosition
();
for
(
let
i
=
0
;
i
<
this
.
_markers
.
length
;
i
++
)
{
let
range
=
Range
.
lift
(
this
.
_markers
[
i
]);
if
(
range
.
isEmpty
()
&&
this
.
_editor
.
getModel
())
{
const
word
=
this
.
_editor
.
getModel
()
!
.
getWordAtPosition
(
range
.
getStartPosition
());
if
(
word
)
{
range
=
new
Range
(
range
.
startLineNumber
,
word
.
startColumn
,
range
.
startLineNumber
,
word
.
endColumn
);
}
}
if
(
position
&&
(
range
.
containsPosition
(
position
)
||
position
.
isBeforeOrEqual
(
range
.
getStartPosition
())))
{
this
.
_nextIdx
=
i
;
found
=
true
;
break
;
}
}
if
(
!
found
)
{
// after the last change
this
.
_nextIdx
=
fwd
?
0
:
this
.
_markers
.
length
-
1
;
}
if
(
this
.
_nextIdx
<
0
)
{
this
.
_nextIdx
=
this
.
_markers
.
length
-
1
;
}
}
get
currentMarker
():
IMarker
|
undefined
{
return
this
.
canNavigate
()
?
this
.
_markers
[
this
.
_nextIdx
]
:
undefined
;
}
set
currentMarker
(
marker
:
IMarker
|
undefined
)
{
const
idx
=
this
.
_nextIdx
;
this
.
_nextIdx
=
-
1
;
if
(
marker
)
{
this
.
_nextIdx
=
this
.
indexOf
(
marker
);
}
if
(
this
.
_nextIdx
!==
idx
)
{
this
.
_onCurrentMarkerChanged
.
fire
(
marker
);
}
}
public
move
(
fwd
:
boolean
,
inCircles
:
boolean
):
boolean
{
if
(
!
this
.
canNavigate
())
{
this
.
_onCurrentMarkerChanged
.
fire
(
undefined
);
return
!
inCircles
;
}
let
oldIdx
=
this
.
_nextIdx
;
let
atEdge
=
false
;
if
(
this
.
_nextIdx
===
-
1
)
{
this
.
_initIdx
(
fwd
);
}
else
if
(
fwd
)
{
if
(
inCircles
||
this
.
_nextIdx
+
1
<
this
.
_markers
.
length
)
{
this
.
_nextIdx
=
(
this
.
_nextIdx
+
1
)
%
this
.
_markers
.
length
;
}
else
{
atEdge
=
true
;
}
}
else
if
(
!
fwd
)
{
if
(
inCircles
||
this
.
_nextIdx
>
0
)
{
this
.
_nextIdx
=
(
this
.
_nextIdx
-
1
+
this
.
_markers
.
length
)
%
this
.
_markers
.
length
;
}
else
{
atEdge
=
true
;
}
}
if
(
oldIdx
!==
this
.
_nextIdx
)
{
const
marker
=
this
.
_markers
[
this
.
_nextIdx
];
this
.
_onCurrentMarkerChanged
.
fire
(
marker
);
}
return
atEdge
;
}
public
canNavigate
():
boolean
{
return
this
.
_markers
.
length
>
0
;
}
public
findMarkerAtPosition
(
pos
:
Position
):
IMarker
|
undefined
{
return
find
(
this
.
_markers
,
marker
=>
Range
.
containsPosition
(
marker
,
pos
));
}
public
get
total
()
{
return
this
.
_markers
.
length
;
}
public
indexOf
(
marker
:
IMarker
):
number
{
return
1
+
this
.
_markers
.
indexOf
(
marker
);
}
public
dispose
():
void
{
this
.
_toUnbind
.
dispose
();
}
}
import
{
IMarkerNavigationService
,
MarkerList
}
from
'
vs/editor/contrib/gotoError/markerNavigationService
'
;
export
class
MarkerController
implements
IEditorContribution
{
public
static
readonly
ID
=
'
editor.contrib.markerController
'
;
static
readonly
ID
=
'
editor.contrib.markerController
'
;
public
static
get
(
editor
:
ICodeEditor
):
MarkerController
{
static
get
(
editor
:
ICodeEditor
):
MarkerController
{
return
editor
.
getContribution
<
MarkerController
>
(
MarkerController
.
ID
);
}
private
readonly
_editor
:
ICodeEditor
;
private
_model
:
MarkerModel
|
null
=
null
;
private
_widget
:
MarkerNavigationWidget
|
null
=
null
;
private
readonly
_widgetVisible
:
IContextKey
<
boolean
>
;
private
readonly
_disposeOnClose
=
new
DisposableStore
();
private
readonly
_sessionDispoables
=
new
DisposableStore
();
private
_model
?:
MarkerList
;
private
_widget
?:
MarkerNavigationWidget
;
constructor
(
editor
:
ICodeEditor
,
@
IMarker
Service
private
readonly
_markerService
:
IMarker
Service
,
@
IMarker
NavigationService
private
readonly
_markerNavigationService
:
IMarkerNavigation
Service
,
@
IContextKeyService
private
readonly
_contextKeyService
:
IContextKeyService
,
@
ICodeEditorService
private
readonly
_editorService
:
ICodeEditorService
,
@
IInstantiationService
private
readonly
_instantiationService
:
IInstantiationService
,
...
...
@@ -214,195 +51,134 @@ export class MarkerController implements IEditorContribution {
this
.
_widgetVisible
=
CONTEXT_MARKERS_NAVIGATION_VISIBLE
.
bindTo
(
this
.
_contextKeyService
);
}
public
dispose
():
void
{
dispose
():
void
{
this
.
_cleanUp
();
this
.
_
disposeOnClose
.
dispose
();
this
.
_
sessionDispoables
.
dispose
();
}
private
_cleanUp
():
void
{
this
.
_widgetVisible
.
reset
();
this
.
_
disposeOnClose
.
clear
();
this
.
_widget
=
null
;
this
.
_model
=
null
;
this
.
_
sessionDispoables
.
clear
();
this
.
_widget
=
undefined
;
this
.
_model
=
undefined
;
}
p
ublic
getOrCreateModel
():
MarkerModel
{
p
rivate
_getOrCreateModel
(
uri
:
URI
|
undefined
):
MarkerList
{
if
(
this
.
_model
)
{
if
(
this
.
_model
&&
this
.
_model
.
matches
(
uri
)
)
{
return
this
.
_model
;
}
let
reusePosition
=
false
;
if
(
this
.
_model
)
{
reusePosition
=
true
;
this
.
_cleanUp
();
}
const
markers
=
this
.
_getMarkers
();
this
.
_model
=
new
MarkerModel
(
this
.
_editor
,
markers
);
this
.
_markerService
.
onMarkerChanged
(
this
.
_onMarkerChanged
,
this
,
this
.
_disposeOnClose
);
this
.
_model
=
this
.
_markerNavigationService
.
getMarkerList
(
uri
);
if
(
reusePosition
)
{
this
.
_model
.
move
(
true
,
this
.
_editor
.
getModel
()
!
,
this
.
_editor
.
getPosition
()
!
);
}
this
.
_widget
=
this
.
_instantiationService
.
createInstance
(
MarkerNavigationWidget
,
this
.
_editor
);
this
.
_widget
.
onDidClose
(()
=>
this
.
close
(),
this
,
this
.
_sessionDispoables
);
this
.
_widgetVisible
.
set
(
true
);
this
.
_widget
.
onDidClose
(()
=>
this
.
closeMarkersNavigation
(),
this
,
this
.
_disposeOnClose
);
this
.
_
disposeOnClose
.
add
(
this
.
_model
);
this
.
_
disposeOnClose
.
add
(
this
.
_widget
);
this
.
_
sessionDispoables
.
add
(
this
.
_model
);
this
.
_
sessionDispoables
.
add
(
this
.
_widget
);
this
.
_disposeOnClose
.
add
(
this
.
_widget
.
onDidSelectRelatedInformation
(
related
=>
{
this
.
_editorService
.
openCodeEditor
({
resource
:
related
.
resource
,
options
:
{
pinned
:
true
,
revealIfOpened
:
true
,
selection
:
Range
.
lift
(
related
).
collapseToStart
()
}
},
this
.
_editor
).
then
(
undefined
,
onUnexpectedError
);
this
.
closeMarkersNavigation
(
false
);
}));
this
.
_disposeOnClose
.
add
(
this
.
_editor
.
onDidChangeModel
(()
=>
this
.
_cleanUp
()));
this
.
_disposeOnClose
.
add
(
this
.
_model
.
onCurrentMarkerChanged
(
marker
=>
{
if
(
!
marker
||
!
this
.
_model
)
{
this
.
_cleanUp
();
}
else
{
this
.
_model
.
withoutWatchingEditorPosition
(()
=>
{
if
(
!
this
.
_widget
||
!
this
.
_model
)
{
return
;
}
this
.
_widget
.
showAtMarker
(
marker
,
this
.
_model
.
indexOf
(
marker
),
this
.
_model
.
total
);
});
// follow cursor
this
.
_sessionDispoables
.
add
(
this
.
_editor
.
onDidChangeCursorPosition
(
e
=>
{
if
(
!
this
.
_model
?.
selected
||
!
Range
.
containsPosition
(
this
.
_model
?.
selected
.
marker
,
e
.
position
))
{
this
.
_model
?.
resetIndex
();
}
}));
this
.
_disposeOnClose
.
add
(
this
.
_model
.
onMarkerSetChanged
(()
=>
{
// update markers
this
.
_sessionDispoables
.
add
(
this
.
_model
.
onDidChange
(()
=>
{
if
(
!
this
.
_widget
||
!
this
.
_widget
.
position
||
!
this
.
_model
)
{
return
;
}
const
marker
=
this
.
_model
.
findMarkerAtPosition
(
this
.
_widget
.
position
);
if
(
marker
)
{
this
.
_widget
.
updateMarker
(
marker
);
const
info
=
this
.
_model
.
find
(
this
.
_editor
.
getModel
()
!
.
uri
,
this
.
_widget
!
.
position
!
);
if
(
info
)
{
this
.
_widget
.
updateMarker
(
info
.
marker
);
}
else
{
this
.
_widget
.
showStale
();
}
}));
// open related
this
.
_sessionDispoables
.
add
(
this
.
_widget
.
onDidSelectRelatedInformation
(
related
=>
{
this
.
_editorService
.
openCodeEditor
({
resource
:
related
.
resource
,
options
:
{
pinned
:
true
,
revealIfOpened
:
true
,
selection
:
Range
.
lift
(
related
).
collapseToStart
()
}
},
this
.
_editor
);
this
.
close
(
false
);
}));
this
.
_sessionDispoables
.
add
(
this
.
_editor
.
onDidChangeModel
(()
=>
this
.
_cleanUp
()));
return
this
.
_model
;
}
public
closeMarkersNavigation
(
focusEditor
:
boolean
=
true
):
void
{
close
(
focusEditor
:
boolean
=
true
):
void
{
this
.
_cleanUp
();
if
(
focusEditor
)
{
this
.
_editor
.
focus
();
}
}
public
show
(
marker
:
IMarker
):
void
{
const
model
=
this
.
getOrCreateModel
();
model
.
currentMarker
=
marker
;
}
private
_onMarkerChanged
(
changedResources
:
readonly
URI
[]):
void
{
const
editorModel
=
this
.
_editor
.
getModel
();
if
(
!
editorModel
)
{
return
;
}
if
(
!
this
.
_model
)
{
return
;
}
if
(
!
changedResources
.
some
(
r
=>
isEqual
(
editorModel
.
uri
,
r
)))
{
return
;
showAtMarker
(
marker
:
IMarker
):
void
{
if
(
this
.
_editor
.
hasModel
())
{
const
model
=
this
.
_getOrCreateModel
(
this
.
_editor
.
getModel
().
uri
);
model
.
resetIndex
();
model
.
move
(
true
,
this
.
_editor
.
getModel
(),
new
Position
(
marker
.
startLineNumber
,
marker
.
startColumn
));
if
(
model
.
selected
)
{
this
.
_widget
!
.
showAtMarker
(
model
.
selected
.
marker
,
model
.
selected
.
index
,
model
.
selected
.
total
);
}
}
this
.
_model
.
setMarkers
(
this
.
_getMarkers
());
}
private
_getMarkers
():
IMarker
[]
{
let
model
=
this
.
_editor
.
getModel
();
if
(
!
model
)
{
return
[];
}
async
nagivate
(
next
:
boolean
,
multiFile
:
boolean
)
{
if
(
this
.
_editor
.
hasModel
())
{
const
model
=
this
.
_getOrCreateModel
(
multiFile
?
undefined
:
this
.
_editor
.
getModel
().
uri
);
model
.
move
(
next
,
this
.
_editor
.
getModel
(),
this
.
_editor
.
getPosition
());
if
(
!
model
.
selected
)
{
return
;
}
if
(
model
.
selected
.
marker
.
resource
.
toString
()
!==
this
.
_editor
.
getModel
().
uri
.
toString
())
{
// show in different editor
this
.
_cleanUp
();
const
otherEditor
=
await
this
.
_editorService
.
openCodeEditor
({
resource
:
model
.
selected
.
marker
.
resource
,
options
:
{
pinned
:
false
,
revealIfOpened
:
true
,
selectionRevealType
:
TextEditorSelectionRevealType
.
NearTop
,
selection
:
model
.
selected
.
marker
}
},
this
.
_editor
);
if
(
otherEditor
)
{
MarkerController
.
get
(
otherEditor
).
close
();
MarkerController
.
get
(
otherEditor
).
nagivate
(
next
,
multiFile
);
}
return
this
.
_markerService
.
read
({
resource
:
model
.
uri
,
severities
:
MarkerSeverity
.
Error
|
MarkerSeverity
.
Warning
|
MarkerSeverity
.
Info
});
}
else
{
// show in this editor
this
.
_widget
!
.
showAtMarker
(
model
.
selected
.
marker
,
model
.
selected
.
index
,
model
.
selected
.
total
);
}
}
}
}
class
MarkerNavigationAction
extends
EditorAction
{
private
readonly
_isNext
:
boolean
;
private
readonly
_multiFile
:
boolean
;
constructor
(
next
:
boolean
,
multiFile
:
boolean
,
opts
:
IActionOptions
)
{
constructor
(
private
readonly
_next
:
boolean
,
private
readonly
_multiFile
:
boolean
,
opts
:
IActionOptions
)
{
super
(
opts
);
this
.
_isNext
=
next
;
this
.
_multiFile
=
multiFile
;
}
public
run
(
accessor
:
ServicesAccessor
,
editor
:
ICodeEditor
):
Promise
<
void
>
{
const
markerService
=
accessor
.
get
(
IMarkerService
);
const
editorService
=
accessor
.
get
(
ICodeEditorService
);
const
controller
=
MarkerController
.
get
(
editor
);
if
(
!
controller
)
{
return
Promise
.
resolve
(
undefined
);
}
const
model
=
controller
.
getOrCreateModel
();
const
atEdge
=
model
.
move
(
this
.
_isNext
,
!
this
.
_multiFile
);
if
(
!
atEdge
||
!
this
.
_multiFile
)
{
return
Promise
.
resolve
(
undefined
);
}
// try with the next/prev file
let
markers
=
markerService
.
read
({
severities
:
MarkerSeverity
.
Error
|
MarkerSeverity
.
Warning
|
MarkerSeverity
.
Info
}).
sort
(
MarkerNavigationAction
.
compareMarker
);
if
(
markers
.
length
===
0
)
{
return
Promise
.
resolve
(
undefined
);
}
const
editorModel
=
editor
.
getModel
();
if
(
!
editorModel
)
{
return
Promise
.
resolve
(
undefined
);
}
let
oldMarker
=
model
.
currentMarker
||
<
IMarker
>
{
resource
:
editorModel
!
.
uri
,
severity
:
MarkerSeverity
.
Error
,
startLineNumber
:
1
,
startColumn
:
1
,
endLineNumber
:
1
,
endColumn
:
1
};
let
idx
=
binarySearch
(
markers
,
oldMarker
,
MarkerNavigationAction
.
compareMarker
);
if
(
idx
<
0
)
{
// find best match...
idx
=
~
idx
;
idx
%=
markers
.
length
;
}
else
if
(
this
.
_isNext
)
{
idx
=
(
idx
+
1
)
%
markers
.
length
;
}
else
{
idx
=
(
idx
+
markers
.
length
-
1
)
%
markers
.
length
;
}
let
newMarker
=
markers
[
idx
];
if
(
isEqual
(
newMarker
.
resource
,
editorModel
.
uri
))
{
// the next `resource` is this resource which
// means we cycle within this file
model
.
move
(
this
.
_isNext
,
true
);
return
Promise
.
resolve
(
undefined
);
}
// close the widget for this editor-instance, open the resource
// for the next marker and re-start marker navigation in there
controller
.
closeMarkersNavigation
();
return
editorService
.
openCodeEditor
({
resource
:
newMarker
.
resource
,
options
:
{
pinned
:
false
,
revealIfOpened
:
true
,
selectionRevealType
:
TextEditorSelectionRevealType
.
NearTop
,
selection
:
newMarker
}
},
editor
).
then
(
editor
=>
{
if
(
!
editor
)
{
return
undefined
;
}
return
editor
.
getAction
(
this
.
id
).
run
();
});
}
static
compareMarker
(
a
:
IMarker
,
b
:
IMarker
):
number
{
let
res
=
compare
(
a
.
resource
.
toString
(),
b
.
resource
.
toString
());
if
(
res
===
0
)
{
res
=
MarkerSeverity
.
compare
(
a
.
severity
,
b
.
severity
);
}
if
(
res
===
0
)
{
res
=
Range
.
compareRangesUsingStarts
(
a
,
b
);
async
run
(
_accessor
:
ServicesAccessor
,
editor
:
ICodeEditor
):
Promise
<
void
>
{
if
(
editor
.
hasModel
())
{
MarkerController
.
get
(
editor
).
nagivate
(
this
.
_next
,
this
.
_multiFile
);
}
return
res
;
}
}
...
...
@@ -501,7 +277,7 @@ const MarkerCommand = EditorCommand.bindToContribution<MarkerController>(MarkerC
registerEditorCommand
(
new
MarkerCommand
({
id
:
'
closeMarkersNavigation
'
,
precondition
:
CONTEXT_MARKERS_NAVIGATION_VISIBLE
,
handler
:
x
=>
x
.
close
MarkersNavigation
(),
handler
:
x
=>
x
.
close
(),
kbOpts
:
{
weight
:
KeybindingWeight
.
EditorContrib
+
50
,
kbExpr
:
EditorContextKeys
.
focus
,
...
...
src/vs/editor/contrib/gotoError/gotoErrorWidget.ts
浏览文件 @
136bbd3b
...
...
@@ -8,7 +8,6 @@ import * as nls from 'vs/nls';
import
*
as
dom
from
'
vs/base/browser/dom
'
;
import
{
dispose
,
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
IMarker
,
MarkerSeverity
,
IRelatedInformation
}
from
'
vs/platform/markers/common/markers
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
registerColor
,
oneOf
,
textLinkForeground
,
editorErrorForeground
,
editorErrorBorder
,
editorWarningForeground
,
editorWarningBorder
,
editorInfoForeground
,
editorInfoBorder
}
from
'
vs/platform/theme/common/colorRegistry
'
;
...
...
@@ -296,6 +295,9 @@ export class MarkerNavigationWidget extends PeekViewWidget {
protected
_fillHead
(
container
:
HTMLElement
):
void
{
super
.
_fillHead
(
container
);
this
.
_disposables
.
add
(
this
.
_actionbarWidget
!
.
actionRunner
.
onDidBeforeRun
(
e
=>
this
.
editor
.
focus
()));
const
actions
:
IAction
[]
=
[];
const
menu
=
this
.
_menuService
.
createMenu
(
MarkerNavigationWidget
.
TitleMenu
,
this
.
_contextKeyService
);
createAndFillInActionBarActions
(
menu
,
undefined
,
actions
);
...
...
@@ -327,7 +329,7 @@ export class MarkerNavigationWidget extends PeekViewWidget {
this
.
_disposables
.
add
(
this
.
_message
);
}
show
(
where
:
Position
,
heightInLines
:
number
):
void
{
show
():
void
{
throw
new
Error
(
'
call showAtMarker
'
);
}
...
...
src/vs/editor/contrib/gotoError/markerNavigationService.ts
0 → 100644
浏览文件 @
136bbd3b
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
IMarkerService
,
MarkerSeverity
,
IMarker
}
from
'
vs/platform/markers/common/markers
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
Position
}
from
'
vs/editor/common/core/position
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
compare
}
from
'
vs/base/common/strings
'
;
import
{
binarySearch
}
from
'
vs/base/common/arrays
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
export
class
MarkerCoordinate
{
constructor
(
readonly
marker
:
IMarker
,
readonly
index
:
number
,
readonly
total
:
number
)
{
}
}
export
class
MarkerList
{
private
readonly
_onDidChange
=
new
Emitter
<
void
>
();
readonly
onDidChange
:
Event
<
void
>
=
this
.
_onDidChange
.
event
;
private
readonly
_dispoables
=
new
DisposableStore
();
private
_markers
:
IMarker
[]
=
[];
private
_nextIdx
:
number
=
-
1
;
constructor
(
private
readonly
_scope
:
URI
|
undefined
,
@
IMarkerService
private
readonly
_markerService
:
IMarkerService
,
)
{
const
filter
=
{
resource
:
this
.
_scope
,
severities
:
MarkerSeverity
.
Error
|
MarkerSeverity
.
Warning
|
MarkerSeverity
.
Info
};
this
.
_markers
=
this
.
_markerService
.
read
(
filter
).
sort
(
MarkerList
.
_compareMarker
);
this
.
_dispoables
.
add
(
_markerService
.
onMarkerChanged
(
e
=>
{
if
(
!
this
.
_scope
||
e
.
some
(
e
=>
e
.
toString
()
===
_scope
?.
toString
()))
{
this
.
_markers
=
this
.
_markerService
.
read
(
filter
).
sort
(
MarkerList
.
_compareMarker
);
this
.
_nextIdx
=
-
1
;
this
.
_onDidChange
.
fire
();
}
}));
}
dispose
():
void
{
this
.
_dispoables
.
dispose
();
this
.
_onDidChange
.
dispose
();
}
matches
(
uri
:
URI
|
undefined
)
{
if
(
this
.
_scope
===
uri
)
{
return
true
;
}
if
(
this
.
_scope
&&
uri
&&
this
.
_scope
.
toString
()
===
uri
.
toString
())
{
return
true
;
}
return
false
;
}
get
selected
():
MarkerCoordinate
|
undefined
{
const
marker
=
this
.
_markers
[
this
.
_nextIdx
];
return
marker
&&
new
MarkerCoordinate
(
marker
,
this
.
_nextIdx
+
1
,
this
.
_markers
.
length
);
}
private
_initIdx
(
model
:
ITextModel
,
position
:
Position
,
fwd
:
boolean
):
void
{
let
found
=
false
;
let
idx
=
this
.
_markers
.
findIndex
(
marker
=>
marker
.
resource
.
toString
()
===
model
.
uri
.
toString
());
if
(
idx
<
0
)
{
idx
=
binarySearch
(
this
.
_markers
,
<
any
>
{
resource
:
model
.
uri
},
(
a
,
b
)
=>
compare
(
a
.
resource
.
toString
(),
b
.
resource
.
toString
()));
if
(
idx
<
0
)
{
idx
=
~
idx
;
}
}
for
(
let
i
=
idx
;
i
<
this
.
_markers
.
length
;
i
++
)
{
let
range
=
Range
.
lift
(
this
.
_markers
[
i
]);
if
(
range
.
isEmpty
())
{
const
word
=
model
.
getWordAtPosition
(
range
.
getStartPosition
());
if
(
word
)
{
range
=
new
Range
(
range
.
startLineNumber
,
word
.
startColumn
,
range
.
startLineNumber
,
word
.
endColumn
);
}
}
if
(
position
&&
(
range
.
containsPosition
(
position
)
||
position
.
isBeforeOrEqual
(
range
.
getStartPosition
())))
{
this
.
_nextIdx
=
i
;
found
=
true
;
break
;
}
if
(
this
.
_markers
[
i
].
resource
.
toString
()
!==
model
.
uri
.
toString
())
{
break
;
}
}
if
(
!
found
)
{
// after the last change
this
.
_nextIdx
=
fwd
?
0
:
this
.
_markers
.
length
-
1
;
}
if
(
this
.
_nextIdx
<
0
)
{
this
.
_nextIdx
=
this
.
_markers
.
length
-
1
;
}
}
resetIndex
()
{
this
.
_nextIdx
=
-
1
;
}
move
(
fwd
:
boolean
,
model
:
ITextModel
,
position
:
Position
):
boolean
{
if
(
this
.
_markers
.
length
===
0
)
{
return
false
;
}
let
oldIdx
=
this
.
_nextIdx
;
if
(
this
.
_nextIdx
===
-
1
)
{
this
.
_initIdx
(
model
,
position
,
fwd
);
}
else
if
(
fwd
)
{
this
.
_nextIdx
=
(
this
.
_nextIdx
+
1
)
%
this
.
_markers
.
length
;
}
else
if
(
!
fwd
)
{
this
.
_nextIdx
=
(
this
.
_nextIdx
-
1
+
this
.
_markers
.
length
)
%
this
.
_markers
.
length
;
}
if
(
oldIdx
!==
this
.
_nextIdx
)
{
return
true
;
}
return
false
;
}
find
(
uri
:
URI
,
position
:
Position
):
MarkerCoordinate
|
undefined
{
let
idx
=
this
.
_markers
.
findIndex
(
marker
=>
marker
.
resource
.
toString
()
===
uri
.
toString
());
if
(
idx
<
0
)
{
return
undefined
;
}
for
(;
idx
<
this
.
_markers
.
length
;
idx
++
)
{
if
(
Range
.
containsPosition
(
this
.
_markers
[
idx
],
position
))
{
return
new
MarkerCoordinate
(
this
.
_markers
[
idx
],
idx
+
1
,
this
.
_markers
.
length
);
}
}
return
undefined
;
}
private
static
_compareMarker
(
a
:
IMarker
,
b
:
IMarker
):
number
{
let
res
=
compare
(
a
.
resource
.
toString
(),
b
.
resource
.
toString
());
if
(
res
===
0
)
{
res
=
MarkerSeverity
.
compare
(
a
.
severity
,
b
.
severity
);
}
if
(
res
===
0
)
{
res
=
Range
.
compareRangesUsingStarts
(
a
,
b
);
}
return
res
;
}
}
export
const
IMarkerNavigationService
=
createDecorator
<
IMarkerNavigationService
>
(
'
IMarkerNavigationService
'
);
export
interface
IMarkerNavigationService
{
readonly
_serviceBrand
:
undefined
;
getMarkerList
(
resource
:
URI
|
undefined
):
MarkerList
;
}
class
MarkerNavigationService
implements
IMarkerNavigationService
{
readonly
_serviceBrand
:
undefined
;
constructor
(@
IMarkerService
private
readonly
_markerService
:
IMarkerService
)
{
}
getMarkerList
(
resource
:
URI
|
undefined
)
{
return
new
MarkerList
(
resource
,
this
.
_markerService
);
}
}
registerSingleton
(
IMarkerNavigationService
,
MarkerNavigationService
,
true
);
src/vs/editor/contrib/gotoError/media/gotoErrorWidget.css
浏览文件 @
136bbd3b
...
...
@@ -32,7 +32,7 @@
user-select
:
text
;
-webkit-user-select
:
text
;
-ms-user-select
:
text
;
padding
:
8px
12px
0
px
20px
;
padding
:
8px
12px
0
20px
;
}
.monaco-editor
.marker-widget
.descriptioncontainer
.message
{
...
...
src/vs/editor/contrib/hover/modesContentHover.ts
浏览文件 @
136bbd3b
...
...
@@ -567,7 +567,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
commandId
:
NextMarkerAction
.
ID
,
run
:
()
=>
{
this
.
hide
();
MarkerController
.
get
(
this
.
_editor
).
show
(
markerHover
.
marker
);
MarkerController
.
get
(
this
.
_editor
).
show
AtMarker
(
markerHover
.
marker
);
this
.
_editor
.
focus
();
}
}));
...
...
@@ -686,4 +686,3 @@ registerThemingParticipant((theme, collector) => {
collector
.
addRule
(
`.monaco-editor-hover .hover-contents a.code-link span:hover { color:
${
linkFg
}
; }`
);
}
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录