home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / packages / minibufmem.el < prev    next >
Encoding:
Text File  |  1990-07-22  |  6.9 KB  |  192 lines

  1. ;From ark1!uakari.primate.wisc.edu!samsung!uunet!mailrus!cornell!bard Tue Mar 27 09:11:27 1990
  2. ;Article 1635 of comp.emacs:
  3. ;Path: ark1!uakari.primate.wisc.edu!samsung!uunet!mailrus!cornell!bard
  4. ;>From bard@brigid.cs.cornell.edu (Bard Bloom)
  5. ;Newsgroups: comp.emacs
  6. ;Subject: minibuffer-memory
  7. ;Message-ID: <39027@cornell.UUCP>
  8. ;Date: 24 Mar 90 18:24:47 GMT
  9. ;References: <120@cvbnetPrime.COM> <640015@hpcvca.CV.HP.COM>
  10. ;Sender: nobody@cornell.UUCP
  11. ;Reply-To: bard@cs.cornell.edu (Bard Bloom)
  12. ;Organization: Cornell Univ. CS Dept, Ithaca NY
  13. ;Lines: 175
  14. ;
  15. ;Various people have been asking for a package which remembers previous
  16. ;strings that have been typed in the minibuffer.  Here's mine.  It's a bit
  17. ;stale (I wrote it a couple years ago, intending to polish it some before 
  18. ;I distributed it, and I never did.) 
  19. ;
  20. ;Bug reports and enhancements welcome.  In particular, I'd like a better way
  21. ;of changing commands in all minibuffer keymaps. Flames will be responded to
  22. ;with a large chunk of m-x flame (highly enhanced) output.
  23. ;
  24. ;Bard Bloom
  25. ;bard@cs.cornell.edu
  26. ;Asst. Professor
  27. ;Department of Computer Science
  28. ;Cornell University
  29. ;Ithaca, NY 14853
  30. ;607/255-9211
  31.  
  32. ;; minibuf-mem.el -- memory for most minibuffer commands
  33. ;; Copyright (C) Bard Bloom, March 1990
  34.  
  35. ;; This file is not yet part of GNU Emacs.
  36.  
  37. ;; GNU Emacs is distributed in the hope that it will be useful,
  38. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  39. ;; accepts responsibility to anyone for the consequences of using it
  40. ;; or for whether it serves any particular purpose or works at all,
  41. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  42. ;; License for full details.
  43.  
  44. ;; Everyone is granted permission to copy, modify and redistribute
  45. ;; GNU Emacs, but only under the conditions described in the
  46. ;; GNU Emacs General Public License.   A copy of this license is
  47. ;; supposed to have been given to you along with GNU Emacs so you
  48. ;; can know your rights and responsibilities.  It should be in a
  49. ;; file named COPYING.  Among other things, the copyright notice
  50. ;; and this notice must be preserved on all copies.
  51.  
  52. ;; This gives GNU Emacs a simple retyping mechanism.  If you enter a string
  53. ;; in a minibuffer command (see caveats below), it will remember it in a list.
  54. ;; In minibuffers, the commands c-p and c-n move up and down in that list.
  55. ;; (The commands m-p and m-n are bound to previous-line and next-line.)
  56. ;; 
  57. ;; If you type the same string repeatedly, the minibuffer memory mechanism
  58. ;; does not remember it.  That is, if the last three strings you entered
  59. ;; were A, B, and C, and you use the memory mechanism to call up the B and use it,
  60. ;; the last three strings remembered are still A, B, and C (rather than A, B, C, B).
  61. ;; The variable minibuffer-search-depth controls this behavior; it is initially
  62. ;; 4, saying that it doesn't duplicate the last four strings.
  63. ;;
  64. ;; This works by rebinding some keys.  There are a lot of minibuffer maps, and
  65. ;; we have to rebind keys in all of them.  They are listed in the 
  66. ;; variable known-minibuffers (which is a list of keymaps).   There are
  67. ;; functions define-in-minibuffers and substitute-in-minibuffers, which 
  68. ;; allow redefinition of commands in all minibuffers at once.
  69. ;;
  70. ;; The list of remembered strings grows without bounds.  I've never had a problem with
  71. ;; it getting too long.   The strings you type in minibuffers are generally pretty
  72. ;; short.
  73. ;;
  74.  
  75.  
  76. (require 'cl)
  77.  
  78. (defvar minibuffer-strings '()
  79.   "A list of strings that have been entered into minibuffers.
  80. For minibuffer-previous-string, minibuffer-next-string, and friends.")
  81.  
  82. (defvar known-minibuffers
  83.   (list
  84.     minibuffer-local-completion-map
  85.     minibuffer-local-map
  86.     minibuffer-local-must-match-map
  87.     minibuffer-local-ns-map
  88. ;    repeat-complex-command-map   ; seems not to work well
  89.     )
  90.   "List of things I know to be minibuffer maps.  Elements must be keymaps.")
  91.  
  92. (defun define-in-minibuffers (key value)
  93.   (mapcar (function (lambda (map) (define-key map key value)))
  94.         known-minibuffers))
  95.  
  96. (defun substitute-in-minibuffers (olddef newdef)
  97.   "Substitutes OLDDEF to NEWDEF to in all the minibuffer maps I can 
  98. think of."
  99.   (mapcar
  100.    (function (lambda (map)
  101.      (substitute-key-definition olddef newdef map)))
  102.    known-minibuffers))
  103.  
  104. (defvar minibuffer-depth -1
  105.   "(nth minibuffer-depth minibuffer-strings) returns the string to 
  106. insert next.  Setting it to -1 means that the next minibuffer-previous-string
  107. returns the most recent string; that function adds 1.")
  108.  
  109. (defvar minibuffer-search-depth 4
  110.   "*Don't save a string if it is one of the first N saved strings.")
  111.  
  112. (defun limited-member (s l &optional n)
  113.   "Return true iff S is an element of L, but one of the first N if
  114. N is present."
  115.   (let ((answer nil) (finished nil))
  116.   (while (and l (> n 0) (not finished))
  117.     (setq n (1- n))
  118.     (cond
  119.      ((equal s (car l))
  120.       (setq answer t finished t))
  121.      (t
  122.       (setq l (cdr l)))))
  123.   answer))
  124.  
  125. (defun minibuffer-save-string ()
  126.   "Prepend the contents of the current buffer -- usually the minibuffer --
  127. onto the list minibuffer-strings, for later recall.  Zeros the counter 
  128. minibuffer-depth as well."
  129.   (setq minibuffer-depth -1)
  130.   (let ((s (buffer-substring (point-min) (point-max))))
  131.     (when
  132.      (and (not (equal s ""))
  133.           (not (limited-member s minibuffer-strings
  134.                                minibuffer-search-depth)))
  135.      (setq minibuffer-strings (cons s minibuffer-strings))
  136.      )))
  137.  
  138. (defun exit-minibuffer-save ()
  139.   "Save the contents of the minibuffer, and exit"
  140.   (interactive)
  141.   (minibuffer-save-string)
  142.   (exit-minibuffer))
  143.  
  144.  
  145. (defvar minibuffer-original "" 
  146.   "What was in this minibuffer before use of history.")
  147.  
  148.  
  149. (defun minibuffer-previous-string (n)
  150.   "Replaces the contents of the current buffer (usually the minibuffer)
  151. by the Nth previous string in minibuffer-strings."
  152.   (interactive "p")
  153.   (cond
  154.    ((<= minibuffer-depth -1)
  155.     (setq minibuffer-original (buffer-string))
  156.     (setq minibuffer-no-history nil)
  157.     )) 
  158.   (setq minibuffer-depth
  159.         (min (length minibuffer-strings)
  160.              (max -1 (+ n minibuffer-depth))))
  161.   (undo-boundary)
  162.   (erase-buffer)
  163.   (cond
  164.    ((<= minibuffer-depth -1)
  165.     (insert minibuffer-original))
  166.    (t 
  167.     (insert (or (nth minibuffer-depth minibuffer-strings) "")))))
  168.  
  169.  
  170. (defun minibuffer-next-string (n)
  171.   "Replaces the contents of the current buffer (usually the minibuffer)
  172. by the N'th next string in minibuffer-strings."
  173.    (interactive "p")
  174.    (minibuffer-previous-string (- n)))
  175.  
  176. (defun get-from-minibuffer-history (n)
  177.   "RTFM.  (Read The Minibuffer, and insert what you read into the real buffer)."
  178.   (interactive "p")
  179.   (setq minibuffer-depth (- n 1))
  180.   (let ((r (read-from-minibuffer "R.T.F.M:"
  181.                 (nth minibuffer-depth minibuffer-strings)
  182.                 minibuffer-local-map)))
  183.   (insert r)))
  184.  
  185. (define-in-minibuffers "\C-p" 'minibuffer-previous-string)
  186. (define-in-minibuffers "\ep" 'previous-line)
  187. (define-in-minibuffers "\C-n" 'minibuffer-next-string)
  188. (define-in-minibuffers "\en" 'next-line)
  189. (substitute-in-minibuffers 'exit-minibuffer 'exit-minibuffer-save)
  190.  
  191.  
  192.