mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-29 04:20:46 +00:00
Merge pull request #1098 from zed-industries/cpp
Introduce support for C++
This commit is contained in:
commit
3ce739f759
15 changed files with 449 additions and 8 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -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
|
||||
|
||||
[
|
||||
|
|
3
crates/zed/src/languages/cpp/brackets.scm
Normal file
3
crates/zed/src/languages/cpp/brackets.scm
Normal file
|
@ -0,0 +1,3 @@
|
|||
("[" @open "]" @close)
|
||||
("{" @open "}" @close)
|
||||
("\"" @open "\"" @close)
|
11
crates/zed/src/languages/cpp/config.toml
Normal file
11
crates/zed/src/languages/cpp/config.toml
Normal file
|
@ -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 },
|
||||
]
|
158
crates/zed/src/languages/cpp/highlights.scm
Normal file
158
crates/zed/src/languages/cpp/highlights.scm
Normal file
|
@ -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
|
7
crates/zed/src/languages/cpp/indents.scm
Normal file
7
crates/zed/src/languages/cpp/indents.scm
Normal file
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
(field_expression)
|
||||
(assignment_expression)
|
||||
] @indent
|
||||
|
||||
(_ "{" "}" @end) @indent
|
||||
(_ "(" ")" @end) @indent
|
101
crates/zed/src/languages/cpp/outline.scm
Normal file
101
crates/zed/src/languages/cpp/outline.scm
Normal file
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue