aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2018-03-23 01:01:55 +0100
committerJoe Wilm <joe@jwilm.com>2018-06-02 09:56:50 -0700
commit688cabefc0bfc3224189c10235668eae5e5b0101 (patch)
tree7579612ed4a2d22e897918f6f678bce272745109
parent4333b2fb1992b8185dc7041d9d3df8eee86717bc (diff)
downloadalacritty-688cabefc0bfc3224189c10235668eae5e5b0101.tar.gz
alacritty-688cabefc0bfc3224189c10235668eae5e5b0101.zip
Rework auto-scrolling options
This changes two things, the first thing it does is that now whenever a keybinding sends an escape sequence, the viewport is automatically scrolled to the bottom. This is enabled by default and fixes #1187. The second thing is automatic scrolling when a command writes to the terminal. So when running a command like `sleep 3; ls -lah`, alacritty will scroll to the bottom once the output is sent, even if the viewport is currently not at the bottom of the scrollback. Because this can have an impact on performance, and is not enabled by default in terminals like iTerm or Termite (VTE), it is an opt-in setting in the config.
-rw-r--r--alacritty.yml4
-rw-r--r--alacritty_macos.yml4
-rw-r--r--src/config.rs3
-rw-r--r--src/event_loop.rs15
-rw-r--r--src/input.rs1
-rw-r--r--src/term/mod.rs10
6 files changed, 33 insertions, 4 deletions
diff --git a/alacritty.yml b/alacritty.yml
index 546d6259..f21db6cc 100644
--- a/alacritty.yml
+++ b/alacritty.yml
@@ -52,6 +52,10 @@ scrolling:
# To disable this completely, set `faux_multiplier` to 0.
faux_multiplier: 3
+ # Automatically scroll to the bottom when new text is written
+ # to the terminal.
+ auto_scroll: false
+
# Display tabs using this many cells (changes require restart)
tabspaces: 8
diff --git a/alacritty_macos.yml b/alacritty_macos.yml
index 8f8c4703..9b7b8d1a 100644
--- a/alacritty_macos.yml
+++ b/alacritty_macos.yml
@@ -50,6 +50,10 @@ scrolling:
# To disable this completely, set `faux_multiplier` to 0.
faux_multiplier: 3
+ # Automatically scroll to the bottom when new text is written
+ # to the terminal.
+ auto_scroll: false
+
# Display tabs using this many cells (changes require restart)
tabspaces: 8
diff --git a/src/config.rs b/src/config.rs
index f8dad1f2..0eab1bfb 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -478,6 +478,8 @@ pub struct Scrolling {
#[serde(deserialize_with="deserialize_scrolling_multiplier")]
#[serde(default="default_scrolling_multiplier")]
pub faux_multiplier: u8,
+ #[serde(default, deserialize_with="failure_default")]
+ pub auto_scroll: bool,
}
fn default_scrolling_history() -> u32 {
@@ -495,6 +497,7 @@ impl Default for Scrolling {
history: default_scrolling_history(),
multiplier: default_scrolling_multiplier(),
faux_multiplier: default_scrolling_multiplier(),
+ auto_scroll: false,
}
}
}
diff --git a/src/event_loop.rs b/src/event_loop.rs
index 18d48a52..d7d27243 100644
--- a/src/event_loop.rs
+++ b/src/event_loop.rs
@@ -255,6 +255,9 @@ impl<Io> EventLoop<Io>
let mut processed = 0;
let mut terminal = None;
+ // Flag to keep track if wakeup has already been sent
+ let mut send_wakeup = false;
+
loop {
match self.pty.read(&mut buf[..]) {
Ok(0) => break,
@@ -272,10 +275,14 @@ impl<Io> EventLoop<Io>
// Get reference to terminal. Lock is acquired on initial
// iteration and held until there's no bytes left to parse
// or we've reached MAX_READ.
- if terminal.is_none() {
+ let terminal = if terminal.is_none() {
terminal = Some(self.terminal.lock());
- }
- let terminal = terminal.as_mut().unwrap();
+ let terminal = terminal.as_mut().unwrap();
+ send_wakeup = !terminal.dirty;
+ terminal
+ } else {
+ terminal.as_mut().unwrap()
+ };
// Run the parser
for byte in &buf[..got] {
@@ -301,7 +308,7 @@ impl<Io> EventLoop<Io>
// Only request a draw if one hasn't already been requested.
if let Some(mut terminal) = terminal {
- if !terminal.dirty {
+ if send_wakeup {
self.display.notify();
terminal.dirty = true;
}
diff --git a/src/input.rs b/src/input.rs
index 8cf11811..047c81aa 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -192,6 +192,7 @@ impl Action {
fn execute<A: ActionContext>(&self, ctx: &mut A) {
match *self {
Action::Esc(ref s) => {
+ ctx.scroll(Scroll::Bottom);
ctx.write_to_pty(s.clone().into_bytes())
},
Action::Copy => {
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 3c7ef87c..198f8cea 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -756,6 +756,9 @@ pub struct Term {
/// Number of spaces in one tab
tabspaces: usize,
+
+ /// Automatically scroll to bottom when new lines are added
+ auto_scroll: bool,
}
/// Terminal size info
@@ -879,6 +882,7 @@ impl Term {
default_cursor_style: config.cursor_style(),
dynamic_title: config.dynamic_title(),
tabspaces,
+ auto_scroll: config.scrolling().auto_scroll,
}
}
@@ -905,6 +909,7 @@ impl Term {
self.visual_bell.update_config(config);
self.default_cursor_style = config.cursor_style();
self.dynamic_title = config.dynamic_title();
+ self.auto_scroll = config.scrolling().auto_scroll;
}
#[inline]
@@ -1255,6 +1260,11 @@ impl ansi::Handler for Term {
/// A character to be displayed
#[inline]
fn input(&mut self, c: char) {
+ // If enabled, scroll to bottom when character is received
+ if self.auto_scroll {
+ self.scroll_display(Scroll::Bottom);
+ }
+
if self.input_needs_wrap {
if !self.mode.contains(mode::TermMode::LINE_WRAP) {
return;