Hello.
If the former was the final version, then this is the optimized version, thanks to Nigels code from above.
Edit
Maybe all of this was in vain, as I use accented characters, and other who use accented characters will discover the same: This version doesn’t treat accented characters very well. you may get \\U008 sequences. in the dialog.
I want to make a point of the fact that the utf-16 is only deleted from the file, not written back, so it looks good under the recent documents of your program.
I am not going to fix this, or try to fix this before I have thought it thru at least.
Edit++
If the treatment of utf-16 diacriticals doesn’t please you go to the script in post #18 or Shane’s version in post #31.
This won’t be fixed. The reason is that there are two kinds of utf-16 in the Apple-world besides big endian, loose and tight (wrong terms).
The loose encoding scheme stores diacritical’s in separate codepoints, this is what Apple uses for filenames.
With tight encoding, the diacriticals are stored with the character in one codepoint.
Normally, when you use an operating system call to to parse a value, the Darwin layer transforms the loose utf-16 into utf-8 for us. What has happened here, is that the loose utf-16 is stored inside a text file, and doesn’t enjoy the transformation by Darwin.
I am not doing all this for speed, and then having to do a do shell script for each and every name that is going to be displayed"in the hope of managing to decode/encode it right by some construct/incantation, (and lots of trial and errors). It defies the whole purpose of using sed/defaults in the first place.
There are also other possibilities for optimizing this, but the cost/performance ratio expressed by readability/speed, just doesn’t justify it, it is almost undreadable, as it is.
So, stick with it, or let it be.
-- http://macscripter.net/viewtopic.php?pid=161038#p161038
-- New version that uses sed and defaults for doing the job quicker!
property sTitle : "Recent Items Forensics"
property recentItemIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:RecentItemsIcon.icns")
-- We get in a reasonably list of the files with recent items for applications, that we choose one from
set AppleScript's text item delimiters to ""
set plpth to (path to preferences folder from user domain)
set pxpth to POSIX path of plpth
set plists to paragraphs of (do shell script "cd " & quoted form of pxpth & "; ls * |sed -e '/lockfile/ d' -ne 's/\\(.*\\)\\(\\.LSSharedFileList.plist\\)/\\1/p'")
set shtnms to {}
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
repeat with i from 1 to count plists
set end of shtnms to (text -2 thru -1 of ("0" & i)) & space & space & (text items -2 thru -1 of item i of plists)
end repeat
set AppleScript's text item delimiters to tids
set chosenapp to choose from list shtnms with title sTitle with prompt "Choose app to clean up recent items for" default items item 1 of shtnms without multiple selections allowed
-- We have chosen an app, we must verify that it isn't running, since it may have unsaved documents, we quit the script if it is so
if chosenapp is not false then
set chosenapp to chosenapp as text
set pfnm to text 1 thru 2 of chosenapp
set chosenapp to text 5 thru -1 of chosenapp
if running of application id (item pfnm of plists) is true then
display dialog "You must quit " & chosenapp & " in order to continue." with title sTitle buttons {"Ok"} default button 1 with icon recentItemIcon
error number -128
end if
-- we check to see that the recent item plist isn't a zero sized file on disk!
tell application "System Events"
set daPlist to ((item pfnm of plists) & ".LSSharedFileList.plist")
-- Here we read in the plist file and everything is as earlier.
if (size of disk item daPlist of (plpth as alias)) = 0 then
tell me to display dialog "Nothing to remove ..." with title sTitle buttons {"Ok"} default button 1 with icon recentItemIcon
error number -128
end if
end tell
set domain to (item pfnm of plists) & ".LSSharedFileList"
repeat
set recentNames to paragraphs of (do shell script ("defaults read " & domain & " RecentDocuments | sed -En '/^[[:space:]]*CustomListItems[[:space:]]*=[[:space:]]*\\(/,/\\)/ s/^[[:space:]]+Name = (.+);$/\\1/p '"))
-- checks to see that the file indeed contains something
set recentNamesCount to length of recentNames
if recentNamesCount = 0 then
display dialog "Nothing to remove ..." with title sTitle buttons {"Ok"} default button 1 with icon recentItemIcon
error number -128
end if
set namesToCut to {}
-- We have to create the list, and remove any "" as not every name has gotten those in the recent items list
repeat with i from 1 to recentNamesCount
set AppleScript's text item delimiters to "\""
set recentNmTms to text items of item i of recentNames
try
if length of recentNmTms > 1 then
if item 2 of recentNmTms ≠"" then
set item i of recentNames to item 2 of recentNmTms
else
set item i of recentNames to item 1 of recentNmTms
end if
end if
end try
set AppleScript's text item delimiters to tids
set item i of recentNames to (text -2 thru -1 of ("0" & i)) & space & space & item i of recentNames
end repeat
set namesToCut to (choose from list recentNames with title sTitle with prompt "Delete document(s) from " & chosenapp & "´s Recent Items list:" default items item 1 of recentNames with multiple selections allowed)
if (namesToCut is false) then error number -128
set numberlist to {} -- We do calculate the ranges, which we are to delete in the current recent items property list file, so we incinerate the items we want to remove
repeat with i from 1 to (count namesToCut)
set mn to ((text 1 thru 2 of item i of namesToCut) as number)
set end of numberlist to "" & (1 + ((mn - 1) * 5)) & "," & (mn * 5) & "d"
-- *TOTALLY DEPENDENT ON THE LAYOUT OF RECENT ITEMS. 2 LINES UP FRONT, 5 LINES FOR EACH OF THEM.
end repeat
-- Join the selected names with vertical bars to use as an OR sequence in a regex.
set AppleScript's text item delimiters to ";"
set numberlist to (numberlist as text)
set AppleScript's text item delimiters to tids
-- all done with selecting the items, we filter out anything we won't keep
set newData to quoted form of text 1 thru -2 of (do shell script "defaults read " & domain & " RecentDocuments |sed -e " & quoted form of numberlist without altering line endings)
-- and writes it back into the existing dictionary
do shell script ("defaults write " & domain & " RecentDocuments -dict \"CustomListItems\" " & newData)
tell me to display dialog "I removed " & (count namesToCut) & " items(s) from" & chosenapp & "´s Recent items." with title sTitle buttons {"Cancel", "Again"} default button 1 with icon recentItemIcon
end repeat
end if