Skip to content

Commit

Permalink
Use "cursor" terminology instead of "selection" in EditableText
Browse files Browse the repository at this point in the history
Our usage of the word "selection" to refer to what effectively amounts
to a cursor is a bit confusing, as a selection in an input context
typically refers to something that is being replaced by input or
otherwise worked with and that can stretch multiple characters. In our
case, however, it is merely an index where to insert/remove the next
character.
With this change we rename "selection" to "cursor" in an attempt to
remove ambiguity.
  • Loading branch information
d-e-s-o committed Apr 12, 2024
1 parent 8504825 commit 5f41095
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 46 deletions.
56 changes: 28 additions & 28 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl Deref for Text {
}


/// A text with an associated selection.
/// A text with an associated cursor.
///
/// Please note that at the moment, selections take into account
/// character width. That is arguably more of a property pertaining the
Expand All @@ -150,8 +150,8 @@ impl Deref for Text {
pub struct EditableText {
/// The text.
text: Text,
/// The "character" index of the selection.
selection: usize,
/// The "character" index of the cursor.
cursor: usize,
}

#[allow(unused)]
Expand All @@ -165,69 +165,69 @@ impl EditableText {
Self {
text: Text::from_string(text),
// An index of zero is always valid, even if `text` was empty.
selection: 0,
cursor: 0,
}
}

/// Select the first character.
pub fn select_start(&mut self) {
self.selection = 0;
pub fn move_start(&mut self) {
self.cursor = 0;
}

/// Move the selection towards the end of the text, i.e., past the
/// Move the cursor to the end of the text, i.e., past the
/// last character.
pub fn select_end(&mut self) {
self.selection = self.len();
pub fn move_end(&mut self) {
self.cursor = self.len();
}

/// Select the next character, if any.
pub fn select_next(&mut self) {
self.selection = min(self.selection + 1, self.len());
pub fn move_next(&mut self) {
self.cursor = min(self.cursor + 1, self.len());
}

/// Select the previous character, if any.
pub fn select_prev(&mut self) {
self.selection = min(self.selection.saturating_sub(1), self.len());
pub fn move_prev(&mut self) {
self.cursor = min(self.cursor.saturating_sub(1), self.len());
}

/// Select a character based on its byte index.
#[cfg(feature = "readline")]
pub fn select_byte_index(&mut self, byte_index: usize) {
self.selection = char_index(&self.text, byte_index);
pub fn set_cursor_byte_index(&mut self, byte_index: usize) {
self.cursor = char_index(&self.text, byte_index);
}

/// Insert a character into the text at the current selection.
/// Insert a character into the text at the current cursor position.
pub fn insert_char(&mut self, c: char) {
let byte_index = byte_index(&self.text, self.selection);
let byte_index = byte_index(&self.text, self.cursor);
let () = self.text.text.insert(byte_index, c);
self.selection = min(self.selection + 1, self.len());
self.cursor = min(self.cursor + 1, self.len());
}

/// Remove the currently selected character from the text.
pub fn remove_char(&mut self) {
if self.selection >= self.len() {
if self.cursor >= self.len() {
return
}

let byte_index = byte_index(&self.text, self.selection);
let byte_index = byte_index(&self.text, self.cursor);
let _removed = self.text.text.remove(byte_index);
self.selection = min(self.selection, self.len());
self.cursor = min(self.cursor, self.len());
}

/// Retrieve the current selection index.
/// Retrieve the current cursor index.
#[inline]
pub fn selection(&self) -> usize {
self.selection
pub fn cursor(&self) -> usize {
self.cursor
}

/// Retrieve the current selection expressed as a byte index.
/// Retrieve the current cursor position expressed as a byte index.
#[inline]
#[cfg(feature = "readline")]
pub fn selection_byte_index(&self) -> usize {
byte_index(&self.text, self.selection)
pub fn cursor_byte_index(&self) -> usize {
byte_index(&self.text, self.cursor)
}

/// Convert the object into a `String`, discarding selection
/// Convert the object into a `String`, discarding any cursor
/// information.
#[inline]
pub fn into_string(self) -> String {
Expand Down
28 changes: 14 additions & 14 deletions src/ui/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl InputText {
readline: {
let mut rl = Readline::new();
let cstr = CString::new(text.as_str()).unwrap();
let cursor = text.selection_byte_index();
let cursor = text.cursor_byte_index();
let clear_undo = true;
let () = rl.reset(cstr, cursor, clear_undo);
rl
Expand All @@ -75,49 +75,49 @@ impl InputText {
InputResult::Updated
},
Key::Backspace => {
if self.text.selection() > 0 {
let () = self.text.select_prev();
if self.text.cursor() > 0 {
let () = self.text.move_prev();
let () = self.text.remove_char();
InputResult::Updated
} else {
InputResult::Unchanged
}
},
Key::Delete => {
if self.text.selection() < self.text.len() {
if self.text.cursor() < self.text.len() {
let () = self.text.remove_char();
InputResult::Updated
} else {
InputResult::Unchanged
}
},
Key::Left => {
if self.text.selection() > 0 {
let () = self.text.select_prev();
if self.text.cursor() > 0 {
let () = self.text.move_prev();
InputResult::Updated
} else {
InputResult::Unchanged
}
},
Key::Right => {
if self.text.selection() < self.text.len() {
let () = self.text.select_next();
if self.text.cursor() < self.text.len() {
let () = self.text.move_next();
InputResult::Updated
} else {
InputResult::Unchanged
}
},
Key::Home => {
if self.text.selection() != 0 {
let () = self.text.select_start();
if self.text.cursor() != 0 {
let () = self.text.move_start();
InputResult::Updated
} else {
InputResult::Unchanged
}
},
Key::End => {
if self.text.selection() != self.text.len() {
let () = self.text.select_end();
if self.text.cursor() != self.text.len() {
let () = self.text.move_end();
InputResult::Updated
} else {
InputResult::Unchanged
Expand All @@ -142,7 +142,7 @@ impl InputText {
// to the left by one). If nothing changed, then we actually
// cancel the text input. That is not the nicest logic, but
// the only way we have found that accomplishes what we want.
if key == Key::Esc && idx == self.text.selection_byte_index() {
if key == Key::Esc && idx == self.text.cursor_byte_index() {
// TODO: We have a problem here. What may end up happening
// is that we disrupt libreadline's workflow by
// effectively canceling what it was doing. If, for
Expand All @@ -159,7 +159,7 @@ impl InputText {
InputResult::Canceled
} else {
self.text = EditableText::from_string(s.to_string_lossy());
let () = self.text.select_byte_index(idx);
let () = self.text.set_cursor_byte_index(idx);
InputResult::Updated
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/ui/task_list_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ impl Handleable<Event, Message> for TaskListBox {
data.state = Some(State::Edit { task, edited });

let mut text = EditableText::from_string(string);
let () = text.select_end();
let () = text.move_end();

let message = Message::SetInOut(InOut::Input(InputText::new(text)));
cap.send(self.in_out, message).await.into_event()
Expand Down
6 changes: 3 additions & 3 deletions src/ui/term_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,16 +550,16 @@ where
// Calculate the number of displayable characters we have
// available after the "prefix".
let limit = bbox.w.saturating_sub(x) as usize;
let idx = text.selection();
let offset = sanitize_offset(data.offset, idx, limit);
let cursor = text.cursor();
let offset = sanitize_offset(data.offset, cursor, limit);
let string = text.substr(offset..);

data.offset = offset;

let () = self.writer.write(x, bbox.h - 1, fg, bg, string)?;
let () = self
.writer
.goto(x + idx as u16 - offset as u16, bbox.h - 1)?;
.goto(x + cursor as u16 - offset as u16, bbox.h - 1)?;
let () = self.writer.show()?;
} else {
let () = self.writer.write(x, bbox.h - 1, fg, bg, string)?;
Expand Down

0 comments on commit 5f41095

Please sign in to comment.