diff --git a/contrib/completion/hx.bash b/contrib/completion/hx.bash index 37893bf56..f5473cac6 100644 --- a/contrib/completion/hx.bash +++ b/contrib/completion/hx.bash @@ -21,7 +21,7 @@ _hx() { case "$2" in -*) - mapfile -t COMPREPLY < <(compgen -W "-h --help --tutor -V --version -v -vv -vvv --health -g --grammar --vsplit --hsplit -c --config --log" -- """$2""") + mapfile -t COMPREPLY < <(compgen -W "-h --help --tutor -V --version -v -vv -vvv --health -g --grammar --vsplit --hsplit -e --execute -c --config --log" -- """$2""") return 0 ;; *) diff --git a/contrib/completion/hx.elv b/contrib/completion/hx.elv index 8d86ed7af..f8a72beaf 100644 --- a/contrib/completion/hx.elv +++ b/contrib/completion/hx.elv @@ -50,6 +50,8 @@ set edit:completion:arg-completer[hx] = {|@args| $candidate "--grammar" "(Fetch or build the tree-sitter grammars)" $candidate "--vsplit" "(Splits all given files vertically)" $candidate "--hsplit" "(Splits all given files horizontally)" + $candidate "-e" "(Executes the given command on startup)" + $candidate "--execute" "(Executes the given command on startup)" $candidate "--config" "(Specifies a file to use for configuration)" $candidate "--log" "(Specifies a file to write log data into)" } diff --git a/contrib/completion/hx.fish b/contrib/completion/hx.fish index f05dba8dd..01f92be5e 100644 --- a/contrib/completion/hx.fish +++ b/contrib/completion/hx.fish @@ -12,6 +12,7 @@ complete -c hx -l hsplit -d "Splits all given files horizontally" complete -c hx -s c -l config -r -d "Specifies a file to use for config" complete -c hx -l log -r -d "Specifies a file to use for logging" complete -c hx -s w -l working-dir -d "Specify initial working directory" -xa "(__fish_complete_directories)" +complete -c hx -s e -l execute -d "Executes the given command on startup" function __hx_langs_ops hx --health languages | tail -n '+2' | string replace -fr '^(\S+) .*' '$1' diff --git a/contrib/completion/hx.nu b/contrib/completion/hx.nu index 30eeb20fc..e5c2a9864 100644 --- a/contrib/completion/hx.nu +++ b/contrib/completion/hx.nu @@ -24,6 +24,7 @@ export extern hx [ --version(-V), # Prints version information --vsplit, # Splits all given files vertically into different windows --hsplit, # Splits all given files horizontally into different windows + --execute(-e), # Executes the given command on startup --working-dir(-w): glob, # Specify an initial working directory ...files: glob, # Sets the input file to use, position can also be specified via file[:row[:col]] ] diff --git a/contrib/completion/hx.zsh b/contrib/completion/hx.zsh index 2631d2283..305e9870d 100644 --- a/contrib/completion/hx.zsh +++ b/contrib/completion/hx.zsh @@ -18,6 +18,8 @@ _hx() { "--hsplit[Splits all given files horizontally]" \ "-c[Specifies a file to use for configuration]" \ "--config[Specifies a file to use for configuration]" \ + "-e[Executes the given command on startup]" \ + "--execute[Executes the given command on startup]" \ "-w[Specify initial working directory]" \ "--working-dir[Specify initial working directory]" \ "--log[Specifies a file to use for logging]" \ diff --git a/helix-term/src/args.rs b/helix-term/src/args.rs index 9b1b4409b..f3b6b6198 100644 --- a/helix-term/src/args.rs +++ b/helix-term/src/args.rs @@ -19,6 +19,8 @@ pub struct Args { pub config_file: Option, pub files: IndexMap>, pub working_directory: Option, + /// The macro to execute on startup + pub execute: Vec, } impl Args { @@ -74,6 +76,10 @@ impl Args { Some(path) => args.log_file = Some(path.into()), None => anyhow::bail!("--log must specify a path to write"), }, + "-e" | "--execute" => match argv.next().as_deref() { + Some(command) => args.execute = helix_view::input::parse_macro(command)?, + None => anyhow::bail!("--execute receives a command to execute"), + }, "-w" | "--working-dir" => match argv.next().as_deref() { Some(path) => { args.working_directory = if Path::new(path).is_dir() { diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index 31ab85cff..cc5b08190 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Error, Result}; use crossterm::event::EventStream; +use futures_util::{stream, StreamExt}; use helix_loader::VERSION_AND_GIT_HASH; use helix_term::application::Application; use helix_term::args::Args; @@ -40,7 +41,7 @@ fn main() -> Result<()> { #[tokio::main] async fn main_impl() -> Result { - let args = Args::parse_args().context("could not parse arguments")?; + let mut args = Args::parse_args().context("could not parse arguments")?; helix_loader::initialize_config_file(args.config_file.clone()); helix_loader::initialize_log_file(args.log_file.clone()); @@ -75,6 +76,7 @@ FLAGS: --hsplit Splits all given files horizontally into different windows -w, --working-dir Specify an initial working directory +N Open the first given file at line number N + -e, --execute Executes the given command on startup ", env!("CARGO_PKG_NAME"), VERSION_AND_GIT_HASH, @@ -147,10 +149,20 @@ FLAGS: helix_core::config::default_lang_loader() }); + // sequence of key events to execute before launching the editor + let execute_at_start = + stream::iter(std::mem::take(&mut args.execute).into_iter().map(|item| { + Ok(crossterm::event::Event::Key( + crossterm::event::KeyEvent::from(item), + )) + })); + // TODO: use the thread local executor to spawn the application task separately from the work pool let mut app = Application::new(args, config, lang_loader).context("unable to start Helix")?; - let exit_code = app.run(&mut EventStream::new()).await?; + let exit_code = app + .run(&mut execute_at_start.chain(EventStream::new())) + .await?; Ok(exit_code) }