Skip to content

Commit

Permalink
Scrolling features
Browse files Browse the repository at this point in the history
- Caret end of line, press right moves to start of next line
- Caret at start of line, press left moves to start of prev line
- Add page up, down support
- Update tests

Fix #23
  • Loading branch information
nazmulidris committed Oct 3, 2022
1 parent dcd552f commit e81e39c
Show file tree
Hide file tree
Showing 7 changed files with 726 additions and 140 deletions.
24 changes: 16 additions & 8 deletions TODO.todo
Expand Up @@ -38,14 +38,22 @@ editor engine core (https://github.com/r3bl-org/r3bl_rs_utils/issues/23):
✔ up, down @done(22-09-28 11:07)
✔ resize (caret & scroll fix - `validate_caret_in_viewport_activate_scroll_if_needed` in `render`) @done(22-09-28 13:12)
✔ left, right @done(22-10-01 16:15)
☐ move caret left / right -> move up / down as well (`validate_caret_position()`)
☐ left at start of line, move up to end of previous line
☐ right at end of line, move down to start of next line
☐ down at start of last line, move to end of line
☐ up at end of first line, move to 0,0
☐ other key inputs
☐ page up/down
☐ home/end
✔ move caret left, right -> move up, down as well @done(22-10-03 08:56)
✔ right at end of line, move down to start of next line @done(22-10-02 12:16)
✔ left at start of line, move up to end of previous line @done(22-10-02 12:16)
✔ down on last line, move to end of line @done(22-10-02 15:22)
✔ up at first line, move to 0,0 @done(22-10-03 08:56)
✔ other key inputs @done(22-10-03 11:22)
✔ home/end @done(22-10-03 09:24)
✔ page up/down @done(22-10-03 11:22)
✔ tests for page up, down @done(22-10-03 12:08)
✔ add docs for viewport & scrolling in editor_ops.rs @done(22-10-03 12:16)
✔ tests for scrolling @done(22-10-03 15:44)

create reorg (https://github.com/r3bl-org/r3bl_rs_utils/issues/42):
☐ Break up r3bl_rs_utils into smaller crates
☐ r3bl_redux
☐ r3bl_tui (examples moved here)

editor engine extras (core):
☐ syntax highlighting support
Expand Down
91 changes: 88 additions & 3 deletions src/tui/ed/editor_buffer.rs
Expand Up @@ -26,9 +26,82 @@ use crate::*;
// ╭┄┄┄┄┄┄┄┄┄┄┄┄┄┄╮
// │ EditorBuffer │
// ╯ ╰┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
/// Stores the data for a single editor buffer. This struct is stored in the [Store]. And it is
/// paired w/ [EditorRenderEngine] at runtime; which provides all the operations that can be
/// performed on this.
/// Stores the data for a single editor buffer.
///
/// 1. This struct is stored in the [Store].
/// 2. And it is paired w/ [EditorRenderEngine] at runtime; which is responsible for rendering it to
/// TUI, and handling user input.
///
/// # Modifying the buffer
///
/// You have to supply an [EditorBufferCommand] to the [EditorBuffer] to modify it via:
/// 1. [apply_editor_event](EditorBuffer::apply_editor_event)
/// 2. [apply_editor_events](EditorBuffer::apply_editor_events)
///
/// In order for the commands to be executed, the following functions are used (in
/// `editor_buffer_command_impl.rs`):
/// - [locate_caret]
/// - [move_caret]
/// - [get_content]
/// - [mut_content]
/// - [validate]
/// - [scroll]
///
/// These functions take any one of the following args:
/// 1. [EditorArgsMut]
/// 2. [EditorArgs]
/// 3. [EditorBuffer] and [EditorRenderEngine]
///
/// # Accessing and mutating the fields (w/ validation)
///
/// All the fields in this struct are private. In order to access them you have to use the accessor
/// associated functions. To mutate them, you have to use the [get_mut](EditorBuffer::get_mut)
/// method, which returns a tuple w/ mutable references to the fields. This rather strange design
/// allows for all mutations to be tracked easily and allows for validation operations to be applied
/// post mutation (by [validate::apply_change]).
///
/// # Different kinds of caret positions
///
/// There are two variants for the caret position value:
/// 1. [CaretKind::Raw] - this is the position of the caret (unadjusted for scroll_offset) and this
/// represents the position of the caret in the viewport.
/// 2. [CaretKind::ScrollAdjusted] - this is the position of the caret (adjusted for scroll_offset)
/// and represents the position of the caret in the buffer (not the viewport).
///
/// # Vertical scrolling and viewport
///
/// ```text
/// +0--------------------+
/// 0 |
/// | above | <- caret_row_adj
/// | |
/// +--- scroll_offset ---+
/// -> | ↑ | ↑
/// | | | |
/// caret.row | | within vp | vp height
/// | | | |
/// -> | ↓ | ↓
/// +--- scroll_offset ---+
/// | + vp height |
/// | |
/// | below | <- caret_row_adj
/// | |
/// +---------------------+
/// ```
///
/// # Horizontal scrolling and viewport
///
/// ```text
/// <- vp width ->
/// +0--------+----------------+---------->
/// 0 | |
/// | left of |<- within vp ->| right of
/// | | |
/// +---------+----------------+---------->
/// scroll_offset scroll_offset
/// + vp width
/// ```

#[derive(Clone, PartialEq, Serialize, Deserialize, GetSize)]
pub struct EditorBuffer {
/// A list of lines representing the document being edited.
Expand Down Expand Up @@ -181,6 +254,18 @@ impl EditorBuffer {
// Check to see whether scroll is valid.
scroll::validate_scroll(EditorArgsMut { buffer, engine });
}
EditorBufferCommand::Home => {
move_caret::to_start_of_line(buffer, engine);
}
EditorBufferCommand::End => {
move_caret::to_end_of_line(buffer, engine);
}
EditorBufferCommand::PageDown => {
move_caret::page_down(buffer, engine);
}
EditorBufferCommand::PageUp => {
move_caret::page_up(buffer, engine);
}
};
}

Expand Down
28 changes: 28 additions & 0 deletions src/tui/ed/editor_buffer_command.rs
Expand Up @@ -32,6 +32,10 @@ pub enum EditorBufferCommand {
InsertNewLine,
Delete,
Backspace,
Home,
End,
PageDown,
PageUp,
MoveCaret(CaretDirection),
Resize(Size),
}
Expand All @@ -49,28 +53,52 @@ impl TryFrom<&InputEvent> for EditorBufferCommand {

fn try_from(input_event: &InputEvent) -> Result<Self, Self::Error> {
match input_event {
InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::PageDown),
}) => Ok(EditorBufferCommand::PageDown),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::PageUp),
}) => Ok(EditorBufferCommand::PageUp),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Home),
}) => Ok(EditorBufferCommand::Home),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::End),
}) => Ok(EditorBufferCommand::End),

InputEvent::Resize(size) => Ok(EditorBufferCommand::Resize(*size)),

InputEvent::Keyboard(Keypress::Plain {
key: Key::Character(character),
}) => Ok(Self::InsertChar(*character)),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Enter),
}) => Ok(Self::InsertNewLine),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Delete),
}) => Ok(Self::Delete),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Backspace),
}) => Ok(Self::Backspace),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Up),
}) => Ok(Self::MoveCaret(CaretDirection::Up)),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Down),
}) => Ok(Self::MoveCaret(CaretDirection::Down)),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Left),
}) => Ok(Self::MoveCaret(CaretDirection::Left)),

InputEvent::Keyboard(Keypress::Plain {
key: Key::SpecialKey(SpecialKey::Right),
}) => Ok(Self::MoveCaret(CaretDirection::Right)),
Expand Down

0 comments on commit e81e39c

Please sign in to comment.