From 216a275ef24a26175ae49b4bd829cf6dd7411308 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 16 Jun 2022 14:20:09 -0700 Subject: [PATCH] Disable auto-indent entirely for markdown --- crates/editor/src/editor.rs | 44 ++++++++++++----------- crates/language/src/buffer.rs | 60 ++++++++++++++++--------------- crates/language/src/language.rs | 63 +++++++++++++++------------------ crates/language/src/tests.rs | 41 +++++++++++++++++++++ 4 files changed, 125 insertions(+), 83 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 7e5066f693..8a1cf4afd8 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -9810,26 +9810,30 @@ mod tests { #[gpui::test] async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) { cx.update(|cx| cx.set_global(Settings::test(cx))); - let language = Arc::new(Language::new( - LanguageConfig { - brackets: vec![ - BracketPair { - start: "{".to_string(), - end: "}".to_string(), - close: true, - newline: true, - }, - BracketPair { - start: "/* ".to_string(), - end: " */".to_string(), - close: true, - newline: true, - }, - ], - ..Default::default() - }, - Some(tree_sitter_rust::language()), - )); + let language = Arc::new( + Language::new( + LanguageConfig { + brackets: vec![ + BracketPair { + start: "{".to_string(), + end: "}".to_string(), + close: true, + newline: true, + }, + BracketPair { + start: "/* ".to_string(), + end: " */".to_string(), + close: true, + newline: true, + }, + ], + ..Default::default() + }, + Some(tree_sitter_rust::language()), + ) + .with_indents_query("") + .unwrap(), + ); let text = concat!( "{ }\n", // Suppress rustfmt diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index f6725a202f..46a658729a 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -1523,16 +1523,17 @@ impl BufferSnapshot { // Get the "indentation ranges" that intersect this row range. let grammar = self.grammar()?; let prev_non_blank_row = self.prev_non_blank_row(row_range.start); + let indents_query = grammar.indents_query.as_ref()?; let mut query_cursor = QueryCursorHandle::new(); - let indent_capture_ix = grammar.indents_query.capture_index_for_name("indent"); - let end_capture_ix = grammar.indents_query.capture_index_for_name("end"); + let indent_capture_ix = indents_query.capture_index_for_name("indent"); + let end_capture_ix = indents_query.capture_index_for_name("end"); query_cursor.set_point_range( Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0).to_ts_point() ..Point::new(row_range.end, 0).to_ts_point(), ); let mut indentation_ranges = Vec::>::new(); for mat in query_cursor.matches( - &grammar.indents_query, + indents_query, self.tree.as_ref()?.root_node(), TextProvider(self.as_rope()), ) { @@ -1787,20 +1788,20 @@ impl BufferSnapshot { .as_ref() .and_then(|language| language.grammar.as_ref())?; + let outline_query = grammar.outline_query.as_ref()?; let mut cursor = QueryCursorHandle::new(); cursor.set_byte_range(range.clone()); let matches = cursor.matches( - &grammar.outline_query, + outline_query, tree.root_node(), TextProvider(self.as_rope()), ); let mut chunks = self.chunks(0..self.len(), true); - let item_capture_ix = grammar.outline_query.capture_index_for_name("item")?; - let name_capture_ix = grammar.outline_query.capture_index_for_name("name")?; - let context_capture_ix = grammar - .outline_query + let item_capture_ix = outline_query.capture_index_for_name("item")?; + let name_capture_ix = outline_query.capture_index_for_name("name")?; + let context_capture_ix = outline_query .capture_index_for_name("context") .unwrap_or(u32::MAX); @@ -1892,14 +1893,15 @@ impl BufferSnapshot { range: Range, ) -> Option<(Range, Range)> { let (grammar, tree) = self.grammar().zip(self.tree.as_ref())?; - let open_capture_ix = grammar.brackets_query.capture_index_for_name("open")?; - let close_capture_ix = grammar.brackets_query.capture_index_for_name("close")?; + let brackets_query = grammar.brackets_query.as_ref()?; + let open_capture_ix = brackets_query.capture_index_for_name("open")?; + let close_capture_ix = brackets_query.capture_index_for_name("close")?; // Find bracket pairs that *inclusively* contain the given range. let range = range.start.to_offset(self).saturating_sub(1)..range.end.to_offset(self) + 1; let mut cursor = QueryCursorHandle::new(); let matches = cursor.set_byte_range(range).matches( - &grammar.brackets_query, + &brackets_query, tree.root_node(), TextProvider(self.as_rope()), ); @@ -2071,24 +2073,26 @@ impl<'a> BufferChunks<'a> { ) -> Self { let mut highlights = None; if let Some((grammar, tree)) = grammar.zip(tree) { - let mut query_cursor = QueryCursorHandle::new(); + if let Some(highlights_query) = grammar.highlights_query.as_ref() { + let mut query_cursor = QueryCursorHandle::new(); - // TODO - add a Tree-sitter API to remove the need for this. - let cursor = unsafe { - std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut()) - }; - let captures = cursor.set_byte_range(range.clone()).captures( - &grammar.highlights_query, - tree.root_node(), - TextProvider(text), - ); - highlights = Some(BufferChunkHighlights { - captures, - next_capture: None, - stack: Default::default(), - highlight_map: grammar.highlight_map(), - _query_cursor: query_cursor, - }) + // TODO - add a Tree-sitter API to remove the need for this. + let cursor = unsafe { + std::mem::transmute::<_, &'static mut QueryCursor>(query_cursor.deref_mut()) + }; + let captures = cursor.set_byte_range(range.clone()).captures( + highlights_query, + tree.root_node(), + TextProvider(text), + ); + highlights = Some(BufferChunkHighlights { + captures, + next_capture: None, + stack: Default::default(), + highlight_map: grammar.highlight_map(), + _query_cursor: query_cursor, + }) + } } let diagnostic_endpoints = diagnostic_endpoints.into_iter().peekable(); diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 4ceff80c7a..3e175d231a 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -171,10 +171,10 @@ pub struct Language { pub struct Grammar { pub(crate) ts_language: tree_sitter::Language, - pub(crate) highlights_query: Query, - pub(crate) brackets_query: Query, - pub(crate) indents_query: Query, - pub(crate) outline_query: Query, + pub(crate) highlights_query: Option, + pub(crate) brackets_query: Option, + pub(crate) indents_query: Option, + pub(crate) outline_query: Option, pub(crate) highlight_map: Mutex, } @@ -437,10 +437,10 @@ impl Language { config, grammar: ts_language.map(|ts_language| { Arc::new(Grammar { - brackets_query: Query::new(ts_language, "").unwrap(), - highlights_query: Query::new(ts_language, "").unwrap(), - indents_query: Query::new(ts_language, "").unwrap(), - outline_query: Query::new(ts_language, "").unwrap(), + highlights_query: None, + brackets_query: None, + indents_query: None, + outline_query: None, ts_language, highlight_map: Default::default(), }) @@ -457,45 +457,33 @@ impl Language { } pub fn with_highlights_query(mut self, source: &str) -> Result { - let grammar = self - .grammar - .as_mut() - .and_then(Arc::get_mut) - .ok_or_else(|| anyhow!("grammar does not exist or is already being used"))?; - grammar.highlights_query = Query::new(grammar.ts_language, source)?; + let grammar = self.grammar_mut(); + grammar.highlights_query = Some(Query::new(grammar.ts_language, source)?); Ok(self) } pub fn with_brackets_query(mut self, source: &str) -> Result { - let grammar = self - .grammar - .as_mut() - .and_then(Arc::get_mut) - .ok_or_else(|| anyhow!("grammar does not exist or is already being used"))?; - grammar.brackets_query = Query::new(grammar.ts_language, source)?; + let grammar = self.grammar_mut(); + grammar.brackets_query = Some(Query::new(grammar.ts_language, source)?); Ok(self) } pub fn with_indents_query(mut self, source: &str) -> Result { - let grammar = self - .grammar - .as_mut() - .and_then(Arc::get_mut) - .ok_or_else(|| anyhow!("grammar does not exist or is already being used"))?; - grammar.indents_query = Query::new(grammar.ts_language, source)?; + let grammar = self.grammar_mut(); + grammar.indents_query = Some(Query::new(grammar.ts_language, source)?); Ok(self) } pub fn with_outline_query(mut self, source: &str) -> Result { - let grammar = self - .grammar - .as_mut() - .and_then(Arc::get_mut) - .ok_or_else(|| anyhow!("grammar does not exist or is already being used"))?; - grammar.outline_query = Query::new(grammar.ts_language, source)?; + let grammar = self.grammar_mut(); + grammar.outline_query = Some(Query::new(grammar.ts_language, source)?); Ok(self) } + fn grammar_mut(&mut self) -> &mut Grammar { + Arc::get_mut(self.grammar.as_mut().unwrap()).unwrap() + } + pub fn with_lsp_adapter(mut self, lsp_adapter: Arc) -> Self { self.adapter = Some(lsp_adapter); self @@ -586,8 +574,10 @@ impl Language { pub fn set_theme(&self, theme: &SyntaxTheme) { if let Some(grammar) = self.grammar.as_ref() { - *grammar.highlight_map.lock() = - HighlightMap::new(grammar.highlights_query.capture_names(), theme); + if let Some(highlights_query) = &grammar.highlights_query { + *grammar.highlight_map.lock() = + HighlightMap::new(highlights_query.capture_names(), theme); + } } } @@ -621,7 +611,10 @@ impl Grammar { } pub fn highlight_id_for_name(&self, name: &str) -> Option { - let capture_id = self.highlights_query.capture_index_for_name(name)?; + let capture_id = self + .highlights_query + .as_ref()? + .capture_index_for_name(name)?; Some(self.highlight_map.lock().get(capture_id)) } } diff --git a/crates/language/src/tests.rs b/crates/language/src/tests.rs index 1cee723d12..8b3ba0e8b7 100644 --- a/crates/language/src/tests.rs +++ b/crates/language/src/tests.rs @@ -784,6 +784,47 @@ fn test_autoindent_with_edit_at_end_of_buffer(cx: &mut MutableAppContext) { }); } +#[gpui::test] +fn test_autoindent_disabled(cx: &mut MutableAppContext) { + cx.add_model(|cx| { + let text = " + * one + - a + - b + * two + " + .unindent(); + + let mut buffer = Buffer::new(0, text, cx).with_language( + Arc::new(Language::new( + LanguageConfig { + name: "Markdown".into(), + ..Default::default() + }, + Some(tree_sitter_json::language()), + )), + cx, + ); + buffer.edit_with_autoindent( + [(Point::new(3, 0)..Point::new(3, 0), "\n")], + IndentSize::spaces(4), + cx, + ); + assert_eq!( + buffer.text(), + " + * one + - a + - b + + * two + " + .unindent() + ); + buffer + }); +} + #[gpui::test] fn test_serialization(cx: &mut gpui::MutableAppContext) { let mut now = Instant::now();