Use dynamic dispatch for editor config

pull/1803/head
Joseph Harrison-Lim 3 years ago
parent 4a0eff1129
commit 209112bdbc
No known key found for this signature in database
GPG Key ID: 5DAB214D5E62987D

@ -5,7 +5,10 @@ use helix_core::{
}; };
use helix_dap::{self as dap, Payload, Request}; use helix_dap::{self as dap, Payload, Request};
use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap}; use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
use helix_view::{editor::{Breakpoint, ConfigEvent}, theme, Editor}; use helix_view::{
editor::{Breakpoint, ConfigEvent},
theme, Editor,
};
use serde_json::json; use serde_json::json;
use crate::{ use crate::{
@ -103,11 +106,14 @@ impl Application {
size, size,
theme_loader.clone(), theme_loader.clone(),
syn_loader.clone(), syn_loader.clone(),
ArcSwap::from_pointee(config.load().editor.clone()) Box::new(Map::new(Arc::clone(&config), |config: &Config| {
// config.clone(), &config.editor
})),
); );
let editor_view = Box::new(ui::EditorView::new(std::mem::take(&mut config.load().keys.clone()))); let editor_view = Box::new(ui::EditorView::new(std::mem::take(
&mut config.load().keys.clone(),
)));
compositor.push(editor_view); compositor.push(editor_view);
if args.load_tutor { if args.load_tutor {
@ -230,8 +236,8 @@ impl Application {
Some(payload) = self.editor.debugger_events.next() => { Some(payload) = self.editor.debugger_events.next() => {
self.handle_debugger_message(payload).await; self.handle_debugger_message(payload).await;
} }
Some(ConfigEvent) = self.editor.config_events.next() => { Some(config_event) = self.editor.config_events.next() => {
self.refresh_config(); self.handle_config_events(config_event);
self.render(); self.render();
} }
Some(callback) = self.jobs.futures.next() => { Some(callback) = self.jobs.futures.next() => {
@ -251,7 +257,18 @@ impl Application {
} }
} }
pub fn refresh_config(&mut self) { pub fn handle_config_events(&mut self, config_event: ConfigEvent) {
match config_event {
ConfigEvent::Refresh => { self.refresh_config() }
ConfigEvent::Update(editor_config) => {
let mut app_config = (*self.config.load().clone()).clone();
app_config.editor = editor_config;
self.config.swap(Arc::new(app_config));
}
}
}
fn refresh_config(&mut self) {
let config = Config::load(helix_loader::config_file()).unwrap(); let config = Config::load(helix_loader::config_file()).unwrap();
// Just an example to start; Some config properties like "theme" are a bit more involved and require a reload // Just an example to start; Some config properties like "theme" are a bit more involved and require a reload
if let Some(theme) = config.theme.clone() { if let Some(theme) = config.theme.clone() {
@ -275,8 +292,6 @@ impl Application {
); );
} }
self.config.store(Arc::new(config)); self.config.store(Arc::new(config));
// Is it possible to not do this manually? Presumably I've completely butchered using ArcSwap?
self.editor.config.store(Arc::new(self.config.load().editor.clone()));
} }
fn true_color(&self) -> bool { fn true_color(&self) -> bool {

@ -1,5 +1,3 @@
use std::{borrow::BorrowMut, sync::Arc};
use super::*; use super::*;
use helix_view::editor::{Action, ConfigEvent}; use helix_view::editor::{Action, ConfigEvent};
@ -864,7 +862,7 @@ fn setting(
} }
let (key, arg) = (&args[0].to_lowercase(), &args[1]); let (key, arg) = (&args[0].to_lowercase(), &args[1]);
if let Ok(runtime_config) = &mut std::sync::Arc::try_unwrap(cx.editor.config.load().clone()) { let mut runtime_config = cx.editor.config.load().clone();
match key.as_ref() { match key.as_ref() {
"scrolloff" => runtime_config.scrolloff = arg.parse()?, "scrolloff" => runtime_config.scrolloff = arg.parse()?,
"scroll-lines" => runtime_config.scroll_lines = arg.parse()?, "scroll-lines" => runtime_config.scroll_lines = arg.parse()?,
@ -880,9 +878,10 @@ fn setting(
"search.wrap-around" => runtime_config.search.wrap_around = arg.parse()?, "search.wrap-around" => runtime_config.search.wrap_around = arg.parse()?,
_ => anyhow::bail!("Unknown key `{}`.", args[0]), _ => anyhow::bail!("Unknown key `{}`.", args[0]),
} }
cx.editor.config.store(Arc::new(runtime_config.clone()));
}
cx.editor
.config_events
.push(tokio_stream::once(ConfigEvent::Update(runtime_config)));
Ok(()) Ok(())
} }
@ -977,7 +976,8 @@ fn open_config(
_args: &[Cow<str>], _args: &[Cow<str>],
_event: PromptEvent, _event: PromptEvent,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
cx.editor.open(helix_loader::config_file(), Action::Replace)?; cx.editor
.open(helix_loader::config_file(), Action::Replace)?;
Ok(()) Ok(())
} }
@ -986,7 +986,9 @@ fn refresh_config(
_args: &[Cow<str>], _args: &[Cow<str>],
_event: PromptEvent, _event: PromptEvent,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
cx.editor.config_events.push(tokio_stream::once(ConfigEvent)); cx.editor
.config_events
.push(tokio_stream::once(ConfigEvent::Refresh));
Ok(()) Ok(())
} }

@ -35,7 +35,7 @@ impl Config {
Config::default() Config::default()
})), })),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Result::Ok(Config::default()), Err(err) if err.kind() == std::io::ErrorKind::NotFound => Result::Ok(Config::default()),
Err(err) => return Err(Error::new(err)), Err(err) => Err(err.into()),
} }
} }
} }

@ -1,4 +1,4 @@
use anyhow::{Context, Error, Result}; use anyhow::{Context, Result};
use helix_term::application::Application; use helix_term::application::Application;
use helix_term::args::Args; use helix_term::args::Args;
use helix_term::config::Config; use helix_term::config::Config;

@ -17,8 +17,8 @@ term = ["crossterm"]
bitflags = "1.3" bitflags = "1.3"
anyhow = "1" anyhow = "1"
helix-core = { version = "0.6", path = "../helix-core" } helix-core = { version = "0.6", path = "../helix-core" }
helix-lsp = { version = "0.6", path = "../helix-lsp"} helix-lsp = { version = "0.6", path = "../helix-lsp" }
helix-dap = { version = "0.6", path = "../helix-dap"} helix-dap = { version = "0.6", path = "../helix-dap" }
crossterm = { version = "0.23", optional = true } crossterm = { version = "0.23", optional = true }
# Conversion traits # Conversion traits

@ -39,7 +39,7 @@ use helix_dap as dap;
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize}; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize};
use arc_swap::{access::{DynAccess}, ArcSwap}; use arc_swap::{access::{DynAccess, DynGuard}};
fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result<Duration, D::Error> fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where where
@ -272,9 +272,6 @@ pub struct Breakpoint {
pub log_message: Option<String>, pub log_message: Option<String>,
} }
pub trait DynAccessDebug<T>: DynAccess<T> + std::fmt::Debug {}
#[derive(Debug)]
pub struct Editor { pub struct Editor {
pub tree: Tree, pub tree: Tree,
pub next_document_id: DocumentId, pub next_document_id: DocumentId,
@ -298,7 +295,7 @@ pub struct Editor {
pub status_msg: Option<(Cow<'static, str>, Severity)>, pub status_msg: Option<(Cow<'static, str>, Severity)>,
pub autoinfo: Option<Info>, pub autoinfo: Option<Info>,
pub config: ArcSwap<Config>, pub config: Box<dyn DynAccess<Config>>,
pub auto_pairs: Option<AutoPairs>, pub auto_pairs: Option<AutoPairs>,
pub idle_timer: Pin<Box<Sleep>>, pub idle_timer: Pin<Box<Sleep>>,
@ -313,7 +310,10 @@ pub struct Editor {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct ConfigEvent; pub enum ConfigEvent {
Refresh,
Update(Config),
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CompleteAction { pub struct CompleteAction {
@ -334,7 +334,7 @@ impl Editor {
mut area: Rect, mut area: Rect,
theme_loader: Arc<theme::Loader>, theme_loader: Arc<theme::Loader>,
syn_loader: Arc<syntax::Loader>, syn_loader: Arc<syntax::Loader>,
config: ArcSwap<Config>, config: Box<dyn DynAccess<Config>>,
) -> Self { ) -> Self {
let language_servers = helix_lsp::Registry::new(); let language_servers = helix_lsp::Registry::new();
let conf = config.load(); let conf = config.load();

Loading…
Cancel
Save