diff --git a/cli/src/commands/next.rs b/cli/src/commands/next.rs index 6a78a790b6..beea7ff5fe 100644 --- a/cli/src/commands/next.rs +++ b/cli/src/commands/next.rs @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::io::Write; - use itertools::Itertools; use jj_lib::commit::Commit; use jj_lib::repo::Repo; use jj_lib::revset::{RevsetExpression, RevsetFilterPredicate, RevsetIteratorExt}; -use crate::cli_util::{short_commit_hash, CommandHelper, WorkspaceCommandHelper}; +use crate::cli_util::{short_commit_hash, CommandHelper}; use crate::command_error::{user_error, CommandError}; +use crate::movement_util::choose_commit; use crate::ui::Ui; /// Move the working-copy commit to the child revision @@ -70,38 +69,6 @@ pub(crate) struct NextArgs { conflict: bool, } -pub fn choose_commit<'a>( - ui: &mut Ui, - workspace_command: &WorkspaceCommandHelper, - cmd: &str, - commits: &'a [Commit], -) -> Result<&'a Commit, CommandError> { - writeln!(ui.stdout(), "ambiguous {cmd} commit, choose one to target:")?; - let mut formatter = ui.stdout_formatter(); - let template = workspace_command.commit_summary_template(); - let mut choices: Vec = Default::default(); - for (i, commit) in commits.iter().enumerate() { - write!(formatter, "{}: ", i + 1)?; - template.format(commit, formatter.as_mut())?; - writeln!(formatter)?; - choices.push(format!("{}", i + 1)); - } - writeln!(formatter, "q: quit the prompt")?; - choices.push("q".to_string()); - drop(formatter); - - let choice = ui.prompt_choice( - "enter the index of the commit you want to target", - &choices, - None, - )?; - if choice == "q" { - return Err(user_error("ambiguous target commit")); - } - - Ok(&commits[choice.parse::().unwrap() - 1]) -} - pub(crate) fn cmd_next( ui: &mut Ui, command: &CommandHelper, diff --git a/cli/src/commands/prev.rs b/cli/src/commands/prev.rs index 659f116e6c..b47d16a50e 100644 --- a/cli/src/commands/prev.rs +++ b/cli/src/commands/prev.rs @@ -18,7 +18,7 @@ use jj_lib::revset::{RevsetExpression, RevsetFilterPredicate, RevsetIteratorExt} use crate::cli_util::{short_commit_hash, CommandHelper}; use crate::command_error::{user_error, CommandError}; -use crate::commands::next::choose_commit; +use crate::movement_util::choose_commit; use crate::ui::Ui; /// Change the working copy revision relative to the parent revision /// diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 6e60b293a7..20004e3ff5 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -27,6 +27,7 @@ pub mod generic_templater; pub mod git_util; pub mod graphlog; pub mod merge_tools; +pub mod movement_util; pub mod operation_templater; mod progress; pub mod revset_util; diff --git a/cli/src/movement_util.rs b/cli/src/movement_util.rs new file mode 100644 index 0000000000..17dc2b6029 --- /dev/null +++ b/cli/src/movement_util.rs @@ -0,0 +1,67 @@ +// Copyright 2024 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//! Contains the internals for the movement commands, `next` and `prev`. +//! And additional helpers such as [`choose_commit`] + +use std::io::Write; + +use jj_lib::commit::Commit; +use jj_lib::revset::Revset; + +use crate::cli_util::WorkspaceCommandHelper; +use crate::command_error::{user_error, CommandError}; +use crate::ui::Ui; + +/// Display a option of choices of `commits`, which you can use +pub fn choose_commit<'a>( + ui: &mut Ui, + workspace_command: &WorkspaceCommandHelper, + cmd: &str, + commits: &'a [Commit], +) -> Result<&'a Commit, CommandError> { + writeln!(ui.stdout(), "ambiguous {cmd} commit, choose one to target:")?; + let mut formatter = ui.stdout_formatter(); + let template = workspace_command.commit_summary_template(); + let mut choices: Vec = Default::default(); + for (i, commit) in commits.iter().enumerate() { + write!(formatter, "{}: ", i + 1)?; + template.format(commit, formatter.as_mut())?; + writeln!(formatter)?; + choices.push(format!("{}", i + 1)); + } + writeln!(formatter, "q: quit the prompt")?; + choices.push("q".to_string()); + drop(formatter); + + let choice = ui.prompt_choice( + "enter the index of the commit you want to target", + &choices, + None, + )?; + if choice == "q" { + return Err(user_error("ambiguous target commit")); + } + + Ok(&commits[choice.parse::().unwrap() - 1]) +} + +/// Describes in which direction to move. +pub enum Direction { + /// Move to ancestors, so parents and their ancestors. + Ancestors, + /// Move to children and their descendants. + Descendants, +} + +pub fn move_direction(amount: i64, direction: Direction, revset: Revset) -> Commit {}