Restructure how bracket pairs are overridden to unify lists

Max Brunsfeld created

This way, a bracket pair that is disabled in a given scope can still be skipped, if
it was auto-closed before that scope existed.

Change summary

crates/editor/src/editor.rs                     |   8 
crates/editor/src/editor_tests.rs               | 261 ++++++++++--------
crates/editor/src/highlight_matching_bracket.rs |  36 +-
crates/language/src/buffer_tests.rs             |  80 +++--
crates/language/src/language.rs                 | 106 ++++++-
crates/zed/src/languages/c/config.toml          |  20 -
crates/zed/src/languages/cpp/config.toml        |  20 -
crates/zed/src/languages/css/config.toml        |  18 -
crates/zed/src/languages/elixir/config.toml     |  18 -
crates/zed/src/languages/go/config.toml         |  20 -
crates/zed/src/languages/html/config.toml       |  20 -
crates/zed/src/languages/javascript/config.toml |  24 -
crates/zed/src/languages/json/config.toml       |   8 
crates/zed/src/languages/lua/config.toml        |  12 
crates/zed/src/languages/python/config.toml     |  24 -
crates/zed/src/languages/ruby/config.toml       |  18 -
crates/zed/src/languages/rust/config.toml       |  23 -
crates/zed/src/languages/scheme/config.toml     |  14 
crates/zed/src/languages/toml/config.toml       |  16 -
crates/zed/src/languages/tsx/config.toml        |  15 
crates/zed/src/languages/typescript/config.toml |  24 -
crates/zed/src/languages/yaml/config.toml       |   8 
22 files changed, 340 insertions(+), 453 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -1761,8 +1761,8 @@ impl Editor {
                 // bracket of any of this language's bracket pairs.
                 let mut bracket_pair = None;
                 let mut is_bracket_pair_start = false;
-                for pair in language.brackets() {
-                    if pair.close && pair.start.ends_with(text.as_ref()) {
+                for (pair, enabled) in language.brackets() {
+                    if enabled && pair.close && pair.start.ends_with(text.as_ref()) {
                         bracket_pair = Some(pair.clone());
                         is_bracket_pair_start = true;
                         break;
@@ -1930,11 +1930,11 @@ impl Editor {
                                 .map(|c| c.len_utf8())
                                 .sum::<usize>();
 
-                            insert_extra_newline = language.brackets().iter().any(|pair| {
+                            insert_extra_newline = language.brackets().any(|(pair, enabled)| {
                                 let pair_start = pair.start.trim_end();
                                 let pair_end = pair.end.trim_start();
 
-                                pair.newline
+                                enabled && pair.newline
                                     && buffer
                                         .contains_str_at(end + trailing_whitespace_len, pair_end)
                                     && buffer.contains_str_at(

crates/editor/src/editor_tests.rs 🔗

@@ -14,7 +14,7 @@ use gpui::{
     geometry::{rect::RectF, vector::vec2f},
     platform::{WindowBounds, WindowOptions},
 };
-use language::{FakeLspAdapter, LanguageConfig, LanguageRegistry, Point};
+use language::{BracketPairConfig, FakeLspAdapter, LanguageConfig, LanguageRegistry, Point};
 use project::FakeFs;
 use settings::EditorSettings;
 use util::{
@@ -3002,20 +3002,23 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) {
     let language = Arc::new(
         Language::new(
             LanguageConfig {
-                brackets: vec![
-                    BracketPair {
-                        start: "{".to_string(),
-                        end: "}".to_string(),
-                        close: false,
-                        newline: true,
-                    },
-                    BracketPair {
-                        start: "(".to_string(),
-                        end: ")".to_string(),
-                        close: false,
-                        newline: true,
-                    },
-                ],
+                brackets: BracketPairConfig {
+                    pairs: vec![
+                        BracketPair {
+                            start: "{".to_string(),
+                            end: "}".to_string(),
+                            close: false,
+                            newline: true,
+                        },
+                        BracketPair {
+                            start: "(".to_string(),
+                            end: ")".to_string(),
+                            close: false,
+                            newline: true,
+                        },
+                    ],
+                    ..Default::default()
+                },
                 ..Default::default()
             },
             Some(tree_sitter_rust::language()),
@@ -3059,38 +3062,41 @@ async fn test_autoclose_pairs(cx: &mut gpui::TestAppContext) {
 
     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,
-                },
-                BracketPair {
-                    start: "/*".to_string(),
-                    end: " */".to_string(),
-                    close: true,
-                    newline: true,
-                },
-                BracketPair {
-                    start: "[".to_string(),
-                    end: "]".to_string(),
-                    close: false,
-                    newline: true,
-                },
-                BracketPair {
-                    start: "\"".to_string(),
-                    end: "\"".to_string(),
-                    close: true,
-                    newline: false,
-                },
-            ],
+            brackets: BracketPairConfig {
+                pairs: vec![
+                    BracketPair {
+                        start: "{".to_string(),
+                        end: "}".to_string(),
+                        close: true,
+                        newline: true,
+                    },
+                    BracketPair {
+                        start: "(".to_string(),
+                        end: ")".to_string(),
+                        close: true,
+                        newline: true,
+                    },
+                    BracketPair {
+                        start: "/*".to_string(),
+                        end: " */".to_string(),
+                        close: true,
+                        newline: true,
+                    },
+                    BracketPair {
+                        start: "[".to_string(),
+                        end: "]".to_string(),
+                        close: false,
+                        newline: true,
+                    },
+                    BracketPair {
+                        start: "\"".to_string(),
+                        end: "\"".to_string(),
+                        close: true,
+                        newline: false,
+                    },
+                ],
+                ..Default::default()
+            },
             autoclose_before: "})]".to_string(),
             ..Default::default()
         },
@@ -3227,10 +3233,52 @@ async fn test_autoclose_with_embedded_language(cx: &mut gpui::TestAppContext) {
         Language::new(
             LanguageConfig {
                 name: "HTML".into(),
-                brackets: vec![
+                brackets: BracketPairConfig {
+                    pairs: vec![
+                        BracketPair {
+                            start: "<".into(),
+                            end: ">".into(),
+                            close: true,
+                            ..Default::default()
+                        },
+                        BracketPair {
+                            start: "{".into(),
+                            end: "}".into(),
+                            close: true,
+                            ..Default::default()
+                        },
+                        BracketPair {
+                            start: "(".into(),
+                            end: ")".into(),
+                            close: true,
+                            ..Default::default()
+                        },
+                    ],
+                    ..Default::default()
+                },
+                autoclose_before: "})]>".into(),
+                ..Default::default()
+            },
+            Some(tree_sitter_html::language()),
+        )
+        .with_injection_query(
+            r#"
+            (script_element
+                (raw_text) @content
+                (#set! "language" "javascript"))
+            "#,
+        )
+        .unwrap(),
+    );
+
+    let javascript_language = Arc::new(Language::new(
+        LanguageConfig {
+            name: "JavaScript".into(),
+            brackets: BracketPairConfig {
+                pairs: vec![
                     BracketPair {
-                        start: "<".into(),
-                        end: ">".into(),
+                        start: "/*".into(),
+                        end: " */".into(),
                         close: true,
                         ..Default::default()
                     },
@@ -3247,44 +3295,8 @@ async fn test_autoclose_with_embedded_language(cx: &mut gpui::TestAppContext) {
                         ..Default::default()
                     },
                 ],
-                autoclose_before: "})]>".into(),
                 ..Default::default()
             },
-            Some(tree_sitter_html::language()),
-        )
-        .with_injection_query(
-            r#"
-            (script_element
-                (raw_text) @content
-                (#set! "language" "javascript"))
-            "#,
-        )
-        .unwrap(),
-    );
-
-    let javascript_language = Arc::new(Language::new(
-        LanguageConfig {
-            name: "JavaScript".into(),
-            brackets: vec![
-                BracketPair {
-                    start: "/*".into(),
-                    end: " */".into(),
-                    close: true,
-                    ..Default::default()
-                },
-                BracketPair {
-                    start: "{".into(),
-                    end: "}".into(),
-                    close: true,
-                    ..Default::default()
-                },
-                BracketPair {
-                    start: "(".into(),
-                    end: ")".into(),
-                    close: true,
-                    ..Default::default()
-                },
-            ],
             autoclose_before: "})]>".into(),
             ..Default::default()
         },
@@ -3452,20 +3464,23 @@ async fn test_surround_with_pair(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,
-                    ..Default::default()
-                },
-            ],
+            brackets: BracketPairConfig {
+                pairs: vec![
+                    BracketPair {
+                        start: "{".to_string(),
+                        end: "}".to_string(),
+                        close: true,
+                        newline: true,
+                    },
+                    BracketPair {
+                        start: "/* ".to_string(),
+                        end: "*/".to_string(),
+                        close: true,
+                        ..Default::default()
+                    },
+                ],
+                ..Default::default()
+            },
             ..Default::default()
         },
         Some(tree_sitter_rust::language()),
@@ -3603,12 +3618,15 @@ async fn test_delete_autoclose_pair(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,
-            }],
+            brackets: BracketPairConfig {
+                pairs: vec![BracketPair {
+                    start: "{".to_string(),
+                    end: "}".to_string(),
+                    close: true,
+                    newline: true,
+                }],
+                ..Default::default()
+            },
             autoclose_before: "}".to_string(),
             ..Default::default()
         },
@@ -5030,20 +5048,23 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) {
     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,
-                    },
-                ],
+                brackets: BracketPairConfig {
+                    pairs: 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()
+                },
                 ..Default::default()
             },
             Some(tree_sitter_rust::language()),

crates/editor/src/highlight_matching_bracket.rs 🔗

@@ -32,11 +32,10 @@ pub fn refresh_matching_bracket_highlights(editor: &mut Editor, cx: &mut ViewCon
 
 #[cfg(test)]
 mod tests {
-    use crate::test::editor_lsp_test_context::EditorLspTestContext;
-
     use super::*;
+    use crate::test::editor_lsp_test_context::EditorLspTestContext;
     use indoc::indoc;
-    use language::{BracketPair, Language, LanguageConfig};
+    use language::{BracketPair, BracketPairConfig, Language, LanguageConfig};
 
     #[gpui::test]
     async fn test_matching_bracket_highlights(cx: &mut gpui::TestAppContext) {
@@ -45,20 +44,23 @@ mod tests {
                 LanguageConfig {
                     name: "Rust".into(),
                     path_suffixes: vec!["rs".to_string()],
-                    brackets: vec![
-                        BracketPair {
-                            start: "{".to_string(),
-                            end: "}".to_string(),
-                            close: false,
-                            newline: true,
-                        },
-                        BracketPair {
-                            start: "(".to_string(),
-                            end: ")".to_string(),
-                            close: false,
-                            newline: true,
-                        },
-                    ],
+                    brackets: BracketPairConfig {
+                        pairs: vec![
+                            BracketPair {
+                                start: "{".to_string(),
+                                end: "}".to_string(),
+                                close: false,
+                                newline: true,
+                            },
+                            BracketPair {
+                                start: "(".to_string(),
+                                end: ")".to_string(),
+                                close: false,
+                                newline: true,
+                            },
+                        ],
+                        ..Default::default()
+                    },
                     ..Default::default()
                 },
                 Some(tree_sitter_rust::language()),

crates/language/src/buffer_tests.rs 🔗

@@ -1527,42 +1527,34 @@ fn test_language_config_at(cx: &mut MutableAppContext) {
             LanguageConfig {
                 name: "JavaScript".into(),
                 line_comment: Some("// ".into()),
-                brackets: vec![
-                    BracketPair {
-                        start: "{".into(),
-                        end: "}".into(),
-                        close: true,
-                        newline: false,
-                    },
-                    BracketPair {
-                        start: "'".into(),
-                        end: "'".into(),
-                        close: true,
-                        newline: false,
-                    },
-                ],
-                overrides: [
-                    (
-                        "element".into(),
-                        LanguageConfigOverride {
-                            line_comment: Override::Remove { remove: true },
-                            block_comment: Override::Set(("{/*".into(), "*/}".into())),
-                            ..Default::default()
+                brackets: BracketPairConfig {
+                    pairs: vec![
+                        BracketPair {
+                            start: "{".into(),
+                            end: "}".into(),
+                            close: true,
+                            newline: false,
                         },
-                    ),
-                    (
-                        "string".into(),
-                        LanguageConfigOverride {
-                            brackets: Override::Set(vec![BracketPair {
-                                start: "{".into(),
-                                end: "}".into(),
-                                close: true,
-                                newline: false,
-                            }]),
-                            ..Default::default()
+                        BracketPair {
+                            start: "'".into(),
+                            end: "'".into(),
+                            close: true,
+                            newline: false,
                         },
-                    ),
-                ]
+                    ],
+                    disabled_scopes_by_bracket_ix: vec![
+                        Vec::new(), //
+                        vec!["string".into()],
+                    ],
+                },
+                overrides: [(
+                    "element".into(),
+                    LanguageConfigOverride {
+                        line_comment: Override::Remove { remove: true },
+                        block_comment: Override::Set(("{/*".into(), "*/}".into())),
+                        ..Default::default()
+                    },
+                )]
                 .into_iter()
                 .collect(),
                 ..Default::default()
@@ -1584,11 +1576,19 @@ fn test_language_config_at(cx: &mut MutableAppContext) {
 
         let config = snapshot.language_scope_at(0).unwrap();
         assert_eq!(config.line_comment_prefix().unwrap().as_ref(), "// ");
-        assert_eq!(config.brackets().len(), 2);
+        // Both bracket pairs are enabled
+        assert_eq!(
+            config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, true]
+        );
 
         let string_config = snapshot.language_scope_at(3).unwrap();
-        assert_eq!(config.line_comment_prefix().unwrap().as_ref(), "// ");
-        assert_eq!(string_config.brackets().len(), 1);
+        assert_eq!(string_config.line_comment_prefix().unwrap().as_ref(), "// ");
+        // Second bracket pair is disabled
+        assert_eq!(
+            string_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, false]
+        );
 
         let element_config = snapshot.language_scope_at(10).unwrap();
         assert_eq!(element_config.line_comment_prefix(), None);
@@ -1596,7 +1596,11 @@ fn test_language_config_at(cx: &mut MutableAppContext) {
             element_config.block_comment_delimiters(),
             Some((&"{/*".into(), &"*/}".into()))
         );
-        assert_eq!(element_config.brackets().len(), 2);
+        // Both bracket pairs are enabled
+        assert_eq!(
+            element_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
+            &[true, true]
+        );
 
         buffer
     });

crates/language/src/language.rs 🔗

@@ -231,7 +231,7 @@ pub struct CodeLabel {
 pub struct LanguageConfig {
     pub name: Arc<str>,
     pub path_suffixes: Vec<String>,
-    pub brackets: Vec<BracketPair>,
+    pub brackets: BracketPairConfig,
     #[serde(default = "auto_indent_using_last_non_empty_line_default")]
     pub auto_indent_using_last_non_empty_line: bool,
     #[serde(default, deserialize_with = "deserialize_regex")]
@@ -270,8 +270,8 @@ pub struct LanguageConfigOverride {
     pub line_comment: Override<Arc<str>>,
     #[serde(default)]
     pub block_comment: Override<(Arc<str>, Arc<str>)>,
-    #[serde(default)]
-    pub brackets: Override<Vec<BracketPair>>,
+    #[serde(skip_deserializing)]
+    pub disabled_bracket_ixs: Vec<u16>,
 }
 
 #[derive(Deserialize, Debug)]
@@ -336,7 +336,41 @@ pub struct FakeLspAdapter {
     pub disk_based_diagnostics_sources: Vec<String>,
 }
 
-#[derive(Clone, Debug, Default, Deserialize)]
+#[derive(Clone, Debug, Default)]
+pub struct BracketPairConfig {
+    pub pairs: Vec<BracketPair>,
+    pub disabled_scopes_by_bracket_ix: Vec<Vec<String>>,
+}
+
+impl<'de> Deserialize<'de> for BracketPairConfig {
+    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        #[derive(Deserialize)]
+        pub struct Entry {
+            #[serde(flatten)]
+            pub bracket_pair: BracketPair,
+            #[serde(default)]
+            pub not_in: Vec<String>,
+        }
+
+        let result = Vec::<Entry>::deserialize(deserializer)?;
+        let mut brackets = Vec::with_capacity(result.len());
+        let mut disabled_scopes_by_bracket_ix = Vec::with_capacity(result.len());
+        for entry in result {
+            brackets.push(entry.bracket_pair);
+            disabled_scopes_by_bracket_ix.push(entry.not_in);
+        }
+
+        Ok(BracketPairConfig {
+            pairs: brackets,
+            disabled_scopes_by_bracket_ix,
+        })
+    }
+}
+
+#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
 pub struct BracketPair {
     pub start: String,
     pub end: String,
@@ -393,7 +427,7 @@ struct InjectionConfig {
 
 struct OverrideConfig {
     query: Query,
-    values: HashMap<u32, LanguageConfigOverride>,
+    values: HashMap<u32, (String, LanguageConfigOverride)>,
 }
 
 #[derive(Default, Clone)]
@@ -967,16 +1001,11 @@ impl Language {
     pub fn with_override_query(mut self, source: &str) -> Result<Self> {
         let query = Query::new(self.grammar_mut().ts_language, source)?;
 
-        let mut values = HashMap::default();
+        let mut override_configs_by_id = HashMap::default();
         for (ix, name) in query.capture_names().iter().enumerate() {
             if !name.starts_with('_') {
-                let value = self.config.overrides.remove(name).ok_or_else(|| {
-                    anyhow!(
-                        "language {:?} has override in query but not in config: {name:?}",
-                        self.config.name
-                    )
-                })?;
-                values.insert(ix as u32, value);
+                let value = self.config.overrides.remove(name).unwrap_or_default();
+                override_configs_by_id.insert(ix as u32, (name.clone(), value));
             }
         }
 
@@ -988,7 +1017,28 @@ impl Language {
             ))?;
         }
 
-        self.grammar_mut().override_config = Some(OverrideConfig { query, values });
+        for (name, override_config) in override_configs_by_id.values_mut() {
+            override_config.disabled_bracket_ixs = self
+                .config
+                .brackets
+                .disabled_scopes_by_bracket_ix
+                .iter()
+                .enumerate()
+                .filter_map(|(ix, disabled_scope_names)| {
+                    if disabled_scope_names.contains(name) {
+                        Some(ix as u16)
+                    } else {
+                        None
+                    }
+                })
+                .collect();
+        }
+
+        self.config.brackets.disabled_scopes_by_bracket_ix.clear();
+        self.grammar_mut().override_config = Some(OverrideConfig {
+            query,
+            values: override_configs_by_id,
+        });
         Ok(self)
     }
 
@@ -1132,12 +1182,26 @@ impl LanguageScope {
         .map(|e| (&e.0, &e.1))
     }
 
-    pub fn brackets(&self) -> &[BracketPair] {
-        Override::as_option(
-            self.config_override().map(|o| &o.brackets),
-            Some(&self.language.config.brackets),
-        )
-        .map_or(&[], Vec::as_slice)
+    pub fn brackets(&self) -> impl Iterator<Item = (&BracketPair, bool)> {
+        let mut disabled_ids = self
+            .config_override()
+            .map_or(&[] as _, |o| o.disabled_bracket_ixs.as_slice());
+        self.language
+            .config
+            .brackets
+            .pairs
+            .iter()
+            .enumerate()
+            .map(move |(ix, bracket)| {
+                let mut is_enabled = true;
+                if let Some(next_disabled_ix) = disabled_ids.first() {
+                    if ix == *next_disabled_ix as usize {
+                        disabled_ids = &disabled_ids[1..];
+                        is_enabled = false;
+                    }
+                }
+                (bracket, is_enabled)
+            })
     }
 
     pub fn should_autoclose_before(&self, c: char) -> bool {
@@ -1148,7 +1212,7 @@ impl LanguageScope {
         let id = self.override_id?;
         let grammar = self.language.grammar.as_ref()?;
         let override_config = grammar.override_config.as_ref()?;
-        override_config.values.get(&id)
+        override_config.values.get(&id).map(|e| &e.1)
     }
 }
 

crates/zed/src/languages/c/config.toml 🔗

@@ -6,21 +6,7 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
 ]

crates/zed/src/languages/cpp/config.toml 🔗

@@ -6,21 +6,7 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
 ]

crates/zed/src/languages/css/config.toml 🔗

@@ -5,20 +5,6 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string", "comment"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
 ]

crates/zed/src/languages/elixir/config.toml 🔗

@@ -6,20 +6,6 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string", "comment"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
 ]

crates/zed/src/languages/go/config.toml 🔗

@@ -6,21 +6,7 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["comment", "string"] },
 ]

crates/zed/src/languages/html/config.toml 🔗

@@ -1,26 +1,12 @@
 name = "HTML"
 path_suffixes = ["html"]
 autoclose_before = ">})"
-brackets = [
-    { start = "<", end = ">", close = true, newline = true },
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "!--", end = " --", close = true, newline = false },
-]
-
 block_comment = ["<!-- ", " -->"]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
 brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "<", end = ">", close = true, newline = true, not_in = ["comment", "string"] },
+    { start = "!--", end = " --", close = true, newline = false, not_in = ["comment", "string"] },
 ]

crates/zed/src/languages/javascript/config.toml 🔗

@@ -6,25 +6,11 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-    { start = "`", end = "`", close = true, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "<", end = ">", close = false, newline = true, not_in = ["comment", "string"] },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "`", end = "`", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["comment", "string"] },
 ]
 
 [overrides.element]

crates/zed/src/languages/json/config.toml 🔗

@@ -5,11 +5,5 @@ autoclose_before = ",]}"
 brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
 ]

crates/zed/src/languages/lua/config.toml 🔗

@@ -3,13 +3,7 @@ path_suffixes = ["lua"]
 line_comment = "-- "
 autoclose_before = ",]}"
 brackets = [
-{ start = "{", end = "}", close = true, newline = true },
-{ start = "[", end = "]", close = true, newline = true },
-{ start = "\"", end = "\"", close = true, newline = false },
+    { start = "{", end = "}", close = true, newline = true },
+    { start = "[", end = "]", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
 ]
-
-[overrides.string]
-brackets = [
-{ start = "{", end = "}", close = true, newline = true },
-{ start = "[", end = "]", close = true, newline = true },
-]

crates/zed/src/languages/python/config.toml 🔗

@@ -2,28 +2,14 @@ name = "Python"
 path_suffixes = ["py", "pyi"]
 line_comment = "# "
 autoclose_before = ";:.,=}])>"
-brackets = [
-  { start = "{", end = "}", close = true, newline = true },
-  { start = "[", end = "]", close = true, newline = true },
-  { start = "(", end = ")", close = true, newline = true },
-  { start = "\"", end = "\"", close = true, newline = false },
-  { start = "'", end = "'", close = false, newline = false },
-]
-
-auto_indent_using_last_non_empty_line = false
-increase_indent_pattern = ":\\s*$"
-decrease_indent_pattern = "^\\s*(else|elif|except|finally)\\b.*:"
-
-[overrides.comment]
 brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
+    { start = "'", end = "'", close = false, newline = false, not_in = ["string"] },
 ]
 
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
+auto_indent_using_last_non_empty_line = false
+increase_indent_pattern = ":\\s*$"
+decrease_indent_pattern = "^\\s*(else|elif|except|finally)\\b.*:"

crates/zed/src/languages/ruby/config.toml 🔗

@@ -6,20 +6,6 @@ brackets = [
   { start = "{", end = "}", close = true, newline = true },
   { start = "[", end = "]", close = true, newline = true },
   { start = "(", end = ")", close = true, newline = true },
-  { start = "\"", end = "\"", close = true, newline = false },
-  { start = "'", end = "'", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+  { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
+  { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
 ]

crates/zed/src/languages/rust/config.toml 🔗

@@ -6,24 +6,7 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = false, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true },
+    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
 ]

crates/zed/src/languages/scheme/config.toml 🔗

@@ -5,17 +5,5 @@ autoclose_before = "])"
 brackets = [
     { start = "[", end = "]", close = true, newline = false },
     { start = "(", end = ")", close = true, newline = false },
-    { start = "\"", end = "\"", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
 ]

crates/zed/src/languages/toml/config.toml 🔗

@@ -5,18 +5,6 @@ autoclose_before = ",]}"
 brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
 ]

crates/zed/src/languages/tsx/config.toml 🔗

@@ -6,18 +6,13 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-    { start = "`", end = "`", close = true, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
+    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
+    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
 ]
 
 [overrides.element]
 line_comment = { remove = true }
 block_comment = ["{/* ", " */}"]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-]

crates/zed/src/languages/typescript/config.toml 🔗

@@ -6,23 +6,9 @@ brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
     { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
-    { start = "'", end = "'", close = true, newline = false },
-    { start = "`", end = "`", close = true, newline = false },
-    { start = "/*", end = " */", close = true, newline = false },
-]
-
-[overrides.comment]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
+    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
+    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
+    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
+    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
 ]

crates/zed/src/languages/yaml/config.toml 🔗

@@ -5,13 +5,7 @@ autoclose_before = ",]}"
 brackets = [
     { start = "{", end = "}", close = true, newline = true },
     { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false },
+    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
 ]
 
 increase_indent_pattern = ":\\s*[|>]?\\s*$"
-
-[overrides.string]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-]