Auto merge of #31 - matthiasbeyer:ui-external, r=matthiasbeyer
Ui external Tracking branch for implementation to call external editor and edit file contents with it.
This commit is contained in:
commit
2568c37a25
7 changed files with 122 additions and 0 deletions
12
etc/cli.yml
12
etc/cli.yml
|
@ -22,6 +22,18 @@ args:
|
||||||
required: false
|
required: false
|
||||||
takes_value: true
|
takes_value: true
|
||||||
|
|
||||||
|
- editor:
|
||||||
|
short: e
|
||||||
|
long: editor
|
||||||
|
help: Set editor, if not set $EDITOR of the system will be asked, else vim
|
||||||
|
required: false
|
||||||
|
takes_value: true
|
||||||
|
|
||||||
|
- editor_opts:
|
||||||
|
long: editor-opts
|
||||||
|
help: Set editor options
|
||||||
|
required: false
|
||||||
|
takes_value: true
|
||||||
|
|
||||||
- storename:
|
- storename:
|
||||||
short: s
|
short: s
|
||||||
|
|
11
src/cli.rs
11
src/cli.rs
|
@ -47,6 +47,17 @@ impl<'a> CliConfig<'a> {
|
||||||
.and_then(|s| Some(rtp + s))
|
.and_then(|s| Some(rtp + s))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn editor(&self) -> Option<String> {
|
||||||
|
self.cli_matches.value_of("editor").and_then(|s| Some(String::from(s)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn editor_opts(&self) -> String {
|
||||||
|
self.cli_matches
|
||||||
|
.value_of("editor_opts")
|
||||||
|
.map(|s| String::from(s))
|
||||||
|
.unwrap_or(String::from(""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Debug for CliConfig<'a> {
|
impl<'a> Debug for CliConfig<'a> {
|
||||||
|
|
|
@ -10,6 +10,8 @@ pub struct Configuration {
|
||||||
pub store_sub : String,
|
pub store_sub : String,
|
||||||
pub verbose : bool,
|
pub verbose : bool,
|
||||||
pub debugging : bool,
|
pub debugging : bool,
|
||||||
|
pub editor : Option<String>,
|
||||||
|
pub editor_opts : String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
|
@ -20,6 +22,8 @@ impl Configuration {
|
||||||
let mut verbose = false;
|
let mut verbose = false;
|
||||||
let mut debugging = false;
|
let mut debugging = false;
|
||||||
let mut store_sub = String::from("/store");
|
let mut store_sub = String::from("/store");
|
||||||
|
let mut editor = None;
|
||||||
|
let mut editor_opts = String::from("");
|
||||||
|
|
||||||
if let Some(cfg) = fetch_config(rtp.clone()) {
|
if let Some(cfg) = fetch_config(rtp.clone()) {
|
||||||
if let Some(v) = cfg.lookup_boolean("verbose") {
|
if let Some(v) = cfg.lookup_boolean("verbose") {
|
||||||
|
@ -31,6 +35,12 @@ impl Configuration {
|
||||||
if let Some(s) = cfg.lookup_str("store") {
|
if let Some(s) = cfg.lookup_str("store") {
|
||||||
store_sub = String::from(s);
|
store_sub = String::from(s);
|
||||||
}
|
}
|
||||||
|
if let Some(s) = cfg.lookup_str("editor") {
|
||||||
|
editor = Some(String::from(s));
|
||||||
|
}
|
||||||
|
if let Some(s) = cfg.lookup_str("editor-opts") {
|
||||||
|
editor_opts = String::from(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let runtimepath = rtp.unwrap_or(String::from("/tmp/"));
|
let runtimepath = rtp.unwrap_or(String::from("/tmp/"));
|
||||||
|
@ -40,12 +50,16 @@ impl Configuration {
|
||||||
debug!(" - debugging : {}", debugging);
|
debug!(" - debugging : {}", debugging);
|
||||||
debug!(" - store sub : {}", store_sub);
|
debug!(" - store sub : {}", store_sub);
|
||||||
debug!(" - runtimepath: {}", runtimepath);
|
debug!(" - runtimepath: {}", runtimepath);
|
||||||
|
debug!(" - editor : {:?}", editor);
|
||||||
|
debug!(" - editor-opts: {}", editor_opts);
|
||||||
|
|
||||||
Configuration {
|
Configuration {
|
||||||
verbose: verbose,
|
verbose: verbose,
|
||||||
debugging: debugging,
|
debugging: debugging,
|
||||||
store_sub: store_sub,
|
store_sub: store_sub,
|
||||||
rtp: runtimepath,
|
rtp: runtimepath,
|
||||||
|
editor: editor,
|
||||||
|
editor_opts: editor_opts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +79,14 @@ impl Configuration {
|
||||||
self.rtp.clone()
|
self.rtp.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn editor(&self) -> Option<String> {
|
||||||
|
self.editor.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn editor_opts(&self) -> &String {
|
||||||
|
&self.editor_opts
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rtp_path(config: &CliConfig) -> Option<String> {
|
fn rtp_path(config: &CliConfig) -> Option<String> {
|
||||||
|
|
|
@ -92,6 +92,20 @@ impl<'a> Runtime<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn editor(&self) -> String {
|
||||||
|
use std::env::var;
|
||||||
|
|
||||||
|
if let Some(editor) = self.config.editor() {
|
||||||
|
editor + &self.config.editor_opts()[..]
|
||||||
|
} else if let Some(editor) = self.configuration.editor() {
|
||||||
|
editor + &self.configuration.editor_opts()[..]
|
||||||
|
} else if let Ok(editor) = var("EDITOR") {
|
||||||
|
editor
|
||||||
|
} else {
|
||||||
|
String::from("vim")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Debug for Runtime<'a> {
|
impl<'a> Debug for Runtime<'a> {
|
||||||
|
|
61
src/ui/external/editor.rs
vendored
Normal file
61
src/ui/external/editor.rs
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
use std::ops::Drop;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use runtime::Runtime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function which lets the user provide content by editing a temp files which gets removed after
|
||||||
|
* the function got the content from it.
|
||||||
|
*/
|
||||||
|
pub fn let_user_provide_content(rt: &Runtime) -> Option<String> {
|
||||||
|
use std::io::Read;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Child;
|
||||||
|
|
||||||
|
let filepath = "/tmp/imag-tmp.md";
|
||||||
|
let file_created = File::create(filepath)
|
||||||
|
.map(|_| true)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
if !file_created {
|
||||||
|
warn!("Could not create temporary file for user input!");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = {
|
||||||
|
let mut cmd = Command::new(rt.editor());
|
||||||
|
cmd.arg(filepath);
|
||||||
|
debug!("cmd = {:?}", cmd);
|
||||||
|
cmd.spawn()
|
||||||
|
.and_then(|child| {
|
||||||
|
child.wait_with_output()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let process_out = output.map_err(|e| {
|
||||||
|
error!("Editor call failed");
|
||||||
|
debug!("Editor call failed: {:?}", e);
|
||||||
|
return None as Option<String>;
|
||||||
|
}).unwrap();
|
||||||
|
|
||||||
|
if !process_out.status.success() {
|
||||||
|
error!("Editor call failed");
|
||||||
|
debug!("status = {:?}", process_out.status);
|
||||||
|
debug!("stdout = {:?}", String::from_utf8(process_out.stdout));
|
||||||
|
debug!("stderr = {:?}", String::from_utf8(process_out.stderr));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut contents = String::new();
|
||||||
|
File::open(filepath).map(|mut file| {
|
||||||
|
file.read_to_string(&mut contents);
|
||||||
|
Some(contents)
|
||||||
|
}).unwrap_or(None)
|
||||||
|
}
|
1
src/ui/external/mod.rs
vendored
Normal file
1
src/ui/external/mod.rs
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod editor;
|
|
@ -1 +1,2 @@
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
pub mod external;
|
||||||
|
|
Loading…
Reference in a new issue