[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eev af88c9b 01/64: Initial commit for eev2
From: |
Stefan Monnier |
Subject: |
[elpa] externals/eev af88c9b 01/64: Initial commit for eev2 |
Date: |
Sun, 7 Apr 2019 16:59:01 -0400 (EDT) |
branch: externals/eev
commit af88c9b3b276d6c087b8095da0898e73fb60a83b
Author: Eduardo Ochs <address@hidden>
Commit: Eduardo Ochs <address@hidden>
Initial commit for eev2
---
README.md | 23 +
VERSION | 2 +
eejump.el | 107 ++
eepitch.el | 783 +++++++++
eev-anchors.el | 167 ++
eev-audiovideo.el | 337 ++++
eev-blinks.el | 749 ++++++++
eev-bounded.el | 330 ++++
eev-brxxx.el | 282 +++
eev-channels.el | 236 +++
eev-code.el | 298 ++++
eev-edit.el | 226 +++
eev-elinks.el | 906 ++++++++++
eev-env.el | 86 +
eev-eval.el | 168 ++
eev-flash.el | 97 ++
eev-intro.el | 4837 ++++++++++++++++++++++++++++++++++++++++++++++++++++
eev-mode.el | 243 +++
eev-multiwindow.el | 130 ++
eev-pdflike.el | 436 +++++
eev-plinks.el | 147 ++
eev-prepared.el | 256 +++
eev-rcirc.el | 127 ++
eev-readme.el | 96 ++
eev-tlinks.el | 1438 ++++++++++++++++
eev-wrap.el | 477 ++++++
eev2-all.el | 119 ++
27 files changed, 13103 insertions(+)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..65e8cac
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+This is a README.md file for eev, written in a hurry - in 2013aug26 -
+just to make github happy! You can find an online version of the
+interactive tutorials for eev at:
+
+ http://angg.twu.net/eev-intros/find-eev-intro.html
+
+Besides that the best introductions to eev are these two videos,
+
+ Eepitch: a way to control shell-like programs from Emacs
+ http://www.youtube.com/watch?v=Lj_zKC5BR64
+
+ An introduction to eev2
+ http://www.youtube.com/watch?v=doeyn5MOaB8
+
+and the main URL for eev is this:
+
+ http://angg.twu.net/#eev
+
+
+Cheers! =)
+ Eduardo Ochs
+ address@hidden
+ http://angg.twu.net/
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..a3d4f34
--- /dev/null
+++ b/VERSION
@@ -0,0 +1,2 @@
+Mon Aug 26 05:42:58 GMT 2013
+Mon Aug 26 02:42:58 BRT 2013
diff --git a/eejump.el b/eejump.el
new file mode 100644
index 0000000..c1367ff
--- /dev/null
+++ b/eejump.el
@@ -0,0 +1,107 @@
+;;; eejump.el -- jump quickly to predefined places.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013jan04
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eejump.el>
+;; htmlized: <http://angg.twu.net/eev-current/eejump.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-eejump-intro.html>
+;; (find-eev-intro)
+;; (find-eejump-intro)
+
+;;; Commentary:
+
+;; See: (find-eejump-intro)
+;; and: (find-eev "eev-wrap.el" "eewrap-eejump")
+
+
+
+
+;; This module installs a key binding into eev-mode-keymap, so:
+(require 'eev-mode) ; (find-eev "eev-mode.el")
+
+(define-key eev-mode-map "\M-j" 'eejump)
+
+(defun eejump (arg)
+ "See: (find-eejump-intro)"
+ (interactive "P")
+ (if (null arg)
+ (eejump-*)
+ (if (fboundp (intern (format "eejump-%d" arg)))
+ (funcall (intern (format "eejump-%d" arg)))
+ (eejump-str* (format "%d" arg)))))
+
+(defun eejump-str* (str)
+ "An internal, recursive function used by `eejump'.
+See: (find-eejump-intro \"\\neejump\\n\")"
+ (if (fboundp (intern (format "eejump-%s*" str)))
+ (funcall (intern (format "eejump-%s*" str)))
+ (eejump-str* (substring str 0 -1))))
+
+
+
+
+
+;; This is an "eejump block", as described in:
+;; (find-eejump-intro "eejump blocks")
+;; You should probably copy this to your .emacs - and
+;; then start modifying it.
+;;
+;; Note that with eev-mode you can use:
+;; M-e to follow elisp hyperlinks, see: (find-eval-intro "`M-e'")
+;; M-k to go back, see: (find-eval-intro "`M-k'")
+;; M-j to jump to predefined places, see: (find-eejump-intro "Families")
+;; in particular: M-j --> (find-efunction 'eejump-*)
+;; M-2j --> (find-emacs-intro)
+;; M-5j --> (find-eev-intro)
+;; M-50j --> (find-eev "eev-readme.el")
+;;
+(defun eejump-* () (find-efunction 'eejump-*))
+(defun eejump-1 () (find-fline "~/TODO"))
+(defun eejump-10 () (set-frame-font "5x7" t))
+(defun eejump-11 () (set-frame-font "6x13" t))
+(defun eejump-2 () (find-emacs-intro))
+(defun eejump-5* () (find-efunction 'eejump-5*))
+(defun eejump-5 () (find-eev-intro))
+(defun eejump-50 () (find-eev "eev-readme.el"))
+(defun eejump-59 () (find-eev-update-links))
+
+(defun eejump-55 () (find-fline "~/.emacs"))
+(defun eejump-552 () (find-eev "eev2-all.el"))
+(defun eejump-555 () (find-eev ""))
+
+
+
+(provide 'eejump)
+
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eepitch.el b/eepitch.el
new file mode 100644
index 0000000..7f3935e
--- /dev/null
+++ b/eepitch.el
@@ -0,0 +1,783 @@
+;; eepitch.el - record interactions with shells as readable notes, redo tasks.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug16
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eepitch.el>
+;; htmlized: <http://angg.twu.net/eev-current/eepitch.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-eepitch-intro.html>
+;; (find-eev-intro)
+;; (find-eepitch-intro)
+
+;;; Commentary:
+
+;; This implements a much simpler way to interact with external
+;; programs than the one shown in:
+;; <http://angg.twu.net/eev-current/anim/channels.anim.html>
+;;
+;;
+;; Quick start guide (note: old!)
+;; ==============================
+;; Read the first sections of
+;; <http://angg.twu.net/eev-current/eepitch.readme.html>
+;; then load this file, with something like:
+;; (load-file "eepitch.el")
+;; Then in the '( ... ) block below type M-T on the `shell' line to
+;; convert it to an "eepitch block", then use `F8's to execute the
+;; three red-star lines, then use more `F8's to send the "cd /tmp/"
+;; and the "ls" to the shell buffer.
+'(
+
+shell
+cd /tmp/
+ls
+
+)
+;; Note that as eepitch.el is still a bit prototype-ish we set two
+;; keybindings and a glyph GLOBALLY - search for "set-glyph" and
+;; "global-set-key" below.
+;;
+;;
+;; If you are interested in eev
+;; ============================
+;; The current recommended way to install eev is through the Debian
+;; package - see:
+;; <http://angg.twu.net/debian/README.html>
+;; But this version can be used independently of the rest of eev.
+;;
+;;
+;; My TODO list for eepitch (short and medium term)
+;; ================================================
+;; The current priorities for eepitch are:
+;; 1) Debian packages. There's a quick-and-dirty package, called
+;; "eev-puro", that depends on the Debian package for eev and
+;; that installs some extra demo scripts; a bunch of students
+;; from my university are using that to learn Lua (and *NIX). Its
+;; docs are mostly in Portuguese, and they can be found at:
+;; <http://angg.twu.net/eev-puro/>
+;; <http://angg.twu.net/eev-puro/debian/README.Debian.html>
+;; The package itself is here:
+;; <http://angg.twu.net/debian/>
+;; The important thing is that new versions of that .deb are
+;; built and uploaded to angg.twu.net by templates similar to the
+;; ones in:
+;; <http://angg.twu.net/eev-current/eev-template.el.html>
+;; These templates need to cleaned up and adapted to generate the
+;; Debian packages for eev too (and for dednat5, and for
+;; blogme4).
+;; 2) The support for GUD, SLIME and multi-window settings in
+;; general is quite primitive at the moment. Note also that here
+;; I do not use any of the "inferior <prog> mode" modes of Emacs.
+;; That's just because I never learn hot to use them. 8-(
+;; 3) The docs in plain text format for eepitch, that are at
+;; <http://angg.twu.net/eev-current/eepitch.readme.html>
+;; are ok for the basic ideas but horribly incomplete on
+;; everything more advanced.
+;; 4) I haven't touched this in years:
+;; <http://angg.twu.net/eev-article.html>
+;; It has several good parts, I would like to salvage it.
+;; 5) All these docs should be converted to texinfo, possibly
+;; using blogme4, as in (but this is just a prototype):
+;; <http://angg.twu.net/blogme4/doc/>
+;; 6) Understand packages with similar goals and write comparisons:
+;; eepitch with org-babel and org-babel-screen, and eev-puro with
+;; emacs-starter-kit.
+;; 7) Produce short videos about eepitch, like:
+;; <http://angg.twu.net/eev-current/anim/channels.anim.html>
+;; note that Org has lots of videos, e.g.:
+;; <http://www.youtube.com/watch?v=oJTwQvgfgMM> Carsten Dominik
+;; <http://www.youtube.com/watch?v=ht4JtEbFtFI> \ Kurt Schwehr on
+;; <http://vislab-ccom.unh.edu/~schwehr/rt/> / org-babel
+;;
+;;
+;; The innards
+;; ===========
+;; In order to understand precisely how eepitch works (consider this a
+;; preliminary hacker's guide!), let's make some definitions and
+;; follow a low-level example. I will suppose that you have read
+;; enough of
+;; <http://angg.twu.net/eev-current/eepitch.readme.html>
+;; to understand how to use eepitch in the most basic cases.
+;;
+;; Some sexps, like `(shell)', always switch to a buffer with a
+;; certain name when executed, and they create a buffer with that name
+;; when it does not exist. We call that name the "target buffer name"
+;; of the sexp, and, by convention, the cases in which the sexp raises
+;; an error do not count. So, for example,
+;;
+;; sexp target buffer name
+;; ---------- ------------------
+;; (shell) "*shell*"
+;; (shell "foo") "foo"
+;; (info "(emacs)") "*info*"
+;; (+ 1 2) none/undefined
+;; (error) none/undefined
+;;
+;; A "shell-like sexp" is one that has a target buffer name. So
+;; `(shell)' and `(info "(emacs)")' are shell-like sexps, but `(+ 1
+;; 2)' is not.
+;;
+;; Now consider the two Emacs frames below: we start with
+;; ___
+;; ______________emacs_________|-|X|
+;; | | \
+;; | (eepitch '(shell))_ | | We will call this the
+;; | cd /tmp/ | | "e-script window".
+;; | ls | | The point is at the "_".
+;; | | | We will type F8 three times.
+;; | | |
+;; | | |
+;; | | |
+;; | | /
+;; |--:** NOTES (Fundamental) ------| <-- Its modeline.
+;; |_________________________________| <-- The minibuffer.
+;;
+;; then we type F8 three times, and we get:
+;; ___
+;; ______________emacs_________|-|X|
+;; | | \
+;; | (eepitch '(shell)) | | Let's call this the
+;; | cd /tmp/ | | "e-script window".
+;; | ls | | The point is at the "_".
+;; | _ | | We just typed F8 three times.
+;; | | /
+;; |--:** NOTES (Fundamental) ------| <-- Its modeline.
+;; | | \
+;; | /home/edrx# cd /tmp/ | | Let's call this the
+;; | /tmp# ls | | "target window".
+;; | ./ ../ foo.txt | |
+;; | /tmp# | |
+;; | | /
+;; |--:** *shell* (Shell:run) ------| <-- Its modeline.
+;; |_________________________________| <-- The minibuffer.
+;;
+;; When we typed F8 on the line " (eepitch '(shell))" the system
+;; became "prepared". More precisely:
+;; a) `eepitch-code' was set to `(shell)',
+;; b) `eepitch-buffer-name' was set to the string "*shell*",
+;; c) the buffer "*shell*" was displayed in another window.
+;; The actions (b) and (c) were performed by the function
+;; `eepitch-prepare'.
+;;
+;; When we typed F8 on the line "cd /tmp/" the string "cd /tmp/" was
+;; "pitched" to the target window, by `(eepitch-line "cd /tmp/")'.
+;; Same for the "ls" in the next line. But before pitching each line
+;; `eepitch-prepare' was run to make sure that a target window exists.
+;;
+;; We need more definitions. We say that the system is "(at least)
+;; half-prepared" when:
+;; 1) `eepitch-buffer-name' holds the target buffer name of the sexp
+;; in `eepitch-code',
+;; 2) a buffer with name `eepitch-buffer-name' exists,
+;; and we say that the system is "prepared" when (1) and (2) hold,
+;; and, besides that,
+;; 3) the current buffer's name is not `eepitch-buffer-name', and
+;; 4) there is a window - that we will call the "target window" -
+;; showing the buffer `eepitch-buffer-name'.
+;;
+;; In the code below,
+;; `eepitch-buffer-create' takes care of conditions 1 and 2.
+;; `eepitch-assert-not-target', of condition 3.
+;; `eepitch-window-show', of condition 4 (supposing 1, 2, 3 hold).
+;; `eepitch-prepare', of all the conditions 1-4.
+
+
+(defun ee-bol () (point-at-bol))
+(defun ee-eol () (point-at-eol))
+
+(defun ee-read (str) (read (concat "(progn\n" str "\n)")))
+(defun ee-eval (sexp) (let ((debug-on-error nil)) (eval sexp)))
+
+(defun ee-eval-string (str)
+ "Wrap STR in a progn then read it and eval it.
+Examples: (ee-eval-string \"(+ 1 2) (* 3 4) ;; this returns 12=3*4\")
+ (ee-eval-string \";; this returns nil\")"
+ (ee-eval (ee-read str)))
+
+(defun ee-eval-string-print (str)
+ "Wrap STR in a progn then read it, eval it, and print it."
+ (prin1 (ee-eval-string str)))
+
+(defun ee-next-line (&optional arg try-vscroll)
+ (interactive "p")
+"Line `next-line', but ignoring visual line mode.
+This function is used by `eepitch-this-line'."
+ (let ((line-move-visual nil))
+ (next-line arg try-vscroll)))
+
+
+
+
+;;;
+;;; ___ ___ _ __ ___
+;;; / __/ _ \| '__/ _ \
+;;; | (_| (_) | | | __/
+;;; \___\___/|_| \___|
+;;;
+
+(defvar eepitch-regexp "^\\(.*\\)"
+"The regexp used by `eepitch-this-line' to determine what is a red-star line.
+Red star lines are evaluated as lisp, normal lines are pitched to
+the target buffer.")
+
+(defvar eepitch-comment-regexp "^\\(.*\\)"
+"The regexp used by `eepitch-this-line' to test if a line is a comment.
+Comment lines are neither evaluated nor sent to the target buffer.
+The test that ignores comment lines is applied before the test that decides
+between red-star lines (that are eval'ed) and normal lines (that are sent).")
+
+(defvar eepitch-buffer-name ""
+ "The name of the target buffer for eepitch.
+Set this to \"\" to force running `eepitch-buffer-create' again.
+Note that `eepitch-buffer-create' sets this variable!")
+
+(defvar eepitch-code '(error "eepitch not set up")
+ "The code to create and switch to the target buffer.")
+
+(defvar eepitch-window-show '(eepitch-window-show)) ; cheap indirection
+(defvar eepitch-kill '(eepitch-kill-buffer)) ; cheap indirection
+(defvar eepitch-kill-windows 'nil) ; cheap indirection
+(defun eepitch-buffer-exists () (get-buffer eepitch-buffer-name))
+(defun eepitch-window-exists () (get-buffer-window eepitch-buffer-name))
+(defun eepitch-target-buffer () (get-buffer eepitch-buffer-name))
+(defun eepitch-target-window () (get-buffer-window eepitch-buffer-name))
+(defun eepitch-target-here () (eq (current-buffer) (eepitch-target-buffer)))
+
+(defun eepitch-buffer-create ()
+ "Eval the sexp in `eepitch-code' and set `eepitch-buffer-name'.
+This is done without disturbing the current window configuration.\n
+Remember that we say that \"the system is (at least) half-prepared\" when:
+ 1) `eepitch-buffer-name' holds the target buffer name of the sexp
+ in `eepitch-code',
+ 2) a buffer with name `eepitch-buffer-name' exists.\n
+This function makes sure that the system is at least half-prepared.
+See `eepitch' and `eepitch-prepare'."
+ (save-window-excursion
+ (eval eepitch-code)
+ (setq eepitch-buffer-name
+ (buffer-name (current-buffer)))))
+
+(defun eepitch-window-show ()
+ "Display the buffer `eepitch-buffer-name' in another window.
+This is just the default way of making sure that the \"target
+window\" is visible; note that `eepitch' sets the variable
+`eepitch-window-show' to `(eepitch-window-show)', and that
+`eepitch-prepare' evaluates the sexp in the variable
+`eepitch-window-show'. Alternative eepitch settings - like the
+ones for GUD or Slime, that use multiple windows - put calls to
+other functions instead of this one in the variable
+`eepitch-window-show'.\n
+This function uses `display-buffer', which calls
+`split-window-sensibly'."
+ (let ((pop-up-windows t)
+ (same-window-buffer-names nil))
+ (display-buffer eepitch-buffer-name)))
+
+(defun eepitch-prepare ()
+"If the eepitch buffer does not exist, create it; if it is not shown, show it.
+In eepitch's terminology we say that the system is \"prepared\" when:
+ 1) the variable `eepitch-buffer-name' holds the target buffer
+ name of the sexp in `eepitch-code',
+ 2) a buffer with name `eepitch-buffer-name' exists,
+ 3) the current buffer's name is not `eepitch-buffer-name', and
+ 4) there is a window - that we will call the \"target window\" -
+ showing the buffer `eepitch-buffer-name'.
+This function makes sure that the system is prepared. Note that
+this function is called from both `eepitch' and
+`eepitch-this-line'."
+ (if (not (eepitch-buffer-exists))
+ (eepitch-buffer-create))
+ (if (eq (current-buffer) (eepitch-target-buffer))
+ (error "Can't pitch to the current buffer"))
+ (if (not (eepitch-window-exists))
+ (eval eepitch-window-show)))
+
+(defun eepitch (code)
+"Set up a target for eepitch and make sure it is displayed in another window.
+The argument CODE must be a \"shell-like sexp\", i.e., one that
+when evaluated always switches to a buffer with a fixed name, and
+when that buffer does not exists it creates it.\n
+This function sets `eepitch-code' to CODE and sets the variables
+`eepitch-window-show' and `eepitch-kill' to defaults that are
+good for two-window settings, and then calls `eepitch-prepare',
+which does all the hard work."
+ (setq eepitch-code code)
+ (setq eepitch-buffer-name "") ; so that `eepitch-buffer-exists' will
fail
+ (setq eepitch-window-show ; set the way to set up windows to the
+ '(eepitch-window-show)) ; default two-window setting
+ (setq eepitch-kill ; set the behavior of `eepitch-kill'
+ '(eepitch-kill-buffer)) ; to just kill the target buffer
+ (eepitch-prepare)
+ (list 'Target: eepitch-buffer-name)) ; feedback (for <f8> and `M-e')
+
+(defun eepitch-eval-at-target-window (code)
+ "Run CODE at the eepitch-target-window."
+ (eepitch-prepare)
+ (save-selected-window
+ (select-window (eepitch-target-window))
+ (eval code)))
+
+(defun eepitch-line (line)
+ "Send LINE to the target window and run the key binding for RET there.
+This is a low-level function used by `eepitch-this-line'."
+ (eepitch-eval-at-target-window
+ '(progn (goto-char (point-max)) ; at the end of buffer
+ (insert line) ; "type" the line
+ (call-interactively (key-binding "\r"))))) ; then do a RET
+
+(defun eepitch-this-line ()
+"Pitch this line to the target buffer, or eval it as lisp if it starts with
`'.
+Also, if it starts with `', skip it.
+See: (find-eepitch-intro)
+and: `eepitch', `eepitch-regexp', `eepitch-comment-regexp'."
+ (interactive)
+ (let ((line (buffer-substring (ee-bol) (ee-eol)))) ; get line contents
+ (cond ((string-match eepitch-comment-regexp line) ; comment lines
+ (message "Comment: %s" line)) ; are message'd,
+ ((string-match eepitch-regexp line) ; red star lines
+ (ee-eval-string-print ; are eval'ed and the
+ (match-string 1 line))) ; result is printed,
+ (t (eepitch-prepare) ; normal lines
+ (eepitch-line line)))) ; are sent
+ (ee-next-line 1))
+
+
+
+
+;;; _ _ _ _ _ _ _
+;;; ___ ___ _ __ (_) |_ ___| |__ | | _(_) | |
+;;; / _ \/ _ \ '_ \| | __/ __| '_ \ _____| |/ / | | |
+;;; | __/ __/ |_) | | || (__| | | |_____| <| | | |
+;;; \___|\___| .__/|_|\__\___|_| |_| |_|\_\_|_|_|
+;;; |_|
+
+(defun ee-kill-buffer (buffer)
+ "Kill BUFFER if it exists, asking for fewer confirmations than usual."
+ (if (get-buffer buffer)
+ (let ((kill-buffer-query-functions nil))
+ (kill-buffer buffer))))
+
+(defun eepitch-kill-buffer ()
+ "Kill the eepitch target buffer if it exists, avoiding most warnings.
+This function does not change the current window configuration,
+and is the default behavior for `eepitch-kill' in two-window
+settings. See `eepitch' and `eepitch-kill'."
+ (if (eepitch-buffer-exists)
+ (if (eepitch-target-here)
+ (error "Can't kill this")
+ (ee-kill-buffer eepitch-buffer-name) ; kill with few warnings
+ )))
+
+(defun eepitch-kill ()
+ "Kill the current eepitch target buffer in the default way.
+The default is always the one stored in the variable
+`eepitch-kill', and is usually `eepitch-kill-buffer'.
+
+A common idiom - called an \"eepitch block\"; see `eewrap-eepitch'
+for a quick way to create eepitch blocks - is to use three
+red-star lines in sequence to \"recreate the target\", like this:
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+
+When we run the first `(eepitch-shell)' the eepitch target buffer
+becomes the buffer \"*shell*\"; then we run the `(eepitch-kill)'
+and we are sure that it will kill the buffer \"*shell*\", not
+something else; then we run the last `(eepitch-shell)', and as
+the eepitch target buffer does not exist it is recreated from
+scratch."
+ (eval eepitch-kill))
+
+
+
+
+;;; _ _ _ _ _ _
+;;; ___ ___ _ __ (_) |_ ___| |__ ___| |__ ___| | |
+;;; / _ \/ _ \ '_ \| | __/ __| '_ \ _____/ __| '_ \ / _ \ | |
+;;; | __/ __/ |_) | | || (__| | | |_____\__ \ | | | __/ | |
+;;; \___|\___| .__/|_|\__\___|_| |_| |___/_| |_|\___|_|_|
+;;; |_|
+
+(defun eepitch-shell ()
+ "Same as (eepitch '(shell)). See `eepitch' and `eewrap-eepitch'."
+ (interactive)
+ (eepitch '(shell)))
+
+(defun eepitch-shell2 () (interactive) (eepitch '(shell "*shell 2*")))
+(defun eepitch-eshell () (interactive) (eepitch '(eshell)))
+
+
+
+;;; _ _
+;;; ___ ___ _ __ ___ (_)_ __ | |_
+;;; / __/ _ \| '_ ` _ \| | '_ \| __|
+;;; | (_| (_) | | | | | | | | | | |_
+;;; \___\___/|_| |_| |_|_|_| |_|\__|
+;;;
+
+(defun ee-expand (fname)
+"Expand \"~\"s and \"$ENVVAR\"s in file names, but only at the beginning."
+ (cond ((string-match "^\\$\\([A-Za-z_][0-9A-Za-z_]*\\)\\(.*\\)" fname)
+ (concat (getenv (match-string 1 fname))
+ (match-string 2 fname)))
+ ((string-match "^\\(~\\([a-z][0-9a-z_]*\\)?\\)\\(/.*\\)?$" fname)
+ (concat (expand-file-name (match-string 1 fname))
+ (match-string 3 fname)))
+ (t fname)))
+
+(defun ee-split (str) (if (stringp str) (split-string str "[ \t\n]+") str))
+(defun ee-split-and-expand (str)
+"Convert STR to a list (if it's a string) and apply `ee-expand' to each
element.
+This function is used by `find-comintprocess', `find-bgprocess'
+and `find-callprocess'."
+ (mapcar 'ee-expand (ee-split str)))
+
+(defun find-comintprocess-ne (name program-and-args)
+ "Switch to the buffer named *NAME* and run the command PROGRAM-AND-ARGS
there.
+This function does not run `ee-expand' on the elements of PROGRAM-AND-ARGS."
+ (let ((argv (ee-split program-and-args)))
+ (apply 'make-comint name (car argv) nil (cdr argv))
+ (switch-to-buffer (format "*%s*" name))))
+
+(defun find-comintprocess (name program-and-args)
+ "Switch to the buffer named *NAME* and run the command PROGRAM-AND-ARGS
there.
+If PROGRAM-AND-ARGS is a string, split it at whitespace to make it a list.
+Each element of PROGRAM-AND-ARGS is expanded with `ee-expand'.
+See: (find-eepitch-intro)"
+ (find-comintprocess-ne name (ee-split-and-expand program-and-args)))
+
+(defun eepitch-comint (name program-and-args)
+"Set `eepitch' to run PROGRAM-AND-ARGS in comint mode, in the buffer
\"*NAME*\"."
+ (eepitch `(find-comintprocess ,name ',program-and-args)))
+
+
+
+
+;;; _ _
+;;; __ _| |_ _ _ __ | |__ ___
+;;; / _` | | | | | '_ \| '_ \/ __|
+;;; | (_| | | |_| | |_) | | | \__ \
+;;; \__, |_|\__, | .__/|_| |_|___/
+;;; |___/ |___/|_|
+;;;
+;; More glyphs:
+;; (find-eev "eev-anchors.el")
+;; (find-anchors-intro)
+;; More on glyphs:
+;; http://angg.twu.net/glyphs.html
+;; The `(<= 128 pos)' below is explained at:
+;; http://angg.twu.net/glyphs.html#bug-report
+
+(defface eepitch-star-face
+ '((t (:foreground "red")))
+ "Face used for the red star glyph (char 15).")
+
+(defun eepitch-set-glyph0 (pos &optional char face)
+ "See: (find-eepitch-intro \"glyph\")"
+ (aset standard-display-table pos
+ (if char (vector (make-glyph-code char face)))))
+
+(defun eepitch-set-glyph (pos &optional char face)
+ "See: (find-eepitch-intro \"glyph\")
+and: (find-anchors-intro \"glyphs\")
+This is the high-level version of `eepitch-set-glyph0', with a hack
+to make it work similarly in unibyte and multibyte buffers."
+ (eepitch-set-glyph0 pos char face)
+ (if (<= 128 pos)
+ (eepitch-set-glyph0 (make-char 'eight-bit pos) char face)))
+
+
+;;;
+;;; __ ___ __ __ _ _ __
+;;; \ \ /\ / / '__/ _` | '_ \
+;;; \ V V /| | | (_| | |_) |
+;;; \_/\_/ |_| \__,_| .__/
+;;; |_|
+;;
+;; See: (find-wrap-intro)
+
+(defun ee-no-properties (str)
+ (setq str (copy-sequence str))
+ (set-text-properties 0 (length str) nil str)
+ str)
+
+;; (defun eepitch-delete-and-extract-line ()
+;; (delete-and-extract-region (ee-bol) (ee-eol)))
+
+(defun ee-this-line-extract ()
+ "Delete the contents of the current line and return it as a string."
+ (delete-and-extract-region (ee-bol) (ee-eol)))
+
+(defun eewrap-eepitch () (interactive)
+ (let* ((fmt " (eepitch-%s)\n (eepitch-kill)\n (eepitch-%s)")
+ (li (ee-this-line-extract))
+ (newli (format fmt li li)))
+ (insert newli))
+ (ee-next-line 1))
+
+
+
+;;; _ _ _
+;;; ___ ___| |_ __ _| |_ _ _ __ | |__ ___
+;;; / __|/ _ \ __| / _` | | | | | '_ \| '_ \/ __|
+;;; \__ \ __/ |_ | (_| | | |_| | |_) | | | \__ \
+;;; |___/\___|\__| \__, |_|\__, | .__/|_| |_|___/
+;;; |___/ |___/|_|
+
+(if (not standard-display-table)
+ (setq standard-display-table (make-display-table)))
+(eepitch-set-glyph ?\^O ?* 'eepitch-star-face)
+
+
+;;; _ _
+;;; ___ ___| |_ | | _____ _ _ ___
+;;; / __|/ _ \ __| | |/ / _ \ | | / __|
+;;; \__ \ __/ |_ | < __/ |_| \__ \
+;;; |___/\___|\__| |_|\_\___|\__, |___/
+;;; |___/
+
+;; (global-set-key [f8] 'eepitch-this-line)
+;; (global-set-key "\M-T" 'eewrap-eepitch)
+
+(provide 'eepitch)
+
+
+;;; _____ _ __ _ _
+;;; | ____|_ __ __| | ___ / _| | |_| |__ ___ ___ ___ _ __ ___
+;;; | _| | '_ \ / _` | / _ \| |_ | __| '_ \ / _ \ / __/ _ \| '__/ _ \
+;;; | |___| | | | (_| | | (_) | _| | |_| | | | __/ | (_| (_) | | | __/
+;;; |_____|_| |_|\__,_| \___/|_| \__|_| |_|\___| \___\___/|_| \___|
+;;;
+;;; ----------------------------------------------------------------------
+;;; ----------------------------------------------------------------------
+;;; ----------------------------------------------------------------------
+
+
+
+
+;;; _ _ _
+;;; ___ ___ _ __ ___ (_)_ __ | |_ ___ ___| |__ ___
+;;; / __/ _ \| '_ ` _ \| | '_ \| __|____ / _ \/ __| '_ \ / _ \
+;;; | (_| (_) | | | | | | | | | | ||_____| __/ (__| | | | (_) |
+;;; \___\___/|_| |_| |_|_|_| |_|\__| \___|\___|_| |_|\___/
+;;;
+;; What is this: I am trying to find an elegant way to deal with
+;; programs that echo their input (like zsh)... This is still a bit
+;; experimental!
+;; See: (find-variable 'comint-process-echoes)
+;; To do: send an e-mail to Olin Shivers about echoing and stty.
+
+(defun at-eepitch-target (code)
+ (eepitch-prepare)
+ (save-selected-window
+ (select-window (eepitch-target-window))
+ (eval code)))
+
+(defun del-echo (flag)
+"A hack to help determining whether a program echoes its commands or not.
+An example of use:\n
+ (eepitch-zsh)
+ (eepitch-kill)
+ (eepitch-zsh)
+cd /tmp/
+ (del-echo t)
+cd /tmp/
+ (del-echo nil)
+cd /tmp/\n"
+ (at-eepitch-target `(setq comint-process-echoes ,flag))
+ (message "At %s: %S" eepitch-buffer-name
+ `(setq comint-process-echoes ,flag)))
+
+(defun eepitch-de (code)
+ "Like `eepitch', but deletes the echoed commands.
+Use this to control programs that echo the commands that they receive."
+ (eepitch `(progn ,code (setq comint-process-echoes t))))
+
+(defun eepitch-comint-de (name program-and-args)
+ "Like `eepitch-comint', but deletes the echoed commands.
+Use this to control programs that echo the commands that they receive."
+ (eepitch-de `(find-comintprocess ,name ',program-and-args)))
+
+
+
+;;; ___ _ _ _ _
+;;; / _ \| |_| |__ ___ _ __ | |_ ___ ___ | |___
+;;; | | | | __| '_ \ / _ \ '__| | __/ _ \ / _ \| / __|
+;;; | |_| | |_| | | | __/ | | || (_) | (_) | \__ \
+;;; \___/ \__|_| |_|\___|_| \__\___/ \___/|_|___/
+;;;
+;; Useful for controlling certain external programs.
+
+(defun ee-at0 (dir code)
+ "Eval CODE at DIR.
+If DIR does not end with a slash then weird things might happen.
+Note the DIR is `ee-expand'-ed."
+ (let ((default-directory (ee-expand dir)))
+ (if (not (file-accessible-directory-p dir))
+ (error "Can't chdir to %s" dir))
+ (eval code)))
+
+(defun eepitch-comint-at (dir name program-and-args)
+ "Like `eepitch-comint', but executes `eepitch-buffer-create' at DIR."
+ (ee-at0 dir `(eepitch-comint ,name ,program-and-args)))
+
+(defun with-pager-cat (code)
+ "Run CODE with the environment variable PAGER set to \"cat\".
+This is useful for for running processes that use pagers like
+\"more\" by default."
+ (let ((process-environment (cons "PAGER=cat" process-environment)))
+ (eval code)))
+
+(defun eepitch-to-buffer (name)
+ (interactive "beepitch to buffer: ")
+ (eepitch `(switch-to-buffer ,name)))
+
+(defun at-nth-window (n code)
+ "Run `other-window' N times, run CODE there, and go back."
+ (save-selected-window
+ (other-window n)
+ (eval code)))
+
+
+
+;;; _
+;;; | | __ _ _ __ __ _ _ _ __ _ __ _ ___ ___
+;;; | | / _` | '_ \ / _` | | | |/ _` |/ _` |/ _ \/ __|
+;;; | |__| (_| | | | | (_| | |_| | (_| | (_| | __/\__ \
+;;; |_____\__,_|_| |_|\__, |\__,_|\__,_|\__, |\___||___/
+;;; |___/ |___/
+
+;; Shells
+(defun eepitch-shell () (interactive) (eepitch '(shell)))
+(defun eepitch-shell2 () (interactive) (eepitch '(shell "*shell 2*")))
+(defun eepitch-eshell () (interactive) (eepitch '(eshell)))
+(defun eepitch-bash () (interactive) (eepitch-comint "bash" "bash"))
+(defun eepitch-dash () (interactive) (eepitch-comint "dash" "dash"))
+(defun eepitch-ksh () (interactive) (eepitch-comint "ksh" "ksh"))
+(defun eepitch-tcsh () (interactive) (eepitch-comint "tcsh" "tcsh"))
+(defun eepitch-zsh () (interactive) (eepitch-comint-de "zsh" "zsh"))
+(defun eepitch-scsh () (interactive) (eepitch-comint "scsh" "scsh"))
+
+;; Main interpreted languages
+(defun eepitch-lua51 () (interactive) (eepitch-comint "lua51" "lua5.1"))
+(defun eepitch-python () (interactive) (eepitch-comint "python" "python"))
+(defun eepitch-ruby () (interactive) (eepitch-comint "ruby" "irb1.8"))
+(defun eepitch-perl () (interactive) (eepitch-comint "perl" "perl -d -e 42"))
+
+;; Tcl
+(defun eepitch-tcl () (interactive) (eepitch-comint "tclsh" "tclsh"))
+(defun eepitch-tclsh () (interactive) (eepitch-comint "tclsh" "tclsh"))
+(defun eepitch-wish () (interactive) (eepitch-comint "wish" "wish"))
+(defun eepitch-expect () (interactive) (eepitch-comint "expect" "expect"))
+
+;; Lisps and Schemes
+;; It would be better to run them in Slime.
+(defun eepitch-sbcl () (interactive) (eepitch-comint "sbcl" "sbcl"))
+(defun eepitch-gcl () (interactive) (eepitch-comint "gcl" "gcl"))
+(defun eepitch-guile () (interactive) (eepitch-comint "guile" "guile"))
+(defun eepitch-racket () (interactive) (eepitch-comint "racket" "racket"))
+(defun eepitch-mitscheme () (interactive)
+ (eepitch-comint "mit-scheme" "mit-scheme"))
+(defun eepitch-tinyscheme () (interactive)
+ (eepitch-comint "tinyscheme" "tinyscheme"))
+
+
+;; Haskell, ML, Erlang, Coq
+(defun eepitch-hugs () (interactive) (eepitch-comint "hugs" "hugs"))
+(defun eepitch-hugs98 () (interactive) (eepitch-comint "hugs" "hugs -98"))
+(defun eepitch-ghci () (interactive) (eepitch-comint "ghci" "ghci"))
+(defun eepitch-ocaml () (interactive) (eepitch-comint "ocaml" "ocaml"))
+(defun eepitch-labltk () (interactive) (eepitch-comint "labltk" "labltk"))
+(defun eepitch-polyml () (interactive) (eepitch-comint "polyml" "poly"))
+(defun eepitch-erl () (interactive) (eepitch-comint "erl" "erl"))
+(defun eepitch-coqtop () (interactive) (eepitch-comint "coqtop" "coqtop"))
+
+;; Forth
+(defun eepitch-gforth () (interactive) (eepitch '(run-forth "gforth")))
+(defun eepitch-gforth () (interactive) (eepitch-comint "gforth" "gforth"))
+(defun eepitch-pforth () (interactive) (eepitch-comint "pforth" "pforth"))
+(defun eepitch-yforth () (interactive) (eepitch-comint "yforth" "yforth"))
+
+;; Mathematics
+(defun eepitch-maxima () (interactive) (eepitch-comint "maxima" "maxima"))
+(defun eepitch-octave () (interactive) (eepitch-comint "octave" "octave"))
+(defun eepitch-R () (interactive)
+ (eepitch '(with-pager-cat (find-comintprocess "R" "R"))))
+
+;; Plotters.
+;; We force GhostScript's resolution to make its window fit on the screen.
+(defun eepitch-gs () (interactive) (eepitch-comint "gs" "gs -r45"))
+(defun eepitch-gs () (interactive) (eepitch-comint "gs" "gs -r60"))
+(defun eepitch-gnuplot () (interactive) (eepitch-comint "gnuplot" "gnuplot"))
+
+;; Java-based languages
+(defun eepitch-bsh () (interactive)
+ (eepitch-de '(find-comintprocess "bsh" "bsh")))
+(defun eepitch-scala () (interactive)
+ (eepitch '(find-comintprocess "scala" "scala")))
+(defun eepitch-clojure () (interactive)
+ (eepitch '(find-comintprocess "clojure" "clojure -r")))
+
+;; SQL. To do: add postgres and sqlite
+(defun eepitch-mysql () (interactive)
+ (eepitch '(with-pager-cat '(find-comintprocess "mysql" "mysql -u root"))))
+
+;; SmallTalk
+(defun eepitch-gst () (interactive)
+ (eepitch '(find-comintprocess "gst" "gst")))
+
+;; JavaScript
+;; MozRepl is a Javascript REPL in a running Mozilla browser.
+;; See: https://github.com/bard/mozrepl/wiki/tutorial
+(defun eepitch-smjs () (interactive) (eepitch-comint "smjs" "smjs"))
+(defun eepitch-mozrepl () (interactive)
+ (eepitch-comint "mozrepl" "telnet localhost 4242"))
+
+;; Programs from the TeX family.
+;; They create logfiles in the current dir, so we run them in /tmp/.
+(defun eepitch-luatex () (interactive)
+ (eepitch-comint-at "/tmp/" "luatex" "luatex"))
+(defun eepitch-lualatex () (interactive)
+ (eepitch-comint-at "/tmp/" "lualatex" "lualatex"))
+(defun eepitch-latex () (interactive)
+ (eepitch-comint-at "/tmp/" "latex" "latex"))
+(defun eepitch-tex () (interactive)
+ (eepitch-comint-at "/tmp/" "tex" "tex"))
+(defun eepitch-mf () (interactive)
+ (eepitch-comint-at "/tmp/" "mf" "mf"))
+(defun eepitch-mpost () (interactive)
+ (eepitch-comint-at "/tmp/" "mpost" "mpost"))
+
+;; Pulseaudio (this is to interact with its daemon)
+(defun eepitch-pacmd () (interactive) (eepitch-comint "pacmd" "pacmd"))
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-anchors.el b/eev-anchors.el
new file mode 100644
index 0000000..d39c1f4
--- /dev/null
+++ b/eev-anchors.el
@@ -0,0 +1,167 @@
+;;; eev-anchors.el -- hyperlinks to anchors.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012nov02
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-anchors.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-anchors.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-anchors-intro.html>
+;; (find-eev-intro)
+;; (find-anchors-intro)
+
+;;; Commentary:
+
+
+
+
+(require 'eepitch) ; (find-eev "eepitch.el")
+
+
+
+
+;;; _ _
+;;; __ _| |_ _ _ __ | |__ ___
+;;; / _` | | | | | '_ \| '_ \/ __|
+;;; | (_| | | |_| | |_) | | | \__ \
+;;; \__, |_|\__, | .__/|_| |_|___/
+;;; |___/ |___/|_|
+
+(defface eev-glyph-face-green
+ '((((class color) (background dark))
+ (:foreground "green"))
+ (((class color) (background light))
+ (:foreground "forest green"))
+ (t (:bold t)))
+ "Face used for the green glyphs (`<<' and `>>', chars 171 and 187).")
+
+;; (eepitch-set-glyph ?� ?� 'eev-glyph-face-green)
+;; (eepitch-set-glyph ?� ?� 'eev-glyph-face-green)
+
+(eepitch-set-glyph 171 171 'eev-glyph-face-green)
+(eepitch-set-glyph 187 187 'eev-glyph-face-green)
+
+
+
+
+
+;;; _ __ _
+;;; __ _ _ __ ___| |__ ___ _ __ / _| ___ _ __ _ __ ___ __ _| |_
+;;; / _` | '_ \ / __| '_ \ / _ \| '__|____| |_ / _ \| '__| '_ ` _ \ / _` | __|
+;;; | (_| | | | | (__| | | | (_) | | |_____| _| (_) | | | | | | | | (_| | |_
+;;; \__,_|_| |_|\___|_| |_|\___/|_| |_| \___/|_| |_| |_| |_|\__,_|\__|
+;;;
+
+(defvar ee-anchor-format "�%s�" "See `ee-goto-anchor'.")
+(put 'ee-anchor-format 'safe-local-variable 'stringp)
+
+;; A paranoid setting would be:
+;; (defvar ee-anchor-format nil "See `ee-goto-anchor'.")
+
+(defun ee-format-as-anchor (tag)
+ "Convert TAG into an anchor using `ee-anchor-format'."
+ (if ee-anchor-format
+ (format ee-anchor-format tag)
+ (error "`ee-anchor-format' is nil - can't convert string to anchor")))
+
+
+
+
+;;; __ _ _ _
+;;; / _(_)_ __ __| | __ _ _ __ ___| |__ ___ _ __
+;;; | |_| | '_ \ / _` |_____ / _` | '_ \ / __| '_ \ / _ \| '__|
+;;; | _| | | | | (_| |_____| (_| | | | | (__| | | | (_) | |
+;;; |_| |_|_| |_|\__,_| \__,_|_| |_|\___|_| |_|\___/|_|
+;;;
+;; See: (find-eval-intro "Anchors and pages")
+
+(defun ee-goto-anchor (&optional tag &rest rest)
+ "Like `ee-goto-position', but TAG is converted to an anchor.
+If the anchor obtained from TAG is not found then issue an error
+but do not move point.
+For example, if `ee-anchor-format' is \"<<%s>>\" then
+
+ (ee-goto-anchor \"foo\" \"bar\")
+
+searches for the first occurrence of \"<<foo>>\" in the current
+buffer, then for the first occurrence of \"bar\" after that. If
+\"<<foo>>\" is not found then do not move point.
+
+It is good style to set `ee-goto-anchor' globally to nil and only
+use anchors in files where `ee-anchor-format' is declared in the
+local variables section of the file; see:
+
+ (find-node \"(emacs)File Variables\")
+ (find-node \"(emacs)Specifying File Variables\")
+
+a hint: one way of forcing reloading the local variables by hand
+is by running `\\[normal-mode]'.
+
+The glyphs defined in (find-eev \"eev-glyphs.el\") can be used to
+make anchors using characters that stand out."
+ (if tag (goto-char
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward (ee-format-as-anchor tag))
+ (point))))
+ (ee-goto-rest rest))
+
+(defun find-anchor (fname &optional tag &rest pos-spec-list)
+ "Like `find-fline', but TAG is converted to an anchor if not nil.
+See `ee-goto-anchor'."
+ (find-fline fname)
+ (apply 'ee-goto-anchor tag pos-spec-list))
+
+
+
+;;; _
+;;; | |_ ___
+;;; | __/ _ \
+;;; | || (_) |
+;;; \__\___/
+;;;
+;; Warning: this function does not start with any of the
+;; reserved prefixes!!! =(
+;;
+(defun to (tag &rest pos-spec-list)
+ "Like `find-anchor', but does not switch to another buffer or file."
+ (interactive "sAnchor: ")
+ (apply 'ee-goto-anchor tag pos-spec-list))
+
+
+
+
+(provide 'eev-anchors)
+
+
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-audiovideo.el b/eev-audiovideo.el
new file mode 100644
index 0000000..8c1ba70
--- /dev/null
+++ b/eev-audiovideo.el
@@ -0,0 +1,337 @@
+;;; eev-audiovideo.el -- elisp hyperlinks to audio and video files.
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug17
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-audiovideo.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-audiovideo.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-audiovideo-intro.html>
+;; (find-audiovideo-intro)
+
+;;; Commentary:
+
+
+
+(require 'eev-code)
+(require 'eev-brxxx)
+
+
+
+;; (find-efunction 'ee-stuff-around-point)
+;; (find-elnode "Regexp Search")
+;; (find-elnode "Regexp Backslash" "shy group")
+;;
+(defun ee-time-around-point ()
+ (let ((time (ee-no-properties (ee-stuff-around-point "0-9:"))))
+ (if (not (equal time ""))
+ time)))
+
+
+;;; _ _ __ _ _
+;;; | |_(_)_ __ ___ ___ / _|_ __ ___ _ __ ___ | |__ ___ | |
+;;; | __| | '_ ` _ \ / _ \_____| |_| '__/ _ \| '_ ` _ \ _____| '_ \ / _ \| |
+;;; | |_| | | | | | | __/_____| _| | | (_) | | | | | |_____| |_) | (_) | |
+;;; \__|_|_| |_| |_|\___| |_| |_| \___/|_| |_| |_| |_.__/ \___/|_|
+;;;
+(defvar ee-time-regexp
+ "\\(?:\\([0-9]?[0-9]\\):\\)?\\([0-9]?[0-9]\\):\\([0-9][0-9]\\)")
+
+(defun ee-re-search-from (pos regexp &optional limit repeat)
+ (save-excursion
+ (if pos (goto-char pos))
+ (if (re-search-forward regexp limit t repeat)
+ (match-string-no-properties 0))))
+
+(defun ee-time-from-bol ()
+ "Try this: 98:76:54 3:21 (ee-time-from-bol)"
+ (ee-re-search-from (ee-bol) ee-time-regexp (ee-eol)))
+
+(defun ee-time-from-bol-flash () (interactive)
+ "Try this: 98:76:54 3:21 (ee-time-from-bol-flash)"
+ (if (ee-time-from-bol)
+ (eeflash+ (match-beginning 0) (match-end 0) ee-highlight-spec))
+ (ee-time-from-bol))
+
+
+
+
+
+;;; _ _ _ _ __ _
+;;; | |_(_)_ __ ___ ___ ___| |__ (_)/ _| |_
+;;; | __| | '_ ` _ \ / _ \_____/ __| '_ \| | |_| __|
+;;; | |_| | | | | | | __/_____\__ \ | | | | _| |_
+;;; \__|_|_| |_| |_|\___| |___/_| |_|_|_| \__|
+;;;
+(defun ee-time-to-seconds (time)
+ (save-match-data
+ (if (string-match ee-time-regexp time)
+ (+ (* 3600 (string-to-number (or (match-string 1 time) "0")))
+ (* 60 (string-to-number (match-string 2 time)))
+ (string-to-number (match-string 3 time))))))
+
+(defun ee-seconds-to-time (seconds)
+ (if (> 3600 seconds)
+ (format-seconds "%m:%02s" seconds)
+ (format-seconds "%h:%02m:%02s" seconds)))
+
+(defun ee-time+ (seconds time)
+ (save-match-data
+ (ee-seconds-to-time
+ (max 0 (+ seconds (ee-time-to-seconds time))))))
+
+(defun ee-time-from-bol-shift (seconds)
+ (interactive "P")
+ (save-excursion
+ (let ((time (ee-time-from-bol)))
+ (if time
+ (replace-match (ee-time+ (or seconds 1) time) t t)
+ (error "No time (mm:ss or hh:mm:ss) in the current line")))))
+
+(defun ee-time-from-bol-shift- (seconds)
+ (interactive "P")
+ (ee-time-from-bol-shift (- (or seconds 1))))
+
+
+;;; _ _ _ _ __ _ _
+;;; | | __ _ ___| |_ __ _ _ _ __| (_) ___ / /_ _(_) __| | ___ ___
+;;; | |/ _` / __| __| / _` | | | |/ _` | |/ _ \ / /\ \ / / |/ _` |/ _ \/ _ \
+;;; | | (_| \__ \ |_ | (_| | |_| | (_| | | (_) / / \ V /| | (_| | __/ (_) |
+;;; |_|\__,_|___/\__| \__,_|\__,_|\__,_|_|\___/_/ \_/ |_|\__,_|\___|\___/
+;;;
+;;
+(defvar ee-audiovideo-last nil
+ "See: (find-audiovideo-intro \"The current audio or video\")")
+
+(defun ee-audiovideo-sexp (time)
+ (list ee-audiovideo-last time))
+
+
+;;; _ _ _
+;;; __ _ __ __ __ _ __| |(_) _ __ ___ ___ __| | ___
+;;; / _` |____\ \ / /____ / _` |/ _` || |_____| '_ ` _ \ / _ \ / _` |/ _ \
+;;; | (_| |_____\ V /_____| (_| | (_| || |_____| | | | | | (_) | (_| | __/
+;;; \__,_| \_/ \__,_|\__,_|/ | |_| |_| |_|\___/ \__,_|\___|
+;;; |__/
+;;
+(defun ee-time-from-bol-rerun (&optional arg)
+ "Play the current audio or video starting at '(ee-time-from-bol)'.
+With a prefix of 0 just display what would be done. See:
+ (find-audiovideo-intro \"time-from-bol\")
+ (find-audiovideo-intro \"ee-audiovideo-last\")"
+ (interactive "P")
+ (cond ((eq arg 0)
+ (message "-> %S" (ee-audiovideo-sexp (ee-time-from-bol-flash))))
+ (t (let ((sexp (ee-audiovideo-sexp (ee-time-from-bol))))
+ (eval sexp)
+ (message "%S" sexp)))))
+
+(setq eev-avadj-mode-map (make-sparse-keymap))
+(define-key eev-avadj-mode-map "\M--" 'ee-time-from-bol-shift-)
+(define-key eev-avadj-mode-map "\M-=" 'ee-time-from-bol-shift)
+(define-key eev-avadj-mode-map "\M-+" 'ee-time-from-bol-shift)
+(define-key eev-avadj-mode-map "\M-p" 'ee-time-from-bol-rerun)
+
+(define-minor-mode eev-avadj-mode
+ "eev audio/video adjust mode: a mode for adjusting audio/video link lines.
+See: (find-audiovideo-intro \"`eev-avadj-mode'\")"
+ :init-value nil
+ :global nil
+ :lighter " eev-avadj")
+
+;; (eev-avadj-mode 0)
+;; (eev-avadj-mode 1)
+;; 1:15 foo
+
+;; (find-eev "eev-mode.el")
+;; (find-code-video "thecompanyofwolves"
"/sda5/torrents/The_Company_of_Wolves/The_Company_Of_Wolves.avi")
+;; (code-video "thecompanyofwolves"
"/sda5/torrents/The_Company_of_Wolves/The_Company_Of_Wolves.avi")
+
+;; 0:00 (ee-time-from-bol-shift -100)
+;; 0:00 (ee-time-from-bol-shift -10)
+;; 1:23 (if (ee-time-from-bol) (replace-match "abcd" t t))
+;; 1:23 (if (ee-time-from-bol) (save-excursion (replace-match "abcd" t t)))
+
+;; Ideally `M-1 M-x find-chomskyvideo' should use `ee-time-from-bol'...
+;; (find-elnode "Index" "* replace-match:")
+
+
+
+
+
+;;; _ _ _
+;;; ___ ___ __| | ___ __ _(_) __| | ___ ___
+;;; / __/ _ \ / _` |/ _ \____\ \ / / |/ _` |/ _ \/ _ \
+;;; | (_| (_) | (_| | __/_____\ V /| | (_| | __/ (_) |
+;;; \___\___/ \__,_|\___| \_/ |_|\__,_|\___|\___/
+;;;
+
+;; mplayer for video files
+;;
+(defun find-mplayer (fname &optional pos &rest rest)
+ "Open FNAME with mplayer, with a GUI (in fullscreen mode, for video files)."
+ (interactive "sFile name: ")
+ (find-bgprocess (ee-find-mplayer fname pos)))
+(defvar ee-mplayer-options '("-fs" "-osdlevel" "2" "-zoom"))
+(defun ee-find-mplayer (fname &optional pos &rest rest)
+ `("mplayer"
+ ,fname
+ ,@(if pos `("-ss" ,(ee-secs-to-mm:ss pos)))
+ ,@ee-mplayer-options
+ ))
+
+(defun code-mplayer (c fname)
+ (eval (ee-read (ee-code-mplayer c fname))))
+(defun find-code-mplayer (c fname)
+ (find-estring-elisp (ee-code-mplayer c fname)))
+(defun ee-code-mplayer (c fname)
+ (ee-template0 "\
+ ;; {(ee-S `(find-code-mplayer ,c ,fname))}
+ ;;
+ (defun find-{c} (&optional time &rest rest)
+ (interactive (list (ee-time-around-point)))
+ (setq ee-audiovideo-last 'find-{c})
+ (if (eq time t)
+ \"Just setting the default video\"
+ (find-mplayer {(ee-S fname)} time)))
+ "))
+
+(defalias 'find-video 'find-mplayer)
+(defalias 'code-video 'code-mplayer)
+(defalias 'find-code-video 'find-code-mplayer)
+
+;; (find-code-brfile 'find-video :local 'brvideol :dired 'brvideod)
+ (code-brfile 'find-video :local 'brvideol :dired 'brvideod)
+
+
+
+
+
+;;; _ _ _
+;;; ___ ___ __| | ___ __ _ _ _ __| (_) ___
+;;; / __/ _ \ / _` |/ _ \_____ / _` | | | |/ _` | |/ _ \
+;;; | (_| (_) | (_| | __/_____| (_| | |_| | (_| | | (_) |
+;;; \___\___/ \__,_|\___| \__,_|\__,_|\__,_|_|\___/
+
+;; mplayer in an xterm, for audio files
+;;
+(defvar ee-termplayer-term-options '("xterm" "-geometry" "+200+100" "-e"))
+(defvar ee-termplayer-options ())
+(defun ee-find-termplayer (fname &optional pos &rest rest)
+ `(,@ee-termplayer-term-options
+ "mplayer"
+ ,fname
+ ,@(if pos `("-ss" ,(ee-secs-to-mm:ss pos)))
+ ,@ee-termplayer-options
+ ))
+(defun find-termplayer (fname &optional pos &rest rest)
+ "Open FNAME with mplayer, without a GUI (in a terminal - for audio files)."
+ (interactive "sFile name: ")
+ (find-bgprocess (ee-find-termplayer fname pos)))
+
+(defun code-termplayer (c fname)
+ (eval (ee-read (ee-code-termplayer c fname))))
+(defun find-code-termplayer (c fname)
+ (find-estring-elisp (ee-code-termplayer c fname)))
+(defun ee-code-termplayer (c fname)
+ (ee-template0 "\
+ ;; {(ee-S `(find-code-termplayer ,c ,fname))}
+ ;;
+ (defun find-{c} (&optional time &rest rest)
+ (interactive (list (ee-time-around-point)))
+ (setq ee-audiovideo-last 'find-{c})
+ (find-termplayer {(ee-S fname)} time))
+ "))
+
+(defalias 'find-audio 'find-termplayer)
+(defalias 'code-audio 'code-termplayer)
+(defalias 'find-code-audio 'find-code-termplayer)
+
+;; (find-code-brfile 'find-audio :local 'braudiol :dired 'braudiod)
+ (code-brfile 'find-audio :local 'braudiol :dired 'braudiod)
+
+
+
+
+(provide 'eev-audiovideo)
+
+
+
+
+;; Garbage?
+
+;;;
+;;; _ __ ___ _ __ ___ _ ___ ___
+;;; | '_ ` _ \| '_ ` _ \(_) __/ __|
+;;; | | | | | | | | | | |_\__ \__ \
+;;; |_| |_| |_|_| |_| |_(_)___/___/
+;;;
+
+;; Convert between a number of seconds (a number)
+;; and a "minutes:seconds" thing (a string)
+;;
+(defun ee-secs-to-mm:ss (n)
+ "Force N - a number of seconds or an \"mm:ss\" string - to the mm:ss format"
+ (if (stringp n) n
+ (let* ((s (mod n 60))
+ (m (/ (- n s) 60)))
+ (format "%d:%02d" m s))))
+(defun ee-mm:ss-to-secs (mm:ss)
+ "Force MM:SS - a string or a number of seconds - to a number of seconds"
+ (if (numberp mm:ss) mm:ss
+ (let* ((ms (mapcar 'string-to-number (split-string mm:ss ":"))))
+ (+ (* 60 (car ms)) (cadr ms)))))
+
+
+;;; _ _
+;;; | |_(_)_ __ ___ ___ _ __ ___ __ _ _____ ___ __
+;;; | __| | '_ ` _ \ / _ \_____| '__/ _ \/ _` |/ _ \ \/ / '_ \
+;;; | |_| | | | | | | __/_____| | | __/ (_| | __/> <| |_) |
+;;; \__|_|_| |_| |_|\___| |_| \___|\__, |\___/_/\_\ .__/
+;;; |___/ |_|
+;;
+;; (find-elnode "Time Parsing")
+;; (seconds-to-time 4000)
+;; (float-time '(0 4000 0))
+;; (format-seconds "%h:%m:%s" 4000)
+;; (format-seconds "%h:%02m:%02s" 4000)
+;; (ee-seconds-to-time 260)
+;; (ee-seconds-to-time 4000)
+;; (ee-time-to-seconds "4:20")
+;; (date-to-time "2:30")
+;; (string-to-number "")
+;; (ee-time+ 40 "4:20")
+;; (ee-time+ -1000 "4:20")
+;;
+;; (defvar ee-time-regexp "[0-9]?[0-9]:[0-9][0-9]\\(:[0-9][0-9]\\)?")
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-blinks.el b/eev-blinks.el
new file mode 100644
index 0000000..790eb2a
--- /dev/null
+++ b/eev-blinks.el
@@ -0,0 +1,749 @@
+;;; eev-blinks.el -- support for basic hyperlinks in Emacs.
+;;; The basic hyperlinks are the ones that do not depend on templates,
+;;; and that are not created by `code-c-d' and friends.
+
+;; Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,
+;; 2009,2010,2011,2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012nov08
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-blinks.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-blinks.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+
+
+
+;; �.eek� (to "eek")
+;; �.ee-goto-position� (to "ee-goto-position")
+;; �.ee-goto-rest� (to "ee-goto-rest")
+;; �.find-fline� (to "find-fline")
+;; �.find-wottb� (to "find-wottb")
+;; �.find-ebufferandpos� (to "find-ebufferandpos")
+;; �.find-ebuffer� (to "find-ebuffer")
+;; �.find-eoutput� (to "find-eoutput")
+;; �.find-estring� (to "find-estring")
+;; �.find-sh� (to "find-sh")
+;; �.find-man� (to "find-man")
+;; �.find-w3m� (to "find-w3m")
+;; �.find-Package� (to "find-Package")
+;; �.find-epp� (to "find-epp")
+;; �.find-einternals� (to "find-einternals")
+
+
+
+(defvar ee-buffer-name nil) ; overridden by `let's
+
+;; (find-efunction 'ee-find-tag)
+
+
+
+
+;;; _ _ _
+;;; __ _ _ _| |_ ___ | | ___ __ _ __| |___
+;;; / _` | | | | __/ _ \| |/ _ \ / _` |/ _` / __|
+;;; | (_| | |_| | || (_) | | (_) | (_| | (_| \__ \
+;;; \__,_|\__,_|\__\___/|_|\___/ \__,_|\__,_|___/
+;;;
+;;; autoloads for external functions
+;; (find-elnode "Autoload")
+;;
+(autoload 'find-function-read "find-func")
+(autoload 'pp-to-string "pp")
+(autoload 'Man-fontify-manpage "man" nil t)
+(autoload 'word-at-point "thingatpt")
+(autoload 'list-iso-charset-chars "mule-diag")
+(autoload 'list-non-iso-charset-chars "mule-diag")
+
+
+
+;;; _
+;;; ___ ___| | __
+;;; / _ \/ _ \ |/ /
+;;; | __/ __/ <
+;;; \___|\___|_|\_\
+;;;
+;; �eek� (to ".eek")
+
+(defun eek (str) (interactive "sKeys: ")
+ "Execute STR as a keyboard macro. See `edmacro-mode' for the exact format.\n
+An example: (eek \"C-x 4 C-h\")"
+ (execute-kbd-macro (read-kbd-macro str)))
+
+
+
+
+;;; _ _ _
+;;; _ __ ___ ___ ___ _ __ ___ ___ | (_)___| |_ ___
+;;; | '_ \ / _ \/ __| ___ / __| '_ \ / _ \/ __|___| | / __| __/ __|
+;;; | |_) | (_) \__ \|___|\__ \ |_) | __/ (__|___| | \__ \ |_\__ \
+;;; | .__/ \___/|___/ |___/ .__/ \___|\___| |_|_|___/\__|___/
+;;; |_| |_|
+;;;
+;; �ee-goto-position� (to ".ee-goto-position")
+;; support for pos-spec-lists in hyperlinks
+;; See: (find-eval-intro "Refining hyperlinks")
+
+(defun ee-goto-position (&optional pos-spec &rest rest)
+ "Process the \"absolute pos-spec-lists\" arguments in hyperlink functions.
+POS-SPEC, the first element of a pos-spec-list, is treated
+specially; if it is a string then jump to the first occurrence of
+that string in the buffer, and if it a number jump to the line
+with that number in the buffer; if it is nil, do nothing.
+
+The rest of the pos-spec-list, REST, is treated by
+`ee-goto-rest'.
+
+Many kinds of hyperlinks - for example,
+
+ (find-efunction 'ee-goto-position)
+
+already jump to specific positions of a buffer; those hyperlink
+functions support \"relative pos-spec-lists\", and they invoke
+`ee-goto-rest' straight away to handle their pos-spec-lists -
+they skip the first \"absolute\" pos-spec."
+ (when pos-spec
+ (cond ((numberp pos-spec)
+ (goto-char (point-min))
+ (forward-line (1- pos-spec)))
+ ((stringp pos-spec)
+ (goto-char (save-excursion ; This used to be just:
+ (goto-char (point-min)) ; (goto-char (point-min))
+ (search-forward pos-spec) ; (search-forward pos-spec)
+ (point)))) ;
+ (t (error "This is not a valid pos-spec: %S" pos-spec)))
+ (if rest (ee-goto-rest rest))))
+
+;; �ee-goto-rest� (to ".ee-goto-rest")
+
+(defun ee-goto-rest (list)
+ "Process \"relative pos-spec-lists\".
+For each element in LIST, if it is:
+
+ a string -> jump to the next occurrence of that string in the
+ current buffer
+ a number -> go down that many lines
+ a list -> evaluate the list (take care!)
+
+anything else generates an error - but users are encouraged to
+create their own extended versions of this function and override
+the standard definition."
+ (cond ((null list))
+ ((stringp (car list))
+ (search-forward (car list))
+ (ee-goto-rest (cdr list)))
+ ((numberp (car list))
+ (forward-line (car list))
+ (ee-goto-rest (cdr list)))
+ ((consp (car list))
+ (eval (car list))
+ (ee-goto-rest (cdr list)))
+ (t (error "Not a valid pos-spec item: %S" (car list)))))
+
+
+
+
+;;; __ _ _ __ _ _
+;;; / _(_)_ __ __| | / _| (_)_ __ ___
+;;; | |_| | '_ \ / _` |_____| |_| | | '_ \ / _ \
+;;; | _| | | | | (_| |_____| _| | | | | | __/
+;;; |_| |_|_| |_|\__,_| |_| |_|_|_| |_|\___|
+;;; __ _ _ _
+;;; / _(_)_ __ __| | _ __ ___ __| | ___
+;;; | |_| | '_ \ / _` |_____| '_ \ / _ \ / _` |/ _ \
+;;; | _| | | | | (_| |_____| | | | (_) | (_| | __/
+;;; |_| |_|_| |_|\__,_| |_| |_|\___/ \__,_|\___|
+;;;
+;; �find-fline� (to ".find-fline")
+;;; Basic links: find-fline and find-node
+;; Tests:
+;; (find-fline "~/")
+;; (find-node "(emacs)Top")
+
+(defun find-fline (fname &rest pos-spec-list)
+ "Hyperlink to a file (or a directory).
+This function is similar to `find-file' but it supports a
+\"pos-spec-list\" - see `ee-goto-position'.
+Examples:\n
+ (find-file \"~/.emacs\")
+ (find-fline \"~/.emacs\")
+ (find-fline \"~/.emacs\" \"Beginning of the eev block\")"
+ (find-file (ee-expand fname))
+ (apply 'ee-goto-position pos-spec-list))
+
+(defun find-fline-gz (fname &rest pos-spec-list)
+"Like `find-fline', but also tries \"FNAME.gz\" if \"FNAME\" does not exist."
+ (let* ((efname (ee-expand fname))
+ (efnamegz (concat efname ".gz")))
+ (if (and (not (file-exists-p efname))
+ (file-exists-p efnamegz))
+ (apply 'find-fline efnamegz pos-spec-list)
+ (apply 'find-fline efname pos-spec-list))))
+
+(defun find-node (nodestr &rest pos-spec-list)
+ "Hyperlink to an info page.
+This function is similar to `info' but it supports a
+\"pos-spec-list\" - see `ee-goto-position'.
+Examples:\n
+ (info \"(emacs)Lisp Eval\")
+ (find-node \"(emacs)Lisp Eval\" \"C-x C-e\")"
+ (info nodestr)
+ (apply 'ee-goto-position pos-spec-list))
+
+
+
+
+
+;;; __ _ _ _ _ _
+;;; / _(_)_ __ __| | __ _____ | |_| |_| |__
+;;; | |_| | '_ \ / _` |____\ \ /\ / / _ \| __| __| '_ \
+;;; | _| | | | | (_| |_____\ V V / (_) | |_| |_| |_) |
+;;; |_| |_|_| |_|\__,_| \_/\_/ \___/ \__|\__|_.__/
+;;;
+;; �find-wottb� (to ".find-wottb")
+;;; hyperlinks to the output of Emacs's help-like functions
+
+;; Tests:
+;; (find-efunctiondescr 'next-line "line-move-visual")
+;; (find-ekeydescr [down] "line-move-visual")
+;; (find-evariabledescr 'line-move-visual "visual lines")
+;; (find-efunctiond 'next-line "next-line-add-newlines")
+;; (find-eapropos "^find-.*-links" "find-intro-links")
+;; (find-ecolors " white")
+;; (find-efacedescr 'default "Foreground:")
+;; (find-efaces "default")
+
+(defun find-wottb-call (sexp bufname &rest pos-spec-list)
+ "Hyperlink to functions that call `with-output-to-temp-buffer'.
+First evaluate SEXP with a trick to not let it split the current window,
+then switch to the buffer that it created (it must be called BUFNAME),
+then go to the position specified by POS-SPEC-LIST.\n
+\(This is a horrible hack.)"
+ (let ((same-window-buffer-names
+ (cons bufname same-window-buffer-names)))
+ (eval sexp))
+ (set-buffer bufname) ; why is this needed?
+ (apply 'ee-goto-position pos-spec-list))
+
+(defun find-eapropos (regexp &rest pos-spec-list)
+ "Hyperlink to the result of running `apropos' on REGEXP."
+ (interactive "sApropos symbol (regexp): ")
+ (apply 'find-wottb-call '(apropos regexp) "*Apropos*" pos-spec-list))
+
+(defun find-efunctiondescr (symbol &rest pos-spec-list)
+ "Hyperlink to the result of running `describe-function' on SYMBOL."
+ (interactive (find-function-read))
+ (apply 'find-wottb-call '(describe-function symbol) "*Help*" pos-spec-list))
+
+(defun find-evariabledescr (symbol &rest pos-spec-list)
+ "Hyperlink to the result of running `describe-variable' on SYMBOL."
+ (interactive (find-function-read 'variable))
+ (apply 'find-wottb-call '(describe-variable symbol) "*Help*" pos-spec-list))
+
+(defalias 'find-evardescr 'find-evariabledescr)
+
+(defun find-ekeydescr (key &rest pos-spec-list)
+ "Hyperlink to the result of running `describe-key' on KEY."
+ (interactive "kFind function on key: ")
+ (apply 'find-wottb-call '(describe-key key) "*Help*" pos-spec-list))
+
+(defun find-efacedescr (face &rest pos-spec-list)
+ "Hyperlink to the result of running `describe-face' on FACE."
+ (interactive (list (read-face-name "Describe face")))
+ (apply 'find-wottb-call '(describe-face face) "*Help*" pos-spec-list))
+
+(defun find-efaces (&rest pos-spec-list)
+ "Hyperlink to the result of running `list-faces-display'."
+ (interactive)
+ (apply 'find-wottb-call '(list-faces-display) "*Faces*" pos-spec-list))
+
+(defun find-ecolors (&rest pos-spec-list)
+ "Hyperlink to the result of running `list-colors-display'."
+ (interactive)
+ (apply 'find-wottb-call '(list-colors-display) "*Colors*" pos-spec-list))
+
+(defun find-efunctiond (function &rest pos-spec-list)
+ "Hyperlink to the result of running `disassemble' on FUNCTION."
+ (interactive (find-function-read))
+ (apply 'find-wottb-call '(disassemble function) "*Disassemble*"
+ pos-spec-list))
+
+
+
+
+;;; __ _ _ __ _ _
+;;; / _(_)_ __ __| | ___ / _|_ _ _ __ ___| |_(_) ___ _ __
+;;; | |_| | '_ \ / _` |____ / _ \ |_| | | | '_ \ / __| __| |/ _ \| '_ \
+;;; | _| | | | | (_| |____| __/ _| |_| | | | | (__| |_| | (_) | | | |
+;;; |_| |_|_| |_|\__,_| \___|_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
+;;;
+;; �find-ebufferandpos� (to ".find-ebufferandpos")
+;;; hyperlinks to the source code of Emacs functions and variables
+
+;; Tests:
+;; (find-efunction 'next-line)
+;; (find-evariable 'line-move-visual)
+
+(defun find-ebufferandpos (buffer-and-pos &rest pos-spec-list)
+ "Internal use; hyperlink to a \"buffer and pos\" structure.
+Emacs has some standard (i.e., non-eev) functions that can be
+used as hyperlinks, like `find-function' and `find-variable';
+they call internal functions like `find-function-noselect' and
+`find-variable-noselect', that return structures of the form
+BUFFER-AND-POS, that are conses like (#<buffer foo> . 42). This
+function jumps to the position described by a cons like that, and
+then processes an optional relative POS-SPEC-LIST using
+`ee-goto-rest'.
+
+Functions like `find-efunction' and `find-evariable' (defined in
+eev.el) are wrappers around `find-function' and `find-variable'
+that add support for a relative pos-spec-list after the symbol."
+ (if (not (bufferp (car buffer-and-pos)))
+ (error "Bad (BUFFER . POS): %S" buffer-and-pos))
+ (switch-to-buffer (car buffer-and-pos))
+ (goto-char (cdr buffer-and-pos))
+ (ee-goto-rest pos-spec-list))
+
+(defun find-efunction (symbol &rest pos-spec-list)
+ "Hyperlink to the result of running `find-function' on SYMBOL.
+The `find-function' function of Emacs can be used as a hyperlink
+- it finds the Elisp source code of SYMBOL -, but it doesn't
+support a POS-SPEC-LIST like this function does."
+ (interactive (find-function-read))
+ (apply 'find-ebufferandpos (find-function-noselect symbol) pos-spec-list))
+
+(defun find-evariable (symbol &rest pos-spec-list)
+ "Hyperlink to the result of running `find-variable' on SYMBOL."
+ (interactive (find-function-read 'variable))
+ (apply 'find-ebufferandpos (find-variable-noselect symbol) pos-spec-list))
+
+
+
+
+
+;;; __ _ _ _ __ __
+;;; / _(_)_ __ __| | ___| |__ _ _ / _|/ _| ___ _ __
+;;; | |_| | '_ \ / _` |_____ / _ \ '_ \| | | | |_| |_ / _ \ '__|
+;;; | _| | | | | (_| |_____| __/ |_) | |_| | _| _| __/ |
+;;; |_| |_|_| |_|\__,_| \___|_.__/ \__,_|_| |_| \___|_|
+;;;
+;; �find-ebuffer� (to ".find-ebuffer")
+;; Hyperlinks to buffers
+;; Tests:
+;; (find-ebuffer "*Messages*")
+
+(defun find-ebuffer (buffer &rest pos-spec-list)
+ "Hyperlink to an Emacs buffer (existing or not)."
+ (interactive "bBuffer: ")
+ (switch-to-buffer buffer)
+ (apply 'ee-goto-position pos-spec-list))
+
+
+
+;;; __ _ _ _ _
+;;; / _(_)_ __ __| | ___ ___ _ _| |_ _ __ _ _| |_
+;;; | |_| | '_ \ / _` |_____ / _ \/ _ \| | | | __| '_ \| | | | __|
+;;; | _| | | | | (_| |_____| __/ (_) | |_| | |_| |_) | |_| | |_
+;;; |_| |_|_| |_|\__,_| \___|\___/ \__,_|\__| .__/ \__,_|\__|
+;;; |_|
+;; �find-eoutput� (to ".find-eoutput")
+;; Tests:
+;; (find-estring "a\nb\nc\n")
+;; (find-estring-elisp "(dotimes (i 10) (insert \"\\na\"))")
+
+(defun find-eoutput-rerun (buffer-name code &rest pos-spec-list)
+ "Hyperlink to the effect of running CODE in Emacs.
+If the buffer BUFFER-NAME does not exist then create it and run
+CODE in it. If the buffer already exists, then \"run CODE
+again\" (compare with `find-output-reuse'): delete the buffer,
+recreate it, and run CODE in it.\n
+For simplicity we are deleting the buffer and then recreating it,
+but it could be better to just delete the buffer's contents. This
+needs to be thought out."
+ (if (get-buffer buffer-name) ; if the buffer exists
+ (if (not (kill-buffer buffer-name)) ; try to kill it; confirm if needed
+ (error "Not killing the buffer %s" buffer-name)))
+ (switch-to-buffer buffer-name) ; create the buffer
+ (eval code) ; always run CODE on the empty buffer
+ (goto-char (point-min))
+ (apply 'ee-goto-position pos-spec-list))
+
+(defun find-eoutput-reuse (buffer-name code &rest pos-spec-list)
+ "Hyperlink to the effect of running CODE in Emacs.
+If the buffer BUFFER-NAME does not exist then create it and run
+CODE in it. If the buffer already exists, then \"reuse
+it\" (compare with `find-output-rerun'): switch to it, ignore the
+CODE argument, and process the POS-SPEC-LIST."
+ (if (get-buffer buffer-name) ; if the buffer exists
+ (switch-to-buffer buffer-name) ; then just switch to it
+ (switch-to-buffer buffer-name) ; otherwise switch to it and
+ (eval code) ; run CODE to produce its
contents
+ (goto-char (point-min)))
+ (apply 'ee-goto-position pos-spec-list))
+
+;; �find-estring� (to ".find-estring")
+;;
+(defun find-estring (string &rest pos-spec-list)
+ "Visit a temporary buffer whose contents are given by STR.
+The default name for the buffer is \"*string*\", but this can be
+overriden by setting `ee-buffer-name' to another name with a `let'.
+If the buffer already exists its contents are destroyed.
+The buffer is not made read-only."
+ (apply 'find-eoutput-rerun (or ee-buffer-name "*string*")
+ `(insert ,string) pos-spec-list))
+
+(defun find-estring-elisp (string &rest pos-spec-list)
+ "Visit a temporary buffer whose contents are given by STR.
+This function is similar to `find-estring', but this one also
+runs `emacs-lisp-mode' in the buffer."
+ (apply 'find-eoutput-rerun (or ee-buffer-name "*string*")
+ `(progn (insert ,string) (emacs-lisp-mode)) pos-spec-list))
+
+;; For (find-anchors-intro)
+;; Hacky.
+(defun ee-raw-text-unix ()
+ "Set the current buffer to unibyte (for certain glyphs).
+See: (find-anchors-intro \"WARNING: some glyphs need raw-text-unix\")"
+ (interactive)
+ (set-buffer-file-coding-system 'raw-text-unix 'force)
+ (set-buffer-multibyte nil))
+
+(defun find-estring-lv (string &rest pos-spec-list)
+ "Visit a temporary buffer whose contents are given by STR.
+The default name for the buffer is \"*string*\", but this can be
+overriden by setting `ee-buffer-name' to another name with a `let'.
+If the buffer already exists its contents are destroyed.
+The buffer is not made read-only.
+The \"Local variables:\" section in the buffer is processed."
+ (apply 'find-eoutput-rerun (or ee-buffer-name "*string*")
+ `(progn (ee-raw-text-unix)
+ (insert ,string)
+ (hack-local-variables))
+ pos-spec-list))
+
+
+
+
+
+
+;;; __ _ _ _
+;;; / _(_)_ __ __| | ___| |__
+;;; | |_| | '_ \ / _` |_____/ __| '_ \
+;;; | _| | | | | (_| |_____\__ \ | | |
+;;; |_| |_|_| |_|\__,_| |___/_| |_|
+;;;
+;;; hyperlinks to the output of shell commands
+;;;
+;; �find-sh� (to ".find-sh")
+;; Tests:
+;; (find-sh "seq 2095 2100")
+;; (find-sh0 "seq 2095 2100")
+;; (find-sh00 "seq 2095 2100")
+
+(defun find-sh (command &rest pos-spec-list)
+ "Hyperlink to the result of running the shell command COMMAND.
+If a buffer named COMMAND does not exist then create it and put
+there the output or running COMMAND; if a buffer named COMMAND
+already exists then reuse it and do not run COMMAND again."
+ (interactive "sShell command: ")
+ (if (get-buffer command) ; if the buffer already exists
+ (switch-to-buffer command) ; then just switch to it
+ (switch-to-buffer command) ; otherwise create it
+ (insert (shell-command-to-string command)) ; prepare its contents
+ (goto-char (point-min))) ; and place point at its beginning
+ (apply 'ee-goto-position pos-spec-list))
+
+(defalias 'find-sh00 'shell-command-to-string)
+
+(defun find-sh0 (command)
+ "Hyperlink to the result of running the shell command COMMAND.
+This function does not create a buffer like `find-sh' does;
+instead, it just returns the output of COMMAND as string,
+removing a trailing newline from the output if one is found.
+Follow a `find-sh0' hyperlink just displays the output of the
+COMMAND in the echo area."
+ (replace-regexp-in-string "\n\\'" "" (shell-command-to-string command)))
+
+
+
+;;; __ _ _
+;;; / _(_)_ __ __| | _ __ ___ __ _ _ __
+;;; | |_| | '_ \ / _` |_____| '_ ` _ \ / _` | '_ \
+;;; | _| | | | | (_| |_____| | | | | | (_| | | | |
+;;; |_| |_|_| |_|\__,_| |_| |_| |_|\__,_|_| |_|
+;;;
+;; �find-man� (to ".find-man")
+;; hyperlinks to manpages
+;; Tests:
+;; (find-man "1 cat")
+
+(defvar ee-find-man-flag nil "See `find-man'.")
+
+(defadvice Man-notify-when-ready (around find-man (man-buffer) activate)
+ "After rendering a manpage jump to `ee-find-man-pos-spec-list'."
+ (if (not ee-find-man-flag)
+ ad-do-it
+ (switch-to-buffer man-buffer)
+ (apply 'ee-goto-position ee-find-man-pos-spec-list)
+ (setq ee-find-man-flag nil)))
+
+(defun find-man (manpage &rest pos-spec-list)
+ "Hyperlink to a manpage."
+ (interactive (list (ee-manpagename-ask)))
+ (setq ee-find-man-flag t
+ ee-find-man-pos-spec-list pos-spec-list)
+ (man manpage))
+
+;; Missing: find-woman. (find-node "(woman)Top")
+
+
+
+
+;;; __ _ _ _____
+;;; / _(_)_ __ __| | __ _|___ / _ __ ___
+;;; | |_| | '_ \ / _` |____\ \ /\ / / |_ \| '_ ` _ \
+;;; | _| | | | | (_| |_____\ V V / ___) | | | | | |
+;;; |_| |_|_| |_|\__,_| \_/\_/ |____/|_| |_| |_|
+;;;
+;; �find-w3m� (to ".find-w3m")
+;; Hyperlinks to webpages and files in HTML
+;; Tests:
+;; (find-w3m "http://www.emacswiki.org/")
+
+(defun find-w3m (url &rest pos-spec-list)
+ "Hyperlink to a page in HTML.
+Use w3m to render the page as text in an Emacs buffer.
+Apply `ee-expand' to URL; this changes URL when it starts with
+\"~\" or \"$\". After that if URL starts with \"/\" prepend
+\"file://\" to it.
+
+These operations on URL keep \"real urls\" unchanged and convert
+several kinds of filenames into urls that w3m can process - but
+it doesn't convert relative filenames into urls. See
+`expand-file-name'."
+ (interactive "Murl: ")
+ (require 'w3m)
+ (let ((enable-local-variables nil) ; workaround for a w3m-el bug
+ (w3m-async-exec nil)
+ ;; See: http://emacs-w3m.namazu.org/ml/msg10374.html
+ (w3m-local-find-file-regexps '(nil . ""))
+ (w3m-content-type-alist
+ (append w3m-content-type-alist '(("text/html" "" nil nil)))))
+ (w3m (replace-regexp-in-string "^/" "file:///" (ee-expand url))))
+ (ee-goto-rest pos-spec-list))
+
+
+
+
+
+;;; _ _ _
+;;; __| | ___| |__ (_) __ _ _ __
+;;; / _` |/ _ \ '_ \| |/ _` | '_ \
+;;; | (_| | __/ |_) | | (_| | | | |
+;;; \__,_|\___|_.__/|_|\__,_|_| |_|
+;;;
+;; �find-Package� (to ".find-Package")
+;; Hyperlinks to information about Debian packages.
+;; Tests:
+;; (find-status "bash")
+;; (find-available "bash")
+;; (find-grep-status "bash")
+;; (find-grep-available "bash")
+
+(defun find-Package (fname &optional packagename &rest pos-spec-list)
+ "Hyperlink to \"Package: \" achors in Debian package control files.
+See: `find-status', `find-available', (find-man \"grep-dctrl\")"
+ (find-fline fname)
+ (apply 'ee-goto-position
+ (if packagename (format "\nPackage: %s\n" packagename))
+ pos-spec-list))
+
+(defun find-status (packagename &rest pos-spec-list)
+ "Hyperlink to the info about the package PACKAGENAME in /var/lib/dpkg/status.
+This is Debian-specific. See `find-Package'."
+ (interactive (list (ee-debpkgname-ask)))
+ (apply 'find-Package "/var/lib/dpkg/status" packagename pos-spec-list))
+
+(defun find-available (packagename &rest pos-spec-list)
+"Hyperlink to the info about the package PACKAGENAME in
/var/lib/dpkg/available.
+This is Debian-specific. See `find-Package'."
+ (interactive (list (ee-debpkgname-ask)))
+ (apply 'find-Package "/var/lib/dpkg/available" packagename pos-spec-list))
+
+(defun find-grep-status (grepargs &rest pos-spec-list)
+ (interactive "sgrep-status ")
+ (apply 'find-sh (concat "grep-status " grepargs) pos-spec-list))
+
+(defun find-grep-available (grepargs &rest pos-spec-list)
+ (interactive "sgrep-available ")
+ (apply 'find-sh (concat "grep-available " grepargs) pos-spec-list))
+
+
+
+
+;;; __ _ _
+;;; / _(_)_ __ __| | ___ _ __ _ __
+;;; | |_| | '_ \ / _` |____ / _ \ '_ \| '_ \
+;;; | _| | | | | (_| |____| __/ |_) | |_) |
+;;; |_| |_|_| |_|\__,_| \___| .__/| .__/
+;;; |_| |_|
+;; �find-epp� (to ".find-epp")
+;; Pretty-priting sexps.
+;; "pp0" -> "pretty-print a Lisp object in a very compact way".
+;; Tests:
+;; (find-epp '(apply (lambda (a) (* a a)) 5))
+;; (find-functionpp 'find-efunction)
+
+(defun find-epp0 (object)
+ "Display a pretty-printed version of OBJECT in the echo area.
+This function uses `message' and so it only makes sense to call
+it from commands bound to keys, not by sexps that are evaluated
+explicitly. Try this: (progn (message \"foo\") \"bar\")"
+ (message (ee-pp0 object)))
+
+(defun find-epp (object &rest pos-spec-list)
+ "Visit a temporary buffer containing a pretty-printed version of OBJECT."
+ (let ((ee-buffer-name (or ee-buffer-name "*pp*")))
+ (apply 'find-estring-elisp (pp-to-string object) pos-spec-list)))
+
+(defun find-efunctionpp (symbol &rest pos-spec-list)
+"Visit a temporary buffer containing the pretty-printed Lisp code for SYMBOL."
+ (interactive (find-function-read))
+ (let ((ee-buffer-name
+ (or ee-buffer-name (format "*function %S*" symbol))))
+ (apply 'find-epp
+ (symbol-function symbol)
+ ;; Note: if instead of the above we use
+ ;; `(fset ',symbol ',(symbol-function symbol))
+ ;; the we get a buffer in which we can edit the code for SYMBOL.
+ pos-spec-list)))
+
+
+
+
+
+;;; _ _ _
+;;; ___ _ __ ___ __ _ ___ ___ (_)_ __ | |_ ___ _ __ _ __ __ _| |___
+;;; / _ \ '_ ` _ \ / _` |/ __/ __| | | '_ \| __/ _ \ '__| '_ \ / _` | / __|
+;;; | __/ | | | | | (_| | (__\__ \ | | | | | || __/ | | | | | (_| | \__ \
+;;; \___|_| |_| |_|\__,_|\___|___/ |_|_| |_|\__\___|_| |_| |_|\__,_|_|___/
+;;;
+;; �find-einternals� (to ".find-einternals")
+;; Hyperlinks to other things internal to Emacs
+;; Tests:
+;; (find-ekeymapdescr isearch-mode-map "toggle-regexp")
+;; (find-eminorkeymapdescr 'eev-mode)
+;; (find-einsert '((32 255) 10 (8592 9167)))
+;; (find-etpat)
+;; (find-etpat0)
+
+(defun find-ekeymapdescr (keymap &rest pos-spec-list)
+ "Hyperlink to the list of bindings in KEYMAP.
+Example: (find-ekeymapdescr isearch-mode-map \"toggle-regexp\")"
+ ;; To do: add the buttons/link thing
+ (apply 'find-estring (substitute-command-keys "\\<keymap>\\{keymap}")
+ pos-spec-list))
+
+(defun find-eminorkeymapdescr (mode-symbol &rest pos-spec-list)
+ "Hyperlink to the list of bindings in the minor mode MODE-SYMBOL.
+Example: (find-eminorkeymapdescr 'eev-mode)"
+ (apply 'find-ekeymapdescr (ee-minor-mode-keymap mode-symbol)
+ pos-spec-list))
+
+(defun ee-minor-mode-keymap (mode-symbol)
+ "An auxiliary function used by `find-eminorkeymapdescr'.
+Example: (find-ekeymapdescr (ee-minor-mode-keymap 'eev-mode))"
+ (cdr (assq mode-symbol minor-mode-map-alist)))
+
+(defun ee-insert (&rest rest)
+ "Insert characters, strings, or ranges of characters.
+Example: (ee-insert '(?a ?z) 10 \"Foo!\")"
+ (while rest
+ (let ((o (car rest)))
+ (cond ((stringp o) (insert o))
+ ((numberp o) (if (char-valid-p o) (insert o)))
+ ((consp o) (mapc 'ee-insert (apply 'number-sequence o)))
+ (t (error "Not string/int/pair: %S" o))))
+ (setq rest (cdr rest))))
+
+(defun find-einsert (what &rest rest)
+"See `ee-insert'.
+Example of use: (find-einsert '((32 1000) 10 (8000 12000)))"
+ (apply 'find-eoutput-reuse "*einsert*"
+ `(apply 'ee-insert ',what) rest))
+
+(defun find-etpat (&rest pos-spec-list)
+"Hyperlink to a pretty-version of the result of (text-properties-at (point))."
+ (interactive)
+ (let* ((ee-buffer-name
+ (or ee-buffer-name "*(text-properties-at (point))*")))
+ (apply 'find-epp (text-properties-at (point)) pos-spec-list)))
+
+(defun find-etpat0 ()
+ "Show the result of (text-properties-at (point)) in the echo area."
+ (interactive)
+ (find-epp0 (text-properties-at (point))))
+
+;; Broken? See: (find-efile "international/ccl.el")
+(defun find-eccldump (ccl-code &rest pos-spec-list)
+ "Hyperlink to the result of running `ccl-dump' on CCL-CODE.
+Example: (find-eccldump ccl-decode-mule-utf-8)"
+ (apply 'find-eoutput-reuse "*ccl-dump*"
+ `(ccl-dump ,ccl-code) pos-spec-list))
+
+;; Broken? `list-iso-charset-chars' and friends are not defined in the
+;; Unicode-2 branch of Emacs... Does this still work?
+;;
+(defun find-echarsetchars (charset &rest pos-spec-list)
+ "See: (find-efunction 'list-charset-chars)
+Examples: (find-echarsetchars 'mule-unicode-0100-24ff \"733x\")
+ (find-echarsetchars 'mule-unicode-2500-33ff)"
+ (interactive (list (read-charset "Character set: ")))
+ (apply 'find-eoutput-reuse "*charset*"
+ '(cond ((charsetp charset)
+ (list-iso-charset-chars charset))
+ ((assq charset non-iso-charset-alist)
+ (list-non-iso-charset-chars charset))
+ (t (error "Invalid character set %s" charset)))
+ pos-spec-list))
+
+
+
+
+
+(provide 'eev-blinks)
+
+
+
+
+
+;; was: ee-anchor-format: "defun %s "
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; no-byte-compile: t
+;; End:
diff --git a/eev-bounded.el b/eev-bounded.el
new file mode 100644
index 0000000..3501a97
--- /dev/null
+++ b/eev-bounded.el
@@ -0,0 +1,330 @@
+;;; eev-bounded.el -- functions like `eev-bounded', `eelatex-bounded', etc.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012dec26
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-bounded.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-bounded.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-bounded-intro.html>
+;; (find-eev-intro)
+;; (find-bounded-intro)
+
+;;; Commentary:
+;;
+;; This file adds support for "bounded functions" to eev. For example:
+;; `M-x eev' saves the region between point and mark into the
+;; temporary script file; `M-x eev-bounded' saves the region around
+;; point, up to the first occurences of a certain delimiters before
+;; and after point, into the temporary script file.
+;;
+;; Big letters courtesy of Figlet.
+
+;; See: (find-bounded-intro)
+
+
+
+
+;;; _ _ _ _ _
+;;; __| | ___| (_)_ __ ___ (_) |_ ___ _ __ ___
+;;; / _` |/ _ \ | | '_ ` _ \| | __/ _ \ '__/ __|
+;;; | (_| | __/ | | | | | | | | || __/ | \__ \
+;;; \__,_|\___|_|_|_| |_| |_|_|\__\___|_| |___/
+;;;
+
+(defvar ee-delimiter-hash "\n#\n" "See `eev-bounded'.")
+(defvar ee-delimiter-percent "\n%\n" "See `eelatex-bounded'.")
+(defvar ee-delimiter-semicolon "\n;;\n" "See `eeeval-boudned'.")
+
+(put 'ee-delimiter-hash 'safe-local-variable 'stringp)
+(put 'ee-delimiter-percent 'safe-local-variable 'stringp)
+(put 'ee-delimiter-semicolon 'safe-local-variable 'stringp)
+
+(defun ee-sdelim-to-s (sdelim)
+ "Search backwards for STR and return the position after STR.
+This function does not move point."
+ (+ (save-excursion (search-backward sdelim))
+ (length sdelim)))
+
+(defun ee-edelim-to-e (edelim)
+ "Search forward for STR and return the position before STR.
+This function does not move point."
+ (+ (save-excursion (search-forward edelim))
+ (- (length edelim))))
+
+
+
+;;; _ _ _ _
+;;; ___ ___ __| | ___ | |__ ___ _ _ _ __ __| | ___ __| |
+;;; / __/ _ \ / _` |/ _ \_____| '_ \ / _ \| | | | '_ \ / _` |/ _ \/ _` |
+;;; | (_| (_) | (_| | __/_____| |_) | (_) | |_| | | | | (_| | __/ (_| |
+;;; \___\___/ \__,_|\___| |_.__/ \___/ \__,_|_| |_|\__,_|\___|\__,_|
+;;;
+;; See: (find-bounded-intro "Defining new bounded functions")
+
+(defun code-bounded (newf f delim &optional adjust face dur)
+ (eval (ee-read
+ (ee-code-bounded newf f delim adjust face dur))))
+(defun find-code-bounded (newf f delim &optional adjust face dur)
+ (find-estring-elisp
+ (ee-code-bounded newf f delim adjust face dur)))
+(defun ee-code-bounded (newf f delim &optional adjust face dur)
+ (setq adjust (or adjust 1))
+ (setq face (or face 'highlight))
+ (setq dur (or dur 0.75))
+ (ee-template0 "
+\(defun {newf} ()
+ \"Run the function `{f}' on a delimited region around point.
+See: (find-bounded-intro)\"
+ (interactive)
+ (setq ee-bounded-function '{newf})
+ (let* ((s (ee-sdelim-to-s {(ee-S delim)}))
+ (e (ee-edelim-to-e {(ee-S delim)})))
+ (ee-flash s (+ e {adjust})
+ '{(ee-S face)} {dur})
+ ({f} (ee-se-to-string s e))))
+ "))
+
+(code-bounded 'eev-bounded 'eev 'ee-delimiter-hash)
+(code-bounded 'eeg-bounded 'eeg 'ee-delimiter-hash)
+(code-bounded 'eegdb-bounded 'eegdb 'ee-delimiter-hash)
+(code-bounded 'eelatex-bounded 'eelatex 'ee-delimiter-percent)
+(code-bounded 'eeeval-bounded 'eeeval 'ee-delimiter-semicolon)
+(code-bounded 'eeb-eval 'eeeval 'ee-delimiter-semicolon)
+
+;; Tests:
+;; (find-code-bounded 'eev-bounded 'eev "\n#\n")
+;; (find-code-bounded 'eev-bounded 'eev 'ee-delimiter-hash)
+
+
+
+
+;;; _ __ _ _
+;;; __| | ___ / _| __ _ _ _| | |_
+;;; / _` |/ _ \ |_ / _` | | | | | __|
+;;; | (_| | __/ _| (_| | |_| | | |_
+;;; \__,_|\___|_| \__,_|\__,_|_|\__|
+;;;
+;; See: (find-bounded-intro "The default bounded function")
+
+(defvar ee-bounded-function
+ '(lambda () (error "ee-bounded-function not set"))
+ "See: (find-bounded-intro)")
+
+(defun ee-bounded-function ()
+ "See: (find-bounded-intro)"
+ (interactive)
+ (funcall ee-bounded-function))
+
+;; (define-key eev-mode-map [f3] 'ee-bounded-function)
+
+(provide 'eev-bounded)
+
+
+
+
+
+
+
+
+
+
+;;; _ _ _
+;;; ___ | |__ ___ ___ | | ___| |_ ___
+;;; / _ \| '_ \/ __|/ _ \| |/ _ \ __/ _ \
+;;; | (_) | |_) \__ \ (_) | | __/ || __/
+;;; \___/|_.__/|___/\___/|_|\___|\__\___|
+;;;
+;; Obsolete code that I don't want to delete yet
+;; (mainly because the docstrings have some good ideas in them)
+
+' (progn
+
+(defun ee-add-quote (obj)
+ "Return OBJ is OBJ is constant; else return 'OBJ."
+ (if (or (numberp obj) (stringp obj)
+ (eq obj nil) (eq obj t) (keywordp obj))
+ obj
+ (list 'quote obj)))
+
+(defun ee-pp0q (obj)
+ "Like (ee-pp0 OBJ), but add a \"'\" in front if needed."
+ (ee-pp0 (ee-add-quote obj)))
+
+(defun ee-eeb-define-docstring
+ (eeb-fun fun sdelim edelim flash-spec adjust extra-docs)
+ "Used internally by `ee-eeb-define' to generate the docstring."
+ (let ((args `(,eeb-fun ,fun ,sdelim ,edelim ,flash-spec ,adjust
+ ,@(if extra-docs (list extra-docs)))))
+ (format "Run `%S' on a delimited region around point.
+This is a wrapper function created by a sexp equivalent to first
+one below (see `eeb-define'). To inspect the code that it
+generates run the second sexp; and for an explanation of the
+parameters, and a for a way of experimenting with them, see
+`eeb-define-try'.\n
+ (eeb-define %s)
+ (find-eeb-define %s)%s"
+ fun
+ (mapconcat 'ee-pp0q args " ")
+ (mapconcat 'ee-pp0q args " ")
+ (if extra-docs (concat "\n\n" extra-docs) ""))))
+
+(defun ee-eeb-define
+ (eeb-fun fun sdelim &optional edelim flash-spec adjust extra-docs)
+ "See `eeb-define' and `eeb-define-try'.
+This function generates the code for defining EEB-FUN, as a string,
+and returns it without `read'ing or `eval'ing it. An example:\n
+ (find-estring (ee-eeb-define 'eev-bounded 'eev 'ee-delimiter-hash nil t t))"
+ (format
+ "(defun %S ()
+ %S
+ (interactive)
+ (setq eeb-defaults '%s)
+ (eeb-default-new))"
+ eeb-fun
+ (ee-eeb-define-docstring
+ eeb-fun fun sdelim edelim flash-spec adjust extra-docs)
+ (ee-pp0 (list fun sdelim edelim flash-spec adjust))))
+
+;; Tests:
+;; (find-eeb-define 'eev-bounded 'eev "\n#\n" nil t t)
+;; (find-eeb-define 'eev-bounded 'eev "\n#\n" nil t t "Example\nHere")
+;; (eeb-define 'eev-bounded 'eev "\n#\n" nil t t)
+;; (eeb-define 'eev-bounded 'eev "\n#\n" nil t t "Example\nHere")
+;; (eeb-define 'eev-bounded 'eev 'ee-delimiter-hash nil t t
"Example\nHere")
+;; (find-efunctiondescr 'eev-bounded)
+
+;; Note: the sexps in the docstring might come out wrong if they
+;; contain nasty unibyte characters (this is a known possible bug).
+
+(defun eeb-define
+ (eeb-fun fun sdelim &optional edelim flash-spec adjust extra-docs)
+ "Define EEB-FUN as a wrapper around FUN.
+Use the delimiters SDELIM and EDELIM to find the region around
+point where where FUN will operate; highlight the region using
+FLASH-SPEC and ADJUST. If you want to add an example or extra
+explanations to the docstring of EEB-FUN use EXTRA-DOCS.
+
+See `eeb-define-try' for a detailed explanation of the parameters
+and for a way of experimenting with them; see `find-eeb-define'
+for a way to inspect to wrapper code."
+ (eval (read (ee-eeb-define
+ eeb-fun
+ fun sdelim edelim
+ flash-spec adjust extra-docs))))
+
+(defun find-eeb-define (&rest rest)
+ (find-estring (apply 'ee-eeb-define rest))
+ (emacs-lisp-mode))
+
+
+(defun eeb-define-try
+ (eeb-fun fun sdelim &optional edelim flash-spec adjust extra-docs)
+"This is similar to `eeb-define', but instead of defining EEB-FUN run it now.
+The \"default action over bounded regions\" is determined by the
+five entries in the list stored in the variable `eeb-defaults'
+\(described below). All the \"bounded functions\", like
+`eev-bounded', work by setting the variable `eeb-defaults' and
+then calling the function `eeb-default-new', that interprets the
+entries in `eeb-defaults' in a certain way and acts accordingly.
+
+
+eeb-define
+==========
+Bounded functions like `eev-bounded' are defined by calling the
+function `eeb-define' with the name of the function to define and
+the five entries for the associated value for `eeb-defaults',
+like this:
+
+ (eeb-define 'eev-bounded 'eev 'ee-delimiter-hash nil t t)
+
+`eeb-define-try' provides a nice way to test how functions
+defined by `eeb-define' would behave after they are defined.
+`eeb-define-try' expects the same arguments as `eeb-define', but
+it ignores the first one - EEB-FUN -, and instead of defining a
+function EEB-FUN that would set `eeb-defaults' and run
+`eeb-default', it sets `eeb-defaults' immediately (temporarily,
+using `let') and runs `eeb-default' on that.
+
+
+eeb-defaults and eeb-default
+============================
+The variable `eeb-defaults' always holds a list of this form:
+
+ (FUN SDELIM EDELIM FLASH-SPEC ADJUST)
+
+where:
+ FUN is a function taking arguments \"s\" and \"e\", like `eev',
+ SDELIM is the starting delimiter (see `ee-edelim-adjust'),
+ EDELIM is the ending delimiter (default: same as sdelim),
+ FLASH-SPEC tells how to highlight the region (see `eeflash-new'),
+ ADJUST should usually be t; see `ee-edelim-adjust'.
+
+The \"default action on a delimited region\" is always something
+composed of two \"standard actions\": first, highlight the region
+temporarily, as described below; second, and most important, run
+\"(FUN s e)\" on the region. FLASH-SPEC and ADJUST are only used
+for the highlighting part; FUN is only used for the \"run (FUN s
+e)\" part.
+
+A nil at EDELIM means to use EDELIM := SDELIM; after
+replacing the possible nil at EDELIM both SDELIM and
+EDELIM are \"expanded\" with `ee-symbol-value' if their
+values are symbols, and the results must be strings. Those
+resulting strings are used as region delimiters by
+`ee-sdelim-to-s' and `ee-edelim-to-e' to produce the \"s\" and
+\"e\" arguments for the \"(FUN s e)\" call; see the documentation
+for `ee-edelim-adjust' for an example that also shows how
+ADJUST affects the highlighting.
+
+A t at FLASH-SPEC means to use `eeflash-default' as FLASH-SPEC;
+after treating the `t' case the value of FLASH-SPEC is
+\"expanded\" with `ee-symbol-value' if it's a symbol, and the
+result - that should be either nil or a list of the form \"(face
+duration)\" - becomes temporarily the value of `ee-flash-spec',
+and we invoke `eeflash-new' to highlight the region.
+
+
+Examples
+========
+Here are some demos:\n
+#.
+# (eeb-define-try nil 'list \"\\n#.\\n\" nil t t)
+# (eeb-define-try nil 'ee-se-to-string \"\\n#.\\n\" nil t t)
+# (eeb-define-try nil 'eeflash-new \"\\n#.\\n\" nil t t)
+# (eeb-define-try nil 'eev \"\\n#.\\n\" nil t t)
+echo $[1+2]
+#.\n"
+ (let ((eeb-defaults (list fun sdelim edelim flash-spec adjust)))
+ (eeb-default-new)))
+
+)
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; no-byte-compile: t
+;; End:
diff --git a/eev-brxxx.el b/eev-brxxx.el
new file mode 100644
index 0000000..e189efd
--- /dev/null
+++ b/eev-brxxx.el
@@ -0,0 +1,282 @@
+;;; eev-brxxx.el -- define families of browse-url-like functions.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013mar06
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-brxxx.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-brxxx.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-psne-intro.html>
+;; <http://angg.twu.net/eev-intros/find-brxxx-intro.html>
+;; (find-eev-intro)
+;; (find-psne-intro)
+;; (find-brxxx-intro)
+
+;;; Commentary:
+
+(require 'eev-code) ; (find-eev "eev-code.el")
+
+(autoload 'browse-url-interactive-arg "browse-url")
+
+
+
+
+;;; _
+;;; ___ ___ _ ____ _____ _ __ ___(_) ___ _ __ ___
+;;; / __/ _ \| '_ \ \ / / _ \ '__/ __| |/ _ \| '_ \/ __|
+;;; | (_| (_) | | | \ V / __/ | \__ \ | (_) | | | \__ \
+;;; \___\___/|_| |_|\_/ \___|_| |___/_|\___/|_| |_|___/
+;;;
+;; See: (find-brxxx-intro)
+
+;; Here we define some conversion functions that are used by
+;; `code-brurl' and `code-brfile'.
+;;
+;; The `brxxx' functions call the conversion functions defined below,
+;; that convert between four kinds of strings: "dired", "url",
+;; "fname", and "local-url". The table below explains which function
+;; does what; note that "<$S>" means the expansion of "$S", and that
+;; if the point is on the file name "b" in a dired buffer visiting the
+;; directory "/foo/bar" then `(ee-dired-to-fname)' returns
+;; "/foo/bar/b", not something that starts with "$S".
+;;
+;; dired url fname local-url
+;; "b" "/foo/bar/b" "file:///foo/bar/b"
+;; "http://a/b" "$S/http/a/b" "file:///<$S>/http/a/b"
+;; ==========================================================
+;; * (code-brurl _ :remote _)
+;; * |-----------------------------> * (code-brurl _ :local _)
+;; * |--------------------------------------> * (code-brurl _ :dired _)
+;;
+;; * |----------> * (code-brfile _ :local _)
+;; * |-------------------> * (code-brfile _ :dired _)
+;;
+;; * |----------> * ee-url-to-fname
+;; * |--------------> * ee-fname-to-url
+;; * |-----------------------------> * ee-url-to-local-url
+;; * |-------------------> * ee-dired-to-fname
+;; * |--------------------------------------> * ee-dired-to-url
+
+(defun ee-url-to-fname0 (url)
+ "Convert an url like http://foo/bar to a filename like $S/http/foo/bar."
+ (replace-regexp-in-string "^\\(https?\\|ftp\\)://" "$S/\\1/" url))
+
+(defun ee-url-to-fname (url)
+ "Convert an url like http://foo/bar to a filename like <$S>/http/foo/bar.
+\(The \"<$S>\" above means the expansion of \"$S\"; see `ee-expand')."
+ (ee-expand (ee-url-to-fname0 url)))
+
+(defun ee-fname-to-url (fname)
+ "Convert a filename to a \"file://\" url (after running `ee-expand' on it)."
+ (concat "file://" (expand-file-name (ee-expand fname))))
+
+(defun ee-url-to-local-url (url)
+ "Convert a url like http://foo/bar to a url like file://<$S>/http/foo/bar.
+This should be made smarter - file:// urls should be returned unchanged."
+ ;; Add comments about psne and the snarf directory
+ (ee-fname-to-url (ee-url-to-fname url)))
+
+(defun ee-dired-to-fname (&optional no-error-if-not-filep)
+ "Convert the file name at point (in dired mode) to an absolute file name."
+ (if (eq major-mode 'dired-mode)
+ (file-name-sans-versions (dired-get-filename nil no-error-if-not-filep)
t)
+ (error "Not in dired mode")))
+
+(defun ee-dired-to-url (&optional no-error-if-not-filep)
+"Convert the file name at point (in dired mode) to a url like file://<$S>/___."
+ (ee-fname-to-url (ee-dired-to-fname no-error-if-not-filep)))
+
+
+
+
+;;; _ _ _
+;;; ___ ___ __| | ___ | |__ _ __ _ _ _ __| |
+;;; / __/ _ \ / _` |/ _ \_____| '_ \| '__| | | | '__| |
+;;; | (_| (_) | (_| | __/_____| |_) | | | |_| | | | |
+;;; \___\___/ \__,_|\___| |_.__/|_| \__,_|_| |_|
+;;;
+;; (find-tail-call-links "brurl" "f")
+
+;; code-brurl: top-level functions
+;;
+(defun code-brurl (f &rest rest)
+ "Define a family of brxxx functions from a function that operates on URLs"
+ (eval (ee-read (apply 'ee-code-brurl f rest))))
+(defun find-code-brurl (f &rest rest)
+ (find-estring-elisp (apply 'ee-code-brurl f rest)))
+(defun ee-code-brurl (f &rest rest)
+"Generate code for a family of functions from a function that operates on URLs"
+ (concat (ee-template0 "\
+") (ee-code-brurl-rest rest)))
+
+;; Support for extra arguments
+;;
+(defun ee-code-brurl-rest (rest)
+ (ee-tail-call "ee-code-brurl-%S" rest))
+
+(defun ee-code-brurl-:remote (brxxx &rest rest)
+ (concat (ee-template0 "
+\(defun {brxxx} (url &rest ignore)
+ \"Apply `{f}' on URL.\"
+ (interactive (browse-url-interactive-arg \"URL: \"))
+ (setq browse-url-browser-function '{brxxx})
+ (message \"(%S %S) -> %S\" '{f} url
+ ({f} url)))
+") (ee-code-brurl-rest rest)))
+
+(defun ee-code-brurl-:local (brxxxl &rest rest)
+ (concat (ee-template0 "
+\(defun {brxxxl} (url &rest ignore)
+ \"Apply `{f}' on the local url associated to URL.\"
+ (interactive (browse-url-interactive-arg \"URL: \"))
+ (setq browse-url-browser-function '{brxxxl})
+ (setq url (ee-url-to-local-url url))
+ (message \"(%S %S) -> %S\" '{f} url
+ ({f} url)))
+") (ee-code-brurl-rest rest)))
+
+(defun ee-code-brurl-:dired (brxxxd &rest rest)
+ (concat (ee-template0 "
+\(defun {brxxxd} (&rest ignore)
+ \"Apply `{f}' on the url of the dired file at point.\"
+ (interactive)
+ (let ((url (ee-dired-to-url)))
+ (message \"(%S %S) -> %S\" '{f} url
+ ({f} url))))
+") (ee-code-brurl-rest rest)))
+
+;; Test:
+;; (find-code-brurl 'pluc :remote 'brpluc :local 'brplucl :dired 'brplucd)
+;; (code-brurl 'pluc :remote 'brpluc :local 'brplucl :dired 'brplucd)
+;;
+;; (find-efunction 'find-brxxx-intro)
+;; (find-brxxx-intro "M-x brpluc")
+
+
+
+
+
+;;; _ _ __ _ _
+;;; ___ ___ __| | ___ | |__ _ __ / _(_) | ___
+;;; / __/ _ \ / _` |/ _ \_____| '_ \| '__| |_| | |/ _ \
+;;; | (_| (_) | (_| | __/_____| |_) | | | _| | | __/
+;;; \___\___/ \__,_|\___| |_.__/|_| |_| |_|_|\___|
+;;;
+;; (find-tail-call-links "brfile" "f")
+
+;; code-brfile: top-level functions
+;;
+(defun code-brfile (f &rest rest)
+ "Define a family of brxxx functions from a function that operates on files"
+ (eval (ee-read (apply 'ee-code-brfile f rest))))
+(defun find-code-brfile (f &rest rest)
+ (find-estring-elisp (apply 'ee-code-brfile f rest)))
+(defun ee-code-brfile (f &rest rest)
+"Generate code for a family of functions from a function that operates on
files"
+ (concat (ee-template0 "\
+") (ee-code-brfile-rest rest)))
+
+;; Support for extra arguments
+;;
+(defun ee-code-brfile-rest (rest)
+ (ee-tail-call "ee-code-brfile-%S" rest))
+
+(defun ee-code-brfile-:local (brxxxl &rest rest)
+ (concat (ee-template0 "
+\(defun {brxxxl} (url &rest ignore)
+ \"Apply `{f}' on the local file name associated to URL.\"
+ (interactive (browse-url-interactive-arg \"URL: \"))
+ (setq browse-url-browser-function '{brxxxl})
+ (let ((fname (ee-url-to-fname url)))
+ (message \"(%S %S) -> %S\" '{f} fname
+ ({f} fname))))
+") (ee-code-brfile-rest rest)))
+
+(defun ee-code-brfile-:dired (brxxxd &rest rest)
+ (concat (ee-template0 "
+\(defun {brxxxd} (&rest ignore)
+ \"Apply `{f}' on the dired file at point.\"
+ (interactive)
+ (let ((fname (ee-dired-to-fname)))
+ (message \"(%S %S) -> %S\" '{f} fname
+ ({f} fname))))
+") (ee-code-brfile-rest rest)))
+
+;; Tests:
+;; (find-code-brurl 'pluc :remote 'brpluc :local 'brplucl :dired 'brplucd)
+;; (find-code-brfile 'plic :local 'brplicl :dired 'brplicd)
+
+;; See:
+;; (find-eev "eev-blinks.el" "find-w3m")
+;; (find-efile "net/browse-url.el")
+
+(code-brurl 'find-psne-links
+ :remote 'brep)
+(code-brurl 'browse-url-firefox
+ :remote 'brm :local 'brml :dired 'brmd)
+(code-brurl 'find-googlechrome
+ :remote 'brg :local 'brgl :dired 'brgd)
+(code-brurl 'find-w3m
+ :remote 'brw :local 'brwl :dired 'brwd)
+
+(code-brfile 'find-fline :local 'brfl)
+
+
+
+(defun find-googlechrome (url) (find-bgprocess `("google-chrome" ,url)))
+
+
+;; These are defined elsewhere.
+;; (code-brfile 'find-xpdf-page :local 'brxpdfl :dired 'brxpdfd)
+;; (code-brfile 'find-evince-page :local 'brevincel :dired 'brevinced)
+;; (code-brfile 'find-xdvi-page :local 'brxdvil :dired 'brxdvid)
+;; (code-brfile 'find-pdf-text :local 'brpdftextl :dired 'brpdftextd)
+;; (code-brfile 'find-djvu-text :local 'brdjvutextl :dired 'brdjvutextd)
+;; See: (find-eev "eev-pdflike.el")
+
+;; These too...
+;; (code-brfile 'find-video :local 'brvideol :dired 'brvideod)
+;; (code-brfile 'find-audio :local 'braudiol :dired 'braudiod)
+;; See: (find-eev "eev-audiovideo.el")
+
+;; Some obsolete definitions (with the old syntax):
+;; (eeurl-define-from :fname->action: 'eecd :local: 'brcdl)
+;; (eeurl-define-from :url->action: 'eepsne :remote: 'brp)
+;; (eeurl-define-from :url->action: 'eetmpwget :remote: 'brtmpwget)
+
+;; (find-eevgrep "grep -nH -e brg *.el")
+
+
+
+
+(provide 'eev-brxxx)
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-channels.el b/eev-channels.el
new file mode 100644
index 0000000..4485a65
--- /dev/null
+++ b/eev-channels.el
@@ -0,0 +1,236 @@
+;;; eev-channels.el -- control external processes usign signals,
+;;; temporary files, and Expect scripts.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012dec27
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-channels.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-channels.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+;; TODO: import code from:
+;; (find-eevgrep "grep -nH -e channel *.el")
+;; (find-eev "anim/channels.anim")
+;; (find-eev "eechannel.el")
+
+
+(defun ee-read-file (fname)
+ (with-temp-buffer
+ (insert-file-contents fname)
+ (buffer-string)))
+
+
+
+
+
+
+;;; _ _
+;;; ___ ___ ___| |__ __ _ _ __ _ __ ___| |
+;;; / _ \/ _ \/ __| '_ \ / _` | '_ \| '_ \ / _ \ |
+;;; | __/ __/ (__| | | | (_| | | | | | | | __/ |
+;;; \___|\___|\___|_| |_|\__,_|_| |_|_| |_|\___|_|
+;;;
+;; (find-man "xterm" "-T string")
+;; (find-man "xterm" "-e program [ arguments ... ]")
+;; (find-eev "eegchannel")
+;; (find-eev "eegchannel" "pidfile")
+;; (find-eev "eegchannel" "strfile")
+;;
+;; There is a big diagram explaining how this works at:
+;;
+;; (find-eev "anim/channels.anim")
+;;
+;; Note that this is a "communication diagram" - it shows which
+;; programs start which other programs, and how they communicate.
+;; Here is a call diagram for the lisp functions (and some
+;; variables):
+;;
+;; <F9> ---> eechannel-this-line
+;; | \ (on "" lines)
+;; (on non-"" | v
+;; lines) | ee-eval-string
+;; v
+;; eechannel-send
+;; | | |
+;; | | v (sets)
+;; | v eechannel-default <------ eechannel
+;; v eechannel-strfile
+;; /---> eechannel-pid ----------> eechannel-pidfile
+;; |
+;; eechannel-kill
+
+(defvar eechannel-default nil)
+
+(defun eechannel-strfile (channel)
+ (ee-expand (format "$EEVTMPDIR/eeg.%s.str" channel)))
+
+(defun eechannel-pidfile (channel)
+ (ee-expand (format "$EEVTMPDIR/eeg.%s.pid" channel)))
+
+(defun eechannel-pid (channel)
+"Return the pid stored in the eeg.CHANNEL.pid file, as a string (or nil on
error)."
+ (let ((pidfile (eechannel-pidfile channel)))
+ (if (file-exists-p pidfile)
+ (ee-no-trailing-nl (ee-read-file pidfile)))))
+
+(defun eechannel-kill (channel sig)
+ "Send the signal SIG to the process listening on the channel CHANNEL."
+ ;; We call "kill" to send the signal.
+ (find-callprocess0 (format "kill %s %s" sig (eechannel-pid channel))))
+
+(defun eechannel-send (channel str)
+ "Send STR through channel CHANNEL (or through channel `eechannel-default')."
+ (setq channel (or channel eechannel-default))
+ (write-region str nil (eechannel-strfile channel))
+ (find-callprocess0 (format "kill -USR1 %s" (eechannel-pid channel))))
+
+(defun eechannel-this-line () (interactive)
+ "Send the current line through the channel `eechannel-default', and go down.
+If the line starts with a `' then evaluate it as lisp instead of sending it."
+ (let ((line (buffer-substring (ee-bol) (ee-eol)))) ; contents of this line
+ (if (string-match "^\\(.*\\)" line) ; lines with a red star
+ (ee-eval-string (match-string 1 line)) ; are eval'ed
+ (eechannel-send nil (concat line "\n"))) ; other lines are sent
+ (ee-next-line 1))) ; go down
+
+(defun eechannel (channel)
+ "Set the default channel to CHANNEL."
+ (interactive "sDefault channel: ")
+ (setq eechannel-default channel))
+
+
+
+
+;;; _ _
+;;; ___ ___ ___| |__ __ _ ___ ___ ___ _ __| |_
+;;; / _ \/ _ \/ __| '_ \ _____ / _` / __/ __|/ _ \ '__| __|
+;;; | __/ __/ (__| | | |_____| (_| \__ \__ \ __/ | | |_
+;;; \___|\___|\___|_| |_| \__,_|___/___/\___|_| \__|
+;;;
+
+(defun eechannel-pid-running-p (pid)
+ "Return t if a process with pid PID is running. This is linux-specific."
+ ;; I've heard the on BSDs "/proc" is optional and often disabled...
+ ;; Calling "ps" every time sounds expensive, what should I do?
+ (file-exists-p (format "/proc/%s" pid)))
+
+;; The six functions below are for when we want to use eegchannel
+;; directly, without calling it from an xterm (as in eexterm)...
+
+(defun eechannel-args-ne (channel prog-and-args)
+ `(,(ee-expand "$EEVDIR/eegchannel") ,channel
+ ,@(ee-split prog-and-args)))
+
+(defun eechannel-create-ne (channel prog-and-args)
+ (find-bgprocess-ne (eechannel-args-ne channel prog-and-args)))
+
+(defun eechannel-assert-ne (channel prog-and-args)
+ (let ((pid (eechannel-pid channel)))
+ (if (eechannel-pid-running-p (eechannel-pid channel))
+ (message "Channel %s (pid %s) looks alive, reusing" channel pid)
+ (eechannel-create-ne channel prog-and-args))))
+
+(defun eechannel-args (channel prog-and-args)
+ (eechannel-args-ne channel (ee-split-and-expand prog-and-args)))
+(defun eechannel-create (channel prog-and-args)
+ (eechannel-create-ne channel (ee-split-and-expand prog-and-args)))
+(defun eechannel-assert (channel prog-and-args)
+ (eechannel-assert-ne channel (ee-split-and-expand prog-and-args)))
+
+
+
+
+;;; _
+;;; ___ _____ _| |_ ___ _ __ _ __ ___
+;;; / _ \/ _ \ \/ / __/ _ \ '__| '_ ` _ \
+;;; | __/ __/> <| || __/ | | | | | | |
+;;; \___|\___/_/\_\\__\___|_| |_| |_| |_|
+;;;
+;; A call diagram:
+;;
+;; eexterm ---------> eexterm-ne
+;; | |
+;; | v
+;; | eechannel-pid-running-p
+;; v
+;; eexterm-create --> eexterm-create-ne
+;; |
+;; v
+;; eexterm-args ----> eexterm-args-ne
+;;
+;; eexterm-kill -----> eechannel-kill
+
+(defun eexterm-args-ne (channel prog-and-args xterm-args)
+"Return a list of arguments for running a xterm listening on CHANNEL.
+Try these examples:
+ (eexterm-args-ne \"A\" nil nil)
+ (eexterm-args-ne \"A\" '(\"ssh\" \"address@hidden") \"-geometry 80x20\")"
+ `("xterm"
+ "-T" ,(format "channel %s" channel)
+ ,@(ee-split xterm-args)
+ "-e" ,(ee-expand "$EEVDIR/eegchannel") ,channel
+ ,@(ee-split (or prog-and-args (ee-expand "$SHELL")))))
+
+(defun eexterm-create-ne (channel prog-and-args xterm-args)
+ "Start a xterm listening on CHANNEL. See `eexterm-args-ne'."
+ (find-bgprocess-ne (eexterm-args-ne channel prog-and-args xterm-args)))
+
+(defun eexterm-ne (channel prog-and-args xterm-args)
+"Set the default channel to CHANNEL; create an xterm listening on CHANNEL if
needed."
+ (interactive "sDefault channel: ")
+ (setq eechannel-default channel)
+ (if (eechannel-pid-running-p (eechannel-pid channel))
+ (message "Reusing xterm at channel %s" channel)
+ (eexterm-create-ne channel prog-and-args xterm-args)))
+
+(defun eexterm-args (channel &optional prog-and-args xterm-args)
+ (eexterm-args-ne channel (ee-split-and-expand prog-and-args) xterm-args))
+
+(defun eexterm-create (channel &optional prog-and-args xterm-args)
+ "Create an xterm listening on CHANNEL."
+ (eexterm-create-ne channel (ee-split-and-expand prog-and-args) xterm-args))
+
+(defun eexterm (channel &optional prog-and-args xterm-args)
+"Set the default channel to CHANNEL; create an xterm listening on CHANNEL if
needed."
+ (interactive "sDefault channel: ")
+ (eexterm-ne channel (ee-split-and-expand prog-and-args) xterm-args))
+
+(defalias 'eechannel-xterm 'eexterm)
+
+(defun eexterm-kill (&optional channel sig)
+ (interactive)
+ (eechannel-kill (or channel eechannel-default) (or sig "")))
+
+
+
+(provide 'eev-channels)
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; no-byte-compile: t
+;; End:
diff --git a/eev-code.el b/eev-code.el
new file mode 100644
index 0000000..7ca6f18
--- /dev/null
+++ b/eev-code.el
@@ -0,0 +1,298 @@
+;;; eev-code.el -- `code-c-d', that generates and evaluates Lisp defuns.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013jan07
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-code.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-code.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-code-c-d-intro.html>
+;; (find-eev-intro)
+;; (find-code-c-d-intro)
+
+;;; Commentary:
+
+
+
+
+;; A simple and flexible implementation of argument lists.
+;; Inspired by: (find-node "(cl)Argument Lists")
+;; (find-node "(cl)Argument Lists" "&body")
+;; See also: (find-elnode "Symbol Type" "`:'")
+;; (find-elnode "Constant Variables")
+;; The name "tail call" is misleading - this is recursive,
+;; but not a tail call in the usual sense.
+;;
+(defun ee-tail-call (fmt rest)
+ "An internal function used to support keyword-argument pairs."
+ (cond ((null rest) "")
+ ((keywordp (car rest))
+ (apply (intern (format fmt (car rest)))
+ (cdr rest)))
+ (t (error "Wrong rest: %S" rest))))
+
+
+
+;;; _ _ _
+;;; __ _| (_)___| |_ ___
+;;; / _` | | / __| __/ __|
+;;; | (_| | | \__ \ |_\__ \
+;;; \__,_|_|_|___/\__|___/
+;;;
+
+(defun ee-aref (alist idx)
+ "Like `aref', but for alists.
+Example: (ee-aref '((1 . one) (2 . two) (3 . three)) 2)
+ -> two"
+ (cdr (assoc idx alist)))
+
+(defun ee-adel (alist idx)
+ "Like `remq', but for alists. This is non-destructive, so wrap it in a setq.
+Example: (ee-adel '((1 . one) (2 . two) (3 . three)) 2)
+ -> ((1 . one) (3 . three))"
+ (remq (assoc idx alist) alist))
+
+(defun ee-aset (alist idx newelt)
+ "Like `aset', but for alists. This is non-destructive, so wrap it in a setq.
+Example: (ee-aset '((1 . one) (2 . two) (3 . three)) 2 'foo)
+ -> ((2 . foo) (1 . one) (3 . three))"
+ (cons (cons idx newelt) (ee-adel alist idx)))
+
+(defun ee-areplace (alist idx newelt)
+ "Like `ee-aset', but keeping the order.
+Examples: (ee-areplace '((1 . one) (2 . two) (3 . three)) 2 'foo)
+ -> ((1 . one) (2 . foo) (3 . three))
+ (ee-areplace '((1 . one) (2 . two) (3 . three)) 0 'zero)
+ -> ((0 . zero) (1 . one) (2 . two) (3 . three))"
+ (if (ee-aref alist idx)
+ (progn (setcdr (assoc idx alist) newelt)
+ alist)
+ (cons (cons idx newelt) alist)))
+
+;;; _ _ _
+;;; ___ ___ __| | ___ ___ __| | _ __ __ _(_)_ __ ___
+;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` |_____| '_ \ / _` | | '__/ __|
+;;; | (_| (_) | (_| | __/_____| (_|_____| (_| |_____| |_) | (_| | | | \__ \
+;;; \___\___/ \__,_|\___| \___| \__,_| | .__/ \__,_|_|_| |___/
+;;; |_|
+;; Old: (find-evardescr 'code-c-d-keywords)
+;; (find-evariable 'code-c-d-keywords)
+
+(defvar ee-code-c-d-pairs nil
+ "Each (code-c-d C D) call generates an entry (C (ee-expand D)) here.
+A new entry with the same C as a previous one will replace the
+previous one. This list is maintained by `ee-code-c-d-add-pair' and
+is used by some functions in \"eev-insert.el\".")
+
+(defun ee-code-c-d-add-pair (c d)
+ (setq ee-code-c-d-pairs (ee-areplace ee-code-c-d-pairs c (list d))))
+
+
+
+
+
+;;; _ _
+;;; ___ ___ __| | ___ ___ __| |
+;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` |
+;;; | (_| (_) | (_| | __/_____| (_|_____| (_| |
+;;; \___\___/ \__,_|\___| \___| \__,_|
+;;;
+;; See: (find-code-c-d-intro)
+
+;; code-c-d: top-level functions
+;;
+(defun code-c-d (c d &rest rest)
+ "See: (find-code-c-d-intro)
+Try this: (find-code-c-d \"CODE\" \"/DIR/\" :info \"INFO\")"
+ (ee-code-c-d-add-pair c d)
+ (eval (ee-read (apply 'ee-code-c-d c d rest))))
+(defun find-code-c-d (c d &rest rest)
+ (find-estring-elisp (apply 'ee-code-c-d c d rest)))
+(defun ee-code-c-d (c d &rest rest)
+ (if (stringp (car rest))
+ (setq rest (cons :info rest)))
+ (concat (ee-code-c-d-base c d)
+ (ee-code-c-d-rest rest)))
+
+;; Support for extra arguments
+;;
+(defun ee-code-c-d-rest (rest)
+ (ee-tail-call "ee-code-c-d-%S" rest))
+
+(defun ee-code-c-d-base (c d)
+ (ee-template0 "\
+ ;; {(ee-S `(find-code-c-d ,c ,d ,@rest))}
+ ;; {(ee-S `(ee-code-c-d-base ,c ,d))}
+ (setq ee-{c}dir \"{d}\")
+ (setq ee-{c}tagsfile \"{d}TAGS\")
+ (defun ee-{c}file (str)
+ (concat (ee-expand ee-{c}dir) str))
+ (defun ee-use-{c}-tags ()
+ (setq tags-file-name ee-{c}tagsfile))
+ (defun find-{c}file (str &rest pos-spec-list)
+ (interactive (list \"\"))
+ (ee-use-{c}-tags)
+ (apply 'find-fline (ee-{c}file str) pos-spec-list))
+ (defun find-{c}tag (str &rest pos-spec-list)
+ (ee-use-{c}-tags)
+ (apply 'ee-find-tag str pos-spec-list))
+ (defun find-{c}sh (command &rest pos-spec-list)
+ (apply 'ee-find-xxxsh ee-{c}dir command pos-spec-list))
+ (defun find-{c}sh0 (command)
+ (funcall 'ee-find-xxxsh0 ee-{c}dir command))
+ (defun find-{c}sh00 (command)
+ (funcall 'ee-find-xxxsh00 ee-{c}dir command))
+ (defun find-{c}w3m (furl &rest pos-spec-list)
+ (apply 'find-w3m (ee-{c}file furl) pos-spec-list))
+ (defun find-{c}grep (grep-command-args &rest pos-spec-list)
+ (apply 'ee-find-grep ee-{c}dir grep-command-args pos-spec-list))
+ "))
+
+(defun ee-code-c-d-:info (info &rest rest)
+ (concat (ee-template0 "
+ ;; {(ee-S `(ee-code-c-d-:info ,info ,@rest))}
+ (defun find-{c}node (page &rest pos-spec-list)
+ (interactive (list \"\"))
+ (setq ee-info-code \"{c}\") ;; for M-h M-i
+ (setq ee-info-file \"{info}\") ;; for M-h M-i
+ (apply 'find-node (format \"({info})%s\" page) pos-spec-list))
+ ") (ee-code-c-d-rest rest)))
+
+(defun ee-code-c-d-:linfo (manual &rest rest)
+ (concat (ee-template0 "
+ ;; {(ee-S `(ee-code-c-d-:linfo ,manual ,@rest))}
+ (defun find-{c}node (section &rest pos-spec-list)
+ (interactive (list \"\"))
+ (apply 'ee-find-node ee-{c}dir \"{manual}\" section pos-spec-list))
+ ") (ee-code-c-d-rest rest)))
+
+(defun ee-code-c-d-:gz (&rest rest)
+ (concat (ee-template0 "
+ ;; {(ee-S `(ee-code-c-d-:gz ,@rest))}
+ (defun find-{c}file (str &rest pos-spec-list)
+ (interactive (list \"\"))
+ (ee-use-{c}-tags)
+ (apply 'find-fline-gz (ee-{c}file str) pos-spec-list))
+ ") (ee-code-c-d-rest rest)))
+
+(defun ee-code-c-d-:anchor (&rest rest)
+ (concat (ee-template0 "
+ ;; {(ee-S `(ee-code-c-d-:anchor ,@rest))}
+ (defun find-{c} (str &rest pos-spec-list)
+ (apply 'find-anchor (ee-{c}file str) pos-spec-list))
+ ") (ee-code-c-d-rest rest)))
+
+(defun ee-code-c-d-:wget (url &rest rest)
+ (concat (ee-template0 "
+ ;; {(ee-S `(ee-code-c-d-:wget ,url ,@rest))}
+ (defun ee-{c}url (semiurl) (concat \"{url}\" semiurl))
+ (defun find-{c}wget (semiurl &rest pos-spec-list)
+ (interactive (list \"\"))
+ (apply 'find-wget (ee-{c}url semiurl) pos-spec-list))
+ ") (ee-code-c-d-rest rest)))
+
+(defun ee-code-c-d-:grep (&rest rest) (ee-code-c-d-rest rest)) ; compat
+
+;; support functions
+;;
+(defun ee-find-node (dir manual page &rest pos-spec-list)
+ (apply 'find-node (format "(%s%s)%s" dir manual page) pos-spec-list))
+
+(defun ee-find-grep (dir grep-command-args &rest pos-spec-list)
+ "Example: (ee-find-grep ee-eetcdir \"grep -niH -e tetris *\")
+Note: the POS-SPEC-LIST arguments are currently not used."
+ (let ((default-directory (ee-expand (or dir default-directory))))
+ (grep grep-command-args)))
+
+(defun ee-find-xxxsh (dir command &rest pos-spec-list)
+ "Run COMMAND at DIR and display the result. See `code-c-d'."
+ (apply 'find-sh (format "cd %s\n%s" dir command) pos-spec-list))
+
+(defun ee-find-xxxsh0 (dir command)
+ "Run COMMAND at DIR and return the result. See `code-c-d'."
+ (find-sh0 (format "cd %s\n%s" dir command)))
+
+(defun ee-find-xxxsh00 (dir command)
+ "Run COMMAND at DIR and return the result. See `code-c-d'."
+ (find-sh00 (format "cd %s\n%s" dir command)))
+
+(defun ee-find-tag (tag &rest pos-spec-list)
+ (let ((tags-add-tables nil))
+ (find-tag tag))
+ (ee-goto-rest pos-spec-list))
+
+;; a test
+;; (find-estring-elisp (ee-code-c-d-base "@@@" "!!!"))
+;; (find-estring-elisp (ee-code-c-d "CCC" "DDD"))
+
+
+
+;;; _ _
+;;; ___ ___ __| | ___ ___ __| |___
+;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` / __|
+;;; | (_| (_) | (_| | __/_____| (_|_____| (_| \__ \
+;;; \___\___/ \__,_|\___| \___| \__,_|___/
+;;;
+;; Some default `code-c-d's (debian-centric)
+
+(defun ee-locate-library (fname)
+ (if (locate-library fname)
+ (file-name-directory (locate-library fname))))
+(defvar ee-emacs-lisp-directory
+ (or (ee-locate-library "loadup.el")
+ (format "/usr/share/emacs/%d.%d/lisp/"
+ emacs-major-version emacs-minor-version)))
+(defvar ee-emacs-leim-directory
+ (or (ee-locate-library "leim-list.el")
+ (format "/usr/share/emacs/%d.%d/leim/"
+ emacs-major-version emacs-minor-version)))
+
+(code-c-d "e" ee-emacs-lisp-directory "emacs" :gz) ; (find-enode "Top")
+(code-c-d "el" ee-emacs-lisp-directory "elisp" :gz) ; (find-elnode "Top")
+(code-c-d "eli" ee-emacs-lisp-directory "eintr" :gz) ; (find-elinode "Top")
+(code-c-d "eleim" ee-emacs-leim-directory :gz)
+(code-c-d "equail" (ee-eleimfile "quail/") :gz)
+(code-c-d "eetc" data-directory :gz)
+
+(code-c-d "eev" (ee-locate-library "eev-code.el") :anchor) ; (find-eev "")
+
+;; (find-efile "")
+;; (find-equailfile "")
+;; (find-equailfile "latin-ltx.el")
+
+(code-c-d "ud" "/usr/share/doc/" :gz) ; (find-udfile "bash/")
+(code-c-d "vldi" "/var/lib/dpkg/info/") ; (find-vldifile "bash.list")
+
+
+
+(provide 'eev-code)
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-edit.el b/eev-edit.el
new file mode 100644
index 0000000..1f326cf
--- /dev/null
+++ b/eev-edit.el
@@ -0,0 +1,226 @@
+;;; eev-edit.el -- tools for editing (mainly refining) elisp hyperlinks.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012dec26
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-edit.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-edit.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+;; See:
+;; (find-eev-intro)
+;; (find-eval-intro)
+;; (find-eval-intro "Refining hyperlinks")
+;; (find-eevgrep "grep -niH -e m-- *.el")
+;; (find-angg ".emacs" "ee-shrink-hyperlink-at-eol")
+
+;; (find-eevfile "eev-mode.el" "Keys for editing hyperlinks:")
+;; (find-eevfile "eev-insert.el" "defun ee-ill")
+;; (find-eevgrep "grep -nH -e duplicate *.el")
+
+
+
+;;; _ _ _ _
+;;; __| |_ _ _ __ | (_) ___ __ _| |_ ___
+;;; / _` | | | | '_ \| | |/ __/ _` | __/ _ \
+;;; | (_| | |_| | |_) | | | (_| (_| | || __/
+;;; \__,_|\__,_| .__/|_|_|\___\__,_|\__\___|
+;;; |_|
+
+(define-key eev-mode-map "\M-h\M-2" 'ee-duplicate-this-line)
+
+(defun ee-duplicate-this-line ()
+ "Duplicate the current line (without any changes to the kill ring)."
+ (interactive)
+ (let ((line (buffer-substring (ee-bol) (ee-eol))))
+ (save-excursion (beginning-of-line) (insert-before-markers line "\n"))))
+
+;;; _
+;;; _ _ __ _ _ __ | | __
+;;; | | | |/ _` | '_ \| |/ /
+;;; | |_| | (_| | | | | <
+;;; \__, |\__,_|_| |_|_|\_\
+;;; |___/
+
+(define-key eev-mode-map "\M-h\M-y" 'ee-yank-pos-spec)
+
+(defun ee-yank-pos-spec ()
+ "Append the top of the kill ring to a hyperlink sexp, as a Lisp string.
+This command is useful for \"refining elisp hyperlinks\" by adding a
+pos-spec argument to them. Here's an example; if you are using the
+default `eev-mode-map' keybindings then
+
+ `M-h M-i' runs `find-einfo-links',
+ `M-h M-2' runs `ee-duplicate-this-line', and
+ `M-h M-y' runs `ee-yank-pos-spec'.
+
+Suppose that you are visiting the info node below,
+
+ (find-enode \"Lisp Eval\")
+
+and you find some interesting information in that page, close to
+an occurrence of the string \"`defvar'\". You mark that string,
+add it to the kill-ring with `M-w', then type `M-h M-i', go to
+the line that contains
+
+ # (find-enode \"Lisp Eval\")
+
+and then you type `M-h M-2 M-h M-y'; it becomes these two lines:
+
+ # (find-enode \"Lisp Eval\")
+ # (find-enode \"Lisp Eval\" \"`defvar'\")
+
+Now you check that the second line points to where you wanted,
+and you copy that hyperlink to a more permanent place."
+ (interactive)
+ (goto-char (1- (point-at-eol))) ; put point before the ")"
+ (insert " " (ee-pp0 (ee-last-kill)))) ; insert pos-spec
+
+
+
+;;; _ _ _
+;;; ___| |__ _ __(_)_ __ | | __
+;;; / __| '_ \| '__| | '_ \| |/ /
+;;; \__ \ | | | | | | | | | <
+;;; |___/_| |_|_| |_|_| |_|_|\_\
+;;;
+;; �ee-shrink-hyperlink-at-eol� (to ".ee-shrink-hyperlink-at-eol")
+;;
+(define-key eev-mode-map "\M-h\M--" 'ee-shrink-hyperlink-at-eol)
+
+(defun ee-shrink-sexp (sexp)
+ "If the car of SEXP of the form `find-xxxfile', reduce it to `find-xxx'."
+ (if (eq (car sexp) 'find-esfile)
+ `(find-es ,(substring (nth 1 sexp) 0 -2) ,@(cddr sexp))
+ (let* ((headname (symbol-name (car sexp)))
+ (last4chars (substring headname -4))
+ (-last4chars (substring headname 0 -4)))
+ (if (equal last4chars "file")
+ `(,(intern -last4chars) ,@(cdr sexp))))))
+
+(defun ee-shrink-hyperlink-at-eol ()
+ (interactive)
+ (end-of-line)
+ (let* ((beg (save-excursion (ee-backward-sexp)))
+ (sexp (read (buffer-substring beg (point))))
+ (shrunksexp (ee-shrink-sexp sexp)))
+ (when shrunksexp
+ (delete-region beg (point))
+ (insert (ee-pp0 shrunksexp)))))
+
+
+
+;;; __ _ _
+;;; / _| (_)_ __ _ __ ___ _ __ ___
+;;; | |_| | | '_ \ _____| '_ \/ __| '_ \ / _ \
+;;; | _| | | |_) |_____| |_) \__ \ | | | __/
+;;; |_| |_|_| .__/ | .__/|___/_| |_|\___|
+;;; |_| |_|
+
+;; (find-efunctiondescr 'eemklinks-yank-pos-spec)
+;; (find-eevfile "eev-insert.el" "defun ee-ill")
+
+(define-key eev-mode-map "\M-s" 'ee-flip-psne-ness)
+
+(defun ee-flip-psne-ness ()
+ (interactive)
+ (if (search-forward-regexp
"\\$S/\\(https?\\|ftp\\)/\\|\\(https?\\|ftp\\)://")
+ (cond ((match-string 1) (replace-match "\\1://"))
+ ((match-string 2) (replace-match "$S/\\2/")))))
+
+
+
+
+
+
+;;; _ _ _ _ _ _ _ _
+;;; __ _| | __| (_) | (_)___| |_ | (_)_ __ ___
+;;; \ \ / / |/ _` | |_____| | / __| __|____| | | '_ \ / _ \
+;;; \ V /| | (_| | |_____| | \__ \ ||_____| | | | | | __/
+;;; \_/ |_|\__,_|_| |_|_|___/\__| |_|_|_| |_|\___|
+;;;
+;; This is a hack.
+;;
+;; In a Debian system, for each installed package named xxxx there is
+;; an associated file, at /var/lib/dpkg/info/xxxx.list - let's call
+;; that the "vldi list" associated to the package xxxx - that lists
+;; all the files installed by that package...
+;;
+;; To convert a vldi list to hyperlinks, copy it to a read-write
+;; buffer and run M-I on each of its lines. More details later - this
+;; is a hack. =\
+;;
+;; (find-eev "eev-insert.el" "ee-ill")
+;;
+;; M-I: vldi-list-line
+(define-key eev-mode-map "\M-I" 'eewrap-vldi-list-line)
+
+(defun eewrap-vldi-list-line () (interactive)
+ "Convert a filename at the current line into a hyperlink, and go down.
+Supports `find-man', `find-udfile', and `find-fline' hyperlinks.
+This function recognizes lines containing directory names, and
+handles them in the following way: if the current line contains a
+directory name, say, /foo/bar, and the next line contains the
+name of a file or a directory in /foo/bar, say, /foo/bar/plic,
+then just delete the current line."
+ (beginning-of-line)
+ (if (looking-at "^\\(.*\\)\n\\1/") ; a directory
+ (delete-region (point) (progn (ee-next-line 1) (point)))
+ (ee-this-line-wrapn 1 'ee-wrap-vldi-list-line)))
+
+(defun ee-wrap-vldi-list-line (line)
+ "An internal function used by `eewrap-vldi-list-line'."
+ (if (string-match "^.*/man./\\([^/]+\\)\\.\\([0-9A-Za-z]+\\)\\.gz$" line)
+ (format "%s(find-man \"%s %s\")"
+ ee-H (match-string 2 line) (match-string 1 line))
+ (if (string-match "^/usr/share/doc/\\(.*\\)$" line)
+ (format "%s(find-udfile \"%s\")" ee-H (match-string 1 line))
+ (format "%s(find-fline \"%s\")" ee-H line))))
+
+;; (find-vldifile "bash.list")
+
+
+
+
+
+
+
+
+
+(provide 'eev-edit)
+
+
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-elinks.el b/eev-elinks.el
new file mode 100644
index 0000000..5098f9d
--- /dev/null
+++ b/eev-elinks.el
@@ -0,0 +1,906 @@
+;;; eev-elinks.el --- `find-efunction-links' and other `find-e*-links'
+
+;; Copyright (C) 2012,2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug19
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-elinks.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-elinks.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-links-intro.html>
+;; (find-eev-intro)
+;; (find-links-intro)
+
+;;; Commentary:
+
+;; See this for a (rough) classification of eev's hyperlink functions
+;; into several classes:
+;;
+;; (find-links-intro "Basic and non-basic hyperlinks")
+;;
+;; In this file we define `find-elinks' and several functions based on
+;; it which generate relatively simple elisp hyperlinks buffers -
+;; buffers which are mostly composed of elisp hyperlinks.
+;;
+;; The "more complex" `find-elinks'-based functions are the ones which
+;; use `ee-template0'. They are defined here:
+;;
+;; (find-eevfile "eev-tlinks.el")
+;;
+;; Here's one example of each function in this file:
+;; [to be done]
+
+
+
+
+;; �.find-elinks� (to "find-elinks")
+;; �.find-efunction-links� (to "find-efunction-links")
+;; �.find-evariable-links� (to "find-evariable-links")
+;; �.find-ekey-links� (to "find-ekey-links")
+;; �.find-elongkey-links� (to "find-elongkey-links")
+;; �.find-einfo-links� (to "find-einfo-links")
+
+;; �.ee-code-c-d-pairs-eval� (to "ee-code-c-d-pairs-eval")
+;; �.ee-find-xxxfile-sexps� (to "ee-find-xxxfile-sexps")
+;; �.find-file-links� (to "find-file-links")
+;; �.find-grep-links� (to "find-grep-links")
+;; �.find-ekbmacro-links� (to "find-ekbmacro-links")
+;; �.find-pdflike-page-links� (to "find-pdflike-page-links")
+;; �.ee-hyperlink-prefix� (to "ee-hyperlink-prefix")
+;; �.find-color-links� (to "find-color-links")
+
+
+
+
+
+
+
+;;; _ _ _
+;;; __ _ _ __ ___ _ _ _ __ __| | _ __ ___ (_)_ __ | |_
+;;; / _` | '__/ _ \| | | | '_ \ / _` |_____| '_ \ / _ \| | '_ \| __|
+;;; | (_| | | | (_) | |_| | | | | (_| |_____| |_) | (_) | | | | | |_
+;;; \__,_|_| \___/ \__,_|_| |_|\__,_| | .__/ \___/|_|_| |_|\__|
+;;; |_|
+
+;; (find-eapropos "around-point")
+
+;; (find-elnode "Index" "* thing-at-point:")
+;; (find-efunction 'thing-at-point)
+;; (find-efile "thingatpt.el")
+
+(defun ee-stuff-around-point0 (chars)
+ (interactive "MChars: \np") ; for tests
+ (save-excursion
+ (let* ((e (progn (skip-chars-forward chars) (point)))
+ (s (progn (skip-chars-backward chars) (point))))
+ (buffer-substring s e))))
+
+(defun ee-stuff-around-point (chars)
+ (interactive "MChars: \np") ; for tests
+ (ee-no-properties (ee-stuff-around-point0 chars)))
+
+(defun ee-debpkgname-around-point ()
+"Return the name of the Debian package around point.
+This function is not very smart."
+ (ee-stuff-around-point "a-z0-9-+."))
+
+(defun ee-debpkgname-ask (&optional prompt)
+"Ask for the name of a Debian package; the default is the debpkgname at point."
+ (read-string (or prompt "Debian package name: ")
+ (ee-debpkgname-around-point)))
+
+(defun ee-manpagename-around-point ()
+"Return the manpagename around point.
+This function is not very smart - it doesn't understand section names."
+ (interactive)
+ (ee-stuff-around-point "A-Za-z0-9-+_:."))
+
+(defun ee-manpagename-ask (&optional prompt)
+"Ask for the name of a manpage; the default is the manpage name at point."
+ (interactive)
+ (read-string (or prompt "Manpage: ")
+ (ee-manpagename-around-point)))
+
+
+
+
+;;; __ _ _ _ _ _
+;;; / _(_)_ __ __| | ___| (_)_ __ | | _____
+;;; | |_| | '_ \ / _` |_____ / _ \ | | '_ \| |/ / __|
+;;; | _| | | | | (_| |_____| __/ | | | | | <\__ \
+;;; |_| |_|_| |_|\__,_| \___|_|_|_| |_|_|\_\___/
+;;;
+;; �find-elinks� (to ".find-elinks")
+;; A test:
+;; (find-elinks '("a" nil (b c) (d "e")))
+
+(defun ee-remove-nils (list)
+ "Return a list like LIST, but without the `nil's."
+ (let (newlist)
+ (mapc (lambda (e) (if e (setq newlist (cons e newlist))))
+ list)
+ (nreverse newlist)))
+
+(defun ee-links-to-string0 (list)
+ "Convert a LIST of strings and sexps to a big string."
+ (mapconcat (lambda (o) (if (stringp o) o (ee-HS o)))
+ (ee-remove-nils list)
+ "\n"))
+
+(defun ee-links-to-string (list)
+ "Convert a LIST of strings and sexps to a big string (newline-terminated)."
+ (concat (ee-links-to-string0 list)
+ "\n"))
+
+(defun find-elinks (links &rest pos-spec-list)
+ "Visit a temporary buffer containing LINKS converted to hyperlink lines."
+ (let ((ee-buffer-name (or ee-buffer-name "*Elisp hyperlinks*")))
+ (apply 'find-estring (ee-links-to-string links) pos-spec-list)))
+
+(defun find-elinks-elisp (links &rest pos-spec-list)
+ "Visit a temporary buffer containing LINKS converted to hyperlink lines.
+The buffer is put in Emacs Lisp mode."
+ (let ((ee-buffer-name (or ee-buffer-name "*Elisp hyperlinks*"))
+ (ee-hyperlink-prefix ";; "))
+ (apply 'find-estring-elisp (ee-links-to-string links) pos-spec-list)))
+
+
+
+
+
+;;; __ _ _ __ _ _
+;;; / _(_)_ __ __| | ___ / _|_ _ _ __ ___| |_(_) ___ _ __
+;;; | |_| | '_ \ / _` |_____ / _ \ |_| | | | '_ \ / __| __| |/ _ \| '_ \
+;;; | _| | | | | (_| |_____| __/ _| |_| | | | | (__| |_| | (_) | | | |
+;;; |_| |_|_| |_|\__,_| \___|_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
+;;;
+;; �find-efunction-links� (to ".find-efunction-links")
+;; (find-find-links-links "\\M-f" "efunction" "f")
+;; A test: (find-efunction-links 'next-line)
+;; (eek "M-h M-f next-line")
+
+(define-key eev-mode-map "\M-h\M-f" 'find-efunction-links)
+
+(defun find-efunction-links (&optional f &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks related to the function F."
+ (interactive (find-function-read))
+ (apply 'find-elinks
+ `((find-efunction-links ',f ,@pos-spec-list)
+ ,@(ee-find-efunction-links f)
+ )
+ pos-spec-list))
+
+(defun ee-find-efunction-links (f)
+ "Return a list of hyperlinks for F (a function symbol).
+This is an internal function used by `find-efunction-links' and
+`find-ekey-links'."
+ `((where-is ',f)
+ (describe-function ',f)
+ (find-efunctiondescr ',f)
+ (find-efunction ',f)
+ (find-efunctionpp ',f)
+ (find-efunctiond ',f)
+ ;; (find-eCfunction ',f) ; obsolete
+ (find-estring (documentation ',f))
+ (find-estring (documentation ',f t))
+ (symbol-file ',f 'defun)
+ (find-fline (symbol-file ',f 'defun))
+ ""
+ ,@(if (commandp f)
+ `((Info-goto-emacs-command-node ',f)
+ (find-enode "Command Index" ,(format "* %S:" f))
+ ))
+ (find-elnode "Index" ,(format "* %S:" f))
+ ))
+
+
+
+;;; __ _ _ _ _ _
+;;; / _(_)_ __ __| | _____ ____ _ _ __(_) __ _| |__ | | ___
+;;; | |_| | '_ \ / _` |_____ / _ \ \ / / _` | '__| |/ _` | '_ \| |/ _ \
+;;; | _| | | | | (_| |_____| __/\ V / (_| | | | | (_| | |_) | | __/
+;;; |_| |_|_| |_|\__,_| \___| \_/ \__,_|_| |_|\__,_|_.__/|_|\___|
+;;;
+;; �find-evariable-links� (to ".find-evariable-links")
+;; (find-find-links-links "\\M-v" "evariable" "var")
+;; A test: (find-evariable-links 'line-move-visual)
+;; (eek "M-h M-v line-move-visual")
+
+(define-key eev-mode-map "\M-h\M-v" 'find-evariable-links)
+
+(defun find-evariable-links (var &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks for foo."
+ (interactive (find-function-read 'variable))
+ (apply 'find-elinks
+ `((find-evariable-links ',var ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ ,var
+ (describe-variable ',var)
+ (find-evardescr ',var)
+ (find-evariable ',var)
+ (find-epp ,var)
+ ""
+ (find-enode "Variable Index" ,(format "* %S:" var))
+ (find-elnode "Index" ,(format "* %S:" var))
+ )
+ pos-spec-list))
+
+
+;;; __ _ _ _
+;;; / _(_)_ __ __| | ___| | _____ _ _
+;;; | |_| | '_ \ / _` |_____ / _ \ |/ / _ \ | | |
+;;; | _| | | | | (_| |_____| __/ < __/ |_| |
+;;; |_| |_|_| |_|\__,_| \___|_|\_\___|\__, |
+;;; |___/
+;;
+;; �find-ekey-links� (to ".find-ekey-links")
+;; (find-find-links-links "\\M-k" "ekey" "key")
+;; A test: (find-ekey-links "\C-x2")
+;; (eek "M-h M-k C-x 2")
+(define-key eev-mode-map "\M-h\M-k" 'find-ekey-links)
+
+(defun ee-format-kbd-macro (key)
+ "Example: (ee-format-kbd-macro [down]) --> \"<down> ;; next-line\""
+ (replace-regexp-in-string "[ \t][ \t]+" " " (format-kbd-macro key t)))
+
+(defun find-ekey-links (key &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks related to the key sequence
KEY."
+ (interactive "kElisp hyperlinks for key: ")
+ (let ((longkey (format-kbd-macro key))
+ (longkey+ (ee-format-kbd-macro key))
+ (f (key-binding key)))
+ (apply 'find-elinks
+ `((find-ekey-links ,key ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-ekey-links ,key)
+ (eek ,(format "M-h M-k %s" longkey))
+ (eek ,(format "M-h M-k %s" longkey+))
+ ""
+ (find-elongkey-links ,longkey)
+ (find-elongkey-links ,longkey+)
+ (find-efunction-links ',f)
+ ""
+ ,@(ee-find-eboundkey-links key f)
+ )
+ pos-spec-list)))
+
+;; �find-elongkey-links� (to ".find-elongkey-links")
+;; A test: (find-elongkey-links "C-x 2")
+;; (eek "M-h M-k C-x 2")
+(defun find-elongkey-links (longkey &rest pos-spec-list)
+ "Like `find-ekey-links', but LONGKEY is a key sequence \"spelled out\".
+Example: (find-elongkey-links \"M-h M-k\")
+See `read-kbd-macro' and `edmacro-mode' for the format."
+ (interactive "sElisp hyperlinks for key (long format): ")
+ (let* ((key (read-kbd-macro longkey))
+ (f (key-binding key)))
+ (apply 'find-elinks
+ `((find-elongkey-links ,longkey)
+ (find-ekey-links ,key)
+ (find-efunction-links ',f)
+ ""
+ ,@(ee-find-eboundkey-links key f)
+ )
+ pos-spec-list)))
+
+(defun ee-find-eboundkey-links (key f)
+ "From KEY and its binding, F, produce a list of hyperlinks.
+This is an internal function used by `find-ekey-links' and
+`find-elongkey-links'."
+ `((where-is ',f)
+ (describe-function ',f)
+ (find-efunctiondescr ',f)
+ (find-efunction ',f)
+ (find-efunctionpp ',f)
+ (find-efunctiond ',f)
+ (find-estring (documentation ',f))
+ (find-estring (documentation ',f t))
+ ""
+ (describe-key ,key)
+ (describe-key-briefly ,key)
+ (find-ekeydescr ,key)
+ (Info-goto-emacs-key-command-node ,key)
+ (Info-goto-emacs-command-node ',f)
+ (find-enode "Command Index" ,(format "* %S:" f))
+ (find-elnode "Index" ,(format "* %S:" f))
+ ""
+ (key-description ,key)
+ (format-kbd-macro ,key)
+ (format-kbd-macro ,key t)
+ (ee-format-kbd-macro ,key)
+ (key-binding ,key)
+ ))
+
+
+
+
+
+
+;;; __ _ _ _ __
+;;; / _(_)_ __ __| | ___(_)_ __ / _| ___
+;;; | |_| | '_ \ / _` |_____ / _ \ | '_ \| |_ / _ \
+;;; | _| | | | | (_| |_____| __/ | | | | _| (_) |
+;;; |_| |_|_| |_|\__,_| \___|_|_| |_|_| \___/
+;;;
+;; �find-einfo-links� (to ".find-einfo-links")
+;; (find-find-links-links "\\M-i" "einfo" "")
+;; A test: (progn (find-enode "Lisp Eval") (find-einfo-links))
+;; (progn (find-enode "Lisp Eval") (eek "M-h M-i"))
+(define-key eev-mode-map "\M-h\M-i" 'find-einfo-links)
+
+(defvar ee-info-file "")
+
+(defun ee-infop () (get-buffer "*info*"))
+(defun ee-info-node () (with-current-buffer "*info*" Info-current-node))
+(defun ee-info-book+ () (with-current-buffer "*info*" Info-current-file))
+(defun ee-info-book- () (file-name-nondirectory (ee-info-book+)))
+(defun ee-info-file- () (file-name-nondirectory ee-info-file))
+(defun ee-info-shortp () (string= (ee-info-book-) (ee-info-file-)))
+(defun ee-info-shortf () (ee-intern "find-%snode" ee-info-code))
+(defun ee-info-fullnode () (format "(%s)%s" (ee-info-book-) (ee-info-node)))
+(defun ee-intro-stem (bufname)
+ (if (string-match "^\\*(find-\\(.*\\)-intro)\\*$" bufname)
+ (match-string 1 bufname)))
+
+;; A test: (ee-intro-stem "*(find-foo-intro)*")
+
+(defun find-einfo-links (&optional intro &rest rest)
+ "Visit a temporary buffer containing hyperlinks to the current info page.
+When possible, try to produce also a shorter hyperlink, like the last one in:
+ (info \"(bashref)Pipelines\")
+ (find-node \"(bashref)Pipelines\")
+ (find-bashnode \"Pipelines\")
+The hack for generating the shorter hyperlink uses the global
+variables `ee-info-code' and `ee-info-file' - see:
+ (progn
+ (find-code-c-d \"bash\" \"/usr/share/doc/bash/examples/\" \"bashref\")
+ (ee-goto-position \"ee-info-code\"))
+
+As an extra hack, if this function is called from a \"*(find-???-intro)*\"
+buffer, also generate a link to that buffer."
+ (interactive)
+ (setq intro (or intro (ee-intro-stem (buffer-name (current-buffer)))))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-einfo-links ,intro ,@rest)
+ ;; Body:
+ ""
+ ,@(if (ee-infop)
+ `((info ,(ee-info-fullnode))
+ (find-node ,(ee-info-fullnode))
+ ,(if (ee-info-shortp) (list (ee-info-shortf) (ee-info-node)))
+ )
+ '("[No \"*info*\" buffer]"))
+ ""
+ ,(if intro
+ (list (ee-intern "find-%s-intro" intro))
+ ;; else: "[Not invoked from a \"*find-xxx-intro*\" buffer]"
+ )
+ ) rest))
+
+
+
+
+;;; _ _ _
+;;; ___ ___ __| | ___ ___ __| | _ __ __ _(_)_ __ ___
+;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` |_____| '_ \ / _` | | '__/ __|
+;;; | (_| (_) | (_| | __/_____| (_|_____| (_| |_____| |_) | (_| | | | \__ \
+;;; \___\___/ \__,_|\___| \___| \__,_| | .__/ \__,_|_|_| |___/
+;;; |_|
+;;
+;; �ee-code-c-d-pairs-eval� (to ".ee-code-c-d-pairs-eval")
+
+(defun ee-filter (f list)
+ "Return the elements of LIST for which (F elt) is true.
+Actually return a list of `(F elt)'s."
+ (ee-remove-nils (mapcar f list)))
+
+(defun ee-prefixp (prefix str)
+ "Return t if STR begins with PREFIX."
+ (and (<= (length prefix) (length str))
+ (equal prefix (substring str 0 (length prefix)))))
+
+(defun ee-remove-prefix (prefix str)
+ "Example: (ee-remove-prefix \"ab\" \"abcde\") --> \"cde\""
+ (substring str (length prefix)))
+
+(defun ee-replace-prefix0 (prefix newprefix fname)
+ (if (ee-prefixp prefix fname)
+ (concat newprefix (ee-remove-prefix prefix fname))))
+
+(defun ee-replace-prefix (prefix newprefix fname)
+ (ee-replace-prefix0 (ee-expand prefix) newprefix (ee-expand fname)))
+
+(defun ee-intern (fmt &rest args)
+ (intern (apply 'format fmt args)))
+
+(defun ee-code-c-d-pairs-eval (fname code)
+ "For each entry (C D) in `ee-code-c-d-pairs' for which D is a prefix of
FNAME,
+evaluate f in the context of a big `let', and return the result."
+ (let ((efname (ee-expand fname)))
+ (ee-filter (lambda (c-d)
+ (let* ((c (car c-d))
+ (d (cadr c-d))
+ (ed (ee-expand d)))
+ (if (ee-prefixp ed efname)
+ (let ((fname- (ee-remove-prefix ed efname)))
+ (eval code)))))
+ ee-code-c-d-pairs)))
+
+;; �ee-find-xxxfile-sexps� (to ".ee-find-xxxfile-sexps")
+(defun ee-find-xxxfile-sexps (fname)
+ (ee-code-c-d-pairs-eval
+ fname
+ '(list (ee-intern "find-%sfile" c) fname-)))
+
+
+
+;;; __ _ _ __ _ _ _ _ _
+;;; / _(_)_ __ __| | / _(_) | ___ | (_)_ __ | | _____
+;;; | |_| | '_ \ / _` |_____| |_| | |/ _ \_____| | | '_ \| |/ / __|
+;;; | _| | | | | (_| |_____| _| | | __/_____| | | | | | <\__ \
+;;; |_| |_|_| |_|\__,_| |_| |_|_|\___| |_|_|_| |_|_|\_\___/
+;;;
+;; �find-file-links� (to ".find-file-links")
+;; (find-find-links-links "f" "file" "fname")
+;; A test: (find-file-links "~/tmp/foo")
+(define-key eev-mode-map "\M-hf" 'find-file-links)
+
+(defun ee-if-prefixp (d newd fname code)
+ "An internal function used by `find-file-links'."
+ (let* ((ed (ee-expand d))
+ (efname (ee-expand fname)))
+ (if (ee-prefixp ed efname)
+ (let* ((fname- (ee-remove-prefix ed efname))
+ (fname+ (concat newd fname-)))
+ (eval code)))))
+
+(defun ee-find-file-extra-links (fname) ())
+
+(defun find-file-links (fname &rest pos-spec-list)
+ (interactive (list (or (buffer-file-name) default-directory)))
+ (apply 'find-elinks
+ `((find-file-links ,fname ,@pos-spec-list)
+ ,(ee-if-prefixp "~/" "~/" fname '`(find-fline ,fname+))
+ ,(ee-if-prefixp "$S/http/" "http://" fname '(ee-H fname+))
+ ,(ee-if-prefixp "$S/shttp/" "shttp://" fname '(ee-H fname+))
+ ""
+ (find-file ,fname) ; non-refinable
+ (find-fline ,fname) ; refinable
+ ,@(ee-find-xxxfile-sexps (ee-expand fname))
+ ;;
+ ,@(ee-find-file-extra-links fname) ; customizable by the user
+ )
+ pos-spec-list))
+
+
+
+;;; __ _ _ _ _ _
+;;; / _(_)_ __ __| | __ _ _ __ ___ _ __ | (_)_ __ | | _____
+;;; | |_| | '_ \ / _` |_____ / _` | '__/ _ \ '_ \ _____| | | '_ \| |/ / __|
+;;; | _| | | | | (_| |_____| (_| | | | __/ |_) |_____| | | | | | <\__ \
+;;; |_| |_|_| |_|\__,_| \__, |_| \___| .__/ |_|_|_| |_|_|\_\___/
+;;; |___/ |_|
+;;
+;; �find-grep-links� (to ".find-grep-links")
+;; (find-find-links-links "\\M-g" "grep" "")
+;; Tests:
+;; (ee-find-grep-commands)
+;; (ee-find-grep-functions "~/eev-current/")
+;; (ee-find-grep-links '(find-agrep find-bgrep) '("grep a *" "grep b *"))
+;; (find-grep-links)
+;;
+(define-key eev-mode-map "\M-h\M-g" 'find-grep-links)
+
+(defun ee-first-n-elements (n list)
+ "Example: (ee-first-n-elements 2 '(a b c d e f)) ==> (a b)"
+ (if (and (> n 0) list)
+ (cons (car list)
+ (ee-first-n-elements (1- n) (cdr list)))))
+
+(defun ee-find-grep-functions (dir)
+ "An internal function used by `find-grep-links'."
+ (ee-code-c-d-pairs-eval dir '(ee-intern "find-%sgrep" c)))
+
+(defun ee-find-grep-commands ()
+ "An internal function used by `find-grep-links'."
+ (cons "grep -nH -e _ *" (ee-first-n-elements 4 grep-history)))
+
+(defun ee-find-grep-links (find-xxxgreps grep-commands)
+ "An internal function used by `find-grep-links'."
+ (let (result)
+ (dolist (head find-xxxgreps)
+ (dolist (command grep-commands)
+ (setq result (cons `(,head ,command) result))))
+ (nreverse result)))
+
+(defun find-grep-links (&rest pos-spec-list)
+"Visit a temporary buffer containing `find-xxxgrep' sexps."
+ (interactive)
+ (apply 'find-elinks
+ `((find-grep-links ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-grep-links)
+ ""
+ ,@(ee-find-grep-links
+ (ee-find-grep-functions default-directory)
+ (ee-find-grep-commands))
+ )
+ pos-spec-list))
+
+
+
+
+;;; __ _ _
+;;; / _(_)_ __ __| | _ __ ___ __ _ ___ _ __ ___
+;;; | |_| | '_ \ / _` |_____| '_ ` _ \ / _` |/ __| '__/ _ \
+;;; | _| | | | | (_| |_____| | | | | | (_| | (__| | | (_) |
+;;; |_| |_|_| |_|\__,_| |_| |_| |_|\__,_|\___|_| \___/
+;;;
+;; �find-ekbmacro-links� (to ".find-ekbmacro-links")
+;; (find-find-links-links "M" "macro" "")
+;; (find-efunction 'find-ekbmacro-links)
+
+(define-key eev-mode-map "\M-hM" 'find-ekbmacro-links)
+
+(defun find-ekbmacro-links () (interactive)
+ (find-elinks `(
+ (find-ekbmacro-links)
+ ""
+ (format-kbd-macro last-kbd-macro)
+ (setq last-kbd-macro (kbd ,(format-kbd-macro last-kbd-macro)))
+ ""
+ (find-enode "Keyboard Macros")
+ (find-enode "Edit Keyboard Macro")
+ (eek "M-h M-k C-x C-k C-e ;; kmacro-edit-macro-repeat")
+ (eek " C-x C-k C-e ;; kmacro-edit-macro-repeat")
+ (eek "M-h M-k C-x C-k l ;; kmacro-edit-lossage")
+ (eek " C-x C-k l ;; kmacro-edit-lossage")
+ )))
+
+
+
+;;; _ __ _ _ _
+;;; _ __ __| |/ _| (_) | _____ _ __ __ _ __ _ ___
+;;; | '_ \ / _` | |_| | | |/ / _ \_____| '_ \ / _` |/ _` |/ _ \
+;;; | |_) | (_| | _| | | < __/_____| |_) | (_| | (_| | __/
+;;; | .__/ \__,_|_| |_|_|_|\_\___| | .__/ \__,_|\__, |\___|
+;;; |_| |_| |___/
+
+;; �find-pdflike-page-links� (to ".find-pdflike-page-links")
+;; (find-efunction 'count-lines)
+;;
+(defun ee-count-formfeeds (start end)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region start end)
+ (goto-char (point-min))
+ (save-match-data
+ (let ((done 0))
+ (while (re-search-forward "[\f]" nil t 1)
+ (setq done (+ 1 done)))
+ done)))))
+
+(defun ee-current-page ()
+ (+ 1 (ee-count-formfeeds (point-min) (point))))
+
+(defun ee-last-kill ()
+ (if (stringp (car kill-ring))
+ (ee-no-properties (car kill-ring))))
+
+;; (find-find-links-links "\\M-p" "pdflike-page" "page bufname offset")
+
+(define-key eev-mode-map "\M-h\M-p" 'find-pdflike-page-links)
+
+(defun find-pdflike-page-links (&optional page bufname offset &rest rest)
+"Visit a temporary buffer containing hyperlinks to a pdf-like document.
+See: (find-pdf-like-intro)
+ (find-pdf-like-intro \"refining hyperlinks to pages\")"
+ (interactive)
+ (setq page (or page (ee-current-page)))
+ (setq bufname (or bufname (buffer-name)))
+ (setq offset (or offset ee-page-offset))
+ (let* ((c ee-page-c)
+ (fname ee-page-fname)
+ (find-cpage (ee-intern "find-%spage" c))
+ (find-ctext (ee-intern "find-%stext" c))
+ (kill (or (ee-last-kill) ""))
+ (page- (- page offset))
+ )
+ (apply 'find-elinks `(
+ (find-pdflike-page-links ,page ,bufname ,offset ,@rest)
+ (find-efunction 'find-pdflike-page-links)
+ ""
+ (,find-cpage ,page)
+ (,find-ctext ,page)
+ (,find-cpage (+ ,offset ,page-))
+ (,find-ctext (+ ,offset ,page-))
+ ""
+ (,find-cpage ,page ,kill)
+ (,find-ctext ,page ,kill)
+ (,find-cpage (+ ,offset ,page-) ,kill)
+ (,find-ctext (+ ,offset ,page-) ,kill)
+ ""
+ (code-pdf ,c ,fname)
+ (code-pdf-text ,c ,fname ,offset)
+ ,(ee-HS bufname)
+ ) rest)))
+
+;; (find-pdflike-page-links)
+;; (find-angg ".emacs.papers" "kopkadaly")
+;; (code-pdftotext "kopkadaly4"
"~/books/__comp/kopka_daly__a_guide_to_latex_4th_ed.pdf" 12)
+;; (find-code-pdftotext "kopkadaly4"
"~/books/__comp/kopka_daly__a_guide_to_latex_4th_ed.pdf" 12)
+;; (ee-page-parameters "kopkadaly4" 12)
+;; (find-kopkadaly4page (+ 12 287) "13.1 The picture environment")
+;; (find-kopkadaly4text "13.1 The picture environment")
+;; (find-kopkadaly4text)
+
+
+
+
+
+
+;;; _ _ _ _ __ _
+;;; | |__ _ _ _ __ ___ _ __| (_)_ __ | | __ _ __ _ __ ___ / _(_)_ __
+;;; | '_ \| | | | '_ \ / _ \ '__| | | '_ \| |/ /____| '_ \| '__/ _ \ |_| \ \/ /
+;;; | | | | |_| | |_) | __/ | | | | | | | <_____| |_) | | | __/ _| |> <
+;;; |_| |_|\__, | .__/ \___|_| |_|_|_| |_|_|\_\ | .__/|_| \___|_| |_/_/\_\
+;;; |___/|_| |_|
+;;
+;; �ee-hyperlink-prefix� (to ".ee-hyperlink-prefix")
+
+(defun ee-hyperlink-prefix ()
+ "A lispish interface for customizing the variable `ee-hyperlink-prefix'.
+See the comments in the source code."
+ (interactive)
+ (find-elinks
+ `((ee-hyperlink-prefix)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (setq ee-hyperlink-prefix ,ee-hyperlink-prefix) ; current value
+ ""
+ (setq ee-hyperlink-prefix "# ") ; other common values
+ (setq ee-hyperlink-prefix ";; ")
+ (setq ee-hyperlink-prefix "-- ")
+ (setq ee-hyperlink-prefix "// ")
+ (setq ee-hyperlink-prefix "% ")
+ )))
+
+
+
+;;; __ _ _ _ _ _ _
+;;; / _(_)_ __ __| | ___ ___ ___ | | ___ _ __ | (_)_ __ | | _____
+;;; | |_| | '_ \ / _` |____ / _ \/ __/ _ \| |/ _ \| '__|___| | | '_ \| |/ / __|
+;;; | _| | | | | (_| |____| __/ (_| (_) | | (_) | | |____| | | | | | <\__ \
+;;; |_| |_|_| |_|\__,_| \___|\___\___/|_|\___/|_| |_|_|_| |_|_|\_\___/
+;;;
+;; �find-color-links� (to ".find-color-links")
+;; (find-find-links-links "c" "color" "initialcolor")
+;; Tests:
+;; (find-ecolor-links)
+;; (find-ecolor-links "sienna")
+;;
+(define-key eev-mode-map "\M-hc" 'find-ecolor-links)
+
+(defun find-ecolor-links (&optional initialcolor &rest pos-spec-list)
+ "Visit a temporary buffer containing hyperlinks for the color INITIALCOLOR."
+ (interactive)
+ (setq initialcolor (or initialcolor "{initialcolor}"))
+ (apply 'find-elinks
+ `((find-color-links ,initialcolor ,@pos-spec-list)
+ ""
+ (find-ecolor-links (ee-color-choose-tk ,(or initialcolor "gray")))
+ (find-ecolor-links ,(or initialcolor "gray"))
+ (find-ecolors)
+ (find-ecolors ,initialcolor)
+ ,`(insert (propertize " Sample " 'face '(:background ,initialcolor)))
+ ,`(ee-color-values ,initialcolor)
+ (kill-new ,initialcolor)
+ (kill-new ,(ee-color-values initialcolor))
+ (find-efunction 'find-ecolor-links)
+ )
+ pos-spec-list))
+
+(defun ee-color-values (color)
+ "Return the #RRGGBB representation for COLOR."
+ (apply 'format "#%02x%02x%02x"
+ (mapcar (lambda (c) (lsh c -8)) (color-values color))))
+
+(defun ee-color-choose-tk (&optional initialcolor)
+ "Call Tcl/Tk to choose a color similar to INITIALCOLOR.
+This needs a temporary directory; see: (find-prepared-intro)"
+ (eetcl (format "puts [tk_chooseColor -initialcolor %s]; exit"
+ (or initialcolor "gray")))
+ (find-sh0 (format "wish %s" ee-file-tcl)))
+
+
+
+
+
+
+
+
+
+
+
+
+;; ------------------------------------------------------------
+;; Old stuff:
+
+;; The rest of this block of comments was cut & pasted straight from
+;; eev-insert.el, but most of what they say still hold...
+;;
+;; This is the ugliest part of eev's code. It's being rewritten. Even
+;; if work on it may seem stalled, it _is_ being rewritten. In some
+;; sense.
+;;
+;; I got tired of writing all my hyperlinks by hand, so I created
+;; these functions. The "new way of creating hyperlinks" (the first
+;; block of this file) adds the following key bindings to
+;; eev-mode-map:
+;;
+;; M-h M-k find-ekey-links
+;; M-h M-f find-efunction-links
+;; M-h M-v find-evariable-links
+;; M-h M-i find-einfo-links
+;; M-h M-d find-debpkg-links
+;; M-h f find-file-links
+;; M-h m find-last-manpage-links
+;; M-h M-m find-manpage-links
+;;
+;; All of them work similarly. For example: type M-h M-k RET, and
+;; `find-ekey-links' will create and display a buffer called "*Elisp
+;; hyperlinks*", like this:
+;;
+;; _____________________________________________________________
+;; |(find-ekey-links "\r") |
+;; |(find-elongkey-links "RET") |
+;; |(find-elongkey-links "RET ;; newline") |
+;; |"RET ;; newline" |
+;; | |
+;; |(where-is 'newline) |
+;; |(describe-function 'newline) |
+;; |(find-efunctiondescr 'newline) |
+;; |(find-efunction 'newline) |
+;; |(find-efunctionpp 'newline) |
+;; |(find-efunctiond 'newline) |
+;; |(find-eCfunction 'newline) |
+;; |(find-estring (documentation 'newline)) |
+;; |(find-estring (documentation 'newline t)) |
+;; | |
+;; |(describe-key "\r") |
+;; |(describe-key-briefly "\r") |
+;; |(find-ekeydescr "\r") |
+;; |(Info-goto-emacs-key-command-node "\r") |
+;; |(Info-goto-emacs-command-node 'newline) |
+;; |(find-enode "Command Index" "* newline:") |
+;; |(find-elnode "Index" "* newline:") |
+;; | |
+;; |(key-description "\r") |
+;; |(format-kbd-macro "\r") |
+;; |(format-kbd-macro "\r" t) |
+;; |(key-binding "\r") |
+;; | |
+;; | |
+;; | |
+;; |--:** *Elisp hyperlinks* All L28 (Fundamental)--------|
+;; |_____________________________________________________________|
+;;
+;;
+;; That is, a lot of hyperlinks pointing to interesting pieces of
+;; information about the key RET and the command (`newline') that is
+;; bound to it. Then you may follow these hyperlinks by evaluating the
+;; sexps or you may copy them to other files by copying their text.
+;;
+;; [To do: explain M-h M-y. There's an example in `eesteps' format in
+;; the NEWS file.]
+
+;; See: <http://angg.twu.net/eev-current/README.html>
+;; and: <http://angg.twu.net/eev-current/NEWS.html>
+
+;; The second part of this file contains some older functions that
+;; insert Elisp hyperlinks at the current buffer -- like `inn', that
+;; inserts a hyperlink to the info node currently being visited -- or
+;; transform text -- for example, a series of lines, each one
+;; containing the name of a Debian package -- into hyperliks.
+
+'(
+
+(defun ee-buffer-manpage-name (&optional bufname)
+ "Return the name of the manpage in the buffer BUFNAME, or nil if none.
+The default for BUFNAME is the name of the current buffer.
+This function does a simple string matching and converts \"*Man
+foo*\" to \"foo\"."
+ (if (null bufname)
+ (setq bufname (buffer-name)))
+ (and bufname
+ (string-match "^\\*\\(Wo\\)?Man \\(.*\\)\\*$" bufname)
+ (match-string 2 bufname)))
+
+(defun find-last-manpage-links (manpagename &rest rest)
+ "Visit a temporary buffer containing hyperlinks related to a manpage.
+Use this when you are in a manpage buffer and you want links to it."
+ (interactive (list (ee-buffer-manpage-name)))
+ (apply 'find-elinks
+ (list (ee-pph `(find-man-links ,manpagename))
+ ""
+ (ee-pph `(find-man ,manpagename)))
+ rest))
+
+(defun find-manpage-links (manpagename &rest rest)
+ "Visit a temporary buffer containing hyperlinks related to a manpage.
+Use this when point is over a manpage name and you want links to that page."
+ (interactive (list (ee-manpagename-ask)))
+ (apply 'find-elinks
+ (list (ee-pph `(find-man-links ,manpagename))
+ ""
+ (ee-pph `(find-man ,manpagename)))
+ rest))
+
+)
+
+;; Creating temporary buffers with lots of elisp hyperlinks is an idea
+;; that I only had relatively recently - in 2004, I think... before
+;; that I used some functions that either inserted hyperlinks into the
+;; current buffer or modified the text in the current buffer to
+;; produce hyperlinks. For example, `M-x inn' inserted a link to an
+;; info node, and `M-x dff' converted a line with the name of a debian
+;; package into three lines, each one with a hyperlink to something
+;; related to that debian package...
+
+
+
+
+
+
+;; TODO: move these functions to another file (eev-video.el?)
+;; (find-angg ".emacs" "mm:ss")
+;; (find-angg ".emacs" "find-mplayer")
+;; (find-angg ".emacs" "code-mplayer")
+
+;; (find-man "1 mplayer" " -ss ")
+;; (find-man "1 mplayer" " -fs ")
+;; (find-man "1 mplayer" " -osdlevel ")
+
+
+
+;; Tests:
+;; (find-upload-links "eev-current/eev-template.el")
+;; (find-download-links "" "" "eev-current/eev-template.el")
+;; (eevt-down "eev-current/" "emacs/eev/" "eev-template.el")
+;
+
+
+
+
+
+
+(provide 'eev-elinks)
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; no-byte-compile: t
+;; End:
diff --git a/eev-env.el b/eev-env.el
new file mode 100644
index 0000000..1db1e66
--- /dev/null
+++ b/eev-env.el
@@ -0,0 +1,86 @@
+;;; eev-env.el -- set some environment variables.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012nov02
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-env.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-env.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-psne-intro.html>
+;; <http://angg.twu.net/eev-intros/find-prepared-intro.html>
+;; (find-eev-intro)
+;; (find-psne-intro)
+;; (find-prepared-intro)
+
+;;; Commentary:
+
+;; Used by: (find-eev "eev-prepared.el")
+;;
+;; Related but obsolete files:
+;; <http://angg.twu.net/eev-current/README.html>
+;; <http://angg.twu.net/eev-current/eev-langs.el.html>
+;; <http://angg.twu.net/eev-current/eev-rctool.html>
+
+
+
+
+
+;;; ___ _ ____ __ __ ____ _ _ __ ___
+;;; / _ \ '_ \ \ / / \ \ / / _` | '__/ __|
+;;; | __/ | | \ V / \ V / (_| | | \__ \
+;;; \___|_| |_|\_/ \_/ \__,_|_| |___/
+;;;
+;;; Set some environment variables (for ee-expand, getenv,
+;;; shell buffers, xterms started from Emacs, etc).
+
+;; (find-eevrcfile ".bashrc")
+;; (find-eevrcfile ".zshrc")
+
+(defun ee-setenv (envvar value)
+ "In case the environment variable ENVVAR was not set set it to VALUE."
+ (if (null (getenv envvar))
+ (setenv envvar (ee-expand value))))
+
+(ee-setenv "S" "~/snarf") ; for `find-psne-links'
+
+;; Obsolete? See:
+;; (find-eev "eev-bounded.el")
+;; (find-eev "eev.el" "ee-setenv")
+(ee-setenv "EEVDIR"
+ (let ((fname (locate-library "eev")))
+ (if fname (directory-file-name (file-name-directory fname))
+ "~/eev-current"))) ; eev.el, etc
+
+(provide 'eev-env)
+
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-eval.el b/eev-eval.el
new file mode 100644
index 0000000..0fcb7fe
--- /dev/null
+++ b/eev-eval.el
@@ -0,0 +1,168 @@
+;;; eev.el -- variants of eval-last-sexp.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012dec29
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-eval.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-eval.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-eval-intro.html>
+;; (find-eev-intro)
+;; (find-eval-intro)
+
+;;; Commentary:
+
+
+(require 'eev-flash) ; (find-eev "eev-flash.el")
+
+
+
+;;; _ _
+;;; _____ ____ _| | ___ _____ ___ __ ___ ___ | |
+;;; / _ \ \ / / _` | |_____/ __|/ _ \ \/ / '_ \ _____ / _ \/ _ \| |
+;;; | __/\ V / (_| | |_____\__ \ __/> <| |_) |_____| __/ (_) | |
+;;; \___| \_/ \__,_|_| |___/\___/_/\_\ .__/ \___|\___/|_|
+;;; |_|
+;;;
+;;; evaluating sexps (alternatives to eval-last-sexp)
+;;;
+
+;; ee-eval-sexp-eol may be obsolete
+;; ee-arg is still used in eev-insert.el (ack!)
+
+;; See (find-efunction 'eval-last-sexp-1)
+(defun ee-backward-sexp ()
+ "An internal function used by `ee-eval-last-sexp'."
+ (interactive)
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ (forward-sexp -1)
+ (when (eq (preceding-char) ?\\)
+ (forward-char -1)
+ (when (eq (preceding-char) ??)
+ (forward-char -1))))
+ (point))
+
+(defun ee-forward-sexp ()
+ "An internal function used by `ee-eval-last-sexp'."
+ (interactive)
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ (forward-sexp 1))
+ (point))
+
+(defun ee-last-sexp ()
+ "An internal function used by `ee-eval-last-sexp'."
+ (save-excursion
+ (buffer-substring-no-properties
+ (ee-backward-sexp) (ee-forward-sexp))))
+
+(defmacro ee-no-debug (&rest body)
+ `(let ((debug-on-error nil)) ,@body))
+
+;; (defun ee-eval (sexp) (ee-no-debug (eval sexp)))
+
+(defun ee-eval-last-sexp-0 ()
+ "Highlight the sexp before point."
+ (save-excursion
+ (eeflash+ (ee-backward-sexp) (ee-forward-sexp)
+ ee-highlight-spec)))
+
+(defun ee-eval-last-sexp-2 ()
+ "Show the target of the sexp before point in another window."
+ (find-wset "1so_o" '(ee-eval-last-sexp)))
+
+(defun ee-eval-last-sexp-3 ()
+"Show the target of the sexp before point in another window, and switch to it."
+ (find-wset "1so_" '(ee-eval-last-sexp)))
+
+(defun ee-eval-last-sexp-4 ()
+ "Evaluate the sexp before point in debug mode."
+ (let ((sexp (read (ee-last-sexp))))
+ (debug)
+ (eval sexp)))
+
+(defun ee-eval-last-sexp-5 ()
+ "Evaluate the sexp before point with `debug-on-error' turned on."
+ (let ((sexp (read (ee-last-sexp)))
+ (debug-on-error t))
+ (eval sexp)))
+
+
+
+(defun ee-eval-last-sexp (&optional arg)
+ "By default, evaluate sexp before point, and print value in minibuffer.
+This is eev's variant of `eval-last-sexp', and it can behave in
+several different ways depending on the prefix argument ARG.
+If ARG is:
+ nil: evaluate the sexp with `debug-on-error' turned off
+ 0: highlight the sexp temporarily
+ 1: show the sexp as a string
+ 2: show the target of the sexp in another window
+ 3: same, but also switch to the new window
+ 4: evaluate the sexp in debug mode
+ 5: run the sexp with `debug-on-error' turned on
+ 8: eval then pretty-print the result in another buffer
+ 9: a hack for testing `call-interactively'"
+ (interactive "P")
+ (cond ((eq arg 0)
+ (save-excursion
+ (eeflash+ (ee-backward-sexp) (ee-forward-sexp)
+ ee-highlight-spec)))
+ ((eq arg 1) (prin1 (ee-last-sexp)))
+ ;; ((eq arg 2) (prin1 (read (ee-last-sexp))))
+ ;; ((eq arg 3) (ee-eval (read (ee-last-sexp))))
+ ((eq arg 2) (find-wset "1so_o" ' (ee-eval-last-sexp)))
+ ((eq arg 3) (find-wset "1so_" ' (ee-eval-last-sexp)))
+ ((eq arg 4) (let ((sexp (read (ee-last-sexp)))) (debug) (eval sexp)))
+ ((eq arg 5) (let ((sexp (read (ee-last-sexp)))
+ (debug-on-error t))
+ (eval sexp)))
+ ((eq arg 8) (find-epp (ee-eval (read (ee-last-sexp)))))
+ ((eq arg 9) (let ((interactive-clause (read (ee-last-sexp))))
+ (let ((debug-on-error nil))
+ (call-interactively
+ `(lambda (&rest args) ,interactive-clause
+ (message "%S" args))))))
+ (t (prin1 (let ((ee-arg arg))
+ (ee-eval (read (ee-last-sexp))))))))
+
+(defun ee-eval-sexp-eol (&optional arg)
+"Go to the end of line, then run `ee-eval-last-sexp'.
+See: (find-eval-intro)"
+ (interactive "P")
+ (end-of-line)
+ (ee-eval-last-sexp arg))
+
+
+
+(provide 'eev-eval)
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-flash.el b/eev-flash.el
new file mode 100644
index 0000000..f374854
--- /dev/null
+++ b/eev-flash.el
@@ -0,0 +1,97 @@
+;;; eev-flash.el -- functions to highlight a range of text temporarily.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012dec26
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-flash.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-flash.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-eval-intro.html>
+;; (find-eev-intro)
+;; (find-eval-intro "M-0 M-e")
+
+;; These functions are used by some variants of `ee-eval-last-sexp'
+;; (especially `M-0 M-e') and by `eev-bounded' and friends.
+;; (find-eev "eev-eval.el")
+;; (find-eev "eev-bounded.el")
+
+
+;; New version - with a `-' because it is non-interactive, and
+;; consequently an internal function.
+
+(defun ee-flash (start end &optional face duration)
+ "Highlight the region between START and END using FACE, for time DURATION."
+ (let ((ovl (make-overlay start end)))
+ (overlay-put ovl 'face (or face 'region))
+ (run-at-time (or duration 1) nil 'delete-overlay ovl)))
+
+
+
+
+;; The old code follows.
+;; To do: delete most of this, use just `ee-flash' instead.
+;; Drop the idea of flash-specs as lists.
+
+;; (setq eeb-highlight-spec '(highlight 0.2))
+(defvar ee-highlight-spec '(highlight 0.75)) ; to do: rename highlight->flash
+(defvar eeb-highlight-spec '(highlight 0.5))
+(defvar eek-highlight-spec '(region 0.75))
+(defvar eeflash-default '(highlight 0.5))
+
+
+;;; __ _ _
+;;; ___ ___ / _| | __ _ ___| |__
+;;; / _ \/ _ \ |_| |/ _` / __| '_ \
+;;; | __/ __/ _| | (_| \__ \ | | |
+;;; \___|\___|_| |_|\__,_|___/_| |_|
+;;;
+;;; temporary highlighting (flashing)
+;;;
+
+(defun eeflash (start end &optional face duration)
+ "Highlight the region between START and END using FACE, for time DURATION."
+ (let ((ovl (make-overlay start end)))
+ (overlay-put ovl 'face (or face 'region))
+ (run-at-time (or duration 1) nil 'delete-overlay ovl)))
+
+(defun eeflash+ (s &optional e spec add-to-e)
+ "Highlight the region between S and E; face and duration are taken from SPEC.
+This function only tries to do any work when S is a number and SPEC is non-nil.
+When SPEC is non-nil it should be a pair of the form (FACE DURATION).
+The argument ADD-TO-E is a hack for when we know that the region between S and
+E+1 ends with a newline and it looks nicer to highlight the newline too; then
+we set ADD-TO-E to 1."
+ (if (and (numberp s) spec)
+ (eeflash s (+ e (or add-to-e 0))
+ (car spec) (cadr spec)))
+ (list s e spec add-to-e))
+
+
+(provide 'eev-flash)
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; no-byte-compile: t
+;; End:
diff --git a/eev-intro.el b/eev-intro.el
new file mode 100644
index 0000000..1c0a599
--- /dev/null
+++ b/eev-intro.el
@@ -0,0 +1,4837 @@
+;;; eev-intro.el --- intro scripts for eev
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug18
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-intro.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-intro.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+;;
+;; To use this, simply execute any of the sexps below:
+;; (find-eev-intro)
+;; (find-eval-intro)
+;; (find-eepitch-intro)
+;; (find-wrap-intro)
+;; (find-code-c-d-intro)
+
+
+
+;; Quick index:
+;; �.find-eev-intro� (to "find-eev-intro")
+;; �.find-eval-intro� (to "find-eval-intro")
+;; �.find-eepitch-intro� (to "find-eepitch-intro")
+;; �.find-wrap-intro� (to "find-wrap-intro")
+;; �.find-links-intro� (to "find-links-intro")
+;; �.find-code-c-d-intro� (to "find-code-c-d-intro")
+;; �.find-psne-intro� (to "find-psne-intro")
+;; �.find-brxxx-intro� (to "find-brxxx-intro")
+;; �.find-eejump-intro� (to "find-eejump-intro")
+;; �.find-pdf-like-intro� (to "find-pdf-like-intro")
+;; �.find-audiovideo-intro� (to "find-audiovideo-intro")
+;; �.find-multiwindow-intro� (to "find-multiwindow-intro")
+;; �.find-rcirc-intro� (to "find-rcirc-intro")
+;; �.find-templates-intro� (to "find-templates-intro")
+;; �.find-anchors-intro� (to "find-anchors-intro")
+;; �.find-prepared-intro� (to "find-prepared-intro")
+;; �.find-bounded-intro� (to "find-bounded-intro")
+;; �.find-channels-intro� (to "find-channels-intro")
+;; �.find-videos-intro� (to "find-videos-intro")
+
+;; �.find-defun-intro� (to "find-defun-intro")
+;; �.find-emacs-intro� (to "find-emacs-intro")
+
+;; See: (find-anchors-intro)
+
+;; Ignore this - this is a temporary hack to make the htmlization in
+;; <http://angg.twu.net/eev-intros/> work better...
+;; (find-angg "eev-intros/")
+;; (find-angg "eev-intros/README")
+' (fooi-re "Source code: (find-efunction '\\([!-~]*\\))"
+ "Source code: (find-eev \\\\\"eev-intro.el\\\\\" \\\\\"\\1\\\\\")")
+
+
+
+
+;;; _ _
+;;; ___ _____ __ (_)_ __ | |_ _ __ ___
+;;; / _ \/ _ \ \ / /____| | '_ \| __| '__/ _ \
+;;; | __/ __/\ V /_____| | | | | |_| | | (_) |
+;;; \___|\___| \_/ |_|_| |_|\__|_| \___/
+;;;
+;; This works as an index.
+;; (find-intro-links "eev")
+;; �find-eev-intro� (to ".find-eev-intro")
+
+(defun find-eev-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eev-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-eev-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-eev-intro\")
+Main intros: (find-eval-intro)
+ (find-eepitch-intro)
+ (find-wrap-intro)
+Index to the source files: (find-eev \"eev2-all.el\")
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+The quickest way to reach this index is with `M-5 M-j'.
+
+
+Here is a list of all the available sandbox-y tutorials that
+explain parts and concepts of eev, listed in (a kind of)
+recommended reading order:
+
+ 0. (find-eev-intro)
+ 1. (find-eval-intro)
+ 2. (find-eepitch-intro)
+ 3. (find-wrap-intro)
+ 4. (find-links-intro)
+ 5. (find-eejump-intro)
+ 6. (find-code-c-d-intro)
+ 7. (find-psne-intro)
+ 9. (find-brxxx-intro)
+ 10. (find-pdf-like-intro)
+ 11. (find-audiovideo-intro)
+ 12. (find-anchors-intro)
+ 13. (find-multiwindow-intro)
+ 14. (find-rcirc-intro)
+ 15. (find-templates-intro)
+ 16. (find-prepared-intro)
+ 17. (find-bounded-intro)
+ 18. (find-channels-intro)
+ 19. (find-videos-intro)
+
+Items 1 and 2 should give you a good grasp of the main ideas -
+namely, that _elisp hyperlinks and interactive scripts can be
+embedded anywhere_. The other tutorials mainly show how to make
+these ideas pervasive.
+
+The last item above is an index of the video tutorials, with
+scripts for downloading local copies of them and links to
+important positions in the videos.
+
+There are also these two, ahem, \"things\", that I use in
+workshops, but that are not very eev-specific:
+
+ A. (find-emacs-intro)
+ B. (find-defun-intro)
+
+
+
+
+The README
+==========
+The README for eev2 is an elisp file,
+
+ (find-eev \"eev-readme.el\")
+
+that contains an easy way of installing eev - in either a
+temporary directory or in a permanent one - and initial
+instructions for trying the main keys. HIGHLY RECOMMENDED!
+
+
+
+Installing eev
+==============
+The instructions below are adapted from:
+
+ (find-eev-update-links \"/tmp/eev/\")
+ and: (find-eev \"eev-readme.el\")
+
+You should download the tarball with all the elisp files, unpack
+it somewhere - doing something like this (here you can use F8 if
+you already have eev installed),
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+rm -Rv /tmp/eev/
+mkdir /tmp/eev/
+cd /tmp/eev/
+wget http://angg.twu.net/eev-current/eev2.tgz
+tar -xvzf eev2.tgz
+
+and then evaluate these sexps (type C-x C-e at the end of each
+line):
+
+ (add-to-list 'load-path \"/tmp/eev/\")
+ (require 'eev2-all)
+ (eev-mode 1)
+
+This will turn on eev-mode - which just activates a few
+keybindings. To understand the main ideas, please follow these
+two tutorials:
+
+ (find-eval-intro)
+ (find-eepitch-intro)
+
+To toggle eev-mode on and off, use `M-x eev-mode'.
+
+
+
+The keybindings
+===============
+`eev-mode' defines its own meanings for lots of meta-shift-letter
+key combinations - which are not normally used by Emacs - and,
+besides that, only for:
+
+ `M-e' (find-eval-intro \"`M-e'\")
+ `M-k' (find-eval-intro \"`M-k'\")
+ `M-j' (find-eejump-intro \"\\neejump\\n\")
+ `M-h' (find-links-intro \"Elisp hyperlinks buffers\")
+ `<f8>' (find-eepitch-intro \"The main key: <F8>\")
+
+For the full lists of keybindings, see:
+
+ (find-efunctiondescr 'eev-mode)
+ (find-eminormodekeymapdescr 'eev-mode)
+ (find-efunctiondescr 'eev-avadj-mode)
+ (find-eminormodekeymapdescr 'eev-avadj-mode)
+" rest)))
+
+;; (find-eev-intro)
+
+
+
+
+
+
+
+
+;;; _
+;;; _____ ____ _| |
+;;; / _ \ \ / / _` | |
+;;; | __/\ V / (_| | |
+;;; \___| \_/ \__,_|_|
+;;;
+;; �find-eval-intro� (to ".find-eval-intro")
+;; (find-intro-links "eval")
+;; (find-TH "eev-article" "hyperlinks")
+;; http://angg.twu.net/eev-article.html#hyperlinks
+;; file:///home/edrx/TH/L/eev-article.html#hyperlinks
+;; (find-TH "eev-article" "forward-and-back")
+;; (find-efunction 'eek-eval-last-sexp)
+
+
+(defun find-eval-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eval-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-eval-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-eval-intro\")
+More intros: (find-eev-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
+
+
+
+The standard way to evaluate Lisp: `C-x C-e'
+============================================
+The most important idea in Emacs is that Lisp code can appear
+anywhere, and you can evaluate a Lisp expression (a \"sexp\") by
+placing the cursor (the \"point\") just after it and typing `C-x
+C-e'; the result is then displayed in the echo area. Try it in
+the line below, with the point in the three different indicated
+positions - you should get different results.
+
+ (+ (* 2 3) (* 4 5))
+ ^ ^^
+ | | \\
+ 6 20 26
+
+
+
+The end of line and `M-e'
+=========================
+A common operation is to move the point to the end of the current
+line, then run `C-x C-e'. That can be done with `C-e C-x C-e',
+but eev-mode implements a shorthand for it: `M-e'. Try it here:
+
+ (+ (* 2 3)
+ (* 4 5)
+ )
+
+`M-e' accepts several different numeric prefixes that alter its
+behavior. We are only interested in one of them now - `M-0 M-e'
+highlights the sexp for a fraction of a second insted of
+executing it. Try it above.
+
+In some rare occasions we might want to run something like `M-e'
+but without moving to the end of the line first. Eev-mode
+implements a key binding for that: `M-E' (meta-shift-e). As an
+exercise, try to use `M-0 M-E' at several positions below, to
+hightlight the subsexps `(* 2 3)', `(* 4 5)', and `4'.
+
+ (+ (* 2 3) (* 4 5))
+
+
+
+
+What to execute, and in what order
+==================================
+Note that the order of evaluation may be important:
+
+ (setq a 5)
+ (setq a 6)
+ (* a a)
+
+By executing `(setq a 5)' and then `(* a a)' above we get 25,
+by executing `(setq a 6)' and then `(* a a)' we get 36 - the
+current value of `a' is the one of the last `setq' executed.
+
+An exercise: edit the three sexps above to introduce a
+`(setq a 22)', then use that sexp and the `(* a a)' to calculate
+the square of 22.
+
+MORAL: Elisp code can appear anywhere in any Emacs buffer, but it
+is _passive by default_. It only gets executed if we move the
+point to the right positions and type `C-x C-e', `M-e', or
+similar keys. Sexps can be executed any number of times, in any
+order, and can be edited and modified.
+
+
+
+
+Elisp hyperlinks
+================
+Some Emacs functions can be used as hyperlinks. When sexps like
+
+ (find-file \"/tmp/\")
+ (info \"(emacs)Lisp Eval\")
+ (describe-function 'find-file)
+ (find-function 'find-file)
+ (man \"cat\")
+
+are executed they \"open a new page\" - actually, they create a
+new buffer, or reuse it if it already exists - and it is usually
+possible to \"go back\" by killing the new buffer. However for
+some functions, like `man', which by default open a manpage in
+another window, \"going back\" would mean something different.
+
+Eev defines several functions to let us use sexps as hyperlinks.
+The main conventions on these functions are:
+
+ 1) their names start with \"find-\",
+
+ 2) calls to them can be \"refined\" with a pos-spec (this will
+ be discussed below),
+
+ 3) they open the new buffer in the current window (to make it
+ easier to \"go back\" after following them - see the next
+ section),
+
+ 4) they don't display much output in the echo area,
+
+ 5) when they create temporary buffers with lots of sexps then:
+
+ a) the first sexp in that buffer is one that can regenerate
+ that buffer when executed,
+
+ b) all the sexps are prefixed with the string stored in the
+ variable `ee-hyperlink-prefix', to let these sexps be
+ pasted into scripts as comments (see below).
+
+Note that sometimes the most obvious name for a hyperlink
+function starting with `find-' is already taken by Emacs - for
+example, `find-file' and `find-function'. In those cases eev use
+other names: `find-fline', `find-efunction', etc. Here are the
+eev versions of the links above:
+
+ (find-fline \"/tmp/\")
+ (find-node \"(emacs)Lisp Eval\")
+ (find-efunctiondescr 'find-file)
+ (find-efunction 'find-file)
+ (find-man \"cat\")
+
+
+
+
+Going back
+==========
+Web browsers let you follow a hyperlink and then \"go back\".
+There are different ways of going back - if you opened the new
+page on a new window or tab, then going back means deleting the
+new window or tab (or just switching to the old window/tab); if
+you opened the new page on the same window/tab, then you need to
+use the \"back\" button.
+
+Eev-mode defines two keys for \"going back\": `M-k', that kills
+the current buffer, and `M-K', that just hides it (\"buries\" it
+in the bottom of the list of all buffers). Try following the link
+below by <M-e>, then deleting its buffer with `M-k' to go back:
+
+ (find-node \"(emacs)Shell\")
+
+In some cases we know that we may want to go \"forward\" again
+after going back, and we may not want to delete the target buffer
+- for example, because it would take a while to rebuild it again,
+or because we would lose the position of the point there. Most
+hyperlink functions in eev are able to reuse a buffer that
+\"looks like\" the desired target buffer; the test for
+lookalikeness is based on the name of the buffer only. Try to
+follow the links below with `M-e', then come back to this buffer
+with `M-k', then follow them again. Then try the same thing with
+`M-K' instead of `M-k', to see the difference - in the `find-sh'
+example below the \"sleep\" takes one second to run, so
+revisiting the existing output buffer after a `M-K' is much
+quicker than recreating it anew.
+
+ (find-man \"1 bash\")
+ (find-sh \"sleep 1; echo 'This was run at:'; date\")
+
+
+
+
+Refining hyperlinks
+===================
+Most hyperlinks functions defined by eev can be \"refined\" by
+the addition of extra arguments. These extra arguments are called
+a \"pos-spec\" (or a \"pos-spec-list\") and they specify a
+position in the target buffer. The first argument means a certain
+line number, when it is a number, or the first occurrence of a
+certain string, when it is a string. Try:
+
+ (find-node \"(emacs)Command Index\")
+ (find-node \"(emacs)Command Index\" \"eval-last-sexp\")
+
+Further arguments mean either \"move down n lines\" or \"search
+for the next occurrence of a string\", depending on whether they
+are numbers or strings. Try:
+
+ (find-sh \"seq 2095 2115\")
+ (find-sh \"seq 2095 2115\" \"2100\")
+ (find-sh \"seq 2095 2115\" \"2100\" \"9\")
+ (find-sh \"seq 2095 2115\" \"2100\" 2)
+
+
+
+Pos-spec-lists
+==============
+The optional arguments that refine a hyperlink form what we call
+a \"pos-spec-list\". For example, the pos-spec-list here has two
+elements,
+
+ (find-sh \"seq 2095 2115\" \"2100\" \"9\")
+
+and in most cases an empty pos-spec-list, like this,
+
+ (find-sh \"seq 2095 2115\")
+
+means: \"if the target buffer already exists then just open it\"
+- so that following that hyperlink would jump to the current
+position of the point in that buffer.
+
+Pos-spec-lists are usually interpreted by the function
+`ee-goto-position'. The first argument is interpreted in a
+special way, according to its type:
+
+ string -> jump to the first occurrence of
+ that string in the buffer
+ number -> jump to the n-th line
+
+and the other arguments are interpreted (recursively) by
+`ee-goto-rest':
+
+ string -> jump to the next occurence of that string
+ number -> move down n lines
+ list -> evaluate the list
+
+If you want to add support for more complex pos-spec-lists, just
+replace `ee-goto-rest' with your own extended version.
+
+
+
+Anchors and pages
+=================
+\[See:\] (find-anchors-intro)
+
+Some hyperlink functions, like `find-efunction' and
+`find-evariable', jump to specific positions in buffers - the
+beginning of the definition of a function or a variable in the
+source code - even when their pos-spec-lists are empty, so they
+process all their extra arguments with just `ee-goto-rest'.
+
+Other hyperlink functions transform the first argument of a
+pos-spec-list in a special way it if is a string - for example,
+in `find-available', which is based on `find-Package',
+
+ (find-available \"bash\")
+ (find-available \"bash\" \"bash-doc\")
+
+the argument \"bash\" is converted to \"\\nPackage: bash\\n\",
+and the two hyperlinks above jump to the description of the
+package \"bash\" in the list of the available packages in a
+Debian system.
+
+The functions based on `find-anchor' transform an initial string
+argument in the pos-spec-list by running `ee-format-as-anchor' on
+it [TODO: document this], and the ones based on
+`ee-goto-position-page' jump to the n-th \"page\" of a buffer if
+the first argument of the pos-spec-list is a number, n; for
+exemple, if n is 234 that will jump to the 233-th formfeed (233
+and not 234 because the page 1 is before the first formfeed). For
+more on \"pages\", see:
+
+ (find-pdf-like-intro \"PDF-like documents as text\")
+
+
+
+
+Producing and refining hyperlinks
+=================================
+If you are on an Info page, typing `M-h M-i' will create a
+temporary buffer containing a header - which we will discuss
+later - and several (possibly equivalent) links to that info
+page. Something like this:
+ ________________________________________________________
+ |;; (find-einfo-links) |
+ | |
+ |;; (info \"(emacs)Misc Buffer\") |
+ |;; (find-node \"(emacs)Misc Buffer\") |
+ |;; (find-enode \"Misc Buffer\") |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental)---|
+ |________________________________________________________|
+
+These links are meant to be cut & pasted - possibly after
+refining them to make them more precise. Let's look first at the
+two key sequences that make refining much easier. Remember that
+`M-w' (`kill-ring-save') is roughly correspondent to what is
+called \"copy\" is most modern interfaces, and `C-y' (`yank') is
+roughly correspondent to \"paste\". Both `M-w' and `C-y' operate
+on Emacs's \"kill ring\", and to make our examples trivial to
+follow we will first put a string on the kill ring:
+
+ (kill-new \"C-y\")
+ (car kill-ring)
+
+Now let's see how refine hyperlinks quickly. `M-h M-2' duplicates
+the current line; we will use that to refine a copy of a working
+hyperlink, instead of working directly on the original, and
+risking breaking it. And `M-h M-y' refines the hyperlink on the
+current line by adding a string - the top element in the kill
+ring - to its sexp. Try this below; you should be able to convert
+
+ (find-enode \"Kill Ring\")
+ (find-enode \"Yanking\")
+
+into
+
+ (find-enode \"Kill Ring\")
+ (find-enode \"Kill Ring\" \"C-y\")
+ (find-enode \"Yanking\")
+ (find-enode \"Yanking\" \"C-y\")
+
+with few keystrokes, as you can leave the Meta key pressed. The
+full key sequence for duplicating and refining is `M-h M-2 M-h
+M-y', but we can think of it as `M-h2hy'.
+
+Now try a more serious exercise: follow the `(find-enode ...)'
+hyperlink below, copy a word or two from its contents to the kill
+ring with `M-w', then generate the temporary buffer with
+hyperlinks to that Info page with `M-h M-i', then duplicate one
+of its hyperlinks with `M-h M-2', refine it with `M-h M-y', and
+copy the result to this sandbox with `M-w' (or `C-w') and `C-y'.
+As this is a long sequence of instructions, it is better to run
+`C-x 1 C-x 2' or `C-x 1 C-x 3' before following the hyperlink, to
+keep the instructions visible.
+
+ (find-enode \"Command Index\")
+
+
+
+
+What else?
+==========
+Eev-mode defines several other key sequences similar to `M-h
+M-i'. You can get the full list here:
+
+ (find-efunctiondescr 'eev-mode)
+ (find-efunctiondescr 'eev-mode \"M-h f\")
+
+Try also this:
+
+ (find-efunction-links 'eev-mode)
+
+and for other tutorials like this one, try:
+
+ (find-wrap-intro)
+ (find-eepitch-intro)
+
+\[To do: explain M-x ee-hyperlink prefix and how to embed
+hyperlinks in scripts]
+" rest)))
+
+;; (find-eval-intro)
+
+
+
+;;; _ _ _ _ _
+;;; ___ ___ _ __ (_) |_ ___| |__ (_)_ __ | |_ _ __ ___
+;;; / _ \/ _ \ '_ \| | __/ __| '_ \ _____| | '_ \| __| '__/ _ \
+;;; | __/ __/ |_) | | || (__| | | |_____| | | | | |_| | | (_) |
+;;; \___|\___| .__/|_|\__\___|_| |_| |_|_| |_|\__|_| \___/
+;;; |_|
+;;
+;; �find-eepitch-intro� (to ".find-eepitch-intro")
+;; (find-intro-links "eepitch")
+;; (find-eev "eepitch.readme")
+
+(defun find-eepitch-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eepitch-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-eepitch-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-eepitch-intro\")
+More intros: (find-eval-intro)
+ (find-wrap-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial (for eepitch) and a sandbox.
+
+
+
+The motivation for eepitch: taking notes and redoing
+====================================================
+Suppose that we have to do some reasonably complex task using a
+shell, and that we want to take notes of what we do because we
+might have to do something similar later.
+
+The two usual ways to interact with a shell are:
+
+ 1) through a _script_, that is, by preparing in advance all
+ commands to be executed, putting them in a script file, and
+ then running that file,
+
+ 2) _interactively_, by typing the commands one by one on a
+ shell prompt.
+
+Suppose that we have to discover which commands to run as we go;
+that rules out preparing a script beforehand, so we need to use
+the shell interactively. After issuing the right commands, the
+two usual ways to retrieve what we did are:
+
+ a) through the _shell history_, which records the last commands
+ that the shell received,
+
+ b) by looking at the full _transcript_ of our interaction with
+ the shell.
+
+The way (a) gets a list of commands, without comments, that can
+be then saved into a text editor; the way (b) may require some
+tricky editing to isolate the commands from their outputs.
+
+Eepitch.el implements a simple alternative way of interacting
+with shells (and other shell-like programs) while keeping notes.
+It has only one essential key binding, <F8>, which is better
+explained through the executable example in the next section, and
+two unessential features, `M-T' and \"\", which will be
+explained later.
+
+
+
+The main key: <F8>
+==================
+Emacs can run a shell in a buffer, and it can split its frame
+into windows, like this:
+ ___________________
+ | | |
+ | our | a |
+ | notes | shell |
+ | | buffer |
+ |_________|_________|
+
+The usual way to use a shell buffer is to move the cursor there
+and type commands into its prompt; the eepitch-y way is to leave
+the cursor at the \"notes\" buffer, write the commands for the
+shell there, and send these commands to the shell with <F8>.
+
+Here's what <F8> does:
+
+ When we type <F8> on a line that starts with a red
+ star (\"\"), it executes the rest of the line as Lisp, and
+ moves down; when we type <F8> on a line that does not start
+ with a \"\", it makes sure that the \"target buffer\" is being
+ displayed (the \"target\" is usually the buffer called
+ \"*shell*\"), it \"send\"s the current line to the target
+ buffer, and moves down.
+
+ \"Sending the current line to the target buffer\" means copying
+ the contents of the current line to the target - as if the user
+ had typed that line there by hand -, then \"typing\" a <RET> at
+ the target buffet.
+
+Please try that in the example after this paragraph, by typing
+<F8> six times starting at the first line that says
+\" (eepitch-shell)\". The three red star lines at the top will
+create a target buffer, destroy it, and create it again; the
+other three lines will send commands to the target shell.
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo \"We are at: $PWD\"
+cd /tmp/
+echo \"We changed to: $(pwd)\"
+
+
+
+
+Other targets
+=============
+Just like `(eepitch-shell)' creates a shell buffer and sets the
+eepitch target to it, `(eepitch-python)' creates a buffer with a
+Python interpreter and uses it as the eepitch target. Try:
+
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+def square (x):
+ return x*x
+
+print(square(5))
+
+ We can use several targets at the time, alternating between them.
+ For example:
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo Hello... > /tmp/o
+
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+print(open(\"/tmp/o\").read())
+
+ (eepitch-shell)
+echo ...and bye >> /tmp/o
+
+ (eepitch-python)
+print(open(\"/tmp/o\").read())
+
+
+ There is a (much) more advanced example of working with several
+ targets here:
+
+ (find-prepared-intro \"An `ee' for Python\")
+
+
+
+
+
+More on eepitch-kill
+====================
+Note that `(eepitch-kill)' kills the _current_ target, that may
+or may not be a shell buffer, a Python interaction buffer, etc...
+That explains the first line in blocks like:
+
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+
+and:
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+
+by running the first `(eepitch-python)' we can be sure that the
+following `(eepitch-kill)' will kill the Python buffer, not the
+shell buffer! And the last `(eepitch-python)' in the block of
+three lines will then create a new Python interaction buffer,
+erasing all definitions done in previous sessions.
+
+
+
+
+Creating eepitch blocks: `M-T'
+==============================
+Write just \"shell\" or \"python\" in a line, then type
+`M-T' (i.e., meta-shift-t) there. The line will be turned into
+three - an \" (eepitch-xxx)\", an \" (eepitch-kill)\", and an
+\" (eepitch-xxx)\". We call these blocks of three lines
+\"eepitch blocks\". Try this below, converting the \"shell\" into
+an eepitch block for starting a shell.
+
+shell
+pwd
+cd /tmp/
+pwd
+
+
+
+
+Red stars
+=========
+Eepitch.el sets the glyph for the char 15 to a red star in the
+standard display table. In layman's terms: eepitch.el tells Emacs
+that the character 15 should be displayed as a red star. The
+character 15 corresponds to control-O, whose default
+representation on screen would be \"^O\". You can enter a
+literal ^O in a buffer by typing `C-q C-o'.
+
+
+
+For more information
+====================
+On hyperlinks: (find-eval-intro)
+On keys similar to `M-T': (find-wrap-intro)
+An older text about eepitch:
+ (find-eev \"eepitch.readme\")
+ (find-eev \"eepitch.readme\" \"the-trivial-case\")
+ (find-eev \"eepitch.readme\" \"red-stars\")
+ (find-eev \"eepitch.readme\" \"eepitch-blocks\")
+ (find-eev \"eepitch.readme\" \"eepitch-blocks\")
+Many functions like `eepitch-shell':
+ (find-efunction 'eepitch-bash)
+What functions can generate target buffers:
+ (find-eevfile \"eepitch.el\" \"shell-like sexp\")
+ (find-efunction 'eepitch)
+" rest)))
+
+;; (find-eepitch-intro)
+
+;; (find-pytutnode "Methods of File Objects")
+
+
+
+
+;;; _ _
+;;; __ ___ __ __ _ _ __ (_)_ __ | |_ _ __ ___
+;;; \ \ /\ / / '__/ _` | '_ \ _____| | '_ \| __| '__/ _ \
+;;; \ V V /| | | (_| | |_) |_____| | | | | |_| | | (_) |
+;;; \_/\_/ |_| \__,_| .__/ |_|_| |_|\__|_| \___/
+;;; |_|
+;;
+;; (find-intro-links "wrap")
+;; �find-wrap-intro� (to ".find-wrap-intro")
+
+(defun find-wrap-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-wrap-intro)*"))
+ (apply 'find-estring-lv "\
+\(Re)generate: (find-wrap-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-wrap-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.
+
+
+
+Eepitch and eev
+===============
+Eepitch defines only two keys - <F8> and <M-T> - and <M-T> is a
+particular case of something more general: \"wrapping commands\", that
+follow these conventions:
+
+ 1) they are bound to meta-shift-letter keys (M-T, M-F, M-M, ...),
+ 2) they transform the current line and then move down,
+ 3) they produce Lisp code meant to be executed with `M-e' or `F8',
+ 4) they are listed at:
+ (find-efunctiondescr 'eev-mode \"M-F\")
+ 5) their keybindings are only available when eev-mode is turned on.
+
+To understand how they work, please follow the instructions below and
+try them here. Note that this buffer is a sandbox, and it can be
+recreated by executing the sexp \"(find-wrap-intro)\" at the top.
+
+Note that the wrapping commands are all bound to key sequences of
+the form meta-SHIFT-letter - don't forget the shift!!!
+
+
+
+<M-T>: produce an eepitch block
+===============================
+If you type <M-T> on a line containing just the word \"shell\" you get
+three lines, like this:
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+
+We call a block of three lines like this an \"eepitch block\", and
+eepitch blocks can be used to set up interactions with external
+programs. Try typing <M-T> on the lines that say \"shell\" and \"python\"
+below, and use them to send some lines to bash and to a python
+interpreter (with <F8>):
+
+bash
+export PS1='$PWD% '
+cd /tmp/
+function ee () { set -v; . /tmp/ee.sh; set +v; }
+rm -v /tmp/ee.sh
+cat > /tmp/ee.sh <<'%%%'
+ echo Hello
+ cd /etc/
+%%%
+cat /tmp/ee.sh
+bash /tmp/ee.sh
+ee
+
+python
+square = lambda x: x*x
+square(5)
+
+
+
+<M-F>: hyperlink to a file or a directory
+=========================================
+If you type <M-F> on the lines below,
+
+/etc/
+/tmp/
+~/
+~/.emacs
+
+you get hyperlinks like these:
+
+# (find-fline \"/etc/\")
+# (find-fline \"/tmp/\")
+# (find-fline \"~/\")
+# (find-fline \"~/.emacs\")
+
+
+
+<M-S>: hyperlink to the output of a shell command
+=================================================
+If you type <M-S> on a line containing a shell command you get a
+hyperlink that starts with `find-sh', and that when followed opens a
+temporary buffer with the output of that shell command, like these:
+
+ # (find-sh \"find --help\")
+ # (find-sh \"find /etc | sort\")
+ # (find-sh \"find /etc -type d | sort\")
+ # (find-sh \"find /etc -type d -maxdepth 1 | sort\")
+ # (find-sh \"find /etc -type d -maxdepth 2 | sort\")
+
+Try it here:
+
+dict smop
+dict 'minor detail'
+
+If you have the packages dict, dictd and dict-jargon installed
+these hyperlinks will show you the meaning of the expressions
+\"smop\" and \"minor detail\".
+
+ # (find-sh \"dict smop\")
+ # (find-sh \"dict 'minor detail'\")
+
+
+
+<M-M>: hyperlink to a manpage
+=============================
+Try <M-M> here:
+
+1 tac
+
+
+
+All wrapping functions
+======================
+Below is a list of all wrapping functions, with tests and
+hyperlinks:
+
+ (eek \"2*<down> M-A <down> ;;; Test eewrap-anchor\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-anchor\")
+;; <anchor>
+
+ (eek \"2*<down> M-C <down> ;;; Test eewrap-code-c-d\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-code-c-d\")
+foo /tmp/foobar/
+
+ (eek \"2*<down> M-D <down> ;;; Test eewrap-debian\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-debian\")
+bash
+
+ (eek \"2*<down> M-F <down> ;;; Test eewrap-find-fline\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-find-fline\")
+/tmp/foobar/
+
+ (eek \"2*<down> M-J <down> ;;; Test eewrap-eejump\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-eejump\")
+422 (find-eev-intro \"find-wrap-intro\")
+
+ (eek \"2*<down> M-J <down> ;;; Test eewrap-eejump\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-eejump\")
+42
+
+ (eek \"2*<down> M-M <down> ;;; Test eewrap-man\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-man\")
+1 tac
+
+ (eek \"2*<down> M-P <down> ;;; Test eewrap-pdflike\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-pdflike\")
+foopdf $S/http/foo.org/bar.pdf
+
+ (eek \"2*<down> M-R <down> ;;; Test eewrap-rm/mkdir/cd\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-rm/mkdir/cd\")
+/tmp/foo/
+
+ (eek \"2*<down> M-S <down> ;;; Test eewrap-sh\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-sh\")
+seq 1 20
+
+ (eek \"2*<down> M-T <down> ;;; Test eewrap-eepitch\")
+ Source: (find-eev \"eepitch.el\" \"eewrap-eepitch\")
+python
+
+ (eek \"2*<down> M-V <down> ;;; Test eewrap-audiovideo\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-audiovideo\")
+slimetutorial /tmp/slime-tutorial.mp4
+
+ (eek \"2*<down> M-Z <down> ;;; Test eewrap-zsh\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-zsh\")
+echo $SHELL
+
+ (eek \"2*<down> <<eewrap-eewrap>> <down> ;;; Test eewrap-eewrap\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-eewrap\")
+U user-defined a b c
+
+
+
+
+Wrapping functions generate hyperlinks
+======================================
+...this is a slogan - a huge idea, in a very shortened form. In its
+full form, that would be:
+
+ (Some) wrapping function provide one of the basic ways to produce
+ elisp hyperlinks quickly; the second basic way, which is a bit more
+ complex conceptually, is via Elisp hyperlinks buffers. This, and the
+ whole rationale behind generating and using elisp hyperlinks, is
+ explained here:
+
+ (find-links-intro \"Elisp hyperlinks buffers\")
+
+The \"some\" in beginning of the long version of the slogan, above, is
+because a few of the wrapping commands, for example, <M-T> and <M-R>,
+are used to produce things that are not hyperlinks - usually other
+kinds of scripts.
+
+
+
+
+# Local Variables:
+# coding: raw-text-unix
+# ee-anchor-format: \"�%s�\"
+# End:
+" rest)))
+
+;; (find-wrap-intro)
+
+
+
+
+;;; _ _ _
+;;; | (_)_ __ | | _____
+;;; | | | '_ \| |/ / __|
+;;; | | | | | | <\__ \
+;;; |_|_|_| |_|_|\_\___/
+;;;
+;; (find-intro-links "links")
+;; �find-links-intro� (to ".find-links-intro")
+
+(defun find-links-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-links-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-links-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-links-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.
+
+
+
+
+What is a hyperlink?
+====================
+In a previous tutorial - (find-eval-intro) - we saw that several
+kinds of sexps can be used as hyperlinks. For example, these:
+
+ (find-fline \"/tmp/\")
+ (find-node \"(emacs)Lisp Eval\")
+ (find-efunctiondescr 'find-file)
+ (find-efunction 'find-file)
+ (find-man \"cat\")
+
+Hyperlinks in a web browser _usually_ take us to a different
+page, or to a different position in the same page, and in those
+cases it is possible to go back to previous position from there;
+but sometimes hyperlinks - or webpage buttons - are associated to
+Javascript code, and \"following the link\" then means executing
+that code. Web browsers try to make it impossible to have
+hyperlinks or webpages that will send out your private
+information, or that will put your system in a unusable state.
+Security is web browsers is achieved by restricting what the
+scripts in a page can do.
+
+Sexp hyperlinks, in contrast, can do essentially anything - and,
+instead of _security_, they have _transparency_. The code that a
+sexp hyperlink will execute is visible, and users are supposed to
+know that sexp hyperlinks with `find-fline', `find-node',
+`find-efunctiondescr', etc, are very safe - but the ones that
+start with `find-sh' may not be. It is possible to write
+something like:
+
+ (find-sh \"<code that deletes all your e-mails>\")
+
+but it is not possible to hide that action behind an
+innocent-looking button that says \"click for a larger image\".
+
+So, _any_ elisp sexp can be _used_ as a sexp hyperlink; but
+people are only going to follow a sexp hyperlink if they can more
+or less predict (quickly!) what that hyperlink is going to do...
+Readability is important, so let's take a look at the most common
+kinds of hyperlinks.
+
+
+
+
+Elisp hyperlinks buffers
+========================
+Emacs has several help commands, whose bindings start with `C-h',
+that display their information in (temporary) \"help buffers\" -
+and in many cases these generated help buffers have hyperlinks,
+that can be followed by typing <RET> on them.
+
+Eev has something similar, but using the prefix `M-h' and
+following very different design decisions. Let's start with a
+comparison, between Emacs's `C-h f' (`describe-function') and
+eev's `M-h M-f' (`find-efunction-links'). Remember that `M-e'
+accepts prefix arguments, and that `M-2 M-e' displays the target
+of a hyperlink at another window without switching to there; use
+that on the two sexps below to see the results by yourself:
+
+ \"C-h f find-file\" -> (find-efunctiondescr 'find-file)
+ \"M-h M-f find-file\" -> (find-efunction-links 'find-file)
+
+Note that we used `find-efunctiondescr' instead of
+`describe-function'; `find-efunctiondescr' is a variant of
+`describe-function' that that follows eev's conventions, as
+explained here:
+
+ (find-eval-intro \"main conventions\")
+
+`C-h f find-file' produces a buffer with readable text and
+\"usual\" hyperlinks that can be followed by typing RET on them,
+while `M-h M-f find-file' produces a buffer like this:
+
+ ___________________________________________________________
+ |# (find-efunction-links 'find-file) |
+ |# (where-is 'find-file) |
+ |# (describe-function 'find-file) |
+ |# (find-efunctiondescr 'find-file) |
+ |# (find-efunction 'find-file) |
+ |# (find-efunctionpp 'find-file) |
+ |# (find-efunctiond 'find-file) |
+ |# (find-estring (documentation 'find-file)) |
+ |# (find-estring (documentation 'find-file t)) |
+ |# (symbol-file 'find-file 'defun) |
+ |# (find-fline (symbol-file 'find-file 'defun)) |
+ | |
+ |# (Info-goto-emacs-command-node 'find-file) |
+ |# (find-enode \"Command Index\" \"* find-file:\") |
+ |# (find-elnode \"Index\" \"* find-file:\") |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
+ |___________________________________________________________|
+
+What is that?...
+
+
+
+
+Elisp hyperlinks buffers conventions
+====================================
+Let's refer to Emacs's help buffers as \"C-h buffers\" and to
+eev's elisp hyperlink buffers as \"M-h buffers\". Here is a quick
+list of the main differences and conventions; some of them will
+be expanded later:
+
+ 1) C-h buffers are usually named \"*Help*\", while
+ M-h buffers are usually named \"*Elisp Hyperlinks*\";
+
+ 2) C-h buffers are generated by functions called \"describe-*\",
+ M-h buffers are generated by functions called \"find-*-links\";
+
+ 3) C-h buffers may contain \"usual-looking\" links, that can be
+ followed by typing RET on them, and this is implemented via
+ \"buttons\"; C-h buffers are \"ascii plus text properties\",
+ while M-h buffers are plain ascii;
+
+ 4) C-h buffers are read-only, while
+ M-h buffers are read-and-write. The idea is that we can not
+ only follow the hyperlinks in a M-h buffer but also modify
+ them - usually by \"refining\" them, like this,
+
+ (find-eval-intro \"Refining hyperlinks\")
+
+ then test the modified versions, and copy-and-paste those
+ hyperlinks to other, more permanent places. This is much
+ easier to do when we are working in plain ascii; the buttons
+ in C-h buffers are non-trivial to create, to edit and to
+ save.
+
+ 5) C-h buffers are _readable_, while
+ M-h buffers may look like (technical) gibberish.
+
+ This is intentional - M-h buffers have a do-it-yourself,
+ \"I'm the result of a 5-minute hack\" feeling because most
+ of them started just like that, as 5-minute hacks that
+ turned out to be useful enough, and only suffered very minor
+ changes later on. Try this:
+
+ (find-find-links-links)
+
+ Most `find-*-links' were created from that template - and it
+ should be easy to create other ones.
+
+ 5) Many `M-h' commands, like `M-h f' and `M-h M-i', generate
+ sexp hyperlinks that \"point to where we are now\"; but once
+ we are in an M-h buffer this idea - whose basis is:
+ from (almost) anywhere in Emacs it should to be easy to
+ create a hyperlink to where we are now - changes to:
+
+ 6) The first line (the \"top sexp\") of an M-h buffer
+ regenerates the buffer. And, at last,
+
+ 7) The elisp hyperlinks in M-h buffers are prefixed by the
+ string in `ee-hyperlink-prefix'.
+
+
+
+
+Basic and non-basic hyperlinks
+==============================
+We can start by dividing the hyperlink functions into a fixed set
+of \"basic\" ones and an unbounded set of \"non-basic\" ones. In
+the buffer generated by
+
+ (find-efunction-links 'find-file)
+
+these hyperlinks
+
+ (find-efunctiondescr 'find-file)
+ (find-efunction 'find-file)
+ (find-efunctionpp 'find-file)
+ (find-efunctiond 'find-file)
+ (find-estring (documentation 'find-file))
+ (find-estring (documentation 'find-file t))
+ (find-fline (symbol-file 'find-file 'defun))
+
+calls \"basic\" eev hyperlink functions, that are just interfaces
+to Emacs function slightly tweaked into functions that follow
+eev's conventions - they are refinable, use the current window,
+etc. But these two,
+
+ (find-enode \"Command Index\" \"* find-file:\")
+ (find-elnode \"Index\" \"* find-file:\")
+
+are generated by calls to `code-c-d' or similar functions, that
+generate some elisp code as text, from templates, and evaluate
+that code, as explained here:
+
+ (find-code-c-d-intro)
+ (find-pdf-like-intro)
+ (find-audiovideo-intro)
+
+The `code-*' functions define hyperlink functions whose names are
+of the form `find-{stem}{suffix}', and each of these `code-*'
+function has an associated `find-code-*' function that just
+displays what the corresponding `code-*' would execute. So one
+way to get acquainted to the most common of these suffixes is to
+follow these hyperlinks:
+
+ (find-code-c-d \"CODE\" \"/DIR/\" :info \"INFO\")
+ (find-code-pdf \"CODE\" \"FILE.pdf\")
+ (find-code-pdf-text \"CODE\" \"FILE.pdf\")
+ (find-code-audio \"CODE\" \"FILE\")
+ (find-code-video \"CODE\" \"FILE\")
+
+From these only the functions whose suffixes end with \"sh\" or
+\"sh0\" and inherently dangerous; the others are usually safe if
+no hacks had been done.
+
+Some hyperlinks functions - for example the ones created by
+`code-pdf', `code-audio', etc - invoke external programs, and
+_may_ behave in bad ways when given unsafe arguments; these
+functions are implemented using the low-level functions
+`find-bgprocess' and `find-callprocess', which of course are
+unsafe too.
+
+Also, the functions `find-*-links', `find-*-intro' and
+`find-code-*' simply create temporary buffers, and are thus very
+safe - but, as always, think carefully before executing any code
+that they generate.
+
+
+
+
+ee-hyperlink-prefix
+===================
+`ee-hyperlink-prefix' is both a variable and a function that
+helps us set that variable; it started to an experiment on how to
+create an alternative to `M-x customize' and ended up becoming
+the inspiration for all the `find-*-links' functions.
+
+If you run `M-x ee-hyperlink-prefix' you should get a buffer like
+this:
+
+ ___________________________________________________________
+ |# (ee-hyperlink-prefix) |
+ |# (setq ee-hyperlink-prefix \"# \") |
+ | |
+ |# (setq ee-hyperlink-prefix \"# \") |
+ |# (setq ee-hyperlink-prefix \";; \") |
+ |# (setq ee-hyperlink-prefix \"-- \") |
+ |# (setq ee-hyperlink-prefix \"// \") |
+ |# (setq ee-hyperlink-prefix \"% \") |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
+ |___________________________________________________________|
+
+where the first line regenerates the buffer, the second line sets
+the variable `ee-hyperlink-prefix' to its current value, and each
+one of the lines after the first blank line sets
+`ee-hyperlink-prefix' to one of several fixed common values. If
+we change the value of `ee-hyperlink-prefix' with one of the
+`setq's and execute the first line again we see that all the
+prefixes, plus the argument \"# \" in the second line, change.
+Try this, with `M-2 M-e' on each line:
+
+ (progn (setq ee-hyperlink-prefix \"# \") (ee-hyperlink-prefix))
+ (progn (setq ee-hyperlink-prefix \"% \") (ee-hyperlink-prefix))
+
+
+
+
+The first line regenerates the buffer
+=====================================
+ (find-find-links-links)
+ (find-find-links-links \"\\\\M-u\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a b\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a b c\")
+
+
+
+Pointing to where we are now
+============================
+
+ - for example, `M-h M-i' generates links to
+ the current \"intro\" buffer - like this one - _and_ to the
+ current Info page (the \"i\" in `M-h M-i' has two meanings).
+ Try:
+
+ (eek \"M-h M-i\")
+
+ you should get something like this:
+
+ ___________________________________________________________
+ |# (find-einfo-links \"links\") |
+ | |
+ |[No \"*info*\" buffer] |
+ | |
+ |# (find-links-intro) |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
+ |___________________________________________________________|
+
+
+
+
+ (find-enode \"Easy Customization\")
+
+
+
+
+" rest)))
+
+;; (find-links-intro)
+
+;; (find-eevfile "eev-template.el" "defun find-efunction-links")
+
+
+
+
+
+;;; _ _ _ _
+;;; ___ ___ __| | ___ ___ __| | (_)_ __ | |_ _ __ ___
+;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` |_____| | '_ \| __| '__/ _ \
+;;; | (_| (_) | (_| | __/_____| (_|_____| (_| |_____| | | | | |_| | | (_) |
+;;; \___\___/ \__,_|\___| \___| \__,_| |_|_| |_|\__|_| \___/
+;;;
+;; �find-code-c-d-intro� (to ".find-code-c-d-intro")
+
+(defun find-code-c-d-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-code-c-d-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-code-c-d-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-code-c-d-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.
+
+
+
+Avoiding full path names
+========================
+Suppose that you have downloaded (\"psne\"-ed) this URL,
+
+ http://www.lua.org/ftp/lua-5.1.4.tar.gz
+
+with `M-x brep' - see:
+
+ (find-psne-intro)
+
+and you unpacked that tarball into the directory ~/usrc/ (I
+prefer to use that instead of /usr/src/) with:
+
+ tar -C ~/usrc/ -xvzf $S/http/www.lua.org/ftp/lua-5.1.4.tar.gz
+
+Now you can access some directories and files of the unpacked
+tarball with:
+
+ (find-fline \"~/usrc/lua-5.1.4/\")
+ (find-fline \"~/usrc/lua-5.1.4/src/\")
+ (find-fline \"~/usrc/lua-5.1.4/src/lstrlib.c\")
+ (find-fline \"~/usrc/lua-5.1.4/test/\")
+ (find-fline \"~/usrc/lua-5.1.4/test/README\")
+ (find-fline \"~/usrc/lua-5.1.4/doc/\")
+ (find-w3m \"~/usrc/lua-5.1.4/doc/contents.html\")
+
+but it's a bit clumsy to have to use the \"~/usrc/lua-5.1.4/\"
+every time, so eev provides a nice way to define shorthands. We
+want to be able to write just this instead of the sexps above,
+
+ (find-lua51file \"\")
+ (find-lua51file \"src/\")
+ (find-lua51file \"src/lstrlib.c\")
+ (find-lua51file \"test/\")
+ (find-lua51file \"test/README\")
+ (find-lua51file \"doc/\")
+ (find-lua51w3m \"doc/contents.html\")
+
+and here the directory \"~/usrc/lua-5.1.4/\" became a mnemonic
+\"lua51\" in the middle of the names of some functions.
+
+We will call these sexps with \"lua51\" \"shorter hyperlinks\".
+
+
+
+Shorter hyperlinks
+==================
+How can we generate the definitions for `find-lua51file' and
+`find-lua51w3m' from just the strings \"lua51\" and
+\"~/usrc/lua-5.1.4/\"? Try this:
+
+ (find-code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
+
+you will get a temporary buffer with a lot of Lisp code -
+including a definition for `find-lua51file' and another one for
+`find-lua51w3m'. That Lisp code has not been executed yet; the
+function `find-code-c-d' is just for debugging, and we can regard
+it as a hyperlink to the code that this sexp would execute:
+
+ (code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
+
+So, to define a family of functions including `find-lua51file'
+and `find-lua51w3m', for a given \"mnemonic\" - \"lua51\" in this
+case - and a given \"directory\" - \"~/usrc/lua-5.1.4/\" - we run
+this:
+
+ (code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
+
+which generates a block of Lisp code, as a string, and evaluates
+it. Note: the original (and rather confusing) terminology for the
+\"mnemonic\" was \"code\"; that's why the \"c\" in `code-c-d'.
+
+
+
+Extra arguments to `code-c-d'
+=============================
+`code-c-d' supports extra arguments - for example, this works:
+
+ (find-code-c-d \"el\" \"~/usrc/emacs/lisp/\" :info \"elisp\")
+
+Look at the end of the generated code and you will see that it
+has a definition for `find-elnode' - such that
+
+ (find-elnode \"Constant Variables\")
+
+is a shorthand (a \"shorter hyperlink\") for:
+
+ (find-node \"(elisp)Constant Variables\")
+
+What is important to understand here is how these definitions
+with extra arguments are structured - so that you will be able to
+understand the source code when you need to. Both `code-c-d' and
+`find-code-c-d' are defined with a `&rest' in their argument
+lists, like this (NOTE: do not execute these defuns!):
+
+ (defun code-c-d (c d &rest rest) ...)
+ (defun find-code-c-d (c d &rest rest) ...)
+
+and they both invoke `ee-code-c-d', which does all the template
+work and returns a big string; `ee-code-c-d' passes its `rest'
+argument to a recursive function called `ee-code-c-d-rest', and
+for each one of the suported keywords there is a corresponding
+function, also recursive; for `:info' it is called
+`ee-code-c-d-:info'. Their specifications are like this:
+
+ (defun ee-code-c-d (c d &rest rest) ...)
+ (defun ee-code-c-d-rest (rest) ...)
+ (defun ee-code-c-d-:info (manual &rest rest) ...)
+
+and one very non-obvious trick is used to make the code short.
+When `ee-code-c-d-rest' and `ee-code-c-d-:info' are run they can
+access the values the `c' and the `d' that were passed to
+`ee-code-c-d' (due to dynamic scoping), so `c' and `d' do not
+need to be passed down explicitly as arguments.
+
+
+
+ (find-code-c-d \"CODE\" \"/DIR/\" :info \"INFO\")
+ (find-code-pdf \"CODE\" \"FILE.pdf\")
+ (find-code-pdf-text \"CODE\" \"FILE.pdf\")
+ (find-code-audio \"CODE\" \"FILE\")
+ (find-code-video \"CODE\" \"FILE\")
+
+
+
+
+Other similar functions
+=======================
+See: (find-brxxx-intro)
+ (find-pdf-like-intro)
+ (find-audiovideo-intro)
+" rest)))
+
+;; (find-TH "eev-article")
+;; (find-TH "eev-article" "shorter-hyperlinks")
+;; (find-code-c-d-intro)
+
+
+
+
+
+;;; _ _
+;;; _ __ ___ _ __ ___ (_)_ __ | |_ _ __ ___
+;;; | '_ \/ __| '_ \ / _ \_____| | '_ \| __| '__/ _ \
+;;; | |_) \__ \ | | | __/_____| | | | | |_| | | (_) |
+;;; | .__/|___/_| |_|\___| |_|_| |_|\__|_| \___/
+;;; |_|
+;;
+;; �find-psne-intro� (to ".find-psne-intro")
+;; (find-TH "eev-article" "local-copies")
+;; (find-angg ".emacs" "brep")
+;; (find-eev "eev-browse-url.el" "find-psne-links")
+;; (find-eev "eev-browse-url.el" "brep")
+
+(defun find-psne-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-psne-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-psne-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-psne-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.
+
+
+
+
+Local copies of files from the internet
+=======================================
+Emacs knows how to fetch files from the internet, but for most
+purposes it is better to use local copies. Suppose that the
+environment variable $S is set to ~/snarf/; then running this
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ mkdir -p $S/http/www.gnu.org/software/emacs/
+ cd $S/http/www.gnu.org/software/emacs/
+ wget http://www.gnu.org/software/emacs/emacs-paper.html
+ echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
+
+ # (find-fline \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+ # (find-w3m \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+
+creates a local copy of `emacs-paper.html' inside ~/snarf/http/
+and appends the URL to the file ~/.psne.log. The two lines in
+comments are hyperlinks to the local copy; The `find-fline' opens
+it as a file in the obvious way, and `find-w3m' opens it \"as
+HTML\", using a text-mode web browser called w3m that can be run
+either in standalone mode or inside Emacs; `find-w3m' uses w3m's
+Emacs interface, and it accepts extra arguments, which are
+treated as a pos-spec-list.
+
+
+
+The old way: psne
+=================
+A long time ago eev used to include a shell function called
+`psne' that ran all that with a single command. This:
+
+ psne http://www.gnu.org/software/emacs/emacs-paper.html
+
+would run the `mkdir', the `cd', the `wget' and the `echo' above.
+
+If psne were just a shell script then it wouldn't be able to
+change the current directory for the calling shell, so it had to
+be defined as shell function instead of a script, and the user
+had to patch his ~/.bashrc (or ~/.zshrc, or whatever) to install
+the definition for psne and make it available. That was VERY
+clumsy.
+
+From now on we will use \"psne\" as a verb: to psne a URL means
+to download a local copy of it into the right place, change to
+its directory and save its name into the file \"~/.psne.log\".
+
+
+
+
+The new way: M-x brep
+=====================
+Try to run this:
+
+ (find-psne-links \"http://www.gnu.org/software/emacs/emacs-paper.html\")
+
+or, equivalently, put the point on the URL below and then run
+`M-x brep':
+
+ http://www.gnu.org/software/emacs/emacs-paper.html
+
+You will get a temporary buffer for psne-ing the URL above. It
+will contain a `mkdir', a `cd', a `wget' and an `echo', plus an
+eepitch block and some elisp hyperlinks, and it can be executed
+with `F8's. Moral of the story: the \"new\" way to download a
+local copy of a url is to put the point on it, then run `M-x
+brep', then execute the resulting e-script. This does not require
+any patching of rcfiles, as the shell-function version of `psne'
+used to do.
+
+
+
+The environment variable $S
+===========================
+If when eev is loaded by Emacs the environment variable $S is
+unset, it will be set to a default value - namely, to the
+expansion of \"$HOME/snarf\". Processes started from Emacs, such
+as shells created with `eepitch-shell' or `find-sh', or external
+terminals created by sexps like
+
+ (find-bgprocess \"xterm\")
+ (find-bgprocess \"gnome-terminal\")
+ (find-bgprocess \"eterm\")
+
+will then inherit that value. Try it:
+
+ (getenv \"S\")
+ (find-sh0 \"echo $S\")
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo $S
+
+Try also to create an external shell not from Emacs - for
+example, from your window manager's list of available
+applications, or from a text-mode login - and run \"echo $S\"
+there: you will notice that $S is unset.
+
+Old versions of eev used to require the user to run a script that
+would patch his rcfiles (i.e., ~/.bashrc, ~/.zshrc, etc) to set
+$S on startup. That turned out to be unreliable - it was better
+to teach people how to distinguish those processes that inherit
+$S from Emacs from those that don't, and let the experts patch
+their rcfiles by hand.
+
+
+
+`browse-url' and friends
+========================
+If you place the point on the URL below
+
+ http://www.gnu.org/software/emacs/emacs-paper.html
+
+and run `M-x browse-url', Emacs will make an external browser
+visit the remote version of that URL. One (bad) way to visit the
+local copy of that URL is to modify the URL above by hand to
+adjust it to your value of $S, until you obtain something like
+this:
+
+ file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
+
+and then run `M-x browse-url' on it.
+
+One - rather primitive - way of visiting the local copy of that
+URL with find-file is to modify the URL by hand, replacing its
+\"http://\" with n \"$S/http/\", and then visit that file. For
+example:
+
+ http://www.gnu.org/software/emacs/emacs-paper.html
+ (find-file \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+ (find-fline \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+
+If you put the point on the URL and run `M-x brfl' on it you will
+visit the local copy \"as a file\", with `find-file' /
+`find-fline'. Visiting URLs - or their local copies - is
+something that we do so frequently that we need ways to do that
+with few keystrokes, which is why `brfl' has a short - and
+cryptic - name. The conventions are:
+
+ \"br\" is the common prefix for all the browse-url-like
+ functions in eev,
+ \"f\" means to use `find-fline' (or, equivalently, `find-file'),
+ \"l\" is an optional suffix meaning to use the local copy.
+
+The details on how to create these \"brxxx functions\" are here:
+ (find-brxxx-intro)
+
+" rest)))
+
+;; (find-enode "Command Index" "browse-url")
+;; (find-efunction 'browse-url)
+;; (find-elnode "System Environment")
+;; (find-enode "Environment")
+;; (find-eevfile \"eev.el\" \"$HOME/snarf\")
+
+;; (find-psne-intro)
+
+
+
+
+;;; _ _ _
+;;; | |__ _ ____ ____ ____ __ (_)_ __ | |_ _ __ ___
+;;; | '_ \| '__\ \/ /\ \/ /\ \/ /____| | '_ \| __| '__/ _ \
+;;; | |_) | | > < > < > <_____| | | | | |_| | | (_) |
+;;; |_.__/|_| /_/\_\/_/\_\/_/\_\ |_|_| |_|\__|_| \___/
+;;;
+;; �find-brxxx-intro� (to ".find-brxxx-intro")
+
+(defun find-brxxx-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-brxxx-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-brxxx-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-brxxx-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.
+
+
+
+\[Note: these intros refer to the code in \"eev-code.el\", that
+is not yet loaded by default!]
+
+
+Introduction
+============
+Suppose that `plic' is a function that expects a file name, and
+`pluc' is a function that expects a URL; to make these ideas more
+concrete, suppose that these are typical calls to them,
+
+ (plic \"/foo/bar/b\")
+ (pluc \"http://a/b\")
+
+and that both `plic' and `pluc' invoke external programs to visit
+the given file name or url - `plic' opens a file with a PDF
+viewer, and `pluc' makes a certain web browser open the given
+URL. And suppose that both `plic' and `pluc' are just Emacs
+\"functions\", not \"commands\" - remember that \"commands\" are
+the things that can be invoked with `M-x'.
+
+We saw in
+
+ (find-psne-intro)
+
+that by \"psne-ing\" the URL \"http://a/b\" we create a local
+copy of its contents in \"$S/http/a/b\". Emacs has a family of
+`browse-url' functions, briefly described in:
+
+ (find-enode \"Browse-URL\")
+
+We will soon see in detail how we can create families of
+\"browse-url-like\" commands associated to each function like
+`plic' or `pluc'. Briefly, if we run
+
+ (code-brurl 'pluc :remote 'brpluc :local 'brplucl)
+ (code-brfile 'plic :local 'brplicl)
+
+we create commands `brpluc', `brplucl', and `brplicl', that can
+be invoked when the point is on a URL to visit either that URL or
+the local copy of its contents with `pluc' or `plic'; by
+convention, the `brxxx' commands that end with \"l\" operate on
+the local copy, and all of them start with \"br\" and have short
+\(and unfortunately often cryptic) names, as they're meant to be
+invokeable with few keystrokes.
+
+
+
+A test
+======
+All commands created by calls to `code-brurl' and `code-brfile'
+display a message in the echo acrea that explain which function
+like `pluc' or `plic' they invoked, with what argument, and what
+result it returned. We can use that to understand them better.
+Run this,
+
+ (defun pluc (url) url)
+ (defun plic (filename) filename)
+ (code-brurl 'pluc :remote 'brpluc :local 'brplucl)
+ (code-brfile 'plic :local 'brplicl)
+
+and now with the point on the URL below
+
+ http://a/b
+
+type `M-x brpluc', `M-x brplucl', and `M-x brplicl'. You should
+see messages like this in your echo area:
+
+ (pluc \"http://a/b\") -> \"http://a/b\"
+ (pluc \"file:///home/edrx/snarf/http/a/b\") ->
\"file:///home/edrx/snarf/http/a/b\"
+ (plic \"/home/edrx/snarf/http/a/b\") -> \"/home/edrx/snarf/http/a/b\"
+
+
+
+The dired variation
+===================
+
+In dired mode each line corresponds to a file
+
+
+" rest)))
+
+;; (find-brxxx-intro)
+;; (find-brxxx-intro "M-x brpluc")
+
+
+
+
+;;; _
+;;; ___ ___ (_)_ _ _ __ ___ _ __
+;;; / _ \/ _ \| | | | | '_ ` _ \| '_ \
+;;; | __/ __/| | |_| | | | | | | |_) |
+;;; \___|\___|/ |\__,_|_| |_| |_| .__/
+;;; |__/ |_|
+;;
+;; (find-elnode "Defining Commands")
+;; (find-enode "Arguments")
+;; (find-TH "emacs" "eejump")
+;; http://angg.twu.net/emacs.html#eejump
+;; file:///home/edrx/TH/L/emacs.html#eejump
+;; �find-eejump-intro� (to ".find-eejump-intro")
+
+(defun find-eejump-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eejump-intro)*"))
+ (apply 'find-estring "\
+\(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:
+" rest)))
+
+;; (find-eejump-intro)
+
+
+
+
+;;; _ __ _ _ _
+;;; _ __ __| |/ _| | (_) | _____
+;;; | '_ \ / _` | |_ _____| | | |/ / _ \
+;;; | |_) | (_| | _|_____| | | < __/
+;;; | .__/ \__,_|_| |_|_|_|\_\___|
+;;; |_|
+;;
+;; �find-pdf-like-intro� (to ".find-pdf-like-intro")
+
+(defun find-pdf-like-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-pdf-like-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-pdf-like-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-pdf-like-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.
+
+
+
+
+PDF-like documents
+==================
+Let's introduce a bit of (improvised!) terminology: we will say
+that a document is \"PDF-like\" when it is in a format like PDF,
+PostScript, DVI or DJVU - i.e., divided into pages. Emacs has a
+standard mode for viewing PDF-like documents,
+
+ (find-enode \"Document View\")
+
+but we will see a more eev-like way of pointing to pages of
+PDF-like documents.
+
+
+
+
+Two test documents
+==================
+The following script creates two PDF-like documents - a DVI and a
+PDF - that we will use in the examples below.
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd /tmp/
+cat > /tmp/foo.tex <<'%%%'
+\\documentclass[12pt,oneside]{book}
+\\begin{document}
+\\Huge
+\\frontmatter
+a \\newpage
+b \\newpage
+c \\newpage
+\\mainmatter
+\\chapter{One}
+\\newpage foo
+\\chapter{Two}
+\\end{document}
+%%%
+ latex foo.tex
+pdflatex foo.tex
+
+In these two documents the page _names_ do not correspond to the
+page _numbers_; the pages are named \"i\", \"ii\", \"iii\",
+\"1\", \"2\", \"3\", but their numbers are 1, 2, 3, 4, 5, 6.
+In a table:
+
+ number name contents
+ ----------------------
+ 1 i a
+ 2 ii b
+ 3 iii c
+ 4 1 Chapter 1 - One
+ 5 2 foo
+ 6 3 Chapter 3 - Two
+
+
+
+
+Using external viewers
+======================
+The following sexps can be used to open the documents
+\"/tmp/foo.dvi\" and \"/tmp/foo.pdf\" on the first page of
+Chapter 1 - i.e., the page whose number is 4, and whose \"name\"
+is 1 - using two of my favorite viewers, xdvi and xpdf, and a
+low-level function, `find-bgprocess':
+
+ (find-bgprocess '(\"xdvi\" \"+4\" \"/tmp/foo.dvi\"))
+ (find-bgprocess '(\"xpdf\" \"/tmp/foo.pdf\" \"4\"))
+
+Alternatively, we can invoke these viewers like this,
+
+ (find-xdvi-page \"/tmp/foo.dvi\" 4)
+ (find-xpdf-page \"/tmp/foo.pdf\" 4)
+
+or, as they ignore extra arguments, like this,
+
+ (find-xdvi-page \"/tmp/foo.dvi\" (+ 3 1) \"Chapter 1\")
+ (find-xpdf-page \"/tmp/foo.pdf\" (+ 3 1) \"Chapter 1\")
+
+where the `(+ 3 1)' and the \"Chapter 1\" are just to make these
+links more readable by humans. The `3' is what we will call the
+\"offset\" of the document: a quantity that can be added to page
+\"names\" (outside the \"front matter\" of the document) to
+convert them to page \"numbers\".
+
+Let's introduce more terminology. Programs like xdvi and xpdf are
+\"external viewers for PDF-like documents\", but that's too long,
+so let's shorten this to \"external PDF-like viewers\", or
+\"external viewers\", or just \"viewers\"; `find-xdvi-page',
+`find-xpdf-page' and similar functions are \"medium-level viewing
+words\".
+
+
+
+
+The high-level way
+==================
+File names of PDF-like documents are often very long - especially
+for documents that we have \"psne\"-ed from the web. To avoid
+having to keep copies of these file names everywhere we can use
+`code-c-d'-like words - like these:
+
+ (code-xdvi \"fd\" \"/tmp/foo.dvi\")
+ (code-xpdf \"fp\" \"/tmp/foo.pdf\")
+ (find-fdpage (+ 3 1) \"Chapter 1\")
+ (find-fppage (+ 3 1) \"Chapter 1\")
+
+Each medium-level viewing word has an associated code-c-d-like
+word - that creates \"high-level viewing words\". In the example
+above, we used `code-xdvi' to create the high-level viewing word
+`find-fdpage', that invokes `find-xdvi-page', and `code-xpdf' to
+create the high-level viewing word `find-fppage', which invokes
+`find-xpdf-page',
+
+Note that the \"fd\" in `find-fdpage' stands for not only the
+filename - \"/tmp/foo.dvi\" - but also for the medium-level word
+to be used - `find-xdvi-page'; same for \"fp\".
+
+
+
+
+Default external viewers
+========================
+We saw that for each of the supported formats of PDF-like
+documents - DVI, PostScript, PDF, DJVU - there are medium-level
+and high-level viewing words that use specific programs; for
+example, for \"xpdf\" we have `find-xpdf-page' and `code-xpdf',
+and for \"evince\" we have `find-evince-page' and `code-evince'.
+But for each of the formats we also have words that use the
+current default viewer for that format:
+
+ Format Medium-level High-level
+ ----------------------------------------
+ DVI find-dvi-page code-dvi
+ PostScript find-ps-page code-ps
+ PDF find-pdf-page code-pdf
+ DJVU find-djvu-page code-djvu
+
+The four `find-<formatname>-page' words above are aliases to
+`find-<viewername>-page' names, and to change a default viewer
+you should use a `defalias' on the `find-', like these:
+
+ (defalias 'find-pdf-page 'find-evince-page)
+ (defalias 'find-pdf-page 'find-xdpf-page)
+
+After running a `defalias' like the above all the high-level
+viewing words defined using `code-pdf' will automatically switch
+to the new default viewer (because words defined with `code-pdf'
+call `find-pdf-page').
+
+
+
+
+PDF-like documents as text
+==========================
+Some PDF-like documents can be converted to text - usually uglily
+and imprecisely, but the result is often useful anyway - by
+external programs like \"pdftotext\" and \"djvutxt\". The
+medium-level sexps below invoke these programs on the given
+filenames and displays their output in an Emacs buffer:
+
+ (find-pdftotext-text \"/tmp/foo.pdf\")
+ (find-djvutxt-text \"/tmp/foo.djvu\")
+
+We can also use the correspondent generic medium-level words,
+that are aliases to the default converters:
+
+ (find-pdf-text \"/tmp/foo.pdf\")
+ (find-djvu-text \"/tmp/foo.djvu\")
+
+As the output of these converters is also divided into pages -
+with formfeeds as separators - it is easy to jump to specific
+pages in the output, and if the first argument after the file
+name is a number it is interpreted as a page number; string
+arguments coming after that are interpreted as strings to be
+search (forward) for. So these links make sense:
+
+ (find-pdf-text \"/tmp/foo.pdf\" (+ 3 1))
+ (find-pdf-text \"/tmp/foo.pdf\" (+ 3 1) \"Chapter 1\")
+
+and note that the following pair of links make sense too - the
+first one calls an external viewer, the second one opens the
+conversion to text:
+
+ (find-pdf-page \"/tmp/foo.pdf\" (+ 3 1) \"Chapter 1\")
+ (find-pdf-text \"/tmp/foo.pdf\" (+ 3 1) \"Chapter 1\")
+
+Note that they both point to the same page... The argument
+\"Chapter 1\" is ignored in the first link, but when a pair of
+links like that appear on consecutive lines it is clear for human
+readers that they are both links to the same place, only rendered
+in different ways. Note that the passage from this:
+
+ (find-pdf-text \"/tmp/foo.pdf\" (+ 3 1))
+
+to this:
+
+ (find-pdf-text \"/tmp/foo.pdf\" (+ 3 1))
+ (find-pdf-text \"/tmp/foo.pdf\" (+ 3 1) \"Chapter 1\")
+
+is a special case of \"refining hyperlinks\", an idea that we saw
+in:
+
+ (find-eval-intro \"Refining hyperlinks\")
+
+
+
+
+High-level hyperlinks to pdf-like documents
+===========================================
+By executing
+
+ (code-pdf \"fp\" \"/tmp/foo.pdf\")
+ (code-pdf-text \"fp\" \"/tmp/foo.pdf\" 3)
+
+we can use shorter hyperlinks, like
+
+ (find-fppage (+ 3 1) \"Chapter 1\")
+ (find-fptext (+ 3 1) \"Chapter 1\")
+
+instead of the longer forms with `find-pdf-page' and
+`find-pdf-text'. This works exactly like `code-c-d', as explained
+here:
+
+ (find-code-c-d-intro)
+
+Try these sexps to see the code that the `code-pdf' and the
+`code-pdf-text' above execute:
+
+ (find-code-pdf \"fp\" \"/tmp/foo.pdf\")
+ (find-code-pdf-text \"fp\" \"/tmp/foo.pdf\" 3)
+
+There is a wrapping comand for producing these
+`code-pdf'/`code-pdf-text' pairs quickly - `M-P'. Try it here:
+
+ fp /tmp/foo.pdf
+
+
+
+
+Producing and refining hyperlinks to pages
+==========================================
+We also have something like this
+
+ (find-eval-intro \"Producing and refining hyperlinks\")
+
+for pdf-like documents, that will let us produce hyperlinks to
+the current page of the current pdf-like document very quickly,
+but it depends on several hacks.
+
+Note that the functions `code-pdf', `code-pdf-text',
+`find-xxxpage', `find-xxxtext', set the global variables
+`ee-page-c', `ee-page-fname', and `ee-page-offset'. You can
+inspect their definitions with:
+
+ (find-code-pdf \"fp\" \"/tmp/foo.pdf\")
+ (find-code-pdf-text \"fp\" \"/tmp/foo.pdf\" 3)
+
+Here's how these variables are used. Try this:
+
+ (code-pdf \"fp\" \"/tmp/foo.pdf\")
+ (code-pdf-text \"fp\" \"/tmp/foo.pdf\" 3)
+ (kill-new \"Two\")
+ (eek \"M-h M-p\")
+
+You should get a page with several hyperlinks to the \"current
+page\" of the current pdf-like document, including some like
+these:
+
+ (find-fppage 1)
+ (find-fptext 1)
+ (find-fppage (+ 3 -2))
+ (find-fptext (+ 3 -2))
+
+ (find-fppage 1 \"Two\")
+ (find-fptext 1 \"Two\")
+ (find-fppage (+ 3 -2) \"Two\")
+ (find-fptext (+ 3 -2) \"Two\")
+
+Where did the \"fp\", the \"1\", the \"3\", the \"-2\" and the
+\"Two\" above come from?
+
+The page number, which in the links above is sometimes \"1\",
+sometimes \"(+ 3 -2)\", is obtained by counting the number of
+formfeeds before point; this makes sense only when we are
+visiting the buffer generated by \"(find-fptext ...)\". The
+\"fp\" is taken from the variable `ee-page-c', which was set by
+`(code-pdf-text \"fp\" ...)' or by `(find-fptext ...)'; same for \"3\",
+which is taken from the variable `ee-page-offset'. Finally, the \"Two\"
+is the last kill, from the top of the kill-ring; we usually set it by
+selecting a region of text from the `(find-fptext ...)' buffer and
+typing `M-w'.
+
+An alternative way to produce hyperlinks to pages, which, as the hack
+above, also uses `ee-page-c' and `ee-page-offset', is to prepare a
+series of lines with a page number followed by a text that will play a
+similar role to the \"last kill\", and then type `M-Q' on each line. Try
+this below, by first executing the `code-pdf-text' then typing four
+`M-Q's.
+
+ (code-pdf \"debt\" \"~/books/graeber__debt.pdf\")
+ (code-pdf-text \"debt\" \"~/books/graeber__debt.pdf\" 8)
+
+ 1 1 On The Experience of Moral Confusion
+ 21 2 The Myth of Barter
+ 43 3 Primordial Debts
+ 73 4 Cruelty and Redemption
+
+It is usually not hard to produce such page-number-plus-text
+lines for `M-Q' from the table of contents of a book. The ones
+above were extracted from
+
+ (find-debttext 7 \"Contents\")
+
+with a bit of fiddling by hand and keyboard macros. Keyboard
+macros are VERY useful; if you don't use them yet, see:
+
+ (find-enode \"Keyboard Macros\")
+" rest)))
+
+;; (find-pdf-like-intro)
+
+
+
+
+;;; _ _ __ _ _
+;;; __ _ _ _ __| (_) ___ / /_ _(_) __| | ___ ___
+;;; / _` | | | |/ _` | |/ _ \ / /\ \ / / |/ _` |/ _ \/ _ \
+;;; | (_| | |_| | (_| | | (_) / / \ V /| | (_| | __/ (_) |
+;;; \__,_|\__,_|\__,_|_|\___/_/ \_/ |_|\__,_|\___|\___/
+;;;
+;; �find-audiovideo-intro� (to ".find-audiovideo-intro")
+;; (find-intro-links "audiovideo")
+
+(defun find-audiovideo-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-audiovideo-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-audiovideo-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-audiovideo-intro\")
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+
+
+Time offsets
+============
+Links to audio and video files are similar to links to pdf-like
+documents, but instead of page numbers we use \"time offsets\" to
+refer to positions. Time offsets are strings like 1:23, 12:34, or
+1:23:45. The sexp hyperlinks below should all work if you have the
+files that they refer to:
+
+ (find-audio \"/tmp/mysong.mp3\")
+ (find-audio \"/tmp/mysong.mp3\" \"1:23\")
+ (find-audio \"/tmp/mysong.mp3\" \"1:23\" \"comment are ignored\")
+ (find-video \"/tmp/myvideo.mp4\")
+ (find-video \"/tmp/myvideo.mp4\" \"1:23\")
+ (find-video \"/tmp/myvideo.mp4\" \"1:23\" \"comment are ignored\")
+
+Note that they work by invoking an external player - mplayer, by
+default - and its error messages appear here:
+
+ (find-ebuffer \"*Messages*\")
+
+
+
+
+Shorter hyperlinks to audio and video files
+===========================================
+If you type `M-V' (`eewrap-audiovideo') on a line containing a
+shorthand word and a file name of an audio or video file, for
+example, here,
+
+ sunwillset ~/Zoe_Keating/Sun_Will_Set.ogg
+
+you will get something like this:
+
+ ;; (find-fline \"~/Zoe_Keating/\")
+ (code-audio \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
+ (code-video \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
+ ;; (find-sunwillset)
+ ;; (find-sunwillset \"0:00\")
+
+you should delete the line with the wrong sexp by hand - in this
+case the wrong one is the one with `code-video', as we are
+working with a sound file - and execute the other one; this will
+define a function called `find-sunwillset', that plays the audio
+file with `find-audio'. Run this this sexp to inspect its code:
+
+ (find-code-audio \"sunwillset\" \"/tmp/Zoe_Keating__Sun_Will_Set.ogg\")
+
+you will notice that running `find-sunwillset' sets a variable,
+with:
+
+ (setq ee-audiovideo-last 'find-sunwillset)
+
+As we shall see soon, some operations play again the default
+audio or video file, starting from some given time offset. The
+default is always what is stored in `ee-audiovideo-last', and
+each call to a short hyperlink of the form `find-xxxaudio' or
+`find-xxxvideo' sets that variable.
+
+
+
+`eev-avadj-mode'
+================
+\"avadj-mode\" is a shorthand for \"audio/video adjust mode\".
+When `eev-avadj-mode' is active we get keys for adjusting time
+offsets quickly and for playing again the default audio or video
+file at a given time offset, all of this without moving the
+point. The keys are:
+
+ M-- decrease the time offset by one second
+ M-+ increase the time offset by one second
+ M-= same as M-+, for convenience
+ M-p play the default audio/video file at a time offset
+
+You can toggle eev-avadj-mode on and off with `M-x
+eev-avadj-mode', or with this sexp:
+
+ (eev-avadj-mode)
+
+When it is on you will see an \"avadj\" at the mode line. Let's
+examine `M--' and `M-+' first. With eev-avadj-mode on, try typing
+several `M--'s and `M-+'s (or `M-='s) on the line below:
+
+ This time offset - 9:59 - will change
+
+Now, as an exercise, try to use `M--'s and `M-+'s/`M-='s, plus
+`M-h M-2' (`ee-duplicate-this-line') and other more standard
+editing commands, to convert this line
+
+ (find-exampleaudio \"0:00\")
+
+into:
+
+ (find-exampleaudio \"0:00\")
+ (find-exampleaudio \"0:12\" \"blah\")
+ (find-exampleaudio \"0:30\" \"bleh\")
+
+That should give you an idea of how to index audio or video files
+- by creating elisp hyperlinks, with comments, to specific
+positions in them. Of course in a real-world situation we would
+execute these sexps occasionally to check if they are really
+pointing to the right places, and then make further adjustments;
+we are not doing that yet.
+
+
+
+The time-from-bol
+=================
+All the keys in eev-avadj-mode operate on the \"time-from-bol\"
+of the current line: the first occurrence, in the current line,
+of a string that looks like a time offset. Note that the search
+starts from the beginning of the line (\"-from-bol\"), and if
+there are several possibilities, the first one is chosen.
+
+Remember that `M-e' has a variant that just highlights what would
+be executed, instead of evaluating a sexp:
+
+ (find-eval-intro \"`M-0 M-e'\")
+
+`M-p' also has something like this: `M-0 M-p' highlights the
+time-from-bol and displays in the echo area the sexp that it
+would execute to invoke a player - instead of running that sexp.
+Try to evaluate these sexps:
+
+ (code-audio \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
+ (find-sunwillset)
+ ;; ^ don't worry if this fails - we are only calling it
+ ;; to set `ee-audiovideo-last'
+
+and now try `M-0 M-p' on these lines:
+
+ ;; 4:19 blah
+ ;; 2:19
+
+For more realistic examples, see:
+
+ (find-videos-intro)
+
+
+
+
+Youtube-dl
+==========
+Videos at Youtube are identified by unique 11-char codes that are
+assigned to them when they are uploaded. We will call those 11-char
+codes \"hashes\", even though the term is not totally adequade in this
+case, and we will explain the main ideas considering the case of an
+imaginary video whose title is just TITLE, and whose hash is
+\"abcdefghijk\". The URL to access that video at Youtube would be this:
+
+ http://www.youtube.com/watch?v=abcdefghijk
+ \\---------/
+ its hash
+
+If we execute this on a shell,
+
+ cd /tmp/
+ youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'
+
+then youtube-dl would download a local copy of the video; due to the
+option \"-t\" (\"--title\"), the name of the local copy would have both
+the title of the video and its hash, and, if the video is in MP4
+format, that would be
+
+ /tmp/TITLE-abcdefghijk.mp4.part
+
+during the download, and would be renamed to
+
+ /tmp/TITLE-abcdefghijk.mp4
+
+as soon as the download is finished.
+
+
+
+
+Downloading a local copy
+========================
+Place the point at hash in the URL below,
+
+ http://www.youtube.com/watch?v=abcdefghijk
+
+and run `M-x find-youtubedl-links'; `find-youtubedl-links' will use
+the hash at point as a default for one of its arguments, will run
+something equivalent to this sexp,
+
+ (find-youtubedl-links nil nil \"abcdefghijk\")
+
+and will create a buffer like this:
+
+ ___________________________________________________________________________
+ |# (find-youtubedl-links \"/tmp/\" \"{title}\" \"abcdefghijk\" \"{ext-}\"
\"{stem}\") |
+ |# (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
|
+ | |
+ |# (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
|
+ |# (find-youtubedl-links \"~/videos/tech/\" nil \"abcdefghijk\" nil
\"{stem}\") |
+ |# (find-youtubedl-links \"/tmp/videos/\" nil \"abcdefghijk\" nil
\"{stem}\") |
+ |# (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
|
+ |# (find-efunction 'find-youtubedl-links) |
+ | |
+ | (eepitch-shell2) |
+ | (eepitch-kill) |
+ | (eepitch-shell2) |
+ |# http://www.youtube.com/watch?v=abcdefghijk |
+ |# http://www.youtube.com/watch?v=abcdefghijk#t=0m00s |
+ |# http://www.youtube.com/watch?v=abcdefghijk#t=0h00m00s |
+ |cd /tmp/ |
+ |youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk' |
+ | |
+ |# youtube-dl -t -F 'http://www.youtube.com/watch?v=abcdefghijk' |
+ |# youtube-dl -t -f 18 'http://www.youtube.com/watch?v=abcdefghijk' |
+ | |
+ |# (find-es \"video\" \"youtube-dl\")
|
+ |# (find-fline \"/tmp/\" \"abcdefghijk\")
|
+ |# (find-fline \"/tmp/\" \"{title}-abcdefghijk\")
|
+ |# (find-fline \"/tmp/\" \"{title}-abcdefghijk{ext-}\")
|
+ |# (find-video \"/tmp/{title}-abcdefghijk{ext-}\")
|
+ |# (find-video \"/tmp/{title}-abcdefghijk{ext-}.part\")
|
+ |# (code-video \"{stem}video\" \"/tmp/{title}-abcdefghijk{ext-}\")
|
+ |# (code-video \"{stem}video\" \"/tmp/{title}-abcdefghijk{ext-}.part\")
|
+ |# (find-{stem}video) |
+ |# (find-{stem}video \"0:00\")
|
+ | |
+ |# Error messages (for the player): |
+ |# (find-ebuffer \"*Messages*\")
|
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental)----------------------|
+ |___________________________________________________________________________|
+
+which has LOTS of things... the part
+
+ (eepitch-shell2)
+ (eepitch-kill)
+ (eepitch-shell2)
+ cd /tmp/
+ youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'
+
+is obvious: it is an eepitch script that downloads a local copy
+of the video from Youtube.
+
+
+
+
+Guessing the title and extension
+================================
+Let's simulate what would happen after the eepitch script above -
+Execute this:
+
+ (find-sh0 \"rm -v /tmp/TITLE-abcdefghijk*\")
+ (find-sh0 \"echo > /tmp/TITLE-abcdefghijk.mp4.part\")
+
+Now use `M-2 M-e' to compare the buffers generated by two calls
+to `find-youtubedl-links' below:
+
+ (find-youtubedl-links nil nil \"abcdefghijk\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\")
+
+In the second one we get a buffer where all occurrences
+of \"{title}\" have been substituted by \"TITLE\", and all
+occurrences of \"{ext-}\" by \".mp4\". What happenned was that
+
+ (ee-youtubedl-guess* \"/tmp/\" \"abcdefghijk\")
+ --> (\"/tmp/TITLE-abcdefghijk.mp4.part\")
+
+did find files what that hash string in their names in the
+directory \"/tmp/\", and the function `ee-youtubedl-split' has
+picked up the first of these file names and has split it into
+components:
+
+ (ee-youtubedl-split \"/tmp/TITLE-abcdefghijk.mp4.part\")
+ --> (\"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\" \".mp4.part\")
+
+The last of these components is what we will call the \"ext\" -
+the \"full extension\" - and the previous one is the \"ext-\" -
+the \"extension minus its optional `.part'\". The first three
+components are the \"dir\", the \"title\", and the \"hash\".
+
+
+
+
+The first lines regenerate the buffer
+=====================================
+The arguments to `find-youtubedl-links' are:
+
+ (find-youtubedl-links DIR TITLE HASH EXT- STEM)
+
+and we just saw how `ee-youtubedl-guess*' and
+`ee-youtubedl-split' can be used to guess TITLE, EXT and EXT-
+from DIR and HASH.
+
+All the arguments to `find-youtubedl-links' have defaults,
+that are used when the received arguments are nil:
+
+ * when HASH is nil, use the youtube hash around point,
+ or \"{hash}\" if none;
+ * when DIR is nil, use the value of `ee-youtubedl-dir',
+ or \"{dir}\" if none;
+ * when TITLE or EXT- are nil use the guessing method described
+ above, and when they fail use \"{title}\" or \"{ext-}\";
+ * when STEM is nil, use \"{stem}\".
+
+The first two lines in a `find-youtubedl-links' regenerate the
+buffer, and are usually equivalent to one another. In the buffer
+generated by:
+
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\")
+
+they are:
+
+ (find-youtubedl-links \"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\"
\"{stem}\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
+
+The first one has only non-nil arguments - all the rules for
+guesses and defaults have been applied - where in the second one
+TITLE and EXT- are made nil.
+
+
+
+Selecting a directory
+=====================
+The second block of lines in the `find-youtubedl-links' buffer
+are used to let we switch the directory quickly. If we just
+execute `M-x find-youtubedl-links' with the point on our example
+hash, or, equivalently, if we do this,
+
+ (find-youtubedl-links nil nil \"abcdefghijk\")
+
+you will see that the first two lines will be:
+
+ (find-youtubedl-links \"~/videos/\" \"{title}\" \"abcdefghijk\" \"{ext-}\"
\"{stem}\")
+ (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
+
+which means that the guessing process didn't find a downloaded
+copy, as TITLE is \"{title}\" and EXT- is \"{ext-}\". That's because
+we are using \"~/videos/\" as the DIR, and our file
+
+ /tmp/TITLE-abcdefghijk.mp4.part
+
+is elsewhere, and the guessing functions only search in one
+directory...
+
+The second block contains these sexps,
+
+ (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
+ (find-youtubedl-links \"~/videos/tech/\" nil \"abcdefghijk\" nil \"{stem}\")
+ (find-youtubedl-links \"/tmp/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
+
+and if we execute the last one we set DIR to \"/tmp/\".
+
+To change the dir strings \"~/videos/\", \"~/videos/tech/\", \"/tmp/videos/\",
+\"/tmp/\", that appear in the second block of `find-youtubedl-links'
+buffers, change the variables `ee-youtubedl-dir', `ee-youtubedl-dir2',
+`ee-youtubedl-dir3', `ee-youtubedl-dir4.'
+
+
+
+How to download
+===============
+
+
+
+Test the download
+=================
+
+
+Create short links
+==================
+
+
+
+
+ (find-youtubedl-links \"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\"
\"{stem}\")
+ (find-youtubedl-links nil nil \"abcdefghijk\")
+
+ (find-eev \"eev-audiovideo.el\")
+ (find-eev \"eev-audiovideo.el\" \"eev-avadj-mode\")
+
+" pos-spec-list)))
+
+;; (find-audiovideo-intro)
+
+
+
+
+
+;;; _ _ _ _ _
+;;; _ __ ___ _ _| | |_(_)_ _(_)_ __ __| | _____ __
+;;; | '_ ` _ \| | | | | __| \ \ /\ / / | '_ \ / _` |/ _ \ \ /\ / /
+;;; | | | | | | |_| | | |_| |\ V V /| | | | | (_| | (_) \ V V /
+;;; |_| |_| |_|\__,_|_|\__|_| \_/\_/ |_|_| |_|\__,_|\___/ \_/\_/
+;;;
+;; �find-multiwindow-intro� (to ".find-multiwindow-intro")
+;; (find-intro-links "multiwindow")
+
+(defun find-multiwindow-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-multiwindow-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-multiwindow-intro)
+Source code: (find-efunction 'find-multiwindow-intro)
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+
+
+
+Introduction
+============
+In many situations - for example, when we want to script a
+debugger, or to test programs that have to talk to one another,
+or to control several external machines simultaneously - the
+default window setup for eepitch, which is this,
+
+ ____________________
+ | | |
+ | | |
+ | script | shell |
+ | | |
+ | | |
+ |__________|_________|
+
+is not enough; other setups, like these,
+
+ ______________________
+ | | | _________________________
+ | | shell A | | | |
+ | |___________| | script | GDB |
+ | script | | | | |
+ | | shell B | |____________|____________|
+ | |___________| | | |
+ | | | | program | program |
+ | | shell C | | I/O | source |
+ |__________|___________| |____________|____________|
+
+may be necessary. Eev comes with a few _low-level_ tools for
+creating these setups; they are not very smart, but they should
+be easy to understand and to tweak - and I have the impression
+that ideas for good high-level tools will only come from
+practical experimentation.
+
+
+
+`find-wset'
+===========
+Suppose that we are in a buffer A, and we want to create a window
+configuration with A at the left, and with the buffers B and C
+stacked on one another at the right. That is:
+
+ ___________ ___________
+ | | | | |
+ | | | | B |
+ | A | --> | A |_____|
+ | | | | |
+ | | | | C |
+ |___________| |_____|_____|
+
+To do that from the keyboard we could type this:
+
+ C-x 3 C-x o C-x b B RET C-x 2 C-x o C-x b C RET
+
+You can try that here (the initial `C-x 1' is an extra, for
+convenience):
+
+ (eek \"C-x 1 ;; delete-other-windows
+ C-x 3 ;; split-window-horizontally (left/right)
+ C-x o ;; other-window (-> right)
+ C-x b B RET ;; switch to the buffer `B'
+ C-x 2 ;; split-window-vertically (upper/lower)
+ C-x o ;; other-window (-> lower right)
+ C-x b C RET ;; switch to the buffer `C'
+ \")
+
+We can write something equivalent to that as a `progn', in a way
+that makes it easy to replace later the `C-x b B RET' and the
+`C-x b C RET' by arbitrary sexp hyperlinks. We get:
+
+ (progn (eek \"C-x 1 C-x 3 C-x o\")
+ (find-ebuffer \"B\")
+ (eek \"C-x 2 C-x o\")
+ (find-ebuffer \"C\")
+ (eek \"C-x o\")
+ )
+
+When I started to rewrite my window configurations into that form
+I realized that the `eek's were being used in a very limited way
+- they only invoked a very small repertoire of window commands,
+all of them starting with `C-x'. So maybe I should have an
+interpreter for a simple language of window commands and sexp
+hyperlinks, in the which window setup above could be expressed
+like this:
+
+ `(\"13o\"
+ (find-ebuffer \"B\")
+ \"2o\"
+ (find-ebuffer \"C\")
+ \"o\"
+ )
+
+`find-wset' supports something like that, but with all the window
+command strings collapsed into a single one, with \"_\"s meaning
+\"execute the next sexp from the sexp list\". The corresponding
+call to `find-wset' is:
+
+ (find-wset \"13o_2o_o\" '(find-ebuffer \"B\") '(find-ebuffer \"C\"))
+
+For the full list of supported window command characters - and
+how to extend it - see the source:
+
+ (find-eev \"eev-multiwindow.el\")
+
+
+
+
+Several eepitch targets
+=======================
+If we try to build a window setup like this one, with two eepitch
+targets, with just `find-wset', we will run into problems -
+
+ ________________________
+ | | |
+ | | *shell* |
+ | script |_____________|
+ | | |
+ | | *shell 2* |
+ |__________|_____________|
+
+because `(eepitch-shell)' and `(eepitch-shell2)' try to create a
+shell buffer and put it in an _another_ window, not the one we
+are in... one solution is to call the `(eepitch-*)' sexps inside
+an `ee-here', like this:
+
+ (ee-here '(eepitch-shell))
+ (ee-here '(eepitch-shell2))
+
+where `ee-here' is a hack that runs a sexp in a way that
+preserves the current window configuration, then switches the
+buffer in the current selected window to the current eepitch
+target. We can use this to create the window setting above,
+
+ (find-wset \"13o2_o_o\"
+ ' (ee-here '(eepitch-shell))
+ ' (ee-here '(eepitch-shell2))
+ )
+
+This is too long - and would make a very bad one-liner - but a
+workaround is easy:
+
+
+
+
+Adding support for new characters in `find-wset'
+================================================
+The standard characters supported by `find-wset' are these:
+
+ char action key
+ ---- ---------------------------- ---------
+ `1' `delete-other-windows' (C-x C-1)
+ `2' `split-window-vertically' (C-x C-2)
+ `3' `split-window-horizontally' (C-x C-3)
+ `s' `split-window-sensibly'
+ `o' `other-window' (C-x o)
+ `+' `balance-windows' (C-x +)
+ `_' execute the next sexp
+
+but the action of each one is defined in a different function,
+and to add support for a new character, say, `=', we just need to
+define a function with the right name - in this case,
+`find-wset-='.
+
+The source code is simple enough, so take a look:
+
+ (find-eev \"eev-multiwindow.el\" \"find-wset-_\")
+ (find-eev \"eev-multiwindow.el\" \"find-wset-=\")
+ (find-eev \"eev-multiwindow.el\" \"find-wset-!\")
+
+Note that `find-wset-!' restarts an eepitch target, while
+`find-wset-=' will reuse an eepitch target if its buffer already
+exists.
+
+
+
+
+Eepitch to two targets
+======================
+Examples:
+
+ (defun eepitch2 (s1 s2) (find-wset \"13o2=o=o\" s1 s2))
+ (defun eepitch2! (s1 s2) (find-wset \"13o2!o!o\" s1 s2))
+ (eepitch2! '(eepitch-shell) '(eepitch-shell2))
+
+See: (find-prepared-intro)
+
+ [Example at find-prepared-intro]
+
+
+
+
+Executing key sequences at other windows
+========================================
+It is possible to use multi-window settings, together with the
+trick that `<f8>' on a red star line executes it as Lisp and
+moves down, to create tutorials for Emacs modes. An example:
+
+
+
+A tutorial for Info mode
+========================
+Here's a mini-tutorial for Info mode, demonstrating how to
+navigate in Info using the usual movement keys, plus TAB,
+<backtab>, RET, l (last), u (up), n (next), p (prev), q (quit),
+C-h i, and the digits 1-9. Note that the display in Info mode is
+like this:
+
+ ____________________________________________
+ |Next: Nonincremental Search, Up: Search | <- next/prev/up
+ | (emacs)Top > Search > Incremental Search | <- breadcrumbs
+ | |
+ | 19.1 Incremental Search | <- section number /
+ | | node name (long)
+ | (...) |
+ | |
+ |--:%%- *info* (emacs) Incremental Search |
+ |____________________________________________|
+
+Here:
+
+ Define some hacks
+ (defun ow (n) (other-window n))
+ (defun eeoe (code) (ow 1) (prog1 (eval code) (ow -1)))
+ (defun eeok (keystr) (eeoe `(eek ,keystr)))
+
+ Prepare the windows
+ (ee-kill-buffer \"*info*\")
+ (find-wset \"1so_o\" '(find-enode \"Search\"))
+
+ The arrows (and other movent keys) work as expected.
+ Watch the cursor in the Info window...
+ (eeok \"3*<down>\")
+ (eeok \"10*<right>\")
+
+ TAB and <backtab> move to the next and to the previous link.
+ Note that they consider all the links in a page, not only
+ the ones in menus - including the breadcrumb links at the top.
+ (eeok \"TAB ;; Info-next-reference\")
+ (eeok \"TAB ;; Info-next-reference\")
+ (eeok \"TAB ;; Info-next-reference\")
+ (eeok \"TAB ;; Info-next-reference\")
+ (eeok \"TAB ;; Info-next-reference\")
+ (eeok \"<backtab> ;; Info-prev-reference\")
+ (eeok \"<backtab> ;; Info-prev-reference\")
+ (eeok \"<backtab> ;; Info-prev-reference\")
+ (eeok \"<backtab> ;; Info-prev-reference\")
+
+ RET follows a link, l (last) goes back.
+ Watch the section number: 19 -> 32.3.6 -> 19.
+ (eeok \"RET ;; Info-follow-nearest-node\")
+ (eeok \"l ;; Info-history-back\")
+
+ The digits 1-9 can be used to go straight to subsections.
+ For example, a `4' would follow the 4th _menu_ link -
+ ignoring the non-menu links.
+ Watch the section number: 19 -> 19.1 -> 19.1.1.
+ (eeok \"1 ;; Info-nth-menu-item\")
+ (eeok \"1 ;; Info-nth-menu-item\")
+
+ The keys `u', `n', `p' (up, next, and prev) move through the
+ tree structure. Watch the section number:
+ 19.1.1 -u-> 19.1 -u-> 19 -n-> 20 -n-> 21 -p-> 20 -p-> 19
+ (eeok \"u ;; Info-up\")
+ (eeok \"u ;; Info-up\")
+ (eeok \"n ;; Info-next\")
+ (eeok \"n ;; Info-next\")
+ (eeok \"p ;; Info-prev\")
+ (eeok \"p ;; Info-prev\")
+
+ `q' leaves Info mode - more precisely, it buries the info buffer.
+ `C-h i' goes back to the Info buffer (or restarts info).
+ (eeok \"q ;; Info-exit\")
+ (eeok \"C-h i ;; info\")
+
+" pos-spec-list)))
+
+;; (find-multiwindow-intro)
+
+
+
+;;; _
+;;; _ __ ___(_)_ __ ___
+;;; | '__/ __| | '__/ __|
+;;; | | | (__| | | | (__
+;;; |_| \___|_|_| \___|
+;;;
+;; �find-rcirc-intro� (to ".find-rcirc-intro")
+;; (find-intro-links "rcirc")
+
+(defun find-rcirc-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-rcirc-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-rcirc-intro)
+Source code: (find-efunction 'find-rcirc-intro)
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+Not yet!
+========
+See: (find-eev \"eepitch.el\" \"eepitch-freenode\")
+" pos-spec-list)))
+
+;; (find-rcirc-intro)
+
+
+
+
+
+;;; _ _ _
+;;; | |_ ___ _ __ ___ _ __ | | __ _| |_ ___ ___
+;;; | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \/ __|
+;;; | || __/ | | | | | |_) | | (_| | || __/\__ \
+;;; \__\___|_| |_| |_| .__/|_|\__,_|\__\___||___/
+;;; |_|
+;;
+;; �find-templates-intro� (to ".find-templates-intro")
+;; (find-intro-links "templates")
+
+(defun find-templates-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-templates-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-templates-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-templates-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.
+
+
+`ee-template0'
+==============
+\(find-efunctiondescr 'ee-template0)
+\(find-efunction 'ee-template0)
+
+
+`ee-H', `ee-S', `ee-HS'
+=======================
+
+
+
+`find-find-links-links'
+=======================
+\(find-links-intro)
+\(find-find-links-links)
+\(find-efunction 'ee-stuff-around-point)
+interactive
+
+
+`find-elinks'
+=============
+\(find-efunction 'find-elinks)
+
+
+
+ (find-intro-links)
+\(find-eev \"eev-tlinks.el\" \"find-intro-links\")
+\(find-eevfile \"eev-tlinks.el\")
+
+
+
+The innards: templates
+======================
+Several functions in eev besides `code-c-d' work by replacing
+some substrings in \"templates\"; they all involve calls to
+either the function `ee-template0', which is simpler, or to
+`ee-template', which is much more complex.
+
+The function `ee-template0' receives a single argument - a
+string, in which each substring surrounded by `{...}'s is to be
+replaced, and replaces each `{...}' by the result of evaluating
+the `...' in it. For example:
+
+ (ee-template0 \"a{(+ 2 3)}b\")
+ --> \"a5b\"
+
+Usually the contents of each `{...}' is the name of a variable,
+and when the result of evaluating a `{...}' is a string the
+replacement does not get `\"\"'s.
+
+The function `ee-template' receives two arguments, a list and a
+template string, and the list describes which `{...}' are to be
+replaced in the template string, and by what. For example, here,
+
+ (let ((a \"AA\")
+ (b \"BB\"))
+ (ee-template '(a
+ b
+ (c \"CC\"))
+ \"_{a}_{b}_{c}_{d}_\"))
+
+ --> \"_AA_BB_CC_{d}_\"
+
+the \"{d}\" is not replaced. Note that the list (a b (c \"CC\"))
+contains some variables - which get replaced by their values -
+and a pair, that specifies explicitly that every \"{c}\" should
+be replaced by \"CC\".
+
+
+
+
+Templated buffers
+=================
+Introduction
+Conventions:
+ the first line regenerates the buffer,
+ buffer names with \"**\"s,
+ (find-evariable 'ee-buffer-name)
+ code
+
+`find-elinks'
+=============
+Variant: `find-elinks-elisp'
+
+`find-e*-links'
+===============
+\(find-eev \"eev-elinks.el\")
+
+`find-*-intro'
+==============
+
+`eewrap-*'
+==========
+
+Experiments
+===========
+\(find-efunction 'find-youtubedl-links)
+\(find-efunction 'ee-hyperlinks-prefix)
+\(find-efunction 'find-newhost-links)
+\(find-efunction 'find-eface-links)
+ Note that there is no undo.
+" rest)))
+
+;; (find-templates-intro)
+
+
+
+;; �find-anchors-intro� (to ".find-anchors-intro")
+;; (find-intro-links "anchors")
+
+(defun find-anchors-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-anchors-intro)*"))
+ (apply 'find-estring-lv "\
+\(Re)generate: (find-anchors-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-anchors-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.
+
+
+
+Introduction: `ee-anchor-format' and `to'
+=========================================
+A hyperlink like
+
+ (to \"foo\")
+
+jumps to the first occurrence of the string \"�foo�\" in the
+current buffer. The way to convert from \"foo\" to \"�foo�\" is
+controlled by the variable `ee-anchor-format', and the sexp
+`(to \"foo\")' is roughly equivalent the third sexp below:
+
+ ee-anchor-format
+ (format ee-anchor-format \"foo\")
+ (ee-goto-position (format ee-anchor-format \"foo\"))
+
+We will call strings in `��'s _anchors_, and we will say
+that `(to \"foo\")' jumps \"to the anchor `foo'\".
+
+Anchors can be used to create sections and indexes, as we shall
+see soon - but due to some old design decisions that I was never
+able to find good alternatives for, this tutorial needs to start
+with a BIG WARNING.
+
+
+
+WARNING: some glyphs need raw-text-unix
+=======================================
+The best way to make anchors stand out is to use colored glyphs
+for them - just like we made `^O's appear as red star glyphs for
+eepitch, as described here:
+
+ (find-eepitch-intro \"\\nRed stars\\n\")
+
+For historical reasons, the glyphs for `�' and `�' defined in
+
+ (find-eev \"eev-anchors.el\")
+
+use the characters 171 and 187; as far as I know, these
+characters are only \"safe\" - in the sense that Emacs will not
+try to convert them to anything else - in unibyte buffers. The
+best way to make sure that anchors with `��'s will work in a
+certain file is to put a \"Local variables:\" section at the end
+of it, as has been done in this buffer - and use that to set both
+the file coding to raw-text-unix and the value of
+`ee-anchor-format' to \"�%s�\".
+
+Note that if you change a \"Local variables:\" section by hand
+you will probably have to either reload the file or run `M-x
+normal-mode' to make the new settings take effect.
+
+
+
+Indexes
+=======
+In a situation like this,
+
+ �one� (to \"two\")
+ �two� (to \"one\")
+
+we have two anchors, and typing `M-e' at the line with the anchor
+\"one\" takes us to the line with the anchor \"two\", and typing
+`M-e' at the line with the anchor \"two\" takes us to the line
+with the anchor \"one\". In a situation like this we say that the
+anchors \"one\" and \"two\" _point to one another_.
+
+In a case like this,
+
+ �.three� (to \"three\")
+ �three� (to \".three\")
+
+where the names of two anchors pointing to one another differ by
+an initial dot, we will say that the anchor \".three\" is the
+\"index anchor\", and the anchor \"three\" is the \"section
+anchor\"; and one way to create an index for a file is to group
+all the index anchors together. For an example, see:
+
+ (find-eev \"eev-intro.el\" \".find-eev-intro\")
+
+
+
+
+Creating index/section anchor pairs
+===================================
+Use `M-A' (`eewrap-anchor'). Note that this has been briefly
+mentioned here:
+
+ (find-wrap-intro \"All wrapping functions\")
+
+It will convert a line with a syntax like
+
+ comment-prefix <anchor-name>
+
+into:
+
+ comment-prefix �.anchor-name� (to \"anchor-name\")
+ comment-prefix �anchor-name� (to \".anchor-name\")
+
+where comment-prefix is any string and anchor-name is a string
+without `<>'s. Note that the `<>'s, which are easy to type, are
+converted into `��'s, which are harder.
+
+
+
+find-anchor
+===========
+\(find-eev \"eev-anchors.el\")
+\(find-eev \"eev-anchors.el\" \"find-anchor\")
+
+
+code-c-d and :anchor
+====================
+\(find-eev \"eev-code.el\" \"ee-code-c-d-:anchor\")
+
+
+
+# Local Variables:
+# coding: raw-text-unix
+# ee-anchor-format: \"�%s�\"
+# End:
+" rest)))
+
+;; (find-anchors-intro)
+
+
+
+
+;;; _
+;;; _ __ _ __ ___ _ __ __ _ _ __ ___ __| |
+;;; | '_ \| '__/ _ \ '_ \ / _` | '__/ _ \/ _` |
+;;; | |_) | | | __/ |_) | (_| | | | __/ (_| |
+;;; | .__/|_| \___| .__/ \__,_|_| \___|\__,_|
+;;; |_| |_|
+;;
+;; �find-prepared-intro� (to ".find-prepared-intro")
+;; (find-eev "eev-bounded.el")
+
+(defun find-prepared-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-prepared-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-prepared-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-prepared-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.
+
+
+Prepared shells
+===============
+Long before eepitch had been created, eev had another way -
+technically much simpler, but clumsier from the user's point of
+view - to send commands to external shells (and other shell-like
+programs; but to simplify we will say just \"shells\"). Here is
+an overview of how it worked: if the user marked the three lines
+below,
+
+ rm -Rv /tmp/foo
+ mkdir /tmp/foo/
+ cd /tmp/foo/
+
+and typed `M-x eev' (which stood for \"Emacs-execute-verbosely\")
+then Emacs would save those three lines into a temporary script
+file, usually \"~/.eev/ee.sh\"; that would be just half of
+\"sending commands to an external shell\", and for the other half
+the user would have to go to an external prepared shell - that
+would usually be running in an xterm, and totally independent
+from Emacs - and type \"ee\" there. The shell had to be
+\"prepared\" in the sense that it would understand the \"ee\"
+command correctly, as meaning: \"execute the commands in the
+temporary script as if the user were typing them at the prompt\".
+Technically, that would mean that instead of calling
+\"~/.eev/ee.sh\" as a shell script its contents would be
+\"sourced\" - i.e., executed in the current shell context - and
+in verbose mode.
+
+Usually we would prepare bash by patching the file ~/.bashrc and
+putting the definition for \"ee\" there. We will discuss how to
+do that later; now let's test a simple environment in which `M-x
+eev' and \"ee\" work. First execute these two sexps:
+
+ (make-directory \"~/.eev/\" 'force)
+ (eev \"rm -Rv /tmp/foo\\nmkdir /tmp/foo/\\ncd /tmp/foo/\\n\")
+
+Now run this script
+
+ (eepitch-bash)
+ (eepitch-kill)
+ (eepitch-bash)
+export PS1='$PWD# '
+function ee () { set -v; . ~/.eev/ee.sh; set +v; }
+
+
+
+`ee'
+====
+\[Explain how several interpreters can be programmed to accept
+an `ee' command to execute temporary scripts\]
+
+ http://angg.twu.net/eev-article.html#making-progs-receive-cmds
+
+ (find-eev \"eev-langs.el\")
+ (find-eev \"eev-bounded.el\")
+ (find-eev \"eev-rctool\")
+
+
+
+
+An `ee' for Python
+==================
+Here is a simple way to make Python execute commands saved in a
+temporary script when the user types `ee()' (note that it is not
+just `ee' - the `()' is needed). We will show first an example in
+which the temporary script is prepared by running \"cat\" from a
+shell - then we will explain a more user-friendly way to save a
+region from the current buffer as the temporary script.
+
+Note that the demo below uses `find-wset', which is an
+advanced (i.e., hackish) feature explained here:
+
+ (find-multiwindow-intro)
+
+
+ (ee-kill-buffer \"*shell*\")
+ (ee-kill-buffer \"*python*\")
+ (find-wset \"13o2=o=o\" '(eepitch-shell) '(eepitch-python))
+ (eepitch-python)
+import os
+def ee():
+ execfile(os.getenv(\"HOME\")+\"/.eev/ee.py\", globals())
+
+ (eepitch-shell)
+cat > ~/.eev/ee.py <<'%%%'
+print(1+2)
+%%%
+
+ (eepitch-python)
+ee()
+
+ (eepitch-shell)
+cat > ~/.eev/ee.py <<'%%%'
+def foo (x):
+ return x*x
+
+print foo(5)
+%%%
+
+ (eepitch-python)
+ee()
+print(foo(6))
+
+
+
+`eepy'
+======
+The function `eev' receives three parameters, called `s', `e', and
+`altfile'; `e' and `altfile' are optional, and `s' should be either a
+string or a number. When `s' is a string, then the commands to be
+saved into the temporary script are taken from `s'; the numeric case
+will be discussed later.
+
+A call to
+
+ (eev \"print(1+2)\" nil \"~/.eev/ee.py\")
+
+writes \"print(1+2)\" (with an added trailing newline, but that's
+a technical detail) into the \"alternative file\"
+\"~/.eev/ee.py\" - the default would be \"~/.eev/ee.sh\". We can
+that to simplify our demo a bit:
+
+ (eek \"C-x 1\")
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+import os
+def ee():
+ execfile(os.getenv(\"HOME\")+\"/.eev/ee.py\", globals())
+
+ (eev \"print(1+2)\" nil \"~/.eev/ee.py\")
+ee()
+ (eev \"def foo (x):\\n return x*x\\n\\nprint foo(5)\" nil
\"~/.eev/ee.py\")
+ee()
+print(foo(6))
+
+
+ In the example below the first line defines a `eepy' in a
+ simplistic way:
+
+ (defun eepy (s &optional e) (eev s e \"~/.eev/ee.py\"))
+ (eek \"C-x 1\")
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+import os
+def ee():
+ execfile(os.getenv(\"HOME\")+\"/.eev/ee.py\", globals())
+
+ (eepy \"print(1+2)\")
+ee()
+ (eepy \"def foo (x):\\n return x*x\\n\\nprint foo(5)\")
+ee()
+print(foo(6))
+
+
+
+
+`M-x eepy' and `M-x eev'
+========================
+Now let's define a more realistic `eepy' - one that can also be
+called interactively. We want `M-x eepy' to save the current
+_region_ into the temporary script; `eepy' has to be a _command_,
+and we will use the argument \"r\" to its `interactive' clause,
+to make the function `eepy' receive two numbers - the start and
+the end of the region - and it will pass these two numbers to
+`eev'.
+
+ (defun eepy (s &optional e)
+ \"Save the region between S and E (or the string S) into ~/.eev/ee.py .\"
+ (interactive \"r\")
+ (eev s e \"~/.eev/ee.py\"))
+
+When the first argument, `s', to `eev', is a number, not a
+string, then `eev' expects the second argument, `e', to also be a
+number - and then `s' and `e' are considered as the extremities
+of a region of text in the current buffer. This idea - that the
+first argument can be either a string or a number - comes from:
+
+ (find-efunctiondescr 'write-region \"If START is a string\")
+
+But try these:
+
+ (ee-se-to-string \"foo\" nil)
+ (ee-se-to-string-with-nl \"foo\" nil)
+ (ee-se-to-string \"foo\\n\" nil)
+ (ee-se-to-string-with-nl \"foo\\n\" nil)
+ (ee-se-to-string (- (point) 5) (point))
+ (ee-se-to-string-with-nl (- (point) 5) (point))
+ (ee-se-to-string (point) (- (point) 5))
+ (ee-se-to-string-with-nl (point) (- (point) 5))
+
+
+
+
+\[Garbage:\]
+
+ (find-elnode \"Defining Commands\")
+ (find-defun-intro \"\\ninteractive\\n\")
+ (find-efunction 'eev)
+
+" rest)))
+
+;; (find-prepared-intro)
+
+;; (find-bashnode "Bourne Shell Builtins" "current shell context")
+
+
+
+
+;;; _ _ _
+;;; | |__ ___ _ _ _ __ __| | ___ __| |
+;;; | '_ \ / _ \| | | | '_ \ / _` |/ _ \/ _` |
+;;; | |_) | (_) | |_| | | | | (_| | __/ (_| |
+;;; |_.__/ \___/ \__,_|_| |_|\__,_|\___|\__,_|
+;;;
+;; �find-bounded-intro� (to ".find-bounded-intro")
+;; (find-intro-links "bounded")
+(defun find-bounded-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-bounded-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-bounded-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-bounded-intro\")
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+
+
+Note that you need to understand the concept of \"prepared
+shells\" quite well to be able to use this... see:
+
+ (find-prepared-intro)
+
+
+
+Bad news: I've been using this feature very little, and I have
+not yet adapted the old, crappy docs to the new \"intro\"
+format... =\\ So this is just a bunch of notes!
+
+Source code: \(find-eev \"eev-bounded.el\")
+Obsolete related code: \(find-eev \"eev-langs.el\")
+Old mentions to this: \(find-TH \"eev-article\" \"delimited-regions\")
+ http://angg.twu.net/eev-article.html#delimited-regions
+
+
+
+
+Delimited (\"bounded\") regions
+===============================
+Try:
+
+#
+# (eev-bounded)
+cd
+echo At: $PWD
+cd /tmp/
+echo At: $PWD
+
+#
+%
+% (eelatex-bounded)
+
+Hello
+
+%
+
+
+Defining new bounded functions
+==============================
+Try:
+
+ (find-code-bounded 'eev-bounded 'eev \"\\n#\\n\")
+ (find-code-bounded 'eev-bounded 'eev 'ee-delimiter-hash)
+
+as usual, when we remove the \"find-\"s the generated code is
+executed instead of displayed.
+
+
+
+
+The default bounded function
+============================
+...is stored in the variable `ee-bounded-function', and can be
+re-run with `M-x ee-bounded-function' (i.e., there's a function
+with the same name as the variable). I used to bind `f3' to that,
+but in modern Emacsen this is bound to a macro key:
+
+ (find-enode \"Basic Keyboard Macro\" \"<F3>\")
+
+so you should do something like this, but for your favourite key:
+
+ (define-key eev-mode-map [f3] 'ee-bounded-function)
+" pos-spec-list)))
+
+;; (find-bounded-intro)
+
+
+
+
+;;; _ _
+;;; ___| |__ __ _ _ __ _ __ ___| |___
+;;; / __| '_ \ / _` | '_ \| '_ \ / _ \ / __|
+;;; | (__| | | | (_| | | | | | | | __/ \__ \
+;;; \___|_| |_|\__,_|_| |_|_| |_|\___|_|___/
+;;;
+;; �find-channels-intro� (to ".find-channels-intro")
+;; (find-intro-links "channels")
+
+(defun find-channels-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-channels-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-channels-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-channels-intro\")
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+
+Introduction
+============
+Before eepitch had been invented, eev had two other ways to send
+commands to external shell-like programs. The first way was
+technically very simple - something like `M-x eev' would be used
+to save commands into a temporary script file, and then the user
+would type something like `ee' on a shell, which would make it
+run the commands in the temporary file. This required a temporary
+file and a \"prepared shell\" which could interpret `ee'
+correctly. The details are here:
+
+ (find-prepared-intro \"\\n`ee'\\n\")
+
+Here we will describe the second of the Old Ways - one in which
+the target program, which is usually a shell running in an xterm,
+receives a signal saying \"execute the sent command NOW\" as soon
+as the command is saved into a temporary file by Emacs... the
+problem is that this require an Expect script in addition to
+temporary files, and, as some people have said, all this is \"a
+nightmare to set up\".
+
+
+
+The innards
+===========
+We will start with a detailed low-level view of of what we have
+just summarized as to \"save a command into a temporary file,
+then send a signal to the external program etc etc\".
+
+Warning: this document is still VERY INCOMPLETE, and some parts
+of it are just notes, drafts, and links that may not work for
+you... =(
+
+ (find-eev \"eegchannel\")
+ (find-eev \"anim/\")
+ (find-eev \"anim/channels.anim\")
+ http://angg.twu.net/eev-current/eegchannel.html
+
+
+
+
+
+The protocol, in diagrams
+=========================
+Here's a diagram that shows roughly what we have when X is
+running both an Emacs and an xterm, each in a separate window.
+Many details have been omitted - for examples, the real
+communication happens through fifos and ptys, that are not shown
+- but it's easy to build a complete diagram from this. The arrows
+indicate flow of information.
+
+ keyboard mouse display
+ | | ^
+ v v |
+ +----------------------------+
+ | |
+ | X |
+ | |
+ +----------------------------+
+ key/mouse | ^ display key/mouse | ^ display
+ events v | commands events v | commands
+ +---------+ +---------+
+ | | | |
+ | emacs | | xterm |
+ | | | |
+ +---------+ +---------+
+ chars and | ^ chars and
+ signals v | signals
+ +---------+
+ | |
+ | sh |
+ | |
+ +---------+
+
+To make the external shell at the right able to receive commands
+from Emacs we will insert a program between the \"xterm\" and the
+\"sh\" boxes - an Expect script called eechannel, that will
+usually be totally transparent, in the sense that it will let all
+the chars and signals that it receives pass through it without
+changes.
+
+The trick is that \"eechannel\" will also be \"listening to
+commands from the outside\", according to the following protocol:
+
+ 1) each instance of eechannel \"listens\" to a fixed, named
+ \"channel\"; for simplicity, let's suppose that this name is
+ \"A\".
+
+ 2) When an eechannel receives a signal SIGUSR1 it reads a
+ string from the file \"eech.A.str\" and sends that to the
+ shell, as if the user had typed that.
+
+ 3) To make it simpler to send the signal, when eechannel starts
+ up it saves its pid into the file \"eech.A.pid\".
+
+That protocol can be depicted as the four horizontal arrows
+below; the temporal order is from top to bottom.
+
+ +-------------+
+ | |
+ | xterm |
+ | |
+ +-------------+
+ +-----------+ | ^
+ | | --> eeg.A.str v |
+ | emacs | <-- eeg.A.pid +-------------+
+ | | -----------------> | |
+ +-----------+ eeg.A.str ---> | eechannel A |
+ | |
+ +-------------+
+ | ^
+ v |
+ +-------------+
+ | |
+ | sh |
+ | |
+ +-------------+
+
+When Emacs wants to send a line, say, \"cd /tmp/\", to eechannel,
+it does this:
+
+ 1) \"--> eeg.A.str \" writes \"cd /tmp/\" into eech.A.str,
+ 2) \"<-- eeg.A.pid \" reads eechannel's pid from eech.B.str,
+ 3) \"----------------->\" sends a signal SIGUSR1 to that pid,
+ 4) \" eeg.A.str --->\" ...and when eechannel receives a SIGUSR1
+ it reads the contents of eech.A.str and
+ sends that to its spawned shell.
+
+Actually there's something else - how these programs are started.
+If we run just \"xterm\", it behaves in its default way, and runs
+a shell. But if we run
+
+ \"xterm -e eechannel A /bin/sh\"
+
+then xterm runs \"eechannel A /bin/sh\" instead of just
+\"/bin/sh\"; and \"eechannel A /bin/sh\" runs \"/bin/sh\".
+
+Also, evaluating this
+
+ (find-bgprocess \"xterm\")
+
+from Emacs runs an xterm, which runs a shell; evaluating either
+of these sexps,
+
+ (find-bgprocess \"xterm -e eechannel A /bin/sh\")
+ (find-bgprocess \"xterm -e eechannel A $SHELL\")
+
+runs an xterm, which runs the \"eechannel\" script, which runs a
+shell. The sexp
+
+ (eexterm \"A\")
+
+is a shorthand for the one using \"$SHELL\". Also, note that
+\"eechannel A ...\" saves its pid into \"eech.A.pid\".
+
+The diagram that shows what happens when we run `(eexterm \"A\")'
+is this one, below - note that the four arrows of the sending
+protocol are not shown.
+
+ +------------+
+ | |
+ | X |
+ | |
+ +------------+
+ / ^ \\ ^
+ v / v \\
+ +-----------+ +-------------+
+ | | initiates | |
+ | emacs |:::::::::::>| xterm |
+ | | | |
+ +-----------+ +-------------+
+ :: | ^
+ \\/ v |
+ +-------------+
+ | |
+ eeg.A.pid <-- | eechannel A |
+ | |
+ +-------------+
+ :: | ^
+ \\/ v |
+ +-------------+
+ | |
+ | sh |
+ | |
+ +-------------+
+
+
+
+Downloading and testing eechannel
+=================================
+Here I'll suppose that the directory \"~/bin/\" exists and is in
+your PATH. Run this to download the \"eechannel\" script and make
+it executable:
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd ~/bin/
+# See: http://angg.twu.net/bin/eechannel.html
+wget -n http://angg.twu.net/bin/eechannel
+chmod 755 eechannel
+
+Now let's test - from Emacs - if a local copy of \"eechannel\"
+exists, is in your PATH, and can be executed (remember that it
+needs Expect). Calling \"eechannel\" with not enough arguments
+should yield a nice error message.
+
+ (find-fline \"~/bin/eechannel\")
+ (find-sh \"~/bin/eechannel\")
+ (find-sh \"eechannel\")
+
+It uses the environment variable EEVTMPDIR to decide where the
+temporary files - ee.CHANNELAME.pid, ee.CHANNELNAME.str - will
+be, so let's check that this directory exists:
+
+ (getenv \"EEVTMPDIR\")
+ (find-fline \"$EEVTMPDIR/\")
+
+Running eechannel with a first argument \"-v\" should show a lot
+of info, and then save the pid at eech.CHANNELAME.pid and run the
+given command. Let's try with a command that exits immediately.
+
+ (find-sh \"eechannel -v A /bin/true\")
+ (find-fline \"$EEVTMPDIR/\" \"eech.A.pid\")
+
+Now let's verify - using just eepitch, without xterm at this
+moment - whether eechannel is being able to receive signals. In
+the eepitch script below, two `(find-sh0 \"kill ...\")'s should
+each make the controlled program receive a command - at the first
+\"kill\" an \"echo 2\", at the second an \"echo 3\".
+
+ (eepitch-comint \"A\" \"eechannel -v A /bin/sh\")
+ (eepitch-kill)
+ (eepitch-comint \"A\" \"eechannel -v A /bin/sh\")
+echo 1
+
+ (find-sh0 \" cat $EEVTMPDIR/eech.A.pid\")
+ (find-sh0 \"echo 'echo 2' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \" cat $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+
+ (find-sh0 \"echo 'echo 3' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+echo 4
+
+If the eepitched shell did run \"echo 1\", \"echo 2\", \"echo
+3\", \"echo 4\", then things are working - \"echo 1\" and \"echo
+4\" were sent through eepitch, but \"echo 3\" and \"echo 4\" were
+sent though channels.
+
+Now let's check if we can run an xterm, and if it can run an
+eechannel-ed shell instead of a plain shell. Check if the second
+sexp above starts an xterm, displays the info from \"eechannel
+-v\", and then runs a shell:
+
+ (find-bgprocess \"xterm\")
+ (find-bgprocess \"xterm -e eechannel -v A $SHELL\")
+ (find-bgprocess \"xterm -e eechannel A $SHELL\")
+
+if that worked, run the four sexps below with <f8>,
+
+ (find-sh0 \"echo 'echo 1' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+ (find-sh0 \"echo 'echo 2' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+
+and check if the eechannel-ed shell in the xterm has received the
+commands \"echo 1\" and \"echo 2\". If it did, try the
+higher-level version below - but use <f9>s on each line instead
+of the <f8>s:
+
+ (eexterm \"A\")
+echo 3
+echo 4
+
+If that worked, we're done. =)
+
+
+
+Several xterms
+==============
+http://angg.twu.net/eev-current/anim/channels.anim.html
+
+ (eexterm \"A\")
+ (eexterm \"B\")
+# listen on port 1234
+netcat -l -p 1234
+
+ (eexterm \"A\")
+# Send things to port 1234 (on localhost)
+{
+ echo hi
+ sleep 1
+ echo bye
+ sleep 1
+} | netcat -q O localhost 1234
+
+
+
+
+
+
+\[NOT DONE YET. The rest is (recyclable) garbage.\]
+
+
+
+
+
+
+\(Old stuff:)
+
+ emacs runs: (find-bgprocess \"xterm -T 'channel A' -e eegchannel A /bin/sh\")
+ xterm runs: eegchannel A /bin/sh
+ eegchannel saves its pid at ~/.eev/eeg.A.pid and runs: /bin/sh
+
+At this point the xterm is running a shell that is \"listening on
+channel A\"; eegchannel pretends to be transparent and passes all
+characters and signals in the vertical arrows transparently - but when
+it receives a certain signal (a SIGUSR1) it reads the contents from
+the file ~/.eev/eeg.A.str and passes it to the shell, as if those
+characters were coming from the xterm - i.e., as if the used had typed
+them.
+
+Here are the details of this \"protocol\":
+when we type F9 on a line containing \"echo foo\",
+
+ emacs saves the string \"echo foo\\n\" into ~/.eev/A.str,
+ emacs reads the pid of eegchannel from ~/.eev/eeg.A.pid (say, \"1022\"),
+ emacs runs \"kill -USR1 1022\",
+ eegchannel reads the string from ~/.eev/A.str, and sends it to the shell.
+
+NOTE: one frequent question is: \"why are you using two normal files
+and SIGUSR1s for the communication between emacs and eegchannel,
+instead of making them talk through a fifo?\" - the answer is: try to
+explain the details of fifos - including creation - to someone who
+knows little about the inner workings of a *NIX kernel and who is
+uncomfortable to accept another kind of black box... The way with two
+files and SIGUSR1s is simpler, works well enough, and I've been able
+to write all the code for it in a few hours - and I still don't know
+enough about fifos to implement a fifo version of this.
+
+and another one, that was mostly used to control external
+programs running in dedicated xterms. You can see an animation
+demonstrating it - and an explanation of what each line does -
+here:
+
+ http://angg.twu.net/eev-current/anim/channels.anim.html
+ http://angg.twu.net/eev-current/doc/shot-f9.png
+
+
+
+How to set it up
+================
+\[To be written\]
+
+ ssh address@hidden
+ eegchannel A ssh address@hidden
+ (find-prepared-intro \"\\n`ee'\\n\")
+ (find-eev \"anim/channels.anim\")
+" pos-spec-list)))
+
+;; (find-channels-intro)
+
+
+
+
+
+;;; _ _
+;;; __ _(_) __| | ___ ___ ___
+;;; \ \ / / |/ _` |/ _ \/ _ \/ __|
+;;; \ V /| | (_| | __/ (_) \__ \
+;;; \_/ |_|\__,_|\___|\___/|___/
+;;;
+;; �find-videos-intro� (to ".find-videos-intro")
+;; (find-intro-links "videos")
+
+(defun find-videos-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-videos-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-videos-intro)
+Source code: (find-efunction 'find-videos-intro)
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+
+
+What we have now
+================
+I am producing a series of videos about eev - but at this moment
+only two very broad introductions are ready 8-(. I have plans for
+several short videos about specific usage patterns, but don't
+hold your breath yet... also, these are my first videos EVER - so
+please excuse any stutterings, hesitations and false starts...
+
+The videos are uploaded to Youtube to make them very easy to
+find, but Youtube reduces the resolution of the original videos
+and makes them blurry and almost unreadable - so the best way to
+watch them is to fetch local copies of the high-res .mp4 files.
+
+
+
+Downloading local copies
+========================
+Here are direct links to both the low-res versions at Youtube
+and to the corresponding high-res \".mp4\"s:
+
+ Eepitch: a way to control shell-like programs from Emacs
+ http://www.youtube.com/watch?v=Lj_zKC5BR64
+ http://angg.twu.net/eev-videos/video4-eepitch.mp4
+
+ An introduction to eev2 (2012nov11)
+ http://www.youtube.com/watch?v=doeyn5MOaB8
+ http://angg.twu.net/eev-videos/video2.mp4
+
+\(The video about eepitch is shorter and far better than the
+other one - please start by it.)
+
+The ideas behind \"local copies\" are here:
+
+ (find-psne-intro)
+
+These sexps generate the download scripts in temporary buffers:
+
+ (find-eev-video-links \"eepitchvideo\" \"video4-eepitch\" \"Lj_zKC5BR64\")
+ (find-eev-video-links \"eevvideo\" \"video2\" \"doeyn5MOaB8\")
+
+
+
+
+Hyperlinks to the local copies of the videos
+============================================
+Notice that the download scripts above contain these sexps:
+
+\(code-video \"eepitchvideo\"
\"$S/http/angg.twu.net/eev-videos/video4-eepitch.mp4\")
+\(code-video \"eevvideo\" \"$S/http/angg.twu.net/eev-videos/video2.mp4\")
+
+After you execute them hyperlinks like these should work:
+
+ (find-eepitchvideo)
+ (find-eevvideo2)
+
+Note that they use mplayer to display the videos, and if you
+don't have mplayer - or if you haven't downloaded the \".mp4\"s -
+then you will get error messages in the \"*Messages*\" buffer.
+You can inspect them with `C-x b *Messages*' or with:
+
+ (find-ebuffer \"*Messages*\")
+
+
+
+
+Hyperlinks to positions
+=======================
+The first argument to `find-eepitchvideo' and to other similar
+functions is a time offset; it is optional, and it defaults to
+\"0:00\". Any further arguments are ignored, and this allows us
+to use them as comments. So these two sexps are equivalent:
+
+ (find-eepitchvideo \"0:16\")
+ (find-eepitchvideo \"0:16\" \"the eepitch-to-shell-and-python example\")
+
+We could use a series of `find-eepitchvideo' sexps to create a
+\"table of contents\" for a video, similarly to what we do for
+written documents...
+
+
+
+Time offsets as hyperlinks to positions
+=======================================
+In some cases using sexps creates too much visual clutter, and we
+would like to be able to create an index or table of contents
+writing lines just like this,
+
+ 0:16 the eepitch-to-shell-and-python example
+
+instead of using explicit elisp hyperlinks.
+
+There is a way to do this, but it is tricky. It involves
+activating a mode, called `eev-avadj-mode', in which `M-p' is
+bound to a command that locates the first thing looking like a
+time offset in the current line, and calls the video player to
+make it play the *current default video* starting from that time
+offset; a sexp like
+
+ (find-eepitchvideo t)
+
+just sets the current default video, but does not invoke the
+player. All this is explained here:
+
+ (find-audiovideo-intro \"The time-from-bol\")
+
+
+
+
+Eepitch video: table of contents
+================================
+\(eev-avadj-mode 1)
+\(find-eepitchvideo t)
+
+0:16 the eepitch-to-shell-and-python example, very quickly
+1:18 executing eepitch scripts with `f8's; f8 on red star lines and normal
lines
+2:33 the eepitch-to-shell-and-python example - what each line does
+3:15 the first three lines use advanced features
+3:52 eepitch scripts are made to be executed interactively
+5:25 the eepitch-to-shell-and-python example again, more slowly
+
+5:58 what happens when the eepitch target is being shown
+7:13 the default is to use two windows
+7:33 what happens when the target does not exist
+8:25 how to send commands to a new shell
+8:54 how an eepitch block (like eepitch-shell/kill/shell) works
+
+9:38 an example with shell comments (which eev uses as hyperlinks)
+12:35 refining hyperlinks
+12:35 converting shell commands into hyperlinks (by wrapping - by hand)
+13:04 wrapping commands - bound to meta-uppercase-letters
+13:53 M-M wraps the current line into a hyperlink to a manpage
+14:12 demonstrating M-M, M-S and M-T with eek sexps
+14:40 M-T wraps the current linto an eepitch-xxx/kill/xxx triple
+15:47 introduction to the sandboxed tutorials and to M-j (eejump)
+16:17 the default numeric arguments for eejump
+16:35 M-5 M-j jumps to the index for the documentation for eev
+17:15 temp. eev buffers usually start with a sexp that regenerates the buffer
+18:23 where the eepitch-to-shell-and-python example is in the documentation
+
+18:58 Other examples
+19:07 pdf-like documents
+20:43 a tutorial for Lua based on eepitch
+22:26 that's it - last comments, where to find more info, how to get in touch
+
+
+
+Eev video: table of contents
+============================
+\(eev-avadj-mode 1)
+\(find-eevvideo t)
+
+
+
+In Portuguese
+=============
+ (find-eev-video-links \"eevvideopt\" \"video2pt\" \"yztYD9Y7Iz4\")
+
+
+
+
+Comparison with youtube
+=======================
+Note that Youtube has a trick that lets we use URLs that point to
+specific positions in videos. For example, this,
+
+ http://www.youtube.com/watch?v=Lj_zKC5BR64&t=0m16s
+
+makes the video about eepitch start at 0:16 instead of from the
+beginning. Also, each video at Youtube can have uploader comments
+and a discussion, and in the text of these comments things like
+\"12:34\" become links that make the current video skip to that
+position.
+
+ (find-audiovideo-intro)
+
+Video2pt: Uma introducao ao eev2 (2012nov15)
+=============================================
+This is a version in Portuguese of the video above.
+It is slightly longer than the version in English because it's
+intended mostly for non-Emacsers, so some things are explained
+\(much) more slowly...
+
+At youtube: http://www.youtube.com/watch?v=yztYD9Y7Iz4
+ http://www.youtube.com/watch?v=yztYD9Y7Iz4&t=1h07m40s
+Hi-res mp4: http://angg.twu.net/eev-videos/video2pt.mp4
+ (128228339 bytes, 122MB. Duration: 1:09:42)
+
+# (find-eevvideo2pt)
+# (find-eevvideo2pt \"1:07:40\" \"eepitch pro shell e pro Python\")
+" pos-spec-list)))
+
+;; (find-videos-intro)
+
+
+;; A preliminary experiment (in Portuguese, and quite bad):
+;; Introducao ao eev2 (preliminar, 2012oct28)
+;; http://www.youtube.com/watch?v=1XtbM0D6leM
+
+
+
+
+
+
+
+
+;;; _ __
+;;; __| | ___ / _|_ _ _ __
+;;; / _` |/ _ \ |_| | | | '_ \
+;;; | (_| | __/ _| |_| | | | |
+;;; \__,_|\___|_| \__,_|_| |_|
+;;;
+;; �find-defun-intro� (to ".find-defun-intro")
+;; (find-intro-links "defun")
+
+(defun find-defun-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-defun-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-defun-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-defun-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.
+
+
+\[At present this is just a _skeleton_ for a tutorial on defining
+functions in Lisp...]
+
+
+
+Simple examples
+===============
+
+ (* 5 5)
+ (* 6 6)
+ (defun foo (a) (* a a))
+ (foo 5)
+ (foo 6)
+
+ (+ 5 5)
+ (defun foo (a) (+ a a))
+ (foo 5)
+
+ (symbol-function 'foo)
+ ((lambda (a) (* a a)) 5)
+ ((lambda (a) (+ a a)) 5)
+
+See:
+ (find-elnode \"Function Cells\")
+ (find-elnode \"Defining Functions\")
+
+
+
+Several arguments
+=================
+
+ (defun foo (a b) (+ (* a a) (* b b)))
+ (foo 10 2)
+ (foo 5)
+ (defun foo () (+ (* 2 3) (* 4 5)))
+ (foo 10 2)
+ (foo 5)
+ (foo)
+
+
+
+progn and prog1
+===============
+The body of a \"defun\" works like a \"progn\".
+See: (find-elnode \"Index\" \"* progn:\")
+
+ (defun foo (a b) (* a b))
+ (defun foo (a b) (+ a b) (* a b))
+ (defun foo (a b) (* a b) (+ a b))
+ (defun foo (a b) (+ a b))
+ (foo 5 6)
+
+ (progn (* 5 6) (+ 5 6))
+ (progn \"ignored\" (+ 5 6) \"result\")
+ (progn)
+
+ (prog1 (* 5 6) (+ 5 6))
+ (prog1 \"result\" (+ 5 6) \"ignored\")
+ (prog1)
+
+
+
+Docstrings
+==========
+Note that a string in a (progn ...) does nothing - unless it is
+the last BODY-FORM.
+
+But see: (find-elnode \"Documentation\")
+
+Try:
+
+ (defun foo (a b) \"IGNORED\" (+ a b))
+ (defun foo (a b) \"This is the description of `foo'\" (+ a b))
+ (defun foo (a b) \"This is the docstring of `foo'\" (+ a b))
+ (defun foo (a b) \"This function returns (* A B). Note the italics!\" (+ a
b))
+ (find-efunctiondescr 'foo)
+
+
+
+&optional and &rest
+===================
+See: (find-elnode \"Argument List\")
+Try:
+
+ (defun foo (a &optional b c) (list \"a,b,c:\" a b c))
+ (foo 11 22 33)
+ (foo 11 22)
+ (foo 11)
+ (foo)
+ (foo 11 22 33 44)
+
+ (defun foo (a &optional b c &rest r) (list \"a,b,c,r:\" a b c r))
+ (foo 11 22 33 44 55 66)
+ (foo 11 22 33 44 55)
+ (foo 11 22 33 44)
+ (foo 11 22 33)
+ (foo 11 22)
+ (foo 11)
+ (foo)
+
+ (defun foo (a &rest r) (list \"a,r:\" a r))
+ (foo 11 22 33 44)
+ (foo 11 22 33)
+ (foo 11 22)
+ (foo 11)
+ (foo)
+
+
+
+A tool: my-insert
+=================
+See: (find-elnode \"Formatting Strings\")
+Try:
+
+ (format \"<%s>\" \"hello\")
+ (format \"<%s>\" \"123\")
+ (format \"<%s>\" 123)
+ (format \"<%s>\" 'hello)
+ (format \"<%s>\" '(+ 2 3))
+
+ (format \"<%S>\" \"hello\")
+ (format \"<%S>\" \"123\")
+ (format \"<%S>\" 123)
+ (format \"<%S>\" 'hello)
+ (format \"<%S>\" '(+ 2 3))
+
+Now define:
+
+ (defun my-insert (obj)
+ \"Print (insert) OBJ in the current buffer.\"
+ (insert (format \"\\n ;; \\\\--> %S\" obj)))
+
+Try:
+
+ (my-insert 123)
+ (my-insert \"123\")
+ (my-insert \"hello\")
+ (my-insert 'hello)
+ (my-insert '(+ 2 3))
+ (my-insert nil)
+ (my-insert '())
+ (my-insert ())
+
+See also:
+ (find-elnode \"Character Type\")
+ (find-elnode \"Basic Char Syntax\")
+ (find-elnode \"Basic Char Syntax\" \"?\\\\n\")
+ (find-elnode \"General Escape Syntax\")
+
+
+
+interactive
+===========
+Not all Emacs functions are callable with `M-x' - only those that
+are \"commands\" are callable in this way. And only \"commands\"
+can be bound to keys...
+
+See:
+ (find-elnode \"Defining Functions\" \"the first two of the BODY-FORMS\")
+ (find-elnode \"Defining Commands\")
+ (find-elnode \"Command Overview\")
+
+When you execute an `(interactive ...)' it does nothing - it
+simply ignores its arguments (which aren't even evaluated!) and
+returns nil. But just as
+
+
+ (defun my-insert (obj) (insert (format \"\\n ;; \\\\--> %S\" obj)))
+
+ (find-efunctiondescr 'interactive)
+
+ (eek \"M-x foo\")
+ (commandp 'foo)
+
+ (defun foo (&rest rest) (interactive) (bar rest))
+ (eek \"M-x foo\")
+
+ (defun foo (&rest rest) (bar rest))
+ (defun foo (&rest rest) (interactive \"P\") (bar rest))
+ (eek \" M-x foo\")
+ (eek \"M-1 M-x foo\")
+ (eek \"M-1 M-2 M-3 M-x foo\")
+ (eek \"M-- M-2 M-3 M-x foo\")
+
+ (defun foo (&rest rest) (interactive \"R\") (bar rest))
+ (eek \"M-x foo\")
+
+
+" rest)))
+
+;; (find-defun-intro)
+;; (find-defun-intro "&rest")
+;; (find-defun-intro "\ninteractive\n")
+;; (find-defun-intro "Defining Commands")
+
+
+
+;;; _ _
+;;; ___ _ __ ___ __ _ ___ ___ (_)_ __ | |_ _ __ ___
+;;; / _ \ '_ ` _ \ / _` |/ __/ __|_____| | '_ \| __| '__/ _ \
+;;; | __/ | | | | | (_| | (__\__ \_____| | | | | |_| | | (_) |
+;;; \___|_| |_| |_|\__,_|\___|___/ |_|_| |_|\__|_| \___/
+;;;
+;; �find-emacs-intro� (to ".find-emacs-intro")
+;; (find-intro-links "emacs")
+
+(defun find-emacs-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-emacs-intro)*"))
+ (apply 'find-estring "\
+\(Re)generate: (find-emacs-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-emacs-intro\")
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+
+
+Basic keys (eev)
+================
+The most basic keys of eev are:
+ M-e - to follow a hyperlink, see: (find-eval-intro \"Elisp hyperlinks\")
+ M-k - to go back, see: (find-eval-intro \"\\nGoing back\")
+ M-j - to jump to certain predefined places - in particular,
+ `M-j' takes you to the list of jump targets in (find-eev
\"eejump.el\")
+ `M-2j' takes you to this help page.
+ `M-5j' takes you to: (find-eev-intro)
+ See: (find-eejump-intro \"Families\")
+
+The mnemonics are:
+ M-e - evaluate/execute
+ M-j - jump
+ M-k - kill buffer
+
+It is possible to start learning Emacs and eev by remembering
+only that `M-j' jumps to an index; when you're lost, type `M-j',
+and will see a reminder of the main keys and of the main jump
+targets - after that you can learn how to use `M-k' to kill the
+top buffer, and `M-e' to follow elisp hyperlinks. The other keys
+are explained in \"intros\" like this one.
+
+
+
+
+Files, Buffers, Windows, Frames, Display, etc
+=============================================
+Emacs can edit several files at the same time, each one
+in a \"buffer\".
+
+ (find-enode \"Files\")
+ (find-enode \"Buffers\")
+ (find-enode \"Windows\")
+ (find-enode \"Frames\")
+
+The display of Emacs looks like this (asciified):
+ __ _ _
+ ______________emacs_______\\/|-|X|
+ / | | \\
+ | | bla. | | Emacs
+Window | | | | calls this
+managers | | | | a \"window\".
+call | | | /
+this a | |--:** foo.txt (Fundamental) ----| <-- Its \"modeline\".
+\"window\". / | | \\
+Emacs \\ | bla bla. | | Another
+calls | | bleh | | window.
+this a | | | |
+\"frame\". | | | /
+ | |--:** bar.txt (Fundamental) ----| <-- Its modeline.
+ \\ |Find file: ~/bletch.txt_ ________| <-- The minibuffer.
+
+The bottom line of a frame is sometimes the \"echo area\",
+sometimes the \"minibuffer\". The minibuffer acts like a
+window when it is active, and `C-x o' can be used to move
+from it to the \"normal windows\" and back. You can also
+use the mouse to move between windows.
+
+ (find-enode \"Echo Area\")
+ (find-enode \"Minibuffer\")
+ (find-enode \"Other Window\")
+
+By default there's also a \"menu bar\" (with textual entries) and
+a \"tool bar\" (with icons) at the top of each frame, but
+advanced users usually disable them.
+
+ (find-enode \"Menu Bar\")
+ (find-enode \"Tool Bars\")
+
+
+
+
+Basic keys (Emacs)
+==================
+\(find-enode \"Keys\" \"key sequence\")
+\(find-enode \"User Input\" \"`Control-a'\" \"usually written `C-a'\")
+\(find-enode \"User Input\" \"<META> key\")
+\(find-enode \"Completion\" \"<TAB>\")
+
+<ESC> <ESC> <ESC> (find-enode \"Quitting\")
+C-g keyboard-quit (find-enode \"Quitting\" \"`C-g'\")
+
+M-x execute-extended-command (find-enode \"M-x\" \"Running Commands by
Name\")
+
+
+
+Cutting & pasting
+=================
+The \"region\" where cut & copy operate is always what is between
+the \"point\" and the \"mark\":
+
+ (find-enode \"Point\")
+ (find-enode \"Mark\")
+
+You can do cut, copy and paste by using the icons in the toolbar
+or by using the menu bar (the relevant options are under
+\"Edit\"), but the keys are worth learning:
+
+ C-SPC -- set-mark-command (find-enode \"Setting Mark\")
+ C-x C-x -- exchange-point-and-mark (find-enode \"Setting Mark\" \"C-x
C-x\")
+ C-w -- kill-region (cut) (find-enode \"Other Kill Commands\")
+ M-w -- kill-ring-save (copy) (find-enode \"Kill Ring\")
+ C-y -- yank (paste) (find-enode \"Kill Ring\")
+
+
+
+Undoing
+=======
+C-/ -- undo (find-enode \"Basic Undo\")
+ (find-enode \"Undo\")
+
+
+
+
+Other keys / reference
+======================
+M-x -- execute-extended-command (find-enode \"M-x\")
+ more about the minibuffer: (find-enode \"Minibuffer\")
+TAB -- for completion: (find-enode \"Completion\")
+ for indentation: (find-enode \"Indentation\")
+ in programming modes: (find-enode \"Basic Indent\")
+
+C-x o -- other-window (find-enode \"Other Window\")
+C-x 0 -- delete-window (find-enode \"Change Window\")
+C-x 1 -- delete-other-windows (\"1 window\") (find-enode \"Change Window\")
+C-x 2 -- split-window-vertically (Abv/Blw) (find-enode \"Split Window\")
+C-x 3 -- split-window-horizontally (L|R) (find-enode \"Split Window\")
+
+ (find-enode \"Dired\")
+C-x C-f -- find-file (find-enode \"Visiting\")
+C-x C-s -- save-buffer (find-enode \"Saving\")
+C-x C-c -- save-buffers-kill-emacs (find-enode \"Saving\")
+C-x b -- switch-to-buffer (find-enode \"Select Buffer\")
+C-x k -- kill-buffer (find-enode \"Kill Buffer\")
+
+C-a -- beginning-of-line (find-enode \"Moving Point\")
+C-e -- end-of-line (find-enode \"Moving Point\")
+M-< -- beginning-of-buffer (find-enode \"Moving Point\")
+M-> -- end-of-buffer (find-enode \"Moving Point\")
+
+M-q -- fill-paragraph (find-enode \"Fill Commands\")
+
+C-s -- isearch-forward (find-enode \"Incremental Search\")
+C-r -- isearch-backward (find-enode \"Incremental Search\")
+M-C-s -- isearch-forward-regexp (find-enode \"Regexp Search\")
+M-C-r -- isearch-backward-regexp (find-enode \"Regexp Search\")
+M-% -- query-replace (find-enode \"Replace\")
+
+C-x ( -- start-kbd-macro (find-enode \"Keyboard Macros\")
+C-x ) -- end-kbd-macro (find-enode \"Keyboard Macros\")
+C-x e -- call-last-kbd-macro (find-enode \"Keyboard Macros\")
+" pos-spec-list)))
+
+;; (find-emacs-intro)
+;; (find-TH "emacs" "short-emacs-tutorial")
+
+
+
+
+(provide 'eev-intro)
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; no-byte-compile: t
+;; End:
diff --git a/eev-mode.el b/eev-mode.el
new file mode 100644
index 0000000..783a057
--- /dev/null
+++ b/eev-mode.el
@@ -0,0 +1,243 @@
+;;; eev-mode.el -- a minor mode with keybindings for using eev conveniently.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013feb16
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-mode.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-mode.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+(defun ee-kill-this-buffer ()
+ "Kill the current buffer with fewer warnings than `kill-this-buffer'.
+See: (find-eval-intro \"`M-k'\")"
+ (interactive)
+ (let ((kill-buffer-query-functions nil))
+ (kill-this-buffer)))
+
+
+
+
+;;; _
+;;; | | _____ _ _ _ __ ___ __ _ _ __
+;;; | |/ / _ \ | | | '_ ` _ \ / _` | '_ \
+;;; | < __/ |_| | | | | | | (_| | |_) |
+;;; |_|\_\___|\__, |_| |_| |_|\__,_| .__/
+;;; |___/ |_|
+;;;
+;;; eev mode keymap
+
+(defvar eev-mode-map nil)
+
+(defun eev-mode-map-set ()
+ "Add the standard keybindings for eev to `eev-mode-keymap'."
+ ;;
+ ;; Eepitch: a simple way to script interactive programs.
+ ;; Explanation: (find-eepitch-intro "The main key: <F8>")
+ ;; (find-eepitch-intro "Creating eepitch blocks: <M-T>")
+ ;; Source: (find-eev "eepitch.el")
+ (define-key eev-mode-map [f8] 'eepitch-this-line)
+ (define-key eev-mode-map "\M-T" 'eewrap-eepitch)
+ ;;
+ ;; Keys for following hyperlinks and for going back.
+ ;; Explanation: (find-eval-intro "`M-e'")
+ ;; (find-eval-intro "Going back")
+ ;; Source: (find-eev "eev-eval.el")
+ (define-key eev-mode-map "\M-e" 'ee-eval-sexp-eol) ; extends C-e C-x C-e
+ (define-key eev-mode-map "\M-E" 'ee-eval-last-sexp) ; extends C-x C-e
+ (define-key eev-mode-map "\M-k" 'ee-kill-this-buffer)
+ (define-key eev-mode-map "\M-K" 'bury-buffer)
+ ;;
+ ;; Explanation: (find-wrap-intro)
+ ;; Tests: (find-wrap-intro "all wrapping functions")
+ ;; Source: (find-eev "eev-wrap.el")
+ (define-key eev-mode-map "\M-A" 'eewrap-anchor)
+ (define-key eev-mode-map "\M-C" 'eewrap-code-c-d)
+ (define-key eev-mode-map "\M-D" 'eewrap-debian)
+ (define-key eev-mode-map "\M-F" 'eewrap-find-fline)
+ (define-key eev-mode-map "\M-J" 'eewrap-eejump)
+ (define-key eev-mode-map "\M-M" 'eewrap-man)
+ (define-key eev-mode-map "\M-P" 'eewrap-pdflike)
+ (define-key eev-mode-map "\M-R" 'eewrap-rm/mkdir/cd)
+ (define-key eev-mode-map "\M-S" 'eewrap-sh)
+ (define-key eev-mode-map "\M-Z" 'eewrap-zsh)
+ ;;
+ ;; Keys for creating temporary buffers with elisp hyperlinks:
+ ;; Source: (find-eev "eev-elinks.el")
+ (define-key eev-mode-map "\M-h\M-d" 'find-debpkg-links)
+ (define-key eev-mode-map "\M-h\M-f" 'find-efunction-links)
+ (define-key eev-mode-map "\M-h\M-i" 'find-einfo-links)
+ (define-key eev-mode-map "\M-h\M-k" 'find-ekey-links)
+ (define-key eev-mode-map "\M-h\M-m" 'find-manpage-links)
+ (define-key eev-mode-map "\M-h\M-p" 'find-pdflike-page-links)
+ (define-key eev-mode-map "\M-h\M-v" 'find-evariable-links)
+ (define-key eev-mode-map "\M-hf" 'find-file-links)
+ (define-key eev-mode-map "\M-hm" 'find-last-manpage-links)
+ (define-key eev-mode-map "\M-hM" 'find-ekbmacro-links)
+ ;; Information about text properties, faces, and chars:
+ (define-key eev-mode-map "\M-h\M-s" 'find-efacedescr)
+ (define-key eev-mode-map "\M-h\M-c" 'describe-char)
+ (define-key eev-mode-map "\M-h\M-t" 'find-etpat)
+ (define-key eev-mode-map "\M-ht" 'find-etpat0)
+ ;; Extras:
+ (define-key eev-mode-map "\M-hg" 'find-git-links-1)
+ ;;
+ ;; Keys for editing hyperlinks:
+ ;; Source: (find-eev "eev-edit.el")
+ (define-key eev-mode-map "\M-h\M-2" 'ee-duplicate-this-line)
+ (define-key eev-mode-map "\M-h\M-y" 'ee-yank-pos-spec)
+ (define-key eev-mode-map "\M-h\M--" 'ee-shrink-hyperlink-at-eol)
+ ;;
+ )
+
+(when (not eev-mode-map)
+ (setq eev-mode-map (make-sparse-keymap))
+ (eev-mode-map-set))
+
+
+
+
+
+;;; _
+;;; ___ _____ __ _ __ ___ ___ __| | ___
+;;; / _ \/ _ \ \ / /____| '_ ` _ \ / _ \ / _` |/ _ \
+;;; | __/ __/\ V /_____| | | | | | (_) | (_| | __/
+;;; \___|\___| \_/ |_| |_| |_|\___/ \__,_|\___|
+;;;
+;;; eev mode
+;;
+;; (find-efunctiondescr 'eev-mode)
+;; (find-ekeymapdescr eev-mode-map)
+;; (find-elnode "Keys in Documentation")
+
+(defvar eev-mode-lighter " eev")
+(defvar eev-mode-help "Toggle eev mode, i.e, activate or deactivate the
`eev-mode-map' keymap.
+With a prefix argument ARG, turn eev-mode on if positive, else off.
+See: (find-eev-intro)
+\\<eev-mode-map>
+Commands to follow hyperlinks:
+ \\[ee-eval-sexp-eol] -- go to the end of line, then do \\[ee-eval-last-sexp]
+ \\[ee-eval-last-sexp] -- eval the sexp at the left of point
+ See: (find-eval-intro)
+Commands to return from hyperlinks:
+ \\[ee-kill-this-buffer] -- kill this buffer
+ \\[bury-buffer] -- put this buffer at the end of the list of all buffers
+ See: (find-eval-intro \"\\nGoing back\\n\")
+Other very very important commands:
+ \\[eejump] -- jump to where the main eejump targets are defined
+ M-5 \\[eejump] -- jump to the index of all sandbox tutorials for eev
+ See: (find-eejump-intro)
+ \\[eepitch-this-line] -- pitch this line to another Emacs buffer,
+ or execute it as lisp if it starts with `'
+ See: (find-eepitch-intro)
+Commands to convert the current line into hyperlinks:
+ \\[eewrap-find-fline] -- wrap its contents in a `find-fline'
+ \\[eewrap-man] -- wrap its contents in a `find-man'
+ \\[eewrap-sh] -- wrap its contents in a `find-sh'
+ \\[eewrap-eepitch] -- generate an \" (eepitch-{xxx,kill,xxx})\" block
+ \\[eewrap-anchor] -- convert to two anchors pointing to one another
+ \\[eewrap-code-c-d] -- wrap its contents in a `code-c-d' and a `find-_file'
+ \\[eewrap-debian] -- wrap its contents in three Debian hyperlinks
+ \\[eewrap-eejump] -- make a `(defun eejump-N ...)' from N and a hyperlink
+ \\[eewrap-rm/mkdir/cd] -- make a rm/mkdir/cd triple
+ \\[eewrap-pdflike] -- generate links to pdf-like documents
+ \\[eewrap-audiovideo] -- generate audio/video hyperlinks
+ See: (find-wrap-intro)
+Commands to generate pages with lists of hyperlinks:
+ \\[find-file-links] -- hyperlinks to the current file
+ \\[find-grep-links] -- hyperlinks to `find-xxxgrep' sexps
+ \\[find-efunction-links] -- hyperlinks to an Emacs function
+ \\[find-einfo-links] -- hyperlinks to the current Info node
+ \\[find-ekey-links] -- hyperlinks to a key sequence and to the function
+ associated to it
+ \\[find-evariable-links] -- hyperlinks to an Emacs variable
+ \\[find-eface-links] -- hyperlinks to a face (default: face at point)
+ \\[find-manpage-links] -- hyperlinks to a manpage (ask for name)
+ \\[find-last-manpage-links] -- hyperlinks to a manpage (being viewed)
+ \\[find-debpkg-links] -- hyperlinks about a Debian package
+ \\[find-ecolor-links] -- hyperlinks to a color
+Commands to edit hyperlinks:
+ \\[ee-duplicate-this-line] -- duplicate this line
+ \\[ee-yank-pos-spec] -- yank into pos-spec-list
+ \\[ee-shrink-hyperlink-at-eol] -- shrink `find-xxxfile' to `find-xxx'
+ \\[eewrap-vldi-list-line] -- transform filename into hyperlink
+Other commands:
+ \\[find-eev-mode-links] -- show this help about eev-mode, or some links
+ \\[describe-char] -- lots of info about the character at point
+ \\[find-etpat] -- text properties at point
+ \\[find-etpat0] -- text properties at point (output in the echo area)")
+
+
+(defun eev-mode-define ()
+ "Use this to redefine `eev-mode' with another lighter and another docstring."
+ (eval `
+ ;;
+ (define-minor-mode eev-mode
+ ,eev-mode-help
+ :init-value nil
+ :global t
+ :lighter ,eev-mode-lighter)
+ ;;
+ ))
+
+(eev-mode-define)
+
+;; (progn (eev-mode 0) (eev-mode 1))
+;; (find-efunctiondescr 'eev-mode)
+
+
+
+(provide 'eev-mode)
+
+
+;; Deleted code:
+;;
+;; Run the default bounded action (usually `eev-bounded'):
+;; (define-key eev-mode-map [f3] 'eeb-default)
+;; Steppers:
+;; (define-key eev-mode-map [f9] 'eechannel-do-this-line)
+;; (define-key eev-mode-map [f12] 'eesteps-do-step)
+;; (define-key eev-mode-map "\M-P" 'ee-yank-one-line)
+;; For "compose pairs":
+;; (define-key eev-mode-map [?\C-,] 'eev-compose-two-keys) ; only works on X
+;; (define-key eev-mode-map [?\M-,] 'eev-compose-two-keys) ; works anywhere
+
+;; \\[eechannel-do-this-line] -- send this line through the default channel,
+;; or execute this line as lisp if it starts with `'
+;; \\[eeb-default] -- execute the default action on bounded regions
+;; \\[ee-yank-one-line] -- \"send\" the first line of the last kill, as if
the
+;; user had typed it
+;; \\[eesteps-do-step] -- execute the next step from an `eesteps' list
+;; \\[eev-help-page] -- switch to a help page, or hide it and return
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-multiwindow.el b/eev-multiwindow.el
new file mode 100644
index 0000000..f601f64
--- /dev/null
+++ b/eev-multiwindow.el
@@ -0,0 +1,130 @@
+;; eev-multiwindow.el - functions to create multi-window setups
+
+;; Copyright (C) 2012,2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug24
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-multiwindow.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-multiwindow.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+
+(defun find-wset-1 () (delete-other-windows))
+(defun find-wset-2 () (split-window-vertically))
+(defun find-wset-3 () (split-window-horizontally))
+(defun find-wset-s () (split-window-sensibly (selected-window)))
+(defun find-wset-o () (other-window 1))
+(defun find-wset-+ () (balance-windows))
+(defun find-wset-_ () (eval (car sexps)) (setq sexps (cdr sexps)))
+(defun find-wset-\ ()) ; allow whitespace
+
+(defun find-wset (chars &rest sexps)
+ "Create a multi-window setting according to CHARS and SEXPS.
+A detailed explanation is here: (find-multiwindow-intro)
+
+Here is a list of the standard characters that can be used in CHARS:
+ 1: `delete-other-windows' (C-x C-1)
+ 2: `split-window-vertically' (C-x C-2)
+ 3: `split-window-horizontally' (C-x C-3)
+ s: `split-window-sensibly'
+ o: `other-window' (C-x o)
+ +: `balance-windows' (C-x +)
+ _: execute the next sexp in SEXPS.
+
+To add support for a new character, say `C', just define
+a function `find-wset-C'."
+ (if (not (equal chars ""))
+ (let ((c (substring chars 0 1))
+ (chars (substring chars 1)))
+ (funcall (ee-intern "find-wset-%s" c))
+ (apply 'find-wset chars sexps))))
+
+
+
+
+
+;;; _ _ _ _ _
+;;; ___ ___ _ __ (_) |_ ___| |__ | |__ __ _ ___| | _____
+;;; / _ \/ _ \ '_ \| | __/ __| '_ \ | '_ \ / _` |/ __| |/ / __|
+;;; | __/ __/ |_) | | || (__| | | | | | | | (_| | (__| <\__ \
+;;; \___|\___| .__/|_|\__\___|_| |_| |_| |_|\__,_|\___|_|\_\___/
+;;; |_|
+
+(defun ee-here (code)
+ "Example: (ee-here '(eepitch-xxx)) opens the target of (eepitch-xxx) here.
+\"Here\" means \"in the current window, without disturbing the
+current window configuration\". Normal calls to `eepitch-xxx'
+functions split the screen and open the target buffer in another
+window; by wrapping them in an `(ee-here ...)' we can bypass
+that. This is mainly for `find-wset'."
+ (let (result)
+ (find-ebuffer
+ (save-window-excursion
+ (setq result (eval code))
+ eepitch-buffer-name))
+ result))
+
+(defun ee-here-reset (code)
+ "Like `ee-here', but also does an `eepitch-kill'."
+ (let (result)
+ (find-ebuffer
+ (save-window-excursion
+ (eval code)
+ (eepitch-kill)
+ (setq result (eval code))
+ eepitch-buffer-name))
+ result))
+
+(defun find-wset-= () (ee-here (car sexps)) (setq sexps (cdr sexps)))
+(defun find-wset-! () (ee-here-reset (car sexps)) (setq sexps (cdr sexps)))
+(defun find-wset-O () (other-window -1))
+
+
+
+;; (find-multiwindow-intro)
+;; Temporary hacks
+(defun find-2a (a b) (find-wset "13_o_o" a b))
+(defun find-2b (a b) (find-wset "13_o_" a b))
+(defun find-3a (a b c) (find-wset "13_o2_o_o" a b c))
+(defun find-3b (a b c) (find-wset "13_o2_o_oo" a b c))
+(defun find-3c (a b c) (find-wset "13_o2_o_" a b c))
+
+(defun find-3ee (b c) (find-wset "13o2=o=o" b c))
+(defun find-3EE (b c) (find-wset "13o2!o!o" b c))
+
+
+
+
+(provide 'eev-multiwindow)
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-pdflike.el b/eev-pdflike.el
new file mode 100644
index 0000000..8f9e6d7
--- /dev/null
+++ b/eev-pdflike.el
@@ -0,0 +1,436 @@
+;;; eev-pdflike.el -- hyperlinks to documents made of pages.
+
+;; Copyright (C) 2012,2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013jun16
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-pdflike.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-pdflike.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-pdf-like-intro.html>
+;; (find-eev-intro)
+;; (find-pdf-like-intro)
+
+;;; Commentary:
+
+
+
+
+;; (code-brfile 'find-fline :local 'brfl)
+;; (code-brfile 'find-xpdfpage :local 'brxpdf :dired 'brxpdfd)
+;; (code-brurl 'find-firefox :remote 'brm :local 'brml :dired 'brmd)
+
+
+(require 'eev-brxxx)
+
+;;; _ _ _
+;;; __ ____ _ _ __(_) __ _| |__ | | ___ ___
+;;; \ \ / / _` | '__| |/ _` | '_ \| |/ _ \/ __|
+;;; \ V / (_| | | | | (_| | |_) | | __/\__ \
+;;; \_/ \__,_|_| |_|\__,_|_.__/|_|\___||___/
+;;
+(defvar ee-page-c "{?}")
+(defvar ee-page-fname "{?}")
+(defvar ee-page-offset 0)
+
+
+
+
+
+;;; ____ ____ _____ _ _ _
+;;; | _ \| _ \| ___| | (_) | _____
+;;; | |_) | | | | |_ _____| | | |/ / _ \
+;;; | __/| |_| | _|_____| | | < __/
+;;; |_| |____/|_| |_|_|_|\_\___|
+;;;
+;; See: (find-pdf-like-intro)
+
+
+(defun ee-code-pdftext-rest (rest)
+ (ee-template0 "
+;; {(ee-S `(ee-code-pdftext-rest ,@rest))}
+"))
+
+
+;;; _ __
+;;; __ ___ __ __| |/ _|
+;;; \ \/ / '_ \ / _` | |_
+;;; > <| |_) | (_| | _|
+;;; /_/\_\ .__/ \__,_|_|
+;;; |_|
+;;
+;; (find-pdflikedef-links "xpdf" "c fname")
+;;
+;; find-xpdfpage
+;; find-xpdf-page
+;; code-xpdf
+;;
+(defalias 'find-xpdfpage
+ 'find-xpdf-page)
+(defun find-xpdf-page (fname &optional page &rest rest)
+ (find-bgprocess (ee-find-xpdf-page fname page)))
+(defvar ee-find-xpdf-page-options '())
+(defun ee-find-xpdf-page (fname &optional page)
+ `("xpdf"
+ ,@ee-find-xpdf-page-options
+ ,fname
+ ,@(if page `(,(format "%d" page)))
+ ))
+
+(defun code-xpdf (c fname &rest rest)
+ (eval (ee-read (apply 'ee-code-xpdf c fname rest))))
+(defun find-code-xpdf (c fname &rest rest)
+ (find-estring-elisp (apply 'ee-code-xpdf c fname rest)))
+(defun ee-code-xpdf (c fname &rest rest)
+ (concat (ee-template0 "\
+;; {(ee-S `(find-code-xpdf ,c ,fname ,@rest))}
+;;
+\(setq ee-pdflike-last 'find-{c}page)
+\(defun find-{c}page (&optional page &rest rest)
+ (setq ee-pdflike-last 'find-{c}page)
+ (find-xpdf-page {(ee-pp0 fname)} page))
+") (ee-code-pdftext-rest rest)))
+
+(code-brfile 'find-xpdf-page :local 'brxpdfl :dired 'brxpdfd)
+
+
+
+;;; _ __
+;;; _ __ __| |/ _|
+;;; | '_ \ / _` | |_
+;;; | |_) | (_| | _|
+;;; | .__/ \__,_|_|
+;;; |_|
+;;
+(defalias 'find-pdfpage 'find-xpdfpage)
+(defalias 'find-pdf-page 'find-xpdf-page)
+(defalias 'code-pdf 'code-xpdf)
+(defalias 'find-code-pdf 'find-code-xpdf)
+
+
+
+;;; _
+;;; _____ _(_)_ __ ___ ___
+;;; / _ \ \ / / | '_ \ / __/ _ \
+;;; | __/\ V /| | | | | (_| __/
+;;; \___| \_/ |_|_| |_|\___\___|
+;;;
+;;
+;; (find-pdflikedef-links "evince" "c fname")
+;; (find-man "1 evince")
+;;
+;; find-evincepage
+;; find-evince-page
+;; code-evince
+;;
+(defalias 'find-evincepage
+ 'find-evince-page)
+(defun find-evince-page (fname &optional page &rest rest)
+ (find-bgprocess (ee-find-evince-page fname page)))
+(defvar ee-find-evince-page-options '())
+(defun ee-find-evince-page (fname &optional page)
+ `("evince"
+ ,@ee-find-evince-page-options
+ ,@(if page `(,(format "--page-label=%d" page)))
+ ,fname))
+
+(defun code-evince (c fname &rest rest)
+ (eval (ee-read (apply 'ee-code-evince c fname rest))))
+(defun find-code-evince (c fname &rest rest)
+ (find-estring-elisp (apply 'ee-code-evince c fname rest)))
+(defun ee-code-evince (c fname &rest rest)
+ (concat (ee-template0 "\
+\(defun find-{c}page (&optional page &rest rest)
+ (find-evince-page {(ee-pp0 fname)} page))
+{(ee-code-pdftext-rest rest)}
+") (ee-code-pdftext-rest rest)))
+
+(code-brfile 'find-evince-page :local 'brevincel :dired 'brevinced)
+
+
+
+;;; _ _
+;;; __ ____| |_ _(_)
+;;; \ \/ / _` \ \ / / |
+;;; > < (_| |\ V /| |
+;;; /_/\_\__,_| \_/ |_|
+;;;
+;;
+;; (find-pdflikedef-links "xdvi" "c fname")
+;;
+;; find-xdvipage
+;; find-xdvi-page
+;; code-xdvi
+;;
+(defalias 'find-xdvipage
+ 'find-xdvi-page)
+(defun find-xdvi-page (fname &optional page &rest rest)
+ (find-bgprocess (ee-find-xdvi-page fname page)))
+(defvar ee-find-xdvi-page-options '())
+(defun ee-find-xdvi-page (fname &optional page)
+ `("xdvi"
+ ,@ee-find-xdvi-page-options
+ ,@(if page `(,(format "+%d" page)))
+ ,fname))
+
+(defun code-xdvi (c fname &rest rest)
+ (eval (ee-read (apply 'ee-code-xdvi c fname rest))))
+(defun find-code-xdvi (c fname &rest rest)
+ (find-estring-elisp (apply 'ee-code-xdvi c fname rest)))
+(defun ee-code-xdvi (c fname &rest rest)
+ (concat (ee-template0 "\
+\(defun find-{c}page (&optional page &rest rest)
+ (find-xdvi-page {(ee-pp0 fname)} page))
+{(ee-code-pdftext-rest rest)}
+") (ee-code-pdftext-rest rest)))
+
+(code-brfile 'find-xdvi-page :local 'brxdvil :dired 'brxdvid)
+
+(defalias 'code-dvi 'code-xdvi)
+(defalias 'find-code-dvi 'find-code-xdvi)
+
+
+
+;;; _ _
+;;; __| |(_)_ ___ _
+;;; / _` || \ \ / / | | |
+;;; | (_| || |\ V /| |_| |
+;;; \__,_|/ | \_/ \__,_|
+;;; |__/
+;;
+;; (find-pdflikedef-links "djvu" "c fname")
+;;
+;; find-djvupage
+;; find-djvu-page
+;; code-djvu
+;;
+(defalias 'find-djvupage
+ 'find-djvu-page)
+(defun find-djvu-page (fname &optional page &rest rest)
+ (find-bgprocess (ee-find-djvu-page fname page)))
+(defvar ee-find-djvu-page-options '())
+(defun ee-find-djvu-page (fname &optional page)
+ `("djview"
+ ,@ee-find-djvu-page-options
+ ,@(if page `(,(format "--page=%d" page)))
+ ,fname))
+
+(defun code-djvu (c fname &rest rest)
+ (eval (ee-read (apply 'ee-code-djvu c fname rest))))
+(defun find-code-djvu (c fname &rest rest)
+ (find-estring-elisp (apply 'ee-code-djvu c fname rest)))
+(defun ee-code-djvu (c fname &rest rest)
+ (concat (ee-template0 "\
+\(defun find-{c}page (&optional page &rest rest)
+ (find-djvu-page {(ee-pp0 fname)} page))
+") (ee-code-pdftext-rest rest)))
+
+(code-brfile 'find-djvu-page :local 'brdjvul :dired 'brdjvud)
+
+
+
+
+;;;
+;;; _ __ ___
+;;; | '_ \/ __|
+;;; | |_) \__ \
+;;; | .__/|___/
+;;; |_|
+;;
+;; (find-pdflikedef-links "ps" "c fname")
+;;
+;; find-pspage
+;; find-ps-page
+;; code-ps
+;;
+(defalias 'find-pspage
+ 'find-ps-page)
+(defun find-ps-page (fname &optional page &rest rest)
+ (find-bgprocess (ee-find-ps-page fname page)))
+(defvar ee-find-ps-page-options '())
+(defun ee-find-ps-page (fname &optional page)
+ `("gv"
+ ,@ee-find-ps-page-options
+ ,@(if page `(,(format "--page=%d" page)))
+ ,fname))
+
+(defun code-ps (c fname &rest rest)
+ (eval (ee-read (apply 'ee-code-ps c fname rest))))
+(defun find-code-ps (c fname &rest rest)
+ (find-estring-elisp (apply 'ee-code-ps c fname rest)))
+(defun ee-code-ps (c fname &rest rest)
+ (concat (ee-template0 "\
+\(defun find-{c}page (&optional page &rest rest)
+ (find-ps-page {(ee-pp0 fname)} page))
+") (ee-code-pdftext-rest rest)))
+
+
+
+
+
+
+
+;;; __ _ _ _ _
+;;; / _(_)_ __ __| | __ ____ ____ __ | |_ _____ _| |_
+;;; | |_| | '_ \ / _` |____\ \/ /\ \/ /\ \/ /____| __/ _ \ \/ / __|
+;;; | _| | | | | (_| |_____> < > < > <_____| || __/> <| |_
+;;; |_| |_|_| |_|\__,_| /_/\_\/_/\_\/_/\_\ \__\___/_/\_\\__|
+;;;
+
+(defun ee-goto-position-page (&optional pos-spec &rest rest)
+ "Like `ee-goto-position', but interpreting a number as a page number.
+\(Note that POS-SPEC is only interpreted as a page if it is a number.)"
+ (when pos-spec
+ (cond ((numberp pos-spec)
+ (goto-char (point-min))
+ (re-search-forward "[\f]" nil nil (1- pos-spec)))
+ ((stringp pos-spec)
+ (goto-char (save-excursion ; This used to be just:
+ (goto-char (point-min)) ; (goto-char (point-min))
+ (search-forward pos-spec) ; (search-forward pos-spec)
+ (point)))) ;
+ (t (error "This is not a valid pos-spec: %S" pos-spec)))
+ (if rest (ee-goto-rest rest))))
+
+(defun find-sh-page (command &rest pos-spec-list)
+ "Like `find-sh', but interpreting the car of POS-SPEC-LIST as a page."
+ (interactive "sShell command: ")
+ (find-eoutput-reuse
+ command
+ `(insert (shell-command-to-string ,command)))
+ (apply 'ee-goto-position-page pos-spec-list))
+
+;; find-pdf-text
+;;
+(defalias 'find-pdf-text
+ 'find-pdftotext-text)
+(defun find-pdftotext-text (fname &rest rest)
+ (apply 'find-sh-page (ee-find-pdftotext-text fname) rest))
+(defun ee-find-pdftotext-text (fname)
+ (format "pdftotext -layout -enc Latin1 '%s' -" (ee-expand fname)))
+
+(code-brfile 'find-pdf-text
+ :local 'brpdftextl
+ :dired 'brpdftextd)
+
+;; find-djvu-text
+;;
+(defalias 'find-djvu-text
+ 'find-djvutxt-text)
+(defun find-djvutxt-text (fname &rest rest)
+ (apply 'find-sh-page (ee-find-djvutxt-text fname) rest))
+(defun ee-find-djvutxt-text (fname)
+ (format "djvutxt '%s'" fname))
+
+(code-brfile 'find-djvu-text
+ :local 'brdjvutextl
+ :dired 'brdjvutextd)
+
+
+
+;; (find-pdflikedef-links "pdf" "c fname")
+
+(defun code-pdf-text (c fname &optional offset &rest rest)
+ (eval (ee-read (apply 'ee-code-pdf-text c fname offset rest))))
+(defun find-code-pdf-text (c fname &optional offset &rest rest)
+ (find-estring-elisp (apply 'ee-code-pdf-text c fname offset rest)))
+(defun ee-code-pdf-text (c fname &optional offset &rest rest)
+ (setq offset (or offset 0))
+ (concat (ee-template0 "\
+;; {(ee-S `(find-code-pdf-text ,c ,fname ,offset ,@rest))}
+\(defun find-{c}text (&optional page &rest rest)
+ (setq ee-page-c {(ee-pp0 c)})
+ (setq ee-page-fname {(ee-pp0 fname)})
+ (setq ee-page-offset {(ee-pp0 offset)})
+ (apply 'find-pdf-text {(ee-pp0 fname)} page rest))
+
+;; Set the defaults now
+;; See: (find-pdf-like-intro \"find-code-pdf-text\")
+\(setq ee-page-c {(ee-pp0 c)})
+\(setq ee-page-fname {(ee-pp0 fname)})
+\(setq ee-page-offset {(ee-pp0 offset)})
+")))
+
+
+(defun code-djvu-text (c fname &optional offset &rest rest)
+ (eval (ee-read (apply 'ee-code-djvu-text c fname offset rest))))
+(defun find-code-djvu-text (c fname &optional offset &rest rest)
+ (find-estring-elisp (apply 'ee-code-djvu-text c fname offset rest)))
+(defun ee-code-djvu-text (c fname &optional offset &rest rest)
+ (setq offset (or offset 0))
+ (concat (ee-template0 "\
+\(defun find-{c}text (&optional page &rest rest)
+ (setq ee-page-c {(ee-pp0 c)})
+ (setq ee-page-fname {(ee-pp0 fname)})
+ (setq ee-page-offset {(ee-pp0 offset)})
+ (find-djvu-text {(ee-pp0 fname)} page))
+
+;; Set the defaults now - see (find-pdf-like-intro \"find-code-pdf-text\")
+\(setq ee-page-c {(ee-pp0 c)})
+\(setq ee-page-fname {(ee-pp0 fname)})
+\(setq ee-page-offset {(ee-pp0 offset)})
+")))
+
+
+
+;; Tests:
+;; (find-code-pdf-text "foo" "/tmp/foo.pdf" 3)
+;; (code-pdf-text "foo" "/tmp/foo.pdf" 3)
+;; (find-footext)
+;; (find-footext 2)
+
+
+;; (find-efunction 'find-page-links)
+
+
+
+
+
+;; Test:
+;; (find-code-xpdf "{c}" "{fname}" :key "{foo}" :key "{bar}")
+;; (find-xpdfpage "~/tmp/discussao_proifesgroups.pdf")
+
+;; Garbage?
+;; (defun ee-pspage (fname &optional page gvargs)
+;; `("gv" ,@gvargs ,@(if page (list (format "--page=%d" page))) ,fname))
+;; (defun ee-xpdfpage (fname &optional page xpdfargs)
+;; `("xpdf" ,@xpdfargs ,fname ,(format "%s" (or page 1))))
+;; (defun ee-djvupage (fname &optional page)
+;; `("djview" ,@(if page (list (format "--page=%d" page))) ,fname))
+
+
+
+
+
+
+
+(provide 'eev-pdflike)
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-plinks.el b/eev-plinks.el
new file mode 100644
index 0000000..6b03888
--- /dev/null
+++ b/eev-plinks.el
@@ -0,0 +1,147 @@
+;;; eev-plinks.el -- elisp hyperlinks to invoke external processes.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012nov02
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-plinks.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-plinks.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-links-intro.html>
+;; (find-eev-intro)
+;; (find-links-intro)
+
+;;; Commentary:
+
+;; See:
+;; (find-eev "eepitch.el" "find-comintprocess-ne")
+;; (find-eev "eev-blinks.el" "find-sh")
+;; (find-node "(libc)Executing a File" "execv")
+
+;; Obvious applications:
+;; (find-eev "eev-pdflike.el")
+;; (find-eev "eev-audiovideo.el")
+;; (find-eev "eev-brxxx.el")
+
+
+
+;;;
+;;; _ __ _ __ ___ ___ ___ ___ ___ ___ ___
+;;; | '_ \| '__/ _ \ / __/ _ \/ __/ __|/ _ \/ __|
+;;; | |_) | | | (_) | (_| __/\__ \__ \ __/\__ \
+;;; | .__/|_| \___/ \___\___||___/___/\___||___/
+;;; |_|
+;;
+
+;; 2007sep29: Copied these functions from eev-mini.el to here...
+;; In a near future all calls to external processes in eev will happen
+;; through these functions... mainly because (1) they accept their
+;; "program-and-args" argument as either a string (to be split at
+;; whitespace) or as a list of strings, (2) they can either expand
+;; each "word" or "program-and-args" with ee-expand or keep all words
+;; unchanged, (3) they're short and clean.
+
+;; Sorry, no docstrings yet... some tests:
+;; (find-callprocess0 '("lua51" "-e" "print(1+2)"))
+;; (find-callprocess00 '("lua51" "-e" "print(1+2)"))
+
+;; Suffixes:
+;; "-ne" means "(do) not ee-expand"
+;; "0" means "don't display in a temp buffer, just return the string"
+;; "00" means "like `0', but more low-level: don't strip the trailing newline".
+
+(defun ee-split (str) (if (stringp str) (split-string str "[ \t\n]+") str))
+(defun ee-unsplit (list) (if (listp list) (mapconcat 'identity list " ") list))
+(defun ee-split-and-expand (str) (mapcar 'ee-expand (ee-split str)))
+(defun ee-no-trailing-nl (str) (replace-regexp-in-string "\n$" "" str))
+
+(defun find-bgprocess-ne (program-and-args)
+ (let ((argv (ee-split program-and-args)))
+ (apply 'start-process (car argv) "*Messages*" argv)))
+
+(defun find-callprocess00-ne (program-and-args)
+ (let ((argv (ee-split program-and-args)))
+ (with-output-to-string
+ (with-current-buffer standard-output
+ (apply 'call-process (car argv) nil t nil (cdr argv))))))
+
+(defun find-callprocess0-ne (program-and-args)
+ (ee-no-trailing-nl (find-callprocess00 program-and-args)))
+
+(defun find-comintprocess-ne (name program-and-args)
+ (let ((argv (ee-split program-and-args)))
+ (apply 'make-comint name (car argv) nil (cdr argv))
+ (switch-to-buffer (format "*%s*" name))))
+
+(defun find-bgprocess (program-and-args)
+ (find-bgprocess-ne (ee-split-and-expand program-and-args)))
+(defun find-callprocess00 (program-and-args)
+ (find-callprocess00-ne (ee-split-and-expand program-and-args)))
+(defun find-callprocess0 (program-and-args)
+ (find-callprocess0-ne (ee-split-and-expand program-and-args)))
+(defun find-callprocessregion (program-and-args input)
+ (find-callprocessregion (ee-split-and-expand program-and-args)))
+(defun find-comintprocess (name program-and-args)
+ (find-comintprocess-ne name (ee-split-and-expand program-and-args)))
+
+;; These two are like `find-sh', but more low-level.
+(defun find-callprocess-ne (program-and-args &rest pos-spec-list)
+ (apply 'find-eoutput-reuse (ee-unsplit program-and-args)
+ `(insert (find-callprocess00-ne ',program-and-args))
+ pos-spec-list))
+(defun find-callprocess (program-and-args &rest pos-spec-list)
+ (apply 'find-eoutput-reuse (ee-unsplit program-and-args)
+ `(insert (find-callprocess00 ',program-and-args))
+ pos-spec-list))
+
+
+
+
+;; New, 2008jan02
+;; Compare with `ee-find-grep'
+
+(defun ee-find-comintprocess-ne (dir name program-and-args)
+ (switch-to-buffer
+ (with-temp-buffer
+ (cd dir)
+ (find-comintprocess-ne name program-and-args)
+ (current-buffer))))
+
+(defun ee-find-comintprocess (dir name program-and-args)
+ (ee-find-comintprocess-ne
+ (ee-expand dir) name (ee-split-and-expand program-and-args)))
+
+
+(provide 'eev-plinks)
+
+
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-prepared.el b/eev-prepared.el
new file mode 100644
index 0000000..4e3d145
--- /dev/null
+++ b/eev-prepared.el
@@ -0,0 +1,256 @@
+;;; eev-prepared.el -- eev modules that use temporary dirs and prepared shells.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012nov02
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-prepared.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-prepared.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+;; See: (find-eev "eev-env.el")
+;; (find-prepared-intro)
+
+
+
+
+
+(require 'eev-env)
+
+(ee-setenv "EEVTMPDIR" "$HOME/.eev") ; ee.sh and other temp scripts
+(ee-setenv "EEVRCDIR" "$EEVDIR/rcfiles")
+(ee-setenv "EE" "$EEVTMPDIR/ee.sh")
+(ee-setenv "EEG" "$EEVTMPDIR/ee.eeg")
+(ee-setenv "EEGDB" "$EEVTMPDIR/ee.gdb")
+(ee-setenv "EETEX" "$EEVTMPDIR/ee.tex")
+(ee-setenv "EEC" "$EEVTMPDIR/ee.c")
+(ee-setenv "EETMPC" "$EEVTMPDIR/tmp.c")
+(ee-setenv "EEAOUT" "$EEVTMPDIR/ee.aout")
+
+(defvar ee-eevtmpdir (ee-expand "$EEVTMPDIR/")
+ "The directory where the temporary script files are put.")
+
+(defvar ee-eevrcdir (ee-expand "$EEVRCDIR/")
+ "The directory where some auxiliary rcfiles for eev are to be found.")
+
+(defvar ee-file (ee-expand "$EE")
+ "The temporary script file used by `eev'.")
+(defvar ee-file-tex (ee-expand "$EETEX")
+ "The temporary script file used by `eelatex'.")
+(defvar ee-file-gdb (ee-expand "$EEGDB")
+ "The temporary script file used by `eegdb'.")
+(defvar ee-file-generic (ee-expand "$EEG"))
+
+(defvar eelatex-eevscript
+ "cd $EEVTMPDIR/; latex tmp.tex && xdvi tmp.dvi &" "See `eelatex'.")
+
+
+
+(code-c-d "eevtmp" "$EEVTMPDIR/" :anchor) ; (find-eevtmpfile "")
+(code-c-d "eevrc" "$EEVRCDIR/" :anchor) ; (find-eevrcfile "")
+(code-c-d "eevex" "$EEVDIR/examples/" :anchor) ; (find-eevexfile "")
+
+;; (defvar ee-eevdir (ee-expand "$EEVDIR/")
+;; "The directory where the elisp files for eev live.")
+;; (code-c-d "eev" "$EEVDIR/" :anchor) ; (find-eev "")
+
+
+
+;;; __ __
+;;; | \/ | __ __ ___ _____ __
+;;; | |\/| | __ \ \/ / / _ \/ _ \ \ / /
+;;; | | | ||__| > < | __/ __/\ V /
+;;; |_| |_| /_/\_\ \___|\___| \_/
+;;;
+;;; eev and friends (or: saving regions as temporary scripts)
+;;;
+
+(defun ee-se-to-string (s e)
+ "Convert the pair (S E) to a string.
+If S is a number then return the contents of the current buffer
+between the positions S and E; if S is a string then return S and
+ignore E. See `write-region' - it uses the same convention for
+interpreting \"(S E)\"-pairs as this function."
+ (cond ((numberp s) (buffer-substring-no-properties s e))
+ ((stringp s) s)))
+
+(defun octal-to-num (str)
+ "Convert STR - a sequence of octal digits - to a number."
+ (let ((lastv (- (string-to-char (substring str -1)) ?0))
+ (rest (substring str 0 -1)))
+ (if (string= "" rest) lastv (+ lastv (* 8 (octal-to-num rest))))))
+
+(defun ee-write-string (str &optional altfile fmode)
+ "Write STR to ALTFILE, or to ee-file if ALTFILE is nil.
+FMODE should be either nil or a string containing a sequence of
+octal digits; if it is not nil then do the equivalent of a
+\"chmod FMODE file\"."
+ (let ((fname (substitute-in-file-name (or altfile ee-file))))
+ (write-region str nil fname) ; a standard kludge
+ (if fmode (set-file-modes fname (octal-to-num fmode)))))
+
+(defun ee-write (s e pre post &optional altfile fmode)
+ "Write PRE+(ee-se-to-string S E)+POST to ALTFILE, or to `ee-file'.
+PRE and POST must be strings. See `ee-se-to-string' and
+`ee-write-string'."
+ (ee-write-string (concat pre (ee-se-to-string s e) post)
+ altfile fmode))
+
+(defun ee-se-to-string-with-nl (s e)
+ "Same as `ee-se-to-string', but force the result to end with a newline."
+ (let ((str (ee-se-to-string s e)))
+ (if (string-match "[^\n]\\'" str) (concat str "\n") str)))
+
+(defun ee-write-with-nl (s e pre post &optional altfile fmode)
+ "Same as `ee-write', but using `ee-se-to-string-with-nl'."
+ (ee-write-string (concat pre (ee-se-to-string-with-nl s e) post)
+ altfile fmode))
+
+
+
+(defun eev (s &optional e altfile)
+ "Save the region in `ee-file', or in ALTFILE if it is non-nil.
+If S is a string write then write the string instead. See `ee-write'.
+This function is mostly used to send blocks of commands to shells via
+a temporary script file. The shells do not receive the commands
+immediately - we need to tell them to execute the commands stored in
+the temporary script.\n
+For example, if we mark the block below and type `M-x eev',\n
+ # A hyperlink: (find-efunction 'eev)
+ echo $[1+2]
+ # Temporary scripts can change the
+ # directory and the environment.
+ cd /tmp/\n
+and then go to a prepared shell and run `ee', we see something like
+this:\n
+ /home/edrx$ ee
+ # A hyperlink: (find-efunction 'eev)
+ echo $[1+2]
+ 3
+ # Temporary scripts can change the
+ # directory and the environment.
+ cd /tmp/
+ /tmp$ \n
+Note that this only works in \"prepared shells\", where `ee' has been
+defined as a shell function in the correct way; the relevant code for
+.bashrc or .zshrc is this:\n
+ export EEVTMPDIR ;: ${EEVTMPDIR:=~/.eev}
+ export EE ;: ${EE:=$EEVTMPDIR/ee.sh}
+ function ee () { set -v; . $EE$*; set +v; }\n
+See: (find-eevfile \"INSTALL\")
+and: (find-eevfile \"eev-rctool\")"
+ (interactive "r")
+ (ee-write-with-nl s e "" "" altfile)
+ (format "eev: wrote %s" (or altfile ee-file)))
+
+(defun eevs (s &optional e suffix)
+ "Like `eev', but with a suffix; write the region to `ee-file'+SUFFIX.
+For example, if $EE is \"~/.eev/ee.sh\" and SUFFIX is \"0\" then
+write the region to the file \"~/.eev/ee.sh0\". The shell
+function \"ee\" concatenates its first argument to the value of
+$EE, so running \"ee 0\" on a prepared shell executes the
+temporary script \"~/.eev/ee.sh0\" instead of \"~/.eev/ee.sh\".
+If S is a string write then write the string instead. See `ee-write'."
+ (interactive "r\nsSuffix: ")
+ (eev s e (concat ee-file suffix)))
+
+(defun eelatex (s &optional e)
+ "Save the region to `ee-file-tex', then save `eelatex-eevscript' to
`ee-file'.
+An example: run `M-x eelatex' on the line below,
+
+ Hello! $\\frac{42}{\\sqrt{5}}$
+
+then go to a prepared shell and run \"ee\". A temporary LaTeX
+file will be processed by \"latex\" and the resulting dvi file
+will be shown on the screen.
+If S is a string write then write the string instead. See `eev'."
+ (interactive "r")
+ (ee-write s e "" "" ee-file-tex)
+ (eev eelatex-eevscript nil)
+ (format "eelatex: wrote %s and %s" ee-file-tex ee-file))
+
+(defun eegdb (s &optional e)
+ "Save the region to the temporary GDB script file given by `ee-file-gdb'.
+After that if your GDB init file was prepared adequately then
+running \"ee\" on a GDB prompt will make GDB execute the commands
+in the temporary GDB script.
+If S is a string write then write the string instead. See `eev'."
+ (interactive "r")
+ (ee-write s e "" "" ee-file-gdb)
+ (format "eegdb: wrote %s" ee-file-gdb))
+
+;; Obsolete, or almost? Used by: (find-eevfile "eeg4")
+(defun eeg (s &optional e)
+ (interactive "r")
+ (ee-write s e "" "" ee-file-generic)
+ (format "eeg: wrote %s" ee-file-gdb))
+
+(defun eeeval (s &optional e)
+"Like `eev', but instead of saving the region execute it immediately as Lisp.
+This function is very similar to `eval-region'."
+ (interactive "r")
+ (eval (read (concat "(progn " (ee-se-to-string s e) "\n)"))))
+
+
+
+(defun ee-default-directory ()
+ "Return `default-directory' usually, but behave specially in some modes.
+If the current buffer is a w3m buffer that is visiting a local
+file (i.e., if the url is like \"file://...\") then extract the
+directory from the url instead of returning the value of
+`default-directory'.\n
+This function is used by `eecd'."
+ (if (eq major-mode 'w3-mode)
+ (let ((url (url-view-url 0)))
+ (if (string-match "^file:\\(.*/\\)[^/]*$" url)
+ (match-string 1 url)
+ (error "Current url is %S, which is not a local file" url)))
+ default-directory))
+
+;; 2005jan10, incompatible change: added "dir"
+(defun eecd (&optional dir command)
+ "Save to $EE a \"cd\" command to `cd' to the current directory.
+If DIR is not nil then use DIR; otherwise run `ee-default-directory'.
+If COMMAND is not nil then save \"cd DIR; COMMAND\" instead of just
+\"cd DIR\".\n
+See `eev' for more about $EE and the temporary script file."
+ (interactive)
+ (eev (concat "cd " (file-name-directory
+ (or dir (ee-default-directory)))
+ "\n" (or command ""))))
+
+
+
+(provide 'eev-prepared)
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-rcirc.el b/eev-rcirc.el
new file mode 100644
index 0000000..fbd5f7d
--- /dev/null
+++ b/eev-rcirc.el
@@ -0,0 +1,127 @@
+;;; eev-rcirc.el -- rcirc-related elisp hyperlinks.
+
+;; Copyright (C) 2012,2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug16
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-rcirc.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-rcirc.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+
+
+
+
+;; When we run (rcirc-connect "irc.freenode.net" ...)
+;; and the buffer "*irc.freenode.net*" already exists, `rcirc-connect'
+;; does nasty things; so it's better to run
+;; (eepitch '(ee-rcirc-connect))
+;; instead.
+;;
+;; Actually we want to do another trick too. Killing the buffer
+;; "*irc.freenode.net*" is too expensive, as reconnection takes about
+;; 10 seconds; so we set `eepitch-kill' to something different from
+;; the default, which is `(eepitch-kill-buffer)'.
+
+(defun ee-rcirc-serverbuf (server) (format "*%s*" server))
+(defun ee-rcirc-channelbuf (server channel) (format "address@hidden" channel
server))
+(defun ee-rcirc-connected (server)
+ (and (get-buffer (ee-rcirc-serverbuf server))
+ (rcirc-buffer-process (ee-rcirc-serverbuf server))))
+
+(defun ee-rcirc-connect (server channels)
+ "Connect to an irc server (if not already connected).
+TODO: if we are already connected to SERVER, just connect to CHANNELS."
+ (if (not (ee-rcirc-connected server))
+ (rcirc-connect server nil nil nil nil channels))
+ (switch-to-buffer (ee-rcirc-serverbuf server)))
+
+
+
+;; Hyperlinks to rcirc buffers
+;;
+(defun find-rcirc-buffer (server channels &optional channel &rest
pos-spec-list)
+ "Connect to an irc server (if not already connected) and switch to CHANNEL.
+If CHANNEL is a string starting with \"#\", it is a channel to /join;
+if CHANNEL is a string not starting with \"#\", it is a nick to /query;
+if CHANNEL is nil, that means to use the server buffer."
+ (ee-rcirc-connect server channels)
+ (if channel
+ (if (equal "#" (substring channel 0 1))
+ (rcirc-cmd-join channel)
+ (rcirc-cmd-query channel)))
+ (apply 'ee-goto-position pos-spec-list))
+
+(defvar ee-freenode-server "irc.freenode.net")
+(defvar ee-freenode-channels '("#eev"))
+
+(defun find-freenode (&optional channel &rest pos-spec-list)
+ (apply 'find-rcirc-buffer
+ ee-freenode-server ee-freenode-channels channel pos-spec-list))
+
+;; (find-freenode "#eev")
+;; (find-freenode "#org-mode")
+;; (find-freenode "edrx")
+
+
+;; (find-freenode)
+
+
+
+
+
+;; Support for eepitch'ing to rcirc buffers
+;;
+(defun ee-rcirc-sexp (server channel)
+ `(find-ebuffer ,(ee-rcirc-channelbuf server channel)))
+
+(defun eepitch-kill-rcirc (server)
+ (message "Not killing: %S" (ee-rcirc-serverbuf server)))
+
+(defun eepitch-rcirc-server (server channels)
+ "Connect to the irc server SERVER if not already connected, and to CHANNELS."
+ (interactive)
+ (eepitch `(ee-rcirc-connect ,server ',channels))
+ (setq eepitch-kill `(eepitch-kill-rcirc ,server))
+ (ee-rcirc-sexp server (car channels))) ; easter egg (use M-1 C-x C-e)
+
+(defun eepitch-freenode (&optional channels) (interactive)
+ (eepitch-rcirc-server "irc.freenode.net" (or channels '("#eev"))))
+
+(defun eepitch-ircgnome (&optional channels) (interactive)
+ (eepitch-rcirc-server "irc.gnome.org" (or channels '("#docs"))))
+
+
+
+(provide 'eev-rcirc)
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev-readme.el b/eev-readme.el
new file mode 100644
index 0000000..d451474
--- /dev/null
+++ b/eev-readme.el
@@ -0,0 +1,96 @@
+;; eev-readme.el -- an executable README for eev2 (-> eev-0.96).
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012dec29
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-readme.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-eev-update-intro.html>
+;; (find-eev-intro)
+;; (find-eev-update-links)
+
+;;; Commentary:
+
+;; Quick instructions:
+;;
+;; 1) Download http://angg.twu.net/eev-current/eev2.tgz
+;; 2) Unpack it somewhere - for example, in "/tmp/eev/".
+;; 3) One of the files in eev2.tgz is called "eev-readme.el" (a.k.a.
+;; "this file"). Open it with Emacs. Suggestion: invoke Emacs with
+;; "emacs -fg bisque -bg black eev-readme.el", to get good colors.
+;; So, 1-3 can be:
+;;
+;; mkdir /tmp/eev/
+;; cd /tmp/eev/
+;; wget http://angg.twu.net/eev-current/eev2.tgz
+;; tar -xvzf eev2.tgz
+;; emacs -fg bisque -bg black eev-readme.el
+;;
+;; 4) Execute the multi-line "(progn ...)" block below. To do that,
+;; put the cursor after the ')' that is on a line by itself and
+;; type `C-x C-e' (`eval-last-sexp').
+;; 5) Or, instead of executing the "(progn ...)" block below by hand
+;; with `C-x C-e', you can use a command-line argument to make
+;; Emacs execute ("load") this whole file:
+;;
+;; emacs -fg bisque -bg black -l eev-readme.el
+;;
+;; 6) Now you should have eev-mode activated - and the mode line
+;; for this buffer should show an "eev", like this:
+;; _______________________________________________________
+;; | |
+;; | (...) |
+;; | |
+;; |-:--- eev-readme.el 16% L23 (Emacs-Lisp eev)-----|
+;; |_______________________________________________________|
+;;
+;; this means that the eev-mode keybindings are available.
+;;
+;; The most important key is `M-e', which operates on the "sexp at
+;; eol", the sexp whose last `)' is at the end of the current line.
+;; A plain `M-e' executes the sexp at eol, and is roughly
+;; equivalent to `C-e C-x C-e' (where `C-e' moves to eol).
+;; If you type `M-0 M-e' (which we will abbreviate as `M-0e'),
+;; this moves to eol and highlights the sexp at eol instead of
+;; evaluating it.
+;;
+;; 7) You can now type:
+;; `M-0e' to highlight the sexp at eol - try: (eek "M-0 M-e")
+;; `M-e' to execute the sexp at eol (-> follow a hyperlink),
+;; `M-k' to kill the current buffer (-> go back),
+;; `M-j' to go to the list of predefined targets for `M-j',
+;; `M-5j' to go to the list of "intros", (find-eev-intro)
+;; `M-50j' to come back to this readme, i.e., (find-eev "eev-readme.el")
+;; `M-59j' to visit this: (find-eev-update-links)
+;; that contains scripts for installing and updating eev2.
+;; If you are an Emacs newbie, then this may be interesting too:
+;; `M-2j' visits the list of basic keys in: (find-emacs-intro)
+;;
+(progn
+ (add-to-list 'load-path default-directory)
+ (require 'eev2-all)
+ (eev-mode 1)
+ )
+
+;; (insert-file "2.el")
diff --git a/eev-tlinks.el b/eev-tlinks.el
new file mode 100644
index 0000000..b193bc8
--- /dev/null
+++ b/eev-tlinks.el
@@ -0,0 +1,1438 @@
+;;; eev-tlinks.el --- hyperlinks to temporary buffers generated by templates
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug23
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-tlinks.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-tlinks.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-links-intro.html>
+;; (find-eev-intro)
+;; (find-links-intro)
+
+;;; Commentary:
+
+;; (find-eev "eev-elinks.el")
+;; (find-efunctiondescr 'ee-upload-links)
+;; (find-eev "eev-wrap.el" "eewrap-eewrap")
+
+
+
+
+;; �.ee-copy-after-and� (to "ee-copy-after-and")
+;;
+;; �.find-find-links-links� (to "find-find-links-links")
+;; �.find-intro-links� (to "find-intro-links")
+;; �.find-pdflikedef-links� (to "find-pdflikedef-links")
+;; �.find-eev-header-links� (to "find-eev-header-links")
+;;
+;; �.find-debpkg-links� (to "find-debpkg-links")
+;; �.find-eev-update-links� (to "find-eev-update-links")
+;; �.find-newhost-links� (to "find-newhost-links")
+;; �.find-dhmake-links� (to "find-dhmake-links")
+;; �.find-youtubedl-links� (to "find-youtubedl-links")
+;; �.find-upload-links� (to "find-upload-links")
+;; �.find-psne-links� (to "find-psne-links")
+;; �.find-git-links� (to "find-git-links")
+;; �.find-netcat-test-links� (to "find-netcat-test-links")
+;; �.find-eev-video-links� (to "find-eev-video-links")
+
+
+(require 'eev-env)
+
+
+
+;; �ee-copy-after-and� (to ".ee-copy-after-and")
+;; A hack for template-based find-*-links functions in which the
+;; second half of the buffer in meant to be copied to somewhere else.
+;;
+(defun ee-count-lines (str)
+ "Count the number of lines in STR (which should be newline-terminated)."
+ (length (replace-regexp-in-string "[^\n]" "" str)))
+
+(defun ee-copy-after-and (nlines code)
+ "Copy into the kill ring everything from NLINES down on, and run CODE."
+ (move-beginning-of-line (- nlines 1))
+ (kill-new (buffer-substring (point) (point-max)))
+ (eval code)
+ (let ((n (ee-count-lines (ee-last-kill))))
+ `(Copied ,n lines to the kill ring - use C-y to paste)))
+
+(defun ee-copy-after-and-2b (nlines code)
+ "Copy into the kill ring everything from NLINES down on, and run CODE.
+The target of the hyperlink in CODE is opened in the right-side window."
+ (ee-copy-after-and nlines `(find-2b nil ',code)))
+
+
+
+
+;;; __ _ _ _ _ _ /\ ____
+;;; / _(_)_ __ __| | | (_)_ __ | | ____|/\|___ \
+;;; | |_| | '_ \ / _` |_____| | | '_ \| |/ / __| __) |
+;;; | _| | | | | (_| |_____| | | | | | <\__ \ / __/
+;;; |_| |_|_| |_|\__,_| |_|_|_| |_|_|\_\___/ |_____|
+;;;
+;;
+;; �find-find-links-links� (to ".find-find-links-links")
+;; See:
+;; (find-eev "eev-template.el" "find-find-links-links")
+;; (find-find-links-links "u" "find-links" "k stem args")
+
+(defun ee-prepend-commas (str)
+ (save-match-data
+ (replace-regexp-in-string "\\([^ ]+\\)" ",\\1" str)))
+(defun ee-if-nil-setq (str)
+ (format "(setq %s (or %s \"{%s}\"))" str str str))
+(defun ee-if-nil-setqs (vars sep)
+ (mapconcat 'ee-if-nil-setq (save-match-data (ee-split vars)) sep))
+
+(defun find-find-links-links (&optional k stem args &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks for foo."
+ (interactive)
+ (setq k (or k "{k}"))
+ (setq stem (or stem "{stem}"))
+ (setq args (or args "{args}"))
+ (apply 'find-elinks-elisp
+ `((find-find-links-links ,k ,stem ,args ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-find-links-links)
+ ""
+ ,(ee-template0 "\
+;; See: (find-links-intro)
+;; (find-templates-intro)
+
+;; <find-{stem}-links>
+;; {(ee-S `(find-find-links-links ,k ,stem ,args))}
+;; A test: (find-{stem}-links ___)
+\(define-key eev-mode-map \"\\M-h{k}\" 'find-{stem}-links)
+
+\(defun find-{stem}-links (&optional {args} &rest pos-spec-list)
+\"Visit a temporary buffer containing hyperlinks for foo.\"
+ (interactive)
+ {(ee-if-nil-setqs args \"\n \")}
+ (apply 'find-elinks
+ `((find-{stem}-links {(ee-prepend-commas args)} ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-{stem}-links)
+ \"\"
+ ,(ee-template0 \"\\
+\")
+ )
+ pos-spec-list))
+
+;; Test: (find-{stem}-links ___)
+
+
+;; ,@(ee-find-{stem}-links {args})
+;;
+\(defun ee-find-{stem}-links ({args})
+ \"Return a list of sexps and strings for {stem}.
+This is an internal function used by `find-{stem}-links'.\"
+ `(
+ ))")
+ ) pos-spec-list))
+
+
+
+;;; _ _ _ _ _
+;;; (_)_ __ | |_ _ __ ___ | (_)_ __ | | _____
+;;; | | '_ \| __| '__/ _ \ _____| | | '_ \| |/ / __|
+;;; | | | | | |_| | | (_) |_____| | | | | | <\__ \
+;;; |_|_| |_|\__|_| \___/ |_|_|_| |_|_|\_\___/
+;;;
+;; �find-intro-links� (to ".find-intro-links")
+;; (find-find-links-links "i" "intro" "stem")
+;; A test: (find-intro-links)
+(define-key eev-mode-map "\M-hi" 'find-intro-links)
+
+(defun ee-intro-stem (bufname)
+ (if (string-match "^\\*(find-\\(.*\\)-intro)\\*$" bufname)
+ (match-string 1 bufname)))
+
+(defun find-intro-links (&optional stem &rest pos-spec-list)
+"Visit a temporary buffer with a skeleton for defining `find-<STEM>-intro'.
+See: (find-eev \"eev-intro.el\")"
+ (interactive (list (ee-intro-stem (buffer-name))))
+ (setq stem (or stem "{stem}"))
+ (apply 'find-elinks-elisp
+ `((find-intro-links ,stem ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-intro-links)
+ ,(ee-template0 "\
+;; (find-{stem}-intro)
+
+;; <find-{stem}-intro>
+;; (find-intro-links \"{stem}\")
+
+\(defun find-{stem}-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name \"*(find-{stem}-intro)*\"))
+ (apply 'find-estring \"\\
+\\(Re)generate: (find-{stem}-intro)
+Source code: (find-efunction 'find-{stem}-intro)
+More intros: (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+Is is meant as both a tutorial and a sandbox.
+
+Hello
+=====
+\" pos-spec-list)))
+
+;; (find-{stem}-intro)
+")) pos-spec-list))
+
+;; (find-intro-links "emacs")
+
+
+
+
+
+;;; _ __ _ _ _ _ __
+;;; _ __ __| |/ _| (_) | _____ __| | ___ / _|
+;;; | '_ \ / _` | |_| | | |/ / _ \/ _` |/ _ \ |_
+;;; | |_) | (_| | _| | | < __/ (_| | __/ _|
+;;; | .__/ \__,_|_| |_|_|_|\_\___|\__,_|\___|_|
+;;; |_|
+;;
+;; �find-pdflikedef-links� (to ".find-pdflikedef-links")
+;; Used in: (find-eev "eev-pdflike.el")
+;; e.g.: (find-efunction 'find-xdvi-page)
+;; (find-find-links-links "pdflikedef" "stem firstargs")
+;;
+(defun find-pdflikedef-links (&optional stem firstargs &rest rest)
+ "Visit a temporary buffer containing hyperlinks for pdflikedef."
+ (interactive)
+ (setq stem (or stem "{stem}"))
+ (setq firstargs (or firstargs "{firstargs}"))
+ (apply 'find-elinks-elisp `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-pdflikedef-links ,stem ,firstargs ,@rest)
+ (find-efunction 'find-pdflikedef-links)
+ (emacs-lisp-mode)
+ ;; Body:
+ ""
+ ,(ee-template0 "\
+;; (find-efunction 'code-{stem})
+
+;; find-{stem}page
+;; find-{stem}-page
+;; code-{stem}
+;;
+\(defalias 'find-{stem}page
+ 'find-{stem}-page)
+\(defun find-{stem}-page (fname &optional page &rest rest)
+ (find-bgprocess (ee-find-{stem}-page fname page)))
+\(defvar ee-find-{stem}-page-options '())
+\(defun ee-find-{stem}-page (fname &optional page)
+ `(\"{stem}\"
+ ,@ee-find-{stem}-page-options
+ ,@(if page `(,(format \"--page=%d\" page)))
+ ,fname))
+
+\(defun code-{stem} ({firstargs} &rest rest)
+ (eval (ee-read (apply 'ee-code-{stem} {firstargs} rest))))
+\(defun find-code-{stem} ({firstargs} &rest rest)
+ (find-estring-elisp (apply 'ee-code-{stem} {firstargs} rest)))
+\(defun ee-code-{stem} ({firstargs} &rest rest)
+ (concat (ee-template0 \"\\
+\\(defun find-{<}c{>}page (&optional page &rest rest)
+ (find-{stem}-page {<}(ee-pp0 fname){>} page))
+{<}(ee-code-pdftext-rest rest){>}
+\") (ee-code-pdftext-rest rest)))
+
+\(code-brfile 'find-xpdf-page :local 'brxpdfl :dired 'brxpdfl)
+
+
+;; Tests:
+;; (find-epp (ee-find-{stem}-page \"/tmp/foo.pdf\"))
+;; (find-epp (ee-find-{stem}-page \"/tmp/foo.pdf\" 2))
+;; (find-{stem}-page \"/tmp/foo.pdf\")
+;; (find-{stem}-page \"/tmp/foo.pdf\" 2)
+;;
+;; (find-code-{stem} \"foo\" \"/tmp/foo.pdf\")
+;; (code-{stem} \"foo\" \"/tmp/foo.pdf\")
+;; (find-foopage)
+;; (find-foopage 2)
+;; (code-pdftotext \"foo\" \"/tmp/foo.pdf\")
+")
+ ) rest))
+
+;; (find-pdflikedef-links "djvu" "c fname")
+;; (find-efunctionpp 'find-pdflikedef-links)
+
+
+
+
+;;; _ _
+;;; ___ _____ __ | |__ ___ __ _ __| | ___ _ __
+;;; / _ \/ _ \ \ / /____| '_ \ / _ \/ _` |/ _` |/ _ \ '__|
+;;; | __/ __/\ V /_____| | | | __/ (_| | (_| | __/ |
+;;; \___|\___| \_/ |_| |_|\___|\__,_|\__,_|\___|_|
+;;;
+;; �find-eev-header-links� (to ".find-eev-header-links")
+;; (find-find-links-links "<none>" "eev-header" "stem-el date")
+;; A test: (find-eev-header-links "eev-audiovideo.el")
+
+(defun find-eev-header-links (&optional stem-el date &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks for foo."
+ (interactive)
+ (setq stem-el (or stem-el "{stem-el}"))
+ (setq date (or date (downcase (format-time-string "%Y%b%d"))))
+ (apply 'find-elinks-elisp
+ `((find-eev-header-links ,stem-el ,date ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-eev-header-links)
+ (find-eev ,stem-el)
+ (wrobak 2 '(find-eev ,stem-el))
+ ,(ee-template0 "
+;;; {stem-el} -- ???.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: {date}
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/{stem-el}>
+;; htmlized: <http://angg.twu.net/eev-current/{stem-el}.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: \"defun %s \"
+;; no-byte-compile: t
+;; End:
+")) pos-spec-list))
+
+
+
+
+;;; __ _ _ _ _ _
+;;; / _(_)_ __ __| | __| | ___| |__ _ __ | | ____ _
+;;; | |_| | '_ \ / _` |_____ / _` |/ _ \ '_ \| '_ \| |/ / _` |
+;;; | _| | | | | (_| |_____| (_| | __/ |_) | |_) | < (_| |
+;;; |_| |_|_| |_|\__,_| \__,_|\___|_.__/| .__/|_|\_\__, |
+;;; |_| |___/
+;;
+;; �find-debpkg-links� (to ".find-debpkg-links")
+
+(defun ee-links-for-debpkg (pkgname)
+ "Return the three main links for the debian package PKGNAME."
+ (list (ee-template0 "\
+{ee-H}(find-status \"{pkgname}\")
+{ee-H}(find-vldifile \"{pkgname}.list\")
+{ee-H}(find-udfile \"{pkgname}/\")")))
+
+(defun ee-dfs0 (pkg ext)
+ "If the file /var/lib/dpkg/info/PKG.EXT exists, return a link to it."
+ (let ((fname (concat pkg "." ext)))
+ (if (file-exists-p (ee-vldifile fname))
+ `(find-vldifile ,fname))))
+
+(defun ee-links-for-debpkg-extra-vldi (pkg)
+ "Return a list of links for files in /var/lib/dpkg/info/ belonging to PKG.
+This is an internal function used by `find-debpkg-links'."
+ (list (ee-dfs0 pkg "preinst") (ee-dfs0 pkg "postinst")
+ (ee-dfs0 pkg "prerm") (ee-dfs0 pkg "postrm")
+ (ee-dfs0 pkg "conffiles") (ee-dfs0 pkg "config")
+ (ee-dfs0 pkg "templates")
+ (ee-dfs0 pkg "md5sums") (ee-dfs0 pkg "shlibs")
+ ))
+
+(defun ee-debian-pooldir (pkg)
+ "Used by `find-debpkg-links'; \"foo\" -> \"f\", \"libfoo\" -> \"libf\"."
+ (if (string-match "^\\(lib\\)?." pkgname)
+ (match-string 0 pkgname)))
+
+(defun find-debpkg-links (&optional pkgname &rest rest)
+ "Visit a temporary buffer containing hyperlinks related to a Debian package.
+Try this: (find-debpkg-links \"bash\")"
+ (interactive (list (ee-debpkgname-ask)))
+ (setq pkgname (or pkgname "{pkgname}"))
+ (let ((p (ee-debian-pooldir pkgname)))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-debpkg-links ,pkgname ,@rest)
+ (find-available ,pkgname)
+ ""
+ ,@(ee-links-for-debpkg pkgname)
+ ""
+ ,@(ee-links-for-debpkg-extra-vldi pkgname)
+ ""
+ ,(ee-template0 "\
+{ee-H}(find-sh \"apt-cache dump | grep-dctrl -P {pkgname}\")
+{ee-H}(find-sh \"apt-cache search {pkgname} | sort\")
+{ee-H}(find-sh \"apt-cache showpkg {pkgname}\")
+{ee-H}(find-sh \"grep-aptavail -P {pkgname}\")
+
+http://packages.debian.org/{pkgname}
+http://packages.debian.org/src:{pkgname}
+http://ftp.debian.org/debian/pool/main/{p}/{pkgname}/
+http://backports.org/debian/pool/main/{p}/{pkgname}/
+http://bugs.debian.org/cgi-bin/pkgreport.cgi?which=pkg&data={pkgname}&archive=no
+
+http://packages.ubuntu.org/{pkgname}
+
+ (eepitch-shell2)
+sudo apt-get install {pkgname}
+sudo apt-get install -y {pkgname}
+")
+ ) rest)))
+
+
+
+;;; __ _ _ _ _ _ _ _
+;;; / _(_)_ __ __| | __| |___ ___| |__ _ _(_) | __| |
+;;; | |_| | '_ \ / _` |_____ / _` / __|/ __| '_ \| | | | | |/ _` |
+;;; | _| | | | | (_| |_____| (_| \__ \ (__| |_) | |_| | | | (_| |
+;;; |_| |_|_| |_|\__,_| \__,_|___/\___|_.__/ \__,_|_|_|\__,_|
+;;;
+;; This is a VERY EARLY prototype (hi Marc!)
+;; of a rewrite of something that was very ugly.
+
+;; (find-angg ".emacs" "find-dpkg-build-escript")
+
+(defun ee-dsc-url-split (dsc-url)
+ "Example:
+ (ee-dsc-url-split
+
\"http://ftp.debian.org/debian/pool/main/i/imagemagick/imagemagick_6.2.4.5.dfsg1-0.9.dsc\")
+ -> (\"http\" \"ftp.debian.org/debian/pool/main/i/imagemagick/\"
+ \"imagemagick\" \"6.2.4.5.dfsg1\" \"-0.9\")"
+ (let ((prot://dir/ (file-name-directory dsc-url))
+ (fname-dsc (file-name-nondirectory dsc-url))
+ prot dir/ xxx vvv -sv)
+ (if (string-match "^\\([a-z]+\\)://\\(.*\\)" prot://dir/)
+ (setq prot (match-string 1 prot://dir/)
+ dir/ (match-string 2 prot://dir/)))
+ (if (string-match "^\\([^_]+\\)_\\([^-]+\\)\\(-.*\\)?\\.dsc$" fname-dsc)
+ (setq xxx (match-string 1 fname-dsc)
+ vvv (match-string 2 fname-dsc)
+ -sv (or (match-string 3 fname-dsc) "")))
+ (list prot dir/ xxx vvv -sv)))
+
+(defun ee-links-for-dscbuild (dsc-url)
+ (apply 'ee-links-for-dscbuild0
+ (downcase (format-time-string "%Y%b%d"))
+ (ee-dsc-url-split dsc-url)))
+
+(defun ee-links-for-dscbuild0 (date prot dir/ xxx vvv -sv)
+ (ee-template
+ '(date prot dir/ xxx vvv -sv) "\
+#####
+#
+# {xxx} (from the debian sources)
+# {date}
+#
+#####
+
+# <{xxx}-deb-src>
+# {prot}://{dir/}
+# {prot}://{dir/}{xxx}_{vvv}{-sv}.dsc
+# {prot}://{dir/}{xxx}_{vvv}{-sv}.diff.gz
+# {prot}://{dir/}{xxx}_{vvv}.orig.tar.gz
+#
+rm -Rv ~/usrc/{xxx}/
+mkdir ~/usrc/{xxx}/
+cd $S/{prot}/{dir/}
+cp -v {xxx}_{vvv}* ~/usrc/{xxx}/
+cd ~/usrc/{xxx}/
+dpkg-source -sn -x {xxx}_{vvv}{-sv}.dsc
+cd ~/usrc/{xxx}/{xxx}-{vvv}/
+dpkg-buildpackage -us -uc -b -rfakeroot 2>&1 | tee odb
+
+#
+# (find-fline \"~/usrc/{xxx}/\")
+ (eepitch-shell)
+cd ~/usrc/{xxx}/
+sudo dpkg -i *.deb
+
+#
+# (code-c-d \"{xxx}\" \"~/usrc/{xxx}/{xxx}-{vvv}/\")
+# (find-{xxx}file \"\")"))
+
+
+
+;;; _ _
+;;; ___ _____ __ _ _ _ __ __| | __ _| |_ ___
+;;; / _ \/ _ \ \ / /____| | | | '_ \ / _` |/ _` | __/ _ \
+;;; | __/ __/\ V /_____| |_| | |_) | (_| | (_| | || __/
+;;; \___|\___| \_/ \__,_| .__/ \__,_|\__,_|\__\___|
+;;; |_|
+;;
+;; �find-eev-update-links� (to ".find-eev-update-links")
+;; (find-find-links-links "<none>" "eev-update" "dir")
+;; A test: (find-eev-update-links)
+
+(defun find-eev-update-links (&optional dir &rest pos-spec-list)
+"Visit a temporary buffer with scripts for installing and updating eev."
+ (interactive)
+ (setq dir (or dir ee-eevdir))
+ (apply 'find-elinks
+ `((find-eev-update-links ,dir ,@pos-spec-list)
+ (find-eev-update-links "/tmp/eev/" ,@pos-spec-list)
+ (find-eev-update-links "~/eev/" ,@pos-spec-list)
+ (find-eev-update-links "{dir}" ,@pos-spec-list)
+ ,(ee-template0 "\
+#
+# In most \"*Elisp hyperlinks\" buffers the top sexp can be used
+# to re-generate the buffer, and it may be followed by other
+# similar sexps that re-generate the buffer using different
+# parameters in the templates.
+#
+# Try the top sexps above, and also see:
+# (find-links-intro)
+# (find-eev \"eev-readme.el\")
+
+
+
+# Download / unpack the tarball
+# =============================
+# See: (find-eepitch-intro)
+# (find-eev \"eev-readme.el\")
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+#rm -Rv {dir}
+mkdir {dir}
+cd {dir}
+rm -v eev2.tgz
+wget http://angg.twu.net/eev-current/eev2.tgz
+tar -xvzf eev2.tgz
+
+# Tests:
+emacs -Q -fg bisque -bg black -l eev-readme.el eev-readme.el
+emacs -Q -fg bisque -bg black eev-readme.el
+emacs -fg bisque -bg black eev-readme.el
+
+
+
+# Tell Emacs to load eev2 by default
+# ==================================
+# Emacs executes the file ~/.emacs when it starts up - see:
+# (find-enode \"Init File\")
+# The easiest way to make Emacs load eev2 by default is to
+# open your ~/.emacs in another window with:
+# (find-wset \"1so_o\" '(find-fline \"~/.emacs\"))
+# and then copy the elisp code below to it.
+
+;; Load eev2.
+;; See: (find-file \"{dir}\")
+;; (find-file \"{dir}eev-readme.el\")
+;; Generated by: (find-eev-update-links \"{dir}\")
+;;
+\(add-to-list 'load-path \"{dir}\")
+\(require 'eev2-all) ; (find-eev \"eev2-all.el\")
+\(eev-mode 1) ; (find-eev \"eev-mode.el\")
+")) pos-spec-list))
+
+;; (find-eev-update-links)
+
+
+
+
+;;; _ _
+;;; _ __ _____ _| |__ ___ ___| |_
+;;; | '_ \ / _ \ \ /\ / / '_ \ / _ \/ __| __|
+;;; | | | | __/\ V V /| | | | (_) \__ \ |_
+;;; |_| |_|\___| \_/\_/ |_| |_|\___/|___/\__|
+;;;
+;; �find-newhost-links� (to ".find-newhost-links")
+;; Scripts to connect to a newly-installed Debian machine
+;; (find-angg ".emacs.templates" "find-newhost-links")
+;; (find-find-links-links "newhost" "thatmname thatip thismname thisip
thisiface")
+;; (find-angg "bin/etc.lua" "inet_addr")
+
+(defvar ee-this-mname nil)
+(defvar ee-this-iface "wlan0")
+(defvar ee-this-ip nil)
+;;
+(defun ee-this-mname () (find-sh0 "uname -n"))
+(defun ee-this-ip (&optional iface)
+ (find-sh0 (format "/sbin/ifconfig %s | etc.lua inet_addr"
+ (or ee-this-iface iface))))
+;;
+;; (find-sh0 "uname -n")
+;; (find-sh0 "/sbin/ifconfig")
+;; (find-sh0 "/sbin/ifconfig wlan0")
+;; (find-sh0 "/sbin/ifconfig eth0")
+;; (setq ee-this-iface "wlan0")
+;; (setq ee-this-iface "eth0")
+;; (ee-this-mname)
+;; (ee-this-ip)
+;; (setq ee-this-mname (ee-this-mname))
+;; (setq ee-this-ip (ee-this-ip))
+
+(defun find-newhost-links (&optional thatmname thatip thismname thisip
thisiface &rest rest)
+ "Visit a temporary buffer with an e-script to set up a new host."
+ (interactive)
+ (let ((thisdisplay))
+ (setq thatmname (or thatmname "{thatmname}"))
+ (setq thatip (or thatip "{thatip}"))
+ (setq thismname (or thismname ee-this-mname "{thismname}"))
+ (setq thisip (or thisip ee-this-ip "{thisip}"))
+ (setq thisiface (or thisiface ee-this-iface "{thisiface}"))
+ (setq thisdisplay (or (getenv "DISPLAY") "{thisdisplay}"))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-newhost-links ,thatmname ,thatip ,thismname ,thisip ,thisiface)
+ (find-newhost-links ,thatmname ,thatip ,ee-this-mname ,ee-this-ip
,ee-this-iface)
+ (find-newhost-links ,thatmname ,thatip nil nil nil)
+ (find-newhost-links ,thatmname ,thatip)
+ (find-efunction 'find-newhost-links)
+ ;; Body:
+ ""
+ ,(ee-template0 "\
+# Basic setup (on this machine, {thismname} - set thismname and thisip):
+# (find-sh0 \"/sbin/ifconfig wlan0\")
+# (find-sh0 \"/sbin/ifconfig eth0\")
+# (setq ee-this-iface \"wlan0\")
+# (setq ee-this-iface \"eth0\")
+# (ee-this-mname)
+# (ee-this-ip)
+# (setq ee-this-mname (ee-this-mname))
+# (setq ee-this-ip (ee-this-ip))
+# (find-newhost-links \"{thatmname}\" \"{thatip}\")
+
+# Make sure that we can refer to {thatmname} by name
+# (find-sh0 \"ls -l /etc/hosts\")
+# (find-sh0 \"sudo chmod 666 /etc/hosts\")
+# (kill-new \"{thatip} {thatmname}\")
+# (find-fline \"/etc/hosts\")
+# (find-fline \"/etc/hosts\" \"{thatmname}\")
+# (find-fline \"/etc/hosts\" \"{thatip}\")
+
+# Basic setup (on the remote machine, {thatmname} - by hand):
+# adduser edrx
+# (find-es \"sudo\" \"sudo\")
+# apt-get install openssh-server xterm
+# chmod 666 /etc/hosts
+# nano /etc/hosts
+# (kill-new \"{thisip} {thismname}\")
+
+# Try to connect:
+# (find-sh0 \"ssh-keygen -R {thatip}\")
+# (find-sh0 \"ssh-keygen -R {thatmname}\")
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ssh address@hidden
+exit
+ssh address@hidden
+exit
+
+# Try file access by tramp
+# (find-fline \"/ssh:address@hidden:/\")
+# (find-fline \"/scp:address@hidden:/\")
+# (find-fline \"/ssh:address@hidden:/\")
+# (find-fline \"/scp:address@hidden:/\")
+
+;; If that works:
+\(code-c-d \"{thatmname}\" \"/scp:address@hidden:\")
+\(code-c-d \"{thatmname}\" \"/ssh:address@hidden:\")
+;; (find-{thatmname}file \"/\")
+;; (find-{thatmname}file \"/home/edrx/\")
+\(defun eepitch-{thatmname} () (interactive)
+ (eepitch '(find-comintprocess \"ssh {thatmname}\" \"ssh address@hidden")))
+\(defun eepitch-{thatmname}root () (interactive)
+ (eepitch '(find-comintprocess \"ssh {thatmname}\" \"ssh address@hidden")))
+
+
+# Make sure that the remote machine knows this hostname
+ssh address@hidden
+ #
+ # Does the remote machine know this hostname?
+ echo \"{thisip} {thismname}\"
+ cat /etc/hosts | grep {thismname}
+ #
+ # If it isn't there, add it:
+ cat /etc/hosts
+ ls -l /etc/hosts
+ sudo chmod 666 /etc/hosts
+ echo \"{thisip} {thismname}\" >> /etc/hosts
+ cat /etc/hosts | grep {thismname}
+ cat /etc/hosts
+ #
+ # Try to open a remote xterm on this X server
+ # (find-sh0 \"xhost -\")
+ # (find-sh0 \"xhost +\")
+ DISPLAY={thisip}{thisdisplay} xterm -T \"address@hidden" &
+ DISPLAY={thismname}{thisdisplay} xterm -T \"address@hidden" &
+ exit
+
+
+# A high-level version of the above:
+# (find-sh0 \"xhost +\")
+# (find-{thatmname}file \"/etc/hosts\" \"{thismname}\")
+# (eekill \"{thisip} {thismname}\\n\")
+# (eekill \"# (setq backup-inhibited t)\\n\")
+
+ (eepitch-{thatmname})
+ (eepitch-kill)
+ (eepitch-{thatmname})
+DISPLAY={thisip}{thisdisplay} xterm -T \"address@hidden" &
+DISPLAY={thismname}{thisdisplay} xterm -T \"address@hidden" &
+
+")
+ ) rest)))
+
+;; (find-newhost-links)
+;; (find-newhost-links "gwen" "192.168.1.101")
+
+
+
+;;; _ _ _
+;;; __| | |__ _ __ ___ __ _| | _____
+;;; / _` | '_ \| '_ ` _ \ / _` | |/ / _ \
+;;; | (_| | | | | | | | | | (_| | < __/
+;;; \__,_|_| |_|_| |_| |_|\__,_|_|\_\___|
+;;;
+;; �find-dhmake-links� (to ".find-dhmake-links")
+;;
+;; Some templates for generating ".deb"s.
+;; If you want to build a .deb for a package called, say, "foo-bar",
+;; these scripts will use the directory "~/usrc/foo-bar/foo-bar_xxx/"
+;; to build it - that directory will be recreated from scratch each
+;; time - and the "override files for dhmake" will be taken from the
+;; directory "~/foo-bar/". At this moment these paths are hardcoded.
+;;
+;; I generate the 3 main packages at
+;; http://angg.twu.net/debian/
+;; http://angg.twu.net/debian/README.html
+;; with these commands:
+;; (find-dhmake-links "eev" "eevbuild")
+;; (find-dhmake-links "eev-puro" "eevpuro")
+;; (find-dhmake-links "eev-lua-extras" "eevluaextras")
+
+(defvar ee-dhmake-fullname "Eduardo Ochs")
+(defvar ee-dhmake-email "address@hidden")
+
+;; (find-estring-elisp (ee-dhmake-codecds "eev-puro" "eevpuro" "20120305"))
+;;
+(defun ee-dhmake-codecds (stem c date)
+ (ee-template '(stem c date) "\
+;; Generated by:
+;; (ee-dhmake-codecds \"{stem}\" \"{c}\" \"{date}\")
+;;
+\(code-c-d \"{c}dh\" \"~/{stem}/\")
+\(code-c-d \"{c}dhd\" \"~/{stem}/debian/\")
+\(code-c-d \"{c}\" \"~/usrc/{stem}/{stem}-0.1.{date}/\")
+\(code-c-d \"{c}d\" \"~/usrc/{stem}/{stem}-0.1.{date}/debian/\")
+\(code-c-d \"{c}dd\" \"~/usrc/{stem}/{stem}-0.1.{date}/debian/{stem}/\")
+\(code-c-d \"{c}unp\" \"~/usrc/{stem}/{stem}-unpacked/\")
+;; (find-{c}dhfile \"\")
+;; (find-{c}dhdfile \"\")
+;; (find-{c}file \"\")
+;; (find-{c}dfile \"\")
+;; (find-{c}ddfile \"\")
+;; (find-{c}unpfile \"\")
+;; (find-{c}dsh \"find * | sort\")
+;; (find-{c}ddsh \"find * | sort\")
+;; (find-{c}unpsh \"find * | sort\")
+;; (find-status \"{stem}-deb\")
+;; (find-vldifile \"{stem}-deb.list\")
+;; (find-udfile \"{stem}-deb-puro/\")"))
+
+;; (find-estring (ee-dhmake-build "eev-puro" "eevpuro" "20120305"))
+;;
+(defun ee-dhmake-build (stem c date)
+ (ee-template '(stem c date ee-dhmake-fullname ee-dhmake-email) "\
+# Generated by:
+# (ee-dhmake-build \"{stem}\" \"{c}\" \"{date}\")
+#
+rm -Rv ~/usrc/{stem}/
+mkdir -p ~/usrc/{stem}/
+mkdir ~/usrc/{stem}/{stem}-0.1.{date}/
+# ln -s {stem}-0.1.{date} ~/usrc/{stem}/{stem}-0.1
+ ln -s {stem}-0.1.{date} {stem}-0.1
+cd ~/usrc/{stem}/{stem}-0.1.{date}/
+
+echo | \\
+DEBFULLNAME=\"{ee-dhmake-fullname}\" \\
+ dh_make --email {ee-dhmake-email} \\
+ --copyright=gpl \\
+ --cdbs \\
+ --native
+rm -v debian/README.Debian
+rm -v debian/*.EX
+rm -v debian/*.ex
+cp -iv debian/control debian/control.orig
+
+# (find-fline \"~/{stem}/debian/\")
+# (find-sh0 \"rm -Rv ~/{stem}/debian/\")
+mkdir -p ~/{stem}/debian/
+if [ ! -e ~/{stem}/Makefile ]; then
+ echo Creating: ~/{stem}/Makefile
+ echo \"clean:\" > ~/{stem}/Makefile
+fi
+if [ ! -e ~/{stem}/debian/control ]; then
+ echo Creating: ~/{stem}/debian/control
+ cp -v debian/control ~/{stem}/debian/control
+fi
+if [ ! -e ~/{stem}/debian/rules ]; then
+ echo Creating: ~/{stem}/debian/rules
+ cp -v debian/rules ~/{stem}/debian/rules
+ echo \"build/{stem}::\" >> ~/{stem}/debian/rules
+ echo \"install/{stem}::\" >> ~/{stem}/debian/rules
+fi
+
+# (find-{c}dh \"debian/\")
+# (find-{c}dh \"debian/control\")
+# (find-{c}dh \"debian/rules\")
+cp -v ~/{stem}/debian/* debian/
+cp -v ~/{stem}/Makefile .
+
+# (find-man \"1 dpkg-buildpackage\")
+# dpkg-buildpackage -us -uc -rfakeroot 2>&1 | tee odb
+ dpkg-buildpackage -us -uc -b -rfakeroot 2>&1 | tee odb
+# (find-{c}file \"odb\")
+
+rm -Rv ~/usrc/{stem}/{stem}-unpacked/
+mkdir ~/usrc/{stem}/{stem}-unpacked/
+mkdir ~/usrc/{stem}/{stem}-unpacked/DEBIAN/
+cd ~/usrc/{stem}/
+ar p {stem}_*.deb control.tar.gz | tar -C {stem}-unpacked/DEBIAN/ -xvzf -
+ar p {stem}_*.deb data.tar.gz | tar -C {stem}-unpacked/ -xvzf -
+
+# (find-{c}unpfile \"\")
+# (find-{c}unpfile \"DEBIAN/\")
+# (find-{c}unpfile \"DEBIAN/control\")
+# (find-{c}unpsh \"find * | sort\")"))
+
+(defun find-dhmake-links (&optional stem c date &rest rest)
+ "Visit a temporary buffer containing hyperlinks for dhmake."
+ (interactive)
+ (setq stem (or stem "{stem}"))
+ (setq c (or c "{c}"))
+ (setq date (or date (format-time-string "%Y%m%d")))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-dhmake-links ,stem ,c ,date ,@rest)
+ (find-efunction 'find-dhmake-links)
+ ;; Body:
+ ""
+ ;; (find-estring-elisp (ee-dhmake-codecds ,stem ,c ,date))
+ ;; (find-estring (ee-dhmake-build ,stem ,c ,date))
+ ;; (eev (ee-dhmake-build ,stem ,c ,date))
+ ;; (find-fline "$EE")
+ ;; (find-fline (format "~/%s/debian/" stem))
+ ;; (find-sh0 ,(format "rm -Rv ~/%s/debian/" stem))
+ ;; ""
+ ,(ee-template `(stem c date) "\
+# Set up the build script that `ee' will execute:
+# (find-estring-elisp (ee-dhmake-codecds \"{stem}\" \"{c}\" \"{date}\"))
+# (find-estring (ee-dhmake-build \"{stem}\" \"{c}\" \"{date}\"))
+# (eev (ee-dhmake-build \"{stem}\" \"{c}\" \"{date}\"))
+# (find-fline \"$EE\")
+
+# Examine its main control files:
+# (find-fline \"~/{stem}/debian/rules\")
+# (find-fline \"~/{stem}/debian/control\")
+# (find-fline \"~/{stem}/debian/\")
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ee
+cd ~/usrc/{stem}/
+ls -lF *.deb
+sudo dpkg -i {stem}*.deb
+# sudo dselect update
+
+# (find-status \"{stem}\")
+# (find-vldifile \"{stem}.list\")
+# (find-udfile \"{stem}/\")
+
+
+# Upload to angg.twu.net.
+# (THIS IS A HACK!)
+# (find-twusfile \"debian/\")
+
+ (eepitch-eshell)
+cd ~/usrc/{stem}/
+ls -l {stem}_0.1.{date}_all.deb
+cp -v {stem}_0.1.{date}_all.deb (ee-twusfile \"debian/\")
+ls -l (ee-twusfile \"debian/\")
+# (find-twusfile \"debian/\")
+
+ (eepitch-Twu)
+cd ~/slow_html/debian/
+mkdir -p dists/./main/binary-i386/
+mkdir -p dists/./main/binary-amd64/
+ls -lAF
+apt-ftparchive packages .
+apt-ftparchive packages . \\
+ | tee dists/./main/binary-i386/Packages \\
+ | gzip -c9 > dists/./main/binary-i386/Packages.gz
+apt-ftparchive packages . \\
+ | tee dists/./main/binary-amd64/Packages \\
+ | gzip -c9 > dists/./main/binary-amd64/Packages.gz
+")
+ ) rest))
+
+;; (find-dhmake-links)
+;; (find-dhmake-links "{stem}" "{c}" "{date}")
+;; (find-dhmake-links "foo-bar" "foobar")
+;; (find-dhmake-links "eev" "eevbuild")
+;; (find-dhmake-links "eev" "eevbuild" "20120404")
+
+
+
+
+
+;;; _ _ _ _
+;;; _ _ ___ _ _| |_ _ _| |__ ___ __| | |
+;;; | | | |/ _ \| | | | __| | | | '_ \ / _ \_____ / _` | |
+;;; | |_| | (_) | |_| | |_| |_| | |_) | __/_____| (_| | |
+;;; \__, |\___/ \__,_|\__|\__,_|_.__/ \___| \__,_|_|
+;;; |___/
+;;
+;; �find-youtubedl-links� (to ".find-youtubedl-links")
+
+;; Code for splitting filenames of downloaded videos into components.
+;;
+(defvar ee-youtubedl-ext-re
+ "\\(\\.[A-Za-z0-9]\\{2,5\\}\\)\\{0,2\\}$")
+
+(setq ee-youtubedl-ext-re
+ "\\(\\.[A-Za-z0-9]\\{2,5\\}\\)\\(\\.part\\)?$")
+
+(defun ee-youtubedl-split (fname)
+"Split FNAME into (dir title hash ext).
+Example:
+\(ee-youtubedl-split \"~/tmp/videos/foo_bar-abF7go7RLTc.flv\")
+ --> (\"~/tmp/videos/\" \"foo_bar\" \"abF7go7RLTc\" \".flv\")"
+ (string-match ee-youtubedl-ext-re fname)
+ (let (dir title hash ext- ext dth dt)
+ (setq ext- (match-string 1 fname))
+ (setq ext (match-string 0 fname))
+ (setq dth (substring fname 0 (match-beginning 0)))
+ (setq hash (substring dth -11))
+ (setq dt (substring dth 0 -12))
+ (setq title (file-name-nondirectory dt))
+ (setq dir (file-name-directory dt))
+ (list dir title hash ext- ext)))
+
+(defun ee-youtubedl-dir (fname) (nth 0 (ee-youtubedl-split fname)))
+(defun ee-youtubedl-title (fname) (nth 1 (ee-youtubedl-split fname)))
+(defun ee-youtubedl-hash (fname) (nth 2 (ee-youtubedl-split fname)))
+(defun ee-youtubedl-ext- (fname) (nth 3 (ee-youtubedl-split fname)))
+(defun ee-youtubedl-ext (fname) (nth 4 (ee-youtubedl-split fname)))
+
+;; Code for guessing the "title" and the "ext" parts of a video from
+;; the "dir" and "hash" parts (in case the video has already been
+;; downloaded).
+;;
+(defun ee-youtubedl-guess* (dir hash)
+ "Return all the files in DIR containing the string HASH."
+ (file-expand-wildcards (format "%s*%s*" dir hash)))
+
+(defun ee-youtubedl-guess (dir hash n)
+ "Return a component of the first file in DIR containing the string HASH."
+ (let ((fname (car (ee-youtubedl-guess* dir hash))))
+ (if fname (nth n (ee-youtubedl-split fname)))))
+
+(defun ee-youtubedl-guess-title (dir hash) (ee-youtubedl-guess dir hash 1))
+(defun ee-youtubedl-guess-ext- (dir hash) (ee-youtubedl-guess dir hash 3))
+
+;; The function `find-youtubedl-links' itself.
+;; It will try to guess "dir", "title", "hash", and "ext" if they are nil.
+;; Its ancestor: (find-angg ".emacs.templates" "find-youtubedl-links")
+;;
+(defvar ee-youtubedl-dir "~/videos/")
+(defvar ee-youtubedl-dir2 "~/videos/tech/")
+(defvar ee-youtubedl-dir3 "/tmp/videos/")
+(defvar ee-youtubedl-dir4 "/tmp/")
+(defvar ee-youtubedl-command "youtube-dl -t")
+
+(defun ee-youtubedl-hash-around-point ()
+ (let ((hash (ee-stuff-around-point "-0-9A-Za-z_")))
+ (if (>= (length hash) 11)
+ (substring hash -11))))
+
+(defun find-youtubedl-links (&optional dir title hash ext- stem &rest rest)
+ "Visit a temporary buffer containing hyperlinks for youtube-dl."
+ (interactive)
+ (setq dir (or dir ee-youtubedl-dir "{dir}"))
+ (setq hash (or hash (ee-youtubedl-hash-around-point) "{hash}"))
+ (setq title (or title (ee-youtubedl-guess-title dir hash) "{title}"))
+ (setq ext- (or ext- (ee-youtubedl-guess-ext- dir hash) "{ext-}"))
+ (setq stem (or stem "{stem}"))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-youtubedl-links ,dir ,title ,hash ,ext- ,stem)
+ (find-youtubedl-links ,dir nil ,hash nil ,stem)
+ ""
+ (find-youtubedl-links ,ee-youtubedl-dir nil ,hash nil ,stem)
+ (find-youtubedl-links ,ee-youtubedl-dir2 nil ,hash nil ,stem)
+ (find-youtubedl-links ,ee-youtubedl-dir3 nil ,hash nil ,stem)
+ (find-youtubedl-links ,ee-youtubedl-dir4 nil ,hash nil ,stem)
+ (find-efunction 'find-youtubedl-links)
+ ;; (find-youtubedl-links ee-youtubedl-dir ,title ,hash ,ext- ,stem)
+ ;; (setq ee-youtubedl-dir ,ee-youtubedl-dir)
+ ;; Body:
+ ""
+ ,(ee-template0 "\
+ (eepitch-shell2)
+ (eepitch-kill)
+ (eepitch-shell2)
+# http://www.youtube.com/watch?v={hash}
+# http://www.youtube.com/watch?v={hash}#t=0m00s
+# http://www.youtube.com/watch?v={hash}#t=0h00m00s
+cd {dir}
+{ee-youtubedl-command} 'http://www.youtube.com/watch?v={hash}'
+
+# {ee-youtubedl-command} -F 'http://www.youtube.com/watch?v={hash}'
+# {ee-youtubedl-command} -f 18 'http://www.youtube.com/watch?v={hash}'
+
+# (find-es \"video\" \"youtube-dl\")
+# (find-fline \"{dir}\" \"{hash}\")
+# (find-fline \"{dir}\" \"{title}-{hash}\")
+# (find-fline \"{dir}\" \"{title}-{hash}{ext-}\")
+# (find-video \"{dir}{title}-{hash}{ext-}\")
+# (find-video \"{dir}{title}-{hash}{ext-}.part\")
+# (code-video \"{stem}video\" \"{dir}{title}-{hash}{ext-}\")
+# (code-video \"{stem}video\" \"{dir}{title}-{hash}{ext-}.part\")
+# (find-{stem}video)
+# (find-{stem}video \"0:00\")
+
+# Error messages (for the player):
+# (find-ebuffer \"*Messages*\")
+")
+ ) rest))
+
+
+
+;;; _ _ _ _ _
+;;; | | | |_ __ | | ___ __ _ __| | __ _ _ __ __| |
+;;; | | | | '_ \| |/ _ \ / _` |/ _` | / _` | '_ \ / _` |
+;;; | |_| | |_) | | (_) | (_| | (_| | | (_| | | | | (_| |
+;;; \___/| .__/|_|\___/ \__,_|\__,_| \__,_|_| |_|\__,_|
+;;; |_|
+;;; _ _ _
+;;; __| | _____ ___ __ | | ___ __ _ __| |
+;;; / _` |/ _ \ \ /\ / / '_ \| |/ _ \ / _` |/ _` |
+;;; | (_| | (_) \ V V /| | | | | (_) | (_| | (_| |
+;;; \__,_|\___/ \_/\_/ |_| |_|_|\___/ \__,_|\__,_|
+;;;
+;; �find-upload-links� (to ".find-upload-links")
+
+;; 2012jan26 - experimental hack.
+;; Some of these functions use environment variables for readability
+;; (i.e., to make the shell scripts more readable).
+;; Default values (all for angg.twu.net):
+(ee-setenv "MYPAGEDIR" "/scp:address@hidden:public_html")
+(ee-setenv "MYPAGEURL" "http://angg.twu.net")
+(ee-setenv "DNPAGEURL" "http://angg.twu.net")
+;; (getenv "MYPAGEDIR")
+;; (getenv "MYPAGEURL")
+;; (getenv "DNPAGEURL")
+;; (setenv "DNPAGEURL" "http://0branch.com/highlight/snippets")
+
+(defun find-tkdiff (f1 f2)
+ (find-bgprocess `("tkdiff" ,f1 ,f2)))
+
+(defun ee-upload-links (fromdir/ todir/ fname)
+ "An internal function used by `find-upload-links'.
+Try this: (find-elinks (ee-upload-links \"eev-current/eev-template.el\"))"
+ (let ((dir (file-name-directory (ee-expand fname)))
+ (fname- (file-name-nondirectory fname))
+ (mypagedir (getenv "MYPAGEDIR"))
+ (mypageurl (getenv "MYPAGEURL"))
+ )
+ `("# Env vars (current values):"
+ (setenv "MYPAGEDIR" ,(getenv "MYPAGEDIR"))
+ (setenv "MYPAGEURL" ,(getenv "MYPAGEURL"))
+ ,(ee-template0 "\
+# Upload (warning: SLOW, uses tramp!):
+ (eepitch-eshell)
+cp -v ~/{fromdir/}{fname} $MYPAGEDIR/{todir/}{fname}
+ls -l ~/{fromdir/}{fname} $MYPAGEDIR/{todir/}{fname}\n
+# Test:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd /tmp/
+wget -N {mypageurl}/{fname}
+ls -l /tmp/{fname-} ~/{fname}
+# (find-fline \"/tmp/{fname-}\")"))))
+
+(defun ee-download-links (fromdir/ todir/ fname)
+ "Visit a temporary buffer containing a script for downloading FNAME."
+ (setq fromdir/ (or fromdir/ (file-name-directory fname)))
+ (setq todir/ (or todir/ (file-name-directory fname)))
+ (let ((fname- (file-name-nondirectory fname))
+ (dnpageurl (getenv "DNPAGEURL")))
+ `(,(ee-template `(fromdir/ todir/ fname fname- dnpageurl) "\
+# Download:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd /tmp/
+wget -N {dnpageurl}/{fromdir/}{fname}
+ls -l /tmp/{fname-} ~/{todir/}{fname}
+cp -v /tmp/{fname-} ~/{todir/}{fname}
+# (diff \"/tmp/{fname-}\" \"~/{todir/}{fname}\")
+# (find-tkdiff \"/tmp/{fname-}\" \"~/{todir/}{fname}\")
+# (find-fline \"/tmp/{fname-}\")
+# (find-fline \"~/{todir/}{fname}\")"))))
+
+(defun find-upload-links (&optional fromdir/ todir/ fname &rest rest)
+ "Visit a temporary buffer containing a script for uploading FNAME."
+ (interactive)
+ (setq fname (or fname "{fname}"))
+ (setq fromdir/ (or fromdir/ (file-name-directory fname)))
+ (setq todir/ (or todir/ (file-name-directory fname)))
+ (let ((ee-hyperlink-prefix "# "))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-upload-links ,fromdir/ ,todir/ ,fname ,@rest)
+ ;; The second sexp generates the corresponding download link.
+ (find-download-links ,fname ,@rest)
+ ""
+ ,@(ee-upload-links fromdir/ todir/ fname)) rest)))
+
+(defun find-download-links (&optional fromdir/ todir/ fname extras &rest rest)
+ "Visit a temporary buffer containing a script for downloading FNAME."
+ (interactive)
+ (setq fname (or fname "{fname}"))
+ (setq fromdir/ (or fromdir/ (file-name-directory fname)))
+ (setq todir/ (or todir/ (file-name-directory fname)))
+ (apply 'find-elinks `(
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-download-links ,fromdir/ ,todir/ ,fname ,@rest)
+ ;; Body:
+ ""
+ ,@(ee-download-links fromdir/ todir/ fname)
+ ,@extras) rest))
+
+(defun ut ()
+ (interactive)
+ "Upload eev-template.el"
+ (find-upload-links "eev-current/" "eev-current/" "eev-template.el"))
+
+(defun dt ()
+ (interactive)
+ "Download eev-template.el and load the new version."
+ (find-download-links
+ "eev-current/" "emacs/eev/" "eev-template.el"
+ '("\n (load \"eev-template.el\")")))
+
+
+
+
+;;;
+;;; _ __ ___ _ __ ___
+;;; | '_ \/ __| '_ \ / _ \
+;;; | |_) \__ \ | | | __/
+;;; | .__/|___/_| |_|\___|
+;;; |_|
+;;
+;; �find-psne-links� (to ".find-psne-links")
+;; (find-find-links-links "<none>" "psne" "url wget-options")
+;; A test: (find-psne-links "http://foo/bar")
+
+(defun find-psne-links (&optional url wget-options &rest pos-spec-list)
+"See: (find-psne-intro)"
+ (interactive)
+ (setq url (or url "{url}"))
+ (setq wget-options (or wget-options ""))
+ (apply 'find-elinks
+ `((find-psne-links ,url ,wget-options ,@pos-spec-list)
+ (find-psne-links ,url "-c" ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-psne-links)
+ ""
+ " (eepitch-shell2)"
+ ,(ee-find-psne-core url wget-options)
+ )
+ pos-spec-list))
+
+(defun ee-find-psne-core (url &optional wget-options)
+ "This is an internal function used by `find-psne-links'."
+ (let* ((localurl (ee-url-to-fname0 url))
+ (localdir (file-name-directory localurl))
+ (o (format "%3s" (or wget-options ""))))
+ (ee-template0 "\
+mkdir -p {localdir}
+cd {localdir}
+wget {o} '{url}'
+echo '{url}' >> ~/.psne.log
+
+# (find-fline \"{localdir}\")
+# (find-fline \"{localurl}\")
+")))
+
+;; Links to the old version:
+;; (find-eev "eev-browse-url.el" "find-psne-links")
+;; (find-eev "eev-browse-url.el" "brep")
+
+
+
+
+
+;;; _ _
+;;; __ _(_) |_
+;;; / _` | | __|
+;;; | (_| | | |_
+;;; \__, |_|\__|
+;;; |___/
+
+;; �find-git-links� (to ".find-git-links")
+;; (find-find-links-links "g" "git" "usrc/ git/ gitname")
+(define-key eev-mode-map "\M-hg" 'find-git-links-1)
+
+(defun find-git-links (&optional usrc/ git/ gitname c &rest pos-spec-list)
+"Visit a temporary buffer containing scripts for acting on a Git URL.
+This is normally invoked interactively via `find-git-links-1' (`M-h g').
+I have VERY LITTLE experience with Git, so these scripts are kind of silly.
+Please send suggestions!"
+ ;; (interactive)
+ (setq usrc/ (or usrc/ "{usrc/}"))
+ (setq git/ (or git/ "{git/}"))
+ (setq gitname (or gitname "{gitname}"))
+ (setq c (or c "{c}"))
+ (apply 'find-elinks
+ `((find-git-links ,usrc/ ,git/ ,gitname ,c ,@pos-spec-list)
+ (find-git-links "/tmp/" ,git/ ,gitname ,c ,@pos-spec-list)
+ (find-git-links "~/usrc/" ,git/ ,gitname ,c ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ ;; (find-efunction 'find-git-links)
+ ;; ""
+ ,(ee-template0 "\
+{ee-H}(find-efunction 'find-git-links-1)
+{ee-H}(find-efunction 'find-git-links)
+{ee-H}{git/}{gitname}
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+rm -Rfv {usrc/}{gitname}/
+mkdir {usrc/}{gitname}/
+cd {usrc/}
+git clone {git/}{gitname}
+cd {usrc/}{gitname}/
+# (find-fline \"{usrc/}{gitname}/\")
+
+# (code-c-d \"{c}\" \"{usrc/}{gitname}\")
+# (find-{c}file \"\")
+# (find-{c}sh0 \"gitk\")
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd {usrc/}{gitname}
+find {usrc/}{gitname} -maxdepth 1 -mindepth 1 | sort | grep -v '/\.git$'
+rm -Rv $(
+find {usrc/}{gitname} -maxdepth 1 -mindepth 1 | sort | grep -v '/\.git$'
+)
+git pull
+git reset --hard
+
+# (code-c-d \"{c}\" \"{usrc/}{gitname}/\")
+# (find-{c}file \"\")
+")
+ )
+ pos-spec-list))
+
+(defun ee-git-url-at-point ()
+ (require 'thingatpt)
+ (let ((thing-at-point-url-regexp
+ (concat "\\<\\(https?:\\|git:\\)"
+ thing-at-point-url-path-regexp)))
+ (thing-at-point 'url)))
+
+(defun find-git-links-1 ()
+ "Visit a temporary buffer containing scripts for acting on a Git URL.
+This is the high-level version, that runs `ee-git-url-at-point',
+splits the Git URL at point, and calls `find-git-links' with
+reasonable default arguments.
+
+To test this, type `M-h g' on a Git URL - for example, on:
+ https://github.com/kikito/inspect.lua"
+ (interactive)
+ (let* ((url/ (ee-git-url-at-point))
+ (url (replace-regexp-in-string "/*\\'" "" url/))
+ (git/ (file-name-directory url))
+ (gitname (file-name-nondirectory url))
+ (c (replace-regexp-in-string "[-.]" "" gitname)))
+ (if (equal gitname "") (error "Maybe your git url ended with `/'?..."))
+ (find-git-links "/tmp/" git/ gitname c)))
+
+;; Test by typing `M-h g' on this git url:
+;; https://github.com/kikito/inspect.lua
+
+
+
+
+;;; _ _ _ _
+;;; _ __ ___| |_ ___ __ _| |_ | |_ ___ ___| |_
+;;; | '_ \ / _ \ __/ __/ _` | __|____| __/ _ \/ __| __|
+;;; | | | | __/ || (_| (_| | ||_____| || __/\__ \ |_
+;;; |_| |_|\___|\__\___\__,_|\__| \__\___||___/\__|
+;;;
+
+;; �find-netcat-test-links� (to ".find-netcat-test-links")
+;; (find-find-links-links "{k}" "netcat-test" "eesrc eetgt tgtname tgtport")
+;; A test: (find-netcat-test-links)
+
+(defun find-netcat-test-links (&optional eesrc eetgt tgtname tgtport &rest
pos-spec-list)
+"Visit a temporary buffer with a script to test sending data though netcat."
+ (interactive)
+ (setq eesrc (or eesrc "{eesrc}"))
+ (setq eetgt (or eetgt "{eetgt}"))
+ (setq tgtname (or tgtname "{tgtname}"))
+ (setq tgtport (or tgtport "{tgtport}"))
+ (apply 'find-elinks
+ `((find-netcat-test-links ,eesrc ,eetgt ,tgtname ,tgtport)
+ (find-netcat-test-links "shell" "shell2" "localhost" "1234")
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-netcat-test-links)
+ ""
+ ,(ee-template0 "\
+ (find-wset \"13o2!o!o\" '(eepitch-{eesrc}) '(eepitch-{eetgt}))
+ (find-wset \"13o2=o=o\" '(eepitch-{eesrc}) '(eepitch-{eetgt}))
+ (eepitch-{eetgt})
+# listen on port {tgtport}
+netcat -l -p {tgtport}
+
+ (eepitch-{eesrc})
+# Send things to port {tgtport} (on {tgtname})
+{<}
+ echo hi
+ sleep 1
+ echo bye
+ sleep 1
+{>} | netcat -q 0 {tgtname} {tgtport}
+
+")
+ )
+ pos-spec-list))
+
+;; Test: (find-netcat-test-links)
+
+
+
+
+
+
+;;; _ _
+;;; ___ _____ __ __ _(_) __| | ___ ___
+;;; / _ \/ _ \ \ / /___\ \ / / |/ _` |/ _ \/ _ \
+;;; | __/ __/\ V /_____\ V /| | (_| | __/ (_) |
+;;; \___|\___| \_/ \_/ |_|\__,_|\___|\___/
+;;;
+;; �find-eev-video-links� (to ".find-eev-video-links")
+
+;; (find-find-links-links "{k}" "eev-video" "c anggstem youtubehash")
+
+(defun find-eev-video-links (&optional c anggstem youtubehash &rest
pos-spec-list)
+"Visit a temporary buffer containing a script for downloading an eev video.
+See: (find-videos-intro)
+Examples:
+ (find-eev-video-links \"eepitchvideo\" \"video4-eepitch\" \"Lj_zKC5BR64\")
+ (find-eev-video-links \"eevvideo2\" \"video2\" \"doeyn5MOaB8\")
+ (find-eev-video-links \"eevvideo2-pt\" \"video2pt\" \"yztYD9Y7Iz4\")
+Warning: the last one is in Portuguese..."
+ (interactive)
+ (setq c (or c "{c}"))
+ (setq anggstem (or anggstem "{anggstem}"))
+ (setq youtubehash (or youtubehash "{youtubehash}"))
+ (let ((s (replace-regexp-in-string "." " " c)))
+ (apply 'find-elinks
+ `((find-eev-video-links ,c ,anggstem ,youtubehash)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-eev-video-links)
+ ""
+ ,(ee-template0 "\
+ Download (or make sure we have) a local copy of the video:
+ (eepitch-shell2)
+ (eepitch-kill)
+ (eepitch-shell2)
+mkdir -p $S/http/angg.twu.net/eev-videos/
+cd $S/http/angg.twu.net/eev-videos/
+wget -c 'http://angg.twu.net/eev-videos/{anggstem}.mp4'
+echo 'http://angg.twu.net/eev-videos/{anggstem}.mp4' >> ~/.psne.log
+
+# Test:
+# (find-fline {s} \"$S/http/angg.twu.net/eev-videos/\")
+# (find-video {s} \"$S/http/angg.twu.net/eev-videos/{anggstem}.mp4\")
+# (code-video \"{c}\" \"$S/http/angg.twu.net/eev-videos/{anggstem}.mp4\")
+# (find-{c})
+# Error messages:
+# (find-ebuffer \"*Messages*\")
+
+# Links to the version at youtube:
+# http://www.youtube.com/watch?v={youtubehash}
+# http://www.youtube.com/watch?v={youtubehash}&t=0m00s
+# http://www.youtube.com/watch?v={youtubehash}&t=0h00m00s
+")
+ )
+ pos-spec-list)))
+
+;; Links to all the eev videos (best ones first):
+;; (find-eev-video-links "eepitchvideo" "video4-eepitch" "Lj_zKC5BR64")
+;; (find-eev-video-links "eevvideo2" "video2" "doeyn5MOaB8")
+;; (find-eev-video-links "eevvideo2-pt" "video2pt" "yztYD9Y7Iz4")
+;; The ones with "pt" are in Portuguese, the other ones are in English.
+
+;; (find-eepitchvideo "0:18" "Demonstration (first time, very quickly)")
+
+
+
+
+
+(provide 'eev-tlinks)
+
+
+
+;; was: ee-anchor-format: "defun %s "
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "�%s�"
+;; no-byte-compile: t
+;; End:
diff --git a/eev-wrap.el b/eev-wrap.el
new file mode 100644
index 0000000..37355e8
--- /dev/null
+++ b/eev-wrap.el
@@ -0,0 +1,477 @@
+;;; eev-wrap.el --- wrap the current line into a hyperlink
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2013aug10
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev-wrap.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev-wrap.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; <http://angg.twu.net/eev-intros/find-wrap-intro.html>
+;; (find-eev-intro)
+;; (find-wrap-intro)
+
+;;; Commentary:
+
+;; This module installs new key bindings into eev-mode-keymap, so:
+(require 'eev-mode) ; (find-eev "eev-mode.el")
+
+
+(defvar ee-hyperlink-prefix "# "
+ "Hyperlinks created by `ee-HS' are prefixed with this.
+The best way to change this variable interactively is by running
+`M-x ee-hyperlink-prefix'.")
+
+(defvaralias 'ee-H 'ee-hyperlink-prefix)
+
+
+
+;;; _ _ _ ___
+;;; ___ ___ | |_ ___ _ __ ___ _ __ | | __ _| |_ ___ / _ \
+;;; / _ \/ _ \_____| __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \ | | |
+;;; | __/ __/_____| || __/ | | | | | |_) | | (_| | || __/ |_| |
+;;; \___|\___| \__\___|_| |_| |_| .__/|_|\__,_|\__\___|\___/
+;;; |_|
+;;
+(defun ee-template00 (str)
+"Replace substrings enclosed by `{}'s in STR by the result of evaluating them.
+Examples:\n
+ (ee-template00 \"a{(+ 2 3)}b\")
+ --> \"a5b\"\n
+ (let ((hi \"Here:\") (a 22) (b 33))
+ (ee-template00 \"{hi} {a} + {b} = {(+ a b)}\"))
+ --> \"22 + 33 = 55\""
+ (replace-regexp-in-string
+ "{\\([^{}]+\\)}"
+ (lambda (_code_) (format "%s" (eval (read (substring _code_ 1 -1)))))
+ str 'fixedcase 'literal))
+
+(defun ee-template0 (str)
+"Replace substrings enclosed by `{}'s in STR by the result of evaluating them.
+Substrings of the form `{<}' and `{>}' in STR are replaced by `{'
+and `}' respectively; apart from that, this is the same as
+`ee-template00'.
+Example: (ee-template0 \"{<} a{(+ 2 3)} {>}\") --> \"{ 5 }\""
+ (let ((< "{") (> "}"))
+ (ee-template00 str)))
+
+
+;;; ____
+;;; ___ ___ / ___|
+;;; / _ \/ _ \____\___ \
+;;; | __/ __/_____|__) |
+;;; \___|\___| |____/
+;;;
+;; ee-S and ee-HS, for pretty-printing of sexps
+;; (mainly for use in ee-template0)
+;;
+(defun ee-S (object)
+ "Convert OBJECT (usually a sexp) into a string, for use in hyperlinks.
+Quote newlines to make it fit in a single line.
+The result of this function is always a string that can be `read' as Lisp.
+The name of this function comes from the \"S\" in `(format \"%S\" <obj>)'."
+ (let ((str (let ((print-escape-newlines t)
+ (print-escape-nonascii t) ; isn't escaping esc, \r, etc
+ (print-quoted t))
+ (prin1-to-string object))))
+ (replace-regexp-in-string "\r" "\\\\r" str)))
+
+(defun ee-HS (object) (concat ee-hyperlink-prefix (ee-S object)))
+
+(defun ee-H (str) (format "%s%s" ee-hyperlink-prefix str))
+
+
+
+
+;;; _ _ _ _ _
+;;; | |_| |__ (_)___ | (_)_ __ ___
+;;; | __| '_ \| / __|_____| | | '_ \ / _ \
+;;; | |_| | | | \__ \_____| | | | | | __/
+;;; \__|_| |_|_|___/ |_|_|_| |_|\___|
+;;;
+;; The main function in this block is `ee-this-line-wrapn' -
+;; all the `eewrap-*' functions defined below call it.
+
+(defun ee-splitn (n str)
+"Example: (ee-splitn 3 \"aa bb cc dd ee\")
+ --> (\"aa\" \"bb\" \"cc dd ee\")"
+ (if (= n 1) (list str)
+ (if (string-match "^\\`[ \t]*\\([^ \t]+\\)[ \t]*" str)
+ (cons (match-string 1 str)
+ (ee-splitn (- n 1) (substring str (match-end 0))))
+ (cons "" (ee-splitn (- n 1) "")))))
+
+(defun ee-this-line-extract ()
+ "Delete the contents of the current line and return it as a string."
+ (delete-and-extract-region (ee-bol) (ee-eol)))
+(defun ee-this-line-extractn (n)
+ "Delete the contents of the current line and return it as a list."
+ (ee-splitn n (ee-no-properties (ee-this-line-extract))))
+(defun ee-this-line-wrapn (n f)
+ "Run F on the current line, after splitting it into N strings.
+F is a function that receives N arguments and returns a string.
+This function extracts the contents of the curren line, splits it,
+runs F on the result of the splitting, inserts the result in the
+place of what was deleted, and moves down one line.
+If an error happens the original contents are not restored; you
+have to run an \"undo\"."
+ (insert (apply f (ee-this-line-extractn n)))
+ (ee-next-line 1))
+
+
+
+
+;;; --------------------
+;;; All the standard wrapping functions, bound to M-UPPERCASE keys.
+;;; Note that they are listed in alphabetical order below, and that in
+;;; each section the higher level functions come first.
+
+
+
+
+
+;;; __ __ _ _
+;;; | \/ | / \ _ __ _ _ __ ___| |__ ___ _ __
+;;; | |\/| |_____ / _ \ (_) / _` | '_ \ / __| '_ \ / _ \| '__|
+;;; | | | |_____/ ___ \ _ | (_| | | | | (__| | | | (_) | |
+;;; |_| |_| /_/ \_(_) \__,_|_| |_|\___|_| |_|\___/|_|
+;;;
+;; See: (find-anchors-intro "Creating index/section anchor pairs")
+(define-key eev-mode-map "\M-A" 'eewrap-anchor)
+
+(defun eewrap-anchor () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-anchor))
+(defun ee-wrap-anchor (line)
+ "An internal function used by `eewrap-anchor'."
+ (if (string-match "^\\(.*\\)<\\([^<>]*\\)>" line)
+ (ee-wrap-anchor0 (match-string 1 line) (match-string 2 line))
+ (error "Does not match")))
+(defun ee-wrap-anchor0 (prefix anchor)
+ "An internal function used by `ee-wrap-anchor'."
+ (ee-template0 "\
+{prefix}�.{anchor}�\t(to \"{anchor}\")
+{prefix}�{anchor}� (to \".{anchor}\")"))
+
+
+;;; __ __ ____ _ _
+;;; | \/ | / ___|_ ___ ___ __| | ___ ___ __| |
+;;; | |\/| |_____| | (_) / __/ _ \ / _` |/ _ \_____ / __|____ / _` |
+;;; | | | |_____| |___ _ | (_| (_) | (_| | __/_____| (_|_____| (_| |
+;;; |_| |_| \____(_) \___\___/ \__,_|\___| \___| \__,_|
+;;;
+;; See: (find-code-c-d-intro)
+(define-key eev-mode-map "\M-C" 'eewrap-code-c-d)
+
+(defun eewrap-code-c-d () (interactive)
+ (ee-this-line-wrapn 2 'ee-wrap-code-c-d))
+(defun ee-wrap-code-c-d (c d)
+ "An internal function used by `eewrap-code-c-d'."
+ (ee-template0 "\
+\(code-c-d \"{c}\" \"{d}\"\)
+;; (find-{c}file \"\")"))
+
+
+;;; __ __ ____ _ _ _
+;;; | \/ | | _ \ _ __| | ___| |__ (_) __ _ _ __
+;;; | |\/| |_____| | | (_) / _` |/ _ \ '_ \| |/ _` | '_ \
+;;; | | | |_____| |_| |_ | (_| | __/ |_) | | (_| | | | |
+;;; |_| |_| |____/(_) \__,_|\___|_.__/|_|\__,_|_| |_|
+;;;
+(define-key eev-mode-map "\M-D" 'eewrap-debian)
+
+(defun eewrap-debian () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-debian))
+(defun ee-wrap-debian (stem)
+ (ee-template0 "\
+{ee-H}(find-status \"{stem}\")
+{ee-H}(find-vldifile \"{stem}.list\")
+{ee-H}(find-udfile \"{stem}/\")"))
+
+
+;;; __ __ _____ __ _ _
+;;; | \/ | | ___| / _(_) | ___
+;;; | |\/| |_____| |_ (_) | |_| | |/ _ \
+;;; | | | |_____| _| _ | _| | | __/
+;;; |_| |_| |_| (_) |_| |_|_|\___|
+;;;
+;; See: (find-wrap-intro "<M-F>")
+(define-key eev-mode-map "\M-F" 'eewrap-find-fline)
+
+(defun eewrap-find-fline () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-find-fline))
+(defun ee-wrap-find-fline (fname)
+ "An internal function used by `eewrap-find-fline'."
+ (ee-HS `(find-fline ,fname)))
+
+
+;;; __ __ _ _
+;;; | \/ | | |_ ___ ___ (_)_ _ _ __ ___ _ __
+;;; | |\/| |_____ _ | (_) / _ \/ _ \| | | | | '_ ` _ \| '_ \
+;;; | | | |_____| |_| |_ | __/ __/| | |_| | | | | | | |_) |
+;;; |_| |_| \___/(_) \___|\___|/ |\__,_|_| |_| |_| .__/
+;;; |__/ |_|
+;;
+;; See: (find-eejump-intro "Producing `eejump-nnn's and `eejump-nnn*'s")
+(define-key eev-mode-map "\M-J" 'eewrap-eejump)
+
+(defun eewrap-eejump () (interactive)
+ (ee-this-line-wrapn 2 'ee-wrap-eejump))
+(defun ee-wrap-eejump (n sexp)
+ "An internal function used by `eewrap-eejump'."
+ (if (equal sexp "")
+ (ee-template0 "(defun eejump-{n}* () (find-efunction 'eejump-{n}*))")
+ (ee-template0 "(defun eejump-{n} () {sexp})")))
+
+
+;;; __ __ __ __
+;;; | \/ | | \/ |_ _ __ ___ __ _ _ __
+;;; | |\/| |_____| |\/| (_) | '_ ` _ \ / _` | '_ \
+;;; | | | |_____| | | |_ | | | | | | (_| | | | |
+;;; |_| |_| |_| |_(_) |_| |_| |_|\__,_|_| |_|
+;;;
+;; See: (find-wrap-intro "<M-M>")
+(define-key eev-mode-map "\M-M" 'eewrap-man)
+
+(defun eewrap-man () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-man))
+(defun ee-wrap-man (str)
+ "An internal function used by `eewrap-man'."
+ (ee-HS `(find-man ,str)))
+
+
+
+;;; __ __ ____ _ __ _ _ _
+;;; | \/ | | _ \ _ _ __ __| |/ _| (_) | _____
+;;; | |\/| |_____| |_) (_) | '_ \ / _` | |_| | | |/ / _ \
+;;; | | | |_____| __/ _ | |_) | (_| | _| | | < __/
+;;; |_| |_| |_| (_) | .__/ \__,_|_| |_|_|_|\_\___|
+;;; |_|
+;; See: (find-pdf-like-intro)
+(define-key eev-mode-map "\M-P" 'eewrap-pdflike)
+
+(defun eewrap-pdflike () (interactive)
+ (ee-this-line-wrapn 2 'ee-wrap-pdflike))
+(defun ee-wrap-pdflike (stem fname)
+ "An internal function used by `eewrap-pdflike'."
+ (ee-template0 "\
+;; (find-fline {(ee-S (file-name-directory fname))})
+\(code-xpdf \"{stem}\" \"{fname}\")
+\(code-pdf-text \"{stem}\" \"{fname}\")
+;; \(find-{stem}page)
+;; \(find-{stem}text)
+"))
+
+
+
+;;; __ __ ___ _ __ _ _ _ _ _ _
+;;; | \/ | / _ \ _ _ __ __| |/ _| (_) | _____ | (_)_ __ | | __
+;;; | |\/| |_____| | | (_) | '_ \ / _` | |_| | | |/ / _ \_____| | | '_ \| |/ /
+;;; | | | |_____| |_| |_ | |_) | (_| | _| | | < __/_____| | | | | | <
+;;; |_| |_| \__\_(_) | .__/ \__,_|_| |_|_|_|\_\___| |_|_|_| |_|_|\_\
+;;; |_|
+;; See: (find-pdf-like-intro)
+;; (define-key eev-mode-map "\M-Q" 'eewrap-pdflike-link)
+
+(defun eewrap-pdflike-link () (interactive)
+ (ee-this-line-wrapn 2 'ee-wrap-pdflike-link))
+(defun ee-wrap-pdflike-link (n text)
+ "An internal function used by `eewrap-pdflike-link'."
+ (format "%s\n%s"
+ (ee-wrap-pdflike-link1 "page" n text)
+ (ee-wrap-pdflike-link1 "text" n text)))
+(defun ee-wrap-pdflike-link1 (what n text)
+ "An internal function used by `eewrap-pdflike-link'."
+ (ee-template0
+ "{ee-H}(find-{ee-page-c}{what} (+ {ee-page-offset} {n}) {(ee-S text)})"))
+
+
+
+
+
+;;; __ __ ____ __ _ _ _
+;;; | \/ | | _ \ _ _ __ _ __ ___ / / __ ___ | | ____| (_)_ __
+;;; | |\/| |_____| |_) (_) | '__| '_ ` _ \ / / '_ ` _ \| |/ / _` | | '__|
+;;; | | | |_____| _ < _ | | | | | | | |/ /| | | | | | < (_| | | |
+;;; |_| |_| |_| \_(_) |_| |_| |_| |_/_/ |_| |_| |_|_|\_\__,_|_|_|
+;;;
+(define-key eev-mode-map "\M-R" 'eewrap-rm/mkdir/cd)
+
+(defun eewrap-rm/mkdir/cd () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-rm/mkdir/cd))
+(defun ee-wrap-rm/mkdir/cd (dir)
+ "An internal function used by `eewrap-rm/mkdir/cd'."
+ (ee-template0 "\
+# (find-fline \"{dir}\")
+rm -Rv {dir}
+mkdir {dir}
+cd {dir}"))
+
+
+;;; __ __ ____ __ _ _ _
+;;; | \/ | / ___|_ / _(_)_ __ __| | ___| |__
+;;; | |\/| |____\___ (_) | |_| | '_ \ / _` |_____/ __| '_ \
+;;; | | | |_____|__) | | _| | | | | (_| |_____\__ \ | | |
+;;; |_| |_| |____(_) |_| |_|_| |_|\__,_| |___/_| |_|
+;;;
+;; See: (find-wrap-intro "<M-S>")
+(define-key eev-mode-map "\M-S" 'eewrap-sh)
+
+(defun eewrap-sh () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-sh))
+(defun ee-wrap-sh (str)
+ "An internal function used by `eewrap-sh'."
+ (ee-HS `(find-sh ,str)))
+
+(defun eewrap-sh0 () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-sh0))
+(defun ee-wrap-sh0 (str)
+ "An internal function used by `eewrap-sh0'."
+ (ee-HS `(find-sh0 ,str)))
+
+
+;;; __ __ _____ _ _ _
+;;; | \/ | |_ _| ___ ___ _ __ (_) |_ ___| |__
+;;; | |\/| |_____| |(_) / _ \/ _ \ '_ \| | __/ __| '_ \
+;;; | | | |_____| | _ | __/ __/ |_) | | || (__| | | |
+;;; |_| |_| |_|(_) \___|\___| .__/|_|\__\___|_| |_|
+;;; |_|
+;; (define-key eev-mode-map "\M-T" 'eewrap-eepitch)
+;; (find-eev "eepitch.el" "eepitch-wrap")
+
+
+
+;;; __ __ __ __ _ _ _ _
+;;; | \/ | \ \ / / __ _ _ _ __| (_) _____ _(_) __| | ___ ___
+;;; | |\/| |____\ \ / (_) / _` | | | |/ _` | |/ _ \ \ / / |/ _` |/ _ \/ _ \
+;;; | | | |_____\ V / _ | (_| | |_| | (_| | | (_) \ V /| | (_| | __/ (_) |
+;;; |_| |_| \_/ (_) \__,_|\__,_|\__,_|_|\___/ \_/ |_|\__,_|\___|\___/
+;;;
+;; See: (find-audiovideo-intro)
+(define-key eev-mode-map "\M-V" 'eewrap-audiovideo)
+
+(defun eewrap-audiovideo () (interactive)
+ (ee-this-line-wrapn 2 'ee-wrap-audiovideo))
+(defun ee-wrap-audiovideo (stem fname)
+ "An internal function used by `eewrap-audiovideo'."
+ (ee-template0 "\
+;; (find-fline {(ee-S (file-name-directory fname))})
+\(code-audio \"{stem}\" \"{fname}\")
+\(code-video \"{stem}\" \"{fname}\")
+;; \(find-{stem})
+;; \(find-{stem} \"0:00\")
+"))
+
+
+
+;;; __ __ _____ __ _ _ _
+;;; | \/ | |__ /_ / _(_)_ __ __| | _______| |__
+;;; | |\/| |_____ / /(_) | |_| | '_ \ / _` |____|_ / __| '_ \
+;;; | | | |_____/ /_ _ | _| | | | | (_| |_____/ /\__ \ | | |
+;;; |_| |_| /____(_) |_| |_|_| |_|\__,_| /___|___/_| |_|
+;;;
+(define-key eev-mode-map "\M-Z" 'eewrap-zsh)
+
+(defun eewrap-zsh () (interactive)
+ (ee-this-line-wrapn 1 'ee-wrap-zsh))
+(defun ee-wrap-zsh (str)
+ "An internal function used by `eewrap-zsh'."
+ (ee-HS `(find-zsh ,str)))
+
+
+
+
+
+;;; /\ ____
+;;; ___ _____ ___ __ __ _ _ __|/\|___ \
+;;; / _ \/ _ \ \ /\ / / '__/ _` | '_ \ __) |
+;;; | __/ __/\ V V /| | | (_| | |_) | / __/
+;;; \___|\___| \_/\_/ |_| \__,_| .__/ |_____|
+;;; |_|
+;;
+;; See: (find-eev "eev-tlinks.el" "find-find-links-links")
+;; (find-wrap-intro "eewrap-eewrap")
+;; This is somewhat similar to `find-find-links-links',
+;; but it is MUCH more primitive - consider it a demo!
+
+(defun eewrap-eewrap () (interactive)
+ (ee-this-line-wrapn 3 'ee-wrap-eewrap))
+(defun ee-wrap-eewrap (C stem args)
+ (let ((n (length (ee-split args))))
+ (ee-template0 "
+;; M-{C}: {stem}
+\(define-key eev-mode-map \"\\M-{C}\" 'eewrap-{stem})
+
+\(defun eewrap-{stem} () (interactive)
+ (ee-this-line-wrapn {n} 'ee-wrap-{stem}))
+\(defun ee-wrap-{stem} ({args})
+ \"An internal function used by `eewrap-{stem}'.\"
+ (ee-template0 \"\\
+{<}(ee-HS `(find-{stem} ,{args})){>}\"))\n")))
+
+
+;; A more standard way to create `eewrap-*' functions.
+;; (find-find-links-links "<none>" "eewrap" "C stem args")
+;;
+(defun find-eewrap-links (&optional C stem args &rest pos-spec-list)
+"Visit a temporary buffer containing hyperlinks for foo."
+ (interactive)
+ (setq C (or C "{C}"))
+ (setq stem (or stem "{stem}"))
+ (setq args (or args "{args}"))
+ (apply 'find-elinks-elisp
+ `((find-eewrap-links ,C ,stem ,args ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-eewrap-links)
+ ,(ee-wrap-eewrap C stem args)
+ )
+ pos-spec-list))
+
+;; Test: (find-eewrap-links)
+
+
+
+
+
+;;; _
+;;; ___ ___ _ __ ___ _ __ __ _| |_
+;;; / __/ _ \| '_ ` _ \| '_ \ / _` | __|
+;;; | (_| (_) | | | | | | |_) | (_| | |_
+;;; \___\___/|_| |_| |_| .__/ \__,_|\__|
+;;; |_|
+
+;; (defalias 'ee-H 'ee-hyperlink-prefix)
+;; (defalias 'ee-S 'ee-pp0)
+
+(defalias 'ee-pp0 'ee-S) ; compatibility
+
+
+(provide 'eev-wrap)
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; ee-anchor-format: "defun %s "
+;; no-byte-compile: t
+;; End:
diff --git a/eev2-all.el b/eev2-all.el
new file mode 100644
index 0000000..f4624cd
--- /dev/null
+++ b/eev2-all.el
@@ -0,0 +1,119 @@
+;;; eev2-all.el -- load all the modules of the rewrite of eev (-> 0.96).
+;;; This can also be used as an index to the (new) source files.
+
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is (not yet?) part of GNU eev.
+;;
+;; GNU eev is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU eev is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;;
+;; Author: Eduardo Ochs <address@hidden>
+;; Maintainer: Eduardo Ochs <address@hidden>
+;; Version: 2012nov02
+;; Keywords: e-scripts
+;;
+;; Latest version: <http://angg.twu.net/eev-current/eev2-all.el>
+;; htmlized: <http://angg.twu.net/eev-current/eev2-all.el.html>
+;; See also: <http://angg.twu.net/eev-current/eev-readme.el.html>
+;; <http://angg.twu.net/eev-intros/find-eev-intro.html>
+;; (find-eev-intro)
+
+;;; Commentary:
+
+;; Just as eev-all.el loads all modules of the stable version of eev
+;; (0.95.2) this loads all the refactored modules of eev, that are
+;; going to become eev-0.96 - a major rewrite.
+
+;; (find-eev-intro)
+
+
+;; The main "killer feature" of eev: a way to control interactive programs.
+;; See: (find-eepitch-intro)
+;; (find-wrap-intro)
+(require 'eepitch) ; (find-eev "eepitch.el")
+(require 'eev-wrap) ; (find-eev "eev-wrap.el")
+
+;; The other main killer feature: elisp hyperlinks.
+;;
+;; The main way to follow hyperlinks (`M-e') and to go back (`M-k')
+;; is described in:
+;; (find-eval-intro)
+(require 'eev-flash) ; (find-eev "eev-flash.el")
+(require 'eev-eval) ; (find-eev "eev-eval.el")
+(require 'eev-multiwindow) ; (find-eev "eev-multiwindow.el")
+(require 'eev-mode) ; (find-eev "eev-mode.el")
+;;
+;; The implementation of hyperlink functions
+;; is described in:
+;; (find-links-intro)
+(require 'eev-blinks) ; (find-eev "eev-blinks.el")
+(require 'eev-plinks) ; (find-eev "eev-plinks.el")
+(require 'eev-elinks) ; (find-eev "eev-elinks.el")
+(require 'eev-tlinks) ; (find-eev "eev-tlinks.el")
+;;
+;; The ways to mass-produce hyperlink functions
+;; are described in:
+;; (find-code-c-d-intro "\nShorter hyperlinks\n")
+(require 'eev-code) ; (find-eev "eev-code.el")
+(require 'eev-env) ; (find-eev "eev-env.el")
+(require 'eev-brxxx) ; (find-eev "eev-brxxx.el")
+(require 'eev-pdflike) ; (find-eev "eev-pdflike.el")
+(require 'eev-audiovideo) ; (find-eev "eev-audiovideo.el")
+(require 'eev-anchors) ; (find-eev "eev-anchors.el")
+
+;; User stuff.
+;; (find-eejump-intro)
+(require 'eev-intro) ; (find-eev "eev-intro.el")
+(require 'eev-edit) ; (find-eev "eev-edit.el")
+(require 'eejump) ; (find-eev "eejump.el")
+(require 'eev-rcirc) ; (find-eev "eev-rcirc.el")
+
+;; Advanced (and hard to use) features that may require creating a
+;; temporary directory, patching rcfiles, and installing Expect
+;; scripts. They have not been completely ported to eev2 yet! See:
+;; (find-prepared-intro)
+;; (find-bounded-intro)
+;; (find-channels-intro)
+(require 'eev-prepared) ; (find-eev "eev-prepared.el")
+(require 'eev-bounded) ; (find-eev "eev-bounded.el")
+(require 'eev-channels) ; (find-eev "eev-channels.el")
+
+(provide 'eev2-all)
+
+
+
+;; Garbage-ish:
+;;
+;; I am keeping these links here just for reference - these files and
+;; functions contain useful things that have not been copied to eev2
+;; yet, not even in broken form. DO NOT UNCOMMENT!
+;;
+;; (require 'eev) ; (find-eev "eev.el")
+;; (require 'eev-glyphs) ; (find-eev "eev-glyphs.el")
+;; (require 'eev-compose) ; (find-eev "eev-compose.el")
+;; ; (find-eev "eev-glyphs.el" "eev-set-default-glyphs")
+;; ; (find-eev "eev.el" "ee-setenv")
+;; (require 'eev-steps) ; (find-eev "eev-steps.el")
+;; (require 'eev-langs) ; (find-eev "eev-langs.el")
+;; (require 'eev-mini-steps) ; (find-eev "eev-mini-steps.el")
+;; (require 'eechannel) ; (find-eev "eechannel.el")
+
+
+
+
+
+;; Local Variables:
+;; coding: raw-text-unix
+;; no-byte-compile: t
+;; End:
- [elpa] externals/eev c77ca3b 27/64: Rewrote eev-pdflike.el, added sections about it to (find-eev-quick-intro)., (continued)
- [elpa] externals/eev c77ca3b 27/64: Rewrote eev-pdflike.el, added sections about it to (find-eev-quick-intro)., Stefan Monnier, 2019/04/07
- [elpa] externals/eev 7162184 51/64: Added `find-texworkspdf-page'., Stefan Monnier, 2019/04/07
- [elpa] externals/eev b9baae6 17/64: First commit after an HD crash; lots of changes, Stefan Monnier, 2019/04/07
- [elpa] externals/eev 2518e75 50/64: Use "eev-beginner.el" instead of "eev-readme.el"., Stefan Monnier, 2019/04/07
- [elpa] externals/eev 51e636a 63/64: Deleted eev-pdflike-old.el., Stefan Monnier, 2019/04/07
- [elpa] externals/eev b56266f 54/64: Added `eev-beginner' (our first autoload)., Stefan Monnier, 2019/04/07
- [elpa] externals/eev 5dbba21 40/64: Added `find-eunicodeucs'; added lots of documentation., Stefan Monnier, 2019/04/07
- [elpa] externals/eev 14d1125 46/64: Converted several elisp files to utf-8., Stefan Monnier, 2019/04/07
- [elpa] externals/eev 22702eb 31/64: Made all secondary intros point to sections of find-eev-quick-intro., Stefan Monnier, 2019/04/07
- [elpa] externals/eev a5f9343 30/64: Small changes in `find-eev-install-links' and in eev-intro.el., Stefan Monnier, 2019/04/07
- [elpa] externals/eev af88c9b 01/64: Initial commit for eev2,
Stefan Monnier <=