Skip to content

Commit cf92421

Browse files
committed
Do not remove change listeners but disable them
1 parent e4f64d9 commit cf92421

File tree

5 files changed

+88
-54
lines changed

5 files changed

+88
-54
lines changed

src/completion.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ pub fn escape(input: String, esc_char: Option<char>, break_chars: &BTreeSet<char
130130
return input;
131131
}
132132
let esc_char = esc_char.unwrap();
133-
let n = input.chars().filter(|c| break_chars.contains(c)).count();
133+
let n = input.chars()
134+
.filter(|c| break_chars.contains(c))
135+
.count();
134136
if n == 0 {
135137
return input;
136138
}

src/kill_ring.rs

+12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub struct KillRing {
2020
index: usize,
2121
// whether or not the last command was a kill or a yank
2222
last_action: Action,
23+
killing: bool,
2324
}
2425

2526
impl KillRing {
@@ -29,9 +30,17 @@ impl KillRing {
2930
slots: Vec::with_capacity(size),
3031
index: 0,
3132
last_action: Action::Other,
33+
killing: false,
3234
}
3335
}
3436

37+
pub fn start_killing(&mut self) {
38+
self.killing = true;
39+
}
40+
pub fn stop_killing(&mut self) {
41+
self.killing = false;
42+
}
43+
3544
/// Reset `last_action` state.
3645
pub fn reset(&mut self) {
3746
self.last_action = Action::Other;
@@ -107,6 +116,9 @@ impl ChangeListener for KillRing {
107116
fn insert_char(&mut self, _: usize, _: char) {}
108117
fn insert_str(&mut self, _: usize, _: &str) {}
109118
fn delete(&mut self, _: usize, string: &str, dir: Direction) {
119+
if !self.killing {
120+
return;
121+
}
110122
let mode = match dir {
111123
Direction::Forward => Mode::Append,
112124
Direction::Backward => Mode::Prepend,

src/lib.rs

+20-20
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ impl<'out, 'prompt> State<'out, 'prompt> {
214214
let mut info = try!(self.term.get_console_screen_buffer_info());
215215
info.dwCursorPosition.X = 0;
216216
info.dwCursorPosition.Y -= self.cursor.row as i16;
217-
try!(self.term.set_console_cursor_position(info.dwCursorPosition));
217+
try!(self.term
218+
.set_console_cursor_position(info.dwCursorPosition));
218219
let mut _count = 0;
219220
try!(self.term
220221
.fill_console_output_character((info.dwSize.X * (self.old_rows as i16 + 1)) as u32,
@@ -230,7 +231,8 @@ impl<'out, 'prompt> State<'out, 'prompt> {
230231
let mut info = try!(self.term.get_console_screen_buffer_info());
231232
info.dwCursorPosition.X = cursor.col as i16;
232233
info.dwCursorPosition.Y -= (end_pos.row - cursor.row) as i16;
233-
try!(self.term.set_console_cursor_position(info.dwCursorPosition));
234+
try!(self.term
235+
.set_console_cursor_position(info.dwCursorPosition));
234236

235237
self.cursor = cursor;
236238
self.old_rows = end_pos.row;
@@ -838,9 +840,6 @@ fn reverse_incremental_search<R: RawReader>(rdr: &mut R,
838840
Ok(Some(cmd))
839841
}
840842

841-
static KILL_RING_NAME: &'static str = "kill_ring";
842-
static UNDOS_NAME: &'static str = "undos";
843-
844843
/// Handles reading and editting the readline buffer.
845844
/// It will also handle special inputs in an appropriate fashion
846845
/// (e.g., C-c will exit readline)
@@ -860,7 +859,10 @@ fn readline_edit<C: Completer>(prompt: &str,
860859
prompt,
861860
editor.history.len(),
862861
editor.custom_bindings.clone());
863-
s.line.bind(UNDOS_NAME, s.changes.clone());
862+
863+
s.line.bind(s.changes.clone());
864+
s.line.bind(editor.kill_ring.clone());
865+
864866
try!(s.refresh_line());
865867

866868
let mut rdr = try!(s.term.create_reader(&editor.config));
@@ -945,15 +947,15 @@ fn readline_edit<C: Completer>(prompt: &str,
945947
}
946948
Cmd::Kill(Movement::EndOfLine) => {
947949
// Kill the text from point to the end of the line.
948-
s.line.bind(KILL_RING_NAME, editor.kill_ring.clone());
950+
editor.kill_ring.borrow_mut().start_killing();
949951
try!(edit_kill_line(&mut s));
950-
s.line.unbind(KILL_RING_NAME);
952+
editor.kill_ring.borrow_mut().stop_killing();
951953
}
952954
Cmd::Kill(Movement::WholeLine) => {
953955
try!(edit_move_home(&mut s));
954-
s.line.bind(KILL_RING_NAME, editor.kill_ring.clone());
956+
editor.kill_ring.borrow_mut().start_killing();
955957
try!(edit_kill_line(&mut s));
956-
s.line.unbind(KILL_RING_NAME);
958+
editor.kill_ring.borrow_mut().stop_killing();
957959
}
958960
Cmd::ClearScreen => {
959961
// Clear the screen leaving the current line at the top of the screen.
@@ -974,9 +976,9 @@ fn readline_edit<C: Completer>(prompt: &str,
974976
}
975977
Cmd::Kill(Movement::BeginningOfLine) => {
976978
// Kill backward from point to the beginning of the line.
977-
s.line.bind(KILL_RING_NAME, editor.kill_ring.clone());
979+
editor.kill_ring.borrow_mut().start_killing();
978980
try!(edit_discard_line(&mut s));
979-
s.line.unbind(KILL_RING_NAME);
981+
editor.kill_ring.borrow_mut().stop_killing();
980982
}
981983
#[cfg(unix)]
982984
Cmd::QuotedInsert => {
@@ -1003,9 +1005,9 @@ fn readline_edit<C: Completer>(prompt: &str,
10031005
}
10041006
Cmd::Kill(Movement::BackwardWord(n, word_def)) => {
10051007
// kill one word backward (until start of word)
1006-
s.line.bind(KILL_RING_NAME, editor.kill_ring.clone());
1008+
editor.kill_ring.borrow_mut().start_killing();
10071009
try!(edit_delete_prev_word(&mut s, word_def, n));
1008-
s.line.unbind(KILL_RING_NAME);
1010+
editor.kill_ring.borrow_mut().stop_killing();
10091011
}
10101012
Cmd::BeginningOfHistory => {
10111013
// move to first entry in history
@@ -1025,9 +1027,9 @@ fn readline_edit<C: Completer>(prompt: &str,
10251027
}
10261028
Cmd::Kill(Movement::ForwardWord(n, at, word_def)) => {
10271029
// kill one word forward (until start/end of word)
1028-
s.line.bind(KILL_RING_NAME, editor.kill_ring.clone());
1030+
editor.kill_ring.borrow_mut().start_killing();
10291031
try!(edit_delete_word(&mut s, at, word_def, n));
1030-
s.line.unbind(KILL_RING_NAME);
1032+
editor.kill_ring.borrow_mut().stop_killing();
10311033
}
10321034
Cmd::Move(Movement::ForwardWord(n, at, word_def)) => {
10331035
// move forwards one word
@@ -1053,16 +1055,14 @@ fn readline_edit<C: Completer>(prompt: &str,
10531055
}
10541056
Cmd::Move(Movement::ViCharSearch(n, cs)) => try!(edit_move_to(&mut s, cs, n)),
10551057
Cmd::Kill(Movement::ViCharSearch(n, cs)) => {
1056-
s.line.bind(KILL_RING_NAME, editor.kill_ring.clone());
1058+
editor.kill_ring.borrow_mut().start_killing();
10571059
try!(edit_delete_to(&mut s, cs, n));
1058-
s.line.unbind(KILL_RING_NAME);
1060+
editor.kill_ring.borrow_mut().stop_killing();
10591061
}
10601062
Cmd::Undo => {
1061-
s.line.unbind(UNDOS_NAME);
10621063
if s.changes.borrow_mut().undo(&mut s.line) {
10631064
try!(s.refresh_line());
10641065
}
1065-
s.line.bind(UNDOS_NAME, s.changes.clone());
10661066
}
10671067
Cmd::Interrupt => {
10681068
return Err(error::ReadlineError::Interrupted);

src/line_buffer.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Line buffer with current cursor position
22
use std::cell::RefCell;
3-
use std::collections::HashMap;
43
use std::fmt;
54
use std::iter;
65
use std::ops::{Deref, Range};
@@ -40,7 +39,7 @@ pub trait ChangeListener {
4039
pub struct LineBuffer {
4140
buf: String, // Edited line buffer
4241
pos: usize, // Current cursor position (byte position)
43-
cl: HashMap<&'static str, Rc<RefCell<ChangeListener>>>,
42+
cl: Vec<Rc<RefCell<ChangeListener>>>,
4443
}
4544

4645
impl fmt::Debug for LineBuffer {
@@ -58,7 +57,7 @@ impl LineBuffer {
5857
LineBuffer {
5958
buf: String::with_capacity(capacity),
6059
pos: 0,
61-
cl: HashMap::new(),
60+
cl: Vec::new(),
6261
}
6362
}
6463

@@ -68,16 +67,13 @@ impl LineBuffer {
6867
assert!(lb.insert_str(0, line));
6968
lb.set_pos(pos);
7069
if cl.is_some() {
71-
lb.bind("test", cl.unwrap());
70+
lb.bind(cl.unwrap());
7271
}
7372
lb
7473
}
7574

76-
pub fn bind(&mut self, key: &'static str, cl: Rc<RefCell<ChangeListener>>) {
77-
self.cl.insert(key, cl);
78-
}
79-
pub fn unbind(&mut self, key: &'static str) {
80-
self.cl.remove(key);
75+
pub fn bind(&mut self, cl: Rc<RefCell<ChangeListener>>) {
76+
self.cl.push(cl);
8177
}
8278

8379
/// Extracts a string slice containing the entire buffer.
@@ -179,7 +175,7 @@ impl LineBuffer {
179175
let push = self.pos == self.buf.len();
180176
if n == 1 {
181177
self.buf.insert(self.pos, ch);
182-
for cl in self.cl.values() {
178+
for cl in &self.cl {
183179
cl.borrow_mut().insert_char(self.pos, ch);
184180
}
185181
} else {
@@ -269,7 +265,8 @@ impl LineBuffer {
269265
match self.next_pos(n) {
270266
Some(pos) => {
271267
let start = self.pos;
272-
let chars = self.drain(start..pos, Direction::Forward).collect::<String>();
268+
let chars = self.drain(start..pos, Direction::Forward)
269+
.collect::<String>();
273270
Some(chars)
274271
}
275272
None => None,
@@ -573,7 +570,8 @@ impl LineBuffer {
573570
if start == end {
574571
return false;
575572
}
576-
let word = self.drain(start..end, Direction::default()).collect::<String>();
573+
let word = self.drain(start..end, Direction::default())
574+
.collect::<String>();
577575
let result = match a {
578576
WordAction::CAPITALIZE => {
579577
let ch = (&word).graphemes(true).next().unwrap();
@@ -608,7 +606,8 @@ impl LineBuffer {
608606

609607
let w1 = self.buf[w1_beg..w1_end].to_owned();
610608

611-
let w2 = self.drain(w2_beg..w2_end, Direction::default()).collect::<String>();
609+
let w2 = self.drain(w2_beg..w2_end, Direction::default())
610+
.collect::<String>();
612611
self.insert_str(w2_beg, &w1);
613612

614613
self.drain(w1_beg..w1_end, Direction::default());
@@ -628,7 +627,7 @@ impl LineBuffer {
628627
}
629628

630629
pub fn insert_str(&mut self, idx: usize, s: &str) -> bool {
631-
for cl in self.cl.values() {
630+
for cl in &self.cl {
632631
cl.borrow_mut().insert_str(idx, s);
633632
}
634633
if idx == self.buf.len() {
@@ -646,8 +645,9 @@ impl LineBuffer {
646645
}
647646

648647
fn drain(&mut self, range: Range<usize>, dir: Direction) -> Drain {
649-
for cl in self.cl.values() {
650-
cl.borrow_mut().delete(range.start, &self.buf[range.start..range.end], dir);
648+
for cl in &self.cl {
649+
cl.borrow_mut()
650+
.delete(range.start, &self.buf[range.start..range.end], dir);
651651
}
652652
self.buf.drain(range)
653653
}

0 commit comments

Comments
 (0)