pane: Serialize pinned tab state (#17670)

Release Notes:

- Tab pin state is now persisted across Zed runs.
This commit is contained in:
Piotr Osiewicz 2024-09-10 19:19:21 -04:00 committed by GitHub
parent d1a47faeb7
commit f374038da0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 11 deletions

View file

@ -715,6 +715,14 @@ impl Pane {
}
}
pub(crate) fn set_pinned_count(&mut self, count: usize) {
self.pinned_tab_count = count;
}
pub(crate) fn pinned_count(&self) -> usize {
self.pinned_tab_count
}
pub fn handle_item_edit(&mut self, item_id: EntityId, cx: &AppContext) {
if let Some(preview_item) = self.preview_item() {
if preview_item.item_id() == item_id && !preview_item.preserve_preview(cx) {

View file

@ -13,7 +13,7 @@ use sqlez::{
};
use ui::px;
use util::ResultExt;
use util::{maybe, ResultExt};
use uuid::Uuid;
use crate::WorkspaceId;
@ -352,6 +352,9 @@ define_connection! {
sql!(
ALTER TABLE workspaces ADD COLUMN window_id INTEGER DEFAULT NULL;
),
sql!(
ALTER TABLE panes ADD COLUMN pinned_count INTEGER DEFAULT 0;
)
];
}
@ -846,6 +849,7 @@ impl WorkspaceDb {
SerializedPaneGroup::Pane(SerializedPane {
active: true,
children: vec![],
pinned_count: 0,
})
}))
}
@ -861,15 +865,17 @@ impl WorkspaceDb {
Option<SerializedAxis>,
Option<PaneId>,
Option<bool>,
Option<usize>,
Option<String>,
);
self.select_bound::<GroupKey, GroupOrPane>(sql!(
SELECT group_id, axis, pane_id, active, flexes
SELECT group_id, axis, pane_id, active, pinned_count, flexes
FROM (SELECT
group_id,
axis,
NULL as pane_id,
NULL as active,
NULL as pinned_count,
position,
parent_group_id,
workspace_id,
@ -881,6 +887,7 @@ impl WorkspaceDb {
NULL,
center_panes.pane_id,
panes.active as active,
pinned_count,
position,
parent_group_id,
panes.workspace_id as workspace_id,
@ -891,7 +898,8 @@ impl WorkspaceDb {
ORDER BY position
))?((group_id, workspace_id))?
.into_iter()
.map(|(group_id, axis, pane_id, active, flexes)| {
.map(|(group_id, axis, pane_id, active, pinned_count, flexes)| {
let maybe_pane = maybe!({ Some((pane_id?, active?, pinned_count?)) });
if let Some((group_id, axis)) = group_id.zip(axis) {
let flexes = flexes
.map(|flexes: String| serde_json::from_str::<Vec<f32>>(&flexes))
@ -902,10 +910,11 @@ impl WorkspaceDb {
children: self.get_pane_group(workspace_id, Some(group_id))?,
flexes,
})
} else if let Some((pane_id, active)) = pane_id.zip(active) {
} else if let Some((pane_id, active, pinned_count)) = maybe_pane {
Ok(SerializedPaneGroup::Pane(SerializedPane::new(
self.get_items(pane_id)?,
active,
pinned_count,
)))
} else {
bail!("Pane Group Child was neither a pane group or a pane");
@ -977,10 +986,10 @@ impl WorkspaceDb {
parent: Option<(GroupId, usize)>,
) -> Result<PaneId> {
let pane_id = conn.select_row_bound::<_, i64>(sql!(
INSERT INTO panes(workspace_id, active)
VALUES (?, ?)
INSERT INTO panes(workspace_id, active, pinned_count)
VALUES (?, ?, ?)
RETURNING pane_id
))?((workspace_id, pane.active))?
))?((workspace_id, pane.active, pane.pinned_count))?
.ok_or_else(|| anyhow!("Could not retrieve inserted pane_id"))?;
let (parent_id, order) = parent.unzip();
@ -1219,6 +1228,7 @@ mod tests {
SerializedItem::new("Terminal", 6, true, false),
],
false,
0,
)),
SerializedPaneGroup::Pane(SerializedPane::new(
vec![
@ -1226,6 +1236,7 @@ mod tests {
SerializedItem::new("Terminal", 8, false, false),
],
false,
0,
)),
],
),
@ -1235,6 +1246,7 @@ mod tests {
SerializedItem::new("Terminal", 10, true, false),
],
false,
0,
)),
],
);
@ -1523,6 +1535,7 @@ mod tests {
SerializedItem::new("Terminal", 2, true, false),
],
false,
0,
)),
SerializedPaneGroup::Pane(SerializedPane::new(
vec![
@ -1530,6 +1543,7 @@ mod tests {
SerializedItem::new("Terminal", 3, true, false),
],
true,
0,
)),
],
),
@ -1539,6 +1553,7 @@ mod tests {
SerializedItem::new("Terminal", 6, false, false),
],
false,
0,
)),
],
);
@ -1570,6 +1585,7 @@ mod tests {
SerializedItem::new("Terminal", 2, true, false),
],
false,
0,
)),
SerializedPaneGroup::Pane(SerializedPane::new(
vec![
@ -1577,6 +1593,7 @@ mod tests {
SerializedItem::new("Terminal", 3, true, false),
],
true,
0,
)),
],
),
@ -1586,6 +1603,7 @@ mod tests {
SerializedItem::new("Terminal", 6, true, false),
],
false,
0,
)),
],
);
@ -1605,6 +1623,7 @@ mod tests {
SerializedItem::new("Terminal", 2, true, false),
],
false,
0,
)),
SerializedPaneGroup::Pane(SerializedPane::new(
vec![
@ -1612,6 +1631,7 @@ mod tests {
SerializedItem::new("Terminal", 3, false, false),
],
true,
0,
)),
],
);

View file

@ -297,6 +297,7 @@ impl Default for SerializedPaneGroup {
Self::Pane(SerializedPane {
children: vec![SerializedItem::default()],
active: false,
pinned_count: 0,
})
}
}
@ -379,11 +380,16 @@ impl SerializedPaneGroup {
pub struct SerializedPane {
pub(crate) active: bool,
pub(crate) children: Vec<SerializedItem>,
pub(crate) pinned_count: usize,
}
impl SerializedPane {
pub fn new(children: Vec<SerializedItem>, active: bool) -> Self {
SerializedPane { children, active }
pub fn new(children: Vec<SerializedItem>, active: bool, pinned_count: usize) -> Self {
SerializedPane {
children,
active,
pinned_count,
}
}
pub async fn deserialize_to(
@ -442,6 +448,9 @@ impl SerializedPane {
}
})?;
}
pane.update(cx, |pane, _| {
pane.set_pinned_count(self.pinned_count);
})?;
anyhow::Ok(items)
}

View file

@ -4025,7 +4025,7 @@ impl Workspace {
};
fn serialize_pane_handle(pane_handle: &View<Pane>, cx: &WindowContext) -> SerializedPane {
let (items, active) = {
let (items, active, pinned_count) = {
let pane = pane_handle.read(cx);
let active_item_id = pane.active_item().map(|item| item.item_id());
(
@ -4042,10 +4042,11 @@ impl Workspace {
})
.collect::<Vec<_>>(),
pane.has_focus(cx),
pane.pinned_count(),
)
};
SerializedPane::new(items, active)
SerializedPane::new(items, active, pinned_count)
}
fn build_serialized_pane_group(