Ideally this would be a view property, but the view controller only expose the content view, which is an NSView instance that does not support the property by default, so we would have to introduce a subclass for this.
This fixes problems with symbolic links, for example file browser may show contents of /private/tmp when we ask to select /tmp/foo.txt. Comparing file path URLs will fail even though /tmp is a symbolic link for /private/tmp.
Note that this fix only works for when the current document is already part of the items in the file browser, as we still store pending URLs to select as file path URLs.
This is for multi-selecting items in the pasteboard chooser and they are stored as auto-generated items and with their history identifiers, so that we can treat them as multiple items.
Previously we stored discontinuous selections as a newline-delimited string, and therefore the individual fragments could not contain any newlines.
Now that we use NSPasteboard’s multi-string support, we no longer have this limitation.
I was using the clipboard history as a testbed for CoreData but my conclusion is that it was not a good fit, and with the API we used now being deprecated, and the clipboard history needing various improvements, it’s easier just to replace the CoreData backend with sqlite3 and offers us more flexibility going forward.
With this re-implementation there is now support for storing multiple strings on the clipboard and the check to see if other applications changed the clipboard should work better (it appears that if an application is changing the clipboard while TextMate is active, sometimes the NSPasteboard’s changeCount is not updated).
It now also stores the history item’s row ID on the pasteboard, so if we select the non-latest history item and relaunch TextMate, it will no longer treat the current item on the pasteboard as a new item.
Incase of a file reference URL, moving an item will have the URL resolve to the new file path, therefore such URL cannot be used for storing the old location/path of the item.
This is currently not a problem with TextMate, as all URLs are file path URLs, but as we are moving to using readObjectsForClasses: with NSURL, we will be receiving file reference URLs from Finder.
Terminal.app is peculiar about what it expects to be on the clipboard. If we only write URLs like this:
[pboard clearContents];
[pboard writeObjects:urls];
Then it will not paste anything. There *must* be string fallbacks for it to support paste. But if we also write an array of strings like this:
[pboard clearContents];
[pboard writeObjects:urls];
[pboard writeObjects:[urls valueForKeyPath:@"path.lastPathComponent"]];
Then it will paste both the URLs and the strings, but where the URLs will be space-separated, the strings will not. If instead we write a single string fallback only for the first item, like this:
[pboard clearContents];
[pboard writeObjects:urls];
[pboard setString:@"whatever" forType:NSPasteboardTypeString];
Then it will paste the URLs and ignore the string fallback for the first URL.
There are no subclasses of this type, so no need to make them virtual, and going forward, we will be refactoring how this API works and subclassing will not be supported.
Currently this just moves constructing the options and LF-separating the strings into the clipboard_t::entry_t, but going forward, we will be able to utilize NSPasteboard’s native support for multiple strings (and avoid storing the “fragments” count).
When CommonAncestor is called with only a single directory then it returns that directory, which meant that searching a selected folder and selecting File Browser → Enclosing Folder would not go up a level (only on second use of this action, would it ascend to the parent folder).
As the CommonAncestor function is used in several places, I didn’t want to change its behavior, but it appears that there are multiple checks in the code to see if “file browser items” only contain a single item, and we just added a new one, so grounds for refactoring.
The reason we were doing a fetch was because it may provide better performance, furthermore, the count returned by the array controller is count of filtered objects, so this change is a slight regression, should be addressed later.
By implementing this, we avoid potentially updating the menu when pressing “menu keys”, which can be slow due to collecting information about system applications, such as supported file types, icon, and display name.
This would happen when opening the menu via the file browser’s action menu, and then using arrow keys in the text view. On my setup, moving the insertion point was slowed down noticeably.
While in theory just a wrapper for VNODE events, there are some edge cases:
- Observe missing file: Report when created (observe all ancestors to know).
- Rename ancestor: Treat as rename (observe all ancestors to know).
- Move observed file to trash: Treat as delete (reported as rename).
- Rename file with symbolic link in path (e.g. /tmp): Preserve symbolic path.
- Delete observed file and write new one: Treat as a write (reported as delete).
- Rename observed file and write new one: Treat as a write (reported as rename).
- Change case of file: Tricky on case-insensitive but preserving file systems because newPath != oldPath but both exist, so it looks the same as “rename and write new file” (previous case) that should be reported as write.
There is also an issue observing a symbolic link, here we should really observe both the link itself (does it get renamed or deleted) but also the resolved path (does this file get updated).
Currently though this is NOT implemented.
We setup a default in default.tmProperties but incase file chooser code is used outside of TextMate then no such default is found, and the file chooser defaults to excluding everything.
This is a subclass of NSTitlebarAccessoryViewController so it can be added directly to windows as an accessory view controller.
It is key/value bindings-compliant for its properties, which should be bound directly to an NSArrayController, which will make the tab bar view reflect the objects managed by this array controller, including updating the tab bar view when object properties such as title or modified state changes.
The property returns NSNotFound when there is no selection. This seems to be consistent with NSArrayController’s selectionIndex (but inconsistent with many other views, like NSTableView, which return -1 when there is no selection).
While AppKit identifiers are generally strings, which have more flexibility, I think this is mainly because NSUUID was introduced later, and for tab items, identifiers must be unique, which is not enforced (or implied) when using strings.