#[allow(clippy::wildcard_imports)]
use super::*;
pub(in crate::app) fn render_repos(app: &App, f: &mut ratatui::Frame, area: Rect) {
let block = Block::default()
.borders(Borders::ALL)
.title("Repositories (F6)");
let inner = block.inner(area);
f.render_widget(block, area);
if inner.height == 0 || inner.width == 0 {
return;
}
let entries = app.repo_entries();
if entries.is_empty() {
let lines = vec![
Line::from(Span::styled(
"No repositories configured.",
Style::default()
.fg(Color::Yellow)
.add_modifier(Modifier::BOLD),
)),
Line::from(""),
Line::from(
"Add the child repositories this project coordinates under `[repos]` in tix.toml:",
),
Line::from(Span::styled(
" [repos]",
Style::default().fg(Color::DarkGray),
)),
Line::from(Span::styled(
" tix-tracker = \"../tix\"",
Style::default().fg(Color::DarkGray),
)),
Line::from(""),
Line::from("Each value is that repository's project root; Enter runs tix inside it."),
Line::from("When this repository is itself a managed child, set `parent_repo` so this"),
Line::from("mode can jump back to the parent."),
];
f.render_widget(Paragraph::new(lines).wrap(Wrap { trim: false }), inner);
return;
}
let mut lines: Vec<Line<'static>> = Vec::new();
for (index, (label, path, is_parent)) in entries.iter().enumerate() {
let selected = index == app.repos_cursor;
let style = if selected {
Style::default()
.fg(Color::Black)
.bg(Color::Cyan)
.add_modifier(Modifier::BOLD)
} else {
Style::default()
};
let marker = if selected { ">" } else { " " };
let kind = if *is_parent { " (parent)" } else { "" };
lines.push(Line::from(Span::styled(
format!("{marker} {label}{kind}"),
style,
)));
lines.push(Line::from(Span::styled(
format!(" {}", path.display()),
Style::default().fg(Color::DarkGray),
)));
}
f.render_widget(Paragraph::new(lines), inner);
let mut y = inner.y;
for (_, path, _) in &entries {
if y >= inner.y + inner.height {
break;
}
app.record_region(
Rect {
x: inner.x,
y,
width: inner.width,
height: 2.min(inner.y + inner.height - y),
},
Action::OpenRepo(path.clone()),
);
y += 2;
}
}
pub(in crate::app) fn run_child_tix(repo: &Path, parent: &Path) -> Result<()> {
if !repo.is_dir() {
return Err(crate::error::TixError::InvalidInput(format!(
"{} is not a directory",
repo.display()
)));
}
if !repo.join("tix.toml").is_file() {
return Err(crate::error::TixError::InvalidInput(format!(
"{} has no tix.toml — is it a tix repository?",
repo.display()
)));
}
let exe = std::env::current_exe().map_err(io_err)?;
std::process::Command::new(exe)
.current_dir(repo)
.env("TIX_PARENT_REPO", parent)
.status()
.map_err(|e| {
crate::error::TixError::InvalidInput(format!(
"failed to launch tix in {}: {e}",
repo.display()
))
})?;
Ok(())
}