1 use super::{completer::IonCompleter, InteractiveShell}; 2 use ion_shell::Shell; 3 use std::io::ErrorKind; 4 5 impl<'a> InteractiveShell<'a> { 6 /// Ion's interface to Liner's `read_line` method, which handles everything related to 7 /// rendering, controlling, and getting input from the prompt. readln<T: Fn(&mut Shell<'_>)>(&self, prep_for_exit: &T) -> Option<String>8 pub fn readln<T: Fn(&mut Shell<'_>)>(&self, prep_for_exit: &T) -> Option<String> { 9 let prompt = self.prompt(); 10 let line = self.context.borrow_mut().read_line( 11 prompt, 12 None, 13 &mut IonCompleter::new(&self.shell.borrow()), 14 ); 15 16 match line { 17 Ok(line) => { 18 if line.bytes().next() != Some(b'#') 19 && line.bytes().any(|c| !c.is_ascii_whitespace()) 20 { 21 self.terminated.set(false); 22 } 23 Some(line) 24 } 25 // Handles Ctrl + C 26 Err(ref err) if err.kind() == ErrorKind::Interrupted => None, 27 // Handles Ctrl + D 28 Err(ref err) if err.kind() == ErrorKind::UnexpectedEof => { 29 let mut shell = self.shell.borrow_mut(); 30 if self.terminated.get() && shell.exit_block().is_err() { 31 prep_for_exit(&mut shell); 32 std::process::exit(shell.previous_status().as_os_code()) 33 } 34 None 35 } 36 Err(err) => { 37 eprintln!("ion: liner: {}", err); 38 None 39 } 40 } 41 } 42 } 43