I don’t think this is a SD6 bug per se, since the same behavior is observed for both SD6 and SE.
The script runs very fast for any folder EXCEPT my ~/Documents folder.
When I choose it, the script locks up.
I’ve given it several minutes, than have to force quit.
Any ideas on how to fix/avoid?
###ASObjC Script
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
--- SET FOLDER TO SEARCH ---
set folderToSearchPath to POSIX path of (choose folder)
## OR
##set folderToSearchPath to "~/Documents"
### ISSUE ###
# Script locks up on last statement of script if the "~/Documents" folder is chosen by either method.
-- classes, constants, and enums used
set curApp to current application
set NSDirectoryEnumerationSkipsHiddenFiles to a reference to 4
set NSFileManager to a reference to curApp's NSFileManager
set NSDirectoryEnumerationSkipsPackageDescendants to a reference to 2
set nsPath to curApp's NSString's stringWithString:folderToSearchPath
--- EXPAND TILDE & SYMLINK (if any exist) ---
set nsPath to nsPath's stringByResolvingSymlinksInPath()
--- GETS THE NSURL, WHETHER OR NOT THE FILE/FOLDER EXISTS ---
set folderNSURL to curApp's |NSURL|'s fileURLWithPath:nsPath
set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:folderNSURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsPackageDescendants + (get NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
--- GET THE FOLDER CONTENTS ---
### THIS LOCKS UP FOR A LARGE FOLDER LIKE ~/Documents ###
with timeout of 60 seconds -- Doesn't help. Still locks up.
set folderItemList to (theURLs's valueForKey:"path") as list
end timeout
You’re running into the GFL (giant freakin’ list) problem.
On my system there are about 40,000 items found.
The appended script works.
-Chris
------------------------------------------------------------------------------
# Auth: Christopher Stone (adapted from a script by @JMichaelTx)
# dCre: 2017/03/23 22:04
# dMod: 2017/03/23 22:04
# Appl: AppleScriptObjC & BBEdit
# Task: Recursively extract all file and folder paths from the ~/Documents folder and send to BBEdit.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @BBEdit, @Recursively, @Extract, @File, @Folder, @Paths, @Documents, @Folder, @Send
------------------------------------------------------------------------------
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
------------------------------------------------------------------------------
set folderToSearchPath to "~/Documents"
-- classes, constants, and enums used
set curApp to current application
set NSDirectoryEnumerationSkipsHiddenFiles to a reference to 4
set NSFileManager to a reference to curApp's NSFileManager
set NSDirectoryEnumerationSkipsPackageDescendants to a reference to 2
set nsPath to curApp's NSString's stringWithString:folderToSearchPath
--- EXPAND TILDE & SYMLINK (if any exist) ---
set nsPath to nsPath's stringByResolvingSymlinksInPath()
--- GETS THE NSURL, WHETHER OR NOT THE FILE/FOLDER EXISTS ---
set folderNSURL to curApp's |NSURL|'s fileURLWithPath:nsPath
set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:folderNSURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsPackageDescendants + (get NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
set AppleScript's text item delimiters to linefeed
set folderItemList to ((theURLs's valueForKey:"path") as list) as text
bbeditNewDoc(folderItemList, true)
------------------------------------------------------------------------------
--» HANDLERS
------------------------------------------------------------------------------
on bbeditNewDoc(_text, _activate)
tell application "BBEdit"
set newDoc to make new document with properties {text:_text, bounds:{0, 44, 1920, 1200}}
tell newDoc
select insertion point before its text
end tell
if _activate = true or _activate = 1 or _activate = "activate" then activate
end tell
end bbeditNewDoc
------------------------------------------------------------------------------
See NSArray’s componentsJoinedByString: Constructs and returns an NSString object that is the result of interposing a given separator between the elements of the array.
No real need or reason – just testing the script.
It did not occur to me that there would be 10’s of thousands of items.
I don’t use ~/Documents for very much.
OK, stopping the script at the next to last line:
set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:folderNSURL . . .
and adding a count line, takes only 2.39 sec in SD6.
I have 90789 items in my Documents folder!
Wow!
I cannot imagine what they are.
I’ve got to investigate. . .
Per Shane and Chris (above), the issue is the large number of items that can be in one’s ~/Documents folder.
So, I have added a check for number of items, and ask the user to confirm if it is a large number.
###Revised Script
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property _CR : return
property _TAB : tab
--- GET LIST OF POSIX PATHS OF ALL ITEMS IN THE FOLDER & SUB-FOLDERS ---
(*
REF:
1. NSFileManager
https://developer.apple.com/reference/foundation/nsfilemanager
2. NSURL
https://developer.apple.com/reference/foundation/nsurl
REQUIRES:
• use framework "Foundation"
*)
--- SET FOLDER TO SEARCH ---
##set folderToSearchPath to POSIX path of (choose folder)
## OR
set folderToSearchPath to "~/Documents/Test"
### ISSUE ###
# Script locks up on last statement if the "~/Documents" folder is chosen by either method.
-- classes, constants, and enums used
set curApp to current application
set NSDirectoryEnumerationSkipsHiddenFiles to a reference to 4
set NSFileManager to a reference to curApp's NSFileManager
set NSDirectoryEnumerationSkipsPackageDescendants to a reference to 2
set nsPath to curApp's NSString's stringWithString:folderToSearchPath
--- EXPAND TILDE & SYMLINK (if any exist) ---
set nsPath to nsPath's stringByResolvingSymlinksInPath()
--- GETS THE NSURL, WHETHER OR NOT THE FILE/FOLDER EXISTS ---
set folderNSURL to curApp's |NSURL|'s fileURLWithPath:nsPath
set nsItemURLList to (NSFileManager's defaultManager()'s enumeratorAtURL:folderNSURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsPackageDescendants + (get NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
set numItems to nsItemURLList's |count|()
--- IF LARGE NUMBER OF ITEMS, ASK USER TO CONFIRM CONTINUING ---
if (numItems > 1000) then
set msgStr to ¬
"You have a VERY LARGE number of items in your folder:" & _CR & folderToSearchPath ¬
& _CR & "Number of Items: " & numItems ¬
& _CR & _CR & ¬
"Are you SURE you want to proceed?" & _CR & _CR & "It could take many minutes to get the AppleScript List"
set oAns to (display dialog msgStr ¬
buttons {"No", "Yes"} ¬
default button ¬
"Yes" cancel button ¬
"No" with title ¬
"Get Entire Folder/Sub-Folder Contents" with icon stop)
if (button returned of oAns = "Yes") then
--- GET THE FOLDER CONTENTS ---
### THIS LOCKS UP FOR A LARGE FOLDER LIKE ~/Documents ###
with timeout of 60 seconds -- Doesn't help. Still locks up.
set folderItemList to (nsItemURLList's valueForKey:"path") as list
end timeout
end if
end if