@@ -147,6 +147,8 @@ <h1>Unix Shell JS - Live Demo</h1>
147147 < div class ="terminal " id ="terminal ">
148148 < div class ="terminal-output "> Unix Shell JS v1.0.0
149149Type 'help' to see available commands, 'ls' to list files, or 'vim README.md' to edit a file.
150+
151+ 👉 Click anywhere in this terminal to start typing commands!
150152</ div >
151153 < div class ="terminal-line ">
152154 < span class ="prompt "> user@demo:~$</ span >
@@ -216,6 +218,45 @@ <h2>Try These Commands:</h2>
216218 }
217219
218220 input . addEventListener ( 'keydown' , ( e ) => {
221+ // Handle Tab for autocomplete
222+ if ( e . key === 'Tab' ) {
223+ e . preventDefault ( ) ;
224+
225+ const partial = input . value . trim ( ) ;
226+ if ( ! partial ) return ;
227+
228+ const completions = shell . getCompletions ( partial ) ;
229+
230+ if ( completions . matches . length === 1 ) {
231+ // Single match - auto complete
232+ const match = completions . matches [ 0 ] ;
233+
234+ if ( completions . type === 'command' ) {
235+ input . value = match ;
236+ } else if ( completions . type === 'path' ) {
237+ // Replace the path part
238+ const parts = partial . split ( / \s + / ) ;
239+ const pathPrefix = completions . prefix ;
240+
241+ if ( pathPrefix . includes ( '/' ) ) {
242+ const lastSlash = pathPrefix . lastIndexOf ( '/' ) ;
243+ const dirPart = pathPrefix . substring ( 0 , lastSlash + 1 ) ;
244+ parts [ parts . length - 1 ] = dirPart + match ;
245+ } else {
246+ parts [ parts . length - 1 ] = match ;
247+ }
248+
249+ input . value = parts . join ( ' ' ) ;
250+ }
251+ } else if ( completions . matches . length > 1 ) {
252+ // Multiple matches - show them
253+ const matchList = completions . matches . join ( ' ' ) ;
254+ addOutput ( matchList ) ;
255+ window . scrollTo ( 0 , document . body . scrollHeight ) ;
256+ }
257+ return ;
258+ }
259+
219260 if ( e . key === 'Enter' ) {
220261 const command = input . value . trim ( ) ;
221262
0 commit comments