Eev-mode is a tool to let record “executable logs” of what we do in a format that is reasonably easy to read and to modify, and that lets us “play back” those logs step by step in any order.

Most steps are either

This video has a demo of eepitch blocks.

The main starting point of eev is this tutorial (accessible by ‘M-x find-eev-quick-intro’ or ‘M-5 M-j’).

Home page: (by EduardoOchs).

Getting Help

There are several channels to get help:

Everything below this point was written by ThierryVolpiatto in 2013. Some things may be obsolete!

Build a TOC for your files

EevMode is a great tool to build table of contents of your files.

Be sure of course to have Eev installed correctly,([1])

if you find ‘eev-mode’ too invasive,

(it can have some strange effect, like reverting versioned files with VC become impossible)

you can set M-e globally, like that you can use eev links even when ‘eev-mode’ is turned off.

(global-set-key (kbd "M-e") 'eek-eval-sexp-eol) 

;; Local Variables:
;; eev-comment-prefix: ";"
;; ee-anchor-format: "«%s»"
;; End:

Note: ‘eev-comment-prefix’ is the comment string you use for this file (elisp ⇒ ;)

To make the little green glyph, turn on ‘eev-mode’, then hit M-,

and at prompt enter < < or > >.

(Of course you set ‘ee-anchor-format’ as you want)

Now save your file, kill buffer and reopen your file.

Now when you write an entry like:

;; «title-of-section» (to “.title-of-section”)

You are able to write an entry in your index at beginning of file like:

;; «.title-of-section» (to “title-of-section”)

To write that, just write:

;; title of section

And then hit M-, (with the cursor on the line) using this code:

(defun tv-eev-tag-entry ()
  "Tag entry in file with eev glyph"
  (if (and ee-anchor-format
      (let ((entry (replace-regexp-in-string (format "^[%s ]+"
                                             (thing-at-point 'line)))
        (setq entry (replace-regexp-in-string "\n" "" entry))
        (setq new-entry (replace-regexp-in-string " " "-" entry))
        (re-search-backward entry)
        (delete-region (point) (line-end-position))
        (insert (concat (format ee-anchor-format new-entry)
                        " (to \"." new-entry "\")")))
      (message "Did you forget to set up ee-anchor-format and eev-comment-prefix?")))

(global-set-key (kbd "C-M-,") 'tv-eev-tag-entry)

So on one or the over link, when you hit M-e you will move to index or your entry.

That’s cool but if you have a file with hundred of lines and many entries , it will be a big work to

write an index.

;; (tv-ee-index-create)

And eval it with M-e.

It will create your index or update it if you made some changes in your file.

(defmacro *string (str num)
  "* a string with a number"
  `(let ((str-lis))
    (dotimes (n ,num)
      (push ,str str-lis))
    (mapconcat #'(lambda (i) i) str-lis "")))

(defun tv-ee-index-create ()
  "Create or update an index of all tagged entries found in file.
Put the definition of function in comment at start of index
and eval it with \"M-e\""
  (flet ((create ()
           (let ((entry-list nil)
                 (new-entry nil)
             (insert (concat (*string eev-comment-prefix 4)
                             (format ee-anchor-format "INDEX") "\n"))
             (setq start-pos (point))
             (while (not (eobp))
               (forward-line 1)
               (when (re-search-forward (concat (format "^%s*"
                                                " *"
                                                (format ee-anchor-format ".+")) nil t)
                 (setq new-entry
                       (replace-regexp-in-string (format "%s* *" eev-comment-prefix)
                                                           (match-string 0)))
                 (push new-entry entry-list)))
             (setq entry-list (reverse entry-list))
             ;; we have now a list with elmts like «elmt»
             (goto-char start-pos)
             (dolist (i entry-list)
              (let ((new-entry (substring i 1 (1- (length i)))))
                (insert (concat (*string eev-comment-prefix 3)
                                " "
                                (format ee-anchor-format
                                        (concat "." new-entry))
                                (concat " (to \""
             (setq end-pos (point))
             (and (fboundp 'align-cols)
                  (align-cols start-pos end-pos 3))
             (insert "\n")
             (insert (concat (*string eev-comment-prefix 3)
                             "==UPDATE-EEV-BOUNDARY== ;; (Don't delete this line!)\n"))))
         (update ()
           (let ((beg (point))
             (when (re-search-forward (format "^%s\\{3\\}==UPDATE-EEV-BOUNDARY==" eev-comment-prefix) nil t)
               (setq end (point)))
             (delete-region beg end)
    (let ((action))
        (if (re-search-forward (format "^%s\\{3\\}==UPDATE-EEV-BOUNDARY==" eev-comment-prefix) nil t)
            (setq action 'update)
            (setq action 'create)))
        (when (and ee-anchor-format
          (funcall action)))))

Note: To have a nice index install

You should have now a file indexed like:


Have fun!


This page needs more informations to explain what it is useful for, etc.

CategoryHypermedia CategoryShell CategoryRegion CategoryProgrammerUtils CategoryModes CategoryMenus CategoryJournaling CategoryExternalUtilities CategoryHypermedia CategoryHelp CategoryNavigation