Skip to content

Instantly share code, notes, and snippets.

@nathanross
Created July 4, 2015 10:04
Show Gist options
  • Save nathanross/44b28fa43e720e7027de to your computer and use it in GitHub Desktop.
Save nathanross/44b28fa43e720e7027de to your computer and use it in GitHub Desktop.
termfx.rs
#!/usr/bin/cargo-script-run
//! ```cargo
//! [dependencies]
//! regex = "*"
//! tempdir = "*"
//!
//!
//!
//! ```
#![feature(path_ext)]
#![feature(convert)]
// trmfx.rs
// a toy program for learning rust
// pass it a string matching
// a terminal theme (.Xresources) file
// in ~/.fx/ and it will launch uxterm
// with that theme.
// precisely, the first argument is
// matched against filenames in ~/.fx/
// 1. the first match is merged as an XRDB
// 2. an uxterm process is spawned
// 3. the original XRDB is restored
extern crate regex;
extern crate tempdir;
use regex::Regex;
use std::fs::{self, PathExt};
use std::path::{PathBuf};
use std::env;
use std::io::{Result, Write};
use std::process::{Command, Stdio};
use std::thread;
fn quick_cmd(cmdname: &str,
o_inbuf: Option<&Vec<u8>>,
cmdargs: Vec<&str>) -> Result<Vec<u8>> {
let mut newcmd = Command::new(cmdname)
.args(cmdargs.as_slice())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn().unwrap();
match o_inbuf {
Some(inbuf) => {
if let Some(ref mut cmd_stdin)=newcmd.stdin {
cmd_stdin.write_all(inbuf).unwrap();
}
}
None => {}
}
let out = newcmd.wait_with_output().unwrap();
Ok(out.stdout)
}
//fn quick_scmd(cmdname: &str,
// o_inbuf: Option<&Vec<u8>>,
// cmdargs: Vec<&str>) -> io::Result<Vec<u8>> {
// inbuf =
//}
// TODO :
fn op() -> Result<()> {
// todo: probably gratuitous unwraps here.
// learn more about Option and Result handling;
// has to be a more expressive, or if not that
// more communicative way of handling this
// that doesn't involve writing a dozen callbacks
// or passing a single generic one.
let args: Vec<_> = env::args().collect();
let passed_args = args.len() -1;
if passed_args == 1 {
let pattern_str = args[1].clone();
let re = Regex::new(pattern_str.as_str()).unwrap();
let p_home = env::home_dir()
.unwrap_or_else(|| { panic!("this program only makes sense on *nix+X11")});
//only works on linux where we have a homedir
let mut fx_dir = PathBuf::from(p_home);
fx_dir.push(".fx");
let mut found = false;
for entry in try!(fs::read_dir(fx_dir)) {
let vp = try!(entry).path();
if vp.is_file() {
//since we've already checked it has a file, it definitely
//is a path with a filename
let fname =vp.file_name().unwrap()
.to_str().expect("failed converting OS string to string");
if re.is_match(fname) {
found = true;
println!("first matching theme: {}", fname);
let xrdb_results = quick_cmd("xrdb", None, vec!["-query"]).unwrap();
quick_cmd("xrdb", None, vec!["-merge", vp.to_str().unwrap()]);
Command::new("uxterm").arg("-bw").arg("0")
.spawn();
thread::sleep_ms(700);
quick_cmd("xrdb", Some(&xrdb_results), vec!["-load"]);
break;
}
}
}
if ! found {
println!("no match found. sorry.")
}
} else {
println!("error, right now this script requires 1 arg")
}
Ok(())
}
fn main() {
match op() {
Ok(_) => return,
// to do : add individual err cases here for the errors handled above.
Err(reason) => panic!(match reason {
_ => println!("technical difficulties. please ask again later.")
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment