Skip to content

Commit

Permalink
feat(horizontal-scroll): Get a basic working model for horizontal scroll
Browse files Browse the repository at this point in the history
  • Loading branch information
AMythicDev committed Dec 30, 2023
1 parent 6aa272b commit 29839cf
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/core/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use std::{
};

#[cfg(feature = "static_output")]
use {super::utils::display::write_lines, crossterm::tty::IsTty};
use {super::utils::display::write_raw_lines, crossterm::tty::IsTty};

#[cfg(feature = "search")]
use parking_lot::Condvar;
Expand Down Expand Up @@ -98,7 +98,7 @@ pub fn init_core(pager: &Pager, rm: RunMode) -> std::result::Result<(), MinusErr
if *RUNMODE.lock() == RunMode::Static {
// If stdout is not a tty, write everything and quit
if !out.is_tty() {
write_lines(&mut out, &[ps.screen.orig_text], None)?;
write_raw_lines(&mut out, &[ps.screen.orig_text], None)?;
let mut rm = RUNMODE.lock();
*rm = RunMode::Uninitialized;
drop(rm);
Expand All @@ -107,7 +107,7 @@ pub fn init_core(pager: &Pager, rm: RunMode) -> std::result::Result<(), MinusErr
// If number of lines of text is less than available rows, write everything and quit
// unless run_no_overflow is set to true
if ps.screen.formatted_lines_count() <= ps.rows && !ps.run_no_overflow {
write_lines(&mut out, &ps.screen.formatted_lines, Some("\r"))?;
write_raw_lines(&mut out, &ps.screen.formatted_lines, Some("\r"))?;
ps.exit();
let mut rm = RUNMODE.lock();
*rm = RunMode::Uninitialized;
Expand Down
14 changes: 10 additions & 4 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,25 @@ impl CommandQueue {
}
/// Store `value` only if [RUNMODE] is not unintialized.
///
/// # Panics
/// This function will panic if it is called in an environment where [RUNMODE] is
/// uninitialized.
/// If [RUNMODE] is uninitialized, this will not append anything into the queue and simply
/// return
pub fn push_back(&mut self, value: Command) {
assert!(!RUNMODE.lock().is_uninitialized(), "CommandQueue::push_back() caled when RUNMODE is not set. This is most likely a bug. Please report the issue on minus's issue tracker on Github.");
if RUNMODE.lock().is_uninitialized() {
return;
}
self.0.push_back(value);
}
/// Store `value` without checking [RUNMODE].
///
/// This is only meant to be used as an optimization over [push_back](CommandQueue::push_back)
/// when it is absolutely sure that [RUNMODE] isn't uninitialized. Hence calling this in an
/// enviroment where [RUNMODE] is uninitialized can lead to unexpect slowdowns.
///
/// # Panics
/// This function will panic if it is called in an environment where [RUNMODE] is
/// uninitialized.
pub fn push_back_unchecked(&mut self, value: Command) {
assert!(!RUNMODE.lock().is_uninitialized(), "CommandQueue::push_back() caled when RUNMODE is not set. This is most likely a bug. Please report the issue on minus's issue tracker on Github.");
self.0.push_back(value);
}
pub fn pop_front(&mut self) -> Option<Command> {
Expand Down
57 changes: 51 additions & 6 deletions src/core/utils/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,7 @@ pub fn draw_for_change(
Ordering::Equal => return Ok(()),
};

for line in lines {
writeln!(out, "\r{line}")?;
}
write_lines(out, lines, p.cols, p.horizontal_scroll, p.left_mark)?;

p.upper_mark = *new_upper_mark;

Expand Down Expand Up @@ -243,7 +241,7 @@ pub fn write_text_checked(
term::move_cursor(out, 0, 0, false)?;
term::clear_entire_screen(out, false)?;

write_lines(out, display_lines, Some("\r"))
write_raw_lines(out, display_lines, Some("\r"))
}

pub fn write_from_pagerstate(out: &mut impl Write, ps: &mut PagerState) -> Result<(), MinusError> {
Expand All @@ -267,7 +265,54 @@ pub fn write_from_pagerstate(out: &mut impl Write, ps: &mut PagerState) -> Resul
.screen
.get_formatted_lines_with_bounds(ps.upper_mark, lower_mark);

write_lines(out, display_lines, Some("\r"))
write_lines(
out,
display_lines,
ps.cols,
ps.horizontal_scroll,
ps.left_mark,
)
}

pub fn write_lines(
out: &mut impl Write,
lines: &[String],
cols: usize,
horizontal_scroll: bool,
left_mark: usize,
) -> crate::Result {
if horizontal_scroll {
let rightmost = lines.iter().max().unwrap().len();
let range = (left_mark, rightmost);
write_lines_in_horizontal_scroll(out, lines, cols, range)
} else {
write_raw_lines(out, lines, Some("\r"))
}
}

pub fn write_lines_in_horizontal_scroll(
out: &mut impl Write,
lines: &[String],
cols: usize,
range: (usize, usize),
) -> crate::Result {
let mut line_output = String::with_capacity(range.1);
for line in lines {
let line = line.as_str();
let (start, end) = range;
line_output.push_str(line.get(start..end.min(cols)).unwrap());

let visible_part = line.len().saturating_sub(start);
let end_padding_count = cols.saturating_sub(visible_part);

for _ in 0..end_padding_count {
line_output.push(' ');
}

writeln!(out, "\r{}", line_output)?;
line_output.clear();
}
Ok(())
}

/// Write lines to the the output
Expand All @@ -276,7 +321,7 @@ pub fn write_from_pagerstate(out: &mut impl Write, ps: &mut PagerState) -> Resul
/// `initial` tells any extra text to be inserted before each line. For functions that use this
/// function over terminals, this should be set to `\r` to avoid broken display.
/// The `\r` resets the cursor to the start of the line.
pub fn write_lines(
pub fn write_raw_lines(
out: &mut impl Write,
lines: &[String],
initial: Option<&str>,
Expand Down

0 comments on commit 29839cf

Please sign in to comment.