‘M-x view-file’ (C-x C-r) allows you to scan or read a file by sequential screenfuls. It reads a file name argument using the minibuffer. After reading the file into an Emacs buffer,
‘view-file’ displays the beginning. You can then type <SPC> to scroll forward one windowful, or <DEL> to scroll backward. Various other commands are provided for moving around in the file, but none for changing it; type `?’ while viewing for a list of them. They are mostly the same as normal Emacs cursor motion commands. To exit from viewing, type
‘q’. The commands for viewing are defined by a special major mode called View mode.
‘M-x view-buffer’ is much like
‘M-x view-file’ except that it examines an already existing Emacs buffer. View mode provides commands for scrolling through the buffer conveniently but not for changing it. When you exit View mode with
‘q’, that switches back to the buffer (and the position) which was previously displayed in the window. Alternatively, if you exit View mode with
‘e’, the buffer and the value of point that resulted from your perusal remain in effect.
I exclusively use view-mode for unwritable files.
(defadvice find-file (around find-file-switch-to-view-file (file &optional wild) activate) (if (and (not (file-writable-p file)) (not (file-directory-p file))) (view-file file) ad-do-it))
There’s an easier way:
(setq view-read-only t)
(defmacro do-not-exit-view-mode-unless-writable-advice (f) `(defadvice ,f (around do-not-exit-view-mode-unless-writable activate) (if (and (buffer-file-name) (not (file-writable-p (buffer-file-name)))) (message "File is unwritable, so stay in view-mode.") ad-do-it))) (do-not-exit-view-mode-unless-writable-advice view-mode-exit) (do-not-exit-view-mode-unless-writable-advice view-mode-disable)
I think toggling view-mode is better than toggle-read-only.
(define-key ctl-x-map "\C-q" 'view-mode)
I have heavily customized view-mode-map, so I want to recognize view-mode at a glance.
(defun change-mode-line-color () (interactive) (when (get-buffer-window (current-buffer)) (cond (window-system (cond (view-mode (set-face-background 'modeline "black") (set-face-foreground 'modeline "orange") ) (t (set-face-background 'modeline "black") (set-face-foreground 'modeline "white"))) ) (t (set-face-background 'modeline (if view-mode "red" "white")))))) (defmacro change-mode-line-color-advice (f) `(defadvice ,f (after change-mode-line-color activate) (change-mode-line-color) (force-mode-line-update))) (progn (change-mode-line-color-advice set-window-configuration) (change-mode-line-color-advice switch-to-buffer) (change-mode-line-color-advice pop-to-buffer) (change-mode-line-color-advice other-window) (change-mode-line-color-advice toggle-read-only) (change-mode-line-color-advice vc-toggle-read-only) (change-mode-line-color-advice vc-next-action) (change-mode-line-color-advice view-mode-enable) (change-mode-line-color-advice view-mode-disable) (change-mode-line-color-advice bury-buffer) (change-mode-line-color-advice kill-buffer) (change-mode-line-color-advice delete-window) ;; for windows.el (change-mode-line-color-advice win-switch-to-window) (change-mode-line-color-advice win-toggle-window) )
From Help buffer how to automatically examine *.el source in view-mode?
C-h f view-mode
With point over ‘view.el’ of Help buffer @ line 1
“Here is a
‘help-function-def’ button labeled `view.el’. There are text properties here: button (t) category help-function-def-button help-args (view-mode “../emacs/lisp/view.el”)”
Most of the time, when I go to examine the source from Help I want to do so without having to worry about mucking it up accidentally esp. when the source is beneath “../emacs/lisp/*.el”. In these situations I almost alwasy want to read the source not edit it. View-mode is my prefered way of examining source when I want only to read it as it allows me to page in a manner congruent with most unix environments/vi/less/more etc. Is it possible to hook into the help button actions to toggle view-mode when opening for an *.el file from Help? AFAICT Help is already leveraging view-mode in a non extensible manner. How does one get Emacs to jump over its own head? --mon_key
I had a look at it, for me it works if I advice two functions. Try the following code:
(defadvice find-function-search-for-symbol (after oxy-adv1 last (symbol type library) activate) (with-current-buffer (car ad-return-value) (view-mode 1)))
(defadvice find-variable-noselect (after oxy-adv2 last (variable &optional file) activate) (with-current-buffer (car ad-return-value) (view-mode 1)))
Great Thanks! Works for me. I hesitate to reveal the path I went down to attempt accomplishing the same :P I’ve been wondering about a solution for that puzzle for quite awhile now. I’d be curious to learn if there is a way to accomplish the same without advice… --mon_key
As of Emacs 27.1 at least, the
‘help-function’ property mentioned here has been made a named function, so it can be advised. Moreover, it now runs the hook
‘find-function-after-hook’. It’s found in “help-mode.el” if you want to check whether this holds in earlier versions. As a result, the following code can be used to enable
‘view-mode’ when following the source links:
(add-hook 'find-function-after-hook #'view-mode-enter) ; or #'view-mode
Despite the hook’s name, this also enables
‘view-mode’ for source code from C-h v for some reason.
Warning: this will enable
‘view-mode’ even if the file was previous open and not in
‘view-mode’. On the other hand, leaving
‘view-mode’ should be as easy as e .
The only problem with this is that it’s not carried over if you go to a different file using M-. or
‘imenu’. That could maybe be implemented with a minor mode for “viewing sources” and advising those functions to preserve
‘view-mode’ and the new mode when it’s enabled.
You can use DirectoryVariables to make the Lisp directory read-only, but not in view-mode.
;; Always open installed Emacs files as read-only. (dir-locals-set-class-variables 'unwritable-directory '((nil . ((buffer-read-only . t))))) (dir-locals-set-directory-class "/usr/share/emacs/" 'unwritable-directory)
I have this to pop open a window onto the current buffer for isearch or to grab something from elsewhere without losing my place:
(defun view-indirect-buffer-other-window () (interactive) (clone-indirect-buffer-other-window (buffer-name) t) (view-buffer (current-buffer)))