Merge remote-tracking branch 'origin/main' into project-reconnection
This commit is contained in:
commit
386f7ba16d
39 changed files with 750 additions and 786 deletions
43
Cargo.lock
generated
43
Cargo.lock
generated
|
@ -2759,6 +2759,12 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "human_bytes"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39b528196c838e8b3da8b665e08c30958a6f2ede91d79f2ffcd0d4664b9c64eb"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
|
@ -3757,6 +3763,15 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -4426,7 +4441,7 @@ source = "git+https://github.com/zed-industries/wezterm?rev=5cd757e5f2eb039ed0c6
|
|||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"ntapi",
|
||||
"ntapi 0.3.7",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
|
@ -6222,6 +6237,21 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccb297c0afb439440834b4bcf02c5c9da8ec2e808e70f36b0d8e815ff403bd24"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"ntapi 0.4.0",
|
||||
"once_cell",
|
||||
"rayon",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-interface"
|
||||
version = "0.20.0"
|
||||
|
@ -7204,6 +7234,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urlencoding"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
|
||||
|
||||
[[package]]
|
||||
name = "usvg"
|
||||
version = "0.14.1"
|
||||
|
@ -8151,7 +8187,7 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
|||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.68.0"
|
||||
version = "0.69.0"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"anyhow",
|
||||
|
@ -8183,6 +8219,7 @@ dependencies = [
|
|||
"fuzzy",
|
||||
"go_to_line",
|
||||
"gpui",
|
||||
"human_bytes",
|
||||
"ignore",
|
||||
"image",
|
||||
"indexmap",
|
||||
|
@ -8216,6 +8253,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"smol",
|
||||
"sum_tree",
|
||||
"sysinfo",
|
||||
"tempdir",
|
||||
"terminal_view",
|
||||
"text",
|
||||
|
@ -8244,6 +8282,7 @@ dependencies = [
|
|||
"tree-sitter-typescript",
|
||||
"unindent",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"util",
|
||||
"vim",
|
||||
"workspace",
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
"alt-cmd-left": "pane::ActivatePrevItem",
|
||||
"alt-cmd-right": "pane::ActivateNextItem",
|
||||
"cmd-w": "pane::CloseActiveItem",
|
||||
"cmd-shift-w": "workspace::CloseWindow",
|
||||
"alt-cmd-t": "pane::CloseInactiveItems",
|
||||
"cmd-k u": "pane::CloseCleanItems",
|
||||
"cmd-k cmd-w": "pane::CloseAllItems",
|
||||
"cmd-shift-w": "workspace::CloseWindow",
|
||||
"cmd-s": "workspace::Save",
|
||||
"cmd-shift-s": "workspace::SaveAs",
|
||||
"cmd-=": "zed::IncreaseBufferFontSize",
|
||||
|
@ -67,9 +69,11 @@
|
|||
"up": "editor::MoveUp",
|
||||
"pageup": "editor::PageUp",
|
||||
"shift-pageup": "editor::MovePageUp",
|
||||
"home": "editor::MoveToBeginningOfLine",
|
||||
"down": "editor::MoveDown",
|
||||
"pagedown": "editor::PageDown",
|
||||
"shift-pagedown": "editor::MovePageDown",
|
||||
"end": "editor::MoveToEndOfLine",
|
||||
"left": "editor::MoveLeft",
|
||||
"right": "editor::MoveRight",
|
||||
"ctrl-p": "editor::MoveUp",
|
||||
|
@ -110,6 +114,12 @@
|
|||
"stop_at_soft_wraps": true
|
||||
}
|
||||
],
|
||||
"shift-home": [
|
||||
"editor::SelectToBeginningOfLine",
|
||||
{
|
||||
"stop_at_soft_wraps": true
|
||||
}
|
||||
],
|
||||
"ctrl-shift-a": [
|
||||
"editor::SelectToBeginningOfLine",
|
||||
{
|
||||
|
@ -122,6 +132,12 @@
|
|||
"stop_at_soft_wraps": true
|
||||
}
|
||||
],
|
||||
"shift-end": [
|
||||
"editor::SelectToEndOfLine",
|
||||
{
|
||||
"stop_at_soft_wraps": true
|
||||
}
|
||||
],
|
||||
"ctrl-shift-e": [
|
||||
"editor::SelectToEndOfLine",
|
||||
{
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
// rust-analyzer
|
||||
// typescript-language-server
|
||||
// vscode-json-languageserver
|
||||
// "rust_analyzer": {
|
||||
// "rust-analyzer": {
|
||||
// //These initialization options are merged into Zed's defaults
|
||||
// "initialization_options": {
|
||||
// "checkOnSave": {
|
||||
|
|
|
@ -35,7 +35,7 @@ use repository::FakeGitRepositoryState;
|
|||
use std::sync::Weak;
|
||||
|
||||
lazy_static! {
|
||||
static ref CARRIAGE_RETURNS_REGEX: Regex = Regex::new("\r\n|\r").unwrap();
|
||||
static ref LINE_SEPERATORS_REGEX: Regex = Regex::new("\r\n|\r|\u{2028}|\u{2029}").unwrap();
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
@ -80,13 +80,13 @@ impl LineEnding {
|
|||
}
|
||||
|
||||
pub fn normalize(text: &mut String) {
|
||||
if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(text, "\n") {
|
||||
if let Cow::Owned(replaced) = LINE_SEPERATORS_REGEX.replace_all(text, "\n") {
|
||||
*text = replaced;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn normalize_arc(text: Arc<str>) -> Arc<str> {
|
||||
if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(&text, "\n") {
|
||||
if let Cow::Owned(replaced) = LINE_SEPERATORS_REGEX.replace_all(&text, "\n") {
|
||||
replaced.into()
|
||||
} else {
|
||||
text
|
||||
|
|
|
@ -52,7 +52,7 @@ fn compile_metal_shaders() {
|
|||
println!("cargo:rerun-if-changed={}", shader_path);
|
||||
|
||||
let output = Command::new("xcrun")
|
||||
.args(&[
|
||||
.args([
|
||||
"-sdk",
|
||||
"macosx",
|
||||
"metal",
|
||||
|
@ -76,7 +76,7 @@ fn compile_metal_shaders() {
|
|||
}
|
||||
|
||||
let output = Command::new("xcrun")
|
||||
.args(&["-sdk", "macosx", "metallib"])
|
||||
.args(["-sdk", "macosx", "metallib"])
|
||||
.arg(air_output_path)
|
||||
.arg("-o")
|
||||
.arg(metallib_output_path)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,19 +1,44 @@
|
|||
use crate::MutableAppContext;
|
||||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
use std::{hash::Hash, sync::Weak};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use collections::{btree_map, BTreeMap, HashMap};
|
||||
|
||||
use crate::MutableAppContext;
|
||||
|
||||
pub type Mapping<K, F> = Mutex<HashMap<K, BTreeMap<usize, Option<F>>>>;
|
||||
|
||||
pub struct CallbackCollection<K: Hash + Eq, F> {
|
||||
internal: Arc<Mapping<K, F>>,
|
||||
pub struct CallbackCollection<K: Clone + Hash + Eq, F> {
|
||||
internal: Arc<Mutex<Mapping<K, F>>>,
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, F> Clone for CallbackCollection<K, F> {
|
||||
pub struct Subscription<K: Clone + Hash + Eq, F> {
|
||||
key: K,
|
||||
id: usize,
|
||||
mapping: Option<Weak<Mutex<Mapping<K, F>>>>,
|
||||
}
|
||||
|
||||
struct Mapping<K, F> {
|
||||
callbacks: HashMap<K, BTreeMap<usize, F>>,
|
||||
dropped_subscriptions: HashMap<K, HashSet<usize>>,
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, F> Mapping<K, F> {
|
||||
fn clear_dropped_state(&mut self, key: &K, subscription_id: usize) -> bool {
|
||||
if let Some(subscriptions) = self.dropped_subscriptions.get_mut(&key) {
|
||||
subscriptions.remove(&subscription_id)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, F> Default for Mapping<K, F> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
callbacks: Default::default(),
|
||||
dropped_subscriptions: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Clone + Hash + Eq, F> Clone for CallbackCollection<K, F> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
internal: self.internal.clone(),
|
||||
|
@ -21,7 +46,7 @@ impl<K: Hash + Eq, F> Clone for CallbackCollection<K, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq + Copy, F> Default for CallbackCollection<K, F> {
|
||||
impl<K: Clone + Hash + Eq + Copy, F> Default for CallbackCollection<K, F> {
|
||||
fn default() -> Self {
|
||||
CallbackCollection {
|
||||
internal: Arc::new(Mutex::new(Default::default())),
|
||||
|
@ -29,78 +54,114 @@ impl<K: Hash + Eq + Copy, F> Default for CallbackCollection<K, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq + Copy, F> CallbackCollection<K, F> {
|
||||
pub fn downgrade(&self) -> Weak<Mapping<K, F>> {
|
||||
Arc::downgrade(&self.internal)
|
||||
}
|
||||
|
||||
impl<K: Clone + Hash + Eq + Copy, F> CallbackCollection<K, F> {
|
||||
#[cfg(test)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.internal.lock().is_empty()
|
||||
self.internal.lock().callbacks.is_empty()
|
||||
}
|
||||
|
||||
pub fn add_callback(&mut self, id: K, subscription_id: usize, callback: F) {
|
||||
self.internal
|
||||
.lock()
|
||||
.entry(id)
|
||||
.or_default()
|
||||
.insert(subscription_id, Some(callback));
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, id: K) {
|
||||
self.internal.lock().remove(&id);
|
||||
}
|
||||
|
||||
pub fn add_or_remove_callback(&mut self, id: K, subscription_id: usize, callback: F) {
|
||||
match self
|
||||
.internal
|
||||
.lock()
|
||||
.entry(id)
|
||||
.or_default()
|
||||
.entry(subscription_id)
|
||||
{
|
||||
btree_map::Entry::Vacant(entry) => {
|
||||
entry.insert(Some(callback));
|
||||
}
|
||||
|
||||
btree_map::Entry::Occupied(entry) => {
|
||||
// TODO: This seems like it should never be called because no code
|
||||
// should ever attempt to remove an existing callback
|
||||
debug_assert!(entry.get().is_none());
|
||||
entry.remove();
|
||||
}
|
||||
pub fn subscribe(&mut self, key: K, subscription_id: usize) -> Subscription<K, F> {
|
||||
Subscription {
|
||||
key,
|
||||
id: subscription_id,
|
||||
mapping: Some(Arc::downgrade(&self.internal)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emit_and_cleanup<C: FnMut(&mut F, &mut MutableAppContext) -> bool>(
|
||||
pub fn add_callback(&mut self, key: K, subscription_id: usize, callback: F) {
|
||||
let mut this = self.internal.lock();
|
||||
|
||||
// If this callback's subscription was dropped before the callback was
|
||||
// added, then just drop the callback.
|
||||
if this.clear_dropped_state(&key, subscription_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.callbacks
|
||||
.entry(key)
|
||||
.or_default()
|
||||
.insert(subscription_id, callback);
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: K) {
|
||||
// Drop these callbacks after releasing the lock, in case one of them
|
||||
// owns a subscription to this callback collection.
|
||||
let mut this = self.internal.lock();
|
||||
let callbacks = this.callbacks.remove(&key);
|
||||
this.dropped_subscriptions.remove(&key);
|
||||
drop(this);
|
||||
drop(callbacks);
|
||||
}
|
||||
|
||||
pub fn emit<C: FnMut(&mut F, &mut MutableAppContext) -> bool>(
|
||||
&mut self,
|
||||
id: K,
|
||||
key: K,
|
||||
cx: &mut MutableAppContext,
|
||||
mut call_callback: C,
|
||||
) {
|
||||
let callbacks = self.internal.lock().remove(&id);
|
||||
let callbacks = self.internal.lock().callbacks.remove(&key);
|
||||
if let Some(callbacks) = callbacks {
|
||||
for (subscription_id, callback) in callbacks {
|
||||
if let Some(mut callback) = callback {
|
||||
let alive = call_callback(&mut callback, cx);
|
||||
if alive {
|
||||
match self
|
||||
.internal
|
||||
.lock()
|
||||
.entry(id)
|
||||
.or_default()
|
||||
.entry(subscription_id)
|
||||
{
|
||||
btree_map::Entry::Vacant(entry) => {
|
||||
entry.insert(Some(callback));
|
||||
}
|
||||
btree_map::Entry::Occupied(entry) => {
|
||||
entry.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (subscription_id, mut callback) in callbacks {
|
||||
// If this callback's subscription was dropped while invoking an
|
||||
// earlier callback, then just drop the callback.
|
||||
let mut this = self.internal.lock();
|
||||
if this.clear_dropped_state(&key, subscription_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
drop(this);
|
||||
let alive = call_callback(&mut callback, cx);
|
||||
|
||||
// If this callback's subscription was dropped while invoking the callback
|
||||
// itself, or if the callback returns false, then just drop the callback.
|
||||
let mut this = self.internal.lock();
|
||||
if this.clear_dropped_state(&key, subscription_id) || !alive {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.callbacks
|
||||
.entry(key)
|
||||
.or_default()
|
||||
.insert(subscription_id, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Clone + Hash + Eq, F> Subscription<K, F> {
|
||||
pub fn id(&self) -> usize {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn detach(&mut self) {
|
||||
self.mapping.take();
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Clone + Hash + Eq, F> Drop for Subscription<K, F> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(mapping) = self.mapping.as_ref().and_then(|mapping| mapping.upgrade()) {
|
||||
let mut mapping = mapping.lock();
|
||||
|
||||
// If the callback is present in the mapping, then just remove it.
|
||||
if let Some(callbacks) = mapping.callbacks.get_mut(&self.key) {
|
||||
let callback = callbacks.remove(&self.id);
|
||||
if callback.is_some() {
|
||||
drop(mapping);
|
||||
drop(callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If this subscription's callback is not present, then either it has been
|
||||
// temporarily removed during emit, or it has not yet been added. Record
|
||||
// that this subscription has been dropped so that the callback can be
|
||||
// removed later.
|
||||
mapping
|
||||
.dropped_subscriptions
|
||||
.entry(self.key.clone())
|
||||
.or_default()
|
||||
.insert(self.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ pub fn key_to_native(key: &str) -> Cow<str> {
|
|||
"right" => NSRightArrowFunctionKey,
|
||||
"pageup" => NSPageUpFunctionKey,
|
||||
"pagedown" => NSPageDownFunctionKey,
|
||||
"home" => NSHomeFunctionKey,
|
||||
"end" => NSEndFunctionKey,
|
||||
"delete" => NSDeleteFunctionKey,
|
||||
"f1" => NSF1FunctionKey,
|
||||
"f2" => NSF2FunctionKey,
|
||||
|
@ -258,6 +260,8 @@ unsafe fn parse_keystroke(native_event: id) -> Keystroke {
|
|||
Some(NSRightArrowFunctionKey) => "right".to_string(),
|
||||
Some(NSPageUpFunctionKey) => "pageup".to_string(),
|
||||
Some(NSPageDownFunctionKey) => "pagedown".to_string(),
|
||||
Some(NSHomeFunctionKey) => "home".to_string(),
|
||||
Some(NSEndFunctionKey) => "end".to_string(),
|
||||
Some(NSDeleteFunctionKey) => "delete".to_string(),
|
||||
Some(NSF1FunctionKey) => "f1".to_string(),
|
||||
Some(NSF2FunctionKey) => "f2".to_string(),
|
||||
|
|
|
@ -647,7 +647,7 @@ impl platform::Platform for MacPlatform {
|
|||
attrs.set(kSecReturnAttributes as *const _, cf_true);
|
||||
attrs.set(kSecReturnData as *const _, cf_true);
|
||||
|
||||
let mut result = CFTypeRef::from(ptr::null_mut());
|
||||
let mut result = CFTypeRef::from(ptr::null());
|
||||
let status = SecItemCopyMatching(attrs.as_concrete_TypeRef(), &mut result);
|
||||
match status {
|
||||
security::errSecSuccess => {}
|
||||
|
|
|
@ -162,11 +162,9 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
|
|||
if let FnArg::Typed(arg) = arg {
|
||||
if let Type::Path(ty) = &*arg.ty {
|
||||
let last_segment = ty.path.segments.last();
|
||||
match last_segment.map(|s| s.ident.to_string()).as_deref() {
|
||||
Some("StdRng") => {
|
||||
inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
|
||||
}
|
||||
_ => {}
|
||||
|
||||
if let Some("StdRng") = last_segment.map(|s| s.ident.to_string()).as_deref() {
|
||||
inner_fn_args.extend(quote!(rand::SeedableRng::seed_from_u64(seed),));
|
||||
}
|
||||
} else {
|
||||
inner_fn_args.extend(quote!(cx,));
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
|||
process::Command,
|
||||
};
|
||||
|
||||
const SWIFT_PACKAGE_NAME: &'static str = "LiveKitBridge";
|
||||
const SWIFT_PACKAGE_NAME: &str = "LiveKitBridge";
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -61,8 +61,8 @@ fn build_bridge(swift_target: &SwiftTarget) {
|
|||
let swift_package_root = swift_package_root();
|
||||
if !Command::new("swift")
|
||||
.arg("build")
|
||||
.args(&["--configuration", &env::var("PROFILE").unwrap()])
|
||||
.args(&["--triple", &swift_target.target.triple])
|
||||
.args(["--configuration", &env::var("PROFILE").unwrap()])
|
||||
.args(["--triple", &swift_target.target.triple])
|
||||
.current_dir(&swift_package_root)
|
||||
.status()
|
||||
.unwrap()
|
||||
|
@ -116,7 +116,7 @@ fn get_swift_target() -> SwiftTarget {
|
|||
let target = format!("{}-apple-macosx{}", arch, MACOS_TARGET_VERSION);
|
||||
|
||||
let swift_target_info_str = Command::new("swift")
|
||||
.args(&["-target", &target, "-print-target-info"])
|
||||
.args(["-target", &target, "-print-target-info"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
|
@ -143,7 +143,7 @@ fn copy_dir(source: &Path, destination: &Path) {
|
|||
assert!(
|
||||
Command::new("cp")
|
||||
.arg("-R")
|
||||
.args(&[source, destination])
|
||||
.args([source, destination])
|
||||
.status()
|
||||
.unwrap()
|
||||
.success(),
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::{env, path::PathBuf, process::Command};
|
|||
fn main() {
|
||||
let sdk_path = String::from_utf8(
|
||||
Command::new("xcrun")
|
||||
.args(&["--sdk", "macosx", "--show-sdk-path"])
|
||||
.args(["--sdk", "macosx", "--show-sdk-path"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
|
|
|
@ -113,9 +113,9 @@ pub mod core_video {
|
|||
let mut this = ptr::null();
|
||||
let result = CVMetalTextureCacheCreate(
|
||||
kCFAllocatorDefault,
|
||||
ptr::null_mut(),
|
||||
ptr::null(),
|
||||
metal_device,
|
||||
ptr::null_mut(),
|
||||
ptr::null(),
|
||||
&mut this,
|
||||
);
|
||||
if result == kCVReturnSuccess {
|
||||
|
@ -192,7 +192,7 @@ pub mod core_video {
|
|||
pub fn as_texture_ref(&self) -> &metal::TextureRef {
|
||||
unsafe {
|
||||
let texture = CVMetalTextureGetTexture(self.as_concrete_TypeRef());
|
||||
&metal::TextureRef::from_ptr(texture as *mut _)
|
||||
metal::TextureRef::from_ptr(texture as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ impl PickerDelegate for RecentProjectsView {
|
|||
.matches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.max_by_key(|(_, m)| OrderedFloat(m.score))
|
||||
.map(|(ix, _)| ix)
|
||||
.unwrap_or(0);
|
||||
|
|
|
@ -23,7 +23,7 @@ pub fn random_token() -> String {
|
|||
for byte in token_bytes.iter_mut() {
|
||||
*byte = rng.gen();
|
||||
}
|
||||
base64::encode_config(&token_bytes, base64::URL_SAFE)
|
||||
base64::encode_config(token_bytes, base64::URL_SAFE)
|
||||
}
|
||||
|
||||
impl PublicKey {
|
||||
|
|
|
@ -106,73 +106,79 @@ impl View for BufferSearchBar {
|
|||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(
|
||||
ChildView::new(&self.query_editor, cx)
|
||||
.aligned()
|
||||
.left()
|
||||
.flex(1., true)
|
||||
.boxed(),
|
||||
)
|
||||
.with_children(self.active_searchable_item.as_ref().and_then(
|
||||
|searchable_item| {
|
||||
let matches = self
|
||||
.seachable_items_with_matches
|
||||
.get(&searchable_item.downgrade())?;
|
||||
let message = if let Some(match_ix) = self.active_match_index {
|
||||
format!("{}/{}", match_ix + 1, matches.len())
|
||||
} else {
|
||||
"No matches".to_string()
|
||||
};
|
||||
|
||||
Some(
|
||||
Label::new(message, theme.search.match_index.text.clone())
|
||||
.contained()
|
||||
.with_style(theme.search.match_index.container)
|
||||
Flex::row()
|
||||
.with_child(
|
||||
ChildView::new(&self.query_editor, cx)
|
||||
.aligned()
|
||||
.left()
|
||||
.flex(1., true)
|
||||
.boxed(),
|
||||
)
|
||||
},
|
||||
))
|
||||
.contained()
|
||||
.with_style(editor_container)
|
||||
.aligned()
|
||||
.constrained()
|
||||
.with_min_width(theme.search.editor.min_width)
|
||||
.with_max_width(theme.search.editor.max_width)
|
||||
.flex(1., false)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(self.render_nav_button("<", Direction::Prev, cx))
|
||||
.with_child(self.render_nav_button(">", Direction::Next, cx))
|
||||
.aligned()
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_children(self.render_search_option(
|
||||
supported_options.case,
|
||||
"Case",
|
||||
SearchOption::CaseSensitive,
|
||||
cx,
|
||||
))
|
||||
.with_children(self.render_search_option(
|
||||
supported_options.word,
|
||||
"Word",
|
||||
SearchOption::WholeWord,
|
||||
cx,
|
||||
))
|
||||
.with_children(self.render_search_option(
|
||||
supported_options.regex,
|
||||
"Regex",
|
||||
SearchOption::Regex,
|
||||
cx,
|
||||
))
|
||||
.contained()
|
||||
.with_style(theme.search.option_button_group)
|
||||
.aligned()
|
||||
.with_children(self.active_searchable_item.as_ref().and_then(
|
||||
|searchable_item| {
|
||||
let matches = self
|
||||
.seachable_items_with_matches
|
||||
.get(&searchable_item.downgrade())?;
|
||||
let message = if let Some(match_ix) = self.active_match_index {
|
||||
format!("{}/{}", match_ix + 1, matches.len())
|
||||
} else {
|
||||
"No matches".to_string()
|
||||
};
|
||||
|
||||
Some(
|
||||
Label::new(message, theme.search.match_index.text.clone())
|
||||
.contained()
|
||||
.with_style(theme.search.match_index.container)
|
||||
.aligned()
|
||||
.boxed(),
|
||||
)
|
||||
},
|
||||
))
|
||||
.contained()
|
||||
.with_style(editor_container)
|
||||
.aligned()
|
||||
.constrained()
|
||||
.with_min_width(theme.search.editor.min_width)
|
||||
.with_max_width(theme.search.editor.max_width)
|
||||
.flex(1., false)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(self.render_nav_button("<", Direction::Prev, cx))
|
||||
.with_child(self.render_nav_button(">", Direction::Next, cx))
|
||||
.aligned()
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_children(self.render_search_option(
|
||||
supported_options.case,
|
||||
"Case",
|
||||
SearchOption::CaseSensitive,
|
||||
cx,
|
||||
))
|
||||
.with_children(self.render_search_option(
|
||||
supported_options.word,
|
||||
"Word",
|
||||
SearchOption::WholeWord,
|
||||
cx,
|
||||
))
|
||||
.with_children(self.render_search_option(
|
||||
supported_options.regex,
|
||||
"Regex",
|
||||
SearchOption::Regex,
|
||||
cx,
|
||||
))
|
||||
.contained()
|
||||
.with_style(theme.search.option_button_group)
|
||||
.aligned()
|
||||
.boxed(),
|
||||
)
|
||||
.flex(1., true)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(self.render_close_button(&theme.search, cx))
|
||||
.contained()
|
||||
.with_style(theme.search.container)
|
||||
.named("search bar")
|
||||
|
@ -325,7 +331,7 @@ impl BufferSearchBar {
|
|||
let is_active = self.is_search_option_enabled(option);
|
||||
Some(
|
||||
MouseEventHandler::<Self>::new(option as usize, cx, |state, cx| {
|
||||
let style = &cx
|
||||
let style = cx
|
||||
.global::<Settings>()
|
||||
.theme
|
||||
.search
|
||||
|
@ -373,7 +379,7 @@ impl BufferSearchBar {
|
|||
|
||||
enum NavButton {}
|
||||
MouseEventHandler::<NavButton>::new(direction as usize, cx, |state, cx| {
|
||||
let style = &cx
|
||||
let style = cx
|
||||
.global::<Settings>()
|
||||
.theme
|
||||
.search
|
||||
|
@ -399,6 +405,38 @@ impl BufferSearchBar {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
fn render_close_button(
|
||||
&self,
|
||||
theme: &theme::Search,
|
||||
cx: &mut RenderContext<Self>,
|
||||
) -> ElementBox {
|
||||
let action = Box::new(Dismiss);
|
||||
let tooltip = "Dismiss Buffer Search";
|
||||
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
|
||||
|
||||
enum CloseButton {}
|
||||
MouseEventHandler::<CloseButton>::new(0, cx, |state, _| {
|
||||
let style = theme.dismiss_button.style_for(state, false);
|
||||
Svg::new("icons/x_mark_8.svg")
|
||||
.with_color(style.color)
|
||||
.constrained()
|
||||
.with_width(style.icon_width)
|
||||
.aligned()
|
||||
.constrained()
|
||||
.with_width(style.button_width)
|
||||
.contained()
|
||||
.with_style(style.container)
|
||||
.boxed()
|
||||
})
|
||||
.on_click(MouseButton::Left, {
|
||||
let action = action.boxed_clone();
|
||||
move |_, cx| cx.dispatch_any_action(action.boxed_clone())
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.with_tooltip::<CloseButton, _>(0, tooltip.to_string(), Some(action), tooltip_style, cx)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn deploy(pane: &mut Pane, action: &Deploy, cx: &mut ViewContext<Pane>) {
|
||||
if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>() {
|
||||
if search_bar.update(cx, |search_bar, cx| search_bar.show(action.focus, true, cx)) {
|
||||
|
|
|
@ -62,7 +62,7 @@ fn parse_snippet<'a>(
|
|||
}
|
||||
}
|
||||
Some(_) => {
|
||||
let chunk_end = source.find(&['}', '$', '\\']).unwrap_or(source.len());
|
||||
let chunk_end = source.find(['}', '$', '\\']).unwrap_or(source.len());
|
||||
let (chunk, rest) = source.split_at(chunk_end);
|
||||
text.push_str(chunk);
|
||||
source = rest;
|
||||
|
|
|
@ -20,7 +20,7 @@ unsafe impl Send for Connection {}
|
|||
impl Connection {
|
||||
pub(crate) fn open(uri: &str, persistent: bool) -> Result<Self> {
|
||||
let mut connection = Self {
|
||||
sqlite3: 0 as *mut _,
|
||||
sqlite3: ptr::null_mut(),
|
||||
persistent,
|
||||
write: RefCell::new(true),
|
||||
_sqlite: PhantomData,
|
||||
|
@ -32,7 +32,7 @@ impl Connection {
|
|||
CString::new(uri)?.as_ptr(),
|
||||
&mut connection.sqlite3,
|
||||
flags,
|
||||
0 as *const _,
|
||||
ptr::null(),
|
||||
);
|
||||
|
||||
// Turn on extended error codes
|
||||
|
@ -97,7 +97,7 @@ impl Connection {
|
|||
let remaining_sql_str = remaining_sql.to_str().unwrap().trim();
|
||||
remaining_sql_str != ";" && !remaining_sql_str.is_empty()
|
||||
} {
|
||||
let mut raw_statement = 0 as *mut sqlite3_stmt;
|
||||
let mut raw_statement = ptr::null_mut::<sqlite3_stmt>();
|
||||
let mut remaining_sql_ptr = ptr::null();
|
||||
sqlite3_prepare_v2(
|
||||
self.sqlite3,
|
||||
|
|
|
@ -48,7 +48,7 @@ impl<'a> Statement<'a> {
|
|||
.trim();
|
||||
remaining_sql_str != ";" && !remaining_sql_str.is_empty()
|
||||
} {
|
||||
let mut raw_statement = 0 as *mut sqlite3_stmt;
|
||||
let mut raw_statement = ptr::null_mut::<sqlite3_stmt>();
|
||||
let mut remaining_sql_ptr = ptr::null();
|
||||
sqlite3_prepare_v2(
|
||||
connection.sqlite3,
|
||||
|
@ -101,7 +101,7 @@ impl<'a> Statement<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn bind_index_with(&self, index: i32, bind: impl Fn(&*mut sqlite3_stmt) -> ()) -> Result<()> {
|
||||
fn bind_index_with(&self, index: i32, bind: impl Fn(&*mut sqlite3_stmt)) -> Result<()> {
|
||||
let mut any_succeed = false;
|
||||
unsafe {
|
||||
for raw_statement in self.raw_statements.iter() {
|
||||
|
@ -133,7 +133,7 @@ impl<'a> Statement<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn column_blob<'b>(&'b mut self, index: i32) -> Result<&'b [u8]> {
|
||||
pub fn column_blob(&mut self, index: i32) -> Result<&[u8]> {
|
||||
let index = index as c_int;
|
||||
let pointer = unsafe { sqlite3_column_blob(self.current_statement(), index) };
|
||||
|
||||
|
@ -217,7 +217,7 @@ impl<'a> Statement<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn column_text<'b>(&'b mut self, index: i32) -> Result<&'b str> {
|
||||
pub fn column_text(&mut self, index: i32) -> Result<&str> {
|
||||
let index = index as c_int;
|
||||
let pointer = unsafe { sqlite3_column_text(self.current_statement(), index) };
|
||||
|
||||
|
|
|
@ -114,12 +114,12 @@ impl<M: Migrator> ThreadSafeConnection<M> {
|
|||
let mut queues = QUEUES.write();
|
||||
if !queues.contains_key(&self.uri) {
|
||||
let mut write_queue_constructor =
|
||||
write_queue_constructor.unwrap_or(background_thread_queue());
|
||||
write_queue_constructor.unwrap_or_else(background_thread_queue);
|
||||
queues.insert(self.uri.clone(), write_queue_constructor());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
false
|
||||
}
|
||||
|
||||
pub fn builder(uri: &str, persistent: bool) -> ThreadSafeConnectionBuilder<M> {
|
||||
|
@ -187,10 +187,9 @@ impl<M: Migrator> ThreadSafeConnection<M> {
|
|||
*connection.write.get_mut() = false;
|
||||
|
||||
if let Some(initialize_query) = connection_initialize_query {
|
||||
connection.exec(initialize_query).expect(&format!(
|
||||
"Initialize query failed to execute: {}",
|
||||
initialize_query
|
||||
))()
|
||||
connection.exec(initialize_query).unwrap_or_else(|_| {
|
||||
panic!("Initialize query failed to execute: {}", initialize_query)
|
||||
})()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
@ -225,7 +224,7 @@ impl<M: Migrator> Clone for ThreadSafeConnection<M> {
|
|||
Self {
|
||||
uri: self.uri.clone(),
|
||||
persistent: self.persistent,
|
||||
connection_initialize_query: self.connection_initialize_query.clone(),
|
||||
connection_initialize_query: self.connection_initialize_query,
|
||||
connections: self.connections.clone(),
|
||||
_migrator: PhantomData,
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
|||
|
||||
impl Connection {
|
||||
pub fn exec<'a>(&'a self, query: &str) -> Result<impl 'a + FnMut() -> Result<()>> {
|
||||
let mut statement = Statement::prepare(&self, query)?;
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move || statement.exec())
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ impl Connection {
|
|||
&'a self,
|
||||
query: &str,
|
||||
) -> Result<impl 'a + FnMut(B) -> Result<()>> {
|
||||
let mut statement = Statement::prepare(&self, query)?;
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move |bindings| statement.with_bindings(bindings)?.exec())
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ impl Connection {
|
|||
&'a self,
|
||||
query: &str,
|
||||
) -> Result<impl 'a + FnMut() -> Result<Vec<C>>> {
|
||||
let mut statement = Statement::prepare(&self, query)?;
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move || statement.rows::<C>())
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ impl Connection {
|
|||
&'a self,
|
||||
query: &str,
|
||||
) -> Result<impl 'a + FnMut(B) -> Result<Vec<C>>> {
|
||||
let mut statement = Statement::prepare(&self, query)?;
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move |bindings| statement.with_bindings(bindings)?.rows::<C>())
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ impl Connection {
|
|||
&'a self,
|
||||
query: &str,
|
||||
) -> Result<impl 'a + FnMut() -> Result<Option<C>>> {
|
||||
let mut statement = Statement::prepare(&self, query)?;
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move || statement.maybe_row::<C>())
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ impl Connection {
|
|||
&'a self,
|
||||
query: &str,
|
||||
) -> Result<impl 'a + FnMut(B) -> Result<Option<C>>> {
|
||||
let mut statement = Statement::prepare(&self, query)?;
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move |bindings| {
|
||||
statement
|
||||
.with_bindings(bindings)
|
||||
|
|
|
@ -33,14 +33,14 @@ fn create_error(
|
|||
.skip_while(|(offset, _)| offset <= &error_offset)
|
||||
.map(|(_, span)| span)
|
||||
.next()
|
||||
.unwrap_or(Span::call_site());
|
||||
.unwrap_or_else(Span::call_site);
|
||||
let error_text = format!("Sql Error: {}\nFor Query: {}", error, formatted_sql);
|
||||
TokenStream::from(Error::new(error_span.into(), error_text).into_compile_error())
|
||||
}
|
||||
|
||||
fn make_sql(tokens: TokenStream) -> (Vec<(usize, Span)>, String) {
|
||||
let mut sql_tokens = vec![];
|
||||
flatten_stream(tokens.clone(), &mut sql_tokens);
|
||||
flatten_stream(tokens, &mut sql_tokens);
|
||||
// Lookup of spans by offset at the end of the token
|
||||
let mut spans: Vec<(usize, Span)> = Vec::new();
|
||||
let mut sql = String::new();
|
||||
|
@ -67,7 +67,7 @@ fn flatten_stream(tokens: TokenStream, result: &mut Vec<(String, Span)>) {
|
|||
result.push((close_delimiter(group.delimiter()), group.span()));
|
||||
}
|
||||
TokenTree::Ident(ident) => {
|
||||
result.push((format!("{} ", ident.to_string()), ident.span()));
|
||||
result.push((format!("{} ", ident), ident.span()));
|
||||
}
|
||||
leaf_tree => result.push((leaf_tree.to_string(), leaf_tree.span())),
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<K: Clone + Debug + Default + Ord, V: Clone + Debug> TreeMap<K, V> {
|
|||
self.0.insert_or_replace(MapEntry { key, value }, &());
|
||||
}
|
||||
|
||||
pub fn remove<'a>(&mut self, key: &'a K) -> Option<V> {
|
||||
pub fn remove(&mut self, key: &K) -> Option<V> {
|
||||
let mut removed = None;
|
||||
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>();
|
||||
let key = MapKeyRef(Some(key));
|
||||
|
|
|
@ -247,6 +247,7 @@ pub struct Search {
|
|||
pub results_status: TextStyle,
|
||||
pub tab_icon_width: f32,
|
||||
pub tab_icon_spacing: f32,
|
||||
pub dismiss_button: Interactive<IconButton>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Default)]
|
||||
|
|
|
@ -4,7 +4,7 @@ use lazy_static::lazy_static;
|
|||
|
||||
lazy_static! {
|
||||
pub static ref RELEASE_CHANNEL_NAME: String = env::var("ZED_RELEASE_CHANNEL")
|
||||
.unwrap_or(include_str!("../../zed/RELEASE_CHANNEL").to_string());
|
||||
.unwrap_or_else(|_| include_str!("../../zed/RELEASE_CHANNEL").to_string());
|
||||
pub static ref RELEASE_CHANNEL: ReleaseChannel = match RELEASE_CHANNEL_NAME.as_str() {
|
||||
"dev" => ReleaseChannel::Dev,
|
||||
"preview" => ReleaseChannel::Preview,
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn truncate_and_trailoff(s: &str, max_chars: usize) -> String {
|
|||
debug_assert!(max_chars >= 5);
|
||||
|
||||
if s.len() > max_chars {
|
||||
format!("{}…", truncate(&s, max_chars.saturating_sub(3)))
|
||||
format!("{}…", truncate(s, max_chars.saturating_sub(3)))
|
||||
} else {
|
||||
s.to_string()
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ actions!(
|
|||
ActivateLastItem,
|
||||
CloseActiveItem,
|
||||
CloseInactiveItems,
|
||||
CloseCleanItems,
|
||||
CloseAllItems,
|
||||
ReopenClosedItem,
|
||||
SplitLeft,
|
||||
SplitUp,
|
||||
|
@ -122,6 +124,8 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
});
|
||||
cx.add_async_action(Pane::close_active_item);
|
||||
cx.add_async_action(Pane::close_inactive_items);
|
||||
cx.add_async_action(Pane::close_clean_items);
|
||||
cx.add_async_action(Pane::close_all_items);
|
||||
cx.add_async_action(|workspace: &mut Workspace, action: &CloseItem, cx| {
|
||||
let pane = action.pane.upgrade(cx)?;
|
||||
let task = Pane::close_item(workspace, pane, action.item_id, cx);
|
||||
|
@ -258,6 +262,13 @@ pub enum ReorderBehavior {
|
|||
MoveToIndex(usize),
|
||||
}
|
||||
|
||||
enum ItemType {
|
||||
Active,
|
||||
Inactive,
|
||||
Clean,
|
||||
All,
|
||||
}
|
||||
|
||||
impl Pane {
|
||||
pub fn new(docked: Option<DockAnchor>, cx: &mut ViewContext<Self>) -> Self {
|
||||
let handle = cx.weak_handle();
|
||||
|
@ -696,40 +707,67 @@ impl Pane {
|
|||
_: &CloseActiveItem,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
let pane_handle = workspace.active_pane().clone();
|
||||
let pane = pane_handle.read(cx);
|
||||
if pane.items.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let item_id_to_close = pane.items[pane.active_item_index].id();
|
||||
let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
|
||||
item_id == item_id_to_close
|
||||
});
|
||||
Some(cx.foreground().spawn(async move {
|
||||
task.await?;
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
Self::close_main(workspace, ItemType::Active, cx)
|
||||
}
|
||||
|
||||
pub fn close_inactive_items(
|
||||
workspace: &mut Workspace,
|
||||
_: &CloseInactiveItems,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
Self::close_main(workspace, ItemType::Inactive, cx)
|
||||
}
|
||||
|
||||
pub fn close_all_items(
|
||||
workspace: &mut Workspace,
|
||||
_: &CloseAllItems,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
Self::close_main(workspace, ItemType::All, cx)
|
||||
}
|
||||
|
||||
pub fn close_clean_items(
|
||||
workspace: &mut Workspace,
|
||||
_: &CloseCleanItems,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
Self::close_main(workspace, ItemType::Clean, cx)
|
||||
}
|
||||
|
||||
fn close_main(
|
||||
workspace: &mut Workspace,
|
||||
close_item_type: ItemType,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
let pane_handle = workspace.active_pane().clone();
|
||||
let pane = pane_handle.read(cx);
|
||||
if pane.items.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let active_item_id = pane.items[pane.active_item_index].id();
|
||||
let task =
|
||||
Self::close_items(workspace, pane_handle, cx, move |id| id != active_item_id);
|
||||
Some(cx.foreground().spawn(async move {
|
||||
task.await?;
|
||||
Ok(())
|
||||
}))
|
||||
return None;
|
||||
}
|
||||
|
||||
let active_item_id = pane.items[pane.active_item_index].id();
|
||||
let clean_item_ids: Vec<_> = pane
|
||||
.items()
|
||||
.filter(|item| !item.is_dirty(cx))
|
||||
.map(|item| item.id())
|
||||
.collect();
|
||||
let task =
|
||||
Self::close_items(
|
||||
workspace,
|
||||
pane_handle,
|
||||
cx,
|
||||
move |item_id| match close_item_type {
|
||||
ItemType::Active => item_id == active_item_id,
|
||||
ItemType::Inactive => item_id != active_item_id,
|
||||
ItemType::Clean => clean_item_ids.contains(&item_id),
|
||||
ItemType::All => true,
|
||||
},
|
||||
);
|
||||
|
||||
Some(cx.foreground().spawn(async move {
|
||||
task.await?;
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn close_item(
|
||||
|
|
|
@ -95,7 +95,7 @@ actions!(
|
|||
ToggleLeftSidebar,
|
||||
ToggleRightSidebar,
|
||||
NewTerminal,
|
||||
NewSearch,
|
||||
NewSearch
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
|
|||
description = "The fast, collaborative code editor."
|
||||
edition = "2021"
|
||||
name = "zed"
|
||||
version = "0.68.0"
|
||||
version = "0.69.0"
|
||||
|
||||
[lib]
|
||||
name = "zed"
|
||||
|
@ -30,6 +30,7 @@ clock = { path = "../clock" }
|
|||
diagnostics = { path = "../diagnostics" }
|
||||
editor = { path = "../editor" }
|
||||
file_finder = { path = "../file_finder" }
|
||||
human_bytes = "0.4.1"
|
||||
search = { path = "../search" }
|
||||
fs = { path = "../fs" }
|
||||
fsevent = { path = "../fsevent" }
|
||||
|
@ -48,6 +49,7 @@ recent_projects = { path = "../recent_projects" }
|
|||
rpc = { path = "../rpc" }
|
||||
settings = { path = "../settings" }
|
||||
sum_tree = { path = "../sum_tree" }
|
||||
sysinfo = "0.27.1"
|
||||
text = { path = "../text" }
|
||||
terminal_view = { path = "../terminal_view" }
|
||||
theme = { path = "../theme" }
|
||||
|
@ -108,6 +110,7 @@ tree-sitter-html = "0.19.0"
|
|||
tree-sitter-scheme = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "af0fd1fa452cb2562dc7b5c8a8c55551c39273b9"}
|
||||
tree-sitter-racket = { git = "https://github.com/zed-industries/tree-sitter-racket", rev = "eb010cf2c674c6fd9a6316a84e28ef90190fe51a"}
|
||||
url = "2.2"
|
||||
urlencoding = "2.1.2"
|
||||
|
||||
[dev-dependencies]
|
||||
call = { path = "../call", features = ["test-support"] }
|
||||
|
|
|
@ -50,14 +50,14 @@ impl LspAdapter for RubyLanguageServer {
|
|||
grammar.highlight_id_for_name("type")?
|
||||
}
|
||||
lsp::CompletionItemKind::KEYWORD => {
|
||||
if label.starts_with(":") {
|
||||
if label.starts_with(':') {
|
||||
grammar.highlight_id_for_name("string.special.symbol")?
|
||||
} else {
|
||||
grammar.highlight_id_for_name("keyword")?
|
||||
}
|
||||
}
|
||||
lsp::CompletionItemKind::VARIABLE => {
|
||||
if label.starts_with("@") {
|
||||
if label.starts_with('@') {
|
||||
grammar.highlight_id_for_name("property")?
|
||||
} else {
|
||||
return None;
|
||||
|
|
|
@ -128,8 +128,14 @@ impl LspAdapter for TypeScriptLspAdapter {
|
|||
Kind::PROPERTY | Kind::FIELD => grammar.highlight_id_for_name("property"),
|
||||
_ => None,
|
||||
}?;
|
||||
|
||||
let text = match &item.detail {
|
||||
Some(detail) => format!("{} {}", item.label, detail),
|
||||
None => item.label.clone(),
|
||||
};
|
||||
|
||||
Some(language::CodeLabel {
|
||||
text: item.label.clone(),
|
||||
text,
|
||||
runs: vec![(0..len, highlight_id)],
|
||||
filter_range: 0..len,
|
||||
})
|
||||
|
|
|
@ -101,7 +101,7 @@ fn main() {
|
|||
|
||||
//Setup settings global before binding actions
|
||||
cx.set_global(SettingsFile::new(
|
||||
&*paths::SETTINGS,
|
||||
&paths::SETTINGS,
|
||||
settings_file_content.clone(),
|
||||
fs.clone(),
|
||||
));
|
||||
|
@ -586,7 +586,7 @@ async fn handle_cli_connection(
|
|||
|
||||
responses
|
||||
.send(CliResponse::Exit {
|
||||
status: if errored { 1 } else { 0 },
|
||||
status: i32::from(errored),
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
|
|
|
@ -338,18 +338,25 @@ pub fn menus() -> Vec<Menu<'static>> {
|
|||
action: Box::new(crate::OpenTelemetryLog),
|
||||
},
|
||||
MenuItem::Separator,
|
||||
MenuItem::Action {
|
||||
name: "Copy System Specs Into Clipboard",
|
||||
action: Box::new(crate::CopySystemSpecsIntoClipboard),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "File Bug Report",
|
||||
action: Box::new(crate::FileBugReport),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "Request Feature",
|
||||
action: Box::new(crate::RequestFeature),
|
||||
},
|
||||
MenuItem::Separator,
|
||||
MenuItem::Action {
|
||||
name: "Documentation",
|
||||
action: Box::new(crate::OpenBrowser {
|
||||
url: "https://zed.dev/docs".into(),
|
||||
}),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "Give Feedback",
|
||||
action: Box::new(crate::OpenBrowser {
|
||||
url: super::feedback::NEW_ISSUE_URL.into(),
|
||||
}),
|
||||
},
|
||||
MenuItem::Action {
|
||||
name: "Zed Twitter",
|
||||
action: Box::new(crate::OpenBrowser {
|
||||
|
|
52
crates/zed/src/system_specs.rs
Normal file
52
crates/zed/src/system_specs.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use std::{env, fmt::Display};
|
||||
|
||||
use gpui::AppContext;
|
||||
use human_bytes::human_bytes;
|
||||
use sysinfo::{System, SystemExt};
|
||||
use util::channel::ReleaseChannel;
|
||||
|
||||
pub struct SystemSpecs {
|
||||
app_version: &'static str,
|
||||
release_channel: &'static str,
|
||||
os_name: &'static str,
|
||||
os_version: Option<String>,
|
||||
memory: u64,
|
||||
architecture: &'static str,
|
||||
}
|
||||
|
||||
impl SystemSpecs {
|
||||
pub fn new(cx: &AppContext) -> Self {
|
||||
let platform = cx.platform();
|
||||
let system = System::new_all();
|
||||
|
||||
SystemSpecs {
|
||||
app_version: env!("CARGO_PKG_VERSION"),
|
||||
release_channel: cx.global::<ReleaseChannel>().dev_name(),
|
||||
os_name: platform.os_name(),
|
||||
os_version: platform
|
||||
.os_version()
|
||||
.ok()
|
||||
.map(|os_version| os_version.to_string()),
|
||||
memory: system.total_memory(),
|
||||
architecture: env::consts::ARCH,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SystemSpecs {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let os_information = match &self.os_version {
|
||||
Some(os_version) => format!("OS: {} {}", self.os_name, os_version),
|
||||
None => format!("OS: {}", self.os_name),
|
||||
};
|
||||
let system_specs = [
|
||||
format!("Zed: {} ({})", self.app_version, self.release_channel),
|
||||
os_information,
|
||||
format!("Memory: {}", human_bytes(self.memory as f64)),
|
||||
format!("Architecture: {}", self.architecture),
|
||||
]
|
||||
.join("\n");
|
||||
|
||||
write!(f, "{system_specs}")
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
mod feedback;
|
||||
pub mod languages;
|
||||
pub mod menus;
|
||||
pub mod system_specs;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub mod test;
|
||||
|
||||
|
@ -21,7 +22,7 @@ use gpui::{
|
|||
},
|
||||
impl_actions,
|
||||
platform::{WindowBounds, WindowOptions},
|
||||
AssetSource, AsyncAppContext, TitlebarOptions, ViewContext, WindowKind,
|
||||
AssetSource, AsyncAppContext, ClipboardItem, TitlebarOptions, ViewContext, WindowKind,
|
||||
};
|
||||
use language::Rope;
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -33,6 +34,7 @@ use serde::Deserialize;
|
|||
use serde_json::to_string_pretty;
|
||||
use settings::{keymap_file_json_schema, settings_file_json_schema, Settings};
|
||||
use std::{env, path::Path, str, sync::Arc};
|
||||
use system_specs::SystemSpecs;
|
||||
use util::{channel::ReleaseChannel, paths, ResultExt};
|
||||
pub use workspace;
|
||||
use workspace::{sidebar::SidebarSide, AppState, Workspace};
|
||||
|
@ -67,6 +69,9 @@ actions!(
|
|||
ResetBufferFontSize,
|
||||
InstallCommandLineInterface,
|
||||
ResetDatabase,
|
||||
CopySystemSpecsIntoClipboard,
|
||||
RequestFeature,
|
||||
FileBugReport
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -245,6 +250,41 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
cx.add_action(
|
||||
|_: &mut Workspace, _: &CopySystemSpecsIntoClipboard, cx: &mut ViewContext<Workspace>| {
|
||||
let system_specs = SystemSpecs::new(cx).to_string();
|
||||
let item = ClipboardItem::new(system_specs.clone());
|
||||
cx.prompt(
|
||||
gpui::PromptLevel::Info,
|
||||
&format!("Copied into clipboard:\n\n{system_specs}"),
|
||||
&["OK"],
|
||||
);
|
||||
cx.write_to_clipboard(item);
|
||||
},
|
||||
);
|
||||
|
||||
cx.add_action(
|
||||
|_: &mut Workspace, _: &RequestFeature, cx: &mut ViewContext<Workspace>| {
|
||||
let url = "https://github.com/zed-industries/feedback/issues/new?assignees=&labels=enhancement%2Ctriage&template=0_feature_request.yml";
|
||||
cx.dispatch_action(OpenBrowser {
|
||||
url: url.into(),
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
cx.add_action(
|
||||
|_: &mut Workspace, _: &FileBugReport, cx: &mut ViewContext<Workspace>| {
|
||||
let system_specs_text = SystemSpecs::new(cx).to_string();
|
||||
let url = format!(
|
||||
"https://github.com/zed-industries/feedback/issues/new?assignees=&labels=defect%2Ctriage&template=2_bug_report.yml&environment={}",
|
||||
urlencoding::encode(&system_specs_text)
|
||||
);
|
||||
cx.dispatch_action(OpenBrowser {
|
||||
url: url.into(),
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
activity_indicator::init(cx);
|
||||
call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
|
||||
settings::KeymapFileContent::load_defaults(cx);
|
||||
|
@ -298,11 +338,11 @@ pub fn initialize_workspace(
|
|||
},
|
||||
"schemas": [
|
||||
{
|
||||
"fileMatch": [schema_file_match(&*paths::SETTINGS)],
|
||||
"fileMatch": [schema_file_match(&paths::SETTINGS)],
|
||||
"schema": settings_file_json_schema(theme_names, language_names),
|
||||
},
|
||||
{
|
||||
"fileMatch": [schema_file_match(&*paths::KEYMAP)],
|
||||
"fileMatch": [schema_file_match(&paths::KEYMAP)],
|
||||
"schema": keymap_file_json_schema(&action_names),
|
||||
}
|
||||
]
|
||||
|
@ -606,7 +646,7 @@ fn open_bundled_config_file(
|
|||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
workspace
|
||||
.with_local_workspace(&app_state.clone(), cx, |workspace, cx| {
|
||||
.with_local_workspace(&app_state, cx, |workspace, cx| {
|
||||
let project = workspace.project().clone();
|
||||
let buffer = project.update(cx, |project, cx| {
|
||||
let text = Assets::get(asset_path).unwrap().data;
|
||||
|
|
|
@ -32,13 +32,13 @@ export default function contactNotification(colorScheme: ColorScheme): Object {
|
|||
},
|
||||
},
|
||||
dismissButton: {
|
||||
color: foreground(layer, "on"),
|
||||
color: foreground(layer, "variant"),
|
||||
iconWidth: 8,
|
||||
iconHeight: 8,
|
||||
buttonWidth: 8,
|
||||
buttonHeight: 8,
|
||||
hover: {
|
||||
color: foreground(layer, "on", "hovered"),
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -257,7 +257,6 @@ export default function editor(colorScheme: ColorScheme) {
|
|||
right: 6,
|
||||
},
|
||||
hover: {
|
||||
color: foreground(layer, "on", "hovered"),
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -80,5 +80,17 @@ export default function search(colorScheme: ColorScheme) {
|
|||
...text(layer, "mono", "on"),
|
||||
size: 18,
|
||||
},
|
||||
dismissButton: {
|
||||
color: foreground(layer, "variant"),
|
||||
iconWidth: 12,
|
||||
buttonWidth: 14,
|
||||
padding: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
},
|
||||
hover: {
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function tabBar(colorScheme: ColorScheme) {
|
|||
// Close icons
|
||||
iconWidth: 8,
|
||||
iconClose: foreground(layer, "variant"),
|
||||
iconCloseActive: foreground(layer),
|
||||
iconCloseActive: foreground(layer, "hovered"),
|
||||
|
||||
// Indicators
|
||||
iconConflict: foreground(layer, "warning"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue