Skip to content

Commit 5e2de16

Browse files
committed
feat: toggle tree view nesting
1 parent f51f380 commit 5e2de16

File tree

9 files changed

+90
-21
lines changed

9 files changed

+90
-21
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@
1111
- If no Taskfile is detected a button will appear in the sidebar.
1212
- Refresh on save.
1313
- Configurable via `task.updateOn` setting (values: `save` (default) or `manual`).
14+
- Toggle tree nesting on/off
15+
- Configurable via `task.nesting` setting (values: `true` (default) or `false`).
1416
- Sidebar icon provided by @drite93.

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,10 @@
2929
---
3030

3131
![Task for Visual Studio Code Preview](./res/preview.png)
32+
33+
## Configuration
34+
35+
| Setting | Type | Allowed Values | Default | Description |
36+
| -------------- | --------- | -------------------- | -------- | ------------------------------------------------ |
37+
| `updateOn` | `string` | `"manual"`, `"save"` | `"save"` | When should the task list be updated. |
38+
| `tree.nesting` | `boolean` | | `true` | Should the task list be nested or not by default |

package.json

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@
4848
"category": "Task",
4949
"icon": "$(refresh)"
5050
},
51+
{
52+
"command": "vscode-task.viewAsList",
53+
"title": "View as List",
54+
"category": "Task Tree",
55+
"icon": "$(list-tree)"
56+
},
57+
{
58+
"command": "vscode-task.viewAsTree",
59+
"title": "View as Tree",
60+
"category": "Task Tree",
61+
"icon": "$(list-flat)"
62+
},
5163
{
5264
"command": "vscode-task.runTask",
5365
"title": "Run Task",
@@ -117,7 +129,17 @@
117129
{
118130
"command": "vscode-task.refresh",
119131
"when": "view == vscode-task.tasks",
120-
"group": "navigation"
132+
"group": "navigation@1"
133+
},
134+
{
135+
"command": "vscode-task.viewAsList",
136+
"when": "view == vscode-task.tasks && vscode-task:treeNesting",
137+
"group": "navigation@2"
138+
},
139+
{
140+
"command": "vscode-task.viewAsTree",
141+
"when": "view == vscode-task.tasks && !vscode-task:treeNesting",
142+
"group": "navigation@3"
121143
}
122144
],
123145
"view/item/context": [
@@ -190,6 +212,17 @@
190212
],
191213
"default": "save",
192214
"description": "When the list of tasks should be updated."
215+
},
216+
"tree": {
217+
"type": "object",
218+
"description": "Tree view configuration options.",
219+
"properties": {
220+
"nesting": {
221+
"type": "boolean",
222+
"default": true,
223+
"description": "Whether to nest tasks by their namespace in the tree view."
224+
}
225+
}
193226
}
194227
}
195228
}

res/preview.png

331 Bytes
Loading

src/elements/activityBar.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import * as providers from '../providers';
33
import * as models from '../models';
44

55
export class ActivityBar {
6-
private _provider: providers.Tasks;
6+
private _provider: providers.TaskTreeDataProvider;
77

88
constructor() {
99
// Create the data provider
10-
this._provider = new providers.Tasks();
10+
this._provider = new providers.TaskTreeDataProvider();
1111

1212
// Register the tree view with its data provider
1313
vscode.window.createTreeView('vscode-task.tasks', {
@@ -16,7 +16,12 @@ export class ActivityBar {
1616
});
1717
}
1818

19-
public refresh(taskfiles: models.Taskfile[]) {
19+
public setTreeNesting(enabled: boolean) {
20+
this._provider.setTreeNesting(enabled);
21+
this._provider.refresh();
22+
}
23+
24+
public refresh(taskfiles?: models.Taskfile[]) {
2025
this._provider.refresh(taskfiles);
2126
}
2227
}

src/providers/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './tasks';
1+
export * from './taskTreeDataProvider';
Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@ import * as path from 'path';
55

66
const namespaceSeparator = ':';
77

8-
export class Tasks implements vscode.TreeDataProvider<elements.TreeItem> {
8+
export class TaskTreeDataProvider implements vscode.TreeDataProvider<elements.TreeItem> {
99
private _onDidChangeTreeData: vscode.EventEmitter<elements.TaskTreeItem | undefined> = new vscode.EventEmitter<elements.TaskTreeItem | undefined>();
1010
readonly onDidChangeTreeData: vscode.Event<elements.TaskTreeItem | undefined> = this._onDidChangeTreeData.event;
1111
private _taskfiles?: models.Taskfile[];
1212

13+
constructor(
14+
private nestingEnabled: boolean = false
15+
) { }
16+
17+
setTreeNesting(enabled: boolean) {
18+
this.nestingEnabled = enabled;
19+
}
20+
1321
getTreeItem(element: elements.TreeItem): vscode.TreeItem {
1422
return element;
1523
}
@@ -74,7 +82,7 @@ export class Tasks implements vscode.TreeDataProvider<elements.TreeItem> {
7482

7583
// Check if the task has a namespace
7684
// If it does, add it to the namespace/tasks map
77-
if (namespacePath !== "") {
85+
if (this.nestingEnabled && namespacePath !== "") {
7886
let namespaceLabel = getNamespaceLabel(namespacePath);
7987
let namespaceTreeItem = namespaceTreeItems.get(namespaceLabel) ?? new elements.NamespaceTreeItem(
8088
namespaceLabel,
@@ -89,7 +97,7 @@ export class Tasks implements vscode.TreeDataProvider<elements.TreeItem> {
8997

9098
// Otherwise, create a tree item for the task
9199
else {
92-
let taskLabel = getTaskLabel(task);
100+
let taskLabel = getTaskLabel(task, this.nestingEnabled);
93101
let taskTreeItem = new elements.TaskTreeItem(
94102
taskLabel,
95103
workspace,
@@ -138,8 +146,10 @@ export class Tasks implements vscode.TreeDataProvider<elements.TreeItem> {
138146
return workspaceTreeItems;
139147
}
140148

141-
refresh(taskfiles: models.Taskfile[]): void {
142-
this._taskfiles = taskfiles;
149+
refresh(taskfiles?: models.Taskfile[]): void {
150+
if (taskfiles) {
151+
this._taskfiles = taskfiles;
152+
}
143153
this._onDidChangeTreeData.fire(undefined);
144154
}
145155
}
@@ -174,9 +184,9 @@ function getNamespaceLabel(namespacePath: string): string {
174184
return namespacePath.substring(0, namespacePath.indexOf(namespaceSeparator));
175185
}
176186

177-
function getTaskLabel(task: models.Task): string {
187+
function getTaskLabel(task: models.Task, nestingEnabled: boolean): string {
178188
// If the task has no namespace, return the task's name
179-
if (!task.name.includes(namespaceSeparator)) {
189+
if (!task.name.includes(namespaceSeparator) || !nestingEnabled) {
180190
return task.name;
181191
}
182192
// Return the task's name by removing the namespace

src/settings.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
11
import * as vscode from 'vscode';
22

3-
43
export class Settings {
4+
public updateOn!: string;
5+
public treeNesting!: boolean;
56

67
constructor() {
78
this.update();
89
}
910

10-
// Variables
11-
public updateOn!: string;
12-
1311
// Fetches all the settings from the workspace configuration file
1412
public update() {
1513
// Get the workspace config
1614
let config = vscode.workspace.getConfiguration("task");
1715

18-
// Get the configs
19-
let updateOn: string | undefined = config.get("updateOn");
20-
21-
// Set the configs
22-
this.updateOn = updateOn !== undefined ? updateOn : "change";
16+
// Set the properties
17+
this.updateOn = config.get("updateOn") ?? "change";
18+
this.treeNesting = config.get("tree.nesting") ?? true;
2319
}
2420
}

src/task.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export class TaskExtension {
1414
this._settings = new Settings();
1515
this._activityBar = new elements.ActivityBar();
1616
this._watcher = vscode.workspace.createFileSystemWatcher("**/*.{yml,yaml}");
17+
this.setTreeNesting(this._settings.treeNesting);
1718
}
1819

1920
public async update(): Promise<void> {
@@ -38,6 +39,11 @@ export class TaskExtension {
3839
});
3940
}
4041

42+
public setTreeNesting(enabled: boolean): void {
43+
this._activityBar.setTreeNesting(enabled);
44+
vscode.commands.executeCommand('setContext', 'vscode-task:treeNesting', enabled);
45+
}
46+
4147
public registerCommands(context: vscode.ExtensionContext): void {
4248

4349
// Initialise Taskfile
@@ -65,6 +71,16 @@ export class TaskExtension {
6571
this.updateAndRefresh();
6672
}));
6773

74+
// View tasks as list
75+
context.subscriptions.push(vscode.commands.registerCommand('vscode-task.viewAsList', () => {
76+
this.setTreeNesting(false);
77+
}));
78+
79+
// View tasks as tree
80+
context.subscriptions.push(vscode.commands.registerCommand('vscode-task.viewAsTree', () => {
81+
this.setTreeNesting(true);
82+
}));
83+
6884
// Run task
6985
context.subscriptions.push(vscode.commands.registerCommand('vscode-task.runTask', (treeItem?: elements.TaskTreeItem) => {
7086
if (treeItem?.task) {

0 commit comments

Comments
 (0)