summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2017-04-18 10:41:11 -0700
committerJoe Wilm <joe@jwilm.com>2017-04-18 19:53:31 -0700
commita27f166ef92b7782ee5833bf51d8559d1bb47934 (patch)
treed8f321f8cac94b5a51316147e739bde62008aa90
parent35f8f152cf80526155fdba8676758eea25202d28 (diff)
downloadalacritty-a27f166ef92b7782ee5833bf51d8559d1bb47934.tar.gz
alacritty-a27f166ef92b7782ee5833bf51d8559d1bb47934.zip
Implement LF/NL
-rw-r--r--src/ansi.rs11
-rw-r--r--src/term/mod.rs53
2 files changed, 50 insertions, 14 deletions
diff --git a/src/ansi.rs b/src/ansi.rs
index d2c255a5..df445031 100644
--- a/src/ansi.rs
+++ b/src/ansi.rs
@@ -266,6 +266,11 @@ pub enum Mode {
LineWrap = 7,
/// ?12
BlinkingCursor = 12,
+ /// 20
+ ///
+ /// NB This is actually a private mode. We should consider adding a second
+ /// enumeration for public/private modesets.
+ LineFeedNewLine = 20,
/// ?25
ShowCursor = 25,
/// ?1000
@@ -300,8 +305,10 @@ impl Mode {
_ => return None
})
} else {
- // TODO
- None
+ Some(match num {
+ 20 => Mode::LineFeedNewLine,
+ _ => return None
+ })
}
}
}
diff --git a/src/term/mod.rs b/src/term/mod.rs
index b88a0d98..1e9201aa 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -258,17 +258,18 @@ fn limit<T: PartialOrd + Ord>(val: T, min_limit: T, max_limit: T) -> T {
pub mod mode {
bitflags! {
- pub flags TermMode: u8 {
- const SHOW_CURSOR = 0b00000001,
- const APP_CURSOR = 0b00000010,
- const APP_KEYPAD = 0b00000100,
- const MOUSE_REPORT_CLICK = 0b00001000,
- const BRACKETED_PASTE = 0b00010000,
- const SGR_MOUSE = 0b00100000,
- const MOUSE_MOTION = 0b01000000,
- const LINE_WRAP = 0b10000000,
- const ANY = 0b11111111,
- const NONE = 0b00000000,
+ pub flags TermMode: u16 {
+ const SHOW_CURSOR = 0b000000001,
+ const APP_CURSOR = 0b000000010,
+ const APP_KEYPAD = 0b000000100,
+ const MOUSE_REPORT_CLICK = 0b000001000,
+ const BRACKETED_PASTE = 0b000010000,
+ const SGR_MOUSE = 0b000100000,
+ const MOUSE_MOTION = 0b001000000,
+ const LINE_WRAP = 0b010000000,
+ const LINE_FEED_NEW_LINE = 0b100000000,
+ const ANY = 0b111111111,
+ const NONE = 0,
}
}
@@ -1258,9 +1259,35 @@ impl ansi::Handler for Term {
trace!("[unimplemented] substitute");
}
+ /// Run LF/NL
+ ///
+ /// LF/NL mode has some interesting history. According to ECMA-48 4th
+ /// edition, in LINE FEED mode,
+ ///
+ /// > The execution of the formator functions LINE FEED (LF), FORM FEED
+ /// (FF), LINE TABULATION (VT) cause only movement of the active position in
+ /// the direction of the line progression.
+ ///
+ /// In NEW LINE mode,
+ ///
+ /// > The execution of the formator functions LINE FEED (LF), FORM FEED
+ /// (FF), LINE TABULATION (VT) cause movement to the line home position on
+ /// the following line, the following form, etc. In the case of LF this is
+ /// referred to as the New Line (NL) option.
+ ///
+ /// Additionally, ECMA-48 4th edition says that this option is deprecated.
+ /// ECMA-48 5th edition only mentions this option (without explanation)
+ /// saying that it's been removed.
+ ///
+ /// As an emulator, we need to support it since applications may still rely
+ /// on it.
#[inline]
fn newline(&mut self) {
- trace!("[unimplemented] newline");
+ self.linefeed();
+
+ if self.mode.contains(mode::LINE_FEED_NEW_LINE) {
+ self.carriage_return();
+ }
}
#[inline]
@@ -1516,6 +1543,7 @@ impl ansi::Handler for Term {
ansi::Mode::BracketedPaste => self.mode.insert(mode::BRACKETED_PASTE),
ansi::Mode::SgrMouse => self.mode.insert(mode::SGR_MOUSE),
ansi::Mode::LineWrap => self.mode.insert(mode::LINE_WRAP),
+ ansi::Mode::LineFeedNewLine => self.mode.insert(mode::LINE_FEED_NEW_LINE),
_ => {
debug!(".. ignoring set_mode");
}
@@ -1538,6 +1566,7 @@ impl ansi::Handler for Term {
ansi::Mode::BracketedPaste => self.mode.remove(mode::BRACKETED_PASTE),
ansi::Mode::SgrMouse => self.mode.remove(mode::SGR_MOUSE),
ansi::Mode::LineWrap => self.mode.remove(mode::LINE_WRAP),
+ ansi::Mode::LineFeedNewLine => self.mode.remove(mode::LINE_FEED_NEW_LINE),
_ => {
debug!(".. ignoring unset_mode");
}