CodeEdit
CodeEdit copied to clipboard
✨ Remember Workspace State Per Window
Describe the solution you'd like
We need to persist workspace state per window after the user quits and opens CodeEdit again.
We will need to also remember
- [x] editor layout
- [x] for each editor
- [x] size (width/height where applicable)
- [x] which tabs/files are open
- [x] which tab is active
- [x] order of tabs
- [ ] the navigator, inspector, and utility areas
- [ ] size (width/height respectively)
- [x] navigator area
- [ ] inspector area
- [ ] utility area
- [x] opened/closed state
- [x] navigator area
- [x] inspector area
- [x] utility area
- [ ] which tab is active
- [ ] navigator area
- [ ] inspector area
- [ ] utility area
- [ ] order of tabs
- [ ] navigator area
- [ ] inspector area
- [ ] utility area
- [ ] size (width/height respectively)
Related
- #904
- #882
@Code-DJ would you be able to look at this?
As this is a View-related problem, I'd suggest looking into using SceneStorage instead of storing this state in the NSWindow instance.
@Code-DJ would you be able to look at this?
Yes I can take a stab at it. I assume, right now, Workspace = Open Folder, so all the settings need to saved by an identifier = "path of the folder".
Note: I am new to Apple API - so Wouter01 pointing to SceneStorage already helps.
@Code-DJ would you be able to look at this?
Yes I can take a stab at it. I assume, right now, Workspace = Open Folder, so all the settings need to saved by an identifier = "path of the folder".
Note: I am new to Apple API - so Wouter01 pointing to SceneStorage already helps.
That's indeed a good idea. I'd split it up in a few SceneStorage variables. For example, You could save the workspace navigator state as @SceneStorage("navigatorFolder\(url.path())") var isOpened: Bool. This way, if another SceneStorage variable will depend on the URL, there won't be conflicts
That is a good question, should we use the path as the workspace identifier? What if the user renames a parent directory? What if we decide later down the road (like VS Code) that we want to support multiple folders per workspace.
This can be a later discussion and we can use the path as the identifier for the time being but I did want to point that out.
That is a good question, should we use the path as the workspace identifier? What if the user renames a parent directory? What if we decide later down the road (like VS Code) that we want to support multiple folders per workspace.
This can be a later discussion and we can use the path as the identifier for the time being but I did want to point that out.
We can assume the user doesn't rename it. If he/she does, the window frames will be reset, but it's not a huge deal. I think the project won't even appear in the recent items list anymore. You don't really have another way of doing it.
I'd guess if you want multiple folders in a workspace, you'd need to create a workspace with the parent folder of both.
Here are my thoughts:
- The key for
SceneStoragewill be the "path to the workspace folder" - Is there still uncertainty about this? - save all settings in
Dictionary<String, Any>inWorkspaceDocument. - add two new methods to
WorkspaceDocument-writeToSceneStorage,readFromSceneStorageneed better names, this will allow views e.g.InspectorSidebarto read on init and write on change. - restore values from
SceneStorageinWorkspaceDocument.initWorkspaceState. - save the dictionary to
SceneStoragein a new methodWorkspaceDocument.saveWorkspaceState. - call
WorkspaceDocument.saveWorkspaceStatefromWorkspaceDocument.write.
In addition to the above, do we need to periodically save state (in case the user keeps CodeEdit open for days)?
Is it somehow possible to bind everything to this state? The state should be saved when anything changes.
It looks like SceneStorage automatically does the saving and restoring of the state - I am not sure when it does that - for details see the link below.
Based on this, it appears we don't need to do any of initWorkspaceState and saveWorkspaceState stuff I mentioned above.
If we prefix the dictionary variable with @SceneStorage(url) var viewState = Dictionary<String, Any>(), it may just work. @Wouter01 any thoughts?
Taken from SceneStorage Example
struct DevTechieSceneStorageExample: View {
@SceneStorage("name") var name = ""
@SceneStorage("email") var email = ""
var body: some View {
NavigationStack {
Form {
Section(header: Text("Personal Information")) {
TextField("Enter name", text: $name)
TextField("Enter email", text: $email)
}
}
.navigationTitle("DevTechie")
}
}
}
Maybe we save on window/app close then?
@austincondiff I didn't realize this was ready for me. Can you assign it to me. Thanks!
Here are my thoughts:
The key for
SceneStoragewill be the "path to the workspace folder" - Is there still uncertainty about this?save all settings in
Dictionary<String, Any>inWorkspaceDocument.add two new methods to
WorkspaceDocument-writeToSceneStorage,readFromSceneStorageneed better names, this will allow views e.g.InspectorSidebarto read on init and write on change.restore values from
SceneStorageinWorkspaceDocument.initWorkspaceState.save the dictionary to
SceneStoragein a new methodWorkspaceDocument.saveWorkspaceState.call
WorkspaceDocument.saveWorkspaceStatefromWorkspaceDocument.write.In addition to the above, do we need to periodically save state (in case the user keeps CodeEdit open for days)?
Apologies for the late response, I must've missed your mention. Regarding SceneStorage, it's meant to be used in SwiftUI views only. On second thought, this may not play well with the current state of the app. I don't know if there's an appkit alternative, or if you had figured it out already?
What I can tell though, in my test build with the SwiftUI lifecycle, lots of this is done automatically, liking saving the sidebar and inspector width. Other things, like the state of the file navigator, won't be saved automatically, as these are done in AppKit. Maybe it's worth a try looking into those first?
Is it somehow possible to bind everything to this state? The state should be saved when anything changes.
You can see SceneStorage as a variant of AppStorage, except it's done for a window instance instead of the whole app. SceneStorage will load the precious data in automatically, and will save new data automatically. No need to worry about when to save it.
Important to notice:
If the Scene is explicitly destroyed (e.g. the switcher snapshot is destroyed on iPadOS or the window is closed on macOS), the data is also destroyed.
from: https://developer.apple.com/documentation/swiftui/scenestorage