Merge branch 'main' into kvark-linux

This commit is contained in:
Mikayla 2024-02-07 11:49:49 -08:00
commit 67555ee5b4
No known key found for this signature in database
238 changed files with 6624 additions and 3524 deletions

View file

@ -2,7 +2,7 @@
description = "The fast, collaborative code editor."
edition = "2021"
name = "zed"
version = "0.122.0"
version = "0.123.0"
publish = false
license = "GPL-3.0-or-later"
@ -16,98 +16,99 @@ name = "Zed"
path = "src/main.rs"
[dependencies]
activity_indicator = { path = "../activity_indicator" }
ai = { path = "../ai" }
activity_indicator.workspace = true
ai.workspace = true
anyhow.workspace = true
assets = { path = "../assets" }
assistant = { path = "../assistant" }
assets.workspace = true
assistant.workspace = true
async-compression.workspace = true
async-recursion = "0.3"
async-tar = "0.4.2"
async-trait.workspace = true
audio = { path = "../audio" }
auto_update = { path = "../auto_update" }
audio.workspace = true
auto_update.workspace = true
backtrace = "0.3"
breadcrumbs = { path = "../breadcrumbs" }
call = { path = "../call" }
channel = { path = "../channel" }
breadcrumbs.workspace = true
call.workspace = true
channel.workspace = true
chrono = "0.4"
cli = { path = "../cli" }
client = { path = "../client" }
collab_ui = { path = "../collab_ui" }
collections = { path = "../collections" }
command_palette = { path = "../command_palette" }
copilot = { path = "../copilot" }
copilot_ui = { path = "../copilot_ui" }
cli.workspace = true
client.workspace = true
collab_ui.workspace = true
collections.workspace = true
command_palette.workspace = true
copilot.workspace = true
copilot_ui.workspace = true
ctor.workspace = true
db = { path = "../db" }
diagnostics = { path = "../diagnostics" }
editor = { path = "../editor" }
db.workspace = true
diagnostics.workspace = true
editor.workspace = true
env_logger.workspace = true
feature_flags = { path = "../feature_flags" }
feedback = { path = "../feedback" }
file_finder = { path = "../file_finder" }
fs = { path = "../fs" }
fsevent = { path = "../fsevent" }
feature_flags.workspace = true
feedback.workspace = true
file_finder.workspace = true
fs.workspace = true
fsevent.workspace = true
futures.workspace = true
go_to_line = { path = "../go_to_line" }
gpui = { path = "../gpui" }
go_to_line.workspace = true
gpui.workspace = true
ignore = "0.4"
image = "0.23"
indexmap = "1.6.2"
install_cli = { path = "../install_cli" }
install_cli.workspace = true
isahc.workspace = true
itertools = "0.11"
journal = { path = "../journal" }
language = { path = "../language" }
language_selector = { path = "../language_selector" }
language_tools = { path = "../language_tools" }
journal.workspace = true
language.workspace = true
language_selector.workspace = true
language_tools.workspace = true
lazy_static.workspace = true
libc = "0.2"
log.workspace = true
lsp = { path = "../lsp" }
markdown_preview = { path = "../markdown_preview" }
menu = { path = "../menu" }
lsp.workspace = true
markdown_preview.workspace = true
menu.workspace = true
mimalloc = "0.1"
node_runtime = { path = "../node_runtime" }
notifications = { path = "../notifications" }
node_runtime.workspace = true
notifications.workspace = true
num_cpus = "1.13.0"
outline = { path = "../outline" }
outline.workspace = true
parking_lot.workspace = true
postage.workspace = true
project = { path = "../project" }
project_panel = { path = "../project_panel" }
project_symbols = { path = "../project_symbols" }
quick_action_bar = { path = "../quick_action_bar" }
project.workspace = true
project_panel.workspace = true
project_symbols.workspace = true
quick_action_bar.workspace = true
rand.workspace = true
recent_projects = { path = "../recent_projects" }
recent_projects.workspace = true
regex.workspace = true
release_channel = { path = "../release_channel" }
rope = { path = "../rope" }
rpc = { path = "../rpc" }
release_channel.workspace = true
rope.workspace = true
rpc.workspace = true
rsa = "0.4"
rust-embed.workspace = true
schemars.workspace = true
search = { path = "../search" }
semantic_index = { path = "../semantic_index" }
search.workspace = true
semantic_index.workspace = true
serde.workspace = true
serde_derive.workspace = true
serde_json.workspace = true
settings = { path = "../settings" }
settings.workspace = true
shellexpand = "2.1.0"
simplelog = "0.9"
smallvec.workspace = true
smol.workspace = true
sum_tree = { path = "../sum_tree" }
sum_tree.workspace = true
tempfile.workspace = true
terminal_view = { path = "../terminal_view" }
text = { path = "../text" }
theme = { path = "../theme" }
theme_selector = { path = "../theme_selector" }
terminal_view.workspace = true
text.workspace = true
theme.workspace = true
theme_selector.workspace = true
thiserror.workspace = true
tiny_http = "0.8"
toml.workspace = true
tree-sitter-bash.workspace = true
tree-sitter-beancount.workspace = true
tree-sitter-c-sharp.workspace = true
tree-sitter-c.workspace = true
tree-sitter-cpp.workspace = true
@ -123,6 +124,7 @@ tree-sitter-go.workspace = true
tree-sitter-gomod.workspace = true
tree-sitter-gowork.workspace = true
tree-sitter-haskell.workspace = true
tree-sitter-hcl.workspace = true
tree-sitter-heex.workspace = true
tree-sitter-html.workspace = true
tree-sitter-json.workspace = true
@ -130,6 +132,7 @@ tree-sitter-lua.workspace = true
tree-sitter-markdown.workspace = true
tree-sitter-nix.workspace = true
tree-sitter-nu.workspace = true
tree-sitter-ocaml.workspace = true
tree-sitter-php.workspace = true
tree-sitter-proto.workspace = true
tree-sitter-purescript.workspace = true
@ -148,22 +151,22 @@ tree-sitter-zig.workspace = true
tree-sitter.workspace = true
url.workspace = true
urlencoding = "2.1.2"
util = { path = "../util" }
util.workspace = true
uuid.workspace = true
vim = { path = "../vim" }
welcome = { path = "../welcome" }
workspace = { path = "../workspace" }
zed_actions = { path = "../zed_actions" }
vim.workspace = true
welcome.workspace = true
workspace.workspace = true
zed_actions.workspace = true
[dev-dependencies]
call = { path = "../call", features = ["test-support"] }
editor = { path = "../editor", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] }
text = { path = "../text", features = ["test-support"] }
call = { workspace = true, features = ["test-support"] }
editor = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
language = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
text = { workspace = true, features = ["test-support"] }
unindent.workspace = true
workspace = { path = "../workspace", features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
[package.metadata.bundle-dev]
icon = ["resources/app-icon-preview@2x.png", "resources/app-icon-preview.png"]

View file

@ -25,6 +25,7 @@ mod json;
mod language_plugin;
mod lua;
mod nu;
mod ocaml;
mod php;
mod purescript;
mod python;
@ -66,6 +67,7 @@ pub fn init(
};
language("bash", tree_sitter_bash::language(), vec![]);
language("beancount", tree_sitter_beancount::language(), vec![]);
language(
"c",
tree_sitter_c::language(),
@ -302,6 +304,16 @@ pub fn init(
tree_sitter_nu::language(),
vec![Arc::new(nu::NuLanguageServer {})],
);
language(
"ocaml",
tree_sitter_ocaml::language_ocaml(),
vec![Arc::new(ocaml::OCamlLspAdapter)],
);
language(
"ocaml-interface",
tree_sitter_ocaml::language_ocaml_interface(),
vec![Arc::new(ocaml::OCamlLspAdapter)],
);
language(
"vue",
tree_sitter_vue::language(),
@ -313,6 +325,8 @@ pub fn init(
vec![Arc::new(uiua::UiuaLanguageServer {})],
);
language("proto", tree_sitter_proto::language(), vec![]);
language("terraform", tree_sitter_hcl::language(), vec![]);
language("hcl", tree_sitter_hcl::language(), vec![]);
if let Ok(children) = std::fs::read_dir(&*PLUGINS_DIR) {
for child in children {

View file

@ -0,0 +1,3 @@
name = "Beancount"
path_suffixes = ["beancount"]
brackets = [{ start = "\"", end = "\"", close = false, newline = false }]

View file

@ -0,0 +1,21 @@
(comment) @comment
(headline) @comment
[
(payee)
(narration)
(string)
] @string
(number) @number
(date) @function
(currency) @constant
(account) @identifier
[
(option)
(include)
(open)
(balance)
(pad)
(close)
] @keyword

View file

@ -1,9 +1,13 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use futures::StreamExt;
use gpui::AppContext;
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::LanguageServerBinary;
use node_runtime::NodeRuntime;
use project::project_settings::ProjectSettings;
use serde_json::Value;
use settings::Settings;
use smol::fs;
use std::{
any::Any,
@ -13,6 +17,7 @@ use std::{
};
use util::ResultExt;
const SERVER_NAME: &'static str = "elm-language-server";
const SERVER_PATH: &'static str = "node_modules/@elm-tooling/elm-language-server/out/node/index.js";
fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
@ -32,7 +37,7 @@ impl ElmLspAdapter {
#[async_trait]
impl LspAdapter for ElmLspAdapter {
fn name(&self) -> LanguageServerName {
LanguageServerName("elm-language-server".into())
LanguageServerName(SERVER_NAME.into())
}
fn short_name(&self) -> &'static str {
@ -88,6 +93,27 @@ impl LspAdapter for ElmLspAdapter {
) -> Option<LanguageServerBinary> {
get_cached_server_binary(container_dir, &*self.node).await
}
fn workspace_configuration(&self, _workspace_root: &Path, cx: &mut AppContext) -> Value {
// elm-language-server expects workspace didChangeConfiguration notification
// params to be the same as lsp initialization_options
let override_options = ProjectSettings::get_global(cx)
.lsp
.get(SERVER_NAME)
.and_then(|s| s.initialization_options.clone())
.unwrap_or_default();
match override_options.clone().as_object_mut() {
Some(op) => {
// elm-language-server requests workspace configuration
// for the `elmLS` section, so we have to nest
// another copy of initialization_options there
op.insert("elmLS".into(), override_options);
serde_json::to_value(op).unwrap_or_default()
}
None => override_options,
}
}
}
async fn get_cached_server_binary(

View file

@ -398,7 +398,6 @@ mod tests {
let highlight_type = grammar.highlight_id_for_name("type").unwrap();
let highlight_keyword = grammar.highlight_id_for_name("keyword").unwrap();
let highlight_number = grammar.highlight_id_for_name("number").unwrap();
let highlight_field = grammar.highlight_id_for_name("property").unwrap();
assert_eq!(
language
@ -454,7 +453,7 @@ mod tests {
Some(CodeLabel {
text: "two.Three a.Bcd".to_string(),
filter_range: 0..9,
runs: vec![(4..9, highlight_field), (12..15, highlight_type)],
runs: vec![(12..15, highlight_type)],
})
);
}

View file

@ -1,6 +1,10 @@
(identifier) @variable
(type_identifier) @type
(field_identifier) @property
(field_identifier) @variable.member
(keyed_element
.
(literal_element
(identifier) @variable.member))
(call_expression
function: (identifier) @function)
@ -15,6 +19,15 @@
(method_declaration
name: (field_identifier) @function.method)
[
"("
")"
"{"
"}"
"["
"]"
] @punctuation.bracket
[
"--"
"-"

View file

@ -7,20 +7,21 @@
"func" @context
name: (identifier) @name
parameters: (parameter_list
"(" @context
")" @context)) @item
"("
")")) @item
(method_declaration
"func" @context
receiver: (parameter_list
"(" @context
(parameter_declaration
name: (_) @name
type: (_) @context)
")" @context)
name: (field_identifier) @name
parameters: (parameter_list
"(" @context
")" @context)) @item
"("
")")) @item
(const_declaration
"const" @context
@ -40,4 +41,4 @@
")" @context)) @item
(field_declaration
name: (_) @name) @item
name: (_) @name) @item

View file

@ -0,0 +1,26 @@
(adt
"data" @context
name: (type) @name) @item
(type_alias
"type" @context
name: (type) @name) @item
(newtype
"newtype" @context
name: (type) @name) @item
(signature
name: (variable) @name) @item
(class
"class" @context
(class_head) @name) @item
(instance
"instance" @context
(instance_head) @name) @item
(foreign_import
"foreign" @context
(impent) @name) @item

View file

@ -0,0 +1,13 @@
name = "HCL"
path_suffixes = ["hcl"]
line_comments = ["# ", "// "]
block_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, not_in = ["comment", "string"] },
{ start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
{ start = "/*", end = " */", close = true, newline = false, not_in = ["comment", "string"] },
]

View file

@ -0,0 +1,117 @@
; https://github.com/nvim-treesitter/nvim-treesitter/blob/cb79d2446196d25607eb1d982c96939abdf67b8e/queries/hcl/highlights.scm
; highlights.scm
[
"!"
"\*"
"/"
"%"
"\+"
"-"
">"
">="
"<"
"<="
"=="
"!="
"&&"
"||"
] @operator
[
"{"
"}"
"["
"]"
"("
")"
] @punctuation.bracket
[
"."
".*"
","
"[*]"
] @punctuation.delimiter
[
(ellipsis)
"\?"
"=>"
] @punctuation.special
[
":"
"="
] @punctuation
[
"for"
"endfor"
"in"
"if"
"else"
"endif"
] @keyword
[
(quoted_template_start) ; "
(quoted_template_end) ; "
(template_literal) ; non-interpolation/directive content
] @string
[
(heredoc_identifier) ; END
(heredoc_start) ; << or <<-
] @punctuation.delimiter
[
(template_interpolation_start) ; ${
(template_interpolation_end) ; }
(template_directive_start) ; %{
(template_directive_end) ; }
(strip_marker) ; ~
] @punctuation.special
(numeric_lit) @number
(bool_lit) @boolean
(null_lit) @constant
(comment) @comment
(identifier) @variable
(body
(block
(identifier) @keyword))
(body
(block
(body
(block
(identifier) @type))))
(function_call
(identifier) @function)
(attribute
(identifier) @variable)
; { key: val }
;
; highlight identifier keys as though they were block attributes
(object_elem
key:
(expression
(variable_expr
(identifier) @variable)))
; var.foo, data.bar
;
; first element in get_attr is a variable.builtin or a reference to a variable.builtin
(expression
(variable_expr
(identifier) @variable)
(get_attr
(identifier) @variable))

View file

@ -0,0 +1,11 @@
; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/indents.scm
[
(block)
(object)
(tuple)
(function_call)
] @indent
(_ "[" "]" @end) @indent
(_ "(" ")" @end) @indent
(_ "{" "}" @end) @indent

View file

@ -0,0 +1,6 @@
; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/injections.scm
(heredoc_template
(template_literal) @content
(heredoc_identifier) @language
(#downcase! @language))

View file

@ -0,0 +1,6 @@
("(" @open ")" @close)
("{" @open "}" @close)
("<" @open ">" @close)
("sig" @open "end" @close)
("object" @open "end" @close)

View file

@ -0,0 +1,13 @@
name = "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 },
{ start = "(", end = ")", close = true, newline = true },
{ start = "sig", end = " end", close = true, newline = true },
# HACK: For some reason `object` alone does not work
{ start = "object ", end = "end", close = true, newline = true },
]

View file

@ -0,0 +1 @@
../ocaml/highlights.scm

View file

@ -0,0 +1,21 @@
[
(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

View file

@ -0,0 +1,48 @@
(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

View file

@ -0,0 +1,317 @@
use std::{any::Any, ops::Range, path::PathBuf, sync::Arc};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use language::{CodeLabel, LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::{CompletionItemKind, LanguageServerBinary, SymbolKind};
use rope::Rope;
const OPERATOR_CHAR: [char; 17] = [
'~', '!', '?', '%', '<', ':', '.', '$', '&', '*', '+', '-', '/', '=', '>', '@', '^',
];
pub struct OCamlLspAdapter;
#[async_trait]
impl LspAdapter for OCamlLspAdapter {
fn name(&self) -> LanguageServerName {
LanguageServerName("ocamllsp".into())
}
fn short_name(&self) -> &'static str {
"ocaml"
}
async fn fetch_latest_server_version(
&self,
_: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
Ok(Box::new(()))
}
async fn fetch_server_binary(
&self,
_: Box<dyn 'static + Send + Any>,
_: PathBuf,
_: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
Err(anyhow!(
"ocamllsp (ocaml-language-server) must be installed manually."
))
}
async fn cached_server_binary(
&self,
_: PathBuf,
_: &dyn LspAdapterDelegate,
) -> Option<LanguageServerBinary> {
Some(LanguageServerBinary {
path: "ocamllsp".into(),
arguments: vec![],
})
}
fn can_be_reinstalled(&self) -> bool {
false
}
async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
None
}
async fn label_for_completion(
&self,
completion: &lsp::CompletionItem,
language: &Arc<language::Language>,
) -> Option<CodeLabel> {
let name = &completion.label;
let detail = completion.detail.as_ref().map(|s| s.replace("\n", " "));
match completion.kind.zip(detail) {
// Error of 'b : ('a, 'b) result
// Stack_overflow : exn
Some((CompletionItemKind::CONSTRUCTOR | CompletionItemKind::ENUM_MEMBER, detail)) => {
let (argument, return_t) = detail
.split_once("->")
.map_or((None, detail.as_str()), |(arg, typ)| {
(Some(arg.trim()), typ.trim())
});
let constr_decl = argument.map_or(name.to_string(), |argument| {
format!("{} of {}", name, argument)
});
let constr_host = if return_t.ends_with("exn") {
"exception "
} else {
"type t = "
};
let source_host = Rope::from([constr_host, &constr_decl].join(" "));
let mut source_highlight = {
let constr_host_len = constr_host.len() + 1;
language.highlight_text(
&source_host,
Range {
start: constr_host_len,
end: constr_host_len + constr_decl.len(),
},
)
};
let signature_host: Rope = Rope::from(format!("let _ : {} = ()", return_t));
// We include the ': ' in the range as we use it later
let mut signature_highlight =
language.highlight_text(&signature_host, 6..8 + return_t.len());
if let Some(last) = source_highlight.last() {
let offset = last.0.end + 1;
signature_highlight.iter_mut().for_each(|(r, _)| {
r.start += offset;
r.end += offset;
});
};
Some(CodeLabel {
text: format!("{} : {}", constr_decl, return_t),
runs: {
source_highlight.append(&mut signature_highlight);
source_highlight
},
filter_range: 0..name.len(),
})
}
// version : string
// NOTE: (~|?) are omitted as we don't use them in the fuzzy filtering
Some((CompletionItemKind::FIELD, detail))
if name.starts_with("~") || name.starts_with("?") =>
{
let label = name.trim_start_matches(&['~', '?']);
let text = format!("{} : {}", label, detail);
let signature_host = Rope::from(format!("let _ : {} = ()", detail));
let signature_highlight =
&mut language.highlight_text(&signature_host, 6..8 + detail.len());
let offset = label.len() + 1;
for (r, _) in signature_highlight.iter_mut() {
r.start += offset;
r.end += offset;
}
let mut label_highlight = vec![(
0..0 + label.len(),
language.grammar()?.highlight_id_for_name("property")?,
)];
Some(CodeLabel {
text,
runs: {
label_highlight.append(signature_highlight);
label_highlight
},
filter_range: 0..label.len(),
})
}
// version: string;
Some((CompletionItemKind::FIELD, detail)) => {
let (_record_t, field_t) = detail.split_once("->")?;
let text = format!("{}: {};", name, field_t);
let source_host: Rope = Rope::from(format!("type t = {{ {} }}", text));
let runs: Vec<(Range<usize>, language::HighlightId)> =
language.highlight_text(&source_host, 11..11 + text.len());
Some(CodeLabel {
text,
runs,
filter_range: 0..name.len(),
})
}
// let* : 'a t -> ('a -> 'b t) -> 'b t
Some((CompletionItemKind::VALUE, detail))
if name.contains(OPERATOR_CHAR)
|| (name.starts_with("let") && name.contains(OPERATOR_CHAR)) =>
{
let text = format!("{} : {}", name, detail);
let source_host = Rope::from(format!("let ({}) : {} = ()", name, detail));
let mut runs = language.highlight_text(&source_host, 5..6 + text.len());
if runs.len() > 1 {
// ')'
runs.remove(1);
for run in &mut runs[1..] {
run.0.start -= 1;
run.0.end -= 1;
}
}
Some(CodeLabel {
text,
runs,
filter_range: 0..name.len(),
})
}
// version : Version.t list -> Version.t option Lwt.t
Some((CompletionItemKind::VALUE, detail)) => {
let text = format!("{} : {}", name, detail);
let source_host = Rope::from(format!("let {} = ()", text));
let runs = language.highlight_text(&source_host, 4..4 + text.len());
Some(CodeLabel {
text,
runs,
filter_range: 0..name.len(),
})
}
// status : string
Some((CompletionItemKind::METHOD, detail)) => {
let text = format!("{} : {}", name, detail);
let method_host = Rope::from(format!("class c : object method {} end", text));
let runs = language.highlight_text(&method_host, 24..24 + text.len());
Some(CodeLabel {
text,
runs,
filter_range: 0..name.len(),
})
}
Some((kind, _)) => {
let highlight_name = match kind {
CompletionItemKind::MODULE | CompletionItemKind::INTERFACE => "title",
CompletionItemKind::KEYWORD => "keyword",
CompletionItemKind::TYPE_PARAMETER => "type",
_ => return None,
};
Some(CodeLabel {
text: name.clone(),
runs: vec![(
0..name.len(),
language.grammar()?.highlight_id_for_name(highlight_name)?,
)],
filter_range: 0..name.len(),
})
}
_ => None,
}
}
async fn label_for_symbol(
&self,
name: &str,
kind: SymbolKind,
language: &Arc<language::Language>,
) -> Option<CodeLabel> {
let (text, filter_range, display_range) = match kind {
SymbolKind::PROPERTY => {
let text = format!("type t = {{ {}: (); }}", name);
let filter_range: Range<usize> = 0..name.len();
let display_range = 11..11 + name.len();
(text, filter_range, display_range)
}
SymbolKind::FUNCTION
if name.contains(OPERATOR_CHAR)
|| (name.starts_with("let") && name.contains(OPERATOR_CHAR)) =>
{
let text = format!("let ({}) () = ()", name);
let filter_range = 5..5 + name.len();
let display_range = 0..filter_range.end + 1;
(text, filter_range, display_range)
}
SymbolKind::FUNCTION => {
let text = format!("let {} () = ()", name);
let filter_range = 4..4 + name.len();
let display_range = 0..filter_range.end;
(text, filter_range, display_range)
}
SymbolKind::CONSTRUCTOR => {
let text = format!("type t = {}", name);
let filter_range = 0..name.len();
let display_range = 9..9 + name.len();
(text, filter_range, display_range)
}
SymbolKind::MODULE => {
let text = format!("module {} = struct end", name);
let filter_range = 7..7 + name.len();
let display_range = 0..filter_range.end;
(text, filter_range, display_range)
}
SymbolKind::CLASS => {
let text = format!("class {} = object end", name);
let filter_range = 6..6 + name.len();
let display_range = 0..filter_range.end;
(text, filter_range, display_range)
}
SymbolKind::METHOD => {
let text = format!("class c = object method {} = () end", name);
let filter_range = 0..name.len();
let display_range = 17..24 + name.len();
(text, filter_range, display_range)
}
SymbolKind::STRING => {
let text = format!("type {} = T", name);
let filter_range = 5..5 + 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,
})
}
}

View file

@ -0,0 +1,12 @@
("(" @open ")" @close)
("[" @open "]" @close)
("[|" @open "|]" @close)
("{" @open "}" @close)
("<" @open ">" @close)
("\"" @open "\"" @close)
("begin" @open "end" @close)
("struct" @open "end" @close)
("sig" @open "end" @close)
("object" @open "end" @close)
("do" @open "done" @close)

View file

@ -0,0 +1,18 @@
name = "OCaml"
path_suffixes = ["ml"]
block_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 = true, not_in = ["string"] },
{ start = "(", end = ")", close = true, newline = true },
{ start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
{ start = "begin", end = " end", close = true, newline = true },
{ start = "struct", end = " end", close = true, newline = true },
{ start = "sig", end = " end", close = true, newline = true },
# HACK: For some reason `object` alone does not work
{ start = "object ", end = "end", close = true, newline = true },
{ start = "do", end = " done", close = true, newline = true }
]

View file

@ -0,0 +1,142 @@
; Modules
;--------
[(module_name) (module_type_name)] @title
; Types
;------
[(class_name) (class_type_name) (type_constructor)] @type
[(constructor_name) (tag)] @constructor
; 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
;----------
[(type_variable) (value_pattern)] @variable
; Properties
;-----------
[(label_name) (field_name) (instance_variable_name)] @property
; 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

View file

@ -0,0 +1,43 @@
[
(let_binding)
(type_binding)
(method_definition)
(external)
(value_specification)
(method_specification)
(match_case)
(function_expression)
(field_declaration)
(field_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

View file

@ -0,0 +1,59 @@
(_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

View file

@ -0,0 +1,13 @@
name = "Terraform"
path_suffixes = ["tf", "tfvars"]
line_comments = ["# ", "// "]
block_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, not_in = ["comment", "string"] },
{ start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
{ start = "/*", end = " */", close = true, newline = false, not_in = ["comment", "string"] },
]

View file

@ -0,0 +1,159 @@
; https://github.com/nvim-treesitter/nvim-treesitter/blob/cb79d2446196d25607eb1d982c96939abdf67b8e/queries/hcl/highlights.scm
; highlights.scm
[
"!"
"\*"
"/"
"%"
"\+"
"-"
">"
">="
"<"
"<="
"=="
"!="
"&&"
"||"
] @operator
[
"{"
"}"
"["
"]"
"("
")"
] @punctuation.bracket
[
"."
".*"
","
"[*]"
] @punctuation.delimiter
[
(ellipsis)
"\?"
"=>"
] @punctuation.special
[
":"
"="
] @punctuation
[
"for"
"endfor"
"in"
"if"
"else"
"endif"
] @keyword
[
(quoted_template_start) ; "
(quoted_template_end) ; "
(template_literal) ; non-interpolation/directive content
] @string
[
(heredoc_identifier) ; END
(heredoc_start) ; << or <<-
] @punctuation.delimiter
[
(template_interpolation_start) ; ${
(template_interpolation_end) ; }
(template_directive_start) ; %{
(template_directive_end) ; }
(strip_marker) ; ~
] @punctuation.special
(numeric_lit) @number
(bool_lit) @boolean
(null_lit) @constant
(comment) @comment
(identifier) @variable
(body
(block
(identifier) @keyword))
(body
(block
(body
(block
(identifier) @type))))
(function_call
(identifier) @function)
(attribute
(identifier) @variable)
; { key: val }
;
; highlight identifier keys as though they were block attributes
(object_elem
key:
(expression
(variable_expr
(identifier) @variable)))
; var.foo, data.bar
;
; first element in get_attr is a variable.builtin or a reference to a variable.builtin
(expression
(variable_expr
(identifier) @variable)
(get_attr
(identifier) @variable))
; https://github.com/nvim-treesitter/nvim-treesitter/blob/cb79d2446196d25607eb1d982c96939abdf67b8e/queries/terraform/highlights.scm
; Terraform specific references
;
;
; local/module/data/var/output
(expression
(variable_expr
(identifier) @variable
(#any-of? @variable "data" "var" "local" "module" "output"))
(get_attr
(identifier) @variable))
; path.root/cwd/module
(expression
(variable_expr
(identifier) @type
(#eq? @type "path"))
(get_attr
(identifier) @variable
(#any-of? @variable "root" "cwd" "module")))
; terraform.workspace
(expression
(variable_expr
(identifier) @type
(#eq? @type "terraform"))
(get_attr
(identifier) @variable
(#any-of? @variable "workspace")))
; Terraform specific keywords
; FIXME: ideally only for identifiers under a `variable` block to minimize false positives
((identifier) @type
(#any-of? @type "bool" "string" "number" "object" "tuple" "list" "map" "set" "any"))
(object_elem
val:
(expression
(variable_expr
(identifier) @type
(#any-of? @type "bool" "string" "number" "object" "tuple" "list" "map" "set" "any"))))

View file

@ -0,0 +1,14 @@
; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/indents.scm
[
(block)
(object)
(tuple)
(function_call)
] @indent
(_ "[" "]" @end) @indent
(_ "(" ")" @end) @indent
(_ "{" "}" @end) @indent
; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/terraform/indents.scm
; inherits: hcl

View file

@ -0,0 +1,9 @@
; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/hcl/injections.scm
(heredoc_template
(template_literal) @content
(heredoc_identifier) @language
(#downcase! @language))
; https://github.com/nvim-treesitter/nvim-treesitter/blob/ce4adf11cfe36fc5b0e5bcdce0c7c6e8fbc9798a/queries/terraform/injections.scm
; inherits: hcl

View file

@ -44,7 +44,7 @@ use std::{
thread,
time::Duration,
};
use theme::{ActiveTheme, ThemeRegistry, ThemeSettings};
use theme::{ActiveTheme, SystemAppearance, ThemeRegistry, ThemeSettings};
use util::{
async_maybe,
http::{self, HttpClient, ZedHttpClient},
@ -127,6 +127,7 @@ fn main() {
AppCommitSha::set_global(AppCommitSha(build_sha.into()), cx);
}
SystemAppearance::init(cx);
OpenListener::set_global(listener.clone(), cx);
load_embedded_fonts(cx);
@ -475,6 +476,7 @@ fn init_paths() {
fn init_logger() {
if stdout_is_a_pty() {
Builder::new()
.parse_default_env()
.format(|buf, record| {
use env_logger::fmt::Color;
@ -814,7 +816,7 @@ async fn load_login_shell_environment() -> Result<()> {
"SHELL environment variable is not assigned so we can't source login environment variables",
)?;
let output = Command::new(&shell)
.args(["-lic", &format!("echo {marker} && /usr/bin/env -0")])
.args(["-l", "-i", "-c", &format!("echo {marker}; /usr/bin/env -0")])
.output()
.await
.context("failed to spawn login shell to source login environment variables")?;
@ -896,27 +898,39 @@ fn load_user_themes_in_background(fs: Arc<dyn fs::Fs>, cx: &mut AppContext) {
if let Some(theme_registry) =
cx.update(|cx| ThemeRegistry::global(cx).clone()).log_err()
{
if let Some(()) = theme_registry
.load_user_themes(&paths::THEMES_DIR.clone(), fs)
let themes_dir = paths::THEMES_DIR.as_ref();
match fs
.metadata(themes_dir)
.await
.log_err()
.ok()
.flatten()
.map(|m| m.is_dir)
{
cx.update(|cx| {
let mut theme_settings = ThemeSettings::get_global(cx).clone();
if let Some(requested_theme) = theme_settings.requested_theme.clone() {
if let Some(_theme) = theme_settings.switch_theme(&requested_theme, cx)
{
ThemeSettings::override_global(theme_settings, cx);
}
}
})
.log_err();
Some(is_dir) => {
anyhow::ensure!(is_dir, "Themes dir path {themes_dir:?} is not a directory")
}
None => {
fs.create_dir(themes_dir).await.with_context(|| {
format!("Failed to create themes dir at path {themes_dir:?}")
})?;
}
}
theme_registry.load_user_themes(themes_dir, fs).await?;
cx.update(|cx| {
let mut theme_settings = ThemeSettings::get_global(cx).clone();
if let Some(theme_selection) = theme_settings.theme_selection.clone() {
let theme_name = theme_selection.theme(*SystemAppearance::global(cx));
if let Some(_theme) = theme_settings.switch_theme(&theme_name, cx) {
ThemeSettings::override_global(theme_settings, cx);
}
}
})?;
}
anyhow::Ok(())
}
})
.detach();
.detach_and_log_err(cx);
}
//todo!(linux): Port fsevents to linux
@ -945,11 +959,14 @@ fn watch_themes(fs: Arc<dyn fs::Fs>, cx: &mut AppContext) {
cx.update(|cx| {
let mut theme_settings = ThemeSettings::get_global(cx).clone();
if let Some(requested_theme) =
theme_settings.requested_theme.clone()
if let Some(theme_selection) =
theme_settings.theme_selection.clone()
{
let theme_name =
theme_selection.theme(*SystemAppearance::global(cx));
if let Some(_theme) =
theme_settings.switch_theme(&requested_theme, cx)
theme_settings.switch_theme(&theme_name, cx)
{
ThemeSettings::override_global(theme_settings, cx);
}

View file

@ -1,6 +1,7 @@
use anyhow::{anyhow, Context, Result};
use cli::{ipc, IpcHandshake};
use cli::{ipc::IpcSender, CliRequest, CliResponse};
use collections::HashMap;
use editor::scroll::Autoscroll;
use editor::Editor;
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
@ -10,7 +11,6 @@ use gpui::{AppContext, AsyncAppContext, Global};
use itertools::Itertools;
use language::{Bias, Point};
use release_channel::parse_zed_link;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::os::unix::prelude::OsStrExt;
use std::path::Path;
@ -176,7 +176,7 @@ pub async fn handle_cli_connection(
if let Some(request) = requests.next().await {
match request {
CliRequest::Open { paths, wait } => {
let mut caret_positions = HashMap::new();
let mut caret_positions = HashMap::default();
let paths = if paths.is_empty() {
workspace::last_opened_workspace_paths()

View file

@ -353,7 +353,7 @@ fn initialize_pane(workspace: &mut Workspace, pane: &View<Pane>, cx: &mut ViewCo
toolbar.add_item(buffer_search_bar.clone(), cx);
let quick_action_bar =
cx.new_view(|_| QuickActionBar::new(buffer_search_bar, workspace));
cx.new_view(|cx| QuickActionBar::new(buffer_search_bar, workspace, cx));
toolbar.add_item(quick_action_bar, cx);
let diagnostic_editor_controls = cx.new_view(|_| diagnostics::ToolbarControls::new());
toolbar.add_item(diagnostic_editor_controls, cx);
@ -733,6 +733,7 @@ fn open_settings_file(
mod tests {
use super::*;
use assets::Assets;
use collections::HashSet;
use editor::{scroll::Autoscroll, DisplayPoint, Editor};
use gpui::{
actions, Action, AnyWindowHandle, AppContext, AssetSource, Entity, TestAppContext,
@ -742,10 +743,7 @@ mod tests {
use project::{project_settings::ProjectSettings, Project, ProjectPath};
use serde_json::json;
use settings::{handle_settings_file_changes, watch_config_file, SettingsStore};
use std::{
collections::HashSet,
path::{Path, PathBuf},
};
use std::path::{Path, PathBuf};
use theme::{ThemeRegistry, ThemeSettings};
use workspace::{
item::{Item, ItemHandle},