Neovim message process cleanup
This commit is contained in:
parent
a22594ac80
commit
27b498a36d
@ -19,6 +19,7 @@ extern crate serde_derive;
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
|
||||||
|
mod value;
|
||||||
mod ui_model;
|
mod ui_model;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod ui;
|
mod ui;
|
||||||
|
100
src/nvim.rs
100
src/nvim.rs
@ -5,7 +5,6 @@ use std::process::{Stdio, Command};
|
|||||||
use std::result;
|
use std::result;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use neovim_lib::{Handler, Neovim, NeovimApi, Session, Value, UiAttachOptions, CallError, UiOption};
|
use neovim_lib::{Handler, Neovim, NeovimApi, Session, Value, UiAttachOptions, CallError, UiOption};
|
||||||
use neovim_lib::neovim_api::Tabpage;
|
use neovim_lib::neovim_api::Tabpage;
|
||||||
@ -15,6 +14,8 @@ use ui_model::{ModelRect, ModelRectVec};
|
|||||||
use shell;
|
use shell;
|
||||||
use glib;
|
use glib;
|
||||||
|
|
||||||
|
use value::ValueMapExt;
|
||||||
|
|
||||||
pub trait RedrawEvents {
|
pub trait RedrawEvents {
|
||||||
fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode;
|
fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode;
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ pub trait RedrawEvents {
|
|||||||
|
|
||||||
fn tabline_update(&mut self,
|
fn tabline_update(&mut self,
|
||||||
selected: Tabpage,
|
selected: Tabpage,
|
||||||
tabs: Vec<(Tabpage, Option<&str>)>)
|
tabs: Vec<(Tabpage, Option<String>)>)
|
||||||
-> RepaintMode;
|
-> RepaintMode;
|
||||||
|
|
||||||
fn mode_info_set(&mut self,
|
fn mode_info_set(&mut self,
|
||||||
@ -88,6 +89,23 @@ macro_rules! try_bool {
|
|||||||
($exp:expr) => ($exp.as_bool().ok_or("Can't convert argument to bool".to_owned())?)
|
($exp:expr) => ($exp.as_bool().ok_or("Can't convert argument to bool".to_owned())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! map_array {
|
||||||
|
($arg:expr, $err:expr, |$item:ident| $exp:expr) => (
|
||||||
|
$arg.as_array()
|
||||||
|
.ok_or($err)
|
||||||
|
.and_then(|items| items.iter().map(|$item| {
|
||||||
|
$exp
|
||||||
|
}).collect::<Result<Vec<_>, _>>())
|
||||||
|
);
|
||||||
|
($arg:expr, $err:expr, |$item:ident| {$exp:expr}) => (
|
||||||
|
$arg.as_array()
|
||||||
|
.ok_or($err)
|
||||||
|
.and_then(|items| items.iter().map(|$item| {
|
||||||
|
$exp
|
||||||
|
}).collect::<Result<Vec<_>, _>>())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub enum CursorShape {
|
pub enum CursorShape {
|
||||||
Block,
|
Block,
|
||||||
Horizontal,
|
Horizontal,
|
||||||
@ -119,15 +137,7 @@ pub struct ModeInfo {
|
|||||||
|
|
||||||
impl ModeInfo {
|
impl ModeInfo {
|
||||||
pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result<Self, String> {
|
pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result<Self, String> {
|
||||||
let mode_info_map = mode_info_arr
|
let mode_info_map = mode_info_arr.to_attrs_map()?;
|
||||||
.iter()
|
|
||||||
.map(|p| {
|
|
||||||
p.0
|
|
||||||
.as_str()
|
|
||||||
.ok_or("mode_info key not string".to_owned())
|
|
||||||
.map(|key| (key, p.1.clone()))
|
|
||||||
})
|
|
||||||
.collect::<Result<HashMap<&str, Value>, String>>()?;
|
|
||||||
|
|
||||||
let cursor_shape = if let Some(shape) = mode_info_map.get("cursor_shape") {
|
let cursor_shape = if let Some(shape) = mode_info_map.get("cursor_shape") {
|
||||||
Some(CursorShape::new(shape)?)
|
Some(CursorShape::new(shape)?)
|
||||||
@ -372,17 +382,11 @@ fn call(ui: &mut shell::State,
|
|||||||
"busy_start" => ui.on_busy(true),
|
"busy_start" => ui.on_busy(true),
|
||||||
"busy_stop" => ui.on_busy(false),
|
"busy_stop" => ui.on_busy(false),
|
||||||
"popupmenu_show" => {
|
"popupmenu_show" => {
|
||||||
let mut menu_items = Vec::new();
|
let menu_items = map_array!(args[0], "Error get menu list array", |item| {
|
||||||
|
map_array!(item,
|
||||||
let items = args[0].as_array().ok_or("Error get menu list array")?;
|
"Error get menu item array",
|
||||||
for item in items {
|
|col| col.as_str().ok_or("Error get menu column"))
|
||||||
let item_line: result::Result<Vec<_>, &str> = item.as_array()
|
})?;
|
||||||
.ok_or("Error get menu item array")?
|
|
||||||
.iter()
|
|
||||||
.map(|col| col.as_str().ok_or("Error get menu column"))
|
|
||||||
.collect();
|
|
||||||
menu_items.push(item_line?);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.popupmenu_show(&menu_items,
|
ui.popupmenu_show(&menu_items,
|
||||||
try_int!(args[1]),
|
try_int!(args[1]),
|
||||||
@ -392,40 +396,32 @@ fn call(ui: &mut shell::State,
|
|||||||
"popupmenu_hide" => ui.popupmenu_hide(),
|
"popupmenu_hide" => ui.popupmenu_hide(),
|
||||||
"popupmenu_select" => ui.popupmenu_select(try_int!(args[0])),
|
"popupmenu_select" => ui.popupmenu_select(try_int!(args[0])),
|
||||||
"tabline_update" => {
|
"tabline_update" => {
|
||||||
let tabs_in = args[1].as_array().ok_or("Error get tabline list")?;
|
let tabs_out = map_array!(args[1], "Error get tabline list".to_owned(), |tab| {
|
||||||
|
tab.as_map()
|
||||||
|
.ok_or("Error get map for tab".to_owned())
|
||||||
|
.and_then(|tab_map| tab_map.to_attrs_map())
|
||||||
|
.map(|tab_attrs| {
|
||||||
|
let name_attr = tab_attrs
|
||||||
|
.get("name")
|
||||||
|
.and_then(|n| n.as_str().map(|s| s.to_owned()));
|
||||||
|
let tab_attr = tab_attrs
|
||||||
|
.get("tab")
|
||||||
|
.map(|tab_id| Tabpage::new(tab_id.clone()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut tabs_out = Vec::new();
|
(tab_attr, name_attr)
|
||||||
for tab in tabs_in {
|
})
|
||||||
let tab_attrs = tab.as_map().ok_or("Error get map for tab")?;
|
})?;
|
||||||
|
|
||||||
let mut tab_attr = None;
|
|
||||||
let mut name_attr = None;
|
|
||||||
|
|
||||||
for attr in tab_attrs {
|
|
||||||
let key = attr.0.as_str().ok_or("Error get key value")?;
|
|
||||||
if key == "tab" {
|
|
||||||
tab_attr = Some(Tabpage::new(attr.1.clone()));
|
|
||||||
} else if key == "name" {
|
|
||||||
name_attr = attr.1.as_str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tabs_out.push((tab_attr.unwrap(), name_attr));
|
|
||||||
}
|
|
||||||
ui.tabline_update(Tabpage::new(args[0].clone()), tabs_out)
|
ui.tabline_update(Tabpage::new(args[0].clone()), tabs_out)
|
||||||
}
|
}
|
||||||
"mode_info_set" => {
|
"mode_info_set" => {
|
||||||
let mode_info_array = args[1]
|
let mode_info = map_array!(args[1],
|
||||||
.as_array()
|
"Error get array key value for mode_info".to_owned(),
|
||||||
.ok_or("Erro get array key value for mode_info")?;
|
|mi| {
|
||||||
|
mi.as_map()
|
||||||
let mode_info = mode_info_array
|
.ok_or("Erro get map for mode_info".to_owned())
|
||||||
.iter()
|
.and_then(|mi_map| ModeInfo::new(mi_map))
|
||||||
.map(|mi| {
|
})?;
|
||||||
mi.as_map()
|
|
||||||
.ok_or("Erro get map for mode_info".to_owned())
|
|
||||||
.and_then(|mi_map| ModeInfo::new(mi_map))
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, String>>()?;
|
|
||||||
ui.mode_info_set(try_bool!(args[0]), mode_info)
|
ui.mode_info_set(try_bool!(args[0]), mode_info)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -1007,7 +1007,7 @@ impl RedrawEvents for State {
|
|||||||
|
|
||||||
fn tabline_update(&mut self,
|
fn tabline_update(&mut self,
|
||||||
selected: Tabpage,
|
selected: Tabpage,
|
||||||
tabs: Vec<(Tabpage, Option<&str>)>)
|
tabs: Vec<(Tabpage, Option<String>)>)
|
||||||
-> RepaintMode {
|
-> RepaintMode {
|
||||||
self.tabs.update_tabs(&self.nvim, &selected, &tabs);
|
self.tabs.update_tabs(&self.nvim, &selected, &tabs);
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ impl Tabline {
|
|||||||
fn update_state(&self,
|
fn update_state(&self,
|
||||||
nvim: &Rc<RefCell<nvim::NeovimClient>>,
|
nvim: &Rc<RefCell<nvim::NeovimClient>>,
|
||||||
selected: &Tabpage,
|
selected: &Tabpage,
|
||||||
tabs: &Vec<(Tabpage, Option<&str>)>) {
|
tabs: &Vec<(Tabpage, Option<String>)>) {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
if state.nvim.is_none() {
|
if state.nvim.is_none() {
|
||||||
@ -84,7 +84,7 @@ impl Tabline {
|
|||||||
pub fn update_tabs(&self,
|
pub fn update_tabs(&self,
|
||||||
nvim: &Rc<RefCell<nvim::NeovimClient>>,
|
nvim: &Rc<RefCell<nvim::NeovimClient>>,
|
||||||
selected: &Tabpage,
|
selected: &Tabpage,
|
||||||
tabs: &Vec<(Tabpage, Option<&str>)>) {
|
tabs: &Vec<(Tabpage, Option<String>)>) {
|
||||||
if tabs.len() <= 1 {
|
if tabs.len() <= 1 {
|
||||||
self.tabs.hide();
|
self.tabs.hide();
|
||||||
return;
|
return;
|
||||||
@ -113,7 +113,7 @@ impl Tabline {
|
|||||||
for (idx, tab) in tabs.iter().enumerate() {
|
for (idx, tab) in tabs.iter().enumerate() {
|
||||||
let tab_child = self.tabs.get_nth_page(Some(idx as u32));
|
let tab_child = self.tabs.get_nth_page(Some(idx as u32));
|
||||||
self.tabs
|
self.tabs
|
||||||
.set_tab_label_text(&tab_child.unwrap(), &tab.1.unwrap_or("??"));
|
.set_tab_label_text(&tab_child.unwrap(), &tab.1.as_ref().unwrap_or(&"??".to_owned()));
|
||||||
|
|
||||||
if *selected == tab.0 {
|
if *selected == tab.0 {
|
||||||
self.tabs.set_current_page(Some(idx as u32));
|
self.tabs.set_current_page(Some(idx as u32));
|
||||||
|
20
src/value.rs
Normal file
20
src/value.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use neovim_lib::Value;
|
||||||
|
|
||||||
|
pub trait ValueMapExt {
|
||||||
|
fn to_attrs_map(&self) -> Result<HashMap<&str, Value>, String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ValueMapExt for Vec<(Value, Value)> {
|
||||||
|
fn to_attrs_map(&self) -> Result<HashMap<&str, Value>, String> {
|
||||||
|
self.iter()
|
||||||
|
.map(|p| {
|
||||||
|
p.0
|
||||||
|
.as_str()
|
||||||
|
.ok_or("Can't convert map key to string".to_owned())
|
||||||
|
.map(|key| (key, p.1.clone()))
|
||||||
|
})
|
||||||
|
.collect::<Result<HashMap<&str, Value>, String>>()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user