ocaml: Extract to zed-extensions/ocaml repository (#20825)
This PR extracts the OCaml extensions to the [zed-extensions/ocaml](https://github.com/zed-extensions/ocaml) repository. Release Notes: - N/A
This commit is contained in:
parent
ad94ad511a
commit
df1d0dec0a
20 changed files with 1 additions and 650 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -15346,13 +15346,6 @@ dependencies = [
|
||||||
"zed_extension_api 0.1.0",
|
"zed_extension_api 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zed_ocaml"
|
|
||||||
version = "0.1.1"
|
|
||||||
dependencies = [
|
|
||||||
"zed_extension_api 0.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zed_php"
|
name = "zed_php"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
|
@ -148,7 +148,6 @@ members = [
|
||||||
"extensions/haskell",
|
"extensions/haskell",
|
||||||
"extensions/html",
|
"extensions/html",
|
||||||
"extensions/lua",
|
"extensions/lua",
|
||||||
"extensions/ocaml",
|
|
||||||
"extensions/php",
|
"extensions/php",
|
||||||
"extensions/perplexity",
|
"extensions/perplexity",
|
||||||
"extensions/prisma",
|
"extensions/prisma",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# OCaml
|
# OCaml
|
||||||
|
|
||||||
OCaml support is available through the [OCaml extension](https://github.com/zed-industries/zed/tree/main/extensions/ocaml).
|
OCaml support is available through the [OCaml extension](https://github.com/zed-extensions/ocaml).
|
||||||
|
|
||||||
- Tree Sitter: [tree-sitter/tree-sitter-ocaml](https://github.com/tree-sitter/tree-sitter-ocaml)
|
- Tree Sitter: [tree-sitter/tree-sitter-ocaml](https://github.com/tree-sitter/tree-sitter-ocaml)
|
||||||
- Language Server: [ocaml/ocaml-lsp](https://github.com/ocaml/ocaml-lsp)
|
- Language Server: [ocaml/ocaml-lsp](https://github.com/ocaml/ocaml-lsp)
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "zed_ocaml"
|
|
||||||
version = "0.1.1"
|
|
||||||
edition = "2021"
|
|
||||||
publish = false
|
|
||||||
license = "Apache-2.0"
|
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "src/ocaml.rs"
|
|
||||||
crate-type = ["cdylib"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
zed_extension_api = "0.1.0"
|
|
|
@ -1 +0,0 @@
|
||||||
../../LICENSE-APACHE
|
|
|
@ -1,25 +0,0 @@
|
||||||
id = "ocaml"
|
|
||||||
name = "OCaml"
|
|
||||||
description = "OCaml support."
|
|
||||||
version = "0.1.1"
|
|
||||||
schema_version = 1
|
|
||||||
authors = ["Rashid Almheiri <69181766+huwaireb@users.noreply.github.com>"]
|
|
||||||
repository = "https://github.com/zed-industries/zed"
|
|
||||||
|
|
||||||
[language_servers.ocamllsp]
|
|
||||||
name = "ocamllsp"
|
|
||||||
languages = ["OCaml", "OCaml Interface"]
|
|
||||||
|
|
||||||
[grammars.ocaml]
|
|
||||||
repository = "https://github.com/tree-sitter/tree-sitter-ocaml"
|
|
||||||
commit = "0b12614ded3ec7ed7ab7933a9ba4f695ba4c342e"
|
|
||||||
path = "grammars/ocaml"
|
|
||||||
|
|
||||||
[grammars.ocaml_interface]
|
|
||||||
repository = "https://github.com/tree-sitter/tree-sitter-ocaml"
|
|
||||||
commit = "0b12614ded3ec7ed7ab7933a9ba4f695ba4c342e"
|
|
||||||
path = "grammars/interface"
|
|
||||||
|
|
||||||
[grammars.dune]
|
|
||||||
repository = "https://github.com/WHForks/tree-sitter-dune"
|
|
||||||
commit = "b3f7882e1b9a1d8811011bf6f0de1c74c9c93949"
|
|
|
@ -1,8 +0,0 @@
|
||||||
name = "Dune"
|
|
||||||
grammar = "dune"
|
|
||||||
path_suffixes = ["dune", "dune-project"]
|
|
||||||
brackets = [
|
|
||||||
{ start = "(", end = ")", close = true, newline = true },
|
|
||||||
{ start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }
|
|
||||||
]
|
|
||||||
tab_size = 2
|
|
|
@ -1,5 +0,0 @@
|
||||||
(stanza_name) @function
|
|
||||||
(field_name) @property
|
|
||||||
(quoted_string) @string
|
|
||||||
(multiline_string) @string
|
|
||||||
(action_name) @keyword
|
|
|
@ -1,2 +0,0 @@
|
||||||
((ocaml_syntax) @injection.content
|
|
||||||
(#set! injection.language "ocaml"))
|
|
|
@ -1,2 +0,0 @@
|
||||||
("(" @open ")" @close)
|
|
||||||
("{" @open "}" @close)
|
|
|
@ -1,12 +0,0 @@
|
||||||
name = "OCaml Interface"
|
|
||||||
code_fence_block_name = "ocaml"
|
|
||||||
grammar = "ocaml_interface"
|
|
||||||
path_suffixes = ["mli"]
|
|
||||||
block_comment = ["(* ", " *)"]
|
|
||||||
autoclose_before = ";,=)}"
|
|
||||||
brackets = [
|
|
||||||
{ start = "{", end = "}", close = true, newline = true },
|
|
||||||
{ start = "[", end = "]", close = true, newline = true },
|
|
||||||
{ start = "(", end = ")", close = true, newline = true }
|
|
||||||
]
|
|
||||||
tab_size = 2
|
|
|
@ -1 +0,0 @@
|
||||||
../ocaml/highlights.scm
|
|
|
@ -1,21 +0,0 @@
|
||||||
[
|
|
||||||
(type_binding)
|
|
||||||
|
|
||||||
(value_specification)
|
|
||||||
(method_specification)
|
|
||||||
|
|
||||||
(external)
|
|
||||||
(field_declaration)
|
|
||||||
] @indent
|
|
||||||
|
|
||||||
(_ "<" ">" @end) @indent
|
|
||||||
(_ "{" "}" @end) @indent
|
|
||||||
(_ "(" ")" @end) @indent
|
|
||||||
|
|
||||||
(_ "object" @start "end" @end) @indent
|
|
||||||
|
|
||||||
(signature
|
|
||||||
"sig" @start
|
|
||||||
"end" @end) @indent
|
|
||||||
|
|
||||||
";;" @outdent
|
|
|
@ -1,48 +0,0 @@
|
||||||
(module_type_definition
|
|
||||||
"module" @context
|
|
||||||
"type" @context
|
|
||||||
name: (_) @name) @item
|
|
||||||
|
|
||||||
(module_definition
|
|
||||||
"module" @context
|
|
||||||
(module_binding name: (_) @name)) @item
|
|
||||||
|
|
||||||
(type_definition
|
|
||||||
"type" @context
|
|
||||||
(type_binding name: (_) @name)) @item
|
|
||||||
|
|
||||||
(class_definition
|
|
||||||
"class" @context
|
|
||||||
(class_binding
|
|
||||||
"virtual"? @context
|
|
||||||
name: (_) @name)) @item
|
|
||||||
|
|
||||||
(class_type_definition
|
|
||||||
"class" @context
|
|
||||||
"type" @context
|
|
||||||
(class_type_binding
|
|
||||||
"virtual"? @context
|
|
||||||
name: (_) @name)) @item
|
|
||||||
|
|
||||||
(instance_variable_definition
|
|
||||||
"val" @context
|
|
||||||
"method"? @context
|
|
||||||
name: (_) @name) @item
|
|
||||||
|
|
||||||
(method_specification
|
|
||||||
"method" @context
|
|
||||||
"virtual"? @context
|
|
||||||
(method_name) @name) @item
|
|
||||||
|
|
||||||
(value_specification
|
|
||||||
"val" @context
|
|
||||||
(value_name) @name) @item
|
|
||||||
|
|
||||||
(external
|
|
||||||
"external" @context
|
|
||||||
(value_name) @name) @item
|
|
||||||
|
|
||||||
(exception_definition
|
|
||||||
"exception" @context
|
|
||||||
(constructor_declaration
|
|
||||||
(constructor_name) @name)) @item
|
|
|
@ -1,5 +0,0 @@
|
||||||
("(" @open ")" @close)
|
|
||||||
("[" @open "]" @close)
|
|
||||||
("[|" @open "|]" @close)
|
|
||||||
("{" @open "}" @close)
|
|
||||||
("\"" @open "\"" @close)
|
|
|
@ -1,14 +0,0 @@
|
||||||
name = "OCaml"
|
|
||||||
grammar = "ocaml"
|
|
||||||
path_suffixes = ["ml"]
|
|
||||||
block_comment = ["(* ", " *)"]
|
|
||||||
autoclose_before = ";,=)}]"
|
|
||||||
brackets = [
|
|
||||||
{ start = "{", end = "}", close = true, newline = true },
|
|
||||||
{ start = "{|", end = "|", close = true, newline = true, not_in = ["string"] },
|
|
||||||
{ start = "[", end = "]", close = true, newline = true },
|
|
||||||
{ start = "[|", end = "|", close = true, newline = true, not_in = ["string"] },
|
|
||||||
{ start = "(", end = ")", close = true, newline = true },
|
|
||||||
{ start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }
|
|
||||||
]
|
|
||||||
tab_size = 2
|
|
|
@ -1,158 +0,0 @@
|
||||||
; Modules
|
|
||||||
;--------
|
|
||||||
|
|
||||||
[(module_name) (module_type_name)] @title
|
|
||||||
|
|
||||||
; Types
|
|
||||||
;------
|
|
||||||
|
|
||||||
[(class_name) (class_type_name) (type_constructor)] @type
|
|
||||||
|
|
||||||
(tag) @variant ;; Polymorphic Variants
|
|
||||||
(constructor_name) @constructor ;; Exceptions, variants and the like
|
|
||||||
|
|
||||||
; Functions
|
|
||||||
;----------
|
|
||||||
|
|
||||||
(let_binding
|
|
||||||
pattern: (value_name) @function
|
|
||||||
(parameter))
|
|
||||||
|
|
||||||
(let_binding
|
|
||||||
pattern: (value_name) @function
|
|
||||||
body: [(fun_expression) (function_expression)])
|
|
||||||
|
|
||||||
(value_specification (value_name) @function)
|
|
||||||
|
|
||||||
(external (value_name) @function)
|
|
||||||
|
|
||||||
(method_name) @function
|
|
||||||
|
|
||||||
(infix_expression
|
|
||||||
left: (value_path (value_name) @function)
|
|
||||||
operator: (concat_operator) @operator
|
|
||||||
(#eq? @operator "@@"))
|
|
||||||
|
|
||||||
(infix_expression
|
|
||||||
operator: (rel_operator) @operator
|
|
||||||
right: (value_path (value_name) @function)
|
|
||||||
(#eq? @operator "|>"))
|
|
||||||
|
|
||||||
(application_expression
|
|
||||||
function: (value_path (value_name) @function))
|
|
||||||
|
|
||||||
; Variables
|
|
||||||
;----------
|
|
||||||
|
|
||||||
(value_pattern) @variable
|
|
||||||
|
|
||||||
(type_variable) @variable.special
|
|
||||||
|
|
||||||
; Properties
|
|
||||||
;-----------
|
|
||||||
|
|
||||||
[(field_name) (instance_variable_name)] @property
|
|
||||||
|
|
||||||
; Labels
|
|
||||||
;-------
|
|
||||||
|
|
||||||
[(label_name) (parameter)] @label
|
|
||||||
|
|
||||||
(parameter
|
|
||||||
pattern: (value_pattern) @label)
|
|
||||||
; despite the above rule, we should still label value_pattern as a variable
|
|
||||||
; when a label name is present
|
|
||||||
(parameter
|
|
||||||
(label_name)
|
|
||||||
pattern: (value_pattern) @variable)
|
|
||||||
|
|
||||||
; Constants
|
|
||||||
;----------
|
|
||||||
|
|
||||||
(boolean) @boolean
|
|
||||||
|
|
||||||
[(number) (signed_number)] @number
|
|
||||||
|
|
||||||
[(string) (character)] @string
|
|
||||||
|
|
||||||
(quoted_string "{" @string "}" @string) @string
|
|
||||||
(quoted_string_content) @string
|
|
||||||
|
|
||||||
|
|
||||||
(escape_sequence) @string.escape
|
|
||||||
|
|
||||||
[
|
|
||||||
(conversion_specification)
|
|
||||||
(pretty_printing_indication)
|
|
||||||
] @punctuation.special
|
|
||||||
|
|
||||||
; Operators
|
|
||||||
;----------
|
|
||||||
|
|
||||||
(match_expression (match_operator) @keyword)
|
|
||||||
|
|
||||||
(value_definition [(let_operator) (let_and_operator)] @keyword)
|
|
||||||
|
|
||||||
[
|
|
||||||
(prefix_operator)
|
|
||||||
(sign_operator)
|
|
||||||
(pow_operator)
|
|
||||||
(mult_operator)
|
|
||||||
(add_operator)
|
|
||||||
(concat_operator)
|
|
||||||
(rel_operator)
|
|
||||||
(and_operator)
|
|
||||||
(or_operator)
|
|
||||||
(assign_operator)
|
|
||||||
(hash_operator)
|
|
||||||
(indexing_operator)
|
|
||||||
(let_operator)
|
|
||||||
(let_and_operator)
|
|
||||||
(match_operator)
|
|
||||||
] @operator
|
|
||||||
|
|
||||||
["*" "#" "::" "<-"] @operator
|
|
||||||
|
|
||||||
; Keywords
|
|
||||||
;---------
|
|
||||||
|
|
||||||
[
|
|
||||||
"and" "as" "assert" "begin" "class" "constraint" "do" "done" "downto" "else"
|
|
||||||
"end" "exception" "external" "for" "fun" "function" "functor" "if" "in"
|
|
||||||
"include" "inherit" "initializer" "lazy" "let" "match" "method" "module"
|
|
||||||
"mutable" "new" "nonrec" "object" "of" "open" "private" "rec" "sig" "struct"
|
|
||||||
"then" "to" "try" "type" "val" "virtual" "when" "while" "with"
|
|
||||||
] @keyword
|
|
||||||
|
|
||||||
; Punctuation
|
|
||||||
;------------
|
|
||||||
|
|
||||||
["(" ")" "[" "]" "{" "}" "[|" "|]" "[<" "[>" "[@@" "[@" "[%"] @punctuation.bracket
|
|
||||||
|
|
||||||
(object_type ["<" ">"] @punctuation.bracket)
|
|
||||||
|
|
||||||
[
|
|
||||||
"," "." ";" ":" "=" "|" "~" "?" "+" "-" "!" ">" "&"
|
|
||||||
"->" ";;" ":>" "+=" ":=" ".."
|
|
||||||
] @punctuation.delimiter
|
|
||||||
|
|
||||||
; Attributes
|
|
||||||
;-----------
|
|
||||||
|
|
||||||
[
|
|
||||||
(attribute)
|
|
||||||
(item_attribute)
|
|
||||||
(floating_attribute)
|
|
||||||
(extension)
|
|
||||||
(item_extension)
|
|
||||||
(quoted_extension)
|
|
||||||
(quoted_item_extension)
|
|
||||||
|
|
||||||
] @attribute
|
|
||||||
|
|
||||||
(attribute_id) @tag
|
|
||||||
|
|
||||||
; Comments
|
|
||||||
;---------
|
|
||||||
|
|
||||||
[(comment) (line_number_directive) (directive) (shebang)] @comment
|
|
|
@ -1,45 +0,0 @@
|
||||||
[
|
|
||||||
(let_binding)
|
|
||||||
(type_binding)
|
|
||||||
|
|
||||||
(method_definition)
|
|
||||||
|
|
||||||
(external)
|
|
||||||
(value_specification)
|
|
||||||
(method_specification)
|
|
||||||
|
|
||||||
(match_case)
|
|
||||||
|
|
||||||
(function_expression)
|
|
||||||
|
|
||||||
(field_declaration)
|
|
||||||
(field_expression)
|
|
||||||
|
|
||||||
(application_expression)
|
|
||||||
] @indent
|
|
||||||
|
|
||||||
(_ "[" "]" @end) @indent
|
|
||||||
(_ "[|" "|]" @end) @indent
|
|
||||||
(_ "<" ">" @end) @indent
|
|
||||||
(_ "{" "}" @end) @indent
|
|
||||||
(_ "(" ")" @end) @indent
|
|
||||||
|
|
||||||
(_ "object" @start "end" @end) @indent
|
|
||||||
|
|
||||||
(structure
|
|
||||||
"struct" @start
|
|
||||||
"end" @end) @indent
|
|
||||||
|
|
||||||
(signature
|
|
||||||
"sig" @start
|
|
||||||
"end" @end) @indent
|
|
||||||
|
|
||||||
(parenthesized_expression
|
|
||||||
"begin" @start
|
|
||||||
"end") @indent
|
|
||||||
|
|
||||||
(do_clause
|
|
||||||
"do" @start
|
|
||||||
"done" @end) @indent
|
|
||||||
|
|
||||||
";;" @outdent
|
|
|
@ -1,59 +0,0 @@
|
||||||
(_structure_item/value_definition
|
|
||||||
"let" @context
|
|
||||||
(let_binding
|
|
||||||
pattern: (_) @name)) @item
|
|
||||||
|
|
||||||
(_structure_item/exception_definition
|
|
||||||
"exception" @context
|
|
||||||
(constructor_declaration
|
|
||||||
(constructor_name) @name)) @item
|
|
||||||
|
|
||||||
(_structure_item/module_definition
|
|
||||||
"module" @context
|
|
||||||
(module_binding
|
|
||||||
name: (module_name) @name)) @item
|
|
||||||
|
|
||||||
(module_type_definition
|
|
||||||
"module" @context
|
|
||||||
"type" @context
|
|
||||||
name: (_) @name) @item
|
|
||||||
|
|
||||||
(type_definition
|
|
||||||
"type" @context
|
|
||||||
(type_binding name: (_) @name)) @item
|
|
||||||
|
|
||||||
(value_specification
|
|
||||||
"val" @context
|
|
||||||
(value_name) @name) @item
|
|
||||||
|
|
||||||
(class_definition
|
|
||||||
"class" @context
|
|
||||||
(class_binding
|
|
||||||
"virtual"? @context
|
|
||||||
name: (_) @name)) @item
|
|
||||||
|
|
||||||
(class_type_definition
|
|
||||||
"class" @context
|
|
||||||
"type" @context
|
|
||||||
(class_type_binding
|
|
||||||
"virtual"? @context
|
|
||||||
name: (_) @name)) @item
|
|
||||||
|
|
||||||
(instance_variable_definition
|
|
||||||
"val" @context
|
|
||||||
"method"? @context
|
|
||||||
name: (_) @name) @item
|
|
||||||
|
|
||||||
(method_specification
|
|
||||||
"method" @context
|
|
||||||
"virtual"? @context
|
|
||||||
(method_name) @name) @item
|
|
||||||
|
|
||||||
(method_definition
|
|
||||||
"method" @context
|
|
||||||
"virtual"? @context
|
|
||||||
name: (_) @name) @item
|
|
||||||
|
|
||||||
(external
|
|
||||||
"external" @context
|
|
||||||
(value_name) @name) @item
|
|
|
@ -1,219 +0,0 @@
|
||||||
use std::ops::Range;
|
|
||||||
use zed::lsp::{Completion, CompletionKind, Symbol, SymbolKind};
|
|
||||||
use zed::{CodeLabel, CodeLabelSpan};
|
|
||||||
use zed_extension_api::{self as zed, Result};
|
|
||||||
|
|
||||||
const OPERATOR_CHAR: [char; 17] = [
|
|
||||||
'~', '!', '?', '%', '<', ':', '.', '$', '&', '*', '+', '-', '/', '=', '>', '@', '^',
|
|
||||||
];
|
|
||||||
|
|
||||||
struct OcamlExtension;
|
|
||||||
|
|
||||||
impl zed::Extension for OcamlExtension {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn language_server_command(
|
|
||||||
&mut self,
|
|
||||||
_language_server_id: &zed::LanguageServerId,
|
|
||||||
worktree: &zed::Worktree,
|
|
||||||
) -> Result<zed::Command> {
|
|
||||||
let path = worktree.which("ocamllsp").ok_or_else(|| {
|
|
||||||
"ocamllsp (ocaml-language-server) must be installed manually.".to_string()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(zed::Command {
|
|
||||||
command: path,
|
|
||||||
args: Vec::new(),
|
|
||||||
env: worktree.shell_env(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn label_for_completion(
|
|
||||||
&self,
|
|
||||||
_language_server_id: &zed::LanguageServerId,
|
|
||||||
completion: Completion,
|
|
||||||
) -> Option<CodeLabel> {
|
|
||||||
let name = &completion.label;
|
|
||||||
let detail = completion.detail.as_ref().map(|s| s.replace('\n', " "));
|
|
||||||
|
|
||||||
match completion.kind.zip(detail) {
|
|
||||||
Some((CompletionKind::Constructor | CompletionKind::EnumMember, detail)) => {
|
|
||||||
let (argument, return_t) = detail
|
|
||||||
.split_once("->")
|
|
||||||
.map_or((None, detail.as_str()), |(arg, typ)| {
|
|
||||||
(Some(arg.trim()), typ.trim())
|
|
||||||
});
|
|
||||||
|
|
||||||
let type_decl = "type t = ";
|
|
||||||
let type_of = argument.map(|_| " of ").unwrap_or_default();
|
|
||||||
let argument = argument.unwrap_or_default();
|
|
||||||
let terminator = "\n";
|
|
||||||
let let_decl = "let _ ";
|
|
||||||
let let_colon = ": ";
|
|
||||||
let let_suffix = " = ()";
|
|
||||||
let code = format!(
|
|
||||||
"{type_decl}{name}{type_of}{argument}{terminator}{let_decl}{let_colon}{return_t}{let_suffix}"
|
|
||||||
);
|
|
||||||
|
|
||||||
let name_start = type_decl.len();
|
|
||||||
let argument_end = name_start + name.len() + type_of.len() + argument.len();
|
|
||||||
let colon_start = argument_end + terminator.len() + let_decl.len();
|
|
||||||
let return_type_end = code.len() - let_suffix.len();
|
|
||||||
Some(CodeLabel {
|
|
||||||
code,
|
|
||||||
spans: vec![
|
|
||||||
CodeLabelSpan::code_range(name_start..argument_end),
|
|
||||||
CodeLabelSpan::code_range(colon_start..return_type_end),
|
|
||||||
],
|
|
||||||
filter_range: (0..name.len()).into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Some((CompletionKind::Field, detail)) => {
|
|
||||||
let filter_range_start = if name.starts_with(['~', '?']) { 1 } else { 0 };
|
|
||||||
|
|
||||||
let record_prefix = "type t = { ";
|
|
||||||
let record_suffix = "; }";
|
|
||||||
let code = format!("{record_prefix}{name} : {detail}{record_suffix}");
|
|
||||||
|
|
||||||
Some(CodeLabel {
|
|
||||||
spans: vec![CodeLabelSpan::code_range(
|
|
||||||
record_prefix.len()..code.len() - record_suffix.len(),
|
|
||||||
)],
|
|
||||||
code,
|
|
||||||
filter_range: (filter_range_start..name.len()).into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Some((CompletionKind::Value, detail)) => {
|
|
||||||
let let_prefix = "let ";
|
|
||||||
let suffix = " = ()";
|
|
||||||
let (l_paren, r_paren) = if name.contains(OPERATOR_CHAR) {
|
|
||||||
("( ", " )")
|
|
||||||
} else {
|
|
||||||
("", "")
|
|
||||||
};
|
|
||||||
let code = format!("{let_prefix}{l_paren}{name}{r_paren} : {detail}{suffix}");
|
|
||||||
|
|
||||||
let name_start = let_prefix.len() + l_paren.len();
|
|
||||||
let name_end = name_start + name.len();
|
|
||||||
let type_annotation_start = name_end + r_paren.len();
|
|
||||||
let type_annotation_end = code.len() - suffix.len();
|
|
||||||
|
|
||||||
Some(CodeLabel {
|
|
||||||
spans: vec![
|
|
||||||
CodeLabelSpan::code_range(name_start..name_end),
|
|
||||||
CodeLabelSpan::code_range(type_annotation_start..type_annotation_end),
|
|
||||||
],
|
|
||||||
filter_range: (0..name.len()).into(),
|
|
||||||
code,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Some((CompletionKind::Method, detail)) => {
|
|
||||||
let method_decl = "class c : object method ";
|
|
||||||
let end = " end";
|
|
||||||
let code = format!("{method_decl}{name} : {detail}{end}");
|
|
||||||
|
|
||||||
Some(CodeLabel {
|
|
||||||
spans: vec![CodeLabelSpan::code_range(
|
|
||||||
method_decl.len()..code.len() - end.len(),
|
|
||||||
)],
|
|
||||||
code,
|
|
||||||
filter_range: (0..name.len()).into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Some((kind, _)) => {
|
|
||||||
let highlight_name = match kind {
|
|
||||||
CompletionKind::Module | CompletionKind::Interface => "title",
|
|
||||||
CompletionKind::Keyword => "keyword",
|
|
||||||
CompletionKind::TypeParameter => "type",
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(CodeLabel {
|
|
||||||
spans: vec![(CodeLabelSpan::literal(name, Some(highlight_name.to_string())))],
|
|
||||||
filter_range: (0..name.len()).into(),
|
|
||||||
code: String::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn label_for_symbol(
|
|
||||||
&self,
|
|
||||||
_language_server_id: &zed::LanguageServerId,
|
|
||||||
symbol: Symbol,
|
|
||||||
) -> Option<CodeLabel> {
|
|
||||||
let name = &symbol.name;
|
|
||||||
|
|
||||||
let (code, filter_range, display_range) = match symbol.kind {
|
|
||||||
SymbolKind::Property => {
|
|
||||||
let code = format!("type t = {{ {}: (); }}", name);
|
|
||||||
let filter_range: Range<usize> = 0..name.len();
|
|
||||||
let display_range = 11..11 + name.len();
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::Function
|
|
||||||
if name.contains(OPERATOR_CHAR)
|
|
||||||
|| (name.starts_with("let") && name.contains(OPERATOR_CHAR)) =>
|
|
||||||
{
|
|
||||||
let code = format!("let ( {name} ) () = ()");
|
|
||||||
|
|
||||||
let filter_range = 6..6 + name.len();
|
|
||||||
let display_range = 0..filter_range.end + 1;
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::Function => {
|
|
||||||
let code = format!("let {name} () = ()");
|
|
||||||
|
|
||||||
let filter_range = 4..4 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::Constructor => {
|
|
||||||
let code = format!("type t = {name}");
|
|
||||||
let filter_range = 0..name.len();
|
|
||||||
let display_range = 9..9 + name.len();
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::Module => {
|
|
||||||
let code = format!("module {name} = struct end");
|
|
||||||
let filter_range = 7..7 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::Class => {
|
|
||||||
let code = format!("class {name} = object end");
|
|
||||||
let filter_range = 6..6 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::Method => {
|
|
||||||
let code = format!("class c = object method {name} = () end");
|
|
||||||
let filter_range = 0..name.len();
|
|
||||||
let display_range = 17..24 + name.len();
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
SymbolKind::String => {
|
|
||||||
let code = format!("type {name} = T");
|
|
||||||
let filter_range = 5..5 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(code, filter_range, display_range)
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(CodeLabel {
|
|
||||||
code,
|
|
||||||
spans: vec![CodeLabelSpan::code_range(display_range)],
|
|
||||||
filter_range: filter_range.into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zed::register_extension!(OcamlExtension);
|
|
Loading…
Add table
Add a link
Reference in a new issue