summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--Cargo.toml2
-rw-r--r--src/ansi.rs12
-rw-r--r--src/term/mod.rs218
4 files changed, 139 insertions, 99 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d14530d8..dba08302 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -23,7 +23,7 @@ dependencies = [
"serde_derive 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "vte 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vte 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1098,7 +1098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vte"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"utf8parse 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1344,7 +1344,7 @@ dependencies = [
"checksum utf8parse 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a15ea87f3194a3a454c78d79082b4f5e85f6956ddb6cb86bbfbe4892aa3c0323"
"checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-"checksum vte 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0221cd88a06e81dea3ef4dcad02a881b19c03c48b6e6a34875cb301ec8de78d9"
+"checksum vte 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8abafc42c98c6e9f8ee68f3b55daf55d2af7047052facec9f6ac08f4e2addfa1"
"checksum walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c66c0b9792f0a765345452775f3adbd28dde9d33f30d13e5dcc5ae17cf6f3780"
"checksum wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ced3094c157b5cc0a08d40530e1a627d9f88b9a436971338d2646439128a559e"
"checksum wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "73bc10e84c1da90777beffecd24742baea17564ffc2a9918af41871c748eb050"
diff --git a/Cargo.toml b/Cargo.toml
index b93206c2..f7bbb161 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@ parking_lot = { version = "0.3.1", features = ["nightly"] }
serde = "0.9"
serde_yaml = "0.6"
serde_derive = "0.9"
-vte = "0.2.1"
+vte = "0.2.2"
mio = "0.6"
serde_json = "0.9"
copypasta = { path = "./copypasta" }
diff --git a/src/ansi.rs b/src/ansi.rs
index c9f7e268..b1a70130 100644
--- a/src/ansi.rs
+++ b/src/ansi.rs
@@ -462,6 +462,12 @@ pub enum CharsetIndex {
G3,
}
+impl Default for CharsetIndex {
+ fn default() -> Self {
+ CharsetIndex::G0
+ }
+}
+
/// Standard or common character sets which can be designated as G0-G3
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum StandardCharset {
@@ -469,6 +475,12 @@ pub enum StandardCharset {
SpecialCharacterAndLineDrawing,
}
+impl Default for StandardCharset {
+ fn default() -> Self {
+ StandardCharset::Ascii
+ }
+}
+
impl<'a, H, W> vte::Perform for Performer<'a, H, W>
where H: Handler + TermInfo + 'a,
W: io::Write + 'a
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 92242071..a69d3f66 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -271,14 +271,9 @@ impl CharsetMapping for StandardCharset {
}
}
+#[derive(Default, Copy, Clone)]
struct Charsets([StandardCharset; 4]);
-impl Charsets {
- fn new() -> Charsets {
- Charsets([StandardCharset::Ascii; 4])
- }
-}
-
impl Index<CharsetIndex> for Charsets {
type Output = StandardCharset;
fn index(&self, index: CharsetIndex) -> &StandardCharset {
@@ -292,6 +287,18 @@ impl IndexMut<CharsetIndex> for Charsets {
}
}
+#[derive(Default, Copy, Clone)]
+pub struct Cursor {
+ /// The location of this cursor
+ point: Point,
+
+ /// Template cell when using this cursor
+ template: Cell,
+
+ /// Currently configured graphic character sets
+ charsets: Charsets,
+}
+
pub struct Term {
/// The grid
grid: Grid<Cell>,
@@ -315,13 +322,7 @@ pub struct Term {
alt: bool,
/// The cursor
- cursor: Point,
-
- /// Alt cursor
- alt_cursor: Point,
-
- /// Currently configured graphic character sets
- charsets: Charsets,
+ cursor: Cursor,
/// The graphic character set, out of `charsets`, which ASCII is currently
/// being mapped to
@@ -339,15 +340,18 @@ pub struct Term {
/// Size
size_info: SizeInfo,
- /// Template cell
- template_cell: Cell,
-
/// Empty cell
empty_cell: Cell,
pub dirty: bool,
custom_cursor_colors: bool,
+
+ /// Saved cursor from main grid
+ cursor_save: Cursor,
+
+ /// Saved cursor from alt grid
+ cursor_save_alt: Cursor,
}
/// Terminal size info
@@ -422,15 +426,14 @@ impl Term {
grid: grid,
alt_grid: alt,
alt: false,
- cursor: Point::default(),
- alt_cursor: Point::default(),
- active_charset: CharsetIndex::G0,
- charsets: Charsets::new(),
+ active_charset: Default::default(),
+ cursor: Default::default(),
+ cursor_save: Default::default(),
+ cursor_save_alt: Default::default(),
tabs: tabs,
mode: Default::default(),
scroll_region: scroll_region,
size_info: size,
- template_cell: template,
empty_cell: template,
custom_cursor_colors: config.custom_cursor_colors(),
}
@@ -590,7 +593,13 @@ impl Term {
/// background color. Cells with an alternate background color are
/// considered renderable as are cells with any text content.
pub fn renderable_cells(&mut self, selection: &Selection) -> RenderableCellsIter {
- RenderableCellsIter::new(&mut self.grid, &self.cursor, self.mode, selection, self.custom_cursor_colors)
+ RenderableCellsIter::new(
+ &mut self.grid,
+ &self.cursor.point,
+ self.mode,
+ selection,
+ self.custom_cursor_colors
+ )
}
/// Resize terminal to new dimensions
@@ -628,22 +637,22 @@ impl Term {
self.scroll_region = Line(0)..self.grid.num_lines();
// Scroll up to keep cursor in terminal
- if self.cursor.line >= num_lines {
- let lines = self.cursor.line - num_lines + 1;
+ if self.cursor.point.line >= num_lines {
+ let lines = self.cursor.point.line - num_lines + 1;
self.scroll_up(lines);
- self.cursor.line -= lines;
+ self.cursor.point.line -= lines;
}
println!("num_cols, num_lines = {}, {}", num_cols, num_lines);
// Resize grids to new size
- let template = self.template_cell;
+ let template = self.cursor.template;
self.grid.resize(num_lines, num_cols, &template);
self.alt_grid.resize(num_lines, num_cols, &template);
// Ensure cursor is in-bounds
- self.cursor.line = limit(self.cursor.line, Line(0), num_lines - 1);
- self.cursor.col = limit(self.cursor.col, Column(0), num_cols - 1);
+ self.cursor.point.line = limit(self.cursor.point.line, Line(0), num_lines - 1);
+ self.cursor.point.col = limit(self.cursor.point.col, Column(0), num_cols - 1);
// Recreate tabs list
self.tabs = IndexRange::from(Column(0)..self.grid.num_cols())
@@ -655,8 +664,8 @@ impl Term {
if num_lines > old_lines {
// Make sure bottom of terminal is clear
let template = self.empty_cell;
- self.grid.clear_region((self.cursor.line + 1).., |c| c.reset(&template));
- self.alt_grid.clear_region((self.cursor.line + 1).., |c| c.reset(&template));
+ self.grid.clear_region((self.cursor.point.line + 1).., |c| c.reset(&template));
+ self.alt_grid.clear_region((self.cursor.point.line + 1).., |c| c.reset(&template));
}
// Reset scrolling region to new size
@@ -676,7 +685,6 @@ impl Term {
pub fn swap_alt(&mut self) {
self.alt = !self.alt;
::std::mem::swap(&mut self.grid, &mut self.alt_grid);
- ::std::mem::swap(&mut self.cursor, &mut self.alt_cursor);
if self.alt {
let template = self.empty_cell;
@@ -782,32 +790,32 @@ impl ansi::Handler for Term {
{
let location = Point {
- line: self.cursor.line,
- col: self.cursor.col
+ line: self.cursor.point.line,
+ col: self.cursor.point.col
};
let cell = &mut self.grid[&location];
cell.flags.insert(cell::WRAPLINE);
}
- if (self.cursor.line + 1) >= self.scroll_region.end {
+ if (self.cursor.point.line + 1) >= self.scroll_region.end {
self.linefeed();
} else {
- self.cursor.line += 1;
+ self.cursor.point.line += 1;
}
- self.cursor.col = Column(0);
+ self.cursor.point.col = Column(0);
self.input_needs_wrap = false;
}
{
- let cell = &mut self.grid[&self.cursor];
- *cell = self.template_cell;
- cell.c = self.charsets[self.active_charset].map(c);
+ let cell = &mut self.grid[&self.cursor.point];
+ *cell = self.cursor.template;
+ cell.c = self.cursor.charsets[self.active_charset].map(c);
}
- if (self.cursor.col + 1) < self.grid.num_cols() {
- self.cursor.col += 1;
+ if (self.cursor.point.col + 1) < self.grid.num_cols() {
+ self.cursor.point.col += 1;
} else {
self.input_needs_wrap = true;
}
@@ -817,22 +825,22 @@ impl ansi::Handler for Term {
#[inline]
fn goto(&mut self, line: Line, col: Column) {
trace!("goto: line={}, col={}", line, col);
- self.cursor.line = min(line, self.grid.num_lines() - 1);
- self.cursor.col = min(col, self.grid.num_cols() - 1);
+ self.cursor.point.line = min(line, self.grid.num_lines() - 1);
+ self.cursor.point.col = min(col, self.grid.num_cols() - 1);
self.input_needs_wrap = false;
}
#[inline]
fn goto_line(&mut self, line: Line) {
trace!("goto_line: {}", line);
- self.cursor.line = min(line, self.grid.num_lines() - 1);
+ self.cursor.point.line = min(line, self.grid.num_lines() - 1);
self.input_needs_wrap = false;
}
#[inline]
fn goto_col(&mut self, col: Column) {
trace!("goto_col: {}", col);
- self.cursor.col = min(col, self.grid.num_cols() - 1);
+ self.cursor.point.col = min(col, self.grid.num_cols() - 1);
self.input_needs_wrap = false;
}
@@ -840,13 +848,13 @@ impl ansi::Handler for Term {
fn insert_blank(&mut self, count: Column) {
// Ensure inserting within terminal bounds
- let count = min(count, self.size_info.cols() - self.cursor.col);
+ let count = min(count, self.size_info.cols() - self.cursor.point.col);
- let source = self.cursor.col;
- let destination = self.cursor.col + count;
+ let source = self.cursor.point.col;
+ let destination = self.cursor.point.col + count;
let num_cells = (self.size_info.cols() - destination).0;
- let line = self.cursor.line; // borrowck
+ let line = self.cursor.point.line; // borrowck
let line = &mut self.grid[line];
unsafe {
@@ -867,27 +875,27 @@ impl ansi::Handler for Term {
#[inline]
fn move_up(&mut self, lines: Line) {
trace!("move_up: {}", lines);
- let lines = min(self.cursor.line, lines);
- self.cursor.line = min(self.cursor.line - lines, self.grid.num_lines() -1);
+ let lines = min(self.cursor.point.line, lines);
+ self.cursor.point.line = min(self.cursor.point.line - lines, self.grid.num_lines() -1);
}
#[inline]
fn move_down(&mut self, lines: Line) {
trace!("move_down: {}", lines);
- self.cursor.line = min(self.cursor.line + lines, self.grid.num_lines() - 1);
+ self.cursor.point.line = min(self.cursor.point.line + lines, self.grid.num_lines() - 1);
}
#[inline]
fn move_forward(&mut self, cols: Column) {
trace!("move_forward: {}", cols);
- self.cursor.col = min(self.cursor.col + cols, self.grid.num_cols() - 1);
+ self.cursor.point.col = min(self.cursor.point.col + cols, self.grid.num_cols() - 1);
self.input_needs_wrap = false;
}
#[inline]
fn move_backward(&mut self, cols: Column) {
trace!("move_backward: {}", cols);
- self.cursor.col -= min(self.cursor.col, cols);
+ self.cursor.point.col -= min(self.cursor.point.col, cols);
self.input_needs_wrap = false;
}
@@ -910,7 +918,7 @@ impl ansi::Handler for Term {
fn put_tab(&mut self, mut count: i64) {
trace!("put_tab: {}", count);
- let mut col = self.cursor.col;
+ let mut col = self.cursor.point.col;
while col < self.grid.num_cols() && count != 0 {
count -= 1;
loop {
@@ -921,7 +929,7 @@ impl ansi::Handler for Term {
}
}
- self.cursor.col = col;
+ self.cursor.point.col = col;
self.input_needs_wrap = false;
}
@@ -929,8 +937,8 @@ impl ansi::Handler for Term {
#[inline]
fn backspace(&mut self) {
trace!("backspace");
- if self.cursor.col > Column(0) {
- self.cursor.col -= 1;
+ if self.cursor.point.col > Column(0) {
+ self.cursor.point.col -= 1;
self.input_needs_wrap = false;
}
}
@@ -939,7 +947,7 @@ impl ansi::Handler for Term {
#[inline]
fn carriage_return(&mut self) {
trace!("carriage_return");
- self.cursor.col = Column(0);
+ self.cursor.point.col = Column(0);
self.input_needs_wrap = false;
}
@@ -947,10 +955,10 @@ impl ansi::Handler for Term {
#[inline]
fn linefeed(&mut self) {
trace!("linefeed");
- if (self.cursor.line + 1) >= self.scroll_region.end {
+ if (self.cursor.point.line + 1) >= self.scroll_region.end {
self.scroll_up(Line(1));
} else {
- self.cursor.line += 1;
+ self.cursor.point.line += 1;
}
}
@@ -990,8 +998,8 @@ impl ansi::Handler for Term {
#[inline]
fn insert_blank_lines(&mut self, lines: Line) {
trace!("insert_blank_lines: {}", lines);
- if self.scroll_region.contains_(self.cursor.line) {
- let origin = self.cursor.line;
+ if self.scroll_region.contains_(self.cursor.point.line) {
+ let origin = self.cursor.point.line;
self.scroll_down_relative(origin, lines);
}
}
@@ -999,19 +1007,19 @@ impl ansi::Handler for Term {
#[inline]
fn delete_lines(&mut self, lines: Line) {
trace!("delete_lines: {}", lines);
- if self.scroll_region.contains_(self.cursor.line) {
- let origin = self.cursor.line;
+ if self.scroll_region.contains_(self.cursor.point.line) {
+ let origin = self.cursor.point.line;
self.scroll_up_relative(origin, lines);
}
}
#[inline]
fn erase_chars(&mut self, count: Column) {
- trace!("erase_chars: {}, {}", count, self.cursor.col);
- let start = self.cursor.col;
+ trace!("erase_chars: {}, {}", count, self.cursor.point.col);
+ let start = self.cursor.point.col;
let end = min(start + count, self.grid.num_cols() - 1);
- let row = &mut self.grid[self.cursor.line];
+ let row = &mut self.grid[self.cursor.point.line];
let template = self.empty_cell;
for c in &mut row[start..end] {
c.reset(&template);
@@ -1023,11 +1031,11 @@ impl ansi::Handler for Term {
// Ensure deleting within terminal bounds
let count = min(count, self.size_info.cols());
- let start = self.cursor.col;
+ let start = self.cursor.point.col;
let end = min(start + count, self.grid.num_cols() - 1);
let n = (self.size_info.cols() - end).0;
- let line = self.cursor.line; // borrowck
+ let line = self.cursor.point.line; // borrowck
let line = &mut self.grid[line];
unsafe {
@@ -1058,35 +1066,49 @@ impl ansi::Handler for Term {
#[inline]
fn save_cursor_position(&mut self) {
- trace!("[unimplemented] save_cursor_position");
+ trace!("CursorSave");
+ let mut holder = if self.alt {
+ &mut self.cursor_save_alt
+ } else {
+ &mut self.cursor_save
+ };
+
+ *holder = self.cursor;
}
#[inline]
fn restore_cursor_position(&mut self) {
- trace!("[unimplemented] restore_cursor_position");
+ trace!("CursorRestore");
+ let holder = if self.alt {
+ &self.cursor_save_alt
+ } else {
+ &self.cursor_save
+ };
+
+ self.cursor = *holder;
}
#[inline]
fn clear_line(&mut self, mode: ansi::LineClearMode) {
trace!("clear_line: {:?}", mode);
let template = self.empty_cell;
- let col = self.cursor.col;
+ let col = self.cursor.point.col;
match mode {
ansi::LineClearMode::Right => {
- let row = &mut self.grid[self.cursor.line];
+ let row = &mut self.grid[self.cursor.point.line];
for cell in &mut row[col..] {
cell.reset(&template);
}
},
ansi::LineClearMode::Left => {
- let row = &mut self.grid[self.cursor.line];
+ let row = &mut self.grid[self.cursor.point.line];
for cell in &mut row[..(col + 1)] {
cell.reset(&template);
}
},
ansi::LineClearMode::All => {
- let row = &mut self.grid[self.cursor.line];
+ let row = &mut self.grid[self.cursor.point.line];
for cell in &mut row[..] {
cell.reset(&template);
}
@@ -1100,7 +1122,7 @@ impl ansi::Handler for Term {
let template = self.empty_cell;
match mode {
ansi::ClearMode::Below => {
- for row in &mut self.grid[self.cursor.line..] {
+ for row in &mut self.grid[self.cursor.point.line..] {
for cell in row {
cell.reset(&template);
}
@@ -1129,10 +1151,10 @@ impl ansi::Handler for Term {
fn reverse_index(&mut self) {
trace!("reverse_index");
// if cursor is at the top
- if self.cursor.line == self.scroll_region.start {
+ if self.cursor.point.line == self.scroll_region.start {
self.scroll_down(Line(1));
} else {
- self.cursor.line -= min(self.cursor.line, Line(1));
+ self.cursor.point.line -= min(self.cursor.point.line, Line(1));
}
}
@@ -1141,21 +1163,21 @@ impl ansi::Handler for Term {
fn terminal_attribute(&mut self, attr: Attr) {
trace!("Set Attribute: {:?}", attr);
match attr {
- Attr::Foreground(color) => self.template_cell.fg = color,
- Attr::Background(color) => self.template_cell.bg = color,
+ Attr::Foreground(color) => self.cursor.template.fg = color,
+ Attr::Background(color) => self.cursor.template.bg = color,
Attr::Reset => {
- self.template_cell.fg = Color::Named(NamedColor::Foreground);
- self.template_cell.bg = Color::Named(NamedColor::Background);
- self.template_cell.flags = cell::Flags::empty();
+ self.cursor.template.fg = Color::Named(NamedColor::Foreground);
+ self.cursor.template.bg = Color::Named(NamedColor::Background);
+ self.cursor.template.flags = cell::Flags::empty();
},
- Attr::Reverse => self.template_cell.flags.insert(cell::INVERSE),
- Attr::CancelReverse => self.template_cell.flags.remove(cell::INVERSE),
- Attr::Bold => self.template_cell.flags.insert(cell::BOLD),
- Attr::CancelBoldDim => self.template_cell.flags.remove(cell::BOLD),
- Attr::Italic => self.template_cell.flags.insert(cell::ITALIC),
- Attr::CancelItalic => self.template_cell.flags.remove(cell::ITALIC),
- Attr::Underscore => self.template_cell.flags.insert(cell::UNDERLINE),
- Attr::CancelUnderline => self.template_cell.flags.remove(cell::UNDERLINE),
+ Attr::Reverse => self.cursor.template.flags.insert(cell::INVERSE),
+ Attr::CancelReverse => self.cursor.template.flags.remove(cell::INVERSE),
+ Attr::Bold => self.cursor.template.flags.insert(cell::BOLD),
+ Attr::CancelBoldDim => self.cursor.template.flags.remove(cell::BOLD),
+ Attr::Italic => self.cursor.template.flags.insert(cell::ITALIC),
+ Attr::CancelItalic => self.cursor.template.flags.remove(cell::ITALIC),
+ Attr::Underscore => self.cursor.template.flags.insert(cell::UNDERLINE),
+ Attr::CancelUnderline => self.cursor.template.flags.remove(cell::UNDERLINE),
_ => {
debug!("Term got unhandled attr: {:?}", attr);
}
@@ -1166,7 +1188,10 @@ impl ansi::Handler for Term {
fn set_mode(&mut self, mode: ansi::Mode) {
trace!("set_mode: {:?}", mode);
match mode {
- ansi::Mode::SwapScreenAndSetRestoreCursor => self.swap_alt(),
+ ansi::Mode::SwapScreenAndSetRestoreCursor => {
+ self.save_cursor_position();
+ self.swap_alt();
+ },
ansi::Mode::ShowCursor => self.mode.insert(mode::SHOW_CURSOR),
ansi::Mode::CursorKeys => self.mode.insert(mode::APP_CURSOR),
ansi::Mode::ReportMouseClicks => self.mode.insert(mode::MOUSE_REPORT_CLICK),
@@ -1184,7 +1209,10 @@ impl ansi::Handler for Term {
fn unset_mode(&mut self,mode: ansi::Mode) {
trace!("unset_mode: {:?}", mode);
match mode {
- ansi::Mode::SwapScreenAndSetRestoreCursor => self.swap_alt(),
+ ansi::Mode::SwapScreenAndSetRestoreCursor => {
+ self.restore_cursor_position();
+ self.swap_alt();
+ },
ansi::Mode::ShowCursor => self.mode.remove(mode::SHOW_CURSOR),
ansi::Mode::CursorKeys => self.mode.remove(mode::APP_CURSOR),
ansi::Mode::ReportMouseClicks => self.mode.remove(mode::MOUSE_REPORT_CLICK),
@@ -1221,7 +1249,7 @@ impl ansi::Handler for Term {
#[inline]
fn configure_charset(&mut self, index: CharsetIndex, charset: StandardCharset) {
trace!("designate {:?} character set as {:?}", index, charset);
- self.charsets[index] = charset;
+ self.cursor.charsets[index] = charset;
}
#[inline]