diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index ce28a3ca..4a6e697a 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -83,3 +83,4 @@ | `:run-shell-command`, `:sh` | Run a shell command | | `:reset-diff-change`, `:diffget`, `:diffg` | Reset the diff change at the cursor position. | | `:clear-register` | Clear given register. If no argument is provided, clear all registers. | +| `:redraw` | Clear and re-render the whole UI | diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 0d40fa66..3e6da5bb 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -251,6 +251,11 @@ impl Application { } async fn render(&mut self) { + if self.compositor.full_redraw { + self.terminal.clear().expect("Cannot clear the terminal"); + self.compositor.full_redraw = false; + } + let mut cx = crate::compositor::Context { editor: &mut self.editor, jobs: &mut self.jobs, diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index e38853c0..ef539180 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -2291,6 +2291,29 @@ fn clear_register( Ok(()) } +fn redraw( + cx: &mut compositor::Context, + _args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + let callback = Box::pin(async move { + let call: job::Callback = + job::Callback::EditorCompositor(Box::new(|_editor, compositor| { + compositor.need_full_redraw(); + })); + + Ok(call) + }); + + cx.jobs.callback(callback); + + Ok(()) +} + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2877,6 +2900,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: clear_register, signature: CommandSignature::none(), }, + TypableCommand { + name: "redraw", + aliases: &[], + doc: "Clear and re-render the whole UI", + fun: redraw, + signature: CommandSignature::none(), + }, ]; pub static TYPABLE_COMMAND_MAP: Lazy> = diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index dc962e1f..3dcb5f2b 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -80,6 +80,7 @@ pub struct Compositor { area: Rect, pub(crate) last_picker: Option>, + pub(crate) full_redraw: bool, } impl Compositor { @@ -88,6 +89,7 @@ impl Compositor { layers: Vec::new(), area, last_picker: None, + full_redraw: false, } } @@ -206,6 +208,10 @@ impl Compositor { .find(|component| component.id() == Some(id)) .and_then(|component| component.as_any_mut().downcast_mut()) } + + pub fn need_full_redraw(&mut self) { + self.full_redraw = true; + } } // View casting, taken straight from Cursive