This was previously placed in the file browser’s action menu and thus probably overlooked by many, even though ⇧⌘A is a very useful key equivalent, since many commands work on the entire project when there is no selection in the file browser.
Majority of the time in the main thread was spent updating the countOfLeafs property since canReplaceAll and the result text are dependent on this property.
Unfortunately disabling the “Delete” button is cumbersome because our history is stored with CoreData so knowing the number of items in the history requires a fetch request, which we would not know when to re-run (to update the disabled state when the history is changed).
When the filter string is empty we can use the array controller’s results, but I’m leaving that for the future.
Technically we are unable to delete the pasteboard’s current item so “Clear All” was performing a “Clear All Minus One”. While the new label does not make this clear, it at least does not promise to clear everything.
This serves to make the code slightly more abstract and allows the document to optimize the comparison operator, e.g. testing pointer equivalence before involving more complex checks.
We do not display this counter during the search but triggering a KVO notification for each search result has a noticeable overhead and can result in unresponsive UI when the number of results are in the hundreds of thousands.
This is significantly faster on OS X 10.11.
The API is slightly different so this is probably still faster in macOS 10.12 where there should be less of a performance difference between using Foundation and CoreFoundation.
This relates to documents with many matches on the same (long) line.
Previously we would search for “end of line” per match found, which for a single-line document was effectively quadratic time complexity.
Furthermore we would make a string copy of the entire line for every match. This is now limited to 500 bytes (or longer if the match requires it) with the context before the match being up to 150 bytes (it’s using modulo so adjacent matches should generally show context starting from the same offset).
The test case for the optimization was a 3MB file with only 2 lines and 150,000 matches. After this commit the results are presented in about two seconds (Macbook Pro). Not impressive but much better than before :)
Both of these objects may observe the buffer owned by the document, so we should be sure the observers are gone since closing a document may delete its buffer.
The Navigate menu now contains a mixture of items with prefixes "Jump to", "Go to" or none at all. The "Go to" prefix is especially inconsistent since we have already have a dedicate "Go" item in the Main menu bar. For consistency, change them to use the "Jump to" prefix.
The commit also renames the appropriate dialog boxes and updates some documentation to refer to the new names.
When building with Xcode 8 beta (on my system at least), clang produced the following warning:
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of OS X 10.9
It appears clang will link with libstdc++ if present by default instead of libc++. This was verified using `otool -L bundles.dylib` which produce the following output prior to this change.
bundles.dylib:
@rpath/bundles.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/OakSystem.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/io.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/plist.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/regexp.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/scope.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/text.dylib (compatibility version 1.0.0, current version 1.0.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
With this change the output is now:
bundles.dylib:
@rpath/bundles.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/OakSystem.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/io.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/plist.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/regexp.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/scope.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/text.dylib (compatibility version 1.0.0, current version 1.0.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
Previously this was done by exposing iterators but for this to go into the abstract base class we sort of need abstract iterators and that is too complex and visitor interface is sufficient for our single use case.