Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
d50aae12
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,发现更多精彩内容 >>
提交
d50aae12
编写于
6月 28, 2017
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
introduce and use ResourceGlobMatcher
上级
63def6eb
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
206 addition
and
72 deletion
+206
-72
src/vs/workbench/browser/parts/editor/titleControl.ts
src/vs/workbench/browser/parts/editor/titleControl.ts
+1
-1
src/vs/workbench/common/resources.ts
src/vs/workbench/common/resources.ts
+170
-0
src/vs/workbench/parts/files/browser/views/explorerView.ts
src/vs/workbench/parts/files/browser/views/explorerView.ts
+16
-9
src/vs/workbench/services/history/browser/history.ts
src/vs/workbench/services/history/browser/history.ts
+19
-62
未找到文件。
src/vs/workbench/browser/parts/editor/titleControl.ts
浏览文件 @
d50aae12
...
...
@@ -36,7 +36,7 @@ import { CloseEditorsInGroupAction, SplitEditorAction, CloseEditorAction, KeepEd
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
createActionItem
,
fillInActions
}
from
'
vs/platform/actions/browser/menuItemActionItem
'
;
import
{
IMenuService
,
MenuId
,
IMenu
,
ExecuteCommandAction
}
from
'
vs/platform/actions/common/actions
'
;
import
{
ResourceContextKey
}
from
'
vs/workbench/common/resource
ContextKey
'
;
import
{
ResourceContextKey
}
from
'
vs/workbench/common/resource
s
'
;
import
{
IThemeService
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
Themable
}
from
'
vs/workbench/common/theme
'
;
...
...
src/vs/workbench/common/resource
ContextKey
.ts
→
src/vs/workbench/common/resource
s
.ts
浏览文件 @
d50aae12
...
...
@@ -2,9 +2,17 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
objects
=
require
(
'
vs/base/common/objects
'
);
import
paths
=
require
(
'
vs/base/common/paths
'
);
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
ParsedExpression
,
IExpression
}
from
'
vs/base/common/glob
'
;
import
{
basename
}
from
'
vs/base/common/paths
'
;
import
{
RawContextKey
,
IContextKeyService
,
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IModeService
}
from
'
vs/editor/common/services/modeService
'
;
...
...
@@ -47,4 +55,116 @@ export class ResourceContextKey implements IContextKey<URI> {
public
get
():
URI
{
return
this
.
_resourceKey
.
get
();
}
}
export
class
ResourceGlobMatcher
{
private
static
readonly
NO_ROOT
=
null
;
private
_onExpressionChange
:
Emitter
<
void
>
;
private
toUnbind
:
IDisposable
[];
private
mapRootToParsedExpression
:
Map
<
string
,
ParsedExpression
>
;
private
mapRootToExpressionConfig
:
Map
<
string
,
IExpression
>
;
constructor
(
private
globFn
:
(
root
?:
URI
)
=>
IExpression
,
private
parseFn
:
(
expression
:
IExpression
)
=>
ParsedExpression
,
@
IWorkspaceContextService
private
contextService
:
IWorkspaceContextService
,
@
IConfigurationService
private
configurationService
:
IConfigurationService
)
{
this
.
toUnbind
=
[];
this
.
mapRootToParsedExpression
=
new
Map
<
string
,
ParsedExpression
>
();
this
.
mapRootToExpressionConfig
=
new
Map
<
string
,
IExpression
>
();
this
.
_onExpressionChange
=
new
Emitter
<
void
>
();
this
.
toUnbind
.
push
(
this
.
_onExpressionChange
);
this
.
updateExcludes
(
false
);
this
.
registerListeners
();
}
public
get
onExpressionChange
():
Event
<
void
>
{
return
this
.
_onExpressionChange
.
event
;
}
private
registerListeners
():
void
{
this
.
toUnbind
.
push
(
this
.
configurationService
.
onDidUpdateConfiguration
(()
=>
this
.
onConfigurationChanged
()));
this
.
toUnbind
.
push
(
this
.
contextService
.
onDidChangeWorkspaceRoots
(()
=>
this
.
onDidChangeWorkspaceRoots
()));
}
private
onConfigurationChanged
():
void
{
this
.
updateExcludes
(
true
);
}
private
onDidChangeWorkspaceRoots
():
void
{
this
.
updateExcludes
(
true
);
}
private
updateExcludes
(
fromEvent
:
boolean
):
void
{
let
changed
=
false
;
// Add excludes per workspaces that got added
if
(
this
.
contextService
.
hasWorkspace
())
{
this
.
contextService
.
getWorkspace2
().
roots
.
forEach
(
root
=>
{
const
rootExcludes
=
this
.
globFn
(
root
);
if
(
!
this
.
mapRootToExpressionConfig
.
has
(
root
.
toString
())
||
!
objects
.
equals
(
this
.
mapRootToExpressionConfig
.
get
(
root
.
toString
()),
rootExcludes
))
{
changed
=
true
;
this
.
mapRootToParsedExpression
.
set
(
root
.
toString
(),
this
.
parseFn
(
rootExcludes
));
this
.
mapRootToExpressionConfig
.
set
(
root
.
toString
(),
objects
.
clone
(
rootExcludes
));
}
});
}
// Remove excludes per workspace no longer present
this
.
mapRootToExpressionConfig
.
forEach
((
value
,
root
)
=>
{
if
(
root
===
ResourceGlobMatcher
.
NO_ROOT
)
{
return
;
// always keep this one
}
if
(
!
this
.
contextService
.
getRoot
(
URI
.
parse
(
root
)))
{
this
.
mapRootToParsedExpression
.
delete
(
root
);
this
.
mapRootToExpressionConfig
.
delete
(
root
);
changed
=
true
;
}
});
// Always set for resources outside root as well
const
globalExcludes
=
this
.
globFn
();
if
(
!
this
.
mapRootToExpressionConfig
.
has
(
ResourceGlobMatcher
.
NO_ROOT
)
||
!
objects
.
equals
(
this
.
mapRootToExpressionConfig
.
get
(
ResourceGlobMatcher
.
NO_ROOT
),
globalExcludes
))
{
changed
=
true
;
this
.
mapRootToParsedExpression
.
set
(
ResourceGlobMatcher
.
NO_ROOT
,
this
.
parseFn
(
globalExcludes
));
this
.
mapRootToExpressionConfig
.
set
(
ResourceGlobMatcher
.
NO_ROOT
,
objects
.
clone
(
globalExcludes
));
}
if
(
fromEvent
&&
changed
)
{
this
.
_onExpressionChange
.
fire
();
}
}
public
matches
(
resource
:
URI
):
boolean
{
const
root
=
this
.
contextService
.
getRoot
(
resource
);
const
expressionForRoot
=
this
.
mapRootToParsedExpression
.
get
(
root
?
root
.
toString
()
:
ResourceGlobMatcher
.
NO_ROOT
);
// If the resource if from a workspace, convert its absolute path to a relative
// path so that glob patterns have a higher probability to match. For example
// a glob pattern of "src/**" will not match on an absolute path "/folder/src/file.txt"
// but can match on "src/file.txt"
let
resourcePathToMatch
:
string
;
if
(
root
)
{
resourcePathToMatch
=
paths
.
normalize
(
paths
.
relative
(
root
.
fsPath
,
resource
.
fsPath
));
}
else
{
resourcePathToMatch
=
resource
.
fsPath
;
}
return
!!
expressionForRoot
(
resourcePathToMatch
);
}
public
dispose
():
void
{
this
.
toUnbind
=
dispose
(
this
.
toUnbind
);
}
}
\ No newline at end of file
src/vs/workbench/parts/files/browser/views/explorerView.ts
浏览文件 @
d50aae12
...
...
@@ -40,7 +40,7 @@ import { IProgressService } from 'vs/platform/progress/common/progress';
import
{
IContextMenuService
}
from
'
vs/platform/contextview/browser/contextView
'
;
import
{
IMessageService
,
Severity
}
from
'
vs/platform/message/common/message
'
;
import
{
IContextKeyService
,
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ResourceContextKey
}
from
'
vs/workbench/common/resourceContextKey
'
;
import
{
ResourceContextKey
,
ResourceGlobMatcher
}
from
'
vs/workbench/common/resources
'
;
import
{
IWorkbenchThemeService
,
IFileIconTheme
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
isLinux
}
from
'
vs/base/common/platform
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
...
...
@@ -76,6 +76,8 @@ export class ExplorerView extends CollapsibleView {
private
filesExplorerFocussedContext
:
IContextKey
<
boolean
>
;
private
explorerFocussedContext
:
IContextKey
<
boolean
>
;
private
fileEventsFilter
:
ResourceGlobMatcher
;
private
shouldRefresh
:
boolean
;
private
autoReveal
:
boolean
;
...
...
@@ -115,6 +117,15 @@ export class ExplorerView extends CollapsibleView {
this
.
filesExplorerFocussedContext
=
FilesExplorerFocussedContext
.
bindTo
(
contextKeyService
);
this
.
explorerFocussedContext
=
ExplorerFocussedContext
.
bindTo
(
contextKeyService
);
this
.
fileEventsFilter
=
instantiationService
.
createInstance
(
ResourceGlobMatcher
,
root
=>
this
.
getFileEventsExcludes
(
root
),
(
expression
:
glob
.
IExpression
)
=>
glob
.
parse
(
expression
));
}
private
getFileEventsExcludes
(
root
?:
URI
):
glob
.
IExpression
{
const
scope
=
root
?
{
resource
:
root
}
:
void
0
;
const
configuration
=
this
.
configurationService
.
getConfiguration
<
IFilesConfiguration
>
(
undefined
,
scope
);
return
(
configuration
&&
configuration
.
files
&&
configuration
.
files
.
exclude
)
||
Object
.
create
(
null
);
}
public
renderHeader
(
container
:
HTMLElement
):
void
{
...
...
@@ -619,16 +630,12 @@ export class ExplorerView extends CollapsibleView {
return
false
;
// we only want added / removed
}
// Getting closest root which is not correct in all cases
const
root
=
this
.
contextService
.
getRoot
(
change
.
resource
);
if
(
!
root
)
{
return
false
;
if
(
!
this
.
contextService
.
isInsideWorkspace
(
change
.
resource
))
{
return
false
;
// exclude changes for resources outside of workspace
}
const
configuration
=
this
.
configurationService
.
getConfiguration
<
IFilesConfiguration
>
(
undefined
,
{
resource
:
root
});
const
excludesConfig
=
(
configuration
&&
configuration
.
files
&&
configuration
.
files
.
exclude
)
||
Object
.
create
(
null
);
if
(
glob
.
match
(
excludesConfig
,
paths
.
normalize
(
paths
.
relative
(
root
.
fsPath
,
change
.
resource
.
fsPath
))))
{
return
false
;
// hidden through pattern
if
(
this
.
fileEventsFilter
.
matches
(
change
.
resource
))
{
return
false
;
// excluded via files.exclude setting
}
return
true
;
...
...
src/vs/workbench/services/history/browser/history.ts
浏览文件 @
d50aae12
...
...
@@ -8,7 +8,6 @@
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
errors
=
require
(
'
vs/base/common/errors
'
);
import
URI
from
'
vs/base/common/uri
'
;
import
objects
=
require
(
'
vs/base/common/objects
'
);
import
{
IEditor
}
from
'
vs/editor/common/editorCommon
'
;
import
{
IEditor
as
IBaseEditor
,
IEditorInput
,
ITextEditorOptions
,
IResourceInput
}
from
'
vs/platform/editor/common/editor
'
;
import
{
EditorInput
,
IEditorCloseEvent
,
IEditorRegistry
,
Extensions
,
toResource
,
IEditorGroup
}
from
'
vs/workbench/common/editor
'
;
...
...
@@ -27,9 +26,10 @@ import { IEditorGroupService } from 'vs/workbench/services/group/common/groupSer
import
{
IWindowService
}
from
'
vs/platform/windows/common/windows
'
;
import
{
getCodeEditor
}
from
'
vs/editor/common/services/codeEditorService
'
;
import
{
getExcludes
,
ISearchConfiguration
}
from
'
vs/platform/search/common/search
'
;
import
{
ParsedExpression
,
parse
,
IExpression
}
from
'
vs/base/common/glob
'
;
import
{
parse
,
IExpression
}
from
'
vs/base/common/glob
'
;
import
{
ICursorPositionChangedEvent
}
from
'
vs/editor/common/controller/cursorEvents
'
;
import
{
getPathLabel
}
from
"
vs/base/common/labels
"
;
import
{
IInstantiationService
}
from
"
vs/platform/instantiation/common/instantiation
"
;
import
{
ResourceGlobMatcher
}
from
"
vs/workbench/common/resources
"
;
/**
* Stores the selection & view state of an editor and allows to compare it to other selection states.
...
...
@@ -81,67 +81,18 @@ interface ISerializedFileHistoryEntry {
export
abstract
class
BaseHistoryService
{
protected
toUnbind
:
IDisposable
[];
protected
mapRootToExcludes
:
Map
<
string
,
ParsedExpression
>
;
private
mapRootToExpression
:
Map
<
string
,
IExpression
>
;
private
activeEditorListeners
:
IDisposable
[];
constructor
(
protected
editorGroupService
:
IEditorGroupService
,
protected
editorService
:
IWorkbenchEditorService
,
protected
contextService
:
IWorkspaceContextService
,
private
configurationService
:
IConfigurationService
protected
editorService
:
IWorkbenchEditorService
)
{
this
.
toUnbind
=
[];
this
.
activeEditorListeners
=
[];
this
.
mapRootToExcludes
=
new
Map
<
string
,
ParsedExpression
>
();
this
.
mapRootToExpression
=
new
Map
<
string
,
IExpression
>
();
// Listeners
this
.
toUnbind
.
push
(
this
.
editorGroupService
.
onEditorsChanged
(()
=>
this
.
onEditorsChanged
()));
this
.
toUnbind
.
push
(
this
.
configurationService
.
onDidUpdateConfiguration
(()
=>
this
.
onConfigurationChanged
()));
this
.
toUnbind
.
push
(
this
.
contextService
.
onDidChangeWorkspaceRoots
(()
=>
this
.
onDidChangeWorkspaceRoots
()));
this
.
updateExcludes
(
false
);
}
private
onConfigurationChanged
():
void
{
this
.
updateExcludes
(
true
);
}
private
onDidChangeWorkspaceRoots
():
void
{
this
.
updateExcludes
(
true
);
}
private
updateExcludes
(
fromEvent
:
boolean
):
void
{
let
changed
=
false
;
// Parse excludes per workspace
if
(
this
.
contextService
.
hasWorkspace
())
{
this
.
contextService
.
getWorkspace2
().
roots
.
forEach
(
root
=>
{
const
rootExcludes
=
getExcludes
(
this
.
configurationService
.
getConfiguration
<
ISearchConfiguration
>
(
void
0
,
{
resource
:
root
}));
if
(
!
this
.
mapRootToExpression
.
has
(
root
.
toString
())
||
!
objects
.
equals
(
this
.
mapRootToExpression
.
get
(
root
.
toString
()),
rootExcludes
))
{
changed
=
true
;
this
.
mapRootToExcludes
.
set
(
root
.
toString
(),
parse
(
rootExcludes
));
this
.
mapRootToExpression
.
set
(
root
.
toString
(),
objects
.
clone
(
rootExcludes
));
}
});
}
// Always set for files outside root as well
const
globalExcludes
=
getExcludes
(
this
.
configurationService
.
getConfiguration
<
ISearchConfiguration
>
());
if
(
!
this
.
mapRootToExpression
.
has
(
null
)
||
!
objects
.
equals
(
this
.
mapRootToExpression
.
get
(
null
),
globalExcludes
))
{
changed
=
true
;
this
.
mapRootToExcludes
.
set
(
null
,
parse
(
globalExcludes
));
this
.
mapRootToExpression
.
set
(
null
,
objects
.
clone
(
globalExcludes
));
}
if
(
fromEvent
&&
changed
)
{
this
.
handleExcludesChange
();
}
}
private
onEditorsChanged
():
void
{
...
...
@@ -205,35 +156,43 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
private
recentlyClosedFiles
:
IRecentlyClosedFile
[];
private
loaded
:
boolean
;
private
registry
:
IEditorRegistry
;
private
resourceFilter
:
ResourceGlobMatcher
;
constructor
(
@
IWorkbenchEditorService
editorService
:
IWorkbenchEditorService
,
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
,
@
IWorkspaceContextService
contextService
:
IWorkspaceContextService
,
@
IWorkspaceContextService
private
contextService
:
IWorkspaceContextService
,
@
IStorageService
private
storageService
:
IStorageService
,
@
IConfigurationService
configurationService
:
IConfigurationService
,
@
IConfigurationService
private
configurationService
:
IConfigurationService
,
@
ILifecycleService
private
lifecycleService
:
ILifecycleService
,
@
IFileService
private
fileService
:
IFileService
,
@
IWindowService
private
windowService
:
IWindowService
@
IWindowService
private
windowService
:
IWindowService
,
@
IInstantiationService
private
instantiationService
:
IInstantiationService
,
)
{
super
(
editorGroupService
,
editorService
,
contextService
,
configurationService
);
super
(
editorGroupService
,
editorService
);
this
.
index
=
-
1
;
this
.
stack
=
[];
this
.
recentlyClosedFiles
=
[];
this
.
loaded
=
false
;
this
.
registry
=
Registry
.
as
<
IEditorRegistry
>
(
Extensions
.
Editors
);
this
.
resourceFilter
=
instantiationService
.
createInstance
(
ResourceGlobMatcher
,
root
=>
this
.
getExcludes
(
root
),
(
expression
:
IExpression
)
=>
parse
(
expression
));
this
.
registerListeners
();
}
private
getExcludes
(
root
?:
URI
):
IExpression
{
const
scope
=
root
?
{
resource
:
root
}
:
void
0
;
return
getExcludes
(
this
.
configurationService
.
getConfiguration
<
ISearchConfiguration
>
(
void
0
,
scope
));
}
private
registerListeners
():
void
{
this
.
toUnbind
.
push
(
this
.
lifecycleService
.
onShutdown
(
reason
=>
this
.
save
()));
this
.
toUnbind
.
push
(
this
.
editorGroupService
.
onEditorOpenFail
(
editor
=>
this
.
remove
(
editor
)));
this
.
toUnbind
.
push
(
this
.
editorGroupService
.
getStacksModel
().
onEditorClosed
(
event
=>
this
.
onEditorClosed
(
event
)));
// File changes
this
.
toUnbind
.
push
(
this
.
fileService
.
onFileChanges
(
e
=>
this
.
onFileChanges
(
e
)));
this
.
toUnbind
.
push
(
this
.
resourceFilter
.
onExpressionChange
(()
=>
this
.
handleExcludesChange
()));
}
private
onFileChanges
(
e
:
FileChangesEvent
):
void
{
...
...
@@ -422,10 +381,8 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
}
const
resourceInput
=
input
as
IResourceInput
;
const
rootForInput
=
this
.
contextService
.
getRoot
(
resourceInput
.
resource
);
const
excludesForInput
=
this
.
mapRootToExcludes
.
get
(
rootForInput
?
rootForInput
.
toString
()
:
null
);
return
!
excludesForInput
(
getPathLabel
(
resourceInput
.
resource
,
this
.
contextService
)
);
return
!
this
.
resourceFilter
.
matches
(
resourceInput
.
resource
);
}
protected
handleExcludesChange
():
void
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录