Listing directory contents

This came up elsewhere, but the code might be useful for people here too. It’s what I use when I want to check the contents of a complex folder hierarchy.

The resulting .rtf file is saved in your tmp folder, and opened in your default editor for .rtf files. File names are in blue, folder names in red, with the rest of the path in light gray. Change the value of the fullPaths property depending on whether you want to see the full paths or not. It’s best run from a scripts menu, like the built-in one or FastScripts.

It requirs 10.10, although you could put it in a Script Library and use it under 10.9.

use AppleScript version "2.4" -- 10.10
use scripting additions
use framework "Foundation"
use framework "AppKit"
property fullPaths : false -- set to true to list full paths rather than relative paths

tell application "Finder"
		set theTarget to target of Finder window 1 as alias
	on error
		error number -128
	end try
end tell

-- make URL
set targetURL to current application's |NSURL|'s fileURLWithPath:(POSIX path of theTarget)
if not fullPaths then set targetLength to (targetURL's |path|()'s |length|()) + 1 -- use to trim paths
-- set up destination path
set tempPath to POSIX path of (path to temporary items)
set destURL to ((current application's |NSURL|'s fileURLWithPath:tempPath)'s URLByAppendingPathComponent:(targetURL's lastPathComponent()))'s URLByAppendingPathExtension:"rtf"
-- set up paragraph style for line-spacing
set parStyle to current application's NSParagraphStyle's defaultParagraphStyle()'s mutableCopy()
parStyle's setLineHeightMultiple:1.3
-- set up font
set theFont to current application's NSFont's fontWithName:"Menlo-Regular" |size|:14.0
-- set up colors
set fileColor to current application's NSDictionary's dictionaryWithObject:(current application's NSColor's blueColor()) forKey:(current application's NSForegroundColorAttributeName)
set folderColor to current application's NSDictionary's dictionaryWithObject:(current application's NSColor's redColor()) forKey:(current application's NSForegroundColorAttributeName)
set lighterColor to current application's NSDictionary's dictionaryWithObject:(current application's NSColor's lightGrayColor()) forKey:(current application's NSForegroundColorAttributeName)
-- define base style from above
set baseStyle to current application's NSMutableDictionary's dictionaryWithObjects:{theFont, parStyle, -0.1} forKeys:{current application's NSFontAttributeName, current application's NSParagraphStyleAttributeName, current application's NSExpansionAttributeName}
baseStyle's addEntriesFromDictionary:lighterColor
set styledLinefeed to current application's NSAttributedString's alloc()'s initWithString:linefeed attributes:baseStyle

-- set up styled string
set theStyledString to current application's NSMutableAttributedString's new()
theStyledString's beginEditing()
set theString to current application's NSString's stringWithFormat_("Listing of %@, %@" & linefeed & linefeed, targetURL's |path|(), ((current date) as text))
set styledPath to (current application's NSAttributedString's alloc()'s initWithString:theString attributes:baseStyle)
theStyledString's appendAttributedString:styledPath
theStyledString's addAttributes:folderColor range:{0, theString's |length|()}
-- get all items in folder
set dirKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set theFileManager to current application's NSFileManager's defaultManager()
set theEnumerator to theFileManager's enumeratorAtURL:targetURL includingPropertiesForKeys:{dirKey, packageKey} options:((current application's NSDirectoryEnumerationSkipsHiddenFiles) + (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer)) errorHandler:(missing value)
repeat with anItem in theEnumerator's allObjects()
	-- flag for file status
	set isFile to true
	-- is it a directory?
	set {theResult, theValue, theError} to (anItem's getResourceValue:(reference) forKey:dirKey |error|:(reference))
	if theValue as boolean then
		-- is it a package?
		set {theResult, theValue, theError} to (anItem's getResourceValue:(reference) forKey:packageKey |error|:(reference))
		if not theValue as boolean then
			set isFile to false
		end if
	end if
	-- add styled path 
	if fullPaths then
		set styledPath to (current application's NSAttributedString's alloc()'s initWithString:(anItem's |path|()) attributes:baseStyle)
		set styledPath to (current application's NSAttributedString's alloc()'s initWithString:(anItem's |path|()'s substringFromIndex:targetLength) attributes:baseStyle)
	end if
	(theStyledString's appendAttributedString:styledPath)
	-- style name differently depending on whether it's a folder or file
	set theLength to anItem's lastPathComponent()'s |length|()
	set fullLength to theStyledString's |length|()
	if isFile then
		(theStyledString's addAttributes:fileColor range:{fullLength - theLength, theLength})
		(theStyledString's addAttributes:folderColor range:{fullLength - theLength, theLength})
	end if
	-- add linefeed
	(theStyledString's appendAttributedString:styledLinefeed)
end repeat
-- end editing of styled string
theStyledString's endEditing()

-- get RTF data, write it to file, then open the file
set docAtts to current application's NSDictionary's dictionaryWithObjects:{current application's NSRTFTextDocumentType} forKeys:{current application's NSDocumentTypeDocumentAttribute}
set theData to theStyledString's RTFFromRange:{0, theStyledString's |length|()} documentAttributes:(missing value)
theData's writeToURL:destURL atomically:true
current application's NSWorkspace's sharedWorkspace()'s openURL:destURL