@@ -13,7 +13,7 @@ import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list
13
13
import { ElementsDragAndDropData , ListViewTargetSector } from 'vs/base/browser/ui/list/listView' ;
14
14
import { IAsyncDataSource , ITreeContextMenuEvent , ITreeDragAndDrop , ITreeDragOverReaction , ITreeNode , ITreeRenderer , TreeDragOverBubble } from 'vs/base/browser/ui/tree/tree' ;
15
15
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults' ;
16
- import { ActionRunner , IAction } from 'vs/base/common/actions' ;
16
+ import { ActionRunner , IAction , Separator } from 'vs/base/common/actions' ;
17
17
import { timeout } from 'vs/base/common/async' ;
18
18
import { CancellationToken , CancellationTokenSource } from 'vs/base/common/cancellation' ;
19
19
import { Codicon } from 'vs/base/common/codicons' ;
@@ -1599,13 +1599,53 @@ class TreeMenus implements IDisposable {
1599
1599
this . contextKeyService = service ;
1600
1600
}
1601
1601
1602
+ private filterNonUniversalActions ( groups : Map < string , IAction > [ ] , newActions : IAction [ ] ) {
1603
+ const newActionsSet : Set < string > = new Set ( newActions . map ( a => a . id ) ) ;
1604
+ for ( const group of groups ) {
1605
+ const actions = group . keys ( ) ;
1606
+ for ( const action of actions ) {
1607
+ if ( ! newActionsSet . has ( action ) ) {
1608
+ group . delete ( action ) ;
1609
+ }
1610
+ }
1611
+ }
1612
+ }
1613
+
1614
+ private buildMenu ( groups : Map < string , IAction > [ ] ) : IAction [ ] {
1615
+ const result : IAction [ ] = [ ] ;
1616
+ for ( const group of groups ) {
1617
+ if ( group . size > 0 ) {
1618
+ if ( result . length ) {
1619
+ result . push ( new Separator ( ) ) ;
1620
+ }
1621
+ result . push ( ...group . values ( ) ) ;
1622
+ }
1623
+ }
1624
+ return result ;
1625
+ }
1626
+
1627
+ private createGroups ( actions : IAction [ ] ) : Map < string , IAction > [ ] {
1628
+ const groups : Map < string , IAction > [ ] = [ ] ;
1629
+ let group : Map < string , IAction > = new Map ( ) ;
1630
+ for ( const action of actions ) {
1631
+ if ( action instanceof Separator ) {
1632
+ groups . push ( group ) ;
1633
+ group = new Map ( ) ;
1634
+ } else {
1635
+ group . set ( action . id , action ) ;
1636
+ }
1637
+ }
1638
+ groups . push ( group ) ;
1639
+ return groups ;
1640
+ }
1641
+
1602
1642
private getActions ( menuId : MenuId , elements : ITreeItem [ ] , listen ?: DisposableStore ) : { primary : IAction [ ] ; secondary : IAction [ ] } {
1603
1643
if ( ! this . contextKeyService ) {
1604
1644
return { primary : [ ] , secondary : [ ] } ;
1605
1645
}
1606
1646
1607
- const allowedPrimary = new Map < string , IAction > ( ) ;
1608
- const allowedSecondary = new Map < string , IAction > ( ) ;
1647
+ let primaryGroups : Map < string , IAction > [ ] = [ ] ;
1648
+ let secondaryGroups : Map < string , IAction > [ ] = [ ] ;
1609
1649
for ( let i = 0 ; i < elements . length ; i ++ ) {
1610
1650
const element = elements [ i ] ;
1611
1651
const contextKeyService = this . contextKeyService . createOverlay ( [
@@ -1619,25 +1659,11 @@ class TreeMenus implements IDisposable {
1619
1659
const result = { primary, secondary, menu } ;
1620
1660
createAndFillInContextMenuActions ( menu , { shouldForwardArgs : true } , result , 'inline' ) ;
1621
1661
if ( i === 0 ) {
1622
- for ( const action of result . primary ) {
1623
- allowedPrimary . set ( action . id , action ) ;
1624
- }
1625
- for ( const action of result . secondary ) {
1626
- allowedSecondary . set ( action . id , action ) ;
1627
- }
1662
+ primaryGroups = this . createGroups ( result . primary ) ;
1663
+ secondaryGroups = this . createGroups ( result . secondary ) ;
1628
1664
} else {
1629
- const primaryKeys = allowedPrimary . keys ( ) ;
1630
- for ( const key of primaryKeys ) {
1631
- if ( ! result . primary . some ( action => action . id === key ) ) {
1632
- allowedPrimary . delete ( key ) ;
1633
- }
1634
- }
1635
- const secondaryKeys = allowedSecondary . keys ( ) ;
1636
- for ( const key of secondaryKeys ) {
1637
- if ( ! result . secondary . some ( action => action . id === key ) ) {
1638
- allowedSecondary . delete ( key ) ;
1639
- }
1640
- }
1665
+ this . filterNonUniversalActions ( primaryGroups , result . primary ) ;
1666
+ this . filterNonUniversalActions ( secondaryGroups , result . secondary ) ;
1641
1667
}
1642
1668
if ( listen && elements . length === 1 ) {
1643
1669
listen . add ( menu . onDidChange ( ( ) => this . _onDidChange . fire ( element ) ) ) ;
@@ -1647,7 +1673,7 @@ class TreeMenus implements IDisposable {
1647
1673
}
1648
1674
}
1649
1675
1650
- return { primary : Array . from ( allowedPrimary . values ( ) ) , secondary : Array . from ( allowedSecondary . values ( ) ) } ;
1676
+ return { primary : this . buildMenu ( primaryGroups ) , secondary : this . buildMenu ( secondaryGroups ) } ;
1651
1677
}
1652
1678
1653
1679
dispose ( ) {
0 commit comments