aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2014-06-11 17:51:44 -0400
committerStefan Monnier2014-06-11 17:51:44 -0400
commit7e74ad023826cfe89604b09b605ef74679b375e2 (patch)
treeb60095b9e15c1177ff6d30e6db571bd509690c5b
parentb83db3b9439b36e84cf8dfb253b8a6006f726c4d (diff)
downloademacs-7e74ad023826cfe89604b09b605ef74679b375e2.tar.gz
emacs-7e74ad023826cfe89604b09b605ef74679b375e2.zip
* lisp/rect.el: Make it possible to move bounds past EOL or into TABs.
(operate-on-rectangle): Use apply-on-rectangle. (rectangle--mark-crutches): New var. (rectangle--pos-cols, rectangle--col-pos, rectangle--point-col) (rectangle--crutches, rectangle--reset-crutches): New functions. (apply-on-rectangle): Obey crutches. Avoid setq. Fix missing final iteration if end is at EOB&BOL. (rectangle-mark-mode-map): Add remap bindings for exchange-point-and-mark and char/line movements. (rectangle--*-char): New function. (rectangle-exchange-point-and-mark, rectangle-right-char) (rectangle-left-char, rectangle-forward-char) (rectangle-backward-char, rectangle-next-line) (rectangle-previous-line): New commands. (rectangle--place-cursor): New function. (rectangle--highlight-for-redisplay): Use it. Use apply-on-rectangle.
-rw-r--r--etc/NEWS3
-rw-r--r--lisp/ChangeLog19
-rw-r--r--lisp/rect.el412
3 files changed, 303 insertions, 131 deletions
diff --git a/etc/NEWS b/etc/NEWS
index ff878c75b3d..3db5db20eb4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -72,6 +72,9 @@ performance improvements when pasting large amounts of text.
72 72
73* Changes in Specialized Modes and Packages in Emacs 24.5 73* Changes in Specialized Modes and Packages in Emacs 24.5
74 74
75** rectangle-mark-mode can now have corners past EOL or in the middle of a TAB
76Also C-x C-x in rectangle-mark-mode now cycles through the four corners.
77
75** font-lock 78** font-lock
76*** New functions font-lock-ensure and font-lock-flush that should be used 79*** New functions font-lock-ensure and font-lock-flush that should be used
77instead of font-lock-fontify-buffer when called from Elisp. 80instead of font-lock-fontify-buffer when called from Elisp.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 2ce06f6ba54..3df94a73929 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,22 @@
12014-06-11 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * rect.el: Make it possible to move bounds past EOL or into TABs.
4 (operate-on-rectangle): Use apply-on-rectangle.
5 (rectangle--mark-crutches): New var.
6 (rectangle--pos-cols, rectangle--col-pos, rectangle--point-col)
7 (rectangle--crutches, rectangle--reset-crutches): New functions.
8 (apply-on-rectangle): Obey crutches. Avoid setq.
9 Fix missing final iteration if end is at EOB&BOL.
10 (rectangle-mark-mode-map): Add remap bindings for
11 exchange-point-and-mark and char/line movements.
12 (rectangle--*-char): New function.
13 (rectangle-exchange-point-and-mark, rectangle-right-char)
14 (rectangle-left-char, rectangle-forward-char)
15 (rectangle-backward-char, rectangle-next-line)
16 (rectangle-previous-line): New commands.
17 (rectangle--place-cursor): New function.
18 (rectangle--highlight-for-redisplay): Use it. Use apply-on-rectangle.
19
12014-06-08 Glenn Morris <rgm@gnu.org> 202014-06-08 Glenn Morris <rgm@gnu.org>
2 21
3 * startup.el (initial-buffer-choice): Doc fix. 22 * startup.el (initial-buffer-choice): Doc fix.
diff --git a/lisp/rect.el b/lisp/rect.el
index e798b07b556..603ed8c95d1 100644
--- a/lisp/rect.el
+++ b/lisp/rect.el
@@ -31,6 +31,8 @@
31 31
32;;; Code: 32;;; Code:
33 33
34(eval-when-compile (require 'cl-lib))
35
34;; FIXME: this function should be replaced by `apply-on-rectangle' 36;; FIXME: this function should be replaced by `apply-on-rectangle'
35(defun operate-on-rectangle (function start end coerce-tabs) 37(defun operate-on-rectangle (function start end coerce-tabs)
36 "Call FUNCTION for each line of rectangle with corners at START, END. 38 "Call FUNCTION for each line of rectangle with corners at START, END.
@@ -42,42 +44,95 @@ FUNCTION is called with three arguments:
42 number of columns that belong to rectangle but are before that position, 44 number of columns that belong to rectangle but are before that position,
43 number of columns that belong to rectangle but are after point. 45 number of columns that belong to rectangle but are after point.
44Point is at the end of the segment of this line within the rectangle." 46Point is at the end of the segment of this line within the rectangle."
45 (let (startcol startlinepos endcol endlinepos) 47 (apply-on-rectangle
46 (save-excursion 48 (lambda (startcol endcol)
47 (goto-char start) 49 (let (startpos begextra endextra)
48 (setq startcol (current-column)) 50 (move-to-column startcol coerce-tabs)
49 (beginning-of-line) 51 (setq begextra (- (current-column) startcol))
50 (setq startlinepos (point))) 52 (setq startpos (point))
51 (save-excursion 53 (move-to-column endcol coerce-tabs)
52 (goto-char end) 54 ;; If we overshot, move back one character
53 (setq endcol (current-column)) 55 ;; so that endextra will be positive.
54 (forward-line 1) 56 (if (and (not coerce-tabs) (> (current-column) endcol))
55 (setq endlinepos (point-marker))) 57 (backward-char 1))
56 (if (< endcol startcol) 58 (setq endextra (- endcol (current-column)))
57 (setq startcol (prog1 endcol (setq endcol startcol)))) 59 (if (< begextra 0)
58 (save-excursion 60 (setq endextra (+ endextra begextra)
59 (goto-char startlinepos) 61 begextra 0))
60 (while (< (point) endlinepos) 62 (funcall function startpos begextra endextra)))
61 (let (startpos begextra endextra) 63 start end))
62 (if coerce-tabs 64
63 (move-to-column startcol t) 65;;; Crutches to let rectangle's corners be where point can't be
64 (move-to-column startcol)) 66;; (e.g. in the middle of a TAB, or past the EOL).
65 (setq begextra (- (current-column) startcol)) 67
66 (setq startpos (point)) 68(defvar-local rectangle--mark-crutches nil
67 (if coerce-tabs 69 "(POS . COL) to override the column to use for the mark.")
68 (move-to-column endcol t) 70
69 (move-to-column endcol)) 71(defun rectangle--pos-cols (start end)
70 ;; If we overshot, move back one character 72 ;; At this stage, we don't know which of start/end is point/mark :-(
71 ;; so that endextra will be positive. 73 ;; And in case start=end, it might still be that point and mark have
72 (if (and (not coerce-tabs) (> (current-column) endcol)) 74 ;; different crutches!
73 (backward-char 1)) 75 (let ((cw (window-parameter nil 'rectangle--point-crutches)))
74 (setq endextra (- endcol (current-column))) 76 (cond
75 (if (< begextra 0) 77 ((eq start (car cw))
76 (setq endextra (+ endextra begextra) 78 (let ((sc (cdr cw))
77 begextra 0)) 79 (ec (if (eq end (car rectangle--mark-crutches))
78 (funcall function startpos begextra endextra)) 80 (cdr rectangle--mark-crutches)
79 (forward-line 1))) 81 (if rectangle--mark-crutches
80 (- endcol startcol))) 82 (setq rectangle--mark-crutches nil))
83 (goto-char end) (current-column))))
84 (if (eq start end) (cons (min sc ec) (max sc ec)) (cons sc ec))))
85 ((eq end (car cw))
86 (if (eq start (car rectangle--mark-crutches))
87 (cons (cdr rectangle--mark-crutches) (cdr cw))
88 (if rectangle--mark-crutches (setq rectangle--mark-crutches nil))
89 (cons (progn (goto-char start) (current-column)) (cdr cw))))
90 ((progn
91 (if cw (setf (window-parameter nil 'rectangle--point-crutches) nil))
92 (eq start (car rectangle--mark-crutches)))
93 (let ((sc (cdr rectangle--mark-crutches))
94 (ec (progn (goto-char end) (current-column))))
95 (if (eq start end) (cons (min sc ec) (max sc ec)) (cons sc ec))))
96 ((eq end (car rectangle--mark-crutches))
97 (cons (progn (goto-char start) (current-column))
98 (cdr rectangle--mark-crutches)))
99 (t
100 (if rectangle--mark-crutches (setq rectangle--mark-crutches nil))
101 (cons (progn (goto-char start) (current-column))
102 (progn (goto-char end) (current-column)))))))
103
104(defun rectangle--col-pos (col kind)
105 (let ((c (move-to-column col)))
106 (if (= c col)
107 (if (eq kind 'point)
108 (if (window-parameter nil 'rectangle--point-crutches)
109 (setf (window-parameter nil 'rectangle--point-crutches) nil))
110 (if rectangle--mark-crutches (setq rectangle--mark-crutches nil)))
111 ;; If move-to-column over-shooted, move back one char so we're
112 ;; at the position where rectangle--highlight-for-redisplay
113 ;; will add the overlay (so that the cursor can be drawn at the
114 ;; right place).
115 (when (> c col) (forward-char -1))
116 (setf (if (eq kind 'point)
117 (window-parameter nil 'rectangle--point-crutches)
118 rectangle--mark-crutches)
119 (cons (point) col)))))
120
121(defun rectangle--point-col (pos)
122 (let ((pc (window-parameter nil 'rectangle--point-crutches)))
123 (if (eq pos (car pc)) (cdr pc)
124 (goto-char pos)
125 (current-column))))
126
127(defun rectangle--crutches ()
128 (cons rectangle--mark-crutches
129 (window-parameter nil 'rectangle--point-crutches)))
130(defun rectangle--reset-crutches ()
131 (kill-local-variable 'rectangle--mark-crutches)
132 (if (window-parameter nil 'rectangle--point-crutches)
133 (setf (window-parameter nil 'rectangle--point-crutches) nil)))
134
135;;; Rectangle operations.
81 136
82(defun apply-on-rectangle (function start end &rest args) 137(defun apply-on-rectangle (function start end &rest args)
83 "Call FUNCTION for each line of rectangle with corners at START, END. 138 "Call FUNCTION for each line of rectangle with corners at START, END.
@@ -85,27 +140,27 @@ FUNCTION is called with two arguments: the start and end columns of the
85rectangle, plus ARGS extra arguments. Point is at the beginning of line when 140rectangle, plus ARGS extra arguments. Point is at the beginning of line when
86the function is called. 141the function is called.
87The final point after the last operation will be returned." 142The final point after the last operation will be returned."
88 (let (startcol startpt endcol endpt final-point) 143 (save-excursion
89 (save-excursion 144 (let* ((cols (rectangle--pos-cols start end))
90 (goto-char start) 145 (startcol (car cols))
91 (setq startcol (current-column)) 146 (endcol (cdr cols))
92 (beginning-of-line) 147 (startpt (progn (goto-char start) (line-beginning-position)))
93 (setq startpt (point)) 148 (endpt (progn (goto-char end)
94 (goto-char end) 149 (copy-marker (line-end-position))))
95 (setq endcol (current-column)) 150 final-point)
96 (forward-line 1) 151 ;; Ensure the start column is the left one.
97 (setq endpt (point-marker))
98 ;; ensure the start column is the left one.
99 (if (< endcol startcol) 152 (if (< endcol startcol)
100 (let ((col startcol)) 153 (let ((col startcol))
101 (setq startcol endcol endcol col))) 154 (setq startcol endcol endcol col)))
102 ;; start looping over lines 155 ;; Start looping over lines.
103 (goto-char startpt) 156 (goto-char startpt)
104 (while (< (point) endpt) 157 (while
105 (apply function startcol endcol args) 158 (progn
106 (setq final-point (point)) 159 (apply function startcol endcol args)
107 (forward-line 1))) 160 (setq final-point (point))
108 final-point)) 161 (and (zerop (forward-line 1))
162 (<= (point) endpt))))
163 final-point)))
109 164
110(defun delete-rectangle-line (startcol endcol fill) 165(defun delete-rectangle-line (startcol endcol fill)
111 (when (= (move-to-column startcol (if fill t 'coerce)) startcol) 166 (when (= (move-to-column startcol (if fill t 'coerce)) startcol)
@@ -429,8 +484,12 @@ with a prefix argument, prompt for START-AT and FORMAT."
429 (let ((map (make-sparse-keymap))) 484 (let ((map (make-sparse-keymap)))
430 (define-key map [?\C-o] 'open-rectangle) 485 (define-key map [?\C-o] 'open-rectangle)
431 (define-key map [?\C-t] 'string-rectangle) 486 (define-key map [?\C-t] 'string-rectangle)
432 ;; (define-key map [remap open-line] 'open-rectangle) 487 (define-key map [remap exchange-point-and-mark]
433 ;; (define-key map [remap transpose-chars] 'string-rectangle) 488 'rectangle-exchange-point-and-mark)
489 (dolist (cmd '(right-char left-char forward-char backward-char
490 next-line previous-line))
491 (define-key map (vector 'remap cmd)
492 (intern (format "rectangle-%s" cmd))))
434 map) 493 map)
435 "Keymap used while marking a rectangular region.") 494 "Keymap used while marking a rectangular region.")
436 495
@@ -439,6 +498,7 @@ with a prefix argument, prompt for START-AT and FORMAT."
439 "Toggle the region as rectangular. 498 "Toggle the region as rectangular.
440Activates the region if needed. Only lasts until the region is deactivated." 499Activates the region if needed. Only lasts until the region is deactivated."
441 nil nil nil 500 nil nil nil
501 (rectangle--reset-crutches)
442 (when rectangle-mark-mode 502 (when rectangle-mark-mode
443 (add-hook 'deactivate-mark-hook 503 (add-hook 'deactivate-mark-hook
444 (lambda () (rectangle-mark-mode -1))) 504 (lambda () (rectangle-mark-mode -1)))
@@ -447,6 +507,96 @@ Activates the region if needed. Only lasts until the region is deactivated."
447 (activate-mark) 507 (activate-mark)
448 (message "Mark set (rectangle mode)")))) 508 (message "Mark set (rectangle mode)"))))
449 509
510(defun rectangle-exchange-point-and-mark (&optional arg)
511 "Like `exchange-point-and-mark' but cycles through the rectangle's corners."
512 (interactive "P")
513 (if arg
514 (progn
515 (setq this-command 'exchange-point-and-mark)
516 (exchange-point-and-mark arg))
517 (let* ((p (point))
518 (repeat (eq this-command last-command))
519 (m (mark))
520 (p<m (< p m))
521 (cols (if p<m (rectangle--pos-cols p m) (rectangle--pos-cols m p)))
522 (cp (if p<m (car cols) (cdr cols)))
523 (cm (if p<m (cdr cols) (car cols))))
524 (if repeat (setq this-command 'exchange-point-and-mark))
525 (rectangle--reset-crutches)
526 (goto-char p)
527 (rectangle--col-pos (if repeat cm cp) 'mark)
528 (set-mark (point))
529 (goto-char m)
530 (rectangle--col-pos (if repeat cp cm) 'point))))
531
532(defun rectangle--*-char (cmd n &optional other-cmd)
533 ;; Part of the complexity here is that I'm trying to avoid making assumptions
534 ;; about the L2R/R2L direction of text around point, but this is largely
535 ;; useless since the rectangles implemented in this file are "logical
536 ;; rectangles" and not "visual rectangles", so in the presence of
537 ;; bidirectional text things won't work well anyway.
538 (if (< n 0) (rectangle--*-char other-cmd (- n))
539 (let ((col (rectangle--point-col (point))))
540 (while (> n 0)
541 (let* ((bol (line-beginning-position))
542 (eol (line-end-position))
543 (curcol (current-column))
544 (nextcol
545 (condition-case nil
546 (save-excursion
547 (funcall cmd 1)
548 (cond
549 ((> bol (point)) (- curcol 1))
550 ((< eol (point)) (+ col (1+ n)))
551 (t (current-column))))
552 (end-of-buffer (+ col (1+ n)))
553 (beginning-of-buffer (- curcol 1))))
554 (diff (abs (- nextcol col))))
555 (cond
556 ((and (< nextcol curcol) (< curcol col))
557 (let ((curdiff (- col curcol)))
558 (if (<= curdiff n)
559 (progn (cl-decf n curdiff) (setq col curcol))
560 (setq col (- col n) n 0))))
561 ((< nextcol 0) (ding) (setq n 0 col 0)) ;Bumping into BOL!
562 ((= nextcol curcol) (funcall cmd 1))
563 (t ;; (> nextcol curcol)
564 (if (<= diff n)
565 (progn (cl-decf n diff) (setq col nextcol))
566 (setq col (if (< col nextcol) (+ col n) (- col n)) n 0))))))
567 ;; FIXME: This rectangle--col-pos's move-to-column is wasted!
568 (rectangle--col-pos col 'point))))
569
570(defun rectangle-right-char (&optional n)
571 "Like `right-char' but steps into wide chars and moves past EOL."
572 (interactive "p") (rectangle--*-char #'right-char n #'left-char))
573(defun rectangle-left-char (&optional n)
574 "Like `left-char' but steps into wide chars and moves past EOL."
575 (interactive "p") (rectangle--*-char #'left-char n #'right-char))
576
577(defun rectangle-forward-char (&optional n)
578 "Like `forward-char' but steps into wide chars and moves past EOL."
579 (interactive "p") (rectangle--*-char #'forward-char n #'backward-char))
580(defun rectangle-backward-char (&optional n)
581 "Like `backward-char' but steps into wide chars and moves past EOL."
582 (interactive "p") (rectangle--*-char #'backward-char n #'forward-char))
583
584(defun rectangle-next-line (&optional n)
585 "Like `next-line' but steps into wide chars and moves past EOL.
586Ignores `line-move-visual'."
587 (interactive "p")
588 (let ((col (rectangle--point-col (point))))
589 (forward-line n)
590 (rectangle--col-pos col 'point)))
591(defun rectangle-previous-line (&optional n)
592 "Like `previous-line' but steps into wide chars and moves past EOL.
593Ignores `line-move-visual'."
594 (interactive "p")
595 (let ((col (rectangle--point-col (point))))
596 (forward-line (- n))
597 (rectangle--col-pos col 'point)))
598
599
450(defun rectangle--extract-region (orig &optional delete) 600(defun rectangle--extract-region (orig &optional delete)
451 (if (not rectangle-mark-mode) 601 (if (not rectangle-mark-mode)
452 (funcall orig delete) 602 (funcall orig delete)
@@ -476,6 +626,11 @@ Activates the region if needed. Only lasts until the region is deactivated."
476 (while (not (eq pending-undo-list (cdr undo-at-start))) 626 (while (not (eq pending-undo-list (cdr undo-at-start)))
477 (undo-more 1)))))) 627 (undo-more 1))))))
478 628
629(defun rectangle--place-cursor (leftcol left str)
630 (let ((pc (window-parameter nil 'rectangle--point-crutches)))
631 (if (and (eq left (car pc)) (eq leftcol (cdr pc)))
632 (put-text-property 0 1 'cursor 1 str))))
633
479(defun rectangle--highlight-for-redisplay (orig start end window rol) 634(defun rectangle--highlight-for-redisplay (orig start end window rol)
480 (cond 635 (cond
481 ((not rectangle-mark-mode) 636 ((not rectangle-mark-mode)
@@ -483,93 +638,88 @@ Activates the region if needed. Only lasts until the region is deactivated."
483 ((and (eq 'rectangle (car-safe rol)) 638 ((and (eq 'rectangle (car-safe rol))
484 (eq (nth 1 rol) (buffer-chars-modified-tick)) 639 (eq (nth 1 rol) (buffer-chars-modified-tick))
485 (eq start (nth 2 rol)) 640 (eq start (nth 2 rol))
486 (eq end (nth 3 rol))) 641 (eq end (nth 3 rol))
642 (equal (rectangle--crutches) (nth 4 rol)))
487 rol) 643 rol)
488 (t 644 (t
489 (save-excursion 645 (save-excursion
490 (let* ((nrol nil) 646 (let* ((nrol nil)
491 (old (if (eq 'rectangle (car-safe rol)) 647 (old (if (eq 'rectangle (car-safe rol))
492 (nthcdr 4 rol) 648 (nthcdr 5 rol)
493 (funcall redisplay-unhighlight-region-function rol) 649 (funcall redisplay-unhighlight-region-function rol)
494 nil)) 650 nil)))
495 (ptcol (progn (goto-char start) (current-column))) 651 (apply-on-rectangle
496 (markcol (progn (goto-char end) (current-column))) 652 (lambda (leftcol rightcol)
497 (leftcol (min ptcol markcol)) 653 (let* ((mleft (move-to-column leftcol))
498 (rightcol (max ptcol markcol))) 654 (left (point))
499 (goto-char start) 655 (mright (move-to-column rightcol))
500 (while 656 (right (point))
501 (let* ((mleft (move-to-column leftcol)) 657 (ol
502 (left (point)) 658 (if (not old)
503 (mright (move-to-column rightcol)) 659 (let ((ol (make-overlay left right)))
504 (right (point)) 660 (overlay-put ol 'window window)
505 (ol 661 (overlay-put ol 'face 'region)
506 (if (not old) 662 ol)
507 (let ((ol (make-overlay left right))) 663 (let ((ol (pop old)))
508 (overlay-put ol 'window window) 664 (move-overlay ol left right (current-buffer))
509 (overlay-put ol 'face 'region) 665 ol))))
510 ol) 666 ;; `move-to-column' may stop before the column (if bumping into
511 (let ((ol (pop old))) 667 ;; EOL) or overshoot it a little, when column is in the middle
512 (move-overlay ol left right (current-buffer)) 668 ;; of a char.
513 ol)))) 669 (cond
514 ;; `move-to-column' may stop before the column (if bumping into 670 ((< mleft leftcol) ;`leftcol' is past EOL.
515 ;; EOL) or overshoot it a little, when column is in the middle 671 (overlay-put ol 'before-string
516 ;; of a char. 672 (spaces-string (- leftcol mleft)))
517 (cond 673 (setq mright (max mright leftcol)))
518 ((< mleft leftcol) ;`leftcol' is past EOL. 674 ((and (> mleft leftcol) ;`leftcol' is in the middle of a char.
519 (overlay-put ol 'before-string 675 (eq (char-before left) ?\t))
520 (spaces-string (- leftcol mleft))) 676 (setq left (1- left))
521 (setq mright (max mright leftcol))) 677 (move-overlay ol left right)
522 ((and (> mleft leftcol) ;`leftcol' is in the middle of a char. 678 (goto-char left)
523 (eq (char-before left) ?\t)) 679 (overlay-put ol 'before-string
524 (setq left (1- left)) 680 (spaces-string (- leftcol (current-column)))))
525 (move-overlay ol left right) 681 ((overlay-get ol 'before-string)
526 (goto-char left) 682 (overlay-put ol 'before-string nil)))
527 (overlay-put ol 'before-string 683 (cond
528 (spaces-string (- leftcol (current-column))))) 684 ((< mright rightcol) ;`rightcol' is past EOL.
529 ((overlay-get ol 'before-string) 685 (let ((str (make-string (- rightcol mright) ?\s)))
530 (overlay-put ol 'before-string nil))) 686 (put-text-property 0 (length str) 'face 'region str)
531 (cond 687 ;; If cursor happens to be here, draw it at the right place.
532 ((< mright rightcol) ;`rightcol' is past EOL. 688 (rectangle--place-cursor leftcol left str)
533 (let ((str (make-string (- rightcol mright) ?\s))) 689 (overlay-put ol 'after-string str)))
534 (put-text-property 0 (length str) 'face 'region str) 690 ((and (> mright rightcol) ;`rightcol's in the middle of a char.
535 ;; If cursor happens to be here, draw it *before* rather than 691 (eq (char-before right) ?\t))
536 ;; after this highlighted pseudo-text. 692 (setq right (1- right))
537 (put-text-property 0 1 'cursor t str) 693 (move-overlay ol left right)
538 (overlay-put ol 'after-string str))) 694 (if (= rightcol leftcol)
539 ((and (> mright rightcol) ;`rightcol's in the middle of a char. 695 (overlay-put ol 'after-string nil)
540 (eq (char-before right) ?\t)) 696 (goto-char right)
541 (setq right (1- right)) 697 (let ((str (make-string
542 (move-overlay ol left right) 698 (- rightcol (max leftcol (current-column)))
543 (if (= rightcol leftcol) 699 ?\s)))
544 (overlay-put ol 'after-string nil) 700 (put-text-property 0 (length str) 'face 'region str)
545 (goto-char right) 701 (when (= left right)
546 (let ((str (make-string 702 (rectangle--place-cursor leftcol left str))
547 (- rightcol (max leftcol (current-column))) 703 (overlay-put ol 'after-string str))))
548 ?\s))) 704 ((overlay-get ol 'after-string)
549 (put-text-property 0 (length str) 'face 'region str) 705 (overlay-put ol 'after-string nil)))
550 (when (= left right) 706 (when (and (= leftcol rightcol) (display-graphic-p))
551 ;; If cursor happens to be here, draw it *before* rather 707 ;; Make zero-width rectangles visible!
552 ;; than after this highlighted pseudo-text. 708 (overlay-put ol 'after-string
553 (put-text-property 0 1 'cursor 1 str)) 709 (concat (propertize " "
554 (overlay-put ol 'after-string str)))) 710 'face '(region (:height 0.2)))
555 ((overlay-get ol 'after-string) 711 (overlay-get ol 'after-string))))
556 (overlay-put ol 'after-string nil))) 712 (push ol nrol)))
557 (when (and (= leftcol rightcol) (display-graphic-p)) 713 start end)
558 ;; Make zero-width rectangles visible!
559 (overlay-put ol 'after-string
560 (concat (propertize " "
561 'face '(region (:height 0.2)))
562 (overlay-get ol 'after-string))))
563 (push ol nrol)
564 (and (zerop (forward-line 1))
565 (<= (point) end))))
566 (mapc #'delete-overlay old) 714 (mapc #'delete-overlay old)
567 `(rectangle ,(buffer-chars-modified-tick) ,start ,end ,@nrol)))))) 715 `(rectangle ,(buffer-chars-modified-tick)
716 ,start ,end ,(rectangle--crutches)
717 ,@nrol))))))
568 718
569(defun rectangle--unhighlight-for-redisplay (orig rol) 719(defun rectangle--unhighlight-for-redisplay (orig rol)
570 (if (not (eq 'rectangle (car-safe rol))) 720 (if (not (eq 'rectangle (car-safe rol)))
571 (funcall orig rol) 721 (funcall orig rol)
572 (mapc #'delete-overlay (nthcdr 4 rol)) 722 (mapc #'delete-overlay (nthcdr 5 rol))
573 (setcar (cdr rol) nil))) 723 (setcar (cdr rol) nil)))
574 724
575(provide 'rect) 725(provide 'rect)