From c503d32b204f09b23d8ad94b891cc451f0dded84 Mon Sep 17 00:00:00 2001 From: alice pellerin Date: Wed, 18 Mar 2026 03:19:17 -0500 Subject: [PATCH] x/X --- src/action.rs | 42 +++++++++++++++++++++++++++++++++++++++++- src/config.rs | 6 ++++++ src/main.rs | 1 - 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/action.rs b/src/action.rs index 2189375..a024424 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,4 +1,4 @@ -use std::cmp::min; +use std::{cmp::min, mem::swap}; use crate::{BYTES_PER_LINE, app::{App, Mode, PartialAction}}; @@ -37,6 +37,9 @@ pub enum Action { MovePreviousWordStart, CollapseSelection, + + ExtendLineBelow, + ExtendLineAbove, } impl App { @@ -75,6 +78,9 @@ impl App { Action::MovePreviousWordStart => self.move_previous_word_start(), Action::CollapseSelection => self.collapse_selection(), + + Action::ExtendLineBelow => self.extend_line_below(), + Action::ExtendLineAbove => self.extend_line_above(), } } @@ -233,6 +239,40 @@ impl App { const fn collapse_selection(&mut self) { self.cursor.collapse(); } + + fn extend_line_below(&mut self) { + if self.cursor.tail > self.cursor.head { + swap(&mut self.cursor.head, &mut self.cursor.tail); + } + + if self.cursor.tail.is_multiple_of(BYTES_PER_LINE) && + self.cursor.head % BYTES_PER_LINE == BYTES_PER_LINE - 1 + { + self.cursor.head = min( + self.cursor.head + BYTES_PER_LINE, + self.contents.len() - 1 + ) + } else { + self.cursor.tail -= self.cursor.tail % BYTES_PER_LINE; + self.cursor.head += BYTES_PER_LINE - 1 - (self.cursor.head % BYTES_PER_LINE); + } + } + + fn extend_line_above(&mut self) { + if self.cursor.head > self.cursor.tail { + swap(&mut self.cursor.head, &mut self.cursor.tail); + } + + if self.cursor.head.is_multiple_of(BYTES_PER_LINE) && + (self.cursor.tail % BYTES_PER_LINE == BYTES_PER_LINE - 1 || + self.cursor.tail == self.contents.len() - 1) + { + self.cursor.head = self.cursor.head.saturating_sub(BYTES_PER_LINE); + } else { + self.cursor.head -= self.cursor.head % BYTES_PER_LINE; + self.cursor.tail += BYTES_PER_LINE - 1 - (self.cursor.tail % BYTES_PER_LINE); + } + } } // helpers diff --git a/src/config.rs b/src/config.rs index 2e15bd1..8bb351a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -128,6 +128,9 @@ impl Default for Config { ("b".try_into().unwrap(), Action::MovePreviousWordStart), (";".try_into().unwrap(), Action::CollapseSelection), + + ("x".try_into().unwrap(), Action::ExtendLineBelow), + ("X".try_into().unwrap(), Action::ExtendLineAbove), ].into()), (Some(PartialAction::Goto), [ ("j".try_into().unwrap(), Action::GotoLineStart), @@ -165,6 +168,9 @@ impl Default for Config { // ("b".try_into().unwrap(), Action::ExtendPreviousWordStart), (";".try_into().unwrap(), Action::CollapseSelection), + + ("x".try_into().unwrap(), Action::ExtendLineBelow), + ("X".try_into().unwrap(), Action::ExtendLineAbove), ].into()) ].into()) ].into() diff --git a/src/main.rs b/src/main.rs index 1815973..5c5b8ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,6 @@ const CHUNKS_PER_LINE: usize = BYTES_PER_LINE / BYTES_PER_CHUNK; // TODO: // - undo/redo -// - x/X // - modes // - select // - insert