Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
bede31d0
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,体验更适合开发者的 AI 搜索 >>
提交
bede31d0
编写于
10月 11, 2019
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
resource tree: support data in branches
上级
a6981175
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
159 addition
and
157 deletion
+159
-157
src/vs/base/common/resourceTree.ts
src/vs/base/common/resourceTree.ts
+68
-87
src/vs/base/test/common/resourceTree.test.ts
src/vs/base/test/common/resourceTree.test.ts
+41
-17
src/vs/workbench/contrib/scm/browser/repositoryPanel.ts
src/vs/workbench/contrib/scm/browser/repositoryPanel.ts
+50
-53
未找到文件。
src/vs/base/common/resourceTree.ts
浏览文件 @
bede31d0
...
...
@@ -11,58 +11,48 @@ import { URI } from 'vs/base/common/uri';
import
{
mapValues
}
from
'
vs/base/common/collections
'
;
import
{
PathIterator
}
from
'
vs/base/common/map
'
;
export
interface
I
Leaf
Node
<
T
,
C
=
void
>
{
export
interface
I
Resource
Node
<
T
,
C
=
void
>
{
readonly
uri
:
URI
;
readonly
relativePath
:
string
;
readonly
name
:
string
;
readonly
element
:
T
;
readonly
element
:
T
|
undefined
;
readonly
children
:
Iterator
<
IResourceNode
<
T
,
C
>>
;
readonly
childrenCount
:
number
;
readonly
parent
:
IResourceNode
<
T
,
C
>
|
undefined
;
readonly
context
:
C
;
get
(
childName
:
string
):
IResourceNode
<
T
,
C
>
|
undefined
;
}
export
interface
IBranchNode
<
T
,
C
=
void
>
{
readonly
uri
:
URI
;
readonly
relativePath
:
string
;
readonly
name
:
string
;
readonly
size
:
number
;
readonly
children
:
Iterator
<
INode
<
T
,
C
>>
;
readonly
parent
:
IBranchNode
<
T
,
C
>
|
undefined
;
readonly
context
:
C
;
get
(
childName
:
string
):
INode
<
T
,
C
>
|
undefined
;
}
export
type
INode
<
T
,
C
>
=
IBranchNode
<
T
,
C
>
|
ILeafNode
<
T
,
C
>
;
// Internals
class
Node
<
C
>
{
@
memoize
get
name
():
string
{
return
paths
.
posix
.
basename
(
this
.
relativePath
);
}
constructor
(
readonly
uri
:
URI
,
readonly
relativePath
:
string
,
readonly
context
:
C
)
{
}
}
class
BranchNode
<
T
,
C
>
extends
Node
<
C
>
implements
IBranchNode
<
T
,
C
>
{
class
Node
<
T
,
C
>
implements
IResourceNode
<
T
,
C
>
{
private
_children
=
new
Map
<
string
,
BranchNode
<
T
,
C
>
|
Leaf
Node
<
T
,
C
>>
();
private
_children
=
new
Map
<
string
,
Node
<
T
,
C
>>
();
get
size
():
number
{
get
childrenCount
():
number
{
return
this
.
_children
.
size
;
}
get
children
():
Iterator
<
BranchNode
<
T
,
C
>
|
Leaf
Node
<
T
,
C
>>
{
get
children
():
Iterator
<
Node
<
T
,
C
>>
{
return
Iterator
.
fromArray
(
mapValues
(
this
.
_children
));
}
constructor
(
uri
:
URI
,
relativePath
:
string
,
context
:
C
,
readonly
parent
:
IBranchNode
<
T
,
C
>
|
undefined
=
undefined
)
{
super
(
uri
,
relativePath
,
context
);
@
memoize
get
name
():
string
{
return
paths
.
posix
.
basename
(
this
.
relativePath
);
}
get
(
path
:
string
):
BranchNode
<
T
,
C
>
|
LeafNode
<
T
,
C
>
|
undefined
{
constructor
(
readonly
uri
:
URI
,
readonly
relativePath
:
string
,
readonly
context
:
C
,
public
element
:
T
|
undefined
=
undefined
,
readonly
parent
:
IResourceNode
<
T
,
C
>
|
undefined
=
undefined
)
{
}
get
(
path
:
string
):
Node
<
T
,
C
>
|
undefined
{
return
this
.
_children
.
get
(
path
);
}
set
(
path
:
string
,
child
:
BranchNode
<
T
,
C
>
|
Leaf
Node
<
T
,
C
>
):
void
{
set
(
path
:
string
,
child
:
Node
<
T
,
C
>
):
void
{
this
.
_children
.
set
(
path
,
child
);
}
...
...
@@ -75,32 +65,21 @@ class BranchNode<T, C> extends Node<C> implements IBranchNode<T, C> {
}
}
class
LeafNode
<
T
,
C
>
extends
Node
<
C
>
implements
ILeafNode
<
T
,
C
>
{
constructor
(
uri
:
URI
,
path
:
string
,
context
:
C
,
readonly
element
:
T
)
{
super
(
uri
,
path
,
context
);
}
}
function
collect
<
T
,
C
>
(
node
:
INode
<
T
,
C
>
,
result
:
T
[]):
T
[]
{
if
(
ResourceTree
.
isBranchNode
(
node
))
{
Iterator
.
forEach
(
node
.
children
,
child
=>
collect
(
child
,
result
));
}
else
{
function
collect
<
T
,
C
>
(
node
:
IResourceNode
<
T
,
C
>
,
result
:
T
[]):
T
[]
{
if
(
typeof
node
.
element
!==
'
undefined
'
)
{
result
.
push
(
node
.
element
);
}
Iterator
.
forEach
(
node
.
children
,
child
=>
collect
(
child
,
result
));
return
result
;
}
export
class
ResourceTree
<
T
extends
NonNullable
<
any
>
,
C
>
{
readonly
root
:
BranchNode
<
T
,
C
>
;
static
isBranchNode
<
T
,
C
>
(
obj
:
any
):
obj
is
IBranchNode
<
T
,
C
>
{
return
obj
instanceof
BranchNode
;
}
readonly
root
:
Node
<
T
,
C
>
;
static
getRoot
<
T
,
C
>
(
node
:
I
BranchNode
<
T
,
C
>
):
IBranch
Node
<
T
,
C
>
{
static
getRoot
<
T
,
C
>
(
node
:
I
ResourceNode
<
T
,
C
>
):
IResource
Node
<
T
,
C
>
{
while
(
node
.
parent
)
{
node
=
node
.
parent
;
}
...
...
@@ -108,12 +87,16 @@ export class ResourceTree<T extends NonNullable<any>, C> {
return
node
;
}
static
collect
<
T
,
C
>
(
node
:
INode
<
T
,
C
>
):
T
[]
{
static
collect
<
T
,
C
>
(
node
:
I
Resource
Node
<
T
,
C
>
):
T
[]
{
return
collect
(
node
,
[]);
}
static
isResourceNode
<
T
,
C
>
(
obj
:
any
):
obj
is
IResourceNode
<
T
,
C
>
{
return
obj
instanceof
Node
;
}
constructor
(
context
:
C
,
rootURI
:
URI
=
URI
.
file
(
'
/
'
))
{
this
.
root
=
new
Branch
Node
(
rootURI
,
''
,
context
);
this
.
root
=
new
Node
(
rootURI
,
''
,
context
);
}
add
(
uri
:
URI
,
element
:
T
):
void
{
...
...
@@ -129,26 +112,17 @@ export class ResourceTree<T extends NonNullable<any>, C> {
let
child
=
node
.
get
(
name
);
if
(
!
child
)
{
if
(
iterator
.
hasNext
())
{
child
=
new
BranchNode
(
joinPath
(
this
.
root
.
uri
,
path
),
path
,
this
.
root
.
context
,
node
);
node
.
set
(
name
,
child
);
}
else
{
child
=
new
LeafNode
(
uri
,
path
,
this
.
root
.
context
,
element
);
node
.
set
(
name
,
child
);
return
;
}
}
if
(
!
(
child
instanceof
BranchNode
))
{
if
(
iterator
.
hasNext
())
{
throw
new
Error
(
'
Inconsistent tree: can
\'
t override leaf with branch.
'
);
}
// replace
node
.
set
(
name
,
new
LeafNode
(
uri
,
path
,
this
.
root
.
context
,
element
));
return
;
child
=
new
Node
(
joinPath
(
this
.
root
.
uri
,
path
),
path
,
this
.
root
.
context
,
iterator
.
hasNext
()
?
undefined
:
element
,
node
);
node
.
set
(
name
,
child
);
}
else
if
(
!
iterator
.
hasNext
())
{
throw
new
Error
(
'
Inconsistent tree: can
\'
t override branch with leaf.
'
)
;
child
.
element
=
element
;
}
node
=
child
;
...
...
@@ -167,7 +141,7 @@ export class ResourceTree<T extends NonNullable<any>, C> {
return
this
.
_delete
(
this
.
root
,
iterator
);
}
private
_delete
(
node
:
Branch
Node
<
T
,
C
>
,
iterator
:
PathIterator
):
T
|
undefined
{
private
_delete
(
node
:
Node
<
T
,
C
>
,
iterator
:
PathIterator
):
T
|
undefined
{
const
name
=
iterator
.
value
();
const
child
=
node
.
get
(
name
);
...
...
@@ -175,25 +149,14 @@ export class ResourceTree<T extends NonNullable<any>, C> {
return
undefined
;
}
// not at end
if
(
iterator
.
hasNext
())
{
if
(
child
instanceof
BranchNode
)
{
const
result
=
this
.
_delete
(
child
,
iterator
.
next
());
const
result
=
this
.
_delete
(
child
,
iterator
.
next
());
if
(
typeof
result
!==
'
undefined
'
&&
child
.
size
===
0
)
{
node
.
delete
(
name
);
}
return
result
;
}
else
{
throw
new
Error
(
'
Inconsistent tree: Expected a branch, found a leaf instead.
'
);
if
(
typeof
result
!==
'
undefined
'
&&
child
.
childrenCount
===
0
)
{
node
.
delete
(
name
);
}
}
//at end
if
(
child
instanceof
BranchNode
)
{
// TODO: maybe we can allow this
throw
new
Error
(
'
Inconsistent tree: Expected a leaf, found a branch instead.
'
);
return
result
;
}
node
.
delete
(
name
);
...
...
@@ -203,4 +166,22 @@ export class ResourceTree<T extends NonNullable<any>, C> {
clear
():
void
{
this
.
root
.
clear
();
}
getNode
(
uri
:
URI
):
IResourceNode
<
T
,
C
>
|
undefined
{
const
key
=
relativePath
(
this
.
root
.
uri
,
uri
)
||
uri
.
fsPath
;
const
iterator
=
new
PathIterator
(
false
).
reset
(
key
);
let
node
=
this
.
root
;
while
(
true
)
{
const
name
=
iterator
.
value
();
const
child
=
node
.
get
(
name
);
if
(
!
child
||
!
iterator
.
hasNext
())
{
return
child
;
}
node
=
child
;
iterator
.
next
();
}
}
}
src/vs/base/test/common/resourceTree.test.ts
浏览文件 @
bede31d0
...
...
@@ -4,46 +4,70 @@
*--------------------------------------------------------------------------------------------*/
import
*
as
assert
from
'
assert
'
;
import
{
ResourceTree
,
IBranchNode
,
ILeafNode
}
from
'
vs/base/common/resourceTree
'
;
import
{
ResourceTree
}
from
'
vs/base/common/resourceTree
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
suite
(
'
ResourceTree
'
,
function
()
{
suite
.
only
(
'
ResourceTree
'
,
function
()
{
test
(
'
ctor
'
,
function
()
{
const
tree
=
new
ResourceTree
<
string
,
null
>
(
null
);
assert
(
ResourceTree
.
isBranchNode
(
tree
.
root
));
assert
.
equal
(
tree
.
root
.
size
,
0
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
0
);
});
test
(
'
simple
'
,
function
()
{
const
tree
=
new
ResourceTree
<
string
,
null
>
(
null
);
tree
.
add
(
URI
.
file
(
'
/foo/bar.txt
'
),
'
bar contents
'
);
assert
(
ResourceTree
.
isBranchNode
(
tree
.
root
));
assert
.
equal
(
tree
.
root
.
size
,
1
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
1
);
let
foo
=
tree
.
root
.
get
(
'
foo
'
)
as
IBranchNode
<
string
,
null
>
;
let
foo
=
tree
.
root
.
get
(
'
foo
'
)
!
;
assert
(
foo
);
assert
(
ResourceTree
.
isBranchNode
(
foo
));
assert
.
equal
(
foo
.
size
,
1
);
assert
.
equal
(
foo
.
childrenCount
,
1
);
let
bar
=
foo
.
get
(
'
bar.txt
'
)
as
ILeafNode
<
string
,
null
>
;
let
bar
=
foo
.
get
(
'
bar.txt
'
)
!
;
assert
(
bar
);
assert
(
!
ResourceTree
.
isBranchNode
(
bar
));
assert
.
equal
(
bar
.
element
,
'
bar contents
'
);
tree
.
add
(
URI
.
file
(
'
/hello.txt
'
),
'
hello contents
'
);
assert
.
equal
(
tree
.
root
.
size
,
2
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
2
);
let
hello
=
tree
.
root
.
get
(
'
hello.txt
'
)
as
ILeafNode
<
string
,
null
>
;
let
hello
=
tree
.
root
.
get
(
'
hello.txt
'
)
!
;
assert
(
hello
);
assert
(
!
ResourceTree
.
isBranchNode
(
hello
));
assert
.
equal
(
hello
.
element
,
'
hello contents
'
);
tree
.
delete
(
URI
.
file
(
'
/foo/bar.txt
'
));
assert
.
equal
(
tree
.
root
.
size
,
1
);
hello
=
tree
.
root
.
get
(
'
hello.txt
'
)
as
ILeafNode
<
string
,
null
>
;
assert
.
equal
(
tree
.
root
.
childrenCount
,
1
);
hello
=
tree
.
root
.
get
(
'
hello.txt
'
)
!
;
assert
(
hello
);
assert
(
!
ResourceTree
.
isBranchNode
(
hello
));
assert
.
equal
(
hello
.
element
,
'
hello contents
'
);
});
test
(
'
folders with data
'
,
function
()
{
const
tree
=
new
ResourceTree
<
string
,
null
>
(
null
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
0
);
tree
.
add
(
URI
.
file
(
'
/foo
'
),
'
foo
'
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
1
);
assert
.
equal
(
tree
.
root
.
get
(
'
foo
'
)
!
.
element
,
'
foo
'
);
tree
.
add
(
URI
.
file
(
'
/bar
'
),
'
bar
'
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
2
);
assert
.
equal
(
tree
.
root
.
get
(
'
bar
'
)
!
.
element
,
'
bar
'
);
tree
.
add
(
URI
.
file
(
'
/foo/file.txt
'
),
'
file
'
);
assert
.
equal
(
tree
.
root
.
childrenCount
,
2
);
assert
.
equal
(
tree
.
root
.
get
(
'
foo
'
)
!
.
element
,
'
foo
'
);
assert
.
equal
(
tree
.
root
.
get
(
'
bar
'
)
!
.
element
,
'
bar
'
);
assert
.
equal
(
tree
.
root
.
get
(
'
foo
'
)
!
.
get
(
'
file.txt
'
)
!
.
element
,
'
file
'
);
tree
.
delete
(
URI
.
file
(
'
/foo
'
));
assert
.
equal
(
tree
.
root
.
childrenCount
,
1
);
assert
(
!
tree
.
root
.
get
(
'
foo
'
));
assert
.
equal
(
tree
.
root
.
get
(
'
bar
'
)
!
.
element
,
'
bar
'
);
tree
.
delete
(
URI
.
file
(
'
/bar
'
));
assert
.
equal
(
tree
.
root
.
childrenCount
,
0
);
assert
(
!
tree
.
root
.
get
(
'
foo
'
));
assert
(
!
tree
.
root
.
get
(
'
bar
'
));
});
});
src/vs/workbench/contrib/scm/browser/repositoryPanel.ts
浏览文件 @
bede31d0
...
...
@@ -6,7 +6,7 @@
import
'
vs/css!./media/scmViewlet
'
;
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
domEvent
}
from
'
vs/base/browser/event
'
;
import
{
basename
,
isEqual
}
from
'
vs/base/common/resources
'
;
import
{
basename
}
from
'
vs/base/common/resources
'
;
import
{
IDisposable
,
Disposable
,
DisposableStore
,
combinedDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
ViewletPanel
,
IViewletPanelOptions
}
from
'
vs/workbench/browser/parts/views/panelViewlet
'
;
import
{
append
,
$
,
addClass
,
toggleClass
,
trackFocus
,
removeClass
}
from
'
vs/base/browser/dom
'
;
...
...
@@ -37,7 +37,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import
*
as
platform
from
'
vs/base/common/platform
'
;
import
{
ITreeNode
,
ITreeFilter
,
ITreeSorter
,
ITreeContextMenuEvent
}
from
'
vs/base/browser/ui/tree/tree
'
;
import
{
ISplice
}
from
'
vs/base/common/sequence
'
;
import
{
ResourceTree
,
I
BranchNode
,
I
Node
}
from
'
vs/base/common/resourceTree
'
;
import
{
ResourceTree
,
I
Resource
Node
}
from
'
vs/base/common/resourceTree
'
;
import
{
ObjectTree
,
ICompressibleTreeRenderer
,
ICompressibleKeyboardNavigationLabelProvider
}
from
'
vs/base/browser/ui/tree/objectTree
'
;
import
{
Iterator
}
from
'
vs/base/common/iterator
'
;
import
{
ICompressedTreeNode
,
ICompressedTreeElement
}
from
'
vs/base/browser/ui/tree/compressedObjectTreeModel
'
;
...
...
@@ -53,7 +53,7 @@ import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/th
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
toResource
,
SideBySideEditor
}
from
'
vs/workbench/common/editor
'
;
type
TreeElement
=
ISCMResourceGroup
|
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
|
ISCMResource
;
type
TreeElement
=
ISCMResourceGroup
|
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
|
ISCMResource
;
interface
ResourceGroupTemplate
{
readonly
name
:
HTMLElement
;
...
...
@@ -132,11 +132,11 @@ interface ResourceTemplate {
class
MultipleSelectionActionRunner
extends
ActionRunner
{
constructor
(
private
getSelectedResources
:
()
=>
(
ISCMResource
|
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
)[])
{
constructor
(
private
getSelectedResources
:
()
=>
(
ISCMResource
|
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
)[])
{
super
();
}
runAction
(
action
:
IAction
,
context
:
ISCMResource
|
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
):
Promise
<
any
>
{
runAction
(
action
:
IAction
,
context
:
ISCMResource
|
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
):
Promise
<
any
>
{
if
(
!
(
action
instanceof
MenuItemAction
))
{
return
super
.
runAction
(
action
,
context
);
}
...
...
@@ -144,12 +144,12 @@ class MultipleSelectionActionRunner extends ActionRunner {
const
selection
=
this
.
getSelectedResources
();
const
contextIsSelected
=
selection
.
some
(
s
=>
s
===
context
);
const
actualContext
=
contextIsSelected
?
selection
:
[
context
];
const
args
=
flatten
(
actualContext
.
map
(
e
=>
ResourceTree
.
is
Branch
Node
(
e
)
?
ResourceTree
.
collect
(
e
)
:
[
e
]));
const
args
=
flatten
(
actualContext
.
map
(
e
=>
ResourceTree
.
is
Resource
Node
(
e
)
?
ResourceTree
.
collect
(
e
)
:
[
e
]));
return
action
.
run
(...
args
);
}
}
class
ResourceRenderer
implements
ICompressibleTreeRenderer
<
ISCMResource
|
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
,
FuzzyScore
,
ResourceTemplate
>
{
class
ResourceRenderer
implements
ICompressibleTreeRenderer
<
ISCMResource
|
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
,
FuzzyScore
,
ResourceTemplate
>
{
static
readonly
TEMPLATE_ID
=
'
resource
'
;
get
templateId
():
string
{
return
ResourceRenderer
.
TEMPLATE_ID
;
}
...
...
@@ -158,7 +158,7 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IBran
private
viewModelProvider
:
()
=>
ViewModel
,
private
labels
:
ResourceLabels
,
private
actionViewItemProvider
:
IActionViewItemProvider
,
private
getSelectedResources
:
()
=>
(
ISCMResource
|
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
)[],
private
getSelectedResources
:
()
=>
(
ISCMResource
|
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
)[],
private
themeService
:
IThemeService
,
private
menus
:
SCMMenus
)
{
}
...
...
@@ -179,16 +179,16 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IBran
return
{
element
,
name
,
fileLabel
,
decorationIcon
,
actionBar
,
elementDisposables
:
Disposable
.
None
,
disposables
};
}
renderElement
(
node
:
ITreeNode
<
ISCMResource
,
FuzzyScore
>
|
ITreeNode
<
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
):
void
{
renderElement
(
node
:
ITreeNode
<
ISCMResource
,
FuzzyScore
>
|
ITreeNode
<
I
SCMResource
|
IResource
Node
<
ISCMResource
,
ISCMResourceGroup
>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
):
void
{
template
.
elementDisposables
.
dispose
();
const
elementDisposables
=
new
DisposableStore
();
const
resourceOrFolder
=
node
.
element
;
const
theme
=
this
.
themeService
.
getTheme
();
const
icon
=
!
ResourceTree
.
is
Branch
Node
(
resourceOrFolder
)
&&
(
theme
.
type
===
LIGHT
?
resourceOrFolder
.
decorations
.
icon
:
resourceOrFolder
.
decorations
.
iconDark
);
const
icon
=
!
ResourceTree
.
is
Resource
Node
(
resourceOrFolder
)
&&
(
theme
.
type
===
LIGHT
?
resourceOrFolder
.
decorations
.
icon
:
resourceOrFolder
.
decorations
.
iconDark
);
const
uri
=
ResourceTree
.
is
Branch
Node
(
resourceOrFolder
)
?
resourceOrFolder
.
uri
:
resourceOrFolder
.
sourceUri
;
const
fileKind
=
ResourceTree
.
is
Branch
Node
(
resourceOrFolder
)
?
FileKind
.
FOLDER
:
FileKind
.
FILE
;
const
uri
=
ResourceTree
.
is
Resource
Node
(
resourceOrFolder
)
?
resourceOrFolder
.
uri
:
resourceOrFolder
.
sourceUri
;
const
fileKind
=
ResourceTree
.
is
Resource
Node
(
resourceOrFolder
)
?
FileKind
.
FOLDER
:
FileKind
.
FILE
;
const
viewModel
=
this
.
viewModelProvider
();
template
.
fileLabel
.
setFile
(
uri
,
{
...
...
@@ -201,7 +201,7 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IBran
template
.
actionBar
.
clear
();
template
.
actionBar
.
context
=
resourceOrFolder
;
if
(
ResourceTree
.
is
Branch
Node
(
resourceOrFolder
))
{
if
(
ResourceTree
.
is
Resource
Node
(
resourceOrFolder
))
{
elementDisposables
.
add
(
connectPrimaryMenuToInlineActionBar
(
this
.
menus
.
getResourceFolderMenu
(
resourceOrFolder
.
context
),
template
.
actionBar
));
removeClass
(
template
.
name
,
'
strike-through
'
);
removeClass
(
template
.
element
,
'
faded
'
);
...
...
@@ -211,7 +211,7 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IBran
toggleClass
(
template
.
element
,
'
faded
'
,
resourceOrFolder
.
decorations
.
faded
);
}
const
tooltip
=
!
ResourceTree
.
is
Branch
Node
(
resourceOrFolder
)
&&
resourceOrFolder
.
decorations
.
tooltip
||
''
;
const
tooltip
=
!
ResourceTree
.
is
Resource
Node
(
resourceOrFolder
)
&&
resourceOrFolder
.
decorations
.
tooltip
||
''
;
if
(
icon
)
{
template
.
decorationIcon
.
style
.
display
=
''
;
...
...
@@ -227,15 +227,15 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IBran
template
.
elementDisposables
=
elementDisposables
;
}
disposeElement
(
resource
:
ITreeNode
<
ISCMResource
,
FuzzyScore
>
|
ITreeNode
<
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
):
void
{
disposeElement
(
resource
:
ITreeNode
<
ISCMResource
,
FuzzyScore
>
|
ITreeNode
<
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
):
void
{
template
.
elementDisposables
.
dispose
();
}
renderCompressedElements
(
node
:
ITreeNode
<
ICompressedTreeNode
<
ISCMResource
>
|
ICompressedTreeNode
<
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
,
height
:
number
|
undefined
):
void
{
renderCompressedElements
(
node
:
ITreeNode
<
ICompressedTreeNode
<
ISCMResource
>
|
ICompressedTreeNode
<
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
,
height
:
number
|
undefined
):
void
{
template
.
elementDisposables
.
dispose
();
const
elementDisposables
=
new
DisposableStore
();
const
compressed
=
node
.
element
as
ICompressedTreeNode
<
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>>
;
const
compressed
=
node
.
element
as
ICompressedTreeNode
<
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>>
;
const
folder
=
compressed
.
elements
[
compressed
.
elements
.
length
-
1
];
const
label
=
compressed
.
elements
.
map
(
e
=>
e
.
name
).
join
(
'
/
'
);
...
...
@@ -261,7 +261,7 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IBran
template
.
elementDisposables
=
elementDisposables
;
}
disposeCompressedElements
(
node
:
ITreeNode
<
ICompressedTreeNode
<
ISCMResource
>
|
ICompressedTreeNode
<
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
,
height
:
number
|
undefined
):
void
{
disposeCompressedElements
(
node
:
ITreeNode
<
ICompressedTreeNode
<
ISCMResource
>
|
ICompressedTreeNode
<
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>>
,
FuzzyScore
>
,
index
:
number
,
template
:
ResourceTemplate
,
height
:
number
|
undefined
):
void
{
template
.
elementDisposables
.
dispose
();
}
...
...
@@ -276,7 +276,7 @@ class ProviderListDelegate implements IListVirtualDelegate<TreeElement> {
getHeight
()
{
return
22
;
}
getTemplateId
(
element
:
TreeElement
)
{
if
(
ResourceTree
.
is
Branch
Node
(
element
)
||
isSCMResource
(
element
))
{
if
(
ResourceTree
.
is
Resource
Node
(
element
)
||
isSCMResource
(
element
))
{
return
ResourceRenderer
.
TEMPLATE_ID
;
}
else
{
return
ResourceGroupRenderer
.
TEMPLATE_ID
;
...
...
@@ -287,7 +287,7 @@ class ProviderListDelegate implements IListVirtualDelegate<TreeElement> {
class
SCMTreeFilter
implements
ITreeFilter
<
TreeElement
>
{
filter
(
element
:
TreeElement
):
boolean
{
if
(
ResourceTree
.
is
Branch
Node
(
element
))
{
if
(
ResourceTree
.
is
Resource
Node
(
element
))
{
return
true
;
}
else
if
(
isSCMResourceGroup
(
element
))
{
return
element
.
elements
.
length
>
0
||
!
element
.
hideWhenEmpty
;
...
...
@@ -313,15 +313,15 @@ export class SCMTreeSorter implements ITreeSorter<TreeElement> {
return
0
;
}
const
oneIsDirectory
=
ResourceTree
.
is
Branch
Node
(
one
);
const
otherIsDirectory
=
ResourceTree
.
is
Branch
Node
(
other
);
const
oneIsDirectory
=
ResourceTree
.
is
Resource
Node
(
one
);
const
otherIsDirectory
=
ResourceTree
.
is
Resource
Node
(
other
);
if
(
oneIsDirectory
!==
otherIsDirectory
)
{
return
oneIsDirectory
?
-
1
:
1
;
}
const
oneName
=
ResourceTree
.
is
Branch
Node
(
one
)
?
one
.
name
:
basename
((
one
as
ISCMResource
).
sourceUri
);
const
otherName
=
ResourceTree
.
is
Branch
Node
(
other
)
?
other
.
name
:
basename
((
other
as
ISCMResource
).
sourceUri
);
const
oneName
=
ResourceTree
.
is
Resource
Node
(
one
)
?
one
.
name
:
basename
((
one
as
ISCMResource
).
sourceUri
);
const
otherName
=
ResourceTree
.
is
Resource
Node
(
other
)
?
other
.
name
:
basename
((
other
as
ISCMResource
).
sourceUri
);
return
compareFileNames
(
oneName
,
otherName
);
}
...
...
@@ -330,7 +330,7 @@ export class SCMTreeSorter implements ITreeSorter<TreeElement> {
export
class
SCMTreeKeyboardNavigationLabelProvider
implements
ICompressibleKeyboardNavigationLabelProvider
<
TreeElement
>
{
getKeyboardNavigationLabel
(
element
:
TreeElement
):
{
toString
():
string
;
}
|
undefined
{
if
(
ResourceTree
.
is
Branch
Node
(
element
))
{
if
(
ResourceTree
.
is
Resource
Node
(
element
))
{
return
element
.
name
;
}
else
if
(
isSCMResourceGroup
(
element
))
{
return
element
.
label
;
...
...
@@ -340,7 +340,7 @@ export class SCMTreeKeyboardNavigationLabelProvider implements ICompressibleKeyb
}
getCompressedNodeKeyboardNavigationLabel
(
elements
:
TreeElement
[]):
{
toString
():
string
|
undefined
;
}
|
undefined
{
const
folders
=
elements
as
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
[];
const
folders
=
elements
as
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
[];
return
folders
.
map
(
e
=>
e
.
name
).
join
(
'
/
'
);
}
}
...
...
@@ -348,7 +348,7 @@ export class SCMTreeKeyboardNavigationLabelProvider implements ICompressibleKeyb
class
SCMResourceIdentityProvider
implements
IIdentityProvider
<
TreeElement
>
{
getId
(
element
:
TreeElement
):
string
{
if
(
ResourceTree
.
is
Branch
Node
(
element
))
{
if
(
ResourceTree
.
is
Resource
Node
(
element
))
{
const
group
=
element
.
context
;
return
`
${
group
.
provider
.
contextValue
}
/
${
group
.
id
}
/$FOLDER/
${
element
.
uri
.
toString
()}
`
;
}
else
if
(
isSCMResource
(
element
))
{
...
...
@@ -377,16 +377,16 @@ function groupItemAsTreeElement(item: IGroupItem, mode: ViewModelMode): ICompres
return
{
element
:
item
.
group
,
children
,
incompressible
:
true
,
collapsible
:
true
};
}
function
asTreeElement
(
node
:
INode
<
ISCMResource
,
ISCMResourceGroup
>
,
incompressible
:
boolean
):
ICompressedTreeElement
<
TreeElement
>
{
if
(
ResourceTree
.
isBranchNode
(
node
))
{
return
{
element
:
node
,
children
:
Iterator
.
map
(
node
.
children
,
node
=>
asTreeElement
(
node
,
false
)),
incompressible
};
function
asTreeElement
(
node
:
IResourceNode
<
ISCMResource
,
ISCMResourceGroup
>
,
forceIncompressible
:
boolean
):
ICompressedTreeElement
<
TreeElement
>
{
if
(
node
.
childrenCount
===
0
&&
node
.
element
)
{
return
{
element
:
node
.
element
,
incompressible
:
true
};
}
return
{
element
:
node
.
element
,
incompressible
:
true
};
return
{
element
:
node
,
children
:
Iterator
.
map
(
node
.
children
,
node
=>
asTreeElement
(
node
,
false
)),
incompressible
:
forceIncompressible
};
}
const
enum
ViewModelMode
{
...
...
@@ -538,17 +538,14 @@ class ViewModel {
}
// go backwards from last group
for
(
let
i
=
this
.
provider
.
groups
.
elements
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
group
=
this
.
provider
.
groups
.
elements
[
i
];
for
(
const
resource
of
group
.
elements
)
{
if
(
isEqual
(
uri
,
resource
.
sourceUri
))
{
this
.
tree
.
reveal
(
resource
);
this
.
tree
.
setSelection
([
resource
]);
this
.
tree
.
setFocus
([
resource
]);
return
;
}
for
(
let
i
=
this
.
items
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
node
=
this
.
items
[
i
].
tree
.
getNode
(
uri
);
if
(
node
&&
node
.
element
)
{
this
.
tree
.
reveal
(
node
.
element
);
this
.
tree
.
setSelection
([
node
.
element
]);
this
.
tree
.
setFocus
([
node
.
element
]);
return
;
}
}
}
...
...
@@ -753,12 +750,12 @@ export class RepositoryPanel extends ViewletPanel {
this
.
_register
(
Event
.
chain
(
this
.
tree
.
onDidOpen
)
.
map
(
e
=>
e
.
elements
[
0
])
.
filter
(
e
=>
!!
e
&&
!
ResourceTree
.
isBranchNode
(
e
)
&&
isSCMResourc
e
(
e
))
.
filter
(
e
=>
!!
e
&&
!
isSCMResourceGroup
(
e
)
&&
!
ResourceTree
.
isResourceNod
e
(
e
))
.
on
(
this
.
open
,
this
));
this
.
_register
(
Event
.
chain
(
this
.
tree
.
onDidPin
)
.
map
(
e
=>
e
.
elements
[
0
])
.
filter
(
e
=>
!!
e
&&
!
ResourceTree
.
isBranchNode
(
e
)
&&
isSCMResourc
e
(
e
))
.
filter
(
e
=>
!!
e
&&
!
isSCMResourceGroup
(
e
)
&&
!
ResourceTree
.
isResourceNod
e
(
e
))
.
on
(
this
.
pin
,
this
));
this
.
_register
(
this
.
tree
.
onContextMenu
(
this
.
onListContextMenu
,
this
));
...
...
@@ -911,12 +908,12 @@ export class RepositoryPanel extends ViewletPanel {
const
element
=
e
.
element
;
let
actions
:
IAction
[]
=
[];
if
(
ResourceTree
.
isBranchNode
(
element
))
{
if
(
isSCMResourceGroup
(
element
))
{
actions
=
this
.
menus
.
getResourceGroupContextActions
(
element
);
}
else
if
(
ResourceTree
.
isResourceNode
(
element
))
{
actions
=
this
.
menus
.
getResourceFolderContextActions
(
element
.
context
);
}
else
if
(
isSCMResource
(
element
))
{
actions
=
this
.
menus
.
getResourceContextActions
(
element
);
}
else
{
actions
=
this
.
menus
.
getResource
Group
ContextActions
(
element
);
actions
=
this
.
menus
.
getResourceContextActions
(
element
);
}
this
.
contextMenuService
.
showContextMenu
({
...
...
@@ -927,7 +924,7 @@ export class RepositoryPanel extends ViewletPanel {
});
}
private
getSelectedResources
():
(
ISCMResource
|
I
Branch
Node
<
ISCMResource
,
ISCMResourceGroup
>
)[]
{
private
getSelectedResources
():
(
ISCMResource
|
I
Resource
Node
<
ISCMResource
,
ISCMResourceGroup
>
)[]
{
return
this
.
tree
.
getSelection
()
.
filter
(
r
=>
!!
r
&&
!
isSCMResourceGroup
(
r
))
!
as
any
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录