workspace: Add Close Multibuffers pane context menu entry (#39199)
Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -562,10 +562,6 @@ impl Item for AgentDiffPane {
|
||||
self.editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_nav_history(
|
||||
&mut self,
|
||||
nav_history: ItemNavHistory,
|
||||
|
||||
@@ -508,10 +508,6 @@ impl Item for ChannelView {
|
||||
}))
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _cx: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn navigate(
|
||||
&mut self,
|
||||
data: Box<dyn Any>,
|
||||
|
||||
@@ -354,10 +354,6 @@ impl Item for StackTraceView {
|
||||
self.editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_nav_history(
|
||||
&mut self,
|
||||
nav_history: ItemNavHistory,
|
||||
|
||||
@@ -730,10 +730,6 @@ impl Item for BufferDiagnosticsEditor {
|
||||
self.multibuffer.read(cx).is_dirty(cx)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _cx: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn navigate(
|
||||
&mut self,
|
||||
data: Box<dyn Any>,
|
||||
|
||||
@@ -716,10 +716,6 @@ impl Item for ProjectDiagnosticsEditor {
|
||||
self.editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_nav_history(
|
||||
&mut self,
|
||||
nav_history: ItemNavHistory,
|
||||
|
||||
@@ -201,7 +201,7 @@ use workspace::{
|
||||
CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal,
|
||||
RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast,
|
||||
ViewId, Workspace, WorkspaceId, WorkspaceSettings,
|
||||
item::{ItemHandle, PreviewTabsSettings, SaveOptions},
|
||||
item::{ItemBufferKind, ItemHandle, PreviewTabsSettings, SaveOptions},
|
||||
notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt},
|
||||
searchable::SearchEvent,
|
||||
};
|
||||
@@ -7286,7 +7286,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn supports_minimap(&self, cx: &App) -> bool {
|
||||
!self.minimap_visibility.disabled() && self.is_singleton(cx)
|
||||
!self.minimap_visibility.disabled() && self.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
}
|
||||
|
||||
fn edit_predictions_enabled_in_buffer(
|
||||
@@ -17952,7 +17952,7 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.is_singleton(cx) {
|
||||
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
@@ -18018,7 +18018,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn fold(&mut self, _: &actions::Fold, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.is_singleton(cx) {
|
||||
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
let mut to_fold = Vec::new();
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
@@ -18275,7 +18275,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn unfold_lines(&mut self, _: &UnfoldLines, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.is_singleton(cx) {
|
||||
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = &display_map.buffer_snapshot;
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
@@ -19056,7 +19056,7 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Entity<Self>> {
|
||||
(minimap_settings.minimap_enabled() && self.is_singleton(cx))
|
||||
(minimap_settings.minimap_enabled() && self.buffer_kind(cx) == ItemBufferKind::Singleton)
|
||||
.then(|| self.initialize_new_minimap(minimap_settings, window, cx))
|
||||
}
|
||||
|
||||
@@ -21834,7 +21834,7 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
if self.is_singleton(cx)
|
||||
if self.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& !self.mode.is_minimap()
|
||||
&& WorkspaceSettings::get(None, cx).restore_on_startup != RestoreOnStartupBehavior::None
|
||||
{
|
||||
|
||||
@@ -18798,8 +18798,9 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
let active_item = workspace
|
||||
.active_item(cx)
|
||||
.expect("should have an active item after adding the multi buffer");
|
||||
assert!(
|
||||
!active_item.is_singleton(cx),
|
||||
assert_eq!(
|
||||
active_item.buffer_kind(cx),
|
||||
ItemBufferKind::Multibuffer,
|
||||
"A multi buffer was expected to active after adding"
|
||||
);
|
||||
active_item.item_id()
|
||||
@@ -18827,8 +18828,9 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
first_item_id, multibuffer_item_id,
|
||||
"Should navigate into the 1st buffer and activate it"
|
||||
);
|
||||
assert!(
|
||||
active_item.is_singleton(cx),
|
||||
assert_eq!(
|
||||
active_item.buffer_kind(cx),
|
||||
ItemBufferKind::Singleton,
|
||||
"New active item should be a singleton buffer"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -18858,7 +18860,7 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
multibuffer_item_id,
|
||||
"Should navigate back to the multi buffer"
|
||||
);
|
||||
assert!(!active_item.is_singleton(cx));
|
||||
assert_eq!(active_item.buffer_kind(cx), ItemBufferKind::Multibuffer);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
@@ -18886,8 +18888,9 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
second_item_id, first_item_id,
|
||||
"Should navigate into the 2nd buffer and activate it"
|
||||
);
|
||||
assert!(
|
||||
active_item.is_singleton(cx),
|
||||
assert_eq!(
|
||||
active_item.buffer_kind(cx),
|
||||
ItemBufferKind::Singleton,
|
||||
"New active item should be a singleton buffer"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -18917,7 +18920,7 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
multibuffer_item_id,
|
||||
"Should navigate back from the 2nd buffer to the multi buffer"
|
||||
);
|
||||
assert!(!active_item.is_singleton(cx));
|
||||
assert_eq!(active_item.buffer_kind(cx), ItemBufferKind::Multibuffer);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
@@ -18943,8 +18946,9 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
);
|
||||
assert_ne!(third_item_id, first_item_id);
|
||||
assert_ne!(third_item_id, second_item_id);
|
||||
assert!(
|
||||
active_item.is_singleton(cx),
|
||||
assert_eq!(
|
||||
active_item.buffer_kind(cx),
|
||||
ItemBufferKind::Singleton,
|
||||
"New active item should be a singleton buffer"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -18972,7 +18976,7 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) {
|
||||
multibuffer_item_id,
|
||||
"Should navigate back from the 3rd buffer to the multi buffer"
|
||||
);
|
||||
assert!(!active_item.is_singleton(cx));
|
||||
assert_eq!(active_item.buffer_kind(cx), ItemBufferKind::Multibuffer);
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -96,7 +96,8 @@ use util::post_inc;
|
||||
use util::{RangeExt, ResultExt, debug_panic};
|
||||
use workspace::{
|
||||
CollaboratorId, ItemSettings, OpenInTerminal, OpenTerminal, RevealInProjectPanel, Workspace,
|
||||
item::Item, notifications::NotifyTaskExt,
|
||||
item::{Item, ItemBufferKind},
|
||||
notifications::NotifyTaskExt,
|
||||
};
|
||||
|
||||
/// Determines what kinds of highlights should be applied to a lines background.
|
||||
@@ -376,7 +377,7 @@ impl EditorElement {
|
||||
register_action(editor, window, Editor::move_to_enclosing_bracket);
|
||||
register_action(editor, window, Editor::undo_selection);
|
||||
register_action(editor, window, Editor::redo_selection);
|
||||
if !editor.read(cx).is_singleton(cx) {
|
||||
if editor.read(cx).buffer_kind(cx) == ItemBufferKind::Multibuffer {
|
||||
register_action(editor, window, Editor::expand_excerpts);
|
||||
register_action(editor, window, Editor::expand_excerpts_up);
|
||||
register_action(editor, window, Editor::expand_excerpts_down);
|
||||
@@ -1765,7 +1766,7 @@ impl EditorElement {
|
||||
let show_scrollbars = match scrollbar_settings.show {
|
||||
ShowScrollbar::Auto => {
|
||||
let editor = self.editor.read(cx);
|
||||
let is_singleton = editor.is_singleton(cx);
|
||||
let is_singleton = editor.buffer_kind(cx) == ItemBufferKind::Singleton;
|
||||
// Git
|
||||
(is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot.has_diff_hunks())
|
||||
||
|
||||
@@ -3281,7 +3282,7 @@ impl EditorElement {
|
||||
) -> Vec<Option<AnyElement>> {
|
||||
let include_fold_statuses = EditorSettings::get_global(cx).gutter.folds
|
||||
&& snapshot.mode.is_full()
|
||||
&& self.editor.read(cx).is_singleton(cx);
|
||||
&& self.editor.read(cx).buffer_kind(cx) == ItemBufferKind::Singleton;
|
||||
if include_fold_statuses {
|
||||
row_infos
|
||||
.iter()
|
||||
@@ -5810,7 +5811,7 @@ impl EditorElement {
|
||||
}
|
||||
|
||||
fn paint_line_numbers(&mut self, layout: &mut EditorLayout, window: &mut Window, cx: &mut App) {
|
||||
let is_singleton = self.editor.read(cx).is_singleton(cx);
|
||||
let is_singleton = self.editor.read(cx).buffer_kind(cx) == ItemBufferKind::Singleton;
|
||||
|
||||
let line_height = layout.position_map.line_height;
|
||||
window.set_cursor_style(CursorStyle::Arrow, &layout.gutter_hitbox);
|
||||
@@ -6622,7 +6623,7 @@ impl EditorElement {
|
||||
cx: &mut App,
|
||||
) {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
if !editor.is_singleton(cx)
|
||||
if editor.buffer_kind(cx) != ItemBufferKind::Singleton
|
||||
|| !editor
|
||||
.scrollbar_marker_state
|
||||
.should_refresh(scrollbar_layout.hitbox.size)
|
||||
@@ -8774,25 +8775,26 @@ impl Element for EditorElement {
|
||||
.map(|editor| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let all_selections = editor.selections.all::<Point>(cx);
|
||||
let selected_buffer_ids = if editor.is_singleton(cx) {
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut selected_buffer_ids =
|
||||
Vec::with_capacity(all_selections.len());
|
||||
let selected_buffer_ids =
|
||||
if editor.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut selected_buffer_ids =
|
||||
Vec::with_capacity(all_selections.len());
|
||||
|
||||
for selection in all_selections {
|
||||
for buffer_id in snapshot
|
||||
.buffer_snapshot
|
||||
.buffer_ids_for_range(selection.range())
|
||||
{
|
||||
if selected_buffer_ids.last() != Some(&buffer_id) {
|
||||
selected_buffer_ids.push(buffer_id);
|
||||
for selection in all_selections {
|
||||
for buffer_id in snapshot
|
||||
.buffer_snapshot
|
||||
.buffer_ids_for_range(selection.range())
|
||||
{
|
||||
if selected_buffer_ids.last() != Some(&buffer_id) {
|
||||
selected_buffer_ids.push(buffer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selected_buffer_ids
|
||||
};
|
||||
selected_buffer_ids
|
||||
};
|
||||
|
||||
let mut selections = editor
|
||||
.selections
|
||||
|
||||
@@ -43,7 +43,7 @@ use util::{ResultExt, TryFutureExt, paths::PathExt};
|
||||
use workspace::{
|
||||
CollaboratorId, ItemId, ItemNavHistory, ToolbarItemLocation, ViewId, Workspace, WorkspaceId,
|
||||
invalid_buffer_view::InvalidBufferView,
|
||||
item::{FollowableItem, Item, ItemEvent, ProjectItem, SaveOptions},
|
||||
item::{FollowableItem, Item, ItemBufferKind, ItemEvent, ProjectItem, SaveOptions},
|
||||
searchable::{
|
||||
Direction, FilteredSearchRange, SearchEvent, SearchableItem, SearchableItemHandle,
|
||||
},
|
||||
@@ -747,8 +747,11 @@ impl Item for Editor {
|
||||
.for_each_buffer(|buffer| f(buffer.entity_id(), buffer.read(cx)));
|
||||
}
|
||||
|
||||
fn is_singleton(&self, cx: &App) -> bool {
|
||||
self.buffer.read(cx).is_singleton()
|
||||
fn buffer_kind(&self, cx: &App) -> ItemBufferKind {
|
||||
match self.buffer.read(cx).is_singleton() {
|
||||
true => ItemBufferKind::Singleton,
|
||||
false => ItemBufferKind::Multibuffer,
|
||||
}
|
||||
}
|
||||
|
||||
fn can_save_as(&self, cx: &App) -> bool {
|
||||
|
||||
@@ -452,10 +452,6 @@ impl Item for CommitView {
|
||||
.update(cx, |editor, cx| editor.deactivated(window, cx));
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn act_as_type<'a>(
|
||||
&'a self,
|
||||
type_id: TypeId,
|
||||
|
||||
@@ -263,10 +263,6 @@ impl Item for FileDiffView {
|
||||
.update(cx, |editor, cx| editor.deactivated(window, cx));
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn act_as_type<'a>(
|
||||
&'a self,
|
||||
type_id: TypeId,
|
||||
|
||||
@@ -613,10 +613,6 @@ impl Item for ProjectDiff {
|
||||
self.editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_nav_history(
|
||||
&mut self,
|
||||
nav_history: ItemNavHistory,
|
||||
|
||||
@@ -324,10 +324,6 @@ impl Item for TextDiffView {
|
||||
.update(cx, |editor, cx| editor.deactivated(window, cx));
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn act_as_type<'a>(
|
||||
&'a self,
|
||||
type_id: TypeId,
|
||||
|
||||
@@ -98,10 +98,6 @@ impl Item for ImageView {
|
||||
f(self.image_item.entity_id(), self.image_item.read(cx))
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _cx: &App) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn tab_tooltip_text(&self, cx: &App) -> Option<SharedString> {
|
||||
let abs_path = self.image_item.read(cx).abs_path(cx)?;
|
||||
let file_path = abs_path.compact().to_string_lossy().into_owned();
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use gpui::{App, EntityId, EventEmitter, Subscription};
|
||||
use ui::{IconButtonShape, Tooltip, prelude::*};
|
||||
use workspace::item::{ItemEvent, ItemHandle};
|
||||
use workspace::item::{ItemBufferKind, ItemEvent, ItemHandle};
|
||||
use workspace::{ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
|
||||
|
||||
pub struct MultibufferHint {
|
||||
@@ -79,7 +79,7 @@ impl MultibufferHint {
|
||||
return ToolbarItemLocation::Hidden;
|
||||
};
|
||||
|
||||
if active_pane_item.is_singleton(cx)
|
||||
if active_pane_item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
|| active_pane_item.breadcrumbs(cx.theme(), cx).is_none()
|
||||
|| !active_pane_item.can_save(cx)
|
||||
{
|
||||
|
||||
@@ -724,10 +724,6 @@ impl Item for NotebookEditor {
|
||||
f(self.notebook_item.entity_id(), self.notebook_item.read(cx))
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _cx: &App) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn tab_content(&self, params: TabContentParams, window: &Window, cx: &App) -> AnyElement {
|
||||
Label::new(self.tab_content_text(params.detail.unwrap_or(0), cx))
|
||||
.single_line()
|
||||
|
||||
@@ -522,10 +522,6 @@ impl Item for ProjectSearchView {
|
||||
self.results_editor.for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn can_save(&self, _: &App) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
@@ -1257,10 +1257,6 @@ impl Item for TerminalView {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _cx: &App) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn as_searchable(&self, handle: &Entity<Self>) -> Option<Box<dyn SearchableItemHandle>> {
|
||||
Some(Box::new(handle.clone()))
|
||||
}
|
||||
|
||||
@@ -196,6 +196,13 @@ pub enum TabTooltipContent {
|
||||
Custom(Box<dyn Fn(&mut Window, &mut App) -> AnyView>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum ItemBufferKind {
|
||||
Multibuffer,
|
||||
Singleton,
|
||||
None,
|
||||
}
|
||||
|
||||
pub trait Item: Focusable + EventEmitter<Self::Event> + Render + Sized {
|
||||
type Event;
|
||||
|
||||
@@ -260,8 +267,8 @@ pub trait Item: Focusable + EventEmitter<Self::Event> + Render + Sized {
|
||||
_: &mut dyn FnMut(EntityId, &dyn project::ProjectItem),
|
||||
) {
|
||||
}
|
||||
fn is_singleton(&self, _cx: &App) -> bool {
|
||||
false
|
||||
fn buffer_kind(&self, _cx: &App) -> ItemBufferKind {
|
||||
ItemBufferKind::None
|
||||
}
|
||||
fn set_nav_history(&mut self, _: ItemNavHistory, _window: &mut Window, _: &mut Context<Self>) {}
|
||||
fn clone_on_split(
|
||||
@@ -467,7 +474,7 @@ pub trait ItemHandle: 'static + Send {
|
||||
_: &App,
|
||||
_: &mut dyn FnMut(EntityId, &dyn project::ProjectItem),
|
||||
);
|
||||
fn is_singleton(&self, cx: &App) -> bool;
|
||||
fn buffer_kind(&self, cx: &App) -> ItemBufferKind;
|
||||
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
@@ -616,7 +623,7 @@ impl<T: Item> ItemHandle for Entity<T> {
|
||||
fn project_path(&self, cx: &App) -> Option<ProjectPath> {
|
||||
let this = self.read(cx);
|
||||
let mut result = None;
|
||||
if this.is_singleton(cx) {
|
||||
if this.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
this.for_each_project_item(cx, &mut |_, item| {
|
||||
result = item.project_path(cx);
|
||||
});
|
||||
@@ -674,8 +681,8 @@ impl<T: Item> ItemHandle for Entity<T> {
|
||||
self.read(cx).for_each_project_item(cx, f)
|
||||
}
|
||||
|
||||
fn is_singleton(&self, cx: &App) -> bool {
|
||||
self.read(cx).is_singleton(cx)
|
||||
fn buffer_kind(&self, cx: &App) -> ItemBufferKind {
|
||||
self.read(cx).buffer_kind(cx)
|
||||
}
|
||||
|
||||
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
||||
@@ -1292,7 +1299,10 @@ impl<T: FollowableItem> WeakFollowableItemHandle for WeakEntity<T> {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub mod test {
|
||||
use super::{Item, ItemEvent, SerializableItem, TabContentParams};
|
||||
use crate::{ItemId, ItemNavHistory, Workspace, WorkspaceId, item::SaveOptions};
|
||||
use crate::{
|
||||
ItemId, ItemNavHistory, Workspace, WorkspaceId,
|
||||
item::{ItemBufferKind, SaveOptions},
|
||||
};
|
||||
use gpui::{
|
||||
AnyElement, App, AppContext as _, Context, Entity, EntityId, EventEmitter, Focusable,
|
||||
InteractiveElement, IntoElement, Render, SharedString, Task, WeakEntity, Window,
|
||||
@@ -1315,7 +1325,7 @@ pub mod test {
|
||||
pub save_as_count: usize,
|
||||
pub reload_count: usize,
|
||||
pub is_dirty: bool,
|
||||
pub is_singleton: bool,
|
||||
pub buffer_kind: ItemBufferKind,
|
||||
pub has_conflict: bool,
|
||||
pub has_deleted_file: bool,
|
||||
pub project_items: Vec<Entity<TestProjectItem>>,
|
||||
@@ -1399,7 +1409,7 @@ pub mod test {
|
||||
has_conflict: false,
|
||||
has_deleted_file: false,
|
||||
project_items: Vec::new(),
|
||||
is_singleton: true,
|
||||
buffer_kind: ItemBufferKind::Singleton,
|
||||
nav_history: None,
|
||||
tab_descriptions: None,
|
||||
tab_detail: Default::default(),
|
||||
@@ -1420,8 +1430,8 @@ pub mod test {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_singleton(mut self, singleton: bool) -> Self {
|
||||
self.is_singleton = singleton;
|
||||
pub fn with_buffer_kind(mut self, buffer_kind: ItemBufferKind) -> Self {
|
||||
self.buffer_kind = buffer_kind;
|
||||
self
|
||||
}
|
||||
|
||||
@@ -1516,8 +1526,8 @@ pub mod test {
|
||||
.for_each(|item| f(item.entity_id(), item.read(cx)))
|
||||
}
|
||||
|
||||
fn is_singleton(&self, _: &App) -> bool {
|
||||
self.is_singleton
|
||||
fn buffer_kind(&self, _: &App) -> ItemBufferKind {
|
||||
self.buffer_kind
|
||||
}
|
||||
|
||||
fn set_nav_history(
|
||||
@@ -1564,7 +1574,7 @@ pub mod test {
|
||||
save_as_count: self.save_as_count,
|
||||
reload_count: self.reload_count,
|
||||
is_dirty: self.is_dirty,
|
||||
is_singleton: self.is_singleton,
|
||||
buffer_kind: self.buffer_kind,
|
||||
has_conflict: self.has_conflict,
|
||||
has_deleted_file: self.has_deleted_file,
|
||||
project_items: self.project_items.clone(),
|
||||
@@ -1598,7 +1608,7 @@ pub mod test {
|
||||
}
|
||||
|
||||
fn can_save_as(&self, _cx: &App) -> bool {
|
||||
self.is_singleton
|
||||
self.buffer_kind == ItemBufferKind::Singleton
|
||||
}
|
||||
|
||||
fn save(
|
||||
|
||||
+234
-21
@@ -4,9 +4,9 @@ use crate::{
|
||||
WorkspaceItemBuilder,
|
||||
invalid_buffer_view::InvalidBufferView,
|
||||
item::{
|
||||
ActivateOnClose, ClosePosition, Item, ItemHandle, ItemSettings, PreviewTabsSettings,
|
||||
ProjectItemKind, SaveOptions, ShowCloseButton, ShowDiagnostics, TabContentParams,
|
||||
TabTooltipContent, WeakItemHandle,
|
||||
ActivateOnClose, ClosePosition, Item, ItemBufferKind, ItemHandle, ItemSettings,
|
||||
PreviewTabsSettings, ProjectItemKind, SaveOptions, ShowCloseButton, ShowDiagnostics,
|
||||
TabContentParams, TabTooltipContent, WeakItemHandle,
|
||||
},
|
||||
move_item,
|
||||
notifications::NotifyResultExt,
|
||||
@@ -125,6 +125,17 @@ pub struct CloseOtherItems {
|
||||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
/// Closes all multibuffers in the pane.
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||
#[action(namespace = pane)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct CloseMultibufferItems {
|
||||
#[serde(default)]
|
||||
pub save_intent: Option<SaveIntent>,
|
||||
#[serde(default)]
|
||||
pub close_pinned: bool,
|
||||
}
|
||||
|
||||
/// Closes all items in the pane.
|
||||
#[derive(Clone, PartialEq, Debug, Deserialize, JsonSchema, Default, Action)]
|
||||
#[action(namespace = pane)]
|
||||
@@ -900,7 +911,7 @@ impl Pane {
|
||||
let mut existing_item = None;
|
||||
if let Some(project_entry_id) = project_entry_id {
|
||||
for (index, item) in self.items.iter().enumerate() {
|
||||
if item.is_singleton(cx)
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& item.project_entry_ids(cx).as_slice() == [project_entry_id]
|
||||
{
|
||||
let item = item.boxed_clone();
|
||||
@@ -910,7 +921,9 @@ impl Pane {
|
||||
}
|
||||
} else {
|
||||
for (index, item) in self.items.iter().enumerate() {
|
||||
if item.is_singleton(cx) && item.project_path(cx).as_ref() == Some(&project_path) {
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& item.project_path(cx).as_ref() == Some(&project_path)
|
||||
{
|
||||
let item = item.boxed_clone();
|
||||
existing_item = Some((index, item));
|
||||
break;
|
||||
@@ -1046,7 +1059,7 @@ impl Pane {
|
||||
self.close_items_on_item_open(window, cx);
|
||||
}
|
||||
|
||||
if item.is_singleton(cx)
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& let Some(&entry_id) = item.project_entry_ids(cx).first()
|
||||
{
|
||||
let Some(project) = self.project.upgrade() else {
|
||||
@@ -1077,7 +1090,7 @@ impl Pane {
|
||||
};
|
||||
|
||||
// Does the item already exist?
|
||||
let project_entry_id = if item.is_singleton(cx) {
|
||||
let project_entry_id = if item.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
item.project_entry_ids(cx).first().copied()
|
||||
} else {
|
||||
None
|
||||
@@ -1086,7 +1099,7 @@ impl Pane {
|
||||
let existing_item_index = self.items.iter().position(|existing_item| {
|
||||
if existing_item.item_id() == item.item_id() {
|
||||
true
|
||||
} else if existing_item.is_singleton(cx) {
|
||||
} else if existing_item.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
existing_item
|
||||
.project_entry_ids(cx)
|
||||
.first()
|
||||
@@ -1202,7 +1215,9 @@ impl Pane {
|
||||
cx: &App,
|
||||
) -> Option<Box<dyn ItemHandle>> {
|
||||
self.items.iter().find_map(|item| {
|
||||
if item.is_singleton(cx) && (item.project_entry_ids(cx).as_slice() == [entry_id]) {
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& (item.project_entry_ids(cx).as_slice() == [entry_id])
|
||||
{
|
||||
Some(item.boxed_clone())
|
||||
} else {
|
||||
None
|
||||
@@ -1216,7 +1231,8 @@ impl Pane {
|
||||
cx: &App,
|
||||
) -> Option<Box<dyn ItemHandle>> {
|
||||
self.items.iter().find_map(move |item| {
|
||||
if item.is_singleton(cx) && (item.project_path(cx).as_slice() == [project_path.clone()])
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& (item.project_path(cx).as_slice() == [project_path.clone()])
|
||||
{
|
||||
Some(item.boxed_clone())
|
||||
} else {
|
||||
@@ -1475,6 +1491,30 @@ impl Pane {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn close_multibuffer_items(
|
||||
&mut self,
|
||||
action: &CloseMultibufferItems,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
if self.items.is_empty() {
|
||||
return Task::ready(Ok(()));
|
||||
}
|
||||
|
||||
let pinned_item_ids = self.pinned_item_ids();
|
||||
let multibuffer_items = self.multibuffer_item_ids(cx);
|
||||
|
||||
self.close_items(
|
||||
window,
|
||||
cx,
|
||||
action.save_intent.unwrap_or(SaveIntent::Close),
|
||||
move |item_id| {
|
||||
(action.close_pinned || !pinned_item_ids.contains(&item_id))
|
||||
&& multibuffer_items.contains(&item_id)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn close_clean_items(
|
||||
&mut self,
|
||||
action: &CloseCleanItems,
|
||||
@@ -1637,14 +1677,14 @@ impl Pane {
|
||||
}
|
||||
});
|
||||
if dirty_project_item_ids.is_empty() {
|
||||
return !(item.is_singleton(cx) && item.is_dirty(cx));
|
||||
return !(item.buffer_kind(cx) == ItemBufferKind::Singleton && item.is_dirty(cx));
|
||||
}
|
||||
|
||||
for open_item in workspace.items(cx) {
|
||||
if open_item.item_id() == item.item_id() {
|
||||
continue;
|
||||
}
|
||||
if !open_item.is_singleton(cx) {
|
||||
if open_item.buffer_kind(cx) != ItemBufferKind::Singleton {
|
||||
continue;
|
||||
}
|
||||
let other_project_item_ids = open_item.project_item_model_ids(cx);
|
||||
@@ -1999,7 +2039,7 @@ impl Pane {
|
||||
item.is_dirty(cx),
|
||||
item.can_save(cx),
|
||||
item.can_save_as(cx),
|
||||
item.is_singleton(cx),
|
||||
item.buffer_kind(cx) == ItemBufferKind::Singleton,
|
||||
item.has_deleted_file(cx),
|
||||
)
|
||||
})?;
|
||||
@@ -2281,7 +2321,9 @@ impl Pane {
|
||||
cx: &mut Context<Pane>,
|
||||
) -> Option<()> {
|
||||
let item_id = self.items().find_map(|item| {
|
||||
if item.is_singleton(cx) && item.project_entry_ids(cx).as_slice() == [entry_id] {
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& item.project_entry_ids(cx).as_slice() == [entry_id]
|
||||
{
|
||||
Some(item.item_id())
|
||||
} else {
|
||||
None
|
||||
@@ -2701,12 +2743,15 @@ impl Pane {
|
||||
.child(label),
|
||||
);
|
||||
|
||||
let single_entry_to_resolve = self.items[ix]
|
||||
.is_singleton(cx)
|
||||
let single_entry_to_resolve = (self.items[ix].buffer_kind(cx) == ItemBufferKind::Singleton)
|
||||
.then(|| self.items[ix].project_entry_ids(cx).get(0).copied())
|
||||
.flatten();
|
||||
|
||||
let total_items = self.items.len();
|
||||
let has_multibuffer_items = self
|
||||
.items
|
||||
.iter()
|
||||
.any(|item| item.buffer_kind(cx) == ItemBufferKind::Multibuffer);
|
||||
let has_items_to_left = ix > 0;
|
||||
let has_items_to_right = ix < total_items - 1;
|
||||
let has_clean_items = self.items.iter().any(|item| !item.is_dirty(cx));
|
||||
@@ -2727,6 +2772,10 @@ impl Pane {
|
||||
save_intent: None,
|
||||
close_pinned: false,
|
||||
};
|
||||
let close_multibuffers_action = CloseMultibufferItems {
|
||||
save_intent: None,
|
||||
close_pinned: false,
|
||||
};
|
||||
let close_items_to_the_left_action = CloseItemsToTheLeft {
|
||||
close_pinned: false,
|
||||
};
|
||||
@@ -2764,6 +2813,24 @@ impl Pane {
|
||||
.detach_and_log_err(cx);
|
||||
})),
|
||||
))
|
||||
// We make this optional, instead of using disabled as to not overwhelm the context menu unnecessarily
|
||||
.extend(has_multibuffer_items.then(|| {
|
||||
ContextMenuItem::Entry(
|
||||
ContextMenuEntry::new("Close Multibuffers")
|
||||
.action(Box::new(close_multibuffers_action.clone()))
|
||||
.handler(window.handler_for(
|
||||
&pane,
|
||||
move |pane, window, cx| {
|
||||
pane.close_multibuffer_items(
|
||||
&close_multibuffers_action,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.detach_and_log_err(cx);
|
||||
},
|
||||
)),
|
||||
)
|
||||
}))
|
||||
.separator()
|
||||
.item(ContextMenuItem::Entry(
|
||||
ContextMenuEntry::new("Close Left")
|
||||
@@ -3485,6 +3552,13 @@ impl Pane {
|
||||
}
|
||||
}
|
||||
|
||||
fn multibuffer_item_ids(&self, cx: &mut Context<Pane>) -> Vec<EntityId> {
|
||||
self.items()
|
||||
.filter(|item| item.buffer_kind(cx) == ItemBufferKind::Multibuffer)
|
||||
.map(|item| item.item_id())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn drag_split_direction(&self) -> Option<SplitDirection> {
|
||||
self.drag_split_direction
|
||||
}
|
||||
@@ -3706,6 +3780,12 @@ impl Render for Pane {
|
||||
.detach_and_log_err(cx)
|
||||
}),
|
||||
)
|
||||
.on_action(cx.listener(
|
||||
|pane: &mut Self, action: &CloseMultibufferItems, window, cx| {
|
||||
pane.close_multibuffer_items(action, window, cx)
|
||||
.detach_and_log_err(cx)
|
||||
},
|
||||
))
|
||||
.on_action(
|
||||
cx.listener(|pane: &mut Self, action: &RevealInProjectPanel, _, cx| {
|
||||
let entry_id = action
|
||||
@@ -5655,7 +5735,7 @@ mod tests {
|
||||
pane.add_item(
|
||||
Box::new(cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_singleton(true)
|
||||
.with_buffer_kind(ItemBufferKind::Singleton)
|
||||
.with_label("buffer 1")
|
||||
.with_project_items(&[TestProjectItem::new(1, "one.txt", cx)])
|
||||
})),
|
||||
@@ -5673,7 +5753,7 @@ mod tests {
|
||||
pane.add_item(
|
||||
Box::new(cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_singleton(true)
|
||||
.with_buffer_kind(ItemBufferKind::Singleton)
|
||||
.with_label("buffer 1")
|
||||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
|
||||
})),
|
||||
@@ -5691,7 +5771,7 @@ mod tests {
|
||||
pane.add_item(
|
||||
Box::new(cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_singleton(true)
|
||||
.with_buffer_kind(ItemBufferKind::Singleton)
|
||||
.with_label("buffer 2")
|
||||
.with_project_items(&[TestProjectItem::new(2, "2.txt", cx)])
|
||||
})),
|
||||
@@ -5709,7 +5789,7 @@ mod tests {
|
||||
pane.add_item(
|
||||
Box::new(cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_label("multibuffer 1")
|
||||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
|
||||
})),
|
||||
@@ -5727,7 +5807,7 @@ mod tests {
|
||||
pane.add_item(
|
||||
Box::new(cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_label("multibuffer 1b")
|
||||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
|
||||
})),
|
||||
@@ -6281,6 +6361,139 @@ mod tests {
|
||||
assert_item_labels(&pane, [], cx);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_close_multibuffer_items(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||
|
||||
let add_labeled_item = |pane: &Entity<Pane>,
|
||||
label,
|
||||
is_dirty,
|
||||
kind: ItemBufferKind,
|
||||
cx: &mut VisualTestContext| {
|
||||
pane.update_in(cx, |pane, window, cx| {
|
||||
let labeled_item = Box::new(cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_label(label)
|
||||
.with_dirty(is_dirty)
|
||||
.with_buffer_kind(kind)
|
||||
}));
|
||||
pane.add_item(labeled_item.clone(), false, false, None, window, cx);
|
||||
labeled_item
|
||||
})
|
||||
};
|
||||
|
||||
let item_a = add_labeled_item(&pane, "A", false, ItemBufferKind::Multibuffer, cx);
|
||||
add_labeled_item(&pane, "B", false, ItemBufferKind::Multibuffer, cx);
|
||||
add_labeled_item(&pane, "C", false, ItemBufferKind::Singleton, cx);
|
||||
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
||||
|
||||
pane.update_in(cx, |pane, window, cx| {
|
||||
let ix = pane.index_for_item_id(item_a.item_id()).unwrap();
|
||||
pane.pin_tab_at(ix, window, cx);
|
||||
pane.close_multibuffer_items(
|
||||
&CloseMultibufferItems {
|
||||
save_intent: None,
|
||||
close_pinned: false,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_item_labels(&pane, ["A!", "C*"], cx);
|
||||
|
||||
pane.update_in(cx, |pane, window, cx| {
|
||||
let ix = pane.index_for_item_id(item_a.item_id()).unwrap();
|
||||
pane.unpin_tab_at(ix, window, cx);
|
||||
pane.close_multibuffer_items(
|
||||
&CloseMultibufferItems {
|
||||
save_intent: None,
|
||||
close_pinned: false,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_item_labels(&pane, ["C*"], cx);
|
||||
|
||||
add_labeled_item(&pane, "A", true, ItemBufferKind::Singleton, cx).update(cx, |item, cx| {
|
||||
item.project_items
|
||||
.push(TestProjectItem::new_dirty(1, "A.txt", cx))
|
||||
});
|
||||
add_labeled_item(&pane, "B", true, ItemBufferKind::Multibuffer, cx).update(
|
||||
cx,
|
||||
|item, cx| {
|
||||
item.project_items
|
||||
.push(TestProjectItem::new_dirty(2, "B.txt", cx))
|
||||
},
|
||||
);
|
||||
add_labeled_item(&pane, "D", true, ItemBufferKind::Multibuffer, cx).update(
|
||||
cx,
|
||||
|item, cx| {
|
||||
item.project_items
|
||||
.push(TestProjectItem::new_dirty(3, "D.txt", cx))
|
||||
},
|
||||
);
|
||||
assert_item_labels(&pane, ["C", "A^", "B^", "D*^"], cx);
|
||||
|
||||
let save = pane.update_in(cx, |pane, window, cx| {
|
||||
pane.close_multibuffer_items(
|
||||
&CloseMultibufferItems {
|
||||
save_intent: None,
|
||||
close_pinned: false,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
cx.executor().run_until_parked();
|
||||
cx.simulate_prompt_answer("Save all");
|
||||
save.await.unwrap();
|
||||
assert_item_labels(&pane, ["C", "A*^"], cx);
|
||||
|
||||
add_labeled_item(&pane, "B", true, ItemBufferKind::Multibuffer, cx).update(
|
||||
cx,
|
||||
|item, cx| {
|
||||
item.project_items
|
||||
.push(TestProjectItem::new_dirty(2, "B.txt", cx))
|
||||
},
|
||||
);
|
||||
add_labeled_item(&pane, "D", true, ItemBufferKind::Multibuffer, cx).update(
|
||||
cx,
|
||||
|item, cx| {
|
||||
item.project_items
|
||||
.push(TestProjectItem::new_dirty(3, "D.txt", cx))
|
||||
},
|
||||
);
|
||||
assert_item_labels(&pane, ["C", "A^", "B^", "D*^"], cx);
|
||||
let save = pane.update_in(cx, |pane, window, cx| {
|
||||
pane.close_multibuffer_items(
|
||||
&CloseMultibufferItems {
|
||||
save_intent: None,
|
||||
close_pinned: false,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
cx.executor().run_until_parked();
|
||||
cx.simulate_prompt_answer("Discard all");
|
||||
save.await.unwrap();
|
||||
assert_item_labels(&pane, ["C", "A*^"], cx);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_close_with_save_intent(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
@@ -60,7 +60,10 @@ use notifications::{
|
||||
simple_message_notification::MessageNotification,
|
||||
};
|
||||
pub use pane::*;
|
||||
pub use pane_group::*;
|
||||
pub use pane_group::{
|
||||
ActivePaneDecorator, HANDLE_HITBOX_SIZE, Member, PaneAxis, PaneGroup, PaneRenderContext,
|
||||
SplitDirection,
|
||||
};
|
||||
use persistence::{DB, SerializedWindowBounds, model::SerializedWorkspace};
|
||||
pub use persistence::{
|
||||
DB as WORKSPACE_DB, WorkspaceDb, delete_unloaded_items,
|
||||
@@ -117,11 +120,11 @@ pub use workspace_settings::{
|
||||
};
|
||||
use zed_actions::{Spawn, feedback::FileBugReport};
|
||||
|
||||
use crate::notifications::NotificationId;
|
||||
use crate::persistence::{
|
||||
SerializedAxis,
|
||||
model::{DockData, DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup},
|
||||
};
|
||||
use crate::{item::ItemBufferKind, notifications::NotificationId};
|
||||
|
||||
pub const SERIALIZATION_THROTTLE_TIME: Duration = Duration::from_millis(200);
|
||||
|
||||
@@ -2521,8 +2524,12 @@ impl Workspace {
|
||||
};
|
||||
|
||||
for (pane, item) in dirty_items {
|
||||
let (singleton, project_entry_ids) =
|
||||
cx.update(|_, cx| (item.is_singleton(cx), item.project_entry_ids(cx)))?;
|
||||
let (singleton, project_entry_ids) = cx.update(|_, cx| {
|
||||
(
|
||||
item.buffer_kind(cx) == ItemBufferKind::Singleton,
|
||||
item.project_entry_ids(cx),
|
||||
)
|
||||
})?;
|
||||
if (singleton || !project_entry_ids.is_empty())
|
||||
&& !Pane::save_item(project.clone(), &pane, &*item, save_intent, cx).await?
|
||||
{
|
||||
@@ -4805,7 +4812,7 @@ impl Workspace {
|
||||
.items()
|
||||
.find_map(|item| {
|
||||
let item = item.to_followable_item_handle(cx)?;
|
||||
if item.is_singleton(cx)
|
||||
if item.buffer_kind(cx) == ItemBufferKind::Singleton
|
||||
&& item.project_item_model_ids(cx).as_slice()
|
||||
== [buffer_entity_id]
|
||||
{
|
||||
@@ -8192,7 +8199,7 @@ mod tests {
|
||||
use crate::{
|
||||
dock::{PanelEvent, test::TestPanel},
|
||||
item::{
|
||||
ItemEvent,
|
||||
ItemBufferKind, ItemEvent,
|
||||
test::{TestItem, TestProjectItem},
|
||||
},
|
||||
};
|
||||
@@ -8553,7 +8560,7 @@ mod tests {
|
||||
let item_2_3 = cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_project_items(&[
|
||||
single_entry_items[2].read(cx).project_items[0].clone(),
|
||||
single_entry_items[3].read(cx).project_items[0].clone(),
|
||||
@@ -8562,7 +8569,7 @@ mod tests {
|
||||
let item_3_4 = cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_project_items(&[
|
||||
single_entry_items[3].read(cx).project_items[0].clone(),
|
||||
single_entry_items[4].read(cx).project_items[0].clone(),
|
||||
@@ -9583,7 +9590,7 @@ mod tests {
|
||||
let dirty_multi_buffer_with_both = cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_label("Fake Project Search")
|
||||
.with_project_items(&[
|
||||
dirty_regular_buffer.read(cx).project_items[0].clone(),
|
||||
@@ -9734,7 +9741,7 @@ mod tests {
|
||||
let dirty_multi_buffer_with_both = cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_label("Fake Project Search")
|
||||
.with_project_items(&[
|
||||
dirty_regular_buffer.read(cx).project_items[0].clone(),
|
||||
@@ -10148,7 +10155,7 @@ mod tests {
|
||||
let dirty_multi_buffer = cx.new(|cx| {
|
||||
TestItem::new(cx)
|
||||
.with_dirty(true)
|
||||
.with_singleton(false)
|
||||
.with_buffer_kind(ItemBufferKind::Multibuffer)
|
||||
.with_label("Fake Project Search")
|
||||
.with_project_items(&[
|
||||
dirty_regular_buffer.read(cx).project_items[0].clone(),
|
||||
|
||||
@@ -23,6 +23,7 @@ use ui::{
|
||||
IconName, IconSize, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*,
|
||||
};
|
||||
use vim_mode_setting::VimModeSetting;
|
||||
use workspace::item::ItemBufferKind;
|
||||
use workspace::{
|
||||
ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, item::ItemHandle,
|
||||
};
|
||||
@@ -131,7 +132,7 @@ impl Render for QuickActionBar {
|
||||
let code_action_enabled = editor_value.code_actions_enabled_for_toolbar(cx);
|
||||
let focus_handle = editor_value.focus_handle(cx);
|
||||
|
||||
let search_button = editor.is_singleton(cx).then(|| {
|
||||
let search_button = (editor.buffer_kind(cx) == ItemBufferKind::Singleton).then(|| {
|
||||
QuickActionBarButton::new(
|
||||
"toggle buffer search",
|
||||
search::SEARCH_ICON,
|
||||
|
||||
Reference in New Issue
Block a user