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