From 1315b7e2b17bbb87a3dfa2c58484856b5fbaf99e Mon Sep 17 00:00:00 2001 From: yuri <164520341+yohaneYuri@users.noreply.github.com> Date: Sat, 14 Jun 2025 00:09:21 +0800 Subject: [PATCH] Feat: inlay hint length limit (#13742) --- book/src/editor.md | 1 + helix-term/src/commands/lsp.rs | 28 +++++++++++++++++++++++++++- helix-view/src/editor.rs | 6 +++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/book/src/editor.md b/book/src/editor.md index 00db71d27..667a7147c 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -157,6 +157,7 @@ The following statusline elements can be configured: | `display-progress-messages` | Display LSP progress messages below statusline[^1] | `false` | | `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` | | `display-inlay-hints` | Display inlay hints[^2] | `false` | +| `inlay-hints-length-limit` | Maximum displayed length (non-zero number) of inlay hints | Unset by default | | `display-color-swatches` | Show color swatches next to colors | `true` | | `display-signature-help-docs` | Display docs under signature help popup | `true` | | `snippets` | Enables snippet completions. Requires a server restart (`:lsp-restart`) to take effect after `:config-reload`/`:set`. | `true` | diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 9c55c830c..99a6d62f9 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -1357,6 +1357,7 @@ fn compute_inlay_hints_for_view( let mut padding_after_inlay_hints = Vec::new(); let doc_text = doc.text(); + let inlay_hints_length_limit = doc.config.load().lsp.inlay_hints_length_limit; for hint in hints { let char_idx = @@ -1367,7 +1368,7 @@ fn compute_inlay_hints_for_view( None => continue, }; - let label = match hint.label { + let mut label = match hint.label { lsp::InlayHintLabel::String(s) => s, lsp::InlayHintLabel::LabelParts(parts) => parts .into_iter() @@ -1375,6 +1376,31 @@ fn compute_inlay_hints_for_view( .collect::>() .join(""), }; + // Truncate the hint if too long + if let Some(limit) = inlay_hints_length_limit { + // Limit on displayed width + use helix_core::unicode::{ + segmentation::UnicodeSegmentation, width::UnicodeWidthStr, + }; + + let width = label.width(); + let limit = limit.get().into(); + if width > limit { + let mut floor_boundary = 0; + let mut acc = 0; + for (i, grapheme_cluster) in label.grapheme_indices(true) { + acc += grapheme_cluster.width(); + + if acc > limit { + floor_boundary = i; + break; + } + } + + label.truncate(floor_boundary); + label.push('…'); + } + } let inlay_hints_vec = match hint.kind { Some(lsp::InlayHintKind::TYPE) => &mut type_inlay_hints, diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index bc811b88b..cb9586e79 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -29,7 +29,7 @@ use std::{ collections::{BTreeMap, HashMap, HashSet}, fs, io::{self, stdin}, - num::NonZeroUsize, + num::{NonZeroU8, NonZeroUsize}, path::{Path, PathBuf}, pin::Pin, sync::Arc, @@ -459,6 +459,9 @@ pub struct LspConfig { pub display_signature_help_docs: bool, /// Display inlay hints pub display_inlay_hints: bool, + /// Maximum displayed length of inlay hints (excluding the added trailing `…`). + /// If it's `None`, there's no limit + pub inlay_hints_length_limit: Option, /// Display document color swatches pub display_color_swatches: bool, /// Whether to enable snippet support @@ -476,6 +479,7 @@ impl Default for LspConfig { auto_signature_help: true, display_signature_help_docs: true, display_inlay_hints: false, + inlay_hints_length_limit: None, snippets: true, goto_reference_include_declaration: true, display_color_swatches: true,