opening first item of "Open Recent" menu

tell application "Smultron"
	activate
	tell application "System Events"
		tell process "Smultron"
			click menu item 1 of menu 1 of menu item "Open Recent" of menu 3 of menu bar 1
		end tell
	end tell
end tell

I wrote the above script and it works. How do i make it work for all applications instead of just Smultron? (assuming that there is “Open Recent” menu item in the File menu of all the other applications too)

Thanks in advance.

Hi,

I cannot stand GUI scripting :wink:

Try this


property theIdentifier : "com.apple.TextEdit"

try
	set documentRecords to (do shell script "defaults read " & theIdentifier & " NSRecentDocumentRecords")
	set {TID, text item delimiters} to {text item delimiters, "<"}
	set alis to text item 2 of documentRecords
	set text item delimiters to ">"
	set alis to text item 1 of alis
	set text item delimiters to space
	set alis to text items of alis
	set text item delimiters to ""
	set alis to (run script "«data alis" & (alis as text) & "»")
	set text item delimiters to TID
	tell application "Finder" to open alis using application file id theIdentifier
on error e
	display dialog e
end try

Thanks, StefanK

good to know. i thought it was not possible without GUI scripting.
However, I get the error: "Finder got an error: File some object wasn’t found.
Mac OS 10.5

Then the list of recent objects might be empty or the application doesn’t use the built-in recent items functionality

No, that is not the case. But just to confirm, can you tell me how exactly should i run the script. I mean,
can i just run it in the desired application after assigning it a trigger with Quicksilver/Butler(tried both apps)
or
should it be run from the script menu?
I tried both, the former method gives me no error and the second gives me the error i mentioned earlier. None work. Let me know if there is something else i must do which will be helpful in debugging the problem.
Thanks again, StefanK.

You’ re right. I have the same error message running the script triggered by a shortcut
Try this, you have to specify also the name of the app


property theIdentifier : "com.apple.TextEdit"
property theApp : "TextEdit"

try
	set documentRecords to (do shell script "defaults read " & theIdentifier & " NSRecentDocumentRecords")
	set {TID, text item delimiters} to {text item delimiters, "<"}
	set alis to text item 2 of documentRecords
	set text item delimiters to ">"
	set alis to text item 1 of alis
	set text item delimiters to space
	set alis to text items of alis
	set text item delimiters to ""
	set alis to (run script "«data alis" & (alis as text) & "»")
	set text item delimiters to TID
	tell application theApp
		activate
		open alis
	end tell
on error e
	display dialog e
end try

thanks, it works…but it only gives me a non-GUI solution for something which i had a GUI solution. I repeat the question that i asked in my first post. How to make it work for any application? (not just Textedit or any one app)

“Any application” will certainly not work.

The biggest problem for the GUI solution is to retrieve the menu item reliably.
Even if the targeted application supports NSRecentDocument, the menu item could be everywhere,
if the author doesn’t follow Apple’s default locations.
The second problem is, the menu item could be named differently in localized versions.
Furthermore GUI scripting is always time critical and slow.

The non-GUI solution works for every application, which support the NSRecentDocument function.
The targeted application will only be opened, if it’s most recent document has been found.
If the targeted application doesn’t support the function or the list is empty, you get an error.

Hi Stephan

The problem is not the described one.

property theIdentifier : "org.smultron.Smultron"
property theApp : "Smultron"

try
	set documentRecords to (do shell script "defaults read " & theIdentifier & " NSRecentDocumentRecords")
	set {TID, text item delimiters} to {text item delimiters, "<"}
	set alis to text item 2 of documentRecords
	set text item delimiters to ">"
	set alis to text item 1 of alis
	set text item delimiters to space
	set alis to text items of alis
	set text item delimiters to ""
	set alis to (run script "«data alis" & (alis as text) & "»")
	set text item delimiters to TID
	tell application theApp
		activate
		open alis
	end tell
on error e
	display dialog e
end try

The log report is:
tell current application
do shell script “defaults read org.smultron.Smultron NSRecentDocumentRecords”
“(
{
"_NSLocator" = {
"_NSAlias" = <00000000 016c0002 00000c4d 6163696e 746f7368 20484400 00000000 00000000 00000000 0000c45c 8cef482b 00000008 a77a0966 69636869 65722033 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000038 913fc5d0 213d534d 4c64534d 554cffff ffff0000 09200000 00000000 00000000 00000000 00074465 736b746f 70000010 00080000 c45c70cf 00000011 00080000 c5d0132d 00000001 000c0008 a77a0008 a76f0000 6bdf0002 00304d61 63696e74 6f736820 48443a55 73657273 3a797661 6e5f6b6f 656e6967 3a446573 6b746f70 3a666963 68696572 2033000e 00140009 00660069 00630068 00690065 00720020 0033000f 001a000c 004d0061 00630069 006e0074 006f0073 00680020 00480044 00120023 55736572 732f7976 616e5f6b 6f656e69 672f4465 736b746f 702f6669 63686965 72203300 00130001 2f000015 00020012 ffff0000 >;
};
},
{
"_NSLocator" = {
"_NSAlias" = <00000000 016c0002 00000c4d 6163696e 746f7368 20484400 00000000 00000000 00000000 0000c45c 8cef482b 00000008 a77a0966 69636869 65722032 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000038 9137c5d0 212d534d 4c64534d 554cffff ffff0000 09200000 00000000 00000000 00000000 00074465 736b746f 70000010 00080000 c45c70cf 00000011 00080000 c5d0131d 00000001 000c0008 a77a0008 a76f0000 6bdf0002 00304d61 63696e74 6f736820 48443a55 73657273 3a797661 6e5f6b6f 656e6967 3a446573 6b746f70 3a666963 68696572 2032000e 00140009 00660069 00630068 00690065 00720020 0032000f 001a000c 004d0061 00630069 006e0074 006f0073 00680020 00480044 00120023 55736572 732f7976 616e5f6b 6f656e69 672f4465 736b746f 702f6669 63686965 72203200 00130001 2f000015 00020012 ffff0000 >;
};
},
{
"_NSLocator" = {
"_NSAlias" = <00000000 016c0002 00000c4d 6163696e 746f7368 20484400 00000000 00000000 00000000 0000c45c 8cef482b 00000008 a77a0966 69636869 65722031 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000038 912ec5d0 211a534d 4c64534d 554cffff ffff0000 09200000 00000000 00000000 00000000 00074465 736b746f 70000010 00080000 c45c70cf 00000011 00080000 c5d0130a 00000001 000c0008 a77a0008 a76f0000 6bdf0002 00304d61 63696e74 6f736820 48443a55 73657273 3a797661 6e5f6b6f 656e6967 3a446573 6b746f70 3a666963 68696572 2031000e 00140009 00660069 00630068 00690065 00720020 0031000f 001a000c 004d0061 00630069 006e0074 006f0073 00680020 00480044 00120023 55736572 732f7976 616e5f6b 6f656e69 672f4465 736b746f 702f6669 63686965 72203100 00130001 2f000015 00020012 ffff0000 >;
};
}
)”
run script “«data alis00000000016c000200000c4d6163696e746f7368204844000000000000000000000000000000c45c8cef482b00000008a77a096669636869657220330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038913fc5d0213d534d4c64534d554cffffffff00000920000000000000000000000000000000074465736b746f7000001000080000c45c70cf0000001100080000c5d0132d00000001000c0008a77a0008a76f00006bdf000200304d6163696e746f73682048443a55736572733a7976616e5f6b6f656e69673a4465736b746f703a666963686965722033000e00140009006600690063006800690065007200200033000f001a000c004d006100630069006e0074006f007300680020004800440012002355736572732f7976616e5f6b6f656e69672f4465736b746f702f66696368696572203300001300012f00001500020012ffff0000»”
display dialog “Beaucoup trop long.”
“Annulé par l’utilisateur.”

I tried to code:

set appName to "Smultron"
set prefName to "org.smultron.Smultron.plist"
set p2p to (path to preferences from user domain as text) & prefName
tell application "System Events"
	set listRecents to get (value of property list item "NSRecentDocumentRecords" of property list file p2p)
	try
		set alis to (get |_NSAlias| of |_NSLocator| of item 1 of listRecents)
	on error errmsg
		error "no recent item descriptor available"
	end try
end tell

log alis

It behaves well returning the log:

tell current application
path to preferences from user domain as text
“Macintosh HD:Users:yvan_koenig:Library:Preferences:”
end tell
tell application “System Events”
get value of property list item “NSRecentDocumentRecords” of property list file “Macintosh HD:Users:yvan_koenig:Library:Preferences:org.smultron.Smultron.plist”
. (I stripped the entire list )
(*«data ***00000000016C000200000C4D6163696E746F7368204844000000000000000000000000000000C45C8CEF482B00000008A77A096669636869657220330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038913FC5D0213D534D4C64534D554CFFFFFFFF00000920000000000000000000000000000000074465736B746F7000001000080000C45C70CF0000001100080000C5D0132D00000001000C0008A77A0008A76F00006BDF000200304D6163696E746F73682048443A55736572733A7976616E5F6B6F656E69673A4465736B746F703A666963686965722033000E00140009006600690063006800690065007200200033000F001A000C004D006100630069006E0074006F007300680020004800440012002355736572732F7976616E5F6B6F656E69672F4465736B746F702F66696368696572203300001300012F00001500020012FFFF0000»)
end tell

but I am unable to find the way to decipher alis.

Yvan KOENIG (from FRANCE dimanche 1 mars 2009 12:17:53)

Hi Yvan,

The problem is, you obviously don’t use Leopard.
AppleScript 1 has a data literal («data …») limitation of 127 bytes.

Deciphering a data encapsulated alias read from a property list file in AppleScript works only with the data literal method,
otherwise you have to write an ObjC command line interface tool to do the job

Right, I’m using 10.4.11.

I got a workaround.

set appName to "Smultron"
set prefName to "org.smultron.Smultron.plist"

set p2p to (path to preferences from user domain as text) & prefName
tell application "System Events"
	set listRecents to get (value of property list item "NSRecentDocumentRecords" of property list file p2p)
	try
		set alis to (get |_NSAlias| of |_NSLocator| of item 1 of listRecents)
	on error errmsg
		error "no recent item descriptor available"
	end try
end tell

try
	alis as text
on error errmsg
	set AppleScript's text item delimiters to "****"
	set errmsg to text item 2 of errmsg
	set AppleScript's text item delimiters to "»"
	set errmsg to text item 1 of errmsg
	set AppleScript's text item delimiters to ""
end try

set decode to ""
set hexa to "0123456789ABCDEF"
repeat with i from 1 to count of errmsg by 2
	set c1 to character i of errmsg
	set c2 to character (i + 1) of errmsg
	if c1 = "0" and c2 = "0" then
		set decode to decode & return
	else
		set k to (((offset of c1 in hexa) - 1) * 16) + (offset of c2 in hexa) - 1
		set decode to decode & (ASCII character k)
	end if
end repeat

set maybe to {}
repeat with p in paragraphs of decode
	if ((count of p) > 1) and p contains ":" then copy p to end of maybe
end repeat

tell application "System Events"
	set found to false
	repeat with f in maybe
		if exists file f then
			set found to true
			exit repeat
		else
			set f to text 2 thru -1 of f
			if exists file f then
				set found to true
				exit repeat
			end if
		end if
	end repeat
end tell

if found then set chemin to f

It works under 10.4.11 but I didn’t tested it under 10.5.x

Yvan KOENIG (from FRANCE dimanche 1 mars 2009 14:16:49)

I wrote this before in my first post and I repeat it now:
Please assume that there is “Open Recent” menu item in the File menu of all the other applications too.
Since, i expressly mentioned “Open Recent” (and not menu item number), I meant, i am concerned only with English language. (See also, that i expressly mentioned “File” menu instead of menu number)

GUI or non-GUI: can a script be written that works with all applications instead of just “TextEdit”?
The script should work when the i press the trigger while the current application is open and active.
Thanks.

This retrieves both values for name and bundle identifier from the active application.
Replace the properties with it


tell application "System Events"
	set {name:theApp, bundle identifier:theIdentifier} to (get 1st application process whose frontmost is true)
end tell

perfect. Thanks, StefanK.

CAUTION

the script posted by StephanK doesn’t apply before macOS X 10.5.

Yvan KOENIG (from FRANCE lundi 2 mars 2009 19:21:42)