(sh-alias-alist): Recognize lignux.
[bpt/emacs.git] / lisp / view.el
CommitLineData
d501f516
ER
1;;; view.el --- peruse file or buffer without editing.
2
bab0c3c1 3;; Copyright (C) 1985, 1989, 1994, 1995 Free Software Foundation, Inc.
eea8d4ef 4
e5167999
ER
5;; Author: K. Shane Hartman
6;; Maintainer: FSF
e6211d55
RS
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
e5167999 12;; the Free Software Foundation; either version 2, or (at your option)
e6211d55
RS
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b578f267
EN
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
e6211d55 24
c91c4e6d
ER
25;;; Commentary:
26
bab0c3c1 27;; This package provides the `view' minor mode documented in the Emacs
c91c4e6d
ER
28;; user's manual.
29
e5167999 30;;; Code:
e6211d55 31
82380f84
RS
32;;;###autoload
33(defvar view-highlight-face 'highlight
34 "*The overlay face used for highlighting the match found by View mode search.")
35
c88daaef 36(defvar view-mode nil "Non-nil if View mode is enabled.")
bab0c3c1
KH
37(make-variable-buffer-local 'view-mode)
38
c88daaef
RS
39(defvar view-mode-auto-exit nil
40 "Non-nil means scrolling past the end of buffer exits View mode.")
41(make-variable-buffer-local 'view-mode-auto-exit)
42
43(defvar view-old-buffer-read-only nil)
44(make-variable-buffer-local 'view-old-buffer-read-only)
45(defvar view-old-Helper-return-blurb)
46(make-variable-buffer-local 'view-old-Helper-return-blurb)
47
48(defvar view-scroll-size nil)
49(make-variable-buffer-local 'view-scroll-size)
50
51(defvar view-last-regexp nil)
52(make-variable-buffer-local 'view-last-regexp)
53
54(defvar view-exit-action nil)
55(make-variable-buffer-local 'view-exit-action)
56(defvar view-return-here nil)
57(make-variable-buffer-local 'view-return-here)
58(defvar view-exit-position nil)
59(make-variable-buffer-local 'view-exit-position)
60
4fe11426 61(defvar view-overlay nil
82380f84
RS
62 "Overlay used to display where a search operation found its match.
63This is local in each buffer, once it is used.")
4fe11426
RS
64(make-variable-buffer-local 'view-overlay)
65
bab0c3c1
KH
66(or (assq 'view-mode minor-mode-alist)
67 (setq minor-mode-alist
68 (cons '(view-mode " View") minor-mode-alist)))
69
e6211d55
RS
70(defvar view-mode-map nil)
71(if view-mode-map
72 nil
73 (setq view-mode-map (make-keymap))
b2926fb3
RS
74 ;; We used to call suppress-keymap here, but that isn't good in a minor mode.
75 ;; Self-inserting characters will beep anyway, since the buffer is read-only,
76 ;; and we should not interfere with letters that serve as useful commands.
e6211d55 77 (define-key view-mode-map "q" 'view-exit)
e6211d55
RS
78 (define-key view-mode-map "<" 'beginning-of-buffer)
79 (define-key view-mode-map ">" 'end-of-buffer)
80 (define-key view-mode-map "\ev" 'View-scroll-lines-backward)
81 (define-key view-mode-map "\C-v" 'View-scroll-lines-forward)
82 (define-key view-mode-map " " 'View-scroll-lines-forward)
bab0c3c1 83 (define-key view-mode-map "\C-?" 'View-scroll-lines-backward)
e6211d55
RS
84 (define-key view-mode-map "\n" 'View-scroll-one-more-line)
85 (define-key view-mode-map "\r" 'View-scroll-one-more-line)
e6211d55
RS
86 (define-key view-mode-map "z" 'View-scroll-lines-forward-set-scroll-size)
87 (define-key view-mode-map "g" 'View-goto-line)
88 (define-key view-mode-map "=" 'what-line)
89 (define-key view-mode-map "." 'set-mark-command)
e6211d55
RS
90 (define-key view-mode-map "'" 'View-back-to-mark)
91 (define-key view-mode-map "@" 'View-back-to-mark)
92 (define-key view-mode-map "x" 'exchange-point-and-mark)
bc15ba42
RS
93 (define-key view-mode-map "h" 'describe-mode)
94 (define-key view-mode-map "?" 'describe-mode)
e6211d55
RS
95 (define-key view-mode-map "s" 'isearch-forward)
96 (define-key view-mode-map "r" 'isearch-backward)
97 (define-key view-mode-map "/" 'View-search-regexp-forward)
98 (define-key view-mode-map "\\" 'View-search-regexp-backward)
99 ;; This conflicts with the standard binding of isearch-regexp-forward
100 (define-key view-mode-map "\e\C-s" 'View-search-regexp-forward)
101 (define-key view-mode-map "\e\C-r" 'View-search-regexp-backward)
102 (define-key view-mode-map "n" 'View-search-last-regexp-forward)
103 (define-key view-mode-map "p" 'View-search-last-regexp-backward)
104 )
105
c88daaef
RS
106(or (assq 'view-mode minor-mode-map-alist)
107 (setq minor-mode-map-alist
108 (cons (cons 'view-mode view-mode-map) minor-mode-map-alist)))
109
e6211d55 110
7229064d 111;;;###autoload
e6211d55
RS
112(defun view-file (file-name)
113 "View FILE in View mode, returning to previous buffer when done.
114The usual Emacs commands are not available; instead,
115a special set of commands (mostly letters and punctuation)
116are defined for moving around in the buffer.
117Space scrolls forward, Delete scrolls backward.
118For list of all View commands, type ? or h while viewing.
119
bd0d2c58 120This command runs the normal hook `view-mode-hook'."
e6211d55
RS
121 (interactive "fView file: ")
122 (let ((old-buf (current-buffer))
123 (had-a-buf (get-file-buffer file-name))
124 (buf-to-view (find-file-noselect file-name)))
7392e4d3
RS
125 ;; This used to pass t as second argument,
126 ;; but then the buffer did not show up in the Buffers menu.
872c2845 127 (switch-to-buffer buf-to-view had-a-buf)
c88daaef
RS
128 (view-mode-enter old-buf
129 (and (not had-a-buf) (not (buffer-modified-p buf-to-view))
130 'kill-buffer))))
e6211d55 131
b82fef5c
JB
132;;;###autoload
133(defun view-file-other-window (file-name)
134 "View FILE in View mode in other window.
135Return to previous buffer when done.
136The usual Emacs commands are not available; instead,
137a special set of commands (mostly letters and punctuation)
138are defined for moving around in the buffer.
139Space scrolls forward, Delete scrolls backward.
140For list of all View commands, type ? or h while viewing.
141
bd0d2c58 142This command runs the normal hook `view-mode-hook'."
b82fef5c
JB
143 (interactive "fView file: ")
144 (let ((old-arrangement (current-window-configuration))
145 (had-a-buf (get-file-buffer file-name))
146 (buf-to-view (find-file-noselect file-name)))
7392e4d3 147 (switch-to-buffer-other-window buf-to-view)
c88daaef
RS
148 (view-mode-enter old-arrangement
149 (and (not had-a-buf) (not (buffer-modified-p buf-to-view))
150 'kill-buffer))))
b82fef5c 151
7229064d 152;;;###autoload
e6211d55
RS
153(defun view-buffer (buffer-name)
154 "View BUFFER in View mode, returning to previous buffer when done.
155The usual Emacs commands are not available; instead,
156a special set of commands (mostly letters and punctuation)
157are defined for moving around in the buffer.
158Space scrolls forward, Delete scrolls backward.
159For list of all View commands, type ? or h while viewing.
160
bd0d2c58 161This command runs the normal hook `view-mode-hook'."
e6211d55
RS
162 (interactive "bView buffer: ")
163 (let ((old-buf (current-buffer)))
164 (switch-to-buffer buffer-name t)
c88daaef 165 (view-mode-enter old-buf nil)))
e6211d55 166
b82fef5c
JB
167;;;###autoload
168(defun view-buffer-other-window (buffer-name not-return)
bab0c3c1
KH
169 "View BUFFER in View mode in another window.
170Return to previous buffer when done, unless NOT-RETURN is non-nil.
5c05f569
RS
171
172The usual Emacs commands are not available in View mode; instead,
b82fef5c
JB
173a special set of commands (mostly letters and punctuation)
174are defined for moving around in the buffer.
175Space scrolls forward, Delete scrolls backward.
176For list of all View commands, type ? or h while viewing.
177
bd0d2c58 178This command runs the normal hook `view-mode-hook'."
79d0c1e7 179 (interactive "bView buffer:\nP")
b82fef5c
JB
180 (let ((return-to (and not-return (current-window-configuration))))
181 (switch-to-buffer-other-window buffer-name)
c88daaef 182 (view-mode-enter return-to)))
b82fef5c 183
7229064d 184;;;###autoload
c88daaef
RS
185(defun view-mode (&optional arg)
186 "Toggle View mode.
187If you use this function to turn on View mode,
188\"exiting\" View mode does nothing except turn View mode off.
189The other way to turn View mode on is by calling
bc15ba42 190`view-mode-enter'.
c88daaef 191
e6211d55
RS
192Letters do not insert themselves. Instead these commands are provided.
193Most commands take prefix arguments. Commands dealing with lines
194default to \"scroll size\" lines (initially size of window).
195Search commands default to a repeat count of one.
bc15ba42 196
e6211d55
RS
197M-< or < move to beginning of buffer.
198M-> or > move to end of buffer.
199C-v or Space scroll forward lines.
200M-v or DEL scroll backward lines.
201CR or LF scroll forward one line (backward with prefix argument).
202z like Space except set number of lines for further
203 scrolling commands to scroll by.
204C-u and Digits provide prefix arguments. `-' denotes negative argument.
205= prints the current line number.
206g goes to line given by prefix argument.
207/ or M-C-s searches forward for regular expression
208\\ or M-C-r searches backward for regular expression.
209n searches forward for last regular expression.
210p searches backward for last regular expression.
211C-@ or . set the mark.
212x exchanges point and mark.
213C-s or s do forward incremental search.
214C-r or r do reverse incremental search.
215@ or ' return to mark and pops mark ring.
216 Mark ring is pushed at start of every
217 successful search and when jump to line to occurs.
218 The mark is set on jump to buffer start or end.
219? or h provide help message (list of commands).
5b7a91bb 220\\[help-command] provides help (list of commands or description of a command).
e6211d55
RS
221C-n moves down lines vertically.
222C-p moves upward lines vertically.
223C-l recenters the screen.
bc15ba42
RS
224q exit view-mode and return to previous buffer."
225 (interactive "P")
226 (setq view-mode
227 (if (null arg)
228 (not view-mode)
229 (> (prefix-numeric-value arg) 0)))
230 (force-mode-line-update))
231
232(defun view-mode-enter (&optional prev-buffer action)
233 "Enter View mode, a Minor mode for viewing text but not editing it.
234See the function `view-mode' for more details.
e6211d55 235
c88daaef 236This function runs the normal hook `view-mode-hook'.
5c05f569 237
e6211d55
RS
238\\{view-mode-map}"
239; Not interactive because dangerous things happen
240; if you call it without passing a buffer as argument
241; and they are not easy to fix.
242; (interactive)
e6211d55 243 (setq view-old-buffer-read-only buffer-read-only)
e6211d55
RS
244 (setq view-old-Helper-return-blurb
245 (and (boundp 'Helper-return-blurb) Helper-return-blurb))
246
c88daaef
RS
247 ;; Enable view-exit to make use of the data we just saved
248 ;; and to perform the exit action.
249 (setq view-mode-auto-exit t)
250
e6211d55 251 (setq buffer-read-only t)
bab0c3c1 252 (setq view-mode t)
e6211d55
RS
253 (setq Helper-return-blurb
254 (format "continue viewing %s"
255 (if (buffer-file-name)
256 (file-name-nondirectory (buffer-file-name))
257 (buffer-name))))
258
e6211d55 259 (setq view-exit-action action)
b82fef5c 260 (setq view-return-here prev-buffer)
e6211d55
RS
261 (setq view-exit-position (point-marker))
262
e6211d55
RS
263 (beginning-of-line)
264 (setq goal-column nil)
265
bab0c3c1 266 (run-hooks 'view-mode-hook)
b32e8455 267 (message "%s"
bab0c3c1 268 (substitute-command-keys
bc15ba42 269 "Type \\[help-command] for help, \\[describe-mode] for commands, \\[view-exit] to quit.")))
b82fef5c 270\f
e6211d55
RS
271(defun view-exit ()
272 "Exit from view-mode.
273If you viewed an existing buffer, that buffer returns to its previous mode.
274If you viewed a file that was not present in Emacs, its buffer is killed."
275 (interactive)
c88daaef 276 (setq view-mode nil)
641889d6 277 (and view-overlay (delete-overlay view-overlay))
c88daaef
RS
278 (force-mode-line-update)
279 (cond (view-mode-auto-exit
280 (setq buffer-read-only view-old-buffer-read-only)
281 (setq view-mode-auto-exit nil)
282
283 (goto-char view-exit-position)
284 (set-marker view-exit-position nil)
285
286 ;; Now do something to the buffer that we were viewing
287 ;; (such as kill it).
288 (let ((viewed-buffer (current-buffer))
289 (action view-exit-action))
290 (cond
291 ((bufferp view-return-here)
292 (switch-to-buffer view-return-here))
293 ((window-configuration-p view-return-here)
294 (set-window-configuration view-return-here)))
295 (if action (funcall action viewed-buffer))))))
e6211d55 296
e6211d55
RS
297(defun view-window-size () (1- (window-height)))
298
299(defun view-scroll-size ()
300 (min (view-window-size) (or view-scroll-size (view-window-size))))
301
bd0d2c58
RS
302(defvar view-mode-hook nil
303 "Normal hook run when starting to view a buffer or file.")
304
e6211d55
RS
305;(defun view-last-command (&optional who what)
306; (setq view-last-command-entry this-command)
307; (setq view-last-command who)
308; (setq view-last-command-argument what))
309
310;(defun View-repeat-last-command ()
311; "Repeat last command issued in View mode."
312; (interactive)
313; (if (and view-last-command
314; (eq view-last-command-entry last-command))
315; (funcall view-last-command view-last-command-argument))
316; (setq this-command view-last-command-entry))
317
bab0c3c1 318(defun View-goto-line (line)
5c05f569 319 "Move to line LINE in View mode.
e6211d55
RS
320Display is centered at LINE. Sets mark at starting position and pushes
321mark ring."
322 (interactive "p")
323 (push-mark)
bab0c3c1 324 (goto-line line)
e6211d55
RS
325 (recenter (/ (view-window-size) 2)))
326
327(defun View-scroll-lines-forward (&optional lines)
328 "Scroll forward in View mode, or exit if end of text is visible.
329No arg means whole window full, or number of lines set by \\[View-scroll-lines-forward-set-scroll-size].
330Arg is number of lines to scroll."
331 (interactive "P")
bab0c3c1
KH
332 (setq lines
333 (if lines (prefix-numeric-value lines)
334 (view-scroll-size)))
6ebbf1dc
RS
335 (if (and (pos-visible-in-window-p (point-max))
336 ;; Allow scrolling backward at the end of the buffer.
c88daaef
RS
337 (> lines 0)
338 view-mode-auto-exit)
ca160bc4 339 (view-exit)
ca160bc4
RS
340 ;; (view-last-command 'View-scroll-lines-forward lines)
341 (if (>= lines (view-window-size))
342 (scroll-up nil)
343 (if (>= (- lines) (view-window-size))
344 (scroll-down nil)
345 (scroll-up lines)))
346 (cond ((pos-visible-in-window-p (point-max))
347 (goto-char (point-max))
b32e8455
KH
348 (message "%s"
349 (substitute-command-keys
ca160bc4
RS
350 "End. Type \\[view-exit] to quit viewing."))))
351 (move-to-window-line -1)
352 (beginning-of-line)))
e6211d55
RS
353
354(defun View-scroll-lines-forward-set-scroll-size (&optional lines)
355 "Scroll forward LINES lines in View mode, setting the \"scroll size\".
356This is the number of lines which \\[View-scroll-lines-forward] and \\[View-scroll-lines-backward] scroll by default.
357The absolute value of LINES is used, so this command can be used to scroll
358backwards (but \"scroll size\" is always positive). If LINES is greater than
359window height or omitted, then window height is assumed. If LINES is less
360than window height then scrolling context is provided from previous screen."
361 (interactive "P")
362 (if (not lines)
363 (setq view-scroll-size (view-window-size))
364 (setq lines (prefix-numeric-value lines))
365 (setq view-scroll-size
366 (min (if (> lines 0) lines (- lines)) (view-window-size))))
367 (View-scroll-lines-forward lines))
368
369(defun View-scroll-one-more-line (&optional arg)
370 "Scroll one more line up in View mode.
371With ARG scroll one line down."
372 (interactive "P")
373 (View-scroll-lines-forward (if (not arg) 1 -1)))
374
375(defun View-scroll-lines-backward (&optional lines)
376 "Scroll backward in View mode.
377No arg means whole window full, or number of lines set by \\[View-scroll-lines-forward-set-scroll-size].
378Arg is number of lines to scroll."
379 (interactive "P")
380 (View-scroll-lines-forward (if lines
381 (- (prefix-numeric-value lines))
382 (- (view-scroll-size)))))
383
5c05f569
RS
384(defun View-search-regexp-forward (n regexp)
385 "Search forward for Nth occurrence of REGEXP.
e6211d55 386Displays line found at center of window. REGEXP is remembered for
5534818b
RS
387searching with \\[View-search-last-regexp-forward] and \\[View-search-last-regexp-backward]. Sets mark at starting position and pushes mark ring.
388
389The variable `view-highlight-face' controls the face that is used
390for highlighting the match that is found."
e6211d55 391 (interactive "p\nsSearch forward (regexp): ")
4fe11426 392;;;(view-last-command 'View-search-last-regexp-forward n)
f42c58a2 393 (view-search n (if (equal regexp "") view-last-regexp regexp)))
e6211d55 394
5c05f569
RS
395(defun View-search-regexp-backward (n regexp)
396 "Search backward from window start for Nth instance of REGEXP.
e6211d55 397Displays line found at center of window. REGEXP is remembered for
5534818b
RS
398searching with \\[View-search-last-regexp-forward] and \\[View-search-last-regexp-backward]. Sets mark at starting position and pushes mark ring.
399
400The variable `view-highlight-face' controls the face that is used
401for highlighting the match that is found."
e6211d55 402 (interactive "p\nsSearch backward (regexp): ")
4fe11426
RS
403 (View-search-regexp-forward (- n)
404 (if (equal regexp "") view-last-regexp regexp)))
e6211d55 405
5c05f569
RS
406(defun View-search-last-regexp-forward (n)
407 "Search forward from window end for Nth instance of last regexp.
e6211d55 408Displays line found at center of window. Sets mark at starting position
5534818b
RS
409and pushes mark ring.
410
411The variable `view-highlight-face' controls the face that is used
412for highlighting the match that is found."
e6211d55 413 (interactive "p")
8ba83f4b
RS
414 (if view-last-regexp
415 (View-search-regexp-forward n view-last-regexp)
416 (error "No previous View-mode search")))
e6211d55 417
5c05f569
RS
418(defun View-search-last-regexp-backward (n)
419 "Search backward from window start for Nth instance of last regexp.
e6211d55 420Displays line found at center of window. Sets mark at starting position and
5534818b
RS
421pushes mark ring.
422
423The variable `view-highlight-face' controls the face that is used
424for highlighting the match that is found."
e6211d55 425 (interactive "p")
8ba83f4b
RS
426 (if view-last-regexp
427 (View-search-regexp-backward n view-last-regexp)
428 (error "No previous View-mode search")))
e6211d55
RS
429
430(defun View-back-to-mark (&optional ignore)
431 "Return to last mark set in View mode, else beginning of file.
432Displays line at center of window. Pops mark ring so successive
433invocations return to earlier marks."
434 (interactive)
bab0c3c1 435 (goto-char (or (mark t) (point-min)))
e6211d55
RS
436 (pop-mark)
437 (recenter (/ (view-window-size) 2)))
438
439(defun view-search (times regexp)
440 (setq view-last-regexp regexp)
441 (let (where)
442 (save-excursion
443 (move-to-window-line (if (< times 0) 0 -1))
444 (if (re-search-forward regexp nil t times)
445 (setq where (point))))
446 (if where
447 (progn
448 (push-mark)
449 (goto-char where)
4fe11426
RS
450 (if view-overlay
451 (move-overlay view-overlay (match-beginning 0) (match-end 0))
452 (setq view-overlay
453 (make-overlay (match-beginning 0) (match-end 0))))
82380f84 454 (overlay-put view-overlay 'face view-highlight-face)
e6211d55
RS
455 (beginning-of-line)
456 (recenter (/ (view-window-size) 2)))
457 (message "Can't find occurrence %d of %s" times regexp)
458 (sit-for 4))))
459
b82fef5c 460\f
49116ac0
JB
461(provide 'view)
462
d501f516 463;;; view.el ends here