Skip to content

Commit

Permalink
completion: allow calling jj multiple times
Browse files Browse the repository at this point in the history
  • Loading branch information
senekor committed Nov 25, 2024
1 parent f819dc9 commit e4a7423
Showing 1 changed file with 38 additions and 13 deletions.
51 changes: 38 additions & 13 deletions cli/src/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ fn split_help_text(line: &str) -> (&str, Option<StyledStr>) {
}

pub fn local_bookmarks() -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
with_jj(|jj, _| {
let output = jj
.build()
.arg("bookmark")
.arg("list")
.arg("--config-toml")
Expand All @@ -75,8 +76,9 @@ pub fn local_bookmarks() -> Vec<CompletionCandidate> {
}

pub fn tracked_bookmarks() -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
with_jj(|jj, _| {
let output = jj
.build()
.arg("bookmark")
.arg("list")
.arg("--tracked")
Expand All @@ -96,8 +98,9 @@ pub fn tracked_bookmarks() -> Vec<CompletionCandidate> {
}

pub fn untracked_bookmarks() -> Vec<CompletionCandidate> {
with_jj(|mut jj, config| {
with_jj(|jj, config| {
let output = jj
.build()
.arg("bookmark")
.arg("list")
.arg("--all-remotes")
Expand Down Expand Up @@ -133,8 +136,9 @@ pub fn untracked_bookmarks() -> Vec<CompletionCandidate> {
}

pub fn bookmarks() -> Vec<CompletionCandidate> {
with_jj(|mut jj, config| {
with_jj(|jj, config| {
let output = jj
.build()
.arg("bookmark")
.arg("list")
.arg("--all-remotes")
Expand Down Expand Up @@ -177,8 +181,9 @@ pub fn bookmarks() -> Vec<CompletionCandidate> {
}

pub fn git_remotes() -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
with_jj(|jj, _| {
let output = jj
.build()
.arg("git")
.arg("remote")
.arg("list")
Expand Down Expand Up @@ -211,8 +216,9 @@ pub fn aliases() -> Vec<CompletionCandidate> {
}

fn revisions(revisions: &str) -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
with_jj(|jj, _| {
let output = jj
.build()
.arg("log")
.arg("--no-graph")
.arg("--limit")
Expand Down Expand Up @@ -244,8 +250,9 @@ pub fn all_revisions() -> Vec<CompletionCandidate> {
}

pub fn operations() -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
with_jj(|jj, _| {
let output = jj
.build()
.arg("operation")
.arg("log")
.arg("--no-graph")
Expand Down Expand Up @@ -274,8 +281,9 @@ pub fn operations() -> Vec<CompletionCandidate> {
}

pub fn workspaces() -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
with_jj(|jj, _| {
let output = jj
.build()
.arg("--config-toml")
.arg(r#"templates.commit_summary = 'if(description, description.first_line(), "(no description set)")'"#)
.arg("workspace")
Expand Down Expand Up @@ -359,7 +367,7 @@ pub fn leaf_config_keys() -> Vec<CompletionCandidate> {
/// In case of errors, print them and early return an empty vector.
fn with_jj<F>(completion_fn: F) -> Vec<CompletionCandidate>
where
F: FnOnce(std::process::Command, &Config) -> Result<Vec<CompletionCandidate>, CommandError>,
F: FnOnce(JjBuilder, &Config) -> Result<Vec<CompletionCandidate>, CommandError>,
{
get_jj_command()
.and_then(|(jj, config)| completion_fn(jj, &config))
Expand All @@ -378,7 +386,7 @@ where
/// give completion code access to custom backends. Shelling out was chosen as
/// the preferred method, because it's more maintainable and the performance
/// requirements of completions aren't very high.
fn get_jj_command() -> Result<(std::process::Command, Config), CommandError> {
fn get_jj_command() -> Result<(JjBuilder, Config), CommandError> {
let current_exe = std::env::current_exe().map_err(user_error)?;
let mut cmd_args = Vec::<String>::new();

Expand Down Expand Up @@ -459,10 +467,27 @@ fn get_jj_command() -> Result<(std::process::Command, Config), CommandError> {
cmd_args.push(config_toml);
}

let mut cmd = std::process::Command::new(current_exe);
cmd.args(&cmd_args);
let builder = JjBuilder {
cmd: current_exe,
args: cmd_args,
};

Ok((cmd, config))
Ok((builder, config))
}

/// A helper struct to allow completion functions to call jj multiple times with
/// different arguments.
struct JjBuilder {
cmd: std::path::PathBuf,
args: Vec<String>,
}

impl JjBuilder {
fn build(&self) -> std::process::Command {
let mut cmd = std::process::Command::new(&self.cmd);
cmd.args(&self.args);
cmd
}
}

#[cfg(test)]
Expand Down

0 comments on commit e4a7423

Please sign in to comment.