julian@uhccux.uhcc.hawaii.edu (Julian Cowley) (01/17/90)
Here is something which I wrote a year back to view buffers without using view.el. It has been slightly extended in the year since. I am aware that there might be some discrepancy between the naming of functions between this and view.el, but I am too lazy to check. The reason that I wrote a replacment is that I found view.el too cumbersome, especially with its use of recursive edit, and I wanted something closer to the standard `more' functions of Unix. Hope you folks find it useful. julian@uhccux.uhcc.hawaii.edu julian@uhccux.bitnet "I press Execute." -- KT ;;; Simple mode for the viewing the current buffer ;;; ;;; Written by Julian Cowley <julian@uhccux.uhcc.hawaii.edu> Jan. 1989 ;;; This program is now in the public domain as of 22 Feb. 1989. ;;; ;;; This is a simple replacement for view-mode that is ;;; intentionally small, doesn't use recursive edit, etc. While ;;; it is really a major mode, view-buffer-mode makes almost no ;;; disturbances to the buffer, and is able to appear/disappear ;;; upon command like minor modes do. In addition, whenever view ;;; buffer mode is active, the word "View" will be present on the ;;; mode line right after the name of the major mode, also ;;; similar to minor modes. ;;; ;;; Suggested key binding: M-# ;;; ;;; (global-set-key "\M-#" 'view-buffer-mode) ;;; ;;; An interesting thing to do is to automatically go into ;;; view-buffer-mode whenever you find a read-only file. You can ;;; do this by putting the following in your .emacs: ;;; ;;; (setq find-file-hooks '((lambda () ;;; (if buffer-read-only ;;; (view-buffer-mode))))) ;;; ;;; If you want to be able to use C-x C-r (find-file-read-only) ;;; to find a file that you have write access to and go straight ;;; into view mode, you must redefine find-file-read-only so that ;;; it sets the buffer read-only *before* it runs the ;;; find-file-hooks. Put the following redefinition in your ;;; .emacs, or better yet, byte-compile it and place it in a file ;;; that gets loaded upon start up. If you have write access to ;;; the Emacs sources, replace the distribution version in simple.el ;;; with this. ;;; ;;; (defun find-file-read-only (filename) ;;; "Edit file FILENAME but don't save without confirmation. ;;; Like find-file but marks buffer as read-only." ;;; (interactive "fFind file read-only: ") ;;; (let ((find-file-hooks (append '((lambda () ;;; (setq buffer-read-only t))) ;;; find-file-hooks))) ;;; (find-file filename))) ;;; ;;; Please send comments/suggestions/bugs to me at the above address. (defvar view-buffer-mode-map nil "The keymap for View buffer mode.") (defvar old-local-map nil "Temporary storage for the buffer's local map while View buffer mode is in effect.") (defvar old-buffer-read-only nil "Temporary storage for the buffer's buffer-read-only variable while View buffer mode is in effect.") (make-variable-buffer-local 'viewing-buffer) (make-variable-buffer-local 'old-local-map) (make-variable-buffer-local 'old-buffer-read-only) (or (assq 'viewing-buffer minor-mode-alist) (nconc minor-mode-alist '((viewing-buffer " View")))) (if view-buffer-mode-map () (setq view-buffer-mode-map (make-sparse-keymap)) (define-key view-buffer-mode-map " " 'scroll-up) (define-key view-buffer-mode-map "\r" 'scroll-up-line) (define-key view-buffer-mode-map "\C-d" 'scroll-up-half-screen) (define-key view-buffer-mode-map "d" 'scroll-up-half-screen) (define-key view-buffer-mode-map "s" 'search-forward) (define-key view-buffer-mode-map "r" 'search-backward) (define-key view-buffer-mode-map "/" 're-search-forward) (define-key view-buffer-mode-map "\\" 're-search-backward) (define-key view-buffer-mode-map "\C-?" 'scroll-down) (define-key view-buffer-mode-map "." 'beginning-of-buffer) (define-key view-buffer-mode-map "e" 'end-of-buffer) (define-key view-buffer-mode-map "<" 'beginning-of-buffer) (define-key view-buffer-mode-map ">" 'end-of-buffer) (define-key view-buffer-mode-map "g" 'goto-line) (define-key view-buffer-mode-map "=" 'what-line) (define-key view-buffer-mode-map "n" 'next-occurrence) (define-key view-buffer-mode-map "p" 'previous-occurrence) (define-key view-buffer-mode-map "?" 'describe-view-buffer-mode) (define-key view-buffer-mode-map "\C-hm" 'describe-view-buffer-mode)) (defun view-buffer-mode () "Mode to view the current buffer. Toggles on each call. The bindings are:\\{view-buffer-mode-map}" (interactive) (if viewing-buffer ;; if we are currently viewing a buffer, restore the ;; original buffer (progn (use-local-map old-local-map) (setq buffer-read-only old-buffer-read-only viewing-buffer nil)) ;; save the local map and the state of buffer-read-only (setq old-local-map (current-local-map)) (use-local-map view-buffer-mode-map) (setq old-buffer-read-only buffer-read-only buffer-read-only t viewing-buffer t)) ;; make sure to update the mode line (set-buffer-modified-p (buffer-modified-p))) (defun describe-view-buffer-mode () "Display documentation of View buffer mode." (interactive) (with-output-to-temp-buffer "*Help*" (princ "View Buffer Mode:\n") (princ (documentation 'view-buffer-mode)) (print-help-return-message))) (defun scroll-up-line () (interactive) (scroll-up 1)) (defun scroll-up-half-screen () (interactive) (scroll-up (/ (window-height) 2))) ;; the following two functions are handy to use with M-x occur (defun next-occurrence () "Find the next occurrence from the Occur buffer, if any." (interactive) (let ((occbuf (get-buffer "*Occur*"))) (if (or (null occbuf) (progn (set-buffer occbuf) (not (eq major-mode 'occur-mode)))) (error "Occur buffer does not exist.") ;; skip past the current match (forward-line 1) ;; look for the next line number (if (re-search-forward "^[ 0-9]+" nil t) (let ((occwin (get-buffer-window occbuf))) ;; must be at beginning of line in order for ;; occur-mode-goto-occurrence to work. (beginning-of-line) (if occwin (set-window-point occwin (point))) (occur-mode-goto-occurrence)) (message "End of matches.") ;; go back to the line where we started (forward-line -1))))) (defun previous-occurrence () "Find the previous occurrence from the Occur buffer, if any." (interactive) (let ((occbuf (get-buffer "*Occur*"))) (if (or (null occbuf) (progn (set-buffer occbuf) (not (eq major-mode 'occur-mode)))) (error "Occur buffer does not exist.") ;; look for the previous line number (if (re-search-backward "^[ 0-9]+" nil t) (let ((occwin (get-buffer-window occbuf))) (if occwin (set-window-point occwin (point))) (occur-mode-goto-occurrence)) (message "Beginning of matches.")))))