2019-05-10 11:36:16 +00:00
|
|
|
use std::cmp::max;
|
2019-10-06 10:47:20 +00:00
|
|
|
use std::path::PathBuf;
|
2019-05-03 23:48:25 +00:00
|
|
|
|
2022-01-04 18:25:26 +00:00
|
|
|
#[cfg(unix)]
|
|
|
|
use clap::Subcommand;
|
|
|
|
use clap::{Args, Parser};
|
2020-01-12 00:24:56 +00:00
|
|
|
use log::{self, error, LevelFilter};
|
2021-11-22 18:34:09 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2020-08-22 20:55:27 +00:00
|
|
|
use serde_yaml::Value;
|
2019-05-03 23:48:25 +00:00
|
|
|
|
2021-11-22 18:34:09 +00:00
|
|
|
use alacritty_terminal::config::{Program, PtyConfig};
|
2019-10-05 00:29:26 +00:00
|
|
|
|
2022-01-03 18:55:22 +00:00
|
|
|
use crate::config::window::{Class, Identity, DEFAULT_NAME};
|
2021-11-22 18:34:09 +00:00
|
|
|
use crate::config::{serde_utils, UiConfig};
|
2019-05-03 23:48:25 +00:00
|
|
|
|
2021-10-23 07:16:47 +00:00
|
|
|
/// CLI options for the main Alacritty executable.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[derive(Parser, Default, Debug)]
|
|
|
|
#[clap(author, about, version = env!("VERSION"))]
|
2019-05-10 11:36:16 +00:00
|
|
|
pub struct Options {
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Print all events to stdout.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2019-05-10 11:36:16 +00:00
|
|
|
pub print_events: bool,
|
2021-08-18 09:36:51 +00:00
|
|
|
|
|
|
|
/// Generates ref test.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2019-05-10 11:36:16 +00:00
|
|
|
pub ref_test: bool,
|
2021-08-18 09:36:51 +00:00
|
|
|
|
|
|
|
/// Defines the X11 window ID (as a decimal integer) to embed Alacritty within.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-08-18 09:36:51 +00:00
|
|
|
pub embed: Option<String>,
|
2019-05-03 23:48:25 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.yml].
|
|
|
|
#[cfg(not(any(target_os = "macos", windows)))]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-08-18 09:36:51 +00:00
|
|
|
pub config_file: Option<PathBuf>,
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Specify alternative configuration file [default: %APPDATA%\alacritty\alacritty.yml].
|
|
|
|
#[cfg(windows)]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-08-18 09:36:51 +00:00
|
|
|
pub config_file: Option<PathBuf>,
|
2020-07-04 06:13:32 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Specify alternative configuration file [default: $HOME/.config/alacritty/alacritty.yml].
|
|
|
|
#[cfg(target_os = "macos")]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-08-18 09:36:51 +00:00
|
|
|
pub config_file: Option<PathBuf>,
|
2019-05-03 23:48:25 +00:00
|
|
|
|
2021-10-23 07:16:47 +00:00
|
|
|
/// Path for IPC socket creation.
|
|
|
|
#[cfg(unix)]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub socket: Option<PathBuf>,
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Reduces the level of verbosity (the min level is -qq).
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(short, conflicts_with("verbose"), parse(from_occurrences))]
|
2021-08-18 09:36:51 +00:00
|
|
|
quiet: u8,
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Increases the level of verbosity (the max level is -vvv).
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(short, conflicts_with("quiet"), parse(from_occurrences))]
|
2021-08-18 09:36:51 +00:00
|
|
|
verbose: u8,
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// Override configuration file options [example: cursor.style=Beam].
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(short = 'o', long, multiple_values = true)]
|
2021-08-18 09:36:51 +00:00
|
|
|
option: Vec<String>,
|
2021-10-23 07:16:47 +00:00
|
|
|
|
|
|
|
/// CLI options for config overrides.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(skip)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub config_options: Value,
|
|
|
|
|
2022-01-04 18:25:26 +00:00
|
|
|
/// Options which can be passed via IPC.
|
|
|
|
#[clap(flatten)]
|
2022-01-03 18:55:22 +00:00
|
|
|
pub window_options: WindowOptions,
|
2021-11-22 18:34:09 +00:00
|
|
|
|
2021-10-23 07:16:47 +00:00
|
|
|
/// Subcommand passed to the CLI.
|
|
|
|
#[cfg(unix)]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(subcommand)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub subcommands: Option<Subcommands>,
|
2021-08-18 09:36:51 +00:00
|
|
|
}
|
2019-10-09 21:37:48 +00:00
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
impl Options {
|
|
|
|
pub fn new() -> Self {
|
2022-01-04 18:25:26 +00:00
|
|
|
let mut options = Self::parse();
|
2021-08-18 09:36:51 +00:00
|
|
|
|
|
|
|
// 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),
|
2020-08-22 20:55:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 11:36:16 +00:00
|
|
|
options
|
2019-05-03 23:48:25 +00:00
|
|
|
}
|
|
|
|
|
2020-08-22 20:55:27 +00:00
|
|
|
/// Override configuration file with options from the CLI.
|
2021-11-22 18:34:09 +00:00
|
|
|
pub fn override_config(&self, config: &mut UiConfig) {
|
2021-10-23 07:16:47 +00:00
|
|
|
#[cfg(unix)]
|
|
|
|
{
|
2021-11-22 18:34:09 +00:00
|
|
|
config.ipc_socket |= self.socket.is_some();
|
2021-10-23 07:16:47 +00:00
|
|
|
}
|
|
|
|
|
2022-01-03 18:55:22 +00:00
|
|
|
config.window.dynamic_title &= self.window_options.window_identity.title.is_none();
|
2021-11-22 18:34:09 +00:00
|
|
|
config.window.embed = self.embed.as_ref().and_then(|embed| embed.parse().ok());
|
|
|
|
config.debug.print_events |= self.print_events;
|
|
|
|
config.debug.log_level = max(config.debug.log_level, self.log_level());
|
|
|
|
config.debug.ref_test |= self.ref_test;
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-11-22 18:34:09 +00:00
|
|
|
if config.debug.print_events {
|
|
|
|
config.debug.log_level = max(config.debug.log_level, LevelFilter::Info);
|
2019-05-10 11:36:16 +00:00
|
|
|
}
|
2019-05-03 23:48:25 +00:00
|
|
|
}
|
2021-08-18 09:36:51 +00:00
|
|
|
|
|
|
|
/// 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,
|
|
|
|
}
|
|
|
|
}
|
2019-05-10 11:36:16 +00:00
|
|
|
}
|
|
|
|
|
2020-08-22 20:55:27 +00:00
|
|
|
/// Format an option in the format of `parent.field=value` to a serde Value.
|
|
|
|
fn option_as_value(option: &str) -> Result<Value, serde_yaml::Error> {
|
|
|
|
let mut yaml_text = String::with_capacity(option.len());
|
|
|
|
let mut closing_brackets = String::new();
|
|
|
|
|
|
|
|
for (i, c) in option.chars().enumerate() {
|
|
|
|
match c {
|
|
|
|
'=' => {
|
|
|
|
yaml_text.push_str(": ");
|
|
|
|
yaml_text.push_str(&option[i + 1..]);
|
|
|
|
break;
|
|
|
|
},
|
|
|
|
'.' => {
|
|
|
|
yaml_text.push_str(": {");
|
|
|
|
closing_brackets.push('}');
|
|
|
|
},
|
|
|
|
_ => yaml_text.push(c),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yaml_text += &closing_brackets;
|
|
|
|
|
|
|
|
serde_yaml::from_str(&yaml_text)
|
|
|
|
}
|
|
|
|
|
2021-08-18 09:36:51 +00:00
|
|
|
/// 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() }),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-22 18:34:09 +00:00
|
|
|
/// Terminal specific cli options which can be passed to new windows via IPC.
|
2022-06-02 01:22:50 +00:00
|
|
|
#[derive(Serialize, Deserialize, Args, Default, Debug, Clone, PartialEq, Eq)]
|
2021-11-22 18:34:09 +00:00
|
|
|
pub struct TerminalOptions {
|
|
|
|
/// Start the shell in the specified working directory.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-11-22 18:34:09 +00:00
|
|
|
pub working_directory: Option<PathBuf>,
|
|
|
|
|
|
|
|
/// Remain open after child process exit.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long)]
|
2021-11-22 18:34:09 +00:00
|
|
|
pub hold: bool,
|
|
|
|
|
|
|
|
/// Command and args to execute (must be last argument).
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(short = 'e', long, allow_hyphen_values = true, multiple_values = true)]
|
2021-11-22 18:34:09 +00:00
|
|
|
command: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TerminalOptions {
|
|
|
|
/// 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() })
|
|
|
|
}
|
2021-12-23 10:23:06 +00:00
|
|
|
|
|
|
|
/// Override the [`PtyConfig`]'s fields with the [`TerminalOptions`].
|
|
|
|
pub fn override_pty_config(&self, pty_config: &mut PtyConfig) {
|
|
|
|
if let Some(working_directory) = &self.working_directory {
|
|
|
|
if working_directory.is_dir() {
|
|
|
|
pty_config.working_directory = Some(working_directory.to_owned());
|
|
|
|
} else {
|
|
|
|
error!("Invalid working directory: {:?}", working_directory);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(command) = self.command() {
|
|
|
|
pty_config.shell = Some(command);
|
|
|
|
}
|
|
|
|
|
|
|
|
pty_config.hold |= self.hold;
|
|
|
|
}
|
2021-11-22 18:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<TerminalOptions> for PtyConfig {
|
|
|
|
fn from(mut options: TerminalOptions) -> Self {
|
2021-12-23 10:23:06 +00:00
|
|
|
PtyConfig {
|
|
|
|
working_directory: options.working_directory.take(),
|
|
|
|
shell: options.command(),
|
|
|
|
hold: options.hold,
|
|
|
|
}
|
2021-11-22 18:34:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-03 18:55:22 +00:00
|
|
|
/// Window specific cli options which can be passed to new windows via IPC.
|
2022-06-02 01:22:50 +00:00
|
|
|
#[derive(Serialize, Deserialize, Args, Default, Debug, Clone, PartialEq, Eq)]
|
2022-01-03 18:55:22 +00:00
|
|
|
pub struct WindowIdentity {
|
|
|
|
/// Defines the window title [default: Alacritty].
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(short, long)]
|
2022-01-03 18:55:22 +00:00
|
|
|
pub title: Option<String>,
|
|
|
|
|
|
|
|
/// Defines window class/app_id on X11/Wayland [default: Alacritty].
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long, value_name = "instance> | <instance>,<general", parse(try_from_str = parse_class))]
|
2022-01-03 18:55:22 +00:00
|
|
|
pub class: Option<Class>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl WindowIdentity {
|
|
|
|
/// Override the [`WindowIdentityConfig`]'s fields with the [`WindowOptions`].
|
|
|
|
pub fn override_identity_config(&self, identity: &mut Identity) {
|
|
|
|
if let Some(title) = &self.title {
|
|
|
|
identity.title = title.clone();
|
|
|
|
}
|
|
|
|
if let Some(class) = &self.class {
|
|
|
|
identity.class = class.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-23 07:16:47 +00:00
|
|
|
/// Available CLI subcommands.
|
|
|
|
#[cfg(unix)]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[derive(Subcommand, Debug)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub enum Subcommands {
|
|
|
|
Msg(MessageOptions),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Send a message to the Alacritty socket.
|
|
|
|
#[cfg(unix)]
|
2022-01-04 18:25:26 +00:00
|
|
|
#[derive(Args, Debug)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub struct MessageOptions {
|
|
|
|
/// IPC socket connection path override.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(long, short)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub socket: Option<PathBuf>,
|
|
|
|
|
|
|
|
/// Message which should be sent.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(subcommand)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub message: SocketMessage,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Available socket messages.
|
|
|
|
#[cfg(unix)]
|
2022-06-02 01:22:50 +00:00
|
|
|
#[derive(Subcommand, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
2021-10-23 07:16:47 +00:00
|
|
|
pub enum SocketMessage {
|
|
|
|
/// Create a new window in the same Alacritty process.
|
2022-01-03 18:55:22 +00:00
|
|
|
CreateWindow(WindowOptions),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Subset of options that we pass to a 'create-window' subcommand.
|
2022-06-02 01:22:50 +00:00
|
|
|
#[derive(Serialize, Deserialize, Args, Default, Clone, Debug, PartialEq, Eq)]
|
2022-01-03 18:55:22 +00:00
|
|
|
pub struct WindowOptions {
|
|
|
|
/// Terminal options which can be passed via IPC.
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(flatten)]
|
2022-01-03 18:55:22 +00:00
|
|
|
pub terminal_options: TerminalOptions,
|
|
|
|
|
2022-01-04 18:25:26 +00:00
|
|
|
#[clap(flatten)]
|
2022-01-03 18:55:22 +00:00
|
|
|
/// Window options which could be passed via IPC.
|
|
|
|
pub window_identity: WindowIdentity,
|
2021-10-23 07:16:47 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 11:36:16 +00:00
|
|
|
#[cfg(test)]
|
2020-01-28 12:32:35 +00:00
|
|
|
mod tests {
|
2020-08-22 20:55:27 +00:00
|
|
|
use super::*;
|
|
|
|
|
2021-11-19 23:34:40 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
use std::fs::File;
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
use std::io::Read;
|
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
2022-01-04 18:25:26 +00:00
|
|
|
use clap::IntoApp;
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
use clap_complete::Shell;
|
2020-08-22 20:55:27 +00:00
|
|
|
use serde_yaml::mapping::Mapping;
|
2019-05-10 11:36:16 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dynamic_title_ignoring_options_by_default() {
|
2021-11-22 18:34:09 +00:00
|
|
|
let mut config = UiConfig::default();
|
|
|
|
let old_dynamic_title = config.window.dynamic_title;
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-12-25 19:32:54 +00:00
|
|
|
Options::default().override_config(&mut config);
|
2019-05-03 23:48:25 +00:00
|
|
|
|
2021-11-22 18:34:09 +00:00
|
|
|
assert_eq!(old_dynamic_title, config.window.dynamic_title);
|
2019-05-03 23:48:25 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 11:36:16 +00:00
|
|
|
#[test]
|
|
|
|
fn dynamic_title_overridden_by_options() {
|
2021-11-22 18:34:09 +00:00
|
|
|
let mut config = UiConfig::default();
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2022-01-03 18:55:22 +00:00
|
|
|
let title = Some(String::from("foo"));
|
|
|
|
let window_identity = WindowIdentity { title, ..WindowIdentity::default() };
|
|
|
|
let new_window_options = WindowOptions { window_identity, ..WindowOptions::default() };
|
|
|
|
let options = Options { window_options: new_window_options, ..Options::default() };
|
2020-08-22 20:55:27 +00:00
|
|
|
options.override_config(&mut config);
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-11-22 18:34:09 +00:00
|
|
|
assert!(!config.window.dynamic_title);
|
2019-05-03 23:48:25 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 11:36:16 +00:00
|
|
|
#[test]
|
2020-03-14 15:09:10 +00:00
|
|
|
fn dynamic_title_not_overridden_by_config() {
|
2021-11-22 18:34:09 +00:00
|
|
|
let mut config = UiConfig::default();
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2022-01-03 18:55:22 +00:00
|
|
|
config.window.identity.title = "foo".to_owned();
|
2021-12-25 19:32:54 +00:00
|
|
|
Options::default().override_config(&mut config);
|
2019-05-10 11:36:16 +00:00
|
|
|
|
2021-11-22 18:34:09 +00:00
|
|
|
assert!(config.window.dynamic_title);
|
2019-05-10 11:36:16 +00:00
|
|
|
}
|
2020-08-22 20:55:27 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn valid_option_as_value() {
|
|
|
|
// Test with a single field.
|
|
|
|
let value = option_as_value("field=true").unwrap();
|
|
|
|
|
|
|
|
let mut mapping = Mapping::new();
|
|
|
|
mapping.insert(Value::String(String::from("field")), Value::Bool(true));
|
|
|
|
|
|
|
|
assert_eq!(value, Value::Mapping(mapping));
|
|
|
|
|
|
|
|
// Test with nested fields
|
|
|
|
let value = option_as_value("parent.field=true").unwrap();
|
|
|
|
|
|
|
|
let mut parent_mapping = Mapping::new();
|
|
|
|
parent_mapping.insert(Value::String(String::from("field")), Value::Bool(true));
|
|
|
|
let mut mapping = Mapping::new();
|
|
|
|
mapping.insert(Value::String(String::from("parent")), Value::Mapping(parent_mapping));
|
|
|
|
|
|
|
|
assert_eq!(value, Value::Mapping(mapping));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn invalid_option_as_value() {
|
|
|
|
let value = option_as_value("}");
|
|
|
|
assert!(value.is_err());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn float_option_as_value() {
|
|
|
|
let value = option_as_value("float=3.4").unwrap();
|
|
|
|
|
|
|
|
let mut expected = Mapping::new();
|
|
|
|
expected.insert(Value::String(String::from("float")), Value::Number(3.4.into()));
|
|
|
|
|
|
|
|
assert_eq!(value, Value::Mapping(expected));
|
|
|
|
}
|
2021-08-18 09:36:51 +00:00
|
|
|
|
|
|
|
#[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());
|
|
|
|
}
|
2021-11-19 23:34:40 +00:00
|
|
|
|
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
#[test]
|
|
|
|
fn completions() {
|
2022-01-04 18:25:26 +00:00
|
|
|
let mut clap = Options::into_app();
|
2021-11-19 23:34:40 +00:00
|
|
|
|
|
|
|
for (shell, file) in &[
|
|
|
|
(Shell::Bash, "alacritty.bash"),
|
|
|
|
(Shell::Fish, "alacritty.fish"),
|
|
|
|
(Shell::Zsh, "_alacritty"),
|
|
|
|
] {
|
|
|
|
let mut generated = Vec::new();
|
2022-01-04 18:25:26 +00:00
|
|
|
clap_complete::generate(*shell, &mut clap, "alacritty", &mut generated);
|
2021-11-19 23:34:40 +00:00
|
|
|
let generated = String::from_utf8_lossy(&generated);
|
|
|
|
|
|
|
|
let mut completion = String::new();
|
|
|
|
let mut file = File::open(format!("../extra/completions/{}", file)).unwrap();
|
|
|
|
file.read_to_string(&mut completion).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(generated, completion);
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Use this to generate new completions.
|
|
|
|
//
|
2022-01-04 18:25:26 +00:00
|
|
|
// let mut file = File::create("../extra/completions/alacritty.bash").unwrap();
|
|
|
|
// clap_complete::generate(Shell::Bash, &mut clap, "alacritty", &mut file);
|
|
|
|
// let mut file = File::create("../extra/completions/alacritty.fish").unwrap();
|
|
|
|
// clap_complete::generate(Shell::Fish, &mut clap, "alacritty", &mut file);
|
|
|
|
// let mut file = File::create("../extra/completions/_alacritty").unwrap();
|
|
|
|
// clap_complete::generate(Shell::Zsh, &mut clap, "alacritty", &mut file);
|
2021-11-19 23:34:40 +00:00
|
|
|
}
|
2019-05-03 23:48:25 +00:00
|
|
|
}
|