GNU Eev provides e-script environment.

What is an e-script exactly ? Simple plain old ascii text files holding commands (shell or not) and EmacsLisp commands (hyperlinks).

What would it be useful for ?

The good thing with e-scripts is its format-independant nature allowing them to be embedded in any file: source code (like in litteral programming), documentations, … by EduardoOchs

News (nov/2012)

There’s a video here:

The README above has many pointers (to changes, docs, etc). Please take a look!


Latest version is 0.95.1 released on 2006.

Get it at


Getting Help

There are several channels to get help:

- a mailing list at - a CategoryIrc channel: #eev on freenode

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