-
Notifications
You must be signed in to change notification settings - Fork 147
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
[WIP] Sidebar/File Navigator #232
Conversation
Very cool @lukakerr, I'll give this a proper look in the next day or so. 🎊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few little nits and observations, but this looks good.
String
vs URL
One general Cocoa thought; it feels like there's a lot of confusion here about whether to represent file paths as String
s or as URL
s. The Cocoa APIs are pretty muddled on this point. The String
APIs are definitely older, and the URL
APIs are preferred. In any case, there are is quite a bit of logic here around jumping back and forth. My personal inclination might be to try and keep things as URL
s as much as possible, and do string conversions only when we need to display things or deal with foreign code / RPC?
Look and feel
There are a few things that I'd like to have before we merge this, most of which I think you're planning/tracking, but it might be useful to enumerate:
- sync between documents in the same window
- A menu item to hide the sidebar
- No sidebar by default when opening a single file
And... that's maybe it?
bigger questions
tabs
Looking at this sent me down a bit of a rabbit hole around how window tabbing works on Cocoa, which I hadn't thought about in a while.
It sure looks like the only way to really get the system tabbing behaviour is to have separate NSWindow instances. I'd be really curious of there was another mechanism.
It would be nice to use the system tabbing stuff. Keeping our own implementation up to date would be annoying. This would require us to think more about what a 'window' is, for us, particularly with regards to split views: it would incline us towards an Xcode-style UI where each tab has multiple splits, instead of each split having multiple tabs. In this world a tab is more like a tab in vim, which has its own collection of open documents.
state, tracking changes, etc
Whatever route we go, having workspaces like this will probably lead us to supporting non-visible open files. This is something we would want to support in UI; some visual cue to the user that some file in the sidebar has unsaved changes, even if it isn't currently displayed.
Anyway, that's just off the top of my head. I think this is a good direction, and I'm excited to see this get merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool, I might actually ditch VSCode if this gets merged, although I have a few observations, besides what @cmyr has already touched on:
- Opening a new folder should show that new folder in the foreground.
- There should be a "view sidebar" menu item, although I think that's already on your mind.
- You should make more use of URL methods, as already commented on by @cmyr, since it's the preferred way going forward from Swift 4.
Other than that, I'm really excited to see this make it into Xi. Glad to have you with us!
What's the status on this? |
The only thing left to do is sync the sidebar structure (which items are expanded/selected etc) across tabs. I haven’t had much time to work on it due to uni work though, but I haven’t forgot about it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some things that need a bit more refining, but I'm really excited with the progress!
XiEditor/SidebarViewController.swift
Outdated
|
||
// Get the document controller and open the selected document into a new tab | ||
if let appDelegate = NSApplication.shared.delegate as? AppDelegate { | ||
appDelegate.documentController.openDocumentIntoNewTab( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just UX stuff, but I think the behavior should be if it's a single click, open in current window and if it's a double click, open in new tab. doubleAction
should work here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nangtrongvuon I thought this would be a good idea too, similar to how Xcode handles it. Although, how would we account for unsaved file changes in a document? The way Xcode does it is that it doesn't save the file and stores the changes in the background, so when the file is reopened, the changes are still there. And if a file has unsaved changes when Xcode quits, the changes get saved automatically. Does xi core support this kind of behavior?
Regarding general UX, one bit that I like in atom is that when I single-click on a file in the sidebar it opens a transient "preview" tab for it, or replaces the current "preview" tab if there is already one. Then, if I make an edit in that file, it turns that into a regular (persistent) tab. If I double-click instead, it opens a persistent tab directly. This is a nice way to avoid an unwieldy number of tabs cropping up quickly, as often I just want to skim through a few files to either find some section of the code or to look up details on something. Of course liberal use of ripgrep and RLS definitions could work to the same effect, but definitions require me to already know an exact name to type and ripgrep requires a context switch to a terminal (and is not necessarily the most intuitive solution for people accustomed to GUIs). Just something that came to mind, perfectly fine with this getting ignored or postponed. |
@lukakerr @cmyr, this is incredible! I'm with @nangtrongvuon, when this gets merged I'll be piloting xi as a vscode/atom replacement. I built the project and have a few usability thoughts. Single click/ Double clickAtom has an interesting strategy for this, the current tab is only replaced when the file previously open was also opened with a single click, otherwise the new file is opened in a single tab. Probably there are two modes for a tab: Sidebar across tabsSidebar state should be synced, and if possible the data structure that indicates the status should be shared. Also, when a new folder is opened in the sidebar, it's default should be expanded. Sidebar hide/showThe animation to show the sidebar cuts off part of the open file before it slides right. Hopefully that's helpful, thanks for all your hard work! |
any update? |
@daleione I've been pretty busy at uni to work on this. That said, I've actually implemented the sidebar structure syncing between tabs in my own editor project Pine. So, i'll try to at least get the conflicts resolved and the sidebar structure syncing working in the next few days. Apart from that, there are still a few minor things to fix up. Notably, the 'replace current document in tab' behaviour (similar to Xcode's behaviour) doesn't exist. This is because xi core doesn't (from my understanding) support file changes in the background without saving the file. So for the meantime, a new tab is created when a document is opened from the sidebar. This behaviour might also need to be worked on to iron the specifics out. |
I'm interested in adding a request to this discussion, although I'm not sure if this belongs in a new feature request: having the file navigator on the right side instead of the left side. The reason I personally like this is because when opening/closing the sidebar, instead of pushing the code to the side or pulling it back, it just cuts off or reveals the "back part" of the code. I'm not sure how hard it would be to implement this, but it would be great if you could choose which side to have your sidebar on :) |
Currently a work in progress with a few things to get ironed out. I thought I'd open this PR just to get some initial feedback and/or suggestions regarding the UI, UX and the overall implementation.
Right now i'm just letting the user choose either a folder or file. If they choose a file, just open it as per usual, if they choose a folder then we render the contents of that folder into the sidebar.
The default system folder icon is being used, and the file icons are the specific icons for that file type using the
NSWorkspace.shared.icon(forFileType: item.fileType)
method. These can be changed to custom icons, along with the disclosure arrows next to the icons.Still Todo
Thoughts on behaviour
Currently when a file is clicked on it opens into a new tab (unless it is already open in the current tab). This mimics apps like Sublime Text and VS Code, although more native apps like Xcode (when tabs are open) open the selected file into the current tab. I'm not sure what a better user experience is, but since files aren't autosaved, opening a file into the current tab may not work the best.
Also, each window/tab has its own instance of the sidebar. This is a side effect of creating a new window per document and not much can be done at the moment about this. As a result, memory usage is increased for each new tab. Although, a singleton is used for the actual sidebar data so the complexity there is reduced slightly.
As discussed in #142 this is just a basic implementation to get a file tree rendering in a sidebar. Changes will probably have to be made later for when/if core gets support for workspaces.
Screenshot of current UI
Closes #142
Closes #156