home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cweb28.zip / cweb.el < prev    next >
Lisp/Scheme  |  1992-07-13  |  9KB  |  222 lines

  1. ;; This file contains extensions to GNU-Emacs, to wit:
  2. ; (1) some WEB-oriented functions that are also of general use
  3. ; (2) changes to the GNU-distributed TeX mode
  4. ; (3) definitions of simple WEB and CWEB modes
  5.  
  6. ; To use: Put this in your EMACS-lisp library and say (load-library "cweb")
  7. ; in your .emacs init file.
  8.  
  9. ; Contributed by Don Knuth, July 1990
  10.  
  11. ;; OK, here's part (1): some WEB-oriented functions whose main purpose is
  12. ; to maintain a stack of module names that are "pending" as you are writing
  13. ; a program. When you first think of a module that needs to be written later,
  14. ; put it into the pending list (by typing CTL-Z instead of @> after the
  15. ; name). Later you can say CTL-\ to retrieve a pending name (and if
  16. ; you want to cycle through the pending names, ESC-y after CTL-\ will
  17. ; do it, just as ESC-y works after a yank).
  18. ; After you've said CTL-\, the current region is the name just removed from
  19. ; the pending list. If you change your mind, you can put it back again by
  20. ; saying ESC-\. If you had put it into the pending list by mistake, you
  21. ; can get rid of it by using the normal CTL-W operation (kill-region).
  22. ; The following code binds the new commands to CTL-Z, CTL-\, and ESC-\
  23. ; in all modes. You may prefer other bindings, of course.
  24. ; CTL-Z is normally "suspend emacs", but it is best not used when emacs
  25. ; has its own window as it usually does nowadays; if you need the
  26. ; old CTL-Z, you might rather bind it to CTL-X CTL-Z.
  27. ; CTL-\ is normally undefined.
  28. ; ESC-\ is normally "delete space", but ESC-space DEL does that easily too.
  29.  
  30. (defvar pending-list nil
  31.  "List of strings (usually WEB module names) still pending.")
  32.  
  33. (defun into-pending-list (beg end)
  34.  "Copy region into pending-list."
  35.  (interactive "r")
  36.  (indicate-region)
  37.  (setq pending-list (cons (buffer-substring beg end) pending-list)))
  38.  
  39. (defun new-module-name-pending ()
  40.  "Insert @> to complete a module name, then put it into pending-list."
  41.  (interactive)
  42.  (insert "@>")
  43.  (push-mark)
  44.  (if (search-backward "@<" nil t)
  45.      (progn
  46.        (exchange-point-and-mark)
  47.        (into-pending-list (point) (mark))
  48.        )
  49.    (message "There's no @< to begin the module name!")))
  50. (global-set-key "\C-z" 'new-module-name-pending)
  51.  
  52. (defun pop-pending-list (arg)
  53.  "Remove first element of pending-list and insert it as current region.
  54. With argument, put point at left; otherwise point will follow the insertion.
  55. Say \\[new-yank-pop] to replace this by another element of the list.
  56. Say \\[into-pending-list] to put it back in the list."
  57.  (interactive "*P")
  58.  (if (consp pending-list)
  59.      (progn
  60.        (push-mark (point))
  61.        (insert (car pending-list))
  62.        (setq pending-list (cdr pending-list))
  63.        (if arg
  64.            (exchange-point-and-mark)))
  65.    (message "Nothing is pending.")
  66.    (setq this-command nil)))
  67. (global-set-key "\C-\\" 'pop-pending-list)
  68. (global-set-key "\M-\\" 'into-pending-list)
  69.  
  70. (defun new-yank-pop (arg)
  71.  "If previous command was \\[pop-pending-list], pop a different string;
  72. otherwise do an ordinary Meta-y."
  73.  (interactive "*p")
  74.  (if (eq last-command 'pop-pending-list)
  75.      (let (xch)
  76.        (setq xch (< (point) (mark)))
  77.        (setq pending-list (append pending-list
  78.                                  (list (buffer-substring (point) (mark)))))
  79.        (delete-region (point) (mark))
  80.        (setq this-command 'pop-pending-list)
  81.        (pop-pending-list xch))
  82.    (yank-pop arg)))
  83. (global-set-key "\M-y" 'new-yank-pop)
  84.  
  85. (defun indicate-region ()
  86.   "Bounce cursor to mark and back again"
  87.   (let ((point-save (point)))
  88.     (unwind-protect
  89.         (progn (goto-char (mark))
  90. ; The next two lines of code are controversial ---
  91. ; they seem to be the best way to do a short wait and redraw the screen with
  92. ; standard emacs primitives --- but the short wait is a "busy wait".
  93. ; On a faster machine, it would be better to install the function
  94. ; sit-for-millisecs found in sunfns.c (if not already installed)
  95. ; and to say (sit-for-millisecs 100) instead.
  96. ; On a slower machine, do the call-process only once.
  97. ; On a still slower machine, (sit-for 1) is probably best.
  98.                (call-process "echo" nil nil t)
  99.                (call-process "echo" nil nil t))
  100.       (goto-char point-save))))
  101.  
  102. ; I prefer to change the standard copy-region command to the following,
  103. ; which gives me visual feedback about what I've copied to the kill ring:
  104. (defun indicate-and-copy-region (beg end)
  105.   "Indicate current region, then copy it to the kill ring."
  106.   (interactive "r")(indicate-region)(copy-region-as-kill beg end))
  107. (global-set-key "\M-w" 'indicate-and-copy-region)
  108.  
  109. ; Here's another convenient command, bound to the usually unused ESC-".
  110. (defun ditto (arg)
  111.   "Copy ARG characters from the line above."
  112.   (interactive "*p")
  113.   (let (ch)
  114.     (while (> arg 0)
  115.       (setq temporary-goal-column (current-column))
  116.       (save-excursion
  117.         (previous-line 1)
  118.         (setq ch (following-char)))
  119.       (insert ch)
  120.       (setq arg (1- arg)))))
  121. (global-set-key "\M-\"" 'ditto)
  122.  
  123. ;; OK, here's part (2): Changes to TeX mode.
  124. ; The WEB modes below are very much like TeX mode, but some improvements were
  125. ; desirable in TeX mode:
  126. ; I made newline act as it does in indented-text mode, since this
  127. ; works nicely for both TeX and WEB (Pascal or C code).
  128. ; I made RET check for unmatched delimiters if it ends a paragraph.
  129. ; Otherwise TeX mode remains as it was before.
  130.  
  131. (setq TeX-mode-map (make-sparse-keymap))
  132. (define-key TeX-mode-map "\C-c\C-k" 'TeX-kill-job)
  133. (define-key TeX-mode-map "\C-c\C-l" 'TeX-recenter-output-buffer)
  134. (define-key TeX-mode-map "\C-c\C-q" 'TeX-show-print-queue)
  135. (define-key TeX-mode-map "\C-c\C-p" 'TeX-print)
  136. (define-key TeX-mode-map "\"" 'TeX-insert-quote)
  137. (define-key TeX-mode-map "\e}" 'up-list)
  138. (define-key TeX-mode-map "\e{" 'TeX-insert-braces)
  139. (define-key TeX-mode-map "\C-c\C-r" 'TeX-region)
  140. (define-key TeX-mode-map "\C-c\C-b" 'TeX-buffer)
  141. (define-key TeX-mode-map "\C-c\C-f" 'TeX-close-LaTeX-block)
  142. (define-key TeX-mode-map "\r" 'TeX-newline)
  143. (define-key TeX-mode-map "\t" 'indent-relative)
  144. (setq TeX-mode-hook '(lambda ()
  145.   (make-local-variable 'indent-line-function)
  146.   (setq indent-line-function 'indent-relative-maybe)))
  147.  
  148. (defun TeX-newline (arg)
  149. "If previous character is newline and no ARG, check for unbalanced braces
  150. and/or dollar signs in previous paragraph. If ARG is \\[universal-argument],
  151. do a single newline; otherwise do ordinary newline."
  152.  (interactive "*P")
  153.  (if (and (eq (preceding-char) ?\n) (not arg))
  154.      (TeX-check-paragraph)
  155.    (if (listp arg)
  156.        (newline)
  157.      (newline arg))))
  158.  
  159. (defun TeX-check-paragraph ()
  160. "Insert a newline following a newline, breaking a paragraph for TeX.
  161. Check for mismatched delimiters in paragraph being terminated."
  162.   (interactive)
  163.   (if (TeX-validate-paragraph
  164.            (save-excursion
  165.              (search-backward "\n\n" nil 'move)
  166.              (point))
  167.            (point))
  168.       (insert ?\n)
  169.     (insert ?\n)
  170.     (error "Mismatched delimiters in that paragraph?")))
  171.  
  172. ;; and now, part (3): WEB and CWEB modes.
  173. ; These are like plain TeX mode except that the automatic conversion of
  174. ; " to `` or '' is disabled. (Personally I never liked that feature anyway,
  175. ; since it's easy to get used to typing `` and ''. In WEB modes, the
  176. ; feature soon becomes intolerable, unless you never use string constants!)
  177. ; Another thing distinguishing WEB mode from TeX is ESC-p and ESC-n, to
  178. ; move to previous or next module. These keys are usually unbound, except
  179. ; when processing email.
  180.  
  181. (defun forward-module (arg)
  182. "Advance past next WEB module beginning; with ARG, repeat ARG times."
  183.  (interactive "p")
  184.  (move-to-module arg))
  185. (defun backward-module (arg)
  186. "Advance to previous WEB module beginning; with ARG, repeat ARG times."
  187.  (interactive "p")
  188.  (move-to-module (- arg)))
  189. (defun move-to-module (arg)
  190.  (while (> arg 0)
  191.    (re-search-forward "@ \\|@\\*\\|@\n")
  192.    (setq arg (1- arg)))
  193.  (while (< arg 0)
  194.    (re-search-backward "@ \\|@\\*\\|@\n")
  195.    (setq arg (1+ arg))))
  196.  
  197. (defun web-mode ()
  198.   "Major mode like TeX mode plus \\[forward-module] and \\[backward-module]
  199. for relative module movement. The automatic \" feature is disabled."
  200.   (interactive)
  201.   (plain-tex-mode)
  202.   (local-set-key "\M-n" 'forward-module)
  203.   (local-set-key "\M-p" 'backward-module)
  204.   (local-set-key "\"" 'self-insert-command)
  205.   (setq mode-name "WEB")
  206.   (setq major-mode 'web-mode)
  207.   (run-hooks 'web-mode-hook))
  208. (setq auto-mode-alist (cons '("\\.web$" . web-mode) auto-mode-alist))
  209.  
  210. (defun cweb-mode ()
  211.   "Major mode like TeX mode plus \\[forward-module] and \\[backward-module]
  212. for relative module movement. The automatic \" feature is disabled."
  213.   (interactive)
  214.   (plain-tex-mode)
  215.   (local-set-key "\M-n" 'forward-module)
  216.   (local-set-key "\M-p" 'backward-module)
  217.   (local-set-key "\"" 'self-insert-command)
  218.   (setq mode-name "CWEB")
  219.   (setq major-mode 'cweb-mode)
  220.   (run-hooks 'cweb-mode-hook))
  221. (setq auto-mode-alist (cons '("\\.w$" . cweb-mode) auto-mode-alist))
  222.