Unnamed repository; edit this file 'description' to name the repository.
snippets: Discard placeholder text for the `$0` tabstop
| -rw-r--r-- | helix-core/src/snippets/active.rs | 17 | ||||
| -rw-r--r-- | helix-core/src/snippets/elaborate.rs | 9 |
2 files changed, 25 insertions, 1 deletions
diff --git a/helix-core/src/snippets/active.rs b/helix-core/src/snippets/active.rs index c5c743cd..98007ab6 100644 --- a/helix-core/src/snippets/active.rs +++ b/helix-core/src/snippets/active.rs @@ -252,4 +252,21 @@ mod tests { snippet.map(edit.changes()); assert!(!snippet.is_valid(&Selection::point(4))) } + + #[test] + fn tabstop_zero_with_placeholder() { + // The `$0` tabstop should not have placeholder text. When we receive a snippet like this + // (from older versions of clangd for example) we should discard the placeholder text. + let snippet = Snippet::parse("sizeof(${0:expression-or-type})").unwrap(); + let mut doc = Rope::from("\n"); + let (transaction, _, snippet) = snippet.render( + &doc, + &Selection::point(0), + |_| (0, 0), + &mut SnippetRenderCtx::test_ctx(), + ); + assert!(transaction.apply(&mut doc)); + assert_eq!(doc, "sizeof()\n"); + assert!(ActiveSnippet::new(snippet).is_none()); + } } diff --git a/helix-core/src/snippets/elaborate.rs b/helix-core/src/snippets/elaborate.rs index 0fb5fb7b..012d1db7 100644 --- a/helix-core/src/snippets/elaborate.rs +++ b/helix-core/src/snippets/elaborate.rs @@ -178,9 +178,16 @@ impl Snippet { &mut self, idx: usize, parent: Option<TabstopIdx>, - default: Vec<parser::SnippetElement>, + mut default: Vec<parser::SnippetElement>, ) -> TabstopIdx { let idx = TabstopIdx::elaborate(idx); + if idx == LAST_TABSTOP_IDX && !default.is_empty() { + // Older versions of clangd for example may send a snippet like `${0:placeholder}` + // which is considered by VSCode to be a misuse of the `$0` tabstop. + log::warn!("Discarding placeholder text for the `$0` tabstop ({default:?}). \ + The `$0` tabstop signifies the final cursor position and should not include placeholder text."); + default.clear(); + } let default = self.elaborate(default, Some(idx)); self.tabstops.push(Tabstop { idx, |