Faster open recent documents

This takes ¼~1s to run (and even longer in some applications, like TextMate):

set l to {"Open Recent", "Recent Projects"}
tell application "System Events" to tell (process 1 where it is frontmost)
    set m1 to menu bar 1's menu bar item 3
    click m1
    repeat with v in l
        try
            set m2 to m1's menu 1's menu item v
            click m2
            click m2's menu 1's menu item 1
            exit repeat
        end try
    end repeat
end tell

This is even slower:

tell application "System Events" to tell (process 1 where it is frontmost)
    click menu bar 1's menu bar item 3's menu 1's menu item "Open Recent"'s menu 1's menu item 1
end tell

I looked at getting the path to from ~/Library/Preferences/{bid}.LSSharedFileList.plist. Those files only seem to contain document names, not paths; though I’m not sure what the Bookmark key is for:

{ RecentDocuments = { Controller = CustomListItems; CustomListItems = ( { Bookmark = <626f6f6b 4c020000 00000110 10000000 8c010000 05000000 01010000 55736572 73000000 05000000 01010000 6c617572 69000000 07000000 01010000 4465736b 746f7000 19000000 01010000 72656365 6e742069 74656d73 20312070 6c697374 2e736370 74000000 10000000 01060000 04000000 14000000 24000000 34000000 08000000 04030000 9f910000 00000000 08000000 04030000 acab0500 00000000 08000000 04030000 b7ab0500 00000000 08000000 04030000 60632c00 00000000 10000000 01060000 70000000 80000000 90000000 a0000000 18000000 01020000 01000000 00000000 0f000000 00000000 00000000 00000000 04000000 03030000 02000000 04000000 03030000 f5010000 02000000 01010000 48440000 08000000 04030000 00808ef9 39000000 08000000 00040000 41b33747 34000000 24000000 01010000 45463939 43434533 2d423845 432d3330 45422d41 3830462d 31374131 44373144 46443943 18000000 01020000 81000000 01000800 ef3f0000 01000800 00000000 00000000 01000000 01010000 2f000000 00000000 01050000 a8000000 feffffff 01000000 00000000 0d000000 04100000 58000000 00000000 05100000 b0000000 00000000 10100000 c8000000 00000000 02200000 78010000 00000000 10200000 00010000 00000000 11200000 2c010000 00000000 12200000 0c010000 00000000 13200000 1c010000 00000000 20200000 58010000 00000000 30200000 84010000 00000000 01c00000 e8000000 00000000 11c00000 14000000 00000000 12c00000 f4000000 00000000>; Icon = <496d6752 0000010c 00000000 4642494c 00000100 00000002 00000000 00000000 00f00003 00000000 c9acc034 0000482b 00000000 000120f1 000121a9 0000c67d eae90000 00000920 fffe0000 00000000 0000ffff ffff0001 00140001 20f10001 20f00001 20ef0011 37010000 0133000e 002c0015 00530045 0043006f 006d0070 0069006c 00650064 00530063 00720069 00700074 002e0069 0063006e 0073000f 00060002 00480044 00120056 4170706c 69636174 696f6e73 2f557469 6c697469 65732f41 70706c65 53637269 70742045 6469746f 722e6170 702f436f 6e74656e 74732f52 65736f75 72636573 2f534543 6f6d7069 6c656453 63726970 742e6963 6e730013 00012f00 ffff0000>; Name = "recent items 1.scpt"; } ); MaxAmount = 20; }; }
So is there some way to get the path to a recent item, or a faster way to select menu items for recent items?

Runnig this script


set book_mark to "626f6f6b 4c020000 00000110 10000000 8c010000 05000000 01010000 55736572 73000000 05000000 01010000 6c617572 69000000 07000000 01010000 4465736b 746f7000 19000000 01010000 72656365 6e742069 74656d73 20312070 6c697374 2e736370 74000000 10000000 01060000 04000000 14000000 24000000 34000000 08000000 04030000 9f910000 00000000 08000000 04030000 acab0500 00000000 08000000 04030000 b7ab0500 00000000 08000000 04030000 60632c00 00000000 10000000 01060000 70000000 80000000 90000000 a0000000 18000000 01020000 01000000 00000000 0f000000 00000000 00000000 00000000 04000000 03030000 02000000 04000000 03030000 f5010000 02000000 01010000 48440000 08000000 04030000 00808ef9 39000000 08000000 00040000 41b33747 34000000 24000000 01010000 45463939 43434533 2d423845 432d3330 45422d41 3830462d 31374131 44373144 46443943 18000000 01020000 81000000 01000800 ef3f0000 01000800 00000000 00000000 01000000 01010000 2f000000 00000000 01050000 a8000000 feffffff 01000000 00000000 0d000000 04100000 58000000 00000000 05100000 b0000000 00000000 10100000 c8000000 00000000 02200000 78010000 00000000 10200000 00010000 00000000 11200000 2c010000 00000000 12200000 0c010000 00000000 13200000 1c010000 00000000 20200000 58010000 00000000 30200000 84010000 00000000 01c00000 e8000000 00000000 11c00000 14000000 00000000 12c00000 f4000000 00000000"

set book_mark to my remplace(book_mark, space, "")
set en_liste to {}
repeat with i from 1 to count of book_mark by 2
	set hexa to text i thru (i + 1) of book_mark
	set deci to my hex2dec(hexa)
	if deci < 32 then set deci to 32
	copy (ASCII character deci) to end of en_liste
end repeat
set en_texte to my recolle(en_liste, "")

--=====

on hex2dec(hh)
	log hh
	set digits to {"0123456789ABCDEF"}
	set h1 to character 1 of hh
	set h2 to character 2 of hh
	if (ASCII number of h1) > 224 then set h1 to ASCII character ((ASCII number of h1) - 32)
	
	if (ASCII number of h2) > 224 then set h2 to ASCII character ((ASCII number of h2) - 32)
	return (((offset of h1 in digits) - 1) * 16) + (offset of h2 in digits) - 1
end hex2dec

--=====

on recolle(l, d)
	local oTIDs, t
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

--=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d1
	set l to text items of t
	set AppleScript's text item delimiters to d2
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end remplace

--=====

returned :

"bookL Ã¥ Users lauri Desktop recent items 1 plist.scpt $ 4 üë ¨´ ∑´ `c, p Ä ê ı HD Äé˘9 A≥7G4 $ EF99CCE3-B8EC-30EB-A80F-17A1D71DFD9C Ã… Ô? / ® ˛ˇˇˇ X ∞ » x , X 0 Ñ ¿ Ë ¿ ¿ Ù "

Which let me think that the bookmarked file is the file recent items 1 plist.scpt of Desktop of folder lauri of folder Users of volume HD.

Yvan KOENIG (VALLAURIS, France) mercredi 8 juin 2011 21:17:50

set a to path to frontmost application as text
set bid to id of application a
set f to "$HOME/Library/Preferences/" & bid & ".LSSharedFileList.plist"
set bm to do shell script "/usr/libexec/PlistBuddy -c \"Print :RecentDocuments:CustomListItems:0:Bookmark\" " & f & " | tr '\\1' '/' | tr '\\4' '!' | tr -d '\\0-\\37' | sed 's|/!.*||' | sed 's|.*///|/|' | sed 's|//|/|g'"
set f to (POSIX file bm)
tell application a to open f

PlistBuddy’s Print command converts the hex dump automatically, but you could also use xxd -r -p. (The script posted by Yvan Koenig above takes about 0.5 seconds to run on my MBP, so it’s too slow for this purpose.)

That chain of sed and tr for extracting the path is as hacked together as it looks, and it probably won’t work in all cases.

I wish I had noticed this earlier, but it turns out that the CustomListItems dictionary is updated only after a delay ” the first entry won’t always be the same as the first item in the recent items menu. So this approach is pretty much useless…

I’m open to other suggestions though.