Add ext_cmd event processing

Update event processing code
This commit is contained in:
daa84 2017-11-17 18:40:09 +03:00
parent 8c8195de89
commit 797de26ec2
9 changed files with 158 additions and 65 deletions

1
Cargo.lock generated
View File

@ -20,6 +20,7 @@ dependencies = [
"pangocairo 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"rmpv 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -30,6 +30,7 @@ phf = "0.7"
log = "0.3"
env_logger = "0.4"
htmlescape = "0.3"
rmpv = "0.4"
serde = "1.0"
serde_derive = "1.0"

View File

@ -17,6 +17,7 @@ extern crate phf;
extern crate log;
extern crate env_logger;
extern crate htmlescape;
extern crate rmpv;
extern crate serde;
#[macro_use]

30
src/nvim/cmd_line.rs Normal file
View File

@ -0,0 +1,30 @@
use ui_model;
pub struct CmdLine {
content: Vec<(ui_model::Attrs, String)>,
pos: u64,
firstc: String,
prompt: String,
indent: u64,
level: u64,
}
impl CmdLine {
pub fn new(
content: Vec<(ui_model::Attrs, String)>,
pos: u64,
firstc: String,
prompt: String,
indent: u64,
level: u64,
) -> Self {
CmdLine {
content,
pos,
firstc,
prompt,
indent,
level,
}
}
}

View File

@ -38,7 +38,7 @@ impl NvimHandler {
_ => vec![],
};
let call_reapint_mode =
redraw_handler::call(ui, &ev_name, &args)?;
redraw_handler::call(ui, &ev_name, args)?;
repaint_mode = repaint_mode.join(call_reapint_mode);
}
} else {

View File

@ -4,11 +4,13 @@ mod handler;
mod mode_info;
mod redraw_handler;
mod repaint_mode;
mod cmd_line;
pub use self::redraw_handler::{RedrawEvents, GuiApi};
pub use self::repaint_mode::RepaintMode;
pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef};
pub use self::mode_info::{ModeInfo, CursorShape};
pub use self::cmd_line::{CmdLine};
use std::error;
use std::fmt;
@ -136,20 +138,28 @@ pub fn post_start_init(
cols: u64,
rows: u64,
) -> result::Result<(), NvimInitError> {
let mut opts = UiAttachOptions::new();
opts.set_popupmenu_external(true);
opts.set_tabline_external(true);
nvim.borrow().unwrap().ui_attach(cols, rows, &opts).map_err(
NvimInitError::new_post_init,
)?;
nvim.borrow().unwrap().command("runtime! ginit.vim").map_err(
NvimInitError::new_post_init,
)?;
nvim.borrow()
.unwrap()
.ui_attach(
cols,
rows,
UiAttachOptions::new()
.set_popupmenu_external(true)
.set_tabline_external(true)
.set_cmdline_external(true),
)
.map_err(NvimInitError::new_post_init)?;
nvim.borrow()
.unwrap()
.command("runtime! ginit.vim")
.map_err(NvimInitError::new_post_init)?;
if let Some(path) = open_path {
nvim.borrow().unwrap().command(&format!("e {}", path)).map_err(
NvimInitError::new_post_init,
)?;
nvim.borrow()
.unwrap()
.command(&format!("e {}", path))
.map_err(NvimInitError::new_post_init)?;
}
Ok(())
@ -159,7 +169,7 @@ pub fn post_start_init(
pub trait ErrorReport<T> {
fn report_err(&self, nvim: &mut NeovimApi);
fn ok_and_report(self, nvim: &mut NeovimApi) -> Option<T>;
fn ok_and_report(self, nvim: &mut NeovimApi) -> Option<T>;
}
impl<T> ErrorReport<T> for result::Result<T, CallError> {
@ -175,4 +185,3 @@ impl<T> ErrorReport<T> for result::Result<T, CallError> {
self.ok()
}
}

View File

@ -1,4 +1,5 @@
use std::result;
use std::collections::HashMap;
use neovim_lib::{Value, UiOption};
use neovim_lib::neovim_api::Tabpage;
@ -6,6 +7,7 @@ use neovim_lib::neovim_api::Tabpage;
use shell;
use value::ValueMapExt;
use rmpv;
use super::repaint_mode::RepaintMode;
use super::mode_info::ModeInfo;
@ -21,7 +23,7 @@ pub trait RedrawEvents {
fn on_redraw(&mut self, mode: &RepaintMode);
fn on_highlight_set(&mut self, attrs: &[(Value, Value)]) -> RepaintMode;
fn on_highlight_set(&mut self, attrs: HashMap<String, Value>) -> RepaintMode;
fn on_eol_clear(&mut self) -> RepaintMode;
@ -64,6 +66,16 @@ pub trait RedrawEvents {
cursor_style_enabled: bool,
mode_info: Vec<ModeInfo>,
) -> RepaintMode;
fn cmdline_show(
&mut self,
content: Vec<(HashMap<String, Value>, String)>,
pos: u64,
firstc: String,
prompt: String,
indent: u64,
level: u64,
) -> RepaintMode;
}
pub trait GuiApi {
@ -103,6 +115,31 @@ macro_rules! map_array {
);
}
macro_rules! try_arg {
($value:expr, bool) => (try_bool!($value));
($value:expr, uint) => (try_uint!($value));
($value:expr, str) => (
match $value {
Value::String(s) => {
if let Some(s) = s.into_str() {
Ok(s)
} else {
Err("Can't convert to utf8 string".to_owned())
}
}
_ => Err("Can't convert to string".to_owned()),
}?);
($value:expr, ext) => (rmpv::ext::from_value($value).map_err(|e| e.to_string())?);
}
macro_rules! call {
($s:ident -> $c:ident ($args:ident : $($arg_type:ident),+ )) => (
{
let mut iter = $args.into_iter();
$s.$c($( try_arg!(iter.next().unwrap(), $arg_type)),+ )
}
)
}
pub fn call_gui_event(
ui: &mut shell::State,
@ -140,7 +177,7 @@ pub fn call_gui_event(
pub fn call(
ui: &mut shell::State,
method: &str,
args: &[Value],
args: Vec<Value>,
) -> result::Result<RepaintMode, String> {
let repaint_mode = match method {
"cursor_goto" => ui.on_cursor_goto(try_uint!(args[0]), try_uint!(args[1])),
@ -148,21 +185,12 @@ pub fn call(
"clear" => ui.on_clear(),
"resize" => ui.on_resize(try_uint!(args[0]), try_uint!(args[1])),
"highlight_set" => {
if let Value::Map(ref attrs) = args[0] {
ui.on_highlight_set(attrs);
} else {
panic!("Supports only map value as argument");
}
call!(ui->on_highlight_set(args: ext));
RepaintMode::Nothing
}
"eol_clear" => ui.on_eol_clear(),
"set_scroll_region" => {
ui.on_set_scroll_region(
try_uint!(args[0]),
try_uint!(args[1]),
try_uint!(args[2]),
try_uint!(args[3]),
);
call!(ui->on_set_scroll_region(args: uint, uint, uint, uint));
RepaintMode::Nothing
}
"scroll" => ui.on_scroll(try_int!(args[0])),
@ -221,6 +249,7 @@ pub fn call(
)?;
ui.mode_info_set(try_bool!(args[0]), mode_info)
}
"cmdline_show" => call!(ui->cmdline_show(args: ext, uint, str, str, uint, uint)),
_ => {
println!("Event {}({:?})", method, args);
RepaintMode::Nothing
@ -229,4 +258,3 @@ pub fn call(
Ok(repaint_mode)
}

View File

@ -3,6 +3,7 @@ use std::rc::Rc;
use std::sync::{Arc, Condvar, Mutex};
use std::ops::Deref;
use std::thread;
use std::collections::HashMap;
use cairo;
use pangocairo::CairoContextExt;
@ -20,8 +21,10 @@ use neovim_lib::neovim_api::Tabpage;
use settings::{Settings, FontSource};
use ui_model::{UiModel, Attrs, ModelRect};
use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED};
use nvim;
use nvim::{RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, NeovimRef, NeovimClientAsync};
use nvim::{self, RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, NeovimRef,
NeovimClientAsync, CmdLine};
use input;
use input::keyval_to_input_string;
use cursor::Cursor;
@ -599,7 +602,8 @@ impl Deref for Shell {
fn gtk_focus_in(state: &mut State) -> Inhibit {
if let Some(mut nvim) = state.nvim() {
nvim.command("if exists('#FocusGained') | doautocmd FocusGained | endif").report_err(&mut *nvim);
nvim.command("if exists('#FocusGained') | doautocmd FocusGained | endif")
.report_err(&mut *nvim);
}
state.im_context.focus_in();
@ -611,7 +615,8 @@ fn gtk_focus_in(state: &mut State) -> Inhibit {
fn gtk_focus_out(state: &mut State) -> Inhibit {
if let Some(mut nvim) = state.nvim() {
nvim.command("if exists('#FocusLost') | doautocmd FocusLost | endif").report_err(&mut *nvim);
nvim.command("if exists('#FocusLost') | doautocmd FocusLost | endif")
.report_err(&mut *nvim);
}
state.im_context.focus_out();
@ -959,38 +964,8 @@ impl RedrawEvents for State {
RepaintMode::Area(self.model.scroll(count))
}
fn on_highlight_set(&mut self, attrs: &[(Value, Value)]) -> RepaintMode {
let mut model_attrs = Attrs::new();
for &(ref key_val, ref val) in attrs {
if let Some(key) = key_val.as_str() {
match key {
"foreground" => {
if let Some(fg) = val.as_u64() {
model_attrs.foreground = Some(Color::from_indexed_color(fg));
}
}
"background" => {
if let Some(bg) = val.as_u64() {
model_attrs.background = Some(Color::from_indexed_color(bg));
}
}
"special" => {
if let Some(bg) = val.as_u64() {
model_attrs.special = Some(Color::from_indexed_color(bg));
}
}
"reverse" => model_attrs.reverse = true,
"bold" => model_attrs.bold = true,
"italic" => model_attrs.italic = true,
"underline" => model_attrs.underline = true,
"undercurl" => model_attrs.undercurl = true,
attr_key => println!("unknown attribute {}", attr_key),
};
} else {
panic!("attr key must be string");
}
}
fn on_highlight_set(&mut self, attrs: HashMap<String, Value>) -> RepaintMode {
let model_attrs = Attrs::from_value_map(&attrs);
self.cur_attrs = Some(model_attrs);
RepaintMode::Nothing
@ -1094,6 +1069,19 @@ impl RedrawEvents for State {
self.mode.set_info(cursor_style_enabled, mode_info);
RepaintMode::Nothing
}
fn cmdline_show(
&mut self,
content: Vec<(HashMap<String, Value>, String)>,
pos: u64,
firstc: String,
prompt: String,
indent: u64,
level: u64,
) -> RepaintMode {
// TODO: implement
RepaintMode::Nothing
}
}
impl GuiApi for State {

View File

@ -1,4 +1,7 @@
use std::collections::HashMap;
use color::Color;
use neovim_lib::Value;
#[derive(Clone)]
pub struct Attrs {
@ -28,6 +31,38 @@ impl Attrs {
}
}
pub fn from_value_map(attrs: &HashMap<String, Value>) -> Attrs {
let mut model_attrs = Attrs::new();
for (ref key, ref val) in attrs {
match key.as_ref() {
"foreground" => {
if let Some(fg) = val.as_u64() {
model_attrs.foreground = Some(Color::from_indexed_color(fg));
}
}
"background" => {
if let Some(bg) = val.as_u64() {
model_attrs.background = Some(Color::from_indexed_color(bg));
}
}
"special" => {
if let Some(bg) = val.as_u64() {
model_attrs.special = Some(Color::from_indexed_color(bg));
}
}
"reverse" => model_attrs.reverse = true,
"bold" => model_attrs.bold = true,
"italic" => model_attrs.italic = true,
"underline" => model_attrs.underline = true,
"undercurl" => model_attrs.undercurl = true,
attr_key => error!("unknown attribute {}", attr_key),
};
}
model_attrs
}
fn clear(&mut self) {
self.italic = false;
self.bold = false;