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:
parent
3e0ac752cc
commit
e23d06b70d
6 changed files with 41 additions and 7 deletions
|
|
@ -37,6 +37,7 @@ use route::route_thread_main;
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
channels::{self, ChannelWithContext, SenderWithContext},
|
channels::{self, ChannelWithContext, SenderWithContext},
|
||||||
cli::CliArgs,
|
cli::CliArgs,
|
||||||
|
consts::{DEFAULT_SCROLL_BUFFER_SIZE, SCROLL_BUFFER_SIZE},
|
||||||
errors::{ContextType, ErrorInstruction, ServerContext},
|
errors::{ContextType, ErrorInstruction, ServerContext},
|
||||||
input::{
|
input::{
|
||||||
command::{RunCommand, TerminalAction},
|
command::{RunCommand, TerminalAction},
|
||||||
|
|
@ -541,6 +542,15 @@ fn init_session(
|
||||||
layout,
|
layout,
|
||||||
plugins,
|
plugins,
|
||||||
} = options;
|
} = 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, screen_receiver): ChannelWithContext<ScreenInstruction> = channels::unbounded();
|
||||||
let to_screen = SenderWithContext::new(to_screen);
|
let to_screen = SenderWithContext::new(to_screen);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ use std::{
|
||||||
str,
|
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?
|
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;
|
pub const MAX_TITLE_STACK_SIZE: usize = 1000;
|
||||||
|
|
||||||
use vte::{Params, Perform};
|
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> {
|
fn bounded_push(vec: &mut VecDeque<Row>, value: Row) -> Option<usize> {
|
||||||
let mut dropped_line_width = None;
|
let mut dropped_line_width = None;
|
||||||
if vec.len() >= SCROLL_BACK {
|
if vec.len() >= *SCROLL_BUFFER_SIZE.get().unwrap() {
|
||||||
let line = vec.pop_front();
|
let line = vec.pop_front();
|
||||||
if let Some(line) = line {
|
if let Some(line) = line {
|
||||||
dropped_line_width = Some(line.width());
|
dropped_line_width = Some(line.width());
|
||||||
|
|
@ -419,7 +422,11 @@ impl Debug for Grid {
|
||||||
impl Grid {
|
impl Grid {
|
||||||
pub fn new(rows: usize, columns: usize, colors: Palette) -> Self {
|
pub fn new(rows: usize, columns: usize, colors: Palette) -> Self {
|
||||||
Grid {
|
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()],
|
viewport: vec![Row::new(columns).canonical()],
|
||||||
lines_below: vec![],
|
lines_below: vec![],
|
||||||
horizontal_tabstops: create_horizontal_tabstops(columns),
|
horizontal_tabstops: create_horizontal_tabstops(columns),
|
||||||
|
|
@ -1350,7 +1357,7 @@ impl Grid {
|
||||||
self.should_render = true;
|
self.should_render = true;
|
||||||
}
|
}
|
||||||
fn reset_terminal_state(&mut self) {
|
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.lines_below = vec![];
|
||||||
self.viewport = vec![Row::new(self.width).canonical()];
|
self.viewport = vec![Row::new(self.width).canonical()];
|
||||||
self.alternative_lines_above_viewport_and_cursor = None;
|
self.alternative_lines_above_viewport_and_cursor = None;
|
||||||
|
|
@ -1849,7 +1856,7 @@ impl Perform for Grid {
|
||||||
Some(1049) => {
|
Some(1049) => {
|
||||||
let current_lines_above = std::mem::replace(
|
let current_lines_above = std::mem::replace(
|
||||||
&mut self.lines_above,
|
&mut self.lines_above,
|
||||||
VecDeque::with_capacity(SCROLL_BACK),
|
VecDeque::with_capacity(*SCROLL_BUFFER_SIZE.get().unwrap()),
|
||||||
);
|
);
|
||||||
let current_viewport = std::mem::replace(
|
let current_viewport = std::mem::replace(
|
||||||
&mut self.viewport,
|
&mut self.viewport,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ interprocess = "1.1.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
nix = "0.19.1"
|
nix = "0.19.1"
|
||||||
once_cell = "1.7.2"
|
once_cell = "1.8.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
|
||||||
|
|
@ -461,3 +461,10 @@ plugins:
|
||||||
# - true (default)
|
# - true (default)
|
||||||
# - false
|
# - false
|
||||||
#mouse_mode: 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
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use crate::shared::set_permissions;
|
||||||
use directories_next::ProjectDirs;
|
use directories_next::ProjectDirs;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use nix::unistd::Uid;
|
use nix::unistd::Uid;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{env, fs};
|
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_CONFIG_DIR_ENV: &str = "ZELLIJ_CONFIG_DIR";
|
||||||
pub const ZELLIJ_LAYOUT_DIR_ENV: &str = "ZELLIJ_LAYOUT_DIR";
|
pub const ZELLIJ_LAYOUT_DIR_ENV: &str = "ZELLIJ_LAYOUT_DIR";
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
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_CONFIG_DIR: &str = "/etc/zellij";
|
||||||
pub const SYSTEM_DEFAULT_DATA_DIR_PREFIX: &str = system_default_data_dir();
|
pub const SYSTEM_DEFAULT_DATA_DIR_PREFIX: &str = system_default_data_dir();
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ pub struct Options {
|
||||||
/// Set behaviour on force close (quit or detach)
|
/// Set behaviour on force close (quit or detach)
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
pub on_force_close: Option<OnForceClose>,
|
pub on_force_close: Option<OnForceClose>,
|
||||||
|
#[structopt(long)]
|
||||||
|
pub scroll_buffer_size: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
|
|
@ -96,6 +98,7 @@ impl Options {
|
||||||
let layout_dir = other.layout_dir.or_else(|| self.layout_dir.clone());
|
let layout_dir = other.layout_dir.or_else(|| self.layout_dir.clone());
|
||||||
let theme = other.theme.or_else(|| self.theme.clone());
|
let theme = other.theme.or_else(|| self.theme.clone());
|
||||||
let on_force_close = other.on_force_close.or(self.on_force_close);
|
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 {
|
Options {
|
||||||
simplified_ui,
|
simplified_ui,
|
||||||
|
|
@ -107,6 +110,7 @@ impl Options {
|
||||||
pane_frames,
|
pane_frames,
|
||||||
mirror_session,
|
mirror_session,
|
||||||
on_force_close,
|
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 layout_dir = other.layout_dir.or_else(|| self.layout_dir.clone());
|
||||||
let theme = other.theme.or_else(|| self.theme.clone());
|
let theme = other.theme.or_else(|| self.theme.clone());
|
||||||
let on_force_close = other.on_force_close.or(self.on_force_close);
|
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 {
|
Options {
|
||||||
simplified_ui,
|
simplified_ui,
|
||||||
|
|
@ -146,6 +151,7 @@ impl Options {
|
||||||
pane_frames,
|
pane_frames,
|
||||||
mirror_session,
|
mirror_session,
|
||||||
on_force_close,
|
on_force_close,
|
||||||
|
scroll_buffer_size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,6 +199,7 @@ impl From<CliOptions> for Options {
|
||||||
pane_frames: opts.pane_frames,
|
pane_frames: opts.pane_frames,
|
||||||
mirror_session: opts.mirror_session,
|
mirror_session: opts.mirror_session,
|
||||||
on_force_close: opts.on_force_close,
|
on_force_close: opts.on_force_close,
|
||||||
|
scroll_buffer_size: opts.scroll_buffer_size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue