Double click and open with default...

Great to hear that!

Thank you. Your willingness to take another look at it is much appreciated. If it turns out that you continue to feel it adds more complexity than it’s worth, then so be it :slight_smile:.

Jack

One of my main uses for DTPO is to maintain permanent links within scientific notebooks, and the current behavior of DT causes some friction.

I document scientific processes in the lab with, for example, textedit (rtfd), and within those notes are links to other notes. So my notes page will have lots of links like x-devonthink-item://46E…350. Because I keep all my lab notes (and my students’ notes) indexed within DT, we get the huge benefit that the links don’t break if I ever move/rename things. The downside of DT’s current behavior of opening docs within DT is that when we click on a link to another file, it opens in within DT rather than within Textedit. That’s not ideal, since we really want to use Textedit for its ability to deal with embedded images etc. So, each time we click a link to another note, we then have to do a cmd-shift-O to open another copy of the note within textedit. Then to reduce clutter we go back to DT and close the doc within DT, and then switch back to Textedit to edit the linked note. Not a big deal to do once, but more so to do 100 times a day. Is there an equivalent to cmd-shift-O that I can use with a link to tell DT that the link I’m clicking on should be opened with the default app rather than DT?
Thank you for any thoughts on this,

Carl

P.S. The problem is even more of an issue if, say we open a main note that links to 10 other notes that we need to have open for editing. If we click on those 10 links, now we have 10 DT docs open. We then have to go through each DT doc and do a cmd-shift-O to open them in textedit. But there’s no good way to know which of the 10 you’ve already done cmd-shift-O to, and so you have to move each one to a new window so you can keep track of which ones you’ve already reopened in the correct app.

I recently wrote a script that looks up and opens links. It opens them in DEVONthink, so I made a version for you. Select your link(s), or the whole page, run the script and it will open them in the default app.

It uses macOS System Events to copy selected text so it may be that you have to increase the delay if you use it via shortcut (e.g. via Alfred or Keyboard Maestro) as there’s a chance that once in a while you don’t let your triggering shortcut go fast enough which will let macOS register your shortcut plus the shortcut System Events presses. However waiting 0.5 (or more) seconds should be no problem if you don’t have to open and close all those DEVONthink windows. If you use it via DEVONthink’s menu or toolbar that’s of course no issue.

-- Open selected text's link(s) in default app

property theDelay : 0.5

tell application id "DNtp"
	try
		set theWindow to think window 1
		try
			set selectedText to selected text of theWindow & "" as string
			delay theDelay
			activate
			tell application "System Events" to tell process "DEVONthink 3" to keystroke "c" using {command down}
			try
				set theGrepResults to do shell script "osascript -e 'the clipboard as «class RTF »' | perl -ne 'print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))' | egrep -o 'x-devonthink-item[^\"]*'" -- https://superuser.com/a/1409995/
			on error
				display alert "No link(s) found" buttons {"Ok"} default button 1 message "" as critical
				return
			end try
			set theRefURLs to paragraphs of theGrepResults
		on error
			display alert "No text selected" buttons {"Ok"} default button 1 message "" as critical
			return
		end try
		
		repeat with thisRefURL in theRefURLs
			set thisPath to path of (get record with uuid ((characters 21 thru -1 in thisRefURL) as string))
			tell application "Finder" to open file (POSIX file thisPath as alias)
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

Wow! that’s an unbelievably quick reply. I’m not a scripting expert, but I think I know enough to give this a try. Thank you very much for taking the time to post this!!

So I dropped it into Alfred w/ a shortcut of “dtod”, selected the DT link within textedit, and ran the script. Unfortunately, no joy. I turned on debugging within Alfred and get the following error (which is already past my scripting expertise). I did also try selecting the link within DT to see if that helped, but got the same result. Apologies if it’s an obvious mistake I’m making here.

[16:44:46.062] Logging Started…

[16:45:00.204] DT (open in default) (dtod)[Keyword] Processing complete

[16:45:00.211] DT (open in default) (dtod)[Keyword] Passing output ‘’ to Run NSAppleScript

[16:45:00.211] ERROR: DT (open in default) (dtod)[Run NSAppleScript] {

NSAppleScriptErrorBriefMessage = “Expected \U201cend\U201d but found \U201cproperty\U201d.”;

NSAppleScriptErrorMessage = “Expected \U201cend\U201d but found \U201cproperty\U201d.”;

NSAppleScriptErrorNumber = “-2741”;

NSAppleScriptErrorRange = “NSRange: {70, 8}”;

}

Sorry, wrote it for usage in DEVONthink. It should be no problem to change it so that it works in any app, but I’m running a backup right now. After that I’ll change it

I did get your original script to run from within DT. I could not however get the new version to run even from within DT. Thank you for looking at this error.

This version should work from within any app. Tested with TextEdit, Nisus Writer and TextSoap.

-- Open selected text's link(s) in default app

property theDelay : 0.5

try
	delay theDelay
	tell application "System Events" to tell (first process whose frontmost is true) to keystroke "c" using {command down}
	set theGrepResults to do shell script "osascript -e 'the clipboard as «class RTF »' | perl -ne 'print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))' | egrep -o 'x-devonthink-item[^\"]*'" -- https://superuser.com/a/1409995/
on error
	display alert "No text selected or no link(s) found" buttons {"Ok"} default button 1 message "" as critical
	return
end try

tell application id "DNtp"
	try
		set theRefURLs to paragraphs of theGrepResults
		
		repeat with thisRefURL in theRefURLs
			set thisUUID to (characters 21 thru -1 in thisRefURL) as string
			set thisRecord to get record with uuid thisUUID
			set thisPath to path of thisRecord
			tell application "Finder" to open file (POSIX file thisPath as alias)
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

There are two AppleScript actions in Alfred, the one you need here is

1

then in this action’s first dropdown

2

Replace the example code with the script and it should work.

This partially works for me. After it correctly opens the file corresponding to the link in the default app, DT throws an error: “Can’t get path of missing value.” So if a single file is selected, then the file will open correctly, and then one needs to go to DT and click “ok” on the error dialog. This wouldn’t be that much of an issue except that it seems to interrupt the script. So if you’ve selected several files, the first will open, then you click “ok”, and that causes the script to exit.

Even as is, the script is an improvement over the vanilla DT functioning here, but a script that just looks through a selection for links and opens them all in default apps really would be a brilliant addition to my lab’s workflow. So if you have time for any further thoughts, they will be greatly appreciated.

Alfred debug shows the following if I run it with one link in the selection:
[21:40:12.019] DT (open in default) (dtod)[Keyword] Processing complete
[21:40:12.025] DT (open in default) (dtod)[Keyword] Passing output ‘’ to Run Script

So that seems consistent with it running correctly with the link in the selection, but then passing it a blank. I’ve tried to make sure I’m not passing any arguments to the script within alfred, and that it isn’t expecting an argument. Beyond that, I’m not sure why it’s getting a null input.

Hm, it’s working fine over here

I could add a try block, but you should not get any errors with the current version. Don’t know what it might be.

No that’s not causing the error, my debug looks the same after opening more than one link.

[03:49:14.904] TEST - ausgewählte Links in Standard App öffnen[Keyword] Processing complete
[03:49:14.906] TEST - ausgewählte Links in Standard App öffnen[Keyword] Passing output '' to Run Script

Seems DEVONthink couldn’t get the record but I have no idea why. I would understand an error from Finder like “can’t get path” if one selected a link to a smart group, as those have no path, but I’ve never seen DEVONthink not getting a record.

Don’t know how to solve that other than adding a try block.

-- Open selected text's link(s) in default app

property theDelay : 0.5

try
	delay theDelay
	tell application "System Events" to tell (first process whose frontmost is true) to keystroke "c" using {command down}
	set theGrepResults to do shell script "osascript -e 'the clipboard as «class RTF »' | perl -ne 'print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))' | egrep -o 'x-devonthink-item[^\"]*'" -- https://superuser.com/a/1409995/
on error
	display alert "No text selected or no link(s) found" buttons {"Ok"} default button 1 message "" as critical
	return
end try

tell application id "DNtp"
	try
		set theRefURLs to paragraphs of theGrepResults
		
		repeat with thisRefURL in theRefURLs
			try
				set thisUUID to (characters 21 thru -1 in thisRefURL) as string
				set thisRecord to get record with uuid thisUUID
				set thisPath to path of thisRecord
				tell application "Finder" to open file (POSIX file thisPath as alias)
			end try
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

This creates a text file on your desktop so we can see what DEVONthink gets as input. Run it on the same selection that threw the error

-- Open selected text's link(s) in default app

property theDelay : 0.5

try
	delay theDelay
	tell application "System Events" to tell (first process whose frontmost is true) to keystroke "c" using {command down}
	set theGrepResults to do shell script "osascript -e 'the clipboard as «class RTF »' | perl -ne 'print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))' | egrep -o 'x-devonthink-item[^\"]*'" -- https://superuser.com/a/1409995/
on error
	display alert "No text selected or no link(s) found" buttons {"Ok"} default button 1 message "" as critical
	return
end try

tell application id "DNtp"
	try
		set theRefURLs to paragraphs of theGrepResults
		
		repeat with thisRefURL in theRefURLs
			my write_to_file(thisRefURL & linefeed, (POSIX path of (path to desktop) & "Script Debugging.txt") as string, true)
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell


on write_to_file(this_data, target_file, append_data) -- (string, file path as string, boolean)
	try
		set the target_file to the target_file as text
		set the open_target_file to ¬
			open for access POSIX file target_file with write permission
		if append_data is false then ¬
			set eof of the open_target_file to 0
		write this_data as «class utf8» to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access POSIX file target_file
		end try
		return false
	end try
end write_to_file

I think I understand the problem. In my links, the label and the target are both things like:
x-devonthink-item://D410B352-231E-47E8-82BB-73DECA3E545F , and that doesn’t seem to work.
I know that that’s the problem because if I change the label in the above link to be just some random text then it seems to work. So I either need to rewrite the code that generates the links so it gives them some safer label… or perhaps there’s a way to tell the script to look at the target, not the label.

Yes, the trick seems to be that the link’s label can’t look like a link.

Please post the content of the text file from the above script

Here is the output:

x-devonthink-item://D410B352-231E-47E8-82BB-73DECA3E545F
x-devonthink-item://D410B352-231E-47E8-82BB-73DECA3E545F}}\

Here is the script. Added an option to have the first link as front window instead of the last.

-- Open selected text's link(s) in default app

property theDelay : 0.5
property reverseOrder : true

try
	delay theDelay
	tell application "System Events" to tell (first process whose frontmost is true) to keystroke "c" using {command down}
	set theGrepResults to do shell script "osascript -e 'the clipboard as «class RTF »' | perl -ne 'print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))' | egrep -o 'x-devonthink-item[^\"]*'" -- https://superuser.com/a/1409995/
on error
	display alert "No text selected or no link(s) found" buttons {"Ok"} default button 1 message "" as critical
	return
end try

tell application id "DNtp"
	try
		set theRefURLs to paragraphs of theGrepResults
		
		if reverseOrder = true then
			set theRefURLs_reverse to {}
			repeat with thisRefURL in theRefURLs
				set beginning of theRefURLs_reverse to thisRefURL
			end repeat
			set theRefURLs to theRefURLs_reverse
		end if
		
		repeat with thisRefURL in theRefURLs
			if length of (thisRefURL as string) = 56 then
				try
					set thisUUID to (characters 21 thru -1 in thisRefURL) as string
					set thisRecord to get record with uuid thisUUID
					set thisPath to path of thisRecord
					tell application "Finder" to open file (POSIX file thisPath as alias)
				end try
			end if
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

Perfect! Thank you thank you for your willingness to spend time on this!! And having the script search a whole selection for links is the perfect example of a user not realizing what they need until it’s shown to them. Great design.

Carl

btw: one of my students is doing a project to predict the places most at risk for future covid outbreaks. So your efforts will help him move forward a little more efficiently. Every bit helps.

1 Like