Read from stdin #87

This commit is contained in:
daa 2018-04-09 23:11:15 +03:00
parent 74d7417564
commit 996ced4bec
5 changed files with 75 additions and 8 deletions

1
Cargo.lock generated
View File

@ -379,6 +379,7 @@ dependencies = [
"gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"neovim-lib 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pango 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -43,6 +43,8 @@ serde_derive = "1.0"
toml = "0.4"
serde_json = "1.0"
libc = "0.2"
#[dependencies.neovim-lib]
#git = "https://github.com/daa84/neovim-lib"

View File

@ -23,11 +23,12 @@ extern crate pango_sys;
extern crate pangocairo;
extern crate percent_encoding;
extern crate phf;
extern crate rmpv;
extern crate regex;
extern crate unicode_width;
extern crate rmpv;
extern crate unicode_segmentation;
extern crate unicode_width;
extern crate libc;
extern crate serde;
#[macro_use]
extern crate serde_derive;
@ -63,6 +64,8 @@ mod subscriptions;
mod misc;
use std::env;
use std::io::Read;
use std::cell::RefCell;
use std::time::Duration;
use std::str::FromStr;
use gio::prelude::*;
@ -78,6 +81,8 @@ const DISABLE_WIN_STATE_RESTORE: &str = "--disable-win-restore";
fn main() {
env_logger::init();
let input_data = RefCell::new(read_piped_input());
let app_flags = gio::ApplicationFlags::HANDLES_OPEN | gio::ApplicationFlags::NON_UNIQUE;
glib::set_program_name(Some("NeovimGtk"));
@ -88,12 +93,14 @@ fn main() {
gtk::Application::new(Some("org.daa.NeovimGtk"), app_flags)
}.expect("Failed to initialize GTK application");
app.connect_activate(activate);
app.connect_activate(move |app| {
activate(app, input_data.replace(None))
});
app.connect_open(open);
let new_window_action = gio::SimpleAction::new("new-window", None);
let app_ref = app.clone();
new_window_action.connect_activate(move |_, _| activate(&app_ref));
new_window_action.connect_activate(move |_, _| activate(&app_ref, None));
app.add_action(&new_window_action);
gtk::Window::set_default_icon_name("org.daa.NeovimGtk");
@ -117,16 +124,18 @@ fn open(app: &gtk::Application, files: &[gio::File], _: &str) {
nvim_bin_path(std::env::args()),
files_list,
nvim_timeout(std::env::args()),
None,
));
ui.init(app, !nvim_disable_win_state(std::env::args()));
}
fn activate(app: &gtk::Application) {
fn activate(app: &gtk::Application, input_data: Option<String>) {
let mut ui = Ui::new(ShellOptions::new(
nvim_bin_path(std::env::args()),
Vec::new(),
nvim_timeout(std::env::args()),
input_data,
));
ui.init(app, !nvim_disable_win_state(std::env::args()));
@ -165,6 +174,23 @@ where
.unwrap_or(false)
}
fn read_piped_input() -> Option<String> {
let isatty = unsafe { libc::isatty(libc::STDIN_FILENO) != 0 };
if !isatty {
let mut buf = String::new();
match std::io::stdin().read_to_string(&mut buf) {
Ok(_) => Some(buf),
Err(err) => {
error!("Error read stdin {}", err);
None
}
}
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -141,6 +141,7 @@ pub fn post_start_init(
open_paths: Vec<String>,
cols: u64,
rows: u64,
input_data: Option<String>,
) -> result::Result<(), NvimInitError> {
nvim.borrow()
.unwrap()
@ -170,6 +171,21 @@ pub fn post_start_init(
.command_async(&command)
.cb(|r| r.report_err())
.call();
} else {
if let Some(input_data) = input_data {
let mut nvim = nvim.borrow().unwrap();
let buf = nvim.get_current_buf().ok_and_report();
if let Some(buf) = buf {
buf.set_lines(
&mut *nvim,
0,
0,
true,
input_data.lines().map(|l| l.to_owned()).collect(),
).report_err();
}
}
}
Ok(())

View File

@ -495,6 +495,7 @@ pub struct ShellOptions {
nvim_bin_path: Option<String>,
open_paths: Vec<String>,
timeout: Option<Duration>,
input_data: Option<String>,
}
impl ShellOptions {
@ -502,13 +503,25 @@ impl ShellOptions {
nvim_bin_path: Option<String>,
open_paths: Vec<String>,
timeout: Option<Duration>,
input_data: Option<String>,
) -> Self {
ShellOptions {
nvim_bin_path,
open_paths,
timeout,
input_data,
}
}
// remove input data from original
// shell option, as it need to be used only once
pub fn take(&mut self) -> Self {
let input_data = self.input_data.take();
let mut clone = self.clone();
clone.input_data = input_data;
clone
}
}
pub struct Shell {
@ -1044,7 +1057,13 @@ fn init_nvim_async(
});
// attach ui
if let Err(err) = nvim::post_start_init(nvim, options.open_paths, cols as u64, rows as u64) {
if let Err(err) = nvim::post_start_init(
nvim,
options.open_paths,
cols as u64,
rows as u64,
options.input_data,
) {
show_nvim_init_error(&err, state_arc.clone());
} else {
set_nvim_initialized(state_arc);
@ -1142,7 +1161,7 @@ fn init_nvim(state_ref: &Arc<UiMutex<State>>) {
let state_arc = state_ref.clone();
let nvim_handler = NvimHandler::new(state_ref.clone());
let options = state.options.clone();
let options = state.options.take();
thread::spawn(move || init_nvim_async(state_arc, nvim_handler, options, cols, rows));
}
}
@ -1157,7 +1176,10 @@ impl State {
pub fn on_put(&mut self, text: String) -> RepaintMode {
let double_width = text.is_empty();
RepaintMode::Area(self.model.put(Some(text), double_width, self.cur_attrs.as_ref()))
RepaintMode::Area(
self.model
.put(Some(text), double_width, self.cur_attrs.as_ref()),
)
}
pub fn on_clear(&mut self) -> RepaintMode {