Avoid unnecessary DB writes (#29417)
Part of https://github.com/zed-industries/zed/issues/16472 * Adds debug logging to everywhere near INSERT/UPDATEs in the DB So something like `env RUST_LOG=debug,wasmtime_cranelift=off,cranelift_codegen=off,vte=off cargo run` could be used to view these (current zlog seems to process the exclusions odd, so not sure this is the optimal RUST_LOG line) can be used to debug any further writes. * Removes excessive window stack serialization Previously, it serialized unconditionally every 100ms. Now, only if the stack had changed, which is now check every 500ms. * Removes excessive terminal serialization Previously, it serialized its `cwd` on every `ItemEvent::UpdateTab` which was caused by e.g. any character output. Now, only if the `cwd` has changed at the next event processing time. Release Notes: - Fixed more excessive DB writes
This commit is contained in:
parent
37fa437990
commit
f106dfca42
16 changed files with 224 additions and 168 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -3158,6 +3158,7 @@ dependencies = [
|
|||
"go_to_line",
|
||||
"gpui",
|
||||
"language",
|
||||
"log",
|
||||
"menu",
|
||||
"picker",
|
||||
"postage",
|
||||
|
@ -3208,6 +3209,7 @@ dependencies = [
|
|||
"db",
|
||||
"gpui",
|
||||
"languages",
|
||||
"log",
|
||||
"notifications",
|
||||
"project",
|
||||
"serde",
|
||||
|
@ -7100,6 +7102,7 @@ dependencies = [
|
|||
"editor",
|
||||
"file_icons",
|
||||
"gpui",
|
||||
"log",
|
||||
"project",
|
||||
"schemars",
|
||||
"serde",
|
||||
|
|
|
@ -20,6 +20,7 @@ command_palette_hooks.workspace = true
|
|||
db.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
log.workspace = true
|
||||
picker.workspace = true
|
||||
postage.workspace = true
|
||||
serde.workspace = true
|
||||
|
|
|
@ -67,7 +67,12 @@ impl CommandPaletteDB {
|
|||
command_name: impl Into<String>,
|
||||
user_query: impl Into<String>,
|
||||
) -> Result<()> {
|
||||
self.write_command_invocation_internal(command_name.into(), user_query.into())
|
||||
let command_name = command_name.into();
|
||||
let user_query = user_query.into();
|
||||
log::debug!(
|
||||
"Writing command invocation: command_name={command_name}, user_query={user_query}"
|
||||
);
|
||||
self.write_command_invocation_internal(command_name, user_query)
|
||||
.await
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ component.workspace = true
|
|||
gpui.workspace = true
|
||||
languages.workspace = true
|
||||
notifications.workspace = true
|
||||
log.workspace = true
|
||||
project.workspace = true
|
||||
ui.workspace = true
|
||||
ui_input.workspace = true
|
||||
|
|
|
@ -23,6 +23,9 @@ impl ComponentPreviewDb {
|
|||
workspace_id: WorkspaceId,
|
||||
active_page_id: String,
|
||||
) -> Result<()> {
|
||||
log::debug!(
|
||||
"Saving active page: item_id={item_id:?}, workspace_id={workspace_id:?}, active_page_id={active_page_id}"
|
||||
);
|
||||
let query = "INSERT INTO component_previews(item_id, workspace_id, active_page_id)
|
||||
VALUES (?1, ?2, ?3)
|
||||
ON CONFLICT DO UPDATE SET
|
||||
|
|
|
@ -18,8 +18,13 @@ impl KeyValueStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn write_kvp(&self, key: String, value: String) -> anyhow::Result<()> {
|
||||
log::debug!("Writing key-value pair for key {key}");
|
||||
self.write_kvp_inner(key, value).await
|
||||
}
|
||||
|
||||
query! {
|
||||
pub async fn write_kvp(key: String, value: String) -> Result<()> {
|
||||
async fn write_kvp_inner(key: String, value: String) -> Result<()> {
|
||||
INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))
|
||||
}
|
||||
}
|
||||
|
@ -78,8 +83,13 @@ impl GlobalKeyValueStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn write_kvp(&self, key: String, value: String) -> anyhow::Result<()> {
|
||||
log::debug!("Writing global key-value pair for key {key}");
|
||||
self.write_kvp_inner(key, value).await
|
||||
}
|
||||
|
||||
query! {
|
||||
pub async fn write_kvp(key: String, value: String) -> Result<()> {
|
||||
async fn write_kvp_inner(key: String, value: String) -> Result<()> {
|
||||
INSERT OR REPLACE INTO kv_store(key, value) VALUES ((?), (?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1251,6 +1251,7 @@ impl SerializableItem for Editor {
|
|||
language,
|
||||
mtime,
|
||||
};
|
||||
log::debug!("Serializing editor {item_id:?} in workspace {workspace_id:?}");
|
||||
DB.save_serialized_editor(item_id, workspace_id, editor)
|
||||
.await
|
||||
.context("failed to save serialized editor")
|
||||
|
|
|
@ -276,6 +276,7 @@ impl EditorDb {
|
|||
workspace_id: WorkspaceId,
|
||||
selections: Vec<(usize, usize)>,
|
||||
) -> Result<()> {
|
||||
log::debug!("Saving selections for editor {editor_id} in workspace {workspace_id:?}");
|
||||
let mut first_selection;
|
||||
let mut last_selection = 0_usize;
|
||||
for (count, placeholders) in std::iter::once("(?1, ?2, ?, ?)")
|
||||
|
@ -327,6 +328,7 @@ VALUES {placeholders};
|
|||
workspace_id: WorkspaceId,
|
||||
folds: Vec<(usize, usize)>,
|
||||
) -> Result<()> {
|
||||
log::debug!("Saving folds for editor {editor_id} in workspace {workspace_id:?}");
|
||||
let mut first_fold;
|
||||
let mut last_fold = 0_usize;
|
||||
for (count, placeholders) in std::iter::once("(?1, ?2, ?, ?)")
|
||||
|
|
|
@ -270,6 +270,9 @@ impl ScrollManager {
|
|||
|
||||
cx.foreground_executor()
|
||||
.spawn(async move {
|
||||
log::debug!(
|
||||
"Saving scroll position for item {item_id:?} in workspace {workspace_id:?}"
|
||||
);
|
||||
DB.save_scroll_position(
|
||||
item_id,
|
||||
workspace_id,
|
||||
|
|
|
@ -21,6 +21,7 @@ db.workspace = true
|
|||
editor.workspace = true
|
||||
file_icons.workspace = true
|
||||
gpui.workspace = true
|
||||
log.workspace = true
|
||||
project.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
|
|
|
@ -261,6 +261,7 @@ impl SerializableItem for ImageView {
|
|||
|
||||
Some(cx.background_spawn({
|
||||
async move {
|
||||
log::debug!("Saving image at path {image_path:?}");
|
||||
IMAGE_VIEWER
|
||||
.save_image_path(item_id, workspace_id, image_path)
|
||||
.await
|
||||
|
@ -399,18 +400,6 @@ mod persistence {
|
|||
}
|
||||
|
||||
impl ImageViewerDb {
|
||||
query! {
|
||||
pub async fn update_workspace_id(
|
||||
new_id: WorkspaceId,
|
||||
old_id: WorkspaceId,
|
||||
item_id: ItemId
|
||||
) -> Result<()> {
|
||||
UPDATE image_viewers
|
||||
SET workspace_id = ?
|
||||
WHERE workspace_id = ? AND item_id = ?
|
||||
}
|
||||
}
|
||||
|
||||
query! {
|
||||
pub async fn save_image_path(
|
||||
item_id: ItemId,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use gpui::{AnyWindowHandle, AppContext as _, Context, Subscription, Task, WindowId};
|
||||
use gpui::{App, AppContext as _, Context, Subscription, Task, WindowId};
|
||||
use util::ResultExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -59,7 +59,7 @@ impl Session {
|
|||
|
||||
pub struct AppSession {
|
||||
session: Session,
|
||||
_serialization_task: Option<Task<()>>,
|
||||
_serialization_task: Task<()>,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
|
@ -67,17 +67,21 @@ impl AppSession {
|
|||
pub fn new(session: Session, cx: &Context<Self>) -> Self {
|
||||
let _subscriptions = vec![cx.on_app_quit(Self::app_will_quit)];
|
||||
|
||||
let _serialization_task = Some(cx.spawn(async move |_, cx| {
|
||||
let _serialization_task = cx.spawn(async move |_, cx| {
|
||||
let mut current_window_stack = Vec::new();
|
||||
loop {
|
||||
if let Some(windows) = cx.update(|cx| cx.window_stack()).ok().flatten() {
|
||||
store_window_stack(windows).await;
|
||||
if let Some(windows) = cx.update(|cx| window_stack(cx)).ok().flatten() {
|
||||
if windows != current_window_stack {
|
||||
store_window_stack(&windows).await;
|
||||
current_window_stack = windows;
|
||||
}
|
||||
}
|
||||
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(100))
|
||||
.timer(Duration::from_millis(500))
|
||||
.await;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
Self {
|
||||
session,
|
||||
|
@ -87,8 +91,8 @@ impl AppSession {
|
|||
}
|
||||
|
||||
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> Task<()> {
|
||||
if let Some(windows) = cx.window_stack() {
|
||||
cx.background_spawn(store_window_stack(windows))
|
||||
if let Some(window_stack) = window_stack(cx) {
|
||||
cx.background_spawn(async move { store_window_stack(&window_stack).await })
|
||||
} else {
|
||||
Task::ready(())
|
||||
}
|
||||
|
@ -107,13 +111,17 @@ impl AppSession {
|
|||
}
|
||||
}
|
||||
|
||||
async fn store_window_stack(windows: Vec<AnyWindowHandle>) {
|
||||
let window_ids = windows
|
||||
.into_iter()
|
||||
.map(|window| window.window_id().as_u64())
|
||||
.collect::<Vec<_>>();
|
||||
fn window_stack(cx: &App) -> Option<Vec<u64>> {
|
||||
Some(
|
||||
cx.window_stack()?
|
||||
.into_iter()
|
||||
.map(|window| window.window_id().as_u64())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
if let Ok(window_ids_json) = serde_json::to_string(&window_ids) {
|
||||
async fn store_window_stack(windows: &[u64]) {
|
||||
if let Ok(window_ids_json) = serde_json::to_string(windows) {
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(SESSION_WINDOW_STACK_KEY.to_string(), window_ids_json)
|
||||
.await
|
||||
|
|
|
@ -429,6 +429,9 @@ impl TerminalDb {
|
|||
workspace_id: WorkspaceId,
|
||||
working_directory: PathBuf,
|
||||
) -> Result<()> {
|
||||
log::debug!(
|
||||
"Saving working directory {working_directory:?} for item {item_id} in workspace {workspace_id:?}"
|
||||
);
|
||||
let query =
|
||||
"INSERT INTO terminals(item_id, workspace_id, working_directory, working_directory_path)
|
||||
VALUES (?1, ?2, ?3, ?4)
|
||||
|
|
|
@ -112,6 +112,7 @@ pub struct TerminalView {
|
|||
cursor_shape: CursorShape,
|
||||
blink_state: bool,
|
||||
blinking_terminal_enabled: bool,
|
||||
cwd_serialized: bool,
|
||||
blinking_paused: bool,
|
||||
blink_epoch: usize,
|
||||
hover_target_tooltip: Option<String>,
|
||||
|
@ -207,6 +208,7 @@ impl TerminalView {
|
|||
scroll_handle,
|
||||
show_scrollbar: !Self::should_autohide_scrollbar(cx),
|
||||
hide_scrollbar_task: None,
|
||||
cwd_serialized: false,
|
||||
_subscriptions: vec![
|
||||
focus_in,
|
||||
focus_out,
|
||||
|
@ -843,167 +845,176 @@ fn subscribe_for_terminal_events(
|
|||
cx: &mut Context<TerminalView>,
|
||||
) -> Vec<Subscription> {
|
||||
let terminal_subscription = cx.observe(terminal, |_, _, cx| cx.notify());
|
||||
let mut previous_cwd = None;
|
||||
let terminal_events_subscription = cx.subscribe_in(
|
||||
terminal,
|
||||
window,
|
||||
move |terminal_view, _, event, window, cx| match event {
|
||||
Event::Wakeup => {
|
||||
cx.notify();
|
||||
cx.emit(Event::Wakeup);
|
||||
cx.emit(ItemEvent::UpdateTab);
|
||||
cx.emit(SearchEvent::MatchesInvalidated);
|
||||
move |terminal_view, terminal, event, window, cx| {
|
||||
let current_cwd = terminal.read(cx).working_directory();
|
||||
if current_cwd != previous_cwd {
|
||||
previous_cwd = current_cwd;
|
||||
terminal_view.cwd_serialized = false;
|
||||
}
|
||||
|
||||
Event::Bell => {
|
||||
terminal_view.has_bell = true;
|
||||
cx.emit(Event::Wakeup);
|
||||
}
|
||||
|
||||
Event::BlinkChanged(blinking) => {
|
||||
if matches!(
|
||||
TerminalSettings::get_global(cx).blinking,
|
||||
TerminalBlink::TerminalControlled
|
||||
) {
|
||||
terminal_view.blinking_terminal_enabled = *blinking;
|
||||
match event {
|
||||
Event::Wakeup => {
|
||||
cx.notify();
|
||||
cx.emit(Event::Wakeup);
|
||||
cx.emit(ItemEvent::UpdateTab);
|
||||
cx.emit(SearchEvent::MatchesInvalidated);
|
||||
}
|
||||
}
|
||||
|
||||
Event::TitleChanged => {
|
||||
cx.emit(ItemEvent::UpdateTab);
|
||||
}
|
||||
Event::Bell => {
|
||||
terminal_view.has_bell = true;
|
||||
cx.emit(Event::Wakeup);
|
||||
}
|
||||
|
||||
Event::NewNavigationTarget(maybe_navigation_target) => {
|
||||
match maybe_navigation_target.as_ref() {
|
||||
None => {
|
||||
terminal_view.hover_target_tooltip = None;
|
||||
terminal_view.hover_tooltip_update = Task::ready(());
|
||||
}
|
||||
Some(MaybeNavigationTarget::Url(url)) => {
|
||||
terminal_view.hover_target_tooltip = Some(url.clone());
|
||||
terminal_view.hover_tooltip_update = Task::ready(());
|
||||
}
|
||||
Some(MaybeNavigationTarget::PathLike(path_like_target)) => {
|
||||
let valid_files_to_open_task = possible_open_target(
|
||||
&workspace,
|
||||
&path_like_target.terminal_dir,
|
||||
&path_like_target.maybe_path,
|
||||
cx,
|
||||
);
|
||||
|
||||
terminal_view.hover_tooltip_update =
|
||||
cx.spawn(async move |terminal_view, cx| {
|
||||
let file_to_open = valid_files_to_open_task.await;
|
||||
terminal_view
|
||||
.update(cx, |terminal_view, _| match file_to_open {
|
||||
Some(
|
||||
OpenTarget::File(path, _)
|
||||
| OpenTarget::Worktree(path, _),
|
||||
) => {
|
||||
terminal_view.hover_target_tooltip =
|
||||
Some(path.to_string(|path| {
|
||||
path.to_string_lossy().to_string()
|
||||
}));
|
||||
}
|
||||
None => {
|
||||
terminal_view.hover_target_tooltip = None;
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
});
|
||||
Event::BlinkChanged(blinking) => {
|
||||
if matches!(
|
||||
TerminalSettings::get_global(cx).blinking,
|
||||
TerminalBlink::TerminalControlled
|
||||
) {
|
||||
terminal_view.blinking_terminal_enabled = *blinking;
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify()
|
||||
}
|
||||
Event::TitleChanged => {
|
||||
cx.emit(ItemEvent::UpdateTab);
|
||||
}
|
||||
|
||||
Event::Open(maybe_navigation_target) => match maybe_navigation_target {
|
||||
MaybeNavigationTarget::Url(url) => cx.open_url(url),
|
||||
Event::NewNavigationTarget(maybe_navigation_target) => {
|
||||
match maybe_navigation_target.as_ref() {
|
||||
None => {
|
||||
terminal_view.hover_target_tooltip = None;
|
||||
terminal_view.hover_tooltip_update = Task::ready(());
|
||||
}
|
||||
Some(MaybeNavigationTarget::Url(url)) => {
|
||||
terminal_view.hover_target_tooltip = Some(url.clone());
|
||||
terminal_view.hover_tooltip_update = Task::ready(());
|
||||
}
|
||||
Some(MaybeNavigationTarget::PathLike(path_like_target)) => {
|
||||
let valid_files_to_open_task = possible_open_target(
|
||||
&workspace,
|
||||
&path_like_target.terminal_dir,
|
||||
&path_like_target.maybe_path,
|
||||
cx,
|
||||
);
|
||||
|
||||
MaybeNavigationTarget::PathLike(path_like_target) => {
|
||||
if terminal_view.hover_target_tooltip.is_none() {
|
||||
return;
|
||||
terminal_view.hover_tooltip_update =
|
||||
cx.spawn(async move |terminal_view, cx| {
|
||||
let file_to_open = valid_files_to_open_task.await;
|
||||
terminal_view
|
||||
.update(cx, |terminal_view, _| match file_to_open {
|
||||
Some(
|
||||
OpenTarget::File(path, _)
|
||||
| OpenTarget::Worktree(path, _),
|
||||
) => {
|
||||
terminal_view.hover_target_tooltip =
|
||||
Some(path.to_string(|path| {
|
||||
path.to_string_lossy().to_string()
|
||||
}));
|
||||
}
|
||||
None => {
|
||||
terminal_view.hover_target_tooltip = None;
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
});
|
||||
}
|
||||
}
|
||||
let task_workspace = workspace.clone();
|
||||
let path_like_target = path_like_target.clone();
|
||||
cx.spawn_in(window, async move |terminal_view, cx| {
|
||||
let open_target = terminal_view
|
||||
.update(cx, |_, cx| {
|
||||
possible_open_target(
|
||||
&task_workspace,
|
||||
&path_like_target.terminal_dir,
|
||||
&path_like_target.maybe_path,
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
.await;
|
||||
if let Some(open_target) = open_target {
|
||||
let path_to_open = open_target.path();
|
||||
let opened_items = task_workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(
|
||||
vec![path_to_open.path.clone()],
|
||||
OpenOptions {
|
||||
visible: Some(OpenVisible::OnlyDirectories),
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
window,
|
||||
|
||||
cx.notify()
|
||||
}
|
||||
|
||||
Event::Open(maybe_navigation_target) => match maybe_navigation_target {
|
||||
MaybeNavigationTarget::Url(url) => cx.open_url(url),
|
||||
|
||||
MaybeNavigationTarget::PathLike(path_like_target) => {
|
||||
if terminal_view.hover_target_tooltip.is_none() {
|
||||
return;
|
||||
}
|
||||
let task_workspace = workspace.clone();
|
||||
let path_like_target = path_like_target.clone();
|
||||
cx.spawn_in(window, async move |terminal_view, cx| {
|
||||
let open_target = terminal_view
|
||||
.update(cx, |_, cx| {
|
||||
possible_open_target(
|
||||
&task_workspace,
|
||||
&path_like_target.terminal_dir,
|
||||
&path_like_target.maybe_path,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.context("workspace update")?
|
||||
})?
|
||||
.await;
|
||||
if opened_items.len() != 1 {
|
||||
debug_panic!(
|
||||
"Received {} items for one path {path_to_open:?}",
|
||||
opened_items.len(),
|
||||
);
|
||||
}
|
||||
if let Some(open_target) = open_target {
|
||||
let path_to_open = open_target.path();
|
||||
let opened_items = task_workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.open_paths(
|
||||
vec![path_to_open.path.clone()],
|
||||
OpenOptions {
|
||||
visible: Some(OpenVisible::OnlyDirectories),
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.context("workspace update")?
|
||||
.await;
|
||||
if opened_items.len() != 1 {
|
||||
debug_panic!(
|
||||
"Received {} items for one path {path_to_open:?}",
|
||||
opened_items.len(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(opened_item) = opened_items.first() {
|
||||
if open_target.is_file() {
|
||||
if let Some(Ok(opened_item)) = opened_item {
|
||||
if let Some(row) = path_to_open.row {
|
||||
let col = path_to_open.column.unwrap_or(0);
|
||||
if let Some(active_editor) =
|
||||
opened_item.downcast::<Editor>()
|
||||
{
|
||||
active_editor
|
||||
.downgrade()
|
||||
.update_in(cx, |editor, window, cx| {
|
||||
editor.go_to_singleton_buffer_point(
|
||||
language::Point::new(
|
||||
row.saturating_sub(1),
|
||||
col.saturating_sub(1),
|
||||
),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.log_err();
|
||||
if let Some(opened_item) = opened_items.first() {
|
||||
if open_target.is_file() {
|
||||
if let Some(Ok(opened_item)) = opened_item {
|
||||
if let Some(row) = path_to_open.row {
|
||||
let col = path_to_open.column.unwrap_or(0);
|
||||
if let Some(active_editor) =
|
||||
opened_item.downcast::<Editor>()
|
||||
{
|
||||
active_editor
|
||||
.downgrade()
|
||||
.update_in(cx, |editor, window, cx| {
|
||||
editor.go_to_singleton_buffer_point(
|
||||
language::Point::new(
|
||||
row.saturating_sub(1),
|
||||
col.saturating_sub(1),
|
||||
),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if open_target.is_dir() {
|
||||
task_workspace.update(cx, |workspace, cx| {
|
||||
workspace.project().update(cx, |_, cx| {
|
||||
cx.emit(project::Event::ActivateProjectPanel);
|
||||
})
|
||||
})?;
|
||||
}
|
||||
} else if open_target.is_dir() {
|
||||
task_workspace.update(cx, |workspace, cx| {
|
||||
workspace.project().update(cx, |_, cx| {
|
||||
cx.emit(project::Event::ActivateProjectPanel);
|
||||
})
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx)
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx)
|
||||
}
|
||||
},
|
||||
Event::BreadcrumbsChanged => cx.emit(ItemEvent::UpdateBreadcrumbs),
|
||||
Event::CloseTerminal => cx.emit(ItemEvent::CloseItem),
|
||||
Event::SelectionsChanged => {
|
||||
window.invalidate_character_coordinates();
|
||||
cx.emit(SearchEvent::ActiveMatchChanged)
|
||||
}
|
||||
},
|
||||
Event::BreadcrumbsChanged => cx.emit(ItemEvent::UpdateBreadcrumbs),
|
||||
Event::CloseTerminal => cx.emit(ItemEvent::CloseItem),
|
||||
Event::SelectionsChanged => {
|
||||
window.invalidate_character_coordinates();
|
||||
cx.emit(SearchEvent::ActiveMatchChanged)
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -1539,6 +1550,9 @@ impl Item for TerminalView {
|
|||
) {
|
||||
if self.terminal().read(cx).task().is_none() {
|
||||
if let Some((new_id, old_id)) = workspace.database_id().zip(self.workspace_id) {
|
||||
log::debug!(
|
||||
"Updating workspace id for the terminal, old: {old_id:?}, new: {new_id:?}",
|
||||
);
|
||||
cx.background_spawn(TERMINAL_DB.update_workspace_id(
|
||||
new_id,
|
||||
old_id,
|
||||
|
@ -1587,6 +1601,7 @@ impl SerializableItem for TerminalView {
|
|||
}
|
||||
|
||||
if let Some((cwd, workspace_id)) = terminal.working_directory().zip(self.workspace_id) {
|
||||
self.cwd_serialized = true;
|
||||
Some(cx.background_spawn(async move {
|
||||
TERMINAL_DB
|
||||
.save_working_directory(item_id, workspace_id, cwd)
|
||||
|
@ -1597,8 +1612,8 @@ impl SerializableItem for TerminalView {
|
|||
}
|
||||
}
|
||||
|
||||
fn should_serialize(&self, event: &Self::Event) -> bool {
|
||||
matches!(event, ItemEvent::UpdateTab)
|
||||
fn should_serialize(&self, _: &Self::Event) -> bool {
|
||||
!self.cwd_serialized
|
||||
}
|
||||
|
||||
fn deserialize(
|
||||
|
|
|
@ -1644,6 +1644,7 @@ impl VimDb {
|
|||
path: Arc<Path>,
|
||||
marks: HashMap<String, Vec<Point>>,
|
||||
) -> Result<()> {
|
||||
log::debug!("Setting path {path:?} for {} marks", marks.len());
|
||||
let result = self
|
||||
.write(move |conn| {
|
||||
let mut query = conn.exec_bound(sql!(
|
||||
|
@ -1694,6 +1695,7 @@ impl VimDb {
|
|||
mark_name: String,
|
||||
path: Arc<Path>,
|
||||
) -> Result<()> {
|
||||
log::debug!("Setting global mark path {path:?} for {mark_name}");
|
||||
self.write(move |conn| {
|
||||
conn.exec_bound(sql!(
|
||||
INSERT OR REPLACE INTO vim_global_marks_paths
|
||||
|
|
|
@ -739,6 +739,7 @@ impl WorkspaceDb {
|
|||
/// Saves a workspace using the worktree roots. Will garbage collect any workspaces
|
||||
/// that used this workspace previously
|
||||
pub(crate) async fn save_workspace(&self, workspace: SerializedWorkspace) {
|
||||
log::debug!("Saving workspace at location: {:?}", workspace.location);
|
||||
self.write(move |conn| {
|
||||
conn.with_savepoint("update_worktrees", || {
|
||||
// Clear out panes and pane_groups
|
||||
|
@ -909,6 +910,7 @@ impl WorkspaceDb {
|
|||
{
|
||||
Ok(project)
|
||||
} else {
|
||||
log::debug!("Inserting SSH project at host {host}");
|
||||
self.insert_ssh_project(host, port, paths, user)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("failed to insert ssh project"))
|
||||
|
@ -1209,6 +1211,9 @@ impl WorkspaceDb {
|
|||
pane_group: &SerializedPaneGroup,
|
||||
parent: Option<(GroupId, usize)>,
|
||||
) -> Result<()> {
|
||||
if parent.is_none() {
|
||||
log::debug!("Saving a pane group for workspace {workspace_id:?}");
|
||||
}
|
||||
match pane_group {
|
||||
SerializedPaneGroup::Group {
|
||||
axis,
|
||||
|
@ -1387,6 +1392,10 @@ impl WorkspaceDb {
|
|||
relative_worktree_path: String,
|
||||
toolchain: Toolchain,
|
||||
) -> Result<()> {
|
||||
log::debug!(
|
||||
"Setting toolchain for workspace, worktree: {worktree_id:?}, relative path: {relative_worktree_path:?}, toolchain: {}",
|
||||
toolchain.name
|
||||
);
|
||||
self.write(move |conn| {
|
||||
let mut insert = conn
|
||||
.exec_bound(sql!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue