gnu-emacs-sources
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

austex.el (revision 1)


From: Joe Corneli
Subject: austex.el (revision 1)
Date: Mon, 25 Oct 2004 15:42:38 -0500

Updated with these new features:

 speedy insertion of single variables ($a$, $\alpha$), a la cdlatex

 "visual" register handling (see `austex-copy-rectangle-to-register')


;;; austex.el -- general latex utilities

;; Copyright (C) 2004 Joseph Corneli <address@hidden>

;; Time-stamp: <jac -- Tue Oct 26 15:38:49 CDT 2004>

;; This file is not part of GNU Emacs, but it is distributed under
;; the same terms as GNU Emacs.

;; GNU Emacs 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 2, or (at your
;; option) any later version.

;; GNU Emacs 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; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; This file collects my code for working with LaTeX under Emacs.  I
;; use these commands together with LaTeX mode.  I tend to have no
;; trouble typing math "in real time", as I take lecture notes for
;; example.

;; Since this file makes available a large number of functions that
;; one needs to be able to select and execute very quickly, the choice
;; of bindings is important (see austex-bindings.el).

;; In order to use these commands and bindings with LaTeX mode, place
;;
;;   (add-hook 'latex-mode-hook 'austex-mode)
;;
;; in your .emacs configuration file.

;; Some people might wonder why I don't just use AUCTeX.  Other than
;; the simple answer that I think my bindings are better, there are
;; two additional reasons.  When I was learning to type math with
;; Emacs, the AUCTeX learning curve seemed too steep.  Also, AUCTeX's
;; advertised functionality seemed like overkill for what I wanted to
;; do.  Eventually, if I continue to develop this code, I will
;; probably cherrypick things I like from AUCTeX's code.  The name of
;; this file is a joke on AUCTeX and AUStin TEXas.

;; Some people are sure to frown on the duplication of effort and the
;; fact that my code is not as nice in many ways.  Perhaps others will
;; appreciate the speed and simplicity of the approach I've been
;; using.  The speediness probably comes down to choice of bindings.
;; The simplicity in part a side-effect of the fact that I haven't
;; made any effort to provide an additional customization layer: if
;; you want to change the way this package works, change the code.  No
;; effort has been made to be fully general, so you may well have to
;; do some editing to get this file to do what you want.

;; Thanks to Klaus Berndl for help with the macro evaluation strategy.
;; An alternative approach was suggested by Daniel Pittman, viz.,
;;
;; (dolist (name '("alpha" "beta"))
;;   (fset (intern (concat "austex-" name))
;;        `(lambda () (interactive) (insert "\\" ,name))))
;;
;; And this is tighter...

;;; History:

;; I decided to revise my LaTeX-under-Emacs code into this
;; "publishable" form following email conversations with Ross Moore
;; about what makes a good LaTeX macro.  Many "convenience" LaTeX
;; macros should actually be handled at the editor-macro level.  My
;; hope is that this code will be a positive contribution to the
;; development of a tightly integrated and correctly divied up editing
;; environment for mathematical writing.

;;; Future:

;; First of all, add navigation features.  Cf. cdlatex.el where
;; `cdlatex-tab' is defined; its docstring says
;;
;;     The cursor stops... 
;;     - before closing brackets if preceding-char is any of -({[]})
;;     - after  closing brackets, but not if following-char is any 
;;       of ({[_^
;;     - just after $, if the cursor was before that $.
;;     - at end of non-empty lines
;;     - at the beginning of empty lines
;;     - before a SPACE at beginning of line
;;     - after first of several SPACE).
;;
;; It would be good to do this sort of thing, but (probably) in more
;; generality.  (I should test out `cdlatex-tab' to see how it
;; behaves.)  In particular, I think it would be nice to be able to
;; navigate both backwards and forwards.  See comments at the
;; beginning of the section "Forms to fill in" below.

;; Another feature that would be useful to emulate would be that
;; provided by address@hidden', which allows one to put
;; braces around things already in the buffer.

;; (defun address@hidden (string &optional arg)
;;   (if arg
;;       (progn
;;         (setq arg (prefix-numeric-value arg))
;;         (if (< arg 0)
;;             (progn
;;               (skip-chars-backward " \t\n\r\f")
;;               (save-excursion
;;                 (forward-sexp arg)
;;                 (insert "@" string "{"))
;;               (insert "}"))
;;           (skip-chars-forward " \t\n\r\f")
;;           (insert "@" string "{")
;;           (forward-sexp arg)
;;           (insert "}")))
;;     (insert "@" string "{}")
;;     (backward-char)))

;; With an eye to the distant future, let me mention that I am
;; interested in developing software that can parse and "understand"
;; mathematical writing.  Some beginning steps towards linguistic
;; analysis of mathematical writing may (eventually) be included in
;; this package.

;;; Code:

;;; Environment:

(defvar austex-visual-registers t)

;;; Basic navigation:

;; The basic pattern "$<math>$" has to be filled in time and again.
;; We provide some simple commands related to this pattern.  Note that
;; these should probably be made to work with other math environments,
;; as in auctex's texmathp.el.

;; Some commands to skip _over_ a math environment or a block of text
;; between two math environments would be handy.

(defun austex-end-of-math ()
  "Jump forwards past text, positioning cursor just before the next $."
  (interactive)
  (search-forward "$")
  (backward-char 1))

(defun austex-beginning-of-math ()
  "Jump backwards past text, positioning cursor just after the previous $."
  (interactive)
  (search-backward "$")
  (forward-char 1))

(defun austex-out-of-math ()
  "Jump past next $ and insert a space (if there isn't one already)."
  (interactive)
  (search-forward "$")
  (just-one-space))

;; these require that you are inside of a "form" to start with.  This
;; code is not fully general!  and I'm not sure it works anyway!
;; "Forms" are something like sexps and perhaps the code for moving
;; around between sexps can be modified to produce the desired effect
;; here.
(defun austex-next-form ()
  "Jump to next } or $."
  (interactive)
  (up-list)
  (unless (search-forward "}" nil t)
    (search-forward "$"))
  (backward-char 1))

(defun austex-previous-form ()
  "Jump to previous } or $."
  (interactive)
  (backward-up-list)
  (unless (search-backward "}" nil t)
    (search-backward "$")))

;; Even more questionable...

(defun austex-next-bracket ()
  (interactive)
  (search-forward "{}")
  (backward-char))

;;; Environments:

(defmacro austex-define-tex-environment (name)
  "Create a function that inserts the TeX environment NAME."
  `(defun ,(intern (concat "austex-" name)) ()
     (interactive)
     (insert "\\begin{" ,name "}")
     (newline)
     (insert "\\end{" ,name "}")
     (beginning-of-line)
     (newline)
     (backward-char)))

;; Actually, arrays should maybe be handled separately, and read in
;; number of cols.  Also, inserting some arrays can be quick, cf. 
;; section on sequences.
(dolist
    (elt '("defn" "eqnarray*" "proof" "quote" "array" "cases"))
  (eval `(austex-define-tex-environment ,elt)))

;; this is to be used in combination with `mmm-mode' and `multi-task'.
;; the purpose is to have a nice literate programming environment for
;; elisp/whatever.  We only get fancy if `mmm-mode' is available
;; however.
(if (require 'mmm-mode nil t)
    (defun austex-verbatim ()
      (interactive)
      (let ((beg (point)))
        (insert "\\begin{verbatim}")
        (newline)
        (insert "\\end{verbatim}")
        (let ((end (point)))
          (beginning-of-line)
          (newline)
          (backward-char)
          (mmm-parse-region beg (1+ end))))
      (message nil))
  (austex-define-tex-environment "verbatim"))

;;; Lists:

(defmacro austex-define-tex-list (name)
  "Create a function that inserts the TeX list NAME."
  `(defun ,(intern (concat "austex-" name)) ()
     (interactive)
     (insert
      "\\begin{" ,name "}
\\item 
\\end{" ,name "}")
     (search-backward "\\item ")
     (end-of-line)))

(dolist
    (elt '("enumerate" "itemize"))
  (eval `(austex-define-tex-list ,elt)))

;; This decorative line between items should probably be optional/customizable.
(defun austex-item ()
  (interactive)
  (newline)
  (insert
   "%------------------------------------------------------------------*
\\item "))

;;; Greek letters and other simple symbols:

;; Note that some capitalized greek letters need nonstandard latex support.
(defmacro austex-define-tex-symbol (name)
  "Create a function that inserts the TeX symbol NAME."
  `(defun ,(intern (concat "austex-" name)) (&optional capitalize)
     ,(concat "Insert the TeX symbol \\" name 
              ", or \\" (upcase-initials name) 
              " if CAPITALIZE is non-nil.")
     (interactive "P")
     (insert "\\" (if capitalize
                      (upcase-initials ,name)
                    ,name))))

(dolist
    (elt '("alpha" "beta" "gamma" "delta" "epsilon" "zeta" "eta" "theta"
           "iota" "kappa" "lambda" "mu" "nu" "xi" "omicron" "pi" "rho"
           "sigma" "tau" "upsilon" "phi" "chi" "psi" "omega" "varphi"
           "infty"))
  (eval `(austex-define-tex-symbol ,elt)))

(defmacro austex-define-tex-symbol-1 (name)
  "Create a function that inserts the TeX symbol NAME, followed by a space."
  `(defun ,(intern (concat "austex-" name)) ()
     (interactive)
     (insert "\\" ,name " ")))

;; int should maybe be different.
(dolist
    (elt '("Leftarrow" "Leftrightarrow" "Rightarrow" "Subset" "Supset"
           "approx" "cap" "cdot" "cdots" "circ" "cong" "cup" "equiv"
           "exists" "forall" "geq" "in" "int" "ldots" "leq"
           "nabla" "ni" "neq" "openset" "otimes" "partial"
           "rightarrow" "setminus" "sim" "simeq" "square" "subset"
           "supset" "times" "triangle" "vdots" "vee" "wedge"))
  (eval `(austex-define-tex-symbol-1 ,elt)))

(defmacro austex-define-tex-symbol-2 (name)
  "Create a function that inserts NAME.
Simple, maybe even silly, but useful in combination with 
`austex-fast-math-insert'."
  `(defun ,(intern (concat "austex-" name)) ()
     (interactive)
     (insert ,name)))

(dolist
    (elt '("1" "2" "3" "4" "5" "6" "7" "8" "9" "0"
           "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" 
           "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
           "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"
           "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
  (eval `(austex-define-tex-symbol-2 ,elt)))

;; Th openset symbol is part of Unicode now I think, though not yet
;; part of a standardard LaTeX font as far as I know.

;;; Fontification and unary operators:

(defmacro austex-define-tex-unary-markup (name)
  "Create a function that inserts the TeX unary markup command NAME.
Examples of such commands are emph, mathop, mathrm, and hat."
  `(defun ,(intern (concat "austex-" name)) ()
     (interactive)
     (insert "\\" ,name "{}")
     (backward-char 1)))

(dolist
    (elt '("bar" "check" "dot" "emph" "hat" "mathbf" "mathcal" "mathit"
           "mathop" "mathord" "mathrm" "overdoubledot" "text" "tilde"))
  (eval `(austex-define-tex-unary-markup ,elt)))

;;; Speedy insertion of single letters.

;; Enables extra-speedy insertion of common single symbol phrases,
;; e.g. $\alpha$ or $3$ (cf. cdlatex.el).

(defun austex-fast-math-insert (symbol-producer)
  "A quick way to insert TeX symbols in between dollar signs. 
SYMBOL-PRODUCER is a function that actually inserts the symbols."
  (insert "$") 
  (funcall symbol-producer)
  (insert "$ "))

(defun austex-period ()
  (interactive)
  (when (not (looking-at "[^\n\\.]*\\.[^\n\\.]$"))
      (end-of-line))
  (while (search-backward-regexp "\\s-$" (line-beginning-position) t)
    (replace-match ""))
  (insert ".  "))

;;; Fancy exponents:

;; These could be built by a combination of other functions from this
;; file.  But I don't know if that would make them "more transparent".

(defun austex-complement ()
  (interactive)
  (insert "^{\\complement}"))

(defun austex-inverse ()
  (interactive)
  (insert "^{-1}"))

(defun austex-to-the-star ()
  (interactive)
  (insert "^{\\star}"))

(defun austex-to-the-ast ()
  (interactive)
  (insert "^*"))

;;; Forms to fill in:

;; By a "form" I mean something that is designed for entering data
;; into.  For example, if a variable has a subscript "form", the data
;; it is looking for is the expression giving the value of the
;; subscript.  The simplest form in LaTeX is probably "$$", which asks
;; you to fill in some math expression.  Most of the forms here take
;; one argument, but some (e.g. `austex-langle-rangle', `austex-frac')
;; take two -- of course, you are free to leave any of the forms blank
;; and LaTeX will still work.  Forms like `austex-partial-derivative'
;; _expect_ to take a variable number of data (1 or 2).

;; If you want to be _literal_, the various environments are also
;; forms, as is the buffer itself.

;; The LaTeX code for forms is associated with a set of regular
;; expressions that one should be able to use to decide e.g. what the
;; "next" or "previous" form insertion point is, and move the cursor
;; to that point.

;; Since forms tend to be nested, navigating forms should be similar
;; to navigating sexps.  It would be nice if "next" could move you
;; "up" or "forward" depending on context, but this would also be a
;; nice feature to have for navigating sexps.

;; Note that the syntax of sexps is not quite right for us in places.
;; For example, <1000 is considered to be one sexp.  I don't know if
;; this is a valid variable name in Lisp: I guess it is.  But it is
;; still wrong for us.  

;; I guess we could call the new sexps "texps" -- that would be funny.

;; But what is not so funny is that in order to hack these things I'll
;; probably have to read and modify the Emacs C code in syntax.c.  :(

;; Luckily the sexps for LaTeX mode aren't *too* far off from how they
;; should be.


;; This isn't really the right way to accomplish what we want.  We
;; don't just want the *first* match (which is found here), nor do we
;; want the *minimal* match.  Instead, we want the match that makes
;; sense syntactically.  Again, this is like with sexps.  We find the
;; left "paren" and then skip over "paren pairs" until we find the
;; correct "right paren".  This gives some clue about how
;; `austex-define-tex-form' should be defined -- it can take a MIDDLE
;; as well as an end, and the stuff in the MIDDLE you should have to
;; skip over, in addition to whatever stuff you skip over by matching
;; paren pairs.
;;
;; But in the mean time, this sort of works -- in cases where the
;; first match is the correct match, which should be the case for
;; example if you are outside of math mode and request the previous
;; piece of text that was in math mode.
(defun austex-get-prev-form (beginning end)
  "Retrieve and insert any previous text between BEGINNING and END.
BEGINNING and END are buffer substrings to match."
  (let ((beg (save-excursion
               (search-backward end nil t)
               (search-backward beginning nil t)))
        (end (save-excursion
               (if (search-backward end nil t)
                   (match-end 0)))))
    (if (and beg end)
        (insert (buffer-substring beg end))
      (message "No match."))))

(defmacro austex-define-tex-form (name beginning end)
  "Create a function that inserts the TeX form named NAME.
The form is based on BEGINNING and ENDING text.  Cursor will
be positioned between the two pieces of text."
  ;; if given a prefix argument, this should insert the previous
  ;; matching form.  We could also set it up to take a numeric
  ;; argument and select the nth previous form.  That could be a
  ;; little challenging for the user without additional visual
  ;; feedback to help in seeing what n is supposed to be.
  `(defun ,(intern (concat "austex-" name)) (&optional copy-previous)
     (interactive "P")
     (if copy-previous
         (austex-get-prev-form ,beginning ,end)
       (insert ,beginning ,end)
       (backward-char (length ,end)))))

;; Note: the tex environments could be treated like forms too.  The
;; only one I have special concern about is arrays, because we would
;; probably be best served by giving `austex-array' a prefix argument.
;; If instead of using a prefix arg to enter previous text selection
;; "mode", but *actually* used a *mode* and some *other* key to enter
;; that mode, this wouldn't be a problem at all.  That's something
;; that can wait until we have the basic selection functions down
;; however.
;;
;; Including of course a way to select something that was earlier than
;; just the immediately previous expression.  So, once we have the
;; immediately previous expression part taken care of, we should be
;; able to give a numeric argument to select something earlier.  (Like
;; `forward-sexp' does, for example.)
;;
;; These should maybe be able to have functions associated with
;; them that they run when they insert too.
(dolist (elt '(("math" "$" "$")
               ("exponent" "^{" "}")
               ("subscript" "_{" "}")
               ("set" "\\{" "\\}")
               ("norm" "\\|" "\\|")
               ("absolute-value" "|" "|")
               ("sqrt" "\\sqrt{" "}")
               ("prod" "\\prod_{" "}")
               ("sum" "\\sum_{" "}")
               ("quote-marks" "\"" "\"")
               ("parentheses" "(" ")")
               ("braces" "{" "}")
               ("brackets" "[" "]")
               ("lfloor-rfloor" "\\lfloor " "\\rfloor")
               ("verb" "\\verb|" "|")
               ;; Note: unlike the previous forms, the following have
               ;; a "variable" quality to them, i.e. the end or the
               ;; beginning of the form after it is edited won't
               ;; always match the end or the beginning as it is
               ;; indicated here.
               ("langle-rangle" "\\langle " ",\\rangle")
               ("frac" "\\frac{" "}{}")
               ("partial-derivative" "\\frac{\\partial}{\\partial " "}")
               ("derivative" "\\frac{d}{d " "}")))
  (eval `(austex-define-tex-form ,@elt)))

;;; Operations on the current equation:

;; The simplest thing is just selecting the text of the current
;; equation.  Should add this.

;; Also should have a function for converting quickly between
;; displayed and non-displayed equations.

;; Eventually it might be cool to be able to select previous equations
;; by number (like you can do with alternative spellings under
;; ispell).  That would involve some fancy work.

;; this macro lets you operate on just the current equation, nothing
;; else.  It could do a little bit better checking to see whether or
;; not we are inside an equation according to e.g. fontlock or
;; auctex's mathp (texmathp.el/`texmathp-match-environment' etc.).
(defmacro austex-narrowed-to-current-equation (&rest args)
  "Run ARGS on the current equation."
  `(save-excursion
     ;; this should match one _or_ two $'s
     (search-forward-regexp "\\$+")
     (let ((end (point)))
       (goto-char (match-beginning 0))
       (search-backward-regexp "\\$+")
       (save-restriction
         (narrow-to-region (point) end)
         ,@args))))

;; probably should be able to modify the previous macro to include an
;; `if' in the appropriate place & get this behavior as a bonus
(defmacro austex-narrowed-to-current-equation-excursive (&rest args)
  "Run ARGS on the current equation.
Point is allowed to move."
  `(progn
     ;; this should match one _or_ two $'s
     (search-forward-regexp "\\$+")
     (let ((end (point)))
       (goto-char (match-beginning 0))
       (search-backward-regexp "\\$+")
       (save-restriction
         (narrow-to-region (point) end)
         ,@args))))

;; Does the prefix arg really do what the docstring says it does?
(defun austex-turn-current-equation-into-equation-array (&optional prefix)
  "Turn a simple equation into an unnumbered equation array.
A non-nil PREFIX argument switches to a full replacement mode for
inequalities.  With no prefix, the equal sign is treated as the
only comparison operator.  This is to one's advantage e.g. when
greater-than or less-than signs are used inside some of the
members of an equation."
  (interactive "p")
  (austex-narrowed-to-current-equation
   (let ((bs (buffer-substring-no-properties (point-min) (point-max))))
     ;; replace dollar signs at the beginning and end of the equation
     ;; with empty string
     (delete-region (point-min) (point-max))
     (insert (replace-regexp-in-string "\\(^\\$+\\)\\|\\(\\$+$\\)" "" bs)))
   (goto-char (point-min))
   (insert "\n\\begin{eqnarray*}\n")
   (let ((past-first nil))
     ;; more different equation separators could be added to this list
     ;; and the regexp could be optimized.
     (while (re-search-forward
             (if prefix
                 "\\s-?[=><]\\|\\(\\\\geq\\)\\|\\(\\\\leq\\)\\s-?"
               "\\s-?=\\s-?")
             nil t)
       (if past-first
           (replace-match "\\\\\\\\\n&\\&& ")
         ;; we could be fancy and record the number of characters by
         ;; which the comparison operator is inserted, then use this
         ;; number of spaces later on.  But it isn't clear that this
         ;; makes for more readable code (esp.  in the case of long
         ;; equations!).  More ideally, we'd have another function for
         ;; fixing up equation arrays to look like that.
         (replace-match " &\\&& ")
         (setq past-first t))))
   (goto-char (point-max))
   (insert "\n\\end{eqnarray*}")))

;;; Sequences:

;; This section still has quite a ways to go.  The idea is to speed up
;; the entry of sequences, which otherwise take a long time to type
;; out.

;; It would be good to have a two-level prefix as used
;; for example with ¡rectangles! that would allow you to
;; input various different kinds of sequences cleanly.

;; It would also be cool to have a "graphical" way
;; to select inputs, maybe using something like ratmen
;; to input things by moving down the branches of some
;; tree.

;; But anyway, the different kinds of sequences we might
;; want are as follows:

;; a_0, a_1, ..., a_n
;; a_1, a_2, ..., a_n
;; a_1, a_2, ..., a_{n+1}

;; TODO: check that the subscript is a number, and
;; iterate the number.  But this provides basic
;; functionality.
(defun austex-insert-sequence-of-variables
  (term substart subend interterm)
  ;; read in three strings; if subend is empty,
  ;; we will insert "..." at the end of the sequence.
  (interactive (list (read-string
                      "Term: ")
                     (read-string
                      "Subscript starting: ")
                     (read-string
                      "Subscript ending: ")
                     (read-string
                      "What goes between terms?: ")))
  (insert term
          "_"
          (if (> (length substart) 1)
              (concat "{" substart "}")
            substart)
          interterm
          ;; would be good to be able to specify
          ;; that we want ldots with some
          ;; prefix argument.
          "\\cdots"
          interterm
          (if (not (equal subend ""))
              (concat term
                      "_"
                      (if (> (length subend) 1)
                          (concat "{" subend "}")
                        subend))
            "\\ldots")))

;;; Registers:

;; Basically copied right out of register.el (I think a code snippet
;; this small constitutes "fair use".), I personally find this
;; behavior to be more natural in general.  For the public, this is
;; only turned on in `austex-mode'.  (What it does: sets point and
;; mark opposite to the way `insert-register' does it.)
;;
;; I'm not sure why this messes with the mark?
(defun austex-insert-register (register)
  "Insert contents of register REGISTER.  (REGISTER is a character.)
Normally puts mark before and point after the inserted text."
  (interactive "*cInsert register: \n")
  (push-mark)
  (let ((val (get-register register)))
    (cond
     ((consp val)
      (insert-rectangle val))
     ((stringp val)
      (insert-for-yank val))
     ((numberp val)
      (princ val (current-buffer)))
     ((and (markerp val) (marker-position val))
      (princ (marker-position val) (current-buffer)))
     (t
      ;; avoid error
      nil))))

;; This should move anything it is replacing further down the list.
;;
;; Kyle Schalm suggested having the registers be populated
;; automatically by something like Huffman coding that detects which
;; phrases are commonly typed into the buffer.  I think this is an
;; excellent idea!  But probably we won't be able to do it that
;; effectively until we have the issues with fields sorted out.
;; However, we could play around with doing it with words only first.
(defun austex-copy-rectangle-to-register (register &optional overwrite)
  "Like `copy-rectangle-to-register' but assumes you mean \"copy current 
region\".
REGISTER is a character stating which register to use.  Further
differences from `copy-rectangle-to-register' are that visual
feedback on the register bank is provided (if `austex-visual-registers' 
is non-nil), and an attempt is made to preserve the register's
previous contents, if any.  Optional argument OVERWRITE says
don't bother trying to preserve the old contents of REGISTER."
  (interactive "cRegister: \nP:")
  (let ((old-contents (get-register register)))
    (when (and (not overwrite)
               old-contents
               (austex-move-contents-of-register register old-contents)))
    (copy-rectangle-to-register register 
                                (region-beginning) 
                                (region-end))
    (austex-update-register-display)))

(defun austex-update-register-display ()
  (when austex-visual-registers
    (let ((curbuff (current-buffer)))
      (save-excursion
        (set-buffer (get-buffer-create "*Registers*"))
        (delete-region (point-min) (point-max))
        (dolist 
            (elt (string-to-list
                  ;; "etaoinshrdlucmfgypwbvkxjqz"
                  "abcdefghijklmnopqrstuvwxyz"))
          (let ((letter (char-to-string elt)))
            (insert letter ": ")
            (or (austex-insert-register elt)
                "")
            (insert        "\n"))))
      (display-buffer "*Registers*")
      (set-buffer curbuff))))

(defun austex-move-contents-of-register (register old-contents)
  "If move content of this register to next nil register, if any."
  (let* ((remaining-registers 
          (member register 
                  (string-to-list "abcdefghijklmnopqrstuvwxyz")))
         (under-consideration (car remaining-registers)))
    (while (and remaining-registers
                (not (eq under-consideration (string-to-char "z"))))
      (setq remaining-registers (cdr remaining-registers))
      (setq under-consideration (car remaining-registers))
      (unless (get-register under-consideration)
        (set-register under-consideration old-contents)
        (setq remaining-registers nil)))))

(defun austex-delete-matching-registers (regexp)
  "Set to nil any register that contains text matching REGEXP."
  (interactive "MRegexp: ")
  (dolist 
      (elt (string-to-list
            "abcdefghijklmnopqrstuvwxyz"))
    (let ((reg (get-register elt)))
      (when reg
        (with-temp-buffer
          (austex-insert-register elt)
          (when (string-match regexp (buffer-string))
            (set-register elt nil))))))
  (austex-update-register-display))

(defun austex-clear-all-registers ()
  "Set all registers to nil."
  (interactive)
  (austex-delete-matching-registers ".*")
  (austex-update-register-display))

(defun austex-clear-register (char)
  (interactive "cRegister: ")
  (set-register char nil)
  (austex-update-register-display))

;;; Bonus Features:

(defun parenthesize ()
  "Add parentheses around everything on this line (modulo whitespace)."
  (interactive)
  (save-excursion
    (end-of-line)
    (delete-horizontal-space)
    (insert ")")
    (beginning-of-line)
    (while (looking-at " \\|\t")
      (forward-char 1))
    (insert "(")))

(when (require 'mmm-mode nil t)
  (defun multi-task ()
    "Use `emacs-lisp-mode' inside of `latex-mode'."
    (interactive)
    (mmm-ify-by-regexp
     (quote emacs-lisp-mode)
     "\\\\begin{verbatim}" 0 "\\\\end{verbatim}" 0 25)))

(require 'austex-bindings)
(provide 'austex)

;;; austex.el ends here

;;; austex-bindings.el -- bindings for the austex latex utilities

;; Copyright (C) 2004 Joseph Corneli <address@hidden>

;; Time-stamp: <jac -- Mon Oct 11 20:16:24 CDT 2004>

;; This file is not part of GNU Emacs, but it is distributed under
;; the same terms as GNU Emacs.

;; GNU Emacs 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 2, or (at your
;; option) any later version.

;; GNU Emacs 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; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; This file includes the bindings I use with AusTeX (see austex.el).

;; The long-term goal is to make this into an "optimal" keyboard
;; layout in the sense of Dvorak.  Right now it is just a good one in
;; the sense of the default Emacs map.  The bindings are built on top
;; of a Dvorak layout, and so some of them may appear awkward or
;; confusing to users of other layouts.  If you are already a Dvorak
;; user, adding these bindings to your repertoire should not be very
;; hard.  On the other hand, if you are not a Dvorak user and you
;; still want to use AusTeX, you have at least three options: (1) see
;; if the bindings make sense to you with your layout after all; (2)
;; port the bindings to your layout in such a way that they do make
;; sense; (3) learn Dvorak.

;; Unlike what you may be used to in Emacs, these bindings involve
;; using a lot of modifiers!  It is helpful to have a sense of the
;; physical layout of modifiers on my keyboard, even if you use some
;; other layout.

;; I actually have two Xmodmap setups; I will describe the one I use
;; on my laptop first, because it turns out that I seem to spend the
;; majority of my time typing on the laptop, especially when I am
;; taking lecture notes.

;; I replaced the number row on my laptop by modifiers. The layout is
;;
;;                     A H S C M G A G M C S H A
;;
;; where
;;
;;    A = Alt
;;    H = Hyper
;;    S = Super
;;    C = Control
;;    M = Meta
;;    G = AltGr (Mode_switch)
;;
;; The reason for the choice of the order is not arbitrary.  The basic
;; principle that is I want commonly-used modifiers to be reachable
;; without moving my wrists.  I can reach Mode_switch, Meta, Control,
;; and Super just by extending my fingers.  The middle Alt key is a
;; slightly longer reach.  Hyper is again a longer reach, and if I try
;; to press outside Alt keys without lifting my hand up and moving it,
;; I definitely feel a bit tweaked in the wrist.

;; As for what happens to the numbers -- they have been moved to the
;; AltGr layer in the right hand, in a traditional "embedded keypad"
;; arrangement.  In my view, a better configuration would probably
;; require a better keyboard layout to begin with and/or better logic
;; in the keyboard, together with a more robust system of modifiers
;; inside of X.

;; This setup makes the two-modifier chords Super+Control,
;; Control+Meta, Super+Meta easy to reach as well.  Hyper+Super and
;; Hyper+Control aren't that bad either, but they aren't quite as
;; nice.  Other two-modifier chords aren't particularly comfortable,
;; but at least it is _possible_ to enter Alt+Hyper and Alt+Super
;; (this would be much more dubious if it weren't for the extra Alt
;; keys out on the ends of the row).

;; Though three-modifier chords may seem silly, Hyper+Super+Control
;; and Super+Control+Meta are not very hard to press down using this
;; keyboard layout.  I don't bind to these much yet.

;; In general, the main benefit of using modifiers (and modifier
;; chords) instead of prefix keys is *speed*.  It takes less time, for
;; example, to press C-n than it does to press C-c n.  Sometimes
;; keypresses within the same modifier can be faster than you'd
;; expect, e.g. C-t C-t or G-. G-, (i.e., Up followed by backspace,
;; according to my Xmodmap).

;; Single keypresses tend to be the fastest, then single modifiers
;; plus single keys, then two modifiers plus single keys, then a
;; prefix key followed by a single key.

;; A time-savings is also afforded by finding the keys right where you
;; seek them.  This is not quite the same as knowing the keyboard
;; layout: it also means that the layout should have some internal
;; logic that is easy to understand.  Subjectively, the Dvorak layout
;; seems to be quite good in this regard.  One goal for this file is
;; to map out some of the psychological space behind the act of typing
;; math.

;; The second Xmodmap file I use is the one I have set up for typing
;; with my Kinesis Classic keyboard.  It is similar to the one I use
;; with my laptop's keyboard, but because the Kinesis keyboard comes
;; with an extra row of easy-to-reach keys below the standard four
;; rows, it is not necessary to replace the number row with modifiers.
;; This is the main difference between the two Xmodmap files.  Because
;; I don't have to remap the number row, I don't use an embedded
;; number keypad approach with this keyboard, instead, I have two
;; symmetrical "editing" keypads.  Because the extra fifth row has
;; only four keys for either hand, I do not bind the Alt modifier in
;; the same place with this Xmodmap file (rather it is bound to one of
;; the Kinesis "thumb keys").

;; There seems to be some risk associated with trying to share
;; something as "personal" as a keyboard layout.  However, I think
;; I've put enough work into these bindings to make them worth sharing
;; with anyone who's interested.  I've reduced the risk by not
;; including all of my bindings!  For anyone who is _really_
;; interested, the rest of the bindings (and various nonstandard
;; functions that are bound) are available on my website.  Oh yes, and
;; finally, the xmodmap files described above are also available on my
;; website.

;;; Code:

;; This is a very long variable definition...
(defvar austex-mode-map
  (let ((map (make-sparse-keymap)))

;;; Latin-1 (AltGr layer on standard keys):

    ;; The layout on my keyboards are:
    ;;
    ;; Laptop
    ;;          `  BS   Up   Del   =   + 7    8    9     ^
    ;;          ¡  Left Down Right ¿   - 4    5    6     _
    ;;          [  ]    {    }     ¥   ¤ 1    2    3     0
    ;;
    ;; Kinesis
    ;;          `  BS   Up   Del   =   + BS   Up   Del   ^
    ;;          ¡  Left Down Right ¿   - Left Down Right _
    ;;          [  ]    {    }     ¥   ¤ {    }    (     )

    (define-key map (quote [2212]) 'austex-math)                      ; currency
    (define-key map (quote [2213]) 'austex-out-of-math)               ; yen

    ;; This is used sort of like "tab", and when the function
    ;; `austex-next-field' is written, this should probably be bound to
    ;; that instead of `austex-end-of-math'.
    (define-key map (quote [2239]) 'austex-end-of-math)               ; 
questiondown

    ;; This probably won't be used very much (I might be wrong).  The
    ;; main use would seem to be for selecting text, and there should
    ;; be a seperate function that does that.
    (define-key map (quote [2209]) 'austex-beginning-of-math)         ; 
exclamdown

;;; Latin-1 (Peripheral keys):

    (define-key map [insert] 'parentheses)
    (define-key map [select] 'parenthesize)

    ;; Everything that doesn't have to take place very quickly should
    ;; probably not be bound in this section. `austex-math' and
    ;; `austex-out-of-math' are two examples of functions that need to
    ;; be able to be called very quickly.

;;; Control Characters:

    ;; These are things like C-w, C-y, etc.  Usually they are bound by
    ;; default in Emacs. Some of these keys have been cannibalized to
    ;; make prefix keymaps (see below).  It is worth knowing the
    ;; default bindings!!

;;; Keymaps:

    ;; Things just got more interesting.  These keymaps let us bind
    ;; lots more editor commands to speedy (though not lightning fast)
    ;; keyboard shortcuts.  The sections that give the bindings with
    ;; the associated "prefix commands" appear in later sections.  Not
    ;; sure whether these should be sparse keymaps or not?

    (define-key map [?\C-.] (make-keymap))
    (define-key map [?\C-,] (make-keymap))
    (define-key map [?\C-'] (make-keymap))
    (define-key map [?\C-\;] (make-keymap))

    ;; Setting up hyper and super for a non-X-enabled Emacs. Though
    ;; these are not strictly speaking keymaps, they are "prefix
    ;; commands" in the sense that you have to press the key, release
    ;; it, then find the next key in the sequence.

    (define-key function-key-map "\e[17~" 'event-apply-hyper-modifier); f6
    (define-key function-key-map "\e[20~" 'event-apply-super-modifier); f9

    ;; Next follow several sections of "single modifier plus
    ;; character" bindings.

;;; Hyper:

    ;; Mostly greek letters.

    (define-key map [(hyper ,)] 'austex-leq)
    (define-key map [(hyper .)] 'austex-geq)
    (define-key map [(hyper ?')] 'austex-neq)
    (define-key map [(hyper ?\040)] 'austex-out-of-math)              ; H-SPC
    (define-key map [(hyper ?\134)] 'austex-pipe)                     ; H-\
    (define-key map [(hyper ?\;)] 'austex-sim)
    (define-key map [(hyper a)] 'austex-alpha)
    (define-key map [(hyper b)] 'austex-beta)
    (define-key map [(hyper c)] 'austex-psi)
    (define-key map [(hyper d)] 'austex-delta)
    (define-key map [(hyper e)] 'austex-epsilon)
    (define-key map [(hyper f)] 'austex-varphi)
    (define-key map [(hyper g)] 'austex-gamma)
    (define-key map [(hyper h)] 'austex-theta)
    (define-key map [(hyper i)] 'austex-iota)
    (define-key map [(hyper j)] 'austex-ldots)
    (define-key map [(hyper k)] 'austex-kappa)
    (define-key map [(hyper l)] 'austex-lambda)
    (define-key map [(hyper m)] 'austex-mu)
    (define-key map [(hyper n)] 'austex-nu)
    (define-key map [(hyper o)] 'austex-omicron)
    (define-key map [(hyper o)] 'austex-phi)
    (define-key map [(hyper p)] 'austex-pi)
    (define-key map [(hyper q)] 'austex-chi)
    (define-key map [(hyper r)] 'austex-rho)
    (define-key map [(hyper s)] 'austex-sigma)
    (define-key map [(hyper t)] 'austex-tau)
    (define-key map [(hyper u)] 'austex-upsilon)
    (define-key map [(hyper v)] 'austex-infty)
    (define-key map [(hyper w)] 'austex-omega)
    (define-key map [(hyper x)] 'austex-xi)
    (define-key map [(hyper y)] 'austex-eta)
    (define-key map [(hyper z)] 'austex-zeta)

;;; Super:

    ;; Math symbols and the simplest math forms.

    ;; I have a sort of weird "graphical" mnemonic for these symbols.
    ;; It tends to work out pretty well, the only difficulty that
    ;; stands out to be being that I seem to forget which finger to
    ;; use for \cap and which to use for \cup.  Some of the other
    ;; commands require a little bit of hunt-and-peck activity as
    ;; well.  Eventually it would be good to optimize this layout in a
    ;; Dvorakian way or find other means of reorganizing the confusing
    ;; symbols to make them easier to find.

    ;; I tend to use this super binding on the laptop and the
    ;; corresponding Latin 1 binding with the Kinesis.  It might
    ;; actually be better to use one binding all the time.
    (define-key map [(super ?\040)] 'austex-math)                     ; s-SPC
    (define-key map [(super ,)] 'austex-subset)
    (define-key map [(super .)] 'austex-supset)
    (define-key map [(super <)] 'austex-Subset)
    (define-key map [(super >)] 'austex-Supset)
    (define-key map [(super ?\134)] 'austex-setminus)                 ; s-\
    (define-key map [(super \')] 'austex-equiv)
    (define-key map [(super \;)] 'austex-cong)
    (define-key map [(super a)] 'austex-simeq)
    (define-key map [(super b)] 'austex-nabla)
    (define-key map [(super c)] 'austex-cap)
    (define-key map [(super d)] 'austex-forall)
    (define-key map [(super e)] 'austex-ni)
    (define-key map [(super f)] 'austex-frac)
    (define-key map [(super g)] 'austex-int)
    (define-key map [(super h)] 'austex-circ)
    (define-key map [(super i)] 'austex-exists)
    (define-key map [(super j)] 'austex-cdots)
    (define-key map [(super k)] 'austex-wedge)
    (define-key map [(super l)] 'austex-Leftrightarrow)
    (define-key map [(super m)] 'austex-vee)
    (define-key map [(super n)] 'austex-rightarrow)
    (define-key map [(super o)] 'austex-in)
    (define-key map [(super p)] 'austex-partial)
    (define-key map [(super q)] 'austex-vdots)
    (define-key map [(super r)] 'austex-cup)
    (define-key map [(super s)] 'austex-Rightarrow)
    (define-key map [(super t)] 'austex-cdot)
    (define-key map [(super u)] 'austex-times)

    ;; we assume that there will be a subscript.  Not always true in
    ;; all math writing, but there _could_ always be one.
    (define-key map [(super v)] 'austex-sum)
    (define-key map [(super w)] 'austex-prod)
    (define-key map [(super x)] 'austex-triangle)
    (define-key map [(super y)] 'austex-sqrt)
    (define-key map [(super z)] 'austex-Leftarrow)

;;; Hyper+Super

    ;; Additional symbols, LaTeX environments and forms, fancy
    ;; exponents.

    ;; Symbols can be moved back and forth with Super until they are
    ;; all settled.

    ;; Some environments probably need to be fast, others can be as slow
    ;; as a prefix map. Forms need to be fast.

    ;; Probably all the fancy exponents could be moved to a prefix map.
    ;; On the other hand, if there aren't enough other things to put here,
    ;; they might as well stay.

    (define-key map [(hyper super ,)] 'austex-openset)
    (define-key map [(hyper super .)] 'austex-alist)
    (define-key map [(hyper super a)] 'austex-absolute-value)
    (define-key map [(hyper super b)] 'austex-next-bracket)
    (define-key map [(hyper super c)] 'austex-complement)
    (define-key map [(hyper super d)] 'austex-defn)
    (define-key map [(hyper super e)] 'austex-emph)
    (define-key map [(hyper super i)] 'austex-inverse)
    (define-key map [(hyper super l)] 'austex-langle-rangle)
    (define-key map [(hyper super o)] 'austex-otimes)
    (define-key map [(hyper super p)] 'austex-proof)
    (define-key map [(hyper super q)] 'austex-quote)
    (define-key map [(hyper super r)] 'austex-eqnarray*)
    (define-key map [(hyper super s)] 'austex-set)
    (define-key map [(hyper super v)] 'austex-verbatim)
    ;; "w" here stands for "wave equation"
    (define-key map [(hyper super w)] 'austex-square)
    (define-key map [(hyper super x)] 'austex-to-the-ast)
    (define-key map [(hyper super y)] 'austex-to-the-star)

;;; Hyper+Control:

    ;; Nothing here yet.

;;; Hyper+Meta:

    ;; Nothing here yet.

;;; Super+Control:

    ;; "fontification" and other unary-style macros, with a few
    ;; missing Emacs functions thrown in, and some math forms.  A nice
    ;; varied collection.

    ;; Note: There is a somewhat clear division between Hyper and
    ;; Super modified characters, namely, the former are mostly greek
    ;; letters and the latter are mostly math symbols.  It might be
    ;; sensible to have similar clear division between Hyper+Super and
    ;; Super+Control modified characters (shuttling anything that
    ;; doesn't fit into our categories off into another double
    ;; modifier group or prefix mapping).

    ;; Probably it would be best for the more infrequently-used
    ;; decorations to be placed into a prefix map (and perhaps all of
    ;; the decorations should go in the same place)

    (define-key map [(super control b)] 'austex-bar)
    (define-key map [(super control c)] 'austex-check)
    (define-key map [(super control d)] 'austex-derivative)
    (define-key map [(super control f)] 'austex-mathbf)
    (define-key map [(super control h)] 'austex-hat)
    (define-key map (quote [8388617]) 'austex-mathit)                 ; s-C-i = 
s-TAB
    (define-key map [(super control o)] 'austex-mathop)
    (define-key map [(super control p)] 'austex-partial-derivative)
    (define-key map [(super control r)] 'austex-mathrm)
    (define-key map [(super control s)] 'austex-subscript)
    (define-key map [(super control t)] 'austex-text)
    (define-key map [(super control l)] 'austex-exponent)
    (define-key map [(super control w)] 'austex-tilde)

;;; Alt:

    ;; Speedy insertion of single-character math patterns, like $1$,
    ;; $g$, and $\lambda$.  This is a fairly long and fairly ugly
    ;; section.

    ;; If possible, clean up so that prefix arg does good things for
    ;; the greek letters.

    (define-key map [(alt ?\040)] 'austex-period)                     ; A-SPC
    (define-key map (quote [4194350]) 'austex-period)                 ; A-.

    ;; double check: are the question marks needed?
    (define-key map [(alt ?1)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-1)))
    (define-key map [(alt ?2)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-2)))
    (define-key map [(alt ?3)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-3)))
    (define-key map [(alt ?4)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-4)))
    (define-key map [(alt ?5)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-5)))
    (define-key map [(alt ?6)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-6)))
    (define-key map [(alt ?7)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-7)))
    (define-key map [(alt ?8)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-8)))
    (define-key map [(alt ?9)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-9)))
    (define-key map [(alt ?0)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-0)))

    (define-key map [(alt a)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-a)))
    (define-key map [(alt b)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-b)))
    (define-key map [(alt c)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-c)))
    (define-key map [(alt d)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-d)))
    (define-key map [(alt e)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-e)))
    (define-key map [(alt f)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-f)))
    (define-key map [(alt g)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-g)))
    (define-key map [(alt h)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-h)))
    (define-key map [(alt i)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-i)))
    (define-key map [(alt j)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-j)))
    (define-key map [(alt k)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-k)))
    (define-key map [(alt l)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-l)))
    (define-key map [(alt m)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-m)))
    (define-key map [(alt n)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-n)))
    (define-key map [(alt o)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-q)))
    (define-key map [(alt p)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-p)))
    (define-key map [(alt q)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-q)))
    (define-key map [(alt r)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-r)))
    (define-key map [(alt s)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-s)))
    (define-key map [(alt t)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-t)))
    (define-key map [(alt u)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-u)))
    (define-key map [(alt v)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-v)))
    (define-key map [(alt w)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-w)))
    (define-key map [(alt x)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-x)))
    (define-key map [(alt y)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-y)))
    (define-key map [(alt z)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-z)))

    ;; It is really too much of a reach to press any of my modifiers
    ;; together with shift, so I use meta as a surrogate shift key.

    (define-key map [(alt meta a)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-A)))
    (define-key map [(alt meta b)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-B)))
    (define-key map [(alt meta c)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-C)))
    (define-key map [(alt meta d)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-D)))
    (define-key map [(alt meta e)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-E)))
    (define-key map [(alt meta f)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-F)))
    (define-key map [(alt meta g)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-G)))
    (define-key map [(alt meta h)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-H)))
    (define-key map [(alt meta i)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-I)))
    (define-key map [(alt meta j)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-J)))
    (define-key map [(alt meta k)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-K)))
    (define-key map [(alt meta l)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-L)))
    (define-key map [(alt meta m)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-M)))
    (define-key map [(alt meta n)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-N)))
    (define-key map [(alt meta o)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-Q)))
    (define-key map [(alt meta p)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-P)))
    (define-key map [(alt meta q)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-Q)))
    (define-key map [(alt meta r)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-R)))
    (define-key map [(alt meta s)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-S)))
    (define-key map [(alt meta t)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-T)))
    (define-key map [(alt meta u)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-U)))
    (define-key map [(alt meta v)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-V)))
    (define-key map [(alt meta w)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-W)))
    (define-key map [(alt meta x)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-X)))
    (define-key map [(alt meta y)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-Y)))
    (define-key map [(alt meta z)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-Z)))

    ;; Works well enough if you use the "outside" Alt keys.

    (define-key map [(alt hyper a)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-alpha)))
    (define-key map [(alt hyper b)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-beta)))
    (define-key map [(alt hyper c)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-psi)))
    (define-key map [(alt hyper d)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-delta)))
    (define-key map [(alt hyper e)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-epsilon)))
    (define-key map [(alt hyper f)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-phi)))
    (define-key map [(alt hyper g)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-gamma)))
    (define-key map [(alt hyper h)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-theta)))
    (define-key map [(alt hyper i)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-iota)))

    (define-key map [(alt hyper k)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-kappa)))
    (define-key map [(alt hyper l)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-lambda)))
    (define-key map [(alt hyper m)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-mu)))
    (define-key map [(alt hyper n)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-nu)))
    (define-key map [(alt hyper o)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-omicron)))
    (define-key map [(alt hyper p)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-pi)))

    (define-key map [(alt hyper r)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-rho)))
    (define-key map [(alt hyper s)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-sigma)))
    (define-key map [(alt hyper t)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-tau)))
    (define-key map [(alt hyper u)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-upsilon)))

    (define-key map [(alt hyper w)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-omega)))
    (define-key map [(alt hyper x)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-xi)))
    (define-key map [(alt hyper y)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-eta)))
    (define-key map [(alt hyper z)] '(lambda () (interactive) 
(austex-fast-math-insert 'austex-zeta)))


;; alt + super

;;     (define-key map [(alt super a)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-alpha t)))))
;;     (define-key map [(alt super b)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-beta t)))))
;;     (define-key map [(alt super c)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-psi t)))))
;;     (define-key map [(alt super d)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-delta t)))))
;;     (define-key map [(alt super e)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-epsilon t)))))
;;     (define-key map [(alt super f)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-phi t)))))
;;     (define-key map [(alt super g)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-gamma t)))))
;;     (define-key map [(alt super h)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-theta t)))))
;;     (define-key map [(alt super i)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-iota t)))))

;;     (define-key map [(alt super k)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-kappa t)))))
;;     (define-key map [(alt super l)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-lambda t)))))
;;     (define-key map [(alt super m)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-mu t)))))
;;     (define-key map [(alt super n)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-nu t)))))
;;     (define-key map [(alt super o)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-omicron t)))))
;;     (define-key map [(alt super p)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-pi t)))))

;;     (define-key map [(alt super r)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-rho t)))))
;;     (define-key map [(alt super s)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-sigma t)))))
;;     (define-key map [(alt super t)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-tau t)))))
;;     (define-key map [(alt super u)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-upsilon t)))))

;;     (define-key map [(alt super w)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-omega t)))))
;;     (define-key map [(alt super x)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-xi t)))))
;;     (define-key map [(alt super y)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-eta t)))))
;;     (define-key map [(alt super z)] '(lambda () (interactive) 
(austex-fast-math-insert '(lambda () (austex-zeta t)))))

    (define-key map [(alt super a)] '(lambda () (interactive) (austex-alpha t)))
    (define-key map [(alt super b)] '(lambda () (interactive) (austex-beta t)))
    (define-key map [(alt super c)] '(lambda () (interactive) (austex-psi t)))
    (define-key map [(alt super d)] '(lambda () (interactive) (austex-delta t)))
    (define-key map [(alt super e)] '(lambda () (interactive) (austex-epsilon 
t)))
    (define-key map [(alt super f)] '(lambda () (interactive) (austex-phi t)))
    (define-key map [(alt super g)] '(lambda () (interactive) (austex-gamma t)))
    (define-key map [(alt super h)] '(lambda () (interactive) (austex-theta t)))
    (define-key map [(alt super i)] '(lambda () (interactive) (austex-iota t)))

    (define-key map [(alt super k)] '(lambda () (interactive) (austex-kappa t)))
    (define-key map [(alt super l)] '(lambda () (interactive) (austex-lambda 
t)))
    (define-key map [(alt super m)] '(lambda () (interactive) (austex-mu t)))
    (define-key map [(alt super n)] '(lambda () (interactive) (austex-nu t)))
    (define-key map [(alt super o)] '(lambda () (interactive) (austex-omicron 
t)))
    (define-key map [(alt super p)] '(lambda () (interactive) (austex-pi t)))

    (define-key map [(alt super r)] '(lambda () (interactive) (austex-rho t)))
    (define-key map [(alt super s)] '(lambda () (interactive) (austex-sigma t)))
    (define-key map [(alt super t)] '(lambda () (interactive) (austex-tau t)))
    (define-key map [(alt super u)] '(lambda () (interactive) (austex-upsilon 
t)))

    (define-key map [(alt super w)] '(lambda () (interactive) (austex-omega t)))
    (define-key map [(alt super x)] '(lambda () (interactive) (austex-xi t)))
    (define-key map [(alt super y)] '(lambda () (interactive) (austex-eta t)))
    (define-key map [(alt super z)] '(lambda () (interactive) (austex-zeta t)))

;;; Super+Meta:

    ;; Nothing here yet.

;;; Control+Meta:

    ;; Plenty here by default.

    ;; Next follow several sections of "three modifiers plus
    ;; character" bindings.

;;; Hyper+Super+Control:

    ;; Nothing here yet.

;;; Super+Control+Meta:

    ;; Nothing here yet.

;;; Control x prefix:

    ;; this overrides the standard behavior for this key sequence
    (define-key map "\C-xri" 'austex-insert-register)

;;; Control . prefix:

    (define-key map [?\C-.?a] '(lambda () (interactive) (austex-insert-register 
(string-to-char "a"))))
    (define-key map [?\C-.?b] '(lambda () (interactive) (austex-insert-register 
(string-to-char "b"))))
    (define-key map [?\C-.?c] '(lambda () (interactive) (austex-insert-register 
(string-to-char "c"))))
    (define-key map [?\C-.?d] '(lambda () (interactive) (austex-insert-register 
(string-to-char "d"))))
    (define-key map [?\C-.?e] '(lambda () (interactive) (austex-insert-register 
(string-to-char "e"))))
    (define-key map [?\C-.?f] '(lambda () (interactive) (austex-insert-register 
(string-to-char "f"))))
    (define-key map [?\C-.?g] '(lambda () (interactive) (austex-insert-register 
(string-to-char "g"))))
    (define-key map [?\C-.?h] '(lambda () (interactive) (austex-insert-register 
(string-to-char "h"))))
    (define-key map [?\C-.?i] '(lambda () (interactive) (austex-insert-register 
(string-to-char "i"))))
    (define-key map [?\C-.?j] '(lambda () (interactive) (austex-insert-register 
(string-to-char "j"))))
    (define-key map [?\C-.?k] '(lambda () (interactive) (austex-insert-register 
(string-to-char "k"))))
    (define-key map [?\C-.?l] '(lambda () (interactive) (austex-insert-register 
(string-to-char "l"))))
    (define-key map [?\C-.?m] '(lambda () (interactive) (austex-insert-register 
(string-to-char "m"))))
    (define-key map [?\C-.?n] '(lambda () (interactive) (austex-insert-register 
(string-to-char "n"))))
    (define-key map [?\C-.?o] '(lambda () (interactive) (austex-insert-register 
(string-to-char "o"))))
    (define-key map [?\C-.?p] '(lambda () (interactive) (austex-insert-register 
(string-to-char "p"))))
    (define-key map [?\C-.?q] '(lambda () (interactive) (austex-insert-register 
(string-to-char "q"))))
    (define-key map [?\C-.?r] '(lambda () (interactive) (austex-insert-register 
(string-to-char "r"))))
    (define-key map [?\C-.?s] '(lambda () (interactive) (austex-insert-register 
(string-to-char "s"))))
    (define-key map [?\C-.?t] '(lambda () (interactive) (austex-insert-register 
(string-to-char "t"))))
    (define-key map [?\C-.?u] '(lambda () (interactive) (austex-insert-register 
(string-to-char "u"))))
    (define-key map [?\C-.?v] '(lambda () (interactive) (austex-insert-register 
(string-to-char "v"))))
    (define-key map [?\C-.?w] '(lambda () (interactive) (austex-insert-register 
(string-to-char "w"))))
    (define-key map [?\C-.?x] '(lambda () (interactive) (austex-insert-register 
(string-to-char "x"))))
    (define-key map [?\C-.?y] '(lambda () (interactive) (austex-insert-register 
(string-to-char "y"))))
    (define-key map [?\C-.?z] '(lambda () (interactive) (austex-insert-register 
(string-to-char "z"))))

;;; Control , prefix:

    ;; faster copying to register

    ;; (copy-rectangle-to-register register start end &optional
    ;; delete-flag)

    (define-key map [?\C-,?a] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "a") ow)))
    (define-key map [?\C-,?b] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "b") ow)))
    (define-key map [?\C-,?c] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "c") ow)))
    (define-key map [?\C-,?d] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "d") ow)))
    (define-key map [?\C-,?e] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "e") ow)))
    (define-key map [?\C-,?f] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "f") ow)))
    (define-key map [?\C-,?g] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "g") ow)))
    (define-key map [?\C-,?h] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "h") ow)))
    (define-key map [?\C-,?i] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "i") ow)))
    (define-key map [?\C-,?j] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "j") ow)))
    (define-key map [?\C-,?k] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "k") ow)))
    (define-key map [?\C-,?l] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "l") ow)))
    (define-key map [?\C-,?m] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "m") ow)))
    (define-key map [?\C-,?n] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "n") ow)))
    (define-key map [?\C-,?o] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "o") ow)))
    (define-key map [?\C-,?p] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "p") ow)))
    (define-key map [?\C-,?q] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "q") ow)))
    (define-key map [?\C-,?r] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "r") ow)))
    (define-key map [?\C-,?s] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "s") ow)))
    (define-key map [?\C-,?t] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "t") ow)))
    (define-key map [?\C-,?u] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "u") ow)))
    (define-key map [?\C-,?v] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "v") ow)))
    (define-key map [?\C-,?w] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "w") ow)))
    (define-key map [?\C-,?x] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "x") ow)))
    (define-key map [?\C-,?y] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "y") ow)))
    (define-key map [?\C-,?z] '(lambda (&optional ow) (interactive "P") 
(austex-copy-rectangle-to-register (string-to-char "z") ow)))

;;; Control ' prefix:

    ;; Miscellaneous stuff (add things here as needed).

    (define-key map [?\C-\'?'] '(lambda () (interactive) (yow t)))

;;; Control ; prefix:

    ;; Miscellaneous stuff (add things here as needed).
    
    ;; Mainly for commands that are supposed to take place in the
    ;; "math mode" parts of a latex buffer.

    ;; These two are also duplicated in the Latin 1 section above,
    ;; where they should be even faster to execute.
    (define-key map [?\C-\;?a] 'austex-beginning-of-math)
    (define-key map [?\C-\;?e] 'austex-end-of-math)

    ;; `austex-next-bracket' is another alternate name for the same
    ;; sort of function, I think.  The question now is whether any of
    ;; these functions work the way they should.
    (define-key map [?\C-\;?n] 'austex-next-field)
    (define-key map [?\C-\;?p] 'austex-previous-field)
    ;; How to make this function behave better when there are equality
    ;; operators inside of the terms that this set of equations is
    ;; talking about (e.g. "P(X=0)")?  Maybe something sort of like
    ;; ispell to select which comparison operators to transform?  That
    ;; would be reasonable.  Some kind of parenthesis counting would
    ;; be sufficient to deal with these examples from probability.
    (define-key map [?\C-\;?r] 
'austex-turn-current-equation-into-equation-array)
    (define-key map [?\C-\;?\;] 'austex-brackets)        ; see below

    map)
  "Keymap for AusTeX minor mode.")

;; OK! we're finally done defining `austex-mode-map'!

;;; Minor mode:

(define-minor-mode austex-mode
  "Toggle AusTeX minor mode.
With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode.

AusTeX mode provides many useful LaTeX functions and key bindings."
  :init-value nil
  :lighter " ATX")

;;; Hacks:

;; This is a section for code that is used to maintain this file.

;; I think it is a little bit strange that single-semicolon comments
;; are not sent to the `comment-column' by TAB when there are other
;; things on the line.  This accomplishes the desired end-result.

(defun force-lisp-indent ()
  "Move comments on this line to comment column.
Unlike with `lisp-indent-line', this effect is accomplished even
when there is other text on the line."
  (interactive)
  (goto-char (line-beginning-position))
  (search-forward-regexp " +\\(;[^\n]*\\)" (line-end-position) t)
  (let ((comment (match-string 1)))
    (replace-match "")
    (goto-char (line-beginning-position))
    (let ((count comment-column))
      (while (looking-at "[^\n]")
        (forward-char 1)
        (decf count))
      (insert-char (string-to-char " ") count)
      (insert comment))))

(defun insert-over-alphabet (&rest strings)
  "Insert string with the letters of the alphabet substituted in useful places.
For example

 (insert-over-alphabet  \"\\n(define-key map [?\\\\C-,?\" \"] '(lambda () 
(interactive) 
                                 (austex-copy-rectangle-to-register 
                                 (string-to-char \" \"))))\")

will insert the bindings for the \\C-, used in this package."
  (dolist (elt (string-to-list "abcdefghijklmnopqrstuvwxyz"))
    (let ((letter (char-to-string elt))
          result)
      (dolist (string (butlast strings 1))
        (setq result (concat result (concat string letter))))
      (insert result (car (last strings))))))

;; Local Variables:
;; mode:Emacs-Lisp
;; comment-column:70
;; End:

(provide 'austex-bindings)

;;; End of austex-bindings.el





reply via email to

[Prev in Thread] Current Thread [Next in Thread]