dart: Extract to zed-extensions/dart repository (#19959)

Marshall Bowers created

This PR extracts the Dart extension to the
[zed-extensions/dart](https://github.com/zed-extensions/dart)
repository.

Release Notes:

- N/A

Change summary

Cargo.lock                                    |   7 
Cargo.toml                                    |   1 
docs/src/languages/dart.md                    |   2 
extensions/dart/Cargo.toml                    |  16 -
extensions/dart/LICENSE-APACHE                |   1 
extensions/dart/README.md                     |   6 
extensions/dart/extension.toml                |  16 -
extensions/dart/languages/dart/brackets.scm   |   6 
extensions/dart/languages/dart/config.toml    |  15 -
extensions/dart/languages/dart/highlights.scm | 269 ---------------------
extensions/dart/languages/dart/indents.scm    |   3 
extensions/dart/languages/dart/outline.scm    |  18 -
extensions/dart/languages/dart/runnables.scm  |  45 ---
extensions/dart/languages/dart/tasks.json     |  26 --
extensions/dart/src/dart.rs                   | 162 ------------
15 files changed, 1 insertion(+), 592 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -15173,13 +15173,6 @@ dependencies = [
  "zed_extension_api 0.1.0",
 ]
 
-[[package]]
-name = "zed_dart"
-version = "0.1.2"
-dependencies = [
- "zed_extension_api 0.1.0",
-]
-
 [[package]]
 name = "zed_deno"
 version = "0.0.2"

Cargo.toml 🔗

@@ -138,7 +138,6 @@ members = [
     "extensions/astro",
     "extensions/clojure",
     "extensions/csharp",
-    "extensions/dart",
     "extensions/deno",
     "extensions/elixir",
     "extensions/elm",

docs/src/languages/dart.md 🔗

@@ -1,6 +1,6 @@
 # Dart
 
-Dart support is available through the [Dart extension](https://github.com/zed-industries/zed/tree/main/extensions/dart).
+Dart support is available through the [Dart extension](https://github.com/zed-extensions/dart).
 
 - Tree Sitter: [UserNobody14/tree-sitter-dart](https://github.com/UserNobody14/tree-sitter-dart)
 - Language Server: [dart language-server](https://github.com/dart-lang/sdk)

extensions/dart/Cargo.toml 🔗

@@ -1,16 +0,0 @@
-[package]
-name = "zed_dart"
-version = "0.1.2"
-edition = "2021"
-publish = false
-license = "Apache-2.0"
-
-[lints]
-workspace = true
-
-[lib]
-path = "src/dart.rs"
-crate-type = ["cdylib"]
-
-[dependencies]
-zed_extension_api = "0.1.0"

extensions/dart/README.md 🔗

@@ -1,6 +0,0 @@
-## Roadmap
-
-1. Add `dart run` command.
-2. Add `dart test` command.
-3. Add `flutter test --name` command, to allow running a single test or group of tests.
-4. Auto hot reload Flutter app when files change.

extensions/dart/extension.toml 🔗

@@ -1,16 +0,0 @@
-id = "dart"
-name = "Dart"
-description = "Dart support."
-version = "0.1.2"
-schema_version = 1
-authors = ["Abdullah Alsigar <abdullah.alsigar@gmail.com>", "Flo <flo80@users.noreply.github.com>", "ybbond <hi@ybbond.id>"]
-repository = "https://github.com/zed-industries/zed"
-
-[language_servers.dart]
-name = "Dart LSP"
-language = "Dart"
-languages = ["Dart"]
-
-[grammars.dart]
-repository = "https://github.com/UserNobody14/tree-sitter-dart"
-commit = "6da46473ab8accb13da48113f4634e729a71d335"

extensions/dart/languages/dart/config.toml 🔗

@@ -1,15 +0,0 @@
-name = "Dart"
-grammar = "dart"
-path_suffixes = ["dart"]
-line_comments = ["// ", "/// "]
-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, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["string", "comment"] },
-]

extensions/dart/languages/dart/highlights.scm 🔗

@@ -1,269 +0,0 @@
-(dotted_identifier_list) @string
-
-; Methods
-; --------------------
-(super) @function
-
-(function_expression_body (identifier) @type)
-; ((identifier)(selector (argument_part)) @function)
-
-(((identifier) @function (#match? @function "^_?[a-z]"))
- . (selector . (argument_part))) @function
-
-; Annotations
-; --------------------
-(annotation
- name: (identifier) @attribute)
-
-; Operators and Tokens
-; --------------------
-(template_substitution
- "$" @punctuation.special
- "{" @punctuation.special
- "}" @punctuation.special) @none
-
-(template_substitution
- "$" @punctuation.special
- (identifier_dollar_escaped) @variable) @none
-
-(escape_sequence) @string.escape
-
-[
- "@"
- "=>"
- ".."
- "??"
- "=="
- "?"
- ":"
- "&&"
- "%"
- "<"
- ">"
- "="
- ">="
- "<="
- "||"
- (multiplicative_operator)
- (increment_operator)
- (is_operator)
- (prefix_operator)
- (equality_operator)
- (additive_operator)
- ] @operator
-
-[
- "("
- ")"
- "["
- "]"
- "{"
- "}"
- ] @punctuation.bracket
-
-; Delimiters
-; --------------------
-[
- ";"
- "."
- ","
- ] @punctuation.delimiter
-
-; Types
-; --------------------
-(class_definition
- name: (identifier) @type)
-(constructor_signature
- name: (identifier) @type)
-(scoped_identifier
- scope: (identifier) @type)
-(function_signature
- name: (identifier) @function.method)
-
-(getter_signature
- (identifier) @function.method)
-
-(setter_signature
- name: (identifier) @function.method)
-(enum_declaration
- name: (identifier) @type)
-(enum_constant
- name: (identifier) @type)
-(void_type) @type
-
-((scoped_identifier
-  scope: (identifier) @type
-  name: (identifier) @type)
- (#match? @type "^[a-zA-Z]"))
-
-(type_identifier) @type
-
-(type_alias
- (type_identifier) @type.definition)
-
-; Variables
-; --------------------
-; var keyword
-(inferred_type) @keyword
-
-((identifier) @type
- (#match? @type "^_?[A-Z].*[a-z]"))
-
-("Function" @type)
-
-; properties
-(unconditional_assignable_selector
- (identifier) @property)
-
-(conditional_assignable_selector
- (identifier) @property)
-
-; assignments
-(assignment_expression
- left: (assignable_expression) @variable)
-
-(this) @variable.builtin
-
-; Parameters
-; --------------------
-(formal_parameter
- name: (identifier) @variable.parameter)
-
-(named_argument
- (label
-    (identifier) @variable.parameter))
-
-; Literals
-; --------------------
-[
- (hex_integer_literal)
- (decimal_integer_literal)
- (decimal_floating_point_literal)
- ; TODO: inaccessible nodes
- ; (octal_integer_literal)
- ; (hex_floating_point_literal)
- ] @number
-
-(symbol_literal) @string.special.symbol
-
-(string_literal) @string
-(true) @boolean
-(false) @boolean
-(null_literal) @constant.builtin
-
-(comment) @comment
-
-(documentation_comment) @comment.documentation
-
-; Keywords
-; --------------------
-[
- "import"
- "library"
- "export"
- "as"
- "show"
- "hide"
- ] @keyword.import
-
-; Reserved words (cannot be used as identifiers)
-[
-  (case_builtin)
- "late"
- "required"
- "extension"
- "on"
- "class"
- "enum"
- "extends"
- "in"
- "is"
- "new"
- "super"
- "with"
- ] @keyword
-
-"return" @keyword.return
-
-; Built in identifiers:
-; alone these are marked as keywords
-[
-  "deferred"
- "factory"
- "get"
- "implements"
- "interface"
- "library"
- "operator"
- "mixin"
- "part"
- "set"
- "typedef"
- ] @keyword
-
-[
-  "async"
-  "async*"
-  "sync*"
-  "await"
-  "yield"
-] @keyword.coroutine
-
-[
- (const_builtin)
- (final_builtin)
- "abstract"
-  "covariant"
- "dynamic"
- "external"
- "static"
- "final"
-  "base"
-  "sealed"
- ] @type.qualifier
-
-; when used as an identifier:
-((identifier) @variable.builtin
- (#any-of? @variable.builtin
-           "abstract"
-           "as"
-           "covariant"
-           "deferred"
-           "dynamic"
-           "export"
-           "external"
-           "factory"
-           "Function"
-           "get"
-           "implements"
-           "import"
-           "interface"
-           "library"
-           "operator"
-           "mixin"
-           "part"
-           "set"
-           "static"
-           "typedef"))
-
-[
-  "if"
-  "else"
-  "switch"
-  "default"
-] @keyword.conditional
-
-[
-  "try"
-  "throw"
-  "catch"
-  "finally"
-  (break_statement)
-] @keyword.exception
-
-[
-  "do"
-  "while"
-  "continue"
-  "for"
-] @keyword.repeat

extensions/dart/languages/dart/outline.scm 🔗

@@ -1,18 +0,0 @@
-(class_definition
-    "class" @context
-    name: (_) @name) @item
-
-(function_signature
-    name: (_) @name) @item
-
-(getter_signature
-    "get" @context
-    name: (_) @name) @item
-
-(setter_signature
-    "set" @context
-    name: (_) @name) @item
-
-(enum_declaration
-    "enum" @context
-    name: (_) @name) @item

extensions/dart/languages/dart/runnables.scm 🔗

@@ -1,45 +0,0 @@
-; Flutter main
-(
-    (
-        (import_or_export
-            (library_import
-                (import_specification
-                    ("import"
-                        (configurable_uri
-                            (uri
-                                (string_literal) @_import
-                                (#match? @_import "package:flutter/(material|widgets|cupertino).dart")
-                                (#not-match? @_import "package:flutter_test/flutter_test.dart")
-                                (#not-match? @_import "package:test/test.dart")
-        ))))))
-        (
-            (function_signature
-                name: (_) @run
-            )
-            (#eq? @run "main")
-        )
-        (#set! tag flutter-main)
-    )
-)
-
-; Flutter test main
-(
-    (
-        (import_or_export
-            (library_import
-                (import_specification
-                    ("import"
-                        (configurable_uri
-                            (uri
-                                (string_literal) @_import
-                                (#match? @_import "package:flutter_test/flutter_test.dart")
-        ))))))
-        (
-            (function_signature
-                name: (_) @run
-            )
-            (#eq? @run "main")
-        )
-        (#set! tag flutter-test-main)
-    )
-)

extensions/dart/languages/dart/tasks.json 🔗

@@ -1,26 +0,0 @@
-[
-  {
-    "label": "flutter run",
-    "command": "flutter",
-    "args": ["run"],
-    "tags": ["flutter-main"]
-  },
-  {
-    "label": "fvm flutter run",
-    "command": "fvm flutter",
-    "args": ["run"],
-    "tags": ["flutter-main"]
-  },
-  {
-    "label": "flutter test $ZED_STEM",
-    "command": "flutter",
-    "args": ["test", "$ZED_FILE"],
-    "tags": ["flutter-test-main"]
-  },
-  {
-    "label": "fvm flutter test $ZED_STEM",
-    "command": "fvm flutter",
-    "args": ["test", "$ZED_FILE"],
-    "tags": ["flutter-test-main"]
-  }
-]

extensions/dart/src/dart.rs 🔗

@@ -1,162 +0,0 @@
-use zed::lsp::CompletionKind;
-use zed::settings::LspSettings;
-use zed::{CodeLabel, CodeLabelSpan};
-use zed_extension_api::{self as zed, serde_json, Result};
-
-struct DartBinary {
-    pub path: String,
-    pub args: Option<Vec<String>>,
-}
-
-struct DartExtension;
-
-impl DartExtension {
-    fn language_server_binary(
-        &mut self,
-        _language_server_id: &zed::LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<DartBinary> {
-        let binary_settings = LspSettings::for_worktree("dart", worktree)
-            .ok()
-            .and_then(|lsp_settings| lsp_settings.binary);
-        let binary_args = binary_settings
-            .as_ref()
-            .and_then(|binary_settings| binary_settings.arguments.clone());
-
-        if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) {
-            return Ok(DartBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        if let Some(path) = worktree.which("dart") {
-            return Ok(DartBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        Err(
-            "dart must be installed from dart.dev/get-dart or pointed to by the LSP binary settings"
-                .to_string(),
-        )
-    }
-}
-
-impl zed::Extension for DartExtension {
-    fn new() -> Self {
-        Self
-    }
-
-    fn language_server_command(
-        &mut self,
-        language_server_id: &zed::LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<zed::Command> {
-        let dart_binary = self.language_server_binary(language_server_id, worktree)?;
-
-        Ok(zed::Command {
-            command: dart_binary.path,
-            args: dart_binary.args.unwrap_or_else(|| {
-                vec!["language-server".to_string(), "--protocol=lsp".to_string()]
-            }),
-            env: Default::default(),
-        })
-    }
-
-    fn language_server_workspace_configuration(
-        &mut self,
-        _language_server_id: &zed::LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<Option<serde_json::Value>> {
-        let settings = LspSettings::for_worktree("dart", worktree)
-            .ok()
-            .and_then(|lsp_settings| lsp_settings.settings.clone())
-            .unwrap_or_default();
-
-        Ok(Some(serde_json::json!({
-            "dart": settings
-        })))
-    }
-
-    fn label_for_completion(
-        &self,
-        _language_server_id: &zed::LanguageServerId,
-        completion: zed::lsp::Completion,
-    ) -> Option<CodeLabel> {
-        let arrow = " → ";
-
-        match completion.kind? {
-            CompletionKind::Class => Some(CodeLabel {
-                filter_range: (0..completion.label.len()).into(),
-                spans: vec![CodeLabelSpan::literal(
-                    completion.label,
-                    Some("type".into()),
-                )],
-                code: String::new(),
-            }),
-            CompletionKind::Function | CompletionKind::Constructor | CompletionKind::Method => {
-                let mut parts = completion.detail.as_ref()?.split(arrow);
-                let (name, _) = completion.label.split_once('(')?;
-                let parameter_list = parts.next()?;
-                let return_type = parts.next()?;
-                let fn_name = " a";
-                let fat_arrow = " => ";
-                let call_expr = "();";
-
-                let code =
-                    format!("{return_type}{fn_name}{parameter_list}{fat_arrow}{name}{call_expr}");
-
-                let parameter_list_start = return_type.len() + fn_name.len();
-
-                Some(CodeLabel {
-                    spans: vec![
-                        CodeLabelSpan::code_range(
-                            code.len() - call_expr.len() - name.len()..code.len() - call_expr.len(),
-                        ),
-                        CodeLabelSpan::code_range(
-                            parameter_list_start..parameter_list_start + parameter_list.len(),
-                        ),
-                        CodeLabelSpan::literal(arrow, None),
-                        CodeLabelSpan::code_range(0..return_type.len()),
-                    ],
-                    filter_range: (0..name.len()).into(),
-                    code,
-                })
-            }
-            CompletionKind::Property => {
-                let class_start = "class A {";
-                let get = " get ";
-                let property_end = " => a; }";
-                let ty = completion.detail?;
-                let name = completion.label;
-
-                let code = format!("{class_start}{ty}{get}{name}{property_end}");
-                let name_start = class_start.len() + ty.len() + get.len();
-
-                Some(CodeLabel {
-                    spans: vec![
-                        CodeLabelSpan::code_range(name_start..name_start + name.len()),
-                        CodeLabelSpan::literal(arrow, None),
-                        CodeLabelSpan::code_range(class_start.len()..class_start.len() + ty.len()),
-                    ],
-                    filter_range: (0..name.len()).into(),
-                    code,
-                })
-            }
-            CompletionKind::Variable => {
-                let name = completion.label;
-
-                Some(CodeLabel {
-                    filter_range: (0..name.len()).into(),
-                    spans: vec![CodeLabelSpan::literal(name, Some("variable".into()))],
-                    code: String::new(),
-                })
-            }
-            _ => None,
-        }
-    }
-}
-
-zed::register_extension!(DartExtension);