Syntax-highlight regex prompts

We can use tree-sitter-regex highlighting in prompts for entering
regexes, like `search` or `global_search`. The `highlighted_code_block`
function from the markdown component makes this a very small change.

This could be improved in the future by leaving the parsed syntax tree
on the prompt, allowing incremental updates. Prompt lines are usually so
short though and tree-sitter-regex is rather small and uncomplicated,
so that improvement probably wouldn't make a big difference.
pull/7764/head
Michael Davis 1 year ago committed by Blaž Hrastnik
parent 6a431afc4e
commit 0dc3753eb2

@ -151,7 +151,8 @@ pub fn regex_prompt(
} }
} }
}, },
); )
.with_language("regex", std::sync::Arc::clone(&cx.editor.syn_loader));
// Calculate initial completion // Calculate initial completion
prompt.recalculate_completion(cx.editor); prompt.recalculate_completion(cx.editor);
// prompt // prompt

@ -1,7 +1,9 @@
use crate::compositor::{Component, Compositor, Context, Event, EventResult}; use crate::compositor::{Component, Compositor, Context, Event, EventResult};
use crate::{alt, ctrl, key, shift, ui}; use crate::{alt, ctrl, key, shift, ui};
use helix_core::syntax;
use helix_view::input::KeyEvent; use helix_view::input::KeyEvent;
use helix_view::keyboard::KeyCode; use helix_view::keyboard::KeyCode;
use std::sync::Arc;
use std::{borrow::Cow, ops::RangeFrom}; use std::{borrow::Cow, ops::RangeFrom};
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
use tui::widgets::{Block, Borders, Widget}; use tui::widgets::{Block, Borders, Widget};
@ -32,6 +34,7 @@ pub struct Prompt {
callback_fn: CallbackFn, callback_fn: CallbackFn,
pub doc_fn: DocFn, pub doc_fn: DocFn,
next_char_handler: Option<PromptCharHandler>, next_char_handler: Option<PromptCharHandler>,
language: Option<(&'static str, Arc<syntax::Loader>)>,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq)]
@ -83,6 +86,7 @@ impl Prompt {
callback_fn: Box::new(callback_fn), callback_fn: Box::new(callback_fn),
doc_fn: Box::new(|_| None), doc_fn: Box::new(|_| None),
next_char_handler: None, next_char_handler: None,
language: None,
} }
} }
@ -94,6 +98,11 @@ impl Prompt {
self self
} }
pub fn with_language(mut self, language: &'static str, loader: Arc<syntax::Loader>) -> Self {
self.language = Some((language, loader));
self
}
pub fn line(&self) -> &String { pub fn line(&self) -> &String {
&self.line &self.line
} }
@ -456,30 +465,28 @@ impl Prompt {
// render buffer text // render buffer text
surface.set_string(area.x, area.y + line, &self.prompt, prompt_color); surface.set_string(area.x, area.y + line, &self.prompt, prompt_color);
let (input, is_suggestion): (Cow<str>, bool) = if self.line.is_empty() { let line_area = area.clip_left(self.prompt.len() as u16).clip_top(line);
// latest value in the register list if self.line.is_empty() {
match self // Show the most recently entered value as a suggestion.
if let Some(suggestion) = self
.history_register .history_register
.and_then(|reg| cx.editor.registers.last(reg)) .and_then(|reg| cx.editor.registers.last(reg))
.map(|entry| entry.into())
{ {
Some(value) => (value, true), surface.set_string(line_area.x, line_area.y, suggestion, suggestion_color);
None => (Cow::from(""), false),
} }
} else if let Some((language, loader)) = self.language.as_ref() {
let mut text: ui::text::Text = crate::ui::markdown::highlighted_code_block(
self.line.clone(),
language,
Some(&cx.editor.theme),
loader.clone(),
None,
)
.into();
text.render(line_area, surface, cx);
} else { } else {
(self.line.as_str().into(), false) surface.set_string(line_area.x, line_area.y, self.line.clone(), prompt_color);
}; }
surface.set_string(
area.x + self.prompt.len() as u16,
area.y + line,
&input,
if is_suggestion {
suggestion_color
} else {
prompt_color
},
);
} }
} }

Loading…
Cancel
Save