source: branches/1.10-appstore/source/cocoa-ide/hemlock/unused/archive/bufed.lisp

Last change on this file was 6569, checked in by Gary Byers, 18 years ago

Move more (currently unused, often unlikely to ever be used) stuff to an
archive directory.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1;;; -*- Log: hemlock.log; Package: Hemlock -*-
2;;;
3;;; **********************************************************************
4;;; This code was written as part of the CMU Common Lisp project at
5;;; Carnegie Mellon University, and has been placed in the public domain.
6;;;
7#+CMU (ext:file-comment
8 "$Header$")
9;;;
10;;; **********************************************************************
11;;;
12;;; This file contains Bufed (Buffer Editing) code.
13;;;
14
15(in-package :hemlock)
16
17
18
19
20;;;; Representation of existing buffers.
21
22;;; This is the array of buffers in the bufed buffer. Each element is a cons,
23;;; where the CAR is the buffer, and the CDR indicates whether the buffer
24;;; should be deleted (t deleted, nil don't).
25;;;
26(defvar *bufed-buffers* nil)
27(defvar *bufed-buffers-end* nil)
28;;;
29(defmacro bufed-buffer (x) `(car ,x))
30(defmacro bufed-buffer-deleted (x) `(cdr ,x))
31(defmacro make-bufed-buffer (buffer) `(list ,buffer))
32
33
34;;; This is the bufed buffer if it exists.
35;;;
36(defvar *bufed-buffer* nil)
37
38;;; This is the cleanup method for deleting *bufed-buffer*.
39;;;
40(defun delete-bufed-buffers (buffer)
41 (when (eq buffer *bufed-buffer*)
42 (setf *bufed-buffer* nil)
43 (setf *bufed-buffers* nil)))
44
45
46
47
48;;;; Commands.
49
50(defmode "Bufed" :major-p t
51 :documentation
52 "Bufed allows the user to quickly save, goto, delete, etc., his buffers.")
53
54(defhvar "Virtual Buffer Deletion"
55 "When set, \"Bufed Delete\" marks a buffer for deletion instead of immediately
56 deleting it."
57 :value t)
58
59(defhvar "Bufed Delete Confirm"
60 "When set, \"Bufed\" commands that actually delete buffers ask for
61 confirmation before taking action."
62 :value t)
63
64(defcommand "Bufed Delete" (p)
65 "Delete the buffer.
66 Any windows displaying this buffer will display some other buffer."
67 "Delete the buffer indicated by the current line. Any windows displaying this
68 buffer will display some other buffer."
69 (declare (ignore p))
70 (let* ((point (current-point))
71 (buf-info (array-element-from-mark point *bufed-buffers*)))
72 (if (and (not (value virtual-buffer-deletion))
73 (or (not (value bufed-delete-confirm))
74 (prompt-for-y-or-n :prompt "Delete buffer? " :default t
75 :must-exist t :default-string "Y")))
76 (delete-bufed-buffer (bufed-buffer buf-info))
77 (with-writable-buffer (*bufed-buffer*)
78 (setf (bufed-buffer-deleted buf-info) t)
79 (with-mark ((point point))
80 (setf (next-character (line-start point)) #\D))))))
81
82(defcommand "Bufed Undelete" (p)
83 "Undelete the buffer.
84 Any windows displaying this buffer will display some other buffer."
85 "Undelete the buffer. Any windows displaying this buffer will display some
86 other buffer."
87 (declare (ignore p))
88 (with-writable-buffer (*bufed-buffer*)
89 (setf (bufed-buffer-deleted (array-element-from-mark
90 (current-point) *bufed-buffers*))
91 nil)
92 (with-mark ((point (current-point)))
93 (setf (next-character (line-start point)) #\space))))
94
95(defcommand "Bufed Expunge" (p)
96 "Expunge buffers marked for deletion."
97 "Expunge buffers marked for deletion."
98 (declare (ignore p))
99 (expunge-bufed-buffers))
100
101(defcommand "Bufed Quit" (p)
102 "Kill the bufed buffer, expunging any buffer marked for deletion."
103 "Kill the bufed buffer, expunging any buffer marked for deletion."
104 (declare (ignore p))
105 (expunge-bufed-buffers)
106 (when *bufed-buffer* (delete-buffer-if-possible *bufed-buffer*)))
107
108;;; EXPUNGE-BUFED-BUFFERS deletes the marked buffers in the bufed buffer,
109;;; signalling an error if the current buffer is not the bufed buffer. This
110;;; returns t if it deletes some buffer, otherwise nil. We build a list of
111;;; buffers before deleting any because the BUFED-DELETE-HOOK moves elements
112;;; around in *bufed-buffers*.
113;;;
114(defun expunge-bufed-buffers ()
115 (unless (eq *bufed-buffer* (current-buffer))
116 (editor-error "Not in the Bufed buffer."))
117 (let (buffers)
118 (dotimes (i *bufed-buffers-end*)
119 (let ((buf-info (svref *bufed-buffers* i)))
120 (when (bufed-buffer-deleted buf-info)
121 (push (bufed-buffer buf-info) buffers))))
122 (if (and buffers
123 (or (not (value bufed-delete-confirm))
124 (prompt-for-y-or-n :prompt "Delete buffers? " :default t
125 :must-exist t :default-string "Y")))
126 (dolist (b buffers t) (delete-bufed-buffer b)))))
127
128(defun delete-bufed-buffer (buf)
129 (when (and (buffer-modified buf)
130 (prompt-for-y-or-n :prompt (list "~A is modified. Save it first? "
131 (buffer-name buf))))
132 (save-file-command nil buf))
133 (delete-buffer-if-possible buf))
134
135
136(defcommand "Bufed Goto" (p)
137 "Change to the buffer."
138 "Change to the buffer."
139 (declare (ignore p))
140 (change-to-buffer
141 (bufed-buffer (array-element-from-mark (current-point) *bufed-buffers*))))
142
143(defcommand "Bufed Goto and Quit" (p)
144 "Change to the buffer quitting Bufed.
145 This supplies a function for \"Generic Pointer Up\" which is a no-op."
146 "Change to the buffer quitting Bufed."
147 (declare (ignore p))
148 (expunge-bufed-buffers)
149 (point-to-here-command nil)
150 (change-to-buffer
151 (bufed-buffer (array-element-from-pointer-pos *bufed-buffers*
152 "No buffer on that line.")))
153 (when *bufed-buffer* (delete-buffer-if-possible *bufed-buffer*))
154 (supply-generic-pointer-up-function #'(lambda () nil)))
155
156(defcommand "Bufed Save File" (p)
157 "Save the buffer."
158 "Save the buffer."
159 (declare (ignore p))
160 (save-file-command
161 nil
162 (bufed-buffer (array-element-from-mark (current-point) *bufed-buffers*))))
163
164(defcommand "Bufed" (p)
165 "Creates a list of buffers in a buffer supporting operations such as deletion
166 and selection. If there already is a bufed buffer, just go to it."
167 "Creates a list of buffers in a buffer supporting operations such as deletion
168 and selection. If there already is a bufed buffer, just go to it."
169 (declare (ignore p))
170 (let ((buf (or *bufed-buffer*
171 (make-buffer "Bufed" :modes '("Bufed")
172 :delete-hook (list #'delete-bufed-buffers)))))
173
174 (unless *bufed-buffer*
175 (setf *bufed-buffer* buf)
176 (setf *bufed-buffers-end*
177 ;; -1 echo, -1 bufed.
178 (- (length (the list *buffer-list*)) 2))
179 (setf *bufed-buffers* (make-array *bufed-buffers-end*))
180 (setf (buffer-writable buf) t)
181 (with-output-to-mark (s (buffer-point buf))
182 (let ((i 0))
183 (do-strings (n b *buffer-names*)
184 (declare (simple-string n))
185 (unless (or (eq b *echo-area-buffer*)
186 (eq b buf))
187 (bufed-write-line b n s)
188 (setf (svref *bufed-buffers* i) (make-bufed-buffer b))
189 (incf i)))))
190 (setf (buffer-writable buf) nil)
191 (setf (buffer-modified buf) nil)
192 (let ((fields (buffer-modeline-fields *bufed-buffer*)))
193 (setf (cdr (last fields))
194 (list (or (modeline-field :bufed-cmds)
195 (make-modeline-field
196 :name :bufed-cmds :width 18
197 :function
198 #'(lambda (buffer window)
199 (declare (ignore buffer window))
200 " Type ? for help.")))))
201 (setf (buffer-modeline-fields *bufed-buffer*) fields))
202 (buffer-start (buffer-point buf)))
203 (change-to-buffer buf)))
204
205(defun bufed-write-line (buffer name s
206 &optional (buffer-pathname (buffer-pathname buffer)))
207 (let ((modified (buffer-modified buffer)))
208 (write-string (if modified " *" " ") s)
209 (if buffer-pathname
210 (format s "~A ~A~:[~50T~A~;~]~%"
211 (file-namestring buffer-pathname)
212 (directory-namestring buffer-pathname)
213 (string= (pathname-to-buffer-name buffer-pathname) name)
214 name)
215 (write-line name s))))
216
217
218(defcommand "Bufed Help" (p)
219 "Show this help."
220 "Show this help."
221 (declare (ignore p))
222 (describe-mode-command nil "Bufed"))
223
224
225
226
227;;;; Maintenance hooks.
228
229(eval-when (:compile-toplevel :execute)
230(defmacro with-bufed-point ((point buffer &optional pos) &rest body)
231 (let ((pos (or pos (gensym))))
232 `(when (and *bufed-buffers*
233 (not (eq *bufed-buffer* ,buffer))
234 (not (eq *echo-area-buffer* ,buffer)))
235 (let ((,pos (position ,buffer *bufed-buffers* :key #'car
236 :test #'eq :end *bufed-buffers-end*)))
237 (unless ,pos (error "Unknown Bufed buffer."))
238 (let ((,point (buffer-point *bufed-buffer*)))
239 (unless (line-offset (buffer-start ,point) ,pos 0)
240 (error "Bufed buffer not displayed?"))
241 (with-writable-buffer (*bufed-buffer*) ,@body))))))
242) ;eval-when
243
244
245(defun bufed-modified-hook (buffer modified)
246 (with-bufed-point (point buffer)
247 (setf (next-character (mark-after point)) (if modified #\* #\space))))
248;;;
249(add-hook buffer-modified-hook 'bufed-modified-hook)
250
251(defun bufed-make-hook (buffer)
252 (declare (ignore buffer))
253 (when *bufed-buffer* (delete-buffer-if-possible *bufed-buffer*)))
254;;;
255(add-hook make-buffer-hook 'bufed-make-hook)
256
257(defun bufed-delete-hook (buffer)
258 (with-bufed-point (point buffer pos)
259 (with-mark ((temp point :left-inserting))
260 (line-offset temp 1)
261 (delete-region (region point temp)))
262 (let ((len-1 (1- *bufed-buffers-end*)))
263 (replace *bufed-buffers* *bufed-buffers*
264 :start1 pos :end1 len-1
265 :start2 (1+ pos) :end1 *bufed-buffers-end*)
266 (setf (svref *bufed-buffers* len-1) nil)
267 (setf *bufed-buffers-end* len-1))))
268;;;
269(add-hook delete-buffer-hook 'bufed-delete-hook)
270
271(defun bufed-name-hook (buffer name)
272 (with-bufed-point (point buffer)
273 (with-mark ((temp point :left-inserting))
274 (line-offset temp 1)
275 (delete-region (region point temp)))
276 (with-output-to-mark (s point)
277 (bufed-write-line buffer name s))))
278;;;
279(add-hook buffer-name-hook 'bufed-name-hook)
280
281(defun bufed-pathname-hook (buffer pathname)
282 (with-bufed-point (point buffer)
283 (with-mark ((temp point :left-inserting))
284 (line-offset temp 1)
285 (delete-region (region point temp)))
286 (with-output-to-mark (s point)
287 (bufed-write-line buffer (buffer-name buffer) s pathname))))
288;;;
289(add-hook buffer-pathname-hook 'bufed-pathname-hook)
290
291
292
293;;;; Utilities
294
295(defun array-element-from-pointer-pos (vector &optional
296 (error-msg "Invalid line."))
297 (multiple-value-bind (x y window) (last-key-event-cursorpos)
298 (declare (ignore x window))
299 (when (>= y (length vector))
300 (editor-error error-msg))
301 (svref vector y)))
Note: See TracBrowser for help on using the repository browser.