diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index c1c9cfebbead5..cea921438dbfa 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -642,6 +642,9 @@ pub struct LanguageConfig { /// languages, but should not appear to the user as a distinct language. #[serde(default)] pub hidden: bool, + /// Insert trailing commas within blocks, like { } in JSON/JSONC + #[serde(default)] + pub insert_trailing_commas: bool, } #[derive(Clone, Debug, Serialize, Deserialize, Default, JsonSchema)] @@ -729,6 +732,7 @@ impl Default for LanguageConfig { soft_wrap: None, prettier_parser_name: None, hidden: false, + insert_trailing_commas: false, } } } @@ -1525,6 +1529,10 @@ impl LanguageScope { let override_config = grammar.override_config.as_ref()?; override_config.values.get(&id).map(|e| &e.1) } + + pub fn insert_trailing_commas(&self) -> bool { + self.language.config.insert_trailing_commas + } } impl Hash for Language { diff --git a/crates/languages/src/json/config.toml b/crates/languages/src/json/config.toml index c4a91c20b0186..e98b61bc03b9f 100644 --- a/crates/languages/src/json/config.toml +++ b/crates/languages/src/json/config.toml @@ -10,3 +10,4 @@ brackets = [ ] tab_size = 2 prettier_parser_name = "json" +insert_trailing_commas = true diff --git a/crates/languages/src/jsonc/config.toml b/crates/languages/src/jsonc/config.toml index fe62764b2790c..db5de96d3ec3a 100644 --- a/crates/languages/src/jsonc/config.toml +++ b/crates/languages/src/jsonc/config.toml @@ -10,3 +10,4 @@ brackets = [ ] tab_size = 2 prettier_parser_name = "jsonc" +insert_trailing_commas = true diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index aecd0f90b2312..5293cb99e3437 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -374,9 +374,37 @@ impl Vim { .collect::(); let end_of_line = Point::new(row, snapshot.line_len(MultiBufferRow(row))); - (end_of_line..end_of_line, "\n".to_string() + &indent) + let last_char_point = Point::new( + row, + snapshot.line_len(MultiBufferRow(row)).saturating_sub(1), + ); + let inside_brackets = snapshot + .enclosing_bracket_ranges(end_of_line..end_of_line) + .into_iter() + .flatten() + .next() + .is_some(); + let last_char = snapshot + .text_for_range(last_char_point..end_of_line) + .next() + .unwrap_or_default(); + let mut edit = String::with_capacity(indent.len() + 2); + + let insert_trailing_commas = snapshot + .language_scope_at(Point::new(row, 0)) + .map(|s| s.insert_trailing_commas()) + .unwrap_or_default(); + dbg!(insert_trailing_commas); + let should_insert_trailing = !["{", ",", " ", "", "["].contains(&last_char); + if should_insert_trailing && inside_brackets && insert_trailing_commas { + edit.push(','); + } + edit.push('\n'); + edit.push_str(&indent); + (end_of_line..end_of_line, edit) }) .collect::>(); + editor.change_selections(Some(Autoscroll::fit()), cx, |s| { s.maybe_move_cursors_with(|map, cursor, goal| { Motion::CurrentLine.move_point(