Add support for -e argument

This commit is contained in:
Niklas Claesson 2017-01-25 00:19:45 +01:00 committed by Joe Wilm
parent 08f348ecea
commit 019daa8b69
4 changed files with 45 additions and 8 deletions

View File

@ -14,6 +14,7 @@
extern crate log; extern crate log;
use clap::{Arg, App}; use clap::{Arg, App};
use index::{Line, Column}; use index::{Line, Column};
use config::Shell;
const DEFAULT_TITLE: &'static str = "Alacritty"; const DEFAULT_TITLE: &'static str = "Alacritty";
@ -24,7 +25,8 @@ pub struct Options {
pub columns: Column, pub columns: Column,
pub lines: Line, pub lines: Line,
pub title: String, pub title: String,
pub log_level: log::LogLevelFilter pub log_level: log::LogLevelFilter,
pub shell: Option<Shell<'static>>,
} }
impl Default for Options { impl Default for Options {
@ -35,7 +37,8 @@ impl Default for Options {
columns: Column(80), columns: Column(80),
lines: Line(24), lines: Line(24),
title: DEFAULT_TITLE.to_owned(), title: DEFAULT_TITLE.to_owned(),
log_level: log::LogLevelFilter::Warn log_level: log::LogLevelFilter::Warn,
shell: None,
} }
} }
} }
@ -74,6 +77,13 @@ impl Options {
.multiple(true) .multiple(true)
.conflicts_with("q") .conflicts_with("q")
.help("Increases the level of verbosity (the max level is -vvv)")) .help("Increases the level of verbosity (the max level is -vvv)"))
.arg(Arg::with_name("command")
.short("e")
.multiple(true)
.takes_value(true)
.min_values(1)
.allow_hyphen_values(true)
.help("Command and args to execute (must be last argument)"))
.get_matches(); .get_matches();
if matches.is_present("ref-test") { if matches.is_present("ref-test") {
@ -106,6 +116,15 @@ impl Options {
3 | _ => options.log_level = log::LogLevelFilter::Trace 3 | _ => options.log_level = log::LogLevelFilter::Trace
} }
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 command = String::from(args.next().unwrap());
let args = args.map(String::from).collect();
options.shell = Some(Shell::new_with_args(command, args));
}
options options
} }
@ -116,4 +135,8 @@ impl Options {
pub fn columns_u32(&self) -> u32 { pub fn columns_u32(&self) -> u32 {
self.columns.0 as u32 self.columns.0 as u32
} }
pub fn shell(&self) -> Option<&Shell> {
self.shell.as_ref()
}
} }

View File

@ -176,13 +176,24 @@ pub struct Shell<'a> {
} }
impl<'a> Shell<'a> { impl<'a> Shell<'a> {
pub fn new(program: &'a str) -> Shell<'a> { pub fn new<S>(program: S) -> Shell<'a>
where S: Into<Cow<'a, str>>
{
Shell { Shell {
program: Cow::from(program), program: program.into(),
args: Vec::new(), args: Vec::new(),
} }
} }
pub fn new_with_args<S>(program: S, args: Vec<String>) -> Shell<'a>
where S: Into<Cow<'a, str>>
{
Shell {
program: program.into(),
args: args
}
}
pub fn program(&self) -> &str { pub fn program(&self) -> &str {
&*self.program &*self.program
} }

View File

@ -103,7 +103,7 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// The pty forks a process to run the shell on the slave side of the // The pty forks a process to run the shell on the slave side of the
// pseudoterminal. A file descriptor for the master side is retained for // pseudoterminal. A file descriptor for the master side is retained for
// reading/writing to the shell. // reading/writing to the shell.
let mut pty = tty::new(&config, display.size()); let mut pty = tty::new(&config, &options, display.size());
// Create the pseudoterminal I/O loop // Create the pseudoterminal I/O loop
// //

View File

@ -26,6 +26,7 @@ use libc::{self, winsize, c_int, pid_t, WNOHANG, WIFEXITED, WEXITSTATUS, SIGCHLD
use term::SizeInfo; use term::SizeInfo;
use display::OnResize; use display::OnResize;
use config::{Config, Shell}; use config::{Config, Shell};
use cli::Options;
/// Process ID of child process /// Process ID of child process
/// ///
@ -179,15 +180,17 @@ fn get_pw_entry(buf: &mut [i8; 1024]) -> Passwd {
} }
/// Create a new tty and return a handle to interact with it. /// Create a new tty and return a handle to interact with it.
pub fn new<T: ToWinsize>(config: &Config, size: T) -> Pty { pub fn new<T: ToWinsize>(config: &Config, options: &Options, size: T) -> Pty {
let win = size.to_winsize(); let win = size.to_winsize();
let mut buf = [0; 1024]; let mut buf = [0; 1024];
let pw = get_pw_entry(&mut buf); let pw = get_pw_entry(&mut buf);
let (master, slave) = openpty(win.ws_row as _, win.ws_col as _); let (master, slave) = openpty(win.ws_row as _, win.ws_col as _);
let default_shell = Shell::new(pw.shell); let default_shell = &Shell::new(pw.shell);
let shell = config.shell().unwrap_or(&default_shell); let shell = options.shell()
.or_else(|| config.shell())
.unwrap_or(&default_shell);
let mut builder = Command::new(shell.program()); let mut builder = Command::new(shell.program());
for arg in shell.args() { for arg in shell.args() {