Merge branch 'main' into in-app-feedback
This commit is contained in:
commit
f2a5a4d0fd
135 changed files with 3316 additions and 2821 deletions
|
@ -1,3 +1,4 @@
|
|||
use anyhow::Context;
|
||||
use gpui::executor::Background;
|
||||
pub use language::*;
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -145,7 +146,9 @@ pub(crate) fn language(
|
|||
.unwrap()
|
||||
.data,
|
||||
)
|
||||
.with_context(|| format!("failed to load config.toml for language {name:?}"))
|
||||
.unwrap();
|
||||
|
||||
let mut language = Language::new(config, Some(grammar));
|
||||
|
||||
if let Some(query) = load_query(name, "/highlights") {
|
||||
|
@ -173,6 +176,11 @@ pub(crate) fn language(
|
|||
.with_injection_query(query.as_ref())
|
||||
.expect("failed to load injection query");
|
||||
}
|
||||
if let Some(query) = load_query(name, "/overrides") {
|
||||
language = language
|
||||
.with_override_query(query.as_ref())
|
||||
.expect("failed to load override query");
|
||||
}
|
||||
if let Some(lsp_adapter) = lsp_adapter {
|
||||
language = language.with_lsp_adapter(lsp_adapter)
|
||||
}
|
||||
|
|
|
@ -7,5 +7,20 @@ brackets = [
|
|||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/c/overrides.scm
Normal file
2
crates/zed/src/languages/c/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string_literal) @string
|
|
@ -7,5 +7,20 @@ brackets = [
|
|||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/cpp/overrides.scm
Normal file
2
crates/zed/src/languages/cpp/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string_literal) @string
|
|
@ -5,5 +5,20 @@ 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 },
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/css/overrides.scm
Normal file
2
crates/zed/src/languages/css/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string_value) @string
|
|
@ -6,5 +6,20 @@ 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 },
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/elixir/overrides.scm
Normal file
2
crates/zed/src/languages/elixir/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
[(string) (charlist)] @string
|
|
@ -4,5 +4,4 @@ autoclose_before = ">})"
|
|||
brackets = [
|
||||
{ start = "<", end = ">", close = true, newline = true },
|
||||
]
|
||||
|
||||
block_comment = ["<%#", "%>"]
|
||||
block_comment = ["<%#", "%>"]
|
||||
|
|
|
@ -7,5 +7,20 @@ brackets = [
|
|||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
|
@ -40,5 +40,4 @@
|
|||
")" @context)) @item
|
||||
|
||||
(field_declaration
|
||||
name: (_) @name
|
||||
type: (_) @context) @item
|
||||
name: (_) @name) @item
|
6
crates/zed/src/languages/go/overrides.scm
Normal file
6
crates/zed/src/languages/go/overrides.scm
Normal file
|
@ -0,0 +1,6 @@
|
|||
(comment) @comment
|
||||
[
|
||||
(interpreted_string_literal)
|
||||
(raw_string_literal)
|
||||
(rune_literal)
|
||||
] @string
|
|
@ -9,4 +9,18 @@ brackets = [
|
|||
{ start = "!--", end = " --", close = true, newline = false },
|
||||
]
|
||||
|
||||
block_comment = ["<!-- ", " -->"]
|
||||
block_comment = ["<!-- ", " -->"]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/html/overrides.scm
Normal file
2
crates/zed/src/languages/html/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(quoted_attribute_value) @string
|
|
@ -37,6 +37,8 @@ pub(crate) struct GithubReleaseAsset {
|
|||
|
||||
pub async fn npm_package_latest_version(name: &str) -> Result<String> {
|
||||
let output = smol::process::Command::new("npm")
|
||||
.args(["-fetch-retry-mintimeout", "2000"])
|
||||
.args(["-fetch-retry-maxtimeout", "5000"])
|
||||
.args(["info", name, "--json"])
|
||||
.output()
|
||||
.await
|
||||
|
@ -60,6 +62,8 @@ pub async fn npm_install_packages(
|
|||
directory: &Path,
|
||||
) -> Result<()> {
|
||||
let output = smol::process::Command::new("npm")
|
||||
.args(["-fetch-retry-mintimeout", "2000"])
|
||||
.args(["-fetch-retry-maxtimeout", "5000"])
|
||||
.arg("install")
|
||||
.arg("--prefix")
|
||||
.arg(directory)
|
||||
|
|
|
@ -12,3 +12,21 @@ brackets = [
|
|||
{ start = "`", end = "`", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.element]
|
||||
line_comment = { remove = true }
|
||||
block_comment = ["{/* ", " */}"]
|
||||
|
|
0
crates/zed/src/languages/javascript/contexts.scm
Normal file
0
crates/zed/src/languages/javascript/contexts.scm
Normal file
9
crates/zed/src/languages/javascript/overrides.scm
Normal file
9
crates/zed/src/languages/javascript/overrides.scm
Normal file
|
@ -0,0 +1,9 @@
|
|||
(comment) @comment
|
||||
(string) @string
|
||||
|
||||
[
|
||||
(jsx_element)
|
||||
(jsx_fragment)
|
||||
(jsx_self_closing_element)
|
||||
(jsx_expression)
|
||||
] @element
|
|
@ -7,3 +7,9 @@ brackets = [
|
|||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
]
|
||||
|
|
1
crates/zed/src/languages/json/overrides.scm
Normal file
1
crates/zed/src/languages/json/overrides.scm
Normal file
|
@ -0,0 +1 @@
|
|||
(string) @string
|
|
@ -12,4 +12,18 @@ brackets = [
|
|||
|
||||
auto_indent_using_last_non_empty_line = false
|
||||
increase_indent_pattern = ":$"
|
||||
decrease_indent_pattern = "^\\s*(else|elif|except|finally)\\b.*:"
|
||||
decrease_indent_pattern = "^\\s*(else|elif|except|finally)\\b.*:"
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/python/overrides.scm
Normal file
2
crates/zed/src/languages/python/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string) @string
|
|
@ -7,5 +7,19 @@ brackets = [
|
|||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
{ start = "'", end = "'", close = false, newline = false },
|
||||
]
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/ruby/overrides.scm
Normal file
2
crates/zed/src/languages/ruby/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string) @string
|
|
@ -11,3 +11,19 @@ brackets = [
|
|||
{ start = "'", end = "'", close = false, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "<", end = ">", close = false, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "<", end = ">", close = false, newline = true },
|
||||
]
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
[
|
||||
"as"
|
||||
"async"
|
||||
"await"
|
||||
"break"
|
||||
"const"
|
||||
"continue"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
(assignment_expression)
|
||||
(let_declaration)
|
||||
(let_chain)
|
||||
(await_expression)
|
||||
] @indent
|
||||
|
||||
(_ "[" "]" @end) @indent
|
||||
|
|
8
crates/zed/src/languages/rust/overrides.scm
Normal file
8
crates/zed/src/languages/rust/overrides.scm
Normal file
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
(string_literal)
|
||||
(raw_string_literal)
|
||||
] @string
|
||||
[
|
||||
(line_comment)
|
||||
(block_comment)
|
||||
] @comment
|
|
@ -7,3 +7,15 @@ brackets = [
|
|||
{ start = "(", end = ")", close = true, newline = false },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
]
|
||||
|
|
6
crates/zed/src/languages/scheme/overrides.scm
Normal file
6
crates/zed/src/languages/scheme/overrides.scm
Normal file
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
(comment)
|
||||
(block_comment)
|
||||
(directive)
|
||||
] @comment
|
||||
(string) @string
|
|
@ -6,4 +6,17 @@ brackets = [
|
|||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
{ start = "'", end = "'", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/toml/overrides.scm
Normal file
2
crates/zed/src/languages/toml/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string) @string
|
|
@ -12,3 +12,12 @@ brackets = [
|
|||
{ start = "`", end = "`", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.element]
|
||||
line_comment = { remove = true }
|
||||
block_comment = ["{/* ", " */}"]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
]
|
||||
|
|
7
crates/zed/src/languages/tsx/overrides.scm
Normal file
7
crates/zed/src/languages/tsx/overrides.scm
Normal file
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
(jsx_element)
|
||||
(jsx_fragment)
|
||||
(jsx_self_closing_element)
|
||||
(jsx_expression)
|
||||
] @element
|
||||
(string) @string
|
|
@ -12,7 +12,8 @@ use util::ResultExt;
|
|||
pub struct TypeScriptLspAdapter;
|
||||
|
||||
impl TypeScriptLspAdapter {
|
||||
const BIN_PATH: &'static str = "node_modules/typescript-language-server/lib/cli.js";
|
||||
const OLD_BIN_PATH: &'static str = "node_modules/typescript-language-server/lib/cli.js";
|
||||
const NEW_BIN_PATH: &'static str = "node_modules/typescript-language-server/lib/cli.mjs";
|
||||
}
|
||||
|
||||
struct Versions {
|
||||
|
@ -57,7 +58,7 @@ impl LspAdapter for TypeScriptLspAdapter {
|
|||
fs::create_dir_all(&version_dir)
|
||||
.await
|
||||
.context("failed to create version directory")?;
|
||||
let binary_path = version_dir.join(Self::BIN_PATH);
|
||||
let binary_path = version_dir.join(Self::NEW_BIN_PATH);
|
||||
|
||||
if fs::metadata(&binary_path).await.is_err() {
|
||||
npm_install_packages(
|
||||
|
@ -98,9 +99,12 @@ impl LspAdapter for TypeScriptLspAdapter {
|
|||
}
|
||||
}
|
||||
let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
|
||||
let bin_path = last_version_dir.join(Self::BIN_PATH);
|
||||
if bin_path.exists() {
|
||||
Ok(bin_path)
|
||||
let old_bin_path = last_version_dir.join(Self::OLD_BIN_PATH);
|
||||
let new_bin_path = last_version_dir.join(Self::NEW_BIN_PATH);
|
||||
if new_bin_path.exists() {
|
||||
Ok(new_bin_path)
|
||||
} else if old_bin_path.exists() {
|
||||
Ok(old_bin_path)
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"missing executable in directory {:?}",
|
||||
|
|
|
@ -12,3 +12,17 @@ brackets = [
|
|||
{ start = "`", end = "`", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[overrides.comment]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
||||
[overrides.string]
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
]
|
||||
|
|
2
crates/zed/src/languages/typescript/overrides.scm
Normal file
2
crates/zed/src/languages/typescript/overrides.scm
Normal file
|
@ -0,0 +1,2 @@
|
|||
(comment) @comment
|
||||
(string) @string
|
|
@ -19,7 +19,7 @@ use futures::{
|
|||
channel::{mpsc, oneshot},
|
||||
FutureExt, SinkExt, StreamExt,
|
||||
};
|
||||
use gpui::{executor::Background, App, AssetSource, AsyncAppContext, Task, ViewContext};
|
||||
use gpui::{App, AssetSource, AsyncAppContext, MutableAppContext, Task, ViewContext};
|
||||
use isahc::{config::Configurable, Request};
|
||||
use language::LanguageRegistry;
|
||||
use log::LevelFilter;
|
||||
|
@ -30,6 +30,7 @@ use settings::{
|
|||
self, settings_file::SettingsFile, KeymapFileContent, Settings, SettingsFileContent,
|
||||
WorkingDirectory,
|
||||
};
|
||||
use simplelog::ConfigBuilder;
|
||||
use smol::process::Command;
|
||||
use std::fs::OpenOptions;
|
||||
use std::{env, ffi::OsStr, panic, path::PathBuf, sync::Arc, thread, time::Duration};
|
||||
|
@ -51,10 +52,13 @@ fn main() {
|
|||
|
||||
log::info!("========== starting zed ==========");
|
||||
let mut app = gpui::App::new(Assets).unwrap();
|
||||
|
||||
let app_version = ZED_APP_VERSION
|
||||
.or_else(|| app.platform().app_version().ok())
|
||||
.map_or("dev".to_string(), |v| v.to_string());
|
||||
init_panic_hook(app_version, http.clone(), app.background());
|
||||
init_panic_hook(app_version);
|
||||
|
||||
app.background();
|
||||
|
||||
load_embedded_fonts(&app);
|
||||
|
||||
|
@ -62,7 +66,6 @@ fn main() {
|
|||
|
||||
let themes = ThemeRegistry::new(Assets, app.font_cache());
|
||||
let default_settings = Settings::defaults(Assets, &app.font_cache(), &themes);
|
||||
|
||||
let config_files = load_config_files(&app, fs.clone());
|
||||
|
||||
let login_shell_env_loaded = if stdout_is_a_pty() {
|
||||
|
@ -74,6 +77,7 @@ fn main() {
|
|||
};
|
||||
|
||||
let (cli_connections_tx, mut cli_connections_rx) = mpsc::unbounded();
|
||||
let (open_paths_tx, open_paths_rx) = mpsc::unbounded();
|
||||
app.on_open_urls(move |urls, _| {
|
||||
if let Some(server_name) = urls.first().and_then(|url| url.strip_prefix("zed-cli://")) {
|
||||
if let Some(cli_connection) = connect_to_cli(server_name).log_err() {
|
||||
|
@ -82,6 +86,16 @@ fn main() {
|
|||
.map_err(|_| anyhow!("no listener for cli connections"))
|
||||
.log_err();
|
||||
};
|
||||
} else {
|
||||
let paths: Vec<_> = urls
|
||||
.iter()
|
||||
.flat_map(|url| url.strip_prefix("file://"))
|
||||
.map(|path| PathBuf::from(path))
|
||||
.collect();
|
||||
open_paths_tx
|
||||
.unbounded_send(paths)
|
||||
.map_err(|_| anyhow!("no listener for open urls requests"))
|
||||
.log_err();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -89,6 +103,18 @@ fn main() {
|
|||
cx.set_global(*RELEASE_CHANNEL);
|
||||
cx.set_global(HomeDir(paths::HOME.to_path_buf()));
|
||||
|
||||
let (settings_file_content, keymap_file) = cx.background().block(config_files).unwrap();
|
||||
|
||||
//Setup settings global before binding actions
|
||||
cx.set_global(SettingsFile::new(
|
||||
&paths::SETTINGS,
|
||||
settings_file_content.clone(),
|
||||
fs.clone(),
|
||||
));
|
||||
|
||||
watch_settings_file(default_settings, settings_file_content, themes.clone(), cx);
|
||||
upload_previous_panics(http.clone(), cx);
|
||||
|
||||
let client = client::Client::new(http.clone(), cx);
|
||||
let mut languages = LanguageRegistry::new(login_shell_env_loaded);
|
||||
languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone());
|
||||
|
@ -98,15 +124,6 @@ fn main() {
|
|||
.spawn(languages::init(languages.clone(), cx.background().clone()));
|
||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
|
||||
|
||||
let (settings_file_content, keymap_file) = cx.background().block(config_files).unwrap();
|
||||
|
||||
//Setup settings global before binding actions
|
||||
cx.set_global(SettingsFile::new(
|
||||
&paths::SETTINGS,
|
||||
settings_file_content.clone(),
|
||||
fs.clone(),
|
||||
));
|
||||
watch_settings_file(default_settings, settings_file_content, themes.clone(), cx);
|
||||
watch_keymap_file(keymap_file, cx);
|
||||
|
||||
cx.set_global(client.clone());
|
||||
|
@ -147,7 +164,11 @@ fn main() {
|
|||
.detach();
|
||||
|
||||
client.start_telemetry();
|
||||
client.report_event("start app", Default::default());
|
||||
client.report_event(
|
||||
"start app",
|
||||
Default::default(),
|
||||
cx.global::<Settings>().telemetry(),
|
||||
);
|
||||
|
||||
let app_state = Arc::new(AppState {
|
||||
languages,
|
||||
|
@ -170,11 +191,15 @@ fn main() {
|
|||
|
||||
cx.set_menus(menus::menus());
|
||||
|
||||
cx.spawn(|cx| handle_open_paths(open_paths_rx, app_state.clone(), cx))
|
||||
.detach();
|
||||
|
||||
if stdout_is_a_pty() {
|
||||
cx.platform().activate(true);
|
||||
let paths = collect_path_args();
|
||||
if paths.is_empty() {
|
||||
restore_or_create_workspace(cx);
|
||||
cx.spawn(|cx| async move { restore_or_create_workspace(cx).await })
|
||||
.detach()
|
||||
} else {
|
||||
cx.dispatch_global_action(OpenPaths { paths });
|
||||
}
|
||||
|
@ -183,7 +208,8 @@ fn main() {
|
|||
cx.spawn(|cx| handle_cli_connection(connection, app_state.clone(), cx))
|
||||
.detach();
|
||||
} else {
|
||||
restore_or_create_workspace(cx);
|
||||
cx.spawn(|cx| async move { restore_or_create_workspace(cx).await })
|
||||
.detach()
|
||||
}
|
||||
cx.spawn(|cx| async move {
|
||||
while let Some(connection) = cli_connections_rx.next().await {
|
||||
|
@ -207,13 +233,17 @@ fn main() {
|
|||
});
|
||||
}
|
||||
|
||||
fn restore_or_create_workspace(cx: &mut gpui::MutableAppContext) {
|
||||
if let Some(location) = workspace::last_opened_workspace_paths() {
|
||||
cx.dispatch_global_action(OpenPaths {
|
||||
paths: location.paths().as_ref().clone(),
|
||||
})
|
||||
async fn restore_or_create_workspace(mut cx: AsyncAppContext) {
|
||||
if let Some(location) = workspace::last_opened_workspace_paths().await {
|
||||
cx.update(|cx| {
|
||||
cx.dispatch_global_action(OpenPaths {
|
||||
paths: location.paths().as_ref().clone(),
|
||||
})
|
||||
});
|
||||
} else {
|
||||
cx.dispatch_global_action(NewFile);
|
||||
cx.update(|cx| {
|
||||
cx.dispatch_global_action(NewFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,70 +274,16 @@ fn init_logger() {
|
|||
.append(true)
|
||||
.open(&*paths::LOG)
|
||||
.expect("could not open logfile");
|
||||
simplelog::WriteLogger::init(level, simplelog::Config::default(), log_file)
|
||||
.expect("could not initialize logger");
|
||||
|
||||
let config = ConfigBuilder::new()
|
||||
.set_time_format_str("%Y-%m-%dT%T") //All timestamps are UTC
|
||||
.build();
|
||||
|
||||
simplelog::WriteLogger::init(level, config, log_file).expect("could not initialize logger");
|
||||
}
|
||||
}
|
||||
|
||||
fn init_panic_hook(app_version: String, http: Arc<dyn HttpClient>, background: Arc<Background>) {
|
||||
background
|
||||
.spawn({
|
||||
async move {
|
||||
let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL);
|
||||
let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
|
||||
while let Some(child) = children.next().await {
|
||||
let child = child?;
|
||||
let child_path = child.path();
|
||||
if child_path.extension() != Some(OsStr::new("panic")) {
|
||||
continue;
|
||||
}
|
||||
let filename = if let Some(filename) = child_path.file_name() {
|
||||
filename.to_string_lossy()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut components = filename.split('-');
|
||||
if components.next() != Some("zed") {
|
||||
continue;
|
||||
}
|
||||
let version = if let Some(version) = components.next() {
|
||||
version
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let text = smol::fs::read_to_string(&child_path)
|
||||
.await
|
||||
.context("error reading panic file")?;
|
||||
let body = serde_json::to_string(&json!({
|
||||
"text": text,
|
||||
"version": version,
|
||||
"token": ZED_SECRET_CLIENT_TOKEN,
|
||||
}))
|
||||
.unwrap();
|
||||
let request = Request::post(&panic_report_url)
|
||||
.redirect_policy(isahc::config::RedirectPolicy::Follow)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(body.into())?;
|
||||
let response = http.send(request).await.context("error sending panic")?;
|
||||
if response.status().is_success() {
|
||||
std::fs::remove_file(child_path)
|
||||
.context("error removing panic after sending it successfully")
|
||||
.log_err();
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"error uploading panic to server: {}",
|
||||
response.status()
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok::<_, anyhow::Error>(())
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
|
||||
fn init_panic_hook(app_version: String) {
|
||||
let is_pty = stdout_is_a_pty();
|
||||
panic::set_hook(Box::new(move |info| {
|
||||
let backtrace = Backtrace::new();
|
||||
|
@ -356,6 +332,69 @@ fn init_panic_hook(app_version: String, http: Arc<dyn HttpClient>, background: A
|
|||
}));
|
||||
}
|
||||
|
||||
fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut MutableAppContext) {
|
||||
let diagnostics_telemetry = cx.global::<Settings>().telemetry_diagnostics();
|
||||
|
||||
cx.background()
|
||||
.spawn({
|
||||
async move {
|
||||
let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL);
|
||||
let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
|
||||
while let Some(child) = children.next().await {
|
||||
let child = child?;
|
||||
let child_path = child.path();
|
||||
|
||||
if child_path.extension() != Some(OsStr::new("panic")) {
|
||||
continue;
|
||||
}
|
||||
let filename = if let Some(filename) = child_path.file_name() {
|
||||
filename.to_string_lossy()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut components = filename.split('-');
|
||||
if components.next() != Some("zed") {
|
||||
continue;
|
||||
}
|
||||
let version = if let Some(version) = components.next() {
|
||||
version
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if diagnostics_telemetry {
|
||||
let text = smol::fs::read_to_string(&child_path)
|
||||
.await
|
||||
.context("error reading panic file")?;
|
||||
let body = serde_json::to_string(&json!({
|
||||
"text": text,
|
||||
"version": version,
|
||||
"token": ZED_SECRET_CLIENT_TOKEN,
|
||||
}))
|
||||
.unwrap();
|
||||
let request = Request::post(&panic_report_url)
|
||||
.redirect_policy(isahc::config::RedirectPolicy::Follow)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(body.into())?;
|
||||
let response = http.send(request).await.context("error sending panic")?;
|
||||
if !response.status().is_success() {
|
||||
log::error!("Error uploading panic to server: {}", response.status());
|
||||
}
|
||||
}
|
||||
|
||||
// We've done what we can, delete the file
|
||||
std::fs::remove_file(child_path)
|
||||
.context("error removing panic")
|
||||
.log_err();
|
||||
}
|
||||
Ok::<_, anyhow::Error>(())
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
async fn load_login_shell_environment() -> Result<()> {
|
||||
let marker = "ZED_LOGIN_SHELL_START";
|
||||
let shell = env::var("SHELL").context(
|
||||
|
@ -484,6 +523,17 @@ fn load_config_files(
|
|||
rx
|
||||
}
|
||||
|
||||
async fn handle_open_paths(
|
||||
mut rx: mpsc::UnboundedReceiver<Vec<PathBuf>>,
|
||||
app_state: Arc<AppState>,
|
||||
mut cx: AsyncAppContext,
|
||||
) {
|
||||
while let Some(paths) = rx.next().await {
|
||||
cx.update(|cx| workspace::open_paths(&paths, &app_state, cx))
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_to_cli(
|
||||
server_name: &str,
|
||||
) -> Result<(mpsc::Receiver<CliRequest>, IpcSender<CliResponse>)> {
|
||||
|
|
|
@ -11,6 +11,7 @@ use collections::VecDeque;
|
|||
pub use editor;
|
||||
use editor::{Editor, MultiBuffer};
|
||||
|
||||
use futures::StreamExt;
|
||||
use gpui::{
|
||||
actions,
|
||||
geometry::{
|
||||
|
@ -19,7 +20,8 @@ use gpui::{
|
|||
},
|
||||
impl_actions,
|
||||
platform::{WindowBounds, WindowOptions},
|
||||
AssetSource, AsyncAppContext, TitlebarOptions, ViewContext, WindowKind,
|
||||
AssetSource, AsyncAppContext, ClipboardItem, PromptLevel, TitlebarOptions, ViewContext,
|
||||
WindowKind,
|
||||
};
|
||||
use language::Rope;
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -379,7 +381,23 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
|
|||
// prompt in the active window before switching to a different window.
|
||||
workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id()));
|
||||
|
||||
let should_confirm = cx.global::<Settings>().confirm_quit;
|
||||
cx.spawn(|mut cx| async move {
|
||||
if let (true, Some(workspace)) = (should_confirm, workspaces.first()) {
|
||||
let answer = cx
|
||||
.prompt(
|
||||
workspace.window_id(),
|
||||
PromptLevel::Info,
|
||||
"Are you sure you want to quit?",
|
||||
&["Quit", "Cancel"],
|
||||
)
|
||||
.next()
|
||||
.await;
|
||||
if answer != Some(0) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
// If the user cancels any save prompt, then keep the app open.
|
||||
for workspace in workspaces {
|
||||
if !workspace
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue