From c6bfb6646c3cab5d6e99915fcaafa4fd26297ea3 Mon Sep 17 00:00:00 2001 From: gwenn <gtreguier@gmail.com> Date: Sun, 15 Jan 2017 17:15:28 +0100 Subject: [PATCH] Introduce type alias RepeatCount --- src/keymap.rs | 44 +++++++++++++++++++++++--------------------- src/lib.rs | 28 ++++++++++++++-------------- src/line_buffer.rs | 40 ++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 55 deletions(-) diff --git a/src/keymap.rs b/src/keymap.rs index 75c3f990..3bb0ae9b 100644 --- a/src/keymap.rs +++ b/src/keymap.rs @@ -4,38 +4,40 @@ use consts::KeyPress; use tty::RawReader; use super::Result; +pub type RepeatCount = usize; + #[derive(Debug, Clone, PartialEq)] pub enum Cmd { Abort, // Miscellaneous Command AcceptLine, - BackwardChar(usize), - BackwardDeleteChar(usize), - BackwardKillWord(usize, Word), // Backward until start of word - BackwardWord(usize, Word), // Backward until start of word + BackwardChar(RepeatCount), + BackwardDeleteChar(RepeatCount), + BackwardKillWord(RepeatCount, Word), // Backward until start of word + BackwardWord(RepeatCount, Word), // Backward until start of word BeginningOfHistory, BeginningOfLine, CapitalizeWord, ClearScreen, Complete, - DeleteChar(usize), + DeleteChar(RepeatCount), DowncaseWord, EndOfFile, EndOfHistory, EndOfLine, - ForwardChar(usize), + ForwardChar(RepeatCount), ForwardSearchHistory, - ForwardWord(usize, At, Word), // Forward until start/end of word + ForwardWord(RepeatCount, At, Word), // Forward until start/end of word Interrupt, KillLine, KillWholeLine, - KillWord(usize, At, Word), // Forward until start/end of word + KillWord(RepeatCount, At, Word), // Forward until start/end of word NextHistory, Noop, PreviousHistory, QuotedInsert, - Replace(usize, char), + Replace(RepeatCount, char), ReverseSearchHistory, - SelfInsert(usize, char), + SelfInsert(RepeatCount, char), Suspend, TransposeChars, TransposeWords, @@ -43,9 +45,9 @@ pub enum Cmd { UnixLikeDiscard, // UnixWordRubout, // = BackwardKillWord(Word::Big) UpcaseWord, - ViCharSearch(usize, CharSearch), - ViDeleteTo(usize, CharSearch), - Yank(usize, Anchor), + ViCharSearch(RepeatCount, CharSearch), + ViDeleteTo(RepeatCount, CharSearch), + Yank(RepeatCount, Anchor), YankPop, } @@ -378,7 +380,7 @@ impl EditState { rdr: &mut R, config: &Config, key: KeyPress, - n: usize) + n: RepeatCount) -> Result<Cmd> { let mut mvt = try!(rdr.next_key(config.keyseq_timeout())); if mvt == key { @@ -435,7 +437,7 @@ impl EditState { }) } - fn common(&mut self, key: KeyPress, n: usize, positive: bool) -> Cmd { + fn common(&mut self, key: KeyPress, n: RepeatCount, positive: bool) -> Cmd { match key { KeyPress::Home => Cmd::BeginningOfLine, KeyPress::Left => { @@ -501,25 +503,25 @@ impl EditState { num_args } - fn emacs_num_args(&mut self) -> (usize, bool) { + fn emacs_num_args(&mut self) -> (RepeatCount, bool) { let num_args = self.num_args(); if num_args < 0 { if let (n, false) = num_args.overflowing_abs() { - (n as usize, false) + (n as RepeatCount, false) } else { - (usize::max_value(), false) + (RepeatCount::max_value(), false) } } else { - (num_args as usize, true) + (num_args as RepeatCount, true) } } - fn vi_num_args(&mut self) -> usize { + fn vi_num_args(&mut self) -> RepeatCount { let num_args = self.num_args(); if num_args < 0 { unreachable!() } else { - num_args.abs() as usize + num_args.abs() as RepeatCount } } } diff --git a/src/lib.rs b/src/lib.rs index f7d79c92..eef4b9da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,7 +56,7 @@ use tty::{RawMode, RawReader, Terminal, Term}; use completion::{Completer, longest_common_prefix}; use history::{Direction, History}; use line_buffer::{LineBuffer, MAX_LINE, WordAction}; -use keymap::{Anchor, At, CharSearch, Cmd, EditState, Word}; +use keymap::{Anchor, At, CharSearch, Cmd, EditState, RepeatCount, Word}; use kill_ring::{Mode, KillRing}; pub use config::{CompletionType, Config, EditMode, HistoryDuplicates}; @@ -314,7 +314,7 @@ fn calculate_position(s: &str, orig: Position, cols: usize) -> Position { } /// Insert the character `ch` at cursor current position. -fn edit_insert(s: &mut State, ch: char, n: usize) -> Result<()> { +fn edit_insert(s: &mut State, ch: char, n: RepeatCount) -> Result<()> { if let Some(push) = s.line.insert(ch, n) { if push { if n == 1 && s.cursor.col + ch.width().unwrap_or(0) < s.cols { @@ -336,7 +336,7 @@ fn edit_insert(s: &mut State, ch: char, n: usize) -> Result<()> { } /// Replace a single (or n) character(s) under the cursor (Vi mode) -fn edit_replace_char(s: &mut State, ch: char, n: usize) -> Result<()> { +fn edit_replace_char(s: &mut State, ch: char, n: RepeatCount) -> Result<()> { if let Some(chars) = s.line.delete(n) { let count = chars.graphemes(true).count(); s.line.insert(ch, count); @@ -348,7 +348,7 @@ fn edit_replace_char(s: &mut State, ch: char, n: usize) -> Result<()> { } // Yank/paste `text` at current position. -fn edit_yank(s: &mut State, text: &str, anchor: Anchor, n: usize) -> Result<()> { +fn edit_yank(s: &mut State, text: &str, anchor: Anchor, n: RepeatCount) -> Result<()> { if s.line.yank(text, anchor, n).is_some() { s.refresh_line() } else { @@ -363,7 +363,7 @@ fn edit_yank_pop(s: &mut State, yank_size: usize, text: &str) -> Result<()> { } /// Move cursor on the left. -fn edit_move_left(s: &mut State, n: usize) -> Result<()> { +fn edit_move_left(s: &mut State, n: RepeatCount) -> Result<()> { if s.line.move_left(n) { s.refresh_line() } else { @@ -372,7 +372,7 @@ fn edit_move_left(s: &mut State, n: usize) -> Result<()> { } /// Move cursor on the right. -fn edit_move_right(s: &mut State, n: usize) -> Result<()> { +fn edit_move_right(s: &mut State, n: RepeatCount) -> Result<()> { if s.line.move_right(n) { s.refresh_line() } else { @@ -400,7 +400,7 @@ fn edit_move_end(s: &mut State) -> Result<()> { /// Delete the character at the right of the cursor without altering the cursor /// position. Basically this is what happens with the "Delete" keyboard key. -fn edit_delete(s: &mut State, n: usize) -> Result<()> { +fn edit_delete(s: &mut State, n: RepeatCount) -> Result<()> { if s.line.delete(n).is_some() { s.refresh_line() } else { @@ -409,7 +409,7 @@ fn edit_delete(s: &mut State, n: usize) -> Result<()> { } /// Backspace implementation. -fn edit_backspace(s: &mut State, n: usize) -> Result<()> { +fn edit_backspace(s: &mut State, n: RepeatCount) -> Result<()> { if s.line.backspace(n).is_some() { s.refresh_line() } else { @@ -446,7 +446,7 @@ fn edit_transpose_chars(s: &mut State) -> Result<()> { } } -fn edit_move_to_prev_word(s: &mut State, word_def: Word, n: usize) -> Result<()> { +fn edit_move_to_prev_word(s: &mut State, word_def: Word, n: RepeatCount) -> Result<()> { if s.line.move_to_prev_word(word_def, n) { s.refresh_line() } else { @@ -456,7 +456,7 @@ fn edit_move_to_prev_word(s: &mut State, word_def: Word, n: usize) -> Result<()> /// Delete the previous word, maintaining the cursor at the start of the /// current word. -fn edit_delete_prev_word(s: &mut State, word_def: Word, n: usize) -> Result<Option<String>> { +fn edit_delete_prev_word(s: &mut State, word_def: Word, n: RepeatCount) -> Result<Option<String>> { if let Some(text) = s.line.delete_prev_word(word_def, n) { try!(s.refresh_line()); Ok(Some(text)) @@ -465,7 +465,7 @@ fn edit_delete_prev_word(s: &mut State, word_def: Word, n: usize) -> Result<Opti } } -fn edit_move_to_next_word(s: &mut State, at: At, word_def: Word, n: usize) -> Result<()> { +fn edit_move_to_next_word(s: &mut State, at: At, word_def: Word, n: RepeatCount) -> Result<()> { if s.line.move_to_next_word(at, word_def, n) { s.refresh_line() } else { @@ -473,7 +473,7 @@ fn edit_move_to_next_word(s: &mut State, at: At, word_def: Word, n: usize) -> Re } } -fn edit_move_to(s: &mut State, cs: CharSearch, n: usize) -> Result<()> { +fn edit_move_to(s: &mut State, cs: CharSearch, n: RepeatCount) -> Result<()> { if s.line.move_to(cs, n) { s.refresh_line() } else { @@ -482,7 +482,7 @@ fn edit_move_to(s: &mut State, cs: CharSearch, n: usize) -> Result<()> { } /// Kill from the cursor to the end of the current word, or, if between words, to the end of the next word. -fn edit_delete_word(s: &mut State, at: At, word_def: Word, n: usize) -> Result<Option<String>> { +fn edit_delete_word(s: &mut State, at: At, word_def: Word, n: RepeatCount) -> Result<Option<String>> { if let Some(text) = s.line.delete_word(at, word_def, n) { try!(s.refresh_line()); Ok(Some(text)) @@ -491,7 +491,7 @@ fn edit_delete_word(s: &mut State, at: At, word_def: Word, n: usize) -> Result<O } } -fn edit_delete_to(s: &mut State, cs: CharSearch, n: usize) -> Result<Option<String>> { +fn edit_delete_to(s: &mut State, cs: CharSearch, n: RepeatCount) -> Result<Option<String>> { if let Some(text) = s.line.delete_to(cs, n) { try!(s.refresh_line()); Ok(Some(text)) diff --git a/src/line_buffer.rs b/src/line_buffer.rs index 9b6cf1b9..b114036b 100644 --- a/src/line_buffer.rs +++ b/src/line_buffer.rs @@ -3,7 +3,7 @@ use std::iter; use std::ops::{Deref, Range}; use std_unicode::str::UnicodeStr; use unicode_segmentation::UnicodeSegmentation; -use keymap::{Anchor, At, CharSearch, Word}; +use keymap::{Anchor, At, CharSearch, RepeatCount, Word}; /// Maximum buffer size for the line read pub static MAX_LINE: usize = 4096; @@ -99,7 +99,7 @@ impl LineBuffer { } } - fn next_pos(&self, n: usize) -> Option<usize> { + fn next_pos(&self, n: RepeatCount) -> Option<usize> { if self.pos == self.buf.len() { return None; } @@ -110,7 +110,7 @@ impl LineBuffer { .map(|(i, s)| i + self.pos + s.len()) } /// Returns the position of the character just before the current cursor position. - fn prev_pos(&self, n: usize) -> Option<usize> { + fn prev_pos(&self, n: RepeatCount) -> Option<usize> { if self.pos == 0 { return None; } @@ -126,7 +126,7 @@ impl LineBuffer { /// and advance cursor position accordingly. /// Return `None` when maximum buffer size has been reached, /// `true` when the character has been appended to the end of the line. - pub fn insert(&mut self, ch: char, n: usize) -> Option<bool> { + pub fn insert(&mut self, ch: char, n: RepeatCount) -> Option<bool> { let shift = ch.len_utf8() * n; if self.buf.len() + shift > self.buf.capacity() { return None; @@ -151,7 +151,7 @@ impl LineBuffer { /// Yank/paste `text` at current position. /// Return `None` when maximum buffer size has been reached, /// `true` when the character has been appended to the end of the line. - pub fn yank(&mut self, text: &str, anchor: Anchor, n: usize) -> Option<bool> { + pub fn yank(&mut self, text: &str, anchor: Anchor, n: RepeatCount) -> Option<bool> { let shift = text.len() * n; if text.is_empty() || (self.buf.len() + shift) > self.buf.capacity() { return None; @@ -182,7 +182,7 @@ impl LineBuffer { } /// Move cursor on the left. - pub fn move_left(&mut self, n: usize) -> bool { + pub fn move_left(&mut self, n: RepeatCount) -> bool { match self.prev_pos(n) { Some(pos) => { self.pos = pos; @@ -193,7 +193,7 @@ impl LineBuffer { } /// Move cursor on the right. - pub fn move_right(&mut self, n: usize) -> bool { + pub fn move_right(&mut self, n: RepeatCount) -> bool { match self.next_pos(n) { Some(pos) => { self.pos = pos; @@ -226,7 +226,7 @@ impl LineBuffer { /// Delete the character at the right of the cursor without altering the cursor /// position. Basically this is what happens with the "Delete" keyboard key. /// Return the number of characters deleted. - pub fn delete(&mut self, n: usize) -> Option<String> { + pub fn delete(&mut self, n: RepeatCount) -> Option<String> { match self.next_pos(n) { Some(pos) => { let chars = self.buf.drain(self.pos..pos).collect::<String>(); @@ -238,7 +238,7 @@ impl LineBuffer { /// Delete the character at the left of the cursor. /// Basically that is what happens with the "Backspace" keyboard key. - pub fn backspace(&mut self, n: usize) -> Option<String> { + pub fn backspace(&mut self, n: RepeatCount) -> Option<String> { match self.prev_pos(n) { Some(pos) => { let chars = self.buf.drain(pos..self.pos).collect::<String>(); @@ -292,7 +292,7 @@ impl LineBuffer { } /// Go left until start of word - fn prev_word_pos(&self, pos: usize, word_def: Word, n: usize) -> Option<usize> { + fn prev_word_pos(&self, pos: usize, word_def: Word, n: RepeatCount) -> Option<usize> { if pos == 0 { return None; } @@ -325,7 +325,7 @@ impl LineBuffer { } /// Moves the cursor to the beginning of previous word. - pub fn move_to_prev_word(&mut self, word_def: Word, n: usize) -> bool { + pub fn move_to_prev_word(&mut self, word_def: Word, n: RepeatCount) -> bool { if let Some(pos) = self.prev_word_pos(self.pos, word_def, n) { self.pos = pos; true @@ -336,7 +336,7 @@ impl LineBuffer { /// Delete the previous word, maintaining the cursor at the start of the /// current word. - pub fn delete_prev_word(&mut self, word_def: Word, n: usize) -> Option<String> { + pub fn delete_prev_word(&mut self, word_def: Word, n: RepeatCount) -> Option<String> { if let Some(pos) = self.prev_word_pos(self.pos, word_def, n) { let word = self.buf.drain(pos..self.pos).collect(); self.pos = pos; @@ -346,7 +346,7 @@ impl LineBuffer { } } - fn next_word_pos(&self, pos: usize, at: At, word_def: Word, n: usize) -> Option<usize> { + fn next_word_pos(&self, pos: usize, at: At, word_def: Word, n: RepeatCount) -> Option<usize> { match at { At::End => { match self.next_end_of_word_pos(pos, word_def, n) { @@ -359,7 +359,7 @@ impl LineBuffer { } /// Go right until start of word - fn next_start_of_word_pos(&self, pos: usize, word_def: Word, n: usize) -> Option<usize> { + fn next_start_of_word_pos(&self, pos: usize, word_def: Word, n: RepeatCount) -> Option<usize> { if pos == self.buf.len() { return None; } @@ -391,7 +391,7 @@ impl LineBuffer { /// Go right until end of word /// Returns the position (start, end) of the next word. - fn next_end_of_word_pos(&self, pos: usize, word_def: Word, n: usize) -> Option<(usize, usize)> { + fn next_end_of_word_pos(&self, pos: usize, word_def: Word, n: RepeatCount) -> Option<(usize, usize)> { if pos == self.buf.len() { return None; } @@ -424,7 +424,7 @@ impl LineBuffer { } /// Moves the cursor to the end of next word. - pub fn move_to_next_word(&mut self, at: At, word_def: Word, n: usize) -> bool { + pub fn move_to_next_word(&mut self, at: At, word_def: Word, n: RepeatCount) -> bool { if let Some(pos) = self.next_word_pos(self.pos, at, word_def, n) { self.pos = pos; true @@ -433,7 +433,7 @@ impl LineBuffer { } } - fn search_char_pos(&mut self, cs: &CharSearch, n: usize) -> Option<usize> { + fn search_char_pos(&mut self, cs: &CharSearch, n: RepeatCount) -> Option<usize> { let mut shift = 0; let search_result = match *cs { CharSearch::Backward(c) | @@ -477,7 +477,7 @@ impl LineBuffer { } } - pub fn move_to(&mut self, cs: CharSearch, n: usize) -> bool { + pub fn move_to(&mut self, cs: CharSearch, n: RepeatCount) -> bool { if let Some(pos) = self.search_char_pos(&cs, n) { self.pos = pos; true @@ -487,7 +487,7 @@ impl LineBuffer { } /// Kill from the cursor to the end of the current word, or, if between words, to the end of the next word. - pub fn delete_word(&mut self, at: At, word_def: Word, n: usize) -> Option<String> { + pub fn delete_word(&mut self, at: At, word_def: Word, n: RepeatCount) -> Option<String> { if let Some(pos) = self.next_word_pos(self.pos, at, word_def, n) { let word = self.buf.drain(self.pos..pos).collect(); Some(word) @@ -496,7 +496,7 @@ impl LineBuffer { } } - pub fn delete_to(&mut self, cs: CharSearch, n: usize) -> Option<String> { + pub fn delete_to(&mut self, cs: CharSearch, n: RepeatCount) -> Option<String> { let search_result = match cs { CharSearch::ForwardBefore(c) => self.search_char_pos(&CharSearch::Forward(c), n), _ => self.search_char_pos(&cs, n), -- GitLab