Detailed changes
@@ -1755,8 +1755,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;
@@ -1924,11 +1924,12 @@ 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(
@@ -13,8 +13,9 @@ use gpui::{
executor::Deterministic,
geometry::{rect::RectF, vector::vec2f},
platform::{WindowBounds, WindowOptions},
+ serde_json,
};
-use language::{FakeLspAdapter, LanguageConfig, LanguageRegistry, Point};
+use language::{BracketPairConfig, FakeLspAdapter, LanguageConfig, LanguageRegistry, Point};
use project::FakeFs;
use settings::EditorSettings;
use util::{
@@ -3002,20 +3003,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 +3063,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 +3234,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 +3296,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()
},
@@ -3447,25 +3460,125 @@ async fn test_autoclose_with_embedded_language(cx: &mut gpui::TestAppContext) {
);
}
+#[gpui::test]
+async fn test_autoclose_with_overrides(cx: &mut gpui::TestAppContext) {
+ let mut cx = EditorTestContext::new(cx);
+
+ let rust_language = Arc::new(
+ Language::new(
+ LanguageConfig {
+ name: "Rust".into(),
+ brackets: serde_json::from_value(json!([
+ { "start": "{", "end": "}", "close": true, "newline": true },
+ { "start": "\"", "end": "\"", "close": true, "newline": false, "not_in": ["string"] },
+ ]))
+ .unwrap(),
+ autoclose_before: "})]>".into(),
+ ..Default::default()
+ },
+ Some(tree_sitter_rust::language()),
+ )
+ .with_override_query("(string_literal) @string")
+ .unwrap(),
+ );
+
+ let registry = Arc::new(LanguageRegistry::test());
+ registry.add(rust_language.clone());
+
+ cx.update_buffer(|buffer, cx| {
+ buffer.set_language_registry(registry);
+ buffer.set_language(Some(rust_language), cx);
+ });
+
+ cx.set_state(
+ &r#"
+ let x = ˇ
+ "#
+ .unindent(),
+ );
+
+ // Inserting a quotation mark. A closing quotation mark is automatically inserted.
+ cx.update_editor(|editor, cx| {
+ editor.handle_input("\"", cx);
+ });
+ cx.assert_editor_state(
+ &r#"
+ let x = "ˇ"
+ "#
+ .unindent(),
+ );
+
+ // Inserting another quotation mark. The cursor moves across the existing
+ // automatically-inserted quotation mark.
+ cx.update_editor(|editor, cx| {
+ editor.handle_input("\"", cx);
+ });
+ cx.assert_editor_state(
+ &r#"
+ let x = ""ˇ
+ "#
+ .unindent(),
+ );
+
+ // Reset
+ cx.set_state(
+ &r#"
+ let x = ˇ
+ "#
+ .unindent(),
+ );
+
+ // Inserting a quotation mark inside of a string. A second quotation mark is not inserted.
+ cx.update_editor(|editor, cx| {
+ editor.handle_input("\"", cx);
+ editor.handle_input(" ", cx);
+ editor.move_left(&Default::default(), cx);
+ editor.handle_input("\\", cx);
+ editor.handle_input("\"", cx);
+ });
+ cx.assert_editor_state(
+ &r#"
+ let x = "\"ˇ "
+ "#
+ .unindent(),
+ );
+
+ // Inserting a closing quotation mark at the position of an automatically-inserted quotation
+ // mark. Nothing is inserted.
+ cx.update_editor(|editor, cx| {
+ editor.move_right(&Default::default(), cx);
+ editor.handle_input("\"", cx);
+ });
+ cx.assert_editor_state(
+ &r#"
+ let x = "\" "ˇ
+ "#
+ .unindent(),
+ );
+}
+
#[gpui::test]
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 +3716,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()
},
@@ -4897,20 +5013,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()),
@@ -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()),
@@ -1480,42 +1480,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()
@@ -1537,11 +1529,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);
@@ -1549,7 +1549,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
});
@@ -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")]
@@ -258,7 +258,7 @@ pub struct LanguageQueries {
pub overrides: Option<Cow<'static, str>>,
}
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct LanguageScope {
language: Arc<Language>,
override_id: Option<u32>,
@@ -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,46 @@ impl Language {
))?;
}
- self.grammar_mut().override_config = Some(OverrideConfig { query, values });
+ for disabled_scope_name in self
+ .config
+ .brackets
+ .disabled_scopes_by_bracket_ix
+ .iter()
+ .flatten()
+ {
+ if !override_configs_by_id
+ .values()
+ .any(|(scope_name, _)| scope_name == disabled_scope_name)
+ {
+ Err(anyhow!(
+ "language {:?} has overrides in config not in query: {disabled_scope_name:?}",
+ self.config.name
+ ))?;
+ }
+ }
+
+ 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 +1200,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 +1230,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)
}
}
@@ -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"] },
]
@@ -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"] },
]
@@ -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"] },
]
@@ -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"] },
]
@@ -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"] },
]
@@ -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"] },
]
@@ -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]
@@ -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"] },
]
@@ -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 },
-]
@@ -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.*:"
@@ -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"] },
]
@@ -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"] },
]
@@ -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"] },
]
@@ -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"] },
]
@@ -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 },
-]
@@ -1,7 +1,8 @@
+(comment) @comment
+(string) @string
[
(jsx_element)
(jsx_fragment)
(jsx_self_closing_element)
(jsx_expression)
] @element
-(string) @string
@@ -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"] },
]
@@ -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 },
-]
@@ -696,8 +696,9 @@ mod tests {
use assets::Assets;
use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor};
use gpui::{
- executor::Deterministic, AssetSource, MutableAppContext, TestAppContext, ViewHandle,
+ executor::Deterministic, AssetSource, MutableAppContext, Task, TestAppContext, ViewHandle,
};
+ use language::LanguageRegistry;
use project::{Project, ProjectPath};
use serde_json::json;
use std::{
@@ -1881,6 +1882,18 @@ mod tests {
assert!(has_default_theme);
}
+ #[gpui::test]
+ fn test_bundled_languages(cx: &mut MutableAppContext) {
+ let mut languages = LanguageRegistry::new(Task::ready(()));
+ languages.set_executor(cx.background().clone());
+ let languages = Arc::new(languages);
+ languages::init(languages.clone());
+ for name in languages.language_names() {
+ languages.language_for_name(&name);
+ }
+ cx.foreground().run_until_parked();
+ }
+
fn init(cx: &mut TestAppContext) -> Arc<AppState> {
cx.foreground().forbid_parking();
cx.update(|cx| {