aboutsummaryrefslogtreecommitdiff
path: root/src/term/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/term/mod.rs')
-rw-r--r--src/term/mod.rs122
1 files changed, 117 insertions, 5 deletions
diff --git a/src/term/mod.rs b/src/term/mod.rs
index bb0bbc1b..45ce12e0 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -13,12 +13,12 @@
// limitations under the License.
//
//! Exports the `Term` type which is a high-level API for the Grid
-use std::ops::{Deref, Range};
+use std::ops::{Deref, Range, Index, IndexMut};
use std::ptr;
use std::cmp::min;
use std::io;
-use ansi::{self, Color, NamedColor, Attr, Handler};
+use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset};
use grid::{Grid, ClearRegion, ToRange};
use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive};
use selection::{Span, Selection};
@@ -200,6 +200,79 @@ pub use self::mode::TermMode;
pub const TAB_SPACES: usize = 8;
+trait CharsetMapping {
+ fn map(&self, c: char) -> char {
+ c
+ }
+}
+
+impl CharsetMapping for StandardCharset {
+ /// Switch/Map character to the active charset. Ascii is the common case and
+ /// for that we want to do as little as possible.
+ #[inline]
+ fn map(&self, c: char) -> char {
+ match *self {
+ StandardCharset::Ascii => c,
+ StandardCharset::SpecialCharacterAndLineDrawing =>
+ match c {
+ '`' => '◆',
+ 'a' => '▒',
+ 'b' => '\t',
+ 'c' => '\u{000c}',
+ 'd' => '\r',
+ 'e' => '\n',
+ 'f' => '°',
+ 'g' => '±',
+ 'h' => '\u{2424}',
+ 'i' => '\u{000b}',
+ 'j' => '┘',
+ 'k' => '┐',
+ 'l' => '┌',
+ 'm' => '└',
+ 'n' => '┼',
+ 'o' => '⎺',
+ 'p' => '⎻',
+ 'q' => '─',
+ 'r' => '⎼',
+ 's' => '⎽',
+ 't' => '├',
+ 'u' => '┤',
+ 'v' => '┴',
+ 'w' => '┬',
+ 'x' => '│',
+ 'y' => '≤',
+ 'z' => '≥',
+ '{' => 'π',
+ '|' => '≠',
+ '}' => '£',
+ '~' => '·',
+ _ => c
+ },
+ }
+ }
+}
+
+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 {
+ &self.0[index as usize]
+ }
+}
+
+impl IndexMut<CharsetIndex> for Charsets {
+ fn index_mut(&mut self, index: CharsetIndex) -> &mut StandardCharset {
+ &mut self.0[index as usize]
+ }
+}
+
pub struct Term {
/// The grid
grid: Grid<Cell>,
@@ -228,6 +301,13 @@ pub struct Term {
/// Alt cursor
alt_cursor: Point,
+ /// Currently configured graphic character sets
+ charsets: Charsets,
+
+ /// The graphic character set, out of `charsets`, which ASCII is currently
+ /// being mapped to
+ active_charset: CharsetIndex,
+
/// Tabstops
tabs: Vec<bool>,
@@ -323,6 +403,8 @@ impl Term {
alt: false,
cursor: Point::default(),
alt_cursor: Point::default(),
+ active_charset: CharsetIndex::G0,
+ charsets: Charsets::new(),
tabs: tabs,
mode: Default::default(),
scroll_region: scroll_region,
@@ -695,7 +777,7 @@ impl ansi::Handler for Term {
{
let cell = &mut self.grid[&self.cursor];
*cell = self.template_cell;
- cell.c = c;
+ cell.c = self.charsets[self.active_charset].map(c);
}
if (self.cursor.col + 1) < self.grid.num_cols() {
@@ -1109,6 +1191,18 @@ impl ansi::Handler for Term {
debug_println!("unset mode::APP_KEYPAD");
self.mode.remove(mode::APP_KEYPAD);
}
+
+ #[inline]
+ fn configure_charset(&mut self, index: CharsetIndex, charset: StandardCharset) {
+ debug_println!("designate {:?} character set as {:?}", index, charset);
+ self.charsets[index] = charset;
+ }
+
+ #[inline]
+ fn set_active_charset(&mut self, index: CharsetIndex) {
+ debug_println!("Activate {:?} character set", index);
+ self.active_charset = index;
+ }
}
#[cfg(test)]
@@ -1116,11 +1210,12 @@ mod tests {
extern crate serde_json;
extern crate test;
- use super::limit;
+ use super::{Term, limit, SizeInfo};
use grid::Grid;
- use index::{Line, Column};
+ use index::{Point, Line, Column};
use term::{Cell};
+ use ansi::{Handler, CharsetIndex, StandardCharset};
/// Check that the grid can be serialized back and forth losslessly
///
@@ -1144,6 +1239,23 @@ mod tests {
assert_eq!(limit(5, 6, 10), 6);
assert_eq!(limit(5, 1, 4), 4);
}
+
+ #[test]
+ fn input_line_drawing_character() {
+ let size = SizeInfo {
+ width: 21.0,
+ height: 51.0,
+ cell_width: 3.0,
+ cell_height: 3.0,
+ };
+ let mut term = Term::new(size);
+ let cursor = Point::new(Line(0), Column(0));
+ term.configure_charset(CharsetIndex::G0,
+ StandardCharset::SpecialCharacterAndLineDrawing);
+ term.input('a');
+
+ assert_eq!(term.grid()[&cursor].c, '▒');
+ }
}
#[cfg(test)]