diff --git a/src/completion.rs b/src/completion.rs index 8aa4f4785bbefb984eb857ba4739755609e04ef8..5c2a00b981a18fd32ff2289d2bd500b7072dac06 100644 --- a/src/completion.rs +++ b/src/completion.rs @@ -68,14 +68,49 @@ pub struct FilenameCompleter { } #[cfg(unix)] -static DEFAULT_BREAK_CHARS: [char; 18] = [' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', '>', - '<', '=', ';', '|', '&', '{', '(', '\0']; +static DEFAULT_BREAK_CHARS: [char; 18] = [ + ' ', + '\t', + '\n', + '"', + '\\', + '\'', + '`', + '@', + '$', + '>', + '<', + '=', + ';', + '|', + '&', + '{', + '(', + '\0', +]; #[cfg(unix)] static ESCAPE_CHAR: Option<char> = Some('\\'); // Remove \ to make file completion works on windows #[cfg(windows)] -static DEFAULT_BREAK_CHARS: [char; 17] = [' ', '\t', '\n', '"', '\'', '`', '@', '$', '>', '<', - '=', ';', '|', '&', '{', '(', '\0']; +static DEFAULT_BREAK_CHARS: [char; 17] = [ + ' ', + '\t', + '\n', + '"', + '\'', + '`', + '@', + '$', + '>', + '<', + '=', + ';', + '|', + '&', + '{', + '(', + '\0', +]; #[cfg(windows)] static ESCAPE_CHAR: Option<char> = None; @@ -132,10 +167,7 @@ pub fn escape(input: String, esc_char: Option<char>, break_chars: &BTreeSet<char return input; } let esc_char = esc_char.unwrap(); - let n = input - .chars() - .filter(|c| break_chars.contains(c)) - .count(); + let n = input.chars().filter(|c| break_chars.contains(c)).count(); if n == 0 { return input; } @@ -150,10 +182,11 @@ pub fn escape(input: String, esc_char: Option<char>, break_chars: &BTreeSet<char result } -fn filename_complete(path: &str, - esc_char: Option<char>, - break_chars: &BTreeSet<char>) - -> Result<Vec<String>> { +fn filename_complete( + path: &str, + esc_char: Option<char>, + break_chars: &BTreeSet<char>, +) -> Result<Vec<String>> { use std::env::{current_dir, home_dir}; let sep = path::MAIN_SEPARATOR; @@ -204,11 +237,12 @@ fn filename_complete(path: &str, /// try to find backward the start of a word. /// Return (0, `line[..pos]`) if no break char has been found. /// Return the word and its start position (idx, `line[idx..pos]`) otherwise. -pub fn extract_word<'l>(line: &'l str, - pos: usize, - esc_char: Option<char>, - break_chars: &BTreeSet<char>) - -> (usize, &'l str) { +pub fn extract_word<'l>( + line: &'l str, + pos: usize, + esc_char: Option<char>, + break_chars: &BTreeSet<char>, +) -> (usize, &'l str) { let line = &line[..pos]; if line.is_empty() { return (0, line); @@ -250,7 +284,8 @@ pub fn longest_common_prefix(candidates: &[String]) -> Option<&str> { let b1 = c1.as_bytes(); let b2 = candidates[i + 1].as_bytes(); if b1.len() <= longest_common_prefix || b2.len() <= longest_common_prefix || - b1[longest_common_prefix] != b2[longest_common_prefix] { + b1[longest_common_prefix] != b2[longest_common_prefix] + { break 'o; } } @@ -273,11 +308,15 @@ mod tests { pub fn extract_word() { let break_chars: BTreeSet<char> = super::DEFAULT_BREAK_CHARS.iter().cloned().collect(); let line = "ls '/usr/local/b"; - assert_eq!((4, "/usr/local/b"), - super::extract_word(line, line.len(), Some('\\'), &break_chars)); + assert_eq!( + (4, "/usr/local/b"), + super::extract_word(line, line.len(), Some('\\'), &break_chars) + ); let line = "ls /User\\ Information"; - assert_eq!((3, "/User\\ Information"), - super::extract_word(line, line.len(), Some('\\'), &break_chars)); + assert_eq!( + (3, "/User\\ Information"), + super::extract_word(line, line.len(), Some('\\'), &break_chars) + ); } #[test] @@ -294,8 +333,10 @@ mod tests { pub fn escape() { let break_chars: BTreeSet<char> = super::DEFAULT_BREAK_CHARS.iter().cloned().collect(); let input = String::from("/usr/local/b"); - assert_eq!(input.clone(), - super::escape(input, Some('\\'), &break_chars)); + assert_eq!( + input.clone(), + super::escape(input, Some('\\'), &break_chars) + ); let input = String::from("/User Information"); let result = String::from("/User\\ Information"); assert_eq!(result, super::escape(input, Some('\\'), &break_chars)); diff --git a/src/history.rs b/src/history.rs index 988bad98e1a7afc08f12dc8624233949a50805cb..68d355c4067348950794d1c1dc9da03ec16ca83e 100644 --- a/src/history.rs +++ b/src/history.rs @@ -57,11 +57,12 @@ impl History { return false; } if line.as_ref().is_empty() || - (self.ignore_space && - line.as_ref() - .chars() - .next() - .map_or(true, |c| c.is_whitespace())) { + (self.ignore_space && + line.as_ref().chars().next().map_or( + true, + |c| c.is_whitespace(), + )) + { return false; } if self.ignore_dups { @@ -168,7 +169,8 @@ impl History { } fn search_match<F>(&self, term: &str, start: usize, dir: Direction, test: F) -> Option<usize> - where F: Fn(&String) -> bool + where + F: Fn(&String) -> bool, { if term.is_empty() || start >= self.len() { return None; diff --git a/src/keymap.rs b/src/keymap.rs index bbbfe54b2aa4636420a9e556d6e1f663e7b70c59..4c57f734a3ad4774e59f427d443e202c05e9592c 100644 --- a/src/keymap.rs +++ b/src/keymap.rs @@ -295,9 +295,10 @@ impl EditState { if self.num_args == -1 { self.num_args *= digit.to_digit(10).unwrap() as i16; } else { - self.num_args = self.num_args - .saturating_mul(10) - .saturating_add(digit.to_digit(10).unwrap() as i16); + self.num_args = self.num_args.saturating_mul(10).saturating_add( + digit.to_digit(10).unwrap() as + i16, + ); } } _ => return Ok(key), @@ -316,10 +317,10 @@ impl EditState { if let Some(cmd) = self.custom_bindings.borrow().get(&key) { debug!(target: "rustyline", "Custom command: {:?}", cmd); return Ok(if cmd.is_repeatable() { - cmd.redo(Some(n)) - } else { - cmd.clone() - }); + cmd.redo(Some(n)) + } else { + cmd.clone() + }); } let cmd = match key { KeyPress::Char(c) => { @@ -431,9 +432,10 @@ impl EditState { let key = try!(rdr.next_key()); match key { KeyPress::Char(digit @ '0'...'9') => { - self.num_args = self.num_args - .saturating_mul(10) - .saturating_add(digit.to_digit(10).unwrap() as i16); + self.num_args = self.num_args.saturating_mul(10).saturating_add( + digit.to_digit(10).unwrap() as + i16, + ); } _ => return Ok(key), }; @@ -450,14 +452,14 @@ impl EditState { if let Some(cmd) = self.custom_bindings.borrow().get(&key) { debug!(target: "rustyline", "Custom command: {:?}", cmd); return Ok(if cmd.is_repeatable() { - if no_num_args { - cmd.redo(None) - } else { - cmd.redo(Some(n)) - } - } else { - cmd.clone() - }); + if no_num_args { + cmd.redo(None) + } else { + cmd.redo(Some(n)) + } + } else { + cmd.clone() + }); } let cmd = match key { KeyPress::Char('$') | @@ -611,10 +613,10 @@ impl EditState { if let Some(cmd) = self.custom_bindings.borrow().get(&key) { debug!(target: "rustyline", "Custom command: {:?}", cmd); return Ok(if cmd.is_repeatable() { - cmd.redo(None) - } else { - cmd.clone() - }); + cmd.redo(None) + } else { + cmd.clone() + }); } let cmd = match key { KeyPress::Char(c) => { @@ -645,11 +647,12 @@ impl EditState { Ok(cmd) } - fn vi_cmd_motion<R: RawReader>(&mut self, - rdr: &mut R, - key: KeyPress, - n: RepeatCount) - -> Result<Option<Movement>> { + fn vi_cmd_motion<R: RawReader>( + &mut self, + rdr: &mut R, + key: KeyPress, + n: RepeatCount, + ) -> Result<Option<Movement>> { let mut mvt = try!(rdr.next_key()); if mvt == key { return Ok(Some(Movement::WholeLine)); @@ -661,76 +664,77 @@ impl EditState { n = self.vi_num_args().saturating_mul(n); } Ok(match mvt { - KeyPress::Char('$') => Some(Movement::EndOfLine), - KeyPress::Char('0') => Some(Movement::BeginningOfLine), - KeyPress::Char('^') => Some(Movement::ViFirstPrint), - KeyPress::Char('b') => Some(Movement::BackwardWord(n, Word::Vi)), - KeyPress::Char('B') => Some(Movement::BackwardWord(n, Word::Big)), - KeyPress::Char('e') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi)), - KeyPress::Char('E') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big)), - KeyPress::Char(c) if c == 'f' || c == 'F' || c == 't' || c == 'T' => { - let cs = try!(self.vi_char_search(rdr, c)); - match cs { - Some(cs) => Some(Movement::ViCharSearch(n, cs)), - None => None, + KeyPress::Char('$') => Some(Movement::EndOfLine), + KeyPress::Char('0') => Some(Movement::BeginningOfLine), + KeyPress::Char('^') => Some(Movement::ViFirstPrint), + KeyPress::Char('b') => Some(Movement::BackwardWord(n, Word::Vi)), + KeyPress::Char('B') => Some(Movement::BackwardWord(n, Word::Big)), + KeyPress::Char('e') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi)), + KeyPress::Char('E') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big)), + KeyPress::Char(c) if c == 'f' || c == 'F' || c == 't' || c == 'T' => { + let cs = try!(self.vi_char_search(rdr, c)); + match cs { + Some(cs) => Some(Movement::ViCharSearch(n, cs)), + None => None, + } } - } - KeyPress::Char(';') => { - match self.last_char_search { - Some(ref cs) => Some(Movement::ViCharSearch(n, cs.clone())), - None => None, - } - } - KeyPress::Char(',') => { - match self.last_char_search { - Some(ref cs) => Some(Movement::ViCharSearch(n, cs.opposite())), - None => None, - } - } - KeyPress::Char('h') | - KeyPress::Ctrl('H') | - KeyPress::Backspace => Some(Movement::BackwardChar(n)), - KeyPress::Char('l') | - KeyPress::Char(' ') => Some(Movement::ForwardChar(n)), - KeyPress::Char('w') => { - // 'cw' is 'ce' - if key == KeyPress::Char('c') { - Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi)) - } else { - Some(Movement::ForwardWord(n, At::Start, Word::Vi)) + KeyPress::Char(';') => { + match self.last_char_search { + Some(ref cs) => Some(Movement::ViCharSearch(n, cs.clone())), + None => None, + } } - } - KeyPress::Char('W') => { - // 'cW' is 'cE' - if key == KeyPress::Char('c') { - Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big)) - } else { - Some(Movement::ForwardWord(n, At::Start, Word::Big)) + KeyPress::Char(',') => { + match self.last_char_search { + Some(ref cs) => Some(Movement::ViCharSearch(n, cs.opposite())), + None => None, + } } - } - _ => None, - }) + KeyPress::Char('h') | + KeyPress::Ctrl('H') | + KeyPress::Backspace => Some(Movement::BackwardChar(n)), + KeyPress::Char('l') | + KeyPress::Char(' ') => Some(Movement::ForwardChar(n)), + KeyPress::Char('w') => { + // 'cw' is 'ce' + if key == KeyPress::Char('c') { + Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi)) + } else { + Some(Movement::ForwardWord(n, At::Start, Word::Vi)) + } + } + KeyPress::Char('W') => { + // 'cW' is 'cE' + if key == KeyPress::Char('c') { + Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big)) + } else { + Some(Movement::ForwardWord(n, At::Start, Word::Big)) + } + } + _ => None, + }) } - fn vi_char_search<R: RawReader>(&mut self, - rdr: &mut R, - cmd: char) - -> Result<Option<CharSearch>> { + fn vi_char_search<R: RawReader>( + &mut self, + rdr: &mut R, + cmd: char, + ) -> Result<Option<CharSearch>> { let ch = try!(rdr.next_key()); Ok(match ch { - KeyPress::Char(ch) => { - let cs = match cmd { - 'f' => CharSearch::Forward(ch), - 't' => CharSearch::ForwardBefore(ch), - 'F' => CharSearch::Backward(ch), - 'T' => CharSearch::BackwardAfter(ch), - _ => unreachable!(), - }; - self.last_char_search = Some(cs.clone()); - Some(cs) - } - _ => None, - }) + KeyPress::Char(ch) => { + let cs = match cmd { + 'f' => CharSearch::Forward(ch), + 't' => CharSearch::ForwardBefore(ch), + 'F' => CharSearch::Backward(ch), + 'T' => CharSearch::BackwardAfter(ch), + _ => unreachable!(), + }; + self.last_char_search = Some(cs.clone()); + Some(cs) + } + _ => None, + }) } fn common(&mut self, key: KeyPress, n: RepeatCount, positive: bool) -> Cmd { diff --git a/src/lib.rs b/src/lib.rs index fbb147abcf70acda073ebd2d07bb2b34c32d4d56..df8af324936a319c62db065233679e8a30dca117 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,12 +86,13 @@ struct State<'out, 'prompt> { } impl<'out, 'prompt> State<'out, 'prompt> { - fn new(out: &'out mut Renderer, - config: &Config, - prompt: &'prompt str, - history_index: usize, - custom_bindings: Rc<RefCell<HashMap<KeyPress, Cmd>>>) - -> State<'out, 'prompt> { + fn new( + out: &'out mut Renderer, + config: &Config, + prompt: &'prompt str, + history_index: usize, + custom_bindings: Rc<RefCell<HashMap<KeyPress, Cmd>>>, + ) -> State<'out, 'prompt> { let capacity = MAX_LINE; let prompt_size = out.calculate_position(prompt, Position::default()); State { @@ -122,19 +123,24 @@ impl<'out, 'prompt> State<'out, 'prompt> { } fn backup(&mut self) { - self.saved_line_for_history - .update(self.line.as_str(), self.line.pos()); + self.saved_line_for_history.update( + self.line.as_str(), + self.line.pos(), + ); } fn restore(&mut self) { - self.line - .update(self.saved_line_for_history.as_str(), - self.saved_line_for_history.pos()); + self.line.update( + self.saved_line_for_history.as_str(), + self.saved_line_for_history.pos(), + ); } fn move_cursor(&mut self) -> Result<()> { // calculate the desired position of the cursor - let cursor = self.out - .calculate_position(&self.line[..self.line.pos()], self.prompt_size); + let cursor = self.out.calculate_position( + &self.line[..self.line.pos()], + self.prompt_size, + ); if self.cursor == cursor { return Ok(()); } @@ -156,12 +162,13 @@ impl<'out, 'prompt> State<'out, 'prompt> { } fn refresh(&mut self, prompt: &str, prompt_size: Position) -> Result<()> { - let (cursor, end_pos) = try!(self.out - .refresh_line(prompt, - prompt_size, - &self.line, - self.cursor.row, - self.old_rows)); + let (cursor, end_pos) = try!(self.out.refresh_line( + prompt, + prompt_size, + &self.line, + self.cursor.row, + self.old_rows, + )); self.cursor = cursor; self.old_rows = end_pos.row; @@ -190,8 +197,10 @@ fn edit_insert(s: &mut State, ch: char, n: RepeatCount) -> Result<()> { if push { if n == 1 && s.cursor.col + ch.width().unwrap_or(0) < s.out.get_columns() { // Avoid a full update of the line in the trivial case. - let cursor = s.out - .calculate_position(&s.line[..s.line.pos()], s.prompt_size); + let cursor = s.out.calculate_position( + &s.line[..s.line.pos()], + s.prompt_size, + ); s.cursor = cursor; let bits = ch.encode_utf8(&mut s.byte_buffer); let bits = bits.as_bytes(); @@ -456,7 +465,8 @@ fn edit_history_search(s: &mut State, history: &History, dir: Direction) -> Resu s.history_index += 1; } if let Some(history_index) = - history.starts_with(&s.line.as_str()[..s.line.pos()], s.history_index, dir) { + history.starts_with(&s.line.as_str()[..s.line.pos()], s.history_index, dir) + { s.history_index = history_index; let buf = history.get(history_index).unwrap(); s.changes.borrow_mut().begin(); @@ -498,11 +508,12 @@ fn edit_history(s: &mut State, history: &History, first: bool) -> Result<()> { } /// Completes the line/word -fn complete_line<R: RawReader>(rdr: &mut R, - s: &mut State, - completer: &Completer, - config: &Config) - -> Result<Option<Cmd>> { +fn complete_line<R: RawReader>( + rdr: &mut R, + s: &mut State, + completer: &Completer, + config: &Config, +) -> Result<Option<Cmd>> { // get a list of completions let (start, candidates) = try!(completer.complete(&s.line, s.line.pos())); // if no completions, we are done @@ -580,9 +591,10 @@ fn complete_line<R: RawReader>(rdr: &mut R, try!(s.out.write_and_flush(msg.as_bytes())); s.old_rows += 1; while cmd != Cmd::SelfInsert(1, 'y') && cmd != Cmd::SelfInsert(1, 'Y') && - cmd != Cmd::SelfInsert(1, 'n') && - cmd != Cmd::SelfInsert(1, 'N') && - cmd != Cmd::Kill(Movement::BackwardChar(1)) { + cmd != Cmd::SelfInsert(1, 'n') && + cmd != Cmd::SelfInsert(1, 'N') && + cmd != Cmd::Kill(Movement::BackwardChar(1)) + { cmd = try!(s.next_cmd(rdr)); } match cmd { @@ -604,20 +616,23 @@ fn complete_line<R: RawReader>(rdr: &mut R, } } -fn page_completions<R: RawReader>(rdr: &mut R, - s: &mut State, - candidates: &[String]) - -> Result<Option<Cmd>> { +fn page_completions<R: RawReader>( + rdr: &mut R, + s: &mut State, + candidates: &[String], +) -> Result<Option<Cmd>> { use std::cmp; let min_col_pad = 2; let cols = s.out.get_columns(); - let max_width = cmp::min(cols, - candidates - .into_iter() - .map(|s| s.as_str().width()) - .max() - .unwrap() + min_col_pad); + let max_width = cmp::min( + cols, + candidates + .into_iter() + .map(|s| s.as_str().width()) + .max() + .unwrap() + min_col_pad, + ); let num_cols = cols / max_width; let mut pause_row = s.out.get_rows() - 1; @@ -628,13 +643,14 @@ fn page_completions<R: RawReader>(rdr: &mut R, try!(s.out.write_and_flush(b"\n--More--")); let mut cmd = Cmd::Noop; while cmd != Cmd::SelfInsert(1, 'y') && cmd != Cmd::SelfInsert(1_, 'Y') && - cmd != Cmd::SelfInsert(1, 'n') && - cmd != Cmd::SelfInsert(1_, 'N') && - cmd != Cmd::SelfInsert(1, 'q') && - cmd != Cmd::SelfInsert(1, 'Q') && - cmd != Cmd::SelfInsert(1, ' ') && - cmd != Cmd::Kill(Movement::BackwardChar(1)) && - cmd != Cmd::AcceptLine { + cmd != Cmd::SelfInsert(1, 'n') && + cmd != Cmd::SelfInsert(1_, 'N') && + cmd != Cmd::SelfInsert(1, 'q') && + cmd != Cmd::SelfInsert(1, 'Q') && + cmd != Cmd::SelfInsert(1, ' ') && + cmd != Cmd::Kill(Movement::BackwardChar(1)) && + cmd != Cmd::AcceptLine + { cmd = try!(s.next_cmd(rdr)); } match cmd { @@ -674,10 +690,11 @@ fn page_completions<R: RawReader>(rdr: &mut R, } /// Incremental search -fn reverse_incremental_search<R: RawReader>(rdr: &mut R, - s: &mut State, - history: &History) - -> Result<Option<Cmd>> { +fn reverse_incremental_search<R: RawReader>( + rdr: &mut R, + s: &mut State, + history: &History, +) -> Result<Option<Cmd>> { if history.is_empty() { return Ok(None); } @@ -757,20 +774,23 @@ fn reverse_incremental_search<R: RawReader>(rdr: &mut R, /// It will also handle special inputs in an appropriate fashion /// (e.g., C-c will exit readline) #[allow(let_unit_value)] -fn readline_edit<C: Completer>(prompt: &str, - editor: &mut Editor<C>, - original_mode: tty::Mode) - -> Result<String> { +fn readline_edit<C: Completer>( + prompt: &str, + editor: &mut Editor<C>, + original_mode: tty::Mode, +) -> Result<String> { let completer = editor.completer.as_ref().map(|c| c as &Completer); let mut stdout = editor.term.create_writer(); editor.reset_kill_ring(); - let mut s = State::new(&mut stdout, - &editor.config, - prompt, - editor.history.len(), - editor.custom_bindings.clone()); + let mut s = State::new( + &mut stdout, + &editor.config, + prompt, + editor.history.len(), + editor.custom_bindings.clone(), + ); s.line.set_delete_listener(editor.kill_ring.clone()); s.line.set_change_listener(s.changes.clone()); @@ -789,7 +809,12 @@ fn readline_edit<C: Completer>(prompt: &str, // autocomplete if cmd == Cmd::Complete && completer.is_some() { - let next = try!(complete_line(&mut rdr, &mut s, completer.unwrap(), &editor.config)); + let next = try!(complete_line( + &mut rdr, + &mut s, + completer.unwrap(), + &editor.config, + )); if next.is_some() { cmd = next.unwrap(); } else { @@ -807,7 +832,11 @@ fn readline_edit<C: Completer>(prompt: &str, if cmd == Cmd::ReverseSearchHistory { // Search history backward - let next = try!(reverse_incremental_search(&mut rdr, &mut s, &editor.history)); + let next = try!(reverse_incremental_search( + &mut rdr, + &mut s, + &editor.history, + )); if next.is_some() { cmd = next.unwrap(); } else { @@ -886,10 +915,18 @@ fn readline_edit<C: Completer>(prompt: &str, try!(edit_history_next(&mut s, &editor.history, true)) } Cmd::HistorySearchBackward => { - try!(edit_history_search(&mut s, &editor.history, Direction::Reverse)) + try!(edit_history_search( + &mut s, + &editor.history, + Direction::Reverse, + )) } Cmd::HistorySearchForward => { - try!(edit_history_search(&mut s, &editor.history, Direction::Forward)) + try!(edit_history_search( + &mut s, + &editor.history, + Direction::Forward, + )) } Cmd::TransposeChars => { // Exchange the char before cursor with the character at cursor. @@ -1155,7 +1192,8 @@ impl<C: Completer> fmt::Debug for Editor<C> { /// Edited lines iterator pub struct Iter<'a, C: Completer> - where C: 'a +where + C: 'a, { editor: &'a mut Editor<C>, prompt: &'a str, @@ -1281,13 +1319,19 @@ mod test { #[test] fn delete_key() { - assert_line(&[KeyPress::Char('a'), KeyPress::Delete, KeyPress::Enter], - "a"); - assert_line(&[KeyPress::Char('a'), - KeyPress::Left, - KeyPress::Delete, - KeyPress::Enter], - ""); + assert_line( + &[KeyPress::Char('a'), KeyPress::Delete, KeyPress::Enter], + "a", + ); + assert_line( + &[ + KeyPress::Char('a'), + KeyPress::Left, + KeyPress::Delete, + KeyPress::Enter, + ], + "", + ); } #[test] diff --git a/src/line_buffer.rs b/src/line_buffer.rs index f574b3e9af9142e9a3a63a50088515005674d685..cae5fe4591606dc774ebeb68a75b04e1f61e903e 100644 --- a/src/line_buffer.rs +++ b/src/line_buffer.rs @@ -500,18 +500,18 @@ impl LineBuffer { }; if let Some(pos) = search_result { Some(match *cs { - CharSearch::Backward(_) => pos, - CharSearch::BackwardAfter(c) => pos + c.len_utf8(), - CharSearch::Forward(_) => shift + pos, - CharSearch::ForwardBefore(_) => { - shift + pos - - self.buf[..shift + pos] - .chars() - .next_back() - .unwrap() - .len_utf8() - } - }) + CharSearch::Backward(_) => pos, + CharSearch::BackwardAfter(c) => pos + c.len_utf8(), + CharSearch::Forward(_) => shift + pos, + CharSearch::ForwardBefore(_) => { + shift + pos - + self.buf[..shift + pos] + .chars() + .next_back() + .unwrap() + .len_utf8() + } + }) } else { None } @@ -638,8 +638,11 @@ impl LineBuffer { pub fn replace(&mut self, range: Range<usize>, text: &str) { let start = range.start; for cl in &self.cl { - cl.borrow_mut() - .replace(start, self.buf.index(range.clone()), text); + cl.borrow_mut().replace( + start, + self.buf.index(range.clone()), + text, + ); } self.buf.drain(range); if start == self.buf.len() { @@ -673,12 +676,18 @@ impl LineBuffer { fn drain(&mut self, range: Range<usize>, dir: Direction) -> Drain { for dl in &self.dl { - dl.borrow_mut() - .delete(range.start, &self.buf[range.start..range.end], dir); + dl.borrow_mut().delete( + range.start, + &self.buf[range.start..range.end], + dir, + ); } for cl in &self.cl { - cl.borrow_mut() - .delete(range.start, &self.buf[range.start..range.end], dir); + cl.borrow_mut().delete( + range.start, + &self.buf[range.start..range.end], + dir, + ); } self.buf.drain(range) } @@ -737,13 +746,11 @@ impl LineBuffer { }; if let Some(pos) = search_result { Some(match cs { - CharSearch::Backward(_) | - CharSearch::BackwardAfter(_) => self.buf[pos..self.pos].to_owned(), - CharSearch::ForwardBefore(_) => self.buf[self.pos..pos].to_owned(), - CharSearch::Forward(c) => { - self.buf[self.pos..pos + c.len_utf8()].to_owned() - } - }) + CharSearch::Backward(_) | + CharSearch::BackwardAfter(_) => self.buf[pos..self.pos].to_owned(), + CharSearch::ForwardBefore(_) => self.buf[self.pos..pos].to_owned(), + CharSearch::Forward(c) => self.buf[self.pos..pos + c.len_utf8()].to_owned(), + }) } else { None } @@ -776,11 +783,11 @@ impl Deref for LineBuffer { fn is_start_of_word(word_def: Word, previous: &str, grapheme: &str) -> bool { (!is_word_char(word_def, previous) && is_word_char(word_def, grapheme)) || - (word_def == Word::Vi && !is_other_char(previous) && is_other_char(grapheme)) + (word_def == Word::Vi && !is_other_char(previous) && is_other_char(grapheme)) } fn is_end_of_word(word_def: Word, grapheme: &str, next: &str) -> bool { (!is_word_char(word_def, next) && is_word_char(word_def, grapheme)) || - (word_def == Word::Vi && !is_other_char(next) && is_other_char(grapheme)) + (word_def == Word::Vi && !is_other_char(next) && is_other_char(grapheme)) } fn is_word_char(word_def: Word, grapheme: &str) -> bool { diff --git a/src/tty/mod.rs b/src/tty/mod.rs index 4393efd59a052baed5df083aa1f377f2e0531494..347d1d231566cf8b9c556f17000a1f93972d8f6e 100644 --- a/src/tty/mod.rs +++ b/src/tty/mod.rs @@ -32,13 +32,14 @@ pub trait Renderer { fn move_cursor(&mut self, old: Position, new: Position) -> Result<()>; /// Display prompt, line and cursor in terminal output - fn refresh_line(&mut self, - prompt: &str, - prompt_size: Position, - line: &LineBuffer, - current_row: usize, - old_rows: usize) - -> Result<(Position, Position)>; + fn refresh_line( + &mut self, + prompt: &str, + prompt_size: Position, + line: &LineBuffer, + current_row: usize, + old_rows: usize, + ) -> Result<(Position, Position)>; /// Calculate the number of columns and rows used to display `s` on a /// `cols` width terminal @@ -73,13 +74,14 @@ impl<'a, R: Renderer + ?Sized> Renderer for &'a mut R { fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> { (**self).move_cursor(old, new) } - fn refresh_line(&mut self, - prompt: &str, - prompt_size: Position, - line: &LineBuffer, - current_row: usize, - old_rows: usize) - -> Result<(Position, Position)> { + fn refresh_line( + &mut self, + prompt: &str, + prompt_size: Position, + line: &LineBuffer, + current_row: usize, + old_rows: usize, + ) -> Result<(Position, Position)> { (**self).refresh_line(prompt, prompt_size, line, current_row, old_rows) } fn calculate_position(&self, s: &str, orig: Position) -> Position { diff --git a/src/tty/test.rs b/src/tty/test.rs index fee42656b73a220500a675a03616370fc971ebde..6a1e60c136e7306ea817f45b8eec16cfd293e3c3 100644 --- a/src/tty/test.rs +++ b/src/tty/test.rs @@ -50,13 +50,14 @@ impl Renderer for Sink { Ok(()) } - fn refresh_line(&mut self, - prompt: &str, - prompt_size: Position, - line: &LineBuffer, - _: usize, - _: usize) - -> Result<(Position, Position)> { + fn refresh_line( + &mut self, + prompt: &str, + prompt_size: Position, + line: &LineBuffer, + _: usize, + _: usize, + ) -> Result<(Position, Position)> { try!(self.write_all(prompt.as_bytes())); try!(self.write_all(line.as_bytes())); Ok((prompt_size, prompt_size)) @@ -97,7 +98,7 @@ impl Renderer for Sink { pub type Terminal = DummyTerminal; -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct DummyTerminal { pub keys: Vec<KeyPress>, } diff --git a/src/tty/unix.rs b/src/tty/unix.rs index d03f41eb9d08417f9b22b71b08ec69ec31f82b77..107a8d356fb343e9b0aba1467f4b1973e5ffdc7d 100644 --- a/src/tty/unix.rs +++ b/src/tty/unix.rs @@ -77,9 +77,11 @@ impl Read for StdinRaw { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { loop { let res = unsafe { - libc::read(STDIN_FILENO, - buf.as_mut_ptr() as *mut libc::c_void, - buf.len() as libc::size_t) + libc::read( + STDIN_FILENO, + buf.as_mut_ptr() as *mut libc::c_void, + buf.len() as libc::size_t, + ) }; if res == -1 { let error = io::Error::last_os_error(); @@ -103,9 +105,9 @@ impl PosixRawReader { fn new(config: &Config) -> Result<PosixRawReader> { let stdin = StdinRaw {}; Ok(PosixRawReader { - chars: stdin.chars(), - timeout_ms: config.keyseq_timeout(), - }) + chars: stdin.chars(), + timeout_ms: config.keyseq_timeout(), + }) } fn escape_sequence(&mut self) -> Result<KeyPress> { @@ -119,38 +121,38 @@ impl PosixRawReader { let seq3 = try!(self.next_char()); if seq3 == '~' { Ok(match seq2 { - '1' | '7' => KeyPress::Home, // tmux, xrvt - '2' => KeyPress::Insert, - '3' => KeyPress::Delete, // kdch1 - '4' | '8' => KeyPress::End, // tmux, xrvt - '5' => KeyPress::PageUp, // kpp - '6' => KeyPress::PageDown, // knp - _ => { - debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} ~", seq2); - KeyPress::UnknownEscSeq - } - }) + '1' | '7' => KeyPress::Home, // tmux, xrvt + '2' => KeyPress::Insert, + '3' => KeyPress::Delete, // kdch1 + '4' | '8' => KeyPress::End, // tmux, xrvt + '5' => KeyPress::PageUp, // kpp + '6' => KeyPress::PageDown, // knp + _ => { + debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} ~", seq2); + KeyPress::UnknownEscSeq + } + }) } else if seq3.is_digit(10) { let seq4 = try!(self.next_char()); if seq4 == '~' { Ok(match (seq2, seq3) { - ('1', '1') => KeyPress::F(1), // rxvt-unicode - ('1', '2') => KeyPress::F(2), // rxvt-unicode - ('1', '3') => KeyPress::F(3), // rxvt-unicode - ('1', '4') => KeyPress::F(4), // rxvt-unicode - ('1', '5') => KeyPress::F(5), // kf5 - ('1', '7') => KeyPress::F(6), // kf6 - ('1', '8') => KeyPress::F(7), // kf7 - ('1', '9') => KeyPress::F(8), // kf8 - ('2', '0') => KeyPress::F(9), // kf9 - ('2', '1') => KeyPress::F(10), // kf10 - ('2', '3') => KeyPress::F(11), // kf11 - ('2', '4') => KeyPress::F(12), // kf12 - _ => { - debug!(target: "rustyline", "unsupported esc sequence: ESC [ {}{} ~", seq1, seq2); - KeyPress::UnknownEscSeq - } - }) + ('1', '1') => KeyPress::F(1), // rxvt-unicode + ('1', '2') => KeyPress::F(2), // rxvt-unicode + ('1', '3') => KeyPress::F(3), // rxvt-unicode + ('1', '4') => KeyPress::F(4), // rxvt-unicode + ('1', '5') => KeyPress::F(5), // kf5 + ('1', '7') => KeyPress::F(6), // kf6 + ('1', '8') => KeyPress::F(7), // kf7 + ('1', '9') => KeyPress::F(8), // kf8 + ('2', '0') => KeyPress::F(9), // kf9 + ('2', '1') => KeyPress::F(10), // kf10 + ('2', '3') => KeyPress::F(11), // kf11 + ('2', '4') => KeyPress::F(12), // kf12 + _ => { + debug!(target: "rustyline", "unsupported esc sequence: ESC [ {}{} ~", seq1, seq2); + KeyPress::UnknownEscSeq + } + }) } else if seq4 == ';' { let seq5 = try!(self.next_char()); if seq5.is_digit(10) { @@ -170,19 +172,19 @@ impl PosixRawReader { let seq5 = try!(self.next_char()); if seq2 == '1' { Ok(match (seq4, seq5) { - ('5', 'A') => KeyPress::ControlUp, - ('5', 'B') => KeyPress::ControlDown, - ('5', 'C') => KeyPress::ControlRight, - ('5', 'D') => KeyPress::ControlLeft, - ('2', 'A') => KeyPress::ShiftUp, - ('2', 'B') => KeyPress::ShiftDown, - ('2', 'C') => KeyPress::ShiftRight, - ('2', 'D') => KeyPress::ShiftLeft, - _ => { - debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} ; {} {}", seq2, seq4, seq5); - KeyPress::UnknownEscSeq - } - }) + ('5', 'A') => KeyPress::ControlUp, + ('5', 'B') => KeyPress::ControlDown, + ('5', 'C') => KeyPress::ControlRight, + ('5', 'D') => KeyPress::ControlLeft, + ('2', 'A') => KeyPress::ShiftUp, + ('2', 'B') => KeyPress::ShiftDown, + ('2', 'C') => KeyPress::ShiftRight, + ('2', 'D') => KeyPress::ShiftLeft, + _ => { + debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} ; {} {}", seq2, seq4, seq5); + KeyPress::UnknownEscSeq + } + }) } else { debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} ; {} {}", seq2, seq4, seq5); Ok(KeyPress::UnknownEscSeq) @@ -193,51 +195,51 @@ impl PosixRawReader { } } else { Ok(match (seq2, seq3) { - ('5', 'A') => KeyPress::ControlUp, - ('5', 'B') => KeyPress::ControlDown, - ('5', 'C') => KeyPress::ControlRight, - ('5', 'D') => KeyPress::ControlLeft, - _ => { - debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} {:?}", seq2, seq3); - KeyPress::UnknownEscSeq - } - }) + ('5', 'A') => KeyPress::ControlUp, + ('5', 'B') => KeyPress::ControlDown, + ('5', 'C') => KeyPress::ControlRight, + ('5', 'D') => KeyPress::ControlLeft, + _ => { + debug!(target: "rustyline", "unsupported esc sequence: ESC [ {} {:?}", seq2, seq3); + KeyPress::UnknownEscSeq + } + }) } } else { // ANSI Ok(match seq2 { - 'A' => KeyPress::Up, // kcuu1 - 'B' => KeyPress::Down, // kcud1 - 'C' => KeyPress::Right, // kcuf1 - 'D' => KeyPress::Left, // kcub1 - 'F' => KeyPress::End, - 'H' => KeyPress::Home, // khome - _ => { - debug!(target: "rustyline", "unsupported esc sequence: ESC [ {:?}", seq2); - KeyPress::UnknownEscSeq - } - }) + 'A' => KeyPress::Up, // kcuu1 + 'B' => KeyPress::Down, // kcud1 + 'C' => KeyPress::Right, // kcuf1 + 'D' => KeyPress::Left, // kcub1 + 'F' => KeyPress::End, + 'H' => KeyPress::Home, // khome + _ => { + debug!(target: "rustyline", "unsupported esc sequence: ESC [ {:?}", seq2); + KeyPress::UnknownEscSeq + } + }) } } else if seq1 == 'O' { // xterm // ESC O sequences. (SS3) let seq2 = try!(self.next_char()); Ok(match seq2 { - 'A' => KeyPress::Up, // kcuu1 - 'B' => KeyPress::Down, // kcud1 - 'C' => KeyPress::Right, // kcuf1 - 'D' => KeyPress::Left, // kcub1 - 'F' => KeyPress::End, // kend - 'H' => KeyPress::Home, // khome - 'P' => KeyPress::F(1), // kf1 - 'Q' => KeyPress::F(2), // kf2 - 'R' => KeyPress::F(3), // kf3 - 'S' => KeyPress::F(4), // kf4 - _ => { - debug!(target: "rustyline", "unsupported esc sequence: ESC O {:?}", seq2); - KeyPress::UnknownEscSeq - } - }) + 'A' => KeyPress::Up, // kcuu1 + 'B' => KeyPress::Down, // kcud1 + 'C' => KeyPress::Right, // kcuf1 + 'D' => KeyPress::Left, // kcub1 + 'F' => KeyPress::End, // kend + 'H' => KeyPress::Home, // khome + 'P' => KeyPress::F(1), // kf1 + 'Q' => KeyPress::F(2), // kf2 + 'R' => KeyPress::F(3), // kf3 + 'S' => KeyPress::F(4), // kf4 + _ => { + debug!(target: "rustyline", "unsupported esc sequence: ESC O {:?}", seq2); + KeyPress::UnknownEscSeq + } + }) } else { // TODO ESC-R (r): Undo all changes made to this line. Ok(KeyPress::Meta(seq1)) @@ -251,8 +253,9 @@ impl RawReader for PosixRawReader { let mut key = consts::char_to_key_press(c); if key == KeyPress::Esc { - let mut fds = - [poll::PollFd::new(STDIN_FILENO, poll::POLLIN, poll::EventFlags::empty())]; + let mut fds = [ + poll::PollFd::new(STDIN_FILENO, poll::POLLIN, poll::EventFlags::empty()), + ]; match poll::poll(&mut fds, self.timeout_ms) { Ok(n) if n == 0 => { // single escape @@ -334,13 +337,14 @@ impl Renderer for PosixRenderer { self.write_and_flush(ab.as_bytes()) } - fn refresh_line(&mut self, - prompt: &str, - prompt_size: Position, - line: &LineBuffer, - current_row: usize, - old_rows: usize) - -> Result<(Position, Position)> { + fn refresh_line( + &mut self, + prompt: &str, + prompt_size: Position, + line: &LineBuffer, + current_row: usize, + old_rows: usize, + ) -> Result<(Position, Position)> { use std::fmt::Write; let mut ab = String::new(); @@ -475,9 +479,11 @@ static SIGWINCH: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT; fn install_sigwinch_handler() { SIGWINCH_ONCE.call_once(|| unsafe { - let sigwinch = signal::SigAction::new(signal::SigHandler::Handler(sigwinch_handler), - signal::SaFlags::empty(), - signal::SigSet::empty()); + let sigwinch = signal::SigAction::new( + signal::SigHandler::Handler(sigwinch_handler), + signal::SaFlags::empty(), + signal::SigSet::empty(), + ); let _ = signal::sigaction(signal::SIGWINCH, &sigwinch); }); } @@ -489,7 +495,7 @@ extern "C" fn sigwinch_handler(_: libc::c_int) { pub type Terminal = PosixTerminal; -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct PosixTerminal { unsupported: bool, stdin_isatty: bool, @@ -566,7 +572,7 @@ pub fn suspend() -> Result<()> { Ok(()) } -#[cfg(all(unix,test))] +#[cfg(all(unix, test))] mod test { use std::io::{self, Stdout}; use super::{Position, Renderer}; diff --git a/src/tty/windows.rs b/src/tty/windows.rs index 83ce8993dad8edcf6bd7ba8dce31671f0090eb65..bf66d6fdaecc27dd5506a1635f04fa3cfcb19062 100644 --- a/src/tty/windows.rs +++ b/src/tty/windows.rs @@ -22,8 +22,10 @@ fn get_std_handle(fd: winapi::DWORD) -> Result<winapi::HANDLE> { if handle == winapi::INVALID_HANDLE_VALUE { try!(Err(io::Error::last_os_error())); } else if handle.is_null() { - try!(Err(io::Error::new(io::ErrorKind::Other, - "no stdio handle available for this process"))); + try!(Err(io::Error::new( + io::ErrorKind::Other, + "no stdio handle available for this process", + ))); } Ok(handle) } @@ -45,7 +47,10 @@ fn get_win_size(handle: winapi::HANDLE) -> (usize, usize) { let mut info = unsafe { mem::zeroed() }; match unsafe { kernel32::GetConsoleScreenBufferInfo(handle, &mut info) } { 0 => (80, 24), - _ => (info.dwSize.X as usize, (1 + info.srWindow.Bottom - info.srWindow.Top) as usize), // (info.srWindow.Right - info.srWindow.Left + 1) + _ => ( + info.dwSize.X as usize, + (1 + info.srWindow.Bottom - info.srWindow.Top) as usize, + ), // (info.srWindow.Right - info.srWindow.Left + 1) } } @@ -57,7 +62,7 @@ fn get_console_mode(handle: winapi::HANDLE) -> Result<winapi::DWORD> { pub type Mode = ConsoleMode; -#[derive(Clone,Copy,Debug)] +#[derive(Clone, Copy, Debug)] pub struct ConsoleMode { original_mode: winapi::DWORD, stdin_handle: winapi::HANDLE, @@ -66,7 +71,10 @@ pub struct ConsoleMode { impl RawMode for Mode { /// Disable RAW mode for the terminal. fn disable_raw_mode(&self) -> Result<()> { - check!(kernel32::SetConsoleMode(self.stdin_handle, self.original_mode)); + check!(kernel32::SetConsoleMode( + self.stdin_handle, + self.original_mode, + )); Ok(()) } } @@ -81,9 +89,9 @@ impl ConsoleRawReader { pub fn new() -> Result<ConsoleRawReader> { let handle = try!(get_std_handle(STDIN_FILENO)); Ok(ConsoleRawReader { - handle: handle, - buf: None, - }) + handle: handle, + buf: None, + }) } } @@ -96,10 +104,12 @@ impl RawReader for ConsoleRawReader { let mut count = 0; loop { // TODO GetNumberOfConsoleInputEvents - check!(kernel32::ReadConsoleInputW(self.handle, - &mut rec, - 1 as winapi::DWORD, - &mut count)); + check!(kernel32::ReadConsoleInputW( + self.handle, + &mut rec, + 1 as winapi::DWORD, + &mut count, + )); if rec.EventType == winapi::WINDOW_BUFFER_SIZE_EVENT { SIGWINCH.store(true, atomic::Ordering::SeqCst); @@ -111,7 +121,8 @@ impl RawReader for ConsoleRawReader { let key_event = unsafe { rec.KeyEvent() }; // writeln!(io::stderr(), "key_event: {:?}", key_event).unwrap(); if key_event.bKeyDown == 0 && - key_event.wVirtualKeyCode != winapi::VK_MENU as winapi::WORD { + key_event.wVirtualKeyCode != winapi::VK_MENU as winapi::WORD + { continue; } // key_event.wRepeatCount seems to be always set to 1 (maybe because we only @@ -128,31 +139,31 @@ impl RawReader for ConsoleRawReader { match key_event.wVirtualKeyCode as i32 { winapi::VK_LEFT => { return Ok(if ctrl { - KeyPress::ControlLeft - } else { - KeyPress::Left - }) + KeyPress::ControlLeft + } else { + KeyPress::Left + }) } winapi::VK_RIGHT => { return Ok(if ctrl { - KeyPress::ControlRight - } else { - KeyPress::Right - }) + KeyPress::ControlRight + } else { + KeyPress::Right + }) } winapi::VK_UP => { return Ok(if ctrl { - KeyPress::ControlUp - } else { - KeyPress::Up - }) + KeyPress::ControlUp + } else { + KeyPress::Up + }) } winapi::VK_DOWN => { return Ok(if ctrl { - KeyPress::ControlDown - } else { - KeyPress::Down - }) + KeyPress::ControlDown + } else { + KeyPress::Down + }) } winapi::VK_DELETE => return Ok(KeyPress::Delete), winapi::VK_HOME => return Ok(KeyPress::Home), @@ -233,16 +244,19 @@ impl ConsoleRenderer { Ok(()) } - fn fill_console_output_character(&mut self, - length: winapi::DWORD, - pos: winapi::COORD) - -> Result<()> { + fn fill_console_output_character( + &mut self, + length: winapi::DWORD, + pos: winapi::COORD, + ) -> Result<()> { let mut _count = 0; - check!(kernel32::FillConsoleOutputCharacterA(self.handle, - ' ' as winapi::CHAR, - length, - pos, - &mut _count)); + check!(kernel32::FillConsoleOutputCharacterA( + self.handle, + ' ' as winapi::CHAR, + length, + pos, + &mut _count, + )); Ok(()) } } @@ -263,13 +277,14 @@ impl Renderer for ConsoleRenderer { self.set_console_cursor_position(info.dwCursorPosition) } - fn refresh_line(&mut self, - prompt: &str, - prompt_size: Position, - line: &LineBuffer, - current_row: usize, - old_rows: usize) - -> Result<(Position, Position)> { + fn refresh_line( + &mut self, + prompt: &str, + prompt_size: Position, + line: &LineBuffer, + current_row: usize, + old_rows: usize, + ) -> Result<(Position, Position)> { // calculate the position of the end of the input line let end_pos = self.calculate_position(line, prompt_size); // calculate the desired position of the cursor @@ -281,8 +296,10 @@ impl Renderer for ConsoleRenderer { info.dwCursorPosition.Y -= current_row as i16; try!(self.set_console_cursor_position(info.dwCursorPosition)); let mut _count = 0; - try!(self.fill_console_output_character((info.dwSize.X * (old_rows as i16 + 1)) as u32, - info.dwCursorPosition)); + try!(self.fill_console_output_character( + (info.dwSize.X * (old_rows as i16 + 1)) as u32, + info.dwCursorPosition, + )); let mut ab = String::new(); // display the prompt ab.push_str(prompt); // TODO handle ansi escape code (SetConsoleTextAttribute) @@ -337,11 +354,13 @@ impl Renderer for ConsoleRenderer { check!(kernel32::SetConsoleCursorPosition(self.handle, coord)); let mut _count = 0; let n = info.dwSize.X as winapi::DWORD * info.dwSize.Y as winapi::DWORD; - check!(kernel32::FillConsoleOutputCharacterA(self.handle, - ' ' as winapi::CHAR, - n, - coord, - &mut _count)); + check!(kernel32::FillConsoleOutputCharacterA( + self.handle, + ' ' as winapi::CHAR, + n, + coord, + &mut _count, + )); Ok(()) } @@ -372,7 +391,7 @@ static SIGWINCH: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT; pub type Terminal = Console; -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct Console { stdin_isatty: bool, stdin_handle: winapi::HANDLE, @@ -421,14 +440,16 @@ impl Term for Console { /// Enable RAW mode for the terminal. fn enable_raw_mode(&self) -> Result<Mode> { if !self.stdin_isatty { - try!(Err(io::Error::new(io::ErrorKind::Other, - "no stdio handle available for this process"))); + try!(Err(io::Error::new( + io::ErrorKind::Other, + "no stdio handle available for this process", + ))); } let original_mode = try!(get_console_mode(self.stdin_handle)); // Disable these modes let raw = original_mode & - !(winapi::wincon::ENABLE_LINE_INPUT | winapi::wincon::ENABLE_ECHO_INPUT | - winapi::wincon::ENABLE_PROCESSED_INPUT); + !(winapi::wincon::ENABLE_LINE_INPUT | winapi::wincon::ENABLE_ECHO_INPUT | + winapi::wincon::ENABLE_PROCESSED_INPUT); // Enable these modes let raw = raw | winapi::wincon::ENABLE_EXTENDED_FLAGS; let raw = raw | winapi::wincon::ENABLE_INSERT_MODE; @@ -436,9 +457,9 @@ impl Term for Console { let raw = raw | winapi::wincon::ENABLE_WINDOW_INPUT; check!(kernel32::SetConsoleMode(self.stdin_handle, raw)); Ok(Mode { - original_mode: original_mode, - stdin_handle: self.stdin_handle, - }) + original_mode: original_mode, + stdin_handle: self.stdin_handle, + }) } fn create_reader(&self, _: &Config) -> Result<ConsoleRawReader> { diff --git a/src/undo.rs b/src/undo.rs index 2f37cf84094a4a587046efbfb7cd5f3fabb4c400..80e6ee7632f55d8e7876cccd6e1950276c61d323 100644 --- a/src/undo.rs +++ b/src/undo.rs @@ -152,11 +152,10 @@ impl Changeset { pub fn insert_str<S: Into<String> + Debug>(&mut self, idx: usize, string: S) { debug!(target: "rustyline", "Changeset::insert_str({}, {:?})", idx, string); self.redos.clear(); - self.undos - .push(Change::Insert { - idx: idx, - text: string.into(), - }); + self.undos.push(Change::Insert { + idx: idx, + text: string.into(), + }); } pub fn delete<S: AsRef<str> + Into<String> + Debug>(&mut self, indx: usize, string: S) { @@ -164,22 +163,23 @@ impl Changeset { self.redos.clear(); if !Self::single_char(string.as_ref()) || - !self.undos - .last() - .map_or(false, |lc| lc.delete_seq(indx, string.as_ref().len())) { - self.undos - .push(Change::Delete { - idx: indx, - text: string.into(), - }); + !self.undos.last().map_or(false, |lc| { + lc.delete_seq(indx, string.as_ref().len()) + }) + { + self.undos.push(Change::Delete { + idx: indx, + text: string.into(), + }); return; } // merge consecutive char deletions when char is alphanumeric let mut last_change = self.undos.pop().unwrap(); if let Change::Delete { - ref mut idx, - ref mut text, - } = last_change { + ref mut idx, + ref mut text, + } = last_change + { if *idx == indx { text.push_str(string.as_ref()); } else { @@ -194,38 +194,33 @@ impl Changeset { fn single_char(s: &str) -> bool { let mut graphemes = s.graphemes(true); - graphemes - .next() - .map_or(false, |grapheme| grapheme.is_alphanumeric()) && - graphemes.next().is_none() + graphemes.next().map_or( + false, + |grapheme| grapheme.is_alphanumeric(), + ) && graphemes.next().is_none() } - pub fn replace<S: AsRef<str> + Into<String> + Debug>(&mut self, - indx: usize, - old_: S, - new_: S) { + pub fn replace<S: AsRef<str> + Into<String> + Debug>(&mut self, indx: usize, old_: S, new_: S) { debug!(target: "rustyline", "Changeset::replace({}, {:?}, {:?})", indx, old_, new_); self.redos.clear(); - if !self.undos - .last() - .map_or(false, |lc| lc.replace_seq(indx)) { - self.undos - .push(Change::Replace { - idx: indx, - old: old_.into(), - new: new_.into(), - }); + if !self.undos.last().map_or(false, |lc| lc.replace_seq(indx)) { + self.undos.push(Change::Replace { + idx: indx, + old: old_.into(), + new: new_.into(), + }); return; } // merge consecutive char replacements let mut last_change = self.undos.pop().unwrap(); if let Change::Replace { - ref mut old, - ref mut new, - .. - } = last_change { + ref mut old, + ref mut new, + .. + } = last_change + { old.push_str(old_.as_ref()); new.push_str(new_.as_ref()); } else {