Closes #35803 This PR adds tree view support to the git panel UI as an additional setting and moves git entry checkboxes to the right. Tree view only supports sorting by paths behavior since sorting by status can become noisy, due to having to duplicate directories that have entries with different statuses. ### Tree vs Flat View <img width="358" height="250" alt="image" src="https://github.com/user-attachments/assets/c6b95d57-12fc-4c5e-8537-ee129963e50c" /> <img width="362" height="152" alt="image" src="https://github.com/user-attachments/assets/0a69e00f-3878-4807-ae45-65e2d54174fc" /> #### Architecture changes Before this PR, `GitPanel::entries` represented all entries and all visible entries because both sets were equal to one another. However, this equality isn't true for tree view, because entries can be collapsed. To fix this, `TreeState` was added as a logical indices field that is used to filter out non-visible entries. A benefit of this field is that it could be used in the future to implement searching in the GitPanel. Another significant thing this PR changed was adding a HashMap field `entries_by_indices` on `GitPanel`. We did this because `entry_by_path` used binary search, which becomes overly complicated to implement for tree view. The performance of this function matters because it's a hot code path, so a linear search wasn't ideal either. The solution was using a hash map to improve time complexity from O(log n) to O(1), where n is the count of entries. #### Follow-ups In the future, we could use `ui::ListItem` to render entries in the tree view to improve UI consistency. Release Notes: - Added tree view for Git panel. Users are able to switch between Flat and Tree view in Git panel. --------- Co-authored-by: Anthony Eid <anthony@zed.dev> Co-authored-by: Remco Smits <djsmits12@gmail.com>
64 lines
2.3 KiB
Rust
64 lines
2.3 KiB
Rust
use editor::EditorSettings;
|
|
use gpui::Pixels;
|
|
use schemars::JsonSchema;
|
|
use serde::{Deserialize, Serialize};
|
|
use settings::{RegisterSetting, Settings, StatusStyle};
|
|
use ui::{
|
|
px,
|
|
scrollbars::{ScrollbarVisibility, ShowScrollbar},
|
|
};
|
|
use workspace::dock::DockPosition;
|
|
|
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
|
pub struct ScrollbarSettings {
|
|
pub show: Option<ShowScrollbar>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, RegisterSetting)]
|
|
pub struct GitPanelSettings {
|
|
pub button: bool,
|
|
pub dock: DockPosition,
|
|
pub default_width: Pixels,
|
|
pub status_style: StatusStyle,
|
|
pub scrollbar: ScrollbarSettings,
|
|
pub fallback_branch_name: String,
|
|
pub sort_by_path: bool,
|
|
pub collapse_untracked_diff: bool,
|
|
pub tree_view: bool,
|
|
}
|
|
|
|
impl ScrollbarVisibility for GitPanelSettings {
|
|
fn visibility(&self, cx: &ui::App) -> ShowScrollbar {
|
|
// TODO: This PR should have defined Editor's `scrollbar.axis`
|
|
// as an Option<ScrollbarAxis>, not a ScrollbarAxes as it would allow you to
|
|
// `.unwrap_or(EditorSettings::get_global(cx).scrollbar.show)`.
|
|
//
|
|
// Once this is fixed we can extend the GitPanelSettings with a `scrollbar.axis`
|
|
// so we can show each axis based on the settings.
|
|
//
|
|
// We should fix this. PR: https://github.com/zed-industries/zed/pull/19495
|
|
self.scrollbar
|
|
.show
|
|
.unwrap_or_else(|| EditorSettings::get_global(cx).scrollbar.show)
|
|
}
|
|
}
|
|
|
|
impl Settings for GitPanelSettings {
|
|
fn from_settings(content: &settings::SettingsContent) -> Self {
|
|
let git_panel = content.git_panel.clone().unwrap();
|
|
Self {
|
|
button: git_panel.button.unwrap(),
|
|
dock: git_panel.dock.unwrap().into(),
|
|
default_width: px(git_panel.default_width.unwrap()),
|
|
status_style: git_panel.status_style.unwrap(),
|
|
scrollbar: ScrollbarSettings {
|
|
show: git_panel.scrollbar.unwrap().show.map(Into::into),
|
|
},
|
|
fallback_branch_name: git_panel.fallback_branch_name.unwrap(),
|
|
sort_by_path: git_panel.sort_by_path.unwrap(),
|
|
collapse_untracked_diff: git_panel.collapse_untracked_diff.unwrap(),
|
|
tree_view: git_panel.tree_view.unwrap(),
|
|
}
|
|
}
|
|
}
|