How to get a link to a file on MacOS?

I want to do something like right-click a file and get a file:// link to it that I can paste in to OmniFocus. This seems way harder than it should be.

How can I get a link to a file on MacOS?

I haven’t tried it in a while (I do it in Launchbar) but try right clicking while holding down the option key, and see what is in the contextual menu. I’m at my iPad now so can’t test it.

Screen Shot 2020-01-19 at 3.06.32 PM

This is all there is for Option + Right Click.

How do you do it in Launchbar?

I have an Automator workflow for that. I select the file and choose the workflow from the services menu, when I right-click on the object in Finder. It is just one task that runs an AppleScript that copies the result to the clipboard, the input is that file or folder.

See here how to make a service:
https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/MakeaSystem-WideService.html

The workflow:

The script in Run AppleScript task

(* this copies the file URL *)

on run
	tell application "Finder"
		set selectie to the selection as text
		set TheFile to selectie
		set TheURL to URL of item TheFile
		set the clipboard to TheURL
	end tell
end run

** edit ** changed the script, the Finder supports URL’s directly and there was a mistake in the old script

2 Likes

Regarding the Developer page that @FrankV pointed you to – in Catalina, in the Automator menu, the “Service” option Is called “Quick Action”, and the settings menu for the newly created action is slightly different than the image shown on the web page. If you create the automator action suggested, and save it as, say, “Get File URL”, then that “Quick Action” will appear as a clickable action in Finder’s Preview Panel when the file is selected, as well as the Services Menu in Finder.

Katie

Thank you for the clarification. I’m still on Mojave, so I’m not aware of this.

I don’t use Omnifocus but it might be worth a try to create an Alias and copy that in Omnifocus.

Right (control) + click on the file and select “Make Alias”

Hope this helps.

Rogier

Assuming you have exactly the same folder arborescence, will those links work on two different Macs?

John, check out this page, under “Copying file paths”:

https://www.obdev.at/resources/launchbar/help/WorkingWithFiles.html

Basically you navigate to the file in Launchbar, and just use Command-C, which puts the path on your clipboard

I tested it with a folder that is synchronized via iCloud. Created a an Alias on the desktop on my laptop. Its showing and working on my desktop :slight_smile:

2 Likes

You can condense this somewhat to this:

tell application id "com.apple.Finder" to tell ¬
        (get selection) to if its length = 1 then tell ¬
        URL of item 1 to my (set the clipboard to it)

That’s the conscientious version, but you can be ultra simple and just do:

tell application id "com.apple.Finder" to set the clipboard ¬
        to the URL of item 1 in (get selection)

Functionally, the second is closest to the original: both will throw an error if no file is selected, although the original also throws an error if more than one file is selected. The first version, although slightly convoluted to read out loud, doesn’t throw an error in either of those circumstances, and also avoids the silent error caused by calling set the clipboard from within a Finder tell block (the command belongs to standard additions, so the use of my refers the call immediately to current application).

Thanks!

I have @FrankV’s script working. @chri.sk - I don’t think yours is doing anything for me, maybe I’m missing a bit - I’m guessing the (get selection) and (set the clipboard to it) sections are not exact code, so my copy/paste Applescript skills aren’t quite enough :expressionless:

I’m going to poke around at Launchbar a bit too.

Sure. I wasn’t strong arming you to use my versions under duress. I don’t know what you mean about it not doing anything for you, or what you mean by “exact code”. But it was a good chance to show you a bit of AppleScript that you are new to, and will be able to compare the differences between the two scripts, which is how I learn a new language.

To be clear, they should be performing the same functions, and if you were alluding to something not working, I wasn’t able to glean from what you wrote what was happening or not happening. Any error is likely to be a typo on your end or mine, if it’s mine, you’d be helping me if you’ve observed something unexpected that I should correct for the other users who might scratch their heads if the same thing stops them using the script themselves.

Anyway, get selection is correct. If you remove the word get, you will find it generates an error because of the way lists of file references are returned, which is in what’s called a referenced state (or, partially (de)referenced), and need some additional to happen before the data is available for use. In the original script, there’s a lot of assignments being made on every line, and all rather pointlessly. But the one where the selection is assigned to a variable forces dereferencing by converting a list into text. Firstly, it’s not necessary to do this, and removes all the properties of a filesystem object, which later became necessary to transform back to a filesystem object by creating a new instance of it by way of the item specifier (which I have to say is one of the few to use correctly knowing that the file path could lead to either a file or a folder, and more often, people use file and didn’t know that it would be a problem until Finder has a tantrum and everything is stopped because it gets histrionic about being handed a folder but told it was a file).

This may be inefficient, but you are unlikely to feel the impact of converting back and forth between text and file objects unless it has to do it for lots and lots of them.

However, it never will, because if you do hand it a selection with multiple items, the moment it is converted to text, you get a single sentence of unusable text that is the result of getting all the file paths and sticking them together with no way to separate them without a bit of work and some unreliable methods involving text manipulation. What needs to be done if, for some reason, conversion to text is a good idea (these are few, but do exist) is to have it delimited by newline characters after each item in the list is converted. This lets each file path sit on its own line, and that’s the way that only has a single weakness, which is a file path containing newline characters (luckily, a rare occurrence). For total robustness, the null character is ideal, but a colon can be used since they are illegal in macOS file paths, so they are probably the reason you see this being used in shell environments if you have used the command line before.

So get in my script does the same functional action that occurs with as text in the original, but doesn’t make any changes to the underlying data. This is also the why the scripts I provided can handle multiple file selections in one go, and not generate an error. The first one of the two is also the only one that won’t generate an error if no files get selected.

I’ve now just opened the screenshots full-size and seen the script is part of an Automator workflow that would only be run if it is passed at least one file or folder item. So the bit about the scenario where no selection is made doesn’t apply.

But it also means that the way for the script to do what it needs to in the best possible way and with the fewest weak spots is to not use theselection property at all. And, in fact, not even use Findsr, which is a bad thing to use in scripting but necessary when I thought we needed the selection property unique to Finder.

In fact, the selected files will already be stored by Automator and sent into the AppleScript action as a variable that we can reference if we construct the appropriate handler. The original script uses a run handler which was unnecessary, because it specifically had its parameters deleted. However, the run handler is needed when it’s in its completed form, and gives you the means to receive the selected file list in the ideal format most appropriate for the action–in the case of AppleScript, it gives us a list of alias objects, which are perfect, and allows us to use them in any way we choose). I would highly recommend choosing System Events, as it performs file operations about 200-300 times faster than the Finder (depending on your computer and its power), plus it means that if there is a lot of work to be done with files, it won’t prevent you from using Finder in the meantime. It also has much fewer errors, and it’s able to cope with posix paths (ones with slashes instead of colons) as naturally as everyone expects Finder would be able to. Finder uses a really stupid file referencing style unique to it, and it makes evaluated lists of files a nightmare for AppleScript if you ever have it try and cope with a hundred or more in a single list. Because it makes reference to the entire directory tree and every folder it enters on the way down until reaching the file is individually referenced and occupies memory, then needs to be read each time you make it do it task.

An alias list (which Finder can produce if told to, and would have been a better conversion to an alias list rather than the text option that is problematic), is so much faster and uses less memory because it store the file path as a singular string that is partnered with the alias specifier, and provides immediate access to the properties of the file when you want it. It is also a dereferenced object, which means it was evaluated before being given to us, and won’t be needing to re-evaluate it every time we access it, unlike the string of references that is returned normally by Finder, and without the get command or some other form of dereferencing, makes you cry if you ever thought it would be fine to loop through a directory of files, or perhaps wonder why you have tried to retrieve the name of a file, but can’t then use it without having to explicitly ask for a dereferencing, but when one is unaware, it’s finally a relief to have access given if you ask for it on a separate line (usually not a big issue, but very limiting when you wish to avoid having to store things in memory by assigning a variable, which can be wasteful for a one-time use).

Anyway, I’ve written enough on the various details of what you might not be interested in knowing, and apologise if you have been bored by this (others will hopefully benefit in the future so that’s why I wish to provide yet another version of the script, and one that is optimised for use in Automator workflows):

Thanks for the extra info! Yes, by “not work” I meant that I would run the Automator extension and nothing would be in my clipboard.

I’m going to mess around with it a bit and see what I can make happen.

The easiest way for me to do this is to drag the file from Finder to OmniFocus, then while holding the Control key, drop it in the note section of the targeted OmniFocus task.

1 Like

Has anybody tried if such file links work on iOS for files stored in iCloud?

I would assume no, because the link I get is something like file://Users/John/Document/Special-Project/ImportantInfo.pdf, and the same root path doesn’t exist on my iPhone.

I’ve been following the Devonthink thread with interest. I think using a cross-platform system like that can make links work cross-platform, (maybe even keeping everything in Dropbox & using Dropbox links would work).

1 Like

Thanks! That’s what I’ve been thinking: DT seems to be the only app to provide a kind of Finder replacement that could allow for this. I would also be hoping for a simpler setup if the upcoming iOS version of Hook would provide that.