Emacs Web Wowser (EWW) got ace-link
30 Dec 2014Emacs goodness incoming
I've discovered a nice Emacs-related blog - Content AND Presentation. Unlike The Axis of Eval, the blog that I mentioned yesterday, this one is pretty self-contained, i.e. it doesn't link to many external information sources. So I thought that it's perfect for trying EWW to read it.
Not so fast! Configure first.
For modes that don't require to self-insert (and even for some that do), I like to navigate with h/j/k/l as arrows. These arrows are on the home row, so navigation becomes a pleasant and relaxed experience. But for EWW I decided to add a little twist: if the point is in the first column, j/k will move down/up not by one line, but by one paragraph. This is great for concentration: I navigate to a paragraph, read it, navigate to the next one. The point shows me the paragraph that I'm reading, everything before the point I've already read. So every time I press j, I get a tiny warm feeling of accomplishment. I can also pair this with v, which I bind to recenter the current line to the top.
So here's what my key setup currently looks like:
(defun oleh-eww-hook ()
(define-key eww-mode-map "j" 'oww-down)
(define-key eww-mode-map "k" 'oww-up)
(define-key eww-mode-map "l" 'forward-char)
(define-key eww-mode-map "L" 'eww-back-url)
(define-key eww-mode-map "h" 'backward-char)
(define-key eww-mode-map "v" 'recenter-top-bottom)
(define-key eww-mode-map "V" 'eww-view-source)
(define-key eww-mode-map "m" 'eww-follow-link)
(define-key eww-mode-map "a" 'move-beginning-of-line)
(define-key eww-mode-map "e" 'move-end-of-line)
(define-key eww-mode-map "o" 'ace-link-eww)
(define-key eww-mode-map "y" 'eww))
(add-hook 'eww-mode-hook 'oleh-eww-hook)
As you see, I was careful to re-assign eww-back-url
and
eww-view-source
- the commands that I've displaced from l
and v. And here's the implementation of the arrows:
(defun oww-down (arg)
(interactive "p")
(if (bolp)
(progn
(forward-paragraph arg)
(forward-line 1))
(line-move arg)))
(defun oww-up (arg)
(interactive "p")
(if (bolp)
(progn
(forward-line -1)
(backward-paragraph arg)
(forward-line 1))
(line-move (- arg))))
Cherry on the top
And while I was at it, I've added ace-link support for EWW. It was
pretty easy, basically the same routine as for help-mode
and
info-mode
. The only hard part was to figure out what part of the
code keeps binding shr-save-contents
to o, my preferred
binding for ace-link
. Turns out it was eww-link-keymap
, and not
shr-map
. So here's the new key binding code:
(defun ace-link-setup-default ()
"Setup the defualt shortcuts."
(eval-after-load "info"
'(define-key Info-mode-map "o" 'ace-link-info))
(eval-after-load "help-mode"
'(define-key help-mode-map "o" 'ace-link-help))
(eval-after-load "eww"
'(progn
(define-key eww-link-keymap "o" 'ace-link-eww)
(define-key eww-mode-map "o" 'ace-link-eww))))
If you haven't tried ace-link before, you can get it from MELPA. The minimal configuration that you need is this:
(ace-link-setup-default)
Here's the setup that I'm actually using:
(use-package ace-link
:load-path "~/git/ace-link"
:init (ace-link-setup-default))
I'm using it from my git folder since when I want to edit a project, I like to use smex's jump-to-definition.
And use-package is useful
for the cases when my ~/git/
happens not to contain ace-link
. In
that case, instead of getting a debugger error on starting Emacs, I
get only a polite "Could not load package ace-link" in my *Messages*
buffer.