Fix handling of new files with new buffer/file structure

This commit is contained in:
Max Brunsfeld
2021-05-06 21:06:20 -07:00
parent 290fcb4c06
commit e6323f0d02
4 changed files with 51 additions and 78 deletions

View File

@@ -339,6 +339,10 @@ impl TestAppContext {
pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
self.1.as_ref().simulate_new_path_selection(result);
}
pub fn did_prompt_for_new_path(&self) -> bool {
self.1.as_ref().did_prompt_for_new_path()
}
}
impl UpdateModel for TestAppContext {

View File

@@ -45,6 +45,10 @@ impl Platform {
.expect("prompt_for_new_path was not called");
callback(result(dir_path));
}
pub(crate) fn did_prompt_for_new_path(&self) -> bool {
self.last_prompt_for_new_path_args.borrow().is_some()
}
}
impl super::Platform for Platform {

View File

@@ -484,7 +484,9 @@ impl Buffer {
file: Option<FileHandle>,
ctx: &mut ModelContext<Buffer>,
) {
self.file = file;
if file.is_some() {
self.file = file;
}
self.saved_version = version;
ctx.emit(Event::Saved);
}

View File

@@ -714,7 +714,8 @@ mod tests {
use crate::{editor::BufferView, settings, test::temp_tree};
use gpui::App;
use serde_json::json;
use std::{collections::HashSet, os::unix};
use std::collections::HashSet;
use std::time;
use tempdir::TempDir;
#[test]
@@ -956,67 +957,6 @@ mod tests {
});
}
#[test]
fn test_open_two_paths_to_the_same_file() {
use crate::workspace::ItemViewHandle;
App::test_async((), |mut app| async move {
// Create a worktree with a symlink:
// dir
// ├── hello.txt
// └── hola.txt -> hello.txt
let temp_dir = temp_tree(json!({ "hello.txt": "hi" }));
let dir = temp_dir.path();
unix::fs::symlink(dir.join("hello.txt"), dir.join("hola.txt")).unwrap();
let settings = settings::channel(&app.font_cache()).unwrap().1;
let (_, workspace) = app.add_window(|ctx| {
let mut workspace = Workspace::new(0, settings, ctx);
workspace.add_worktree(dir, ctx);
workspace
});
app.read(|ctx| workspace.read(ctx).worktree_scans_complete(ctx))
.await;
// Simultaneously open both the original file and the symlink to the same file.
app.update(|ctx| {
workspace.update(ctx, |view, ctx| {
view.open_paths(&[dir.join("hello.txt"), dir.join("hola.txt")], ctx)
})
})
.await;
// The same content shows up with two different editors.
let buffer_views = app.read(|ctx| {
workspace
.read(ctx)
.active_pane()
.read(ctx)
.items()
.iter()
.map(|i| i.to_any().downcast::<BufferView>().unwrap())
.collect::<Vec<_>>()
});
app.read(|ctx| {
assert_eq!(buffer_views[0].title(ctx), "hello.txt");
assert_eq!(buffer_views[1].title(ctx), "hola.txt");
assert_eq!(buffer_views[0].read(ctx).text(ctx), "hi");
assert_eq!(buffer_views[1].read(ctx).text(ctx), "hi");
});
// When modifying one buffer, the changes appear in both editors.
app.update(|ctx| {
buffer_views[0].update(ctx, |buf, ctx| {
buf.insert(&"oh, ".to_string(), ctx);
});
});
app.read(|ctx| {
assert_eq!(buffer_views[0].read(ctx).text(ctx), "oh, hi");
assert_eq!(buffer_views[1].read(ctx).text(ctx), "oh, hi");
});
});
}
#[test]
fn test_open_and_save_new_file() {
App::test_async((), |mut app| async move {
@@ -1027,6 +967,15 @@ mod tests {
workspace.add_worktree(dir.path(), ctx);
workspace
});
let worktree = app.read(|ctx| {
workspace
.read(ctx)
.worktrees()
.iter()
.next()
.unwrap()
.clone()
});
// Create a new untitled buffer
let editor = workspace.update(&mut app, |workspace, ctx| {
@@ -1039,11 +988,13 @@ mod tests {
.unwrap()
});
editor.update(&mut app, |editor, ctx| {
assert!(!editor.is_dirty(ctx.as_ref()));
assert_eq!(editor.title(ctx.as_ref()), "untitled");
editor.insert(&"hi".to_string(), ctx)
editor.insert(&"hi".to_string(), ctx);
assert!(editor.is_dirty(ctx.as_ref()));
});
// Save the buffer, selecting a filename
// Save the buffer. This prompts for a filename.
workspace.update(&mut app, |workspace, ctx| {
workspace.save_active_item(&(), ctx)
});
@@ -1051,26 +1002,38 @@ mod tests {
assert_eq!(parent_dir, dir.path());
Some(parent_dir.join("the-new-name"))
});
app.read(|ctx| assert_eq!(editor.title(ctx), "untitled"));
app.read(|ctx| {
assert!(editor.is_dirty(ctx));
assert_eq!(editor.title(ctx), "untitled");
});
// When the save completes, the buffer's title is updated.
let worktree = app.read(|ctx| {
workspace
.read(ctx)
.worktrees()
.iter()
.next()
.unwrap()
.clone()
});
editor
.condition(&app, |editor, ctx| !editor.is_dirty(ctx))
.await;
worktree
.condition(&app, |worktree, _| {
.condition_with_duration(time::Duration::from_millis(500), &app, |worktree, _| {
worktree.inode_for_path("the-new-name").is_some()
})
.await;
app.read(|ctx| assert_eq!(editor.title(ctx), "the-new-name"));
// Open the same newly-created file in another pane item.
// The new editor should reuse the same buffer.
// Edit the file and save it again. This time, there is no filename prompt.
editor.update(&mut app, |editor, ctx| {
editor.insert(&" there".to_string(), ctx);
assert_eq!(editor.is_dirty(ctx.as_ref()), true);
});
workspace.update(&mut app, |workspace, ctx| {
workspace.save_active_item(&(), ctx)
});
assert!(!app.did_prompt_for_new_path());
editor
.condition(&app, |editor, ctx| !editor.is_dirty(ctx))
.await;
app.read(|ctx| assert_eq!(editor.title(ctx), "the-new-name"));
// Open the same newly-created file in another pane item. The new editor should reuse
// the same buffer.
workspace.update(&mut app, |workspace, ctx| {
workspace.open_new_file(&(), ctx);
workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, ctx);