Skip to content

Commit b875c03

Browse files
committed
code: Expose additional Sphinx process properties
This commit extends the Sphinx Process tree view to include additional details about the Sphinx processes currently managed by the server. - The value of `esbonio.sphinx.pythonCommand` - The value of `esbonio.sphinx.buildCommand` - The current builder name, as well as a (basic!) file tree exposing the contents of the build directory. This finally makes the files produced when esbonio writes to its default build dir easily accessible. Including these details not only helps the user figure out the current state of the server, but it provides an obvious location for additional management/maintainance commands in the future
1 parent 349c393 commit b875c03

File tree

3 files changed

+153
-19
lines changed

3 files changed

+153
-19
lines changed

code/changes/881.enchancement.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The Sphinx Process tree view now includes details including `esbonio.sphinx.pythonCommand`, `esbonio.sphinx.buildCommand`, the current builder and output files

code/src/node/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export async function activate(context: vscode.ExtensionContext) {
2222

2323
let previewManager = new PreviewManager(logger, context, esbonio)
2424
context.subscriptions.push(vscode.window.registerTreeDataProvider(
25-
'sphinxProcesses', new SphinxProcessProvider(esbonio)
25+
'sphinxProcesses', new SphinxProcessProvider(logger, esbonio)
2626
));
2727

2828
let config = vscode.workspace.getConfiguration("esbonio.server")

code/src/node/processTreeView.ts

Lines changed: 151 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as vscode from 'vscode'
22
import { Notifications, Events } from "../common/constants";
3+
import { OutputChannelLogger } from '../common/log'
4+
35
import { AppCreatedNotification, ClientCreatedNotification, ClientDestroyedNotification, ClientErroredNotification, EsbonioClient, SphinxClientConfig, SphinxInfo } from './client';
46

57
/**
@@ -13,7 +15,7 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
1315
private _onDidChangeTreeData: vscode.EventEmitter<ProcessTreeNode | undefined | null | void> = new vscode.EventEmitter<ProcessTreeNode | undefined | null | void>();
1416
readonly onDidChangeTreeData: vscode.Event<ProcessTreeNode | undefined | null | void> = this._onDidChangeTreeData.event;
1517

16-
constructor(client: EsbonioClient) {
18+
constructor(private logger: OutputChannelLogger, client: EsbonioClient) {
1719
client.addHandler(
1820
Notifications.SPHINX_CLIENT_CREATED,
1921
(params: ClientCreatedNotification) => this.clientCreated(params)
@@ -52,14 +54,14 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
5254
case 'container':
5355
return { label: element.name, collapsibleState: vscode.TreeItemCollapsibleState.Expanded }
5456

55-
case 'process':
57+
case 'sphinxProcess':
5658
let label = 'Starting...'
5759
let icon: vscode.ThemeIcon | undefined = new vscode.ThemeIcon("sync~spin")
5860
let client = this.sphinxClients.get(element.id)!
5961
let tooltip
6062

6163
if (client.state === 'running') {
62-
label = `Sphinx ${client.app?.version}`
64+
label = `Sphinx v${client.app?.version}`
6365
icon = undefined
6466

6567
} else if (client.state === 'errored') {
@@ -73,11 +75,59 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
7375
iconPath: icon,
7476
tooltip: tooltip,
7577
contextValue: element.kind,
78+
collapsibleState: vscode.TreeItemCollapsibleState.Expanded
79+
}
80+
81+
case 'sphinxBuilder':
82+
return {
83+
label: element.name,
84+
iconPath: new vscode.ThemeIcon('book'),
85+
tooltip: new vscode.MarkdownString("**Build Directory**\n\n" + element.uri.fsPath),
86+
contextValue: element.kind,
87+
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed
88+
}
89+
90+
case 'sphinxCommand':
91+
let cmd: string[] = []
92+
element.command.forEach(c => cmd.push(`- ${c}`))
93+
94+
return {
95+
label: element.command.join(' '),
96+
iconPath: new vscode.ThemeIcon('console'),
97+
tooltip: new vscode.MarkdownString(`**Sphinx Command**\n ${cmd.join('\n ')}`),
98+
contextValue: element.kind,
7699
collapsibleState: vscode.TreeItemCollapsibleState.None
77100
}
78101

79-
case 'property':
80-
return { label: 'Prop', collapsibleState: vscode.TreeItemCollapsibleState.None }
102+
case 'python':
103+
let pyCmd: string[] = []
104+
element.command.forEach(c => pyCmd.push(`- ${c}`))
105+
106+
return {
107+
label: element.command.join(' '),
108+
iconPath: vscode.ThemeIcon.File,
109+
tooltip: new vscode.MarkdownString(`**Python Command**\n ${pyCmd.join('\n ')}`),
110+
resourceUri: vscode.Uri.parse('file:///test.py'), // Needed to pull in the icon for Python
111+
contextValue: element.kind,
112+
collapsibleState: vscode.TreeItemCollapsibleState.None
113+
}
114+
115+
case 'directory':
116+
return {
117+
resourceUri: element.uri,
118+
iconPath: vscode.ThemeIcon.Folder,
119+
contextValue: element.kind,
120+
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
121+
}
122+
123+
case 'file':
124+
return {
125+
resourceUri: element.uri,
126+
iconPath: vscode.ThemeIcon.File,
127+
contextValue: element.kind,
128+
command: { command: 'vscode.open', title: `Open ${element.name}`, arguments: [element.uri], },
129+
collapsibleState: vscode.TreeItemCollapsibleState.None
130+
}
81131
}
82132

83133
}
@@ -90,34 +140,78 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
90140
* @param element The element to return children for
91141
* @returns The given element's children
92142
*/
93-
getChildren(element?: ProcessTreeNode): Thenable<ProcessTreeNode[]> {
143+
async getChildren(element?: ProcessTreeNode): Promise<ProcessTreeNode[]> {
94144
const result: ProcessTreeNode[] = []
95145

96146
if (!element) {
97147
for (let process of this.sphinxClients.values()) {
98148

99149
let cwd = process.config.cwd
100-
let node: ProcssContainerNode = { kind: 'container', name: cwd, path: cwd }
150+
let node: ProcessContainerNode = { kind: 'container', name: cwd, path: cwd }
101151
result.push(node)
102152
}
103153

104-
return Promise.resolve(result)
154+
return result
105155
}
106156

107157
switch (element.kind) {
108158
case 'container':
109159
for (let [id, process] of this.sphinxClients.entries()) {
110160
if (element.name === process.config.cwd) {
111-
let node: SphinxProcessNode = { kind: 'process', id: id }
161+
let node: SphinxProcessNode = { kind: 'sphinxProcess', id: id }
112162
result.push(node)
113163
}
114164
}
115165
break
116-
case 'process':
117-
case 'property':
166+
case 'sphinxProcess':
167+
let client = this.sphinxClients.get(element.id)
168+
if (!client) {
169+
break
170+
}
171+
172+
let pythonNode: PythonCommandNode = { kind: 'python', command: client.config.pythonCommand }
173+
result.push(pythonNode)
174+
175+
let commandNode: SphinxCommandNode = { kind: 'sphinxCommand', command: client.config.buildCommand }
176+
result.push(commandNode)
177+
178+
let app = client.app
179+
if (!app) {
180+
break
181+
}
182+
183+
let builderNode: SphinxBuilderNode = {
184+
kind: 'sphinxBuilder',
185+
name: app.builder_name,
186+
uri: vscode.Uri.file(app.build_dir)
187+
}
188+
result.push(builderNode)
189+
190+
break
191+
192+
// Check the build dir for any files/directories
193+
// TODO: Is there a way to insert VSCode's native file tree here?
194+
// It would save having to reimplement it ourselves.
195+
case 'sphinxBuilder':
196+
case 'directory':
197+
let items = await vscode.workspace.fs.readDirectory(element.uri)
198+
for (let [name, type] of items) {
199+
let node: FileNode | DirNode = {
200+
kind: type === vscode.FileType.Directory ? 'directory' : 'file',
201+
name: name,
202+
uri: vscode.Uri.joinPath(element.uri, name)
203+
}
204+
result.push(node)
205+
}
206+
break
207+
208+
// The following node types have no children
209+
case 'sphinxCommand':
210+
case 'python':
211+
case 'file':
118212
}
119213

120-
return Promise.resolve(result)
214+
return result
121215
}
122216

123217
/**
@@ -126,6 +220,7 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
126220
* @param params Information about the newly created client.
127221
*/
128222
private clientCreated(params: ClientCreatedNotification) {
223+
this.logger.debug(`sphinx/clientCreated: ${JSON.stringify(params.config, undefined, 2)}`)
129224
this.sphinxClients.set(params.id, new SphinxProcess(params.config))
130225
this._onDidChangeTreeData.fire()
131226
}
@@ -136,6 +231,8 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
136231
* @param params Information about the newly created app.
137232
*/
138233
private appCreated(params: AppCreatedNotification) {
234+
this.logger.debug(`sphinx/appCreated: ${JSON.stringify(params.application, undefined, 2)}`)
235+
139236
const client = this.sphinxClients.get(params.id)
140237
if (!client) { return }
141238

@@ -175,32 +272,68 @@ export class SphinxProcessProvider implements vscode.TreeDataProvider<ProcessTre
175272
}
176273
}
177274

178-
type ProcessTreeNode = ProcssContainerNode | SphinxProcessNode | ProcessPropertyNode
275+
type ProcessTreeNode = ProcessContainerNode | SphinxProcessNode | SphinxBuilderNode | SphinxCommandNode | PythonCommandNode | DirNode | FileNode
179276

180277
/**
181-
* Represents a property of the sphinx process
278+
* Represents a Python command
182279
*/
183-
interface ProcessPropertyNode {
184-
kind: 'property'
280+
interface PythonCommandNode {
281+
kind: 'python'
282+
command: string[]
185283
}
186284

187285
/**
188286
* Represents the sphinx process in the tree view
189287
*/
190288
interface SphinxProcessNode {
191-
kind: 'process'
289+
kind: 'sphinxProcess'
192290
id: string
193291
}
194292

293+
/**
294+
* Represents the builder used by the parent sphinx process.
295+
*/
296+
interface SphinxBuilderNode {
297+
kind: 'sphinxBuilder'
298+
name: string
299+
uri: vscode.Uri
300+
}
301+
302+
/**
303+
* Represents the build command used by the parent sphinx process.
304+
*/
305+
interface SphinxCommandNode {
306+
kind: 'sphinxCommand'
307+
command: string[]
308+
}
309+
195310
/**
196311
* Represents a container for the sphinx process
197312
*/
198-
interface ProcssContainerNode {
313+
interface ProcessContainerNode {
199314
kind: 'container'
200315
name: string
201316
path: string
202317
}
203318

319+
/**
320+
* Represents a directory
321+
*/
322+
interface DirNode {
323+
kind: 'directory'
324+
name: string
325+
uri: vscode.Uri
326+
}
327+
328+
/**
329+
* Represents a file node
330+
*/
331+
interface FileNode {
332+
kind: 'file'
333+
name: string
334+
uri: vscode.Uri
335+
}
336+
204337
class SphinxProcess {
205338

206339
/**

0 commit comments

Comments
 (0)