Compare commits
17 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5cda0ec38e | ||
![]() |
01d9d8b6de | ||
![]() |
633ad71cda | ||
![]() |
fa6e8c9bfc | ||
![]() |
36590cf22d | ||
![]() |
203574b975 | ||
![]() |
2fcf186b17 | ||
![]() |
5faceaf659 | ||
![]() |
8ff3f6569d | ||
![]() |
41ef9cc279 | ||
![]() |
08e5e5a43d | ||
![]() |
96dffc06e7 | ||
![]() |
dc8f348cdb | ||
![]() |
fcbdfe849f | ||
![]() |
e23ca8d20e | ||
![]() |
3407b16ec8 | ||
![]() |
cc62945c6b |
23 changed files with 252 additions and 256 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -8546,7 +8546,7 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
|||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.85.0"
|
||||
version = "0.85.4"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"anyhow",
|
||||
|
|
|
@ -273,7 +273,7 @@ impl AutoUpdater {
|
|||
telemetry,
|
||||
})?);
|
||||
|
||||
let mut response = client.post_json(&release.url, request_body, true).await?;
|
||||
let mut response = client.get(&release.url, request_body, true).await?;
|
||||
smol::io::copy(response.body_mut(), &mut dmg_file).await?;
|
||||
log::info!("downloaded update. path:{:?}", dmg_path);
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ impl Telemetry {
|
|||
}])?;
|
||||
|
||||
this.http_client
|
||||
.post_json(MIXPANEL_ENGAGE_URL, json_bytes.into(), false)
|
||||
.post_json(MIXPANEL_ENGAGE_URL, json_bytes.into())
|
||||
.await?;
|
||||
anyhow::Ok(())
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ impl Telemetry {
|
|||
json_bytes.clear();
|
||||
serde_json::to_writer(&mut json_bytes, &events)?;
|
||||
this.http_client
|
||||
.post_json(MIXPANEL_EVENTS_URL, json_bytes.into(), false)
|
||||
.post_json(MIXPANEL_EVENTS_URL, json_bytes.into())
|
||||
.await?;
|
||||
anyhow::Ok(())
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ impl Telemetry {
|
|||
}
|
||||
|
||||
this.http_client
|
||||
.post_json(CLICKHOUSE_EVENTS_URL.as_str(), json_bytes.into(), false)
|
||||
.post_json(CLICKHOUSE_EVENTS_URL.as_str(), json_bytes.into())
|
||||
.await?;
|
||||
anyhow::Ok(())
|
||||
}
|
||||
|
|
|
@ -1306,10 +1306,9 @@ impl View for ContactList {
|
|||
"ContactList"
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
let mut cx = Self::default_keymap_context();
|
||||
cx.add_identifier("menu");
|
||||
cx
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
keymap.add_identifier("menu");
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||
|
|
|
@ -126,7 +126,6 @@ pub struct ContextMenu {
|
|||
selected_index: Option<usize>,
|
||||
visible: bool,
|
||||
previously_focused_view_id: Option<usize>,
|
||||
clicked: bool,
|
||||
parent_view_id: usize,
|
||||
_actions_observation: Subscription,
|
||||
}
|
||||
|
@ -140,10 +139,9 @@ impl View for ContextMenu {
|
|||
"ContextMenu"
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
let mut cx = Self::default_keymap_context();
|
||||
cx.add_identifier("menu");
|
||||
cx
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
keymap.add_identifier("menu");
|
||||
}
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||
|
@ -190,7 +188,6 @@ impl ContextMenu {
|
|||
selected_index: Default::default(),
|
||||
visible: Default::default(),
|
||||
previously_focused_view_id: Default::default(),
|
||||
clicked: false,
|
||||
parent_view_id,
|
||||
_actions_observation: cx.observe_actions(Self::action_dispatched),
|
||||
}
|
||||
|
@ -206,18 +203,14 @@ impl ContextMenu {
|
|||
.iter()
|
||||
.position(|item| item.action_id() == Some(action_id))
|
||||
{
|
||||
if self.clicked {
|
||||
self.cancel(&Default::default(), cx);
|
||||
} else {
|
||||
self.selected_index = Some(ix);
|
||||
cx.notify();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
cx.background().timer(Duration::from_millis(50)).await;
|
||||
this.update(&mut cx, |this, cx| this.cancel(&Default::default(), cx))?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
self.selected_index = Some(ix);
|
||||
cx.notify();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
cx.background().timer(Duration::from_millis(50)).await;
|
||||
this.update(&mut cx, |this, cx| this.cancel(&Default::default(), cx))?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +250,6 @@ impl ContextMenu {
|
|||
self.items.clear();
|
||||
self.visible = false;
|
||||
self.selected_index.take();
|
||||
self.clicked = false;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -457,7 +449,7 @@ impl ContextMenu {
|
|||
.on_up(MouseButton::Left, |_, _, _| {}) // Capture these events
|
||||
.on_down(MouseButton::Left, |_, _, _| {}) // Capture these events
|
||||
.on_click(MouseButton::Left, move |_, menu, cx| {
|
||||
menu.clicked = true;
|
||||
menu.cancel(&Default::default(), cx);
|
||||
let window_id = cx.window_id();
|
||||
match &action {
|
||||
ContextMenuItemAction::Action(action) => {
|
||||
|
|
|
@ -461,14 +461,12 @@ impl Copilot {
|
|||
pub fn sign_in(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
if let CopilotServer::Running(server) = &mut self.server {
|
||||
let task = match &server.sign_in_status {
|
||||
SignInStatus::Authorized { .. } | SignInStatus::Unauthorized { .. } => {
|
||||
Task::ready(Ok(())).shared()
|
||||
}
|
||||
SignInStatus::Authorized { .. } => Task::ready(Ok(())).shared(),
|
||||
SignInStatus::SigningIn { task, .. } => {
|
||||
cx.notify();
|
||||
task.clone()
|
||||
}
|
||||
SignInStatus::SignedOut => {
|
||||
SignInStatus::SignedOut | SignInStatus::Unauthorized { .. } => {
|
||||
let lsp = server.lsp.clone();
|
||||
let task = cx
|
||||
.spawn(|this, mut cx| async move {
|
||||
|
|
|
@ -1425,13 +1425,19 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_keymap_context_layer<Tag: 'static>(&mut self, context: KeymapContext) {
|
||||
pub fn set_keymap_context_layer<Tag: 'static>(
|
||||
&mut self,
|
||||
context: KeymapContext,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
self.keymap_context_layers
|
||||
.insert(TypeId::of::<Tag>(), context);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn remove_keymap_context_layer<Tag: 'static>(&mut self) {
|
||||
pub fn remove_keymap_context_layer<Tag: 'static>(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self.keymap_context_layers.remove(&TypeId::of::<Tag>());
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn set_input_enabled(&mut self, input_enabled: bool) {
|
||||
|
@ -5674,28 +5680,30 @@ impl Editor {
|
|||
}
|
||||
} else if !definitions.is_empty() {
|
||||
let replica_id = self.replica_id(cx);
|
||||
let title = definitions
|
||||
.iter()
|
||||
.find(|definition| definition.origin.is_some())
|
||||
.and_then(|definition| {
|
||||
definition.origin.as_ref().map(|origin| {
|
||||
let buffer = origin.buffer.read(cx);
|
||||
format!(
|
||||
"Definitions for {}",
|
||||
buffer
|
||||
.text_for_range(origin.range.clone())
|
||||
.collect::<String>()
|
||||
)
|
||||
cx.window_context().defer(move |cx| {
|
||||
let title = definitions
|
||||
.iter()
|
||||
.find(|definition| definition.origin.is_some())
|
||||
.and_then(|definition| {
|
||||
definition.origin.as_ref().map(|origin| {
|
||||
let buffer = origin.buffer.read(cx);
|
||||
format!(
|
||||
"Definitions for {}",
|
||||
buffer
|
||||
.text_for_range(origin.range.clone())
|
||||
.collect::<String>()
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
.unwrap_or("Definitions".to_owned());
|
||||
let locations = definitions
|
||||
.into_iter()
|
||||
.map(|definition| definition.target)
|
||||
.collect();
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
Self::open_locations_in_multibuffer(workspace, locations, replica_id, title, cx)
|
||||
})
|
||||
.unwrap_or("Definitions".to_owned());
|
||||
let locations = definitions
|
||||
.into_iter()
|
||||
.map(|definition| definition.target)
|
||||
.collect();
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
Self::open_locations_in_multibuffer(workspace, locations, replica_id, title, cx)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7157,28 +7165,26 @@ impl View for Editor {
|
|||
false
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
let mut context = Self::default_keymap_context();
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
let mode = match self.mode {
|
||||
EditorMode::SingleLine => "single_line",
|
||||
EditorMode::AutoHeight { .. } => "auto_height",
|
||||
EditorMode::Full => "full",
|
||||
};
|
||||
context.add_key("mode", mode);
|
||||
keymap.add_key("mode", mode);
|
||||
if self.pending_rename.is_some() {
|
||||
context.add_identifier("renaming");
|
||||
keymap.add_identifier("renaming");
|
||||
}
|
||||
match self.context_menu.as_ref() {
|
||||
Some(ContextMenu::Completions(_)) => context.add_identifier("showing_completions"),
|
||||
Some(ContextMenu::CodeActions(_)) => context.add_identifier("showing_code_actions"),
|
||||
Some(ContextMenu::Completions(_)) => keymap.add_identifier("showing_completions"),
|
||||
Some(ContextMenu::CodeActions(_)) => keymap.add_identifier("showing_code_actions"),
|
||||
None => {}
|
||||
}
|
||||
|
||||
for layer in self.keymap_context_layers.values() {
|
||||
context.extend(layer);
|
||||
keymap.extend(layer);
|
||||
}
|
||||
|
||||
context
|
||||
}
|
||||
|
||||
fn text_for_range(&self, range_utf16: Range<usize>, cx: &AppContext) -> Option<String> {
|
||||
|
|
|
@ -83,14 +83,15 @@ pub trait View: Entity + Sized {
|
|||
false
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> keymap_matcher::KeymapContext {
|
||||
Self::default_keymap_context()
|
||||
fn update_keymap_context(&self, keymap: &mut keymap_matcher::KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
}
|
||||
fn default_keymap_context() -> keymap_matcher::KeymapContext {
|
||||
let mut cx = keymap_matcher::KeymapContext::default();
|
||||
cx.add_identifier(Self::ui_name());
|
||||
cx
|
||||
|
||||
fn reset_to_default_keymap_context(keymap: &mut keymap_matcher::KeymapContext) {
|
||||
keymap.clear();
|
||||
keymap.add_identifier(Self::ui_name());
|
||||
}
|
||||
|
||||
fn debug_json(&self, _: &AppContext) -> serde_json::Value {
|
||||
serde_json::Value::Null
|
||||
}
|
||||
|
@ -440,6 +441,7 @@ type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> b
|
|||
pub struct AppContext {
|
||||
models: HashMap<usize, Box<dyn AnyModel>>,
|
||||
views: HashMap<(usize, usize), Box<dyn AnyView>>,
|
||||
views_metadata: HashMap<(usize, usize), ViewMetadata>,
|
||||
pub(crate) parents: HashMap<(usize, usize), ParentId>,
|
||||
windows: HashMap<usize, Window>,
|
||||
globals: HashMap<TypeId, Box<dyn Any>>,
|
||||
|
@ -502,6 +504,7 @@ impl AppContext {
|
|||
Self {
|
||||
models: Default::default(),
|
||||
views: Default::default(),
|
||||
views_metadata: Default::default(),
|
||||
parents: Default::default(),
|
||||
windows: Default::default(),
|
||||
globals: Default::default(),
|
||||
|
@ -727,9 +730,9 @@ impl AppContext {
|
|||
}
|
||||
|
||||
pub fn view_type_id(&self, window_id: usize, view_id: usize) -> Option<TypeId> {
|
||||
self.views
|
||||
self.views_metadata
|
||||
.get(&(window_id, view_id))
|
||||
.map(|view| view.as_any().type_id())
|
||||
.map(|metadata| metadata.type_id)
|
||||
}
|
||||
|
||||
pub fn active_labeled_tasks<'a>(
|
||||
|
@ -1045,9 +1048,10 @@ impl AppContext {
|
|||
.read_window(window_id, |cx| {
|
||||
if let Some(focused_view_id) = cx.focused_view_id() {
|
||||
for view_id in cx.ancestors(focused_view_id) {
|
||||
if let Some(view) = cx.views.get(&(window_id, view_id)) {
|
||||
let view_type = view.as_any().type_id();
|
||||
if let Some(actions) = cx.actions.get(&view_type) {
|
||||
if let Some(view_metadata) =
|
||||
cx.views_metadata.get(&(window_id, view_id))
|
||||
{
|
||||
if let Some(actions) = cx.actions.get(&view_metadata.type_id) {
|
||||
if actions.contains_key(&action_type) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1448,6 +1452,7 @@ impl AppContext {
|
|||
for (window_id, view_id) in dropped_views {
|
||||
self.subscriptions.remove(view_id);
|
||||
self.observations.remove(view_id);
|
||||
self.views_metadata.remove(&(window_id, view_id));
|
||||
let mut view = self.views.remove(&(window_id, view_id)).unwrap();
|
||||
view.release(self);
|
||||
let change_focus_to = self.windows.get_mut(&window_id).and_then(|window| {
|
||||
|
@ -1779,9 +1784,11 @@ impl AppContext {
|
|||
observed_window_id: usize,
|
||||
observed_view_id: usize,
|
||||
) {
|
||||
if self
|
||||
let view_key = (observed_window_id, observed_view_id);
|
||||
if let Some((view, mut view_metadata)) = self
|
||||
.views
|
||||
.contains_key(&(observed_window_id, observed_view_id))
|
||||
.remove(&view_key)
|
||||
.zip(self.views_metadata.remove(&view_key))
|
||||
{
|
||||
if let Some(window) = self.windows.get_mut(&observed_window_id) {
|
||||
window
|
||||
|
@ -1791,6 +1798,10 @@ impl AppContext {
|
|||
.insert(observed_view_id);
|
||||
}
|
||||
|
||||
view.update_keymap_context(&mut view_metadata.keymap_context, self);
|
||||
self.views.insert(view_key, view);
|
||||
self.views_metadata.insert(view_key, view_metadata);
|
||||
|
||||
let mut observations = self.observations.clone();
|
||||
observations.emit(observed_view_id, |callback| callback(self));
|
||||
}
|
||||
|
@ -2037,6 +2048,11 @@ pub enum ParentId {
|
|||
Root,
|
||||
}
|
||||
|
||||
struct ViewMetadata {
|
||||
type_id: TypeId,
|
||||
keymap_context: KeymapContext,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct WindowInvalidation {
|
||||
pub updated: HashSet<usize>,
|
||||
|
@ -2365,7 +2381,7 @@ pub trait AnyView {
|
|||
cx: &mut WindowContext,
|
||||
view_id: usize,
|
||||
) -> bool;
|
||||
fn keymap_context(&self, cx: &AppContext) -> KeymapContext;
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, cx: &AppContext);
|
||||
fn debug_json(&self, cx: &WindowContext) -> serde_json::Value;
|
||||
|
||||
fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String>;
|
||||
|
@ -2437,11 +2453,10 @@ where
|
|||
cx.handle().into_any()
|
||||
} else {
|
||||
let focused_type = cx
|
||||
.views
|
||||
.views_metadata
|
||||
.get(&(cx.window_id, focused_id))
|
||||
.unwrap()
|
||||
.as_any()
|
||||
.type_id();
|
||||
.type_id;
|
||||
AnyViewHandle::new(
|
||||
cx.window_id,
|
||||
focused_id,
|
||||
|
@ -2458,11 +2473,10 @@ where
|
|||
cx.handle().into_any()
|
||||
} else {
|
||||
let blurred_type = cx
|
||||
.views
|
||||
.views_metadata
|
||||
.get(&(cx.window_id, blurred_id))
|
||||
.unwrap()
|
||||
.as_any()
|
||||
.type_id();
|
||||
.type_id;
|
||||
AnyViewHandle::new(
|
||||
cx.window_id,
|
||||
blurred_id,
|
||||
|
@ -2493,8 +2507,8 @@ where
|
|||
View::modifiers_changed(self, event, &mut cx)
|
||||
}
|
||||
|
||||
fn keymap_context(&self, cx: &AppContext) -> KeymapContext {
|
||||
View::keymap_context(self, cx)
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, cx: &AppContext) {
|
||||
View::update_keymap_context(self, keymap, cx)
|
||||
}
|
||||
|
||||
fn debug_json(&self, cx: &WindowContext) -> serde_json::Value {
|
||||
|
@ -5559,8 +5573,8 @@ mod tests {
|
|||
"View"
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
self.keymap_context.clone()
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
*keymap = self.keymap_context.clone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5664,7 +5678,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[crate::test(self)]
|
||||
fn test_keystrokes_for_action(cx: &mut AppContext) {
|
||||
fn test_keystrokes_for_action(cx: &mut TestAppContext) {
|
||||
actions!(test, [Action1, Action2, GlobalAction]);
|
||||
|
||||
struct View1 {}
|
||||
|
@ -5694,70 +5708,76 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
let (window_id, view_1) = cx.add_window(Default::default(), |_| View1 {});
|
||||
let (_, view_1) = cx.add_window(|_| View1 {});
|
||||
let view_2 = cx.add_view(&view_1, |cx| {
|
||||
cx.focus_self();
|
||||
View2 {}
|
||||
});
|
||||
|
||||
cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
|
||||
cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
|
||||
cx.add_global_action(|_: &GlobalAction, _| {});
|
||||
cx.update(|cx| {
|
||||
cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
|
||||
cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
|
||||
cx.add_global_action(|_: &GlobalAction, _| {});
|
||||
|
||||
cx.add_bindings(vec![
|
||||
Binding::new("a", Action1, Some("View1")),
|
||||
Binding::new("b", Action2, Some("View1 > View2")),
|
||||
Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
|
||||
]);
|
||||
cx.add_bindings(vec![
|
||||
Binding::new("a", Action1, Some("View1")),
|
||||
Binding::new("b", Action2, Some("View1 > View2")),
|
||||
Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
|
||||
]);
|
||||
});
|
||||
|
||||
cx.update_window(window_id, |cx| {
|
||||
// Sanity check
|
||||
assert_eq!(
|
||||
cx.keystrokes_for_action(view_1.id(), &Action1)
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
&[Keystroke::parse("a").unwrap()]
|
||||
);
|
||||
assert_eq!(
|
||||
cx.keystrokes_for_action(view_2.id(), &Action2)
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
&[Keystroke::parse("b").unwrap()]
|
||||
);
|
||||
// Here we update the views to ensure that, even if they are on the stack,
|
||||
// we can still retrieve keystrokes correctly.
|
||||
view_1.update(cx, |_, cx| {
|
||||
view_2.update(cx, |_, cx| {
|
||||
// Sanity check
|
||||
assert_eq!(
|
||||
cx.keystrokes_for_action(view_1.id(), &Action1)
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
&[Keystroke::parse("a").unwrap()]
|
||||
);
|
||||
assert_eq!(
|
||||
cx.keystrokes_for_action(view_2.id(), &Action2)
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
&[Keystroke::parse("b").unwrap()]
|
||||
);
|
||||
|
||||
// The 'a' keystroke propagates up the view tree from view_2
|
||||
// to view_1. The action, Action1, is handled by view_1.
|
||||
assert_eq!(
|
||||
cx.keystrokes_for_action(view_2.id(), &Action1)
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
&[Keystroke::parse("a").unwrap()]
|
||||
);
|
||||
// The 'a' keystroke propagates up the view tree from view_2
|
||||
// to view_1. The action, Action1, is handled by view_1.
|
||||
assert_eq!(
|
||||
cx.keystrokes_for_action(view_2.id(), &Action1)
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
&[Keystroke::parse("a").unwrap()]
|
||||
);
|
||||
|
||||
// Actions that are handled below the current view don't have bindings
|
||||
assert_eq!(cx.keystrokes_for_action(view_1.id(), &Action2), None);
|
||||
// Actions that are handled below the current view don't have bindings
|
||||
assert_eq!(cx.keystrokes_for_action(view_1.id(), &Action2), None);
|
||||
|
||||
// Actions that are handled in other branches of the tree should not have a binding
|
||||
assert_eq!(cx.keystrokes_for_action(view_2.id(), &GlobalAction), None);
|
||||
// Actions that are handled in other branches of the tree should not have a binding
|
||||
assert_eq!(cx.keystrokes_for_action(view_2.id(), &GlobalAction), None);
|
||||
|
||||
// Check that global actions do not have a binding, even if a binding does exist in another view
|
||||
assert_eq!(
|
||||
&available_actions(view_1.id(), cx),
|
||||
&[
|
||||
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
||||
("test::GlobalAction", vec![])
|
||||
],
|
||||
);
|
||||
// Check that global actions do not have a binding, even if a binding does exist in another view
|
||||
assert_eq!(
|
||||
&available_actions(view_1.id(), cx),
|
||||
&[
|
||||
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
||||
("test::GlobalAction", vec![])
|
||||
],
|
||||
);
|
||||
|
||||
// Check that view 1 actions and bindings are available even when called from view 2
|
||||
assert_eq!(
|
||||
&available_actions(view_2.id(), cx),
|
||||
&[
|
||||
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
||||
("test::Action2", vec![Keystroke::parse("b").unwrap()]),
|
||||
("test::GlobalAction", vec![]),
|
||||
],
|
||||
);
|
||||
// Check that view 1 actions and bindings are available even when called from view 2
|
||||
assert_eq!(
|
||||
&available_actions(view_2.id(), cx),
|
||||
&[
|
||||
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
||||
("test::Action2", vec![Keystroke::parse("b").unwrap()]),
|
||||
("test::GlobalAction", vec![]),
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Produces a list of actions and key bindings
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
elements::AnyRootElement,
|
||||
geometry::rect::RectF,
|
||||
json::ToJson,
|
||||
keymap_matcher::{Binding, Keystroke, MatchResult},
|
||||
keymap_matcher::{Binding, KeymapContext, Keystroke, MatchResult},
|
||||
platform::{
|
||||
self, Appearance, CursorStyle, Event, KeyDownEvent, KeyUpEvent, ModifiersChangedEvent,
|
||||
MouseButton, MouseMovedEvent, PromptLevel, WindowBounds,
|
||||
|
@ -34,7 +34,7 @@ use std::{
|
|||
use util::ResultExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::Reference;
|
||||
use super::{Reference, ViewMetadata};
|
||||
|
||||
pub struct Window {
|
||||
pub(crate) root_view: Option<AnyViewHandle>,
|
||||
|
@ -369,13 +369,13 @@ impl<'a> WindowContext<'a> {
|
|||
let mut contexts = Vec::new();
|
||||
let mut handler_depth = None;
|
||||
for (i, view_id) in self.ancestors(view_id).enumerate() {
|
||||
if let Some(view) = self.views.get(&(window_id, view_id)) {
|
||||
if let Some(actions) = self.actions.get(&view.as_any().type_id()) {
|
||||
if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) {
|
||||
if let Some(actions) = self.actions.get(&view_metadata.type_id) {
|
||||
if actions.contains_key(&action.as_any().type_id()) {
|
||||
handler_depth = Some(i);
|
||||
}
|
||||
}
|
||||
contexts.push(view.keymap_context(self));
|
||||
contexts.push(view_metadata.keymap_context.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -406,10 +406,9 @@ impl<'a> WindowContext<'a> {
|
|||
let mut contexts = Vec::new();
|
||||
let mut handler_depths_by_action_type = HashMap::<TypeId, usize>::default();
|
||||
for (depth, view_id) in self.ancestors(view_id).enumerate() {
|
||||
if let Some(view) = self.views.get(&(window_id, view_id)) {
|
||||
contexts.push(view.keymap_context(self));
|
||||
let view_type = view.as_any().type_id();
|
||||
if let Some(actions) = self.actions.get(&view_type) {
|
||||
if let Some(view_metadata) = self.views_metadata.get(&(window_id, view_id)) {
|
||||
contexts.push(view_metadata.keymap_context.clone());
|
||||
if let Some(actions) = self.actions.get(&view_metadata.type_id) {
|
||||
handler_depths_by_action_type.extend(
|
||||
actions
|
||||
.keys()
|
||||
|
@ -458,9 +457,9 @@ impl<'a> WindowContext<'a> {
|
|||
let dispatch_path = self
|
||||
.ancestors(focused_view_id)
|
||||
.filter_map(|view_id| {
|
||||
self.views
|
||||
self.views_metadata
|
||||
.get(&(window_id, view_id))
|
||||
.map(|view| (view_id, view.keymap_context(self)))
|
||||
.map(|view| (view_id, view.keymap_context.clone()))
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -1177,6 +1176,15 @@ impl<'a> WindowContext<'a> {
|
|||
self.parents.insert((window_id, view_id), parent_id);
|
||||
let mut cx = ViewContext::mutable(self, view_id);
|
||||
let handle = if let Some(view) = build_view(&mut cx) {
|
||||
let mut keymap_context = KeymapContext::default();
|
||||
view.update_keymap_context(&mut keymap_context, cx.app_context());
|
||||
self.views_metadata.insert(
|
||||
(window_id, view_id),
|
||||
ViewMetadata {
|
||||
type_id: TypeId::of::<T>(),
|
||||
keymap_context,
|
||||
},
|
||||
);
|
||||
self.views.insert((window_id, view_id), Box::new(view));
|
||||
self.window
|
||||
.invalidation
|
||||
|
|
|
@ -17,6 +17,11 @@ impl KeymapContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.set.clear();
|
||||
self.map.clear();
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, other: &Self) {
|
||||
for v in &other.set {
|
||||
self.set.insert(v.clone());
|
||||
|
|
|
@ -699,31 +699,6 @@ impl platform::Window for Window {
|
|||
msg: &str,
|
||||
answers: &[&str],
|
||||
) -> oneshot::Receiver<usize> {
|
||||
// macOs applies overrides to modal window buttons after they are added.
|
||||
// Two most important for this logic are:
|
||||
// * Buttons with "Cancel" title will be displayed as the last buttons in the modal
|
||||
// * Last button added to the modal via `addButtonWithTitle` stays focused
|
||||
// * Focused buttons react on "space"/" " keypresses
|
||||
// * Usage of `keyEquivalent`, `makeFirstResponder` or `setInitialFirstResponder` does not change the focus
|
||||
//
|
||||
// See also https://developer.apple.com/documentation/appkit/nsalert/1524532-addbuttonwithtitle#discussion
|
||||
// ```
|
||||
// By default, the first button has a key equivalent of Return,
|
||||
// any button with a title of “Cancel” has a key equivalent of Escape,
|
||||
// and any button with the title “Don’t Save” has a key equivalent of Command-D (but only if it’s not the first button).
|
||||
// ```
|
||||
//
|
||||
// To avoid situations when the last element added is "Cancel" and it gets the focus
|
||||
// (hence stealing both ESC and Space shortcuts), we find and add one non-Cancel button
|
||||
// last, so it gets focus and a Space shortcut.
|
||||
// This way, "Save this file? Yes/No/Cancel"-ish modals will get all three buttons mapped with a key.
|
||||
let latest_non_cancel_label = answers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find(|(_, &label)| label != "Cancel")
|
||||
.filter(|&(label_index, _)| label_index > 0);
|
||||
|
||||
unsafe {
|
||||
let alert: id = msg_send![class!(NSAlert), alloc];
|
||||
let alert: id = msg_send![alert, init];
|
||||
|
@ -734,20 +709,10 @@ impl platform::Window for Window {
|
|||
};
|
||||
let _: () = msg_send![alert, setAlertStyle: alert_style];
|
||||
let _: () = msg_send![alert, setMessageText: ns_string(msg)];
|
||||
|
||||
for (ix, answer) in answers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(ix, _)| Some(ix) != latest_non_cancel_label.map(|(ix, _)| ix))
|
||||
{
|
||||
for (ix, answer) in answers.iter().enumerate() {
|
||||
let button: id = msg_send![alert, addButtonWithTitle: ns_string(answer)];
|
||||
let _: () = msg_send![button, setTag: ix as NSInteger];
|
||||
}
|
||||
if let Some((ix, answer)) = latest_non_cancel_label {
|
||||
let button: id = msg_send![alert, addButtonWithTitle: ns_string(answer)];
|
||||
let _: () = msg_send![button, setTag: ix as NSInteger];
|
||||
}
|
||||
|
||||
let (done_tx, done_rx) = oneshot::channel();
|
||||
let done_tx = Cell::new(Some(done_tx));
|
||||
let block = ConcreteBlock::new(move |answer: NSInteger| {
|
||||
|
@ -755,7 +720,7 @@ impl platform::Window for Window {
|
|||
let _ = postage::sink::Sink::try_send(&mut done_tx, answer.try_into().unwrap());
|
||||
}
|
||||
});
|
||||
|
||||
let block = block.copy();
|
||||
let native_window = self.0.borrow().native_window;
|
||||
self.0
|
||||
.borrow()
|
||||
|
|
|
@ -223,41 +223,41 @@ impl HandlerSet {
|
|||
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::move_disc(), None),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::hover_disc(), None),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
for button in MouseButton::all() {
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::drag_disc(), Some(button)),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::down_disc(), Some(button)),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::up_disc(), Some(button)),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::click_disc(), Some(button)),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::down_out_disc(), Some(button)),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::up_out_disc(), Some(button)),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
}
|
||||
set.insert(
|
||||
HandlerKey::new(MouseEvent::scroll_wheel_disc(), None),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| false)]),
|
||||
SmallVec::from_buf([Rc::new(|_, _, _, _| true)]),
|
||||
);
|
||||
|
||||
HandlerSet { set }
|
||||
|
|
|
@ -126,10 +126,9 @@ impl<D: PickerDelegate> View for Picker<D> {
|
|||
.into_any_named("picker")
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
let mut cx = Self::default_keymap_context();
|
||||
cx.add_identifier("menu");
|
||||
cx
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
keymap.add_identifier("menu");
|
||||
}
|
||||
|
||||
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
|
|
|
@ -1316,10 +1316,9 @@ impl View for ProjectPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
let mut cx = Self::default_keymap_context();
|
||||
cx.add_identifier("menu");
|
||||
cx
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
keymap.add_identifier("menu");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -446,11 +446,11 @@ impl View for TerminalView {
|
|||
});
|
||||
}
|
||||
|
||||
fn keymap_context(&self, cx: &gpui::AppContext) -> KeymapContext {
|
||||
let mut context = Self::default_keymap_context();
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, cx: &gpui::AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
|
||||
let mode = self.terminal.read(cx).last_content.mode;
|
||||
context.add_key(
|
||||
keymap.add_key(
|
||||
"screen",
|
||||
if mode.contains(TermMode::ALT_SCREEN) {
|
||||
"alt"
|
||||
|
@ -460,40 +460,40 @@ impl View for TerminalView {
|
|||
);
|
||||
|
||||
if mode.contains(TermMode::APP_CURSOR) {
|
||||
context.add_identifier("DECCKM");
|
||||
keymap.add_identifier("DECCKM");
|
||||
}
|
||||
if mode.contains(TermMode::APP_KEYPAD) {
|
||||
context.add_identifier("DECPAM");
|
||||
keymap.add_identifier("DECPAM");
|
||||
} else {
|
||||
context.add_identifier("DECPNM");
|
||||
keymap.add_identifier("DECPNM");
|
||||
}
|
||||
if mode.contains(TermMode::SHOW_CURSOR) {
|
||||
context.add_identifier("DECTCEM");
|
||||
keymap.add_identifier("DECTCEM");
|
||||
}
|
||||
if mode.contains(TermMode::LINE_WRAP) {
|
||||
context.add_identifier("DECAWM");
|
||||
keymap.add_identifier("DECAWM");
|
||||
}
|
||||
if mode.contains(TermMode::ORIGIN) {
|
||||
context.add_identifier("DECOM");
|
||||
keymap.add_identifier("DECOM");
|
||||
}
|
||||
if mode.contains(TermMode::INSERT) {
|
||||
context.add_identifier("IRM");
|
||||
keymap.add_identifier("IRM");
|
||||
}
|
||||
//LNM is apparently the name for this. https://vt100.net/docs/vt510-rm/LNM.html
|
||||
if mode.contains(TermMode::LINE_FEED_NEW_LINE) {
|
||||
context.add_identifier("LNM");
|
||||
keymap.add_identifier("LNM");
|
||||
}
|
||||
if mode.contains(TermMode::FOCUS_IN_OUT) {
|
||||
context.add_identifier("report_focus");
|
||||
keymap.add_identifier("report_focus");
|
||||
}
|
||||
if mode.contains(TermMode::ALTERNATE_SCROLL) {
|
||||
context.add_identifier("alternate_scroll");
|
||||
keymap.add_identifier("alternate_scroll");
|
||||
}
|
||||
if mode.contains(TermMode::BRACKETED_PASTE) {
|
||||
context.add_identifier("bracketed_paste");
|
||||
keymap.add_identifier("bracketed_paste");
|
||||
}
|
||||
if mode.intersects(TermMode::MOUSE_MODE) {
|
||||
context.add_identifier("any_mouse_reporting");
|
||||
keymap.add_identifier("any_mouse_reporting");
|
||||
}
|
||||
{
|
||||
let mouse_reporting = if mode.contains(TermMode::MOUSE_REPORT_CLICK) {
|
||||
|
@ -505,7 +505,7 @@ impl View for TerminalView {
|
|||
} else {
|
||||
"off"
|
||||
};
|
||||
context.add_key("mouse_reporting", mouse_reporting);
|
||||
keymap.add_key("mouse_reporting", mouse_reporting);
|
||||
}
|
||||
{
|
||||
let format = if mode.contains(TermMode::SGR_MOUSE) {
|
||||
|
@ -515,9 +515,8 @@ impl View for TerminalView {
|
|||
} else {
|
||||
"normal"
|
||||
};
|
||||
context.add_key("mouse_format", format);
|
||||
keymap.add_key("mouse_format", format);
|
||||
}
|
||||
context
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,14 +40,8 @@ pub trait HttpClient: Send + Sync {
|
|||
&'a self,
|
||||
uri: &str,
|
||||
body: AsyncBody,
|
||||
follow_redirects: bool,
|
||||
) -> BoxFuture<'a, Result<Response<AsyncBody>, Error>> {
|
||||
let request = isahc::Request::builder()
|
||||
.redirect_policy(if follow_redirects {
|
||||
RedirectPolicy::Follow
|
||||
} else {
|
||||
RedirectPolicy::None
|
||||
})
|
||||
.method(Method::POST)
|
||||
.uri(uri)
|
||||
.header("Content-Type", "application/json")
|
||||
|
|
|
@ -35,9 +35,7 @@ fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) {
|
|||
}
|
||||
}
|
||||
|
||||
cx.update_window(editor.window_id(), |cx| {
|
||||
editor.update(cx, |editor, cx| Vim::unhook_vim_settings(editor, cx))
|
||||
});
|
||||
editor.update(cx, |editor, cx| Vim::unhook_vim_settings(editor, cx))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -84,7 +84,12 @@ pub fn init(cx: &mut AppContext) {
|
|||
Vim::active_editor_input_ignored("\n".into(), cx)
|
||||
});
|
||||
|
||||
// Any time settings change, update vim mode to match.
|
||||
// Any time settings change, update vim mode to match. The Vim struct
|
||||
// will be initialized as disabled by default, so we filter its commands
|
||||
// out when starting up.
|
||||
cx.update_default_global::<CommandPaletteFilter, _, _>(|filter, _| {
|
||||
filter.filtered_namespaces.insert("vim");
|
||||
});
|
||||
cx.update_default_global(|vim: &mut Vim, cx: &mut AppContext| {
|
||||
vim.set_enabled(cx.global::<Settings>().vim_mode, cx)
|
||||
});
|
||||
|
@ -309,7 +314,7 @@ impl Vim {
|
|||
editor.set_input_enabled(!state.vim_controlled());
|
||||
editor.selections.line_mode = matches!(state.mode, Mode::Visual { line: true });
|
||||
let context_layer = state.keymap_context_layer();
|
||||
editor.set_keymap_context_layer::<Self>(context_layer);
|
||||
editor.set_keymap_context_layer::<Self>(context_layer, cx);
|
||||
} else {
|
||||
Self::unhook_vim_settings(editor, cx);
|
||||
}
|
||||
|
@ -321,7 +326,7 @@ impl Vim {
|
|||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.set_input_enabled(true);
|
||||
editor.selections.line_mode = false;
|
||||
editor.remove_keymap_context_layer::<Self>();
|
||||
editor.remove_keymap_context_layer::<Self>(cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1831,12 +1831,11 @@ impl View for Pane {
|
|||
});
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
let mut keymap = Self::default_keymap_context();
|
||||
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
|
||||
Self::reset_to_default_keymap_context(keymap);
|
||||
if self.docked.is_some() {
|
||||
keymap.add_identifier("docked");
|
||||
}
|
||||
keymap
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::StatusItemView;
|
||||
use crate::{StatusItemView, Workspace};
|
||||
use gpui::{
|
||||
elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle,
|
||||
AppContext, Entity, Subscription, View, ViewContext, ViewHandle, WindowContext,
|
||||
AppContext, Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
|
@ -84,6 +84,7 @@ struct Item {
|
|||
|
||||
pub struct SidebarButtons {
|
||||
sidebar: ViewHandle<Sidebar>,
|
||||
workspace: WeakViewHandle<Workspace>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
|
@ -210,9 +211,13 @@ impl View for Sidebar {
|
|||
}
|
||||
|
||||
impl SidebarButtons {
|
||||
pub fn new(sidebar: ViewHandle<Sidebar>, cx: &mut ViewContext<Self>) -> Self {
|
||||
pub fn new(
|
||||
sidebar: ViewHandle<Sidebar>,
|
||||
workspace: WeakViewHandle<Workspace>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
cx.observe(&sidebar, |_, _, cx| cx.notify()).detach();
|
||||
Self { sidebar }
|
||||
Self { sidebar, workspace }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,9 +284,18 @@ impl View for SidebarButtons {
|
|||
.with_style(style.container)
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||
this.sidebar
|
||||
.update(cx, |sidebar, cx| sidebar.toggle_item(ix, cx));
|
||||
.on_click(MouseButton::Left, {
|
||||
let action = action.clone();
|
||||
move |_, this, cx| {
|
||||
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||
let action = action.clone();
|
||||
cx.window_context().defer(move |cx| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_sidebar_item(&action, cx)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.with_tooltip::<Self>(
|
||||
ix,
|
||||
|
|
|
@ -37,7 +37,6 @@ use gpui::{
|
|||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
impl_actions,
|
||||
keymap_matcher::KeymapContext,
|
||||
platform::{
|
||||
CursorStyle, MouseButton, PathPromptOptions, Platform, PromptLevel, WindowBounds,
|
||||
WindowOptions,
|
||||
|
@ -584,10 +583,11 @@ impl Workspace {
|
|||
|
||||
let left_sidebar = cx.add_view(|_| Sidebar::new(SidebarSide::Left));
|
||||
let right_sidebar = cx.add_view(|_| Sidebar::new(SidebarSide::Right));
|
||||
let left_sidebar_buttons = cx.add_view(|cx| SidebarButtons::new(left_sidebar.clone(), cx));
|
||||
let left_sidebar_buttons =
|
||||
cx.add_view(|cx| SidebarButtons::new(left_sidebar.clone(), weak_handle.clone(), cx));
|
||||
let toggle_dock = cx.add_view(|cx| ToggleDockButton::new(handle, cx));
|
||||
let right_sidebar_buttons =
|
||||
cx.add_view(|cx| SidebarButtons::new(right_sidebar.clone(), cx));
|
||||
cx.add_view(|cx| SidebarButtons::new(right_sidebar.clone(), weak_handle.clone(), cx));
|
||||
let status_bar = cx.add_view(|cx| {
|
||||
let mut status_bar = StatusBar::new(¢er_pane.clone(), cx);
|
||||
status_bar.add_left_item(left_sidebar_buttons, cx);
|
||||
|
@ -2809,10 +2809,6 @@ impl View for Workspace {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
|
||||
Self::default_keymap_context()
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewId {
|
||||
|
|
|
@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
|
|||
description = "The fast, collaborative code editor."
|
||||
edition = "2021"
|
||||
name = "zed"
|
||||
version = "0.85.0"
|
||||
version = "0.85.4"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -1 +1 @@
|
|||
dev
|
||||
stable
|
Loading…
Add table
Add a link
Reference in a new issue