Compare commits
2 Commits
configurat
...
context-se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a533e622fa | ||
|
|
cd7073bd19 |
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -2329,6 +2329,7 @@ dependencies = [
|
||||
"futures 0.3.30",
|
||||
"gpui",
|
||||
"http_client",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
@@ -2530,6 +2531,7 @@ dependencies = [
|
||||
"gpui",
|
||||
"http_client",
|
||||
"language",
|
||||
"lazy_static",
|
||||
"menu",
|
||||
"notifications",
|
||||
"parking_lot",
|
||||
@@ -3261,6 +3263,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"gpui",
|
||||
"indoc",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"paths",
|
||||
"release_channel",
|
||||
@@ -3540,6 +3543,7 @@ dependencies = [
|
||||
"indoc",
|
||||
"itertools 0.11.0",
|
||||
"language",
|
||||
"lazy_static",
|
||||
"linkify",
|
||||
"log",
|
||||
"lsp",
|
||||
@@ -4302,6 +4306,7 @@ dependencies = [
|
||||
"git",
|
||||
"git2",
|
||||
"gpui",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"notify",
|
||||
"objc",
|
||||
@@ -4627,6 +4632,7 @@ dependencies = [
|
||||
"git2",
|
||||
"gpui",
|
||||
"http_client",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"pretty_assertions",
|
||||
@@ -4825,6 +4831,7 @@ dependencies = [
|
||||
"http_client",
|
||||
"image",
|
||||
"itertools 0.11.0",
|
||||
"lazy_static",
|
||||
"linkme",
|
||||
"log",
|
||||
"media",
|
||||
@@ -5940,6 +5947,7 @@ dependencies = [
|
||||
"http_client",
|
||||
"indoc",
|
||||
"itertools 0.11.0",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lsp",
|
||||
"parking_lot",
|
||||
@@ -6073,6 +6081,7 @@ dependencies = [
|
||||
"gpui",
|
||||
"http_client",
|
||||
"language",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lsp",
|
||||
"node_runtime",
|
||||
@@ -9732,6 +9741,7 @@ dependencies = [
|
||||
"futures 0.3.30",
|
||||
"gpui",
|
||||
"indoc",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"paths",
|
||||
"pretty_assertions",
|
||||
@@ -10143,6 +10153,7 @@ dependencies = [
|
||||
"collections",
|
||||
"futures 0.3.30",
|
||||
"indoc",
|
||||
"lazy_static",
|
||||
"libsqlite3-sys",
|
||||
"parking_lot",
|
||||
"smol",
|
||||
@@ -10155,6 +10166,7 @@ dependencies = [
|
||||
name = "sqlez_macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"sqlez",
|
||||
"sqlformat",
|
||||
"syn 1.0.109",
|
||||
@@ -11002,6 +11014,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"gpui",
|
||||
"http_client",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"postage",
|
||||
@@ -12199,6 +12212,7 @@ dependencies = [
|
||||
"indoc",
|
||||
"itertools 0.11.0",
|
||||
"language",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lsp",
|
||||
"multi_buffer",
|
||||
@@ -13541,6 +13555,7 @@ dependencies = [
|
||||
"http_client",
|
||||
"itertools 0.11.0",
|
||||
"language",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"node_runtime",
|
||||
"parking_lot",
|
||||
@@ -13735,8 +13750,6 @@ dependencies = [
|
||||
"cargo_metadata",
|
||||
"cargo_toml",
|
||||
"clap",
|
||||
"schemars",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -359,6 +359,7 @@ isahc = { version = "1.7.2", default-features = false, features = [
|
||||
] }
|
||||
itertools = "0.11.0"
|
||||
jsonwebtoken = "9.3"
|
||||
lazy_static = "1.4.0"
|
||||
libc = "0.2"
|
||||
linkify = "0.10.0"
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
"ui_font_weight": 400,
|
||||
// The default font size for text in the UI
|
||||
"ui_font_size": 16,
|
||||
// How much to fade out unused code.
|
||||
"unnecessary_code_fade": 0.3,
|
||||
// The factor to grow the active pane by. Defaults to 1.0
|
||||
// which gives the same size as all other panes.
|
||||
"active_pane_magnification": 1.0,
|
||||
|
||||
@@ -926,7 +926,6 @@ impl PromptLibrary {
|
||||
color: Some(cx.theme().status().predictive),
|
||||
..HighlightStyle::default()
|
||||
},
|
||||
..EditorStyle::default()
|
||||
},
|
||||
)),
|
||||
),
|
||||
|
||||
@@ -27,6 +27,7 @@ fs.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
once_cell.workspace = true
|
||||
paths.workspace = true
|
||||
|
||||
@@ -22,6 +22,7 @@ use gpui::{
|
||||
actions, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Global, Model, Task, WeakModel,
|
||||
};
|
||||
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::RwLock;
|
||||
use postage::watch;
|
||||
use proto::ProtoClient;
|
||||
@@ -42,7 +43,7 @@ use std::{
|
||||
path::PathBuf,
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
Arc, LazyLock, Weak,
|
||||
Arc, Weak,
|
||||
},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
@@ -64,35 +65,27 @@ impl fmt::Display for DevServerToken {
|
||||
}
|
||||
}
|
||||
|
||||
static ZED_SERVER_URL: LazyLock<Option<String>> =
|
||||
LazyLock::new(|| std::env::var("ZED_SERVER_URL").ok());
|
||||
static ZED_RPC_URL: LazyLock<Option<String>> = LazyLock::new(|| std::env::var("ZED_RPC_URL").ok());
|
||||
|
||||
/// An environment variable whose presence indicates that the development auth
|
||||
/// provider should be used.
|
||||
///
|
||||
/// Only works in development. Setting this environment variable in other release
|
||||
/// channels is a no-op.
|
||||
pub static ZED_DEVELOPMENT_AUTH: LazyLock<bool> = LazyLock::new(|| {
|
||||
std::env::var("ZED_DEVELOPMENT_AUTH").map_or(false, |value| !value.is_empty())
|
||||
});
|
||||
pub static IMPERSONATE_LOGIN: LazyLock<Option<String>> = LazyLock::new(|| {
|
||||
std::env::var("ZED_IMPERSONATE")
|
||||
lazy_static! {
|
||||
static ref ZED_SERVER_URL: Option<String> = std::env::var("ZED_SERVER_URL").ok();
|
||||
static ref ZED_RPC_URL: Option<String> = std::env::var("ZED_RPC_URL").ok();
|
||||
/// An environment variable whose presence indicates that the development auth
|
||||
/// provider should be used.
|
||||
///
|
||||
/// Only works in development. Setting this environment variable in other release
|
||||
/// channels is a no-op.
|
||||
pub static ref ZED_DEVELOPMENT_AUTH: bool =
|
||||
std::env::var("ZED_DEVELOPMENT_AUTH").map_or(false, |value| !value.is_empty());
|
||||
pub static ref IMPERSONATE_LOGIN: Option<String> = std::env::var("ZED_IMPERSONATE")
|
||||
.ok()
|
||||
.and_then(|s| if s.is_empty() { None } else { Some(s) })
|
||||
});
|
||||
|
||||
pub static ADMIN_API_TOKEN: LazyLock<Option<String>> = LazyLock::new(|| {
|
||||
std::env::var("ZED_ADMIN_API_TOKEN")
|
||||
.and_then(|s| if s.is_empty() { None } else { Some(s) });
|
||||
pub static ref ADMIN_API_TOKEN: Option<String> = std::env::var("ZED_ADMIN_API_TOKEN")
|
||||
.ok()
|
||||
.and_then(|s| if s.is_empty() { None } else { Some(s) })
|
||||
});
|
||||
|
||||
pub static ZED_APP_PATH: LazyLock<Option<PathBuf>> =
|
||||
LazyLock::new(|| std::env::var("ZED_APP_PATH").ok().map(PathBuf::from));
|
||||
|
||||
pub static ZED_ALWAYS_ACTIVE: LazyLock<bool> =
|
||||
LazyLock::new(|| std::env::var("ZED_ALWAYS_ACTIVE").map_or(false, |e| !e.is_empty()));
|
||||
.and_then(|s| if s.is_empty() { None } else { Some(s) });
|
||||
pub static ref ZED_APP_PATH: Option<PathBuf> =
|
||||
std::env::var("ZED_APP_PATH").ok().map(PathBuf::from);
|
||||
pub static ref ZED_ALWAYS_ACTIVE: bool =
|
||||
std::env::var("ZED_ALWAYS_ACTIVE").map_or(false, |e| !e.is_empty());
|
||||
}
|
||||
|
||||
pub const INITIAL_RECONNECTION_DELAY: Duration = Duration::from_millis(500);
|
||||
pub const MAX_RECONNECTION_DELAY: Duration = Duration::from_secs(10);
|
||||
|
||||
@@ -42,6 +42,7 @@ futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
lazy_static.workspace = true
|
||||
menu.workspace = true
|
||||
notifications.workspace = true
|
||||
parking_lot.workspace = true
|
||||
|
||||
@@ -12,10 +12,11 @@ use language::{
|
||||
language_settings::SoftWrap, Anchor, Buffer, BufferSnapshot, CodeLabel, LanguageRegistry,
|
||||
LanguageServerId, ToOffset,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::RwLock;
|
||||
use project::{search::SearchQuery, Completion};
|
||||
use settings::Settings;
|
||||
use std::{ops::Range, sync::Arc, sync::LazyLock, time::Duration};
|
||||
use std::{ops::Range, sync::Arc, time::Duration};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{prelude::*, TextSize};
|
||||
|
||||
@@ -23,17 +24,17 @@ use crate::panel_settings::MessageEditorSettings;
|
||||
|
||||
const MENTIONS_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(50);
|
||||
|
||||
static MENTIONS_SEARCH: LazyLock<SearchQuery> = LazyLock::new(|| {
|
||||
SearchQuery::regex(
|
||||
lazy_static! {
|
||||
static ref MENTIONS_SEARCH: SearchQuery = SearchQuery::regex(
|
||||
"@[-_\\w]+",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default()
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub struct MessageEditor {
|
||||
pub editor: View<Editor>,
|
||||
@@ -398,8 +399,8 @@ impl MessageEditor {
|
||||
end_anchor: Anchor,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<(Anchor, String, &'static [StringMatchCandidate])> {
|
||||
static EMOJI_FUZZY_MATCH_CANDIDATES: LazyLock<Vec<StringMatchCandidate>> =
|
||||
LazyLock::new(|| {
|
||||
lazy_static! {
|
||||
static ref EMOJI_FUZZY_MATCH_CANDIDATES: Vec<StringMatchCandidate> = {
|
||||
let emojis = emojis::iter()
|
||||
.flat_map(|s| s.shortcodes())
|
||||
.map(|emoji| StringMatchCandidate {
|
||||
@@ -409,7 +410,8 @@ impl MessageEditor {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
emojis
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
let end_offset = end_anchor.to_offset(buffer.read(cx));
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ test-support = []
|
||||
anyhow.workspace = true
|
||||
gpui.workspace = true
|
||||
indoc.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
paths.workspace = true
|
||||
release_channel.workspace = true
|
||||
|
||||
@@ -6,6 +6,7 @@ pub use anyhow;
|
||||
use anyhow::Context;
|
||||
use gpui::AppContext;
|
||||
pub use indoc::indoc;
|
||||
pub use lazy_static;
|
||||
pub use paths::database_dir;
|
||||
pub use smol;
|
||||
pub use sqlez;
|
||||
@@ -16,11 +17,9 @@ pub use release_channel::RELEASE_CHANNEL;
|
||||
use sqlez::domain::Migrator;
|
||||
use sqlez::thread_safe_connection::ThreadSafeConnection;
|
||||
use sqlez_macros::sql;
|
||||
use std::env;
|
||||
use std::future::Future;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::LazyLock;
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const CONNECTION_INITIALIZE_QUERY: &str = sql!(
|
||||
@@ -38,10 +37,10 @@ const FALLBACK_DB_NAME: &str = "FALLBACK_MEMORY_DB";
|
||||
|
||||
const DB_FILE_NAME: &str = "db.sqlite";
|
||||
|
||||
pub static ZED_STATELESS: LazyLock<bool> =
|
||||
LazyLock::new(|| env::var("ZED_STATELESS").map_or(false, |v| !v.is_empty()));
|
||||
|
||||
pub static ALL_FILE_DB_FAILED: LazyLock<AtomicBool> = LazyLock::new(|| AtomicBool::new(false));
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref ZED_STATELESS: bool = std::env::var("ZED_STATELESS").map_or(false, |v| !v.is_empty());
|
||||
pub static ref ALL_FILE_DB_FAILED: AtomicBool = AtomicBool::new(false);
|
||||
}
|
||||
|
||||
/// Open or create a database at the given directory path.
|
||||
/// This will retry a couple times if there are failures. If opening fails once, the db directory
|
||||
@@ -139,16 +138,15 @@ macro_rules! define_connection {
|
||||
}
|
||||
}
|
||||
|
||||
use std::sync::LazyLock;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub static $id: LazyLock<$t> = LazyLock::new(|| {
|
||||
$t($crate::smol::block_on($crate::open_test_db(stringify!($id))))
|
||||
});
|
||||
$crate::lazy_static::lazy_static! {
|
||||
pub static ref $id: $t = $t($crate::smol::block_on($crate::open_test_db(stringify!($id))));
|
||||
}
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
pub static $id: LazyLock<$t> = LazyLock::new(|| {
|
||||
$t($crate::smol::block_on($crate::open_db($crate::database_dir(), &$crate::RELEASE_CHANNEL)))
|
||||
});
|
||||
$crate::lazy_static::lazy_static! {
|
||||
pub static ref $id: $t = $t($crate::smol::block_on($crate::open_db($crate::database_dir(), &$crate::RELEASE_CHANNEL)));
|
||||
}
|
||||
};
|
||||
(pub static ref $id:ident: $t:ident<$($d:ty),+> = $migrations:expr;) => {
|
||||
pub struct $t($crate::sqlez::thread_safe_connection::ThreadSafeConnection<( $($d),+, $t )>);
|
||||
@@ -172,14 +170,14 @@ macro_rules! define_connection {
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub static $id: std::sync::LazyLock<$t> = std::sync::LazyLock::new(|| {
|
||||
$t($crate::smol::block_on($crate::open_test_db(stringify!($id))))
|
||||
});
|
||||
$crate::lazy_static::lazy_static! {
|
||||
pub static ref $id: $t = $t($crate::smol::block_on($crate::open_test_db(stringify!($id))));
|
||||
}
|
||||
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
pub static $id: std::sync::LazyLock<$t> = std::sync::LazyLock::new(|| {
|
||||
$t($crate::smol::block_on($crate::open_db($crate::database_dir(), &$crate::RELEASE_CHANNEL)))
|
||||
});
|
||||
$crate::lazy_static::lazy_static! {
|
||||
pub static ref $id: $t = $t($crate::smol::block_on($crate::open_db($crate::database_dir(), &$crate::RELEASE_CHANNEL)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ http_client.workspace = true
|
||||
indoc.workspace = true
|
||||
itertools.workspace = true
|
||||
language.workspace = true
|
||||
lazy_static.workspace = true
|
||||
linkify.workspace = true
|
||||
log.workspace = true
|
||||
lsp.workspace = true
|
||||
|
||||
@@ -74,6 +74,8 @@ pub enum FoldStatus {
|
||||
|
||||
pub type RenderFoldToggle = Arc<dyn Fn(FoldStatus, &mut WindowContext) -> AnyElement>;
|
||||
|
||||
const UNNECESSARY_CODE_FADE: f32 = 0.3;
|
||||
|
||||
pub trait ToDisplayPoint {
|
||||
fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint;
|
||||
}
|
||||
@@ -689,7 +691,7 @@ impl DisplaySnapshot {
|
||||
let mut diagnostic_highlight = HighlightStyle::default();
|
||||
|
||||
if chunk.is_unnecessary {
|
||||
diagnostic_highlight.fade_out = Some(editor_style.unnecessary_code_fade);
|
||||
diagnostic_highlight.fade_out = Some(UNNECESSARY_CODE_FADE);
|
||||
}
|
||||
|
||||
if let Some(severity) = chunk.diagnostic_severity {
|
||||
|
||||
@@ -5,9 +5,9 @@ use super::{
|
||||
};
|
||||
use gpui::{AppContext, Context, Font, LineWrapper, Model, ModelContext, Pixels, Task};
|
||||
use language::{Chunk, Point};
|
||||
use lazy_static::lazy_static;
|
||||
use multi_buffer::MultiBufferSnapshot;
|
||||
use smol::future::yield_now;
|
||||
use std::sync::LazyLock;
|
||||
use std::{cmp, collections::VecDeque, mem, ops::Range, time::Duration};
|
||||
use sum_tree::{Bias, Cursor, SumTree};
|
||||
use text::Patch;
|
||||
@@ -887,12 +887,14 @@ impl Transform {
|
||||
}
|
||||
|
||||
fn wrap(indent: u32) -> Self {
|
||||
static WRAP_TEXT: LazyLock<String> = LazyLock::new(|| {
|
||||
let mut wrap_text = String::new();
|
||||
wrap_text.push('\n');
|
||||
wrap_text.extend((0..LineWrapper::MAX_INDENT as usize).map(|_| ' '));
|
||||
wrap_text
|
||||
});
|
||||
lazy_static! {
|
||||
static ref WRAP_TEXT: String = {
|
||||
let mut wrap_text = String::new();
|
||||
wrap_text.push('\n');
|
||||
wrap_text.extend((0..LineWrapper::MAX_INDENT as usize).map(|_| ' '));
|
||||
wrap_text
|
||||
};
|
||||
}
|
||||
|
||||
Self {
|
||||
summary: TransformSummary {
|
||||
|
||||
@@ -384,7 +384,6 @@ pub struct EditorStyle {
|
||||
pub status: StatusColors,
|
||||
pub inlay_hints_style: HighlightStyle,
|
||||
pub suggestions_style: HighlightStyle,
|
||||
pub unnecessary_code_fade: f32,
|
||||
}
|
||||
|
||||
impl Default for EditorStyle {
|
||||
@@ -401,7 +400,6 @@ impl Default for EditorStyle {
|
||||
status: StatusColors::dark(),
|
||||
inlay_hints_style: HighlightStyle::default(),
|
||||
suggestions_style: HighlightStyle::default(),
|
||||
unnecessary_code_fade: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9700,7 +9698,6 @@ impl Editor {
|
||||
color: Some(cx.theme().status().predictive),
|
||||
..HighlightStyle::default()
|
||||
},
|
||||
..EditorStyle::default()
|
||||
},
|
||||
))
|
||||
.into_any_element()
|
||||
@@ -12591,7 +12588,6 @@ impl Render for Editor {
|
||||
color: Some(cx.theme().status().predictive),
|
||||
..HighlightStyle::default()
|
||||
},
|
||||
unnecessary_code_fade: ThemeSettings::get_global(cx).unnecessary_code_fade,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ futures.workspace = true
|
||||
git.workspace = true
|
||||
git2.workspace = true
|
||||
gpui.workspace = true
|
||||
lazy_static.workspace = true
|
||||
libc.workspace = true
|
||||
parking_lot.workspace = true
|
||||
paths.workspace = true
|
||||
|
||||
@@ -794,8 +794,9 @@ impl FakeFsState {
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub static FS_DOT_GIT: std::sync::LazyLock<&'static OsStr> =
|
||||
std::sync::LazyLock::new(|| OsStr::new(".git"));
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref FS_DOT_GIT: &'static OsStr = OsStr::new(".git");
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl FakeFs {
|
||||
|
||||
@@ -20,6 +20,7 @@ derive_more.workspace = true
|
||||
git2.workspace = true
|
||||
gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
rope.workspace = true
|
||||
|
||||
@@ -5,9 +5,9 @@ use serde::{Deserialize, Serialize};
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
pub use git2 as libgit;
|
||||
pub use lazy_static::lazy_static;
|
||||
|
||||
pub use crate::hosting_provider::*;
|
||||
|
||||
@@ -17,8 +17,10 @@ pub mod diff;
|
||||
pub mod repository;
|
||||
pub mod status;
|
||||
|
||||
pub static DOT_GIT: LazyLock<&'static OsStr> = LazyLock::new(|| OsStr::new(".git"));
|
||||
pub static GITIGNORE: LazyLock<&'static OsStr> = LazyLock::new(|| OsStr::new(".gitignore"));
|
||||
lazy_static! {
|
||||
pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git");
|
||||
pub static ref GITIGNORE: &'static OsStr = OsStr::new(".gitignore");
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub struct Oid(libgit::Oid);
|
||||
|
||||
@@ -43,6 +43,7 @@ gpui_macros.workspace = true
|
||||
http_client.workspace = true
|
||||
image = "0.25.1"
|
||||
itertools.workspace = true
|
||||
lazy_static.workspace = true
|
||||
linkme = "0.3"
|
||||
log.workspace = true
|
||||
num_cpus = "1.13"
|
||||
|
||||
@@ -642,8 +642,10 @@ impl<T> PartialEq<Model<T>> for WeakModel<T> {
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
static LEAK_BACKTRACE: std::sync::LazyLock<bool> =
|
||||
std::sync::LazyLock::new(|| std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty()));
|
||||
lazy_static::lazy_static! {
|
||||
static ref LEAK_BACKTRACE: bool =
|
||||
std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty());
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
|
||||
|
||||
@@ -940,11 +940,11 @@ pub enum CursorStyle {
|
||||
ResizeUpRightDownLeft,
|
||||
|
||||
/// A cursor indicating that the item/column can be resized horizontally.
|
||||
/// corresponds to the CSS cursor value `col-resize`
|
||||
/// corresponds to the CSS curosr value `col-resize`
|
||||
ResizeColumn,
|
||||
|
||||
/// A cursor indicating that the item/row can be resized vertically.
|
||||
/// corresponds to the CSS cursor value `row-resize`
|
||||
/// corresponds to the CSS curosr value `row-resize`
|
||||
ResizeRow,
|
||||
|
||||
/// A text input cursor for vertical layout
|
||||
|
||||
@@ -37,6 +37,7 @@ globset.workspace = true
|
||||
gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
itertools.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
lsp.workspace = true
|
||||
parking_lot.workspace = true
|
||||
|
||||
@@ -24,6 +24,7 @@ use gpui::{
|
||||
AnyElement, AppContext, EventEmitter, HighlightStyle, ModelContext, Task, TaskLabel,
|
||||
WindowContext,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use lsp::LanguageServerId;
|
||||
use parking_lot::Mutex;
|
||||
use serde_json::Value;
|
||||
@@ -43,7 +44,7 @@ use std::{
|
||||
ops::{Deref, Range},
|
||||
path::{Path, PathBuf},
|
||||
str,
|
||||
sync::{Arc, LazyLock},
|
||||
sync::Arc,
|
||||
time::{Duration, Instant, SystemTime},
|
||||
vec,
|
||||
};
|
||||
@@ -66,9 +67,11 @@ pub use {tree_sitter_rust, tree_sitter_typescript};
|
||||
|
||||
pub use lsp::DiagnosticSeverity;
|
||||
|
||||
/// A label for the background task spawned by the buffer to compute
|
||||
/// a diff against the contents of its file.
|
||||
pub static BUFFER_DIFF_TASK: LazyLock<TaskLabel> = LazyLock::new(|| TaskLabel::new());
|
||||
lazy_static! {
|
||||
/// A label for the background task spawned by the buffer to compute
|
||||
/// a diff against the contents of its file.
|
||||
pub static ref BUFFER_DIFF_TASK: TaskLabel = TaskLabel::new();
|
||||
}
|
||||
|
||||
/// Indicate whether a [Buffer] has permissions to edit.
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
|
||||
@@ -16,7 +16,6 @@ use settings::SettingsStore;
|
||||
use std::{
|
||||
env,
|
||||
ops::Range,
|
||||
sync::LazyLock,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use text::network::Network;
|
||||
@@ -25,12 +24,12 @@ use text::{Point, ToPoint};
|
||||
use unindent::Unindent as _;
|
||||
use util::{assert_set_eq, post_inc, test::marked_text_ranges, RandomCharIter};
|
||||
|
||||
pub static TRAILING_WHITESPACE_REGEX: LazyLock<regex::Regex> = LazyLock::new(|| {
|
||||
RegexBuilder::new(r"[ \t]+$")
|
||||
lazy_static! {
|
||||
static ref TRAILING_WHITESPACE_REGEX: Regex = RegexBuilder::new("[ \t]+$")
|
||||
.multi_line(true)
|
||||
.build()
|
||||
.expect("Failed to create TRAILING_WHITESPACE_REGEX")
|
||||
});
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[ctor::ctor]
|
||||
|
||||
@@ -28,6 +28,7 @@ use futures::Future;
|
||||
use gpui::{AppContext, AsyncAppContext, Model, SharedString, Task};
|
||||
pub use highlight_map::HighlightMap;
|
||||
use http_client::HttpClient;
|
||||
use lazy_static::lazy_static;
|
||||
use lsp::{CodeActionKind, LanguageServerBinary};
|
||||
use parking_lot::Mutex;
|
||||
use regex::Regex;
|
||||
@@ -52,7 +53,7 @@ use std::{
|
||||
str,
|
||||
sync::{
|
||||
atomic::{AtomicU64, AtomicUsize, Ordering::SeqCst},
|
||||
Arc, LazyLock,
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
use syntax_map::{QueryCursorHandle, SyntaxSnapshot};
|
||||
@@ -110,23 +111,23 @@ where
|
||||
func(cursor.deref_mut())
|
||||
}
|
||||
|
||||
static NEXT_LANGUAGE_ID: LazyLock<AtomicUsize> = LazyLock::new(Default::default);
|
||||
static NEXT_GRAMMAR_ID: LazyLock<AtomicUsize> = LazyLock::new(Default::default);
|
||||
static WASM_ENGINE: LazyLock<wasmtime::Engine> = LazyLock::new(|| {
|
||||
wasmtime::Engine::new(&wasmtime::Config::new()).expect("Failed to create Wasmtime engine")
|
||||
});
|
||||
lazy_static! {
|
||||
static ref NEXT_LANGUAGE_ID: AtomicUsize = Default::default();
|
||||
static ref NEXT_GRAMMAR_ID: AtomicUsize = Default::default();
|
||||
static ref WASM_ENGINE: wasmtime::Engine = {
|
||||
wasmtime::Engine::new(&wasmtime::Config::new()).unwrap()
|
||||
};
|
||||
|
||||
/// A shared grammar for plain text, exposed for reuse by downstream crates.
|
||||
pub static PLAIN_TEXT: LazyLock<Arc<Language>> = LazyLock::new(|| {
|
||||
Arc::new(Language::new(
|
||||
/// A shared grammar for plain text, exposed for reuse by downstream crates.
|
||||
pub static ref PLAIN_TEXT: Arc<Language> = Arc::new(Language::new(
|
||||
LanguageConfig {
|
||||
name: "Plain Text".into(),
|
||||
soft_wrap: Some(SoftWrap::EditorWidth),
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
))
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
/// Types that represent a position in a buffer, and can be converted into
|
||||
/// an LSP position, to send to a language server.
|
||||
|
||||
@@ -22,6 +22,7 @@ futures.workspace = true
|
||||
gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
language.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
lsp.workspace = true
|
||||
node_runtime.workspace = true
|
||||
|
||||
@@ -4,6 +4,7 @@ use futures::StreamExt;
|
||||
use gpui::{AppContext, AsyncAppContext, Task};
|
||||
use http_client::github::latest_github_release;
|
||||
pub use language::*;
|
||||
use lazy_static::lazy_static;
|
||||
use lsp::LanguageServerBinary;
|
||||
use project::project_settings::{BinarySettings, ProjectSettings};
|
||||
use regex::Regex;
|
||||
@@ -19,7 +20,7 @@ use std::{
|
||||
str,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering::SeqCst},
|
||||
Arc, LazyLock,
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
use task::{TaskTemplate, TaskTemplates, TaskVariables, VariableName};
|
||||
@@ -36,12 +37,12 @@ impl GoLspAdapter {
|
||||
const SERVER_NAME: &'static str = "gopls";
|
||||
}
|
||||
|
||||
static GOPLS_VERSION_REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"\d+\.\d+\.\d+").expect("Failed to create GOPLS_VERSION_REGEX"));
|
||||
|
||||
static GO_ESCAPE_SUBTEST_NAME_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
Regex::new(r#"[.*+?^${}()|\[\]\\]"#).expect("Failed to create GO_ESCAPE_SUBTEST_NAME_REGEX")
|
||||
});
|
||||
lazy_static! {
|
||||
static ref GOPLS_VERSION_REGEX: Regex = Regex::new(r"\d+\.\d+\.\d+").unwrap();
|
||||
static ref GO_EXTRACT_SUBTEST_NAME_REGEX: Regex =
|
||||
Regex::new(r#".*t\.Run\("([^"]*)".*"#).unwrap();
|
||||
static ref GO_ESCAPE_SUBTEST_NAME_REGEX: Regex = Regex::new(r#"[.*+?^${}()|\[\]\\]"#).unwrap();
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl super::LspAdapter for GoLspAdapter {
|
||||
|
||||
@@ -6,6 +6,7 @@ use gpui::{AppContext, AsyncAppContext};
|
||||
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||
pub use language::*;
|
||||
use language_settings::all_language_settings;
|
||||
use lazy_static::lazy_static;
|
||||
use lsp::LanguageServerBinary;
|
||||
use project::project_settings::{BinarySettings, ProjectSettings};
|
||||
use regex::Regex;
|
||||
@@ -17,7 +18,6 @@ use std::{
|
||||
env::consts,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
sync::LazyLock,
|
||||
};
|
||||
use task::{TaskTemplate, TaskTemplates, TaskVariables, VariableName};
|
||||
use util::{fs::remove_matching, maybe, ResultExt};
|
||||
@@ -178,8 +178,9 @@ impl LspAdapter for RustLspAdapter {
|
||||
}
|
||||
|
||||
fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) {
|
||||
static REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"(?m)`([^`]+)\n`$").expect("Failed to create REGEX"));
|
||||
lazy_static! {
|
||||
static ref REGEX: Regex = Regex::new("(?m)`([^`]+)\n`$").unwrap();
|
||||
}
|
||||
|
||||
for diagnostic in &mut params.diagnostics {
|
||||
for message in diagnostic
|
||||
@@ -242,8 +243,9 @@ impl LspAdapter for RustLspAdapter {
|
||||
Some(lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD)
|
||||
if detail.is_some() =>
|
||||
{
|
||||
static REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new("\\(…?\\)").unwrap());
|
||||
|
||||
lazy_static! {
|
||||
static ref REGEX: Regex = Regex::new("\\(…?\\)").unwrap();
|
||||
}
|
||||
let detail = detail.unwrap();
|
||||
const FUNCTION_PREFIXES: [&'static str; 6] = [
|
||||
"async fn",
|
||||
|
||||
@@ -77,7 +77,7 @@ impl gpui::Element for ProjectPanelScrollbar {
|
||||
) {
|
||||
cx.with_content_mask(Some(ContentMask { bounds }), |cx| {
|
||||
let colors = cx.theme().colors();
|
||||
let scrollbar_background = colors.scrollbar_track_background;
|
||||
let scrollbar_background = colors.scrollbar_track_border;
|
||||
let thumb_background = colors.scrollbar_thumb_background;
|
||||
cx.paint_quad(gpui::fill(bounds, scrollbar_background));
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ collections.workspace = true
|
||||
fs.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
paths.workspace = true
|
||||
release_channel.workspace = true
|
||||
|
||||
@@ -3,6 +3,7 @@ use collections::{btree_map, hash_map, BTreeMap, HashMap};
|
||||
use fs::Fs;
|
||||
use futures::{channel::mpsc, future::LocalBoxFuture, FutureExt, StreamExt};
|
||||
use gpui::{AppContext, AsyncAppContext, BorrowAppContext, Global, Task, UpdateGlobal};
|
||||
use lazy_static::lazy_static;
|
||||
use schemars::{gen::SchemaGenerator, schema::RootSchema, JsonSchema};
|
||||
use serde::{de::DeserializeOwned, Deserialize as _, Serialize};
|
||||
use smallvec::SmallVec;
|
||||
@@ -12,10 +13,8 @@ use std::{
|
||||
ops::Range,
|
||||
path::Path,
|
||||
str,
|
||||
sync::{Arc, LazyLock},
|
||||
sync::Arc,
|
||||
};
|
||||
use tree_sitter::Query;
|
||||
use tree_sitter_json::language;
|
||||
use util::{merge_non_null_json_value_into, RangeExt, ResultExt as _};
|
||||
|
||||
use crate::SettingsJsonSchemaParams;
|
||||
@@ -945,10 +944,13 @@ fn replace_value_in_json_text(
|
||||
tab_size: usize,
|
||||
new_value: &serde_json::Value,
|
||||
) -> (Range<usize>, String) {
|
||||
static PAIR_QUERY: LazyLock<Query> = LazyLock::new(|| {
|
||||
Query::new(&language(), "(pair key: (string) @key value: (_) @value)")
|
||||
.expect("Failed to create PAIR_QUERY")
|
||||
});
|
||||
lazy_static! {
|
||||
static ref PAIR_QUERY: tree_sitter::Query = tree_sitter::Query::new(
|
||||
&tree_sitter_json::language(),
|
||||
"(pair key: (string) @key value: (_) @value)",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let mut parser = tree_sitter::Parser::new();
|
||||
parser.set_language(&tree_sitter_json::language()).unwrap();
|
||||
|
||||
@@ -13,6 +13,7 @@ anyhow.workspace = true
|
||||
collections.workspace = true
|
||||
futures.workspace = true
|
||||
indoc.workspace = true
|
||||
lazy_static.workspace = true
|
||||
libsqlite3-sys = { version = "0.26", features = ["bundled"] }
|
||||
parking_lot.workspace = true
|
||||
smol.workspace = true
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
use anyhow::Context;
|
||||
use collections::HashMap;
|
||||
use futures::{channel::oneshot, Future, FutureExt};
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
ops::Deref,
|
||||
sync::{Arc, LazyLock},
|
||||
thread,
|
||||
};
|
||||
use std::{marker::PhantomData, ops::Deref, sync::Arc, thread};
|
||||
use thread_local::ThreadLocal;
|
||||
|
||||
use crate::{connection::Connection, domain::Migrator, util::UnboundedSyncSender};
|
||||
@@ -17,13 +13,14 @@ const MIGRATION_RETRIES: usize = 10;
|
||||
type QueuedWrite = Box<dyn 'static + Send + FnOnce()>;
|
||||
type WriteQueue = Box<dyn 'static + Send + Sync + Fn(QueuedWrite)>;
|
||||
type WriteQueueConstructor = Box<dyn 'static + Send + FnMut() -> WriteQueue>;
|
||||
|
||||
/// List of queues of tasks by database uri. This lets us serialize writes to the database
|
||||
/// and have a single worker thread per db file. This means many thread safe connections
|
||||
/// (possibly with different migrations) could all be communicating with the same background
|
||||
/// thread.
|
||||
static QUEUES: LazyLock<RwLock<HashMap<Arc<str>, WriteQueue>>> =
|
||||
LazyLock::new(|| Default::default());
|
||||
lazy_static! {
|
||||
/// List of queues of tasks by database uri. This lets us serialize writes to the database
|
||||
/// and have a single worker thread per db file. This means many thread safe connections
|
||||
/// (possibly with different migrations) could all be communicating with the same background
|
||||
/// thread.
|
||||
static ref QUEUES: RwLock<HashMap<Arc<str>, WriteQueue>> =
|
||||
Default::default();
|
||||
}
|
||||
|
||||
/// Thread safe connection to a given database file or in memory db. This can be cloned, shared, static,
|
||||
/// whatever. It derefs to a synchronous connection by thread that is read only. A write capable connection
|
||||
@@ -279,7 +276,7 @@ pub fn locking_queue() -> WriteQueueConstructor {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use indoc::indoc;
|
||||
use std::ops::Deref;
|
||||
use lazy_static::__Deref;
|
||||
|
||||
use std::thread;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ proc-macro = true
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
lazy_static.workspace = true
|
||||
sqlez.workspace = true
|
||||
sqlformat = "0.2"
|
||||
syn = "1.0"
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
use proc_macro::{Delimiter, Span, TokenStream, TokenTree};
|
||||
use sqlez::thread_safe_connection::{locking_queue, ThreadSafeConnection};
|
||||
use syn::Error;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
static SQLITE: std::sync::LazyLock<sqlez::thread_safe_connection::ThreadSafeConnection> =
|
||||
std::sync::LazyLock::new(|| {
|
||||
sqlez::thread_safe_connection::ThreadSafeConnection::new(
|
||||
":memory:",
|
||||
false,
|
||||
None,
|
||||
Some(sqlez::thread_safe_connection::locking_queue()),
|
||||
)
|
||||
});
|
||||
lazy_static::lazy_static! {
|
||||
static ref SQLITE: ThreadSafeConnection = {
|
||||
ThreadSafeConnection::new(":memory:", false, None, Some(locking_queue()))
|
||||
};
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn sql(tokens: TokenStream) -> TokenStream {
|
||||
|
||||
@@ -19,6 +19,7 @@ test-support = ["rand"]
|
||||
anyhow.workspace = true
|
||||
clock.workspace = true
|
||||
collections.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
postage.workspace = true
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use lazy_static::lazy_static;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::iter;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static MIN: LazyLock<Locator> = LazyLock::new(|| Locator::min());
|
||||
static MAX: LazyLock<Locator> = LazyLock::new(|| Locator::max());
|
||||
lazy_static! {
|
||||
static ref MIN: Locator = Locator::min();
|
||||
static ref MAX: Locator = Locator::max();
|
||||
}
|
||||
|
||||
/// An identifier for a position in a ordered collection.
|
||||
///
|
||||
|
||||
@@ -19,6 +19,7 @@ use operation_queue::OperationQueue;
|
||||
pub use patch::Patch;
|
||||
use postage::{oneshot, prelude::*};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
pub use rope::*;
|
||||
pub use selection::*;
|
||||
@@ -31,7 +32,7 @@ use std::{
|
||||
num::NonZeroU64,
|
||||
ops::{self, Deref, Range, Sub},
|
||||
str,
|
||||
sync::{Arc, LazyLock},
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
pub use subscription::*;
|
||||
@@ -43,9 +44,9 @@ use util::ResultExt;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
use util::RandomCharIter;
|
||||
|
||||
static LINE_SEPARATORS_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
Regex::new(r"\r\n|\r|\u{2028}|\u{2029}").expect("Failed to create LINE_SEPARATORS_REGEX")
|
||||
});
|
||||
lazy_static! {
|
||||
static ref LINE_SEPARATORS_REGEX: Regex = Regex::new("\r\n|\r|\u{2028}|\u{2029}").unwrap();
|
||||
}
|
||||
|
||||
pub type TransactionId = clock::Lamport;
|
||||
|
||||
|
||||
@@ -91,7 +91,6 @@ pub struct ThemeSettings {
|
||||
pub active_theme: Arc<Theme>,
|
||||
pub theme_overrides: Option<ThemeStyleContent>,
|
||||
pub ui_density: UiDensity,
|
||||
pub unnecessary_code_fade: f32,
|
||||
}
|
||||
|
||||
impl ThemeSettings {
|
||||
@@ -284,10 +283,6 @@ pub struct ThemeSettingsContent {
|
||||
#[serde(rename = "unstable.ui_density", default)]
|
||||
pub ui_density: Option<UiDensity>,
|
||||
|
||||
/// How much to fade out unused code.
|
||||
#[serde(default)]
|
||||
pub unnecessary_code_fade: Option<f32>,
|
||||
|
||||
/// EXPERIMENTAL: Overrides for the current theme.
|
||||
///
|
||||
/// These values will override the ones on the current theme specified in `theme`.
|
||||
@@ -555,7 +550,6 @@ impl settings::Settings for ThemeSettings {
|
||||
.unwrap(),
|
||||
theme_overrides: None,
|
||||
ui_density: defaults.ui_density.unwrap_or(UiDensity::Default),
|
||||
unnecessary_code_fade: defaults.unnecessary_code_fade.unwrap_or(0.0),
|
||||
};
|
||||
|
||||
for value in sources.user.into_iter().chain(sources.release_channel) {
|
||||
@@ -608,10 +602,6 @@ impl settings::Settings for ThemeSettings {
|
||||
value.buffer_font_size.map(Into::into),
|
||||
);
|
||||
merge(&mut this.buffer_line_height, value.buffer_line_height);
|
||||
|
||||
// Clamp the `unnecessary_code_fade` to ensure text can't disappear entirely.
|
||||
merge(&mut this.unnecessary_code_fade, value.unnecessary_code_fade);
|
||||
this.unnecessary_code_fade = this.unnecessary_code_fade.clamp(0.0, 0.9);
|
||||
}
|
||||
|
||||
Ok(this)
|
||||
|
||||
@@ -26,6 +26,7 @@ editor.workspace = true
|
||||
gpui.workspace = true
|
||||
itertools.workspace = true
|
||||
language.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
multi_buffer.workspace = true
|
||||
nvim-rs = { git = "https://github.com/KillTheMule/nvim-rs", branch = "master", features = [
|
||||
|
||||
@@ -2,23 +2,25 @@ use std::sync::Arc;
|
||||
|
||||
use collections::HashMap;
|
||||
use gpui::AppContext;
|
||||
use lazy_static::lazy_static;
|
||||
use settings::Settings;
|
||||
use std::sync::LazyLock;
|
||||
use ui::WindowContext;
|
||||
|
||||
use crate::{Vim, VimSettings};
|
||||
|
||||
mod default;
|
||||
|
||||
static DEFAULT_DIGRAPHS_MAP: LazyLock<HashMap<String, Arc<str>>> = LazyLock::new(|| {
|
||||
let mut map = HashMap::default();
|
||||
for &(a, b, c) in default::DEFAULT_DIGRAPHS {
|
||||
let key = format!("{a}{b}");
|
||||
let value = char::from_u32(c).unwrap().to_string().into();
|
||||
map.insert(key, value);
|
||||
}
|
||||
map
|
||||
});
|
||||
lazy_static! {
|
||||
static ref DEFAULT_DIGRAPHS_MAP: HashMap<String, Arc<str>> = {
|
||||
let mut map = HashMap::default();
|
||||
for &(a, b, c) in default::DEFAULT_DIGRAPHS {
|
||||
let key = format!("{a}{b}");
|
||||
let value = char::from_u32(c).unwrap().to_string().into();
|
||||
map.insert(key, value);
|
||||
}
|
||||
map
|
||||
};
|
||||
}
|
||||
|
||||
fn lookup_digraph(a: char, b: char, cx: &AppContext) -> Arc<str> {
|
||||
let custom_digraphs = &VimSettings::get_global(cx).custom_digraphs;
|
||||
|
||||
@@ -43,6 +43,7 @@ gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
itertools.workspace = true
|
||||
language.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
node_runtime.workspace = true
|
||||
parking_lot.workspace = true
|
||||
|
||||
@@ -44,6 +44,7 @@ pub use item::{
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::{LanguageRegistry, Rope};
|
||||
use lazy_static::lazy_static;
|
||||
pub use modal_layer::*;
|
||||
use node_runtime::NodeRuntime;
|
||||
use notifications::{simple_message_notification::MessageNotification, NotificationHandle};
|
||||
@@ -76,7 +77,7 @@ use std::{
|
||||
hash::{Hash, Hasher},
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
sync::{atomic::AtomicUsize, Arc, LazyLock, Weak},
|
||||
sync::{atomic::AtomicUsize, Arc, Weak},
|
||||
time::Duration,
|
||||
};
|
||||
use task::SpawnInTerminal;
|
||||
@@ -100,19 +101,16 @@ use crate::persistence::{
|
||||
SerializedAxis,
|
||||
};
|
||||
|
||||
static ZED_WINDOW_SIZE: LazyLock<Option<Size<Pixels>>> = LazyLock::new(|| {
|
||||
env::var("ZED_WINDOW_SIZE")
|
||||
lazy_static! {
|
||||
static ref ZED_WINDOW_SIZE: Option<Size<Pixels>> = env::var("ZED_WINDOW_SIZE")
|
||||
.ok()
|
||||
.as_deref()
|
||||
.and_then(parse_pixel_size_env_var)
|
||||
});
|
||||
|
||||
static ZED_WINDOW_POSITION: LazyLock<Option<Point<Pixels>>> = LazyLock::new(|| {
|
||||
env::var("ZED_WINDOW_POSITION")
|
||||
.and_then(parse_pixel_size_env_var);
|
||||
static ref ZED_WINDOW_POSITION: Option<Point<Pixels>> = env::var("ZED_WINDOW_POSITION")
|
||||
.ok()
|
||||
.as_deref()
|
||||
.and_then(parse_pixel_position_env_var)
|
||||
});
|
||||
.and_then(parse_pixel_position_env_var);
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
||||
|
||||
@@ -8,7 +8,7 @@ mod zed;
|
||||
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use assistant::PromptBuilder;
|
||||
use clap::{command, Parser, ValueEnum};
|
||||
use clap::{command, Parser};
|
||||
use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
|
||||
use client::{parse_zed_link, Client, DevServerToken, UserStore};
|
||||
use collab_ui::channel_view::ChannelView;
|
||||
@@ -19,7 +19,7 @@ use fs::{Fs, RealFs};
|
||||
use futures::{future, StreamExt};
|
||||
use git::GitHostingProviderRegistry;
|
||||
use gpui::{
|
||||
Action, App, AppContext, AsyncAppContext, Context, DismissEvent, Global, ReadGlobal as _, Task,
|
||||
Action, App, AppContext, AsyncAppContext, Context, DismissEvent, Global, Task,
|
||||
UpdateGlobal as _, VisualContext,
|
||||
};
|
||||
use image_viewer;
|
||||
@@ -536,45 +536,19 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
let state = app_state.clone();
|
||||
let app_state = app_state.clone();
|
||||
let prompt_builder = prompt_builder.clone();
|
||||
cx.spawn(move |cx| async move {
|
||||
while let Some(urls) = open_rx.next().await {
|
||||
cx.update(|cx| {
|
||||
if let Some(request) = OpenRequest::parse(urls, cx).log_err() {
|
||||
handle_open_request(request, state.clone(), prompt_builder.clone(), cx);
|
||||
handle_open_request(request, app_state.clone(), prompt_builder.clone(), cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
if let Some(schema) = args.schema {
|
||||
let app_state = app_state.clone();
|
||||
cx.spawn(|cx| async move {
|
||||
match schema {
|
||||
SchemaKind::Settings => {
|
||||
let language_names = app_state.languages.language_names();
|
||||
let schema = cx.update(|cx| {
|
||||
SettingsStore::global(cx).json_schema(
|
||||
&settings::SettingsJsonSchemaParams {
|
||||
staff_mode: false,
|
||||
language_names: &language_names,
|
||||
font_names: &[],
|
||||
},
|
||||
cx,
|
||||
)
|
||||
});
|
||||
if let Ok(schema) = schema {
|
||||
if let Ok(schema) = serde_json::to_string(&schema) {
|
||||
let _ = std::fs::write("settings-schema.json", &(schema));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1065,11 +1039,6 @@ fn stdout_is_a_pty() -> bool {
|
||||
std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_none() && std::io::stdout().is_terminal()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, ValueEnum)]
|
||||
enum SchemaKind {
|
||||
Settings,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "zed", disable_version_flag = true)]
|
||||
struct Args {
|
||||
@@ -1084,10 +1053,6 @@ struct Args {
|
||||
/// Instructs zed to run as a dev server on this machine. (not implemented)
|
||||
#[arg(long)]
|
||||
dev_server_token: Option<String>,
|
||||
|
||||
/// Instructs zed to dump a JSON schema to a file.
|
||||
#[arg(long)]
|
||||
schema: Option<SchemaKind>,
|
||||
}
|
||||
|
||||
fn parse_url_arg(arg: &str, cx: &AppContext) -> Result<String> {
|
||||
|
||||
@@ -9,8 +9,8 @@ site-url = "/docs/"
|
||||
[output.html]
|
||||
no-section-label = true
|
||||
preferred-dark-theme = "light"
|
||||
additional-css = ["theme/page-toc.css", "theme/settings-table.css", "theme/plugins.css"]
|
||||
additional-js = ["theme/page-toc.js", "theme/settings-table.js", "theme/plugins.js"]
|
||||
additional-css = ["theme/page-toc.css", "theme/plugins.css"]
|
||||
additional-js = ["theme/page-toc.js", "theme/plugins.js"]
|
||||
|
||||
[output.html.print]
|
||||
enable = false
|
||||
|
||||
@@ -4,9 +4,9 @@ The assistant panel provides you with a way to interact with large language mode
|
||||
|
||||
To open the assistant panel, toggle the right dock by using the `workspace: toggle right dock` action in the command palette or by using the <kbd>cmd-r|ctrl-alt-b</kbd> shortcut.
|
||||
|
||||
> **Note**: A custom [key binding](../key-bindings.md) can be set to toggle the right dock.
|
||||
> **Note**: A custom [key binding](./key-bindings.md) can be set to toggle the right dock.
|
||||
|
||||
Once you have [configured a provider](./configuration.md#providers), you can interact with the provider's language models in a context editor.
|
||||
Once you have [configured a provider](/assistant/configuration.md#providers), you can interact with the provider's language models in a context editor.
|
||||
|
||||

|
||||
|
||||
@@ -48,7 +48,7 @@ Simple back-and-forth conversations work well with the assistant. However, there
|
||||
|
||||
### Editing a Context
|
||||
|
||||
> **Note**: Wondering about Context vs Conversation? [Read more here](./contexts.md).
|
||||
> **Note**: Wondering about Context vs Conversation? [Read more here](/assistant/contexts.md).
|
||||
|
||||
The assistant gives you the flexibility to have control over the context. You can freely edit any previous text, including the responses from the assistant. If you want to remove a message block entirely, simply place your cursor at the beginning of the block and use the `delete` key. A typical workflow might involve making edits and adjustments throughout the context to refine your inquiry or provide additional information. Here's an example:
|
||||
|
||||
|
||||
@@ -5,17 +5,16 @@ A Context Server is an experimental interface for defining simple, language-agno
|
||||
If slash commands allow you to extend the Assistant with new capabilities, Context Servers follow a simple protocol for registering and making use of those capabilities.
|
||||
|
||||
## Using a Context Server
|
||||
|
||||
To configure Zed to use a Context Server, add the command required to start the server to your [settings](../configuring-zed.md):
|
||||
To configure Zed to use a Context Server, add the command required to start the server to your [settings](./configuring-zed.md):
|
||||
|
||||
```json
|
||||
{
|
||||
"experimental.context_servers": {
|
||||
"servers": [
|
||||
"experimental": {
|
||||
"context_servers": [
|
||||
{
|
||||
"id": "python_context_server",
|
||||
"executable": "python",
|
||||
"args": ["-m", "your_context_server_module"]
|
||||
"args": ["-m", "my_context_server"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -24,7 +23,11 @@ To configure Zed to use a Context Server, add the command required to start the
|
||||
|
||||
## Developing a Context Server
|
||||
|
||||
Context Servers are JSON-RPC servers communicating over stdio. Context Servers must comply with the [Model Context Protocol (MCP)](./model-context-protocol.md).
|
||||
A Context Server is a server listening for JSON-RPC requests over stdin/stdout. The server must follow the Model Context Protocol (defined below) in order to declare its capabilities such that Zed can make use of them.
|
||||
|
||||
### Implementing a Context Server
|
||||
|
||||
Context Servers are JSON-RPC servers communicating over stdio. Context Servers must comply with the [Model Context Protocol (MCP)](./model_context_protocol).
|
||||
|
||||
See [python-context-server](https://github.com/zed-industries/python-context-server) for a minimal working example.
|
||||
|
||||
@@ -37,7 +40,6 @@ Currently, Zed's client only implements a subset of the protocol required to sup
|
||||
If your slash commands are already implemented in a language other than Rust, wrapping them in a Context Server implementation will likely be the fastest way to plug them into Zed.
|
||||
|
||||
An Extension should be preferred when:
|
||||
|
||||
- Your slash commands are implemented in WebAssembly-compatible Rust
|
||||
- You want Zed to manage distribution of your slash commands
|
||||
- You want to publish your slash commands
|
||||
|
||||
@@ -87,7 +87,6 @@ Currently, Zed's client only implements a subset of the protocol required to sup
|
||||
#### List Prompts
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -98,7 +97,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -123,7 +121,6 @@ Response:
|
||||
#### Execute Prompt
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -139,7 +136,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -155,7 +151,6 @@ Response:
|
||||
#### List Resources
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -166,7 +161,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -192,7 +186,6 @@ Response:
|
||||
#### Read Resource
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -205,7 +198,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -226,7 +218,6 @@ Response:
|
||||
#### Subscribe to Resource
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -239,7 +230,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -251,7 +241,6 @@ Response:
|
||||
#### Unsubscribe from Resource
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -264,7 +253,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -278,7 +266,6 @@ Response:
|
||||
#### Call Tool
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -294,7 +281,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -310,7 +296,6 @@ Response:
|
||||
#### Set Logging Level
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -323,7 +308,6 @@ Request:
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
|
||||
@@ -29,8 +29,6 @@ Extensions that provide language servers may also provide default settings for t
|
||||
|
||||
# Settings
|
||||
|
||||
<div id="settings-container"></div>
|
||||
|
||||
## Active Pane Magnification
|
||||
|
||||
- Description: Scale by which to zoom the active pane. When set to `1.0`, the active pane has the same size as others, but when set to a larger value, the active pane takes up more space.
|
||||
@@ -1904,27 +1902,6 @@ Run the `theme selector: toggle` action in the command palette to see a current
|
||||
},
|
||||
```
|
||||
|
||||
## Unnecessary Code Fade
|
||||
|
||||
- Description: How much to fade out unused code.
|
||||
- Setting: `unnecessary_code_fade`
|
||||
- Default: `0.3`
|
||||
|
||||
**Options**
|
||||
|
||||
Float values between `0.0` and `0.9`, where:
|
||||
|
||||
- `0.0` means no fading (unused code looks the same as used code)
|
||||
- `0.9` means maximum fading (unused code is very faint but still visible)
|
||||
|
||||
**Example**
|
||||
|
||||
```json
|
||||
{
|
||||
"unnecessary_code_fade": 0.5
|
||||
}
|
||||
```
|
||||
|
||||
## An example configuration:
|
||||
|
||||
```json
|
||||
|
||||
4
docs/theme/css/variables.css
vendored
4
docs/theme/css/variables.css
vendored
@@ -44,8 +44,8 @@
|
||||
--warning-bg: hsl(42, 100%, 60%, 0.1);
|
||||
--warning-icon: hsl(42, 100%, 30%);
|
||||
|
||||
--table-border-color: hsl(219, 10%, 42%, 0.15);
|
||||
--table-header-bg: hsl(219, 18%, 68%, 0.15);
|
||||
--table-border-color: hsl(219, 93%, 42%, 0.15);
|
||||
--table-header-bg: hsl(0, 0%, 80%);
|
||||
--table-alternate-bg: hsl(0, 0%, 97%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
|
||||
4
docs/theme/index.hbs
vendored
4
docs/theme/index.hbs
vendored
@@ -23,6 +23,7 @@
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}plugins.css">
|
||||
{{#if print_enable}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
|
||||
{{/if}}
|
||||
@@ -251,9 +252,10 @@
|
||||
<script src="{{ path_to_root }}highlight.js"></script>
|
||||
<script src="{{ path_to_root }}book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
<!-- Custom JS scripts -->
|
||||
{{#each additional_js}}
|
||||
<script src="{{ ../path_to_root }}{{this}}"></script>
|
||||
<script src="{{ path_to_root }}plugins.js"></script>
|
||||
{{/each}}
|
||||
|
||||
{{#if is_print}}
|
||||
|
||||
95
docs/theme/settings-table.css
vendored
95
docs/theme/settings-table.css
vendored
@@ -1,95 +0,0 @@
|
||||
.settings-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family: var(--font);
|
||||
color: var(--fg);
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
.setting-container {
|
||||
padding: 12px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid var(--table-border-color);
|
||||
}
|
||||
|
||||
.setting-header {
|
||||
grid-column: span 2 / span 2;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.8rem;
|
||||
padding: 0.5em 1em 0.5rem 0;
|
||||
}
|
||||
|
||||
.setting-line {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
/* padding: 0.5em 1em; */
|
||||
}
|
||||
|
||||
.setting-name {
|
||||
font-family: monospace;
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
|
||||
.setting-type {
|
||||
font-family: monospace;
|
||||
font-size: 1.3rem;
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.setting-description {
|
||||
font-size: 1.3rem;
|
||||
color: var(--fg);
|
||||
padding: 0.5em 0 0.5em 0;
|
||||
}
|
||||
|
||||
.setting-default {
|
||||
font-family: monospace;
|
||||
font-size: 1.3rem;
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.setting-status {
|
||||
width: fit-content;
|
||||
padding: 0.2em 0.5em;
|
||||
background-color: var(--sidebar-active-bg);
|
||||
font-size: 1.2rem;
|
||||
font-family: monospace;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.setting-details {
|
||||
grid-column: span 4 / span 4;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.setting-details tr:nth-child(even) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.setting-details td {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
}
|
||||
|
||||
.setting-label {
|
||||
font-size: 1.2rem;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.setting-value {
|
||||
font-size: 1.4rem;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.settings-list code {
|
||||
font-family: var(--mono-font);
|
||||
font-size: 1.4rem;
|
||||
background-color: var(--quote-bg);
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
color: var(--inline-code-color);
|
||||
}
|
||||
1448
docs/theme/settings-table.js
vendored
1448
docs/theme/settings-table.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -13,5 +13,3 @@ anyhow.workspace = true
|
||||
cargo_metadata.workspace = true
|
||||
cargo_toml.workspace = true
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
schemars.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
@@ -18,8 +18,6 @@ enum CliCommand {
|
||||
Licenses(tasks::licenses::LicensesArgs),
|
||||
/// Checks that packages conform to a set of standards.
|
||||
PackageConformity(tasks::package_conformity::PackageConformityArgs),
|
||||
/// Checks that settings schema conforms to a set of standards.
|
||||
ValidateSchema(tasks::validate_schema::SchemaValidationArgs),
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
@@ -31,6 +29,5 @@ fn main() -> Result<()> {
|
||||
CliCommand::PackageConformity(args) => {
|
||||
tasks::package_conformity::run_package_conformity(args)
|
||||
}
|
||||
CliCommand::ValidateSchema(args) => tasks::validate_schema::run_validate_schema(args),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
pub mod clippy;
|
||||
pub mod licenses;
|
||||
pub mod package_conformity;
|
||||
pub mod validate_schema;
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use schemars::{
|
||||
schema::{RootSchema, SchemaObject},
|
||||
visit::Visitor,
|
||||
};
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct SchemaValidationArgs {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Violation {
|
||||
MissingDefault,
|
||||
MissingExample,
|
||||
MissingMetadata,
|
||||
MissingDescription,
|
||||
}
|
||||
struct Violations {
|
||||
schema: SchemaObject,
|
||||
violations: Vec<(Vec<String>, Violation)>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct SettingsSchemaValidator {
|
||||
objects: Vec<Violations>,
|
||||
}
|
||||
|
||||
impl SettingsSchemaValidator {
|
||||
fn validate_schema_object(&mut self, builder: &mut ViolationsBuilder, schema: &SchemaObject) {
|
||||
if schema.metadata.is_none() {
|
||||
builder.add(Violation::MissingMetadata);
|
||||
} else if let Some(metadata) = &schema.metadata {
|
||||
if metadata.description.is_none() {
|
||||
builder.add(Violation::MissingDescription);
|
||||
}
|
||||
if metadata.default.is_none() {
|
||||
builder.add(Violation::MissingDefault);
|
||||
}
|
||||
if metadata.examples.is_empty() && !Self::is_boolean_schema(schema) {
|
||||
builder.add(Violation::MissingExample);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(object) = &schema.object {
|
||||
for (property, property_schema) in &object.properties {
|
||||
builder.push(property.clone());
|
||||
self.validate_schema_object(builder, &property_schema.clone().into_object());
|
||||
builder.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_boolean_schema(schema: &SchemaObject) -> bool {
|
||||
schema.instance_type == Some(schemars::schema::InstanceType::Boolean.into())
|
||||
}
|
||||
}
|
||||
|
||||
struct ViolationsBuilder<'a> {
|
||||
violations: &'a mut Violations,
|
||||
current_path: Vec<String>,
|
||||
}
|
||||
|
||||
impl<'a> ViolationsBuilder<'a> {
|
||||
fn new(violations: &'a mut Violations) -> Self {
|
||||
Self {
|
||||
violations,
|
||||
current_path: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&mut self, violation: Violation) {
|
||||
self.violations
|
||||
.violations
|
||||
.push((self.current_path.clone(), violation));
|
||||
}
|
||||
|
||||
fn push(&mut self, segment: String) {
|
||||
self.current_path.push(segment);
|
||||
}
|
||||
|
||||
fn pop(&mut self) {
|
||||
self.current_path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor for SettingsSchemaValidator {
|
||||
fn visit_schema_object(&mut self, schema: &mut SchemaObject) {
|
||||
let mut violations = Violations {
|
||||
schema: schema.clone(),
|
||||
violations: Vec::new(),
|
||||
};
|
||||
let mut builder = ViolationsBuilder::new(&mut violations);
|
||||
|
||||
self.validate_schema_object(&mut builder, schema);
|
||||
|
||||
if !violations.violations.is_empty() {
|
||||
self.objects.push(violations);
|
||||
}
|
||||
|
||||
schemars::visit::visit_schema_object(self, schema)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_validate_schema(args: SchemaValidationArgs) -> Result<()> {
|
||||
let contents = std::fs::read_to_string(args.path)?;
|
||||
let mut schema: RootSchema = serde_json::from_str(&contents)?;
|
||||
let mut validator = SettingsSchemaValidator::default();
|
||||
validator.visit_root_schema(&mut schema);
|
||||
|
||||
let total_violations: usize = validator.objects.iter().map(|v| v.violations.len()).sum();
|
||||
println!("Total violations found: {}", total_violations);
|
||||
|
||||
for violation in validator.objects.iter().flat_map(|v| &v.violations) {
|
||||
let path_str = if violation.0.is_empty() {
|
||||
"<root>".to_string()
|
||||
} else {
|
||||
violation.0.join(".")
|
||||
};
|
||||
println!("{}: {:?}", path_str, violation.1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user