use std::path::PathBuf;
use relm4::gtk::gio;
use relm4::gtk::prelude::{ApplicationExtManual, FileExt};
use relm4::gtk;
use relm4::prelude::*;
use tree_space::cmd::Command;
use tree_space::ipc;
use tree_space::ui::app::{App, AppInit};
fn main() -> Result<(), Box<dyn std::error::Error>> {
if std::env::args().any(|a| a == "--help" || a == "-h") {
print_usage();
return Ok(());
}
let mut command = Command::parse(std::env::args_os().skip(1));
merge_env_dirs(&mut command);
if ipc::deliver(&command) {
return Ok(());
}
let listener = match ipc::bind() {
Ok(listener) => Some(listener),
Err(_) => {
if ipc::deliver(&command) {
return Ok(());
}
None
}
};
let app = gtk::Application::new(
Some("org.tree_space.panel"),
gio::ApplicationFlags::HANDLES_OPEN,
);
app.connect_open(|_app, files, _hint| {
let mut command = Command::default();
for path in files.iter().filter_map(|f| f.path()) {
command.reveal.push(path);
}
if !command.reveal.is_empty() {
let _ = ipc::deliver(&command);
}
});
let app = RelmApp::from_app(app)
.visible_on_activate(!command.hidden)
.with_args(vec!["tree-space".to_owned()]);
app.run::<App>(AppInit { command, listener });
Ok(())
}
fn merge_env_dirs(command: &mut Command) {
if let Ok(dirs) = std::env::var("TREE_SPACE_DIRS") {
for part in dirs.split(':') {
let trimmed = part.trim();
let path = std::path::absolute(trimmed).unwrap_or_else(|_| PathBuf::from(trimmed));
if path.is_dir() {
command.roots.push(path);
}
}
}
}
fn print_usage() {
println!(
"\
tree-space — a dockable, keyboard-first file manager panel.
USAGE:
tree-space [OPTIONS] [PATH ...]
ARGS:
PATH... Paths to open. A directory opens as a pane (an already-open
directory is never duplicated — the panel is just shown). A file
opens its containing folder as a pane and selects the file.
OPTIONS:
-s, --side <left|right> Which screen edge to dock to. Defaults to the
configured side when omitted.
--select <PATH> Reveal PATH: open its containing folder and
select it. Works for a file or a folder, and is
the mechanism `.desktop`/`xdg-open` activation
uses (`Exec=tree-space %u`).
-H, --hidden Launch hidden (or, for a running panel, hide it
and keep it hidden). Never shows the panel.
-w, --width <W> Resize the panel. `420` sets an absolute width;
`+40` grows it by 40px and `-40` shrinks it.
Does not change whether the panel is shown.
-h, --help Print this help.
The panel is single-instance: an invocation while one is already running is
forwarded to it and exits. With no directory arguments it toggles the panel
(hide when visible, show when hidden); with `--side` it ensures a dock on that
side and shows it; with `--hidden` it ensures the panel is hidden instead."
);
}