summaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/term/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/term/mod.rs')
-rw-r--r--alacritty_terminal/src/term/mod.rs456
1 files changed, 295 insertions, 161 deletions
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index ac5e56b5..89c3723f 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -31,10 +31,11 @@ use crate::event::{Event, EventListener};
use crate::grid::{
BidirectionalIterator, DisplayIter, Grid, GridCell, IndexRegion, Indexed, Scroll,
};
-use crate::index::{self, Column, IndexRange, Line, Point};
+use crate::index::{self, Column, IndexRange, Line, Point, Side};
use crate::selection::{Selection, SelectionRange};
use crate::term::cell::{Cell, Flags, LineLength};
use crate::term::color::Rgb;
+use crate::vi_mode::{ViModeCursor, ViMotion};
pub mod cell;
pub mod color;
@@ -180,7 +181,17 @@ impl<T> Search for Term<T> {
}
}
-/// A key for caching cursor glyphs
+/// Cursor storing all information relevant for rendering.
+#[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize)]
+struct RenderableCursor {
+ text_color: Option<Rgb>,
+ cursor_color: Option<Rgb>,
+ key: CursorKey,
+ point: Point,
+ rendered: bool,
+}
+
+/// A key for caching cursor glyphs.
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, Deserialize)]
pub struct CursorKey {
pub style: CursorStyle,
@@ -198,10 +209,7 @@ pub struct CursorKey {
pub struct RenderableCellsIter<'a, C> {
inner: DisplayIter<'a, Cell>,
grid: &'a Grid<Cell>,
- cursor: &'a Point,
- cursor_offset: usize,
- cursor_key: Option<CursorKey>,
- cursor_style: CursorStyle,
+ cursor: RenderableCursor,
config: &'a Config<C>,
colors: &'a color::List,
selection: Option<SelectionRange<Line>>,
@@ -216,12 +224,10 @@ impl<'a, C> RenderableCellsIter<'a, C> {
term: &'b Term<T>,
config: &'b Config<C>,
selection: Option<SelectionRange>,
- mut cursor_style: CursorStyle,
) -> RenderableCellsIter<'b, C> {
let grid = &term.grid;
let num_cols = grid.num_cols();
- let cursor_offset = grid.num_lines().0 - term.cursor.point.line.0 - 1;
let inner = grid.display_iter();
let selection_range = selection.and_then(|span| {
@@ -242,29 +248,13 @@ impl<'a, C> RenderableCellsIter<'a, C> {
Some(SelectionRange::new(start, end, span.is_block))
});
- // Load cursor glyph
- let cursor = &term.cursor.point;
- let cursor_visible = term.mode.contains(TermMode::SHOW_CURSOR) && grid.contains(cursor);
- let cursor_key = if cursor_visible {
- let is_wide =
- grid[cursor].flags.contains(Flags::WIDE_CHAR) && (cursor.col + 1) < num_cols;
- Some(CursorKey { style: cursor_style, is_wide })
- } else {
- // Use hidden cursor so text will not get inverted
- cursor_style = CursorStyle::Hidden;
- None
- };
-
RenderableCellsIter {
- cursor,
- cursor_offset,
+ cursor: term.renderable_cursor(config),
grid,
inner,
selection: selection_range,
config,
colors: &term.colors,
- cursor_key,
- cursor_style,
}
}
@@ -275,6 +265,18 @@ impl<'a, C> RenderableCellsIter<'a, C> {
None => return false,
};
+ // Do not invert block cursor at selection boundaries
+ if self.cursor.key.style == CursorStyle::Block
+ && self.cursor.point == point
+ && (selection.start == point
+ || selection.end == point
+ || (selection.is_block
+ && ((selection.start.line == point.line && selection.end.col == point.col)
+ || (selection.end.line == point.line && selection.start.col == point.col))))
+ {
+ return false;
+ }
+
// Point itself is selected
if selection.contains(point.col, point.line) {
return true;
@@ -442,43 +444,46 @@ impl<'a, C> Iterator for RenderableCellsIter<'a, C> {
#[inline]
fn next(&mut self) -> Option<Self::Item> {
loop {
- if self.cursor_offset == self.inner.offset() && self.inner.column() == self.cursor.col {
- let selected = self.is_selected(Point::new(self.cursor.line, self.cursor.col));
+ if self.cursor.point.line == self.inner.line()
+ && self.cursor.point.col == self.inner.column()
+ {
+ let selected = self.is_selected(self.cursor.point);
+
+ // Handle cell below cursor
+ if self.cursor.rendered {
+ let mut cell =
+ RenderableCell::new(self.config, self.colors, self.inner.next()?, selected);
- // Handle cursor
- if let Some(cursor_key) = self.cursor_key.take() {
+ if self.cursor.key.style == CursorStyle::Block {
+ mem::swap(&mut cell.bg, &mut cell.fg);
+
+ if let Some(color) = self.cursor.text_color {
+ cell.fg = color;
+ }
+ }
+
+ return Some(cell);
+ } else {
+ // Handle cursor
+ self.cursor.rendered = true;
+
+ let buffer_point = self.grid.visible_to_buffer(self.cursor.point);
let cell = Indexed {
- inner: self.grid[self.cursor],
- column: self.cursor.col,
- // Using `self.cursor.line` leads to inconsitent cursor position when
- // scrolling. See https://github.com/alacritty/alacritty/issues/2570 for more
- // info.
- line: self.inner.line(),
+ inner: self.grid[buffer_point.line][buffer_point.col],
+ column: self.cursor.point.col,
+ line: self.cursor.point.line,
};
let mut renderable_cell =
RenderableCell::new(self.config, self.colors, cell, selected);
- renderable_cell.inner = RenderableCellContent::Cursor(cursor_key);
+ renderable_cell.inner = RenderableCellContent::Cursor(self.cursor.key);
- if let Some(color) = self.config.cursor_cursor_color() {
- renderable_cell.fg = RenderableCell::compute_bg_rgb(self.colors, color);
+ if let Some(color) = self.cursor.cursor_color {
+ renderable_cell.fg = color;
}
return Some(renderable_cell);
- } else {
- let mut cell =
- RenderableCell::new(self.config, self.colors, self.inner.next()?, selected);
-
- if self.cursor_style == CursorStyle::Block {
- std::mem::swap(&mut cell.bg, &mut cell.fg);
-
- if let Some(color) = self.config.cursor_text_color() {
- cell.fg = color;
- }
- }
-
- return Some(cell);
}
} else {
let cell = self.inner.next()?;
@@ -497,26 +502,27 @@ pub mod mode {
use bitflags::bitflags;
bitflags! {
- pub struct TermMode: u16 {
- const SHOW_CURSOR = 0b0000_0000_0000_0001;
- const APP_CURSOR = 0b0000_0000_0000_0010;
- const APP_KEYPAD = 0b0000_0000_0000_0100;
- const MOUSE_REPORT_CLICK = 0b0000_0000_0000_1000;
- const BRACKETED_PASTE = 0b0000_0000_0001_0000;
- const SGR_MOUSE = 0b0000_0000_0010_0000;
- const MOUSE_MOTION = 0b0000_0000_0100_0000;
- const LINE_WRAP = 0b0000_0000_1000_0000;
- const LINE_FEED_NEW_LINE = 0b0000_0001_0000_0000;
- const ORIGIN = 0b0000_0010_0000_0000;
- const INSERT = 0b0000_0100_0000_0000;
- const FOCUS_IN_OUT = 0b0000_1000_0000_0000;
- const ALT_SCREEN = 0b0001_0000_0000_0000;
- const MOUSE_DRAG = 0b0010_0000_0000_0000;
- const MOUSE_MODE = 0b0010_0000_0100_1000;
- const UTF8_MOUSE = 0b0100_0000_0000_0000;
- const ALTERNATE_SCROLL = 0b1000_0000_0000_0000;
- const ANY = 0b1111_1111_1111_1111;
+ pub struct TermMode: u32 {
const NONE = 0;
+ const SHOW_CURSOR = 0b0000_0000_0000_0000_0001;
+ const APP_CURSOR = 0b0000_0000_0000_0000_0010;
+ const APP_KEYPAD = 0b0000_0000_0000_0000_0100;
+ const MOUSE_REPORT_CLICK = 0b0000_0000_0000_0000_1000;
+ const BRACKETED_PASTE = 0b0000_0000_0000_0001_0000;
+ const SGR_MOUSE = 0b0000_0000_0000_0010_0000;
+ const MOUSE_MOTION = 0b0000_0000_0000_0100_0000;
+ const LINE_WRAP = 0b0000_0000_0000_1000_0000;
+ const LINE_FEED_NEW_LINE = 0b0000_0000_0001_0000_0000;
+ const ORIGIN = 0b0000_0000_0010_0000_0000;
+ const INSERT = 0b0000_0000_0100_0000_0000;
+ const FOCUS_IN_OUT = 0b0000_0000_1000_0000_0000;
+ const ALT_SCREEN = 0b0000_0001_0000_0000_0000;
+ const MOUSE_DRAG = 0b0000_0010_0000_0000_0000;
+ const MOUSE_MODE = 0b0000_0010_0000_0100_1000;
+ const UTF8_MOUSE = 0b0000_0100_0000_0000_0000;
+ const ALTERNATE_SCROLL = 0b0000_1000_0000_0000_0000;
+ const VI = 0b0001_0000_0000_0000_0000;
+ const ANY = std::u32::MAX;
}
}
@@ -730,11 +736,69 @@ impl VisualBell {
}
}
+/// Terminal size info.
+#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
+pub struct SizeInfo {
+ /// Terminal window width.
+ pub width: f32,
+
+ /// Terminal window height.
+ pub height: f32,
+
+ /// Width of individual cell.
+ pub cell_width: f32,
+
+ /// Height of individual cell.
+ pub cell_height: f32,
+
+ /// Horizontal window padding.
+ pub padding_x: f32,
+
+ /// Horizontal window padding.
+ pub padding_y: f32,
+
+ /// DPI factor of the current window.
+ #[serde(default)]
+ pub dpr: f64,
+}
+
+impl SizeInfo {
+ #[inline]
+ pub fn lines(&self) -> Line {
+ Line(((self.height - 2. * self.padding_y) / self.cell_height) as usize)
+ }
+
+ #[inline]
+ pub fn cols(&self) -> Column {
+ Column(((self.width - 2. * self.padding_x) / self.cell_width) as usize)
+ }
+
+ /// Check if coordinates are inside the terminal grid.
+ ///
+ /// The padding is not counted as part of the grid.
+ pub fn contains_point(&self, x: usize, y: usize) -> bool {
+ x < (self.width - self.padding_x) as usize
+ && x >= self.padding_x as usize
+ && y < (self.height - self.padding_y) as usize
+ && y >= self.padding_y as usize
+ }
+
+ pub fn pixels_to_coords(&self, x: usize, y: usize) -> Point {
+ let col = Column(x.saturating_sub(self.padding_x as usize) / (self.cell_width as usize));
+ let line = Line(y.saturating_sub(self.padding_y as usize) / (self.cell_height as usize));
+
+ Point {
+ line: min(line, Line(self.lines().saturating_sub(1))),
+ col: min(col, Column(self.cols().saturating_sub(1))),
+ }
+ }
+}
+
pub struct Term<T> {
- /// Terminal focus
+ /// Terminal focus.
pub is_focused: bool,
- /// The grid
+ /// The grid.
grid: Grid<Cell>,
/// Tracks if the next call to input will need to first handle wrapping.
@@ -744,23 +808,25 @@ pub struct Term<T> {
/// arrays. Without it we would have to sanitize cursor.col every time we used it.
input_needs_wrap: bool,
- /// Alternate grid
+ /// Alternate grid.
alt_grid: Grid<Cell>,
- /// Alt is active
+ /// Alt is active.
alt: bool,
- /// The cursor
+ /// The cursor.
cursor: Cursor,
- /// The graphic character set, out of `charsets`, which ASCII is currently
- /// being mapped to
+ /// Cursor location for vi mode.
+ pub vi_mode_cursor: ViModeCursor,
+
+ /// Index into `charsets`, pointing to what ASCII is currently being mapped to.
active_charset: CharsetIndex,
- /// Tabstops
+ /// Tabstops.
tabs: TabStops,
- /// Mode flags
+ /// Mode flags.
mode: TermMode,
/// Scroll region.
@@ -772,33 +838,36 @@ pub struct Term<T> {
pub visual_bell: VisualBell,
- /// Saved cursor from main grid
+ /// Saved cursor from main grid.
cursor_save: Cursor,
- /// Saved cursor from alt grid
+ /// Saved cursor from alt grid.
cursor_save_alt: Cursor,
semantic_escape_chars: String,
- /// Colors used for rendering
+ /// Colors used for rendering.
colors: color::List,
- /// Is color in `colors` modified or not
+ /// Is color in `colors` modified or not.
color_modified: [bool; color::COUNT],
- /// Original colors from config
+ /// Original colors from config.
original_colors: color::List,
- /// Current style of the cursor
+ /// Current style of the cursor.
cursor_style: Option<CursorStyle>,
- /// Default style for resetting the cursor
+ /// Default style for resetting the cursor.
default_cursor_style: CursorStyle,
+ /// Style of the vi mode cursor.
+ vi_mode_cursor_style: Option<CursorStyle>,
+
/// Clipboard access coupled to the active window
clipboard: Clipboard,
- /// Proxy for sending events to the event loop
+ /// Proxy for sending events to the event loop.
event_proxy: T,
/// Current title of the window.
@@ -815,64 +884,6 @@ pub struct Term<T> {
title_stack: Vec<Option<String>>,
}
-/// Terminal size info
-#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
-pub struct SizeInfo {
- /// Terminal window width
- pub width: f32,
-
- /// Terminal window height
- pub height: f32,
-
- /// Width of individual cell
- pub cell_width: f32,
-
- /// Height of individual cell
- pub cell_height: f32,
-
- /// Horizontal window padding
- pub padding_x: f32,
-
- /// Horizontal window padding
- pub padding_y: f32,
-
- /// DPI factor of the current window
- #[serde(default)]
- pub dpr: f64,
-}
-
-impl SizeInfo {
- #[inline]
- pub fn lines(&self) -> Line {
- Line(((self.height - 2. * self.padding_y) / self.cell_height) as usize)
- }
-
- #[inline]
- pub fn cols(&self) -> Column {
- Column(((self.width - 2. * self.padding_x) / self.cell_width) as usize)
- }
-
- /// Check if coordinates are inside the terminal grid.
- ///
- /// The padding is not counted as part of the grid.
- pub fn contains_point(&self, x: usize, y: usize) -> bool {
- x < (self.width - self.padding_x) as usize
- && x >= self.padding_x as usize
- && y < (self.height - self.padding_y) as usize
- && y >= self.padding_y as usize
- }
-
- pub fn pixels_to_coords(&self, x: usize, y: usize) -> Point {
- let col = Column(x.saturating_sub(self.padding_x as usize) / (self.cell_width as usize));
- let line = Line(y.saturating_sub(self.padding_y as usize) / (self.cell_height as usize));
-
- Point {
- line: min(line, Line(self.lines().saturating_sub(1))),
- col: min(col, Column(self.cols().saturating_sub(1))),
- }
- }
-}
-
impl<T> Term<T> {
pub fn selection(&self) -> &Option<Selection> {
&self.grid.selection
@@ -920,6 +931,7 @@ impl<T> Term<T> {
alt: false,
active_charset: Default::default(),
cursor: Default::default(),
+ vi_mode_cursor: Default::default(),
cursor_save: Default::default(),
cursor_save_alt: Default::default(),
tabs,
@@ -931,6 +943,7 @@ impl<T> Term<T> {
semantic_escape_chars: config.selection.semantic_escape_chars().to_owned(),
cursor_style: None,
default_cursor_style: config.cursor.style,
+ vi_mode_cursor_style: config.cursor.vi_mode_style,
dynamic_title: config.dynamic_title(),
clipboard,
event_proxy,
@@ -959,6 +972,7 @@ impl<T> Term<T> {
self.mode.remove(TermMode::ALTERNATE_SCROLL);
}
self.default_cursor_style = config.cursor.style;
+ self.vi_mode_cursor_style = config.cursor.vi_mode_style;
self.default_title = config.window.title.clone();
self.dynamic_title = config.dynamic_title();
@@ -1105,13 +1119,7 @@ impl<T> Term<T> {
pub fn renderable_cells<'b, C>(&'b self, config: &'b Config<C>) -> RenderableCellsIter<'_, C> {
let selection = self.grid.selection.as_ref().and_then(|s| s.to_range(self));
- let cursor = if self.is_focused || !config.cursor.unfocused_hollow() {
- self.cursor_style.unwrap_or(self.default_cursor_style)
- } else {
- CursorStyle::HollowBlock
- };
-
- RenderableCellsIter::new(&self, config, selection, cursor)
+ RenderableCellsIter::new(&self, config, selection)
}
/// Resize terminal to new dimensions
@@ -1129,12 +1137,12 @@ impl<T> Term<T> {
self.grid.selection = None;
self.alt_grid.selection = None;
- // Should not allow less than 1 col, causes all sorts of checks to be required.
+ // Should not allow less than 2 cols, causes all sorts of checks to be required.
if num_cols <= Column(1) {
num_cols = Column(2);
}
- // Should not allow less than 1 line, causes all sorts of checks to be required.
+ // Should not allow less than 2 lines, causes all sorts of checks to be required.
if num_lines <= Line(1) {
num_lines = Line(2);
}
@@ -1178,6 +1186,8 @@ impl<T> Term<T> {
self.cursor_save.point.line = min(self.cursor_save.point.line, num_lines - 1);
self.cursor_save_alt.point.col = min(self.cursor_save_alt.point.col, num_cols - 1);
self.cursor_save_alt.point.line = min(self.cursor_save_alt.point.line, num_lines - 1);
+ self.vi_mode_cursor.point.col = min(self.vi_mode_cursor.point.col, num_cols - 1);
+ self.vi_mode_cursor.point.line = min(self.vi_mode_cursor.point.line, num_lines - 1);
// Recreate tabs list
self.tabs.resize(self.grid.num_cols());
@@ -1200,7 +1210,7 @@ impl<T> Term<T> {
}
self.alt = !self.alt;
- std::mem::swap(&mut self.grid, &mut self.alt_grid);
+ mem::swap(&mut self.grid, &mut self.alt_grid);
}
/// Scroll screen down
@@ -1258,10 +1268,58 @@ impl<T> Term<T> {
self.event_proxy.send_event(Event::Exit);
}
+ #[inline]
pub fn clipboard(&mut self) -> &mut Clipboard {
&mut self.clipboard
}
+ /// Toggle the vi mode.
+ #[inline]
+ pub fn toggle_vi_mode(&mut self) {
+ self.mode ^= TermMode::VI;
+ self.grid.selection = None;
+
+ // Reset vi mode cursor position to match primary cursor
+ if self.mode.contains(TermMode::VI) {
+ let line = min(self.cursor.point.line + self.grid.display_offset(), self.lines() - 1);
+ self.vi_mode_cursor = ViModeCursor::new(Point::new(line, self.cursor.point.col));
+ }
+
+ self.dirty = true;
+ }
+
+ /// Move vi mode cursor.
+ #[inline]
+ pub fn vi_motion(&mut self, motion: ViMotion)
+ where
+ T: EventListener,
+ {
+ // Require vi mode to be active
+ if !self.mode.contains(TermMode::VI) {
+ return;
+ }
+
+ // Move cursor
+ self.vi_mode_cursor = self.vi_mode_cursor.motion(self, motion);
+
+ // Update selection if one is active
+ let viewport_point = self.visible_to_buffer(self.vi_mode_cursor.point);
+ if let Some(selection) = &mut self.grid.selection {
+ // Do not extend empty selections started by single mouse click
+ if !selection.is_empty() {
+ selection.update(viewport_point, Side::Left);
+ selection.include_all();
+ }
+ }
+
+ self.dirty = true;
+ }
+
+ #[inline]
+ pub fn semantic_escape_chars(&self) -> &str {
+ &self.semantic_escape_chars
+ }
+
/// Insert a linebreak at the current cursor position.
#[inline]
fn wrapline(&mut self)
@@ -1297,6 +1355,65 @@ impl<T> Term<T> {
cell.c = self.cursor.charsets[self.active_charset].map(c);
cell
}
+
+ /// Get rendering information about the active cursor.
+ fn renderable_cursor<C>(&self, config: &Config<C>) -> RenderableCursor {
+ let vi_mode = self.mode.contains(TermMode::VI);
+
+ // Cursor position
+ let mut point = if vi_mode {
+ self.vi_mode_cursor.point
+ } else {
+ let mut point = self.cursor.point;
+ point.line += self.grid.display_offset();
+ point
+ };
+
+ // Cursor shape
+ let hidden = !self.mode.contains(TermMode::SHOW_CURSOR) || point.line >= self.lines();
+ let cursor_style = if hidden && !vi_mode {
+ point.line = Line(0);
+ CursorStyle::Hidden
+ } else if !self.is_focused && config.cursor.unfocused_hollow() {
+ CursorStyle::HollowBlock
+ } else {
+ let cursor_style = self.cursor_style.unwrap_or(self.default_cursor_style);
+
+ if vi_mode {
+ self.vi_mode_cursor_style.unwrap_or(cursor_style)
+ } else {
+ cursor_style
+ }
+ };
+
+ // Cursor colors
+ let (text_color, cursor_color) = if vi_mode {
+ (config.vi_mode_cursor_text_color(), config.vi_mode_cursor_cursor_color())
+ } else {
+ let cursor_cursor_color = config.cursor_cursor_color().map(|c| self.colors[c]);
+ (config.cursor_text_color(), cursor_cursor_color)
+ };
+
+ // Expand across wide cell when inside wide char or spacer
+ let buffer_point = self.visible_to_buffer(point);
+ let cell = self.grid[buffer_point.line][buffer_point.col];
+ let is_wide = if cell.flags.contains(Flags::WIDE_CHAR_SPACER)
+ && self.grid[buffer_point.line][buffer_point.col - 1].flags.contains(Flags::WIDE_CHAR)
+ {
+ point.col -= 1;
+ true
+ } else {
+ cell.flags.contains(Flags::WIDE_CHAR)
+ };
+
+ RenderableCursor {
+ text_color,
+ cursor_color,
+ key: CursorKey { style: cursor_style, is_wide },
+ point,
+ rendered: false,
+ }
+ }
}
impl<T> TermInfo for Term<T> {
@@ -2184,7 +2301,7 @@ mod tests {
use crate::event::{Event, EventListener};
use crate::grid::{Grid, Scroll};
use crate::index::{Column, Line, Point, Side};
- use crate::selection::Selection;
+ use crate::selection::{Selection, SelectionType};
use crate::term::cell::{Cell, Flags};
use crate::term::{SizeInfo, Term};
@@ -2222,17 +2339,29 @@ mod tests {
mem::swap(&mut term.semantic_escape_chars, &mut escape_chars);
{
- *term.selection_mut() = Some(Selection::semantic(Point { line: 2, col: Column(1) }));
+ *term.selection_mut() = Some(Selection::new(
+ SelectionType::Semantic,
+ Point { line: 2, col: Column(1) },
+ Side::Left,
+ ));
assert_eq!(term.selection_to_string(), Some(String::from("aa")));
}
{
- *term.selection_mut() = Some(Selection::semantic(Point { line: 2, col: Column(4) }));
+ *term.selection_mut() = Some(Selection::new(
+ SelectionType::Semantic,
+ Point { line: 2, col: Column(4) },
+ Side::Left,
+ ));
assert_eq!(term.selection_to_string(), Some(String::from("aaa")));
}
{
- *term.selection_mut() = Some(Selection::semantic(Point { line: 1, col: Column(1) }));
+ *term.selection_mut() = Some(Selection::new(
+ SelectionType::Semantic,
+ Point { line: 1, col: Column(1) },
+ Side::Left,
+ ));
assert_eq!(term.selection_to_string(), Some(String::from("aaa")));
}
}
@@ -2258,7 +2387,11 @@ mod tests {
mem::swap(&mut term.grid, &mut grid);
- *term.selection_mut() = Some(Selection::lines(Point { line: 0, col: Column(3) }));
+ *term.selection_mut() = Some(Selection::new(
+ SelectionType::Lines,
+ Point { line: 0, col: Column(3) },
+ Side::Left,
+ ));
assert_eq!(term.selection_to_string(), Some(String::from("\"aa\"a\n")));
}
@@ -2285,7 +2418,8 @@ mod tests {
mem::swap(&mut term.grid, &mut grid);
- let mut selection = Selection::simple(Point { line: 2, col: Column(0) }, Side::Left);
+ let mut selection =
+ Selection::new(SelectionType::Simple, Point { line: 2, col: Column(0) }, Side::Left);
selection.update(Point { line: 0, col: Column(2) }, Side::Right);
*term.selection_mut() = Some(selection);
assert_eq!(term.selection_to_string(), Some("aaa\n\naaa\n".into()));