comparison lisp/textmodes/picture.el @ 18412:3febbe908cc3

(picture-draw-rectangle): New command. (picture-mode-map): Add binding for picture-draw-rectangle. (picture-mode): Doc fix. (picture-rectangle-ctl): New variable. (picture-rectangle-ctr): New variable. (picture-rectangle-cbr): New variable. (picture-rectangle-cbl): New variable. (picture-rectangle-v): New variable. (picture-rectangle-h): New variable. (move-to-column-force): Function deleted; calls changed to use move-to-column. (picture-insert): New function. (picture-self-insert): Use picture-insert. (picture-current-line): New function.
author Richard M. Stallman <rms@gnu.org>
date Mon, 23 Jun 1997 04:16:44 +0000
parents 94dd08880c3b
children 9b831f34ff7d
comparison
equal deleted inserted replaced
18411:ed909ffc3c46 18412:3febbe908cc3
29 ;; support for rectangle operations and `etch-a-sketch' character 29 ;; support for rectangle operations and `etch-a-sketch' character
30 ;; insertion in any of eight directions. 30 ;; insertion in any of eight directions.
31 31
32 ;;; Code: 32 ;;; Code:
33 33
34 (defun move-to-column-force (column) 34 (defvar picture-rectangle-ctl ?+
35 "Move to column COLUMN in current line. 35 "*Character picture-draw-rectangle uses for top left corners.")
36 Differs from `move-to-column' in that it creates or modifies whitespace 36 (defvar picture-rectangle-ctr ?+
37 if necessary to attain exactly the specified column." 37 "*Character picture-draw-rectangle uses for top right corners.")
38 (or (natnump column) (setq column 0)) 38 (defvar picture-rectangle-cbr ?+
39 (move-to-column column) 39 "*Character picture-draw-rectangle uses for bottom right corners.")
40 (let ((col (current-column))) 40 (defvar picture-rectangle-cbl ?+
41 (if (< col column) 41 "*Character picture-draw-rectangle uses for bottom left corners.")
42 (indent-to column) 42 (defvar picture-rectangle-v ?|
43 (if (and (/= col column) 43 "*Character picture-draw-rectangle uses for vertical lines.")
44 (= (preceding-char) ?\t)) 44 (defvar picture-rectangle-h ?-
45 (let (indent-tabs-mode) 45 "*Character picture-draw-rectangle uses for horizontal lines.")
46 (delete-char -1) 46
47 (indent-to col)
48 (move-to-column column))))
49 ;; This call will go away when Emacs gets real horizontal autoscrolling
50 (hscroll-point-visible)))
51
52
53 ;; Picture Movement Commands 47 ;; Picture Movement Commands
54 48
55 (defun picture-beginning-of-line (&optional arg) 49 (defun picture-beginning-of-line (&optional arg)
56 "Position point at the beginning of the line. 50 "Position point at the beginning of the line.
57 With ARG not nil, move forward ARG - 1 lines first. 51 With ARG not nil, move forward ARG - 1 lines first.
76 (defun picture-forward-column (arg) 70 (defun picture-forward-column (arg)
77 "Move cursor right, making whitespace if necessary. 71 "Move cursor right, making whitespace if necessary.
78 With argument, move that many columns." 72 With argument, move that many columns."
79 (interactive "p") 73 (interactive "p")
80 (let ((target-column (+ (current-column) arg))) 74 (let ((target-column (+ (current-column) arg)))
81 (move-to-column-force target-column) 75 (move-to-column target-column t)
82 ;; Picture mode isn't really suited to multi-column characters, 76 ;; Picture mode isn't really suited to multi-column characters,
83 ;; but we might as well let the user move across them. 77 ;; but we might as well let the user move across them.
84 (and (< arg 0) 78 (and (< arg 0)
85 (> (current-column) target-column) 79 (> (current-column) target-column)
86 (forward-char -1)))) 80 (forward-char -1))))
95 "Move vertically down, making whitespace if necessary. 89 "Move vertically down, making whitespace if necessary.
96 With argument, move that many lines." 90 With argument, move that many lines."
97 (interactive "p") 91 (interactive "p")
98 (let ((col (current-column))) 92 (let ((col (current-column)))
99 (picture-newline arg) 93 (picture-newline arg)
100 (move-to-column-force col))) 94 (move-to-column col t)))
101 95
102 (defconst picture-vertical-step 0 96 (defconst picture-vertical-step 0
103 "Amount to move vertically after text character in Picture mode.") 97 "Amount to move vertically after text character in Picture mode.")
104 98
105 (defconst picture-horizontal-step 1 99 (defconst picture-horizontal-step 1
186 (picture-motion (- arg))) 180 (picture-motion (- arg)))
187 181
188 182
189 ;; Picture insertion and deletion. 183 ;; Picture insertion and deletion.
190 184
185 (defun picture-insert (ch arg)
186 (while (> arg 0)
187 (setq arg (1- arg))
188 (move-to-column (1+ (current-column)) t)
189 (delete-char -1)
190 (insert ch)
191 (forward-char -1)
192 (picture-move)))
193
191 (defun picture-self-insert (arg) 194 (defun picture-self-insert (arg)
192 "Insert this character in place of character previously at the cursor. 195 "Insert this character in place of character previously at the cursor.
193 The cursor then moves in the direction you previously specified 196 The cursor then moves in the direction you previously specified
194 with the commands `picture-movement-right', `picture-movement-up', etc. 197 with the commands `picture-movement-right', `picture-movement-up', etc.
195 Do \\[command-apropos] `picture-movement' to see those commands." 198 Do \\[command-apropos] `picture-movement' to see those commands."
196 (interactive "p") 199 (interactive "p")
197 (while (> arg 0) 200 (picture-insert last-command-event arg)) ; Always a character in this case.
198 (setq arg (1- arg))
199 (move-to-column-force (1+ (current-column)))
200 (delete-char -1)
201 (insert last-command-event) ; Always a character in this case.
202 (forward-char -1)
203 (picture-move)))
204 201
205 (defun picture-clear-column (arg) 202 (defun picture-clear-column (arg)
206 "Clear out ARG columns after point without moving." 203 "Clear out ARG columns after point without moving."
207 (interactive "p") 204 (interactive "p")
208 (let* ((opoint (point)) 205 (let* ((opoint (point))
209 (original-col (current-column)) 206 (original-col (current-column))
210 (target-col (+ original-col arg))) 207 (target-col (+ original-col arg)))
211 (move-to-column-force target-col) 208 (move-to-column target-col t)
212 (delete-region opoint (point)) 209 (delete-region opoint (point))
213 (save-excursion 210 (save-excursion
214 (indent-to (max target-col original-col))))) 211 (indent-to (max target-col original-col)))))
215 212
216 (defun picture-backward-clear-column (arg) 213 (defun picture-backward-clear-column (arg)
283 (setq list1 (primitive-undo 1 list1)))) 280 (setq list1 (primitive-undo 1 list1))))
284 (goto-char pos) 281 (goto-char pos)
285 (if (> change 0) 282 (if (> change 0)
286 (delete-region (point) 283 (delete-region (point)
287 (progn 284 (progn
288 (move-to-column-force (+ change (current-column))) 285 (move-to-column (+ change (current-column)) t)
289 (point)))) 286 (point))))
290 (replace-match newtext fixedcase literal) 287 (replace-match newtext fixedcase literal)
291 (if (< change 0) 288 (if (< change 0)
292 (insert-char ?\ (- change))))) 289 (insert-char ?\ (- change)))))
293 290
370 (save-excursion (end-of-line) (point)) 367 (save-excursion (end-of-line) (point))
371 'move) 368 'move)
372 (setq target (1- (current-column))) 369 (setq target (1- (current-column)))
373 (setq target nil))) 370 (setq target nil)))
374 (if target 371 (if target
375 (move-to-column-force target) 372 (move-to-column target t)
376 (beginning-of-line)))) 373 (beginning-of-line))))
377 374
378 (defun picture-tab (&optional arg) 375 (defun picture-tab (&optional arg)
379 "Tab transparently (just move point) to next tab stop. 376 "Tab transparently (just move point) to next tab stop.
380 With prefix arg, overwrite the traversed text with spaces. The tab stop 377 With prefix arg, overwrite the traversed text with spaces. The tab stop
416 (prog1 (save-excursion 413 (prog1 (save-excursion
417 (if killp 414 (if killp
418 (delete-extract-rectangle start end) 415 (delete-extract-rectangle start end)
419 (prog1 (extract-rectangle start end) 416 (prog1 (extract-rectangle start end)
420 (clear-rectangle start end)))) 417 (clear-rectangle start end))))
421 (move-to-column-force column)))) 418 (move-to-column column t))))
422 419
423 (defun picture-yank-rectangle (&optional insertp) 420 (defun picture-yank-rectangle (&optional insertp)
424 "Overlay rectangle saved by \\[picture-clear-rectangle] 421 "Overlay rectangle saved by \\[picture-clear-rectangle]
425 The rectangle is positioned with upper left corner at point, overwriting 422 The rectangle is positioned with upper left corner at point, overwriting
426 existing text. With prefix argument, the rectangle is inserted instead, 423 existing text. With prefix argument, the rectangle is inserted instead,
465 (picture-forward-column (length (car rectangle))) 462 (picture-forward-column (length (car rectangle)))
466 (picture-move-down (1- (length rectangle))) 463 (picture-move-down (1- (length rectangle)))
467 (point))))) 464 (point)))))
468 (push-mark) 465 (push-mark)
469 (insert-rectangle rectangle))) 466 (insert-rectangle rectangle)))
467
468 (defun picture-current-line ()
469 "Return the vertical position of point. Top line is 1."
470 (+ (count-lines (point-min) (point))
471 (if (= (current-column) 0) 1 0)))
472
473 (defun picture-draw-rectangle (start end)
474 "Draw a rectangle around region."
475 (interactive "*r") ; start will be less than end
476 (let* ((sl (picture-current-line))
477 (sc (current-column))
478 (pvs picture-vertical-step)
479 (phs picture-horizontal-step)
480 (c1 (progn (goto-char start) (current-column)))
481 (r1 (picture-current-line))
482 (c2 (progn (goto-char end) (current-column)))
483 (r2 (picture-current-line))
484 (right (max c1 c2))
485 (left (min c1 c2))
486 (top (min r1 r2))
487 (bottom (max r1 r2)))
488 (goto-line top)
489 (move-to-column left)
490
491 (picture-movement-right)
492 (picture-insert picture-rectangle-ctl 1)
493 (picture-insert picture-rectangle-h (- right (current-column)))
494
495 (picture-movement-down)
496 (picture-insert picture-rectangle-ctr 1)
497 (picture-insert picture-rectangle-v (- bottom (picture-current-line)))
498
499 (picture-movement-left)
500 (picture-insert picture-rectangle-cbr 1)
501 (picture-insert picture-rectangle-h (- (current-column) left))
502
503 (picture-movement-up)
504 (picture-insert picture-rectangle-cbl 1)
505 (picture-insert picture-rectangle-v (- (picture-current-line) top))
506
507 (picture-set-motion pvs phs)
508 (goto-line sl)
509 (move-to-column sc t)))
470 510
471 511
472 ;; Picture Keymap, entry and exit points. 512 ;; Picture Keymap, entry and exit points.
473 513
474 (defconst picture-mode-map nil) 514 (defconst picture-mode-map nil)
506 (define-key picture-mode-map "\C-c\t" 'picture-set-tab-stops) 546 (define-key picture-mode-map "\C-c\t" 'picture-set-tab-stops)
507 (define-key picture-mode-map "\C-c\C-k" 'picture-clear-rectangle) 547 (define-key picture-mode-map "\C-c\C-k" 'picture-clear-rectangle)
508 (define-key picture-mode-map "\C-c\C-w" 'picture-clear-rectangle-to-register) 548 (define-key picture-mode-map "\C-c\C-w" 'picture-clear-rectangle-to-register)
509 (define-key picture-mode-map "\C-c\C-y" 'picture-yank-rectangle) 549 (define-key picture-mode-map "\C-c\C-y" 'picture-yank-rectangle)
510 (define-key picture-mode-map "\C-c\C-x" 'picture-yank-rectangle-from-register) 550 (define-key picture-mode-map "\C-c\C-x" 'picture-yank-rectangle-from-register)
551 (define-key picture-mode-map "\C-c\C-r" 'picture-draw-rectangle)
511 (define-key picture-mode-map "\C-c\C-c" 'picture-mode-exit) 552 (define-key picture-mode-map "\C-c\C-c" 'picture-mode-exit)
512 (define-key picture-mode-map "\C-c\C-f" 'picture-motion) 553 (define-key picture-mode-map "\C-c\C-f" 'picture-motion)
513 (define-key picture-mode-map "\C-c\C-b" 'picture-motion-reverse) 554 (define-key picture-mode-map "\C-c\C-b" 'picture-motion-reverse)
514 (define-key picture-mode-map "\C-c<" 'picture-movement-left) 555 (define-key picture-mode-map "\C-c<" 'picture-movement-left)
515 (define-key picture-mode-map "\C-c>" 'picture-movement-right) 556 (define-key picture-mode-map "\C-c>" 'picture-movement-right)
573 You can manipulate rectangles with these commands: 614 You can manipulate rectangles with these commands:
574 C-c C-k Clear (or kill) a rectangle and save it. 615 C-c C-k Clear (or kill) a rectangle and save it.
575 C-c C-w Like C-c C-k except rectangle is saved in named register. 616 C-c C-w Like C-c C-k except rectangle is saved in named register.
576 C-c C-y Overlay (or insert) currently saved rectangle at point. 617 C-c C-y Overlay (or insert) currently saved rectangle at point.
577 C-c C-x Like C-c C-y except rectangle is taken from named register. 618 C-c C-x Like C-c C-y except rectangle is taken from named register.
619 C-c C-r Draw a rectangular box around mark and point.
578 \\[copy-rectangle-to-register] Copies a rectangle to a register. 620 \\[copy-rectangle-to-register] Copies a rectangle to a register.
579 \\[advertised-undo] Can undo effects of rectangle overlay commands 621 \\[advertised-undo] Can undo effects of rectangle overlay commands
580 commands if invoked soon enough. 622 commands if invoked soon enough.
581 You can return to the previous mode with: 623 You can return to the previous mode with:
582 C-c C-c Which also strips trailing whitespace from every line. 624 C-c C-c Which also strips trailing whitespace from every line.