Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
(Re)generate: (find-eejump-intro)
Source code:  (find-eev "eev-intro.el" "find-eejump-intro")
More intros:  (find-eval-intro)
              (find-eepitch-intro)
This buffer is _temporary_ and _editable_.
Is is meant as both a tutorial and a sandbox.



The problem
===========
Suppose that we have several files that we are working on, and we
want a quick way to jump to (i.e., to visit) any of them with
very few keystrokes; moreover,

  1) we want our list of files to be preserved between one Emacs
  session and another,

  2) we know that each "visit a file" command will correspond
  to an elisp hyperlink.

One quick solution would be to put the list of elisp hyperlinks
in a file, and make the key `M-j' open that file. But then
jumping to a file in that list becomes a two-step process: type
`M-j', move the point to the right line, type `M-e'. This would
be similar to what happens when we use one of the `find-e*'
commands, for example `find-efunction':

  (find-efunction 'find-efunction)
     (eek "M-h M-f find-efunction")

Those intermediate steps - seeing the list, locating visually the
right line, moving to it - are distracting, so we want to add new
items to our wishlist:

  3) it should be possible to jump straight to any of the files
  in the list, and with very few keystrokes,

  4) the list should be stored in a format that lets us see
  quickly which are the keystrokes for accessing each item - so
  that we won't need to memorize anything,

  5) the list should be easy to modify,

  6) it should be possible to assign shorter key sequences to
  files we visit more often,

  7) the source code must be very simple.


  
A miniature
===========
My original solution was this: I used only one keybinding, `M-j',
that acted differently when invoked with different numeric
prefixes; when invoked as `M-1 M-j' it opened a certain file,
when invoked with `M-2 M-j' it opened another, and so on, and
when it was invoked with an unrecognized prefix or with no prefix
it jumped to its definition in my ~/.emacs. Its code was like
this (**NOTE: do not execute these defuns**):

  ;; eejump-simplified (`M-j'):
  ;; M-1 M-j opens a certain file,
  ;; M-2 M-j opens another file,
  ;; when the argument is 11, 22, 33 or 44 do something special,
  ;; like changing the font;
  ;; with no argument or with an unrecognized argument jump to the
  ;; definition of eejump in ~/.emacs; then we can see which numbers
  ;; correspond to which actions (the source is the documentation!), and
  ;; we can change the definition if needed - just run `M-e' at the
  ;; right place to make the changes apply.
  ;;
  (global-set-key (kbd "M-j") 'eejump-simplified)
  (defun eejump-simplified (arg) (interactive "P")
    (cond ((eq arg 1) (find-file "~/NOTES"))
          ((eq arg 2) (find-file "~/otherfile.txt"))
          ;;
          ((eq arg 11) (set-frame-font "fixed"))
          ((eq arg 22) (set-frame-font "terminus-16"))
          ((eq arg 33) (set-frame-font "terminus-bold-16"))
          ((eq arg 44) (set-frame-font "10x20"))
          (t (find-function 'eejump-simplified))))

except that my definition became huge with time as I added to it
more entries for files (and other actions!) that I used often,
and also entries that were used not so often...

All the "options" - i.e., all the `(eq arg nnn)' lines - had to
be together in a single very big defun, and there was no way to
add new options temporarily...




Families
========
Let's use a shorthand for key sequences: for example, `M-123j'
instead of `M-1 M-2 M-3 M-j'.

I tend to assign related numbers to related files. For example, I
use the prefix "5" for things that are Emacs-related: `M-5j'
visits my .emacs, `M-555j' visits the directory with all of eev's
elisp files, and `M-51j', `M-52j', etc, visit specific eev source
files that I happen to be working on. Also, I use the prefix
"7" for things related to LaTeX. So, the "5*" family is
composed of Emacs-related files, and the "7*" family of
LaTex-related files.

The definition of `eejump-simplified' given above does not
satisfy these two (new!) wishlist items:

  8) it should be possible to jump to the definition of the
  "5*" family by typing something like `M-5678j', where
  "5678" is a non-assigned number that starts with the "5*"
  prefix,

  9) it should be possible to convert a number/hyperlink pair
  very easily into to the code that assigns that elisp hyperlink
  as the desired behavior for that number - and it should be
  possible to do that both permanently (think in changing the
  definition of `eejump-simplified' in your .emacs) and
  temporarily (i.e., for the current Emacs session only).



eejump
======
The definition of `eejump' that comes with eev is a bit more
complex than the one given above, and it will not be shown
here (it involves a tricky recursive function) but it satisfies
the 9 wishlist items above. It works in this way: if you type,
say, `M-123j', then:

  a) if `eejump-123' is defined, then execute it;
  b) otherwise, if `eejump-12*' is defined, execute it;
  c) otherwise, if `eejump-1*' is defined, execute it;
  d) otherwise, if `eejump-*' is defined, execute it,

and if `eejump-*' also is not defined, you get an error.

Here is a block of "defun"s that defines (trivial) meanings for
"91", "92", "991", and "992", plus targets for the "9*"
family and for the "99*" family; it also has two tests in
comments that will be very important for an explanation below.
Let's refer as that, in this section and the next ones, as "the
block of six defuns (plus four tests)".

  (defun eejump-9* () (find-efunction 'eejump-9*))
  (defun eejump-91 () (message "M-91j"))
  (defun eejump-92 () (message "M-92j"))
  (defun eejump-99* () (find-efunction 'eejump-99*))
  (defun eejump-991 () (message "M-991j"))
  (defun eejump-992 () (message "M-992j"))
  ;; (find-function-noselect 'eejump-9*)
  ;; (find-function-noselect 'eejump-99*)
  ;; (find-efunction 'eejump-9*)
  ;; (find-efunction 'eejump-99*)

Try to evaluate each of the sexps above with `M-e', then try to
run things like `M-92j' and `M-992j' - they should work - and
then something like `M-99876j'; that will not work, you'll get an
error like "Don't know where `eejump-99*' is defined"...



eejump blocks
=============
Let's a call a sequence of defuns for eejumps with the same
prefix, like this, starting with a `(defun eejump-<prefix>* ...)',

  (defun eejump-99* () (find-efunction 'eejump-99*))
  (defun eejump-991 () (message "M-991j"))
  (defun eejump-992 () (message "M-992j"))

an "eejump block".

There are two sample eejump blocks in eejump.el, for the prefixes
"" and "5", starting at:

  (find-eev "eejump.el" "eejump-*")
  (find-eev "eejump.el" "eejump-5*")

You should probably copy them to your .emacs, and then start
modifying them.




Making an `eejump-nn*' work
===========================
If you execute a line like 

  (defun eejump-9* () (find-efunction 'eejump-9*))

then Emacs will only record that `eejump-9*' has been defined in
this buffer - and thus will be able to jump to its definition
when you type something like `M-987j' - if two conditions are
met:

  a) the defun is executed with `M-x eval-region', `M-x
     eval-buffer', or some variant of `load' or `require' (`M-e'
     will not do!),

  b) the buffer with the definition is associated to a file; see
     these two pages of the Emacs manuals

       (find-enode "Buffers" "visiting")
       (find-elnode "Buffer File Name")

    if that concept is not totally familiar to you.

So, as an experiment, copy the block with six defuns and four
tests above to some buffer associated to a file, mark it, and
execute it with `M-x eval-region'. Now the tests should work -
and key sequences like `M-987j' should also work, and should jump
to the right places. See also:

  (find-elnode "Where Defined")



Producing `eejump-nnn's and `eejump-nnn*'s
==========================================
Look again to the block of six "defun"s above. Now type `M-J'
on each of the six lines below:

  9
  91 (message "M-91j")
  92 (message "M-92j")
  99
  991 (message "M-991j")
  992 (message "M-992j")

you will notice that you've just generated a block of defuns like
the one in the previous section! `M-J' works like this: it tries
to split the current line into "words" separated by whitespace,
but producing a maximum of two "words" (the 2nd, 3rd, etc
"words" as treated as a single "word"); if the second word is
empty, then `M-J' produces a definition for an `eejump-nnn*'; if
it is not empty, then `M-J' produces a definition for an
`eejump-nnn', treating the second "word" as a sexp.

Note that `M-J' is quite dumb - it doesn't check if the first
"word" is a number, nor if the second is a sexp. Use it with
care! Try using `M-J' on the "a b ..." lines below - you will
get useless definitons.

  a  b  c  d
  a  b  c
  a  b
  a




Permanent and temporary
=======================
If you create a block like the block of six defuns above in your
.emacs file then you'll be attributing a "permanent" meaning to
`M-91j', ..., `M-992j', and if you create it in a file that is
not evaluated in every Emacs session (and execute it, of course),
then you'll be attributing just a "temporary" meaning to
`M-91j', ..., `M-992j'.




# Local Variables:
# coding:           raw-text-unix
# ee-anchor-format: "%s"
# End: