@@ -196,3 +196,68 @@ export class ViewCommand implements CommandDescriptor {
196
196
) ;
197
197
}
198
198
}
199
+
200
+ @injectable ( )
201
+ export class TreeCommand implements CommandDescriptor {
202
+ constructor ( private registry = inject ( NodeRegistry ) ) { }
203
+
204
+ name = "tree" ;
205
+
206
+ command = new Command ( )
207
+ . name ( "tree" )
208
+ . description ( "View a lexicon tree." )
209
+ . type ( "nsid" , inputTypes . nsid )
210
+ . option ( "-d --depth <depth:number>" , "The depth of the tree." , {
211
+ default : Infinity ,
212
+ } )
213
+ . arguments ( "<nsid:nsid>" )
214
+ . action ( ( { depth } , nsid ) => this . #action( nsid , depth ) ) ;
215
+
216
+ async #action( nsid : NSID , maxDepth : number ) {
217
+ const root = await this . registry . get ( nsid ) . resolve ( ) ;
218
+ if ( ! root . success ) {
219
+ console . error ( "failed to resolve " , root . errorCode ) ;
220
+ return ;
221
+ }
222
+
223
+ const getIndent = ( ancestors : string [ ] , isLast : boolean ) : string => {
224
+ let indent = "" ;
225
+ for ( let i = 0 ; i < ancestors . length ; i ++ ) {
226
+ indent += i === ancestors . length - 1
227
+ ? `${ isLast ? "└" : "├" } ─── `
228
+ : "│ " ;
229
+ }
230
+ return indent ;
231
+ } ;
232
+
233
+ const printNode = async (
234
+ node : Resolution ,
235
+ ancestors : string [ ] ,
236
+ isLast = false ,
237
+ ) => {
238
+ if ( ! node . success ) {
239
+ throw new Error ( "failed to resolve" ) ;
240
+ }
241
+ const nodeId = node . nsid . toString ( ) ;
242
+ const indent = getIndent ( ancestors , isLast ) ;
243
+ if ( ancestors . includes ( nodeId ) ) {
244
+ console . log ( `${ indent } ${ nodeId } ${ fmt . yellow ( "●" ) } ` ) ;
245
+ return ;
246
+ }
247
+ console . log (
248
+ `${ indent } ${ node . children . length === 0 ? nodeId : fmt . bold ( nodeId ) } ` ,
249
+ ) ;
250
+ if ( ancestors . length + 1 > maxDepth ) {
251
+ return ;
252
+ }
253
+
254
+ for ( const [ i , child ] of node . children . entries ( ) ) {
255
+ const childResolution = await this . registry . get ( child ) . resolve ( ) ;
256
+ const isLast = i === node . children . length - 1 ;
257
+ await printNode ( childResolution , [ ...ancestors , nodeId ] , isLast ) ;
258
+ }
259
+ } ;
260
+
261
+ await printNode ( root , [ ] ) ;
262
+ }
263
+ }
0 commit comments