home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
util
/
edit
/
jade
/
lisp
/
buffers.jl
< prev
next >
Wrap
Lisp/Scheme
|
1994-10-05
|
19KB
|
527 lines
;;;; buffers.jl -- High-level buffer/file handling
;;; Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
;;; This file is part of Jade.
;;; Jade is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2, or (at your option)
;;; any later version.
;;; Jade is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;; You should have received a copy of the GNU General Public License
;;; along with Jade; see the file COPYING. If not, write to
;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
(defvar auto-save-p t
"When t files are auto-save'd regularly.")
(defvar default-auto-save-interval 120
"The number of seconds between each auto-save.")
(defvar make-backup-files t
"When non-nil backups of files are made when they are saved.")
(defvar backup-by-copying nil
"When non-nil all file backups are made by copying the file, not by
renaming it.")
(defvar else-backup-by-copying t
"Non-nil means make file backups by copying the file if it's not a good
idea to rename it. If `backup-by-copying' is non-nil this variable has no
effect.")
(defvar default-buffer (current-buffer)
"The `*jade*' buffer.")
;; Initialise the first window's buffer-list
(setq buffer-list (cons default-buffer nil))
(defvar standard-output default-buffer
"Stream that `prin?' writes its output to by default")
(defvar standard-input default-buffer
"Stream that `read' takes it's input from by default")
(defvar buffer-file-modtime 0
"Holds the modification time of the file this buffer was loaded from")
(make-variable-buffer-local 'buffer-file-modtime)
(defvar mildly-special-buffer nil
"When a buffer's `special' attribute is set kill-buffer will only kill
it totally if this variable is non-nil.")
(make-variable-buffer-local 'mildly-special-buffer)
(make-variable-buffer-local 'kill-buffer-hook)
(defvar enable-local-variables t
"Tells how to process local variable lists. t means process them
silently, nil means ignore them, anything else means to query each
variable being set.")
(defvar enable-local-eval 'maybe
"Tells how to process the `eval' local variable. Same options as
with `enable-local-variables'.")
(defvar local-variable-lines 20
"This variable defines how many of the bottom-most lines in a file are
searched for a `Local Variables:' section.")
(defun goto-buffer (buffer)
"Switch the current buffer to BUFFER which can either be a buffer-object
or a string naming an existing buffer. The selected buffer is moved to
the head of the buffer list. If BUFFER is a string and it doesn't name
an existing buffer a new one will be created with that name."
(interactive "BSwitch to buffer")
(when (stringp buffer)
(setq buffer (open-buffer buffer)))
(unless (bufferp buffer)
(signal 'bad-arg (list buffer 1)))
(setq buffer-list (cons buffer (delq buffer buffer-list)))
(set-current-buffer buffer))
(defun open-file (name)
"If no buffer containing file NAME exits try to create one.
After creating a new buffer (named after the file's (not path) name)
it first call the hook `read-file-hook' with arguments `(buffer-file-name
buffer)'.
If this hook returns nil (ie, no members of the hook decided to read the
file into memory) the file is read into the buffer verbatim.\n
Once the file is in memory, through the hook or otherwise, this function
then tries to initialise the correct editing mode for the file.\n
`open-file' always returns the buffer holding the file, or nil if it
doesn't exist."
(let
((buf (get-file-buffer name)))
(unless buf
(when (setq buf (make-buffer (file-name-nondirectory name)))
(add-buffer buf buffer-list)
(with-buffer buf
(unless (eval-hook 'read-file-hook name buf)
(set-buffer-file-name buf name)
(if (file-exists-p name)
(progn
(read-buffer name)
(setq buffer-file-modtime (file-modtime name)))
(message "New file")))
(fix-local-variables)
(set-buffer-modified buf nil)
(when auto-save-p
(setq auto-save-interval default-auto-save-interval))
(setq last-save-time (current-time)
buffer-undo-list nil)
(when (auto-save-file-newer-p name)
(message "Warning: Auto-saved file is newer")
(beep))
(when (and (file-exists-p name) (not (file-writable-p name)))
(set-buffer-read-only buf t))
(eval-hook 'open-file-hook buf)
(init-mode buf))))
buf))
;; Scans the end of a file for any local-variable definitions
(defun fix-local-variables ()
(unless enable-local-variables
(return))
(let
((pos (pos 0 (- (buffer-length) local-variable-lines))))
(when (< (pos-line pos) 0)
(set-pos-line pos 0))
(when (find-next-regexp "^(.*)Local Variables:(.*)$" pos)
(let
((re (concat ?^
(regexp-quote (copy-area (match-start 1) (match-end 1)))
"([^:]+):(.*)"
(regexp-quote (copy-area (match-start 2) (match-end 2)))
?$))
name value)
(setq pos (match-end))
(while (find-next-regexp re pos)
(setq pos (match-end)
name (copy-area (match-start 1) (match-end 1))
value (copy-area (match-start 2) (match-end 2)))
(cond
((and (equal name "End") (equal value ""))
(return))
((equal name "mode")
(when (or (eq enable-local-variables t)
(y-or-n-p (format nil "Use major mode %s?" value)))
(setq mode-name name)))
((equal name "eval")
(when (and enable-local-eval
(or (eq enable-local-eval t)
(y-or-n-p (format nil "Eval `%s'?" value))))
(eval (read-from-string value))))
(t
(when (or (eq enable-local-variables t)
(y-or-n-p (format nil "Set %s to %s?" name value)))
(setq name (intern name))
(make-local-variable name)
(set name (read-from-string value))))))))))
(defun find-file (name)
"Sets the current buffer to that containing the file NAME, if NAME
is unspecified it will be prompted for. If the file is not already in memory
`open-file' will be used to load it."
(interactive "FFind file: ")
(goto-buffer (open-file name)))
(defun find-file-read-only (name)
"Similar to `find-file' except that the buffer is edited in read-only mode."
(interactive "FFind file read-only:")
(let
((buf (open-file name)))
(when buf
(set-buffer-read-only buf t)
(goto-buffer buf))))
(defun find-alternate-file (name)
"If NAME is unspecified one will be prompted for. The current buffer is
killed and one editing NAME is found."
(interactive "FFind alternate file:")
(kill-buffer (current-buffer))
(goto-buffer (open-file name)))
(defun backup-file (file-name)
"If necessary make a backup of FILE-NAME. The file called FILE-NAME may or
may not exist after this function returns."
(when (and make-backup-files (file-regular-p name))
(let
((backup-name (concat name ?~)))
(if backup-by-copying
(copy-file name backup-name)
(if (and (file-owner-p name)
(= (file-nlinks name) 1))
(progn
(when (file-exists-p backup-name)
(delete-file backup-name))
(rename-file name backup-name))
(when else-backup-by-copying
(copy-file name backup-name)))))))
(defun write-file (buffer &optional name)
"Writes the contents of BUFFER to the file NAME, or to the one
that it is associated with."
(unless (stringp name)
(setq name (buffer-file-name buffer)))
(unless (eval-hook 'write-file-hook name buffer)
(let
((modes (when (file-exists-p name) (file-modes name))))
(backup-file name)
(when (write-buffer name buffer)
(when modes
(set-file-modes name modes))
t))))
(defun save-file (&optional buffer &aux name)
"Saves the buffer BUFFER, or the current buffer, to the file that it is
associated with, then sets the number of modifications made to this file
to zero.
Note: if no changes have been made to this buffer, it won't be saved."
(interactive)
(unless (bufferp buffer)
(setq buffer (current-buffer)))
(with-