Files
clide/src/main.rs

91 lines
2.8 KiB
Rust
Raw Normal View History

2026-01-31 04:25:14 +00:00
use anyhow::{Context, Result, anyhow};
2026-01-25 20:57:36 +00:00
use clap::Parser;
use log::{info, trace};
use std::process::{Command, Stdio};
2025-03-29 08:01:13 -04:00
2026-01-25 20:57:36 +00:00
pub mod gui;
pub mod tui;
/// Extendable command-line driven development environment written in Rust using the Qt UI framework.
/// If no flags are provided, the GUI editor is launched in a separate process.
/// If no path is provided, the current directory is used.
#[derive(Parser, Debug)]
#[structopt(name = "clide", verbatim_doc_comment)]
struct Cli {
/// The root directory for the project to open with the clide editor.
#[arg(value_parser = clap::value_parser!(std::path::PathBuf))]
pub path: Option<std::path::PathBuf>,
2025-03-29 08:01:13 -04:00
2026-01-25 20:57:36 +00:00
/// Run clide in headless mode.
#[arg(value_name = "tui", short, long)]
pub tui: bool,
2025-03-29 08:01:13 -04:00
2026-01-25 20:57:36 +00:00
/// Run the clide GUI in the current process, blocking the terminal and showing all output streams.
#[arg(value_name = "gui", short, long)]
pub gui: bool,
2025-03-29 08:01:13 -04:00
}
2026-01-31 04:25:14 +00:00
impl Cli {
fn run_mode(&self) -> Result<RunMode> {
let mut modes = Vec::new();
self.tui.then(|| modes.push(RunMode::Tui));
self.gui.then(|| modes.push(RunMode::GuiAttached));
match &modes[..] {
[] => Ok(RunMode::Gui),
[mode] => Ok(*mode),
multiple => Err(anyhow!(
"More than one run mode found {multiple:?} please select one."
)),
}
}
}
pub struct AppContext {
pub path: std::path::PathBuf,
pub run_mode: RunMode,
}
2025-03-29 08:01:13 -04:00
2026-01-31 04:25:14 +00:00
impl AppContext {
fn new(cli: Cli) -> Result<Self> {
let path = match &cli.path {
// If the CLI was provided a directory, convert it to absolute.
Some(path) => std::path::absolute(path)?,
// If no path was provided, use the current directory.
None => std::env::current_dir().context("Failed to obtain current directory")?,
};
info!(target:"main()", "Root path detected: {path:?}");
2025-03-29 08:01:13 -04:00
2026-01-31 04:25:14 +00:00
Ok(Self {
path,
run_mode: cli.run_mode()?,
})
}
}
#[derive(Copy, Clone, Debug, Default)]
pub enum RunMode {
#[default]
Gui,
GuiAttached,
Tui,
}
fn main() -> Result<()> {
let args = Cli::parse();
let app_context = AppContext::new(args)?;
match app_context.run_mode {
RunMode::GuiAttached => gui::run(app_context),
RunMode::Tui => tui::run(app_context),
RunMode::Gui => {
trace!(target:"main()", "Starting GUI in a new process");
Command::new(std::env::current_exe()?)
.args(&["--gui", app_context.path.to_str().unwrap()])
.stdout(Stdio::null())
.stderr(Stdio::null())
.stdin(Stdio::null())
.spawn()
.context("Failed to start GUI")
.map(|_| ())
2025-03-29 08:01:13 -04:00
}
}
}