settings system

macos-click-through
Keith Simmons 5 years ago
parent 86073351d0
commit 67468b20dd

@ -5,6 +5,8 @@ use std::convert::TryInto;
use rmpv::Value;
use skulpin::skia_safe::Color4f;
use crate::editor::EDITOR;
use crate::error_handling::ResultPanicExplanation;
use crate::editor::{Colors, Style, CursorMode, CursorShape};
#[derive(Debug, Clone)]
@ -160,8 +162,7 @@ fn unpack_color(packed_color: u64) -> Color4f {
}
}
fn extract_values<Arr: AsMut<[Value]>>(values: Vec<Value>, mut arr: Arr) -> Result<Arr>
{
fn extract_values<Arr: AsMut<[Value]>>(values: Vec<Value>, mut arr: Arr) -> Result<Arr> {
let arr_ref = arr.as_mut();
if values.len() != arr_ref.len() {
@ -649,17 +650,16 @@ pub fn parse_redraw_event(event_value: Value) -> Result<Vec<RedrawEvent>> {
Ok(parsed_events)
}
pub(in super) fn parse_neovim_event(event_name: &str, arguments: Vec<Value>) -> Result<Vec<RedrawEvent>> {
let mut resulting_events = Vec::new();
if event_name == "redraw" {
resulting_events.reserve(arguments.len());
for event in arguments {
resulting_events.append(&mut parse_redraw_event(event)?);
pub(in super) fn handle_redraw_event_group(arguments: Vec<Value>) {
for events in arguments {
let parsed_events = parse_redraw_event(events)
.unwrap_or_explained_panic("Could not parse event from neovim");
for parsed_event in parsed_events {
let mut editor = EDITOR.lock();
editor.handle_redraw_event(parsed_event);
}
} else {
println!("Unknown global event {}", event_name);
}
Ok(resulting_events)
}

@ -2,11 +2,11 @@ use rmpv::Value;
use nvim_rs::{Neovim, Handler, compat::tokio::Compat};
use async_trait::async_trait;
use tokio::process::ChildStdin;
use tokio::task;
use log::trace;
use crate::error_handling::ResultPanicExplanation;
use crate::editor::EDITOR;
use super::events::parse_neovim_event;
use crate::settings::SETTINGS;
use super::events::handle_redraw_event_group;
#[derive(Clone)]
pub struct NeovimHandler();
@ -17,11 +17,16 @@ impl Handler for NeovimHandler {
async fn handle_notify(&self, event_name: String, arguments: Vec<Value>, _neovim: Neovim<Compat<ChildStdin>>) {
trace!("Neovim notification: {:?}", &event_name);
let parsed_events = parse_neovim_event(&event_name, arguments)
.unwrap_or_explained_panic("Could not parse event from neovim");
for event in parsed_events {
let mut editor = EDITOR.lock();
editor.handle_redraw_event(event);
task::spawn_blocking(move || {
match event_name.as_ref() {
"redraw" => {
handle_redraw_event_group(arguments);
},
"setting_changed" => {
SETTINGS.handle_changed_notification(arguments);
},
_ => {}
}
}).await.ok();
}
}

@ -95,7 +95,6 @@ async fn start_process(mut receiver: UnboundedReceiver<UiCommand>) {
info!("Neovim process attached");
let nvim = Arc::new(nvim);
let input_nvim = nvim.clone();
tokio::spawn(async move {
info!("UiCommand processor started");
@ -117,6 +116,9 @@ async fn start_process(mut receiver: UnboundedReceiver<UiCommand>) {
}
});
SETTINGS.read_initial_values(&nvim).await;
SETTINGS.setup_changed_listeners(&nvim).await;
nvim.set_option("lazyredraw", Value::Boolean(false)).await
.ok();
}

@ -17,7 +17,6 @@ pub struct RedrawScheduler {
impl RedrawScheduler {
pub fn new() -> RedrawScheduler {
RedrawScheduler {
frames_queued: AtomicU16::new(1),
scheduled_frame: Mutex::new(None)
@ -38,7 +37,7 @@ impl RedrawScheduler {
pub fn queue_next_frame(&self) {
trace!("Next frame queued");
let buffer_frames = SETTINGS.buffer_frames.load(Ordering::Relaxed);
let buffer_frames = SETTINGS.get("extra_buffer_frames").read_u16();
self.frames_queued.store(buffer_frames, Ordering::Relaxed);
}

@ -1,19 +1,129 @@
use std::sync::atomic::{AtomicBool, AtomicU16};
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, AtomicU16, Ordering};
use std::convert::TryInto;
use rmpv::Value;
use nvim_rs::Neovim;
use nvim_rs::compat::tokio::Compat;
use flexi_logger::{Logger, Criterion, Naming, Cleanup};
use tokio::process::ChildStdin;
use crate::error_handling::ResultPanicExplanation;
lazy_static! {
pub static ref SETTINGS: Settings = Settings::new();
}
pub enum Setting {
Bool(AtomicBool),
U16(AtomicU16)
}
impl Setting {
fn new_bool(value: bool) -> Setting {
Setting::Bool(AtomicBool::new(value))
}
pub fn read_bool(&self) -> bool {
if let Setting::Bool(atomic_bool) = self {
atomic_bool.load(Ordering::Relaxed)
} else {
panic!("Could not read setting as bool");
}
}
fn new_u16(value: u16) -> Setting {
Setting::U16(AtomicU16::new(value))
}
pub fn read_u16(&self) -> u16 {
if let Setting::U16(atomic_u16) = self {
atomic_u16.load(Ordering::Relaxed)
} else {
panic!("Could not read setting as u16");
}
}
fn parse(&self, value: Value) {
match self {
Setting::Bool(atomic_bool) => {
if let Ok(value) = value.try_into() {
let intermediate: u64 = value;
atomic_bool.store(intermediate != 0, Ordering::Relaxed);
}
},
Setting::U16(atomic_u16) => {
if let Ok(value) = value.try_into() {
let intermediate: u64 = value;
atomic_u16.store(intermediate as u16, Ordering::Relaxed);
}
}
}
}
fn unparse(&self) -> Value {
match self {
Setting::Bool(atomic_bool) => {
let value = if atomic_bool.load(Ordering::Relaxed) {
1
} else {
0
};
Value::from(value)
},
Setting::U16(atomic_u16) => Value::from(atomic_u16.load(Ordering::Relaxed))
}
}
}
pub struct Settings {
pub neovim_arguments: Vec<String>,
pub no_idle: AtomicBool,
pub buffer_frames: AtomicU16
pub settings: HashMap<String, Setting>
}
impl Settings {
pub async fn read_initial_values(&self, nvim: &Neovim<Compat<ChildStdin>>) {
for (name, setting) in self.settings.iter() {
let variable_name = format!("g:neovide_{}", name.to_string());
if let Ok(value) = nvim.get_var(&variable_name).await {
setting.parse(value);
} else {
nvim.set_var(&variable_name, setting.unparse()).await.ok();
}
}
}
pub async fn setup_changed_listeners(&self, nvim: &Neovim<Compat<ChildStdin>>) {
for name in self.settings.keys() {
let name = name.to_string();
let vimscript =
format!("function NeovideNotify{}Changed(d, k, z)\n", name) +
&format!(" call rpcnotify(1, \"setting_changed\", \"{}\", g:neovide_{})\n", name, name) +
"endfunction\n" +
&format!("call dictwatcheradd(g:, \"neovide_{}\", \"NeovideNotify{}Changed\")", name, name);
nvim.exec(&vimscript, false).await
.unwrap_or_explained_panic(&format!("Could not setup setting notifier for {}", name));
}
}
pub fn handle_changed_notification(&self, arguments: Vec<Value>) {
let mut arguments = arguments.into_iter();
let (name, value) = (arguments.next().unwrap(), arguments.next().unwrap());
dbg!(&name, &value);
if let Some(setting) = name
.try_into()
.ok()
.as_ref()
.and_then(|name: &String| self.settings.get(name)) {
setting.parse(value);
}
}
pub fn get(&self, name: &str) -> &Setting {
self.settings.get(name).expect(&format!("Could not find option {}", name))
}
pub fn new() -> Settings {
let mut no_idle = false;
let mut buffer_frames = 1;
@ -37,10 +147,11 @@ impl Settings {
}
}).collect::<Vec<String>>();
Settings {
neovim_arguments,
no_idle: AtomicBool::new(no_idle),
buffer_frames: AtomicU16::new(buffer_frames),
}
let mut settings = HashMap::new();
settings.insert("no_idle".to_string(), Setting::new_bool(no_idle));
settings.insert("extra_buffer_frames".to_string(), Setting::new_u16(buffer_frames));
Settings { neovim_arguments, settings }
}
}

@ -214,7 +214,7 @@ pub fn ui_loop() {
window.set_title(&title);
}
if REDRAW_SCHEDULER.should_draw() || SETTINGS.no_idle.load(Ordering::Relaxed) {
if REDRAW_SCHEDULER.should_draw() || SETTINGS.get("no_idle").read_bool() {
debug!("Render Triggered");
if skulpin_renderer.draw(&window, |canvas, coordinate_system_helper| {
if renderer.draw(canvas, coordinate_system_helper) {

Loading…
Cancel
Save