org-protocol.el – Trigger actions in Emacs via a custom URL scheme
Org protocol
Org protocol (info "(org) Protocols") is a custom URL scheme
(org-protocol://
) used to trigger actions in Emacs. A common
use case for Org protocol is data import (for example a web clipper),
where an external application can send data to Emacs by making an Org
protocol URL request.
The form of an Org protocol URL is
org-protocol://PROTOCOL?key1=val1&key2=val2…
where keyN=valN
is a (key, value) pair specific to the PROTOCOL
used. The value must be percent encoded.
There are three predefined protocols provided by Org protocol:
store-link
- Store a link, push URL to kill-ring.
capture
- Capture a note and let the user view it in a buffer before storing it.
open-source
- Open local source files of published contents for editing.
Motivated users can define their own custom protocol (Note: this links
to a document last updated in 2021 that is likely outdated.) using the
variable org-protocol-protocol-alist
.
The diagram below illustrates how an Org Protocol request is handled.
The scheme handler for GNU/Linux and Windows is typically emacsclient. On recent versions of macOS (since Ventura), security policy prevents external applications from calling programs like emacsclient outside of their sandbox. An alternate, commercial offering (Scrim) is available to serve as a macOS-trusted scheme handler for Org Protocol requests1. Users running a version of macOS older than Ventura can still use emacsclient as a scheme handler for Org Protocol.
Version Compliance
Guidance on this page is up to date with GNU Emacs 30.1 and Org 9.7.11. Sections where there is uncertainty on this are marked as such.
Installation and Configuration
Take the following steps to get Org protocol working for you.
- Setup Emacs server.
- Setup the Org protocol scheme handler.
- Test your Org protocol setup.
- Setup Org protocol capture.
- Construct an Org protocol URL request.
Steps 1, 2, and 5 are platform-specific so this section is largely organized by platform. Setting up Org protocol capture is placed in a common section as it considered platform independent.
GNU/Linux, BSD, and Unix variants
Setup Emacs server
Add the following lines to the Emacs initialization file (init.el
,
$HOME/.emacs
) to start Emacs server.
(server-start) (require 'org-protocol)
Either evaluate the above or restart Emacs to start the server.
Setup the Org protocol scheme handler
On GNU/Linux, Emacs 29.2+ configures emacsclient.desktop
to handle Org
Protocol URL requests. If your GUI window environment can use this
file, no further setup is required. (NOTE: This is not true for some
distributions of xdg-tools as reported in the bug #74467 - 31.0.50;
org-protocol emacsclient.desktop change is not fully functional - GNU
bug report logs.)
- If you use Emacs < 30
Most common desktop environments (Gnome, KDE et al) comply with the XDG Desktop Entry Specification. This means setting up
emacsclient
as theorg-protocol
handler using a .desktop file can be regarded as a standard way to set this up in most common desktop environments.Some environments, e.g. Gnome as of Gnome 3, have deprecated other configuration methods, e.g.
gconftool-2
to set-up protocol handling.Create an
org-protocol.desktop
file either in~/.local/share/applications/
to set-upemacsclient
as theorg-protocol
handler for the current user or in/usr/share/applications
to set-up a system-wide configuration:[Desktop Entry] Name=org-protocol Comment=Intercept calls from emacsclient to trigger custom actions Categories=Other; Keywords=org-protocol; Icon=emacs Type=Application Exec=emacsclient -- %u Terminal=false StartupWMClass=Emacs MimeType=x-scheme-handler/org-protocol;
Update the cache database of MIME types handled by desktop files via:
update-desktop-database ~/.local/share/applications/
Test your Org protocol setup
To test that Org protocol is setup and running, click on the JavaScript link below to store an Org link to this page.
In an Org buffer, use the binding C-c M-l
(org-insert-last-stored-link
) to paste the recently stored Org link.
Setup Org protocol capture
See Setup Org protocol capture in the common section.
Construct Org protocol URL Request
See Construct Org protocol URL request in the common section.
macOS
Setup Emacs Server
Recent versions of macOS (since Ventura) disallow the use of a local
domain socket for inter-process communication between apps with
separate sandboxes. Users using Scrim can instead setup a TCP
socket 1. Add the following lines to the
Emacs initialization file (init.el
, $HOME/.emacs
) to start Emacs
server.
(setopt server-use-tcp t) (server-start) (require 'org-protocol)
Setup the Org protocol scheme handler
If Scrim is installed, no further setup is required as Scrim will automatically handle Org protocol URL requests 1.
Users of the Mitsuharu Yamamoto fork of Emacs also do not need to setup an Org protocol scheme handler as this fork will natively handle Org protocol URL requests.
If you are using an old version of macOS (nee Mac OS X) older than Ventura, this guidance may still be valid. If you are using macOS Ventura or newer, none of this guidance is valid.
Follow the directions for installing EmacsClient.app from https://github.com/neil-smithline-elisp/EmacsClient.app. This should configure the org-protocol for all Mac OS X browsers.
After installing EmacsClient.app you should then verify the installation. Once verified, you can begin using org-protocol.
If that doesn't work, you might check https://github.com/xuchunyang/setup-org-protocol-on-mac for building a custom handler, combined with the per-browser config information below.
Test your Org protocol setup
To test that Org protocol is setup and running, click on the JavaScript link below to store an Org link to this page.
In an Org buffer, use the binding C-c M-l
(org-insert-last-stored-link
) to paste the recently stored Org link.
Setup Org protocol capture
See Setup Org protocol capture in the common section.
Construct Org protocol URL request
See Construct Org protocol URL request in the common section.
Windows
Setup Emacs Server
Native Windows has no support for a local domain socket so a TCP
socket is used instead. Add the following lines to the Emacs
initialization file (init.el
, $HOME/.emacs
) to start Emacs server.
(setopt server-use-tcp t) (server-start) (require 'org-protocol)
Setup the Org protocol scheme handler
This section has not been updated since Windows XP and may not be valid. Updated guidance is wanted.
Windows users may register the "org-protocol
" once for all by
adjusting the following to their facts, save it as *.reg file and
double-click it. This worked for me on Windows-XP Professional and the
emasc23 from ourcomments.org
(http://ourcomments.org/cgi-bin/emacsw32-dl-latest.pl). I'm no Windows
user though and enhancements are more than welcome on the org-mode
mailinglist. The original file is from
http://kb.mozillazine.org/Register_protocol.
REGEDIT4 [HKEY_CLASSES_ROOT\org-protocol] @="URL:Org Protocol" "URL Protocol"="" [HKEY_CLASSES_ROOT\org-protocol\shell] [HKEY_CLASSES_ROOT\org-protocol\shell\open] [HKEY_CLASSES_ROOT\org-protocol\shell\open\command] @="\"C:\\Programme\\Emacs\\emacs\\bin\\emacsclientw.exe\" \"%1\""
Test your Org protocol setup
To test that Org protocol is setup and running, click on the JavaScript link below to store an Org link to this page.
In an Org buffer, use the binding C-c M-l
(org-insert-last-stored-link
) to paste the recently stored Org link.
Setup Org protocol capture
See Setup Org protocol capture in the common section.
Construct Org protocol URL request
See Construct Org protocol URL request in the common section.
Common
Setup Org protocol capture
Knowledge of Org capture (info "(org) Capture") is recommended beforehand to understand how Org protocol extends it.
Org protocol capture (info "(org) The capture protocol") extends Org capture (info "(org) Capture") to support data import from external apps into Emacs. Different data types are supported for import:
- url
- a URL (typically of a web page)
- title
- the title of the web page
- body
- Text (typically selected) within the web page
The form of an Org protocol URL request with the capture
protocol
looks like this:
org-protocol://capture?template=TEMPLATE&url=URL&title=TITLE&body=BODY
In table form the following keys for the capture
protocol are
described as follows:
Key | Description | Template Placeholder | Notes |
---|---|---|---|
template |
Template key | Capture template key in org-capture-templates . If omitted, then org-protocol-default-template-key is used. |
|
url |
URL | %:link |
Typically the web page URL to capture. |
title |
Title | %:description |
Typically the title of the above web page, but can be arbitrary. |
body |
Body Text | %i |
Typically the selected text in the web page, but can be arbitrary. |
The template placeholder %:annotation
is expanded to be an Org link
constructed from url
and title
.
Users can define different capture templates (info "(org) Capture
templates") using the template placeholders described above. These
templates are added to the customizable Org variable
org-capture-templates
which itself is a list of templates.
An example Org protocol capture template is shown below with key name
"capture". The following Elisp shows how this template can be added to
org-capture-templates
.
(add-hook 'org-mode-hook (lambda () (add-to-list 'org-capture-templates ;; The template follows '("capture" "Capture (Org Protocol)" entry (file "notes.org") (function (lambda () (string-join '("* %:description" ":PROPERTIES:" ":CREATED: %U" ":END:" "%:annotation" "%i" "" "%?") "\n"))) :prepend t :empty-lines 1) ;; End template )))
Setup Org protocol open source
This section needs update for Org 9.7.11.
This one was designed to help with opening sources for editing when
browsing in the first place. org-protocol-open-source
uses the
custom variable org-protocol-project-alist
to map URLs to (local)
filenames.
Let's take https://orgmode.org/worg/ as our example.
Our intention is to click a bookmark (or link) to open the source of the
published file we are reading in our favourite editor. The bookmark-URL above
could be used again. But since org-protocol-open-source
regards the first
field only, this here will do:
javascript:location.href='org-protocol://open-source://'+encodeURIComponent(location.href)
To open files publihed on Worg locally, org-protocol-project-alist
should look
like this (you may skip the second project):
(setq org-protocol-project-alist '(("Worg" :base-url "https://orgmode.org/worg/" :working-directory "/home/user/worg/" :online-suffix ".html" :working-suffix ".org") ("My local Org-notes" :base-url "http://localhost/org/" :working-directory "/home/user/org/" :online-suffix ".php" :working-suffix ".org")))
If you're now browsing https://orgmode.org/worg/org-contrib/org-protocol.html and find a typo or have an idea how to enhance the documentation, simply click the bookmark and start editing.
There are two functions to help you fill org-protocol-project-alist
with
valid contents. One possibility is org-protocol-create
that guides you through
the process. If you're editing an Org-mode file that is part of a publishing
project in org-publish-project-alist
, try
M-x org-protocol-create-for-org RET
- Handle rewritten URLs
In some cases, replacing
:base-url
with:working-directory
and:online-suffix
with:working-suffix
will not yield the desired results.Suppose you maintain an online store located at
http://example.com/
. The local sources reside in/home/user/example/
. While most of the URLs map directly to local file names by stripping URL parameters from the end and replacing the:base-url
with:working-diretory
and:online-suffix
with:working-suffix
, this might not work for rewritten URLs. It's common practice to serve all products in such a store through one file and rewrite URLs that do not match an existing file on the server.That way, a request to
http://example.com/print/posters-A4.html
might be rewritten on the server to something likehttp://example.com/shop/products.php/posters-A4.html.php
, where/posters-A4-digital.html.php
is the so called path info. Note that the browser will not notice the rewrite.If you now click your
org-protocol://open-source://
bookmark, the handler will probably not find a file named/home/user/example/print/posters-A4.html.php
and fail.Or, even more simple, assume you're browsing
http://example.com/
. A file named/home/user/example/.php
is not likely to exist.Since Org-mode commit
69b46e10aab3b2374ecbc1a963ba56e77102a9a4
from 15th Nov. 2009, such an entry inorg-protocol-project-alist
may hold an additional property:rewrites
. This property is a list of cons cells, each of which maps a regular expression to a path relative to the:working-directory
.Now map the URL to the path
/home/user/example/products.php
by adding the:rewrites
property like this:(setq org-protocol-project-alist '(("example.com" :base-url "http://example.com/" :working-directory "/home/user/example/" :online-suffix ".php" :working-suffix ".php" :rewrites (("example.com/print/" . "products.php") ("example.com/$" . "index.php")) )))
Guess what the second
:rewrites
element does. Sinceexample.com/$
is used as a regular expression, it mapshttp://example.com/
,https://example.com
,http://www.example.com/
and similar to/home/user/example/index.php
.The
:rewrites
are searched as a last resort if and only if no existing file name is matched.
Construct Org protocol URL request
Numerous approaches can be used to construct an Org protocol request:
- As a web browser bookmark that can invoke JavaScript
- Via program/script generation (Bash, Python, Java, Go, Rust, C#, etc.)
Once the URL request has been constructed, it can be sent to Emacs via the scheme handler.
- Web Browser Bookmark
A cross-platform approach to constructing an Org protocol request is to create a web browser bookmark that can run JavaScript as its location.
- Create a bookmark in your web browser (Chrome, Firefox, Safari) named "Share Org Link".
Add the following code as the location for this bookmark.
javascript:location.href='org-protocol://store-link?' + new URLSearchParams({url:location.href, title:document.title});void(0);
- When visiting a web page, invoke the bookmark "Share Org Link" to share this link to Emacs. Note that a permission may need to be granted with this approach.
Many different variants of this approach can be taken to cover different Org protocol request types.
- 3rd Party Applications
- Captee (macOS)
Captee is an application that can construct an Org protocol URL from the macOS Share Menu1. Native apps that support the Share Menu can make an Org protocol
store-link
orcapture
request. - Acrobat Reader
The guidance in this section is likely stale.
Adapted from https://list.orgmode.org/loom.20080527T012114-502@post.gmane.org
You place a javascript file for each menu entry in
~/.adobe/Acrobat/<VERSION>/JavaScripts
on unix-like systems orc:/Program Files/Adobe/Acrobat <VERSION>/Reader/Javascripts/
on Windows, or wherever your Adobe Reader Installation might look for javascript.The examples given here will place new menu entries in the "Tools" menu, after restarting Adobe Reader.
- org-store-link.js
// from https://list.orgmode.org/loom.20080527T012114-502@post.gmane.org app.addMenuItem({cName:"org-store-link", cParent:"Tools", cExec:"app.launchURL('org-protocol://store-link://' + encodeURIComponent(this.URL) + '/' + encodeURIComponent(this.info.Title));"});
- org-capture.js
// from https://list.orgmode.org/loom.20080527T012114-502@post.gmane.org app.addMenuItem({cName:"org-capture", cParent:"Tools", cExec:"app.launchURL('org-protocol://capture://' + encodeURIComponent(this.URL) + '/' + encodeURIComponent(this.info.Title) + '/');"});
- org-store-link.js
- Opera
The guidance in this section is likely stale.
Opera setup is described here: http://www.opera.com/support/kb/view/535/.
To set up opera for use with org-protocol, follow these steps:
- Choose "Tools" -> "Prefences" from the menu.
- Select the tab "Advanced".
- Choose "Programs" from the list on the left.
- Now click the button "Add" on the very right.
- In the new dialog window, enter "
org-protocol
" as "Protocol", choose the radio button "Open with other application" and enter the path to emacsclient.
- Captee (macOS)
Troubleshooting
Firefox
Firefox users can follow the steps documented on https://kb.mozillazine.org/Register_protocol.
History of Org protocol
A historical account of Org protocol is needed here.
org-protocol.el
is based on code and ideas from
org-annotation-helper.el and org-browser-url.el
.
Deprecated URL Styles
The store-link
, capture
, and open-source
URL styles have been
changed to largely conform to the common internet scheme syntax of RFC
1738 and query component specification of RFC 3986.
This changes the format of the scheme specific part from using /
to
separate parameters to using HTTP query key=value
style parameters.
The following tables illustrate the difference between the old and new styles. Migrating from the old style to new is recommended.
store-link |
|
---|---|
Old Style | org-protocol:/store-link:/URL/TITLE |
New Style | org-protocol://store-link?url=URL&title=TITLE |
capture |
|
---|---|
Old Style | org-protocol:/capture:/URL/TITLE |
New Style | org-protocol://capture?url=URL&title=TITLE&body=BODY |
open-source |
|
---|---|
Old Style | org-protocol:/open-source:/URL |
New Style | org-protocol://open-source?url=URL |
Removed Protocols
The remember
protocol is removed. Users should migrate any
configuration relying on it to the capture
protocol.
Screencast: small introduction to org-protocol.el
This video is obsolete. Retained for archival purposes.
This screencast shows off some nice things you can do with Firefox, Emacs, Org-mode and org-protocol.el.
It first shows how to create two bookmarklets, org-capture
and
org-store-link
. These bookmarklets enable your Firefox to talk to
emacsclient via a new protocol (org-protocol://
); emacsclient then
parses the request and tells Emacs to capture or store stuff at the
relevant places in your Org files.
At the end of the screencast, we create two ubiquity commands from
these bookmarklets. Now in Firefox ALT-SPC org-capture RET
creates
a note in my Org files.