Skip to content

Mac OS

For Mac OS, we need to create our own application.

  1. Launch Script Editor
  2. Use the following script, paying attention to the path to emacsclient:
bash
on open location this_URL
    set EC to "/usr/local/bin/emacsclient --no-wait "
    set filePath to quoted form of this_URL
    do shell script EC & filePath & " &> /dev/null &"
    tell application "Emacs" to activate
end open location
  1. Save the script in /Applications/OrgProtocolClient.app, changing the script type to “Application”, rather than “Script”.
  2. Edit /Applications/OrgProtocolClient.app/Contents/Info.plist, adding the following before the last </dict> tag:
bash
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>org-protocol handler</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>org-protocol</string>
    </array>
  </dict>
</array>
  1. Save the file, and run the OrgProtocolClient.app to register the protocol.

To disable the “confirm” prompt in Chrome, you can also make Chrome show a checkbox to tick, so that the OrgProtocol app will be used without confirmation. To do this, run in a shell:

bash
defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true

If you’re using Emacs Mac Port, it registered its ‘Emacs.app‘ as the default handler for the URL scheme ‘org-protocol‘. To make OrgProtocol.app the default handler instead, run:

bash
defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \
'{"LSHandlerPreferredVersions" = { "LSHandlerRoleAll" = "-"; }; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";}'

Then restart your computer.

If you’re using the Emacs Homebrew formula, you may need one of the following additional configurations:

  1. Add option ‘-c‘ to ‘emacsclient‘ in the script, and start emacs from command line with ‘emacs –daemon‘
    bash
    on open location this_URL
        set EC to "/usr/local/bin/emacsclient -c --no-wait "
        set filePath to quoted form of this_URL
        do shell script EC & filePath & " &> /dev/null &"
        tell application "Emacs" to activate
    end open location
  2. Add ‘(server-start)‘ in .emacs (in this case you do not need option ‘-c‘ for ‘emacsclient‘ in the script, and you do not need to start emacs with ‘emacs –daemon‘
  • Testing org-protocol

    To test that you have the handler setup and registered properly from the command line you can run:

    bash
    open org-protocol://roam-ref\?template=r\&ref=test\&title=this

    If you get an error similar too this or the wrong handler is run:

    No application knows how to open URL org-protocol://roam-ref?template=r&ref=test&title=this (Error Domain=NSOSStatusErrorDomain Code=-10814 “kLSApplicationNotFoundErr: E.g. no application claims the file” UserInfo={_LSLine=1489, _LSFunction=runEvaluator}).

    You may need to manually register your handler, like this:

    bash
    /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R  -f /Applications/OrgProtocolClient.app

    Here is a link to the lsregister command that is really useful: https://eclecticlight.co/2019/03/25/lsregister-a-valuable-undocumented-command-for-launchservices/