diff options
| author | Ayose <ayosec@gmail.com> | 2021-09-23 22:11:02 +0100 |
|---|---|---|
| committer | Ayose <ayosec@gmail.com> | 2021-09-23 22:11:02 +0100 |
| commit | 91b85669b88492bb10b832d2dc6df7641a26d3db (patch) | |
| tree | 89443c85ad9396c9ac03bc3ec4689498427b5f20 /alacritty/src | |
| parent | 699a7a9d13fd741bf4430514ac8d6f579a68484a (diff) | |
| parent | 58985a4dcbe464230b5d2566ee68e2d34a1788c8 (diff) | |
| download | r-alacritty-91b85669b88492bb10b832d2dc6df7641a26d3db.tar.gz r-alacritty-91b85669b88492bb10b832d2dc6df7641a26d3db.tar.bz2 r-alacritty-91b85669b88492bb10b832d2dc6df7641a26d3db.zip | |
Merge remote-tracking branch 'vendor/master' into graphics
Diffstat (limited to 'alacritty/src')
| -rw-r--r-- | alacritty/src/cli.rs | 326 | ||||
| -rw-r--r-- | alacritty/src/config/bindings.rs | 54 | ||||
| -rw-r--r-- | alacritty/src/config/color.rs | 1 | ||||
| -rw-r--r-- | alacritty/src/config/mod.rs | 12 | ||||
| -rw-r--r-- | alacritty/src/config/monitor.rs | 37 | ||||
| -rw-r--r-- | alacritty/src/config/ui_config.rs | 11 | ||||
| -rw-r--r-- | alacritty/src/config/window.rs | 8 | ||||
| -rw-r--r-- | alacritty/src/display/content.rs | 8 | ||||
| -rw-r--r-- | alacritty/src/display/mod.rs | 26 | ||||
| -rw-r--r-- | alacritty/src/display/window.rs | 6 | ||||
| -rw-r--r-- | alacritty/src/event.rs | 64 | ||||
| -rw-r--r-- | alacritty/src/input.rs | 91 | ||||
| -rw-r--r-- | alacritty/src/logging.rs | 18 | ||||
| -rw-r--r-- | alacritty/src/main.rs | 2 | ||||
| -rw-r--r-- | alacritty/src/renderer/mod.rs | 12 | ||||
| -rw-r--r-- | alacritty/src/renderer/rects.rs | 6 |
16 files changed, 335 insertions, 347 deletions
diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index 682bdde3..a1480807 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -1,219 +1,101 @@ use std::cmp::max; use std::path::PathBuf; -use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg}; use log::{self, error, LevelFilter}; use serde_yaml::Value; +use structopt::StructOpt; use alacritty_terminal::config::Program; use crate::config::serde_utils; -use crate::config::window::DEFAULT_NAME; +use crate::config::window::{Class, DEFAULT_NAME}; use crate::config::Config; -#[cfg(not(any(target_os = "macos", windows)))] -const CONFIG_PATH: &str = "$XDG_CONFIG_HOME/alacritty/alacritty.yml"; -#[cfg(windows)] -const CONFIG_PATH: &str = "%APPDATA%\\alacritty\\alacritty.yml"; -#[cfg(target_os = "macos")] -const CONFIG_PATH: &str = "$HOME/.config/alacritty/alacritty.yml"; - /// Options specified on the command line. +#[derive(StructOpt, Debug)] +#[structopt(author, about, version = env!("VERSION"))] pub struct Options { + /// Print all events to stdout. + #[structopt(long)] pub print_events: bool, + + /// Generates ref test. + #[structopt(long)] pub ref_test: bool, + + /// Defines the window title [default: Alacritty]. + #[structopt(short, long)] pub title: Option<String>, - pub class_instance: Option<String>, - pub class_general: Option<String>, - pub embed: Option<String>, - pub log_level: LevelFilter, - pub command: Option<Program>, - pub hold: bool, - pub working_directory: Option<PathBuf>, - pub config_path: Option<PathBuf>, - pub config_options: Value, -} -impl Default for Options { - fn default() -> Options { - Options { - print_events: false, - ref_test: false, - title: None, - class_instance: None, - class_general: None, - embed: None, - log_level: LevelFilter::Warn, - command: None, - hold: false, - working_directory: None, - config_path: None, - config_options: Value::Null, - } - } -} + /// Defines window class/app_id on X11/Wayland [default: Alacritty]. + #[structopt(long, value_name = "instance> | <instance>,<general", parse(try_from_str = parse_class))] + pub class: Option<Class>, -impl Options { - /// Build `Options` from command line arguments. - pub fn new() -> Self { - let mut version = crate_version!().to_owned(); - let commit_hash = env!("GIT_HASH"); - if !commit_hash.is_empty() { - version = format!("{} ({})", version, commit_hash); - } + /// Defines the X11 window ID (as a decimal integer) to embed Alacritty within. + #[structopt(long)] + pub embed: Option<String>, - let mut options = Options::default(); - - let matches = App::new(crate_name!()) - .version(version.as_str()) - .author(crate_authors!("\n")) - .about(crate_description!()) - .arg(Arg::with_name("ref-test").long("ref-test").help("Generates ref test")) - .arg( - Arg::with_name("print-events") - .long("print-events") - .help("Print all events to stdout"), - ) - .arg( - Arg::with_name("title") - .long("title") - .short("t") - .takes_value(true) - .help(&format!("Defines the window title [default: {}]", DEFAULT_NAME)), - ) - .arg( - Arg::with_name("class") - .long("class") - .value_name("instance> | <instance>,<general") - .takes_value(true) - .use_delimiter(true) - .help(&format!( - "Defines window class/app_id on X11/Wayland [default: {}]", - DEFAULT_NAME - )), - ) - .arg( - Arg::with_name("embed").long("embed").takes_value(true).help( - "Defines the X11 window ID (as a decimal integer) to embed Alacritty within", - ), - ) - .arg( - Arg::with_name("q") - .short("q") - .multiple(true) - .conflicts_with("v") - .help("Reduces the level of verbosity (the min level is -qq)"), - ) - .arg( - Arg::with_name("v") - .short("v") - .multiple(true) - .conflicts_with("q") - .help("Increases the level of verbosity (the max level is -vvv)"), - ) - .arg( - Arg::with_name("working-directory") - .long("working-directory") - .takes_value(true) - .help("Start the shell in the specified working directory"), - ) - .arg(Arg::with_name("config-file").long("config-file").takes_value(true).help( - &format!("Specify alternative configuration file [default: {}]", CONFIG_PATH), - )) - .arg( - Arg::with_name("command") - .long("command") - .short("e") - .multiple(true) - .takes_value(true) - .allow_hyphen_values(true) - .help("Command and args to execute (must be last argument)"), - ) - .arg(Arg::with_name("hold").long("hold").help("Remain open after child process exits")) - .arg( - Arg::with_name("option") - .long("option") - .short("o") - .multiple(true) - .takes_value(true) - .help("Override configuration file options [example: cursor.style=Beam]"), - ) - .get_matches(); - - if matches.is_present("ref-test") { - options.ref_test = true; - } + /// Start the shell in the specified working directory. + #[structopt(long)] + pub working_directory: Option<PathBuf>, - if matches.is_present("print-events") { - options.print_events = true; - } + /// Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.yml]. + #[cfg(not(any(target_os = "macos", windows)))] + #[structopt(long)] + pub config_file: Option<PathBuf>, - if let Some(mut class) = matches.values_of("class") { - options.class_instance = class.next().map(|instance| instance.to_owned()); - options.class_general = class.next().map(|general| general.to_owned()); - } + /// Specify alternative configuration file [default: %APPDATA%\alacritty\alacritty.yml]. + #[cfg(windows)] + #[structopt(long)] + pub config_file: Option<PathBuf>, - options.title = matches.value_of("title").map(ToOwned::to_owned); - options.embed = matches.value_of("embed").map(ToOwned::to_owned); + /// Specify alternative configuration file [default: $HOME/.config/alacritty/alacritty.yml]. + #[cfg(target_os = "macos")] + #[structopt(long)] + pub config_file: Option<PathBuf>, - match matches.occurrences_of("q") { - 0 => (), - 1 => options.log_level = LevelFilter::Error, - _ => options.log_level = LevelFilter::Off, - } + /// Remain open after child process exits. + #[structopt(long)] + pub hold: bool, - match matches.occurrences_of("v") { - 0 if !options.print_events => options.log_level = LevelFilter::Warn, - 0 | 1 => options.log_level = LevelFilter::Info, - 2 => options.log_level = LevelFilter::Debug, - _ => options.log_level = LevelFilter::Trace, - } + /// CLI options for config overrides. + #[structopt(skip)] + pub config_options: Value, - if let Some(dir) = matches.value_of("working-directory") { - options.working_directory = Some(PathBuf::from(dir.to_string())); - } + /// Reduces the level of verbosity (the min level is -qq). + #[structopt(short, conflicts_with("verbose"), parse(from_occurrences))] + quiet: u8, - if let Some(path) = matches.value_of("config-file") { - options.config_path = Some(PathBuf::from(path.to_string())); - } + /// Increases the level of verbosity (the max level is -vvv). + #[structopt(short, conflicts_with("quiet"), parse(from_occurrences))] + verbose: u8, - if let Some(mut args) = matches.values_of("command") { - // The following unwrap is guaranteed to succeed. - // If `command` exists it must also have a first item since - // `Arg::min_values(1)` is set. - let program = String::from(args.next().unwrap()); - let args = args.map(String::from).collect(); - options.command = Some(Program::WithArgs { program, args }); - } + /// Command and args to execute (must be last argument). + #[structopt(short = "e", long, allow_hyphen_values = true)] + command: Vec<String>, - if matches.is_present("hold") { - options.hold = true; - } + /// Override configuration file options [example: cursor.style=Beam]. + #[structopt(short = "o", long)] + option: Vec<String>, +} - if let Some(config_options) = matches.values_of("option") { - for option in config_options { - match option_as_value(option) { - Ok(value) => { - options.config_options = serde_utils::merge(options.config_options, value); - }, - Err(_) => eprintln!("Invalid CLI config option: {:?}", option), - } +impl Options { + pub fn new() -> Self { + let mut options = Self::from_args(); + + // Convert `--option` flags into serde `Value`. + for option in &options.option { + match option_as_value(option) { + Ok(value) => { + options.config_options = serde_utils::merge(options.config_options, value); + }, + Err(_) => eprintln!("Invalid CLI config option: {:?}", option), } } options } - /// Configuration file path. - pub fn config_path(&self) -> Option<PathBuf> { - self.config_path.clone() - } - - /// CLI config options as deserializable serde value. - pub fn config_options(&self) -> &Value { - &self.config_options - } - /// Override configuration file with options from the CLI. pub fn override_config(&self, config: &mut Config) { if let Some(working_directory) = &self.working_directory { @@ -224,8 +106,8 @@ impl Options { } } - if let Some(command) = &self.command { - config.shell = Some(command.clone()); + if let Some(command) = self.command() { + config.shell = Some(command); } config.hold = self.hold; @@ -233,17 +115,14 @@ impl Options { if let Some(title) = self.title.clone() { config.ui_config.window.title = title } - if let Some(class_instance) = self.class_instance.clone() { - config.ui_config.window.class.instance = class_instance; - } - if let Some(class_general) = self.class_general.clone() { - config.ui_config.window.class.general = class_general; + if let Some(class) = &self.class { + config.ui_config.window.class = class.clone(); } config.ui_config.window.dynamic_title &= self.title.is_none(); config.ui_config.window.embed = self.embed.as_ref().and_then(|embed| embed.parse().ok()); config.ui_config.debug.print_events |= self.print_events; - config.ui_config.debug.log_level = max(config.ui_config.debug.log_level, self.log_level); + config.ui_config.debug.log_level = max(config.ui_config.debug.log_level, self.log_level()); config.ui_config.debug.ref_test |= self.ref_test; if config.ui_config.debug.print_events { @@ -251,6 +130,32 @@ impl Options { max(config.ui_config.debug.log_level, LevelFilter::Info); } } + + /// Logging filter level. + pub fn log_level(&self) -> LevelFilter { + match (self.quiet, self.verbose) { + // Force at least `Info` level for `--print-events`. + (_, 0) if self.print_events => LevelFilter::Info, + + // Default. + (0, 0) => LevelFilter::Warn, + + // Verbose. + (_, 1) => LevelFilter::Info, + (_, 2) => LevelFilter::Debug, + (0, _) => LevelFilter::Trace, + + // Quiet. + (1, _) => LevelFilter::Error, + (..) => LevelFilter::Off, + } + } + + /// Shell override passed through the CLI. + pub fn command(&self) -> Option<Program> { + let (program, args) = self.command.split_first()?; + Some(Program::WithArgs { program: program.clone(), args: args.to_vec() }) + } } /// Format an option in the format of `parent.field=value` to a serde Value. @@ -278,6 +183,23 @@ fn option_as_value(option: &str) -> Result<Value, serde_yaml::Error> { serde_yaml::from_str(&yaml_text) } +/// Parse the class CLI parameter. +fn parse_class(input: &str) -> Result<Class, String> { + match input.find(',') { + Some(position) => { + let general = input[position + 1..].to_owned(); + + // Warn the user if they've passed too many values. + if general.contains(',') { + return Err(String::from("Too many parameters")); + } + + Ok(Class { instance: input[..position].into(), general }) + }, + None => Ok(Class { instance: input.into(), general: DEFAULT_NAME.into() }), + } +} + #[cfg(test)] mod tests { use super::*; @@ -289,7 +211,7 @@ mod tests { let mut config = Config::default(); let old_dynamic_title = config.ui_config.window.dynamic_title; - Options::default().override_config(&mut config); + Options::new().override_config(&mut config); assert_eq!(old_dynamic_title, config.ui_config.window.dynamic_title); } @@ -298,7 +220,7 @@ mod tests { fn dynamic_title_overridden_by_options() { let mut config = Config::default(); - let options = Options { title: Some("foo".to_owned()), ..Options::default() }; + let options = Options { title: Some("foo".to_owned()), ..Options::new() }; options.override_config(&mut config); assert!(!config.ui_config.window.dynamic_title); @@ -309,7 +231,7 @@ mod tests { let mut config = Config::default(); config.ui_config.window.title = "foo".to_owned(); - Options::default().override_config(&mut config); + Options::new().override_config(&mut config); assert!(config.ui_config.window.dynamic_title); } @@ -350,4 +272,24 @@ mod tests { assert_eq!(value, Value::Mapping(expected)); } + + #[test] + fn parse_instance_class() { + let class = parse_class("one").unwrap(); + assert_eq!(class.instance, "one"); + assert_eq!(class.general, DEFAULT_NAME); + } + + #[test] + fn parse_general_class() { + let class = parse_class("one,two").unwrap(); + assert_eq!(class.instance, "one"); + assert_eq!(class.general, "two"); + } + + #[test] + fn parse_invalid_class() { + let class = parse_class("one,two,three"); + assert!(class.is_err()); + } } diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 12349639..a4271430 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -103,11 +103,15 @@ pub enum Action { /// Perform vi mode action. #[config(skip)] - ViAction(ViAction), + Vi(ViAction), /// Perform search mode action. #[config(skip)] - SearchAction(SearchAction), + Search(SearchAction), + + /// Perform mouse binding exclusive action. + #[config(skip)] + Mouse(MouseAction), /// Paste contents of system clipboard. Paste, @@ -211,7 +215,7 @@ impl From<&'static str> for Action { impl From<ViAction> for Action { fn from(action: ViAction) -> Self { - Self::ViAction(action) + Self::Vi(action) } } @@ -223,7 +227,13 @@ impl From<ViMotion> for Action { impl From<SearchAction> for Action { fn from(action: SearchAction) -> Self { - Self::SearchAction(action) + Self::Search(action) + } +} + +impl From<MouseAction> for Action { + fn from(action: MouseAction) -> Self { + Self::Mouse(action) } } @@ -232,7 +242,8 @@ impl Display for Action { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Action::ViMotion(motion) => motion.fmt(f), - Action::ViAction(action) => action.fmt(f), + Action::Vi(action) => action.fmt(f), + Action::Mouse(action) => action.fmt(f), _ => write!(f, "{:?}", self), } } @@ -262,6 +273,7 @@ pub enum ViAction { } /// Search mode specific actions. +#[allow(clippy::enum_variant_names)] #[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] pub enum SearchAction { /// Move the focus to the next search match. @@ -282,6 +294,13 @@ pub enum SearchAction { SearchHistoryNext, } +/// Mouse binding specific actions. +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +pub enum MouseAction { + /// Expand the selection to the current mouse cursor position. + ExpandSelection, +} + macro_rules! bindings { ( KeyBinding; @@ -342,6 +361,7 @@ macro_rules! bindings { pub fn default_mouse_bindings() -> Vec<MouseBinding> { bindings!( MouseBinding; + MouseButton::Right; MouseAction::ExpandSelection; MouseButton::Middle, ~BindingMode::VI; Action::PasteSelection; ) } @@ -423,16 +443,16 @@ pub fn default_key_bindings() -> Vec<KeyBinding> { F19, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[33~".into()); F20, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[34~".into()); NumpadEnter, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\n".into()); - Space, ModifiersState::SHIFT | ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollToBottom; Space, ModifiersState::SHIFT | ModifiersState::CTRL, ~BindingMode::SEARCH; Action::ToggleViMode; + Space, ModifiersState::SHIFT | ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; + Action::ScrollToBottom; Escape, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; I, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollToBottom; - I, +BindingMode::VI, ~BindingMode::SEARCH; Action::ToggleViMode; + I, +BindingMode::VI, ~BindingMode::SEARCH; + Action::ScrollToBottom; C, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ToggleViMode; Y, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; @@ -1026,6 +1046,9 @@ impl<'a> Deserialize<'a> for RawBinding { SearchAction::deserialize(value.clone()) { Some(search_action.into()) + } else if let Ok(mouse_action) = MouseAction::deserialize(value.clone()) + { + Some(mouse_action.into()) } else { match Action::deserialize(value.clone()).map_err(V::Error::custom) { Ok(action) => Some(action), @@ -1081,7 +1104,7 @@ impl<'a> Deserialize<'a> for RawBinding { let action = match (action, chars, command) { (Some(action @ Action::ViMotion(_)), None, None) - | (Some(action @ Action::ViAction(_)), None, None) => { + | (Some(action @ Action::Vi(_)), None, None) => { if !mode.intersects(BindingMode::VI) || not_mode.intersects(BindingMode::VI) { return Err(V::Error::custom(format!( @@ -1091,7 +1114,7 @@ impl<'a> Deserialize<'a> for RawBinding { } action }, - (Some(action @ Action::SearchAction(_)), None, None) => { + (Some(action @ Action::Search(_)), None, None) => { if !mode.intersects(BindingMode::SEARCH) { return Err(V::Error::custom(format!( "action `{}` is only available in search mode, try adding `mode: \ @@ -1101,6 +1124,15 @@ impl<'a> Deserialize<'a> for RawBinding { } action }, + (Some(action @ Action::Mouse(_)), None, None) => { + if mouse.is_none() { + return Err(V::Error::custom(format!( + "action `{}` is only available for mouse bindings", + action, + ))); + } + action + }, (Some(action), None, None) => action, (None, Some(chars), None) => Action::Esc(chars), (None, None, Some(cmd)) => Action::Command(cmd), diff --git a/alacritty/src/config/color.rs b/alacritty/src/config/color.rs index ddb1da29..c0076edb 100644 --- a/alacritty/src/config/color.rs +++ b/alacritty/src/config/color.rs @@ -17,6 +17,7 @@ pub struct Colors { pub search: SearchColors, pub line_indicator: LineIndicatorColors, pub hints: HintColors, + pub transparent_background_colors: bool, } impl Colors { diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index e2476bb2..4a3c0ae9 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -22,7 +22,9 @@ mod bindings; mod mouse; use crate::cli::Options; -pub use crate::config::bindings::{Action, Binding, BindingMode, Key, SearchAction, ViAction}; +pub use crate::config::bindings::{ + Action, Binding, BindingMode, Key, MouseAction, SearchAction, ViAction, +}; #[cfg(test)] pub use crate::config::mouse::{ClickHandler, Mouse}; use crate::config::ui_config::UiConfig; @@ -99,8 +101,8 @@ impl From<serde_yaml::Error> for Error { /// Load the configuration file. pub fn load(options: &Options) -> Config { - let config_options = options.config_options().clone(); - let config_path = options.config_path().or_else(installed_config); + let config_options = options.config_options.clone(); + let config_path = options.config_file.clone().or_else(installed_config); // Load the config using the following fallback behavior: // - Config path + CLI overrides @@ -126,7 +128,7 @@ pub fn load(options: &Options) -> Config { /// Attempt to reload the configuration file. pub fn reload(config_path: &Path, options: &Options) -> Result<Config> { // Load config, propagating errors. - let config_options = options.config_options().clone(); + let config_options = options.config_options.clone(); let mut config = load_from(config_path, config_options)?; after_loading(&mut config, options); @@ -157,7 +159,7 @@ fn load_from(path: &Path, cli_config: Value) -> Result<Config> { /// Deserialize configuration file from path. fn read_config(path: &Path, cli_config: Value) -> Result<Config> { let mut config_paths = Vec::new(); - let mut config_value = parse_config(&path, &mut config_paths, IMPORT_RECURSION_LIMIT)?; + let mut config_value = parse_config(path, &mut config_paths, IMPORT_RECURSION_LIMIT)?; // Override config with CLI options. config_value = serde_utils::merge(config_value, cli_config); diff --git a/alacritty/src/config/monitor.rs b/alacritty/src/config/monitor.rs index 4a694fac..e3dd0556 100644 --- a/alacritty/src/config/monitor.rs +++ b/alacritty/src/config/monitor.rs @@ -1,4 +1,3 @@ -use std::fs; use std::path::PathBuf; use std::sync::mpsc; use std::time::Duration; @@ -16,23 +15,21 @@ const DEBOUNCE_DELAY: Duration = Duration::from_millis(10); const DEBOUNCE_DELAY: Duration = Duration::from_millis(1000); pub fn watch(mut paths: Vec<PathBuf>, event_proxy: EventProxy) { - // Canonicalize all paths, filtering out the ones that do not exist. - paths = paths - .drain(..) - .filter_map(|path| match fs::canonicalize(&path) { - Ok(path) => Some(path), - Err(err) => { - error!("Unable to canonicalize config path {:?}: {}", path, err); - None - }, - }) - .collect(); - // Don't monitor config if there is no path to watch. if paths.is_empty() { return; } + // Canonicalize paths, keeping the base paths for symlinks. + for i in 0..paths.len() { + if let Ok(canonical_path) = paths[i].canonicalize() { + match paths[i].symlink_metadata() { + Ok(metadata) if metadata.file_type().is_symlink() => paths.push(canonical_path), + _ => paths[i] = canonical_path, + } + } + } + // The Duration argument is a debouncing period. let (tx, rx) = mpsc::channel(); let mut watcher = match watcher(tx, DEBOUNCE_DELAY) { @@ -73,17 +70,15 @@ pub fn watch(mut paths: Vec<PathBuf>, event_proxy: EventProxy) { }; match event { - DebouncedEvent::Rename(..) => continue, - DebouncedEvent::Write(path) + DebouncedEvent::Rename(_, path) + | DebouncedEvent::Write(path) | DebouncedEvent::Create(path) - | DebouncedEvent::Chmod(path) => { - if !paths.contains(&path) { - continue; - } - + | DebouncedEvent::Chmod(path) + if paths.contains(&path) => + { // Always reload the primary configuration file. event_proxy.send_event(Event::ConfigReload(paths[0].clone())); - }, + } _ => {}, } } diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index a58c1fd3..3ce02161 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -69,7 +69,8 @@ pub struct UiConfig { mouse_bindings: MouseBindings, /// Background opacity from 0.0 to 1.0. - background_opacity: Percentage, + #[config(deprecated = "use window.opacity instead")] + background_opacity: Option<Percentage>, } impl Default for UiConfig { @@ -115,13 +116,13 @@ impl UiConfig { } #[inline] - pub fn background_opacity(&self) -> f32 { - self.background_opacity.as_f32() + pub fn window_opacity(&self) -> f32 { + self.background_opacity.unwrap_or(self.window.opacity).as_f32() } #[inline] pub fn key_bindings(&self) -> &[KeyBinding] { - &self.key_bindings.0.as_slice() + self.key_bindings.0.as_slice() } #[inline] @@ -399,7 +400,7 @@ impl LazyRegexVariant { }; // Compile the regex. - let regex_search = match RegexSearch::new(®ex) { + let regex_search = match RegexSearch::new(regex) { Ok(regex_search) => regex_search, Err(error) => { error!("hint regex is invalid: {}", error); diff --git a/alacritty/src/config/window.rs b/alacritty/src/config/window.rs index d74390d8..f7a7511c 100644 --- a/alacritty/src/config/window.rs +++ b/alacritty/src/config/window.rs @@ -7,7 +7,7 @@ use serde::de::{self, MapAccess, Visitor}; use serde::{Deserialize, Deserializer}; use alacritty_config_derive::ConfigDeserialize; -use alacritty_terminal::config::LOG_TARGET_CONFIG; +use alacritty_terminal::config::{Percentage, LOG_TARGET_CONFIG}; use alacritty_terminal::index::Column; use crate::config::ui_config::Delta; @@ -15,7 +15,7 @@ use crate::config::ui_config::Delta; /// Default Alacritty name, used for window title and class. pub const DEFAULT_NAME: &str = "Alacritty"; -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Clone, PartialEq)] pub struct WindowConfig { /// Initial position. pub position: Option<Delta<i32>>, @@ -45,6 +45,9 @@ pub struct WindowConfig { /// Window class. pub class: Class, + /// Background opacity from 0.0 to 1.0. + pub opacity: Percentage, + /// Pixel padding. padding: Delta<u8>, @@ -64,6 +67,7 @@ impl Default for WindowConfig { gtk_theme_variant: Default::default(), dynamic_padding: Default::default(), class: Default::default(), + opacity: Default::default(), padding: Default::default(), dimensions: Default::default(), } diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs index b470343e..0bc2f46f 100644 --- a/alacritty/src/display/content.rs +++ b/alacritty/src/display/content.rs @@ -45,7 +45,7 @@ impl<'a> RenderableContent<'a> { term: &'a Term<T>, search_state: &'a SearchState, ) -> Self { - let search = search_state.dfas().map(|dfas| Regex::new(&term, dfas)); + let search = search_state.dfas().map(|dfas| Regex::new(term, dfas)); let focused_match = search_state.focused_match(); let terminal_content = term.renderable_content(); @@ -205,7 +205,7 @@ impl RenderableCell { mem::swap(&mut fg, &mut bg); 1.0 } else { - Self::compute_bg_alpha(cell.bg) + Self::compute_bg_alpha(&content.config.ui_config, cell.bg) }; let is_selected = content.terminal_content.selection.map_or(false, |selection| { @@ -353,9 +353,11 @@ impl RenderableCell { /// using the named input color, rather than checking the RGB of the background after its color /// is computed. #[inline] - fn compute_bg_alpha(bg: Color) -> f32 { + fn compute_bg_alpha(config: &UiConfig, bg: Color) -> f32 { if bg == Color::Named(NamedColor::Background) { 0. + } else if config.colors.transparent_background_colors { + config.window_opacity() } else { 1. } diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 162c70b9..5e958f03 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -80,7 +80,7 @@ pub enum Error { Render(renderer::Error), /// Error during buffer swap. - ContextError(glutin::ContextError), + Context(glutin::ContextError), } impl std::error::Error for Error { @@ -89,7 +89,7 @@ impl std::error::Error for Error { Error::Window(err) => err.source(), Error::Font(err) => err.source(), Error::Render(err) => err.source(), - Error::ContextError(err) => err.source(), + Error::Context(err) => err.source(), } } } @@ -100,7 +100,7 @@ impl fmt::Display for Error { Error::Window(err) => err.fmt(f), Error::Font(err) => err.fmt(f), Error::Render(err) => err.fmt(f), - Error::ContextError(err) => err.fmt(f), + Error::Context(err) => err.fmt(f), } } } @@ -125,7 +125,7 @@ impl From<renderer::Error> for Error { impl From<glutin::ContextError> for Error { fn from(val: glutin::ContextError) -> Self { - Error::ContextError(val) + Error::Context(val) } } @@ -242,7 +242,7 @@ impl Display { // Spawn the Alacritty window. let mut window = Window::new( event_loop, - &config, + config, estimated_size, #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] wayland_event_queue.as_ref(), @@ -299,7 +299,7 @@ impl Display { // Disable shadows for transparent windows on macOS. #[cfg(target_os = "macos")] - window.set_has_shadow(config.ui_config.background_opacity() >= 1.0); + window.set_has_shadow(config.ui_config.window_opacity() >= 1.0); // On Wayland we can safely ignore this call, since the window isn't visible until you // actually draw something into it and commit those changes. @@ -487,7 +487,7 @@ impl Display { // Collect renderable content before the terminal is dropped. let mut content = RenderableContent::new(config, self, &terminal, search_state); let mut grid_cells = Vec::new(); - while let Some(cell) = content.next() { + for cell in &mut content { grid_cells.push(cell); } let background_color = content.color(NamedColor::Background as usize); @@ -611,7 +611,7 @@ impl Display { for (i, message_text) in text.iter().enumerate() { let point = Point::new(start_line + i, Column(0)); self.renderer.with_api(&config.ui_config, &size_info, |mut api| { - api.render_string(glyph_cache, point, fg, bg, &message_text); + api.render_string(glyph_cache, point, fg, bg, message_text); }); } } else { @@ -682,7 +682,7 @@ impl Display { let vi_highlighted_hint = if term.mode().contains(TermMode::VI) { let mods = ModifiersState::all(); let point = term.vi_mode_cursor.point; - hint::highlighted_at(&term, config, point, mods) + hint::highlighted_at(term, config, point, mods) } else { None }; @@ -698,7 +698,7 @@ impl Display { // Find highlighted hint at mouse position. let point = mouse.point(&self.size_info, term.grid().display_offset()); - let highlighted_hint = hint::highlighted_at(&term, config, point, modifiers); + let highlighted_hint = hint::highlighted_at(term, config, point, modifiers); // Update cursor shape. if highlighted_hint.is_some() { @@ -760,7 +760,7 @@ impl Display { let fg = config.ui_config.colors.search_bar_foreground(); let bg = config.ui_config.colors.search_bar_background(); - self.renderer.with_api(&config.ui_config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, size_info, |mut api| { api.render_string(glyph_cache, point, fg, bg, &text); }); } @@ -778,7 +778,7 @@ impl Display { let fg = config.ui_config.colors.primary.background; let bg = config.ui_config.colors.normal.red; - self.renderer.with_api(&config.ui_config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, size_info, |mut api| { api.render_string(glyph_cache, point, fg, bg, &timing); }); } @@ -801,7 +801,7 @@ impl Display { // Do not render anything if it would obscure the vi mode cursor. if vi_mode_point.map_or(true, |point| point.line != 0 || point.column < column) { let glyph_cache = &mut self.glyph_cache; - self.renderer.with_api(&config.ui_config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, size_info, |mut api| { api.render_string(glyph_cache, Point::new(0, column), fg, bg, &text); }); } diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index 7302c687..12416700 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -177,7 +177,7 @@ impl Window { wayland_event_queue: Option<&EventQueue>, ) -> Result<Window> { let window_config = &config.ui_config.window; - let window_builder = Window::get_platform_window(&window_config.title, &window_config); + let window_builder = Window::get_platform_window(&window_config.title, window_config); // Check if we're running Wayland to disable vsync. #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] @@ -186,9 +186,9 @@ impl Window { let is_wayland = false; let windowed_context = - create_gl_window(window_builder.clone(), &event_loop, false, !is_wayland, size) + create_gl_window(window_builder.clone(), event_loop, false, !is_wayland, size) .or_else(|_| { - create_gl_window(window_builder, &event_loop, true, !is_wayland, size) + create_gl_window(window_builder, event_loop, true, !is_wayland, size) })?; // Text cursor. diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 64283eb7..cc817f6e 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -65,7 +65,7 @@ const MAX_SEARCH_HISTORY_SIZE: usize = 255; /// Events dispatched through the UI event loop. #[derive(Debug, Clone)] pub enum Event { - TerminalEvent(TerminalEvent), + Terminal(TerminalEvent), DprChanged(f64, (u32, u32)), Scroll(Scroll), ConfigReload(PathBuf), @@ -82,7 +82,7 @@ impl From<Event> for GlutinEvent<'_, Event> { impl From<TerminalEvent> for Event { fn from(event: TerminalEvent) -> Self { - Event::TerminalEvent(event) + Event::Terminal(event) } } @@ -421,11 +421,12 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon self.search_state.origin = self.terminal.vi_mode_cursor.point; self.search_state.display_offset_delta = 0; } else { - let screen_lines = self.terminal.screen_lines(); + let viewport_top = Line(-(self.terminal.grid().display_offset() as i32)) - 1; + let viewport_bottom = viewport_top + self.terminal.bottommost_line(); let last_column = self.terminal.last_column(); self.search_state.origin = match direction { - Direction::Right => Point::new(Line(0), Column(0)), - Direction::Left => Point::new(Line(screen_lines as i32 - 2), last_column), + Direction::Right => Point::new(viewport_top, Column(0)), + Direction::Left => Point::new(viewport_bottom, last_column), }; } @@ -670,6 +671,42 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon } } + /// Expand the selection to the current mouse cursor position. + #[inline] + fn expand_selection(&mut self) { + let selection_type = match self.mouse().click_state { + ClickState::Click => { + if self.modifiers().ctrl() { + SelectionType::Block + } else { + SelectionType::Simple + } + }, + ClickState::DoubleClick => SelectionType::Semantic, + ClickState::TripleClick => SelectionType::Lines, + ClickState::None => return, + }; + + // Load mouse point, treating message bar and padding as the closest cell. + let display_offset = self.terminal().grid().display_offset(); + let point = self.mouse().point(&self.size_info(), display_offset); + + let cell_side = self.mouse().cell_side; + + let selection = match &mut self.terminal_mut().selection { + Some(selection) => selection, + None => return, + }; + + selection.ty = selection_type; + self.update_selection(point, cell_side); + + // Move vi mode cursor to mouse click position. + if self.terminal().mode().contains(TermMode::VI) && !self.search_active() { + self.terminal_mut().vi_mode_cursor.point = point; + } + } + /// Paste a text into the terminal. fn paste(&mut self, text: &str) { if self.search_active() { @@ -743,7 +780,7 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> { self.search_state.dfas = None; } else { // Create search dfas for the new regex string. - self.search_state.dfas = RegexSearch::new(®ex).ok(); + self.search_state.dfas = RegexSearch::new(regex).ok(); // Update search highlighting. self.goto_match(MAX_SEARCH_WHILE_TYPING); @@ -770,7 +807,8 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> { // Reset display offset and cursor position. self.terminal.scroll_display(Scroll::Delta(self.search_state.display_offset_delta)); self.search_state.display_offset_delta = 0; - self.terminal.vi_mode_cursor.point = self.search_state.origin; + self.terminal.vi_mode_cursor.point = + self.search_state.origin.grid_clamp(self.terminal, Boundary::Grid); *self.dirty = true; } @@ -805,7 +843,7 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> { // Store number of lines the viewport had to be moved. let display_offset = self.terminal.grid().display_offset(); - self.search_state.display_offset_delta = old_offset - display_offset as i32; + self.search_state.display_offset_delta += old_offset - display_offset as i32; // Since we found a result, we require no delayed re-search. self.scheduler.unschedule(TimerId::DelayedSearch); @@ -1038,7 +1076,7 @@ impl<N: Notify + OnResize> Processor<N> { match event { // Check for shutdown. - GlutinEvent::UserEvent(Event::TerminalEvent(TerminalEvent::Exit)) => { + GlutinEvent::UserEvent(Event::Terminal(TerminalEvent::Exit)) => { *control_flow = ControlFlow::Exit; return; }, @@ -1181,7 +1219,7 @@ impl<N: Notify + OnResize> Processor<N> { processor.ctx.display.cursor_hidden ^= true; *processor.ctx.dirty = true; }, - Event::TerminalEvent(event) => match event { + Event::Terminal(event) => match event { TerminalEvent::Title(title) => { let ui_config = &processor.ctx.config.ui_config; if ui_config.window.dynamic_title { @@ -1347,7 +1385,7 @@ impl<N: Notify + OnResize> Processor<N> { processor.ctx.display_update_pending.dirty = true; } - let config = match config::reload(&path, &processor.ctx.cli_options) { + let config = match config::reload(path, processor.ctx.cli_options) { Ok(config) => config, Err(_) => return, }; @@ -1398,7 +1436,7 @@ impl<N: Notify + OnResize> Processor<N> { // Disable shadows for transparent windows on macOS. #[cfg(target_os = "macos")] - processor.ctx.window().set_has_shadow(config.ui_config.background_opacity() >= 1.0); + processor.ctx.window().set_has_shadow(config.ui_config.window_opacity() >= 1.0); // Update hint keys. processor.ctx.display.hint_state.update_alphabet(config.ui_config.hints.alphabet()); @@ -1493,6 +1531,6 @@ impl EventProxy { impl EventListener for EventProxy { fn send_event(&self, event: TerminalEvent) { - let _ = self.0.send_event(Event::TerminalEvent(event)); + let _ = self.0.send_event(Event::Terminal(event)); } } diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index 948ec67f..98a1b723 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -29,7 +29,7 @@ use alacritty_terminal::term::{ClipboardType, SizeInfo, Term, TermMode}; use alacritty_terminal::vi_mode::ViMotion; use crate::clipboard::Clipboard; -use crate::config::{Action, BindingMode, Config, Key, SearchAction, ViAction}; +use crate::config::{Action, BindingMode, Config, Key, MouseAction, SearchAction, ViAction}; use crate::daemon::start_daemon; use crate::display::hint::HintMatch; use crate::display::window::Window; @@ -104,6 +104,7 @@ pub trait ActionContext<T: EventListener> { fn toggle_vi_mode(&mut self) {} fn hint_input(&mut self, _character: char) {} fn trigger_hint(&mut self, _hint: &HintMatch) {} + fn expand_selection(&mut self) {} fn paste(&mut self, _text: &str) {} } @@ -148,19 +149,19 @@ impl<T: EventListener> Execute<T> for Action { ctx.terminal_mut().vi_motion(*motion); ctx.mark_dirty(); }, - Action::ViAction(ViAction::ToggleNormalSelection) => { + Action::Vi(ViAction::ToggleNormalSelection) => { Self::toggle_selection(ctx, SelectionType::Simple); }, - Action::ViAction(ViAction::ToggleLineSelection) => { + Action::Vi(ViAction::ToggleLineSelection) => { Self::toggle_selection(ctx, SelectionType::Lines); }, - Action::ViAction(ViAction::ToggleBlockSelection) => { + Action::Vi(ViAction::ToggleBlockSelection) => { Self::toggle_selection(ctx, SelectionType::Block); }, - Action::ViAction(ViAction::ToggleSemanticSelection) => { + Action::Vi(ViAction::ToggleSemanticSelection) => { Self::toggle_selection(ctx, SelectionType::Semantic); }, - Action::ViAction(ViAction::Open) => { + Action::Vi(ViAction::Open) => { let hint = ctx.display().vi_highlighted_hint.take(); if let Some(hint) = &hint { ctx.mouse_mut().block_hint_launcher = false; @@ -168,7 +169,7 @@ impl<T: EventListener> Execute<T> for Action { } ctx.display().vi_highlighted_hint = hint; }, - Action::ViAction(ViAction::SearchNext) => { + Action::Vi(ViAction::SearchNext) => { let terminal = ctx.terminal(); let direction = ctx.search_direction(); let vi_point = terminal.vi_mode_cursor.point; @@ -182,7 +183,7 @@ impl<T: EventListener> Execute<T> for Action { ctx.mark_dirty(); } }, - Action::ViAction(ViAction::SearchPrevious) => { + Action::Vi(ViAction::SearchPrevious) => { let terminal = ctx.terminal(); let direction = ctx.search_direction().opposite(); let vi_point = terminal.vi_mode_cursor.point; @@ -196,7 +197,7 @@ impl<T: EventListener> Execute<T> for Action { ctx.mark_dirty(); } }, - Action::ViAction(ViAction::SearchStart) => { + Action::Vi(ViAction::SearchStart) => { let terminal = ctx.terminal(); let origin = terminal.vi_mode_cursor.point.sub(terminal, Boundary::None, 1); @@ -205,7 +206,7 @@ impl<T: EventListener> Execute<T> for Action { ctx.mark_dirty(); } }, - Action::ViAction(ViAction::SearchEnd) => { + Action::Vi(ViAction::SearchEnd) => { let terminal = ctx.terminal(); let origin = terminal.vi_mode_cursor.point.add(terminal, Boundary::None, 1); @@ -214,25 +215,24 @@ impl<T: EventListener> Execute<T> for Action { ctx.mark_dirty(); } }, - Action::SearchAction(SearchAction::SearchFocusNext) => { + Action::Search(SearchAction::SearchFocusNext) => { ctx.advance_search_origin(ctx.search_direction()); }, - Action::SearchAction(SearchAction::SearchFocusPrevious) => { + Action::Search(SearchAction::SearchFocusPrevious) => { let direction = ctx.search_direction().opposite(); ctx.advance_search_origin(direction); }, - Action::SearchAction(SearchAction::SearchConfirm) => ctx.confirm_search(), - Action::SearchAction(SearchAction::SearchCancel) => ctx.cancel_search(), - Action::SearchAction(SearchAction::SearchClear) => { + Action::Search(SearchAction::SearchConfirm) => ctx.confirm_search(), + Action::Search(SearchAction::SearchCancel) => ctx.cancel_search(), + Action::Search(SearchAction::SearchClear) => { let direction = ctx.search_direction(); ctx.cancel_search(); ctx.start_search(direction); }, - Action::SearchAction(SearchAction::SearchDeleteWord) => ctx.search_pop_word(), - Action::SearchAction(SearchAction::SearchHistoryPrevious) => { - ctx.search_history_previous() - }, - Action::SearchAction(SearchAction::SearchHistoryNext) => ctx.search_history_next(), + Action::Search(SearchAction::SearchDeleteWord) => ctx.search_pop_word(), + Action::Search(SearchAction::SearchHistoryPrevious) => ctx.search_history_previous(), + Action::Search(SearchAction::SearchHistoryNext) => ctx.search_history_next(), + Action::Mouse(MouseAction::ExpandSelection) => ctx.expand_selection(), Action::SearchForward => ctx.start_search(Direction::Right), Action::SearchBackward => ctx.start_search(Direction::Left), Action::Copy => ctx.copy_selection(ClipboardType::Clipboard), @@ -533,51 +533,12 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { let display_offset = self.ctx.terminal().grid().display_offset(); let point = self.ctx.mouse().point(&self.ctx.size_info(), display_offset); - match button { - MouseButton::Left => self.on_left_click(point), - MouseButton::Right => self.on_right_click(point), - // Do nothing when using buttons other than LMB. - _ => self.ctx.mouse_mut().click_state = ClickState::None, + if let MouseButton::Left = button { + self.on_left_click(point) } } } - /// Handle selection expansion on right click. - fn on_right_click(&mut self, point: Point) { - match self.ctx.mouse().click_state { - ClickState::Click => { - let selection_type = if self.ctx.modifiers().ctrl() { - SelectionType::Block - } else { - SelectionType::Simple - }; - - self.expand_selection(point, selection_type); - }, - ClickState::DoubleClick => self.expand_selection(point, SelectionType::Semantic), - ClickState::TripleClick => self.expand_selection(point, SelectionType::Lines), - ClickState::None => (), - } - } - - /// Expand existing selection. - fn expand_selection(&mut self, point: Point, selection_type: SelectionType) { - let cell_side = self.ctx.mouse().cell_side; - - let selection = match &mut self.ctx.terminal_mut().selection { - Some(selection) => selection, - None => return, - }; - - selection.ty = selection_type; - self.ctx.update_selection(point, cell_side); - - // Move vi mode cursor to mouse click position. - if self.ctx.terminal().mode().contains(TermMode::VI) && !self.ctx.search_active() { - self.ctx.terminal_mut().vi_mode_cursor.point = point; - } - } - /// Handle left click selection and vi mode cursor movement. fn on_left_click(&mut self, point: Point) { let side = self.ctx.mouse().cell_side; @@ -751,8 +712,9 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { } else { match state { ElementState::Pressed => { - self.process_mouse_bindings(button); + // Process mouse press before bindings to update the `click_state`. self.on_mouse_press(button); + self.process_mouse_bindings(button); }, ElementState::Released => self.on_mouse_release(button), } @@ -1036,7 +998,7 @@ mod tests { } fn terminal(&self) -> &Term<T> { - &self.terminal + self.terminal } fn terminal_mut(&mut self) -> &mut Term<T> { @@ -1140,6 +1102,7 @@ mod tests { let mut mouse = Mouse { click_state: $initial_state, + last_click_button: $initial_button, ..Mouse::default() }; @@ -1241,7 +1204,7 @@ mod tests { }, window_id: unsafe { std::mem::transmute_copy(&0) }, }, - end_state: ClickState::None, + end_state: ClickState::Click, } test_clickstate! { diff --git a/alacritty/src/logging.rs b/alacritty/src/logging.rs index 36d20fa3..7cef3887 100644 --- a/alacritty/src/logging.rs +++ b/alacritty/src/logging.rs @@ -13,7 +13,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use glutin::event_loop::EventLoopProxy; -use log::{self, Level}; +use log::{self, Level, LevelFilter}; use crate::cli::Options; use crate::event::Event; @@ -29,7 +29,7 @@ pub fn initialize( options: &Options, event_proxy: EventLoopProxy<Event>, ) -> Result<Option<PathBuf>, log::SetLoggerError> { - log::set_max_level(options.log_level); + log::set_max_level(options.log_level()); let logger = Logger::new(event_proxy); let path = logger.file_path(); @@ -102,13 +102,13 @@ impl log::Log for Logger { let index = record.target().find(':').unwrap_or_else(|| record.target().len()); let target = &record.target()[..index]; - // Only log our own crates. - if !self.enabled(record.metadata()) || !ALLOWED_TARGETS.contains(&target) { + // Only log our own crates, except when logging at Level::Trace. + if !self.enabled(record.metadata()) || !is_allowed_target(record.level(), target) { return; } // Create log message for the given `record` and `target`. - let message = create_log_message(record, &target); + let message = create_log_message(record, target); if let Ok(mut logfile) = self.logfile.lock() { // Write to logfile. @@ -149,6 +149,14 @@ fn create_log_message(record: &log::Record<'_>, target: &str) -> String { message } +/// Check if log messages from a crate should be logged. +fn is_allowed_target(level: Level, target: &str) -> bool { + match (level, log::max_level()) { + (Level::Error, LevelFilter::Trace) | (Level::Warn, LevelFilter::Trace) => true, + _ => ALLOWED_TARGETS.contains(&target), + } +} + struct OnDemandLogFile { file: Option<LineWriter<File>>, created: Arc<AtomicBool>, diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 85a4fc5e..f6e3c1d0 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -1,7 +1,7 @@ //! Alacritty - The GPU Enhanced Terminal. #![warn(rust_2018_idioms, future_incompatible)] -#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use, clippy::wrong_pub_self_convention)] +#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use)] #![cfg_attr(feature = "cargo-clippy", deny(warnings))] // With the default subsystem, 'console', windows creates an additional console // window for the program. diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 8d0c4b68..71ed6e28 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -194,7 +194,7 @@ impl GlyphCache { let size = font.size(); // Load regular font. - let regular_desc = Self::make_desc(&font.normal(), Slant::Normal, Weight::Normal); + let regular_desc = Self::make_desc(font.normal(), Slant::Normal, Weight::Normal); let regular = Self::load_regular_font(rasterizer, ®ular_desc, size)?; @@ -236,7 +236,7 @@ impl GlyphCache { error!("{}", err); let fallback_desc = - Self::make_desc(&Font::default().normal(), Slant::Normal, Weight::Normal); + Self::make_desc(Font::default().normal(), Slant::Normal, Weight::Normal); rasterizer.load_font(&fallback_desc, size) }, } @@ -375,7 +375,7 @@ impl GlyphCache { /// Calculate font metrics without access to a glyph cache. pub fn static_metrics(font: Font, dpr: f64) -> Result<crossfont::Metrics, crossfont::Error> { let mut rasterizer = crossfont::Rasterizer::new(dpr as f32, font.use_thin_strokes)?; - let regular_desc = GlyphCache::make_desc(&font.normal(), Slant::Normal, Weight::Normal); + let regular_desc = GlyphCache::make_desc(font.normal(), Slant::Normal, Weight::Normal); let regular = Self::load_regular_font(&mut rasterizer, ®ular_desc, font.size())?; rasterizer.get_glyph(GlyphKey { font_key: regular, character: 'm', size: font.size() })?; @@ -785,7 +785,7 @@ impl Drop for QuadRenderer { impl<'a> RenderApi<'a> { pub fn clear(&self, color: Rgb) { unsafe { - let alpha = self.config.background_opacity(); + let alpha = self.config.window_opacity(); gl::ClearColor( (f32::from(color.r) / 255.0).min(1.0) * alpha, (f32::from(color.g) / 255.0).min(1.0) * alpha, @@ -1325,12 +1325,12 @@ impl Atlas { } // If there's not enough room in current row, go onto next one. - if !self.room_in_row(&glyph) { + if !self.room_in_row(glyph) { self.advance_row()?; } // If there's still not room, there's nothing that can be done here.. - if !self.room_in_row(&glyph) { + if !self.room_in_row(glyph) { return Err(AtlasInsertError::Full); } diff --git a/alacritty/src/renderer/rects.rs b/alacritty/src/renderer/rects.rs index 591c9f46..77c22011 100644 --- a/alacritty/src/renderer/rects.rs +++ b/alacritty/src/renderer/rects.rs @@ -158,9 +158,9 @@ impl RenderLines { /// Update the stored lines with the next cell info. #[inline] pub fn update(&mut self, cell: &RenderableCell) { - self.update_flag(&cell, Flags::UNDERLINE); - self.update_flag(&cell, Flags::DOUBLE_UNDERLINE); - self.update_flag(&cell, Flags::STRIKEOUT); + self.update_flag(cell, Flags::UNDERLINE); + self.update_flag(cell, Flags::DOUBLE_UNDERLINE); + self.update_flag(cell, Flags::STRIKEOUT); } /// Update the lines for a specific flag. |