Autoclose brackets before a language-specific set of characters

Fixes #588
This commit is contained in:
Max Brunsfeld 2022-03-14 15:17:40 -07:00
parent 7bdb91f4ec
commit 325e6c31ae
5 changed files with 16 additions and 6 deletions

View file

@ -1910,15 +1910,10 @@ impl Editor {
selection.start.saturating_sub(pair.start.len()), selection.start.saturating_sub(pair.start.len()),
&pair.start, &pair.start,
) { ) {
// Autoclose only if the next character is a whitespace or a pair end
// (possibly a different one from the pair we are inserting).
snapshot snapshot
.chars_at(selection.start) .chars_at(selection.start)
.next() .next()
.map_or(true, |ch| ch.is_whitespace()) .map_or(true, |c| language.should_autoclose_before(c))
|| language.brackets().iter().any(|pair| {
snapshot.contains_str_at(selection.start, &pair.end)
})
} else { } else {
false false
} }
@ -8125,6 +8120,7 @@ mod tests {
newline: true, newline: true,
}, },
], ],
autoclose_before: "})]".to_string(),
..Default::default() ..Default::default()
}, },
Some(tree_sitter_rust::language()), Some(tree_sitter_rust::language()),
@ -8152,6 +8148,7 @@ mod tests {
], ],
cx, cx,
); );
view.handle_input(&Input("{".to_string()), cx); view.handle_input(&Input("{".to_string()), cx);
view.handle_input(&Input("{".to_string()), cx); view.handle_input(&Input("{".to_string()), cx);
view.handle_input(&Input("{".to_string()), cx); view.handle_input(&Input("{".to_string()), cx);
@ -8215,6 +8212,8 @@ mod tests {
.unindent() .unindent()
); );
// Don't autoclose if the next character isn't whitespace and isn't
// listed in the language's "autoclose_before" section.
view.finalize_last_transaction(cx); view.finalize_last_transaction(cx);
view.select_display_ranges(&[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)], cx); view.select_display_ranges(&[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)], cx);
view.handle_input(&Input("{".to_string()), cx); view.handle_input(&Input("{".to_string()), cx);

View file

@ -49,6 +49,7 @@ lazy_static! {
name: "Plain Text".into(), name: "Plain Text".into(),
path_suffixes: Default::default(), path_suffixes: Default::default(),
brackets: Default::default(), brackets: Default::default(),
autoclose_before: Default::default(),
line_comment: None, line_comment: None,
language_server: None, language_server: None,
}, },
@ -109,6 +110,8 @@ pub struct LanguageConfig {
pub name: Arc<str>, pub name: Arc<str>,
pub path_suffixes: Vec<String>, pub path_suffixes: Vec<String>,
pub brackets: Vec<BracketPair>, pub brackets: Vec<BracketPair>,
#[serde(default)]
pub autoclose_before: String,
pub line_comment: Option<String>, pub line_comment: Option<String>,
pub language_server: Option<LanguageServerConfig>, pub language_server: Option<LanguageServerConfig>,
} }
@ -119,6 +122,7 @@ impl Default for LanguageConfig {
name: "".into(), name: "".into(),
path_suffixes: Default::default(), path_suffixes: Default::default(),
brackets: Default::default(), brackets: Default::default(),
autoclose_before: Default::default(),
line_comment: Default::default(), line_comment: Default::default(),
language_server: Default::default(), language_server: Default::default(),
} }
@ -529,6 +533,10 @@ impl Language {
&self.config.brackets &self.config.brackets
} }
pub fn should_autoclose_before(&self, c: char) -> bool {
c.is_whitespace() || self.config.autoclose_before.contains(c)
}
pub fn set_theme(&self, theme: &SyntaxTheme) { pub fn set_theme(&self, theme: &SyntaxTheme) {
if let Some(grammar) = self.grammar.as_ref() { if let Some(grammar) = self.grammar.as_ref() {
*grammar.highlight_map.lock() = *grammar.highlight_map.lock() =

View file

@ -1,6 +1,7 @@
name = "C" name = "C"
path_suffixes = ["c", "h"] path_suffixes = ["c", "h"]
line_comment = "// " line_comment = "// "
autoclose_before = ";:.,=}])>"
brackets = [ brackets = [
{ start = "{", end = "}", close = true, newline = true }, { start = "{", end = "}", close = true, newline = true },
{ start = "[", end = "]", close = true, newline = true }, { start = "[", end = "]", close = true, newline = true },

View file

@ -1,5 +1,6 @@
name = "JSON" name = "JSON"
path_suffixes = ["json"] path_suffixes = ["json"]
autoclose_before = ",]}"
brackets = [ brackets = [
{ start = "{", end = "}", close = true, newline = true }, { start = "{", end = "}", close = true, newline = true },
{ start = "[", end = "]", close = true, newline = true }, { start = "[", end = "]", close = true, newline = true },

View file

@ -1,6 +1,7 @@
name = "Rust" name = "Rust"
path_suffixes = ["rs"] path_suffixes = ["rs"]
line_comment = "// " line_comment = "// "
autoclose_before = ";:.,=}])>"
brackets = [ brackets = [
{ start = "{", end = "}", close = true, newline = true }, { start = "{", end = "}", close = true, newline = true },
{ start = "[", end = "]", close = true, newline = true }, { start = "[", end = "]", close = true, newline = true },