diff options
| author | Chong Yidong | 2007-05-24 23:12:53 +0000 |
|---|---|---|
| committer | Chong Yidong | 2007-05-24 23:12:53 +0000 |
| commit | bb0cb417523a355f34eb057a2d2af66d52ddf8ae (patch) | |
| tree | 0d5450d3b89c9c0342b3d9d5b32983437c104edc | |
| parent | 6db526f0bd7b8611e5e8ff7bfcff405a8958dcc1 (diff) | |
| download | emacs-bb0cb417523a355f34eb057a2d2af66d52ddf8ae.tar.gz emacs-bb0cb417523a355f34eb057a2d2af66d52ddf8ae.zip | |
(image-forward-hscroll, image-backward-hscroll)
(image-next-line, image-previous-line, image-scroll-up)
(image-scroll-down, image-bol, image-eol, image-bob, image-eob):
New functions.
(image-mode-map): Remap motion commands.
(image-mode-text-map): New keymap for viewing images as text.
(image-mode): Use image-mode-map.
(image-toggle-display): Toggle auto-hscroll-mode and mode keymaps.
| -rw-r--r-- | lisp/image-mode.el | 169 |
1 files changed, 161 insertions, 8 deletions
diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 5ff35258c54..6ac864172d8 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el | |||
| @@ -43,11 +43,162 @@ | |||
| 43 | ;;;###autoload (push '("\\.p[bpgn]m\\'" . image-mode) auto-mode-alist) | 43 | ;;;###autoload (push '("\\.p[bpgn]m\\'" . image-mode) auto-mode-alist) |
| 44 | ;;;###autoload (push '("\\.x[bp]m\\'" . image-mode-maybe) auto-mode-alist) | 44 | ;;;###autoload (push '("\\.x[bp]m\\'" . image-mode-maybe) auto-mode-alist) |
| 45 | 45 | ||
| 46 | ;;; Image scrolling functions | ||
| 47 | |||
| 48 | (defun image-forward-hscroll (&optional n) | ||
| 49 | "Scroll image in current window to the left by N character widths. | ||
| 50 | Stop if the right edge of the image is reached." | ||
| 51 | (interactive "p") | ||
| 52 | (cond ((= n 0) nil) | ||
| 53 | ((< n 0) | ||
| 54 | (set-window-hscroll (selected-window) | ||
| 55 | (max 0 (+ (window-hscroll) n)))) | ||
| 56 | (t | ||
| 57 | (let* ((image (get-text-property 1 'display)) | ||
| 58 | (edges (window-inside-edges)) | ||
| 59 | (win-width (- (nth 2 edges) (nth 0 edges))) | ||
| 60 | (img-width (ceiling (car (image-size image))))) | ||
| 61 | (set-window-hscroll (selected-window) | ||
| 62 | (min (max 0 (- img-width win-width)) | ||
| 63 | (+ n (window-hscroll)))))))) | ||
| 64 | |||
| 65 | (defun image-backward-hscroll (&optional n) | ||
| 66 | "Scroll image in current window to the right by N character widths. | ||
| 67 | Stop if the left edge of the image is reached." | ||
| 68 | (interactive "p") | ||
| 69 | (image-forward-hscroll (- n))) | ||
| 70 | |||
| 71 | (defun image-next-line (&optional n) | ||
| 72 | "Scroll image in current window upward by N lines. | ||
| 73 | Stop if the bottom edge of the image is reached." | ||
| 74 | (interactive "p") | ||
| 75 | (cond ((= n 0) nil) | ||
| 76 | ((< n 0) | ||
| 77 | (set-window-vscroll (selected-window) | ||
| 78 | (max 0 (+ (window-vscroll) n)))) | ||
| 79 | (t | ||
| 80 | (let* ((image (get-text-property 1 'display)) | ||
| 81 | (edges (window-inside-edges)) | ||
| 82 | (win-height (- (nth 3 edges) (nth 1 edges))) | ||
| 83 | (img-height (ceiling (cdr (image-size image))))) | ||
| 84 | (set-window-vscroll (selected-window) | ||
| 85 | (min (max 0 (- img-height win-height)) | ||
| 86 | (+ n (window-vscroll)))))))) | ||
| 87 | |||
| 88 | (defun image-previous-line (&optional n) | ||
| 89 | "Scroll image in current window downward by N lines. | ||
| 90 | Stop if the top edge of the image is reached." | ||
| 91 | (interactive "p") | ||
| 92 | (image-next-line (- n))) | ||
| 93 | |||
| 94 | (defun image-scroll-up (&optional n) | ||
| 95 | "Scroll image in current window upward by N lines. | ||
| 96 | Stop if the bottom edge of the image is reached. | ||
| 97 | If ARG is omitted or nil, scroll upward by a near full screen. | ||
| 98 | A near full screen is `next-screen-context-lines' less than a full screen. | ||
| 99 | Negative ARG means scroll downward. | ||
| 100 | If ARG is the atom `-', scroll downward by nearly full screen. | ||
| 101 | When calling from a program, supply as argument a number, nil, or `-'." | ||
| 102 | (interactive "P") | ||
| 103 | (cond ((null n) | ||
| 104 | (let* ((edges (window-inside-edges)) | ||
| 105 | (win-height (- (nth 3 edges) (nth 1 edges)))) | ||
| 106 | (image-next-line | ||
| 107 | (max 0 (- win-height next-screen-context-lines))))) | ||
| 108 | ((eq n '-) | ||
| 109 | (let* ((edges (window-inside-edges)) | ||
| 110 | (win-height (- (nth 3 edges) (nth 1 edges)))) | ||
| 111 | (image-next-line | ||
| 112 | (min 0 (- next-screen-context-lines win-height))))) | ||
| 113 | (t (image-next-line (prefix-numeric-value n))))) | ||
| 114 | |||
| 115 | (defun image-scroll-down (&optional n) | ||
| 116 | "Scroll image in current window downward by N lines | ||
| 117 | Stop if the top edge of the image is reached. | ||
| 118 | If ARG is omitted or nil, scroll downward by a near full screen. | ||
| 119 | A near full screen is `next-screen-context-lines' less than a full screen. | ||
| 120 | Negative ARG means scroll upward. | ||
| 121 | If ARG is the atom `-', scroll upward by nearly full screen. | ||
| 122 | When calling from a program, supply as argument a number, nil, or `-'." | ||
| 123 | (interactive "P") | ||
| 124 | (cond ((null n) | ||
| 125 | (let* ((edges (window-inside-edges)) | ||
| 126 | (win-height (- (nth 3 edges) (nth 1 edges)))) | ||
| 127 | (image-next-line | ||
| 128 | (min 0 (- next-screen-context-lines win-height))))) | ||
| 129 | ((eq n '-) | ||
| 130 | (let* ((edges (window-inside-edges)) | ||
| 131 | (win-height (- (nth 3 edges) (nth 1 edges)))) | ||
| 132 | (image-next-line | ||
| 133 | (max 0 (- win-height next-screen-context-lines))))) | ||
| 134 | (t (image-next-line (- (prefix-numeric-value n)))))) | ||
| 135 | |||
| 136 | (defun image-bol (arg) | ||
| 137 | "Scroll horizontally to the left edge of the image in the current window. | ||
| 138 | With argument ARG not nil or 1, move forward ARG - 1 lines first, | ||
| 139 | stopping if the top or bottom edge of the image is reached." | ||
| 140 | (interactive "p") | ||
| 141 | (and arg | ||
| 142 | (/= (setq arg (prefix-numeric-value arg)) 1) | ||
| 143 | (image-next-line (- arg 1))) | ||
| 144 | (set-window-hscroll (selected-window) 0)) | ||
| 145 | |||
| 146 | (defun image-eol (arg) | ||
| 147 | "Scroll horizontally to the right edge of the image in the current window. | ||
| 148 | With argument ARG not nil or 1, move forward ARG - 1 lines first, | ||
| 149 | stopping if the top or bottom edge of the image is reached." | ||
| 150 | (interactive "p") | ||
| 151 | (and arg | ||
| 152 | (/= (setq arg (prefix-numeric-value arg)) 1) | ||
| 153 | (image-next-line (- arg 1))) | ||
| 154 | (let* ((image (get-text-property 1 'display)) | ||
| 155 | (edges (window-inside-edges)) | ||
| 156 | (win-width (- (nth 2 edges) (nth 0 edges))) | ||
| 157 | (img-width (ceiling (car (image-size image))))) | ||
| 158 | (set-window-hscroll (selected-window) | ||
| 159 | (max 0 (- img-width win-width))))) | ||
| 160 | |||
| 161 | (defun image-bob () | ||
| 162 | "Scroll to the top-left corner of the image in the current window." | ||
| 163 | (interactive) | ||
| 164 | (set-window-hscroll (selected-window) 0) | ||
| 165 | (set-window-vscroll (selected-window) 0)) | ||
| 166 | |||
| 167 | (defun image-eob () | ||
| 168 | "Scroll to the bottom-right corner of the image in the current window." | ||
| 169 | (interactive) | ||
| 170 | (let* ((image (get-text-property 1 'display)) | ||
| 171 | (edges (window-inside-edges)) | ||
| 172 | (win-width (- (nth 2 edges) (nth 0 edges))) | ||
| 173 | (img-width (ceiling (car (image-size image)))) | ||
| 174 | (win-height (- (nth 3 edges) (nth 1 edges))) | ||
| 175 | (img-height (ceiling (cdr (image-size image))))) | ||
| 176 | (set-window-hscroll (selected-window) (max 0 (- img-width win-width))) | ||
| 177 | (set-window-vscroll (selected-window) (max 0 (- img-height win-height))))) | ||
| 178 | |||
| 179 | ;;; Image Mode setup | ||
| 180 | |||
| 46 | (defvar image-mode-map | 181 | (defvar image-mode-map |
| 47 | (let ((map (make-sparse-keymap))) | 182 | (let ((map (make-sparse-keymap))) |
| 48 | (define-key map "\C-c\C-c" 'image-toggle-display) | 183 | (define-key map "\C-c\C-c" 'image-toggle-display) |
| 184 | (define-key map [remap forward-char] 'image-forward-hscroll) | ||
| 185 | (define-key map [remap backward-char] 'image-backward-hscroll) | ||
| 186 | (define-key map [remap previous-line] 'image-previous-line) | ||
| 187 | (define-key map [remap next-line] 'image-next-line) | ||
| 188 | (define-key map [remap scroll-up] 'image-scroll-up) | ||
| 189 | (define-key map [remap scroll-down] 'image-scroll-down) | ||
| 190 | (define-key map [remap move-beginning-of-line] 'image-bol) | ||
| 191 | (define-key map [remap move-end-of-line] 'image-eol) | ||
| 192 | (define-key map [remap beginning-of-buffer] 'image-bob) | ||
| 193 | (define-key map [remap end-of-buffer] 'image-eob) | ||
| 194 | map) | ||
| 195 | "Major mode keymap for viewing images in Image mode.") | ||
| 196 | |||
| 197 | (defvar image-mode-text-map | ||
| 198 | (let ((map (make-sparse-keymap))) | ||
| 199 | (define-key map "\C-c\C-c" 'image-toggle-display) | ||
| 49 | map) | 200 | map) |
| 50 | "Major mode keymap for Image mode.") | 201 | "Major mode keymap for viewing images as text in Image mode.") |
| 51 | 202 | ||
| 52 | ;;;###autoload | 203 | ;;;###autoload |
| 53 | (defun image-mode () | 204 | (defun image-mode () |
| @@ -58,13 +209,13 @@ to toggle between display as an image and display as text." | |||
| 58 | (kill-all-local-variables) | 209 | (kill-all-local-variables) |
| 59 | (setq mode-name "Image") | 210 | (setq mode-name "Image") |
| 60 | (setq major-mode 'image-mode) | 211 | (setq major-mode 'image-mode) |
| 61 | (use-local-map image-mode-map) | ||
| 62 | (add-hook 'change-major-mode-hook 'image-toggle-display-text nil t) | 212 | (add-hook 'change-major-mode-hook 'image-toggle-display-text nil t) |
| 63 | (if (and (display-images-p) | 213 | (if (and (display-images-p) |
| 64 | (not (get-text-property (point-min) 'display))) | 214 | (not (get-text-property (point-min) 'display))) |
| 65 | (image-toggle-display) | 215 | (image-toggle-display) |
| 66 | ;; Set next vars when image is already displayed but local | 216 | ;; Set next vars when image is already displayed but local |
| 67 | ;; variables were cleared by kill-all-local-variables | 217 | ;; variables were cleared by kill-all-local-variables |
| 218 | (use-local-map image-mode-map) | ||
| 68 | (setq cursor-type nil truncate-lines t)) | 219 | (setq cursor-type nil truncate-lines t)) |
| 69 | (run-mode-hooks 'image-mode-hook) | 220 | (run-mode-hooks 'image-mode-hook) |
| 70 | (if (display-images-p) | 221 | (if (display-images-p) |
| @@ -140,6 +291,8 @@ and showing the image as an image." | |||
| 140 | (set-buffer-modified-p modified) | 291 | (set-buffer-modified-p modified) |
| 141 | (kill-local-variable 'cursor-type) | 292 | (kill-local-variable 'cursor-type) |
| 142 | (kill-local-variable 'truncate-lines) | 293 | (kill-local-variable 'truncate-lines) |
| 294 | (kill-local-variable 'auto-hscroll-mode) | ||
| 295 | (use-local-map image-mode-text-map) | ||
| 143 | (if (called-interactively-p) | 296 | (if (called-interactively-p) |
| 144 | (message "Repeat this command to go back to displaying the image"))) | 297 | (message "Repeat this command to go back to displaying the image"))) |
| 145 | ;; Turn the image data into a real image, but only if the whole file | 298 | ;; Turn the image data into a real image, but only if the whole file |
| @@ -161,12 +314,9 @@ and showing the image as an image." | |||
| 161 | nil t))) | 314 | nil t))) |
| 162 | (props | 315 | (props |
| 163 | `(display ,image | 316 | `(display ,image |
| 164 | intangible ,image | 317 | intangible ,image |
| 165 | rear-nonsticky (display intangible) | 318 | rear-nonsticky (display intangible) |
| 166 | ;; This a cheap attempt to make the whole buffer | 319 | read-only t front-sticky (read-only))) |
| 167 | ;; read-only when we're visiting the file (as | ||
| 168 | ;; opposed to just inserting it). | ||
| 169 | read-only t front-sticky (read-only))) | ||
| 170 | (inhibit-read-only t) | 320 | (inhibit-read-only t) |
| 171 | (buffer-undo-list t) | 321 | (buffer-undo-list t) |
| 172 | (modified (buffer-modified-p))) | 322 | (modified (buffer-modified-p))) |
| @@ -179,6 +329,9 @@ and showing the image as an image." | |||
| 179 | ;; This just makes the arrow displayed in the right fringe | 329 | ;; This just makes the arrow displayed in the right fringe |
| 180 | ;; area look correct when the image is wider than the window. | 330 | ;; area look correct when the image is wider than the window. |
| 181 | (setq truncate-lines t) | 331 | (setq truncate-lines t) |
| 332 | ;; Allow navigation of large images | ||
| 333 | (set (make-local-variable 'auto-hscroll-mode) nil) | ||
| 334 | (use-local-map image-mode-map) | ||
| 182 | (if (called-interactively-p) | 335 | (if (called-interactively-p) |
| 183 | (message "Repeat this command to go back to displaying the file as text"))))) | 336 | (message "Repeat this command to go back to displaying the file as text"))))) |
| 184 | 337 | ||