Detailed changes
@@ -5318,6 +5318,16 @@ dependencies = [
"tree-sitter",
]
+[[package]]
+name = "tree-sitter-cpp"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a869e3c5cef4e5db4e9ab16a8dc84d73010e60ada14cdc60d2f6d8aed17779d"
+dependencies = [
+ "cc",
+ "tree-sitter",
+]
+
[[package]]
name = "tree-sitter-json"
version = "0.19.0"
@@ -6030,6 +6040,7 @@ dependencies = [
"toml",
"tree-sitter",
"tree-sitter-c",
+ "tree-sitter-cpp",
"tree-sitter-json 0.20.0",
"tree-sitter-markdown",
"tree-sitter-rust",
@@ -77,7 +77,8 @@ pub trait LspAdapter: 'static + Send + Sync {
container_dir: PathBuf,
) -> BoxFuture<'static, Result<PathBuf>>;
fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option<PathBuf>>;
- fn process_diagnostics(&self, diagnostics: &mut lsp::PublishDiagnosticsParams);
+
+ fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
fn label_for_completion(&self, _: &lsp::CompletionItem, _: &Language) -> Option<CodeLabel> {
None
@@ -88,6 +88,7 @@ tiny_http = "0.8"
toml = "0.5"
tree-sitter = "0.20.6"
tree-sitter-c = "0.20.1"
+tree-sitter-cpp = "0.20.0"
tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "137e1ce6a02698fc246cdb9c6b886ed1de9a1ed8" }
tree-sitter-rust = "0.20.1"
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
@@ -22,6 +22,11 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi
tree_sitter_c::language(),
Some(Arc::new(c::CLspAdapter) as Arc<dyn LspAdapter>),
),
+ (
+ "cpp",
+ tree_sitter_cpp::language(),
+ Some(Arc::new(c::CLspAdapter) as Arc<dyn LspAdapter>),
+ ),
(
"json",
tree_sitter_json::language(),
@@ -106,5 +106,139 @@ impl super::LspAdapter for CLspAdapter {
.boxed()
}
- fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
+ fn label_for_completion(
+ &self,
+ completion: &lsp::CompletionItem,
+ language: &Language,
+ ) -> Option<CodeLabel> {
+ let label = completion
+ .label
+ .strip_prefix("•")
+ .unwrap_or(&completion.label)
+ .trim();
+
+ match completion.kind {
+ Some(lsp::CompletionItemKind::FIELD) if completion.detail.is_some() => {
+ let detail = completion.detail.as_ref().unwrap();
+ let text = format!("{} {}", detail, label);
+ let source = Rope::from(format!("struct S {{ {} }}", text).as_str());
+ let runs = language.highlight_text(&source, 11..11 + text.len());
+ return Some(CodeLabel {
+ filter_range: detail.len() + 1..text.len(),
+ text,
+ runs,
+ });
+ }
+ Some(lsp::CompletionItemKind::CONSTANT | lsp::CompletionItemKind::VARIABLE)
+ if completion.detail.is_some() =>
+ {
+ let detail = completion.detail.as_ref().unwrap();
+ let text = format!("{} {}", detail, label);
+ let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
+ return Some(CodeLabel {
+ filter_range: detail.len() + 1..text.len(),
+ text,
+ runs,
+ });
+ }
+ Some(lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD)
+ if completion.detail.is_some() =>
+ {
+ let detail = completion.detail.as_ref().unwrap();
+ let text = format!("{} {}", detail, label);
+ let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
+ return Some(CodeLabel {
+ filter_range: detail.len() + 1..text.rfind('(').unwrap_or(text.len()),
+ text,
+ runs,
+ });
+ }
+ Some(kind) => {
+ let highlight_name = match kind {
+ lsp::CompletionItemKind::STRUCT
+ | lsp::CompletionItemKind::INTERFACE
+ | lsp::CompletionItemKind::CLASS
+ | lsp::CompletionItemKind::ENUM => Some("type"),
+ lsp::CompletionItemKind::ENUM_MEMBER => Some("variant"),
+ lsp::CompletionItemKind::KEYWORD => Some("keyword"),
+ lsp::CompletionItemKind::VALUE | lsp::CompletionItemKind::CONSTANT => {
+ Some("constant")
+ }
+ _ => None,
+ };
+ if let Some(highlight_id) = language
+ .grammar()
+ .and_then(|g| g.highlight_id_for_name(highlight_name?))
+ {
+ let mut label = CodeLabel::plain(label.to_string(), None);
+ label.runs.push((
+ 0..label.text.rfind('(').unwrap_or(label.text.len()),
+ highlight_id,
+ ));
+ return Some(label);
+ }
+ }
+ _ => {}
+ }
+ Some(CodeLabel::plain(label.to_string(), None))
+ }
+
+ fn label_for_symbol(
+ &self,
+ name: &str,
+ kind: lsp::SymbolKind,
+ language: &Language,
+ ) -> Option<CodeLabel> {
+ let (text, filter_range, display_range) = match kind {
+ lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => {
+ let text = format!("void {} () {{}}", name);
+ let filter_range = 0..name.len();
+ let display_range = 5..5 + name.len();
+ (text, filter_range, display_range)
+ }
+ lsp::SymbolKind::STRUCT => {
+ let text = format!("struct {} {{}}", name);
+ let filter_range = 7..7 + name.len();
+ let display_range = 0..filter_range.end;
+ (text, filter_range, display_range)
+ }
+ lsp::SymbolKind::ENUM => {
+ let text = format!("enum {} {{}}", name);
+ let filter_range = 5..5 + name.len();
+ let display_range = 0..filter_range.end;
+ (text, filter_range, display_range)
+ }
+ lsp::SymbolKind::INTERFACE | lsp::SymbolKind::CLASS => {
+ let text = format!("class {} {{}}", name);
+ let filter_range = 6..6 + name.len();
+ let display_range = 0..filter_range.end;
+ (text, filter_range, display_range)
+ }
+ lsp::SymbolKind::CONSTANT => {
+ let text = format!("const int {} = 0;", name);
+ let filter_range = 10..10 + name.len();
+ let display_range = 0..filter_range.end;
+ (text, filter_range, display_range)
+ }
+ lsp::SymbolKind::MODULE => {
+ let text = format!("namespace {} {{}}", name);
+ let filter_range = 10..10 + name.len();
+ let display_range = 0..filter_range.end;
+ (text, filter_range, display_range)
+ }
+ lsp::SymbolKind::TYPE_PARAMETER => {
+ let text = format!("typename {} {{}};", name);
+ let filter_range = 9..9 + name.len();
+ let display_range = 0..filter_range.end;
+ (text, filter_range, display_range)
+ }
+ _ => return None,
+ };
+
+ Some(CodeLabel {
+ runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
+ text: text[display_range].to_string(),
+ filter_range,
+ })
+ }
}
@@ -1,5 +1,5 @@
name = "C"
-path_suffixes = ["c", "h"]
+path_suffixes = ["c"]
line_comment = "// "
autoclose_before = ";:.,=}])>"
brackets = [
@@ -75,7 +75,6 @@
(comment) @comment
-(null) @constant
(number_literal) @number
[
@@ -0,0 +1,3 @@
+("[" @open "]" @close)
+("{" @open "}" @close)
+("\"" @open "\"" @close)
@@ -0,0 +1,11 @@
+name = "C++"
+path_suffixes = ["cc", "cpp", "h", "hpp"]
+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 = true, newline = false },
+]
@@ -0,0 +1,158 @@
+(call_expression
+ function: (qualified_identifier
+ name: (identifier) @function))
+
+(call_expression
+ function: (identifier) @function)
+
+(call_expression
+ function: (field_expression
+ field: (field_identifier) @function))
+
+(preproc_function_def
+ name: (identifier) @function.special)
+
+(template_function
+ name: (identifier) @function)
+
+(template_method
+ name: (field_identifier) @function)
+
+(function_declarator
+ declarator: (identifier) @function)
+
+(function_declarator
+ declarator: (qualified_identifier
+ name: (identifier) @function))
+
+(function_declarator
+ declarator: (field_identifier) @function)
+
+((namespace_identifier) @type
+ (#match? @type "^[A-Z]"))
+
+(auto) @type
+(type_identifier) @type
+
+(identifier) @variable
+
+((identifier) @constant
+ (#match? @constant "^[A-Z][A-Z\\d_]*$"))
+
+(field_identifier) @property
+(statement_identifier) @label
+(this) @variable.builtin
+
+[
+ "break"
+ "case"
+ "catch"
+ "class"
+ "co_await"
+ "co_return"
+ "co_yield"
+ "const"
+ "constexpr"
+ "continue"
+ "default"
+ "delete"
+ "do"
+ "else"
+ "enum"
+ "explicit"
+ "extern"
+ "final"
+ "for"
+ "friend"
+ "if"
+ "if"
+ "inline"
+ "mutable"
+ "namespace"
+ "new"
+ "noexcept"
+ "override"
+ "private"
+ "protected"
+ "public"
+ "return"
+ "sizeof"
+ "static"
+ "struct"
+ "switch"
+ "template"
+ "throw"
+ "try"
+ "typedef"
+ "typename"
+ "union"
+ "using"
+ "virtual"
+ "volatile"
+ "while"
+ (primitive_type)
+ (type_qualifier)
+] @keyword
+
+[
+ "#define"
+ "#elif"
+ "#else"
+ "#endif"
+ "#if"
+ "#ifdef"
+ "#ifndef"
+ "#include"
+ (preproc_directive)
+] @keyword
+
+(comment) @comment
+
+[
+ (true)
+ (false)
+ (null)
+ (nullptr)
+] @constant
+
+(number_literal) @number
+
+[
+ (string_literal)
+ (system_lib_string)
+ (char_literal)
+ (raw_string_literal)
+] @string
+
+[
+ "."
+ ";"
+] @punctuation.delimiter
+
+[
+ "{"
+ "}"
+ "("
+ ")"
+ "["
+ "]"
+] @punctuation.bracket
+
+[
+ "--"
+ "-"
+ "-="
+ "->"
+ "="
+ "!="
+ "*"
+ "&"
+ "&&"
+ "+"
+ "++"
+ "+="
+ "<"
+ "=="
+ ">"
+ "||"
+] @operator
@@ -0,0 +1,7 @@
+[
+ (field_expression)
+ (assignment_expression)
+] @indent
+
+(_ "{" "}" @end) @indent
+(_ "(" ")" @end) @indent
@@ -0,0 +1,101 @@
+(preproc_def
+ "#define" @context
+ name: (_) @name) @item
+
+(preproc_function_def
+ "#define" @context
+ name: (_) @name
+ parameters: (preproc_params
+ "(" @context
+ ")" @context)) @item
+
+(type_definition
+ "typedef" @context
+ declarator: (_) @name) @item
+
+(struct_specifier
+ "struct" @context
+ name: (_) @name) @item
+
+(class_specifier
+ "class" @context
+ name: (_) @name) @item
+
+(enum_specifier
+ "enum" @context
+ name: (_) @name) @item
+
+(enumerator
+ name: (_) @name) @item
+
+(declaration
+ (storage_class_specifier) @context
+ (type_qualifier)? @context
+ type: (_) @context
+ declarator: (init_declarator
+ declarator: (_) @name)) @item
+
+(function_definition
+ (type_qualifier)? @context
+ type: (_)? @context
+ declarator: [
+ (function_declarator
+ declarator: (_) @name
+ parameters: (parameter_list
+ "(" @context
+ ")" @context))
+ (pointer_declarator
+ "*" @context
+ declarator: (function_declarator
+ declarator: (_) @name
+ parameters: (parameter_list
+ "(" @context
+ ")" @context)))
+ ]
+ (type_qualifier)? @context) @item
+
+(declaration
+ (type_qualifier)? @context
+ type: (_)? @context
+ declarator: [
+ (field_identifier) @name
+ (pointer_declarator
+ "*" @context
+ declarator: (field_identifier) @name)
+ (function_declarator
+ declarator: (_) @name
+ parameters: (parameter_list
+ "(" @context
+ ")" @context))
+ (pointer_declarator
+ "*" @context
+ declarator: (function_declarator
+ declarator: (_) @name
+ parameters: (parameter_list
+ "(" @context
+ ")" @context)))
+ ]
+ (type_qualifier)? @context) @item
+
+(field_declaration
+ (type_qualifier)? @context
+ type: (_) @context
+ declarator: [
+ (field_identifier) @name
+ (pointer_declarator
+ "*" @context
+ declarator: (field_identifier) @name)
+ (function_declarator
+ declarator: (_) @name
+ parameters: (parameter_list
+ "(" @context
+ ")" @context))
+ (pointer_declarator
+ "*" @context
+ declarator: (function_declarator
+ declarator: (_) @name
+ parameters: (parameter_list
+ "(" @context
+ ")" @context)))
+ ]
+ (type_qualifier)? @context) @item
@@ -120,8 +120,6 @@ impl LspAdapter for JsonLspAdapter {
.boxed()
}
- fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
-
fn initialization_options(&self) -> Option<serde_json::Value> {
Some(json!({
"provideFormatter": true
@@ -113,8 +113,6 @@ impl LspAdapter for TypeScriptLspAdapter {
.boxed()
}
- fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
-
fn label_for_completion(
&self,
item: &lsp::CompletionItem,
@@ -74,6 +74,20 @@ fn main() {
..Default::default()
},
)
+ .with_overrides(
+ "C",
+ settings::LanguageOverride {
+ tab_size: Some(2),
+ ..Default::default()
+ },
+ )
+ .with_overrides(
+ "C++",
+ settings::LanguageOverride {
+ tab_size: Some(2),
+ ..Default::default()
+ },
+ )
.with_overrides(
"Markdown",
settings::LanguageOverride {