@@ -13,16 +13,25 @@ use rustyline::highlight::{
1313 Highlighter ,
1414} ;
1515use rustyline:: history:: DefaultHistory ;
16+ use rustyline:: validate:: {
17+ ValidationContext ,
18+ ValidationResult ,
19+ Validator ,
20+ } ;
1621use rustyline:: {
22+ Cmd ,
1723 Completer ,
1824 CompletionType ,
1925 Config ,
2026 Context ,
2127 EditMode ,
2228 Editor ,
29+ EventHandler ,
2330 Helper ,
2431 Hinter ,
25- Validator ,
32+ KeyCode ,
33+ KeyEvent ,
34+ Modifiers ,
2635} ;
2736use winnow:: stream:: AsChar ;
2837
@@ -151,14 +160,44 @@ impl Completer for ChatCompleter {
151160 }
152161}
153162
154- #[ derive( Helper , Completer , Hinter , Validator ) ]
163+ /// Custom validator for multi-line input
164+ pub struct MultiLineValidator ;
165+
166+ impl Validator for MultiLineValidator {
167+ fn validate ( & self , ctx : & mut ValidationContext < ' _ > ) -> rustyline:: Result < ValidationResult > {
168+ let input = ctx. input ( ) ;
169+
170+ if input. trim ( ) . is_empty ( ) {
171+ return Ok ( ValidationResult :: Incomplete ) ;
172+ }
173+
174+ // Check for explicit multi-line markers
175+ if input. starts_with ( "```" ) && !input. ends_with ( "```" ) {
176+ return Ok ( ValidationResult :: Incomplete ) ;
177+ }
178+
179+ // Check for backslash continuation
180+ if input. ends_with ( '\\' ) {
181+ return Ok ( ValidationResult :: Incomplete ) ;
182+ }
183+
184+ Ok ( ValidationResult :: Valid ( None ) )
185+ }
186+ }
187+
188+ #[ derive( Helper , Completer , Hinter ) ]
155189pub struct ChatHelper {
156190 #[ rustyline( Completer ) ]
157191 completer : ChatCompleter ,
158- #[ rustyline( Validator ) ]
159- validator : ( ) ,
160192 #[ rustyline( Hinter ) ]
161193 hinter : ( ) ,
194+ validator : MultiLineValidator ,
195+ }
196+
197+ impl Validator for ChatHelper {
198+ fn validate ( & self , ctx : & mut ValidationContext < ' _ > ) -> rustyline:: Result < ValidationResult > {
199+ self . validator . validate ( ctx)
200+ }
162201}
163202
164203impl Highlighter for ChatHelper {
@@ -203,10 +242,23 @@ pub fn rl() -> Result<Editor<ChatHelper, DefaultHistory>> {
203242 let h = ChatHelper {
204243 completer : ChatCompleter :: new ( ) ,
205244 hinter : ( ) ,
206- validator : ( ) ,
245+ validator : MultiLineValidator ,
207246 } ;
208247 let mut rl = Editor :: with_config ( config) ?;
209248 rl. set_helper ( Some ( h) ) ;
249+
250+ // Add custom keybinding for Alt+Enter to insert a newline
251+ rl. bind_sequence (
252+ KeyEvent ( KeyCode :: Enter , Modifiers :: ALT ) ,
253+ EventHandler :: Simple ( Cmd :: Insert ( 1 , "\n " . to_string ( ) ) ) ,
254+ ) ;
255+
256+ // Add custom keybinding for Ctrl+J to insert a newline
257+ rl. bind_sequence (
258+ KeyEvent ( KeyCode :: Char ( 'j' ) , Modifiers :: CTRL ) ,
259+ EventHandler :: Simple ( Cmd :: Insert ( 1 , "\n " . to_string ( ) ) ) ,
260+ ) ;
261+
210262 Ok ( rl)
211263}
212264
0 commit comments