The auto-calculated key view loop includes everything, which means dynamically added elements such as the close buttons for tab view items, but worse, the subviews of a view-based table view. So this change is required before switching to a view-based file browser.
It seems that after the field editor has been dismissed, the first responder reverts to the outline view (file browser), even though we are asked if we accept first responder.
So now we simply check if we are already first responder, and that seems to work just as well (for clicking on an outline view row while the field editor is showing).
In theory we should include all instance variables, but we only use this check to see if we need to cause a file browser reload (when a row is being edited) and long-term (when we switch to NSTableCellView) most changes can be done without needing to reload the file browser items.
This way it is possible to bind an image view’s value property directly to FSItem’s icon and not worry about having to manually trigger a redraw when the SCM status changes.
Handling return was to prevent that key to move to editing the next row, though it does not seem to have this behavior anymore.
Backtab was to support editing the row above, though Apple has a defined behavior for how tab/backtab should work when editing table view items, so we shouldn’t change that.
It’s important that URLs pointing to the same path are testing as equal, which previously could fail because NSURL doesn’t use ‘localhost’ in its file URLs.
We no longer select items that the delegate tells us are non-selectable (header items) and we no longer deselect when right-clicking outside selectable items.
We now subclass NSOutlineView to detect recursive expansion/collapsing rather than look at the current event (and testing for option). This should be more reliable, for example previously using drag’n’drop with option could falsely trigger recursive expansion.
The way background folder content is loaded is also made simpler with a fairly straightforward code flow (thanks in part to the use of blocks) without the need for “pendingXYZ” variables that got checked at somewhat arbitrary times (to see if we needed to expand/select items that got loaded).
This also better tracks expanded items, as we now remove items that are collapsed from the session info the minute they are collapsed, rather than take a snapshot of the outline view during application termination. This should close#1111.
Another improvement is that we wrap item updating in begin/end update calls to get animated expansion of folders.
There are still a few issues, for example switching to using the view-based API for the outline view and handling reloading items while the field editor is up (which I think require the former).
Also, this commit does not change the data source API so there is some redundant work being done, as we request a reload after getting a “did reload” notification.
All code has been moved to the FSItem subclass.
The advantage is that bookkeeping becomes easier, for example no need to explicitly unregister paths (instead we can do that in the destructor).
The disadvantage is that sharing resources between items becomes harder, for example all (expanded) folders track file system and version control changes, though the existing code only accidentally shared these resources for identical paths, and it actually lacked a tracking system for retain counts.
If you dislike the downscaling of the line numbers then run the following in a terminal:
defaults write com.macromates.TextMate.preview lineNumberScaleFactor -float 1
This must be set in the spelling panel and changing language via the spelling panel does not update the buffer (recheck the text with the new spelling language), so toggle automatic spelling after using the spelling panel to change language.
Closes#1139
This would happen if dragging a tab into an unmodified document (in the same window) while holding down control (to insert the path of the dragged tab).
Here the document would change state to “modified” which would trigger a tab bar view reload, but since the drag session isn’t completed, we reload the tabs while one of them is “outside” the bar, which causes it to be added, and once the drag session completes, the original tab outside the bar, will be re-added, leading to two copies of the same tab.