Feature: Configurable scroll buffer (#936)

* Configurable scroll buffer

* Fix unit test failures

* Add scroll_buffer_size description in the default config file

* Fix config file
This commit is contained in:
Kunal Mohan 2022-01-04 23:24:05 +05:30 committed by GitHub
parent 3e0ac752cc
commit e23d06b70d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 7 deletions

View file

@ -37,6 +37,7 @@ use route::route_thread_main;
use zellij_utils::{
channels::{self, ChannelWithContext, SenderWithContext},
cli::CliArgs,
consts::{DEFAULT_SCROLL_BUFFER_SIZE, SCROLL_BUFFER_SIZE},
errors::{ContextType, ErrorInstruction, ServerContext},
input::{
command::{RunCommand, TerminalAction},
@ -541,6 +542,15 @@ fn init_session(
layout,
plugins,
} = options;
SCROLL_BUFFER_SIZE
.set(
config_options
.scroll_buffer_size
.unwrap_or(DEFAULT_SCROLL_BUFFER_SIZE),
)
.unwrap();
let (to_screen, screen_receiver): ChannelWithContext<ScreenInstruction> = channels::unbounded();
let to_screen = SenderWithContext::new(to_screen);

View file

@ -7,10 +7,13 @@ use std::{
str,
};
use zellij_utils::{position::Position, vte, zellij_tile};
use zellij_utils::{
consts::{DEFAULT_SCROLL_BUFFER_SIZE, SCROLL_BUFFER_SIZE},
position::Position,
vte, zellij_tile,
};
const TABSTOP_WIDTH: usize = 8; // TODO: is this always right?
pub const SCROLL_BACK: usize = 10_000;
pub const MAX_TITLE_STACK_SIZE: usize = 1000;
use vte::{Params, Perform};
@ -226,7 +229,7 @@ fn transfer_rows_from_lines_below_to_viewport(
fn bounded_push(vec: &mut VecDeque<Row>, value: Row) -> Option<usize> {
let mut dropped_line_width = None;
if vec.len() >= SCROLL_BACK {
if vec.len() >= *SCROLL_BUFFER_SIZE.get().unwrap() {
let line = vec.pop_front();
if let Some(line) = line {
dropped_line_width = Some(line.width());
@ -419,7 +422,11 @@ impl Debug for Grid {
impl Grid {
pub fn new(rows: usize, columns: usize, colors: Palette) -> Self {
Grid {
lines_above: VecDeque::with_capacity(SCROLL_BACK),
lines_above: VecDeque::with_capacity(
// .get_or_init() is used instead of .get().unwrap() to prevent
// unit tests from panicking where SCROLL_BUFFER_SIZE is uninitialized.
*SCROLL_BUFFER_SIZE.get_or_init(|| DEFAULT_SCROLL_BUFFER_SIZE),
),
viewport: vec![Row::new(columns).canonical()],
lines_below: vec![],
horizontal_tabstops: create_horizontal_tabstops(columns),
@ -1350,7 +1357,7 @@ impl Grid {
self.should_render = true;
}
fn reset_terminal_state(&mut self) {
self.lines_above = VecDeque::with_capacity(SCROLL_BACK);
self.lines_above = VecDeque::with_capacity(*SCROLL_BUFFER_SIZE.get().unwrap());
self.lines_below = vec![];
self.viewport = vec![Row::new(self.width).canonical()];
self.alternative_lines_above_viewport_and_cursor = None;
@ -1849,7 +1856,7 @@ impl Perform for Grid {
Some(1049) => {
let current_lines_above = std::mem::replace(
&mut self.lines_above,
VecDeque::with_capacity(SCROLL_BACK),
VecDeque::with_capacity(*SCROLL_BUFFER_SIZE.get().unwrap()),
);
let current_viewport = std::mem::replace(
&mut self.viewport,

View file

@ -20,7 +20,7 @@ interprocess = "1.1.1"
lazy_static = "1.4.0"
libc = "0.2"
nix = "0.19.1"
once_cell = "1.7.2"
once_cell = "1.8.0"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
serde_json = "1.0"

View file

@ -461,3 +461,10 @@ plugins:
# - true (default)
# - false
#mouse_mode: false
# Configure the scroll back buffer size
# This is the number of lines zellij stores for each pane in the scroll back
# buffer. Excess number of lines are discarded in a FIFO fashion.
# Valid values: positive integers
# Default value: 10000
#scroll_buffer_size: 10000

View file

@ -5,6 +5,7 @@ use crate::shared::set_permissions;
use directories_next::ProjectDirs;
use lazy_static::lazy_static;
use nix::unistd::Uid;
use once_cell::sync::OnceCell;
use std::path::PathBuf;
use std::{env, fs};
@ -12,6 +13,8 @@ pub const ZELLIJ_CONFIG_FILE_ENV: &str = "ZELLIJ_CONFIG_FILE";
pub const ZELLIJ_CONFIG_DIR_ENV: &str = "ZELLIJ_CONFIG_DIR";
pub const ZELLIJ_LAYOUT_DIR_ENV: &str = "ZELLIJ_LAYOUT_DIR";
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const DEFAULT_SCROLL_BUFFER_SIZE: usize = 10_000;
pub static SCROLL_BUFFER_SIZE: OnceCell<usize> = OnceCell::new();
pub const SYSTEM_DEFAULT_CONFIG_DIR: &str = "/etc/zellij";
pub const SYSTEM_DEFAULT_DATA_DIR_PREFIX: &str = system_default_data_dir();

View file

@ -72,6 +72,8 @@ pub struct Options {
/// Set behaviour on force close (quit or detach)
#[structopt(long)]
pub on_force_close: Option<OnForceClose>,
#[structopt(long)]
pub scroll_buffer_size: Option<usize>,
}
impl Options {
@ -96,6 +98,7 @@ impl Options {
let layout_dir = other.layout_dir.or_else(|| self.layout_dir.clone());
let theme = other.theme.or_else(|| self.theme.clone());
let on_force_close = other.on_force_close.or(self.on_force_close);
let scroll_buffer_size = other.scroll_buffer_size.or(self.scroll_buffer_size);
Options {
simplified_ui,
@ -107,6 +110,7 @@ impl Options {
pane_frames,
mirror_session,
on_force_close,
scroll_buffer_size,
}
}
@ -135,6 +139,7 @@ impl Options {
let layout_dir = other.layout_dir.or_else(|| self.layout_dir.clone());
let theme = other.theme.or_else(|| self.theme.clone());
let on_force_close = other.on_force_close.or(self.on_force_close);
let scroll_buffer_size = other.scroll_buffer_size.or(self.scroll_buffer_size);
Options {
simplified_ui,
@ -146,6 +151,7 @@ impl Options {
pane_frames,
mirror_session,
on_force_close,
scroll_buffer_size,
}
}
@ -193,6 +199,7 @@ impl From<CliOptions> for Options {
pane_frames: opts.pane_frames,
mirror_session: opts.mirror_session,
on_force_close: opts.on_force_close,
scroll_buffer_size: opts.scroll_buffer_size,
}
}
}