comparison lisp/mail/mailabbrev.el @ 717:950a63133bc4

*** empty log message ***
author Roland McGrath <roland@gnu.org>
date Mon, 15 Jun 1992 21:06:57 +0000
parents 4c64c671426f
children 203c23c9f22c
comparison
equal deleted inserted replaced
716:f11e7af7c0d9 717:950a63133bc4
1 ;;; ??? We must get papers for this or delete it. 1 ;;; ??? We must get papers for this or delete it.
2 ;;; mailabbrev.el --- abbrev-expansion of mail aliases. 2 ;;; Abbrev-expansion of mail aliases.
3
4 ;;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc. 3 ;;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
5 ;;; Created: 19 oct 90, Jamie Zawinski <jwz@lucid.com> 4 ;;; Created: 19 oct 90, Jamie Zawinski <jwz@lucid.com>
6 ;;; Modified: 5 apr 92, Roland McGrath <roland@gnu.ai.mit.edu> 5 ;;; Modified: 5 apr 92, Roland McGrath <roland@gnu.ai.mit.edu>
7 ;;; Last change 22-apr-92. jwz 6 ;;; Last change 13-jun-92. jwz
8 7
9 ;;; This file is part of GNU Emacs. 8 ;;; This file is part of GNU Emacs.
10 9
11 ;;; GNU Emacs is free software; you can redistribute it and/or modify 10 ;;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;;; it under the terms of the GNU General Public License as published by 11 ;;; it under the terms of the GNU General Public License as published by
13 ;;; the Free Software Foundation; either version 1, or (at your option) 12 ;;; the Free Software Foundation; either version 2, or (at your option)
14 ;;; any later version. 13 ;;; any later version.
15 14
16 ;;; GNU Emacs is distributed in the hope that it will be useful, 15 ;;; GNU Emacs is distributed in the hope that it will be useful,
17 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
308 (mapatoms (function mail-resolve-all-aliases-1) mail-aliases)) 307 (mapatoms (function mail-resolve-all-aliases-1) mail-aliases))
309 (setq mail-abbrev-aliases-need-to-be-resolved nil) 308 (setq mail-abbrev-aliases-need-to-be-resolved nil)
310 ;; (message "Resolving mail aliases... done.") 309 ;; (message "Resolving mail aliases... done.")
311 ))) 310 )))
312 311
313 (defun mail-resolve-all-aliases-1 (sym) 312 (defun mail-resolve-all-aliases-1 (sym &optional so-far)
313 (if (memq sym so-far)
314 (error "mail alias loop detected: %s"
315 (mapconcat 'symbol-name (cons sym so-far) " <- ")))
314 (let ((definition (and (boundp sym) (symbol-value sym)))) 316 (let ((definition (and (boundp sym) (symbol-value sym))))
315 (if definition 317 (if definition
316 (let ((result '()) 318 (let ((result '())
317 (start 0)) 319 (start 0))
318 (while start 320 (while start
320 (setq result (cons (substring definition start end) result) 322 (setq result (cons (substring definition start end) result)
321 start (and end (match-end 0))))) 323 start (and end (match-end 0)))))
322 (setq definition 324 (setq definition
323 (mapconcat (function (lambda (x) 325 (mapconcat (function (lambda (x)
324 (or (mail-resolve-all-aliases-1 326 (or (mail-resolve-all-aliases-1
325 (intern-soft x mail-aliases)) 327 (intern-soft x mail-aliases)
328 (cons sym so-far))
326 x))) 329 x)))
327 (nreverse result) 330 (nreverse result)
328 mail-alias-separator-string)) 331 mail-alias-separator-string))
329 (set sym definition)))) 332 (set sym definition))))
330 (symbol-value sym)) 333 (symbol-value sym))
457 ;; abbrev expansion. 460 ;; abbrev expansion.
458 ;; - Then we call expand-abbrev again, recursively, to do the abbrev 461 ;; - Then we call expand-abbrev again, recursively, to do the abbrev
459 ;; expansion with the above syntax table. 462 ;; expansion with the above syntax table.
460 ;; - Then we do a trick which tells the expand-abbrev frame which 463 ;; - Then we do a trick which tells the expand-abbrev frame which
461 ;; invoked us to not continue (and thus not expand twice.) 464 ;; invoked us to not continue (and thus not expand twice.)
465 ;; This means that any abbrev expansion will happen as a result
466 ;; of this function's call to expand-abbrev, and not as a result
467 ;; of the call to expand-abbrev which invoked *us*.
462 ;; - Then we set the syntax table to mail-mode-header-syntax-table, 468 ;; - Then we set the syntax table to mail-mode-header-syntax-table,
463 ;; which doesn't have anything to do with abbrev expansion, but 469 ;; which doesn't have anything to do with abbrev expansion, but
464 ;; is just for the user's convenience (see its doc string.) 470 ;; is just for the user's convenience (see its doc string.)
465 ;; 471 ;;
466 (setq local-abbrev-table mail-aliases) 472 (setq local-abbrev-table mail-aliases)
467 ;; If the character just typed was non-alpha-symbol-syntax, then don't 473 ;; If the character just typed was non-alpha-symbol-syntax, then don't
468 ;; expand the abbrev now (that is, don't expand when the user types -.) 474 ;; expand the abbrev now (that is, don't expand when the user types -.)
469 (or (= (char-syntax last-command-char) ?_) 475 ;; Check the character's syntax in the mail-mode-header-syntax-table.
470 (let ((pre-abbrev-expand-hook nil)) ; that's us; don't loop 476 (set-syntax-table mail-mode-header-syntax-table)
477 (or (eq (char-syntax last-command-char) ?_)
478 (let ((pre-abbrev-expand-hook nil)) ; That's us; don't loop.
479 ;; Use this table so that abbrevs can have hyphens in them.
471 (set-syntax-table mail-abbrev-syntax-table) 480 (set-syntax-table mail-abbrev-syntax-table)
472 (expand-abbrev))) 481 (expand-abbrev)
473 (setq abbrev-start-location (point) ; this is the trick 482 ;; Now set it back to what it was before.
483 (set-syntax-table mail-mode-header-syntax-table)))
484 (setq abbrev-start-location (point) ; This is the trick.
474 abbrev-start-location-buffer (current-buffer)) 485 abbrev-start-location-buffer (current-buffer))
475 ;; and do this just because.
476 (set-syntax-table mail-mode-header-syntax-table)
477 ))) 486 )))
478 487
479 ;;; utilities 488 ;;; utilities
480 489
481 (defun merge-mail-aliases (file) 490 (defun merge-mail-aliases (file)
513 522
514 (defun abbrev-hacking-next-line (&optional arg) 523 (defun abbrev-hacking-next-line (&optional arg)
515 "Just like `next-line' (\\[next-line]) but expands abbrevs when at \ 524 "Just like `next-line' (\\[next-line]) but expands abbrevs when at \
516 end of line." 525 end of line."
517 (interactive "p") 526 (interactive "p")
518 (if (looking-at "[ \t]*\n") (sendmail-pre-abbrev-expand-hook)) 527 (if (looking-at "[ \t]*\n") (expand-abbrev))
528 (setq this-command 'next-line)
519 (next-line arg)) 529 (next-line arg))
520 530
521 (defun abbrev-hacking-end-of-buffer (&optional arg) 531 (defun abbrev-hacking-end-of-buffer (&optional arg)
522 "Just like `end-of-buffer' (\\[end-of-buffer]) but expands abbrevs when at \ 532 "Just like `end-of-buffer' (\\[end-of-buffer]) but expands abbrevs when at \
523 end of line." 533 end of line."
524 (interactive "P") 534 (interactive "P")
525 (if (looking-at "[ \t]*\n") (sendmail-pre-abbrev-expand-hook)) 535 (if (looking-at "[ \t]*\n") (expand-abbrev))
536 (setq this-command 'end-of-buffer)
526 (end-of-buffer arg)) 537 (end-of-buffer arg))
527 538
528 (define-key mail-mode-map "\C-c\C-a" 'mail-interactive-insert-alias) 539 (define-key mail-mode-map "\C-c\C-a" 'mail-interactive-insert-alias)
529 540
530 ;;(define-key mail-mode-map "\C-n" 'abbrev-hacking-next-line) 541 ;;(define-key mail-mode-map "\C-n" 'abbrev-hacking-next-line)
538 ;;; All of the Emacs18 stuff is isolated down here so that it will be 549 ;;; All of the Emacs18 stuff is isolated down here so that it will be
539 ;;; easy to delete once v18 finally bites the dust. 550 ;;; easy to delete once v18 finally bites the dust.
540 ;;; 551 ;;;
541 ;;; These defuns and defvars aren't inside the cond in deference to 552 ;;; These defuns and defvars aren't inside the cond in deference to
542 ;;; the intense brokenness of the v18 byte-compiler. 553 ;;; the intense brokenness of the v18 byte-compiler.
554 ;;;
555 ;;; All the code on this page is gross and hidious and awful and might
556 ;;; not even work all that well. Comfort yourself with knowing that the
557 ;;; v19 code above works wonderfully.
543 558
544 (defun sendmail-v18-self-insert-command (arg) 559 (defun sendmail-v18-self-insert-command (arg)
545 "Just like self-insert-command, but runs sendmail-pre-abbrev-expand-hook." 560 "Just like self-insert-command, but runs sendmail-pre-abbrev-expand-hook."
546 (interactive "p") 561 (interactive "p")
547 (if (not (= (char-syntax last-command-char) ?w)) 562 (if (not (eq (char-syntax last-command-char) ?w))
548 (progn 563 (progn
549 (sendmail-pre-abbrev-expand-hook) 564 (sendmail-pre-abbrev-expand-hook)
550 ;; Unhack expand-abbrev, so it will work right next time around. 565 ;; Unhack expand-abbrev, so it will work right next time around.
551 (setq abbrev-start-location nil))) 566 (setq abbrev-start-location nil)))
552 (let ((abbrev-mode nil)) 567 ;; this is gross and wasteful.
568 (let ((abbrev-mode (if (mail-abbrev-in-expansion-header-p)
569 nil
570 abbrev-mode)))
553 (self-insert-command arg))) 571 (self-insert-command arg)))
572
573 (defun abbrev-hacking-next-line-v18 (arg)
574 (if (looking-at "[ \t]*\n") (sendmail-pre-abbrev-expand-hook))
575 (setq this-command 'next-line)
576 (next-line arg))
577
578 (defun abbrev-hacking-end-of-buffer-v18 (arg)
579 (if (looking-at "[ \t]*\n") (sendmail-pre-abbrev-expand-hook))
580 (setq this-command 'end-of-buffer)
581 (end-of-buffer arg))
554 582
555 (defvar mail-abbrevs-v18-map-munged nil) 583 (defvar mail-abbrevs-v18-map-munged nil)
556 584
557 (defun mail-abbrevs-v18-munge-map () 585 (defun mail-abbrevs-v18-munge-map ()
558 ;; For every key that is bound to self-insert-command in global-map, 586 ;; For every key that is bound to self-insert-command in global-map,
560 ;; We used to do this by making the mail-mode-map be a non-sparse map, 588 ;; We used to do this by making the mail-mode-map be a non-sparse map,
561 ;; but that made the esc-map be shared in such a way that making a 589 ;; but that made the esc-map be shared in such a way that making a
562 ;; local meta binding in the mail-mode-map made a *global* binding 590 ;; local meta binding in the mail-mode-map made a *global* binding
563 ;; instead. Yucko. 591 ;; instead. Yucko.
564 (let ((global-map (current-global-map)) 592 (let ((global-map (current-global-map))
593 new-bindings
565 (i 0)) 594 (i 0))
566 (while (< i 128) 595 (while (< i 128)
567 (if (eq 'self-insert-command (or (cdr (assq i mail-mode-map)) 596 (if (eq 'self-insert-command (or (cdr (assq i mail-mode-map))
568 (aref global-map i))) 597 (aref global-map i)))
569 (define-key mail-mode-map (char-to-string i) 598 (setq new-bindings
570 'sendmail-v18-self-insert-command)) 599 (cons (cons i 'sendmail-v18-self-insert-command)
571 (setq i (1+ i)))) 600 new-bindings)))
601 (setq i (1+ i)))
602 (setq mail-mode-map
603 (nconc (copy-keymap mail-mode-map) (nreverse new-bindings))))
572 (setq mail-abbrevs-v18-map-munged t)) 604 (setq mail-abbrevs-v18-map-munged t))
573 605
574 (defun mail-aliases-setup-v18 () 606 (defun mail-aliases-setup-v18 ()
575 "Put this on `mail-setup-hook' to use mail-abbrevs." 607 "Put this on `mail-setup-hook' to use mail-abbrevs."
576 (if (and (not (vectorp mail-aliases)) 608 (if (not (eq major-mode 'mail-mode))
577 (file-exists-p (mail-abbrev-mailrc-file))) 609 nil
578 (build-mail-aliases)) 610 (or (and mail-mode-map (eq (current-local-map) mail-mode-map))
579 (or mail-abbrevs-v18-map-munged (mail-abbrevs-v18-munge-map)) 611 (error "shut 'er down clancy, she's suckin' mud"))
580 (use-local-map mail-mode-map) 612 (if (and (not (vectorp mail-aliases))
581 (abbrev-mode 1)) 613 (file-exists-p (mail-abbrev-mailrc-file)))
614 (build-mail-aliases))
615 (or mail-abbrevs-v18-map-munged (mail-abbrevs-v18-munge-map))
616 (use-local-map mail-mode-map)
617 (abbrev-mode 1)))
582 618
583 619
584 (cond ((or (string-match "^18\\." emacs-version) 620 (cond ((or (string-match "^18\\." emacs-version)
585 (and (boundp 'epoch::version) epoch::version)) 621 (and (boundp 'epoch::version) epoch::version))
586 ;; 622 ;;
602 (fset 'expand-mail-aliases 638 (fset 'expand-mail-aliases
603 (function (lambda (&rest args) 639 (function (lambda (&rest args)
604 "Obsoleted by mail-abbrevs. Does nothing." 640 "Obsoleted by mail-abbrevs. Does nothing."
605 nil))) 641 nil)))
606 ;; 642 ;;
643 ;; Redefine the abbrev-hacking functions. Yuck.
644 (fset 'abbrev-hacking-next-line
645 (function (lambda (p) (interactive "p")
646 (abbrev-hacking-next-line-v18 p))))
647 (fset 'abbrev-hacking-end-of-buffer
648 (function (lambda (p) (interactive "P")
649 (abbrev-hacking-end-of-buffer-v18 p))))
650 ;;
607 ;; Encapsulate mail-setup to do the necessary buffer initializations. 651 ;; Encapsulate mail-setup to do the necessary buffer initializations.
608 (or (fboundp 'mail-setup-v18) 652 (or (fboundp 'mail-setup-v18)
609 (fset 'mail-setup-v18 (symbol-function 'mail-setup))) 653 (fset 'mail-setup-v18 (symbol-function 'mail-setup)))
610 (fset 'mail-setup 654 (fset 'mail-setup
611 (function (lambda (&rest args) 655 (function (lambda (&rest args)
612 (mail-aliases-setup-v18) 656 (mail-aliases-setup-v18)
613 (apply 'mail-setup-v18 args)))) 657 (apply 'mail-setup-v18 args))))
658
659 ;;
660 ;; Encapsulate VM's version of mail-setup as well, if vm-mail is
661 ;; defined as a function or as an autoload.
662 (cond ((and (fboundp 'vm-mail)
663 (if (eq 'autoload (car-safe (symbol-function 'vm-mail)))
664 (load (nth 1 (symbol-function 'vm-mail)) t)
665 t))
666 (or (fboundp 'vm-mail-internal-v18)
667 (fset 'vm-mail-internal-v18
668 (symbol-function 'vm-mail-internal)))
669 (fset 'vm-mail-internal
670 (function (lambda (&rest args)
671 (mail-aliases-setup-v18)
672 (apply 'vm-mail-internal-v18 args))))))
673
674 ;; If we're being loaded from mail-setup-hook or mail-mode-hook
675 ;; as run from inside mail-setup or vm-mail-internal, then install
676 ;; right now.
677 (if (eq major-mode 'mail-mode)
678 (mail-aliases-setup-v18))
614 ) 679 )
615 680
616 (t ; v19 681 (t ; v19
617 (fmakunbound 'expand-mail-aliases))) 682 (fmakunbound 'expand-mail-aliases)))
618
619 ;;; mailabbrev.el ends here