By default, the “find” utility returns paths in an order whereby the items within each folder (or “directory”) are sorted by name and each folder path is followed immediately by the paths to the folder’s items. So for an indented display of the names alone, all that’s needed is to substitute a tab for the “root folder” part of each path and a tab for each subsequent slash-terminated element:
set qpp to quoted form of POSIX path of (choose folder)
set txt to (do shell script ("find -f " & qpp & " | sed -E '1 !s:(^.+//|[^/]+/):'$'\\t'':g ;'"))
tell application "TextEdit"
activate
make new document with properties {text:txt}
end tell
The “sed” code above exploits (and depends on) the fact that the input to “find” is the ‘POSIX path’ of the root folder as supplied by AppleScript, which ends with a slash. This causes the paths returned by “find” to have two slashes between their root parts and subsequent elements, making the root parts easy to identify:
Instead of using the regex “.+//”, I could simply have concatenated the root path and a slash into the “sed” code, but let’s be sophisticated here.
It would be nice to have each folder name in the output terminated with a slash, but “find” doesn’t provide that option. One way round this is to get the folder and file paths separately, doctor the folder paths, and then sort the two groups of paths together before doing the tab substitutions.
To ensure that the sort phase reproduces “find”'s order for a full set of paths, it’s necessary first to replace all the slashes with characters whose codes are lower than or equal to the lowest likely to occur in the paths. Tabs seem a good choice. The process then becomes:
¢ Get the folder paths, replace every slash in them with a tab, and append a tab to the end of each path except for the first (the root path).
¢ Get the file paths and replace every slash in them with a tab.
¢ Concatenate and sort the two groups of paths.
¢ Restore the slashes in the first (root) path.
¢ In each of the other paths, replace any tab at the end with a slash, then substitute tabs for the root section (which now ends with two tabs) and for each subsequent tab-terminated section.
The code below does all this and also contains inserts which suppress (or not) paths where any element begins with “.” or is “Contents”. The filtering could be done by “find”, but on the AppleScript principle that it’s better not to give file utilities too much to think about, I’ve given the job to “sed”.
set withInvisibles to false -- 'false' suppresses items where any name in the path begins with ".".
set withBundleContents to false -- 'false' suppresses items where any folder name in the path is "Contents".
set invisiblesInsert to item ((withInvisibles as integer) + 1) of {"/'$'\\t''\\./ d ; ", ""}
set bundleInsert to item ((withBundleContents as integer) + 1) of {"/\\.[^'$'\\t'']+'$'\\t''Contents'$'\\t''?/ d ; ", ""}
set qpp to quoted form of POSIX path of (choose folder)
set txt to (do shell script ("dirs=$(find -f " & qpp & " \\( -type d \\) | sed -E 's:/:'$'\\t'':g ; 1 !s:$:'$'\\t'': ' ;) ; files=$(find -f " & qpp & " \\( -type f \\) | sed -E 's:/:'$'\\t'':g' ;) ; echo \"$dirs\\n$files\" | sort -f | sed -E '1 s:'$'\\t'':/:g ; 1 !{ " & invisiblesInsert & bundleInsert & " s:'$'\\t''$:/: ; s:(^.+'$'\\t\\t''|[^'$'\\t'']+'$'\\t''):'$'\\t'':g ;}'"))
tell application "TextEdit"
activate
make new document with properties {text:txt}
end tell
(* -- Or:
tell application "TextWrangler"
activate
tell (make new text window with properties {text:txt}) to select insertion point before its text
end tell *)