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_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 crate::{
@ -103,11 +106,14 @@ impl Application {
size,
theme_loader.clone(),
syn_loader.clone(),
ArcSwap::from_pointee(config.load().editor.clone())
// config.clone(),
Box::new(Map::new(Arc::clone(&config), |config: &Config| {
&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);
if args.load_tutor {
@ -230,8 +236,8 @@ impl Application {
Some(payload) = self.editor.debugger_events.next() => {
self.handle_debugger_message(payload).await;
}
Some(ConfigEvent) = self.editor.config_events.next() => {
self.refresh_config();
Some(config_event) = self.editor.config_events.next() => {
self.handle_config_events(config_event);
self.render();
}
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();
// 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() {
@ -275,8 +292,6 @@ impl Application {
);
}
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 {

@ -1,5 +1,3 @@
use std::{borrow::BorrowMut, sync::Arc};
use super::*;
use helix_view::editor::{Action, ConfigEvent};
@ -864,25 +862,26 @@ fn setting(
}
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()) {
match key.as_ref() {
"scrolloff" => runtime_config.scrolloff = arg.parse()?,
"scroll-lines" => runtime_config.scroll_lines = arg.parse()?,
"mouse" => runtime_config.mouse = arg.parse()?,
"line-number" => runtime_config.line_number = arg.parse()?,
"middle-click_paste" => runtime_config.middle_click_paste = arg.parse()?,
"auto-pairs" => runtime_config.auto_pairs = arg.parse()?,
"auto-completion" => runtime_config.auto_completion = arg.parse()?,
"completion-trigger-len" => runtime_config.completion_trigger_len = arg.parse()?,
"auto-info" => runtime_config.auto_info = arg.parse()?,
"true-color" => runtime_config.true_color = arg.parse()?,
"search.smart-case" => runtime_config.search.smart_case = arg.parse()?,
"search.wrap-around" => runtime_config.search.wrap_around = arg.parse()?,
_ => anyhow::bail!("Unknown key `{}`.", args[0]),
}
cx.editor.config.store(Arc::new(runtime_config.clone()));
let mut runtime_config = cx.editor.config.load().clone();
match key.as_ref() {
"scrolloff" => runtime_config.scrolloff = arg.parse()?,
"scroll-lines" => runtime_config.scroll_lines = arg.parse()?,
"mouse" => runtime_config.mouse = arg.parse()?,
"line-number" => runtime_config.line_number = arg.parse()?,
"middle-click_paste" => runtime_config.middle_click_paste = arg.parse()?,
"auto-pairs" => runtime_config.auto_pairs = arg.parse()?,
"auto-completion" => runtime_config.auto_completion = arg.parse()?,
"completion-trigger-len" => runtime_config.completion_trigger_len = arg.parse()?,
"auto-info" => runtime_config.auto_info = arg.parse()?,
"true-color" => runtime_config.true_color = arg.parse()?,
"search.smart-case" => runtime_config.search.smart_case = arg.parse()?,
"search.wrap-around" => runtime_config.search.wrap_around = arg.parse()?,
_ => anyhow::bail!("Unknown key `{}`.", args[0]),
}
cx.editor
.config_events
.push(tokio_stream::once(ConfigEvent::Update(runtime_config)));
Ok(())
}
@ -977,7 +976,8 @@ fn open_config(
_args: &[Cow<str>],
_event: PromptEvent,
) -> anyhow::Result<()> {
cx.editor.open(helix_loader::config_file(), Action::Replace)?;
cx.editor
.open(helix_loader::config_file(), Action::Replace)?;
Ok(())
}
@ -986,7 +986,9 @@ fn refresh_config(
_args: &[Cow<str>],
_event: PromptEvent,
) -> anyhow::Result<()> {
cx.editor.config_events.push(tokio_stream::once(ConfigEvent));
cx.editor
.config_events
.push(tokio_stream::once(ConfigEvent::Refresh));
Ok(())
}

@ -35,7 +35,7 @@ impl Config {
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::args::Args;
use helix_term::config::Config;

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

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

Loading…
Cancel
Save