1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-03 04:34:21 -05:00

Add support for wide characters

This commit is contained in:
Joe Wilm 2017-03-01 22:24:37 -08:00 committed by Joe Wilm
parent 55876522a2
commit 119c7d2856
5 changed files with 87 additions and 32 deletions

1
Cargo.lock generated
View file

@ -22,6 +22,7 @@ dependencies = [
"serde_derive 0.9.8 (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.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (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)",
]

View file

@ -31,6 +31,7 @@ xdg = "2.0.0"
log = "0.3"
clap = "2.20"
fnv = "1.0.5"
unicode-width = "0.1.4"
clippy = { version = "0.0.104", optional = true }

View file

@ -21,19 +21,18 @@
#![cfg_attr(feature = "clippy", deny(wrong_pub_self_convention))]
#![cfg_attr(feature = "nightly", feature(core_intrinsics))]
#[macro_use]
extern crate serde_derive;
#[macro_use] extern crate bitflags;
#[macro_use] extern crate clap;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use] extern crate serde_derive;
extern crate cgmath;
#[macro_use]
extern crate clap;
extern crate copypasta;
extern crate errno;
extern crate font;
extern crate fnv;
extern crate font;
extern crate glutin;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate mio;
extern crate notify;
@ -41,15 +40,10 @@ extern crate parking_lot;
extern crate serde;
extern crate serde_json;
extern crate serde_yaml;
extern crate unicode_width;
extern crate vte;
extern crate xdg;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate log;
#[macro_use]
pub mod macros;

View file

@ -18,11 +18,13 @@ use index::Column;
bitflags! {
#[derive(Serialize, Deserialize)]
pub flags Flags: u32 {
const INVERSE = 0b00000001,
const BOLD = 0b00000010,
const ITALIC = 0b00000100,
const UNDERLINE = 0b00001000,
const WRAPLINE = 0b00010000,
const INVERSE = 0b00000001,
const BOLD = 0b00000010,
const ITALIC = 0b00000100,
const UNDERLINE = 0b00001000,
const WRAPLINE = 0b00010000,
const WIDE_CHAR = 0b00100000,
const WIDE_CHAR_SPACER = 0b01000000,
}
}

View file

@ -20,6 +20,8 @@ use std::cmp::min;
use std::io;
use std::time::{Duration, Instant};
use unicode_width::UnicodeWidthChar;
use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset};
use grid::{BidirectionalIterator, Grid, ClearRegion, ToRange, Indexed};
use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive, Side};
@ -49,7 +51,7 @@ pub struct RenderableCellsIter<'a> {
config: &'a Config,
colors: &'a color::List,
selection: Option<RangeInclusive<index::Linear>>,
cursor_original: Option<Indexed<Cell>>
cursor_original: (Option<Indexed<Cell>>, Option<Indexed<Cell>>),
}
impl<'a> RenderableCellsIter<'a> {
@ -77,25 +79,52 @@ impl<'a> RenderableCellsIter<'a> {
selection: selection,
config: config,
colors: colors,
cursor_original: None,
cursor_original: (None, None),
}.initialize()
}
fn initialize(mut self) -> Self {
if self.cursor_is_visible() {
self.cursor_original = Some(Indexed {
self.cursor_original.0 = Some(Indexed {
line: self.cursor.line,
column: self.cursor.col,
inner: self.grid[self.cursor]
});
let mut spacer = false;
let mut location = *self.cursor;
if self.grid[self.cursor].flags.contains(cell::WIDE_CHAR) &&
self.cursor.col + 1 < self.grid.num_cols()
{
spacer = true;
location.col += 1;
self.cursor_original.1 = Some(Indexed {
line: location.line,
column: location.col,
inner: self.grid[&location]
});
}
if self.config.custom_cursor_colors() {
let cell = &mut self.grid[self.cursor];
cell.fg = Color::Named(NamedColor::CursorText);
cell.bg = Color::Named(NamedColor::Cursor);
{
let cell = &mut self.grid[self.cursor];
cell.fg = Color::Named(NamedColor::CursorText);
cell.bg = Color::Named(NamedColor::Cursor);
}
if spacer {
let cell = &mut self.grid[&location];
cell.fg = Color::Named(NamedColor::CursorText);
cell.bg = Color::Named(NamedColor::Cursor);
}
} else {
let cell = &mut self.grid[self.cursor];
mem::swap(&mut cell.fg, &mut cell.bg);
{
let cell = &mut self.grid[self.cursor];
mem::swap(&mut cell.fg, &mut cell.bg);
}
if spacer {
let cell = &mut self.grid[&location];
mem::swap(&mut cell.fg, &mut cell.bg);
}
}
}
self
@ -112,9 +141,14 @@ impl<'a> Drop for RenderableCellsIter<'a> {
/// Resets temporary render state on the grid
fn drop(&mut self) {
if self.cursor_is_visible() {
if let Some(ref original) = self.cursor_original {
if let Some(ref original) = self.cursor_original.0 {
self.grid[self.cursor] = original.inner;
}
if let Some(ref original) = self.cursor_original.1 {
let mut location = *self.cursor;
location.col += 1;
self.grid[&location] = original.inner;
}
}
}
}
@ -702,7 +736,9 @@ impl Term {
None
} else {
for cell in &line[cols.start..line_end] {
self.push(cell.c);
if !cell.flags.contains(cell::WIDE_CHAR_SPACER) {
self.push(cell.c);
}
}
Some(cols.start..line_end)
@ -1001,7 +1037,6 @@ impl ansi::Handler for Term {
#[inline]
fn input(&mut self, c: char) {
if self.input_needs_wrap {
if !self.mode.contains(mode::LINE_WRAP) {
return;
}
@ -1029,9 +1064,31 @@ impl ansi::Handler for Term {
}
{
let cell = &mut self.grid[&self.cursor.point];
*cell = self.cursor.template;
cell.c = self.cursor.charsets[self.active_charset].map(c);
// Number of cells the char will occupy
let width = c.width();
// Sigh, borrowck making us check the width twice. Hopefully the
// optimizer can fix it.
{
let cell = &mut self.grid[&self.cursor.point];
*cell = self.cursor.template;
cell.c = self.cursor.charsets[self.active_charset].map(c);
// Handle wide chars
if let Some(2) = width {
cell.flags.insert(cell::WIDE_CHAR);
}
}
// Set spacer cell for wide chars.
if let Some(2) = width {
if self.cursor.point.col + 1 < self.grid.num_cols() {
self.cursor.point.col += 1;
let spacer = &mut self.grid[&self.cursor.point];
*spacer = self.cursor.template;
spacer.flags.insert(cell::WIDE_CHAR_SPACER);
}
}
}
if (self.cursor.point.col + 1) < self.grid.num_cols() {