Cargo.lock 🔗
@@ -4878,6 +4878,8 @@ name = "terminal"
version = "0.1.0"
dependencies = [
"alacritty_terminal",
+ "client",
+ "dirs 4.0.0",
"editor",
"futures",
"gpui",
Mikayla Maki created
Cargo.lock | 2
crates/terminal/Cargo.toml | 4 +
crates/terminal/src/terminal.rs | 99 +++++++++++++++++++++++++++++++++-
3 files changed, 102 insertions(+), 3 deletions(-)
@@ -4878,6 +4878,8 @@ name = "terminal"
version = "0.1.0"
dependencies = [
"alacritty_terminal",
+ "client",
+ "dirs 4.0.0",
"editor",
"futures",
"gpui",
@@ -21,7 +21,11 @@ mio-extras = "2.0.6"
futures = "0.3"
ordered-float = "2.1.1"
itertools = "0.10"
+dirs = "4.0.0"
[dev-dependencies]
gpui = { path = "../gpui", features = ["test-support"] }
+client = { path = "../client", features = ["test-support"]}
+project = { path = "../project", features = ["test-support"]}
+
@@ -9,6 +9,7 @@ use alacritty_terminal::{
Term,
};
+use dirs::home_dir;
use futures::{
channel::mpsc::{unbounded, UnboundedSender},
StreamExt,
@@ -17,7 +18,7 @@ use gpui::{
actions, color::Color, elements::*, impl_internal_actions, platform::CursorStyle,
ClipboardItem, Entity, MutableAppContext, View, ViewContext,
};
-use project::{Project, ProjectPath};
+use project::{LocalWorktree, Project, ProjectPath};
use settings::Settings;
use smallvec::SmallVec;
use std::{collections::HashMap, path::PathBuf, sync::Arc};
@@ -268,11 +269,12 @@ impl Terminal {
///Create a new Terminal in the current working directory or the user's home directory
fn deploy(workspace: &mut Workspace, _: &Deploy, cx: &mut ViewContext<Workspace>) {
let project = workspace.project().read(cx);
+
let abs_path = project
.active_entry()
.and_then(|entry_id| project.worktree_for_entry(entry_id, cx))
.and_then(|worktree_handle| worktree_handle.read(cx).as_local())
- .map(|wt| wt.abs_path().to_path_buf());
+ .and_then(get_working_directory);
workspace.add_item(Box::new(cx.add_view(|cx| Terminal::new(cx, abs_path))), cx);
}
@@ -477,19 +479,28 @@ fn to_alac_rgb(color: Color) -> AlacRgb {
}
}
+fn get_working_directory(wt: &LocalWorktree) -> Option<PathBuf> {
+ Some(wt.abs_path().to_path_buf())
+ .filter(|path| path.is_dir())
+ .or_else(|| home_dir())
+}
+
#[cfg(test)]
mod tests {
+
+ use std::{path::Path, sync::atomic::AtomicUsize};
+
use super::*;
use alacritty_terminal::{grid::GridIterator, term::cell::Cell};
use gpui::TestAppContext;
use itertools::Itertools;
+ use project::{FakeFs, Fs, RealFs, RemoveOptions, Worktree};
///Basic integration test, can we get the terminal to show up, execute a command,
//and produce noticable output?
#[gpui::test]
async fn test_terminal(cx: &mut TestAppContext) {
let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None));
-
terminal.update(cx, |terminal, cx| {
terminal.write_to_pty(&Input(("expr 3 + 4".to_string()).to_string()), cx);
terminal.carriage_return(&Return, cx);
@@ -499,6 +510,7 @@ mod tests {
.condition(cx, |terminal, _cx| {
let term = terminal.term.clone();
let content = grid_as_str(term.lock().renderable_content().display_iter);
+ dbg!(&content);
content.contains("7")
})
.await;
@@ -512,4 +524,85 @@ mod tests {
.collect::<Vec<String>>()
.join("\n")
}
+
+ #[gpui::test]
+ async fn single_file_worktree(cx: &mut TestAppContext) {
+ let mut async_cx = cx.to_async();
+ let http_client = client::test::FakeHttpClient::with_404_response();
+ let client = client::Client::new(http_client.clone());
+ let fake_fs = FakeFs::new(cx.background().clone());
+
+ let path = Path::new("/file/");
+ fake_fs.insert_file(path, "a".to_string()).await;
+
+ let worktree_handle = Worktree::local(
+ client,
+ path,
+ true,
+ fake_fs,
+ Arc::new(AtomicUsize::new(0)),
+ &mut async_cx,
+ )
+ .await
+ .ok()
+ .unwrap();
+
+ async_cx.update(|cx| {
+ let wt = worktree_handle.read(cx).as_local().unwrap();
+ let wd = get_working_directory(wt);
+ assert!(wd.is_some());
+ let path = wd.unwrap();
+ //This should be the system's working directory, so querying the real file system is probably ok.
+ assert!(path.is_dir());
+ assert_eq!(path, home_dir().unwrap());
+ });
+ }
+
+ #[gpui::test]
+ async fn test_worktree_directory(cx: &mut TestAppContext) {
+ let mut async_cx = cx.to_async();
+ let http_client = client::test::FakeHttpClient::with_404_response();
+ let client = client::Client::new(http_client.clone());
+
+ let fs = RealFs;
+ let mut test_wd = home_dir().unwrap();
+ test_wd.push("dir");
+
+ fs.create_dir(test_wd.as_path())
+ .await
+ .expect("File could not be created");
+
+ let worktree_handle = Worktree::local(
+ client,
+ test_wd.clone(),
+ true,
+ Arc::new(RealFs),
+ Arc::new(AtomicUsize::new(0)),
+ &mut async_cx,
+ )
+ .await
+ .ok()
+ .unwrap();
+
+ async_cx.update(|cx| {
+ let wt = worktree_handle.read(cx).as_local().unwrap();
+ let wd = get_working_directory(wt);
+ assert!(wd.is_some());
+ let path = wd.unwrap();
+ assert!(path.is_dir());
+ assert_eq!(path, test_wd);
+ });
+
+ //Clean up after ourselves.
+ fs.remove_dir(
+ test_wd.as_path(),
+ RemoveOptions {
+ recursive: false,
+ ignore_if_not_exists: true,
+ },
+ )
+ .await
+ .ok()
+ .expect("Could not remove test directory");
+ }
}