add extend motions, color cursor in select mode
This commit is contained in:
@@ -18,6 +18,11 @@ pub enum Action {
|
|||||||
MoveByteLeft,
|
MoveByteLeft,
|
||||||
MoveByteRight,
|
MoveByteRight,
|
||||||
|
|
||||||
|
ExtendByteUp,
|
||||||
|
ExtendByteDown,
|
||||||
|
ExtendByteLeft,
|
||||||
|
ExtendByteRight,
|
||||||
|
|
||||||
GotoLineStart,
|
GotoLineStart,
|
||||||
GotoLineEnd,
|
GotoLineEnd,
|
||||||
GotoFileStart,
|
GotoFileStart,
|
||||||
@@ -36,6 +41,10 @@ pub enum Action {
|
|||||||
MoveNextWordEnd,
|
MoveNextWordEnd,
|
||||||
MovePreviousWordStart,
|
MovePreviousWordStart,
|
||||||
|
|
||||||
|
ExtendNextWordStart,
|
||||||
|
ExtendNextWordEnd,
|
||||||
|
ExtendPreviousWordStart,
|
||||||
|
|
||||||
CollapseSelection,
|
CollapseSelection,
|
||||||
|
|
||||||
ExtendLineBelow,
|
ExtendLineBelow,
|
||||||
@@ -61,6 +70,11 @@ impl App {
|
|||||||
Action::MoveByteLeft => self.move_byte_left(),
|
Action::MoveByteLeft => self.move_byte_left(),
|
||||||
Action::MoveByteRight => self.move_byte_right(),
|
Action::MoveByteRight => self.move_byte_right(),
|
||||||
|
|
||||||
|
Action::ExtendByteUp => self.extend_byte_up(),
|
||||||
|
Action::ExtendByteDown => self.extend_byte_down(),
|
||||||
|
Action::ExtendByteLeft => self.extend_byte_left(),
|
||||||
|
Action::ExtendByteRight => self.extend_byte_right(),
|
||||||
|
|
||||||
Action::GotoLineStart => self.goto_line_start(),
|
Action::GotoLineStart => self.goto_line_start(),
|
||||||
Action::GotoLineEnd => self.goto_line_end(),
|
Action::GotoLineEnd => self.goto_line_end(),
|
||||||
Action::GotoFileStart => self.goto_file_start(),
|
Action::GotoFileStart => self.goto_file_start(),
|
||||||
@@ -79,6 +93,10 @@ impl App {
|
|||||||
Action::MoveNextWordEnd => self.move_next_word_end(),
|
Action::MoveNextWordEnd => self.move_next_word_end(),
|
||||||
Action::MovePreviousWordStart => self.move_previous_word_start(),
|
Action::MovePreviousWordStart => self.move_previous_word_start(),
|
||||||
|
|
||||||
|
Action::ExtendNextWordStart => self.extend_next_word_start(),
|
||||||
|
Action::ExtendNextWordEnd => self.extend_next_word_end(),
|
||||||
|
Action::ExtendPreviousWordStart => self.extend_previous_word_start(),
|
||||||
|
|
||||||
Action::CollapseSelection => self.collapse_selection(),
|
Action::CollapseSelection => self.collapse_selection(),
|
||||||
|
|
||||||
Action::ExtendLineBelow => self.extend_line_below(),
|
Action::ExtendLineBelow => self.extend_line_below(),
|
||||||
@@ -148,6 +166,34 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn extend_byte_up(&mut self) {
|
||||||
|
if self.cursor.head >= BYTES_PER_LINE {
|
||||||
|
self.cursor.head -= BYTES_PER_LINE;
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn extend_byte_down(&mut self) {
|
||||||
|
if self.contents.len() - 1 - self.cursor.head >= BYTES_PER_LINE {
|
||||||
|
self.cursor.head += BYTES_PER_LINE;
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn extend_byte_left(&mut self) {
|
||||||
|
if self.cursor.head >= 1 {
|
||||||
|
self.cursor.head -= 1;
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn extend_byte_right(&mut self) {
|
||||||
|
if self.contents.len() - 1 - self.cursor.head >= 1 {
|
||||||
|
self.cursor.head += 1;
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const fn goto_line_start(&mut self) {
|
const fn goto_line_start(&mut self) {
|
||||||
self.cursor.head -= self.cursor.head % BYTES_PER_LINE;
|
self.cursor.head -= self.cursor.head % BYTES_PER_LINE;
|
||||||
self.cursor.collapse();
|
self.cursor.collapse();
|
||||||
@@ -240,6 +286,21 @@ impl App {
|
|||||||
self.clamp_screen_to_cursor();
|
self.clamp_screen_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extend_next_word_start(&mut self) {
|
||||||
|
self.cursor.extend_to_next_word(self.contents.len() - 1);
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extend_next_word_end(&mut self) {
|
||||||
|
self.cursor.extend_to_next_end(self.contents.len() - 1);
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn extend_previous_word_start(&mut self) {
|
||||||
|
self.cursor.extend_to_previous_beginning();
|
||||||
|
self.clamp_screen_to_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
const fn collapse_selection(&mut self) {
|
const fn collapse_selection(&mut self) {
|
||||||
self.cursor.collapse();
|
self.cursor.collapse();
|
||||||
}
|
}
|
||||||
@@ -285,6 +346,10 @@ impl App {
|
|||||||
data: self.contents[self.cursor.range()].into()
|
data: self.contents[self.cursor.range()].into()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if self.mode == Mode::Select {
|
||||||
|
self.mode = Mode::Normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -78,7 +78,7 @@ mod hex {
|
|||||||
use itertools::{Itertools, repeat_n};
|
use itertools::{Itertools, repeat_n};
|
||||||
use ratatui::{style::{Color, Style, Stylize}, text::Span};
|
use ratatui::{style::{Color, Style, Stylize}, text::Span};
|
||||||
|
|
||||||
use crate::{BYTES_PER_CHUNK, BYTES_PER_LINE, CHUNKS_PER_LINE, app::App, cardinality::HasCardinality, cursor::InCursor, empty_span::empty_span, custom_greys::CustomGreys};
|
use crate::{BYTES_PER_CHUNK, BYTES_PER_LINE, CHUNKS_PER_LINE, app::{App, Mode}, cardinality::HasCardinality, cursor::InCursor, custom_greys::CustomGreys, empty_span::empty_span};
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn render_chunks(
|
pub fn render_chunks(
|
||||||
@@ -194,8 +194,13 @@ mod hex {
|
|||||||
|
|
||||||
let span = SPAN_FOR_BYTE[byte as usize].clone();
|
let span = SPAN_FOR_BYTE[byte as usize].clone();
|
||||||
|
|
||||||
|
let head_color = match self.mode {
|
||||||
|
Mode::Select => Color::Yellow,
|
||||||
|
_ => Color::Gray
|
||||||
|
};
|
||||||
|
|
||||||
match self.cursor.contains(address) {
|
match self.cursor.contains(address) {
|
||||||
Some(InCursor::Head) => span.bg(Color::Gray),
|
Some(InCursor::Head) => span.bg(head_color),
|
||||||
Some(InCursor::Rest) => span.bg(Color::select_grey()),
|
Some(InCursor::Rest) => span.bg(Color::select_grey()),
|
||||||
None => span,
|
None => span,
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -151,10 +151,10 @@ impl Default for Config {
|
|||||||
("z".try_into().unwrap(), Action::ZPartial),
|
("z".try_into().unwrap(), Action::ZPartial),
|
||||||
("r".try_into().unwrap(), Action::RPartial),
|
("r".try_into().unwrap(), Action::RPartial),
|
||||||
|
|
||||||
// ("i".try_into().unwrap(), Action::ExtendByteUp),
|
("i".try_into().unwrap(), Action::ExtendByteUp),
|
||||||
// ("k".try_into().unwrap(), Action::ExtendByteDown),
|
("k".try_into().unwrap(), Action::ExtendByteDown),
|
||||||
// ("j".try_into().unwrap(), Action::ExtendByteLeft),
|
("j".try_into().unwrap(), Action::ExtendByteLeft),
|
||||||
// ("l".try_into().unwrap(), Action::ExtendByteRight),
|
("l".try_into().unwrap(), Action::ExtendByteRight),
|
||||||
|
|
||||||
("C-e".try_into().unwrap(), Action::ScrollDown),
|
("C-e".try_into().unwrap(), Action::ScrollDown),
|
||||||
("C-y".try_into().unwrap(), Action::ScrollUp),
|
("C-y".try_into().unwrap(), Action::ScrollUp),
|
||||||
@@ -165,9 +165,9 @@ impl Default for Config {
|
|||||||
("C-f".try_into().unwrap(), Action::PageDown),
|
("C-f".try_into().unwrap(), Action::PageDown),
|
||||||
("C-b".try_into().unwrap(), Action::PageUp),
|
("C-b".try_into().unwrap(), Action::PageUp),
|
||||||
|
|
||||||
// ("w".try_into().unwrap(), Action::ExtendNextWordStart),
|
("w".try_into().unwrap(), Action::ExtendNextWordStart),
|
||||||
// ("e".try_into().unwrap(), Action::ExtendNextWordEnd),
|
("e".try_into().unwrap(), Action::ExtendNextWordEnd),
|
||||||
// ("b".try_into().unwrap(), Action::ExtendPreviousWordStart),
|
("b".try_into().unwrap(), Action::ExtendPreviousWordStart),
|
||||||
|
|
||||||
(";".try_into().unwrap(), Action::CollapseSelection),
|
(";".try_into().unwrap(), Action::CollapseSelection),
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,36 @@ impl Cursor {
|
|||||||
self.head -= self.head % 4;
|
self.head -= self.head % 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn extend_to_next_word(&mut self, max: usize) {
|
||||||
|
if self.head == max { return }
|
||||||
|
|
||||||
|
if self.head.is_multiple_of(4) { // at the beginning of a word
|
||||||
|
self.head = (self.head + 4).min(max);
|
||||||
|
} else {
|
||||||
|
self.head = self.head.next_multiple_of(4).min(max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extend_to_next_end(&mut self, max: usize) {
|
||||||
|
if self.head == max { return }
|
||||||
|
|
||||||
|
if self.head % 4 == 3 { // at the end of a word
|
||||||
|
self.head = (self.head + 4).min(max);
|
||||||
|
} else {
|
||||||
|
self.head = ((self.head + 1).next_multiple_of(4) - 1).min(max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn extend_to_previous_beginning(&mut self) {
|
||||||
|
if self.head == 0 { return }
|
||||||
|
|
||||||
|
if self.head.is_multiple_of(4) { // at the beginning of a word
|
||||||
|
self.head -= 4;
|
||||||
|
} else {
|
||||||
|
self.head -= self.head % 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|||||||
Reference in New Issue
Block a user