@@ -5,6 +5,7 @@ use eyre::Result;
5
5
use rustyline:: completion:: {
6
6
Completer ,
7
7
extract_word,
8
+ FilenameCompleter ,
8
9
} ;
9
10
use rustyline:: error:: ReadlineError ;
10
11
use rustyline:: highlight:: {
@@ -61,11 +62,29 @@ pub fn generate_prompt(current_profile: Option<&str>) -> String {
61
62
"> " . to_string ( )
62
63
}
63
64
64
- pub struct ChatCompleter { }
65
+ pub struct ChatCompleter {
66
+ filename_completer : FilenameCompleter ,
67
+ }
65
68
66
69
impl ChatCompleter {
67
70
fn new ( ) -> Self {
68
- Self { }
71
+ Self {
72
+ filename_completer : FilenameCompleter :: new ( ) ,
73
+ }
74
+ }
75
+
76
+ // Check if the input might be referring to a file path
77
+ fn is_path_context ( & self , line : & str ) -> bool {
78
+ // Check for common file path indicators in the input
79
+ line. contains ( "file:" ) ||
80
+ line. contains ( "path:" ) ||
81
+ line. contains ( "directory:" ) ||
82
+ line. contains ( "folder:" ) ||
83
+ line. contains ( "open " ) ||
84
+ line. contains ( "read " ) ||
85
+ line. contains ( "cat " ) ||
86
+ line. contains ( "ls " ) ||
87
+ line. contains ( "cd " )
69
88
}
70
89
}
71
90
@@ -79,18 +98,38 @@ impl Completer for ChatCompleter {
79
98
_ctx : & Context < ' _ > ,
80
99
) -> Result < ( usize , Vec < Self :: Candidate > ) , ReadlineError > {
81
100
let ( start, word) = extract_word ( line, pos, None , |c| c. is_space ( ) ) ;
82
- Ok ( (
83
- start,
84
- if word. starts_with ( '/' ) {
101
+
102
+ // Handle command completion
103
+ if word. starts_with ( '/' ) {
104
+ return Ok ( (
105
+ start,
85
106
COMMANDS
86
107
. iter ( )
87
108
. filter ( |p| p. starts_with ( word) )
88
109
. map ( |s| ( * s) . to_owned ( ) )
89
110
. collect ( )
90
- } else {
91
- Vec :: new ( )
92
- } ,
93
- ) )
111
+ ) ) ;
112
+ }
113
+
114
+ // Handle file path completion if the word contains path separators or context suggests file paths
115
+ if word. contains ( '/' ) || word. starts_with ( '~' ) || self . is_path_context ( line) {
116
+ // Use the filename completer to get path completions
117
+ if let Ok ( ( pos, completions) ) = self . filename_completer . complete ( line, pos, _ctx) {
118
+ // Convert the filename completer's pairs to strings
119
+ let file_completions: Vec < String > = completions
120
+ . iter ( )
121
+ . map ( |pair| pair. replacement . clone ( ) )
122
+ . collect ( ) ;
123
+
124
+ // If we have completions, return them
125
+ if !file_completions. is_empty ( ) {
126
+ return Ok ( ( pos, file_completions) ) ;
127
+ }
128
+ }
129
+ }
130
+
131
+ // Default: no completions
132
+ Ok ( ( start, Vec :: new ( ) ) )
94
133
}
95
134
}
96
135
0 commit comments