jump to selected offset
This commit is contained in:
+51
-1
@@ -81,6 +81,8 @@ pub enum Action {
|
|||||||
SplitSelectionsInto7s,
|
SplitSelectionsInto7s,
|
||||||
SplitSelectionsInto8s,
|
SplitSelectionsInto8s,
|
||||||
SplitSelectionsInto9s,
|
SplitSelectionsInto9s,
|
||||||
|
|
||||||
|
JumpToSelectedOffset,
|
||||||
}
|
}
|
||||||
|
|
||||||
// actions that act on the app as a whole, not just one buffer
|
// actions that act on the app as a whole, not just one buffer
|
||||||
@@ -171,6 +173,8 @@ impl Buffer {
|
|||||||
Action::SplitSelectionsInto7s => self.split_selections_into_size(7),
|
Action::SplitSelectionsInto7s => self.split_selections_into_size(7),
|
||||||
Action::SplitSelectionsInto8s => self.split_selections_into_size(8),
|
Action::SplitSelectionsInto8s => self.split_selections_into_size(8),
|
||||||
Action::SplitSelectionsInto9s => self.split_selections_into_size(9),
|
Action::SplitSelectionsInto9s => self.split_selections_into_size(9),
|
||||||
|
|
||||||
|
Action::JumpToSelectedOffset => self.jump_to_selected_offset(window_size),
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@@ -600,12 +604,48 @@ impl Buffer {
|
|||||||
cursor
|
cursor
|
||||||
.range()
|
.range()
|
||||||
.step_by(size)
|
.step_by(size)
|
||||||
.map(|head| Cursor { head, tail: head + size - 1 })
|
.map(|tail| Cursor { head: tail + size - 1, tail })
|
||||||
});
|
});
|
||||||
|
|
||||||
self.primary_cursor = new_cursors.next().unwrap();
|
self.primary_cursor = new_cursors.next().unwrap();
|
||||||
self.cursors = new_cursors.collect();
|
self.cursors = new_cursors.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn jump_to_selected_offset(&mut self, window_size: WindowSize) {
|
||||||
|
if !iter::once(&self.primary_cursor)
|
||||||
|
.chain(&self.cursors)
|
||||||
|
.all(|cursor| {
|
||||||
|
bytes_as_nat(&self.contents[cursor.range()])
|
||||||
|
.is_some_and(|offset| offset < self.contents.len())
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if self.cursors.is_empty() {
|
||||||
|
self.alert_message = Span::from(
|
||||||
|
"selection is not a valid offset"
|
||||||
|
).red();
|
||||||
|
} else {
|
||||||
|
self.alert_message = Span::from(
|
||||||
|
"not all selections are valid offsets"
|
||||||
|
).red();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.primary_cursor = Cursor::at(
|
||||||
|
bytes_as_nat(&self.contents[self.primary_cursor.range()]).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
for cursor in &mut self.cursors {
|
||||||
|
*cursor = Cursor::at(
|
||||||
|
bytes_as_nat(&self.contents[cursor.range()]).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cursors.sort_by_key(|cursor| cursor.head);
|
||||||
|
|
||||||
|
self.combine_cursors_if_overlapping();
|
||||||
|
self.clamp_screen_to_primary_cursor(window_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
@@ -622,3 +662,13 @@ impl Buffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_as_nat(bytes: &[u8]) -> Option<usize> {
|
||||||
|
bytes
|
||||||
|
.iter()
|
||||||
|
.rev() // little-endian
|
||||||
|
.skip_while(|&&byte| byte == 0)
|
||||||
|
.try_fold(usize::default(), |result, &byte| {
|
||||||
|
Some(result.shl_exact(8)? | (byte as usize))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ impl Default for Config {
|
|||||||
("7".try_into().unwrap(), Action::SplitSelectionsInto7s),
|
("7".try_into().unwrap(), Action::SplitSelectionsInto7s),
|
||||||
("8".try_into().unwrap(), Action::SplitSelectionsInto8s),
|
("8".try_into().unwrap(), Action::SplitSelectionsInto8s),
|
||||||
("9".try_into().unwrap(), Action::SplitSelectionsInto9s),
|
("9".try_into().unwrap(), Action::SplitSelectionsInto9s),
|
||||||
|
|
||||||
|
("J".try_into().unwrap(), Action::JumpToSelectedOffset),
|
||||||
].into()),
|
].into()),
|
||||||
(Some(PartialAction::Goto), [
|
(Some(PartialAction::Goto), [
|
||||||
("j".try_into().unwrap(), Action::GotoLineStart),
|
("j".try_into().unwrap(), Action::GotoLineStart),
|
||||||
@@ -230,6 +232,8 @@ impl Default for Config {
|
|||||||
("7".try_into().unwrap(), Action::SplitSelectionsInto7s),
|
("7".try_into().unwrap(), Action::SplitSelectionsInto7s),
|
||||||
("8".try_into().unwrap(), Action::SplitSelectionsInto8s),
|
("8".try_into().unwrap(), Action::SplitSelectionsInto8s),
|
||||||
("9".try_into().unwrap(), Action::SplitSelectionsInto9s),
|
("9".try_into().unwrap(), Action::SplitSelectionsInto9s),
|
||||||
|
|
||||||
|
("J".try_into().unwrap(), Action::JumpToSelectedOffset),
|
||||||
].into()),
|
].into()),
|
||||||
(Some(PartialAction::Space), [
|
(Some(PartialAction::Space), [
|
||||||
("w".try_into().unwrap(), Action::Save),
|
("w".try_into().unwrap(), Action::Save),
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,7 @@
|
|||||||
#![warn(clippy::pedantic, clippy::nursery)]
|
#![warn(clippy::pedantic, clippy::nursery)]
|
||||||
#![allow(clippy::cast_possible_truncation)]
|
#![allow(clippy::cast_possible_truncation)]
|
||||||
#![feature(get_disjoint_mut_helpers)]
|
#![feature(get_disjoint_mut_helpers)]
|
||||||
|
#![feature(exact_bitshifts)]
|
||||||
|
|
||||||
use app::App;
|
use app::App;
|
||||||
|
|
||||||
@@ -20,7 +21,6 @@ const BYTES_PER_CHUNK: usize = 4;
|
|||||||
const CHUNKS_PER_LINE: usize = BYTES_PER_LINE / BYTES_PER_CHUNK;
|
const CHUNKS_PER_LINE: usize = BYTES_PER_LINE / BYTES_PER_CHUNK;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - J jump to offset under cursor
|
|
||||||
// - m mark offset
|
// - m mark offset
|
||||||
// - search
|
// - search
|
||||||
// - s/A-k/A-K
|
// - s/A-k/A-K
|
||||||
@@ -40,6 +40,8 @@ const CHUNKS_PER_LINE: usize = BYTES_PER_LINE / BYTES_PER_CHUNK;
|
|||||||
// - y/p
|
// - y/p
|
||||||
// - [/] to cycle view offset?
|
// - [/] to cycle view offset?
|
||||||
// - gj jump to entered offset
|
// - gj jump to entered offset
|
||||||
|
// - repeat X times (dec and hex)
|
||||||
|
// - jump relative to last marker?
|
||||||
|
|
||||||
// future directions
|
// future directions
|
||||||
// - 'views' for bytes (i8/16/etc u8/16/etc 20.12/8.4/etc)
|
// - 'views' for bytes (i8/16/etc u8/16/etc 20.12/8.4/etc)
|
||||||
|
|||||||
Reference in New Issue
Block a user