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)",
|
||||
"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)",
|
||||
|
@ -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"
|
||||
|
@ -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
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![],
|
||||
};
|
||||
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 {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
60
src/shell.rs
60
src/shell.rs
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user