zed-industries / zed

Code at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
https://zed.dev
Other
51.04k stars 3.17k forks source link

Terminal: Go to Recent Directory #17840

Open tannal opened 2 months ago

tannal commented 2 months ago

Check for existing issues

Describe the feature

Vscode have a stack which store all the directories user changed. It is very useful for navigating working directory in the terminal.

If applicable, add mockups / screenshots to help present your vision of the feature

image Ctrl+g

tannal commented 2 months ago

Well, I do want to implement this feature for zed but don't know where to start with.

notpeter commented 2 months ago

Gotcha, in VSCode "Terminal: Go to Recent Directory" is bound to cmd-g (Mac). For reference, what's the Linux shortcut?

I haven't used the feature, does it just suggest recent folders from your project or does pull out recent directories you've manually entered via typing cd whatever in terminal too?

tannal commented 2 months ago

It's ctrl-g on Linux and Windows. image

does pull out recent directories you've manually entered via typing cd whatever in terminal too?

Yes.

notpeter commented 2 months ago

does pull out recent directories you've manually entered via typing cd whatever in terminal too?

yes

Interesting. I think Zed would have to monitor the shell subprocess to keep track of this. On Linux this could leverage inotify on /proc/<pid>/cwd but on MacOS I think Zed would have to periodically poll for this info from the child process with proc_pidinfo.

SomeoneToIgnore commented 2 months ago

Zed already does

https://github.com/zed-industries/zed/blob/444115080994413215680f5a43cdf6b5d61cc32d/crates/terminal/src/terminal.rs#L682

where AlacTermEvent::Wakeup is an event appearing on new terminal content.

cwd is retrieved via

https://github.com/zed-industries/zed/blob/444115080994413215680f5a43cdf6b5d61cc32d/crates/terminal/src/terminal.rs#L710-L712

so all that's needed is to store and update this info somehow. Similarly, we can reuse this to restore terminals with their current paths.

SomeoneToIgnore commented 2 months ago

Similarly, we can reuse this to restore terminals with their current paths.

In fact, it is present already:

https://github.com/zed-industries/zed/blob/689da9d0b1b8ff32ebecdd2dbe8d5c93b4c7a3bf/crates/terminal_view/src/terminal_view.rs#L1147-L1151

https://github.com/zed-industries/zed/blob/689da9d0b1b8ff32ebecdd2dbe8d5c93b4c7a3bf/crates/terminal_view/src/terminal_view.rs#L1172-L1180

so it seems that we can adjust serialize contents to store more data in &mut self: we need to keep some LRU-based order there, deduplicated and having its number of elements limited. No need to alter sql schema and persist this new state, keeping it in memory seems to be enough.

After we've done it, we can add another action to the terminal view here: https://github.com/zed-industries/zed/blob/689da9d0b1b8ff32ebecdd2dbe8d5c93b4c7a3bf/crates/terminal_view/src/terminal_view.rs#L73

and open a picker, similar to what is done in e.g. recent projects here: https://github.com/zed-industries/zed/blob/689da9d0b1b8ff32ebecdd2dbe8d5c93b4c7a3bf/crates/recent_projects/src/recent_projects.rs#L132-L143

In our case, candidates is static, received from the terminal view, and all we need is to match over that, similar to how any other picker is doing it in the update_matches.

We can pass a WeakView<TerminalView> inside such delegate and get the terminal instance, but the main question would be "how to switch the directory?". We cannot really input cd /abs/path/from/selected/item enter as terminal could have some unfinished prompt or even some program like Vim running in that moment. Should we also somehow try to restrict when such "go to previous directory" modal appears?

tannal commented 2 months ago

We can issue a ctrl-c then input cd xxx in the terminal.(This is what vscode does and works in most of the cases) For a terminal that has vim running, this method would be broken. I think that's fine, users can easily understand why this don't work.