-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore previously closed session's state (Buffer contents) #961
Comments
I think there are possible security considerations with this. With that in mind, making restoring previous output seems an opt-in rather than opt-out feature seems prudent. On Windows of course if the user's profile is BitLocker-protected, maybe it's less of an issue, but regardless worth considering. I did enjoy this feature of Terminal.app for the few years I used a mac some time ago. |
Firstly, welcome to github and the terminal project, @BEAClerbois! Just adding to the record some of the information @zadjii-msft is referring to, I tried to implement save/restore of state as part of Yori, which is a CMD-like shell. This was opt-in due to the security/privacy issue that @binarycrusader mentioned, and is enabled with an environment variable. See http://www.malsmith.net/yori/guide/#env_yoriautorestart . In that context, save/restore meant saving both terminal state as well as shell state. Terminal state includes things like the size and position of the window, its contents, colors, and fonts. Shell state includes things like current directory, environment, and in this case, aliases and command history. But the real challenge is how to reason about multi-process relationships. One example was given previously: suppose the user launches a CMD window, and within that launches Powershell. Even if both A clearer example of the same effect would be opening CMD and within that executing "vim foo". The terminal will know about the existence of the vim process, but the meaning of "foo" depends on the current directory that vim was launched from, and that information has to come either from vim or from the parent process, and CMD needs to wait for vim. Recovering things accurately would require coordination from three different programs. When the multi-process relationship is outside the console, things get messier still. The specific case that affected Yori users which I couldn't see how to handle is the Virtual Filesystem for Git agent, because launching a shell with a correct current directory does not mean the user can interact with the files there unless the agent is running. But the agent can be launched via any mechanism which may be completely unrelated to the console, so there's no knowledge indicating it must be restored. In the context of restoring a recently closed tab this may not be so problematic. Obviously this is in addition to restoring state which depends on OS configuration which may not be present - having network shares, authentication, a particular IP address, a USB device attached - things that might change between attempting a save and a restore. |
Thanks @malxau for the great explanation. As we can see, restoring shell state is a neigh-impossible thing to do totally correct (and why I wanted this to have it's own thread separate from #766). However buffer content is not impossible to restore. Lets make it opt-in, in addition to opting-in to general window state restore being tracked in #766. |
After sleeping on it, I started remembering even nastier cases about process relationships. Consider pipes: "type foo | more" means saving the state of the "type" command and the "more" command and somehow recreating the pipe. This looks like another cyclic dependency: pipes are normally created by the parent, which carefully hands one end to the child and closes it; but here we need some kind of resumable identifier that describes a pipe between two processes and can recreate that. The "type" command, in turn, needs to know where it was within its source stream to resume from; in this example with a source file that's at least possible. When the source stream is dynamic, finding that point becomes somewhat meaningless. Suppose the command was "tasklist | more" - where should tasklist resume from? Its source stream has completely changed. Agree with "neigh-impossible", and this feels like something where if we tried to solve it, it would end up being Windows-specific and a large part of the terminal effort is better interoperability with other platforms. It seems to me like if there was a push to solve this on other platforms we can contribute to the conversation, but going it alone doesn't seem like the right thing to do. Users would be left with an experience that only works for some programs, some of the time. |
@malxau While all the complications make saving state difficult, I don't feel simply saving the tabs, tab names, panes, and their respective directories should be relatively simple. Having different session setups could also be possible as an argument to wt, for example I could type win+r Thinking about the above suggestion, it may be easier to add a section to the options JSON that let's users describe a session layout. |
@jamieghassibi How would the terminal obtain the directory that is active within the shell processes? I can see how this would work if the session is defined in config, but to capture the current state into the config still sounds like it's depending on capturing state from the terminal and from all of the command line processes executing within it. |
I would like to see allowing a definition of tabs to be opened on startup (much like other Windows terminal applications). As far as restoring state, I accept what happens in the terminal to be volatile. If I want the output, I capture it with the commands executed. |
It would be great if the Terminal could remember:
The actual contents of the buffer are not as important. When I restart my computer or accidentally close the Terminal app, I just want to get back to where I was as quickly as possible. |
@nmoinvaz So those two might be generically impossible for the Terminal to solve.
|
To me, this is just like how browsers allow for reopening tabs. In fact, a terminal kinda is a browser. And while restoring the session might not be easy, restoring the path (and things like the tab title: https://docs.microsoft.com/en-us/windows/terminal/tutorials/tab-title) definitely |
I'm surprised that nobody has mentioned that yet, but iTerm2 for macOS does pretty much what one would expect from such a feature. It's one of the very few things that I miss from the Mac on Windows. The GitHub project: https://github.com/gnachman/iTerm2 |
Now I am not really an OS specialist, but I think iTerm2 is not really a good example as it goes back to macOS which basically only has to hold sessions that go back either to zsh or bash. I think Terminal has to fill much more gaps because under a Windows there is an extremely broad spectrum of terminal sessions possible starting from MinGW sessions, Cygwin sessions, bash sessions, Powershell sessions, CMD sessions (which even don't really have a state and you would need to work around lots of things if it's even possible to save the CMD buffer separately). So I think that request is a whole other beast than what iTerm2 has to fulfill. For Windows you need to compare to a completely other set of shells like e.g. Babun which has been discontinued, cmder or MobaXterm. Lots of these shells base on the initial work that has been done with ConEmu. If you look to all these shell's issue collections you will find out that there have been happening lots of struggles around lots of issues. And the chorus is that some of these shells specialized only on a possible subset of possible shells like e.g. Cygwin sessions or SSH sessions.... Please correct me if I am wrong. |
I know that I don't know enough -- by a long shot -- to correct you or to tell you that you're wrong :) However, sometimes perfect can be the enemy of good (or better). Tools that have to work with a multitude of environments sometimes support features only for a subset of supported environments. If Terraform, for example, only supported features that are supported by all cloud environments it supports, it would not be very useful. Sometimes it makes sense to support features only for a subset of supported environments. In this case, if it can be done, say, for Bash and PowerShell, that would be a huge win for many if not most (or even an overwhelming majority of) users. (FWIW, iTerm2 supports tcsh, zsh, bash, and fish.) |
Agreed! Please consider partial support. |
Just expressing my use case: As an IT Pro, I frequently have 8-10 PowerShell 5.1 or 7+ tabs open in terminal. I don't "pre-plan" what's going to happen in these tabs, and I don't waste time customizing each tab with titles or colors. I just open them as I need them to work on different tasks/projects in parallel. So "losing" the content of these tabs when I come back to my PC when either the PC has restarted for Windows updates, or Terminal has mysteriously restarted (I assume for a forced update of some sort?) is very disruptive. All of this would be solved (for me personally) if only the buffer contents would be restored, as I could easily look and see what I was doing last in each tab and what the most recent command output was. To a lesser degree, restoring the tab's "local" command history would suffice as well, as I could then just use the up arrow to see what the last command was in any given tab. Currently when these Terminal restarts happen, the number, position, and client of each tab are successfully restored, but that is not enough to get me back on track. Ostensibly I could manually customize the title of every tab just in case this happens, which might help a little, but even then it wouldn't tell me exactly what I was doing in that tab or what state I had left that tab's task in. Plus, during a work day I will have opened and closed dozens (maybe hundreds) of tabs, so customizing tabs just in case would be a huge waste of time. Restoration of the buffer/command history is really what's needed. |
Re mmseng's comment:
For me, it's more the buffer than the command history. The buffer contains the output and the commands. If the output of a command changed over time, rerunning the commands might not help getting the information back about what happened. Lateral thought: an on-disk rotating buffer with a maximum lifetime (24h? configurable?) on disk for every tab that contains everything visible on screen would be helpful, too, and would give me most of what the feature of this issue could give me. |
Wholeheartedly agreed. The buffer is far more important; I would even go so far as to call it precious. At the risk of repeating drama from above, from an outside perspective, either item seems relatively simple (compared to something like preservation of state), as both buffer and command history are mostly just plain text and the rendering thereof. The command history implementation already even lends itself to this purpose, since you can technically manually edit it. I know it's always way more complicated than it seems; I only mentioned the above because, as much as I'd like to see this implemented for the good of all, I would personally be willing to implement a custom solution that, at the very least, dumped buffer history to a file along with some sort of identifier as to the tab it belonged to (e.g. name the file after the tab title and date), if it allowed me to recover my work in these instances. Of course, I would have no idea how to develop such a hack myself, and the logic for when to dump that data does not immediately come to mind. |
Is this being worked on? |
Yep, I believe @lhecker's been working on this for a bit now. #8771 was more specifically a PR to implement #766. This issue is more specifically "restore buffer contents", while #766 was more generally "restore various elements of the Terminal's state". #8771 ended up resurrected as #10513 which then was used by #10972 to store the window position, size (but notably, not the buffer content) |
This changeset allows Windows Terminal to dump its buffer contents as UTF-16LE VT text onto disk and restore it later. This functionality is enabled whenever `persistedWindowLayout` is being used. Closes #961 Closes #16741 ## Validation Steps Performed * Open multiple windows with multiple tabs and restart the app Everything's restored ✅ * Reopen a tab with output from `RenderingTests.exe` Everything's restored ✅ * Closing tabs and windows with Ctrl+W deletes their buffer dumps ✅ * Closing tabs doesn't create buffer dumps ✅
@zadjii-msft Did you know how to use this feature? |
This only just merged hours ago, so it's not available yet outside of just building the code from It should be enabled if you have |
Is this supposed to be available in 1.20.11381.0? When I have the |
Nope. This was added in 1.21. |
I've been using it in the 1.21 Windows Terminal Preview. It does work as expected (for a certain definition of expected), however the vast majority of the times when I need it is when Windows updates reboot the machine, or when the machine otherwise reboots while Terminal is open, and from what I've seen I don't believe it's been working in these cases (I haven't been tracking it closely enough to make a more confident statement). As I recall, the failure due to Windows update reboots is an open issue. |
this thread is so Windows. I don't mean to throw any shade at the devs and designers here, it's just that feeling of "@#(^#@^&" when my OS knocks me down with nagging and unwanted reboots only to hit me again by stealing more of my time, for years and years while my macs have never once hurt me this way. My mac picks me up when I'm down (<3 u my silver fox) But seriously the comment above regarding that bastard known as perfection is 100% right. I mean, at least you can stop worrying about privacy, right? we've all used 11. ...well thanks for the hard work, that should serve as catharsis for now. |
Lets talk about restoring the state of the terminal here.
This could arise in two scenarios I'm thinking of:
1 is certainly harder than 2.
Restoring the buffer contents wouldn't be impossible, but restoring the actual state of the running executable might be impossible. IIRC @malxau has a long email from his work on yori that is relevant to this discussion.
We could certainly restore the buffer contents from file, then display some sort of message saying [Restored from previous session]. That's not that hard.
The text was updated successfully, but these errors were encountered: