Add ext_cmd event processing
Update event processing code
This commit is contained in:
parent
8c8195de89
commit
797de26ec2
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -20,6 +20,7 @@ dependencies = [
|
|||||||
"pangocairo 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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 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)",
|
"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 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_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)",
|
"serde_json 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -30,6 +30,7 @@ phf = "0.7"
|
|||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
htmlescape = "0.3"
|
htmlescape = "0.3"
|
||||||
|
rmpv = "0.4"
|
||||||
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
@ -17,6 +17,7 @@ extern crate phf;
|
|||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate htmlescape;
|
extern crate htmlescape;
|
||||||
|
extern crate rmpv;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
30
src/nvim/cmd_line.rs
Normal file
30
src/nvim/cmd_line.rs
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ impl NvimHandler {
|
|||||||
_ => vec![],
|
_ => vec![],
|
||||||
};
|
};
|
||||||
let call_reapint_mode =
|
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);
|
repaint_mode = repaint_mode.join(call_reapint_mode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,11 +4,13 @@ mod handler;
|
|||||||
mod mode_info;
|
mod mode_info;
|
||||||
mod redraw_handler;
|
mod redraw_handler;
|
||||||
mod repaint_mode;
|
mod repaint_mode;
|
||||||
|
mod cmd_line;
|
||||||
|
|
||||||
pub use self::redraw_handler::{RedrawEvents, GuiApi};
|
pub use self::redraw_handler::{RedrawEvents, GuiApi};
|
||||||
pub use self::repaint_mode::RepaintMode;
|
pub use self::repaint_mode::RepaintMode;
|
||||||
pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef};
|
pub use self::client::{NeovimClient, NeovimClientAsync, NeovimRef};
|
||||||
pub use self::mode_info::{ModeInfo, CursorShape};
|
pub use self::mode_info::{ModeInfo, CursorShape};
|
||||||
|
pub use self::cmd_line::{CmdLine};
|
||||||
|
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -136,20 +138,28 @@ pub fn post_start_init(
|
|||||||
cols: u64,
|
cols: u64,
|
||||||
rows: u64,
|
rows: u64,
|
||||||
) -> result::Result<(), NvimInitError> {
|
) -> result::Result<(), NvimInitError> {
|
||||||
let mut opts = UiAttachOptions::new();
|
nvim.borrow()
|
||||||
opts.set_popupmenu_external(true);
|
.unwrap()
|
||||||
opts.set_tabline_external(true);
|
.ui_attach(
|
||||||
nvim.borrow().unwrap().ui_attach(cols, rows, &opts).map_err(
|
cols,
|
||||||
NvimInitError::new_post_init,
|
rows,
|
||||||
)?;
|
UiAttachOptions::new()
|
||||||
nvim.borrow().unwrap().command("runtime! ginit.vim").map_err(
|
.set_popupmenu_external(true)
|
||||||
NvimInitError::new_post_init,
|
.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 {
|
if let Some(path) = open_path {
|
||||||
nvim.borrow().unwrap().command(&format!("e {}", path)).map_err(
|
nvim.borrow()
|
||||||
NvimInitError::new_post_init,
|
.unwrap()
|
||||||
)?;
|
.command(&format!("e {}", path))
|
||||||
|
.map_err(NvimInitError::new_post_init)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -159,7 +169,7 @@ pub fn post_start_init(
|
|||||||
pub trait ErrorReport<T> {
|
pub trait ErrorReport<T> {
|
||||||
fn report_err(&self, nvim: &mut NeovimApi);
|
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> {
|
impl<T> ErrorReport<T> for result::Result<T, CallError> {
|
||||||
@ -175,4 +185,3 @@ impl<T> ErrorReport<T> for result::Result<T, CallError> {
|
|||||||
self.ok()
|
self.ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::result;
|
use std::result;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use neovim_lib::{Value, UiOption};
|
use neovim_lib::{Value, UiOption};
|
||||||
use neovim_lib::neovim_api::Tabpage;
|
use neovim_lib::neovim_api::Tabpage;
|
||||||
@ -6,6 +7,7 @@ use neovim_lib::neovim_api::Tabpage;
|
|||||||
use shell;
|
use shell;
|
||||||
|
|
||||||
use value::ValueMapExt;
|
use value::ValueMapExt;
|
||||||
|
use rmpv;
|
||||||
|
|
||||||
use super::repaint_mode::RepaintMode;
|
use super::repaint_mode::RepaintMode;
|
||||||
use super::mode_info::ModeInfo;
|
use super::mode_info::ModeInfo;
|
||||||
@ -21,7 +23,7 @@ pub trait RedrawEvents {
|
|||||||
|
|
||||||
fn on_redraw(&mut self, mode: &RepaintMode);
|
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;
|
fn on_eol_clear(&mut self) -> RepaintMode;
|
||||||
|
|
||||||
@ -64,6 +66,16 @@ pub trait RedrawEvents {
|
|||||||
cursor_style_enabled: bool,
|
cursor_style_enabled: bool,
|
||||||
mode_info: Vec<ModeInfo>,
|
mode_info: Vec<ModeInfo>,
|
||||||
) -> RepaintMode;
|
) -> 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 {
|
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(
|
pub fn call_gui_event(
|
||||||
ui: &mut shell::State,
|
ui: &mut shell::State,
|
||||||
@ -140,7 +177,7 @@ pub fn call_gui_event(
|
|||||||
pub fn call(
|
pub fn call(
|
||||||
ui: &mut shell::State,
|
ui: &mut shell::State,
|
||||||
method: &str,
|
method: &str,
|
||||||
args: &[Value],
|
args: Vec<Value>,
|
||||||
) -> result::Result<RepaintMode, String> {
|
) -> result::Result<RepaintMode, String> {
|
||||||
let repaint_mode = match method {
|
let repaint_mode = match method {
|
||||||
"cursor_goto" => ui.on_cursor_goto(try_uint!(args[0]), try_uint!(args[1])),
|
"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(),
|
"clear" => ui.on_clear(),
|
||||||
"resize" => ui.on_resize(try_uint!(args[0]), try_uint!(args[1])),
|
"resize" => ui.on_resize(try_uint!(args[0]), try_uint!(args[1])),
|
||||||
"highlight_set" => {
|
"highlight_set" => {
|
||||||
if let Value::Map(ref attrs) = args[0] {
|
call!(ui->on_highlight_set(args: ext));
|
||||||
ui.on_highlight_set(attrs);
|
|
||||||
} else {
|
|
||||||
panic!("Supports only map value as argument");
|
|
||||||
}
|
|
||||||
RepaintMode::Nothing
|
RepaintMode::Nothing
|
||||||
}
|
}
|
||||||
"eol_clear" => ui.on_eol_clear(),
|
"eol_clear" => ui.on_eol_clear(),
|
||||||
"set_scroll_region" => {
|
"set_scroll_region" => {
|
||||||
ui.on_set_scroll_region(
|
call!(ui->on_set_scroll_region(args: uint, uint, uint, uint));
|
||||||
try_uint!(args[0]),
|
|
||||||
try_uint!(args[1]),
|
|
||||||
try_uint!(args[2]),
|
|
||||||
try_uint!(args[3]),
|
|
||||||
);
|
|
||||||
RepaintMode::Nothing
|
RepaintMode::Nothing
|
||||||
}
|
}
|
||||||
"scroll" => ui.on_scroll(try_int!(args[0])),
|
"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)
|
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);
|
println!("Event {}({:?})", method, args);
|
||||||
RepaintMode::Nothing
|
RepaintMode::Nothing
|
||||||
@ -229,4 +258,3 @@ pub fn call(
|
|||||||
|
|
||||||
Ok(repaint_mode)
|
Ok(repaint_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
src/shell.rs
60
src/shell.rs
@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||||||
use std::sync::{Arc, Condvar, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use cairo;
|
use cairo;
|
||||||
use pangocairo::CairoContextExt;
|
use pangocairo::CairoContextExt;
|
||||||
@ -20,8 +21,10 @@ use neovim_lib::neovim_api::Tabpage;
|
|||||||
use settings::{Settings, FontSource};
|
use settings::{Settings, FontSource};
|
||||||
use ui_model::{UiModel, Attrs, ModelRect};
|
use ui_model::{UiModel, Attrs, ModelRect};
|
||||||
use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED};
|
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;
|
||||||
use input::keyval_to_input_string;
|
use input::keyval_to_input_string;
|
||||||
use cursor::Cursor;
|
use cursor::Cursor;
|
||||||
@ -599,7 +602,8 @@ impl Deref for Shell {
|
|||||||
|
|
||||||
fn gtk_focus_in(state: &mut State) -> Inhibit {
|
fn gtk_focus_in(state: &mut State) -> Inhibit {
|
||||||
if let Some(mut nvim) = state.nvim() {
|
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();
|
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 {
|
fn gtk_focus_out(state: &mut State) -> Inhibit {
|
||||||
if let Some(mut nvim) = state.nvim() {
|
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();
|
state.im_context.focus_out();
|
||||||
@ -959,38 +964,8 @@ impl RedrawEvents for State {
|
|||||||
RepaintMode::Area(self.model.scroll(count))
|
RepaintMode::Area(self.model.scroll(count))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_highlight_set(&mut self, attrs: &[(Value, Value)]) -> RepaintMode {
|
fn on_highlight_set(&mut self, attrs: HashMap<String, Value>) -> RepaintMode {
|
||||||
let mut model_attrs = Attrs::new();
|
let model_attrs = Attrs::from_value_map(&attrs);
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cur_attrs = Some(model_attrs);
|
self.cur_attrs = Some(model_attrs);
|
||||||
RepaintMode::Nothing
|
RepaintMode::Nothing
|
||||||
@ -1094,6 +1069,19 @@ impl RedrawEvents for State {
|
|||||||
self.mode.set_info(cursor_style_enabled, mode_info);
|
self.mode.set_info(cursor_style_enabled, mode_info);
|
||||||
RepaintMode::Nothing
|
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 {
|
impl GuiApi for State {
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use color::Color;
|
use color::Color;
|
||||||
|
use neovim_lib::Value;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Attrs {
|
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) {
|
fn clear(&mut self) {
|
||||||
self.italic = false;
|
self.italic = false;
|
||||||
self.bold = false;
|
self.bold = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user