Emacs Web Wowser (EWW) got ace-link

Emacs 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.