Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f40ff0ac85 | ||
![]() |
aae1d99718 | ||
![]() |
cde1b5987f | ||
![]() |
4c71e4b749 | ||
![]() |
32ea881be7 | ||
![]() |
030968ec51 | ||
![]() |
0c7973d274 | ||
![]() |
0071a4598a | ||
![]() |
d7e4544638 | ||
![]() |
432d407539 |
11 changed files with 123 additions and 110 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -8777,7 +8777,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.89.0"
|
||||
version = "0.89.2"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"ai",
|
||||
|
|
|
@ -31,7 +31,9 @@ use copilot::Copilot;
|
|||
pub use display_map::DisplayPoint;
|
||||
use display_map::*;
|
||||
pub use editor_settings::EditorSettings;
|
||||
pub use element::*;
|
||||
pub use element::{
|
||||
Cursor, EditorElement, HighlightedRange, HighlightedRangeLine, LineWithInvisibles,
|
||||
};
|
||||
use futures::FutureExt;
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
|
|
|
@ -965,10 +965,10 @@ impl<'a> WindowContext<'a> {
|
|||
}
|
||||
|
||||
pub fn rect_for_text_range(&self, range_utf16: Range<usize>) -> Option<RectF> {
|
||||
let root_view_id = self.window.root_view().id();
|
||||
let focused_view_id = self.window.focused_view_id?;
|
||||
self.window
|
||||
.rendered_views
|
||||
.get(&root_view_id)?
|
||||
.get(&focused_view_id)?
|
||||
.rect_for_text_range(range_utf16, self)
|
||||
.log_err()
|
||||
.flatten()
|
||||
|
|
|
@ -84,8 +84,8 @@ impl InputHandler for WindowInputHandler {
|
|||
|
||||
fn rect_for_range(&self, range_utf16: Range<usize>) -> Option<RectF> {
|
||||
self.app
|
||||
.borrow_mut()
|
||||
.update_window(self.window_id, |cx| cx.rect_for_text_range(range_utf16))
|
||||
.borrow()
|
||||
.read_window(self.window_id, |cx| cx.rect_for_text_range(range_utf16))
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ struct StateInner {
|
|||
scroll_to: Option<ScrollTarget>,
|
||||
}
|
||||
|
||||
pub struct LayoutState<V: View> {
|
||||
pub struct UniformListLayoutState<V: View> {
|
||||
scroll_max: f32,
|
||||
item_height: f32,
|
||||
items: Vec<AnyElement<V>>,
|
||||
|
@ -152,7 +152,7 @@ impl<V: View> UniformList<V> {
|
|||
}
|
||||
|
||||
impl<V: View> Element<V> for UniformList<V> {
|
||||
type LayoutState = LayoutState<V>;
|
||||
type LayoutState = UniformListLayoutState<V>;
|
||||
type PaintState = ();
|
||||
|
||||
fn layout(
|
||||
|
@ -169,7 +169,7 @@ impl<V: View> Element<V> for UniformList<V> {
|
|||
|
||||
let no_items = (
|
||||
constraint.min,
|
||||
LayoutState {
|
||||
UniformListLayoutState {
|
||||
item_height: 0.,
|
||||
scroll_max: 0.,
|
||||
items: Default::default(),
|
||||
|
@ -263,7 +263,7 @@ impl<V: View> Element<V> for UniformList<V> {
|
|||
|
||||
(
|
||||
size,
|
||||
LayoutState {
|
||||
UniformListLayoutState {
|
||||
item_height,
|
||||
scroll_max,
|
||||
items,
|
||||
|
|
|
@ -55,15 +55,22 @@ pub fn watch_config_file(
|
|||
.spawn(async move {
|
||||
let events = fs.watch(&path, Duration::from_millis(100)).await;
|
||||
futures::pin_mut!(events);
|
||||
|
||||
let contents = fs.load(&path).await.unwrap_or_default();
|
||||
if tx.unbounded_send(contents).is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
loop {
|
||||
if events.next().await.is_none() {
|
||||
break;
|
||||
}
|
||||
|
||||
if let Ok(contents) = fs.load(&path).await {
|
||||
if !tx.unbounded_send(contents).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if events.next().await.is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use collections::{btree_map, hash_map, BTreeMap, HashMap};
|
||||
use gpui::AppContext;
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -84,15 +84,26 @@ pub struct SettingsJsonSchemaParams<'a> {
|
|||
}
|
||||
|
||||
/// A set of strongly-typed setting values defined via multiple JSON files.
|
||||
#[derive(Default)]
|
||||
pub struct SettingsStore {
|
||||
setting_values: HashMap<TypeId, Box<dyn AnySettingValue>>,
|
||||
default_deserialized_settings: Option<serde_json::Value>,
|
||||
user_deserialized_settings: Option<serde_json::Value>,
|
||||
default_deserialized_settings: serde_json::Value,
|
||||
user_deserialized_settings: serde_json::Value,
|
||||
local_deserialized_settings: BTreeMap<Arc<Path>, serde_json::Value>,
|
||||
tab_size_callback: Option<(TypeId, Box<dyn Fn(&dyn Any) -> Option<usize>>)>,
|
||||
}
|
||||
|
||||
impl Default for SettingsStore {
|
||||
fn default() -> Self {
|
||||
SettingsStore {
|
||||
setting_values: Default::default(),
|
||||
default_deserialized_settings: serde_json::json!({}),
|
||||
user_deserialized_settings: serde_json::json!({}),
|
||||
local_deserialized_settings: Default::default(),
|
||||
tab_size_callback: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SettingValue<T> {
|
||||
global_value: Option<T>,
|
||||
|
@ -136,27 +147,24 @@ impl SettingsStore {
|
|||
local_values: Vec::new(),
|
||||
}));
|
||||
|
||||
if let Some(default_settings) = &self.default_deserialized_settings {
|
||||
if let Some(default_settings) = setting_value
|
||||
.deserialize_setting(default_settings)
|
||||
if let Some(default_settings) = setting_value
|
||||
.deserialize_setting(&self.default_deserialized_settings)
|
||||
.log_err()
|
||||
{
|
||||
let mut user_values_stack = Vec::new();
|
||||
|
||||
if let Some(user_settings) = setting_value
|
||||
.deserialize_setting(&self.user_deserialized_settings)
|
||||
.log_err()
|
||||
{
|
||||
let mut user_values_stack = Vec::new();
|
||||
user_values_stack = vec![user_settings];
|
||||
}
|
||||
|
||||
if let Some(user_settings) = &self.user_deserialized_settings {
|
||||
if let Some(user_settings) =
|
||||
setting_value.deserialize_setting(user_settings).log_err()
|
||||
{
|
||||
user_values_stack = vec![user_settings];
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(setting) = setting_value
|
||||
.load_setting(&default_settings, &user_values_stack, cx)
|
||||
.log_err()
|
||||
{
|
||||
setting_value.set_global_value(setting);
|
||||
}
|
||||
if let Some(setting) = setting_value
|
||||
.load_setting(&default_settings, &user_values_stack, cx)
|
||||
.log_err()
|
||||
{
|
||||
setting_value.set_global_value(setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,9 +197,7 @@ impl SettingsStore {
|
|||
/// This is only for debugging and reporting. For user-facing functionality,
|
||||
/// use the typed setting interface.
|
||||
pub fn untyped_user_settings(&self) -> &serde_json::Value {
|
||||
self.user_deserialized_settings
|
||||
.as_ref()
|
||||
.unwrap_or(&serde_json::Value::Null)
|
||||
&self.user_deserialized_settings
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
@ -213,11 +219,7 @@ impl SettingsStore {
|
|||
cx: &AppContext,
|
||||
update: impl FnOnce(&mut T::FileContent),
|
||||
) {
|
||||
if self.user_deserialized_settings.is_none() {
|
||||
self.set_user_settings("{}", cx).unwrap();
|
||||
}
|
||||
let old_text =
|
||||
serde_json::to_string(self.user_deserialized_settings.as_ref().unwrap()).unwrap();
|
||||
let old_text = serde_json::to_string(&self.user_deserialized_settings).unwrap();
|
||||
let new_text = self.new_text_for_update::<T>(old_text, update);
|
||||
self.set_user_settings(&new_text, cx).unwrap();
|
||||
}
|
||||
|
@ -250,11 +252,7 @@ impl SettingsStore {
|
|||
.setting_values
|
||||
.get(&setting_type_id)
|
||||
.unwrap_or_else(|| panic!("unregistered setting type {}", type_name::<T>()))
|
||||
.deserialize_setting(
|
||||
self.user_deserialized_settings
|
||||
.as_ref()
|
||||
.expect("no user settings loaded"),
|
||||
)
|
||||
.deserialize_setting(&self.user_deserialized_settings)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"could not deserialize setting type {} from user settings: {}",
|
||||
|
@ -323,10 +321,14 @@ impl SettingsStore {
|
|||
default_settings_content: &str,
|
||||
cx: &AppContext,
|
||||
) -> Result<()> {
|
||||
self.default_deserialized_settings =
|
||||
Some(parse_json_with_comments(default_settings_content)?);
|
||||
self.recompute_values(None, cx)?;
|
||||
Ok(())
|
||||
let settings: serde_json::Value = parse_json_with_comments(default_settings_content)?;
|
||||
if settings.is_object() {
|
||||
self.default_deserialized_settings = settings;
|
||||
self.recompute_values(None, cx)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!("settings must be an object"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the user settings via a JSON string.
|
||||
|
@ -335,9 +337,14 @@ impl SettingsStore {
|
|||
user_settings_content: &str,
|
||||
cx: &AppContext,
|
||||
) -> Result<()> {
|
||||
self.user_deserialized_settings = Some(parse_json_with_comments(user_settings_content)?);
|
||||
self.recompute_values(None, cx)?;
|
||||
Ok(())
|
||||
let settings: serde_json::Value = parse_json_with_comments(user_settings_content)?;
|
||||
if settings.is_object() {
|
||||
self.user_deserialized_settings = settings;
|
||||
self.recompute_values(None, cx)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!("settings must be an object"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Add or remove a set of local settings via a JSON string.
|
||||
|
@ -443,65 +450,63 @@ impl SettingsStore {
|
|||
let mut user_settings_stack = Vec::<DeserializedSetting>::new();
|
||||
let mut paths_stack = Vec::<Option<&Path>>::new();
|
||||
for setting_value in self.setting_values.values_mut() {
|
||||
if let Some(default_settings) = &self.default_deserialized_settings {
|
||||
let default_settings = setting_value.deserialize_setting(default_settings)?;
|
||||
let default_settings =
|
||||
setting_value.deserialize_setting(&self.default_deserialized_settings)?;
|
||||
|
||||
user_settings_stack.clear();
|
||||
paths_stack.clear();
|
||||
user_settings_stack.clear();
|
||||
paths_stack.clear();
|
||||
|
||||
if let Some(user_settings) = &self.user_deserialized_settings {
|
||||
if let Some(user_settings) =
|
||||
setting_value.deserialize_setting(user_settings).log_err()
|
||||
{
|
||||
user_settings_stack.push(user_settings);
|
||||
paths_stack.push(None);
|
||||
if let Some(user_settings) = setting_value
|
||||
.deserialize_setting(&self.user_deserialized_settings)
|
||||
.log_err()
|
||||
{
|
||||
user_settings_stack.push(user_settings);
|
||||
paths_stack.push(None);
|
||||
}
|
||||
|
||||
// If the global settings file changed, reload the global value for the field.
|
||||
if changed_local_path.is_none() {
|
||||
if let Some(value) = setting_value
|
||||
.load_setting(&default_settings, &user_settings_stack, cx)
|
||||
.log_err()
|
||||
{
|
||||
setting_value.set_global_value(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Reload the local values for the setting.
|
||||
for (path, local_settings) in &self.local_deserialized_settings {
|
||||
// Build a stack of all of the local values for that setting.
|
||||
while let Some(prev_path) = paths_stack.last() {
|
||||
if let Some(prev_path) = prev_path {
|
||||
if !path.starts_with(prev_path) {
|
||||
paths_stack.pop();
|
||||
user_settings_stack.pop();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If the global settings file changed, reload the global value for the field.
|
||||
if changed_local_path.is_none() {
|
||||
if let Some(local_settings) =
|
||||
setting_value.deserialize_setting(&local_settings).log_err()
|
||||
{
|
||||
paths_stack.push(Some(path.as_ref()));
|
||||
user_settings_stack.push(local_settings);
|
||||
|
||||
// If a local settings file changed, then avoid recomputing local
|
||||
// settings for any path outside of that directory.
|
||||
if changed_local_path.map_or(false, |changed_local_path| {
|
||||
!path.starts_with(changed_local_path)
|
||||
}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(value) = setting_value
|
||||
.load_setting(&default_settings, &user_settings_stack, cx)
|
||||
.log_err()
|
||||
{
|
||||
setting_value.set_global_value(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Reload the local values for the setting.
|
||||
for (path, local_settings) in &self.local_deserialized_settings {
|
||||
// Build a stack of all of the local values for that setting.
|
||||
while let Some(prev_path) = paths_stack.last() {
|
||||
if let Some(prev_path) = prev_path {
|
||||
if !path.starts_with(prev_path) {
|
||||
paths_stack.pop();
|
||||
user_settings_stack.pop();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if let Some(local_settings) =
|
||||
setting_value.deserialize_setting(&local_settings).log_err()
|
||||
{
|
||||
paths_stack.push(Some(path.as_ref()));
|
||||
user_settings_stack.push(local_settings);
|
||||
|
||||
// If a local settings file changed, then avoid recomputing local
|
||||
// settings for any path outside of that directory.
|
||||
if changed_local_path.map_or(false, |changed_local_path| {
|
||||
!path.starts_with(changed_local_path)
|
||||
}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(value) = setting_value
|
||||
.load_setting(&default_settings, &user_settings_stack, cx)
|
||||
.log_err()
|
||||
{
|
||||
setting_value.set_local_value(path.clone(), value);
|
||||
}
|
||||
setting_value.set_local_value(path.clone(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,8 +133,8 @@ impl TerminalView {
|
|||
Event::Wakeup => {
|
||||
if !cx.is_self_focused() {
|
||||
this.has_new_content = true;
|
||||
cx.notify();
|
||||
}
|
||||
cx.notify();
|
||||
cx.emit(Event::Wakeup);
|
||||
}
|
||||
Event::Bell => {
|
||||
|
|
|
@ -974,9 +974,8 @@ impl Workspace {
|
|||
let timestamp = entry.timestamp;
|
||||
match history.entry(project_path) {
|
||||
hash_map::Entry::Occupied(mut entry) => {
|
||||
let (old_fs_path, old_timestamp) = entry.get();
|
||||
let (_, old_timestamp) = entry.get();
|
||||
if ×tamp > old_timestamp {
|
||||
assert_eq!(&fs_path, old_fs_path, "Inconsistent nav history");
|
||||
entry.insert((fs_path, timestamp));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
|
|||
description = "The fast, collaborative code editor."
|
||||
edition = "2021"
|
||||
name = "zed"
|
||||
version = "0.89.0"
|
||||
version = "0.89.2"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -1 +1 @@
|
|||
dev
|
||||
stable
|
Loading…
Add table
Add a link
Reference in a new issue