mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-10-01 16:01:56 +00:00
Merge pull request #932 from l0ng-ai/feat/826-sftp-open-at-cwd
feat(sftp): open the Files panel at the shell's current directory
This commit is contained in:
@@ -13,9 +13,12 @@ second login, no second password.
|
||||
|
||||
## Browsing
|
||||
|
||||
The panel opens on the remote home directory. **Go to Shell Directory** in the
|
||||
overflow menu jumps it to wherever the pane's shell currently is, which is
|
||||
usually where you actually want to be.
|
||||
The panel opens wherever the pane's shell currently is. If tty7 cannot tell
|
||||
(the remote shell does not report its directory), it opens on the last folder
|
||||
you browsed in that pane, or on the remote home directory the first time.
|
||||
Switching between panes with the panel open brings each pane back to the folder
|
||||
you left it on. **Go to Shell Directory** in the overflow menu jumps back to the
|
||||
shell's directory at any time.
|
||||
|
||||
Right-click a row for **Edit** (**Open** on a directory), **Download**,
|
||||
**Follow Symlink**, **Rename**, **chmod…**, and delete. The overflow menu adds
|
||||
|
||||
@@ -429,6 +429,7 @@ impl Tty7App {
|
||||
self.sftp_close_browser(cx);
|
||||
}
|
||||
if !panel_open {
|
||||
self.sftp_panel.panel_was_closed = true;
|
||||
return None;
|
||||
}
|
||||
let width = self.right_panel_px(window, cx);
|
||||
|
||||
+62
-7
@@ -150,6 +150,10 @@ pub(crate) struct SftpPanelState {
|
||||
pub(crate) open_workspace: Option<crate::terminal::PaneWorkspace>,
|
||||
pub(crate) cwd: String,
|
||||
pub(crate) cwds: std::collections::HashMap<u64, String>,
|
||||
/// The side panel has been closed since the browser last opened, so the
|
||||
/// next open is the user asking to look at files again rather than the
|
||||
/// browser following a pane switch. See [`sftp_start_dir`].
|
||||
pub(crate) panel_was_closed: bool,
|
||||
pub(crate) entries: Vec<SftpEntry>,
|
||||
pub(crate) filter_input: gpui::Entity<InputState>,
|
||||
pub(crate) error: Option<String>,
|
||||
@@ -201,6 +205,7 @@ impl SftpPanelState {
|
||||
open_workspace: None,
|
||||
cwd: "/".to_string(),
|
||||
cwds: std::collections::HashMap::new(),
|
||||
panel_was_closed: true,
|
||||
entries: Vec::new(),
|
||||
filter_input,
|
||||
error: None,
|
||||
@@ -444,13 +449,10 @@ impl Tty7App {
|
||||
self.sftp_poll_jobs(cx);
|
||||
self.sftp_start_polling(cx);
|
||||
|
||||
if let Some(start) = self
|
||||
.sftp_panel
|
||||
.cwds
|
||||
.get(&pane_id)
|
||||
.cloned()
|
||||
.or_else(|| self.pane_shell_cwd(pane_id, window, cx))
|
||||
{
|
||||
let fresh_open = std::mem::take(&mut self.sftp_panel.panel_was_closed);
|
||||
let remembered = self.sftp_panel.cwds.get(&pane_id).cloned();
|
||||
let shell = self.pane_shell_cwd(pane_id, window, cx);
|
||||
if let Some(start) = sftp_start_dir(fresh_open, shell, remembered) {
|
||||
self.sftp_navigate(start, cx);
|
||||
return;
|
||||
}
|
||||
@@ -1141,6 +1143,7 @@ impl Tty7App {
|
||||
return None;
|
||||
}
|
||||
if !this.right_panel_open(cx) {
|
||||
this.sftp_panel.panel_was_closed = true;
|
||||
this.sftp_close_browser(cx);
|
||||
return None;
|
||||
}
|
||||
@@ -1976,10 +1979,61 @@ impl Tty7App {
|
||||
}
|
||||
}
|
||||
|
||||
/// Where the browser starts when it opens on a pane.
|
||||
///
|
||||
/// Opening the panel afresh is a request to see where the shell is now, so the
|
||||
/// shell's directory wins over wherever the browser was left last time. When
|
||||
/// the browser instead follows a pane switch with the panel still open, the
|
||||
/// user never left it, so the directory they were browsing there comes back.
|
||||
/// Either falls back to the other; `None` means neither is known and the
|
||||
/// caller goes to the login directory.
|
||||
fn sftp_start_dir(
|
||||
fresh_open: bool,
|
||||
shell_cwd: Option<String>,
|
||||
remembered: Option<String>,
|
||||
) -> Option<String> {
|
||||
if fresh_open {
|
||||
shell_cwd.or(remembered)
|
||||
} else {
|
||||
remembered.or(shell_cwd)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_fresh_open_starts_at_the_shell_directory() {
|
||||
let shell = Some("/srv/app".to_string());
|
||||
let last = Some("/var/log".to_string());
|
||||
assert_eq!(
|
||||
sftp_start_dir(true, shell.clone(), last.clone()).as_deref(),
|
||||
Some("/srv/app")
|
||||
);
|
||||
assert_eq!(
|
||||
sftp_start_dir(true, None, last.clone()).as_deref(),
|
||||
Some("/var/log"),
|
||||
"no shell cwd (no shell integration) falls back to the last browsed"
|
||||
);
|
||||
assert_eq!(sftp_start_dir(true, None, None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_pane_switch_returns_to_the_directory_browsed_there() {
|
||||
let shell = Some("/srv/app".to_string());
|
||||
let last = Some("/var/log".to_string());
|
||||
assert_eq!(
|
||||
sftp_start_dir(false, shell.clone(), last).as_deref(),
|
||||
Some("/var/log")
|
||||
);
|
||||
assert_eq!(
|
||||
sftp_start_dir(false, shell, None).as_deref(),
|
||||
Some("/srv/app"),
|
||||
"a pane never browsed starts at its shell directory"
|
||||
);
|
||||
}
|
||||
|
||||
fn upload(job_id: u64, state: SftpJobState) -> SftpJobProgress {
|
||||
SftpJobProgress {
|
||||
job_id,
|
||||
@@ -2243,6 +2297,7 @@ mod gpui_tests {
|
||||
use gpui_component::input::InputState;
|
||||
|
||||
fn harness(cx: &mut TestAppContext) -> (Entity<Tty7App>, VisualTestContext) {
|
||||
crate::core::config::pin_test_config_dir();
|
||||
cx.executor().allow_parking();
|
||||
cx.update(|cx| {
|
||||
gpui_component::init(cx);
|
||||
|
||||
Reference in New Issue
Block a user