From 0dce39e0df064a564bab0f4eba68285ff21ff9d8 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:51:55 +0000 Subject: [PATCH 01/10] feat: add command to toggle diagnostics does not work --- helix-term/src/commands/typed.rs | 25 +++++++++++++++++++++++++ helix-view/src/editor.rs | 7 +++++++ helix-view/src/handlers/diagnostics.rs | 3 +++ 3 files changed, 35 insertions(+) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 49864abb683e..e53a02c374f1 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1928,6 +1928,24 @@ fn set_option( Ok(()) } +fn toggle_diagnostics( + cx: &mut compositor::Context, + args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + ensure!(args.is_empty(), ":toggle-diagnostics takes no arguments"); + + let (view, _) = current!(cx.editor); + + view.diagnostics_handler.toggle_diagnostics(); + + Ok(()) +} + /// Toggle boolean config option at runtime. Access nested values by dot /// syntax, for example to toggle smart case search, use `:toggle search.smart- /// case`. @@ -3149,6 +3167,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: read, signature: CommandSignature::positional(&[completers::filename]), }, + TypableCommand { + name: "toggle-diagnostics", + aliases: &["td"], + doc: "Toggle Diagnostics", + fun: toggle_diagnostics, + signature: CommandSignature::all(completers::register) + } ]; pub static TYPABLE_COMMAND_MAP: Lazy> = diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index aa9a11533bbb..e3e21c068c02 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1049,6 +1049,8 @@ pub struct Editor { pub debugger_events: SelectAll>, pub breakpoints: HashMap>, + pub show_diagnostics: bool, + pub syn_loader: Arc>, pub theme_loader: Arc, /// last_theme is used for theme previews. We store the current theme here, @@ -1195,6 +1197,7 @@ impl Editor { breakpoints: HashMap::new(), syn_loader, theme_loader, + show_diagnostics: true, last_theme: None, last_selection: None, registers: Registers::new(Box::new(arc_swap::access::Map::new( @@ -1328,6 +1331,10 @@ impl Editor { self.set_theme_impl(theme, ThemeAction::Set); } + pub fn toggle_diagnostics(&mut self) { + self.show_diagnostics = !self.show_diagnostics; + } + fn set_theme_impl(&mut self, theme: Theme, preview: ThemeAction) { // `ui.selection` is the only scope required to be able to render a theme. if theme.find_scope_index_exact("ui.selection").is_none() { diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index 2b8ff6325d26..a0eb04c73ba1 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -94,6 +94,9 @@ impl DiagnosticsHandler { } impl DiagnosticsHandler { + pub fn toggle_diagnostics(&mut self) { + self.active = !self.active; + } pub fn immediately_show_diagnostic(&self, doc: &Document, view: ViewId) { self.last_doc.set(doc.id()); let cursor_line = doc From a1a2cce23e0a0bea2694fbfc5434a0204328d22c Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:42:21 +0000 Subject: [PATCH 02/10] feat: add `:toggle-diagnostics` command to hide diagnostics --- helix-term/src/commands/typed.rs | 4 +-- helix-term/src/ui/editor.rs | 32 ++++++++++++------- .../src/ui/text_decorations/diagnostics.rs | 1 + helix-view/src/handlers/diagnostics.rs | 8 +++-- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index e53a02c374f1..dcb782401a42 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1940,8 +1940,8 @@ fn toggle_diagnostics( ensure!(args.is_empty(), ":toggle-diagnostics takes no arguments"); let (view, _) = current!(cx.editor); - - view.diagnostics_handler.toggle_diagnostics(); + view.diagnostics_handler.toggle_active(); + cx.editor.toggle_diagnostics(); Ok(()) } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 5179be4f4e1c..fd86fe4e088a 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -189,19 +189,26 @@ impl EditorView { primary_cursor, }); } - let width = view.inner_width(doc); let config = doc.config.load(); - let enable_cursor_line = view - .diagnostics_handler - .show_cursorline_diagnostics(doc, view.id); - let inline_diagnostic_config = config.inline_diagnostics.prepare(width, enable_cursor_line); - decorations.add_decoration(InlineDiagnostics::new( - doc, - theme, - primary_cursor, - inline_diagnostic_config, - config.end_of_line_diagnostics, - )); + + if editor.show_diagnostics { + log::error!("{:#?}", editor.show_diagnostics); + let width = view.inner_width(doc); + let enable_cursor_line = view + .diagnostics_handler + .show_cursorline_diagnostics(doc, view.id); + let inline_diagnostic_config = + config.inline_diagnostics.prepare(width, enable_cursor_line); + + decorations.add_decoration(InlineDiagnostics::new( + doc, + theme, + primary_cursor, + inline_diagnostic_config, + config.end_of_line_diagnostics, + )); + } + render_document( surface, inner, @@ -229,6 +236,7 @@ impl EditorView { if config.inline_diagnostics.disabled() && config.end_of_line_diagnostics == DiagnosticFilter::Disable + && editor.show_diagnostics { Self::render_diagnostics(doc, view, inner, surface, theme); } diff --git a/helix-term/src/ui/text_decorations/diagnostics.rs b/helix-term/src/ui/text_decorations/diagnostics.rs index fb82bcf54c23..2d1ad5e56a34 100644 --- a/helix-term/src/ui/text_decorations/diagnostics.rs +++ b/helix-term/src/ui/text_decorations/diagnostics.rs @@ -123,6 +123,7 @@ impl Renderer<'_, '_> { end_col - start_col } + // need to toggle this fn draw_diagnostic(&mut self, diag: &Diagnostic, col: u16, next_severity: Option) { let severity = diag.severity(); let (sym, sym_severity) = if let Some(next_severity) = next_severity { diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index a0eb04c73ba1..cb743b443d79 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -94,9 +94,6 @@ impl DiagnosticsHandler { } impl DiagnosticsHandler { - pub fn toggle_diagnostics(&mut self) { - self.active = !self.active; - } pub fn immediately_show_diagnostic(&self, doc: &Document, view: ViewId) { self.last_doc.set(doc.id()); let cursor_line = doc @@ -107,6 +104,11 @@ impl DiagnosticsHandler { self.active_generation .store(self.generation.get(), atomic::Ordering::Relaxed); } + + pub fn toggle_active(&mut self) { + self.active = !self.active; + } + pub fn show_cursorline_diagnostics(&self, doc: &Document, view: ViewId) -> bool { if !self.active { return false; From 1610118d13011ad48af91667b3d3a7ffde1173f0 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:46:45 +0000 Subject: [PATCH 03/10] docs: add toggle-diagnostic command info --- book/src/generated/typable-cmd.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index f0d9a0f492a5..24bb8d7e7d81 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -88,3 +88,4 @@ | `:move`, `:mv` | Move the current buffer and its corresponding file to a different path | | `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default | | `:read`, `:r` | Load a file into buffer | +| `:toggle-diagnostics`, `:td` | Toggle Diagnostics | From 08deeb48b8c52da807f26442e814007a8561ad15 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Sun, 8 Dec 2024 13:47:00 +0000 Subject: [PATCH 04/10] chore: remove pointless comment --- helix-term/src/ui/text_decorations/diagnostics.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/helix-term/src/ui/text_decorations/diagnostics.rs b/helix-term/src/ui/text_decorations/diagnostics.rs index 2d1ad5e56a34..fb82bcf54c23 100644 --- a/helix-term/src/ui/text_decorations/diagnostics.rs +++ b/helix-term/src/ui/text_decorations/diagnostics.rs @@ -123,7 +123,6 @@ impl Renderer<'_, '_> { end_col - start_col } - // need to toggle this fn draw_diagnostic(&mut self, diag: &Diagnostic, col: u16, next_severity: Option) { let severity = diag.severity(); let (sym, sym_severity) = if let Some(next_severity) = next_severity { From 8271a35be27dd7c2e90a52074da1d2fbe3ee8836 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Mon, 9 Dec 2024 04:45:28 +0000 Subject: [PATCH 05/10] feat: config option for toggling diagnostics --- helix-term/src/commands/typed.rs | 25 ----------------------- helix-term/src/ui/editor.rs | 5 ++--- helix-view/src/editor.rs | 23 ++++++++++++--------- helix-view/src/gutter.rs | 8 ++++---- helix-view/src/handlers/diagnostics.rs | 10 +++------ helix-view/src/tree.rs | 28 +++++++++++++------------- helix-view/src/view.rs | 12 ++++++----- 7 files changed, 44 insertions(+), 67 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index dcb782401a42..49864abb683e 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1928,24 +1928,6 @@ fn set_option( Ok(()) } -fn toggle_diagnostics( - cx: &mut compositor::Context, - args: &[Cow], - event: PromptEvent, -) -> anyhow::Result<()> { - if event != PromptEvent::Validate { - return Ok(()); - } - - ensure!(args.is_empty(), ":toggle-diagnostics takes no arguments"); - - let (view, _) = current!(cx.editor); - view.diagnostics_handler.toggle_active(); - cx.editor.toggle_diagnostics(); - - Ok(()) -} - /// Toggle boolean config option at runtime. Access nested values by dot /// syntax, for example to toggle smart case search, use `:toggle search.smart- /// case`. @@ -3167,13 +3149,6 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: read, signature: CommandSignature::positional(&[completers::filename]), }, - TypableCommand { - name: "toggle-diagnostics", - aliases: &["td"], - doc: "Toggle Diagnostics", - fun: toggle_diagnostics, - signature: CommandSignature::all(completers::register) - } ]; pub static TYPABLE_COMMAND_MAP: Lazy> = diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fd86fe4e088a..b6a56cafa585 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -191,8 +191,7 @@ impl EditorView { } let config = doc.config.load(); - if editor.show_diagnostics { - log::error!("{:#?}", editor.show_diagnostics); + if editor.config().enable_diagnostics { let width = view.inner_width(doc); let enable_cursor_line = view .diagnostics_handler @@ -236,7 +235,7 @@ impl EditorView { if config.inline_diagnostics.disabled() && config.end_of_line_diagnostics == DiagnosticFilter::Disable - && editor.show_diagnostics + && editor.config().enable_diagnostics { Self::render_diagnostics(doc, view, inner, surface, theme); } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index e3e21c068c02..74558daa7dc2 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -350,6 +350,7 @@ pub struct Config { deserialize_with = "deserialize_alphabet" )] pub jump_label_alphabet: Vec, + pub enable_diagnostics: bool, /// Display diagnostic below the line they occur. pub inline_diagnostics: InlineDiagnosticsConfig, pub end_of_line_diagnostics: DiagnosticFilter, @@ -992,6 +993,7 @@ impl Default for Config { popup_border: PopupBorderConfig::None, indent_heuristic: IndentationHeuristic::default(), jump_label_alphabet: ('a'..='z').collect(), + enable_diagnostics: true, inline_diagnostics: InlineDiagnosticsConfig::default(), end_of_line_diagnostics: DiagnosticFilter::Disable, clipboard_provider: ClipboardProvider::default(), @@ -1049,8 +1051,6 @@ pub struct Editor { pub debugger_events: SelectAll>, pub breakpoints: HashMap>, - pub show_diagnostics: bool, - pub syn_loader: Arc>, pub theme_loader: Arc, /// last_theme is used for theme previews. We store the current theme here, @@ -1197,7 +1197,6 @@ impl Editor { breakpoints: HashMap::new(), syn_loader, theme_loader, - show_diagnostics: true, last_theme: None, last_selection: None, registers: Registers::new(Box::new(arc_swap::access::Map::new( @@ -1331,10 +1330,6 @@ impl Editor { self.set_theme_impl(theme, ThemeAction::Set); } - pub fn toggle_diagnostics(&mut self) { - self.show_diagnostics = !self.show_diagnostics; - } - fn set_theme_impl(&mut self, theme: Theme, preview: ThemeAction) { // `ui.selection` is the only scope required to be able to render a theme. if theme.find_scope_index_exact("ui.selection").is_none() { @@ -1659,7 +1654,13 @@ impl Editor { .try_get(self.tree.focus) .filter(|v| id == v.doc) // Different Document .cloned() - .unwrap_or_else(|| View::new(id, self.config().gutters.clone())); + .unwrap_or_else(|| { + View::new( + id, + self.config().gutters.clone(), + self.config().enable_diagnostics, + ) + }); let view_id = self.tree.split( view, match action { @@ -1833,7 +1834,11 @@ impl Editor { .map(|(&doc_id, _)| doc_id) .next() .unwrap_or_else(|| self.new_document(Document::default(self.config.clone()))); - let view = View::new(doc_id, self.config().gutters.clone()); + let view = View::new( + doc_id, + self.config().gutters.clone(), + self.config().enable_diagnostics, + ); let view_id = self.tree.insert(view); let doc = doc_mut!(self, &doc_id); doc.ensure_view_init(view_id); diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs index 36f719f795a8..3466f86858c2 100644 --- a/helix-view/src/gutter.rs +++ b/helix-view/src/gutter.rs @@ -346,7 +346,7 @@ mod tests { #[test] fn test_default_gutter_widths() { - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -371,7 +371,7 @@ mod tests { ..Default::default() }; - let mut view = View::new(DocumentId::default(), gutters); + let mut view = View::new(DocumentId::default(), gutters, true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -389,7 +389,7 @@ mod tests { line_numbers: GutterLineNumbersConfig { min_width: 10 }, }; - let mut view = View::new(DocumentId::default(), gutters); + let mut view = View::new(DocumentId::default(), gutters, true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -411,7 +411,7 @@ mod tests { line_numbers: GutterLineNumbersConfig { min_width: 1 }, }; - let mut view = View::new(DocumentId::default(), gutters); + let mut view = View::new(DocumentId::default(), gutters, true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("a\nb"); diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index cb743b443d79..d749b5920a25 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -69,13 +69,13 @@ pub struct DiagnosticsHandler { // but to fix that larger architecutre changes are needed impl Clone for DiagnosticsHandler { fn clone(&self) -> Self { - Self::new() + Self::new(self.active) } } impl DiagnosticsHandler { #[allow(clippy::new_without_default)] - pub fn new() -> Self { + pub fn new(enable_diagnostics: bool) -> Self { let active_generation = Arc::new(AtomicUsize::new(0)); let events = DiagnosticTimeout { active_generation: active_generation.clone(), @@ -88,7 +88,7 @@ impl DiagnosticsHandler { events, last_doc: Cell::new(DocumentId(NonZeroUsize::new(usize::MAX).unwrap())), last_cursor_line: Cell::new(usize::MAX), - active: true, + active: enable_diagnostics, } } } @@ -105,10 +105,6 @@ impl DiagnosticsHandler { .store(self.generation.get(), atomic::Ordering::Relaxed); } - pub fn toggle_active(&mut self) { - self.active = !self.active; - } - pub fn show_cursorline_diagnostics(&self, doc: &Document, view: ViewId) -> bool { if !self.active { return false; diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs index aba947a218cc..5b1ee567a6b3 100644 --- a/helix-view/src/tree.rs +++ b/helix-view/src/tree.rs @@ -736,22 +736,22 @@ mod test { width: 180, height: 80, }); - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(0, 0, 180, 80); tree.insert(view); let l0 = tree.focus; - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Vertical); let r0 = tree.focus; tree.focus = l0; - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Horizontal); let l1 = tree.focus; tree.focus = l0; - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Vertical); // Tree in test @@ -792,28 +792,28 @@ mod test { }); let doc_l0 = DocumentId::default(); - let mut view = View::new(doc_l0, GutterConfig::default()); + let mut view = View::new(doc_l0, GutterConfig::default(), true); view.area = Rect::new(0, 0, 180, 80); tree.insert(view); let l0 = tree.focus; let doc_r0 = DocumentId::default(); - let view = View::new(doc_r0, GutterConfig::default()); + let view = View::new(doc_r0, GutterConfig::default(), true); tree.split(view, Layout::Vertical); let r0 = tree.focus; tree.focus = l0; let doc_l1 = DocumentId::default(); - let view = View::new(doc_l1, GutterConfig::default()); + let view = View::new(doc_l1, GutterConfig::default(), true); tree.split(view, Layout::Horizontal); let l1 = tree.focus; tree.focus = l0; let doc_l2 = DocumentId::default(); - let view = View::new(doc_l2, GutterConfig::default()); + let view = View::new(doc_l2, GutterConfig::default(), true); tree.split(view, Layout::Vertical); let l2 = tree.focus; @@ -908,19 +908,19 @@ mod test { width: tree_area_width, height: 80, }); - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(0, 0, 180, 80); tree.insert(view); - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Vertical); - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Horizontal); tree.remove(tree.focus); - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Vertical); // Make sure that we only have one level in the tree. @@ -946,12 +946,12 @@ mod test { width: tree_area_width, height: tree_area_height, }); - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(0, 0, tree_area_width, tree_area_height); tree.insert(view); for _ in 0..9 { - let view = View::new(DocumentId::default(), GutterConfig::default()); + let view = View::new(DocumentId::default(), GutterConfig::default(), true); tree.split(view, Layout::Vertical); } diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index a229f01ea66a..98c05c5fd7a5 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -168,7 +168,7 @@ impl fmt::Debug for View { } impl View { - pub fn new(doc: DocumentId, gutters: GutterConfig) -> Self { + pub fn new(doc: DocumentId, gutters: GutterConfig, enable_diagnostics: bool) -> Self { Self { id: ViewId::default(), doc, @@ -179,7 +179,7 @@ impl View { object_selections: Vec::new(), gutters, doc_revisions: HashMap::new(), - diagnostics_handler: DiagnosticsHandler::new(), + diagnostics_handler: DiagnosticsHandler::new(enable_diagnostics), } } @@ -695,7 +695,7 @@ mod tests { #[test] fn test_text_pos_at_screen_coords() { - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); let mut doc = Document::from( @@ -870,6 +870,7 @@ mod tests { layout: vec![GutterType::Diagnostics], line_numbers: GutterLineNumbersConfig::default(), }, + true, ); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -900,6 +901,7 @@ mod tests { layout: vec![], line_numbers: GutterLineNumbersConfig::default(), }, + true, ); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -924,7 +926,7 @@ mod tests { #[test] fn test_text_pos_at_screen_coords_cjk() { - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("Hi! こんにちは皆さん"); let mut doc = Document::from( @@ -1008,7 +1010,7 @@ mod tests { #[test] fn test_text_pos_at_screen_coords_graphemes() { - let mut view = View::new(DocumentId::default(), GutterConfig::default()); + let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("Hèl̀l̀ò world!"); let mut doc = Document::from( From be3dea546896e2c71e2d4941fcddb076a0de9be0 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:57:54 +0000 Subject: [PATCH 06/10] feat: attempt at getting config option to disable diagnostics working --- helix-term/src/handlers/diagnostics.rs | 4 +++- helix-term/src/ui/editor.rs | 8 ++++++-- helix-view/src/editor.rs | 11 ++++------- helix-view/src/handlers/diagnostics.rs | 8 ++++---- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/helix-term/src/handlers/diagnostics.rs b/helix-term/src/handlers/diagnostics.rs index 3e44d416d4af..70e8ecc2a746 100644 --- a/helix-term/src/handlers/diagnostics.rs +++ b/helix-term/src/handlers/diagnostics.rs @@ -17,7 +17,9 @@ pub(super) fn register_hooks(_handlers: &Handlers) { }); register_hook!(move |event: &mut OnModeSwitch<'_, '_>| { for (view, _) in event.cx.editor.tree.views_mut() { - view.diagnostics_handler.active = event.new_mode != Mode::Insert; + view.diagnostics_handler + .active + .set(event.new_mode != Mode::Insert); } Ok(()) }); diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index b6a56cafa585..13f2c5d54aa9 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -191,7 +191,11 @@ impl EditorView { } let config = doc.config.load(); - if editor.config().enable_diagnostics { + // view.diagnostics_handler + // .active + // .set(config.enable_diagnostics); + + if config.enable_diagnostics { let width = view.inner_width(doc); let enable_cursor_line = view .diagnostics_handler @@ -235,7 +239,7 @@ impl EditorView { if config.inline_diagnostics.disabled() && config.end_of_line_diagnostics == DiagnosticFilter::Disable - && editor.config().enable_diagnostics + && config.enable_diagnostics { Self::render_diagnostics(doc, view, inner, surface, theme); } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 74558daa7dc2..353f0bf71e07 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1649,18 +1649,15 @@ impl Editor { } Action::HorizontalSplit | Action::VerticalSplit => { // copy the current view, unless there is no view yet + let config = self.config(); + let gutters = config.gutters.clone(); + let enable_diagnostics = config.enable_diagnostics; let view = self .tree .try_get(self.tree.focus) .filter(|v| id == v.doc) // Different Document .cloned() - .unwrap_or_else(|| { - View::new( - id, - self.config().gutters.clone(), - self.config().enable_diagnostics, - ) - }); + .unwrap_or_else(|| View::new(id, gutters, enable_diagnostics)); let view_id = self.tree.split( view, match action { diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index d749b5920a25..b22e04dc616b 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -59,7 +59,7 @@ pub struct DiagnosticsHandler { generation: Cell, last_doc: Cell, last_cursor_line: Cell, - pub active: bool, + pub active: Cell, pub events: Sender, } @@ -69,7 +69,7 @@ pub struct DiagnosticsHandler { // but to fix that larger architecutre changes are needed impl Clone for DiagnosticsHandler { fn clone(&self) -> Self { - Self::new(self.active) + Self::new(self.active.take()) } } @@ -88,7 +88,7 @@ impl DiagnosticsHandler { events, last_doc: Cell::new(DocumentId(NonZeroUsize::new(usize::MAX).unwrap())), last_cursor_line: Cell::new(usize::MAX), - active: enable_diagnostics, + active: true, } } } @@ -106,7 +106,7 @@ impl DiagnosticsHandler { } pub fn show_cursorline_diagnostics(&self, doc: &Document, view: ViewId) -> bool { - if !self.active { + if !self.active.take() { return false; } let cursor_line = doc From 069ca339a67cb770912c512d1a909dd4243feca9 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:18:17 +0000 Subject: [PATCH 07/10] feat: complete implementation for toggle diagnostics option --- book/src/editor.md | 1 + book/src/generated/typable-cmd.md | 1 - helix-term/src/ui/editor.rs | 6 +----- helix-view/src/handlers/diagnostics.rs | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/book/src/editor.md b/book/src/editor.md index 624bdff23d37..d7b023e43890 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -53,6 +53,7 @@ | `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` | | `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid` | `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"` +| `enable-diagnostics` | Whether to show obtrusive diagnostics, such as inline diagnostics and overlay diagnostics | `true` | | `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable" | `clipboard-provider` | Which API to use for clipboard interaction. One of `pasteboard` (MacOS), `wayland`, `x-clip`, `x-sel`, `win-32-yank`, `termux`, `tmux`, `windows`, `termcode`, `none`, or a custom command set. | Platform and environment specific. | diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 24bb8d7e7d81..f0d9a0f492a5 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -88,4 +88,3 @@ | `:move`, `:mv` | Move the current buffer and its corresponding file to a different path | | `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default | | `:read`, `:r` | Load a file into buffer | -| `:toggle-diagnostics`, `:td` | Toggle Diagnostics | diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 13f2c5d54aa9..ebf57a2acd86 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -189,11 +189,8 @@ impl EditorView { primary_cursor, }); } - let config = doc.config.load(); - // view.diagnostics_handler - // .active - // .set(config.enable_diagnostics); + let config = doc.config.load(); if config.enable_diagnostics { let width = view.inner_width(doc); @@ -202,7 +199,6 @@ impl EditorView { .show_cursorline_diagnostics(doc, view.id); let inline_diagnostic_config = config.inline_diagnostics.prepare(width, enable_cursor_line); - decorations.add_decoration(InlineDiagnostics::new( doc, theme, diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index b22e04dc616b..e582197db7d5 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -106,7 +106,7 @@ impl DiagnosticsHandler { } pub fn show_cursorline_diagnostics(&self, doc: &Document, view: ViewId) -> bool { - if !self.active.take() { + if !self.active || !doc.config.load().enable_diagnostics { return false; } let cursor_line = doc From 2b28ce94be5442092958dddad0a8d457a5706bf4 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:23:59 +0000 Subject: [PATCH 08/10] fix: do not use a Cell for self.active --- helix-term/src/handlers/diagnostics.rs | 4 +--- helix-view/src/handlers/diagnostics.rs | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/helix-term/src/handlers/diagnostics.rs b/helix-term/src/handlers/diagnostics.rs index 70e8ecc2a746..3e44d416d4af 100644 --- a/helix-term/src/handlers/diagnostics.rs +++ b/helix-term/src/handlers/diagnostics.rs @@ -17,9 +17,7 @@ pub(super) fn register_hooks(_handlers: &Handlers) { }); register_hook!(move |event: &mut OnModeSwitch<'_, '_>| { for (view, _) in event.cx.editor.tree.views_mut() { - view.diagnostics_handler - .active - .set(event.new_mode != Mode::Insert); + view.diagnostics_handler.active = event.new_mode != Mode::Insert; } Ok(()) }); diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index e582197db7d5..ebf4e4faa544 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -59,7 +59,7 @@ pub struct DiagnosticsHandler { generation: Cell, last_doc: Cell, last_cursor_line: Cell, - pub active: Cell, + pub active: bool, pub events: Sender, } @@ -69,7 +69,7 @@ pub struct DiagnosticsHandler { // but to fix that larger architecutre changes are needed impl Clone for DiagnosticsHandler { fn clone(&self) -> Self { - Self::new(self.active.take()) + Self::new(self.active) } } From 4b5da9e667a53784d0365e018b7807166a08341d Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:27:52 +0000 Subject: [PATCH 09/10] fix: do not pass extra argument --- helix-view/src/editor.rs | 11 ++-------- helix-view/src/gutter.rs | 8 ++++---- helix-view/src/handlers/diagnostics.rs | 4 ++-- helix-view/src/tree.rs | 28 +++++++++++++------------- helix-view/src/view.rs | 12 +++++------ 5 files changed, 27 insertions(+), 36 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 353f0bf71e07..ed0c175ebdad 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1649,15 +1649,12 @@ impl Editor { } Action::HorizontalSplit | Action::VerticalSplit => { // copy the current view, unless there is no view yet - let config = self.config(); - let gutters = config.gutters.clone(); - let enable_diagnostics = config.enable_diagnostics; let view = self .tree .try_get(self.tree.focus) .filter(|v| id == v.doc) // Different Document .cloned() - .unwrap_or_else(|| View::new(id, gutters, enable_diagnostics)); + .unwrap_or_else(|| View::new(id, self.config().gutters.clone())); let view_id = self.tree.split( view, match action { @@ -1831,11 +1828,7 @@ impl Editor { .map(|(&doc_id, _)| doc_id) .next() .unwrap_or_else(|| self.new_document(Document::default(self.config.clone()))); - let view = View::new( - doc_id, - self.config().gutters.clone(), - self.config().enable_diagnostics, - ); + let view = View::new(doc_id, self.config().gutters.clone()); let view_id = self.tree.insert(view); let doc = doc_mut!(self, &doc_id); doc.ensure_view_init(view_id); diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs index 3466f86858c2..36f719f795a8 100644 --- a/helix-view/src/gutter.rs +++ b/helix-view/src/gutter.rs @@ -346,7 +346,7 @@ mod tests { #[test] fn test_default_gutter_widths() { - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -371,7 +371,7 @@ mod tests { ..Default::default() }; - let mut view = View::new(DocumentId::default(), gutters, true); + let mut view = View::new(DocumentId::default(), gutters); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -389,7 +389,7 @@ mod tests { line_numbers: GutterLineNumbersConfig { min_width: 10 }, }; - let mut view = View::new(DocumentId::default(), gutters, true); + let mut view = View::new(DocumentId::default(), gutters); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -411,7 +411,7 @@ mod tests { line_numbers: GutterLineNumbersConfig { min_width: 1 }, }; - let mut view = View::new(DocumentId::default(), gutters, true); + let mut view = View::new(DocumentId::default(), gutters); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("a\nb"); diff --git a/helix-view/src/handlers/diagnostics.rs b/helix-view/src/handlers/diagnostics.rs index ebf4e4faa544..ed6a8b98dc03 100644 --- a/helix-view/src/handlers/diagnostics.rs +++ b/helix-view/src/handlers/diagnostics.rs @@ -69,13 +69,13 @@ pub struct DiagnosticsHandler { // but to fix that larger architecutre changes are needed impl Clone for DiagnosticsHandler { fn clone(&self) -> Self { - Self::new(self.active) + Self::new() } } impl DiagnosticsHandler { #[allow(clippy::new_without_default)] - pub fn new(enable_diagnostics: bool) -> Self { + pub fn new() -> Self { let active_generation = Arc::new(AtomicUsize::new(0)); let events = DiagnosticTimeout { active_generation: active_generation.clone(), diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs index 5b1ee567a6b3..aba947a218cc 100644 --- a/helix-view/src/tree.rs +++ b/helix-view/src/tree.rs @@ -736,22 +736,22 @@ mod test { width: 180, height: 80, }); - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(0, 0, 180, 80); tree.insert(view); let l0 = tree.focus; - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Vertical); let r0 = tree.focus; tree.focus = l0; - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Horizontal); let l1 = tree.focus; tree.focus = l0; - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Vertical); // Tree in test @@ -792,28 +792,28 @@ mod test { }); let doc_l0 = DocumentId::default(); - let mut view = View::new(doc_l0, GutterConfig::default(), true); + let mut view = View::new(doc_l0, GutterConfig::default()); view.area = Rect::new(0, 0, 180, 80); tree.insert(view); let l0 = tree.focus; let doc_r0 = DocumentId::default(); - let view = View::new(doc_r0, GutterConfig::default(), true); + let view = View::new(doc_r0, GutterConfig::default()); tree.split(view, Layout::Vertical); let r0 = tree.focus; tree.focus = l0; let doc_l1 = DocumentId::default(); - let view = View::new(doc_l1, GutterConfig::default(), true); + let view = View::new(doc_l1, GutterConfig::default()); tree.split(view, Layout::Horizontal); let l1 = tree.focus; tree.focus = l0; let doc_l2 = DocumentId::default(); - let view = View::new(doc_l2, GutterConfig::default(), true); + let view = View::new(doc_l2, GutterConfig::default()); tree.split(view, Layout::Vertical); let l2 = tree.focus; @@ -908,19 +908,19 @@ mod test { width: tree_area_width, height: 80, }); - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(0, 0, 180, 80); tree.insert(view); - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Vertical); - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Horizontal); tree.remove(tree.focus); - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Vertical); // Make sure that we only have one level in the tree. @@ -946,12 +946,12 @@ mod test { width: tree_area_width, height: tree_area_height, }); - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(0, 0, tree_area_width, tree_area_height); tree.insert(view); for _ in 0..9 { - let view = View::new(DocumentId::default(), GutterConfig::default(), true); + let view = View::new(DocumentId::default(), GutterConfig::default()); tree.split(view, Layout::Vertical); } diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 98c05c5fd7a5..a229f01ea66a 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -168,7 +168,7 @@ impl fmt::Debug for View { } impl View { - pub fn new(doc: DocumentId, gutters: GutterConfig, enable_diagnostics: bool) -> Self { + pub fn new(doc: DocumentId, gutters: GutterConfig) -> Self { Self { id: ViewId::default(), doc, @@ -179,7 +179,7 @@ impl View { object_selections: Vec::new(), gutters, doc_revisions: HashMap::new(), - diagnostics_handler: DiagnosticsHandler::new(enable_diagnostics), + diagnostics_handler: DiagnosticsHandler::new(), } } @@ -695,7 +695,7 @@ mod tests { #[test] fn test_text_pos_at_screen_coords() { - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); let mut doc = Document::from( @@ -870,7 +870,6 @@ mod tests { layout: vec![GutterType::Diagnostics], line_numbers: GutterLineNumbersConfig::default(), }, - true, ); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -901,7 +900,6 @@ mod tests { layout: vec![], line_numbers: GutterLineNumbersConfig::default(), }, - true, ); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); @@ -926,7 +924,7 @@ mod tests { #[test] fn test_text_pos_at_screen_coords_cjk() { - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("Hi! こんにちは皆さん"); let mut doc = Document::from( @@ -1010,7 +1008,7 @@ mod tests { #[test] fn test_text_pos_at_screen_coords_graphemes() { - let mut view = View::new(DocumentId::default(), GutterConfig::default(), true); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("Hèl̀l̀ò world!"); let mut doc = Document::from( From 9bf32621523ecd727ce407cb616bb3d0f73d855c Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:55:43 +0000 Subject: [PATCH 10/10] refactor: evaluate enable_diagnostics first --- book/src/editor.md | 2 +- helix-term/src/ui/editor.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/book/src/editor.md b/book/src/editor.md index d7b023e43890..54de3df950c8 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -53,7 +53,7 @@ | `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` | | `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid` | `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"` -| `enable-diagnostics` | Whether to show obtrusive diagnostics, such as inline diagnostics and overlay diagnostics | `true` | +| `enable-diagnostics` | Whether to show diagnostics, such as inline diagnostics and overlay diagnostics | `true` | | `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable" | `clipboard-provider` | Which API to use for clipboard interaction. One of `pasteboard` (MacOS), `wayland`, `x-clip`, `x-sel`, `win-32-yank`, `termux`, `tmux`, `windows`, `termcode`, `none`, or a custom command set. | Platform and environment specific. | diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index ebf57a2acd86..fb64f1f78660 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -233,9 +233,9 @@ impl EditorView { } } - if config.inline_diagnostics.disabled() + if config.enable_diagnostics + && config.inline_diagnostics.disabled() && config.end_of_line_diagnostics == DiagnosticFilter::Disable - && config.enable_diagnostics { Self::render_diagnostics(doc, view, inner, surface, theme); }