Created
July 4, 2015 10:04
-
-
Save nathanross/44b28fa43e720e7027de to your computer and use it in GitHub Desktop.
termfx.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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