Reuse workspace on new journal entry command if possible (#16924)

Closes #6783

With this PR, the `journal: new journal entry` command only opens a new
workspace if the current workspace does not already contain the
`journal` directory. Both the root of the work tree and all its
subdirectories are checked.

This does not yet check for the day's file specifically, as suggested
[here](https://github.com/zed-industries/zed/issues/6783#issuecomment-2268509463).

I'm new to writing Rust code in production (as well as contributing in
general), so any feedback is much appreciated!

Release Notes:

- Reuse workspace on `journal: new journal entry` command if possible
This commit is contained in:
ZZzzaaKK 2024-08-29 06:18:42 +02:00 committed by GitHub
parent ca2eb275de
commit 6a5d0a5083
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -61,14 +61,14 @@ pub fn init(_: Arc<AppState>, cx: &mut AppContext) {
cx.observe_new_views( cx.observe_new_views(
|workspace: &mut Workspace, _cx: &mut ViewContext<Workspace>| { |workspace: &mut Workspace, _cx: &mut ViewContext<Workspace>| {
workspace.register_action(|workspace, _: &NewJournalEntry, cx| { workspace.register_action(|workspace, _: &NewJournalEntry, cx| {
new_journal_entry(workspace.app_state().clone(), cx); new_journal_entry(&workspace, cx);
}); });
}, },
) )
.detach(); .detach();
} }
pub fn new_journal_entry(app_state: Arc<AppState>, cx: &mut WindowContext) { pub fn new_journal_entry(workspace: &Workspace, cx: &mut WindowContext) {
let settings = JournalSettings::get_global(cx); let settings = JournalSettings::get_global(cx);
let journal_dir = match journal_dir(settings.path.as_ref().unwrap()) { let journal_dir = match journal_dir(settings.path.as_ref().unwrap()) {
Some(journal_dir) => journal_dir, Some(journal_dir) => journal_dir,
@ -77,6 +77,7 @@ pub fn new_journal_entry(app_state: Arc<AppState>, cx: &mut WindowContext) {
return; return;
} }
}; };
let journal_dir_clone = journal_dir.clone();
let now = Local::now(); let now = Local::now();
let month_dir = journal_dir let month_dir = journal_dir
@ -96,24 +97,51 @@ pub fn new_journal_entry(app_state: Arc<AppState>, cx: &mut WindowContext) {
Ok::<_, std::io::Error>((journal_dir, entry_path)) Ok::<_, std::io::Error>((journal_dir, entry_path))
}); });
let worktrees = workspace.visible_worktrees(cx).collect::<Vec<_>>();
let mut open_new_workspace = true;
'outer: for worktree in worktrees.iter() {
let worktree_root = worktree.read(cx).abs_path();
if *worktree_root == journal_dir_clone {
open_new_workspace = false;
break;
}
for directory in worktree.read(cx).directories(true, 1) {
let full_directory_path = worktree_root.join(&directory.path);
if full_directory_path.ends_with(&journal_dir_clone) {
open_new_workspace = false;
break 'outer;
}
}
}
let app_state = workspace.app_state().clone();
let view_snapshot = workspace.weak_handle().clone();
cx.spawn(|mut cx| async move { cx.spawn(|mut cx| async move {
let (journal_dir, entry_path) = create_entry.await?; let (journal_dir, entry_path) = create_entry.await?;
let (workspace, _) = cx let opened = if open_new_workspace {
.update(|cx| { let (new_workspace, _) = cx
workspace::open_paths( .update(|cx| {
&[journal_dir], workspace::open_paths(
app_state, &[journal_dir],
workspace::OpenOptions::default(), app_state,
cx, workspace::OpenOptions::default(),
) cx,
})? )
.await?; })?
.await?;
let opened = workspace new_workspace
.update(&mut cx, |workspace, cx| { .update(&mut cx, |workspace, cx| {
workspace.open_paths(vec![entry_path], OpenVisible::All, None, cx) workspace.open_paths(vec![entry_path], OpenVisible::All, None, cx)
})? })?
.await; .await
} else {
view_snapshot
.update(&mut cx, |workspace, cx| {
workspace.open_paths(vec![entry_path], OpenVisible::All, None, cx)
})?
.await
};
if let Some(Some(Ok(item))) = opened.first() { if let Some(Some(Ok(item))) = opened.first() {
if let Some(editor) = item.downcast::<Editor>().map(|editor| editor.downgrade()) { if let Some(editor) = item.downcast::<Editor>().map(|editor| editor.downgrade()) {