40704aa7869ed646680a67a7f75c07dcf1643d1e
[lice.git] / buffer.lisp
blob40704aa7869ed646680a67a7f75c07dcf1643d1e
1 (declaim (optimize (debug 3)))
3 (in-package :lice)
5 (defconstant +beg+ 0)
7 (defvar *buffer-list* nil
8 "All buffers managed by lice. buffers are sorted from most recently
9 accessed to least. the CAR is the most recent buffer.")
11 (defvar *current-buffer* nil
12 "When this buffer is non-nil, it contains the current buffer. Calls
13 to `current-buffer' return this buffer. Otherwise, `current-buffer'
14 returns the current frames's current window's buffer.
16 This variable should never be set using `setq' or `setf'. Bind it with
17 `let' for as long as it needs to be set.")
19 (defvar *inhibit-read-only* nil
20 "*Non-nil means disregard read-only status of buffers or characters.
21 If the value is t, disregard `buffer-read-only' and all `read-only'
22 text properties. If the value is a list, disregard `buffer-read-only'
23 and disregard a `read-only' text property if the property value
24 is a member of the list.")
26 (defclass pstring ()
27 ((data :type string :initarg :data :accessor pstring-data)
28 (intervals :type (or null interval) :initform nil :initarg :intervals :accessor intervals))
29 (:documentation "The lice string implementation."))
31 (defmethod print-object ((obj pstring) stream)
32 (print-unreadable-object (obj stream :type t :identity t)
33 (format stream "~s" (pstring-data obj))))
35 (defun pstring-length (ps)
36 "Return the length of the string in PS"
37 (declare (type pstring ps))
38 (length (pstring-data ps)))
40 (defclass base-buffer ()
41 ((file :type (or null pathname) :initarg :file :accessor buffer-file)
42 (name :type string :initarg :name :accessor buffer-name)
43 ;; mode-line
44 (mode-line :type list :initarg :mode-line :initform nil :accessor buffer-mode-line)
45 (mode-line-string :type string :initform "" :accessor buffer-mode-line-string)
46 (modified :type boolean :initform nil :accessor buffer-modified-p)
47 (read-only :type boolean :initform nil :accessor buffer-read-only)
48 (tick :type integer :initform 0 :accessor buffer-modified-tick :documentation
49 "The buffer's tick counter. It is incremented for each change
50 in text.")
51 (display-count :type integer :initform 0 :accessor buffer-display-count :documentation
52 "The buffer's display counter. It is incremented each time it
53 is displayed in a window.")
54 (display-time :type integer :initform 0 :accessor buffer-display-time :documentation
55 "The last time the buffer was switched to in a window.")
56 (major-mode :type major-mode :initarg :major-mode :accessor buffer-major-mode)
57 (local-map :initform nil :initarg :local-map :accessor buffer-local-map :documentation
58 "The keymap local to the buffer. This overrides major mode bindings.")
59 (locals-variables :type hash-table :initform (make-hash-table) :accessor buffer-local-variables)
60 (locals :type hash-table :initform (make-hash-table) :accessor buffer-locals))
61 (:documentation "A Buffer."))
63 ;; undo structures used to record types of undo information. This is
64 ;; an alternative to the cons cells gnu emacs uses which I find
65 ;; obscure.
66 (defstruct undo-entry-insertion
67 beg end)
68 (defstruct undo-entry-delete
69 text position)
70 (defstruct undo-entry-modified
71 time)
72 (defstruct undo-entry-property
73 prop value beg end)
74 (defstruct undo-entry-apply
75 function args)
76 (defstruct undo-entry-selective
77 delta beg end function args)
78 (defstruct undo-entry-marker
79 marker distance)
81 (defclass buffer (base-buffer)
82 ((point :type marker :initarg :point :accessor buffer-point)
83 (mark :type marker :initarg :mark :accessor buffer-mark-marker)
84 ;; A string containing the raw buffer
85 (data :type (array character 1) :initarg :data :accessor buffer-data)
86 (intervals :type (or null interval) :initform nil :initarg :intervals :accessor intervals)
87 (gap-start :type integer :initarg :gap-start :accessor buffer-gap-start)
88 (gap-size :type integer :initarg :gap-size :accessor buffer-gap-size)
89 (markers :type list :initform '() :accessor buffer-markers)
90 (auto-save-modified :type integer :initform 0 :accessor buffer-auto-save-modified)
91 (modiff :type integer :initform 0 :accessor buffer-modiff)
92 ;;(syntax-table :initform *standard-syntax-table* :accessor buffer-syntax-table)
93 (undo-list :initform '() :accessor buffer-undo-list
94 :documentation "List of undo entries in current buffer.
95 Recent changes come first; older changes follow newer.
97 An entry (BEG . END) represents an insertion which begins at
98 position BEG and ends at position END.
100 An entry (TEXT . POSITION) represents the deletion of the string TEXT
101 from (abs POSITION). If POSITION is positive, point was at the front
102 of the text being deleted; if negative, point was at the end.
104 An entry (t HIGH . LOW) indicates that the buffer previously had
105 \"unmodified\" status. HIGH and LOW are the high and low 16-bit portions
106 of the visited file's modification time, as of that time. If the
107 modification time of the most recent save is different, this entry is
108 obsolete.
110 An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
111 was modified between BEG and END. PROPERTY is the property name,
112 and VALUE is the old value.
114 An entry (apply FUN-NAME . ARGS) means undo the change with
115 \(apply FUN-NAME ARGS).
117 An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo
118 in the active region. BEG and END is the range affected by this entry
119 and DELTA is the number of bytes added or deleted in that range by
120 this change.
122 An entry (MARKER . DISTANCE) indicates that the marker MARKER
123 was adjusted in position by the offset DISTANCE (an integer).
125 An entry of the form POSITION indicates that point was at the buffer
126 location given by the integer. Undoing an entry of this form places
127 point at POSITION.
129 nil marks undo boundaries. The undo command treats the changes
130 between two undo boundaries as a single step to be undone.
132 If the value of the variable is t, undo information is not recorded.
134 (:documentation "A text Buffer."))
136 (defmethod print-object ((obj buffer) stream)
137 (print-unreadable-object (obj stream :type t :identity t)
138 (format stream "~a" (buffer-name obj))))
140 (define-condition args-out-of-range (lice-condition)
141 () (:documentation "Raised when some arguments (usually relating to a
142 buffer) are out of range."))
144 (define-condition beginning-of-buffer (lice-condition)
145 () (:documentation "Raised when it is an error that the point is at
146 the beginning of the buffer."))
148 (define-condition end-of-buffer (lice-condition)
149 () (:documentation "Raised when it is an error that the point is at
150 the end of the buffer."))
152 (define-condition buffer-read-only (lice-condition)
153 () (:documentation "Raised when there is an attempt to insert into a read-only buffer."))
155 (defun mark-marker (&optional (buffer (current-buffer)))
156 "Return this buffer's mark, as a marker object.
157 Watch out! Moving this marker changes the mark position.
158 If you set the marker not to point anywhere, the buffer will have no mark."
159 ;; FIXME: marks can't be inactive ATM
160 (buffer-mark-marker buffer))
163 ;;; buffer locals
165 (defstruct buffer-local-binding
166 symbol value local-p doc-string)
168 (defvar *global-buffer-locals* (make-hash-table)
169 "The default values of buffer locals and a hash table containing all possible buffer locals")
171 (defun buffer-local-exists-p (symbol)
172 (multiple-value-bind (v b) (gethash symbol *global-buffer-locals*)
173 (declare (ignore v))
174 b))
176 (defun get-buffer-local-create (symbol default-value &optional doc-string)
177 (if (buffer-local-exists-p symbol)
178 (gethash symbol *global-buffer-locals*)
179 (setf (gethash symbol *global-buffer-locals*)
180 (make-buffer-local-binding :symbol symbol
181 :value default-value
182 :doc-string doc-string))))
184 (defmacro define-buffer-local (symbol default-value &optional doc-string)
185 "buffer locals are data hooks you can use to store values per
186 buffer. Use them when building minor and major modes. You
187 generally want to define them with this so you can create a
188 docstring for them. there is also `get-buffer-local-create'."
189 `(progn
190 (when (boundp ',symbol)
191 (warn "Symbol ~s is already bound. Existing uses of symbol will not be buffer local." ',symbol)
192 (makunbound ',symbol))
193 (define-symbol-macro ,symbol (buffer-local ',symbol))
194 (get-buffer-local-create ',symbol ,default-value ,doc-string)))
196 (defun (setf buffer-local) (value symbol)
197 "Set the value of the buffer local in the current buffer."
198 ;; create a global buffer local entry if needed.
199 (let ((global-binding (get-buffer-local-create symbol value)))
200 ;; if the symbol becomes buffer local when set or it has a buffer
201 ;; value
202 (if (or (buffer-local-binding-local-p global-binding)
203 (second (multiple-value-list
204 (gethash symbol (buffer-locals *current-buffer*)))))
205 ;; set the buffer's value
206 (setf (gethash symbol (buffer-locals *current-buffer*)) value)
207 ;; set the global value
208 (setf (buffer-local-binding-value global-binding) value))))
210 (defun buffer-local (symbol)
211 "Return the value of the buffer local symbol. If none exists
212 for the current buffer then use the global one. If that doesn't
213 exist, throw an error."
214 (multiple-value-bind (v b) (gethash symbol (buffer-locals *current-buffer*))
215 (if b
217 (multiple-value-bind (v b) (gethash symbol *global-buffer-locals*)
218 (if b
219 (buffer-local-binding-value v)
220 (error "No binding for buffer-local ~s" symbol))))))
222 (defun make-local-variable (symbol)
223 "Make VARIABLE have a separate value in the current buffer.
224 Other buffers will continue to share a common default value.
225 \(The buffer-local value of VARIABLE starts out as the same value
226 VARIABLE previously had. If VARIABLE was void, it remains void.\)
227 Return VARIABLE.
229 If the variable is already arranged to become local when set,
230 this function causes a local value to exist for this buffer,
231 just as setting the variable would do.
233 Unlike GNU/Emacs This function does not return
234 VARIABLE. See alse `(SETF MAKE-LOCAL-VARIABLE)'.
236 See also `make-variable-buffer-local' and `define-buffer-local'.
238 Do not use `make-local-variable' to make a hook variable buffer-local.
239 Instead, use `add-hook' and specify t for the LOCAL argument."
240 (setf (gethash symbol (buffer-locals *current-buffer*)) (buffer-local symbol))
241 ;; only setq and setf expand the symbol-macro properly, so we can't
242 ;; return the symbol.
243 nil)
245 (defun (setf make-local-variable) (value symbol)
246 "Make the symbol local to the current buffer like
247 `make-local-variable' and also set its value in the buffer."
248 (setf (gethash symbol (buffer-locals *current-buffer*)) value))
250 (defun make-variable-buffer-local (variable)
251 "Make VARIABLE become buffer-local whenever it is set.
252 At any time, the value for the current buffer is in effect,
253 unless the variable has never been set in this buffer,
254 in which case the default value is in effect.
255 Note that binding the variable with `let', or setting it while
256 a `let'-style binding made in this buffer is in effect,
257 does not make the variable buffer-local. Return VARIABLE.
259 In most cases it is better to use `make-local-variable',
260 which makes a variable local in just one buffer.
262 The function `default-value' gets the default value and `set-default' sets it."
263 (setf (buffer-local-binding-local-p (gethash variable *global-buffer-locals*)) t))
265 (defun default-value (symbol)
266 "Return SYMBOL's default value.
267 This is the value that is seen in buffers that do not have their own values
268 for this variable. The default value is meaningful for variables with
269 local bindings in certain buffers."
270 (buffer-local-binding-value (gethash symbol *global-buffer-locals*)))
272 (defun (setf default-value) (value symbol)
273 "Set symbol's default value to value. symbol and value are evaluated.
274 The default value is seen in buffers that do not have their own values
275 for this variable."
276 (setf (buffer-local-binding-value (gethash symbol *global-buffer-locals*)) value) )
278 (depricate set-default (setf default-value))
279 (defun set-default (symbol value)
280 "Set symbol's default value to value. symbol and value are evaluated.
281 The default value is seen in buffers that do not have their own values
282 for this variable."
283 (setf (default-value symbol) value))
285 (define-buffer-local *buffer-invisibility-spec* nil
286 "Invisibility spec of this buffer.
287 The default is t, which means that text is invisible
288 if it has a non-nil `invisible' property.
289 If the value is a list, a text character is invisible if its `invisible'
290 property is an element in that list.
291 If an element is a cons cell of the form (PROP . ELLIPSIS),
292 then characters with property value PROP are invisible,
293 and they have an ellipsis as well if ELLIPSIS is non-nil.")
295 (define-buffer-local *selective-display* nil
296 "Non-nil enables selective display.
297 An Integer N as value means display only lines
298 that start with less than n columns of space.
299 A value of t means that the character ^M makes itself and
300 all the rest of the line invisible; also, when saving the buffer
301 in a file, save the ^M as a newline.")
305 ;;; buffer related conditions
307 ;;(define-condition end-of-buffer)
310 ;;; Markers
312 (deftype marker-insertion-type () '(member :before :after))
314 (defclass marker ()
315 ((position :type integer :initform 0 :accessor marker-position)
316 (buffer :type (or buffer null) :initform nil :accessor marker-buffer)
317 (insertion-type :type marker-insertion-type :initform :after :accessor marker-insertion-type))
318 (:documentation "A Marker"))
320 (defmethod print-object ((obj marker) stream)
321 (print-unreadable-object (obj stream :type t :identity t)
322 (format stream "~a" (marker-position obj))))
324 (defgeneric ensure-number (thing)
325 (:documentation "Call this function when THING could be a number or a marker or...?"))
327 (defmethod ensure-number ((thing number))
328 thing)
330 (defmethod ensure-number ((thing marker))
331 (marker-position thing))
333 (defun copy-marker (marker &optional (type :after))
334 "Return a new marker pointing at the same place as MARKER.
335 If argument is a number, makes a new marker pointing
336 at that position in the current buffer.
337 **The optional argument TYPE specifies the insertion type of the new marker;
338 **see `marker-insertion-type'."
339 (check-type marker (or marker integer))
340 (check-type type marker-insertion-type)
341 (let ((new (make-marker)))
342 (set-marker new (ensure-number marker)
343 (if (typep marker 'marker)
344 (marker-buffer marker)
345 (current-buffer)))
346 (setf (marker-insertion-type new) type)
347 new))
349 (defun make-marker ()
350 "Return a newly allocated marker which does not point anywhere."
351 (make-instance 'marker))
353 (defun unchain-marker (marker)
354 (when (marker-buffer marker)
355 (setf (buffer-markers (marker-buffer marker))
356 (delete marker (buffer-markers (marker-buffer marker)) :key #'weak-pointer-value))))
358 (defun chain-marker (marker buffer)
359 (push (make-weak-pointer marker) (buffer-markers buffer)))
361 (defun set-marker (marker position &optional (buffer (current-buffer)))
362 ;; remove the marker from its buffer, when appropriate
363 (when (null position)
364 (unchain-marker marker)
365 (return-from set-marker marker))
366 ;; XXX handle dead buffers
368 ;; normalize pos
369 (setf (marker-position marker) (min (max position (begv buffer)) (zv buffer)))
371 ;; update buffer stuff
372 (unless (eq (marker-buffer marker) buffer)
373 (unchain-marker marker)
374 (setf (marker-buffer marker) buffer)
375 (chain-marker marker buffer))
376 marker)
378 (defun update-markers-del (buffer start size)
379 ;; FIXME: insertion-type
380 ;; First get rid of stale markers
381 (purge-markers buffer)
382 (dolist (wp (buffer-markers buffer))
383 (let ((m (weak-pointer-value wp)))
384 ;; paranoia, maybe the GC freed some stuff after the marker
385 ;; purge.
386 (when m
387 ;; markers are before the marker-position.
388 (cond ((>= (marker-position m) (+ start size))
389 (decf (marker-position m) size))
390 ((> (marker-position m) start)
391 (setf (marker-position m) start)))))))
393 (defun update-markers-ins (buffer start size)
394 ;; FIXME: insertion-type
395 ;; First get rid of stale markers
396 (purge-markers buffer)
397 (dolist (wp (buffer-markers buffer))
398 (let ((m (weak-pointer-value wp)))
399 ;; markers are before the marker-position.
400 (when (and m (> (marker-position m) start)
401 (incf (marker-position m) size))))))
403 (defun purge-markers (buffer)
404 "Remove GC'd markers."
405 (setf (buffer-markers buffer)
406 (delete-if (lambda (m)
407 (multiple-value-bind (v c) (weak-pointer-value m)
408 (declare (ignore v))
409 (not c)))
410 (buffer-markers buffer))))
415 (defun inc-buffer-tick (buffer)
416 "Increment the buffer's ticker."
417 (incf (buffer-modified-tick buffer)))
419 ;;; Some wrappers around replace
421 (defun move-subseq-left (seq from end to)
422 "Move the subseq between from and end to before TO, which is assumed to be
423 left of FROM."
424 (replace seq seq :start1 (+ to (- end from) 1) :start2 to :end2 from)
427 (defun move-subseq-right (seq from end to)
428 "Move the subseq between from and end to before TO, which is assumed to be
429 right of FROM."
430 (replace seq seq :start1 from :start2 (1+ end) :end2 to)
431 (+ from (- to end 1)))
433 (defun move-subseq (seq from end to)
434 "Destructively move the gap subseq starting at from and ending at
435 end, inclusive, to before TO."
436 (if (< to from)
437 (move-subseq-left seq from end to)
438 (move-subseq-right seq from end to)))
440 (defun fill-gap (buf)
441 "For debugging purposes. fill the gap with _'s."
442 (fill (buffer-data buf) #\_ :start (buffer-gap-start buf) :end (gap-end buf)))
444 (defun gap-move-to (buf to)
445 "A basic function to move the gap. TO is in aref coordinates and the
446 gap is positioned before TO.
448 BUFFER: ABC__DEF
449 (gap-move-to buffer 6)
450 BUFFER: ABCD__EF"
451 (setf (buffer-gap-start buf)
452 (move-subseq (buffer-data buf) (buffer-gap-start buf) (1- (gap-end buf)) to))
453 ;; for debugging purposes, we set the gap to _'s
454 (fill-gap buf))
456 (defun gap-move-to-point (buf)
457 "Move the gap to the point position in aref space.
458 ABCD___EF
461 A___BCDEF
464 (gap-move-to buf (buffer-char-to-aref buf (marker-position (buffer-point buf)))))
466 ;; ;; Move the gap to the end of the vector
467 ;; (replace data data :start1 gap-start :start2 gap-end)
468 ;; ;; open a space for the gap
469 ;; (replace data data :start1 (+ to (buffer-gap-size buf)) :start2 to)
470 ;; (setf (buffer-gap-start buf) to)))
472 (defun gap-end (buf)
473 "The end of the gap. in aref space. gap-end is the first valid
474 buffer character."
475 (declare (type buffer buf))
476 (+ (buffer-gap-start buf) (buffer-gap-size buf)))
478 (defmacro inc-aref (var buffer)
479 "increment VAR one character forward in BUFFER, avoiding the gap."
480 `(progn
481 (incf ,var)
482 (if (= (buffer-gap-start ,buffer) ,var)
483 (setf ,var (gap-end ,buffer)))))
485 (defmacro inc-both (char-var aref-var buffer)
486 `(progn
487 (inc-aref ,aref-var ,buffer)
488 (incf ,char-var)))
490 (defun aref-minus-1 (aref buffer)
491 (if (= (gap-end buffer) aref)
492 (1- (buffer-gap-start buffer))
493 (1- aref)))
495 (defmacro dec-aref (var buffer)
496 "increment VAR one character forward in BUFFER, avoiding the gap."
497 `(setf ,var (aref-minus-1 ,var ,buffer)))
499 (defmacro dec-both (char-var aref-var buffer)
500 `(progn
501 (dec-aref ,aref-var ,buffer)
502 (decf ,char-var)))
504 ;; (defun gap-close (buf)
505 ;; "Move the gap to the end of the buffer."
506 ;; (let ((gap-start (buffer-gap-start buf))
507 ;; (gap-end (gap-end buf)))
508 ;; (setf (buffer-gap-start buf) (- (length (buffer-data buf)) (buffer-gap-size buf)))
509 ;; (replace (buffer-data buf) (buffer-data buf) :start1 gap-start :start2 gap-end)))
511 (defun grow-buffer-data (buf size)
512 "Grow the buffer data array to be SIZE. SIZE must be larger than before."
513 ;; MOVITZ doesn't have adjust-array
514 ;; ;; #\_ is used for debugging to represent the gap
515 ;; (adjust-array (buffer-data buf) size :initial-element #\_ :fill-pointer t)
516 (let ((newbuf (make-array size :initial-element #\_;; :fill-pointer t
517 :element-type 'character)))
518 (replace newbuf (buffer-data buf))
519 (setf (buffer-data buf) newbuf)))
521 (defun gap-extend (buf size)
522 "Extend the gap by SIZE characters."
523 (let ((new-size (+ (length (buffer-data buf)) size))
524 (old-end (gap-end buf))
525 (old-size (buffer-size buf))
526 (data (buffer-data buf)))
527 (setf data (grow-buffer-data buf new-size))
528 (incf (buffer-gap-size buf) size)
529 (unless (= (buffer-gap-start buf) old-size)
530 (replace data data
531 :start1 (gap-end buf)
532 :start2 old-end))
533 ;; for debugging, mark the gap
534 (fill-gap buf)))
536 (defun buffer-size (buf)
537 "Return the length of the buffer not including the gap."
538 (declare (type buffer buf))
539 (- (length (buffer-data buf))
540 (buffer-gap-size buf)))
542 (defun buffer-min (buf)
543 "The beginning of the buffer in char space."
544 (declare (type buffer buf)
545 (ignore buf))
548 (defun buffer-max (buf)
549 "The end of the buffer in char space."
550 (declare (type buffer buf))
551 (buffer-size buf))
553 (defun begv (&optional (buf (current-buffer)))
554 "Position of beginning of accessible range of buffer."
555 ;; TODO: handle buffer narrowing
556 (buffer-min buf))
558 (defun begv-aref (&optional (buf (current-buffer)))
559 "aref Position of beginning of accessible range of buffer."
560 ;; TODO: handle buffer narrowing
561 (buffer-char-to-aref buf (buffer-min buf)))
563 (defun zv (&optional (buf (current-buffer)))
564 "Position of end of accessible range of buffer."
565 ;; TODO: handle buffer narrowing
566 (buffer-max buf))
568 (defun zv-aref (&optional (buf (current-buffer)))
569 "aref Position of end of accessible range of buffer."
570 ;; TODO: handle buffer narrowing
571 (buffer-char-to-aref buf (buffer-max buf)))
573 (defun point (&optional (buffer (current-buffer)))
574 "Return the point in the current buffer."
575 (marker-position (buffer-point buffer)))
577 (defun point-marker (&optional (buffer (current-buffer)))
578 "Return value of point, as a marker object."
579 (buffer-point buffer))
581 (defun point-min (&optional (buffer (current-buffer)))
582 "Return the minimum permissible value of point in the current buffer."
583 (declare (ignore buffer))
586 (defun point-max (&optional (buffer (current-buffer)))
587 "Return the maximum permissible value of point in the current buffer."
588 (buffer-size buffer))
590 (defun set-point-both (buffer char-pos aref-pos)
591 "Set point in BUFFER to CHARPOS, which corresponds to byte
592 position BYTEPOS. If the target position is
593 before an intangible character, move to an ok place."
594 (declare (ignore aref-pos))
595 ;; TODO: implement
596 (setf (marker-position (buffer-point buffer)) char-pos))
598 (defun set-point (char-pos &optional (buffer (current-buffer)))
599 (set-point-both buffer char-pos nil))
601 (defun goto-char (position &optional (buffer (current-buffer)))
602 "Set point to POSITION, a number."
603 (check-number-coerce-marker position)
604 (when (and (>= position (point-min buffer))
605 (<= position (point-max buffer)))
606 (set-point position buffer)))
608 ;; (defun buffer-char-before-point (buf p)
609 ;; "The character at the point P in buffer BUF. P is in char space."
610 ;; (declare (type buffer buf)
611 ;; (type integer p))
612 ;; (let ((aref (buffer-char-to-aref buf p)))
613 ;; (when (< aref (length (buffer-data buf)))
614 ;; (aref (buffer-data buf) aref))))
616 (defun buffer-char-after (buf p)
617 "The character at the point P in buffer BUF. P is in char space."
618 (declare (type buffer buf)
619 (type integer p))
620 (let ((aref (buffer-char-to-aref buf p)))
621 (when (and (>= aref 0)
622 (< aref (length (buffer-data buf))))
623 (aref (buffer-data buf) aref))))
625 (defun buffer-char-before (buf p)
626 (buffer-char-after buf (1- p)))
628 (defun char-after (&optional (pos (point)))
629 "Return character in current buffer at position POS.
630 ***POS is an integer or a marker.
631 ***If POS is out of range, the value is nil."
632 (buffer-char-after (current-buffer) pos))
634 (defun char-before (&optional (pos (point)))
635 "Return character in current buffer preceding position POS.
636 ***POS is an integer or a marker.
637 ***If POS is out of range, the value is nil."
638 (char-after (1- pos)))
640 (defun buffer-aref-to-char (buf idx)
641 "Translate the index into the buffer data to the index excluding the gap."
642 (declare (type buffer buf)
643 (type integer idx))
644 (if (>= idx (gap-end buf))
645 (- idx (buffer-gap-size buf))
646 idx))
648 (defun buffer-char-to-aref (buf p)
650 (declare (type buffer buf)
651 (type integer p))
652 (if (>= p (buffer-gap-start buf))
653 (+ p (buffer-gap-size buf))
656 (defun buffer-point-aref (buf)
657 "Return the buffer point in aref coordinates."
658 (buffer-char-to-aref buf (point buf)))
660 (defun buffer-fetch-char (aref buf)
661 (aref (buffer-data buf) aref))
663 (defun string-to-vector (s)
664 "Return a resizable vector containing the elements of the string s."
665 (declare (string s))
666 (make-array (length s)
667 :initial-contents s
668 :element-type 'character
669 :adjustable t))
672 (defgeneric buffer-insert (buffer object)
673 (:documentation "Insert OBJECT into BUFFER at the current point."))
675 (defmethod buffer-insert :after ((buf buffer) object)
676 "Any object insertion modifies the buffer."
677 (declare (ignore object))
678 (setf (buffer-modified-p buf) t))
680 (defmethod buffer-insert ((buf buffer) (char character))
681 "Insert a single character into buffer before point."
682 ;; Resize the gap if needed
683 (if (<= (buffer-gap-size buf) 1)
684 (gap-extend buf 100))
685 ;; Move the gap to the point
686 (unless (= (point buf) (buffer-gap-start buf))
687 (gap-move-to buf (buffer-point-aref buf)))
688 (update-markers-ins buf (point buf) 1)
689 ;; undo
690 (record-insert (point buf) 1 buf)
691 ;; set the character
692 (setf (aref (buffer-data buf) (buffer-gap-start buf)) char)
693 ;; move the gap forward
694 (incf (buffer-gap-start buf))
695 (decf (buffer-gap-size buf))
696 ;; expand the buffer intervals
697 (offset-intervals buf (point buf) 1))
699 (defmethod buffer-insert ((buf buffer) (string string))
700 ;; resize
701 (when (<= (buffer-gap-size buf) (length string))
702 (gap-extend buf (+ (length string) 100)))
703 ;; move the gap to the point
704 (unless (= (point buf) (buffer-gap-start buf))
705 (gap-move-to buf (buffer-point-aref buf)))
706 (update-markers-ins buf (point buf) (length string))
707 ;; undo
708 (record-insert (point buf) (length string) buf)
709 ;; insert chars
710 (replace (buffer-data buf) string :start1 (buffer-gap-start buf))
711 (incf (buffer-gap-start buf) (length string))
712 (decf (buffer-gap-size buf) (length string))
713 ;; expand the buffer intervals
714 (offset-intervals buf (point buf) (length string)))
716 (defmethod buffer-insert ((buf buffer) (string pstring))
717 ;; insert string
718 (buffer-insert buf (pstring-data string))
719 ;; insert properties
720 (graft-intervals-into-buffer (intervals string)
721 (point buf)
722 (pstring-length string)
726 (defgeneric insert-move-point (buffer object)
727 (:documentation "Insert OBJECT into BUFFER at the current point. Move the point
728 forward by its length."))
730 (defmethod insert-move-point ((buffer buffer) (object character))
731 (buffer-insert buffer object)
732 (incf (marker-position (buffer-point buffer))))
734 (defmethod insert-move-point ((buffer buffer) (object string))
735 (buffer-insert buffer object)
736 (incf (marker-position (buffer-point buffer)) (length object)))
738 (defmethod insert-move-point ((buffer buffer) (object pstring))
739 (buffer-insert buffer object)
740 (incf (marker-position (buffer-point buffer)) (pstring-length object)))
742 (defun insert (&rest objects)
743 "Insert the arguments, either strings or characters, at point.
744 Point and before-insertion markers move forward to end up after the
745 inserted text. Any other markers at the point of insertion remain
746 before the text."
747 (dolist (o objects)
748 (insert-move-point (current-buffer) o)))
750 (defun buffer-delete (buf p length)
751 "Deletes chars from point to point + n. If N is negative, deletes backwards."
752 (cond ((< length 0)
753 (gap-move-to buf (buffer-char-to-aref buf p))
754 (let* ((new (max 0 (+ (buffer-gap-start buf) length)))
755 (capped-size (- (buffer-gap-start buf) new)))
756 (update-markers-del buf new capped-size)
757 (record-delete new (buffer-substring new (+ new capped-size)))
758 (adjust-intervals-for-deletion buf new capped-size)
759 (incf (buffer-gap-size buf) capped-size)
760 (setf (buffer-gap-start buf) new)))
761 ((> length 0)
762 (unless (>= p (zv buf))
763 ;; can't delete forward if we're at the end of the buffer.
764 (gap-move-to buf (buffer-char-to-aref buf p))
765 ;; Make sure the gap size doesn't grow beyond the buffer size.
766 (let ((capped-size (- (min (+ (gap-end buf) length)
767 (length (buffer-data buf)))
768 (gap-end buf))))
769 (record-delete p (buffer-substring p (+ p capped-size)))
770 (incf (buffer-gap-size buf) capped-size)
771 (update-markers-del buf p capped-size)
772 (adjust-intervals-for-deletion buf p capped-size)))))
773 (setf (buffer-modified-p buf) t)
774 ;; debuggning
775 (fill-gap buf))
777 (defun buffer-erase (&optional (buf (current-buffer)))
778 ;; update properties
779 (record-delete (begv buf) (buffer-substring (begv buf) (zv buf) buf) buf)
780 (adjust-intervals-for-deletion buf 0 (buffer-size buf))
781 (update-markers-del buf 0 (buffer-size buf))
782 ;; expand the gap to take up the whole buffer
783 (setf (buffer-gap-start buf) 0
784 (buffer-gap-size buf) (length (buffer-data buf))
785 (marker-position (buffer-point buf)) 0
786 (buffer-modified-p buf) t)
787 ;; debugging
788 (fill-gap buf))
790 (defun buffer-scan-newline (buf start limit count)
791 "Search BUF for COUNT newlines with a limiting point at LIMIT,
792 starting at START. Returns the point of the last newline or limit and
793 number of newlines found. START and LIMIT are inclusive."
794 (declare (type buffer buf)
795 (type integer start limit count))
796 (labels ((buffer-scan-bk (buf start limit count)
797 "count is always >=0. start >= limit."
798 (let* ((start-aref (buffer-char-to-aref buf start))
799 (limit-aref (buffer-char-to-aref buf limit))
800 (ceiling (if (>= start-aref (gap-end buf))
801 (max limit-aref (gap-end buf))
802 limit-aref))
803 (i 0)
804 ;; :END is not inclusive but START is.
805 (start (1+ start-aref))
807 (loop
808 ;; Always search at least once
809 (setf p (position #\Newline (buffer-data buf)
810 :start ceiling :end start :from-end t))
811 (if p
812 (progn
813 ;; Move start. Note that start isn't set to (1+ p)
814 ;; because we don't want to search p again.
815 (setf start p)
816 ;; Count the newline
817 (incf i)
818 ;; Have we found enough newlines?
819 (when (>= i count)
820 (return-from buffer-scan-bk (values (buffer-aref-to-char buf p)
821 i))))
822 ;; Check if we've searched up to the limit
823 (if (= ceiling limit-aref)
824 (return-from buffer-scan-bk (values limit i))
825 ;; if not, skip past the gap
826 (progn
827 (setf ceiling limit-aref)
828 (setf start (buffer-gap-start buf))))))))
829 (buffer-scan-fw (buf start limit count)
830 "count is always >=0. start >= limit."
831 (let* ((start-aref (buffer-char-to-aref buf start))
832 (limit-aref (1+ (buffer-char-to-aref buf limit)))
833 (ceiling (if (< start (buffer-gap-start buf))
834 (min limit-aref (buffer-gap-start buf))
835 limit-aref))
836 (i 0)
837 (start start-aref)
839 (loop
840 ;; Always search at least once
841 (setf p (position #\Newline (buffer-data buf) :start start :end ceiling))
842 (if p
843 (progn
844 ;; Move start. We don't want to search p again, thus the 1+.
845 (setf start (1+ p))
846 ;; Count the newline
847 (incf i)
848 ;; Have we found enough newlines?
849 (when (>= i count)
850 (return-from buffer-scan-fw (values (buffer-aref-to-char buf p)
851 i))))
852 ;; Check if we've searched up to the limit
853 (if (= ceiling limit-aref)
854 (return-from buffer-scan-fw (values limit i))
855 ;; if not, skip past the gap
856 (progn
857 (setf ceiling limit-aref)
858 (setf start (gap-end buf)))))))))
859 ;; make sure start and limit are within the bounds
860 (setf start (max 0 (min start (1- (buffer-size buf))))
861 limit (max 0 (min limit (1- (buffer-size buf)))))
862 ;; the search always fails on an empty buffer
863 (when (= (buffer-size buf) 0)
864 (return-from buffer-scan-newline (values limit 0)))
865 (cond ((> count 0)
866 (dformat +debug-vv+ "scan-fw ~a ~a ~a~%" start limit count)
867 (buffer-scan-fw buf start limit count))
868 ((< count 0)
869 (dformat +debug-vv+ "scan-bk ~a ~a ~a~%" start limit count)
870 (buffer-scan-bk buf start limit (abs count)))
871 ;; 0 means the newline before the beginning of the current
872 ;; line. We need to handle the case where we are on a newline.
874 (dformat +debug-vv+ "scan-0 ~a ~a ~a~%" start limit count)
875 (if (char= (buffer-char-after buf start) #\Newline)
876 (buffer-scan-bk buf start limit 2)
877 (buffer-scan-bk buf start limit 1))))))
879 ;; ;;; more stuff
881 ;; (defparameter +scratch-buffer+ ";; This buffer is for notes you don't want to save, and for Lisp evaluation.
882 ;; ;; If you want to create a file, visit that file with C-x C-f,
883 ;; ;; then enter the text in that file's own buffer.")
885 ;; (defparameter +other-buf+
886 ;; "678901234567890 abcdefghijklmnopqrstuvwxyz
887 ;; 1 abcdefghijklmnopqrstuvwxyz
888 ;; 2 abcdefghijklmnopqrstuvwxyz
889 ;; 3 abcdefghijklmnopqrstuvwxyz
890 ;; 4 abcdefghijklmnopqrstuvwxyz
891 ;; 5 abcdefghijklmnopqrstuvwxyz
892 ;; 6 abcdefghijklmnopqrstuvwxyz
893 ;; 7 abcdefghijklmnopqrstuvwxyz
894 ;; 8 abcdefghijklmnopqrstuvwxyz")
896 ;; (defun buffer-read-from-stream (buffer stream)
897 ;; "Read the contents of stream until EOF, putting it in buffer-data"
898 ;; (loop for c = (read-char stream nil nil)
899 ;; until (null c)
900 ;; do (vector-push-extend c (buffer-data buffer))))
902 ;; (defun buffer-read-from-file (buffer file)
903 ;; (with-open-file (s file :direction :input)
904 ;; (buffer-read-from-stream buffer s)))
906 ;;; Mode-Line stuff
908 ;; FIXME: this is a parameter for debugging
909 ;; FIXME: be more emacs-like or make it better so we don't just have
910 ;; lambda functions that process data and return a string.
911 (defparameter *mode-line-format* (list "--:" ;; fake it for hype
912 (lambda (buffer)
913 (format nil "~C~C"
914 ;; FIXME: add read-only stuff
915 (if (buffer-modified-p buffer)
916 #\* #\-)
917 (if (buffer-modified-p buffer)
918 #\* #\-)))
920 (lambda (buffer)
921 (format nil "~12,,,a" (buffer-name buffer)))
923 (lambda (buffer)
924 (format nil "(~a)"
925 (major-mode-name (buffer-major-mode buffer)))))
926 "The default mode line format.")
928 (defgeneric mode-line-format-elem (buffer elem)
929 (:documentation "Given the element found in the buffer mode-line,
930 return a string that will be printed in the mode-line."))
932 (defmethod mode-line-format-elem ((b buffer) (elem string))
933 "just return the string."
934 (declare (ignore b))
935 elem)
937 (defmethod mode-line-format-elem ((b buffer) (elem function))
938 "Call the function. It is expected to return a string."
939 (funcall elem b))
941 (defmethod mode-line-format-elem ((b buffer) (elem symbol))
942 "elem is a symbol, so print its value."
943 (princ "~a" elem))
945 (defun update-mode-line (buffer)
946 "Given the buffer, refresh its mode-line string."
947 (setf (buffer-mode-line-string buffer)
948 (format nil "~{~a~}" (mapcar (lambda (elem)
949 (mode-line-format-elem buffer elem))
950 (buffer-mode-line buffer)))))
952 (defun truncate-mode-line (buffer len)
953 "return the buffers mode-line trunctated to len. If the mode-line is
954 shorter than len, it will be padded with -'s."
955 (let ((s (make-array len :element-type 'character :initial-element #\-)))
956 (replace s (buffer-mode-line-string buffer))))
958 ;;; Buffer query/creation
960 (defgeneric get-buffer (name)
961 (:documentation "Return the buffer named NAME. If there is no live
962 buffer named NAME, return NIL."))
964 (defmethod get-buffer ((name string))
965 (find name *buffer-list* :key #'buffer-name :test #'string=))
967 (defmethod get-buffer ((buffer buffer))
968 (find buffer *buffer-list*))
970 (defgeneric get-buffer-create (name)
971 (:documentation "Return the buffer named NAME, or create such a buffer and return it.
972 A new buffer is created if there is no live buffer named NAME.
973 If NAME starts with a space, the new buffer does not keep undo information.
974 If NAME is a buffer instead of a string, then it is the value returned.
975 The value is never nil."))
977 (defmethod get-buffer-create ((name string))
978 (or
979 (get-buffer name)
980 (progn
981 (when (zerop (length name))
982 (error "Empty string for buffer name is not allowed"))
983 (let ((b (make-instance 'buffer
984 :file nil
985 :point (make-marker)
986 :mark (make-marker)
987 ;; Currently a buffer has to have a gap
988 ;; of at least size 1.
989 :data (string-to-vector "_")
990 :gap-start 0
991 :gap-size 1
992 :mode-line *mode-line-format*
993 :name name
994 :major-mode *fundamental-mode*)))
995 (set-marker (buffer-point b) 0 b)
996 (set-marker (mark-marker b) 0 b)
997 (push b *buffer-list*)
998 b))))
1000 (defmethod get-buffer-create ((buffer buffer))
1001 buffer)
1003 ;;;
1005 (defparameter *initial-scratch-message* ";; This buffer is for notes you don't want to save, and for Lisp evaluation.
1006 ;; If you want to create a file, visit that file with C-x C-f,
1007 ;; then enter the text in that file's own buffer.")
1009 (defun make-default-buffers ()
1010 "Called on startup. Create the default buffers, putting them in
1011 *buffer-list*."
1012 ;; for the side effect
1013 (let ((msg (get-buffer-create "*messages*")))
1014 (setf (buffer-undo-list msg) t))
1015 (get-buffer-create "*scratch*"))
1019 (defun generate-new-buffer-name (name &optional ignore)
1020 "Return a string that is the name of no existing buffer based on NAME.
1021 If there is no live buffer named NAME, then return NAME.
1022 Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
1023 until an unused name is found, and then return that name.
1024 Optional second argument IGNORE specifies a name that is okay to use
1025 (if it is in the sequence to be tried)
1026 even if a buffer with that name exists."
1027 (declare (type string name)
1028 (type (or string null) ignore))
1029 (or (unless (get-buffer name)
1030 name)
1031 (loop for count from 1
1032 ;; FIXME: there's gotta be a way to do this where s isn't
1033 ;; "" to start with.
1034 with s = ""
1035 do (setf s (format nil "~a<~d>" name count))
1036 when (and ignore
1037 (string= s ignore))
1038 return ignore
1039 unless (get-buffer s)
1040 return s)))
1042 (defmacro with-current-buffer (buffer &body body)
1043 "Execute the forms in BODY with BUFFER as the current buffer.
1044 The value returned is the value of the last form in BODY.
1045 See also `with-temp-buffer'."
1046 (let ((bk (gensym "BK")))
1047 `(progn
1048 (let ((,bk *current-buffer*))
1049 (set-buffer ,buffer)
1050 (unwind-protect
1051 (progn ,@body)
1052 (set-buffer ,bk))))))
1054 (defmacro with-temp-buffer (&body body)
1055 "Create a temporary buffer, and evaluate BODY there like `progn'.
1056 See also `with-temp-file'."
1057 (let ((temp-buffer (gensym "TEMP-BUFFER")))
1058 `(let ((,temp-buffer (get-buffer-create (generate-new-buffer-name "*temp*"))))
1059 (unwind-protect
1060 (with-current-buffer ,temp-buffer
1061 ,@body)
1062 (and (get-buffer ,temp-buffer)
1063 (kill-buffer ,temp-buffer))))))
1065 (defun bring-buffer-to-front (buf)
1066 "Put buf at the front of *buffer-list*. Assumes BUF is in
1067 *buffer-list*."
1068 (setf *buffer-list* (delete buf *buffer-list*))
1069 (push buf *buffer-list*))
1071 (defun other-buffer (&optional (buffer (current-buffer)) visible-ok frame)
1072 "Return most recently selected buffer other than BUFFER.
1073 Buffers not visible in windows are preferred to visible buffers,
1074 unless optional second argument VISIBLE-OK is non-nil.
1075 If the optional third argument FRAME is non-nil, use that frame's
1076 buffer list instead of the selected frame's buffer list.
1077 If no other buffer exists, the buffer `*scratch*' is returned.
1078 If BUFFER is omitted or nil, some interesting buffer is returned."
1079 (declare (ignore frame))
1080 ;; TODO: honour FRAME argument
1081 (let* (vis
1082 (match (loop for b in *buffer-list*
1083 unless (or (eq b buffer)
1084 (char= (char (buffer-name b) 0) #\Space))
1085 if (and (not visible-ok)
1086 (get-buffer-window b))
1087 do (setf vis b)
1088 else return b)))
1089 (or match
1091 (get-buffer-create "*scratch*"))))
1093 (define-buffer-local *mark-active* nil
1094 "Non-nil means the mark and region are currently active in this buffer.")
1096 (defun mark (&optional force (buffer (current-buffer)))
1097 "Return BUFFER's mark value as integer; error if mark inactive.
1098 If optional argument FORCE is non-nil, access the mark value
1099 even if the mark is not currently active, and return nil
1100 if there is no mark at all."
1101 (declare (ignore force))
1102 ;; FIXME: marks can't be inactive ATM
1103 (marker-position (mark-marker buffer)))
1105 (defun validate-region (start end &optional (buffer (current-buffer)))
1106 "Return a value pair of start and end for buffer. the 1st value
1107 returned will always be <= the second. May raise an args out of range
1108 error.
1110 If START or END are marks, their positions will be used."
1111 (when (typep start 'marker)
1112 (setf start (marker-position start)))
1113 (when (typep end 'marker)
1114 (setf end (marker-position end)))
1115 (when (< end start)
1116 ;; MOVITZ doesn't have psetf
1117 (let ((tmp start))
1118 (setf start end
1119 end tmp))
1120 ;; (psetf end start
1121 ;; start end)
1123 (when (or (< start (buffer-min buffer))
1124 (> end (buffer-max buffer)))
1125 (signal 'args-out-of-range))
1126 (values start end))
1128 (defun eobp (&optional (buffer (current-buffer)))
1129 "Return T when the point is at the end of the buffer."
1130 (= (buffer-max buffer) (point)))
1132 (defun bobp (&optional (buffer (current-buffer)))
1133 "Return T when the point is at the beginning of the buffer."
1134 (= (buffer-min buffer) (point)))
1136 (defun set-buffer (buffer)
1137 "Make the buffer BUFFER current for editing operations.
1138 BUFFER may be a buffer or the name of an existing buffer.
1139 See also `save-excursion' when you want to make a buffer current temporarily.
1140 This function does not display the buffer, so its effect ends
1141 when the current command terminates.
1142 Use `switch-to-buffer' or `pop-to-buffer' to switch buffers permanently."
1143 (setf buffer (get-buffer buffer))
1144 (if buffer
1145 (progn
1146 ;; (when *current-buffer*
1147 ;; (record-local-variables *current-buffer*))
1148 ;; (set-local-variables buffer)
1149 (setf *current-buffer* buffer))
1150 (error "No buffer named ~s" buffer)))
1152 (defun record-buffer (buffer)
1153 "**Move the assoc for buffer BUF to the front of buffer-alist.
1154 Since we do this each time BUF is selected visibly, the more recently
1155 selected buffers are always closer to the front of the list. This
1156 means that other_buffer is more likely to choose a relevant buffer."
1157 (setf *buffer-list* (delete buffer *buffer-list* :test #'eq))
1158 (push buffer *buffer-list*))
1160 (defun barf-if-buffer-read-only ()
1161 "Signal a `buffer-read-only' error if the current buffer is read-only."
1162 (when (buffer-read-only (current-buffer))
1163 (signal 'buffer-read-only)))
1165 (defun bufferp (object)
1166 "Return t if object is an editor buffer."
1167 (typep object 'buffer))
1169 (define-buffer-local *default-directory* (truename "")
1170 "Name of default directory of current buffer.
1171 To interactively change the default directory, use command `cd'.")
1173 ;; (defstruct local-variable-binding
1174 ;; value backup)
1176 ;; (defun make-local-variable (symbol)
1177 ;; "Make variable have a separate value in the current buffer.
1178 ;; Other buffers will continue to share a common default value.
1179 ;; (The buffer-local value of variable starts out as the same value
1180 ;; variable previously had.)
1181 ;; Return variable."
1182 ;; (setf (gethash symbol (buffer-local-variables (current-buffer)))
1183 ;; (make-local-variable-binding :value (symbol-value symbol)))
1184 ;; symbol)
1186 ;; (defun record-local-variables (buffer)
1187 ;; "Update the values BUFFER's local variables."
1188 ;; (labels ((update (k v)
1189 ;; (if (boundp k)
1190 ;; (setf (local-variable-binding-value v) (symbol-value k)
1191 ;; (symbol-value k) (local-variable-binding-backup v))
1192 ;; (remhash k (buffer-local-variables buffer)))))
1193 ;; (maphash #'update (buffer-local-variables buffer))))
1195 ;; (defun set-local-variables (buffer)
1196 ;; "Set all variables to the buffer local value."
1197 ;; (labels ((set-it (k v)
1198 ;; (if (boundp k)
1199 ;; (setf (local-variable-binding-backup v) (symbol-value k)
1200 ;; (symbol-value k) (local-variable-binding-value v))
1201 ;; (remhash k (buffer-local-variables buffer)))))
1202 ;; (maphash #'set-it (buffer-local-variables buffer))))
1204 ;;; reading from the buffer
1206 (defun read-from-buffer (&aux (buffer (current-buffer)))
1207 "Read 1 sexp from the buffer at the current point, moving the point to the end of what was read"
1208 (when (< (buffer-char-to-aref buffer (point buffer))
1209 (buffer-gap-start buffer))
1210 (gap-move-to-point buffer))
1211 (multiple-value-bind (obj pos)
1212 (read-from-string (buffer-data buffer) t nil
1213 :start (buffer-char-to-aref buffer (point buffer)))
1214 (set-point (buffer-aref-to-char buffer pos))
1215 obj))
1217 (defun set-major-mode (mm)
1218 "Set the current buffer's major mode."
1219 ;; Call All inherited init functions
1220 (mapc (lambda (m)
1221 (set-major-mode (symbol-value m))) (major-mode-inherit-init mm))
1223 ;; Now call this mm's init function
1224 (when (major-mode-init mm)
1225 (funcall (major-mode-init mm)))
1227 ;; Finally, set the mode and call the hook
1228 (setf (buffer-major-mode (current-buffer)) mm)
1229 (run-hooks (major-mode-hook mm)))
1231 (defun major-mode ()
1232 (buffer-major-mode (current-buffer)))
1234 (define-buffer-local *fill-column* 70
1235 "*Column beyond which automatic line-wrapping should happen.
1236 Interactively, you can set the buffer local value using \\[set-fill-column].")
1238 (defun buffer-list (&optional (frame (selected-frame)))
1239 "Return a list of all existing live buffers.
1240 If the optional arg frame is a frame, we return the buffer list
1241 in the proper order for that frame: the buffers in FRAME's `buffer-list'
1242 frame parameter come first, followed by the rest of the buffers."
1243 (declare (ignore frame))
1244 *buffer-list*)
1246 (define-buffer-local *auto-fill-function* nil
1247 "Function called (if non-nil) to perform auto-fill.
1248 It is called after self-inserting any character specified in
1249 the `auto-fill-chars' table.
1250 NOTE: This variable is not a hook;
1251 its value may not be a list of functions.")
1252 (make-variable-buffer-local '*auto-fill-function*)
1254 (define-buffer-local mark-active nil
1255 "Non-nil means the mark and region are currently active in this buffer.")
1256 (make-variable-buffer-local 'mark-active)
1258 (define-buffer-local tab-width 8
1259 "*Distance between tab stops (for display of tab characters), in columns.")
1260 (make-variable-buffer-local 'tab-width)
1262 (define-buffer-local left-margin 0
1263 "*Column for the default indent-line-function to indent to.
1264 Linefeed indents to this column in Fundamental mode.")
1265 (make-variable-buffer-local 'left-margin)
1267 (provide :lice-0.1/buffer)