mark offset
This commit is contained in:
+19
-1
@@ -1,4 +1,4 @@
|
||||
use std::{cmp::min, convert::identity, fs::File, io::Write, iter, mem::{replace, swap}};
|
||||
use std::{cmp::min, collections::hash_set::Entry, convert::identity, fs::File, io::Write, iter, mem::{replace, swap}};
|
||||
use ratatui::{style::Stylize, text::Span};
|
||||
|
||||
use crate::{BYTES_PER_LINE, app::WindowSize, buffer::{Buffer, Mode, PartialAction}, cursor::Cursor, edit_action::EditAction};
|
||||
@@ -83,6 +83,8 @@ pub enum Action {
|
||||
SplitSelectionsInto9s,
|
||||
|
||||
JumpToSelectedOffset,
|
||||
|
||||
ToggleMark,
|
||||
}
|
||||
|
||||
// actions that act on the app as a whole, not just one buffer
|
||||
@@ -175,6 +177,8 @@ impl Buffer {
|
||||
Action::SplitSelectionsInto9s => self.split_selections_into_size(9),
|
||||
|
||||
Action::JumpToSelectedOffset => self.jump_to_selected_offset(window_size),
|
||||
|
||||
Action::ToggleMark => self.toggle_mark(),
|
||||
}
|
||||
|
||||
None
|
||||
@@ -646,6 +650,20 @@ impl Buffer {
|
||||
self.combine_cursors_if_overlapping();
|
||||
self.clamp_screen_to_primary_cursor(window_size);
|
||||
}
|
||||
|
||||
fn toggle_mark(&mut self) {
|
||||
match self.marks.entry(self.primary_cursor.lower_bound()) {
|
||||
Entry::Occupied(occupied_entry) => { occupied_entry.remove(); },
|
||||
Entry::Vacant(vacant_entry) => vacant_entry.insert(),
|
||||
}
|
||||
|
||||
for cursor in &self.cursors {
|
||||
match self.marks.entry(cursor.lower_bound()) {
|
||||
Entry::Occupied(occupied_entry) => { occupied_entry.remove(); },
|
||||
Entry::Vacant(vacant_entry) => vacant_entry.insert(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
use core::slice::GetDisjointMutIndex;
|
||||
use std::{fs::File, io::Read, path::PathBuf};
|
||||
use std::{collections::HashSet, fs::File, io::Read, path::PathBuf};
|
||||
use crossterm::event::KeyEvent;
|
||||
use ratatui::{style::Color, text::Span};
|
||||
use crate::{action::AppAction, app::WindowSize, config::Config, cursor::Cursor, edit_action::EditAction};
|
||||
@@ -16,6 +16,8 @@ pub struct Buffer {
|
||||
pub primary_cursor: Cursor,
|
||||
pub cursors: Vec<Cursor>,
|
||||
|
||||
pub marks: HashSet<usize>,
|
||||
|
||||
pub mode: Mode,
|
||||
pub partial_action: Option<PartialAction>,
|
||||
pub partial_replace: Option<u8>,
|
||||
@@ -86,6 +88,8 @@ impl Buffer {
|
||||
primary_cursor: Cursor::default(),
|
||||
cursors: Vec::new(),
|
||||
|
||||
marks: HashSet::from([0, 4, 12, 15, 16, 17]),
|
||||
|
||||
mode: Mode::Normal,
|
||||
partial_action: None,
|
||||
partial_replace: None,
|
||||
|
||||
+33
-30
@@ -76,7 +76,7 @@ mod address {
|
||||
pub fn render_address(address: usize) -> Span<'static> {
|
||||
Span {
|
||||
style: Style::new().fg(Color::Rgb(138, 187, 195)),
|
||||
content: format!("{address:08x} ").into()
|
||||
content: format!("{address:08x}").into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,15 +103,9 @@ mod hex {
|
||||
.iter()
|
||||
.copied()
|
||||
.zip((address..).step_by(BYTES_PER_CHUNK))
|
||||
.map(|(chunk, address)| self.render_chunk(address, &chunk).collect())
|
||||
.interleave(
|
||||
(address..)
|
||||
.step_by(BYTES_PER_CHUNK)
|
||||
.take(CHUNKS_PER_LINE)
|
||||
.skip(1)
|
||||
.map(|address| vec![self.render_large_space_before(address)])
|
||||
)
|
||||
.flatten()
|
||||
.flat_map(|(chunk, address)| {
|
||||
self.render_chunk(address, &chunk).collect::<Vec<_>>()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render_partial_chunks(
|
||||
@@ -161,16 +155,19 @@ mod hex {
|
||||
bytes: &[u8; BYTES_PER_CHUNK]
|
||||
) -> impl Iterator<Item=Span<'static>> {
|
||||
#[allow(unstable_name_collisions)]
|
||||
bytes
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(address..)
|
||||
.map(|(byte, address)| self.render_byte_at(address, byte))
|
||||
.interleave(
|
||||
(address..)
|
||||
.take(BYTES_PER_CHUNK)
|
||||
.skip(1)
|
||||
.map(|address| self.render_space_before(address))
|
||||
iter::once(self.render_large_space_before(address))
|
||||
.chain(
|
||||
bytes
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(address..)
|
||||
.map(|(byte, address)| self.render_byte_at(address, byte))
|
||||
.interleave(
|
||||
(address..)
|
||||
.take(BYTES_PER_CHUNK)
|
||||
.skip(1)
|
||||
.map(|address| self.render_space_before(address))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -244,30 +241,36 @@ mod hex {
|
||||
}
|
||||
|
||||
fn render_large_space_before(&self, address: usize) -> Span<'static> {
|
||||
let span: Span = if self.marks.contains(&address) {
|
||||
" →".into()
|
||||
} else {
|
||||
" ".into()
|
||||
};
|
||||
|
||||
if iter::once(&self.primary_cursor)
|
||||
.chain(&self.cursors)
|
||||
.any(|cursor| cursor.contains_space_before(address))
|
||||
{
|
||||
Span {
|
||||
style: Style::new().bg(Color::select_grey()),
|
||||
content: " ".into()
|
||||
}
|
||||
span.bg(Color::select_grey())
|
||||
} else {
|
||||
" ".into()
|
||||
span
|
||||
}
|
||||
}
|
||||
|
||||
fn render_space_before(&self, address: usize) -> Span<'static> {
|
||||
let span: Span = if self.marks.contains(&address) {
|
||||
"→".into()
|
||||
} else {
|
||||
" ".into()
|
||||
};
|
||||
|
||||
if iter::once(&self.primary_cursor)
|
||||
.chain(&self.cursors)
|
||||
.any(|cursor| cursor.contains_space_before(address))
|
||||
{
|
||||
Span {
|
||||
style: Style::new().bg(Color::select_grey()),
|
||||
content: " ".into()
|
||||
}
|
||||
span.bg(Color::select_grey())
|
||||
} else {
|
||||
" ".into()
|
||||
span
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +163,8 @@ impl Default for Config {
|
||||
("9".try_into().unwrap(), Action::SplitSelectionsInto9s),
|
||||
|
||||
("J".try_into().unwrap(), Action::JumpToSelectedOffset),
|
||||
|
||||
("m".try_into().unwrap(), Action::ToggleMark),
|
||||
].into()),
|
||||
(Some(PartialAction::Goto), [
|
||||
("j".try_into().unwrap(), Action::GotoLineStart),
|
||||
@@ -234,6 +236,8 @@ impl Default for Config {
|
||||
("9".try_into().unwrap(), Action::SplitSelectionsInto9s),
|
||||
|
||||
("J".try_into().unwrap(), Action::JumpToSelectedOffset),
|
||||
|
||||
("m".try_into().unwrap(), Action::ToggleMark),
|
||||
].into()),
|
||||
(Some(PartialAction::Space), [
|
||||
("w".try_into().unwrap(), Action::Save),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#![allow(clippy::cast_possible_truncation)]
|
||||
#![feature(get_disjoint_mut_helpers)]
|
||||
#![feature(exact_bitshifts)]
|
||||
#![feature(hash_set_entry)]
|
||||
|
||||
use app::App;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user