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(
|workspace: &mut Workspace, _cx: &mut ViewContext<Workspace>| {
workspace.register_action(|workspace, _: &NewJournalEntry, cx| {
new_journal_entry(workspace.app_state().clone(), cx);
new_journal_entry(&workspace, cx);
});
},
)
.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 journal_dir = match journal_dir(settings.path.as_ref().unwrap()) {
Some(journal_dir) => journal_dir,
@ -77,6 +77,7 @@ pub fn new_journal_entry(app_state: Arc<AppState>, cx: &mut WindowContext) {
return;
}
};
let journal_dir_clone = journal_dir.clone();
let now = Local::now();
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))
});
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 {
let (journal_dir, entry_path) = create_entry.await?;
let (workspace, _) = cx
.update(|cx| {
workspace::open_paths(
&[journal_dir],
app_state,
workspace::OpenOptions::default(),
cx,
)
})?
.await?;
let opened = workspace
.update(&mut cx, |workspace, cx| {
workspace.open_paths(vec![entry_path], OpenVisible::All, None, cx)
})?
.await;
let opened = if open_new_workspace {
let (new_workspace, _) = cx
.update(|cx| {
workspace::open_paths(
&[journal_dir],
app_state,
workspace::OpenOptions::default(),
cx,
)
})?
.await?;
new_workspace
.update(&mut cx, |workspace, cx| {
workspace.open_paths(vec![entry_path], OpenVisible::All, None, cx)
})?
.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(editor) = item.downcast::<Editor>().map(|editor| editor.downgrade()) {