language: Update block_comment and documentation comment (#34861)

As suggested in https://github.com/zed-industries/zed/pull/34418, this
proposes various changes to language configs to make block comments and
doc-block-style comments more similar. In doing so, it introduces some
breaking changes into the extension schema.

This change is needed to support the changes I'm working on in #34418,
to be able to support `rewrap` in block comments like `/* really long
comment ... */`. As is, we can do this in C-style doc-block comments (eg
`/** ... */`) because of the config in `documentation`, but we can't do
this in regular block comments because we lack the info about what the
line prefix and indentation should be.

And while I was here, I did various other clean-ups, many of which feel
nice but are optional.

I would love special attention on the changes to the schema, version and
related changes; I'm totally unfamiliar with that part of Zed.

**Summary of changes**
- break: changes type of `block_comment` to same type as
`documentation_comment` (**this is the important change**)
- break: rename `documentation` to `documentation_comment` (optional,
but improves consistency w/ `line_comments` and `block_comment`)
- break/refactor?: removes some whitespace in the declaration of
`block_comment` delimiters (optional, may break things, need input; some
langs had no spaces, others did)
- refactor: change `tab_size` from `NonZeroU32` to just a `u32` (some
block comments don't seem to need/want indent past the initial
delimiter, so we need this be 0 sometimes)
- refactor: moves the `documentation_comment` declarations to appear
next to `block_comment`, rearranges the order of the fields in the TOML
for `documentation_comment`, rename backing `struct` (all optional)

**Future scope**
I believe that this will also allow us to extend regular block comments
on newline – as we do doc-block comments – but I haven't looked into
this yet. (eg, in JS try pressing enter in both of these: `/* */` and
`/** */`; the latter should extend w/ a `*` prefixed line, while the
former does not.)

Release Notes:

- BREAKING CHANGE: update extension schema version from 1 to 2, change
format of `block_comment` and rename `documentation_comment`

/cc @smitbarmase
This commit is contained in:
claytonrcarter 2025-07-23 11:08:52 -04:00 committed by GitHub
parent 14171e0721
commit 1f4c9b9427
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 249 additions and 74 deletions

1
Cargo.lock generated
View file

@ -9018,6 +9018,7 @@ dependencies = [
"task",
"text",
"theme",
"toml 0.8.20",
"tree-sitter",
"tree-sitter-elixir",
"tree-sitter-embedded-template",

View file

@ -109,10 +109,10 @@ use inline_completion::{EditPredictionProvider, InlineCompletionProviderHandle};
pub use items::MAX_TAB_TITLE_LEN;
use itertools::Itertools;
use language::{
AutoindentMode, BracketMatch, BracketPair, Buffer, Capability, CharKind, CodeLabel,
CursorShape, DiagnosticEntry, DiffOptions, DocumentationConfig, EditPredictionsMode,
EditPreview, HighlightedText, IndentKind, IndentSize, Language, OffsetRangeExt, Point,
Selection, SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery,
AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, Capability, CharKind,
CodeLabel, CursorShape, DiagnosticEntry, DiffOptions, EditPredictionsMode, EditPreview,
HighlightedText, IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection,
SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery,
language_settings::{
self, InlayHintSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode,
all_language_settings, language_settings,
@ -4408,7 +4408,9 @@ impl Editor {
})
.max_by_key(|(_, len)| *len)?;
if let Some((block_start, _)) = language.block_comment_delimiters()
if let Some(BlockCommentConfig {
start: block_start, ..
}) = language.block_comment()
{
let block_start_trimmed = block_start.trim_end();
if block_start_trimmed.starts_with(delimiter.trim_end()) {
@ -4445,13 +4447,12 @@ impl Editor {
return None;
}
let DocumentationConfig {
let BlockCommentConfig {
start: start_tag,
end: end_tag,
prefix: delimiter,
tab_size: len,
} = language.documentation()?;
} = language.documentation_comment()?;
let is_within_block_comment = buffer
.language_scope_at(start_point)
.is_some_and(|scope| scope.override_name() == Some("comment"));
@ -4521,7 +4522,7 @@ impl Editor {
let cursor_is_at_start_of_end_tag =
column == end_tag_offset;
if cursor_is_at_start_of_end_tag {
indent_on_extra_newline.len = (*len).into();
indent_on_extra_newline.len = *len;
}
}
cursor_is_before_end_tag
@ -4534,7 +4535,7 @@ impl Editor {
&& cursor_is_before_end_tag_if_exists
{
if cursor_is_after_start_tag {
indent_on_newline.len = (*len).into();
indent_on_newline.len = *len;
}
Some(delimiter.clone())
} else {
@ -14349,8 +14350,11 @@ impl Editor {
(position..position, first_prefix.clone())
}));
}
} else if let Some((full_comment_prefix, comment_suffix)) =
language.block_comment_delimiters()
} else if let Some(BlockCommentConfig {
start: full_comment_prefix,
end: comment_suffix,
..
}) = language.block_comment()
{
let comment_prefix = full_comment_prefix.trim_end_matches(' ');
let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];

View file

@ -2875,11 +2875,11 @@ async fn test_newline_documentation_comments(cx: &mut TestAppContext) {
let language = Arc::new(
Language::new(
LanguageConfig {
documentation: Some(language::DocumentationConfig {
documentation_comment: Some(language::BlockCommentConfig {
start: "/**".into(),
end: "*/".into(),
prefix: "* ".into(),
tab_size: NonZeroU32::new(1).unwrap(),
tab_size: 1,
}),
..LanguageConfig::default()
@ -3089,7 +3089,12 @@ async fn test_newline_comments_with_block_comment(cx: &mut TestAppContext) {
let lua_language = Arc::new(Language::new(
LanguageConfig {
line_comments: vec!["--".into()],
block_comment: Some(("--[[".into(), "]]".into())),
block_comment: Some(language::BlockCommentConfig {
start: "--[[".into(),
prefix: "".into(),
end: "]]".into(),
tab_size: 0,
}),
..LanguageConfig::default()
},
None,
@ -13806,7 +13811,12 @@ async fn test_toggle_block_comment(cx: &mut TestAppContext) {
Language::new(
LanguageConfig {
name: "HTML".into(),
block_comment: Some(("<!-- ".into(), " -->".into())),
block_comment: Some(BlockCommentConfig {
start: "<!-- ".into(),
prefix: "".into(),
end: " -->".into(),
tab_size: 0,
}),
..Default::default()
},
Some(tree_sitter_html::LANGUAGE.into()),

View file

@ -14,7 +14,8 @@ use futures::Future;
use gpui::{Context, Entity, Focusable as _, VisualTestContext, Window};
use indoc::indoc;
use language::{
FakeLspAdapter, Language, LanguageConfig, LanguageMatcher, LanguageQueries, point_to_lsp,
BlockCommentConfig, FakeLspAdapter, Language, LanguageConfig, LanguageMatcher, LanguageQueries,
point_to_lsp,
};
use lsp::{notification, request};
use multi_buffer::ToPointUtf16;
@ -269,7 +270,12 @@ impl EditorLspTestContext {
path_suffixes: vec!["html".into()],
..Default::default()
},
block_comment: Some(("<!-- ".into(), " -->".into())),
block_comment: Some(BlockCommentConfig {
start: "<!--".into(),
prefix: "".into(),
end: "-->".into(),
tab_size: 0,
}),
completion_query_characters: ['-'].into_iter().collect(),
..Default::default()
},

View file

@ -92,6 +92,7 @@ tree-sitter-python.workspace = true
tree-sitter-ruby.workspace = true
tree-sitter-rust.workspace = true
tree-sitter-typescript.workspace = true
toml.workspace = true
unindent.workspace = true
util = { workspace = true, features = ["test-support"] }
zlog.workspace = true

View file

@ -2273,7 +2273,12 @@ fn test_language_scope_at_with_javascript(cx: &mut App) {
LanguageConfig {
name: "JavaScript".into(),
line_comments: vec!["// ".into()],
block_comment: Some(("/*".into(), "*/".into())),
block_comment: Some(BlockCommentConfig {
start: "/*".into(),
end: "*/".into(),
prefix: "* ".into(),
tab_size: 1,
}),
brackets: BracketPairConfig {
pairs: vec![
BracketPair {
@ -2300,7 +2305,12 @@ fn test_language_scope_at_with_javascript(cx: &mut App) {
"element".into(),
LanguageConfigOverride {
line_comments: Override::Remove { remove: true },
block_comment: Override::Set(("{/*".into(), "*/}".into())),
block_comment: Override::Set(BlockCommentConfig {
start: "{/*".into(),
prefix: "".into(),
end: "*/}".into(),
tab_size: 0,
}),
..Default::default()
},
)]
@ -2338,9 +2348,15 @@ fn test_language_scope_at_with_javascript(cx: &mut App) {
let config = snapshot.language_scope_at(0).unwrap();
assert_eq!(config.line_comment_prefixes(), &[Arc::from("// ")]);
assert_eq!(
config.block_comment_delimiters(),
Some((&"/*".into(), &"*/".into()))
config.block_comment(),
Some(&BlockCommentConfig {
start: "/*".into(),
prefix: "* ".into(),
end: "*/".into(),
tab_size: 1,
})
);
// Both bracket pairs are enabled
assert_eq!(
config.brackets().map(|e| e.1).collect::<Vec<_>>(),
@ -2360,8 +2376,13 @@ fn test_language_scope_at_with_javascript(cx: &mut App) {
.unwrap();
assert_eq!(string_config.line_comment_prefixes(), &[Arc::from("// ")]);
assert_eq!(
string_config.block_comment_delimiters(),
Some((&"/*".into(), &"*/".into()))
string_config.block_comment(),
Some(&BlockCommentConfig {
start: "/*".into(),
prefix: "* ".into(),
end: "*/".into(),
tab_size: 1,
})
);
// Second bracket pair is disabled
assert_eq!(
@ -2391,8 +2412,13 @@ fn test_language_scope_at_with_javascript(cx: &mut App) {
.unwrap();
assert_eq!(tag_config.line_comment_prefixes(), &[Arc::from("// ")]);
assert_eq!(
tag_config.block_comment_delimiters(),
Some((&"/*".into(), &"*/".into()))
tag_config.block_comment(),
Some(&BlockCommentConfig {
start: "/*".into(),
prefix: "* ".into(),
end: "*/".into(),
tab_size: 1,
})
);
assert_eq!(
tag_config.brackets().map(|e| e.1).collect::<Vec<_>>(),
@ -2408,8 +2434,13 @@ fn test_language_scope_at_with_javascript(cx: &mut App) {
&[Arc::from("// ")]
);
assert_eq!(
expression_in_element_config.block_comment_delimiters(),
Some((&"/*".into(), &"*/".into()))
expression_in_element_config.block_comment(),
Some(&BlockCommentConfig {
start: "/*".into(),
prefix: "* ".into(),
end: "*/".into(),
tab_size: 1,
})
);
assert_eq!(
expression_in_element_config
@ -2528,13 +2559,18 @@ fn test_language_scope_at_with_combined_injections(cx: &mut App) {
let html_config = snapshot.language_scope_at(Point::new(2, 4)).unwrap();
assert_eq!(html_config.line_comment_prefixes(), &[]);
assert_eq!(
html_config.block_comment_delimiters(),
Some((&"<!--".into(), &"-->".into()))
html_config.block_comment(),
Some(&BlockCommentConfig {
start: "<!--".into(),
end: "-->".into(),
prefix: "".into(),
tab_size: 0,
})
);
let ruby_config = snapshot.language_scope_at(Point::new(3, 12)).unwrap();
assert_eq!(ruby_config.line_comment_prefixes(), &[Arc::from("# ")]);
assert_eq!(ruby_config.block_comment_delimiters(), None);
assert_eq!(ruby_config.block_comment(), None);
buffer
});
@ -3490,7 +3526,12 @@ fn html_lang() -> Language {
Language::new(
LanguageConfig {
name: LanguageName::new("HTML"),
block_comment: Some(("<!--".into(), "-->".into())),
block_comment: Some(BlockCommentConfig {
start: "<!--".into(),
prefix: "".into(),
end: "-->".into(),
tab_size: 0,
}),
..Default::default()
},
Some(tree_sitter_html::LANGUAGE.into()),
@ -3521,7 +3562,12 @@ fn erb_lang() -> Language {
path_suffixes: vec!["erb".to_string()],
..Default::default()
},
block_comment: Some(("<%#".into(), "%>".into())),
block_comment: Some(BlockCommentConfig {
start: "<%#".into(),
prefix: "".into(),
end: "%>".into(),
tab_size: 0,
}),
..Default::default()
},
Some(tree_sitter_embedded_template::LANGUAGE.into()),

View file

@ -727,9 +727,12 @@ pub struct LanguageConfig {
/// used for comment continuations on the next line, but only the first one is used for Editor::ToggleComments.
#[serde(default)]
pub line_comments: Vec<Arc<str>>,
/// Starting and closing characters of a block comment.
/// Delimiters and configuration for recognizing and formatting block comments.
#[serde(default)]
pub block_comment: Option<(Arc<str>, Arc<str>)>,
pub block_comment: Option<BlockCommentConfig>,
/// Delimiters and configuration for recognizing and formatting documentation comments.
#[serde(default, alias = "documentation")]
pub documentation_comment: Option<BlockCommentConfig>,
/// A list of additional regex patterns that should be treated as prefixes
/// for creating boundaries during rewrapping, ensuring content from one
/// prefixed section doesn't merge with another (e.g., markdown list items).
@ -774,10 +777,6 @@ pub struct LanguageConfig {
/// A list of preferred debuggers for this language.
#[serde(default)]
pub debuggers: IndexSet<SharedString>,
/// Whether to treat documentation comment of this language differently by
/// auto adding prefix on new line, adjusting the indenting , etc.
#[serde(default)]
pub documentation: Option<DocumentationConfig>,
}
#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
@ -837,17 +836,56 @@ pub struct JsxTagAutoCloseConfig {
pub erroneous_close_tag_name_node_name: Option<String>,
}
/// The configuration for documentation block for this language.
#[derive(Clone, Deserialize, JsonSchema)]
pub struct DocumentationConfig {
/// A start tag of documentation block.
/// The configuration for block comments for this language.
#[derive(Clone, Debug, JsonSchema, PartialEq)]
pub struct BlockCommentConfig {
/// A start tag of block comment.
pub start: Arc<str>,
/// A end tag of documentation block.
/// A end tag of block comment.
pub end: Arc<str>,
/// A character to add as a prefix when a new line is added to a documentation block.
/// A character to add as a prefix when a new line is added to a block comment.
pub prefix: Arc<str>,
/// A indent to add for prefix and end line upon new line.
pub tab_size: NonZeroU32,
pub tab_size: u32,
}
impl<'de> Deserialize<'de> for BlockCommentConfig {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum BlockCommentConfigHelper {
New {
start: Arc<str>,
end: Arc<str>,
prefix: Arc<str>,
tab_size: u32,
},
Old([Arc<str>; 2]),
}
match BlockCommentConfigHelper::deserialize(deserializer)? {
BlockCommentConfigHelper::New {
start,
end,
prefix,
tab_size,
} => Ok(BlockCommentConfig {
start,
end,
prefix,
tab_size,
}),
BlockCommentConfigHelper::Old([start, end]) => Ok(BlockCommentConfig {
start,
end,
prefix: "".into(),
tab_size: 0,
}),
}
}
}
/// Represents a language for the given range. Some languages (e.g. HTML)
@ -864,7 +902,7 @@ pub struct LanguageConfigOverride {
#[serde(default)]
pub line_comments: Override<Vec<Arc<str>>>,
#[serde(default)]
pub block_comment: Override<(Arc<str>, Arc<str>)>,
pub block_comment: Override<BlockCommentConfig>,
#[serde(skip)]
pub disabled_bracket_ixs: Vec<u16>,
#[serde(default)]
@ -916,6 +954,7 @@ impl Default for LanguageConfig {
autoclose_before: Default::default(),
line_comments: Default::default(),
block_comment: Default::default(),
documentation_comment: Default::default(),
rewrap_prefixes: Default::default(),
scope_opt_in_language_servers: Default::default(),
overrides: Default::default(),
@ -929,7 +968,6 @@ impl Default for LanguageConfig {
jsx_tag_auto_close: None,
completion_query_characters: Default::default(),
debuggers: Default::default(),
documentation: None,
}
}
}
@ -1847,12 +1885,17 @@ impl LanguageScope {
.map_or([].as_slice(), |e| e.as_slice())
}
pub fn block_comment_delimiters(&self) -> Option<(&Arc<str>, &Arc<str>)> {
/// Config for block comments for this language.
pub fn block_comment(&self) -> Option<&BlockCommentConfig> {
Override::as_option(
self.config_override().map(|o| &o.block_comment),
self.language.config.block_comment.as_ref(),
)
.map(|e| (&e.0, &e.1))
}
/// Config for documentation-style block comments for this language.
pub fn documentation_comment(&self) -> Option<&BlockCommentConfig> {
self.language.config.documentation_comment.as_ref()
}
/// Returns additional regex patterns that act as prefix markers for creating
@ -1897,14 +1940,6 @@ impl LanguageScope {
.unwrap_or(false)
}
/// Returns config to documentation block for this language.
///
/// Used for documentation styles that require a leading character on each line,
/// such as the asterisk in JSDoc, Javadoc, etc.
pub fn documentation(&self) -> Option<&DocumentationConfig> {
self.language.config.documentation.as_ref()
}
/// Returns a list of bracket pairs for a given language with an additional
/// piece of information about whether the particular bracket pair is currently active for a given language.
pub fn brackets(&self) -> impl Iterator<Item = (&BracketPair, bool)> {
@ -2299,6 +2334,7 @@ pub fn range_from_lsp(range: lsp::Range) -> Range<Unclipped<PointUtf16>> {
mod tests {
use super::*;
use gpui::TestAppContext;
use pretty_assertions::assert_matches;
#[gpui::test(iterations = 10)]
async fn test_language_loading(cx: &mut TestAppContext) {
@ -2460,4 +2496,75 @@ mod tests {
"LSP completion items with duplicate label and detail, should omit the detail"
);
}
#[test]
fn test_deserializing_comments_backwards_compat() {
// current version of `block_comment` and `documentation_comment` work
{
let config: LanguageConfig = ::toml::from_str(
r#"
name = "Foo"
block_comment = { start = "a", end = "b", prefix = "c", tab_size = 1 }
documentation_comment = { start = "d", end = "e", prefix = "f", tab_size = 2 }
"#,
)
.unwrap();
assert_matches!(config.block_comment, Some(BlockCommentConfig { .. }));
assert_matches!(
config.documentation_comment,
Some(BlockCommentConfig { .. })
);
let block_config = config.block_comment.unwrap();
assert_eq!(block_config.start.as_ref(), "a");
assert_eq!(block_config.end.as_ref(), "b");
assert_eq!(block_config.prefix.as_ref(), "c");
assert_eq!(block_config.tab_size, 1);
let doc_config = config.documentation_comment.unwrap();
assert_eq!(doc_config.start.as_ref(), "d");
assert_eq!(doc_config.end.as_ref(), "e");
assert_eq!(doc_config.prefix.as_ref(), "f");
assert_eq!(doc_config.tab_size, 2);
}
// former `documentation` setting is read into `documentation_comment`
{
let config: LanguageConfig = ::toml::from_str(
r#"
name = "Foo"
documentation = { start = "a", end = "b", prefix = "c", tab_size = 1}
"#,
)
.unwrap();
assert_matches!(
config.documentation_comment,
Some(BlockCommentConfig { .. })
);
let config = config.documentation_comment.unwrap();
assert_eq!(config.start.as_ref(), "a");
assert_eq!(config.end.as_ref(), "b");
assert_eq!(config.prefix.as_ref(), "c");
assert_eq!(config.tab_size, 1);
}
// old block_comment format is read into BlockCommentConfig
{
let config: LanguageConfig = ::toml::from_str(
r#"
name = "Foo"
block_comment = ["a", "b"]
"#,
)
.unwrap();
assert_matches!(config.block_comment, Some(BlockCommentConfig { .. }));
let config = config.block_comment.unwrap();
assert_eq!(config.start.as_ref(), "a");
assert_eq!(config.end.as_ref(), "b");
assert_eq!(config.prefix.as_ref(), "");
assert_eq!(config.tab_size, 0);
}
}
}

View file

@ -16,4 +16,4 @@ brackets = [
{ start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
]
debuggers = ["CodeLLDB", "GDB"]
documentation = { start = "/*", end = "*/", prefix = "* ", tab_size = 1 }
documentation_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }

View file

@ -16,4 +16,4 @@ brackets = [
{ start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
]
debuggers = ["CodeLLDB", "GDB"]
documentation = { start = "/*", end = "*/", prefix = "* ", tab_size = 1 }
documentation_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }

View file

@ -10,5 +10,5 @@ brackets = [
{ start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
]
completion_query_characters = ["-"]
block_comment = ["/* ", " */"]
block_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }
prettier_parser_name = "css"

View file

@ -15,4 +15,4 @@ brackets = [
tab_size = 4
hard_tabs = true
debuggers = ["Delve"]
documentation = { start = "/*", end = "*/", prefix = "* ", tab_size = 1 }
documentation_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }

View file

@ -4,7 +4,8 @@ path_suffixes = ["js", "jsx", "mjs", "cjs"]
# [/ ] is so we match "env node" or "/node" but not "ts-node"
first_line_pattern = '^#!.*\b(?:[/ ]node|deno run.*--ext[= ]js)\b'
line_comments = ["// "]
block_comment = ["/*", "*/"]
block_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }
documentation_comment = { start = "/**", prefix = "* ", end = "*/", tab_size = 1 }
autoclose_before = ";:.,=}])>"
brackets = [
{ start = "{", end = "}", close = true, newline = true },
@ -21,7 +22,6 @@ tab_size = 2
scope_opt_in_language_servers = ["tailwindcss-language-server", "emmet-language-server"]
prettier_parser_name = "babel"
debuggers = ["JavaScript"]
documentation = { start = "/**", end = "*/", prefix = "* ", tab_size = 1 }
[jsx_tag_auto_close]
open_tag_node_name = "jsx_opening_element"
@ -31,7 +31,7 @@ tag_name_node_name = "identifier"
[overrides.element]
line_comments = { remove = true }
block_comment = ["{/* ", " */}"]
block_comment = { start = "{/* ", prefix = "", end = "*/}", tab_size = 0 }
opt_into_language_servers = ["emmet-language-server"]
[overrides.string]

View file

@ -2,7 +2,7 @@ name = "Markdown"
grammar = "markdown"
path_suffixes = ["md", "mdx", "mdwn", "markdown", "MD"]
completion_query_characters = ["-"]
block_comment = ["<!-- ", " -->"]
block_comment = { start = "<!--", prefix = "", end = "-->", tab_size = 0 }
autoclose_before = ";:.,=}])>"
brackets = [
{ start = "{", end = "}", close = true, newline = true },

View file

@ -16,4 +16,4 @@ brackets = [
]
collapsed_placeholder = " /* ... */ "
debuggers = ["CodeLLDB", "GDB"]
documentation = { start = "/*", end = "*/", prefix = "* ", tab_size = 1 }
documentation_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }

View file

@ -2,7 +2,8 @@ name = "TSX"
grammar = "tsx"
path_suffixes = ["tsx"]
line_comments = ["// "]
block_comment = ["/*", "*/"]
block_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }
documentation_comment = { start = "/**", prefix = "* ", end = "*/", tab_size = 1 }
autoclose_before = ";:.,=}])>"
brackets = [
{ start = "{", end = "}", close = true, newline = true },
@ -19,7 +20,6 @@ scope_opt_in_language_servers = ["tailwindcss-language-server", "emmet-language-
prettier_parser_name = "typescript"
tab_size = 2
debuggers = ["JavaScript"]
documentation = { start = "/**", end = "*/", prefix = "* ", tab_size = 1 }
[jsx_tag_auto_close]
open_tag_node_name = "jsx_opening_element"
@ -30,7 +30,7 @@ tag_name_node_name_alternates = ["member_expression"]
[overrides.element]
line_comments = { remove = true }
block_comment = ["{/* ", " */}"]
block_comment = { start = "{/*", prefix = "", end = "*/}", tab_size = 0 }
opt_into_language_servers = ["emmet-language-server"]
[overrides.string]

View file

@ -3,7 +3,8 @@ grammar = "typescript"
path_suffixes = ["ts", "cts", "mts"]
first_line_pattern = '^#!.*\b(?:deno run|ts-node|bun|tsx|[/ ]node)\b'
line_comments = ["// "]
block_comment = ["/*", "*/"]
block_comment = { start = "/*", prefix = "* ", end = "*/", tab_size = 1 }
documentation_comment = { start = "/**", prefix = "* ", end = "*/", tab_size = 1 }
autoclose_before = ";:.,=}])>"
brackets = [
{ start = "{", end = "}", close = true, newline = true },
@ -19,7 +20,6 @@ word_characters = ["#", "$"]
prettier_parser_name = "typescript"
tab_size = 2
debuggers = ["JavaScript"]
documentation = { start = "/**", end = "*/", prefix = "* ", tab_size = 1 }
[overrides.string]
completion_query_characters = ["."]

View file

@ -12,7 +12,7 @@ path_suffixes = [
]
first_line_pattern = '^#version \d+'
line_comments = ["// "]
block_comment = ["/* ", " */"]
block_comment = { start = "/* ", prefix = "* ", end = "*/", tab_size = 1 }
brackets = [
{ start = "{", end = "}", close = true, newline = true },
{ start = "[", end = "]", close = true, newline = true },

View file

@ -2,7 +2,7 @@ name = "HTML"
grammar = "html"
path_suffixes = ["html", "htm", "shtml"]
autoclose_before = ">})"
block_comment = ["<!-- ", " -->"]
block_comment = { start = "<!--", prefix = "", end = "-->", tab_size = 0 }
brackets = [
{ start = "{", end = "}", close = true, newline = true },
{ start = "[", end = "]", close = true, newline = true },