Proposal for line wrap - ^[[7h and ^[[7l (private)

These changes provide support for disabling auto line wrap which is
currently default to on.

'tput rman' will now disable auto line wrap and alacritty will now not
automatically wrap lines.

'tput sman' will now (re)enable auto line wrap and alacritty will now
automatically wrap lines once it reaches the end of the line.

My testing showed this to work the same as gnome-terminal.

I should note that simply having ^[[7h or ^[[7l in a recording does not
enable and disable line wrapping. This is the same behavior as
gnome-terminal and xterm. Those cape codes come through as private
which are not handled yet. I behave this is the correct behavior.
This commit is contained in:
Michael Brumlow 2017-01-11 21:00:29 -06:00 committed by Joe Wilm
parent a7fc46afce
commit 06d213fbc7
2 changed files with 34 additions and 24 deletions

View File

@ -247,6 +247,8 @@ pub enum Mode {
CursorKeys = 1,
/// ?6
Origin = 6,
/// ?7
LineWrap = 7,
/// ?12
BlinkingCursor = 12,
/// ?25
@ -272,6 +274,7 @@ impl Mode {
Some(match num {
1 => Mode::CursorKeys,
6 => Mode::Origin,
7 => Mode::LineWrap,
12 => Mode::BlinkingCursor,
25 => Mode::ShowCursor,
1000 => Mode::ReportMouseClicks,

View File

@ -183,6 +183,7 @@ pub mod mode {
const BRACKETED_PASTE = 0b00010000,
const SGR_MOUSE = 0b00100000,
const MOUSE_MOTION = 0b01000000,
const LINE_WRAP = 0b10000000,
const ANY = 0b11111111,
const NONE = 0b00000000,
}
@ -190,7 +191,7 @@ pub mod mode {
impl Default for TermMode {
fn default() -> TermMode {
SHOW_CURSOR
SHOW_CURSOR | LINE_WRAP
}
}
}
@ -203,12 +204,12 @@ pub struct Term {
/// The grid
grid: Grid<Cell>,
/// Tracks if the next call to input will need to first handle wrapping.
/// Tracks if the next call to input will need to first handle wrapping.
/// This is true after the last column is set with the input function. Any function that
/// implicitly sets the line or column needs to set this to false to avoid wrapping twice.
/// input_needs_wrap ensures that cursor.col is always valid for use into indexing into
/// arrays. Without it we wold have to sanitize cursor.col every time we used it.
input_needs_wrap: bool,
/// arrays. Without it we wold have to sanitize cursor.col every time we used it.
input_needs_wrap: bool,
/// Got a request to set title; it's buffered here until next draw.
///
@ -316,7 +317,7 @@ impl Term {
Term {
next_title: None,
dirty: false,
input_needs_wrap: false,
input_needs_wrap: false,
grid: grid,
alt_grid: alt,
alt: false,
@ -504,14 +505,14 @@ impl Term {
return;
}
// Should not allow less than 1 col, causes all sorts of checks to be required.
// Should not allow less than 1 col, causes all sorts of checks to be required.
if num_cols <= Column(1) {
num_cols = Column(2);
num_cols = Column(2);
}
// Should not allow less than 1 line, causes all sorts of checks to be required.
// Should not allow less than 1 line, causes all sorts of checks to be required.
if num_lines <= Line(1) {
num_lines = Line(2);
num_lines = Line(2);
}
// Scroll up to keep cursor and as much context as possible in grid.
@ -627,14 +628,14 @@ impl Term {
}
// Clear `lines` lines starting from origin to origin + lines
{
{
let end = origin + lines;
self.grid.clear_region(origin..end, |c| c.reset(&template));
}
// Scroll from origin to bottom less number of lines
{
let end = self.scroll_region.end - lines;
let end = self.scroll_region.end - lines;
self.grid.scroll_up(origin..end, lines);
}
}
@ -664,9 +665,13 @@ impl ansi::Handler for Term {
fn input(&mut self, c: char) {
if self.input_needs_wrap {
if !self.mode.contains(mode::LINE_WRAP) {
return;
}
debug_println!("wrapping");
{
let location = Point {
line: self.cursor.line,
@ -676,13 +681,13 @@ impl ansi::Handler for Term {
let cell = &mut self.grid[&location];
cell.flags.insert(cell::WRAPLINE);
}
if (self.cursor.line + 1) >= self.scroll_region.end {
self.linefeed();
} else {
self.cursor.line += 1;
}
self.cursor.col = Column(0);
self.input_needs_wrap = false;
}
@ -691,8 +696,8 @@ impl ansi::Handler for Term {
let cell = &mut self.grid[&self.cursor];
*cell = self.template_cell;
cell.c = c;
}
}
if (self.cursor.col + 1) < self.grid.num_cols() {
self.cursor.col += 1;
} else {
@ -726,7 +731,7 @@ impl ansi::Handler for Term {
#[inline]
fn insert_blank(&mut self, count: Column) {
// Ensure inserting within terminal bounds
let count = min(count, self.size_info.cols() - self.cursor.col);
let source = self.cursor.col;
@ -754,7 +759,7 @@ impl ansi::Handler for Term {
#[inline]
fn move_up(&mut self, lines: Line) {
debug_println!("move_up: {}", lines);
let lines = min(self.cursor.line, lines);
let lines = min(self.cursor.line, lines);
self.cursor.line = min(self.cursor.line - lines, self.grid.num_lines() -1);
}
@ -767,14 +772,14 @@ impl ansi::Handler for Term {
#[inline]
fn move_forward(&mut self, cols: Column) {
debug_println!("move_forward: {}", cols);
self.cursor.col = min(self.cursor.col + cols, self.grid.num_cols() - 1);
self.cursor.col = min(self.cursor.col + cols, self.grid.num_cols() - 1);
self.input_needs_wrap = false;
}
#[inline]
fn move_backward(&mut self, cols: Column) {
debug_println!("move_backward: {}", cols);
self.cursor.col -= min(self.cursor.col, cols);
self.cursor.col -= min(self.cursor.col, cols);
self.input_needs_wrap = false;
}
@ -909,7 +914,7 @@ impl ansi::Handler for Term {
fn delete_chars(&mut self, count: Column) {
// Ensure deleting within terminal bounds
let count = min(count, self.size_info.cols());
let start = self.cursor.col;
let end = min(start + count, self.grid.num_cols() - 1);
let n = (self.size_info.cols() - end).0;
@ -957,8 +962,8 @@ impl ansi::Handler for Term {
fn clear_line(&mut self, mode: ansi::LineClearMode) {
debug_println!("clear_line: {:?}", mode);
let template = self.empty_cell;
let col = self.cursor.col;
let col = self.cursor.col;
match mode {
ansi::LineClearMode::Right => {
let row = &mut self.grid[self.cursor.line];
@ -1060,6 +1065,7 @@ impl ansi::Handler for Term {
ansi::Mode::ReportMouseMotion => self.mode.insert(mode::MOUSE_MOTION),
ansi::Mode::BracketedPaste => self.mode.insert(mode::BRACKETED_PASTE),
ansi::Mode::SgrMouse => self.mode.insert(mode::SGR_MOUSE),
ansi::Mode::LineWrap => self.mode.insert(mode::LINE_WRAP),
_ => {
debug_println!(".. ignoring set_mode");
}
@ -1077,6 +1083,7 @@ impl ansi::Handler for Term {
ansi::Mode::ReportMouseMotion => self.mode.remove(mode::MOUSE_MOTION),
ansi::Mode::BracketedPaste => self.mode.remove(mode::BRACKETED_PASTE),
ansi::Mode::SgrMouse => self.mode.remove(mode::SGR_MOUSE),
ansi::Mode::LineWrap => self.mode.remove(mode::LINE_WRAP),
_ => {
debug_println!(".. ignoring unset_mode");
}