Skip to content

Tig-like command line arguments for startup mode #1382

@alexmaco

Description

@alexmaco
Contributor

Is your feature request related to a problem? Please describe.
Sometimes I want to look at something specific, like a file blame or a branch view. Currently this means starting gitui and navigating to that state. This is redundant, especially when having to navigate to a file and open the blame view, instead of opening a blame from the terminal directly.

Describe the solution you'd like
Some tig-like cli arguments:

  • blame <file_path> to directly open gitui in a file blame view
  • <refspec> to start with a log view at that refspec
  • stash to start with the stashes view

Describe alternatives you've considered
Manually doing the navigation after opening gitui.

Activity

changed the title [-]TIg-like command line arguments for startup mode[/-] [+]Tig-like command line arguments for startup mode[/+] on Oct 7, 2022
extrawurst

extrawurst commented on Oct 7, 2022

@extrawurst
Collaborator

Current master at least remembers the current tab. This functionality could be extended to remember more state of the current view

chrisant996

chrisant996 commented on Oct 24, 2022

@chrisant996

This is a great tool. I would love to use it fulltime instead of gitk, especially for viewing file logs.

The startup friction is prohibitive, though, due to not yet having a command line interface for providing startup context.

I can type gitk somefile or gitk somecommit -- somefile.
Or press Up to a command history entry containing somefile and then replace someprogram with gitk.
Or launch them via an editor macro, etc.
From my editor, it's two keystrokes to launch gitk on the current file.
There's no in-built way to accomplish that with gitui.

I haven't looked at the code yet, but the UI makes it look like the internals are probably modular and probably wouldn't take much effort to initialize the UI state based on command line args, instead of manual input within the program.

Unfortunately, I haven't dabbled in Rust yet, so this isn't something I'll be able to contribute to soon.

stale

stale commented on May 21, 2023

@stale

This issue has been automatically marked as stale because it has not had any activity half a year. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

ShamrockLee

ShamrockLee commented on May 21, 2023

@ShamrockLee

This is definitely the feature set I would need the most.

removed
dormantMarked by stale bot on close
on May 21, 2023
chrisant996

chrisant996 commented on Jan 27, 2025

@chrisant996

@extrawurst I have a prototype change that introduces the following subcommands (see patch below):

  • gitui status starts in the Status tab, overriding the saved tab.
  • gitui log starts in Log tab, overriding the saved tab.
  • gitui files starts in Files tab, etc.
  • gitui stashing starts in Stashing tab, etc.
  • gitui stashes starts in Stashes tab, etc.

I'm happy to publish a PR for review.
I intend to extend the subcommands to accept args, e.g. gitui log <file-path>, but I haven't implemented them yet.

Before I go further, I think it would be helpful to discuss subcommands in general for gitui:

  • What subcommands would you like to see, @extrawurst ? I like @AmmarAbouZor 's suggestion of blame and etc subcommands.
  • How would you like to see initial startup states represented in the quit_state loop? My prototype passes optional state into run_app, and then clears the optional state so it doesn't affect subsequent calls. It feels a little messy to pass in an optional state, but App is created inside run_app so passing in optional state seems the most direct approach without some refactoring.

Here's a patch, for reference:

diff --git a/src/app.rs b/src/app.rs
index 45037f0..cac8be2 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -156,6 +156,7 @@ impl App {
 		input: Input,
 		theme: Theme,
 		key_config: KeyConfig,
+		start_tab: Option<AppTabs>,
 	) -> Result<Self> {
 		log::trace!("open repo at: {:?}", &repo);
 
@@ -230,7 +231,10 @@ impl App {
 			popup_stack: PopupStack::default(),
 		};
 
-		app.set_tab(tab)?;
+		match start_tab {
+			None => app.set_tab(tab)?,
+			Some(t) => app.switch_to_tab(&t)?,
+		}
 
 		Ok(app)
 	}
diff --git a/src/args.rs b/src/args.rs
index 7465422..d95a0dc 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -1,4 +1,4 @@
-use crate::bug_report;
+use crate::{bug_report, queue::AppTabs};
 use anyhow::{anyhow, Result};
 use asyncgit::sync::RepoPath;
 use clap::{
@@ -12,10 +12,13 @@ use std::{
 	path::PathBuf,
 };
 
+type ClapCommand = clap::Command;
+
 pub struct CliArgs {
 	pub theme: PathBuf,
 	pub repo_path: RepoPath,
 	pub notify_watcher: bool,
+	pub start_tab: Option<AppTabs>,
 }
 
 pub fn process_cmdline() -> Result<CliArgs> {
@@ -53,10 +56,22 @@ pub fn process_cmdline() -> Result<CliArgs> {
 	let notify_watcher: bool =
 		*arg_matches.get_one("watcher").unwrap_or(&false);
 
+	let start_tab: Option<AppTabs> =
+		match arg_matches.subcommand_name() {
+			Some("status") => Some(AppTabs::Status),
+			Some("log") => Some(AppTabs::Log),
+			Some("files") => Some(AppTabs::Files),
+			Some("stashing") => Some(AppTabs::Stashing),
+			Some("stashes") => Some(AppTabs::Stashlist),
+			None => None,
+			_ => unreachable!(),
+		};
+
 	Ok(CliArgs {
 		theme,
 		repo_path,
 		notify_watcher,
+		start_tab,
 	})
 }
 
@@ -120,6 +135,26 @@ fn app() -> ClapApp {
 				.env("GIT_WORK_TREE")
 				.num_args(1),
 		)
+		.subcommand(
+			ClapCommand::new("status")
+				.about("Start in Status tab"),
+		)
+		.subcommand(
+			ClapCommand::new("log")
+				.about("Start in Log tab"),
+		)
+		.subcommand(
+			ClapCommand::new("files")
+				.about("Start in Files tab"),
+		)
+		.subcommand(
+			ClapCommand::new("stashing")
+				.about("Start in Stashing tab"),
+		)
+		.subcommand(
+			ClapCommand::new("stashes")
+				.about("Start in Stashes tab"),
+		)
 }
 
 fn setup_logging() -> Result<()> {
diff --git a/src/main.rs b/src/main.rs
index e85dca8..a8488af 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -46,7 +46,7 @@ mod tabs;
 mod ui;
 mod watcher;
 
-use crate::{app::App, args::process_cmdline};
+use crate::{app::App, args::process_cmdline, queue::AppTabs};
 use anyhow::{bail, Result};
 use app::QuitState;
 use asyncgit::{
@@ -152,6 +152,8 @@ fn main() -> Result<()> {
 		Updater::Ticker
 	};
 
+	let mut start_tab = cliargs.start_tab;
+
 	loop {
 		let quit_state = run_app(
 			app_start,
@@ -161,8 +163,11 @@ fn main() -> Result<()> {
 			&input,
 			updater,
 			&mut terminal,
+			start_tab,
 		)?;
 
+		start_tab = None;
+
 		match quit_state {
 			QuitState::OpenSubmodule(p) => {
 				repo_path = p;
@@ -182,6 +187,7 @@ fn run_app(
 	input: &Input,
 	updater: Updater,
 	terminal: &mut Terminal,
+	start_tab: Option<AppTabs>,
 ) -> Result<QuitState, anyhow::Error> {
 	let (tx_git, rx_git) = unbounded();
 	let (tx_app, rx_app) = unbounded();
@@ -207,6 +213,7 @@ fn run_app(
 		input.clone(),
 		theme,
 		key_config,
+		start_tab,
 	)?;
 
 	let mut spinner = Spinner::default();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @extrawurst@chrisant996@alexmaco@ShamrockLee

        Issue actions

          Tig-like command line arguments for startup mode · Issue #1382 · gitui-org/gitui