1
- import { FC , FormEvent , useState } from "react" ;
1
+ import { FC , FormEvent , Fragment , KeyboardEvent , useState } from "react" ;
2
2
import { twMerge } from "tailwind-merge" ;
3
3
import { getColorfulPrompt } from "../../lib/utils" ;
4
4
import parse from "html-react-parser" ;
5
+ import { COMMAND_NAMES } from "../../lib/commands" ;
5
6
6
7
interface TerminalPromptInputProps {
7
8
onEnter ( prompt : string ) : void ;
@@ -18,6 +19,20 @@ const TerminalPromptInput: FC<TerminalPromptInputProps> = ({ onEnter }) => {
18
19
setInput ( "" ) ;
19
20
}
20
21
22
+ const autocompleteCommand = input
23
+ ? COMMAND_NAMES . find ( ( x ) => x . startsWith ( input ) )
24
+ : undefined ;
25
+
26
+ function handleKeyDown ( e : KeyboardEvent < HTMLInputElement > ) {
27
+ setCaretPosition ( e . currentTarget . selectionStart ?? 0 ) ;
28
+
29
+ if ( autocompleteCommand && e . key === "Tab" ) {
30
+ e . preventDefault ( ) ;
31
+ setInput ( autocompleteCommand ) ;
32
+ setCaretPosition ( autocompleteCommand . length ) ;
33
+ }
34
+ }
35
+
21
36
return (
22
37
< form onSubmit = { handleSubmit } className = "relative w-full" >
23
38
< input
@@ -30,13 +45,23 @@ const TerminalPromptInput: FC<TerminalPromptInputProps> = ({ onEnter }) => {
30
45
} }
31
46
value = { input }
32
47
onClick = { ( e ) => setCaretPosition ( e . currentTarget . selectionStart ?? 0 ) }
33
- onKeyDown = { ( e ) => setCaretPosition ( e . currentTarget . selectionStart ?? 0 ) }
48
+ onKeyDown = { handleKeyDown }
34
49
onChange = { ( e ) => {
35
50
setInput ( e . target . value ) ;
36
51
setCaretPosition ( e . target . selectionStart ?? 0 ) ;
37
52
} }
38
53
className = "w-full cursor-default whitespace-nowrap bg-transparent p-0 text-kali-white text-transparent focus:outline-none"
39
54
/>
55
+
56
+ { autocompleteCommand && (
57
+ < div className = "absolute left-0 top-1/2 -translate-y-1/2 text-kali-text-muted" >
58
+ { [ ...input ] . map ( ( _ , idx ) => (
59
+ < Fragment key = { idx } > </ Fragment >
60
+ ) ) }
61
+ { autocompleteCommand . substring ( input . length ) }
62
+ </ div >
63
+ ) }
64
+
40
65
< div
41
66
className = { twMerge (
42
67
"pointer-events-none absolute left-0 top-1/2 h-[20px] max-w-full -translate-y-1/2 overflow-hidden overflow-ellipsis whitespace-nowrap pr-2"
0 commit comments