Capturing links quickly with emacsclient, org-protocol, and Chrome Shortcut Manager on Microsoft Windows 8
Posted: - Modified: | emacs, orgUPDATE 2015-11-30: Well, that bitrotted quickly! Chrome Shortcut Manager is no longer available, but maybe Shortkeys will work instead.
Since I’ll be snipping lots of Emacs-related resources and organizing them into Emacs news roundups, I figured it was time to get org-protocol working.
Step 1: Get emacsclient
to work
I was getting the error “No connection could be made because the target machine actively refused it.” I needed to change my Windows Firewall rules. From the Windows Firewall screen, I clicked on Advanced settings and chose Inbound Rules. On the Programs and Services tab, I confirmed that the right Emacs binary was selecI looked for the rules for GNU Emacs, consolidating them down to two rules (UDP and TCP). I limited the scope to local/remote 127.0.0.1. On the advanced tab, I selected all the profiles and changed edge traversal to blocked.
I was still getting the error despite a fresh M-x server-start
. After I deleted the contents of ~/.emacs.d/server
and did another M-x server-start
. When I ran emacsclient test.txt
from the command-line, it correctly opened the file in my existing Emacs instance. Hooray!
Step 2: Load org-protocol
I added org-protocol
to the org-modules
variable so that Org would load it when Emacs reaches the (org-load-modules-maybe t)
in my config. Since I didn’t want to restart Emacs, I also evaluated (load-library "org-protocol")
to load it.
Step 3: Register the protocol
I ran an org-protocol.reg
that set up the appropriate org protocol entry:
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\org-protocol] "URL Protocol"="" @="URL:Org Protocol" [HKEY_CLASSES_ROOT\org-protocol\shell] [HKEY_CLASSES_ROOT\org-protocol\shell\open] [HKEY_CLASSES_ROOT\org-protocol\shell\open\command] @="\"c:\\Program Files (x86)\\GNU Emacs 24.4\\bin\\emacsclientw.exe\" \"%1\""
You can find a similar one in the org-protocol documentation.
Step 4: Add support to Chrome
I wanted something a bit different from the org-capture extensions available for Chrome. In particular, I wanted:
- a keyboard-friendly way to quickly store a link
- a keyboard-friendly way to capture a link with some notes
The Shortcut Manager extension for Chrome lets you specify your own keyboard shortcuts for running short Javascript. Inline Javascript doesn’t work on all sites. For example, Github blocks it with the following error: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src assets-cdn.github.com". Either the 'unsafe-inline' keyword, a hash ('...'), or a nonce ('nonce-...') is required to enable inline execution.
Still, it works for many sites, so it’s a start. Here are the shortcuts I put together.
l | Store link |
L | Store link (prompt for title, default to selection or document title) |
c | Capture link (prompt for template) |
You can import them by going to Chrome’s More Tools > Extensions screen and choosing the Options link for Shortcut Manager. From there, use Import settings.
// ==UserScript== // @ShortcutManager // @name Store link // @namespace XPrUJhE4wRsC // @key l // @include * // ==/UserScript== var storeLink = function(){ var selection = window.getSelection().toString(); var uri = 'org-protocol://store-link://' + encodeURIComponent(window.location.href) + '/' + encodeURIComponent(selection || document.title); window.location = uri; return uri; }; storeLink(); // ==UserScript== // @ShortcutManager // @name Capture link // @namespace XPrUJhE4wRsC // @key c // @include * // ==/UserScript== var captureLink =function(){ var uri = 'org-protocol://capture://' + encodeURIComponent(window.location.href) + '/' + encodeURIComponent(document.title) + '/' + encodeURIComponent(window.getSelection().toString()); window.location = uri; return uri; }; captureLink(); // ==UserScript== // @ShortcutManager // @name Store link with prompt // @namespace XPrUJhE4wRsC // @key Shift+l // @include * // ==/UserScript== var storeLinkWithPrompt = function(){ var selection = window.getSelection().toString(); var uri = 'org-protocol://store-link://' + encodeURIComponent(window.location.href) + '/' + encodeURIComponent(window.prompt('Title', selection || document.title)); window.location = uri; return uri; }; storeLinkWithPrompt();
Shortcut Manager looks like a really useful extension. Here are some other shortcuts I set up:
x | close the current tab |
r | reload (cacheless) |
t | open a new tab |
n | select the right tab |
p | select the left tab |
b | back |
f | forward |
Step 5: Add shortcuts for managing stored links
I added my/org-insert-link
and org-insert-last-stored-link
to my main hydra, which is on my hh
keychord. my/org-insert-link
is like org-insert-link
, except it adds a newline if the cursor is at an Org link so that we don’t trigger org-insert-link
‘s behaviour of editing links.
(defun my/org-insert-link () (interactive) (when (org-in-regexp org-bracket-link-regexp 1) (goto-char (match-end 0)) (insert "\n")) (call-interactively 'org-insert-link)) (key-chord-define-global "hh" (defhydra my/key-chord-commands () "Main" ;; ... ("L" my/org-insert-link) ("l" org-insert-last-stored-link) ;; ... ))
This lets me quickly insert a bunch of links with a key sequence like h h l l l l
or select a link to insert with h h L
. C-y
(yank
) pulls in the URL of the last stored link, too.
Let’s see how this works out!
13 comments
Diego Berrocal
2015-11-07T18:28:12ZYou can also use Ultimate Org Capture if you are using chrome :P https://chrome.google.com/w...
sachac
2015-11-07T23:21:57ZYeah, I looked at that, but I wanted more keyboard-friendliness and customizability. =) Thanks for making and sharing that, though!
As it turns out, Shortcut Manager can sometimes get confused by text areas, so I've changed my shortcuts to be more like the keychords I use in Emacs: hh followed by another key.
Diego Berrocal
2015-11-07T23:31:51ZThe whole point of it is to have a keyboard-friendly interface, like using `Control+Shift-L` in chrome would make the same action as clicking on the extension :P But I guess a more Windows friendly approach is that one. (http://cestdiego.github.io/... this is the post that explains my usage of ultimate org-capture
sachac
2015-11-07T23:55:32ZI looked into it too briefly to determine whether I could set up multiple keyboard shortcuts to do different things (in particular, I wanted quickly storing multiple links vs. storing a link but changing the title vs. capturing a link and writing more of a note about it). I might still end up going with some kind of extension if that gets me around the security limits for sites like Github. We'll see!
NoonianAtall
2015-11-12T16:08:34ZYou may find this useful: https://github.com/alphapap... It lets you convert the HTML of the browser selection to org-mode using Pandoc, and capture it with org-protocol.
Also, here are some straightforward, up-to-date instructions for setting up org-protocol on Linux: http://stackoverflow.com/a/...
sachac
2015-11-16T22:56:06ZNice! I usually capture short snippets, but that will come in handy for lists.
Tamara Temple
2015-12-26T12:03:05ZI was trying to pull all this together for my working environment, which is compiled emacs 24.5 on OSX, rather than using Aquamacs and EmacsClient as suggested in the org-protocol docs, as well as Chrome. I ended up tossing together a tiny Sinatra app to handle the call to emacsclient, and slightly different shortkey & bookmarklet javascript. I threw it up on Github at https://github.com/tamouse/...
Jan-Willem Hiddink
2018-07-18T08:59:59ZThe chrome extension link has become invalid, it seems. I think you mean https://chrome.google.com/w... (edit: Aargh nevermind, I obviously missed your comment exactly about this)
yPunto to
2019-08-26T13:49:18ZHi.
I tried it on windows, with no success. I will try now, once I've seen you wrote about capturing. A question:
The "Jekyll's handler for org-protocol" that is on MELPA is the best way to go, or better old fashion installation?
sachac
2019-08-28T02:11:59ZIt's been a while and I'm no longer on Windows 8, so I'm not sure if things have broken a lot since I posted this. Sorry, and good luck!
yPunto to
2019-08-28T06:09:05ZThanks Sacha :-)
Then where are you? Can you take us there? ;D
sachac
2019-08-30T20:32:04ZI do most of my browsing (and pretty much everything) on my phone, since I have very limited computer time with our 3.5-year-old around. To capture a URL on my Android phone, I simply send it to Orgzly. I have Orgzly set up to sync with a local file repository as often as it can, and I use Syncthing to synchronize between devices. global-auto-revert-mode helps too. :)
Bob
2020-11-20T20:39:08ZIf you want a registry setup that works for non-admins please use the followinging:
REGEDIT 4
[HKEY_CURRENT_USER\Software\Classes\org-protocol]
@="URL:org-protocol"
"URL Protocol"=""
[HKEY_CURRENT_USER\Software\Classes\org-protocol\shell]
[HKEY_CURRENT_USER\Software\Classes\org-protocol\shell\open]
[HKEY_CURRENT_USER\Software\Classes\org-protocol\shell\open\command]
@="\"C:\\Users\\dau\\scoop\\apps\\emacs\\current\\bin\\emacsclientw.exe\" \"%1\""