diff --git a/Cargo.lock b/Cargo.lock index 882558c051..9a3a333fe3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index a9a266a6b7..7e203a15ff 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -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" } diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index 36900e3e71..ab2bb16d17 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -4,6 +4,7 @@ use rust_embed::RustEmbed; use std::{borrow::Cow, str, sync::Arc}; mod c; +mod cpp; mod installation; mod json; mod rust; @@ -22,6 +23,11 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi tree_sitter_c::language(), Some(Arc::new(c::CLspAdapter) as Arc), ), + ( + "cpp", + tree_sitter_cpp::language(), + Some(Arc::new(cpp::CppLspAdapter) as Arc), + ), ( "json", tree_sitter_json::language(), diff --git a/crates/zed/src/languages/c/config.toml b/crates/zed/src/languages/c/config.toml index b7e1f07443..5b48415610 100644 --- a/crates/zed/src/languages/c/config.toml +++ b/crates/zed/src/languages/c/config.toml @@ -1,5 +1,5 @@ name = "C" -path_suffixes = ["c", "h"] +path_suffixes = ["c"] line_comment = "// " autoclose_before = ";:.,=}])>" brackets = [ diff --git a/crates/zed/src/languages/c/highlights.scm b/crates/zed/src/languages/c/highlights.scm index 4a9c7bf2ea..007c871ffa 100644 --- a/crates/zed/src/languages/c/highlights.scm +++ b/crates/zed/src/languages/c/highlights.scm @@ -75,7 +75,6 @@ (comment) @comment -(null) @constant (number_literal) @number [ diff --git a/crates/zed/src/languages/cpp.rs b/crates/zed/src/languages/cpp.rs new file mode 100644 index 0000000000..d6e4bf0819 --- /dev/null +++ b/crates/zed/src/languages/cpp.rs @@ -0,0 +1,35 @@ +use anyhow::Result; +use client::http::HttpClient; +use futures::future::BoxFuture; +pub use language::*; +use std::{any::Any, path::PathBuf, sync::Arc}; + +pub struct CppLspAdapter; + +impl super::LspAdapter for CppLspAdapter { + fn name(&self) -> LanguageServerName { + LanguageServerName("clangd".into()) + } + + fn fetch_latest_server_version( + &self, + http: Arc, + ) -> BoxFuture<'static, Result>> { + super::c::CLspAdapter.fetch_latest_server_version(http) + } + + fn fetch_server_binary( + &self, + version: Box, + http: Arc, + container_dir: PathBuf, + ) -> BoxFuture<'static, Result> { + super::c::CLspAdapter.fetch_server_binary(version, http, container_dir) + } + + fn cached_server_binary(&self, container_dir: PathBuf) -> BoxFuture<'static, Option> { + super::c::CLspAdapter.cached_server_binary(container_dir) + } + + fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {} +} diff --git a/crates/zed/src/languages/cpp/brackets.scm b/crates/zed/src/languages/cpp/brackets.scm new file mode 100644 index 0000000000..9e8c9cd93c --- /dev/null +++ b/crates/zed/src/languages/cpp/brackets.scm @@ -0,0 +1,3 @@ +("[" @open "]" @close) +("{" @open "}" @close) +("\"" @open "\"" @close) diff --git a/crates/zed/src/languages/cpp/config.toml b/crates/zed/src/languages/cpp/config.toml new file mode 100644 index 0000000000..e9a793ec3c --- /dev/null +++ b/crates/zed/src/languages/cpp/config.toml @@ -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 }, +] diff --git a/crates/zed/src/languages/cpp/highlights.scm b/crates/zed/src/languages/cpp/highlights.scm new file mode 100644 index 0000000000..d579d70187 --- /dev/null +++ b/crates/zed/src/languages/cpp/highlights.scm @@ -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 diff --git a/crates/zed/src/languages/cpp/indents.scm b/crates/zed/src/languages/cpp/indents.scm new file mode 100644 index 0000000000..a17f4c4821 --- /dev/null +++ b/crates/zed/src/languages/cpp/indents.scm @@ -0,0 +1,7 @@ +[ + (field_expression) + (assignment_expression) +] @indent + +(_ "{" "}" @end) @indent +(_ "(" ")" @end) @indent diff --git a/crates/zed/src/languages/cpp/outline.scm b/crates/zed/src/languages/cpp/outline.scm new file mode 100644 index 0000000000..cefbac314d --- /dev/null +++ b/crates/zed/src/languages/cpp/outline.scm @@ -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 diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 20d467f276..794c6eff34 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -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 {