diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ansi.rs | 23 | ||||
-rw-r--r-- | src/config.rs | 36 | ||||
-rw-r--r-- | src/event.rs | 36 | ||||
-rw-r--r-- | src/input.rs | 15 | ||||
-rw-r--r-- | src/logging.rs | 2 | ||||
-rw-r--r-- | src/macros.rs | 16 | ||||
-rw-r--r-- | src/main.rs | 6 | ||||
-rw-r--r-- | src/term/color.rs | 11 | ||||
-rw-r--r-- | src/term/mod.rs | 16 | ||||
-rw-r--r-- | src/window.rs | 5 |
10 files changed, 155 insertions, 11 deletions
diff --git a/src/ansi.rs b/src/ansi.rs index e37e25f1..f1ca759a 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -558,11 +558,16 @@ pub enum NamedColor { DimCyan, /// Dim white DimWhite, + /// The bright foreground color + BrightForeground, + /// Dim foreground + DimForeground, } impl NamedColor { pub fn to_bright(self) -> Self { match self { + NamedColor::Foreground => NamedColor::BrightForeground, NamedColor::Black => NamedColor::BrightBlack, NamedColor::Red => NamedColor::BrightRed, NamedColor::Green => NamedColor::BrightGreen, @@ -571,6 +576,7 @@ impl NamedColor { NamedColor::Magenta => NamedColor::BrightMagenta, NamedColor::Cyan => NamedColor::BrightCyan, NamedColor::White => NamedColor::BrightWhite, + NamedColor::DimForeground => NamedColor::Foreground, NamedColor::DimBlack => NamedColor::Black, NamedColor::DimRed => NamedColor::Red, NamedColor::DimGreen => NamedColor::Green, @@ -593,6 +599,7 @@ impl NamedColor { NamedColor::Magenta => NamedColor::DimMagenta, NamedColor::Cyan => NamedColor::DimCyan, NamedColor::White => NamedColor::DimWhite, + NamedColor::Foreground => NamedColor::DimForeground, NamedColor::BrightBlack => NamedColor::Black, NamedColor::BrightRed => NamedColor::Red, NamedColor::BrightGreen => NamedColor::Green, @@ -601,6 +608,7 @@ impl NamedColor { NamedColor::BrightMagenta => NamedColor::Magenta, NamedColor::BrightCyan => NamedColor::Cyan, NamedColor::BrightWhite => NamedColor::White, + NamedColor::BrightForeground => NamedColor::Foreground, val => val } } @@ -814,6 +822,21 @@ impl<'a, H, W> vte::Perform for Performer<'a, H, W> unhandled(params); } + // Set cursor style + b"50" => { + if params.len() >= 2 && params[1].len() >= 13 && params[1][0..12] == *b"CursorShape=" { + let style = match params[1][12] as char { + '0' => CursorStyle::Block, + '1' => CursorStyle::Beam, + '2' => CursorStyle::Underline, + _ => return unhandled(params), + }; + self.handler.set_cursor_style(Some(style)); + return; + } + unhandled(params); + } + // Set clipboard b"52" => { if params.len() < 3 { diff --git a/src/config.rs b/src/config.rs index 7d8600f4..00c3a933 100644 --- a/src/config.rs +++ b/src/config.rs @@ -373,6 +373,10 @@ pub struct Config { #[serde(default, deserialize_with = "failure_default")] cursor_style: CursorStyle, + /// Use hollow block cursor when unfocused + #[serde(default="true_bool", deserialize_with = "default_true_bool")] + unfocused_hollow_cursor: bool, + /// Live config reload #[serde(default="true_bool", deserialize_with = "default_true_bool")] live_config_reload: bool, @@ -593,7 +597,8 @@ impl<'a> de::Deserialize<'a> for ActionWrapper { fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("Paste, Copy, PasteSelection, IncreaseFontSize, DecreaseFontSize, \ - ResetFontSize, ScrollPageUp, ScrollPageDown, ScrollToTop, ScrollToBottom or Quit") + ResetFontSize, ScrollPageUp, ScrollPageDown, ScrollToTop, \ + ScrollToBottom, Hide, or Quit") } fn visit_str<E>(self, value: &str) -> ::std::result::Result<ActionWrapper, E> @@ -610,6 +615,7 @@ impl<'a> de::Deserialize<'a> for ActionWrapper { "ScrollPageDown" => Action::ScrollPageDown, "ScrollToTop" => Action::ScrollToTop, "ScrollToBottom" => Action::ScrollToBottom, + "Hide" => Action::Hide, "Quit" => Action::Quit, _ => return Err(E::invalid_value(Unexpected::Str(value), &self)), })) @@ -1070,6 +1076,26 @@ pub struct PrimaryColors { pub background: Rgb, #[serde(deserialize_with = "rgb_from_hex")] pub foreground: Rgb, + #[serde(default, deserialize_with = "deserialize_optional_color")] + pub bright_foreground: Option<Rgb>, + #[serde(default, deserialize_with = "deserialize_optional_color")] + pub dim_foreground: Option<Rgb>, +} + +fn deserialize_optional_color<'a, D>(deserializer: D) -> ::std::result::Result<Option<Rgb>, D::Error> + where D: de::Deserializer<'a> +{ + match Option::deserialize(deserializer) { + Ok(Some(color)) => { + let color: serde_yaml::Value = color; + Ok(Some(rgb_from_hex(color).unwrap())) + }, + Ok(None) => Ok(None), + Err(err) => { + eprintln!("problem with config: {}; Using standard foreground color", err); + Ok(None) + }, + } } impl Default for PrimaryColors { @@ -1077,6 +1103,8 @@ impl Default for PrimaryColors { PrimaryColors { background: Rgb { r: 0, g: 0, b: 0 }, foreground: Rgb { r: 0xea, g: 0xea, b: 0xea }, + bright_foreground: None, + dim_foreground: None, } } } @@ -1415,6 +1443,12 @@ impl Config { self.cursor_style } + /// Use hollow block cursor when unfocused + #[inline] + pub fn unfocused_hollow_cursor(&self) -> bool { + self.unfocused_hollow_cursor + } + /// Live config reload #[inline] pub fn live_config_reload(&self) -> bool { diff --git a/src/event.rs b/src/event.rs index 3af417bd..de0faf7f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -39,6 +39,7 @@ pub struct ActionContext<'a, N: 'a> { pub received_count: &'a mut usize, pub suppress_chars: &'a mut bool, pub last_modifiers: &'a mut ModifiersState, + pub window_changes: &'a mut WindowChanges, } impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> { @@ -138,6 +139,33 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> { fn last_modifiers(&mut self) -> &mut ModifiersState { &mut self.last_modifiers } + + #[inline] + fn hide_window(&mut self) { + self.window_changes.hide = true; + } +} + +/// The ActionContext can't really have direct access to the Window +/// with the current design. Event handlers that want to change the +/// window must set these flags instead. The processor will trigger +/// the actual changes. +pub struct WindowChanges { + pub hide: bool, +} + +impl WindowChanges { + fn clear(&mut self) { + self.hide = false; + } +} + +impl Default for WindowChanges { + fn default() -> WindowChanges { + WindowChanges { + hide: false, + } + } } pub enum ClickState { @@ -204,6 +232,7 @@ pub struct Processor<N> { suppress_chars: bool, last_modifiers: ModifiersState, pending_events: Vec<Event>, + window_changes: WindowChanges, } /// Notify that the terminal was resized @@ -246,6 +275,7 @@ impl<N: Notify> Processor<N> { suppress_chars: false, last_modifiers: Default::default(), pending_events: Vec::with_capacity(4), + window_changes: Default::default(), } } @@ -398,6 +428,7 @@ impl<N: Notify> Processor<N> { received_count: &mut self.received_count, suppress_chars: &mut self.suppress_chars, last_modifiers: &mut self.last_modifiers, + window_changes: &mut self.window_changes, }; processor = input::Processor { @@ -442,6 +473,11 @@ impl<N: Notify> Processor<N> { window.is_focused = window_is_focused; } + if self.window_changes.hide { + window.hide(); + } + + self.window_changes.clear(); self.wait_for_event = !terminal.dirty; terminal diff --git a/src/input.rs b/src/input.rs index f2337d6a..cccb3bb4 100644 --- a/src/input.rs +++ b/src/input.rs @@ -69,6 +69,7 @@ pub trait ActionContext { fn change_font_size(&mut self, delta: f32); fn reset_font_size(&mut self); fn scroll(&mut self, scroll: Scroll); + fn hide_window(&mut self); } /// Describes a state and action to take in that state @@ -185,6 +186,9 @@ pub enum Action { /// Run given command Command(String, Vec<String>), + /// Hides the Alacritty window + Hide, + /// Quits Alacritty. Quit, } @@ -240,6 +244,9 @@ impl Action { }, } }, + Action::Hide => { + ctx.hide_window(); + }, Action::Quit => { // FIXME should do a more graceful shutdown ::std::process::exit(0); @@ -570,7 +577,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { return; } - self.process_mouse_bindings(ModifiersState::default(), button); + self.process_mouse_bindings(modifiers, button); } /// Process key input @@ -665,7 +672,7 @@ mod tests { use glutin::{VirtualKeyCode, Event, WindowEvent, ElementState, MouseButton, ModifiersState}; use term::{SizeInfo, Term, TermMode}; - use event::{Mouse, ClickState}; + use event::{Mouse, ClickState, WindowChanges}; use config::{self, Config, ClickHandler}; use index::{Point, Side}; use selection::Selection; @@ -691,6 +698,7 @@ mod tests { pub received_count: usize, pub suppress_chars: bool, pub last_modifiers: ModifiersState, + pub window_changes: &'a mut WindowChanges, } impl <'a>super::ActionContext for ActionContext<'a> { @@ -748,6 +756,8 @@ mod tests { } fn reset_font_size(&mut self) { } + fn hide_window(&mut self) { + } } macro_rules! test_clickstate { @@ -786,6 +796,7 @@ mod tests { received_count: 0, suppress_chars: false, last_modifiers: ModifiersState::default(), + window_changes: &mut WindowChanges::default(), }; let mut processor = Processor { diff --git a/src/logging.rs b/src/logging.rs index a691778a..10929980 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -47,7 +47,7 @@ impl<T: Send + io::Write> log::Log for Logger<T> { fn log(&self, record: &log::Record) { if self.enabled(record.metadata()) && record.target().starts_with("alacritty") { if let Ok(ref mut writer) = self.output.lock() { - writer.write_all(format!("{}\n", record.args()).as_ref()).expect("Error while logging!"); + let _ = writer.write_all(format!("{}\n", record.args()).as_ref()); } } } diff --git a/src/macros.rs b/src/macros.rs index 35e69f2d..464110e6 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -29,3 +29,19 @@ macro_rules! maybe { } } } + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => {{ + use std::io::Write; + let _ = write!(::std::io::stdout(), $($arg)*); + }}; +} + +#[macro_export] +macro_rules! eprint { + ($($arg:tt)*) => {{ + use std::io::Write; + let _ = write!(::std::io::stderr(), $($arg)*); + }}; +} diff --git a/src/main.rs b/src/main.rs index 1508103c..0888c9b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,8 @@ extern crate alacritty; #[macro_use] extern crate log; +#[cfg(target_os = "macos")] +extern crate dirs; use std::error::Error; use std::sync::Arc; @@ -48,7 +50,7 @@ fn main() { // Switch to home directory #[cfg(target_os = "macos")] - env::set_current_dir(env::home_dir().unwrap()).unwrap(); + env::set_current_dir(dirs::home_dir().unwrap()).unwrap(); // Set locale #[cfg(target_os = "macos")] locale::set_locale_environment(); @@ -178,7 +180,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> { .as_ref() .and_then(|monitor| monitor.pending_config()) { - config = new_config.update_dynamic_title(&options); + config = new_config.update_dynamic_title(options); display.update_config(&config); processor.update_config(&config); terminal.update_config(&config); diff --git a/src/term/color.rs b/src/term/color.rs index d25f2f3d..6acd092a 100644 --- a/src/term/color.rs +++ b/src/term/color.rs @@ -4,7 +4,7 @@ use std::fmt; use {Rgb, ansi}; use config::Colors; -pub const COUNT: usize = 268; +pub const COUNT: usize = 270; /// List of indexed colors /// @@ -13,6 +13,7 @@ pub const COUNT: usize = 268; /// the configured foreground color, item 257 is the configured background /// color, item 258 is the cursor foreground color, item 259 is the cursor /// background color. Following that are 8 positions for dim colors. +/// Item 268 is the bright foreground color, 269 the dim foreground. #[derive(Copy, Clone)] pub struct List([Rgb; COUNT]); @@ -50,6 +51,10 @@ impl List { self[ansi::NamedColor::BrightMagenta] = colors.bright.magenta; self[ansi::NamedColor::BrightCyan] = colors.bright.cyan; self[ansi::NamedColor::BrightWhite] = colors.bright.white; + self[ansi::NamedColor::BrightForeground] = colors + .primary + .bright_foreground + .unwrap_or(colors.primary.foreground); // Foreground and background self[ansi::NamedColor::Foreground] = colors.primary.foreground; @@ -60,6 +65,10 @@ impl List { self[ansi::NamedColor::Cursor] = colors.cursor.cursor; // Dims + self[ansi::NamedColor::DimForeground] = colors + .primary + .dim_foreground + .unwrap_or(colors.primary.foreground * 0.66); match colors.dim { Some(ref dim) => { trace!("Using config-provided dim colors"); diff --git a/src/term/mod.rs b/src/term/mod.rs index ca3b5025..97f8b779 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -320,11 +320,18 @@ impl<'a> RenderableCellsIter<'a> { Color::Spec(rgb) => rgb, Color::Named(ansi) => { match (self.config.draw_bold_text_with_bright_colors(), cell.flags & Flags::DIM_BOLD) { + // If no bright foreground is set, treat it like the BOLD flag doesn't exist + (_, self::cell::Flags::DIM_BOLD) + if ansi == NamedColor::Foreground + && self.config.colors().primary.bright_foreground.is_none() => + { + self.colors[NamedColor::DimForeground] + } // Draw bold text in bright colors *and* contains bold flag. - (true, self::cell::Flags::DIM_BOLD) | - (true, self::cell::Flags::BOLD) => self.colors[ansi.to_bright()], + (true, self::cell::Flags::BOLD) => self.colors[ansi.to_bright()], // Cell is marked as dim and not bold - (_, self::cell::Flags::DIM) => self.colors[ansi.to_dim()], + (_, self::cell::Flags::DIM) | + (false, self::cell::Flags::DIM_BOLD) => self.colors[ansi.to_dim()], // None of the above, keep original color. _ => self.colors[ansi] } @@ -412,6 +419,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> { if cell.is_empty() && !selected { continue; } + (cell, selected) }; @@ -1071,7 +1079,7 @@ impl Term { .map(|span| { span.to_locations() }); - let cursor = if window_focused { + let cursor = if window_focused || !config.unfocused_hollow_cursor() { self.cursor_style.unwrap_or(self.default_cursor_style) } else { CursorStyle::HollowBlock diff --git a/src/window.rs b/src/window.rs index 1903360f..51a42232 100644 --- a/src/window.rs +++ b/src/window.rs @@ -379,6 +379,11 @@ impl Window { pub fn get_window_id(&self) -> Option<usize> { None } + + /// Hide the window + pub fn hide(&self) { + self.window.hide(); + } } pub trait OsExtensions { |