mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-18 13:55:23 -05:00
support for inverting the cursor or using colors
This commit is contained in:
parent
2b478e7b9c
commit
e04584b082
8 changed files with 80 additions and 22 deletions
|
@ -48,12 +48,19 @@ font:
|
||||||
# Should display the render timer
|
# Should display the render timer
|
||||||
render_timer: false
|
render_timer: false
|
||||||
|
|
||||||
|
# Use custom cursor colors. If true, display the cursor in the cursor.foreground
|
||||||
|
# and cursor.background colors, otherwise invert the colors of the cursor.
|
||||||
|
custom_cursor_colors: false
|
||||||
|
|
||||||
# Colors (Tomorrow Night Bright)
|
# Colors (Tomorrow Night Bright)
|
||||||
colors:
|
colors:
|
||||||
# Default colors
|
# Default colors
|
||||||
primary:
|
primary:
|
||||||
background: '0x000000'
|
background: '0x000000'
|
||||||
foreground: '0xeaeaea'
|
foreground: '0xeaeaea'
|
||||||
|
cursor:
|
||||||
|
background: '0xffffff'
|
||||||
|
foreground: '0x000000'
|
||||||
|
|
||||||
# Normal colors
|
# Normal colors
|
||||||
normal:
|
normal:
|
||||||
|
|
|
@ -48,12 +48,19 @@ font:
|
||||||
# Should display the render timer
|
# Should display the render timer
|
||||||
render_timer: false
|
render_timer: false
|
||||||
|
|
||||||
|
# Use custom cursor colors. If true, display the cursor in the cursor.foreground
|
||||||
|
# and cursor.background colors, otherwise invert the colors of the cursor.
|
||||||
|
custom_cursor_colors: false
|
||||||
|
|
||||||
# Colors (Tomorrow Night Bright)
|
# Colors (Tomorrow Night Bright)
|
||||||
colors:
|
colors:
|
||||||
# Default colors
|
# Default colors
|
||||||
primary:
|
primary:
|
||||||
background: '0x000000'
|
background: '0x000000'
|
||||||
foreground: '0xeaeaea'
|
foreground: '0xeaeaea'
|
||||||
|
cursor:
|
||||||
|
background: '0xffffff'
|
||||||
|
foreground: '0x000000'
|
||||||
|
|
||||||
# Normal colors
|
# Normal colors
|
||||||
normal:
|
normal:
|
||||||
|
|
|
@ -380,6 +380,10 @@ pub enum NamedColor {
|
||||||
Foreground = 256,
|
Foreground = 256,
|
||||||
/// The background color
|
/// The background color
|
||||||
Background,
|
Background,
|
||||||
|
/// The cursor foreground color
|
||||||
|
CursorForeground,
|
||||||
|
/// The cursor background color
|
||||||
|
CursorBackground,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NamedColor {
|
impl NamedColor {
|
||||||
|
|
|
@ -34,9 +34,10 @@ fn true_bool() -> bool {
|
||||||
///
|
///
|
||||||
/// The first 16 entries are the standard ansi named colors. Items 16..232 are
|
/// The first 16 entries are the standard ansi named colors. Items 16..232 are
|
||||||
/// the color cube. Items 233..256 are the grayscale ramp. Finally, item 256 is
|
/// the color cube. Items 233..256 are the grayscale ramp. Finally, item 256 is
|
||||||
/// the configured foreground color, and item 257 is the configured background
|
/// the configured foreground color, item 257 is the configured background
|
||||||
/// color.
|
/// color, item 258 is the cursor foreground color, item 259 is the cursor
|
||||||
pub struct ColorList([Rgb; 258]);
|
//background color.
|
||||||
|
pub struct ColorList([Rgb; 260]);
|
||||||
|
|
||||||
impl fmt::Debug for ColorList {
|
impl fmt::Debug for ColorList {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
@ -88,6 +89,10 @@ impl ColorList {
|
||||||
// Foreground and background
|
// Foreground and background
|
||||||
self[ansi::NamedColor::Foreground] = colors.primary.foreground;
|
self[ansi::NamedColor::Foreground] = colors.primary.foreground;
|
||||||
self[ansi::NamedColor::Background] = colors.primary.background;
|
self[ansi::NamedColor::Background] = colors.primary.background;
|
||||||
|
|
||||||
|
// Foreground and background for custom cursor colors
|
||||||
|
self[ansi::NamedColor::CursorForeground] = colors.cursor.foreground;
|
||||||
|
self[ansi::NamedColor::CursorBackground] = colors.cursor.background;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_cube(&mut self) {
|
fn fill_cube(&mut self) {
|
||||||
|
@ -218,7 +223,11 @@ pub struct Config {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
render_timer: bool,
|
render_timer: bool,
|
||||||
|
|
||||||
/// Should show render timer
|
/// Should use custom cursor colors
|
||||||
|
#[serde(default)]
|
||||||
|
custom_cursor_colors: bool,
|
||||||
|
|
||||||
|
/// Should draw bold text with brighter colors intead of bold font
|
||||||
#[serde(default="true_bool")]
|
#[serde(default="true_bool")]
|
||||||
draw_bold_text_with_bright_colors: bool,
|
draw_bold_text_with_bright_colors: bool,
|
||||||
|
|
||||||
|
@ -266,6 +275,7 @@ impl Default for Config {
|
||||||
dpi: Default::default(),
|
dpi: Default::default(),
|
||||||
font: Default::default(),
|
font: Default::default(),
|
||||||
render_timer: Default::default(),
|
render_timer: Default::default(),
|
||||||
|
custom_cursor_colors: false,
|
||||||
colors: Default::default(),
|
colors: Default::default(),
|
||||||
key_bindings: Vec::new(),
|
key_bindings: Vec::new(),
|
||||||
mouse_bindings: Vec::new(),
|
mouse_bindings: Vec::new(),
|
||||||
|
@ -668,6 +678,7 @@ pub enum Error {
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Colors {
|
pub struct Colors {
|
||||||
primary: PrimaryColors,
|
primary: PrimaryColors,
|
||||||
|
cursor: PrimaryColors,
|
||||||
normal: AnsiColors,
|
normal: AnsiColors,
|
||||||
bright: AnsiColors,
|
bright: AnsiColors,
|
||||||
}
|
}
|
||||||
|
@ -687,6 +698,10 @@ impl Default for Colors {
|
||||||
background: Rgb { r: 0, g: 0, b: 0 },
|
background: Rgb { r: 0, g: 0, b: 0 },
|
||||||
foreground: Rgb { r: 0xea, g: 0xea, b: 0xea },
|
foreground: Rgb { r: 0xea, g: 0xea, b: 0xea },
|
||||||
},
|
},
|
||||||
|
cursor: PrimaryColors {
|
||||||
|
foreground: Rgb { r: 0, g: 0, b: 0 },
|
||||||
|
background: Rgb { r: 0xff, g: 0xff, b: 0xff },
|
||||||
|
},
|
||||||
normal: AnsiColors {
|
normal: AnsiColors {
|
||||||
black: Rgb {r: 0x00, g: 0x00, b: 0x00},
|
black: Rgb {r: 0x00, g: 0x00, b: 0x00},
|
||||||
red: Rgb {r: 0xd5, g: 0x4e, b: 0x53},
|
red: Rgb {r: 0xd5, g: 0x4e, b: 0x53},
|
||||||
|
@ -933,6 +948,11 @@ impl Config {
|
||||||
self.font.use_thin_strokes
|
self.font.use_thin_strokes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// show cursor as inverted
|
||||||
|
#[inline]
|
||||||
|
pub fn custom_cursor_colors(&self) -> bool {
|
||||||
|
self.custom_cursor_colors
|
||||||
|
}
|
||||||
|
|
||||||
pub fn path(&self) -> Option<&Path> {
|
pub fn path(&self) -> Option<&Path> {
|
||||||
self.config_path
|
self.config_path
|
||||||
|
|
|
@ -95,7 +95,7 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
|
||||||
// This object contains all of the state about what's being displayed. It's
|
// This object contains all of the state about what's being displayed. It's
|
||||||
// wrapped in a clonable mutex since both the I/O loop and display need to
|
// wrapped in a clonable mutex since both the I/O loop and display need to
|
||||||
// access it.
|
// access it.
|
||||||
let terminal = Term::new(display.size().to_owned());
|
let terminal = Term::new(&config, display.size().to_owned());
|
||||||
let terminal = Arc::new(FairMutex::new(terminal));
|
let terminal = Arc::new(FairMutex::new(terminal));
|
||||||
|
|
||||||
// Create the pty
|
// Create the pty
|
||||||
|
@ -156,6 +156,7 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
|
||||||
config = new_config;
|
config = new_config;
|
||||||
display.update_config(&config);
|
display.update_config(&config);
|
||||||
processor.update_config(&config);
|
processor.update_config(&config);
|
||||||
|
terminal.update_config(&config);
|
||||||
terminal.dirty = true;
|
terminal.dirty = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
use ansi::{NamedColor, Color};
|
use ansi::{NamedColor, Color};
|
||||||
use grid;
|
use grid;
|
||||||
use index::Column;
|
use index::Column;
|
||||||
|
@ -98,11 +96,6 @@ impl Cell {
|
||||||
// memcpy template to self
|
// memcpy template to self
|
||||||
*self = *template;
|
*self = *template;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn swap_fg_and_bg(&mut self) {
|
|
||||||
mem::swap(&mut self.fg, &mut self.bg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
//! Exports the `Term` type which is a high-level API for the Grid
|
//! Exports the `Term` type which is a high-level API for the Grid
|
||||||
|
use std::mem;
|
||||||
use std::ops::{Deref, Range, Index, IndexMut};
|
use std::ops::{Deref, Range, Index, IndexMut};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
@ -22,6 +23,7 @@ use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset
|
||||||
use grid::{Grid, ClearRegion, ToRange};
|
use grid::{Grid, ClearRegion, ToRange};
|
||||||
use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive};
|
use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive};
|
||||||
use selection::{Span, Selection};
|
use selection::{Span, Selection};
|
||||||
|
use config::{Config};
|
||||||
|
|
||||||
pub mod cell;
|
pub mod cell;
|
||||||
pub use self::cell::Cell;
|
pub use self::cell::Cell;
|
||||||
|
@ -42,6 +44,7 @@ pub struct RenderableCellsIter<'a> {
|
||||||
line: Line,
|
line: Line,
|
||||||
column: Column,
|
column: Column,
|
||||||
selection: Option<RangeInclusive<index::Linear>>,
|
selection: Option<RangeInclusive<index::Linear>>,
|
||||||
|
cursor_original: Option<IndexedCell>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RenderableCellsIter<'a> {
|
impl<'a> RenderableCellsIter<'a> {
|
||||||
|
@ -54,6 +57,7 @@ impl<'a> RenderableCellsIter<'a> {
|
||||||
cursor: &'b Point,
|
cursor: &'b Point,
|
||||||
mode: TermMode,
|
mode: TermMode,
|
||||||
selection: &Selection,
|
selection: &Selection,
|
||||||
|
custom_cursor_colors: bool,
|
||||||
) -> RenderableCellsIter<'b> {
|
) -> RenderableCellsIter<'b> {
|
||||||
let selection = selection.span()
|
let selection = selection.span()
|
||||||
.map(|span| span.to_range(grid.num_cols()));
|
.map(|span| span.to_range(grid.num_cols()));
|
||||||
|
@ -65,14 +69,27 @@ impl<'a> RenderableCellsIter<'a> {
|
||||||
line: Line(0),
|
line: Line(0),
|
||||||
column: Column(0),
|
column: Column(0),
|
||||||
selection: selection,
|
selection: selection,
|
||||||
}.initialize()
|
cursor_original: None,
|
||||||
|
}.initialize(custom_cursor_colors)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(self) -> Self {
|
fn initialize(mut self, custom_cursor_colors: bool) -> Self {
|
||||||
if self.cursor_is_visible() {
|
if self.cursor_is_visible() {
|
||||||
self.grid[self.cursor].swap_fg_and_bg();
|
self.cursor_original = Some(IndexedCell {
|
||||||
}
|
line: self.cursor.line,
|
||||||
|
column: self.cursor.col,
|
||||||
|
inner: self.grid[self.cursor]
|
||||||
|
});
|
||||||
|
if custom_cursor_colors {
|
||||||
|
let cell = &mut self.grid[self.cursor];
|
||||||
|
cell.fg = Color::Named(NamedColor::CursorForeground);
|
||||||
|
cell.bg = Color::Named(NamedColor::CursorBackground);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let cell = &mut self.grid[self.cursor];
|
||||||
|
mem::swap(&mut cell.fg, &mut cell.bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +104,9 @@ impl<'a> Drop for RenderableCellsIter<'a> {
|
||||||
/// Resets temporary render state on the grid
|
/// Resets temporary render state on the grid
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.cursor_is_visible() {
|
if self.cursor_is_visible() {
|
||||||
self.grid[self.cursor].swap_fg_and_bg();
|
if let Some(ref original) = self.cursor_original {
|
||||||
|
self.grid[self.cursor] = original.inner;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,6 +346,8 @@ pub struct Term {
|
||||||
empty_cell: Cell,
|
empty_cell: Cell,
|
||||||
|
|
||||||
pub dirty: bool,
|
pub dirty: bool,
|
||||||
|
|
||||||
|
custom_cursor_colors: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Terminal size info
|
/// Terminal size info
|
||||||
|
@ -377,7 +398,7 @@ impl Term {
|
||||||
self.next_title.take()
|
self.next_title.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(size: SizeInfo) -> Term {
|
pub fn new(config : &Config, size: SizeInfo) -> Term {
|
||||||
let template = Cell::default();
|
let template = Cell::default();
|
||||||
|
|
||||||
let num_cols = size.cols();
|
let num_cols = size.cols();
|
||||||
|
@ -411,9 +432,14 @@ impl Term {
|
||||||
size_info: size,
|
size_info: size,
|
||||||
template_cell: template,
|
template_cell: template,
|
||||||
empty_cell: template,
|
empty_cell: template,
|
||||||
|
custom_cursor_colors: config.custom_cursor_colors(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_config(&mut self, config: &Config) {
|
||||||
|
self.custom_cursor_colors = config.custom_cursor_colors()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn needs_draw(&self) -> bool {
|
pub fn needs_draw(&self) -> bool {
|
||||||
self.dirty
|
self.dirty
|
||||||
|
@ -564,7 +590,7 @@ impl Term {
|
||||||
/// background color. Cells with an alternate background color are
|
/// background color. Cells with an alternate background color are
|
||||||
/// considered renderable as are cells with any text content.
|
/// considered renderable as are cells with any text content.
|
||||||
pub fn renderable_cells(&mut self, selection: &Selection) -> RenderableCellsIter {
|
pub fn renderable_cells(&mut self, selection: &Selection) -> RenderableCellsIter {
|
||||||
RenderableCellsIter::new(&mut self.grid, &self.cursor, self.mode, selection)
|
RenderableCellsIter::new(&mut self.grid, &self.cursor, self.mode, selection, self.custom_cursor_colors)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize terminal to new dimensions
|
/// Resize terminal to new dimensions
|
||||||
|
@ -1248,7 +1274,7 @@ mod tests {
|
||||||
cell_width: 3.0,
|
cell_width: 3.0,
|
||||||
cell_height: 3.0,
|
cell_height: 3.0,
|
||||||
};
|
};
|
||||||
let mut term = Term::new(size);
|
let mut term = Term::new(&Default::default(), size);
|
||||||
let cursor = Point::new(Line(0), Column(0));
|
let cursor = Point::new(Line(0), Column(0));
|
||||||
term.configure_charset(CharsetIndex::G0,
|
term.configure_charset(CharsetIndex::G0,
|
||||||
StandardCharset::SpecialCharacterAndLineDrawing);
|
StandardCharset::SpecialCharacterAndLineDrawing);
|
||||||
|
@ -1306,7 +1332,7 @@ mod benches {
|
||||||
let mut grid: Grid<Cell> = json::from_str(&serialized_grid).unwrap();
|
let mut grid: Grid<Cell> = json::from_str(&serialized_grid).unwrap();
|
||||||
let size: SizeInfo = json::from_str(&serialized_size).unwrap();
|
let size: SizeInfo = json::from_str(&serialized_size).unwrap();
|
||||||
|
|
||||||
let mut terminal = Term::new(size);
|
let mut terminal = Term::new(&Default::default(), size);
|
||||||
mem::swap(&mut terminal.grid, &mut grid);
|
mem::swap(&mut terminal.grid, &mut grid);
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn ref_test(dir: &Path) {
|
||||||
let size: SizeInfo = json::from_str(&serialized_size).unwrap();
|
let size: SizeInfo = json::from_str(&serialized_size).unwrap();
|
||||||
let grid: Grid<Cell> = json::from_str(&serialized_grid).unwrap();
|
let grid: Grid<Cell> = json::from_str(&serialized_grid).unwrap();
|
||||||
|
|
||||||
let mut terminal = Term::new(size);
|
let mut terminal = Term::new(&Default::default(), size);
|
||||||
let mut parser = ansi::Processor::new();
|
let mut parser = ansi::Processor::new();
|
||||||
|
|
||||||
for byte in recording {
|
for byte in recording {
|
||||||
|
|
Loading…
Reference in a new issue