From 4efebb82ef8b4894c6161d33495cbb3e428cba42 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 11 Jul 2008 18:07:01 +0000 Subject: [PATCH] (line-move-visual): Obey goal-column and no-error arg. (track-eol, temporary-goal-column): Update docstring. (move-end-of-line, move-beginning-of-line): Bind line-move-visual to nil. (line-move-visual): New var. (line-move-visual): New function. (line-move): Call line-move-visual. --- lisp/simple.el | 54 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/lisp/simple.el b/lisp/simple.el index 20165ea7f33..c4b47993456 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3871,7 +3871,8 @@ to use and more reliable (no dependence on goal column, etc.)." (defcustom track-eol nil "*Non-nil means vertical motion starting at end of line keeps to ends of lines. This means moving to the end of each line moved onto. -The beginning of a blank line does not count as the end of a line." +The beginning of a blank line does not count as the end of a line. +This has no effect when `line-move-visual' is non-nil." :type 'boolean :group 'editing-basics) @@ -3884,9 +3885,12 @@ The beginning of a blank line does not count as the end of a line." (defvar temporary-goal-column 0 "Current goal column for vertical motion. -It is the column where point was -at the start of current run of vertical motion commands. -When the `track-eol' feature is doing its job, the value is `most-positive-fixnum'.") +It is the column where point was at the start of the current run +of vertical motion commands. It is a floating point number when +moving by visual lines via `line-move-visual'; this is the +x-position, in pixels, divided by the default column width. When +the `track-eol' feature is doing its job, the value is +`most-positive-fixnum'.") (defcustom line-move-ignore-invisible t "*Non-nil means \\[next-line] and \\[previous-line] ignore invisible lines. @@ -3894,6 +3898,12 @@ Outline mode sets this." :type 'boolean :group 'editing-basics) +(defvar line-move-visual t + "When non-nil, `line-move' moves point by visual lines. +This movement is based on where the cursor is displayed on the +screen, instead of relying on buffer contents alone. It takes +into account variable-width characters and line continuation.") + ;; Returns non-nil if partial move was done. (defun line-move-partial (arg noerror to-end) (if (< arg 0) @@ -3966,7 +3976,30 @@ Outline mode sets this." (not executing-kbd-macro) (line-move-partial arg noerror to-end)) (set-window-vscroll nil 0 t) - (line-move-1 arg noerror to-end))) + (if line-move-visual + (line-move-visual arg noerror) + (line-move-1 arg noerror to-end)))) + +;; Display-based alternative to line-move-1. +;; Arg says how many lines to move. The value is t if we can move the +;; specified number of lines. +(defun line-move-visual (arg &optional noerror) + (unless (and (floatp temporary-goal-column) + (or (memq last-command '(next-line previous-line)) + ;; In case we're called from some other command. + (eq last-command this-command))) + (setq temporary-goal-column + (/ (car (nth 2 (posn-at-point))) 1.0 (frame-char-width)))) + (let ((moved (vertical-motion + (cons (or goal-column + (truncate temporary-goal-column)) + arg)))) + (or (= arg moved) + (unless noerror + (signal (if (< arg 0) + 'beginning-of-buffer + 'end-of-buffer) + nil))))) ;; This is the guts of next-line and previous-line. ;; Arg says how many lines to move. @@ -4230,7 +4263,8 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t." (while (not done) (let ((newpos (save-excursion - (let ((goal-column 0)) + (let ((goal-column 0) + (line-move-visual nil)) (and (line-move arg t) (not (bobp)) (progn @@ -4245,9 +4279,8 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t." (backward-char 1) (if (and (> (point) newpos) (not (eobp)) (not (eq (following-char) ?\n))) - ;; If we skipped something intangible - ;; and now we're not really at eol, - ;; keep going. + ;; If we skipped something intangible and now we're not + ;; really at eol, keep going. (setq arg 1) (setq done t))))))) @@ -4267,7 +4300,8 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t." ;; Move by lines, if ARG is not 1 (the default). (if (/= arg 1) - (line-move (1- arg) t)) + (let ((line-move-visual nil)) + (line-move (1- arg) t))) ;; Move to beginning-of-line, ignoring fields and invisibles. (skip-chars-backward "^\n") -- 2.39.2