11import * as vscode from 'vscode'
22import { Notifications , Events } from "../common/constants" ;
3+ import { OutputChannelLogger } from '../common/log'
4+
35import { 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 */
190288interface 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+
204337class SphinxProcess {
205338
206339 /**
0 commit comments