1- class Option {
2- name : string
1+ type OptionsMap = Map < string , Option >
2+
3+ type Complete = ( value : string , description : string ) => void
4+
5+ type OptionCompleter = ( this : Option , complete : Complete , options : OptionsMap ) => void
36
4- constructor ( name : string ) {
5- this . name = name
7+ class Option {
8+ value : string
9+ description : string
10+ command : Command
11+ completer ?: OptionCompleter
12+ shortValue ?: string
13+ // TODO: handle boolean options
14+
15+ constructor ( command : Command , value : string , description : string , completer ?: OptionCompleter , shortValue ?: string ) {
16+ this . command = command
17+ this . value = value
18+ this . description = description
19+ this . completer = completer
20+ this . shortValue = shortValue
621 }
722}
823
9- class Command {
10- root : boolean
24+ type CommandCompleter = ( this : Command , complete : Complete , options : OptionsMap ) => void
1125
12- #name: string = ''
26+ class Command {
27+ value : string
28+ description : string
1329
1430 options = new Map < string , Option >
15- commands = new Map < string , Command >
31+
32+
33+ completer ?: CommandCompleter
1634
17- constructor ( root : boolean ) {
18- this . root = root
35+ constructor ( value : string , description : string , completer ?: CommandCompleter ) {
36+ this . value = value
37+ this . description = description
38+ this . completer = completer
1939 }
2040
21- name ( name : string ) {
22- this . #name = name
41+ option ( value : string , description : string , completer ?: OptionCompleter , shortValue ?: string ) {
42+ this . options . set ( value , new Option ( this , value , description , completer , shortValue ) )
43+ return this
2344 }
2445
25- option ( ) {
2646
27- }
2847
29- command ( ) {
48+ }
49+
50+ import * as zsh from './zsh' ;
51+ import * as bash from './bash' ;
52+ import * as fish from './fish' ;
53+ import * as powershell from './powershell' ;
54+ import assert from 'node:assert'
3055
31- }
56+ class RootCommand extends Command {
57+ completer = undefined
58+ commands = new Map < string , Command >
3259
33- parse ( ) {
60+ constructor ( ) {
61+ super ( '' , '' )
62+ }
3463
64+ command ( value : string , description : string , completer ?: CommandCompleter ) {
65+ const c = new Command ( value , description , completer )
66+ this . commands . set ( value , c )
67+ return c
3568 }
3669
37- setup ( ) {
70+ parse ( args : string [ ] ) {
71+ const endsWithSpace = args [ args . length - 1 ] === ''
72+
73+ if ( endsWithSpace ) {
74+ args . pop ( )
75+ }
3876
77+ const toComplete = args [ args . length - 1 ] || ''
78+ const previousArgs = args . slice ( 0 , - 1 )
79+
80+ for ( const arg of previousArgs ) {
81+ const option = this . options . get ( arg )
82+ }
83+ }
84+
85+ setup ( name : string , executable : string , shell : string ) {
86+ assert ( shell === 'zsh' || shell === 'bash' || shell === 'fish' || shell === 'powershell' , 'Unsupported shell' )
87+
88+ switch ( shell ) {
89+ case 'zsh' : {
90+ const script = zsh . generate ( name , executable ) ;
91+ console . log ( script ) ;
92+ break ;
93+ }
94+ case 'bash' : {
95+ const script = bash . generate ( name , executable ) ;
96+ console . log ( script ) ;
97+ break ;
98+ }
99+ case 'fish' : {
100+ const script = fish . generate ( name , executable ) ;
101+ console . log ( script ) ;
102+ break ;
103+ }
104+ case 'powershell' : {
105+ const script = powershell . generate ( name , executable ) ;
106+ console . log ( script ) ;
107+ break ;
108+ }
109+ }
39110 }
40111}
41112
42- const t = new Command ( true )
113+ const t = new RootCommand ( )
43114
44115export default t
45116
46117// import t from '@bombsh/tab'
47118
48119t . option ( 'help' , 'list available commands' ) // Command (Root)
49120
50- t . command ( 'start' , 'start the development server' ) // Command ('start')
51- . option ( 'port' , 'specify the port number' ) // Command ('port')
121+ t
122+ . command ( 'start' , 'start the development server' ) // Command ('start')
123+ . option ( 'port' , 'specify the port number' , function ( complete , options ) {
124+ complete ( '3000' , 'general port' )
125+ complete ( '3001' , 'another general port' )
126+ complete ( '3002' , 'another general port' )
127+ } ) // Command ('port')
128+
129+ t
130+ . command ( 'start dev' , 'start the development server' ) // Command ('start')
131+
132+
133+ const x = 'npx my-cli'
52134
53- t . parse ( process . argv . slice ( 3 ) )
135+ // t.setup('my-cli', x, process.argv[2])
136+ console . log ( process . argv )
54137
55- t . setup ( process . argv [ 2 ] , x )
138+ t . parse ( process . argv . slice ( 3 ) )
0 commit comments