|
|
1.1 root 1: ;;
2: ;; copyright (C) 1987, 1988 Franz Inc, Berkeley, Ca.
3: ;;
4: ;; The software, data and information contained herein are the property
5: ;; of Franz, Inc.
6: ;;
7: ;; This file (or any derivation of it) may be distributed without
8: ;; further permission from Franz Inc. as long as:
9: ;;
10: ;; * it is not part of a product for sale,
11: ;; * no charge is made for the distribution, other than a tape
12: ;; fee, and
13: ;; * all copyright notices and this notice are preserved.
14: ;;
15: ;; If you have any comments or questions on this interface, please feel
16: ;; free to contact Franz Inc. at
17: ;; Franz Inc.
18: ;; Attn: Kevin Layer
19: ;; 1995 University Ave
20: ;; Suite 275
21: ;; Berkeley, CA 94704
22: ;; (415) 548-3600
23: ;; or
24: ;; emacs-info%[email protected]
25: ;; ucbvax!franz!emacs-info
26: ;;
27:
28: ;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
29: ;;
30: ;; This file is derived from part of GNU Emacs.
31: ;;
32: ;; GNU Emacs is distributed in the hope that it will be useful,
33: ;; but WITHOUT ANY WARRANTY. No author or distributor
34: ;; accepts responsibility to anyone for the consequences of using it
35: ;; or for whether it serves any particular purpose or works at all,
36: ;; unless he says so in writing. Refer to the GNU Emacs General Public
37: ;; License for full details.
38: ;;
39: ;; Everyone is granted permission to copy, modify and redistribute
40: ;; GNU Emacs, but only under the conditions described in the
41: ;; GNU Emacs General Public License. A copy of this license is
42: ;; supposed to have been given to you along with GNU Emacs so you
43: ;; can know your rights and responsibilities. It should be in a
44: ;; file named COPYING. Among other things, the copyright notice
45: ;; and this notice must be preserved on all copies.
46:
47: ;; $Header: ring.el,v 1.8 88/07/15 18:32:33 layer Exp $
48:
49: ;; This code is very similar to the kill-ring implementation
50: ;; and implements the fi::subprocess input ring. Each fi::subprocess buffer
51: ;; has its own input ring.
52:
53: (defvar fi:default-input-ring-max 50
54: "*The default maximum length to which an input ring is allowed to grow.")
55:
56: (defvar fi::input-ring nil
57: "A list of previous input to a subprocess.")
58:
59: (defvar fi::input-ring-max fi:default-input-ring-max
60: "Maximum length of input ring before oldest elements are thrown away.")
61:
62: (defvar fi::input-ring-yank-pointer nil
63: "The tail of the input ring whose car is the last thing yanked.")
64:
65: (defvar fi::last-input-search-string ""
66: "Last input search string in each fi::subprocess buffer.")
67:
68: (defvar fi::last-command-was-successful-search nil
69: "Switch to indicate that last command was a successful input re-search.")
70:
71: (defun fi::input-append (string before-p)
72: (setq fi::last-command-was-successful-search nil)
73: (setcar fi::input-ring
74: (if before-p
75: (concat string (car fi::input-ring))
76: (concat (car fi::input-ring) string))))
77:
78: (defun fi::input-region (beg end)
79: "Delete text between point and mark and save in input ring.
80: This is the primitive for programs to kill text into the input ring.
81: Supply two arguments, character numbers indicating the stretch of text to
82: be killed. If the previous command was also a kill command, the text
83: killed this time appends to the text killed last time to make one entry in
84: the subprocess input ring."
85: (interactive "*r")
86: (setq fi::last-command-was-successful-search nil)
87: (fi::input-ring-save beg end)
88: (delete-region beg end))
89:
90: (defun fi::input-ring-save (beg end)
91: "Save the region on the subprocess input ring but don't kill it."
92: (interactive "r")
93: (setq fi::last-command-was-successful-search nil)
94: (if (eq last-command 'fi::input-region)
95: (fi::input-append (buffer-substring beg end) (< end beg))
96: (setq fi::input-ring (cons (buffer-substring beg end) fi::input-ring))
97: (if (> (length fi::input-ring) fi::input-ring-max)
98: (setcdr (nthcdr (1- fi::input-ring-max) fi::input-ring) nil)))
99: (setq this-command 'fi::input-region)
100: (setq fi::input-ring-yank-pointer fi::input-ring))
101:
102: (defun fi::rotate-yank-input-pointer (arg)
103: "Rotate the yanking point in the fi::subprocess input ring."
104: (interactive "p")
105: (setq fi::last-command-was-successful-search nil)
106: (let ((ring-length (length fi::input-ring))
107: (yank-ring-length (length fi::input-ring-yank-pointer)))
108: (cond
109: ((zerop ring-length)
110: (error "Fi::subprocess input ring is empty."))
111: ((< arg 0)
112: (setq arg (- ring-length (% (- arg) ring-length)))
113: (setq fi::input-ring-yank-pointer
114: (nthcdr (% (+ arg (- ring-length yank-ring-length)) ring-length)
115: fi::input-ring)))
116: (t
117: (setq fi::input-ring-yank-pointer
118: (nthcdr (% (+ arg (- ring-length yank-ring-length)) ring-length)
119: fi::input-ring))))))
120:
121: (defun fi:pop-input (&optional arg)
122: "Yank previous text from input ring. Cycle through input ring with each
123: successive invocation."
124: (interactive "*p")
125: (setq fi::last-command-was-successful-search nil)
126: (if (not (memq last-command '(fi::yank-input
127: fi:re-search-backward-input
128: fi:re-search-forward-input)))
129: (progn
130: (fi::yank-input arg)
131: (setq this-command 'fi::yank-input))
132: (progn
133: (setq this-command 'fi::yank-input)
134: (let ((before (< (point) (mark))))
135: (delete-region (point) (mark))
136: (fi::rotate-yank-input-pointer arg)
137: (set-mark (point))
138: (insert (car fi::input-ring-yank-pointer))
139: (if before (exchange-point-and-mark))))))
140:
141: (defun fi:push-input (&optional arg)
142: "Yank next text from input ring. Cycle through input ring in reverse
143: order with each successive invocation."
144: (interactive "*p")
145: (setq fi::last-command-was-successful-search nil)
146: (if (not (memq last-command '(fi::yank-input
147: fi:re-search-backward-input
148: fi:re-search-forward-input)))
149: (progn
150: (fi::yank-input (- (1- arg)))
151: (setq this-command 'fi::yank-input))
152: (progn
153: (setq this-command 'fi::yank-input)
154: (let ((before (< (point) (mark))))
155: (delete-region (point) (mark))
156: (fi::rotate-yank-input-pointer (- arg))
157: (set-mark (point))
158: (insert (car fi::input-ring-yank-pointer))
159: (if before (exchange-point-and-mark))))))
160:
161: (defun fi::yank-input (&optional arg)
162: "Reinsert the last fi::subprocess input text.
163: More precisely, reinsert the input text most recently killed OR yanked.
164: With just C-U as argument, same but put point in front (and mark at end).
165: With argument n, reinsert the nth most recent input text.
166: See also the command fi::yank-input-pop."
167: (interactive "*P")
168: (setq fi::last-command-was-successful-search nil)
169: (fi::rotate-yank-input-pointer (if (listp arg) 0
170: (if (eq arg '-) -1
171: (1- arg))))
172: (set-mark (point))
173: (insert (car fi::input-ring-yank-pointer))
174: (if (consp arg)
175: (exchange-point-and-mark)))
176:
177: (defun fi:list-input-ring (arg &optional reflect)
178: "Display contents of input ring, starting at arg. The list is displayed
179: in reverse order if called from a program and the optional second parameter
180: is non-nil."
181: (interactive "p")
182: (let* ((input-ring-for-list fi::input-ring)
183: (input-ring-max-for-list fi::input-ring-max)
184: (input-ring-yank-pointer-for-list fi::input-ring-yank-pointer)
185: (ring-length (length fi::input-ring))
186: (yank-ring-length (length fi::input-ring-yank-pointer))
187: (loops ring-length)
188: nth
189: first
190: count)
191: (if (zerop ring-length) (error "Input ring is empty."))
192: ;; We rely on (error) to exit from this function. [HW]
193: (if reflect
194: (if (= arg 1)
195: (setq arg -1)
196: (setq arg (1- arg))))
197: (cond
198: ((< arg 0)
199: (setq arg (- ring-length (% (- arg) ring-length)))
200: (setq count (1+ arg))
201: (setq nth (% (+ arg (- ring-length yank-ring-length)) ring-length)))
202: ((= arg 0)
203: (setq count 1)
204: (setq nth (% (+ arg (- ring-length yank-ring-length)) ring-length)))
205: (t
206: (setq count arg)
207: (setq arg (1- arg))
208: (setq nth (% (+ arg (- ring-length yank-ring-length)) ring-length))))
209: (setq first nth)
210: (with-output-to-temp-buffer
211: "*Input Ring*"
212: (save-excursion
213: (set-buffer standard-output)
214: (let ((lastcdr (nthcdr nth input-ring-for-list)))
215: ; GNU Emacs really needs better looping constructs. [HW]
216: (while
217: (not (cond
218: ((= loops 0)
219: t)
220: ((and (= nth (1- ring-length)) (not reflect))
221: (setq nth 0)
222: nil)
223: ((and (= nth 0) reflect)
224: (setq nth (1- ring-length))
225: nil)
226: (t
227: (setq nth (if reflect (1- nth) (1+ nth)))
228: nil)))
229: (insert (int-to-string count) " " (car lastcdr) "\n")
230: (setq lastcdr (nthcdr nth input-ring-for-list))
231: (setq count (if reflect (1- count) (1+ count)))
232: (setq loops (1- loops))
233: (cond
234: ((> count ring-length)
235: (setq count 1))
236: ((< count 1)
237: (setq count ring-length)))))))))
238:
239: (defun fi::re-search-input-ring (regexp direction)
240: "Look for input text that contains string regexp.
241: Set fi::input-ring-yank-pointer to text."
242: (let* ((ring-length (length fi::input-ring))
243: (yank-ring-length (length fi::input-ring-yank-pointer))
244: (nth (- ring-length yank-ring-length))
245: (loops ring-length)
246: (return-value nil)
247: (lastcdr (nthcdr nth fi::input-ring)))
248: (if (zerop ring-length) (error "Input ring is empty."))
249: ;; We rely on (error) to exit from this function. [HW]
250: (while
251: (not
252: (cond
253: ((= loops 0)
254: t)
255: ((string-match regexp (car lastcdr) nil)
256: (setq fi::input-ring-yank-pointer lastcdr)
257: (setq return-value t))
258: ((and (= nth (1- ring-length)) (>= direction 0))
259: (setq nth 0)
260: nil)
261: ((and (= nth 0) (< direction 0))
262: (setq nth (1- ring-length))
263: nil)
264: (t
265: (setq nth (if (< direction 0) (1- nth) (1+ nth)))
266: nil)))
267: (setq lastcdr (nthcdr nth fi::input-ring))
268: (setq loops (1- loops)))
269: (if return-value (setq fi::last-input-search-string regexp))
270: return-value))
271:
272: (defun fi:re-search-backward-input (arg regexp)
273: "Search in input ring for text that contains regexp and yank."
274: (interactive "*p\nsRE search input backward: ")
275: (if (string= regexp "") (setq regexp fi::last-input-search-string))
276: (if fi::last-command-was-successful-search
277: (fi::rotate-yank-input-pointer 1))
278: (setq fi::last-command-was-successful-search nil)
279: (if (let ((found t))
280: (while (and (> arg 0) found)
281: (setq found (fi::re-search-input-ring regexp 1))
282: (setq arg (1- arg))
283: (if (and (> arg 0) found)
284: (fi::rotate-yank-input-pointer 1)))
285: found)
286: (progn
287: (fi::yank-input-at-pointer)
288: (setq this-command 'fi:re-search-backward-input)
289: (setq fi::last-command-was-successful-search t))
290: (message "Matching string not found in input ring.")))
291:
292: (defun fi:re-search-forward-input (arg regexp)
293: "Search in input ring for text that contains regexp and yank."
294: (interactive "*p\nsRE search input forward: ")
295: (if fi::last-command-was-successful-search
296: (fi::rotate-yank-input-pointer -1))
297: (setq fi::last-command-was-successful-search nil)
298: (if (string= regexp "") (setq regexp fi::last-input-search-string))
299: (if (let ((found t))
300: (while (and (> arg 0) found)
301: (setq found (fi::re-search-input-ring regexp -1))
302: (setq arg (1- arg))
303: (if (and (> arg 0) found)
304: (fi::rotate-yank-input-pointer -1)))
305: found)
306: (progn
307: (fi::yank-input-at-pointer)
308: (setq this-command 'fi:re-search-backward-input)
309: (setq fi::last-command-was-successful-search t))
310: (message "Matching string not found in input ring.")))
311:
312: (defun fi::yank-input-at-pointer ()
313: "Yank input at current input ring pointer.
314: Used internally by fi:re-search-backward-input and fi:re-search-forward-input."
315: ;; This business of last-command does not work here since the
316: ;; `last command' was self-insert-command because of the prompt
317: ;; for a regular expression by (fi:re-search-forward-input) and
318: ;; (fi:re-search-backward-input).
319: (delete-region (process-mark (get-buffer-process (current-buffer))) (point))
320: (set-mark (point))
321: (insert (car fi::input-ring-yank-pointer)))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.