Merge branch 'main' into disconnected-status

This commit is contained in:
Nathan Sobo 2022-03-04 10:07:26 -07:00
commit a72d58a28c
22 changed files with 115 additions and 13 deletions

View file

@ -715,6 +715,18 @@ impl Project {
!self.is_local()
}
pub fn create_buffer(&mut self, cx: &mut ModelContext<Self>) -> Result<ModelHandle<Buffer>> {
if self.is_remote() {
return Err(anyhow!("creating buffers as a guest is not supported yet"));
}
let buffer = cx.add_model(|cx| {
Buffer::new(self.replica_id(), "", cx).with_language(language::PLAIN_TEXT.clone(), cx)
});
self.register_buffer(&buffer, None, cx)?;
Ok(buffer)
}
pub fn open_buffer(
&mut self,
path: impl Into<ProjectPath>,
@ -1342,15 +1354,47 @@ impl Project {
}
for (buffer, buffer_abs_path, lang_server) in local_buffers {
let lsp_edits = lang_server
.request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
text_document: lsp::TextDocumentIdentifier::new(
lsp::Url::from_file_path(&buffer_abs_path).unwrap(),
),
options: Default::default(),
work_done_progress_params: Default::default(),
})
.await?;
let capabilities = if let Some(capabilities) = lang_server.capabilities().await {
capabilities
} else {
continue;
};
let text_document = lsp::TextDocumentIdentifier::new(
lsp::Url::from_file_path(&buffer_abs_path).unwrap(),
);
let lsp_edits = if capabilities
.document_formatting_provider
.map_or(false, |provider| provider != lsp::OneOf::Left(false))
{
lang_server
.request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
text_document,
options: Default::default(),
work_done_progress_params: Default::default(),
})
.await?
} else if capabilities
.document_range_formatting_provider
.map_or(false, |provider| provider != lsp::OneOf::Left(false))
{
let buffer_start = lsp::Position::new(0, 0);
let buffer_end = buffer
.read_with(&cx, |buffer, _| buffer.max_point_utf16())
.to_lsp_position();
lang_server
.request::<lsp::request::RangeFormatting>(
lsp::DocumentRangeFormattingParams {
text_document,
range: lsp::Range::new(buffer_start, buffer_end),
options: Default::default(),
work_done_progress_params: Default::default(),
},
)
.await?
} else {
continue;
};
if let Some(lsp_edits) = lsp_edits {
let edits = buffer
@ -4128,6 +4172,48 @@ mod tests {
assert_eq!(new_text, buffer.read_with(cx, |buffer, _| buffer.text()));
}
#[gpui::test]
async fn test_save_as(cx: &mut gpui::TestAppContext) {
let fs = FakeFs::new(cx.background());
fs.insert_tree("/dir", json!({})).await;
let project = Project::test(fs.clone(), cx);
let (worktree, _) = project
.update(cx, |project, cx| {
project.find_or_create_local_worktree("/dir", true, cx)
})
.await
.unwrap();
let worktree_id = worktree.read_with(cx, |worktree, _| worktree.id());
let buffer = project.update(cx, |project, cx| project.create_buffer(cx).unwrap());
buffer.update(cx, |buffer, cx| {
buffer.edit([0..0], "abc", cx);
assert!(buffer.is_dirty());
assert!(!buffer.has_conflict());
});
project
.update(cx, |project, cx| {
project.save_buffer_as(buffer.clone(), "/dir/file1".into(), cx)
})
.await
.unwrap();
assert_eq!(fs.load(Path::new("/dir/file1")).await.unwrap(), "abc");
buffer.read_with(cx, |buffer, cx| {
assert_eq!(buffer.file().unwrap().full_path(cx), Path::new("dir/file1"));
assert!(!buffer.is_dirty());
assert!(!buffer.has_conflict());
});
let opened_buffer = project
.update(cx, |project, cx| {
project.open_buffer((worktree_id, "file1"), cx)
})
.await
.unwrap();
assert_eq!(opened_buffer, buffer);
}
#[gpui::test(retries = 5)]
async fn test_rescan_and_remote_updates(cx: &mut gpui::TestAppContext) {
let dir = temp_tree(json!({