Created
December 28, 2014 17:35
-
-
Save rolandshoemaker/8b81caeae559a51d770e to your computer and use it in GitHub Desktop.
Drop to $VISUAL or $EDITOR to edit a String in rust (via temporary file)
This file contains hidden or 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
extern crate libc; | |
use std::io::{File, Open, ReadWrite, TempDir, Command, SeekSet}; | |
use std::io::process::{InheritFd}; | |
use std::os; | |
pub use self::libc::{ | |
STDIN_FILENO, | |
STDOUT_FILENO, | |
STDERR_FILENO | |
}; | |
fn temporary_editor(contents: String) -> String { | |
// setup temporary directory | |
let tmpdir = match TempDir::new("tempplace") { | |
Ok(dir) => dir, | |
Err(e) => panic!("couldn't create temporary directory: {}", e) | |
}; | |
// setup temporary file to write/read | |
let tmppath = tmpdir.path().join("something-unique"); | |
let mut tmpfile = match File::open_mode(&tmppath, Open, ReadWrite) { | |
Ok(f) => f, | |
Err(e) => panic!("File error: {}", e) | |
}; | |
tmpfile.write_line(contents.as_slice()).ok().expect("Failed to write line to temp file"); | |
// we now have a temp file, at `tmppath`, that contains `contents` | |
// first we need to know which one | |
let editor = match os::getenv("VISUAL") { | |
Some(val) => val, | |
None => { | |
match os::getenv("EDITOR") { | |
Some(val) => val, | |
None => panic!("Neither $VISUAL nor $EDITOR is set.") | |
} | |
} | |
}; | |
// lets start `editor` and edit the file at `tmppath` | |
// first we need to set STDIN, STDOUT, and STDERR to those that theca is | |
// currently using so we can display the editor | |
let mut editor_command = Command::new(editor); | |
editor_command.arg(tmppath.display().to_string()); | |
editor_command.stdin(InheritFd(libc::STDIN_FILENO)); | |
editor_command.stdout(InheritFd(libc::STDOUT_FILENO)); | |
editor_command.stderr(InheritFd(libc::STDERR_FILENO)); | |
let editor_proc = editor_command.spawn(); | |
match editor_proc.ok().expect("Couldn't launch editor").wait().is_ok() { | |
true => { | |
// finished editing, time to read `tmpfile` for the final output | |
// seek to start of `tmpfile` | |
tmpfile.seek(0, SeekSet).ok().expect("Can't seek to start of temp file"); | |
tmpfile.read_to_string().unwrap() | |
} | |
false => panic!("The editor broke") | |
} | |
} | |
fn main() { | |
let test = temporary_editor("this totes works".to_string()); | |
println!("temp file contained: {}", test); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment