feat: workspaces tmux support #1
1 changed files with 19 additions and 9 deletions
|
|
@ -28,6 +28,8 @@ from rich.console import Console
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.prompt import Prompt, Confirm
|
from rich.prompt import Prompt, Confirm
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
|
from rich.syntax import Syntax
|
||||||
|
from rich.panel import Panel
|
||||||
from iterfzf import iterfzf
|
from iterfzf import iterfzf
|
||||||
|
|
||||||
app = typer.Typer(
|
app = typer.Typer(
|
||||||
|
|
@ -1163,12 +1165,11 @@ def diff_workspace(
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Show git diff for all repos in the workspace.
|
Show git diff for all repos in the workspace.
|
||||||
|
Uses rich Syntax highlighter for diffs.
|
||||||
- If --staged: uses `git diff --cached` (only staged changes).
|
|
||||||
- Otherwise: uses `git diff` (staged + unstaged).
|
|
||||||
"""
|
"""
|
||||||
_settings, _repos_dir, workspaces_dir = get_ctx_paths(ctx)
|
_settings, _repos_dir, workspaces_dir = get_ctx_paths(ctx)
|
||||||
ws_dir = find_workspace_dir(workspaces_dir, workspace)
|
ws_dir = find_workspace_dir(workspaces_dir, workspace)
|
||||||
|
|
||||||
if not ws_dir.exists():
|
if not ws_dir.exists():
|
||||||
console.print(f"[red]Workspace '{ws_dir.name}' does not exist at {ws_dir}[/red]")
|
console.print(f"[red]Workspace '{ws_dir.name}' does not exist at {ws_dir}[/red]")
|
||||||
raise typer.Exit(1)
|
raise typer.Exit(1)
|
||||||
|
|
@ -1178,7 +1179,7 @@ def diff_workspace(
|
||||||
f"Showing diffs for workspace [bold]{title or ws_dir.name}[/bold] (dir: {ws_dir.name})"
|
f"Showing diffs for workspace [bold]{title or ws_dir.name}[/bold] (dir: {ws_dir.name})"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Collect worktrees (repos) in this workspace
|
# Collect repos
|
||||||
worktrees: List[Path] = []
|
worktrees: List[Path] = []
|
||||||
for child in sorted(p for p in ws_dir.iterdir() if p.is_dir()):
|
for child in sorted(p for p in ws_dir.iterdir() if p.is_dir()):
|
||||||
if child.name.lower() == "readme.md":
|
if child.name.lower() == "readme.md":
|
||||||
|
|
@ -1194,12 +1195,13 @@ def diff_workspace(
|
||||||
any_diffs = False
|
any_diffs = False
|
||||||
|
|
||||||
for wt in worktrees:
|
for wt in worktrees:
|
||||||
# Quick check: skip repos with no changes at all
|
# Skip clean repos
|
||||||
changes = git_status_porcelain(wt)
|
changes = git_status_porcelain(wt)
|
||||||
if not changes:
|
if not changes:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
any_diffs = True
|
any_diffs = True
|
||||||
|
|
||||||
console.rule(f"[bold]{wt.name}[/bold]")
|
console.rule(f"[bold]{wt.name}[/bold]")
|
||||||
|
|
||||||
cmd = ["git", "diff"]
|
cmd = ["git", "diff"]
|
||||||
|
|
@ -1215,14 +1217,22 @@ def diff_workspace(
|
||||||
|
|
||||||
if not out.strip():
|
if not out.strip():
|
||||||
console.print("[dim]No diff output.[/dim]")
|
console.print("[dim]No diff output.[/dim]")
|
||||||
else:
|
continue
|
||||||
# Use markup=False so diff characters like [ ] don't get eaten by Rich
|
|
||||||
console.print(out, markup=False)
|
syntax = Syntax(
|
||||||
|
out,
|
||||||
|
"diff",
|
||||||
|
theme="nord",
|
||||||
|
line_numbers=False,
|
||||||
|
word_wrap=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Wrap each repo diff in a Panel for clarity
|
||||||
|
console.print(Panel(syntax, title=wt.name, border_style="cyan"))
|
||||||
|
|
||||||
if not any_diffs:
|
if not any_diffs:
|
||||||
console.print("[green]No changes to diff in any repo.[/green]")
|
console.print("[green]No changes to diff in any repo.[/green]")
|
||||||
|
|
||||||
|
|
||||||
def not_in_tmux() -> bool:
|
def not_in_tmux() -> bool:
|
||||||
"""Return True if not inside tmux or zellij."""
|
"""Return True if not inside tmux or zellij."""
|
||||||
return not os.environ.get("TMUX") and not os.environ.get("ZELLIJ")
|
return not os.environ.get("TMUX") and not os.environ.get("ZELLIJ")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue