aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman2001-12-28 05:15:59 +0000
committerRichard M. Stallman2001-12-28 05:15:59 +0000
commitaf894fc98aaec826059cf8e489070862376a4749 (patch)
treec4c0f6f6cd9181fd2ce116a289959d5983fa5afb
parent1d14d232ddf738ffb019560444536b5a9eedc90c (diff)
downloademacs-af894fc98aaec826059cf8e489070862376a4749.tar.gz
emacs-af894fc98aaec826059cf8e489070862376a4749.zip
(line-move-invisible): New subroutine.
(line-move-to-column): New subroutine--smarter about advancing over invisible parts of a line, or lines, but only as long as hpos grows. (line-move-finish): New subroutine: repeatedly processes desired column, intangibility, and fields. (line-move): Use those subroutines. When moving lines downward, skip invisible text first rather than last.
-rw-r--r--lisp/simple.el160
1 files changed, 90 insertions, 70 deletions
diff --git a/lisp/simple.el b/lisp/simple.el
index 0909090f5b7..8229a8cb4fa 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2530,6 +2530,15 @@ Outline mode sets this."
2530 :type 'boolean 2530 :type 'boolean
2531 :group 'editing-basics) 2531 :group 'editing-basics)
2532 2532
2533(defun line-move-invisible (pos)
2534 "Return non-nil if the character after POS is currently invisible."
2535 (let ((prop
2536 (get-char-property pos 'invisible)))
2537 (if (eq buffer-invisibility-spec t)
2538 prop
2539 (or (memq prop buffer-invisibility-spec)
2540 (assq prop buffer-invisibility-spec)))))
2541
2533;; This is the guts of next-line and previous-line. 2542;; This is the guts of next-line and previous-line.
2534;; Arg says how many lines to move. 2543;; Arg says how many lines to move.
2535(defun line-move (arg) 2544(defun line-move (arg)
@@ -2563,89 +2572,100 @@ Outline mode sets this."
2563 (bolp))) 2572 (bolp)))
2564 (signal (if (< arg 0) 2573 (signal (if (< arg 0)
2565 'beginning-of-buffer 2574 'beginning-of-buffer
2566 'end-of-buffer) 2575a 'end-of-buffer)
2567 nil)) 2576 nil))
2568 ;; Move by arg lines, but ignore invisible ones. 2577 ;; Move by arg lines, but ignore invisible ones.
2569 (while (> arg 0) 2578 (while (> arg 0)
2579 ;; If the following character is currently invisible,
2580 ;; skip all characters with that same `invisible' property value.
2581 (while (and (not (eobp)) (line-move-invisible (point)))
2582 (goto-char (next-char-property-change (point))))
2583 ;; Now move a line.
2570 (end-of-line) 2584 (end-of-line)
2571 (and (zerop (vertical-motion 1)) 2585 (and (zerop (vertical-motion 1))
2572 (signal 'end-of-buffer nil)) 2586 (signal 'end-of-buffer nil))
2573 ;; If the following character is currently invisible,
2574 ;; skip all characters with that same `invisible' property value.
2575 (while (and (not (eobp))
2576 (let ((prop
2577 (get-char-property (point) 'invisible)))
2578 (if (eq buffer-invisibility-spec t)
2579 prop
2580 (or (memq prop buffer-invisibility-spec)
2581 (assq prop buffer-invisibility-spec)))))
2582 (if (get-text-property (point) 'invisible)
2583 (goto-char (or (next-single-property-change (point) 'invisible)
2584 (point-max)))
2585 (goto-char (next-overlay-change (point)))))
2586 (setq arg (1- arg))) 2587 (setq arg (1- arg)))
2587 (while (< arg 0) 2588 (while (< arg 0)
2588 (beginning-of-line) 2589 (beginning-of-line)
2589 (and (zerop (vertical-motion -1)) 2590 (and (zerop (vertical-motion -1))
2590 (signal 'beginning-of-buffer nil)) 2591 (signal 'beginning-of-buffer nil))
2591 (while (and (not (bobp)) 2592 (setq arg (1+ arg))
2592 (let ((prop 2593 (while (and (not (bobp)) (line-move-invisible (1- (point))))
2593 (get-char-property (1- (point)) 'invisible))) 2594 (goto-char (previous-char-property-change (point)))))))
2594 (if (eq buffer-invisibility-spec t) 2595
2595 prop 2596 (line-move-finish (or goal-column temporary-goal-column) opoint)))
2596 (or (memq prop buffer-invisibility-spec)
2597 (assq prop buffer-invisibility-spec)))))
2598 (if (get-text-property (1- (point)) 'invisible)
2599 (goto-char (or (previous-single-property-change (point) 'invisible)
2600 (point-min)))
2601 (goto-char (previous-overlay-change (point)))))
2602 (setq arg (1+ arg))))
2603 (let ((buffer-invisibility-spec nil))
2604 (move-to-column (or goal-column temporary-goal-column))))
2605 (setq new (point))
2606 ;; If we are moving into some intangible text,
2607 ;; look for following text on the same line which isn't intangible
2608 ;; and move there.
2609 (setq line-end (save-excursion (end-of-line) (point)))
2610 (setq line-beg (save-excursion (beginning-of-line) (point)))
2611 (let ((after (and (< new (point-max))
2612 (get-char-property new 'intangible)))
2613 (before (and (> new (point-min))
2614 (get-char-property (1- new) 'intangible))))
2615 (when (and before (eq before after)
2616 (not (bolp)))
2617 (goto-char (point-min))
2618 (let ((inhibit-point-motion-hooks nil))
2619 (goto-char new))
2620 (if (<= new line-end)
2621 (setq new (point)))))
2622 ;; NEW is where we want to move to.
2623 ;; LINE-BEG and LINE-END are the beginning and end of the line.
2624 ;; Move there in just one step, from our starting position,
2625 ;; with intangibility and point-motion hooks enabled this time.
2626 (goto-char opoint)
2627 (setq inhibit-point-motion-hooks nil)
2628 (goto-char
2629 (constrain-to-field new opoint nil t 'inhibit-line-move-field-capture))
2630 ;; If intangibility processing moved us to a different line,
2631 ;; readjust the horizontal position within the line we ended up at.
2632 (when (or (< (point) line-beg) (> (point) line-end))
2633 (setq new (point))
2634 (setq inhibit-point-motion-hooks t)
2635 (setq line-end (save-excursion (end-of-line) (point)))
2636 (beginning-of-line)
2637 (setq line-beg (point))
2638 (let ((buffer-invisibility-spec nil))
2639 (move-to-column (or goal-column temporary-goal-column)))
2640 (if (<= (point) line-end)
2641 (setq new (point)))
2642 (goto-char (point-min))
2643 (setq inhibit-point-motion-hooks nil)
2644 (goto-char
2645 (constrain-to-field new opoint nil t
2646 'inhibit-line-move-field-capture)))))
2647 nil) 2597 nil)
2648 2598
2599(defun line-move-finish (column opoint)
2600 (let ((repeat t))
2601 (while repeat
2602 ;; Set REPEAT to t to repeat the whole thing.
2603 (setq repeat nil)
2604
2605 ;; Move to the desired column.
2606 (line-move-to-column column)
2607
2608 (let ((new (point))
2609 (line-beg (save-excursion (beginning-of-line) (point)))
2610 (line-end (save-excursion (end-of-line) (point))))
2611
2612 ;; Process intangibility within a line.
2613 ;; Move to the chosen destination position from above,
2614 ;; with intangibility processing enabled.
2615
2616 (goto-char (point-min))
2617 (let ((inhibit-point-motion-hooks nil))
2618 (goto-char new)
2619
2620 ;; If intangibility moves us to a different (later) place
2621 ;; in the same line, use that as the destination.
2622 (if (<= (point) line-end)
2623 (setq new (point))))
2624
2625 ;; Now move to the updated destination, processing fields
2626 ;; as well as intangibility.
2627 (goto-char opoint)
2628 (let ((inhibit-point-motion-hooks nil))
2629 (goto-char
2630 (constrain-to-field new opoint nil t
2631 'inhibit-line-move-field-capture)))
2632
2633 ;; If intangibility processing moved us to a different line,
2634 ;; retry everything within that new line.
2635 (when (or (< (point) line-beg) (> (point) line-end))
2636 ;; Repeat the intangibility and field processing.
2637 (setq repeat t))))))
2638
2639(defun line-move-to-column (col)
2640 "Try to find column COL, considering invisibility.
2641This function works only in certain cases,
2642because what we really need is for `move-to-column'
2643and `current-column' to be able to ignore invisible text."
2644 (move-to-column col)
2645
2646 (when (and line-move-ignore-invisible
2647 (not (bolp)) (line-move-invisible (1- (point))))
2648 (let ((normal-location (point))
2649 (normal-column (current-column)))
2650 ;; If the following character is currently invisible,
2651 ;; skip all characters with that same `invisible' property value.
2652 (while (and (not (eobp))
2653 (line-move-invisible (point)))
2654 (goto-char (next-char-property-change (point))))
2655 ;; Have we advanced to a larger column position?
2656 (if (> (current-column) normal-column)
2657 ;; We have made some progress towards the desired column.
2658 ;; See if we can make any further progress.
2659 (line-move-to-column (+ (current-column) (- col normal-column)))
2660 ;; Otherwise, go to the place we originally found
2661 ;; and move back over invisible text.
2662 ;; that will get us to the same place on the screen
2663 ;; but with a more reasonable buffer position.
2664 (goto-char normal-location)
2665 (let ((line-beg (save-excursion (beginning-of-line) (point))))
2666 (while (and (not (bolp)) (line-move-invisible (1- (point))))
2667 (goto-char (previous-char-property-change (point) line-beg))))))))
2668
2649;;; Many people have said they rarely use this feature, and often type 2669;;; Many people have said they rarely use this feature, and often type
2650;;; it by accident. Maybe it shouldn't even be on a key. 2670;;; it by accident. Maybe it shouldn't even be on a key.
2651(put 'set-goal-column 'disabled t) 2671(put 'set-goal-column 'disabled t)