Previously we only looked at the last caret, and if this one was not a selection then we would treat the multiple carets (selection ranges) as nothing being selected, and thus, a command replacing the carets, would not leave anything selected.
When pasting or using Filter Through Command with multiple carets, we ignore a potential final empty line, this is because our text will be something like “foo\nbar\n” and we split on the newline, so we end up with (“foo”, “bar”, “”) and if we have more than two carets, then we insert the empty string for every third caret.
For a command though we expect there is a 1:1 between number of carets and newlines in the result, so we should never skip the last element.
The problem is if we right-click an item that causes content to be changed (e.g. Show Enclosing Folder) then later in the same run loop cycle ask for selected items, we prefer the clicked row, but this one might now no longer exist.
The view passed to the file manager is used to request the undo manager. The problem with using an NSTableCellView instance is that this view may be taken out of the view hierarchy (and thus responder chain) which makes it lose its undo manager.
This isn’t an immediate problem but if we later use undo/redo, it might be.
This way we only have to abort editing if the item being edited is going away.
View-based table views do not supported editedRow so this commit also change the way to figure out if a row is being edited.
Previously if we deleted an expanded folder it would select the first child of this item which would then be removed and leave nothing selected.
There are still a few edge-cases left though where what’s selected after deleting items is not ideal.
We previously did this when the background style was set to dark, but the code for this only works when the view is a direct descendent of the NSTableCellView and also, when a row is selected in an inactive table view, the background style is not set to dark.
The comparison is somewhat shallow, but ideally all changes to the actual items (rather than adding or removing items) is done by updating the properties of the existing instance. The exception here is the SCM Status data source, but FSItem’s isEqual: method does compare scmStatus.
One issue with the view-based version is that there seems to be no hook where we can update the text prior to edit, so in the SCM Status view where item names are disambiguated, editing the item will cause the disambiguated name to be used as basename.
The view-based version is also more eager to start editing rows, for example the “click a selected item to move focus to file browser” now also trigger renaming of that item, which is rather undesirable.
A few other pending issues also remain, like better rendering of labels, not adding a (hidden) close button to each row, and ensuring FSItem instances are re-used when possible (e.g. SCM data source).
The way we mark items as modified or open is also suboptimal, as it’s partly done via bindings and partly manual.
I’m not sure if it is necessary to manually refocus the outline view after aborting the field editor, does seem like a bug and will most likely not be present for view-based outline views.
If the file browser’s root path is already a parent of the item we want to reveal (and a descendent of the requested parent) then we skip changing path.
This simplifies the code (API) and also allows us to skip having to select the clicked item, as the outline view will handle this for us (using a “special” selection indication that can work in parallel with regular selection).
If the button gets hidden while the mouse is hovering above it then it’ll not receive a mouseExited: message once the mouse leaves its bounds (while the control is hidden).
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.