23 Jan 2013

Bit o' Elisp: Find+Insert a Link in reStructuredText

An annoying bit of my workflow that I've finally simplified: inserting links to code libraries, documentation, etc. in reStructuredText files.

Previously, the process went like this:

  1. Decide I want to insert a link to a project, say, Pyramid.
  2. Type Pyramid_ and go to the bottom of the page.
  3. Realize I don't remember the URL to Pyramid's site.
  4. Switch to Chrome, Google for "Pyramid."
  5. Grab URL (usually the top spot, definitely on the first page).
  6. Switch back to Emacs, paste link into buffer.

This process is highly disruptive; who wants to leave Emacs while they're getting their prose on?!

I fixed it by writing a quick function to prompt for link text, try to find the link in the document and, failing that, use google.el and completing-read to search for and insert the appropriate link. With a prefix argument, you can supply anchor text that differs from the link. Hope it helps somebody else:

(require 'google)
(require 'ido)
(require 'rst)

(defun rst-link (prompt-for-text link)
  (interactive "P\nsLink: ")
  (let ((text (if prompt-for-text (read-string "Text: ") link)))
    (if prompt-for-text
        (insert (format "`%s <%s>`_" text link))
      (insert (format (if (string-match " " link) "`%s`_" "%s_") link)))
    (save-excursion
      (unless (re-search-forward (format "\.\. _%s:" link) nil t 1)
        (goto-char (point-max))
        (unless (eq (current-column) 0) (insert "\n") (forward-line 1))
        (insert (format ".. _%s: " link))
        (insert (ido-completing-read "URL:\s" (google-result-urls (google-search-web link))))))))

(define-key rst-mode-map (kbd "C-c C-l") 'rst-link)

(Also available for forking on GitHub)

Tagged: emacs rst elisp