commit 584e01549e49dae15f62029903917769f13e18b5 Author: Valerie Date: Mon Jun 7 20:44:12 2021 -0400 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62f204d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target +.goto +.open +tmp diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e9982e2 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "configparser" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aad39d76dbe45b809ef6d783b8c597732225b8f3d6c4d8ceb4a4f834a844ffe" + +[[package]] +name = "open" +version = "0.1.0" +dependencies = [ + "configparser", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..64d2768 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "open" +version = "0.1.0" +authors = ["Britton Wolfe "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +configparser = "2.0.1" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9a6e794 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,99 @@ +use std::{ + fs::read_to_string, + env::{args, current_dir, var}, + path::Path, + process::{Command, Child, ChildStdin, ChildStdout, Stdio} +}; + +use configparser::ini::Ini; + +fn main() { + // Prepare config file + let i_dir = current_dir().unwrap(); + let mut dir = i_dir.as_path(); + let mut i_path = dir.join(".open"); + let mut path = i_path.as_path(); + let root = Path::new("/"); + while !path.exists() { + if dir == root { + // If we hit root while propagating, default to the + // user config. + let i_dir = String::from(var("HOME").ok().unwrap()); + dir = Path::new(i_dir.as_str()); + i_path = dir.join(".config/open.conf"); + path = i_path.as_path(); + if path.exists() { + break; + } else { + println!("No configuration found."); + return; + } + } + dir = dir.parent().unwrap(); + i_path = dir.join(".open"); + path = i_path.as_path(); + } + let ini_str = read_to_string(path).unwrap(); + let mut config = Ini::new(); + config.read(ini_str).ok(); + dir = i_dir.as_path(); + + let args: Vec = args().collect(); + + let default = ".".to_string(); + let arg_target = args.get(1); + let i_target = arg_target.unwrap_or(&default); + let target = Path::new(i_target); + if !target.exists() { + println!("\"{}\" does not exist.", i_target); + return; + } + let i_ext = target.extension(); + let i_filename: String; + let ext: &str; + if target.is_dir() { + if arg_target.is_none() { + ext = "open"; + } else { + ext = "dir"; + } + } else { + if i_ext.is_none() { + i_filename = ["filename", target.file_name().unwrap().to_str().unwrap()].join(":"); + } else { + i_filename = [".", i_ext.unwrap().to_str().unwrap()].join(""); + } + ext = i_filename.as_str(); + } + let i_exe = config.get(ext, "command"); + if i_exe.is_none() { + match ext { + "open" => {}, + "dir" => println!("No command specified for directories."), + _ => println!("No command specified for \"{}\" files.", ext) + } + return; + } + let exe = i_exe.unwrap(); + let mut parts = exe.split(" "); + let mut command = Command::new(parts.next().unwrap()); + let mut param: Vec<&str> = vec![]; + for part in parts { + param.push(part); + } + param.push(i_target); + command.args(param) + .current_dir(dir); + + let is_sh = config.getbool(ext, "shell").ok().unwrap_or(Some(false)).unwrap_or(false); + if is_sh { + command.stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .stdin(Stdio::inherit()); + command.output().ok(); + } else { + command.stdout(Stdio::null()) + .stderr(Stdio::null()); + command.spawn().ok(); + } +}