Add hidden escape sequence

This adds support for the `hidden` escape sequence `\e[8m`, which will
render the text as invisible.

This has also raised a few questions about the rendering of foreground
and background colors and their interaction with the different escape
sequences. Previously, Alacritty has oriented itself after URxvt, which
has some strange and unexpected behavior.

The new implementation of color inversion is modeled after XTerm, which
has a consistent pattern of always inverting the foreground and
background colors. This should hopefully lead to less confusion for the
user and a more consistent behavior.

A full matrix showcasing the new way Alacritty inverses text can be
found here:
https://i.imgur.com/d1XavG7.png

This fixes #1454 and fixes #1455.
This commit is contained in:
Christian Duerr 2018-09-19 19:18:51 +00:00 committed by GitHub
parent f0ce64e24b
commit d387ebe1d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 42 deletions

View File

@ -8,11 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Implement the `hidden` escape sequence (`echo -e "\e[8mTEST"`)
- Add support for macOS systemwide dark mode
- Set the environment variable `COLORTERM="truecolor"` to advertise 24-bit color support
### Changed
- Inverse/Selection color is now modelled after XTerm/VTE instead of URxvt to improve consistency
- First click on unfocused Alacritty windows is no longer ignored on platforms other than macOS
## Version 0.2.0

View File

@ -1,14 +1,53 @@
#!/bin/bash
printf "Fg=Black, Bg=Background \e[30;49mTEST\e[m\n"
printf "Fg=Black, Bg=Black \e[30;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=Background \e[39;49mTEST\e[m\n"
printf "Fg=Foreground,Bg=Black \e[39;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=White \e[39;47mTEST\e[m\n"
printf "Fg=White, Bg=Foreground \e[37;39mTEST\e[m\n"
printf "Fg=Black, Bg=Background, Inverse \e[7;30;49mTEST\e[m\n"
printf "Fg=Black, Bg=Black, Inverse \e[7;30;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=Background, Inverse \e[7;39;49mTEST\e[m\n"
printf "Fg=Foreground,Bg=Black, Inverse \e[7;39;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=White, Inverse \e[7;39;47mTEST\e[m\n"
printf "Fg=White, Bg=Foreground, Inverse \e[7;37;39mTEST\e[m\n"
printf "Fg=Black Bg=Black \e[30;40mTEST\e[m\n"
printf "Fg=Black Bg=White \e[30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red \e[30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG \e[30;49mTEST\e[m\n"
printf "Fg=White Bg=Black \e[97;40mTEST\e[m\n"
printf "Fg=White Bg=White \e[97;107mTEST\e[m\n"
printf "Fg=White Bg=Red \e[97;41mTEST\e[m\n"
printf "Fg=White Bg=BG \e[97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black \e[31;40mTEST\e[m\n"
printf "Fg=Red Bg=White \e[31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red \e[31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG \e[31;49mTEST\e[m\n"
printf "\n"
printf "Fg=Black Bg=Black Inverse \e[7;30;40mTEST\e[m\n"
printf "Fg=Black Bg=White Inverse \e[7;30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red Inverse \e[7;30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG Inverse \e[7;30;49mTEST\e[m\n"
printf "Fg=White Bg=Black Inverse \e[7;97;40mTEST\e[m\n"
printf "Fg=White Bg=White Inverse \e[7;97;107mTEST\e[m\n"
printf "Fg=White Bg=Red Inverse \e[7;97;41mTEST\e[m\n"
printf "Fg=White Bg=BG Inverse \e[7;97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black Inverse \e[7;31;40mTEST\e[m\n"
printf "Fg=Red Bg=White Inverse \e[7;31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red Inverse \e[7;31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG Inverse \e[7;31;49mTEST\e[m\n"
printf "\n"
printf "Fg=Black Bg=Black Hidden \e[8;30;40mTEST\e[m\n"
printf "Fg=Black Bg=White Hidden \e[8;30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red Hidden \e[8;30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG Hidden \e[8;30;49mTEST\e[m\n"
printf "Fg=White Bg=Black Hidden \e[8;97;40mTEST\e[m\n"
printf "Fg=White Bg=White Hidden \e[8;97;107mTEST\e[m\n"
printf "Fg=White Bg=Red Hidden \e[8;97;41mTEST\e[m\n"
printf "Fg=White Bg=BG Hidden \e[8;97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black Hidden \e[8;31;40mTEST\e[m\n"
printf "Fg=Red Bg=White Hidden \e[8;31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red Hidden \e[8;31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG Hidden \e[8;31;49mTEST\e[m\n"
printf "\n"
printf "Fg=Black Bg=Black Hid+Inv \e[7;8;30;40mTEST\e[m\n"
printf "Fg=Black Bg=White Hid+Inv \e[7;8;30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red Hid+Inv \e[7;8;30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG Hid+Inv \e[7;8;30;49mTEST\e[m\n"
printf "Fg=White Bg=Black Hid+Inv \e[7;8;97;40mTEST\e[m\n"
printf "Fg=White Bg=White Hid+Inv \e[7;8;97;107mTEST\e[m\n"
printf "Fg=White Bg=Red Hid+Inv \e[7;8;97;41mTEST\e[m\n"
printf "Fg=White Bg=BG Hid+Inv \e[7;8;97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black Hid+Inv \e[7;8;31;40mTEST\e[m\n"
printf "Fg=Red Bg=White Hid+Inv \e[7;8;31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red Hid+Inv \e[7;8;31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG Hid+Inv \e[7;8;31;49mTEST\e[m\n"

View File

@ -835,12 +835,17 @@ impl<'a> RenderApi<'a> {
glyph_cache.font_key
};
let glyph_key = GlyphKey {
let mut glyph_key = GlyphKey {
font_key,
size: glyph_cache.font_size,
c: cell.c
};
// Don't render text of HIDDEN cells
if cell.flags.contains(cell::Flags::HIDDEN) {
glyph_key.c = ' ';
}
// Add cell to batch
{
let glyph = glyph_cache.get(glyph_key, self);

View File

@ -18,15 +18,16 @@ use index::Column;
bitflags! {
#[derive(Serialize, Deserialize)]
pub struct Flags: u32 {
const INVERSE = 0b0000_0001;
const BOLD = 0b0000_0010;
const ITALIC = 0b0000_0100;
const UNDERLINE = 0b0000_1000;
const WRAPLINE = 0b0001_0000;
const WIDE_CHAR = 0b0010_0000;
const WIDE_CHAR_SPACER = 0b0100_0000;
const DIM = 0b1000_0000;
const DIM_BOLD = 0b1000_0010;
const INVERSE = 0b0_0000_0001;
const BOLD = 0b0_0000_0010;
const ITALIC = 0b0_0000_0100;
const UNDERLINE = 0b0_0000_1000;
const WRAPLINE = 0b0_0001_0000;
const WIDE_CHAR = 0b0_0010_0000;
const WIDE_CHAR_SPACER = 0b0_0100_0000;
const DIM = 0b0_1000_0000;
const DIM_BOLD = 0b0_1000_0010;
const HIDDEN = 0b1_0000_0000;
}
}

View File

@ -14,9 +14,8 @@
//
//! Exports the `Term` type which is a high-level API for the Grid
use std::ops::{Range, Index, IndexMut};
use std::ptr;
use std::{ptr, io, mem};
use std::cmp::{min, max};
use std::io;
use std::time::{Duration, Instant};
use arraydeque::ArrayDeque;
@ -424,26 +423,15 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
};
// Apply inversion and lookup RGB values
let mut bg_alpha = 1.0;
let fg_rgb;
let bg_rgb;
let mut fg_rgb = self.compute_fg_rgb(cell.fg, &cell);
let mut bg_rgb = self.compute_bg_rgb(cell.bg);
let invert = selected ^ cell.inverse();
if invert {
if cell.fg == cell.bg {
bg_rgb = self.colors[NamedColor::Foreground];
fg_rgb = self.colors[NamedColor::Background];
bg_alpha = 1.0
} else {
bg_rgb = self.compute_fg_rgb(cell.fg, &cell);
fg_rgb = self.compute_bg_rgb(cell.bg);
}
let bg_alpha = if selected ^ cell.inverse() {
mem::swap(&mut fg_rgb, &mut bg_rgb);
self.compute_bg_alpha(cell.fg)
} else {
fg_rgb = self.compute_fg_rgb(cell.fg, &cell);
bg_rgb = self.compute_bg_rgb(cell.bg);
bg_alpha = self.compute_bg_alpha(cell.bg);
}
self.compute_bg_alpha(cell.bg)
};
return Some(RenderableCell {
line: cell.line,
@ -1877,6 +1865,8 @@ impl ansi::Handler for Term {
Attr::CancelItalic => self.cursor.template.flags.remove(cell::Flags::ITALIC),
Attr::Underscore => self.cursor.template.flags.insert(cell::Flags::UNDERLINE),
Attr::CancelUnderline => self.cursor.template.flags.remove(cell::Flags::UNDERLINE),
Attr::Hidden => self.cursor.template.flags.insert(cell::Flags::HIDDEN),
Attr::CancelHidden => self.cursor.template.flags.remove(cell::Flags::HIDDEN),
_ => {
debug!("Term got unhandled attr: {:?}", attr);
}