summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ansi.rs23
-rw-r--r--src/config.rs36
-rw-r--r--src/event.rs36
-rw-r--r--src/input.rs15
-rw-r--r--src/logging.rs2
-rw-r--r--src/macros.rs16
-rw-r--r--src/main.rs6
-rw-r--r--src/term/color.rs11
-rw-r--r--src/term/mod.rs16
-rw-r--r--src/window.rs5
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 {