diff options
| -rw-r--r-- | lisp/view.el | 1021 |
1 files changed, 717 insertions, 304 deletions
diff --git a/lisp/view.el b/lisp/view.el index bbc168b6f9c..89cace0e0ad 100644 --- a/lisp/view.el +++ b/lisp/view.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; view.el --- peruse file or buffer without editing. | 1 | ;;; view.el --- peruse file or buffer without editing. |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1985, 1989, 1994, 1995 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1985, 1989, 1994, 1995, 1997 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: K. Shane Hartman | 5 | ;; Author: K. Shane Hartman |
| 6 | ;; Maintainer: FSF | 6 | ;; Maintainer: FSF |
| @@ -26,6 +26,21 @@ | |||
| 26 | 26 | ||
| 27 | ;; This package provides the `view' minor mode documented in the Emacs | 27 | ;; This package provides the `view' minor mode documented in the Emacs |
| 28 | ;; user's manual. | 28 | ;; user's manual. |
| 29 | ;; View mode entry and exit is done through the functions view-mode-enter | ||
| 30 | ;; and view-mode-exit. Use these functions to enter or exit view-mode from | ||
| 31 | ;; emacs lisp programs. | ||
| 32 | ;; We use both view- and View- as prefix for symbols. View- is used as | ||
| 33 | ;; prefix for commands that have a key binding. view- is used for commands | ||
| 34 | ;; without key binding. The purpose of this is to make it easier for a | ||
| 35 | ;; user to use command name completion. | ||
| 36 | |||
| 37 | ;;; Suggested key bindings: | ||
| 38 | ;; | ||
| 39 | ;; (define-key ctl-x-4-map "v" 'view-file-other-window) ; ^x4v | ||
| 40 | ;; (define-key ctl-x-5-map "v" 'view-file-other-frame) ; ^x5v | ||
| 41 | ;; | ||
| 42 | ;; You could also bind view-file, view-buffer, view-buffer-other-window and | ||
| 43 | ;; view-buffer-other-frame to keys. | ||
| 29 | 44 | ||
| 30 | ;;; Code: | 45 | ;;; Code: |
| 31 | 46 | ||
| @@ -33,33 +48,71 @@ | |||
| 33 | (defvar view-highlight-face 'highlight | 48 | (defvar view-highlight-face 'highlight |
| 34 | "*The overlay face used for highlighting the match found by View mode search.") | 49 | "*The overlay face used for highlighting the match found by View mode search.") |
| 35 | 50 | ||
| 51 | ;; `view-mode-auto-exit' is replaced by the following global variable which | ||
| 52 | ;; only says if scrolling past buffer end should leave view mode or not, it | ||
| 53 | ;; doesn't say if leaving view mode should restore windows or not. The latter | ||
| 54 | ;; is now controlled by the presence of a value in `view-return-to-alist'. | ||
| 55 | ;;;###autoload | ||
| 56 | (defvar view-scroll-auto-exit nil | ||
| 57 | "*Non-nil means scrolling past the end of buffer exits View mode. | ||
| 58 | nil means attempting to scroll past the end of the buffer, | ||
| 59 | only rings the bell and gives a message on how to leave.") | ||
| 60 | |||
| 61 | ;;;###autoload | ||
| 62 | (defvar view-try-extend-at-buffer-end nil | ||
| 63 | "*Non-nil means try load more of file when reaching end of buffer.") | ||
| 64 | |||
| 65 | ;;;###autoload | ||
| 66 | (defvar view-remove-frame-by-deleting nil | ||
| 67 | "*Determine how to remove a not needed frame. | ||
| 68 | If nil, make an icon of the frame. If non-nil, delete the frame.") | ||
| 69 | |||
| 70 | ;;;###autoload | ||
| 71 | (defvar view-exit-all-windows-at-exit nil | ||
| 72 | "*Non-nil means restore all windows displaying buffer. | ||
| 73 | Commands that restore windows apply to all windows displaying buffer. | ||
| 74 | Buffer is removed from all windows displaying it, by using information in | ||
| 75 | `view-return-to-alist' if that is available, otherwise by using | ||
| 76 | `replace-buffer-in-windows'.") | ||
| 77 | |||
| 36 | (defvar view-mode nil "Non-nil if View mode is enabled.") | 78 | (defvar view-mode nil "Non-nil if View mode is enabled.") |
| 37 | (make-variable-buffer-local 'view-mode) | 79 | (make-variable-buffer-local 'view-mode) |
| 38 | 80 | ||
| 39 | (defvar view-mode-auto-exit nil | 81 | (defvar view-mode-hook nil |
| 40 | "Non-nil means scrolling past the end of buffer exits View mode. | 82 | "Normal hook run when starting to view a buffer or file.") |
| 41 | Some commands, such as \\[view-file], set this to t locally; | ||
| 42 | the only way to override that is to set it to nil using `view-mode-hook'.") | ||
| 43 | |||
| 44 | (make-variable-buffer-local 'view-mode-auto-exit) | ||
| 45 | 83 | ||
| 46 | (defvar view-old-buffer-read-only nil) | 84 | (defvar view-old-buffer-read-only nil) |
| 47 | (make-variable-buffer-local 'view-old-buffer-read-only) | 85 | (make-variable-buffer-local 'view-old-buffer-read-only) |
| 86 | |||
| 48 | (defvar view-old-Helper-return-blurb) | 87 | (defvar view-old-Helper-return-blurb) |
| 49 | (make-variable-buffer-local 'view-old-Helper-return-blurb) | 88 | (make-variable-buffer-local 'view-old-Helper-return-blurb) |
| 50 | 89 | ||
| 51 | (defvar view-scroll-size nil) | 90 | (defvar view-page-size nil |
| 52 | (make-variable-buffer-local 'view-scroll-size) | 91 | "Default number of lines to scroll by View page commands. |
| 92 | If nil then the local value of this is initially set to window size.") | ||
| 93 | (make-variable-buffer-local 'view-page-size) | ||
| 53 | 94 | ||
| 54 | (defvar view-last-regexp nil) | 95 | (defvar view-half-page-size nil |
| 55 | (make-variable-buffer-local 'view-last-regexp) | 96 | "Default number of lines to scroll by View half page commands. |
| 97 | If nil then the local value of this is initially set to half window size.") | ||
| 98 | (make-variable-buffer-local 'view-half-page-size) | ||
| 56 | 99 | ||
| 57 | (defvar view-exit-action nil) | 100 | (defvar view-last-regexp nil) |
| 101 | (make-variable-buffer-local 'view-last-regexp) ; Global is better??? | ||
| 102 | |||
| 103 | (defvar view-return-to-alist nil | ||
| 104 | "What to do with selected window and where to go when leaving View mode. | ||
| 105 | Added to by view-mode-enter when entering View mode. | ||
| 106 | See RETURN-TO-ALIST argument of function `view-mode-exit' for format of | ||
| 107 | view-return-to-alist.") | ||
| 108 | (make-variable-buffer-local 'view-return-to-alist) | ||
| 109 | |||
| 110 | (defvar view-exit-action nil | ||
| 111 | "\\<view-mode-map> | ||
| 112 | nil or a function with one argument (a buffer) called at exit of view mode. | ||
| 113 | The \\[view-file] and \\[view-file-other-window] commands may set this to | ||
| 114 | `kill-buffer'.") | ||
| 58 | (make-variable-buffer-local 'view-exit-action) | 115 | (make-variable-buffer-local 'view-exit-action) |
| 59 | (defvar view-return-here nil) | ||
| 60 | (make-variable-buffer-local 'view-return-here) | ||
| 61 | (defvar view-exit-position nil) | ||
| 62 | (make-variable-buffer-local 'view-exit-position) | ||
| 63 | 116 | ||
| 64 | (defvar view-overlay nil | 117 | (defvar view-overlay nil |
| 65 | "Overlay used to display where a search operation found its match. | 118 | "Overlay used to display where a search operation found its match. |
| @@ -70,243 +123,427 @@ This is local in each buffer, once it is used.") | |||
| 70 | (setq minor-mode-alist | 123 | (setq minor-mode-alist |
| 71 | (cons '(view-mode " View") minor-mode-alist))) | 124 | (cons '(view-mode " View") minor-mode-alist))) |
| 72 | 125 | ||
| 73 | (defvar view-mode-map nil) | 126 | ;; Define keymap inside defvar to make it easier to load changes. |
| 74 | (if view-mode-map | 127 | (defvar view-mode-map |
| 75 | nil | 128 | (let ((map (make-sparse-keymap))) |
| 76 | (setq view-mode-map (make-keymap)) | 129 | (define-key map "C" 'View-kill-and-leave) |
| 77 | ;; We used to call suppress-keymap here, but that isn't good in a minor mode. | 130 | (define-key map "c" 'View-leave) |
| 78 | ;; Self-inserting characters will beep anyway, since the buffer is read-only, | 131 | (define-key map "Q" 'View-quit-all) |
| 79 | ;; and we should not interfere with letters that serve as useful commands. | 132 | (define-key map "E" 'View-exit-and-edit) |
| 80 | (define-key view-mode-map "q" 'view-exit) | 133 | ; (define-key map "v" 'View-exit) |
| 81 | (define-key view-mode-map "<" 'beginning-of-buffer) | 134 | (define-key map "e" 'View-exit) |
| 82 | (define-key view-mode-map ">" 'end-of-buffer) | 135 | (define-key map "q" 'View-quit) |
| 83 | (define-key view-mode-map "\ev" 'View-scroll-lines-backward) | 136 | ; (define-key map "N" 'View-search-last-regexp-backward) |
| 84 | (define-key view-mode-map "\C-v" 'View-scroll-lines-forward) | 137 | (define-key map "p" 'View-search-last-regexp-backward) |
| 85 | (define-key view-mode-map " " 'View-scroll-lines-forward) | 138 | (define-key map "n" 'View-search-last-regexp-forward) |
| 86 | (define-key view-mode-map "\C-?" 'View-scroll-lines-backward) | 139 | ; (define-key map "?" 'View-search-regexp-backward) ; Less does this. |
| 87 | (define-key view-mode-map "\n" 'View-scroll-one-more-line) | 140 | (define-key map "\\" 'View-search-regexp-backward) |
| 88 | (define-key view-mode-map "\r" 'View-scroll-one-more-line) | 141 | (define-key map "/" 'View-search-regexp-forward) |
| 89 | (define-key view-mode-map "z" 'View-scroll-lines-forward-set-scroll-size) | 142 | (define-key map "r" 'isearch-backward) |
| 90 | (define-key view-mode-map "g" 'View-goto-line) | 143 | (define-key map "s" 'isearch-forward) |
| 91 | (define-key view-mode-map "=" 'what-line) | 144 | (define-key map "m" 'point-to-register) |
| 92 | (define-key view-mode-map "." 'set-mark-command) | 145 | (define-key map "'" 'register-to-point) |
| 93 | (define-key view-mode-map "'" 'View-back-to-mark) | 146 | (define-key map "x" 'exchange-point-and-mark) |
| 94 | (define-key view-mode-map "@" 'View-back-to-mark) | 147 | (define-key map "@" 'View-back-to-mark) |
| 95 | (define-key view-mode-map "x" 'exchange-point-and-mark) | 148 | (define-key map "." 'set-mark-command) |
| 96 | (define-key view-mode-map "h" 'describe-mode) | 149 | (define-key map "%" 'View-goto-percent) |
| 97 | (define-key view-mode-map "?" 'describe-mode) | 150 | ; (define-key map "G" 'View-goto-line-last) |
| 98 | (define-key view-mode-map "s" 'isearch-forward) | 151 | (define-key map "g" 'View-goto-line) |
| 99 | (define-key view-mode-map "r" 'isearch-backward) | 152 | (define-key map "=" 'what-line) |
| 100 | (define-key view-mode-map "/" 'View-search-regexp-forward) | 153 | (define-key map "F" 'View-revert-buffer-scroll-page-forward) |
| 101 | (define-key view-mode-map "\\" 'View-search-regexp-backward) | 154 | ; (define-key map "k" 'View-scroll-line-backward) |
| 102 | ;; This conflicts with the standard binding of isearch-regexp-forward | 155 | (define-key map "y" 'View-scroll-line-backward) |
| 103 | (define-key view-mode-map "\e\C-s" 'View-search-regexp-forward) | 156 | ; (define-key map "j" 'View-scroll-line-forward) |
| 104 | (define-key view-mode-map "\e\C-r" 'View-search-regexp-backward) | 157 | (define-key map "\n" 'View-scroll-line-forward) |
| 105 | (define-key view-mode-map "n" 'View-search-last-regexp-forward) | 158 | (define-key map "\r" 'View-scroll-line-forward) |
| 106 | (define-key view-mode-map "p" 'View-search-last-regexp-backward) | 159 | (define-key map "u" 'View-scroll-half-page-backward) |
| 107 | ) | 160 | (define-key map "d" 'View-scroll-half-page-forward) |
| 161 | (define-key map "z" 'View-scroll-page-forward-set-page-size) | ||
| 162 | (define-key map "w" 'View-scroll-page-backward-set-page-size) | ||
| 163 | ; (define-key map "b" 'View-scroll-page-backward) | ||
| 164 | (define-key map "\C-?" 'View-scroll-page-backward) | ||
| 165 | ; (define-key map "f" 'View-scroll-page-forward) | ||
| 166 | (define-key map " " 'View-scroll-page-forward) | ||
| 167 | (define-key map "o" 'View-scroll-to-buffer-end) | ||
| 168 | (define-key map ">" 'end-of-buffer) | ||
| 169 | (define-key map "<" 'beginning-of-buffer) | ||
| 170 | (define-key map "-" 'negative-argument) | ||
| 171 | (define-key map "9" 'digit-argument) | ||
| 172 | (define-key map "8" 'digit-argument) | ||
| 173 | (define-key map "7" 'digit-argument) | ||
| 174 | (define-key map "6" 'digit-argument) | ||
| 175 | (define-key map "5" 'digit-argument) | ||
| 176 | (define-key map "4" 'digit-argument) | ||
| 177 | (define-key map "3" 'digit-argument) | ||
| 178 | (define-key map "2" 'digit-argument) | ||
| 179 | (define-key map "1" 'digit-argument) | ||
| 180 | (define-key map "0" 'digit-argument) | ||
| 181 | (define-key map "H" 'describe-mode) | ||
| 182 | (define-key map "?" 'describe-mode) ; Maybe do as less instead? | ||
| 183 | (define-key map "h" 'describe-mode) | ||
| 184 | map)) | ||
| 108 | 185 | ||
| 109 | (or (assq 'view-mode minor-mode-map-alist) | 186 | (or (assq 'view-mode minor-mode-map-alist) |
| 110 | (setq minor-mode-map-alist | 187 | (setq minor-mode-map-alist |
| 111 | (cons (cons 'view-mode view-mode-map) minor-mode-map-alist))) | 188 | (cons (cons 'view-mode view-mode-map) minor-mode-map-alist))) |
| 112 | 189 | ||
| 190 | ;; Always leave view mode before changing major mode. | ||
| 191 | ;; This is to guarantee that the buffer-read-only variable is restored. | ||
| 192 | (add-hook 'change-major-mode-hook 'view-mode-exit) | ||
| 193 | |||
| 194 | ;;; Commands that enter or exit view mode. | ||
| 113 | 195 | ||
| 114 | ;;;###autoload | 196 | ;;;###autoload |
| 115 | (defun view-file (file-name) | 197 | (defun view-file (file-name) |
| 116 | "View FILE in View mode, returning to previous buffer when done. | 198 | "View FILE in View mode, returning to previous buffer when done. |
| 117 | The usual Emacs commands are not available; instead, | 199 | Emacs commands editing the buffer contents are not available; instead, |
| 118 | a special set of commands (mostly letters and punctuation) | 200 | a special set of commands (mostly letters and punctuation) |
| 119 | are defined for moving around in the buffer. | 201 | are defined for moving around in the buffer. |
| 120 | Space scrolls forward, Delete scrolls backward. | 202 | Space scrolls forward, Delete scrolls backward. |
| 121 | For list of all View commands, type ? or h while viewing. | 203 | For list of all View commands, type H or h while viewing. |
| 122 | 204 | ||
| 123 | This command runs the normal hook `view-mode-hook'." | 205 | This command runs the normal hook `view-mode-hook'." |
| 124 | (interactive "fView file: ") | 206 | (interactive "fView file: ") |
| 125 | (let ((old-buf (current-buffer)) | 207 | (let ((had-a-buf (get-file-buffer file-name))) |
| 126 | (had-a-buf (get-file-buffer file-name)) | 208 | (view-buffer (find-file-noselect file-name) |
| 127 | (buf-to-view (find-file-noselect file-name))) | 209 | (and (not had-a-buf) 'kill-buffer)))) |
| 128 | ;; This used to pass t as second argument, | ||
| 129 | ;; but then the buffer did not show up in the Buffers menu. | ||
| 130 | (switch-to-buffer buf-to-view had-a-buf) | ||
| 131 | (view-mode-enter old-buf | ||
| 132 | (and (not had-a-buf) (not (buffer-modified-p buf-to-view)) | ||
| 133 | 'kill-buffer)))) | ||
| 134 | 210 | ||
| 135 | ;;;###autoload | 211 | ;;;###autoload |
| 136 | (defun view-file-other-window (file-name) | 212 | (defun view-file-other-window (file-name) |
| 137 | "View FILE in View mode in other window. | 213 | "View FILE in View mode in another window. |
| 138 | Return to previous buffer when done. | 214 | Return that window to its previous buffer when done. |
| 139 | The usual Emacs commands are not available; instead, | 215 | Emacs commands editing the buffer contents are not available; instead, |
| 140 | a special set of commands (mostly letters and punctuation) | 216 | a special set of commands (mostly letters and punctuation) |
| 141 | are defined for moving around in the buffer. | 217 | are defined for moving around in the buffer. |
| 142 | Space scrolls forward, Delete scrolls backward. | 218 | Space scrolls forward, Delete scrolls backward. |
| 143 | For list of all View commands, type ? or h while viewing. | 219 | For list of all View commands, type H or h while viewing. |
| 144 | 220 | ||
| 145 | This command runs the normal hook `view-mode-hook'." | 221 | This command runs the normal hook `view-mode-hook'." |
| 146 | (interactive "fView file: ") | 222 | (interactive "fIn other window view file: ") |
| 147 | (let ((old-arrangement (current-window-configuration)) | 223 | (let ((had-a-buf (get-file-buffer file-name))) |
| 148 | (had-a-buf (get-file-buffer file-name)) | 224 | (view-buffer-other-window (find-file-noselect file-name) nil |
| 149 | (buf-to-view (find-file-noselect file-name))) | 225 | (and (not had-a-buf) 'kill-buffer)))) |
| 150 | (switch-to-buffer-other-window buf-to-view) | ||
| 151 | (view-mode-enter old-arrangement | ||
| 152 | (and (not had-a-buf) (not (buffer-modified-p buf-to-view)) | ||
| 153 | 'kill-buffer)))) | ||
| 154 | 226 | ||
| 155 | ;;;###autoload | 227 | ;;;###autoload |
| 156 | (defun view-buffer (buffer-name) | 228 | (defun view-file-other-frame (file-name) |
| 157 | "View BUFFER in View mode, returning to previous buffer when done. | 229 | "View FILE in View mode in another frame. |
| 158 | The usual Emacs commands are not available; instead, | 230 | Maybe delete other frame and/or return to previous buffer when done. |
| 231 | Emacs commands editing the buffer contents are not available; instead, | ||
| 159 | a special set of commands (mostly letters and punctuation) | 232 | a special set of commands (mostly letters and punctuation) |
| 160 | are defined for moving around in the buffer. | 233 | are defined for moving around in the buffer. |
| 161 | Space scrolls forward, Delete scrolls backward. | 234 | Space scrolls forward, Delete scrolls backward. |
| 162 | For list of all View commands, type ? or h while viewing. | 235 | For list of all View commands, type H or h while viewing. |
| 163 | 236 | ||
| 164 | This command runs the normal hook `view-mode-hook'." | 237 | This command runs the normal hook `view-mode-hook'." |
| 238 | (interactive "fIn other frame view file: ") | ||
| 239 | (let ((had-a-buf (get-file-buffer file-name))) | ||
| 240 | (view-buffer-other-frame (find-file-noselect file-name) nil | ||
| 241 | (and (not had-a-buf) 'kill-buffer)))) | ||
| 242 | |||
| 243 | |||
| 244 | ;;;###autoload | ||
| 245 | (defun view-buffer (buffer-name &optional exit-action) | ||
| 246 | "View BUFFER in View mode, returning to previous buffer when done. | ||
| 247 | Emacs commands editing the buffer contents are not available; instead, | ||
| 248 | a special set of commands (mostly letters and punctuation) | ||
| 249 | are defined for moving around in the buffer. | ||
| 250 | Space scrolls forward, Delete scrolls backward. | ||
| 251 | For list of all View commands, type H or h while viewing. | ||
| 252 | |||
| 253 | This command runs the normal hook `view-mode-hook'. | ||
| 254 | |||
| 255 | Optional argument EXIT-ACTION is either nil or a function with buffer as | ||
| 256 | argument. This function is called when finished viewing buffer. | ||
| 257 | Use this argument instead of explicitly setting `view-exit-action'." | ||
| 258 | |||
| 165 | (interactive "bView buffer: ") | 259 | (interactive "bView buffer: ") |
| 166 | (let ((old-buf (current-buffer))) | 260 | (let ((undo-window (list (window-buffer) (window-start) (window-point)))) |
| 167 | (switch-to-buffer buffer-name t) | 261 | (switch-to-buffer buffer-name) |
| 168 | (view-mode-enter old-buf nil))) | 262 | (view-mode-enter (cons (selected-window) (cons nil undo-window)) |
| 263 | exit-action))) | ||
| 169 | 264 | ||
| 170 | ;;;###autoload | 265 | ;;;###autoload |
| 171 | (defun view-buffer-other-window (buffer-name not-return) | 266 | (defun view-buffer-other-window |
| 267 | (buffer-name &optional not-return exit-action) | ||
| 172 | "View BUFFER in View mode in another window. | 268 | "View BUFFER in View mode in another window. |
| 173 | Return to previous buffer when done, unless NOT-RETURN is non-nil. | 269 | Return to previous buffer when done, unless optional NOT-RETURN is non-nil. |
| 270 | Emacs commands editing the buffer contents are not available; instead, | ||
| 271 | a special set of commands (mostly letters and punctuation) | ||
| 272 | are defined for moving around in the buffer. | ||
| 273 | Space scrolls forward, Delete scrolls backward. | ||
| 274 | For list of all View commands, type H or h while viewing. | ||
| 275 | |||
| 276 | This command runs the normal hook `view-mode-hook'. | ||
| 277 | |||
| 278 | Optional argument EXIT-ACTION is either nil or a function with buffer as | ||
| 279 | argument. This function is called when finished viewing buffer. | ||
| 280 | Use this argument instead of explicitly setting `view-exit-action'." | ||
| 281 | (interactive "bIn other window view buffer:\nP") | ||
| 282 | (let* ((win ; This window will be selected by | ||
| 283 | (get-lru-window)) ; switch-to-buffer-other-window below. | ||
| 284 | (return-to | ||
| 285 | (and (not not-return) | ||
| 286 | (cons (selected-window) | ||
| 287 | (if (eq win (selected-window)) | ||
| 288 | t ; Has to make new window. | ||
| 289 | (list | ||
| 290 | (window-buffer win) ; Other windows old buffer. | ||
| 291 | (window-start win) | ||
| 292 | (window-point win))))))) | ||
| 293 | (switch-to-buffer-other-window buffer-name) | ||
| 294 | (view-mode-enter (and return-to (cons (selected-window) return-to)) | ||
| 295 | exit-action))) | ||
| 174 | 296 | ||
| 175 | The usual Emacs commands are not available in View mode; instead, | 297 | ;;;###autoload |
| 298 | (defun view-buffer-other-frame | ||
| 299 | (buffer-name &optional not-return exit-action) | ||
| 300 | "View BUFFER in View mode in another frame. | ||
| 301 | Return to previous buffer when done, unless optional NOT-RETURN is non-nil. | ||
| 302 | Emacs commands editing the buffer contents are not available; instead, | ||
| 176 | a special set of commands (mostly letters and punctuation) | 303 | a special set of commands (mostly letters and punctuation) |
| 177 | are defined for moving around in the buffer. | 304 | are defined for moving around in the buffer. |
| 178 | Space scrolls forward, Delete scrolls backward. | 305 | Space scrolls forward, Delete scrolls backward. |
| 179 | For list of all View commands, type ? or h while viewing. | 306 | For list of all View commands, type H or h while viewing. |
| 180 | 307 | ||
| 181 | This command runs the normal hook `view-mode-hook'." | 308 | This command runs the normal hook `view-mode-hook'. |
| 182 | (interactive "bView buffer:\nP") | 309 | |
| 183 | (let ((return-to (and not-return (current-window-configuration)))) | 310 | Optional argument EXIT-ACTION is either nil or a function with buffer as |
| 184 | (switch-to-buffer-other-window buffer-name) | 311 | argument. This function is called when finished viewing buffer. |
| 185 | (view-mode-enter return-to))) | 312 | Use this argument instead of explicitly setting `view-exit-action'." |
| 313 | (interactive "bView buffer in other frame: \nP") | ||
| 314 | (let ((return-to | ||
| 315 | (and (not not-return) (cons (selected-window) t)))) ; Old window. | ||
| 316 | (switch-to-buffer-other-frame buffer-name) | ||
| 317 | (view-mode-enter (and return-to (cons (selected-window) return-to)) | ||
| 318 | exit-action))) | ||
| 186 | 319 | ||
| 187 | ;;;###autoload | 320 | ;;;###autoload |
| 188 | (defun view-mode (&optional arg) | 321 | (defun view-mode (&optional arg) |
| 189 | "Toggle View mode. | 322 | ;; In the following documentation string we have to use some explicit key |
| 190 | With a prefix argument, turn View mode on if the argument is >= zero | 323 | ;; bindings instead of using the \\[] construction. The reason for this |
| 191 | and off if it is not. | 324 | ;; is that most commands have more than one key binding. |
| 192 | 325 | "Toggle View mode, a minor mode for viewing text but not editing it. | |
| 193 | If you use this function to turn on View mode, then subsequently | 326 | With arg, turn View mode on iff arg is positive. |
| 194 | \"exiting\" View mode does nothing except turn View mode off. The | 327 | |
| 195 | other way to turn View mode on is by calling `view-mode-enter'; | 328 | Emacs commands that do not change the buffer contents are available as usual. |
| 196 | that is what Lisp programs usually use. | 329 | Kill commands insert text in kill buffers but do not delete. Other commands |
| 197 | 330 | \(among them most letters and punctuation) beep and tell that the buffer is | |
| 198 | Letters do not insert themselves. Instead these commands are provided. | 331 | read-only. |
| 199 | Most commands take prefix arguments. Commands dealing with lines | 332 | \\<view-mode-map> |
| 200 | default to \"scroll size\" lines (initially size of window). | 333 | The following additional commands are provided. Most commands take prefix |
| 201 | Search commands default to a repeat count of one. | 334 | arguments. Page commands default to \"page size\" lines which is almost a whole |
| 202 | 335 | window full, or number of lines set by \\[View-scroll-page-forward-set-page-size] or \\[View-scroll-page-backward-set-page-size]. Half page commands default to | |
| 203 | M-< or < move to beginning of buffer. | 336 | and set \"half page size\" lines which initially is half a window full. Search |
| 204 | M-> or > move to end of buffer. | 337 | commands default to a repeat count of one. |
| 205 | C-v or Space scroll forward lines. | 338 | |
| 206 | M-v or DEL scroll backward lines. | 339 | H, h, ? This message. |
| 207 | CR or LF scroll forward one line (backward with prefix argument). | 340 | Digits provide prefix arguments. |
| 208 | z like Space except set number of lines for further | 341 | \\[negative-argument] negative prefix argument. |
| 209 | scrolling commands to scroll by. | 342 | \\[beginning-of-buffer] move to the beginning of buffer. |
| 210 | C-u and Digits provide prefix arguments. `-' denotes negative argument. | 343 | > move to the end of buffer. |
| 211 | = prints the current line number. | 344 | \\[View-scroll-to-buffer-end] scroll so that buffer end is at last line of window. |
| 212 | g goes to line given by prefix argument. | 345 | SPC scroll forward prefix (default \"page size\") lines. |
| 213 | / or M-C-s searches forward for regular expression | 346 | DEL scroll backward prefix (default \"page size\") lines. |
| 214 | \\ or M-C-r searches backward for regular expression. | 347 | \\[View-scroll-page-forward-set-page-size] like \\[View-scroll-page-forward] except prefix sets \"page size\". |
| 215 | n searches forward for last regular expression. | 348 | \\[View-scroll-page-backward-set-page-size] like \\[View-scroll-page-backward] except prefix sets \"page size\". |
| 216 | p searches backward for last regular expression. | 349 | \\[View-scroll-half-page-forward] scroll forward (and if prefix set) \"half page size\" lines. |
| 217 | C-@ or . set the mark. | 350 | \\[View-scroll-half-page-backward] scroll backward (and if prefix set) \"half page size\" lines. |
| 218 | x exchanges point and mark. | 351 | RET, LFD scroll forward prefix (default one) line(s). |
| 219 | C-s or s do forward incremental search. | 352 | y scroll backward prefix (default one) line(s). |
| 220 | C-r or r do reverse incremental search. | 353 | \\[View-revert-buffer-scroll-page-forward] revert-buffer if necessary and scroll forward. |
| 221 | @ or ' return to mark and pops mark ring. | 354 | Use this to view a changing file. |
| 222 | Mark ring is pushed at start of every | 355 | \\[what-line] prints the current line number. |
| 223 | successful search and when jump to line to occurs. | 356 | \\[View-goto-percent] goes prefix argument (default 100) percent into buffer. |
| 224 | The mark is set on jump to buffer start or end. | 357 | \\[View-goto-line] goes to line given by prefix argument (default first line). |
| 225 | ? or h provide help message (list of commands). | 358 | . set the mark. |
| 226 | \\[help-command] provides help (list of commands or description of a command). | 359 | x exchanges point and mark. |
| 227 | C-n moves down lines vertically. | 360 | \\[View-back-to-mark] return to mark and pops mark ring. |
| 228 | C-p moves upward lines vertically. | 361 | Mark ring is pushed at start of every successful search and when |
| 229 | C-l recenters the screen. | 362 | jump to line occurs. The mark is set on jump to buffer start or end. |
| 230 | q exit view-mode and return to previous buffer." | 363 | \\[point-to-register] save current position in character register. |
| 364 | ' go to position saved in character register. | ||
| 365 | s do forward incremental search. | ||
| 366 | r do reverse incremental search. | ||
| 367 | \\[View-search-regexp-forward] searches forward for regular expression, starting after current page. | ||
| 368 | ! and @ have a special meaning at the beginning of the regexp. | ||
| 369 | ! means search for a line with no match for regexp. @ means start | ||
| 370 | search at beginning (end for backward search) of buffer. | ||
| 371 | \\ searches backward for regular expression, starting before current page. | ||
| 372 | \\[View-search-last-regexp-forward] searches forward for last regular expression. | ||
| 373 | p searches backward for last regular expression. | ||
| 374 | \\[View-quit] quit View mode, trying to restore window and buffer to previous state. | ||
| 375 | \\[View-quit] is the normal way to leave view mode. | ||
| 376 | \\[View-exit] exit View mode but stay in current buffer. Use this if you started | ||
| 377 | viewing a buffer (file) and find out you want to edit it. | ||
| 378 | \\[View-exit-and-edit] exit View mode and make the current buffer editable. | ||
| 379 | \\[View-quit-all] quit View mode, trying to restore windows and buffer to previous state. | ||
| 380 | \\[View-leave] quit View mode and maybe switch buffers, but don't kill this buffer. | ||
| 381 | \\[View-kill-and-leave] quit View mode, kill current buffer and go back to other buffer. | ||
| 382 | |||
| 383 | The effect of \\[View-leave] , \\[View-quit] and \\[View-kill-and-leave] depends on how view-mode was entered. If it was | ||
| 384 | entered by view-file, view-file-other-window or view-file-other-frame (\\[view-file], | ||
| 385 | \\[view-file-other-window], \\[view-file-other-frame] or the dired mode v command), then \\[View-quit] will try to kill the | ||
| 386 | current buffer. If view-mode was entered from another buffer as is done by | ||
| 387 | View-buffer, View-buffer-other-window, View-buffer-other frame, View-file, | ||
| 388 | View-file-other-window or View-file-other-frame then \\[view-leave] , \\[view-quit] and \\[view-kill-and-leave] will return | ||
| 389 | to that buffer. | ||
| 390 | |||
| 391 | Entry to view-mode runs the normal hook `view-mode-hook'." | ||
| 231 | (interactive "P") | 392 | (interactive "P") |
| 232 | (setq view-mode | 393 | (cond |
| 233 | (if (null arg) | 394 | ((and arg |
| 234 | (not view-mode) | 395 | (if (> (prefix-numeric-value arg) 0) view-mode (not view-mode))) |
| 235 | (> (prefix-numeric-value arg) 0))) | 396 | ()) ; Do nothing if already OK. |
| 236 | (force-mode-line-update)) | 397 | (view-mode (view-mode-exit)) |
| 237 | 398 | (t (view-mode-enter)))) | |
| 238 | (defun view-mode-enter (&optional prev-buffer action) | 399 | |
| 239 | "Enter View mode, a Minor mode for viewing text but not editing it. | 400 | ;;;###autoload |
| 240 | See the function `view-mode' for more details. | 401 | (defun view-mode-enter (&optional return-to exit-action) "\ |
| 241 | 402 | Enter View mode and set up exit from view mode depending on optional arguments. | |
| 242 | This function runs the normal hook `view-mode-hook'. | 403 | If RETURN-TO is non-nil it is added as an element to the buffer local alist |
| 243 | 404 | view-return-to-alist. | |
| 244 | \\{view-mode-map}" | 405 | Save EXIT-ACTION in buffer local variable view-exit-action. |
| 245 | ; Not interactive because dangerous things happen | 406 | RETURN-TO is either nil, meaning do nothing when exiting view mode, or |
| 246 | ; if you call it without passing a buffer as argument | 407 | \(<window> <old-window> . <old-buf-info>). |
| 247 | ; and they are not easy to fix. | 408 | <window> is a window used for viewing. |
| 248 | ; (interactive) | 409 | <old-window> is nil or the window to select after viewing. |
| 249 | (setq view-old-buffer-read-only buffer-read-only) | 410 | <old-buf-info> tells what to do with <window> when exiting. It is one of: |
| 250 | (setq view-old-Helper-return-blurb | 411 | 1) nil Do nothing. |
| 251 | (and (boundp 'Helper-return-blurb) Helper-return-blurb)) | 412 | 2) t Delete <window> or, if it is the only window, its frame. |
| 252 | 413 | 3) (<old-buff> <start> <point>) Display buffer <old-buff> with displayed text | |
| 253 | ;; Enable view-exit to make use of the data we just saved | 414 | starting at <start> and point at <point> in <window>. |
| 254 | ;; and to perform the exit action. | 415 | EXIT-ACTION is either nil or a function with buffer as argument. This function |
| 255 | (setq view-mode-auto-exit t) | 416 | is called by view-mode-exit. |
| 256 | 417 | ||
| 257 | (setq buffer-read-only t) | 418 | See the function `view-mode' for details of view mode. |
| 258 | (setq view-mode t) | 419 | |
| 259 | (setq Helper-return-blurb | 420 | This function runs the normal hook `view-mode-hook'." |
| 260 | (format "continue viewing %s" | 421 | (if return-to |
| 261 | (if (buffer-file-name) | 422 | (let ((entry (assq (car return-to) view-return-to-alist))) |
| 262 | (file-name-nondirectory (buffer-file-name)) | 423 | (if entry (setcdr entry (cdr return-to)) |
| 263 | (buffer-name)))) | 424 | (setq view-return-to-alist (cons return-to view-return-to-alist))))) |
| 264 | 425 | (if view-mode () ; Do nothing if already in view mode. | |
| 265 | (setq view-exit-action action) | 426 | (setq view-mode t |
| 266 | (setq view-return-here prev-buffer) | 427 | view-page-size (view-page-size-default view-page-size) |
| 267 | (setq view-exit-position (point-marker)) | 428 | view-half-page-size (or view-half-page-size (/ (view-window-size) 2)) |
| 268 | 429 | view-old-buffer-read-only buffer-read-only | |
| 269 | (beginning-of-line) | 430 | buffer-read-only t |
| 270 | (setq goal-column nil) | 431 | view-old-Helper-return-blurb (and (boundp 'Helper-return-blurb) |
| 271 | 432 | Helper-return-blurb) | |
| 272 | (run-hooks 'view-mode-hook) | 433 | Helper-return-blurb |
| 273 | (message "%s" | 434 | (format "continue viewing %s" |
| 274 | (substitute-command-keys | 435 | (if (buffer-file-name) |
| 275 | "Type \\[help-command] for help, \\[describe-mode] for commands, \\[view-exit] to quit."))) | 436 | (file-name-nondirectory (buffer-file-name)) |
| 276 | 437 | (buffer-name))) | |
| 277 | (defun view-exit () | 438 | view-exit-action exit-action) |
| 278 | "Exit from view-mode. | 439 | (run-hooks 'view-mode-hook) |
| 279 | If you viewed an existing buffer, that buffer returns to its previous mode. | 440 | (force-mode-line-update) |
| 280 | If you viewed a file that was not present in Emacs, its buffer is killed." | 441 | (message "%s" |
| 442 | (substitute-command-keys "\ | ||
| 443 | Type \\[help-command] for help, \\[describe-mode] for commands, \\[View-quit] to quit.")))) | ||
| 444 | |||
| 445 | (defun view-mode-exit (&optional return-to-alist exit-action all-win) | ||
| 446 | "Exit view-mode in various ways, depending on optional arguments. | ||
| 447 | RETURN-TO-ALIST, EXIT-ACTION and ALL-WIN determine what to do after | ||
| 448 | exit. | ||
| 449 | EXIT-ACTION is nil or a function that is called with current buffer as | ||
| 450 | argument. | ||
| 451 | RETURN-TO-ALIST is an alist that for some of the windows displaying the current | ||
| 452 | buffer, associate information on what to do with those windows. If ALL-WIN is | ||
| 453 | non-nil, then all windows on RETURN-TO-ALIST are restored to their old state. | ||
| 454 | If ALL-WIN is nil, then only the selected window is affected (if it is on | ||
| 455 | ALL-WIN). Each element has the format (<window> <old-window> . <old-buf-info>) | ||
| 456 | where <window> is a window displaying the current buffer and <old-buf-info> is | ||
| 457 | information on what to do with <window>. <old-buf-info> is one of: | ||
| 458 | 1) nil Do nothing. | ||
| 459 | 2) t Delete <window> or, if it is the only window, its frame. | ||
| 460 | 3) (<old-buf> <start> <point>) Display buffer <old-buf> with displayed text | ||
| 461 | starting at <start> and point at <point> in <window>. | ||
| 462 | If one of the <window> in RETURN-TO-ALIST is the selected window and the | ||
| 463 | corresponding <old-window> is a live window, then select <old-window>." | ||
| 464 | (if view-mode ; Only do something if in view mode. | ||
| 465 | (let* ((buffer (current-buffer)) | ||
| 466 | window | ||
| 467 | (sel-old (assq (selected-window) return-to-alist)) | ||
| 468 | (old-window (or (and sel-old (car (cdr sel-old))) | ||
| 469 | (and all-win (selected-window)))) | ||
| 470 | (alist (if (setq all-win | ||
| 471 | (or all-win view-exit-all-windows-at-exit)) | ||
| 472 | return-to-alist ; Try to restore all windows. | ||
| 473 | (and sel-old (list sel-old))))) ; Only selected window. | ||
| 474 | (and view-overlay (delete-overlay view-overlay)) | ||
| 475 | (setq view-mode nil | ||
| 476 | view-exit-action nil | ||
| 477 | view-return-to-alist nil | ||
| 478 | Helper-return-blurb view-old-Helper-return-blurb | ||
| 479 | buffer-read-only view-old-buffer-read-only) | ||
| 480 | (while alist ; Restore windows with info. | ||
| 481 | (if (and (window-live-p (setq window (car (car alist)))) | ||
| 482 | (eq buffer (window-buffer window))) | ||
| 483 | (let ((frame (window-frame window)) | ||
| 484 | (old-buf-info (cdr (cdr (car alist))))) | ||
| 485 | (if all-win (select-window window)) | ||
| 486 | (cond | ||
| 487 | ((and (consp old-buf-info) ; Case 3. | ||
| 488 | (buffer-live-p (car old-buf-info))) | ||
| 489 | (set-window-buffer window (car old-buf-info)) ; old-buf | ||
| 490 | (set-window-start window (car (cdr old-buf-info))) | ||
| 491 | (set-window-point window (car (cdr (cdr old-buf-info))))) | ||
| 492 | ((not (eq old-buf-info t)) nil) ; Not case 2, do nothing. | ||
| 493 | ((not (one-window-p t)) (delete-window)) | ||
| 494 | ((not (eq frame (next-frame))) ; Not the only frame, so | ||
| 495 | (if view-remove-frame-by-deleting (delete-frame frame) | ||
| 496 | (iconify-frame frame)))))) ; can safely be removed. | ||
| 497 | (setq alist (cdr alist))) | ||
| 498 | (if (and return-to-alist view-exit-all-windows-at-exit) | ||
| 499 | (replace-buffer-in-windows buffer)) | ||
| 500 | (if (window-live-p old-window) ; still existing window | ||
| 501 | (select-window old-window)) | ||
| 502 | (if (and exit-action (not (get-buffer-window buffer))) | ||
| 503 | (funcall exit-action buffer)) | ||
| 504 | (force-mode-line-update)))) | ||
| 505 | |||
| 506 | (defun View-exit () | ||
| 507 | "Exit View mode but stay in current buffer." | ||
| 281 | (interactive) | 508 | (interactive) |
| 282 | (setq view-mode nil) | 509 | (view-mode-exit)) |
| 283 | (and view-overlay (delete-overlay view-overlay)) | ||
| 284 | (force-mode-line-update) | ||
| 285 | (cond (view-mode-auto-exit | ||
| 286 | (setq buffer-read-only view-old-buffer-read-only) | ||
| 287 | (setq view-mode-auto-exit nil) | ||
| 288 | |||
| 289 | (goto-char view-exit-position) | ||
| 290 | (set-marker view-exit-position nil) | ||
| 291 | |||
| 292 | ;; Now do something to the buffer that we were viewing | ||
| 293 | ;; (such as kill it). | ||
| 294 | (let ((viewed-buffer (current-buffer)) | ||
| 295 | (action view-exit-action)) | ||
| 296 | (cond | ||
| 297 | ((bufferp view-return-here) | ||
| 298 | (switch-to-buffer view-return-here)) | ||
| 299 | ((window-configuration-p view-return-here) | ||
| 300 | (set-window-configuration view-return-here))) | ||
| 301 | (if action (funcall action viewed-buffer)))))) | ||
| 302 | |||
| 303 | (defun view-window-size () (1- (window-height))) | ||
| 304 | |||
| 305 | (defun view-scroll-size () | ||
| 306 | (min (view-window-size) (or view-scroll-size (view-window-size)))) | ||
| 307 | 510 | ||
| 308 | (defvar view-mode-hook nil | 511 | (defun View-exit-and-edit () |
| 309 | "Normal hook run when starting to view a buffer or file.") | 512 | "Exit View mode and make the current buffer editable." |
| 513 | (interactive) | ||
| 514 | (view-mode-exit) | ||
| 515 | (setq buffer-read-only nil)) | ||
| 516 | |||
| 517 | (defun View-leave () | ||
| 518 | "Quit View mode and maybe switch buffers, but don't kill this buffer." | ||
| 519 | (interactive) | ||
| 520 | (view-mode-exit view-return-to-alist)) | ||
| 521 | |||
| 522 | (defun View-quit () | ||
| 523 | "Quit View mode, trying to restore window and buffer to previous state. | ||
| 524 | Maybe kill current buffer. Try to restore selected window to previous state | ||
| 525 | and go to previous buffer or window." | ||
| 526 | (interactive) | ||
| 527 | (view-mode-exit view-return-to-alist view-exit-action)) | ||
| 528 | |||
| 529 | (defun View-quit-all () | ||
| 530 | "Quit View mode, trying to restore all windows and buffer to previous state. | ||
| 531 | Maybe kill current buffer. Try to restore all windows viewing buffer to | ||
| 532 | previous state and go to previous buffer or window." | ||
| 533 | (interactive) | ||
| 534 | (view-mode-exit view-return-to-alist view-exit-action t)) | ||
| 535 | |||
| 536 | (defun View-kill-and-leave () | ||
| 537 | "Quit View mode, kill current buffer and return to previous buffer." | ||
| 538 | (interactive) | ||
| 539 | (view-mode-exit view-return-to-alist (or view-exit-action 'kill-buffer) t)) | ||
| 540 | |||
| 541 | |||
| 542 | ;;; Some help routines. | ||
| 543 | |||
| 544 | (defun view-window-size () | ||
| 545 | ;; Window height excluding mode line. | ||
| 546 | (1- (window-height))) | ||
| 310 | 547 | ||
| 311 | ;(defun view-last-command (&optional who what) | 548 | ;(defun view-last-command (&optional who what) |
| 312 | ; (setq view-last-command-entry this-command) | 549 | ; (setq view-last-command-entry this-command) |
| @@ -321,133 +558,287 @@ If you viewed a file that was not present in Emacs, its buffer is killed." | |||
| 321 | ; (funcall view-last-command view-last-command-argument)) | 558 | ; (funcall view-last-command view-last-command-argument)) |
| 322 | ; (setq this-command view-last-command-entry)) | 559 | ; (setq this-command view-last-command-entry)) |
| 323 | 560 | ||
| 324 | (defun View-goto-line (line) | 561 | (defun view-recenter () |
| 325 | "Move to line LINE in View mode. | 562 | ;; Center point in window. |
| 326 | Display is centered at LINE. Sets mark at starting position and pushes | 563 | (recenter (/ (view-window-size) 2))) |
| 327 | mark ring." | 564 | |
| 565 | (defun view-page-size-default (lines) | ||
| 566 | ;; Get page size. | ||
| 567 | (let ((default (- (view-window-size) next-screen-context-lines))) | ||
| 568 | (if (or (null lines) (zerop (setq lines (prefix-numeric-value lines)))) | ||
| 569 | default | ||
| 570 | (min (abs lines) default)))) | ||
| 571 | |||
| 572 | (defun view-set-half-page-size-default (lines) | ||
| 573 | ;; Get and maybe set half page size. | ||
| 574 | (if (not lines) view-half-page-size | ||
| 575 | (setq view-half-page-size | ||
| 576 | (if (zerop (setq lines (prefix-numeric-value lines))) | ||
| 577 | (/ (view-window-size) 2) | ||
| 578 | (view-page-size-default lines))))) | ||
| 579 | |||
| 580 | |||
| 581 | ;;; Commands for moving around in the buffer. | ||
| 582 | |||
| 583 | (defun View-goto-percent (&optional percent) | ||
| 584 | "Move to end (or prefix PERCENT) of buffer in View mode. | ||
| 585 | Display is centered at point. | ||
| 586 | Sets mark at starting position and pushes mark ring." | ||
| 587 | (interactive "P") | ||
| 588 | (push-mark) | ||
| 589 | (goto-char | ||
| 590 | (if percent | ||
| 591 | (+ (point-min) | ||
| 592 | (floor (* (- (point-max) (point-min)) 0.01 | ||
| 593 | (max 0 (min 100 (prefix-numeric-value percent)))))) | ||
| 594 | (point-max))) | ||
| 595 | (view-recenter)) | ||
| 596 | |||
| 597 | ;(defun View-goto-line-last (&optional line) | ||
| 598 | ;"Move to last (or prefix LINE) line in View mode. | ||
| 599 | ;Display is centered at LINE. | ||
| 600 | ;Sets mark at starting position and pushes mark ring." | ||
| 601 | ; (interactive "P") | ||
| 602 | ; (push-mark) | ||
| 603 | ; (if line (goto-line (prefix-numeric-value line)) | ||
| 604 | ; (goto-char (point-max)) | ||
| 605 | ; (beginning-of-line)) | ||
| 606 | ; (view-recenter)) | ||
| 607 | |||
| 608 | (defun View-goto-line (&optional line) | ||
| 609 | "Move to first (or prefix LINE) line in View mode. | ||
| 610 | Display is centered at LINE. | ||
| 611 | Sets mark at starting position and pushes mark ring." | ||
| 328 | (interactive "p") | 612 | (interactive "p") |
| 329 | (push-mark) | 613 | (push-mark) |
| 330 | (goto-line line) | 614 | (goto-line line) |
| 331 | (recenter (/ (view-window-size) 2))) | 615 | (view-recenter)) |
| 332 | 616 | ||
| 333 | (defun View-scroll-lines-forward (&optional lines) | 617 | (defun View-scroll-to-buffer-end () |
| 334 | "Scroll forward in View mode, or exit if end of text is visible. | 618 | "Scroll backward or forward so that buffer end is at last line of window." |
| 335 | No arg means whole window full, or number of lines set by \\[View-scroll-lines-forward-set-scroll-size]. | 619 | (interactive) |
| 336 | Arg is number of lines to scroll." | 620 | (let ((p (if (pos-visible-in-window-p (point-max)) (point)))) |
| 621 | (goto-char (point-max)) | ||
| 622 | (recenter -1) | ||
| 623 | (and p (goto-char p)))) | ||
| 624 | |||
| 625 | (defun view-scroll-lines (lines backward default maxdefault) | ||
| 626 | ;; This function does the job for all the scrolling commands. | ||
| 627 | ;; Scroll forward LINES lines. If BACKWARD is true scroll backwards. | ||
| 628 | ;; If LINES is negative scroll in the other direction. If LINES is 0 or nil, | ||
| 629 | ;; scroll DEFAULT lines. If MAXDEFAULT is true then scroll no more than a | ||
| 630 | ;; window full. | ||
| 631 | (if (or (null lines) (zerop (setq lines (prefix-numeric-value lines)))) | ||
| 632 | (setq lines default)) | ||
| 633 | (if (< lines 0) | ||
| 634 | (progn (setq backward (not backward)) (setq lines (- lines)))) | ||
| 635 | (setq default (view-page-size-default nil)) ; Max scrolled at a time. | ||
| 636 | (if maxdefault (setq lines (min lines default))) | ||
| 637 | (cond | ||
| 638 | (backward (scroll-down lines)) | ||
| 639 | ((view-really-at-end) | ||
| 640 | (if view-scroll-auto-exit (View-quit) | ||
| 641 | (ding) | ||
| 642 | (view-end-message))) | ||
| 643 | (t (while (> lines default) | ||
| 644 | (scroll-up default) | ||
| 645 | (setq lines (- lines default)) | ||
| 646 | (if (view-really-at-end) (setq lines 0))) | ||
| 647 | (scroll-up lines) | ||
| 648 | (if (view-really-at-end) (view-end-message)) | ||
| 649 | (move-to-window-line -1) | ||
| 650 | (beginning-of-line)))) | ||
| 651 | |||
| 652 | (defun view-really-at-end () | ||
| 653 | ;; Return true if buffer end visible. Maybe revert buffer and test. | ||
| 654 | (and (pos-visible-in-window-p (point-max)) | ||
| 655 | (let ((buf (current-buffer)) | ||
| 656 | (bufname (buffer-name)) | ||
| 657 | (file (buffer-file-name))) | ||
| 658 | (or (not view-try-extend-at-buffer-end) | ||
| 659 | (not file) | ||
| 660 | (verify-visited-file-modtime buf) | ||
| 661 | (not (file-exists-p file)) | ||
| 662 | (and (buffer-modified-p buf) | ||
| 663 | (setq file (file-name-nondirectory file)) | ||
| 664 | (not (yes-or-no-p | ||
| 665 | (format | ||
| 666 | "File %s changed on disk. Discard your edits%s? " | ||
| 667 | file | ||
| 668 | (if (string= bufname file) "" | ||
| 669 | (concat " in " bufname)))))) | ||
| 670 | (progn (revert-buffer t t t) | ||
| 671 | (pos-visible-in-window-p (point-max))))))) | ||
| 672 | |||
| 673 | (defun view-end-message () | ||
| 674 | ;; Tell that we are at end of buffer. | ||
| 675 | (goto-char (point-max)) | ||
| 676 | (message "End of buffer. Type %s to quit viewing." | ||
| 677 | (substitute-command-keys | ||
| 678 | (if view-scroll-auto-exit "\\[View-scroll-page-forward]" | ||
| 679 | "\\[View-quit]")))) | ||
| 680 | |||
| 681 | (defun View-scroll-page-forward (&optional lines) | ||
| 682 | "Scroll \"page size\" or prefix LINES lines forward in View mode. | ||
| 683 | This will exit if end of text is visible and view-scroll-auto-exit is non-nil. | ||
| 684 | \"page size\" is whole window full, or number of lines set by | ||
| 685 | \\[View-scroll-page-forward-set-page-size] or | ||
| 686 | \\[View-scroll-page-backward-set-page-size]. | ||
| 687 | If LINES is more than a window-full, only the last window-full is shown." | ||
| 337 | (interactive "P") | 688 | (interactive "P") |
| 338 | (setq lines | 689 | (view-scroll-lines lines nil view-page-size nil)) |
| 339 | (if lines (prefix-numeric-value lines) | 690 | |
| 340 | (view-scroll-size))) | 691 | (defun View-scroll-page-backward (&optional lines) |
| 341 | (if (and (pos-visible-in-window-p (point-max)) | 692 | "Scroll \"page size\" or prefix LINES lines backward in View mode. |
| 342 | ;; Allow scrolling backward at the end of the buffer. | 693 | See further View-scroll-page-forward." |
| 343 | (> lines 0) | ||
| 344 | view-mode-auto-exit) | ||
| 345 | (view-exit) | ||
| 346 | ;; (view-last-command 'View-scroll-lines-forward lines) | ||
| 347 | (if (>= lines (view-window-size)) | ||
| 348 | (scroll-up nil) | ||
| 349 | (if (>= (- lines) (view-window-size)) | ||
| 350 | (scroll-down nil) | ||
| 351 | (scroll-up lines))) | ||
| 352 | (cond ((pos-visible-in-window-p (point-max)) | ||
| 353 | (goto-char (point-max)) | ||
| 354 | (message "%s" | ||
| 355 | (substitute-command-keys | ||
| 356 | "End. Type \\[view-exit] to quit viewing.")))) | ||
| 357 | (move-to-window-line -1) | ||
| 358 | (beginning-of-line))) | ||
| 359 | |||
| 360 | (defun View-scroll-lines-forward-set-scroll-size (&optional lines) | ||
| 361 | "Scroll forward LINES lines in View mode, setting the \"scroll size\". | ||
| 362 | This is the number of lines which \\[View-scroll-lines-forward] and \\[View-scroll-lines-backward] scroll by default. | ||
| 363 | The absolute value of LINES is used, so this command can be used to scroll | ||
| 364 | backwards (but \"scroll size\" is always positive). If LINES is greater than | ||
| 365 | window height or omitted, then window height is assumed. If LINES is less | ||
| 366 | than window height then scrolling context is provided from previous screen." | ||
| 367 | (interactive "P") | 694 | (interactive "P") |
| 368 | (if (not lines) | 695 | (view-scroll-lines lines t view-page-size nil)) |
| 369 | (setq view-scroll-size (view-window-size)) | 696 | |
| 370 | (setq lines (prefix-numeric-value lines)) | 697 | (defun View-scroll-page-forward-set-page-size (&optional lines) |
| 371 | (setq view-scroll-size | 698 | "Scroll forward prefix LINES lines in View mode, setting the \"page size\". |
| 372 | (min (if (> lines 0) lines (- lines)) (view-window-size)))) | 699 | This is the number of lines which \\[View-scroll-page-forward] and |
| 373 | (View-scroll-lines-forward lines)) | 700 | \\[View-scroll-page-backward] scroll by default. If LINES is omitted or = 0, |
| 374 | 701 | sets \"page size\" to window height and scrolls forward that much, otherwise | |
| 375 | (defun View-scroll-one-more-line (&optional arg) | 702 | scrolls forward LINES lines and sets \"page size\" to the minimum of window |
| 376 | "Scroll one more line up in View mode. | 703 | height and the absolute value of LINES. |
| 377 | With ARG scroll one line down." | 704 | See further View-scroll-page-forward." |
| 378 | (interactive "P") | 705 | (interactive "P") |
| 379 | (View-scroll-lines-forward (if (not arg) 1 -1))) | 706 | (view-scroll-lines lines nil |
| 707 | (setq view-page-size (view-page-size-default lines)) | ||
| 708 | nil)) | ||
| 380 | 709 | ||
| 381 | (defun View-scroll-lines-backward (&optional lines) | 710 | (defun View-scroll-page-backward-set-page-size (&optional lines) |
| 382 | "Scroll backward in View mode. | 711 | "Scroll backward prefix LINES lines in View mode, setting the \"page size\". |
| 383 | No arg means whole window full, or number of lines set by \\[View-scroll-lines-forward-set-scroll-size]. | 712 | See further View-scroll-page-forward-set-page-size." |
| 384 | Arg is number of lines to scroll." | ||
| 385 | (interactive "P") | 713 | (interactive "P") |
| 386 | (View-scroll-lines-forward (if lines | 714 | (view-scroll-lines lines t |
| 387 | (- (prefix-numeric-value lines)) | 715 | (setq view-page-size (view-page-size-default lines)) |
| 388 | (- (view-scroll-size))))) | 716 | nil)) |
| 389 | 717 | ||
| 718 | (defun View-scroll-line-forward (&optional lines) | ||
| 719 | "Scroll forward one line (or prefix LINES lines) in View mode. | ||
| 720 | See further View-scroll-page-forward, but note that scrolling is limited | ||
| 721 | to minimum of LINES and one window-full." | ||
| 722 | (interactive "P") | ||
| 723 | (view-scroll-lines lines nil 1 t)) | ||
| 724 | |||
| 725 | (defun View-scroll-line-backward (&optional lines) | ||
| 726 | "Scroll backward one line (or prefix LINES lines) in View mode. | ||
| 727 | See further View-scroll-line-forward." | ||
| 728 | (interactive "P") | ||
| 729 | (view-scroll-lines lines t 1 t)) | ||
| 730 | |||
| 731 | (defun View-scroll-half-page-forward (&optional lines) | ||
| 732 | "Scroll forward \"half page size\" (or prefix LINES) lines in View mode. | ||
| 733 | If LINES is not omitted, the \"half page size\" is set to the minimum of | ||
| 734 | window height and the absolute value of LINES. | ||
| 735 | LINES=0 resets \"half page size\" to half window height." | ||
| 736 | (interactive "P") | ||
| 737 | (view-scroll-lines lines nil (view-set-half-page-size-default lines) t)) | ||
| 738 | |||
| 739 | (defun View-scroll-half-page-backward (&optional lines) | ||
| 740 | "Scroll backward \"half page size\" (or prefix LINES) lines in View mode. | ||
| 741 | See further View-scroll-half-page-forward." | ||
| 742 | (interactive "P") | ||
| 743 | (view-scroll-lines lines t (view-set-half-page-size-default lines) t)) | ||
| 744 | |||
| 745 | (defun View-revert-buffer-scroll-page-forward (&optional lines) "\ | ||
| 746 | Scroll \"page size\" or prefix LINES lines forward reverting buffer if needed. | ||
| 747 | If buffer has not been changed and the corresponding file is newer, first | ||
| 748 | revert the buffer, then scroll. | ||
| 749 | This command is useful if you are viewing a changing file. | ||
| 750 | \"page size\" is whole window full, or number of lines set by | ||
| 751 | \\[View-scroll-page-forward-set-page-size] or | ||
| 752 | \\[View-scroll-page-backward-set-page-size]. | ||
| 753 | If LINES is more than a window-full, only the last window-full is shown." | ||
| 754 | (interactive "P") | ||
| 755 | (let ((view-mode-auto-exit nil) | ||
| 756 | (view-try-extend-at-buffer-end t)) | ||
| 757 | (view-scroll-lines lines nil view-page-size nil))) | ||
| 758 | |||
| 759 | (defun View-back-to-mark (&optional ignore) | ||
| 760 | "Return to last mark set in View mode, else beginning of file. | ||
| 761 | Displays line at center of window. Pops mark ring so successive | ||
| 762 | invocations return to earlier marks." | ||
| 763 | (interactive) | ||
| 764 | (goto-char (or (mark t) (point-min))) | ||
| 765 | (pop-mark) | ||
| 766 | (view-recenter)) | ||
| 767 | |||
| 390 | (defun View-search-regexp-forward (n regexp) | 768 | (defun View-search-regexp-forward (n regexp) |
| 391 | "Search forward for Nth occurrence of REGEXP. | 769 | "Search forward for first (or prefix Nth) occurrence of REGEXP in View mode. |
| 392 | Displays line found at center of window. REGEXP is remembered for | 770 | Displays line found at center of window. REGEXP is remembered for searching |
| 393 | searching with \\[View-search-last-regexp-forward] and \\[View-search-last-regexp-backward]. Sets mark at starting position and pushes mark ring. | 771 | with \\[View-search-last-regexp-forward] and \\[View-search-last-regexp-backward]. Sets mark at starting position and pushes mark ring. |
| 772 | Characters @ or ! or combined as @! or !@ are special if entered at the | ||
| 773 | beginning of REGEXP. They modify the search rather than become part of pattern | ||
| 774 | searched for. @ means start search at the beginning of buffer. ! means search | ||
| 775 | for line that not contains match for pattern. If REGEXP only consist of these | ||
| 776 | control characters, then an earlier remembered REGEXP is used. | ||
| 394 | 777 | ||
| 395 | The variable `view-highlight-face' controls the face that is used | 778 | The variable `view-highlight-face' controls the face that is used |
| 396 | for highlighting the match that is found." | 779 | for highlighting the match that is found." |
| 397 | (interactive "p\nsSearch forward (regexp): ") | 780 | (interactive "p\nsSearch forward (regexp): ") |
| 398 | ;;;(view-last-command 'View-search-last-regexp-forward n) | 781 | (view-search n regexp)) |
| 399 | (view-search n (if (equal regexp "") view-last-regexp regexp))) | ||
| 400 | 782 | ||
| 401 | (defun View-search-regexp-backward (n regexp) | 783 | (defun View-search-regexp-backward (n regexp) |
| 402 | "Search backward from window start for Nth instance of REGEXP. | 784 | "Search backward for first (or prefix Nth) occurrence of REGEXP in View mode. |
| 403 | Displays line found at center of window. REGEXP is remembered for | 785 | Displays line found at center of window. REGEXP is remembered for searching |
| 404 | searching with \\[View-search-last-regexp-forward] and \\[View-search-last-regexp-backward]. Sets mark at starting position and pushes mark ring. | 786 | with \\[View-search-last-regexp-forward] and \\[View-search-last-regexp-backward]. Sets mark at starting position and pushes mark ring. |
| 787 | Characters @ or ! or combined as @! or !@ are special if entered at the | ||
| 788 | beginning of REGEXP. They modify the search rather than become part of pattern | ||
| 789 | searched for. @ means start search at the end of buffer. ! means search | ||
| 790 | for line that not contains match for pattern. If REGEXP only consist of these | ||
| 791 | control characters, then an earlier remembered REGEXP is used. | ||
| 405 | 792 | ||
| 406 | The variable `view-highlight-face' controls the face that is used | 793 | The variable `view-highlight-face' controls the face that is used |
| 407 | for highlighting the match that is found." | 794 | for highlighting the match that is found." |
| 408 | (interactive "p\nsSearch backward (regexp): ") | 795 | (interactive "p\nsSearch backward (regexp): ") |
| 409 | (View-search-regexp-forward (- n) | 796 | (view-search (- n) regexp)) |
| 410 | (if (equal regexp "") view-last-regexp regexp))) | ||
| 411 | 797 | ||
| 412 | (defun View-search-last-regexp-forward (n) | 798 | (defun View-search-last-regexp-forward (n) "\ |
| 413 | "Search forward from window end for Nth instance of last regexp. | 799 | Search forward for first (or prefix Nth) instance of last regexp in View mode. |
| 414 | Displays line found at center of window. Sets mark at starting position | 800 | Displays line found at center of window. Sets mark at starting position and |
| 415 | and pushes mark ring. | 801 | pushes mark ring. |
| 416 | 802 | ||
| 417 | The variable `view-highlight-face' controls the face that is used | 803 | The variable `view-highlight-face' controls the face that is used |
| 418 | for highlighting the match that is found." | 804 | for highlighting the match that is found." |
| 419 | (interactive "p") | 805 | (interactive "p") |
| 420 | (if view-last-regexp | 806 | (view-search n nil)) |
| 421 | (View-search-regexp-forward n view-last-regexp) | ||
| 422 | (error "No previous View-mode search"))) | ||
| 423 | 807 | ||
| 424 | (defun View-search-last-regexp-backward (n) | 808 | (defun View-search-last-regexp-backward (n) "\ |
| 425 | "Search backward from window start for Nth instance of last regexp. | 809 | Search backward for first (or prefix Nth) instance of last regexp in View mode. |
| 426 | Displays line found at center of window. Sets mark at starting position and | 810 | Displays line found at center of window. Sets mark at starting position and |
| 427 | pushes mark ring. | 811 | pushes mark ring. |
| 428 | 812 | ||
| 429 | The variable `view-highlight-face' controls the face that is used | 813 | The variable `view-highlight-face' controls the face that is used |
| 430 | for highlighting the match that is found." | 814 | for highlighting the match that is found." |
| 431 | (interactive "p") | 815 | (interactive "p") |
| 432 | (if view-last-regexp | 816 | (view-search (- n) nil)) |
| 433 | (View-search-regexp-backward n view-last-regexp) | ||
| 434 | (error "No previous View-mode search"))) | ||
| 435 | 817 | ||
| 436 | (defun View-back-to-mark (&optional ignore) | ||
| 437 | "Return to last mark set in View mode, else beginning of file. | ||
| 438 | Displays line at center of window. Pops mark ring so successive | ||
| 439 | invocations return to earlier marks." | ||
| 440 | (interactive) | ||
| 441 | (goto-char (or (mark t) (point-min))) | ||
| 442 | (pop-mark) | ||
| 443 | (recenter (/ (view-window-size) 2))) | ||
| 444 | |||
| 445 | (defun view-search (times regexp) | 818 | (defun view-search (times regexp) |
| 446 | (setq view-last-regexp regexp) | 819 | ;; This function does the job for all the view-search commands. |
| 447 | (let (where) | 820 | (let (where no end ln) |
| 821 | (cond | ||
| 822 | ((and regexp (> (length regexp) 0) | ||
| 823 | (or (not (memq (string-to-char regexp) '(?! ?@))) | ||
| 824 | (progn | ||
| 825 | (if (member (substring regexp 0 2) '("!@" "@!")) | ||
| 826 | (setq end t no t ln 2) | ||
| 827 | (setq no (not (setq end (eq ?@ (string-to-char regexp)))) | ||
| 828 | ln 1)) | ||
| 829 | (> (length (setq regexp (substring regexp ln))) 0)))) | ||
| 830 | (setq view-last-regexp (if no (list regexp) regexp))) | ||
| 831 | ((consp view-last-regexp) | ||
| 832 | (setq regexp (car view-last-regexp)) | ||
| 833 | (if (not (setq no (not no))) (setq view-last-regexp regexp))) | ||
| 834 | (view-last-regexp (setq regexp view-last-regexp) | ||
| 835 | (if no (setq view-last-regexp (list regexp)))) | ||
| 836 | (t (error "No previous View-mode search"))) | ||
| 448 | (save-excursion | 837 | (save-excursion |
| 449 | (move-to-window-line (if (< times 0) 0 -1)) | 838 | (if end (goto-char (if (< times 0) (point-max) (point-min))) |
| 450 | (if (re-search-forward regexp nil t times) | 839 | (move-to-window-line (if (< times 0) 0 -1))) |
| 840 | (if (if no (view-search-no-match-lines times regexp) | ||
| 841 | (re-search-forward regexp nil t times)) | ||
| 451 | (setq where (point)))) | 842 | (setq where (point)))) |
| 452 | (if where | 843 | (if where |
| 453 | (progn | 844 | (progn |
| @@ -459,11 +850,33 @@ invocations return to earlier marks." | |||
| 459 | (make-overlay (match-beginning 0) (match-end 0)))) | 850 | (make-overlay (match-beginning 0) (match-end 0)))) |
| 460 | (overlay-put view-overlay 'face view-highlight-face) | 851 | (overlay-put view-overlay 'face view-highlight-face) |
| 461 | (beginning-of-line) | 852 | (beginning-of-line) |
| 462 | (recenter (/ (view-window-size) 2))) | 853 | (view-recenter)) |
| 463 | (message "Can't find occurrence %d of %s" times regexp) | 854 | (message "Can't find occurrence %d of %s%s" |
| 855 | times (if no "no " "") regexp) | ||
| 464 | (sit-for 4)))) | 856 | (sit-for 4)))) |
| 465 | 857 | ||
| 466 | 858 | (defun view-search-no-match-lines (times regexp) | |
| 859 | ;; Search for the TIMESt occurrence of line with no match for REGEXP. | ||
| 860 | (let ((back (and (< times 0) (setq times (- times)) -1)) | ||
| 861 | n) | ||
| 862 | (while (> times 0) | ||
| 863 | (save-excursion (beginning-of-line (if back (- times) (1+ times))) | ||
| 864 | (setq n (point))) | ||
| 865 | (setq times | ||
| 866 | (cond | ||
| 867 | ((< (count-lines (point) n) times) -1) ; Not enough lines. | ||
| 868 | ((or (null (re-search-forward regexp nil t back)) | ||
| 869 | (if back (and (< (match-end 0) n) | ||
| 870 | (> (count-lines (match-end 0) n) 1)) | ||
| 871 | (and (< n (match-beginning 0)) | ||
| 872 | (> (count-lines n (match-beginning 0)) 1)))) | ||
| 873 | 0) ; No match within lines. | ||
| 874 | (back (count-lines (max n (match-beginning 0)) (match-end 0))) | ||
| 875 | (t (count-lines (match-beginning 0) (min n (match-end 0)))))) | ||
| 876 | (goto-char n)) | ||
| 877 | (and (zerop times) (looking-at "^.*$")))) | ||
| 878 | |||
| 879 | |||
| 467 | (provide 'view) | 880 | (provide 'view) |
| 468 | 881 | ||
| 469 | ;;; view.el ends here | 882 | ;;; view.el ends here |