| 1 | ;;; auto-show.el --- perform automatic horizontal scrolling as point moves |
| 2 | ;;; This file is in the public domain. |
| 3 | |
| 4 | ;;; Keywords: scroll display minor-mode |
| 5 | ;;; Author: Pete Ware <ware@cis.ohio-state.edu> |
| 6 | ;;; Maintainer: FSF |
| 7 | |
| 8 | ;;; Commentary: |
| 9 | |
| 10 | ;;; This file provides functions that |
| 11 | ;;; automatically scroll the window horizontally when the point moves |
| 12 | ;;; off the left or right side of the window. |
| 13 | |
| 14 | ;;; Once this library is loaded, automatic horizontal scrolling |
| 15 | ;;; occurs whenever long lines are being truncated. |
| 16 | ;;; To request truncation of long lines, set the variable |
| 17 | ;;; Setting the variable `truncate-lines' to non-nil. |
| 18 | ;;; You can do this for all buffers as follows: |
| 19 | ;;; |
| 20 | ;;; (set-default 'truncate-lines t) |
| 21 | |
| 22 | ;;; Here is how to do it for C mode only: |
| 23 | ;;; |
| 24 | ;;; (set-default 'truncate-lines nil) ; this is the original value |
| 25 | ;;; (defun my-c-mode-hook () |
| 26 | ;;; "Run when C-mode starts up. Changes ..." |
| 27 | ;;; ... set various personal preferences ... |
| 28 | ;;; (setq truncate-lines t)) |
| 29 | ;;; (add-hook 'c-mode-hook 'my-c-mode-hook) |
| 30 | ;;; |
| 31 | ;;; |
| 32 | ;;; As a finer level of control, you can still have truncated lines but |
| 33 | ;;; without the automatic horizontal scrolling by setting the buffer |
| 34 | ;;; local variable `auto-show-mode' to nil. The default value is t. |
| 35 | ;;; The command `auto-show-mode' toggles the value of the variable |
| 36 | ;;; `auto-show-mode'. |
| 37 | |
| 38 | ;;; Code: |
| 39 | |
| 40 | (defgroup auto-show nil |
| 41 | "Perform automatic horizontal scrolling as point moves." |
| 42 | :group 'editing) |
| 43 | |
| 44 | (defcustom auto-show-mode t |
| 45 | "*Non-nil enables automatic horizontal scrolling, when lines are truncated. |
| 46 | The default value is t. To change the default, do this: |
| 47 | (set-default 'auto-show-mode nil) |
| 48 | See also command `auto-show-mode'. |
| 49 | This variable has no effect when lines are not being truncated. |
| 50 | This variable is automatically local in each buffer where it is set." |
| 51 | :type 'boolean |
| 52 | :group 'auto-show) |
| 53 | |
| 54 | (make-variable-buffer-local 'auto-show-mode) |
| 55 | |
| 56 | (defcustom auto-show-shift-amount 8 |
| 57 | "*Extra columns to scroll. for automatic horizontal scrolling." |
| 58 | :type 'integer |
| 59 | :group 'auto-show) |
| 60 | |
| 61 | (defcustom auto-show-show-left-margin-threshold 50 |
| 62 | "*Threshold column for automatic horizontal scrolling to the right. |
| 63 | If point is before this column, we try to scroll to make the left margin |
| 64 | visible. Setting this to 0 disables this feature." |
| 65 | :type 'integer |
| 66 | :group 'auto-show) |
| 67 | |
| 68 | (defun auto-show-truncationp () |
| 69 | "True if line truncation is enabled for the selected window." |
| 70 | (or truncate-lines |
| 71 | (and truncate-partial-width-windows |
| 72 | (< (window-width) (frame-width))))) |
| 73 | |
| 74 | ;;;###autoload |
| 75 | (defun auto-show-mode (arg) |
| 76 | "Turn automatic horizontal scroll mode on or off. |
| 77 | With arg, turn auto scrolling on if arg is positive, off otherwise. |
| 78 | This mode is enabled or disabled for each buffer individually. |
| 79 | It takes effect only when `truncate-lines' is non-nil." |
| 80 | (interactive "P") |
| 81 | (setq auto-show-mode |
| 82 | (if (null arg) |
| 83 | (not auto-show-mode) |
| 84 | (> (prefix-numeric-value arg) 0)))) |
| 85 | |
| 86 | (defun auto-show-make-point-visible (&optional ignore-arg) |
| 87 | "Scroll horizontally to make point visible, if that is enabled. |
| 88 | This function only does something if `auto-show-mode' is non-nil |
| 89 | and longlines are being truncated in the selected window. |
| 90 | See also the command `auto-show-mode'." |
| 91 | (interactive) |
| 92 | (if (and auto-show-mode (auto-show-truncationp) |
| 93 | (equal (window-buffer) (current-buffer))) |
| 94 | (let* ((col (current-column)) ;column on line point is at |
| 95 | (scroll (window-hscroll)) ;how far window is scrolled |
| 96 | (w-width (- (window-width) |
| 97 | (if (> scroll 0) |
| 98 | 2 1))) ;how wide window is on the screen |
| 99 | (right-col (+ scroll w-width))) |
| 100 | (if (and (< col auto-show-show-left-margin-threshold) |
| 101 | (< col (window-width)) |
| 102 | (> scroll 0)) |
| 103 | (scroll-right scroll) |
| 104 | (if (< col scroll) ;to the left of the screen |
| 105 | (scroll-right (+ (- scroll col) auto-show-shift-amount)) |
| 106 | (if (or (> col right-col) ;to the right of the screen |
| 107 | (and (= col right-col) |
| 108 | (not (eolp)))) |
| 109 | (scroll-left (+ auto-show-shift-amount |
| 110 | (- col (+ scroll w-width)))) |
| 111 | ) |
| 112 | ) |
| 113 | ) |
| 114 | ) |
| 115 | ) |
| 116 | ) |
| 117 | |
| 118 | ;; Do auto-scrolling after commands. |
| 119 | (add-hook 'post-command-hook 'auto-show-make-point-visible) |
| 120 | |
| 121 | ;; Do auto-scrolling in comint buffers after process output also. |
| 122 | (add-hook 'comint-output-filter-functions 'auto-show-make-point-visible t) |
| 123 | |
| 124 | (provide 'auto-show) |
| 125 | |
| 126 | ;; auto-show.el ends here |
| 127 | |