diff options
Diffstat (limited to 'helix-view/src/editor.rs')
-rw-r--r-- | helix-view/src/editor.rs | 75 |
1 files changed, 56 insertions, 19 deletions
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 5a1ac6b1..973cf82e 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -9,6 +9,7 @@ use crate::{ tree::{self, Tree}, Align, Document, DocumentId, View, ViewId, }; +use helix_vcs::DiffProviderRegistry; use futures_util::stream::select_all::SelectAll; use futures_util::{future, StreamExt}; @@ -26,7 +27,10 @@ use std::{ }; use tokio::{ - sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, + sync::{ + mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, + Notify, RwLock, + }, time::{sleep, Duration, Instant, Sleep}, }; @@ -454,6 +458,8 @@ pub enum GutterType { LineNumbers, /// Show one blank space Spacer, + /// Highlight local changes + Diff, } impl std::str::FromStr for GutterType { @@ -464,6 +470,7 @@ impl std::str::FromStr for GutterType { "diagnostics" => Ok(Self::Diagnostics), "spacer" => Ok(Self::Spacer), "line-numbers" => Ok(Self::LineNumbers), + "diff" => Ok(Self::Diff), _ => anyhow::bail!("Gutter type can only be `diagnostics` or `line-numbers`."), } } @@ -600,6 +607,8 @@ impl Default for Config { GutterType::Diagnostics, GutterType::Spacer, GutterType::LineNumbers, + GutterType::Spacer, + GutterType::Diff, ], middle_click_paste: true, auto_pairs: AutoPairConfig::default(), @@ -681,6 +690,7 @@ pub struct Editor { pub macro_replaying: Vec<char>, pub language_servers: helix_lsp::Registry, pub diagnostics: BTreeMap<lsp::Url, Vec<lsp::Diagnostic>>, + pub diff_providers: DiffProviderRegistry, pub debugger: Option<dap::Client>, pub debugger_events: SelectAll<UnboundedReceiverStream<dap::Payload>>, @@ -711,8 +721,15 @@ pub struct Editor { pub exit_code: i32, pub config_events: (UnboundedSender<ConfigEvent>, UnboundedReceiver<ConfigEvent>), + /// Allows asynchronous tasks to control the rendering + /// The `Notify` allows asynchronous tasks to request the editor to perform a redraw + /// The `RwLock` blocks the editor from performing the render until an exclusive lock can be aquired + pub redraw_handle: RedrawHandle, + pub needs_redraw: bool, } +pub type RedrawHandle = (Arc<Notify>, Arc<RwLock<()>>); + #[derive(Debug)] pub enum EditorEvent { DocumentSaved(DocumentSavedEventResult), @@ -785,6 +802,7 @@ impl Editor { theme: theme_loader.default(), language_servers: helix_lsp::Registry::new(), diagnostics: BTreeMap::new(), + diff_providers: DiffProviderRegistry::default(), debugger: None, debugger_events: SelectAll::new(), breakpoints: HashMap::new(), @@ -803,6 +821,8 @@ impl Editor { auto_pairs, exit_code: 0, config_events: unbounded_channel(), + redraw_handle: Default::default(), + needs_redraw: false, } } @@ -1109,7 +1129,9 @@ impl Editor { let mut doc = Document::open(&path, None, Some(self.syn_loader.clone()))?; let _ = Self::launch_language_server(&mut self.language_servers, &mut doc); - + if let Some(diff_base) = self.diff_providers.get_diff_base(&path) { + doc.set_diff_base(diff_base, self.redraw_handle.clone()); + } self.new_document(doc) }; @@ -1348,24 +1370,39 @@ impl Editor { } pub async fn wait_event(&mut self) -> EditorEvent { - tokio::select! { - biased; + // the loop only runs once or twice and would be better implemented with a recursion + const generic + // however due to limitations with async functions that can not be implemented right now + loop { + tokio::select! { + biased; + + Some(event) = self.save_queue.next() => { + self.write_count -= 1; + return EditorEvent::DocumentSaved(event) + } + Some(config_event) = self.config_events.1.recv() => { + return EditorEvent::ConfigEvent(config_event) + } + Some(message) = self.language_servers.incoming.next() => { + return EditorEvent::LanguageServerMessage(message) + } + Some(event) = self.debugger_events.next() => { + return EditorEvent::DebuggerEvent(event) + } - Some(event) = self.save_queue.next() => { - self.write_count -= 1; - EditorEvent::DocumentSaved(event) - } - Some(config_event) = self.config_events.1.recv() => { - EditorEvent::ConfigEvent(config_event) - } - Some(message) = self.language_servers.incoming.next() => { - EditorEvent::LanguageServerMessage(message) - } - Some(event) = self.debugger_events.next() => { - EditorEvent::DebuggerEvent(event) - } - _ = &mut self.idle_timer => { - EditorEvent::IdleTimer + _ = self.redraw_handle.0.notified() => { + if !self.needs_redraw{ + self.needs_redraw = true; + let timeout = Instant::now() + Duration::from_millis(96); + if timeout < self.idle_timer.deadline(){ + self.idle_timer.as_mut().reset(timeout) + } + } + } + + _ = &mut self.idle_timer => { + return EditorEvent::IdleTimer + } } } } |