1a4021e0e99ca3c56ee40690c69a9374186a1b79
[lice.git] / src / buffer.lisp
blob1a4021e0e99ca3c56ee40690c69a9374186a1b79
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 *inhibit-read-only* nil
12 "*Non-nil means disregard read-only status of buffers or characters.
13 If the value is t, disregard `buffer-read-only' and all `read-only'
14 text properties. If the value is a list, disregard `buffer-read-only'
15 and disregard a `read-only' text property if the property value
16 is a member of the list.")
18 (defvar *default-major-mode* 'fundamental-mode
19 "*Major mode for new buffers. Defaults to `fundamental-mode'.
20 A value of nil means use current buffer's major mode,
21 provided it is not marked as \"special\".
23 When a mode is used by default, `find-file' switches to it
24 before it reads the contents into the buffer and before
25 it finishes setting up the buffer. Thus, the mode and
26 its hooks should not expect certain variables such as
27 `buffer-read-only' and `buffer-file-coding-system' to be set up.")
29 (define-condition args-out-of-range (lice-condition)
30 () (:documentation "Raised when some arguments (usually relating to a
31 buffer) are out of range."))
33 (define-condition beginning-of-buffer (lice-condition)
34 () (:documentation "Raised when it is an error that the point is at
35 the beginning of the buffer."))
37 (define-condition end-of-buffer (lice-condition)
38 () (:documentation "Raised when it is an error that the point is at
39 the end of the buffer."))
41 (define-condition buffer-read-only (lice-condition)
42 () (:documentation "Raised when there is an attempt to insert into a read-only buffer."))
44 (defun mark-marker (&optional (buffer (current-buffer)))
45 "Return this buffer's mark, as a marker object.
46 Watch out! Moving this marker changes the mark position.
47 If you set the marker not to point anywhere, the buffer will have no mark."
48 ;; FIXME: marks can't be inactive ATM
49 (buffer-mark-marker buffer))
52 ;;; gap basics
54 ;; Some wrappers around replace
55 (defun move-subseq-left (seq from end to)
56 "Move the subseq between from and end to before TO, which is assumed to be
57 left of FROM."
58 (replace seq seq :start1 (+ to (- end from) 1) :start2 to :end2 from)
59 to)
61 (defun move-subseq-right (seq from end to)
62 "Move the subseq between from and end to before TO, which is assumed to be
63 right of FROM."
64 (replace seq seq :start1 from :start2 (1+ end) :end2 to)
65 (+ from (- to end 1)))
67 (defun move-subseq (seq from end to)
68 "Destructively move the gap subseq starting at from and ending at
69 end, inclusive, to before TO."
70 (if (< to from)
71 (move-subseq-left seq from end to)
72 (move-subseq-right seq from end to)))
74 (defun gap-end (buf)
75 "The end of the gap. in aref space. gap-end is the first valid
76 buffer character."
77 (declare (type buffer buf))
78 (+ (buffer-gap-start buf) (buffer-gap-size buf)))
80 (defun fill-gap (buf)
81 "For debugging purposes. fill the gap with _'s."
82 (fill (buffer-data buf) #\_ :start (buffer-gap-start buf) :end (gap-end buf)))
84 (defun buffer-aref-to-char (buf idx)
85 "Translate the index into the buffer data to the index excluding the gap."
86 (declare (type buffer buf)
87 (type integer idx))
88 (if (>= idx (gap-end buf))
89 (- idx (buffer-gap-size buf))
90 idx))
92 (defun buffer-char-to-aref (buf p)
94 (declare (type buffer buf)
95 (type integer p))
96 (if (>= p (buffer-gap-start buf))
97 (+ p (buffer-gap-size buf))
98 p))
100 (defun gap-move-to (buf to)
101 "A basic function to move the gap. TO is in aref coordinates and the
102 gap is positioned before TO.
104 BUFFER: ABC__DEF
105 (gap-move-to buffer 6)
106 BUFFER: ABCD__EF"
107 (setf (buffer-gap-start buf)
108 (move-subseq (buffer-data buf) (buffer-gap-start buf) (1- (gap-end buf)) to))
109 ;; for debugging purposes, we set the gap to _'s
110 (fill-gap buf))
112 (defun gap-move-to-point (buf)
113 "Move the gap to the point position in aref space.
114 ABCD___EF
117 A___BCDEF
120 (gap-move-to buf (buffer-char-to-aref buf (marker-position (buffer-point buf)))))
122 ;; ;; Move the gap to the end of the vector
123 ;; (replace data data :start1 gap-start :start2 gap-end)
124 ;; ;; open a space for the gap
125 ;; (replace data data :start1 (+ to (buffer-gap-size buf)) :start2 to)
126 ;; (setf (buffer-gap-start buf) to)))
128 (defun buffer-size (buf)
129 "Return the length of the buffer not including the gap."
130 (declare (type buffer buf))
131 (- (length (buffer-data buf))
132 (buffer-gap-size buf)))
134 (defun buffer-min (buf)
135 "The beginning of the buffer in char space."
136 (declare (type buffer buf)
137 (ignore buf))
140 (defun buffer-max (buf)
141 "The end of the buffer in char space."
142 (declare (type buffer buf))
143 (buffer-size buf))
145 (defun begv (&optional (buf (current-buffer)))
146 "Position of beginning of accessible range of buffer."
147 ;; TODO: handle buffer narrowing
148 (buffer-min buf))
150 (defun begv-aref (&optional (buf (current-buffer)))
151 "aref Position of beginning of accessible range of buffer."
152 ;; TODO: handle buffer narrowing
153 (buffer-char-to-aref buf (buffer-min buf)))
155 (defun zv (&optional (buf (current-buffer)))
156 "Position of end of accessible range of buffer."
157 ;; TODO: handle buffer narrowing
158 (buffer-max buf))
160 (defun zv-aref (&optional (buf (current-buffer)))
161 "aref Position of end of accessible range of buffer."
162 ;; TODO: handle buffer narrowing
163 (buffer-char-to-aref buf (buffer-max buf)))
165 (defmacro inc-aref (var buffer)
166 "increment VAR one character forward in BUFFER, avoiding the gap."
167 `(progn
168 (incf ,var)
169 (if (= (buffer-gap-start ,buffer) ,var)
170 (setf ,var (gap-end ,buffer)))))
172 (defmacro inc-both (char-var aref-var buffer)
173 `(progn
174 (inc-aref ,aref-var ,buffer)
175 (incf ,char-var)))
177 (defun aref-minus-1 (aref buffer)
178 (if (= (gap-end buffer) aref)
179 (1- (buffer-gap-start buffer))
180 (1- aref)))
182 (defmacro dec-aref (var buffer)
183 "increment VAR one character forward in BUFFER, avoiding the gap."
184 `(setf ,var (aref-minus-1 ,var ,buffer)))
186 (defmacro dec-both (char-var aref-var buffer)
187 `(progn
188 (dec-aref ,aref-var ,buffer)
189 (decf ,char-var)))
191 (defun pt (&optional (buffer (current-buffer)))
192 "Return the point in the current buffer."
193 (marker-position (buffer-point buffer)))
195 (defun buffer-point-aref (buf)
196 "Return the buffer point in aref coordinates."
197 (buffer-char-to-aref buf (pt buf)))
199 (defun set-point-both (buffer char-pos aref-pos)
200 "Set point in BUFFER to CHARPOS, which corresponds to byte
201 position BYTEPOS. If the target position is
202 before an intangible character, move to an ok place."
203 (declare (ignore aref-pos))
204 ;; TODO: implement
205 (setf (marker-position (buffer-point buffer)) char-pos))
207 (defun set-point (char-pos &optional (buffer (current-buffer)))
208 (set-point-both buffer char-pos nil))
210 (defun buffer-char-after (buf p)
211 "The character at the point P in buffer BUF. P is in char space."
212 (declare (type buffer buf)
213 (type (integer 0 *) p))
214 (let ((aref (buffer-char-to-aref buf p)))
215 (when (and (>= aref 0)
216 (< aref (length (buffer-data buf))))
217 (aref (buffer-data buf) aref))))
219 (defun buffer-char-before (buf p)
220 (buffer-char-after buf (1- p)))
223 (defun buffer-fetch-char (aref buf)
224 (aref (buffer-data buf) aref))
227 ;;; Markers
229 (defgeneric ensure-number (thing)
230 (:documentation "Call this function when THING could be a number or a marker or...?"))
232 (defmethod ensure-number ((thing number))
233 thing)
235 (defmethod ensure-number ((thing marker))
236 (marker-position thing))
238 (defmacro check-number-coerce-marker (marker-var)
239 "Verify that MARKER-VAR is a number or if it's a marker then
240 set the var to the marker's position."
241 `(progn
242 (check-type ,marker-var (or marker (integer 0 *)))
243 (when (typep ,marker-var 'marker)
244 (setf ,marker-var (marker-position ,marker-var)))))
246 (defun make-marker ()
247 "Return a newly allocated marker which does not point anywhere."
248 (make-instance 'marker))
250 (defun unchain-marker (marker)
251 (when (marker-buffer marker)
252 (setf (buffer-markers (marker-buffer marker))
253 (delete marker (buffer-markers (marker-buffer marker)) :key #'weak-pointer-value))))
255 (defun chain-marker (marker buffer)
256 (push (make-weak-pointer marker) (buffer-markers buffer)))
258 (defun set-marker (marker position &optional (buffer (current-buffer)))
259 ;; remove the marker from its buffer, when appropriate
260 (when (null position)
261 (unchain-marker marker)
262 (return-from set-marker marker))
263 ;; XXX handle dead buffers
265 ;; normalize pos
266 (setf (marker-position marker) (min (max position (begv buffer)) (zv buffer)))
268 ;; update buffer stuff
269 (unless (eq (marker-buffer marker) buffer)
270 (unchain-marker marker)
271 (setf (marker-buffer marker) buffer)
272 (chain-marker marker buffer))
273 marker)
275 (defun copy-marker (marker &optional (type :after))
276 "Return a new marker pointing at the same place as MARKER.
277 If argument is a number, makes a new marker pointing
278 at that position in the current buffer.
279 **The optional argument TYPE specifies the insertion type of the new marker;
280 **see `marker-insertion-type'."
281 (check-type marker (or marker integer))
282 (check-type type marker-insertion-type)
283 (let ((new (make-marker)))
284 (set-marker new (ensure-number marker)
285 (if (typep marker 'marker)
286 (marker-buffer marker)
287 (current-buffer)))
288 (setf (marker-insertion-type new) type)
289 new))
291 (defun purge-markers (buffer)
292 "Remove GC'd markers."
293 (setf (buffer-markers buffer)
294 (delete-if (lambda (m)
295 (multiple-value-bind (v c) (weak-pointer-value m)
296 (declare (ignore v))
297 (not c)))
298 (buffer-markers buffer))))
300 (defun update-markers-del (buffer start size)
301 ;; FIXME: insertion-type
302 ;; First get rid of stale markers
303 (purge-markers buffer)
304 (dolist (wp (buffer-markers buffer))
305 (let ((m (weak-pointer-value wp)))
306 ;; paranoia, maybe the GC freed some stuff after the marker
307 ;; purge.
308 (when m
309 ;; markers are before the marker-position.
310 (cond ((>= (marker-position m) (+ start size))
311 (decf (marker-position m) size))
312 ((> (marker-position m) start)
313 (setf (marker-position m) start)))))))
315 (defun update-markers-ins (buffer start size)
316 ;; FIXME: insertion-type
317 ;; First get rid of stale markers
318 (purge-markers buffer)
319 (dolist (wp (buffer-markers buffer))
320 (let ((m (weak-pointer-value wp)))
321 ;; markers are before the marker-position.
322 (when (and m (> (marker-position m) start)
323 (incf (marker-position m) size))))))
328 (defun inc-buffer-tick (buffer)
329 "Increment the buffer's ticker."
330 (incf (buffer-modified-tick buffer)))
332 ;; ;;; more stuff
334 ;; (defparameter +scratch-buffer+ ";; This buffer is for notes you don't want to save, and for Lisp evaluation.
335 ;; ;; If you want to create a file, visit that file with C-x C-f,
336 ;; ;; then enter the text in that file's own buffer.")
338 ;; (defparameter +other-buf+
339 ;; "678901234567890 abcdefghijklmnopqrstuvwxyz
340 ;; 1 abcdefghijklmnopqrstuvwxyz
341 ;; 2 abcdefghijklmnopqrstuvwxyz
342 ;; 3 abcdefghijklmnopqrstuvwxyz
343 ;; 4 abcdefghijklmnopqrstuvwxyz
344 ;; 5 abcdefghijklmnopqrstuvwxyz
345 ;; 6 abcdefghijklmnopqrstuvwxyz
346 ;; 7 abcdefghijklmnopqrstuvwxyz
347 ;; 8 abcdefghijklmnopqrstuvwxyz")
349 ;; (defun buffer-read-from-stream (buffer stream)
350 ;; "Read the contents of stream until EOF, putting it in buffer-data"
351 ;; (loop for c = (read-char stream nil nil)
352 ;; until (null c)
353 ;; do (vector-push-extend c (buffer-data buffer))))
355 ;; (defun buffer-read-from-file (buffer file)
356 ;; (with-open-file (s file :direction :input)
357 ;; (buffer-read-from-stream buffer s)))
359 ;;; Mode-Line stuff
361 ;; FIXME: this is a parameter for debugging
362 ;; FIXME: be more emacs-like or make it better so we don't just have
363 ;; lambda functions that process data and return a string.
364 (defvar *default-mode-line-format* nil
365 "Default value of `mode-line-format' for buffers that don't override it.
366 This is the same as (default-value 'mode-line-format).")
368 (define-buffer-local *mode-line-format* nil
369 "The buffer's mode line format.")
370 (make-variable-buffer-local '*mode-line-format*)
372 (defgeneric mode-line-format-elem (buffer elem)
373 (:documentation "Given the element found in the buffer mode-line,
374 return a string that will be printed in the mode-line."))
376 (defmethod mode-line-format-elem ((b buffer) (elem string))
377 "just return the string."
378 (declare (ignore b))
379 elem)
381 (defmethod mode-line-format-elem ((b buffer) (elem function))
382 "Call the function. It is expected to return a string."
383 (funcall elem b))
385 (defmethod mode-line-format-elem ((b buffer) (elem symbol))
386 "elem is a symbol, so print its value."
387 (princ "~a" elem))
389 (defun update-mode-line (buffer)
390 "Given the buffer, refresh its mode-line string."
391 (setf (buffer-mode-line-string buffer)
392 (format nil "~{~a~}" (mapcar (lambda (elem)
393 (mode-line-format-elem buffer elem))
394 (buffer-local '*mode-line-format* buffer)))))
396 (defun truncate-mode-line (buffer len)
397 "return the buffers mode-line trunctated to len. If the mode-line is
398 shorter than len, it will be padded with -'s."
399 (let ((s (make-array len :element-type 'character :initial-element #\-)))
400 (replace s (buffer-mode-line-string buffer))))
402 ;;; Buffer query/creation
404 (defun string-to-vector (s)
405 "Return a resizable vector containing the elements of the string s."
406 (declare (string s))
407 (make-array (length s)
408 :initial-contents s
409 :element-type 'character
410 :adjustable t))
412 (defgeneric get-buffer (name)
413 (:documentation "Return the buffer named NAME. If there is no live
414 buffer named NAME, return NIL."))
416 (defmethod get-buffer ((name string))
417 (find name *buffer-list* :key #'buffer-name :test #'string=))
419 (defmethod get-buffer ((buffer buffer))
420 (find buffer *buffer-list*))
422 (defgeneric get-buffer-create (name)
423 (:documentation "Return the buffer named NAME, or create such a buffer and return it.
424 A new buffer is created if there is no live buffer named NAME.
425 If NAME starts with a space, the new buffer does not keep undo information.
426 If NAME is a buffer instead of a string, then it is the value returned.
427 The value is never nil."))
429 (defmethod get-buffer-create ((name string))
430 (or
431 (get-buffer name)
432 (progn
433 (when (zerop (length name))
434 (error "Empty string for buffer name is not allowed"))
435 (let ((b (make-instance 'buffer
436 :file nil
437 :point (make-marker)
438 :mark (make-marker)
439 ;; Currently a buffer has to have a gap
440 ;; of at least size 1.
441 :data (string-to-vector "_")
442 :major-mode '*fundamental-mode*
443 :gap-start 0
444 :gap-size 1
445 :name name)))
446 (set-marker (buffer-point b) 0 b)
447 (set-marker (mark-marker b) 0 b)
448 (setf (buffer-local '*mode-line-format* b) *default-mode-line-format*)
449 (push b *buffer-list*)
450 b))))
452 (defmethod get-buffer-create ((buffer buffer))
453 buffer)
455 ;;;
457 (defparameter *initial-scratch-message* ";; This buffer is for notes you don't want to save, and for Lisp evaluation.
458 ;; If you want to create a file, visit that file with C-x C-f,
459 ;; then enter the text in that file's own buffer.")
461 (defun make-default-buffers ()
462 "Called on startup. Create the default buffers, putting them in
463 *buffer-list*."
464 ;; for the side effect
465 (let ((msg (get-buffer-create "*messages*")))
466 (setf (buffer-undo-list msg) t))
467 (get-buffer-create "*scratch*"))
471 (defun generate-new-buffer-name (name &optional ignore)
472 "Return a string that is the name of no existing buffer based on NAME.
473 If there is no live buffer named NAME, then return NAME.
474 Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
475 until an unused name is found, and then return that name.
476 Optional second argument IGNORE specifies a name that is okay to use
477 (if it is in the sequence to be tried)
478 even if a buffer with that name exists."
479 (declare (type string name)
480 (type (or string null) ignore))
481 (or (unless (get-buffer name)
482 name)
483 (loop for count from 1
484 ;; FIXME: there's gotta be a way to do this where s isn't
485 ;; "" to start with.
486 with s = ""
487 do (setf s (format nil "~a<~d>" name count))
488 when (and ignore
489 (string= s ignore))
490 return ignore
491 unless (get-buffer s)
492 return s)))
494 (defmacro with-current-buffer (buffer &body body)
495 "Execute the forms in BODY with BUFFER as the current buffer.
496 The value returned is the value of the last form in BODY.
497 See also `with-temp-buffer'."
498 (let ((bk (gensym "BK")))
499 `(progn
500 (let ((,bk *current-buffer*))
501 (set-buffer ,buffer)
502 (unwind-protect
503 (progn ,@body)
504 (set-buffer ,bk))))))
506 (defmacro with-temp-buffer (&body body)
507 "Create a temporary buffer, and evaluate BODY there like `progn'.
508 See also `with-temp-file'."
509 (let ((temp-buffer (gensym "TEMP-BUFFER")))
510 `(let ((,temp-buffer (get-buffer-create (generate-new-buffer-name "*temp*"))))
511 (unwind-protect
512 (with-current-buffer ,temp-buffer
513 ,@body)
514 (and (get-buffer ,temp-buffer)
515 (kill-buffer ,temp-buffer))))))
517 (defun bring-buffer-to-front (buf)
518 "Put buf at the front of *buffer-list*. Assumes BUF is in
519 *buffer-list*."
520 (setf *buffer-list* (delete buf *buffer-list*))
521 (push buf *buffer-list*))
523 (defun mark (&optional force (buffer (current-buffer)))
524 "Return BUFFER's mark value as integer; error if mark inactive.
525 If optional argument FORCE is non-nil, access the mark value
526 even if the mark is not currently active, and return nil
527 if there is no mark at all."
528 (declare (ignore force))
529 ;; FIXME: marks can't be inactive ATM
530 (marker-position (mark-marker buffer)))
532 (defun validate-region (start end &optional (buffer (current-buffer)))
533 "Return a value pair of start and end for buffer. the 1st value
534 returned will always be <= the second. May raise an args out of range
535 error.
537 If START or END are marks, their positions will be used."
538 (when (typep start 'marker)
539 (setf start (marker-position start)))
540 (when (typep end 'marker)
541 (setf end (marker-position end)))
542 (when (< end start)
543 ;; MOVITZ doesn't have psetf
544 (let ((tmp start))
545 (setf start end
546 end tmp))
547 ;; (psetf end start
548 ;; start end)
550 (when (or (< start (buffer-min buffer))
551 (> end (buffer-max buffer)))
552 (signal 'args-out-of-range))
553 (values start end))
555 (defun set-buffer (buffer)
556 "Make the buffer BUFFER current for editing operations.
557 BUFFER may be a buffer or the name of an existing buffer.
558 See also `save-excursion' when you want to make a buffer current temporarily.
559 This function does not display the buffer, so its effect ends
560 when the current command terminates.
561 Use `switch-to-buffer' or `pop-to-buffer' to switch buffers permanently."
562 (setf buffer (get-buffer buffer))
563 (if buffer
564 (progn
565 ;; (when *current-buffer*
566 ;; (record-local-variables *current-buffer*))
567 ;; (set-local-variables buffer)
568 (setf *current-buffer* buffer))
569 (error "No buffer named ~s" buffer)))
571 (defun record-buffer (buffer)
572 "**Move the assoc for buffer BUF to the front of buffer-alist.
573 Since we do this each time BUF is selected visibly, the more recently
574 selected buffers are always closer to the front of the list. This
575 means that other_buffer is more likely to choose a relevant buffer."
576 (setf *buffer-list* (delete buffer *buffer-list* :test #'eq))
577 (push buffer *buffer-list*))
579 (defun buffer-read-only ()
580 "Non-nil if this buffer is read-only."
581 (slot-value (current-buffer) 'read-only))
583 (defun (setf buffer-read-only) (value)
584 (setf (slot-value (current-buffer) 'read-only) (and value t)))
586 (defun barf-if-buffer-read-only ()
587 "Signal a `buffer-read-only' error if the current buffer is read-only."
588 (when (buffer-read-only)
589 (signal 'buffer-read-only)))
591 (defun bufferp (object)
592 "Return t if object is an editor buffer."
593 (typep object 'buffer))
595 (define-buffer-local *default-directory* (truename "")
596 "Name of default directory of current buffer.
597 To interactively change the default directory, use command `cd'.")
599 ;; (defstruct local-variable-binding
600 ;; value backup)
602 ;; (defun make-local-variable (symbol)
603 ;; "Make variable have a separate value in the current buffer.
604 ;; Other buffers will continue to share a common default value.
605 ;; (The buffer-local value of variable starts out as the same value
606 ;; variable previously had.)
607 ;; Return variable."
608 ;; (setf (gethash symbol (buffer-local-variables (current-buffer)))
609 ;; (make-local-variable-binding :value (symbol-value symbol)))
610 ;; symbol)
612 ;; (defun record-local-variables (buffer)
613 ;; "Update the values BUFFER's local variables."
614 ;; (labels ((update (k v)
615 ;; (if (boundp k)
616 ;; (setf (local-variable-binding-value v) (symbol-value k)
617 ;; (symbol-value k) (local-variable-binding-backup v))
618 ;; (remhash k (buffer-local-variables buffer)))))
619 ;; (maphash #'update (buffer-local-variables buffer))))
621 ;; (defun set-local-variables (buffer)
622 ;; "Set all variables to the buffer local value."
623 ;; (labels ((set-it (k v)
624 ;; (if (boundp k)
625 ;; (setf (local-variable-binding-backup v) (symbol-value k)
626 ;; (symbol-value k) (local-variable-binding-value v))
627 ;; (remhash k (buffer-local-variables buffer)))))
628 ;; (maphash #'set-it (buffer-local-variables buffer))))
630 (defun major-mode ()
631 (symbol-value (buffer-major-mode (current-buffer))))
633 (define-buffer-local *fill-column* 70
634 "*Column beyond which automatic line-wrapping should happen.
635 Interactively, you can set the buffer local value using \\[set-fill-column].")
637 (defun buffer-list (&optional frame)
638 "Return a list of all existing live buffers.
639 If the optional arg frame is a frame, we return the buffer list
640 in the proper order for that frame: the buffers in FRAME's `buffer-list'
641 frame parameter come first, followed by the rest of the buffers."
642 ;; FIXME: handle frame
643 (declare (ignore frame))
644 *buffer-list*)
646 (define-buffer-local *auto-fill-function* nil
647 "Function called (if non-nil) to perform auto-fill.
648 It is called after self-inserting any character specified in
649 the `auto-fill-chars' table.
650 NOTE: This variable is not a hook;
651 its value may not be a list of functions.")
652 (make-variable-buffer-local '*auto-fill-function*)
654 (define-buffer-local mark-active nil
655 "Non-nil means the mark and region are currently active in this buffer.")
656 (make-variable-buffer-local 'mark-active)
658 (define-buffer-local tab-width 8
659 "*Distance between tab stops (for display of tab characters), in columns.")
660 (make-variable-buffer-local 'tab-width)
662 (define-buffer-local left-margin 0
663 "*Column for the default indent-line-function to indent to.
664 Linefeed indents to this column in Fundamental mode.")
665 (make-variable-buffer-local 'left-margin)
667 (define-buffer-local truncate-lines nil
668 "*Non-nil means do not display continuation lines.
669 Instead, give each line of text just one screen line.
671 Note that this is overridden by the variable
672 `truncate-partial-width-windows' if that variable is non-nil
673 and this buffer is not full-frame width.")
674 (make-variable-buffer-local 'truncate-lines)
678 (defun make-buffer-string (start end props &optional (buffer (current-buffer)))
679 "Making strings from buffer contents.
681 Return a Lisp_String containing the text of the current buffer from
682 START to END. If text properties are in use and the current buffer has
683 properties in the range specified, the resulting string will also have
684 them, if PROPS is nonzero.
686 We don't want to use plain old make_string here, because it calls
687 make_uninit_string, which can cause the buffer arena to be
688 compacted. make_string has no way of knowing that the data has
689 been moved, and thus copies the wrong data into the string. This
690 doesn't effect most of the other users of make_string, so it should
691 be left as is. But we should use this function when conjuring
692 buffer substrings."
693 (declare (ignore props))
694 ;; If the gap intersects with the range we wanna grab, move it.
695 (if (= start end)
697 (progn
698 (when (and (< start (buffer-gap-start buffer))
699 (< (buffer-gap-start buffer) end))
700 (gap-move-to buffer start))
701 (dformat +debug-v+ "substring: ~a ~a ~a~%" start end (length (buffer-data buffer)))
702 (subseq (buffer-data buffer)
703 (buffer-char-to-aref buffer start)
704 (1+ (buffer-char-to-aref buffer (1- end)))))))
706 (provide :lice-0.1/buffer)