on master help sign in
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.

commit0dc3753eb2a1af296f5faffaf9c3d29bceb5a37f authorMichael Davis <mcarsondavis@gmail.com> dateTue 25 Jul 2023, 14:20 (3 years ago) parent6a431af
2 files changed+28−20
helix-term/src/ui/mod.rs+2−1 helix-term/src/ui/prompt.rs+26−19
helix-term/src/ui/mod.rs+2−1
@@ -151,7 +151,8 @@ pub fn regex_prompt(
151151 }
152152 }
153153 },
154− );
154+ )
155+ .with_language("regex", std::sync::Arc::clone(&cx.editor.syn_loader));
155156 // Calculate initial completion
156157 prompt.recalculate_completion(cx.editor);
157158 // prompt
helix-term/src/ui/prompt.rs+26−19
@@ -1,7 +1,9 @@
11use crate::compositor::{Component, Compositor, Context, Event, EventResult};
22use crate::{alt, ctrl, key, shift, ui};
3+use helix_core::syntax;
34use helix_view::input::KeyEvent;
45use helix_view::keyboard::KeyCode;
6+use std::sync::Arc;
57use std::{borrow::Cow, ops::RangeFrom};
68use tui::buffer::Buffer as Surface;
79use tui::widgets::{Block, Borders, Widget};
@@ -32,6 +34,7 @@ pub struct Prompt {
3234 callback_fn: CallbackFn,
3335 pub doc_fn: DocFn,
3436 next_char_handler: Option<PromptCharHandler>,
37+ language: Option<(&'static str, Arc<syntax::Loader>)>,
3538}
3639
3740#[derive(Clone, Copy, PartialEq, Eq)]
@@ -83,6 +86,7 @@ impl Prompt {
8386 callback_fn: Box::new(callback_fn),
8487 doc_fn: Box::new(|_| None),
8588 next_char_handler: None,
89+ language: None,
8690 }
8791 }
8892
@@ -94,6 +98,11 @@ impl Prompt {
9498 self
9599 }
96100
101+ pub fn with_language(mut self, language: &'static str, loader: Arc<syntax::Loader>) -> Self {
102+ self.language = Some((language, loader));
103+ self
104+ }
105+
97106 pub fn line(&self) -> &String {
98107 &self.line
99108 }
@@ -456,30 +465,28 @@ impl Prompt {
456465 // render buffer text
457466 surface.set_string(area.x, area.y + line, &self.prompt, prompt_color);
458467
459− let (input, is_suggestion): (Cow<str>, bool) = if self.line.is_empty() {
460− // latest value in the register list
461− match self
468+ let line_area = area.clip_left(self.prompt.len() as u16).clip_top(line);
469+ if self.line.is_empty() {
470+ // Show the most recently entered value as a suggestion.
471+ if let Some(suggestion) = self
462472 .history_register
463473 .and_then(|reg| cx.editor.registers.last(reg))
464− .map(|entry| entry.into())
465474 {
466− Some(value) => (value, true),
467− None => (Cow::from(""), false),
475+ surface.set_string(line_area.x, line_area.y, suggestion, suggestion_color);
468476 }
477+ } else if let Some((language, loader)) = self.language.as_ref() {
478+ let mut text: ui::text::Text = crate::ui::markdown::highlighted_code_block(
479+ self.line.clone(),
480+ language,
481+ Some(&cx.editor.theme),
482+ loader.clone(),
483+ None,
484+ )
485+ .into();
486+ text.render(line_area, surface, cx);
469487 } else {
470− (self.line.as_str().into(), false)
471− };
472−
473− surface.set_string(
474− area.x + self.prompt.len() as u16,
475− area.y + line,
476− &input,
477− if is_suggestion {
478− suggestion_color
479− } else {
480− prompt_color
481− },
482− );
488+ surface.set_string(line_area.x, line_area.y, self.line.clone(), prompt_color);
489+ }
483490 }
484491}
485492