unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* visual-line-mode
@ 2008-06-29  6:30 David Reitter
  2008-06-29  7:05 ` visual-line-mode Miles Bader
  2008-07-10  4:53 ` visual-line-mode Chong Yidong
  0 siblings, 2 replies; 73+ messages in thread
From: David Reitter @ 2008-06-29  6:30 UTC (permalink / raw)
  To: Emacs-Devel devel; +Cc: Chong Yidong, Lennart Borgman (gmail)

[-- Attachment #1: Type: text/plain, Size: 231 bytes --]

Here is the visual-line navigation mode that I promised.
It has only been tested minimally, and I haven't tried it with the  
trunk (because they don't compile or work on my machine).

Let me know how it works with the new DTWW.



[-- Attachment #2: visual-line.el --]
[-- Type: application/octet-stream, Size: 19975 bytes --]

;;; visual-line.el
;; Copyright (C) 2008 Free Software Foundation

;; Maintainer: David Reitter <david.reitter@gmail.com>
;; Authors: David Reitter 
;; Keywords: mail

;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Overview:
;;
;; `visual-line-mode' and `global-visual-line-mode' enable
;; navigation by visual lines.  Vertical movement commands such as
;; `next-line' and `previous-line' (normally bound to up/down arrow
;; keys) will move the point to the next line as shown on the
;; screen, even if that is the same line in the underlying buffer.
;; The point is moved to a position that is located (on the screen)
;; horizontally close (pixel-wise), rather than to an equivalent
;; by-character column.
;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Notable changes:
;;
;; Initial version:
;; This file was adapted from Aquamacs Emacs.
;; Lennart Borgmann contributed the code that creates a minor mode
;; for this.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Code Comments:
 
;; Note that `visual-line-up' and friends use two different methods to
;; figure out the best position to move to because of a slowness with
;; outline-(minor-)mode. One of the methods (basically binary search) is
;; much faster when a lot of hidden text is present, but a bit slower in
;; all other cases.


(defun visual-col-at-point ()
  "Returns the visual column at point.
The visual column is relative to the left window edge, not
to the beginning of the (unwrapped) line."
  (- (point)
     (save-excursion
       (vertical-motion 0)
       (point))))
;; seems slower (in situations with very long lines)
;;(or (car (nth 6 (posn-at-point))) 0))

(defun visual-pixel-col-at-point ()
  "Returns the pixel column at point.
This is the distance from the left edge of the window 
to the character at point."
  (or (car-safe 
       (pos-visible-in-window-p (point) nil 'partial))
      0))

(defvar visual-movement-temporary-goal-column nil)
(make-variable-buffer-local 'visual-movement-temporary-goal-column)

(defvar visual-previous-scroll-margin 'none)
(defun visual-restore-scroll-margin ()
  "Restore the scroll margin."
  (if (integerp visual-previous-scroll-margin)
      (setq scroll-margin visual-previous-scroll-margin))
  (remove-hook 'pre-command-hook 'visual-restore-scroll-margin))

(defcustom visual-scroll-margin nil
 "Number of lines of margin at top and bottom of a window.
For visual scrolling with up and down keys, this value
applies instead of `scroll-margin' if it is non-nil.

The reason this variable exists is that clicks in the first and last
line of a window will set the cursor within the standard scroll-margin,
causing the buffer to scroll immediately. This is usually undesired.
In this case, set `scroll-margin' to zero and `visual-scroll-margin'
to the desired margin."
 :group 'Windows)

(defun visual-line-up (num-lines)
 "Move cursor vertically up NUM-LINES lines.
Interactively, vscroll tall lines if `auto-window-vscroll' is
enabled.  If there is no character in the target line exactly
over the current horizontal pixel position, the cursor is
positioned close to the character in that line at the same position,
or at the end of the line if it is not long enough.

The command C-x C-n can be used to create
a semipermanent goal column for this command.
Then instead of trying to move exactly vertically (or as close as
possible),
this command moves to the specified goal column (or as close as
possible).
The goal column is stored in the variable `goal-column', which is nil
when there is no goal column.

This function differs from `previous-line' as it moves vertically
in the visual sense. The result differs when variable-width font is
used or when characters of non-standard width (e.g. TABs) are used.

If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead.  It is usually easier
to use and more reliable (no dependence on goal column, etc.)."
 (interactive "p")
 (if (bobp) (signal 'beginning-of-buffer nil))
 (let ((pixel-col (visual-pixel-col-at-point))
	(visual-col (visual-col-at-point))
	(old-point (point))
	(end-of-old-line))

   ;; temporary binding of scroll-margin
   ;; cannot do this with a temporary let binding
   (setq visual-previous-scroll-margin scroll-margin)
   (if visual-scroll-margin
	(setq scroll-margin visual-scroll-margin))
   (add-hook 'pre-command-hook 'visual-restore-scroll-margin)

   (save-excursion
     (vertical-motion 1)	;; trying going one down, to left
     (setq end-of-old-line (point)))

   (vertical-motion 0)

   (let* ((beg-of-old-line
           ;; move right, but not further than to end of line
	    (prog1 (point)
	      (vertical-motion (- num-lines))))	    ;; one up again
	   (beg-of-new-line (point))
	   (rel-beg-of-old-line  (- beg-of-old-line (point) 1)))

     ;; handle track-eol...
     (if (and track-eol (= old-point (1- end-of-old-line))
	       ;; Don't count beg of empty line as end of line
	       ;; unless we just did explicit end-of-line.
	       (or (not (= old-point beg-of-old-line))
		   (eq last-command 'end-of-line)))
	  (setq visual-movement-temporary-goal-column 9999))

     ;; approximate positioning
     (if (and (or goal-column visual-movement-temporary-goal-column)
	       (memq last-command '(visual-line-up
				    visual-line-down
				    visual-line-up-in-buffers
				    visual-line-down-in-buffers))
	       (= old-point (1- end-of-old-line)))
	  ;; jumping from end of line

         (forward-char (min (or goal-column
                                visual-movement-temporary-goal-column)
                            rel-beg-of-old-line))
	;; else, do complete positioning
	;; save original position
	(setq visual-movement-temporary-goal-column visual-col)
                                       ;	(forward-char (min visual-col rel-beg-of-old-line))

	;; this won't work because we don't have the
	;; absolute position, just the position within window
	;; (let ((p (pos-visible-in-window-p old-point nil 'p))
       ;; 	      (p2 (pos-visible-in-window-p beg-of-new-line nil 'p) ))
       ;; 	  (print (cons (car p) (cdr p2)))
       ;; 	  (posn-set-point (cons (car p) (cdr p2)))
       ;; 	  )
	(if (> (abs (- (point) beg-of-old-line)) 400)
	    ;; find-position-at-pixel-col is much faster when
	    ;; large portions of hidden text are to be crossed.
	    ;; this can happen in outline-(minor-)mode for instance.
	    (goto-char (find-position-at-pixel-col  pixel-col))
	  ;; approximate positioning
	  (forward-char (min visual-col rel-beg-of-old-line))
	  (if (>= (visual-pixel-col-at-point) pixel-col)
	      (progn
		(while (and
			(> (visual-pixel-col-at-point) pixel-col)
			(> (point) beg-of-new-line)) ;; do not cross line
		  (forward-char -1)))
	    (progn
	      (while (and
		      (< (visual-pixel-col-at-point) pixel-col)
		      (< (point) (1- beg-of-old-line))) ;; do not cross line
		(forward-char +1)))))

	))))

(defun visual-line-down (num-lines)
  "Move cursor vertically down NUM-LINES lines.
Interactively, vscroll tall lines if `auto-window-vscroll' is
enabled.  If there is no character in the target line exactly
under the current column, the cursor is positioned after the
character in that line which spans this column, or at the end of
the line if it is not long enough.  If there is no line in the
buffer after this one, behavior depends on the value of
`next-line-add-newlines'.  If non-nil, it inserts a newline
character to create a line, and moves the cursor to that line.
Otherwise it moves the cursor to the end of the buffer.

The command C-x C-n can be used to create a semipermanent goal
column for this command.  Then instead of trying to move exactly
vertically (or as close as possible), this command moves to the
specified goal column (or as close as possible).  The goal column
is stored in the variable `goal-column', which is nil when there
is no goal column.

This function differs from `next-line' as it moves vertically in
the visual sense. The result differs when variable-width font is
used or when characters of non-standard width (e.g. TABs) are
used.

If you are thinking of using this in a Lisp program, consider
using `forward-line' instead.  It is usually easier to use and
more reliable (no dependence on goal column, etc.)."
  (interactive "p")
  (if (and next-line-add-newlines (= num-lines 1))
      (if (save-excursion (end-of-line) (eobp))
	  ;; When adding a newline, don't expand an abbrev.
	  (let ((abbrev-mode nil))
	    (end-of-line)
	    (insert hard-newline)))
    (if (eobp) (signal 'end-of-buffer nil)))
  (let ((pixel-col (visual-pixel-col-at-point))
	(visual-col (visual-col-at-point))
	(old-point (point))
	(beg-of-line)
	(next-line-start)
	(rel-next-line-start))

    ;; temporary binding of scroll-margin
    ;; cannot do this with a temporary let binding
    (setq visual-previous-scroll-margin scroll-margin)
    (if visual-scroll-margin
	(setq scroll-margin visual-scroll-margin))
    (add-hook 'pre-command-hook 'visual-restore-scroll-margin)

    (vertical-motion num-lines) ;; down
    (save-excursion
      (setq beg-of-line (point))
      (vertical-motion +1) ;; down
      (setq next-line-start (point))
      (setq rel-next-line-start  (- (point) beg-of-line 1)))
    (unless (= beg-of-line (point-max))
      ;; handle track-eol...
      (if (and track-eol (= old-point (1- next-line-start))
	       ;; Don't count beg of empty line as end of line
	       ;; unless we just did explicit end-of-line.
	       (or (not (= 0 visual-col))
		   (eq last-command 'end-of-line)))
	  (setq visual-movement-temporary-goal-column 9999))
      ;; approximate positioning
      (if (and (or goal-column visual-movement-temporary-goal-column)
	       (memq last-command '(visual-line-up
				    visual-line-down
				    visual-line-up-in-buffers
				    visual-line-down-in-buffers))
	       (= old-point (- beg-of-line 1))) ;; jumping from end of line

	  (forward-char (min (or goal-column
				 visual-movement-temporary-goal-column)
			     rel-next-line-start))
	;; else, do complete positioning
	;; save original position
	(setq visual-movement-temporary-goal-column visual-col)
	;; find-position-at-pixel-col is much faster when
	;; large portions of hidden text are to be crossed.
	;; this can happen in outline-(minor-)mode for instance.
	(if (> (abs (- old-point next-line-start)) 400)
	    (goto-char (find-position-at-pixel-col  pixel-col))
	  (forward-char (min visual-col rel-next-line-start))
	  (if (> (visual-pixel-col-at-point) pixel-col)
	      (progn
		(while (and
			(> (visual-pixel-col-at-point) pixel-col)
			(> (point) beg-of-line)) ;; do not cross line
		  (forward-char -1)))
	    (progn
	      (while (and
		      (< (visual-pixel-col-at-point) pixel-col)
		      (< (point) (1- next-line-start))) ;; do not cross line
		(forward-char +1)))))))))

(defun find-position-at-pixel-col  (pixel-col)
  (let ((beg-of-line) (end-of-line))
    (vertical-motion 1)	;; trying going one down, to left
    (setq end-of-line (point))
    (if (eq (point) (point-max)) (vertical-motion 0) 
      (vertical-motion -1))
    (setq beg-of-line (point))
    (let ((op (point)))
      ;; move to beg of line
      (vertical-motion 0) ;; trying going one down, to left
      (forward-char (/ pixel-col (frame-char-width)))
      (find-position-at-pixel-col-recursive
       beg-of-line end-of-line pixel-col)
      (let* ((nearest-pos (point))
	     (smallest-distance
	      (abs (- pixel-col (visual-pixel-col-at-point)))))
	(let ((pdif (abs (- pixel-col
			    (progn (forward-char -1)
				   (visual-pixel-col-at-point))))))
	  (when (< pdif smallest-distance)
	    (setq nearest-pos (point))
	    (setq smallest-distance pdif)))
	(let ((pdif (abs (- pixel-col
			    (progn (forward-char 2)
				   (visual-pixel-col-at-point))))))
	  (when (< pdif smallest-distance)
	    (setq nearest-pos (point))
	    (setq smallest-distance pdif)))
	(goto-char nearest-pos))
      (point))))

(defun find-position-at-pixel-col-recursive
  (beg-of-line end-of-line pixel-col)
  ;; set it in the middle
  (if (eq beg-of-line end-of-line)
      (point)
    (let ((middle (+ beg-of-line 
		     (round (/ (- end-of-line beg-of-line) 2)))))
      (if (or (eq middle (point)) ;; wouldn't change point any more
	      (eq (visual-pixel-col-at-point) pixel-col))
	  (point)
	(goto-char middle)
	(if (> (visual-pixel-col-at-point) pixel-col)
	    (find-position-at-pixel-col-recursive
	     beg-of-line (point) pixel-col)
	  (find-position-at-pixel-col-recursive
	   (point) end-of-line pixel-col))))))


(defun beginning-of-visual-line ()
  "Move point to the beginning of the current visual line."
  (interactive)
  (if (bobp)
      (signal 'beginning-of-buffer nil))
  (vertical-motion 0))

(defun end-of-visual-line ()
  "Move point to the end of the current visual line."
  (interactive)
  (if (eobp)
      (signal 'end-of-buffer nil))
  (let ((end-of-line (line-end-position)))
    (vertical-motion 1)
    (unless (eobp)
      ;;or: (< (point) end-of-line) ;; jumping over wrapped text
      (backward-char 1))))

;; this code based on simple.el
(defun kill-visual-line (&optional arg)
  "Kill the rest of the visual line; if no nonblanks there, kill thru
newline.
With prefix argument, kill that many lines from point.
Negative arguments kill lines backward.
With zero argument, kills the text before point on hthe current line.

When calling from a program, nil means \"no arg\",
a number counts as a prefix arg.

To kill a whole line, when point is not at the beginning, type \
\\[beginning-of-line] \\[kill-line] \\[kill-line].

If `kill-whole-line' is non-nil, then this command kills the whole line
including its terminating newline, when used at the beginning of a line
with no argument.  As a consequence, you can always kill a whole line
by typing \\[beginning-of-line] \\[kill-line].

If you want to append the killed line to the last killed text,
use \\[append-next-kill] before \\[kill-line].

If the buffer is read-only, Emacs will beep and refrain from deleting
the line, but put the line in the kill ring anyway.  This means that
you can use this command to copy text from a read-only buffer.
\(If the variable `kill-read-only-ok' is non-nil, then this won't
even beep.)"
  (interactive "P")
  (kill-region (point)
	       ;; It is better to move point to the other end of the
	       ;; kill before killing.  That way, in a read-only
	       ;; buffer, point moves across the text that is copied
	       ;; to the kill ring.  The choice has no effect on undo
	       ;; now that undo records the value of point from before
	       ;; the command was run.
	       (progn
		 (if arg
		     (vertical-motion (prefix-numeric-value arg))
		   (if (eobp)
		       (signal 'end-of-buffer nil))
		   (let ((end
			  (save-excursion
			    (end-of-visual-line) (point))))
		     (if (or (save-excursion
			       ;; If trailing whitespace is visible,
			       ;; don't treat it as nothing.
			       (unless show-trailing-whitespace
				 (skip-chars-forward " \t" end))
			       (= (point) end))
			     (and kill-whole-line (bolp)))
			 (visual-line-down 1)
		       (goto-char end))))
		 (point))))

(defun kill-whole-visual-line (&optional arg)
  "Kill current visual line.
With prefix arg, kill that many lines starting from the current line.
If arg is negative, kill backward.  Also kill the preceding newline.
\(This is meant to make \\[repeat] work well with negative arguments.\)
If arg is zero, kill current line but exclude the trailing newline."
  (interactive "p")
  (if (and (> arg 0) (eobp) (save-excursion (vertical-motion 0) (eobp)))
      (signal 'end-of-buffer nil))
  (if (and (< arg 0) (bobp) (save-excursion (vertical-motion 1) (bobp)))
      (signal 'beginning-of-buffer nil))
  (unless (eq last-command 'kill-region)
    (kill-new "")
    (setq last-command 'kill-region))
  (cond ((zerop arg)
	 ;; We need to kill in two steps, because the previous command
	 ;; could have been a kill command, in which case the text
	 ;; before point needs to be prepended to the current kill
	 ;; ring entry and the text after point appended.  Also, we
	 ;; need to use save-excursion to avoid copying the same text
	 ;; twice to the kill ring in read-only buffers.
	 (save-excursion
	   ;; delete in one go
	   (kill-region (progn (vertical-motion 0) (point))
			(progn (vertical-motion 1) (point)))
	   ))
	((< arg 0)
	 (save-excursion
	   (kill-region (point) (progn (end-of-visual-line) (point))))
	 (kill-region (point)
		      (progn (vertical-motion (1+ arg))
			     (unless (bobp) (backward-char))
			     (point))))
	(t
	 (save-excursion
	   (kill-region (progn (vertical-motion 0) (point))
			(progn (vertical-motion arg) (point)))))))

(defun visual-line-up-in-buffers ()
 "Moves the cursor up one (visual) line.
If the `up' key would normally be bound to something else than
`previous-line' (as it is the case in minibuffers), the other binding
is called."
 (interactive)
 (let* (visual-line-mode  ;; turn off mode temporarily
	 (binding (key-binding [up])))
   (if (eq binding 'previous-line)
	(call-interactively (function visual-line-up))
     (call-interactively binding))))

(defun visual-line-down-in-buffers ()
 "Moves the cursor down one (visual) line.
If the `down' key would normally be bound to something else than
`next-line' (as it is the case in minibuffers), the other binding
is called."
 (interactive)
 (let* (visual-line-mode  ;; turn off mode temporarily
	 (binding (key-binding [down])))
   (if (eq binding 'next-line)
	(call-interactively (function visual-line-down))
     (call-interactively binding))))

;; mark functions for CUA
(dolist (cmd
	 '( beginning-of-visual-line
	    end-of-visual-line
	    visual-line-down visual-line-up
	    visual-line-up-in-buffers
	    visual-line-down-in-buffers))
 (put cmd 'CUA 'move))

(defalias 'original-kill-line 'kill-line)
(defalias 'original-next-line 'next-line)
(defalias 'original-previous-line 'previous-line)

(defun line-wrapped-p ()
  "Return non-nil if the current line is wrapped."
  (let ((here (point))
        result)
    (vertical-motion 0)
    (setq result (/= (line-beginning-position) (point)))
    (unless result
      (let ((line-end-pos (line-end-position)))
        (vertical-motion 1)
        (setq result (/= line-end-pos (- (point) 1)))))
    (goto-char here)
    result))

(defvar visual-line-map
 (let ((map (make-sparse-keymap)))
   (define-key map [remap next-line] 'visual-line-down)
   (define-key map [remap previous-line] 'visual-line-up)
   (define-key map [remap kill-line] 'kill-visual-line)
   (define-key map [(control shift ?k)] 'original-kill-line)
   (define-key map [remap move-beginning-of-line] 'beginning-of-visual-line)
   (define-key map [remap move-end-of-line]  'end-of-visual-line)
   map))

(define-minor-mode visual-line-mode
 "Define key binding for visual line moves."
 :keymap visual-line-map
 :group 'convenience)

(defun turn-on-visual-line-mode ()
 (visual-line-mode 1))

(define-globalized-minor-mode global-visual-line-mode
 visual-line-mode turn-on-visual-line-mode
 :lighter " vl")



(provide 'visual-line)

[-- Attachment #3: Type: text/plain, Size: 1 bytes --]



^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29  6:30 visual-line-mode David Reitter
@ 2008-06-29  7:05 ` Miles Bader
  2008-06-29  7:19   ` visual-line-mode Miles Bader
                     ` (2 more replies)
  2008-07-10  4:53 ` visual-line-mode Chong Yidong
  1 sibling, 3 replies; 73+ messages in thread
From: Miles Bader @ 2008-06-29  7:05 UTC (permalink / raw)
  To: David Reitter; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
> Let me know how it works with the new DTWW.

It basically doesn't work at all with display-time word-wrapping turned
on.

I presume much of the problem is with emacs primitives (vertical-motion
etc) though.

With word-wrapping turned off, it kinda-sorta works.

I noticed the following:

  (1) It seems extremely slow -- moving from line to line is noticeably
      laggy, and sometimes will just ... hang for a while, even if
      there's no wrapped lines at all.

  (2) It seems to cons a lot; even just a bit of movement results in
      frequent pauses to garbage collect (again, this happens even
      without any wrapped lines).

  (3) When the default face is variable-pitch, the positioning with
      C-n/C-p seems a bit "rough".  V.W. fonts, one can't be completely
      precise, but it probably ought to at least use some notion of
      pixel goal column to avoid the tendency of the horizontal position
      to drift with a lot of vertical movement.

I expect emacs primitives will need improvement to work for the
word-wrapping case (and display-time line-prefixes which I've hacked up
locally), so perhaps they can be improved to work better in general too.

-Miles

-- 
My spirit felt washed.  With blood.  [Eli Shin, on "The Passion of the Christ"]




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29  7:05 ` visual-line-mode Miles Bader
@ 2008-06-29  7:19   ` Miles Bader
  2008-06-29 14:01   ` visual-line-mode Stefan Monnier
  2008-06-30  7:32   ` visual-line-mode David Reitter
  2 siblings, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-06-29  7:19 UTC (permalink / raw)
  To: David Reitter; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

Oh, another point I noticed:

  (4) It doesn't properly respect `field' properties.

-Miles

-- 
"Most attacks seem to take place at night, during a rainstorm, uphill,
 where four map sheets join."   -- Anon. British Officer in WW I




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29  7:05 ` visual-line-mode Miles Bader
  2008-06-29  7:19   ` visual-line-mode Miles Bader
@ 2008-06-29 14:01   ` Stefan Monnier
  2008-06-29 15:29     ` visual-line-mode Chong Yidong
  2008-06-30  3:07     ` visual-line-mode Miles Bader
  2008-06-30  7:32   ` visual-line-mode David Reitter
  2 siblings, 2 replies; 73+ messages in thread
From: Stefan Monnier @ 2008-06-29 14:01 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Chong Yidong, Lennart Borgman (gmail),
	Emacs-Devel devel

> I expect emacs primitives will need improvement to work for the
> word-wrapping case (and display-time line-prefixes which I've hacked up
> locally), so perhaps they can be improved to work better in general too.

After looking a bit more at the various visual line movement packages,
and remembering that I've just added a `cols' arg to vertical-motion,
I believe the patch below provides basically the behavior we want.

As it turns out, it doesn't work right with word-wrapping because
posn-at-point returns funny X positions.  Probably the same underlying
bug causes sometimes mouse-clicks to place point elsewhere than under
the mouse.


        Stefan


=== modified file 'lisp/simple.el'
--- lisp/simple.el	2008-06-21 02:48:08 +0000
+++ lisp/simple.el	2008-06-29 13:36:08 +0000
@@ -4030,6 +4030,16 @@
 	 (t
 	  (set-window-vscroll nil (frame-char-height) t)))))))
 
+(defvar line-move-visual t)
+
+(defun line-move-visual (arg)
+  (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))))
+  (vertical-motion (cons (truncate temporary-goal-column) arg)))
 
 ;; This is like line-move-1 except that it also performs
 ;; vertical scrolling of tall images if appropriate.
@@ -4046,7 +4056,9 @@
 	       (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)
+      (line-move-1 arg noerror to-end))))
 
 ;; This is the guts of next-line and previous-line.
 ;; Arg says how many lines to move.





^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29 14:01   ` visual-line-mode Stefan Monnier
@ 2008-06-29 15:29     ` Chong Yidong
  2008-06-30  3:07     ` visual-line-mode Miles Bader
  1 sibling, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-06-29 15:29 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> As it turns out, it doesn't work right with word-wrapping because
> posn-at-point returns funny X positions.  Probably the same underlying
> bug causes sometimes mouse-clicks to place point elsewhere than under
> the mouse.

Could you give a test-case?




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29 14:01   ` visual-line-mode Stefan Monnier
  2008-06-29 15:29     ` visual-line-mode Chong Yidong
@ 2008-06-30  3:07     ` Miles Bader
  2008-06-30  3:15       ` visual-line-mode Chong Yidong
  1 sibling, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-06-30  3:07 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Chong Yidong, Lennart Borgman (gmail),
	Emacs-Devel devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:
> As it turns out, it doesn't work right with word-wrapping because
> posn-at-point returns funny X positions.  Probably the same underlying
> bug causes sometimes mouse-clicks to place point elsewhere than under
> the mouse.

Perhaps the word-wrap changes to display_line and move_it_* are not
entirely consistent.

-Miles

-- 
Mayonnaise, n. One of the sauces that serve the French in place of a state
religion.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  3:07     ` visual-line-mode Miles Bader
@ 2008-06-30  3:15       ` Chong Yidong
  2008-06-30  5:13         ` visual-line-mode Miles Bader
  0 siblings, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-06-30  3:15 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Miles Bader <miles.bader@necel.com> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> As it turns out, it doesn't work right with word-wrapping because
>> posn-at-point returns funny X positions.  Probably the same underlying
>> bug causes sometimes mouse-clicks to place point elsewhere than under
>> the mouse.
>
> Perhaps the word-wrap changes to display_line and move_it_* are not
> entirely consistent.

That's a good guess.  Unfortunately, I can't seem to reproduce it.
Maybe it's the font I'm using.  Could someone try to set up a detailed
recipe?




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  3:15       ` visual-line-mode Chong Yidong
@ 2008-06-30  5:13         ` Miles Bader
  2008-06-30  5:15           ` visual-line-mode Miles Bader
  2008-07-03 19:20           ` visual-line-mode Chong Yidong
  0 siblings, 2 replies; 73+ messages in thread
From: Miles Bader @ 2008-06-30  5:13 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 1527 bytes --]

Chong Yidong <cyd@stupidchicken.com> writes:
>>> As it turns out, it doesn't work right with word-wrapping because
>>> posn-at-point returns funny X positions.  Probably the same underlying
>>> bug causes sometimes mouse-clicks to place point elsewhere than under
>>> the mouse.
>>
>> Perhaps the word-wrap changes to display_line and move_it_* are not
>> entirely consistent.
>
> That's a good guess.  Unfortunately, I can't seem to reproduce it.
> Maybe it's the font I'm using.  Could someone try to set up a detailed
> recipe?

The following text seems to illustrate it for me (I've added it as an
attachment as well, juuust in case).  Put the following long line in a
buffer, and do with (setq word-wrap t), and have Stefan's
line-mode-visual patch enabled:

12:25 *** TOPIC openssl vulnerability: /msg dpkg dsa1571 | 4.0r3 released /msg dpkg etch | /msg dpkg etch->lenny | Offtopic: #debian-offtopic | PUBLIC KEY NOT AVAILABLE? /msg dpkg no public key | THIS IS NOT #ubuntu | FAQ: 

With point at the start of the buffer, you can move with C-n to the next
visual line with no problem, but if you do C-n again at that point, it
acts screwy.

(posn-at-point) does indeed seem to return incorrect results:  after the
first C-n, with the cursor visually located at the start of the 2nd
"visual line", (posn-at-point) returns results with very large  X
coordinates, as if it thinks the cursor is still at the end of the
previous line:

   (#<window 62 on lkasjdf> 81 (640 . 0) 0 nil 81 (80 . 0) nil (0 . 0) (0 . 17))

-Miles


[-- Attachment #2: blarch --]
[-- Type: application/octet-stream, Size: 223 bytes --]

12:25 *** TOPIC openssl vulnerability: /msg dpkg dsa1571 | 4.0r3 released /msg dpkg etch | /msg dpkg etch->lenny | Offtopic: #debian-offtopic | PUBLIC KEY NOT AVAILABLE? /msg dpkg no public key | THIS IS NOT #ubuntu | FAQ: 

[-- Attachment #3: Type: text/plain, Size: 74 bytes --]



-- 
Monday, n. In Christian countries, the day after the baseball game.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  5:13         ` visual-line-mode Miles Bader
@ 2008-06-30  5:15           ` Miles Bader
  2008-06-30 10:39             ` visual-line-mode Miles Bader
  2008-07-03 19:20           ` visual-line-mode Chong Yidong
  1 sibling, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-06-30  5:15 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

BTW, the font I'm using is (according to C-u C-x =):

xft:-unknown-DejaVu Sans Mono-normal-normal-normal-*-12-*-*-*-m-0-iso8859-1

-Miles

-- 
Everywhere is walking distance if you have the time.  -- Steven Wright




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29  7:05 ` visual-line-mode Miles Bader
  2008-06-29  7:19   ` visual-line-mode Miles Bader
  2008-06-29 14:01   ` visual-line-mode Stefan Monnier
@ 2008-06-30  7:32   ` David Reitter
  2008-06-30  7:43     ` visual-line-mode Miles Bader
  2 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-06-30  7:32 UTC (permalink / raw)
  To: Miles Bader; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

On 29 Jun 2008, at 09:05, Miles Bader wrote:
>
> I presume much of the problem is with emacs primitives (vertical- 
> motion
> etc) though.

Yes, because it works fine for me with normal (non-word) wrapping.

>  (1) It seems extremely slow -- moving from line to line is noticeably
>      laggy, and sometimes will just ... hang for a while, even if
>      there's no wrapped lines at all.
>
>  (2) It seems to cons a lot; even just a bit of movement results in
>      frequent pauses to garbage collect (again, this happens even
>      without any wrapped lines).

It's an iterative approach, primarily because we don't have the right  
Emacs primitives.
That said, it's been nice and fast and we've used for standard  
movement commands for a while now.  So I'm not sure what the problem is.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  7:32   ` visual-line-mode David Reitter
@ 2008-06-30  7:43     ` Miles Bader
  2008-06-30  7:58       ` visual-line-mode David Reitter
  0 siblings, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-06-30  7:43 UTC (permalink / raw)
  To: David Reitter; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
>>  (1) It seems extremely slow -- moving from line to line is noticeably
>>      laggy, and sometimes will just ... hang for a while, even if
>>      there's no wrapped lines at all.
>>
>>  (2) It seems to cons a lot; even just a bit of movement results in
>>      frequent pauses to garbage collect (again, this happens even
>>      without any wrapped lines).
>
> It's an iterative approach, primarily because we don't have the right
> Emacs primitives.  That said, it's been nice and fast and we've used
> for standard movement commands for a while now.  So I'm not sure what
> the problem is.

Perhaps you're using a powerful system so that slowdowns aren't very
noticeable.  I presume you'd see the "gcing..." msgs though ... oh wait,
aren't those turned of by default now?

-Miles

-- 
(\(\
(^.^)
(")")
*This is the cute bunny virus, please copy this into your sig so it can spread.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  7:43     ` visual-line-mode Miles Bader
@ 2008-06-30  7:58       ` David Reitter
  2008-06-30  8:05         ` visual-line-mode Miles Bader
  0 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-06-30  7:58 UTC (permalink / raw)
  To: Miles Bader; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

On 30 Jun 2008, at 09:43, Miles Bader wrote:
>
> Perhaps you're using a powerful system so that slowdowns aren't very
> noticeable.  I presume you'd see the "gcing..." msgs though ... oh  
> wait,
> aren't those turned of by default now?

No, I don't see them.

I agree that the right solution would be to provide the right Emacs  
primitives.  (It didn't seem anyone was willing to do it...)

- D




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  7:58       ` visual-line-mode David Reitter
@ 2008-06-30  8:05         ` Miles Bader
  2008-06-30  8:25           ` visual-line-mode David Reitter
  0 siblings, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-06-30  8:05 UTC (permalink / raw)
  To: David Reitter; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
> No, I don't see them.
>
> I agree that the right solution would be to provide the right Emacs
> primitives.  (It didn't seem anyone was willing to do it...)

FWIW, Stefan's patch seems to work a bit better (functionally), and
feels much faster.  It apparently uses a new feature of
`vertical-motion'.

-Miles

-- 
Politics, n. A strife of interests masquerading as a contest of
principles. The conduct of public affairs for private advantage.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  8:05         ` visual-line-mode Miles Bader
@ 2008-06-30  8:25           ` David Reitter
  2008-06-30  8:30             ` visual-line-mode Miles Bader
  0 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-06-30  8:25 UTC (permalink / raw)
  To: Miles Bader; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

On 30 Jun 2008, at 10:05, Miles Bader wrote:
>
> FWIW, Stefan's patch seems to work a bit better (functionally), and
> feels much faster.  It apparently uses a new feature of
> `vertical-motion'.

The (COLS . LINES) specification?
Does it work with variable-width fonts?

Most of the time in my algorithm is spent on figuring out where to go  
in text set in variable-width fonts.





^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  8:25           ` visual-line-mode David Reitter
@ 2008-06-30  8:30             ` Miles Bader
  0 siblings, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-06-30  8:30 UTC (permalink / raw)
  To: David Reitter; +Cc: Chong Yidong, Lennart Borgman (gmail), Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
>> FWIW, Stefan's patch seems to work a bit better (functionally), and
>> feels much faster.  It apparently uses a new feature of
>> `vertical-motion'.
>
> The (COLS . LINES) specification?
> Does it work with variable-width fonts?

Seems to.

As you probably read elsewhere in this thread, there are some problems
with word-wrapping active, but they seem due to bugs in lower-level functions.

-Miles

-- 
Justice, n. A commodity which in a more or less adulterated condition the
State sells to the citizen as a reward for his allegiance, taxes and personal
service.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  5:15           ` visual-line-mode Miles Bader
@ 2008-06-30 10:39             ` Miles Bader
  2008-06-30 11:20               ` visual-line-mode Miles Bader
                                 ` (2 more replies)
  0 siblings, 3 replies; 73+ messages in thread
From: Miles Bader @ 2008-06-30 10:39 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Incidentally, I notice that in cases where posn-at-point is returning
bogus values for word-wrapped lines, it looks like it's just ignoring
word-wrap entirely -- the values returned would be correct if word-wrap
were turned off!

In otherwords, the non-word-wrapped line looked like:

   word1 word2 longw\
   Xrd3 word4

and (posn-at-point) returns x-y of (0 . 1) when the cursor is at the "X".

If I turn on word-wrapping, and the display looks like:

   word1 word2      \
   longwXrd3 word4

Then the first place where (posn-at-point) returns (0 . 1) is when the
cursor is on the "X" again; for positions on the 2nd line but before the
"X", posn-at-point returns a y-value of 1, and large x-values as if the
cursor were still near the end of the first line.

[Do the move_it_* functions even attempt to handle word-wrapping?]

-Miles

-- 
It wasn't the Exxon Valdez captain's driving that caused the Alaskan oil spill.
It was yours.  [Greenpeace advertisement, New York Times, 25 February 1990]




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30 10:39             ` visual-line-mode Miles Bader
@ 2008-06-30 11:20               ` Miles Bader
  2008-06-30 14:01               ` visual-line-mode Chong Yidong
  2008-07-01  9:10               ` visual-line-mode David Reitter
  2 siblings, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-06-30 11:20 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Miles Bader <miles@gnu.org> writes:
> [Do the move_it_* functions even attempt to handle word-wrapping?]

Hmm in _other_ cases, the posn-at-point values seem to be correct for
word-wrapping though...

-Miles

-- 
"Most attacks seem to take place at night, during a rainstorm, uphill,
 where four map sheets join."   -- Anon. British Officer in WW I




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30 10:39             ` visual-line-mode Miles Bader
  2008-06-30 11:20               ` visual-line-mode Miles Bader
@ 2008-06-30 14:01               ` Chong Yidong
  2008-06-30 16:10                 ` visual-line-mode Chong Yidong
  2008-07-01  9:10               ` visual-line-mode David Reitter
  2 siblings, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-06-30 14:01 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Miles Bader <miles@gnu.org> writes:

> [Do the move_it_* functions even attempt to handle word-wrapping?]

Yes, there's code in move_it_in_display_line_to that tries to do this.
Probably a corner case is falling through.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30 14:01               ` visual-line-mode Chong Yidong
@ 2008-06-30 16:10                 ` Chong Yidong
  0 siblings, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-06-30 16:10 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Chong Yidong <cyd@stupidchicken.com> writes:

> Miles Bader <miles@gnu.org> writes:
>
>> [Do the move_it_* functions even attempt to handle word-wrapping?]
>
> Yes, there's code in move_it_in_display_line_to that tries to do this.
> Probably a corner case is falling through.

Okay, apparently the code in move_it_in_display_line_to doesn't handle
the MOVE_TO_X option properly when line wrapping is on.

If someone would like to look into this, that would be great, since I'm
gonna be busy for the next couple of weeks.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30 10:39             ` visual-line-mode Miles Bader
  2008-06-30 11:20               ` visual-line-mode Miles Bader
  2008-06-30 14:01               ` visual-line-mode Chong Yidong
@ 2008-07-01  9:10               ` David Reitter
  2 siblings, 0 replies; 73+ messages in thread
From: David Reitter @ 2008-07-01  9:10 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

On 30 Jun 2008, at 12:39, Miles Bader wrote:

> Incidentally, I notice that in cases where posn-at-point is returning
> bogus values for word-wrapped lines, it looks like it's just ignoring
> word-wrap entirely -- the values returned would be correct if word- 
> wrap
> were turned off!

The same thing appears to happen with `vertical-motion'. Calling it  
with point at the first couple of characters of a visual line behaves  
as if word-wrap wasn't enabled at all.  I don't know if that's due to  
the same bug.

That's at least one of the things that prevents visual-line-mode from  
working with word wrapping.

(Tested with a 22 backport of Chong's patch.)







^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-30  5:13         ` visual-line-mode Miles Bader
  2008-06-30  5:15           ` visual-line-mode Miles Bader
@ 2008-07-03 19:20           ` Chong Yidong
  2008-07-03 23:56             ` visual-line-mode David Reitter
  1 sibling, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-03 19:20 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Could someone please test the following patch to xdisp.c?  It should fix
some bugs in the word-wrapping code, but there are probably still
lurking issues.


*** trunk/src/xdisp.c.~1.1227.~	2008-07-03 11:54:01.000000000 -0400
--- trunk/src/xdisp.c	2008-07-03 15:16:08.000000000 -0400
***************
*** 6664,6670 ****
  {
    enum move_it_result result = MOVE_UNDEFINED;
    struct glyph_row *saved_glyph_row;
!   struct it wrap_it, atpos_it;
    int may_wrap = 0;
  
    /* Don't produce glyphs in produce_glyphs.  */
--- 6664,6670 ----
  {
    enum move_it_result result = MOVE_UNDEFINED;
    struct glyph_row *saved_glyph_row;
!   struct it wrap_it, atpos_it, atx_it;
    int may_wrap = 0;
  
    /* Don't produce glyphs in produce_glyphs.  */
***************
*** 6672,6682 ****
    it->glyph_row = NULL;
  
    /* Use wrap_it to save a copy of IT wherever a word wrap could
!      occur.  Use atpos_it to save a copy of IT at the desired
       position, if found, so that we can scan ahead and check if the
!      word later overshoots the window edge.  */
    wrap_it.sp = -1;
    atpos_it.sp = -1;
  
  #define BUFFER_POS_REACHED_P()					\
    ((op & MOVE_TO_POS) != 0					\
--- 6672,6684 ----
    it->glyph_row = NULL;
  
    /* Use wrap_it to save a copy of IT wherever a word wrap could
!      occur.  Use atpos_it to save a copy of IT at the desired buffer
       position, if found, so that we can scan ahead and check if the
!      word later overshoots the window edge.  Use atx_it similarly, for
!      pixel positions.  */
    wrap_it.sp = -1;
    atpos_it.sp = -1;
+   atx_it.sp = -1;
  
  #define BUFFER_POS_REACHED_P()					\
    ((op & MOVE_TO_POS) != 0					\
***************
*** 6705,6718 ****
  	{
  	  if (it->line_wrap == WORD_WRAP)
  	    {
- 	      /* If wrap_it is valid, the current position might be in
- 		 a word that is wrapped to the next line, so continue
- 		 to see if that happens.  */
  	      if (wrap_it.sp < 0)
  		{
  		  result = MOVE_POS_MATCH_OR_ZV;
  		  break;
  		}
  	      if (atpos_it.sp < 0)
  		atpos_it = *it;
  	    }
--- 6707,6720 ----
  	{
  	  if (it->line_wrap == WORD_WRAP)
  	    {
  	      if (wrap_it.sp < 0)
  		{
  		  result = MOVE_POS_MATCH_OR_ZV;
  		  break;
  		}
+ 	      /* If wrap_it is valid, the current position might be in
+ 		 a word that is wrapped to the next line, so continue
+ 		 to see if that happens.  */
  	      if (atpos_it.sp < 0)
  		atpos_it = *it;
  	    }
***************
*** 6759,6766 ****
  		  if (atpos_it.sp >= 0)
  		    {
  		      *it = atpos_it;
! 		      atpos_it.sp = -1;
! 		      goto buffer_pos_reached;
  		    }
  		  wrap_it = *it;
  		  may_wrap = 0;
--- 6761,6774 ----
  		  if (atpos_it.sp >= 0)
  		    {
  		      *it = atpos_it;
! 		      result = MOVE_POS_MATCH_OR_ZV;
! 		      goto done;
! 		    }
! 		  if (atx_it.sp >= 0)
! 		    {
! 		      *it = atx_it;
! 		      result = MOVE_X_REACHED;
! 		      goto done;
  		    }
  		  wrap_it = *it;
  		  may_wrap = 0;
***************
*** 6816,6836 ****
  	      /* We want to leave anything reaching TO_X to the caller.  */
  	      if ((op & MOVE_TO_X) && new_x > to_x)
  		{
! 		  if (BUFFER_POS_REACHED_P ())
  		    {
! 		      if (it->line_wrap == WORD_WRAP)
  			{
  			  if (wrap_it.sp < 0)
  			    goto buffer_pos_reached;
! 			  if (atpos_it.sp < 0)
  			    atpos_it = *it;
  			}
! 		      else
  			goto buffer_pos_reached;
  		    }
- 		  it->current_x = x;
- 		  result = MOVE_X_REACHED;
- 		  break;
  		}
  
  	      if (/* Lines are continued.  */
--- 6824,6858 ----
  	      /* We want to leave anything reaching TO_X to the caller.  */
  	      if ((op & MOVE_TO_X) && new_x > to_x)
  		{
! 		  if (it->line_wrap == WORD_WRAP)
  		    {
! 		      if (BUFFER_POS_REACHED_P ())
  			{
  			  if (wrap_it.sp < 0)
  			    goto buffer_pos_reached;
! 			  else if (atpos_it.sp < 0)
  			    atpos_it = *it;
  			}
! 		      else if (wrap_it.sp < 0)
! 			{
! 			  it->current_x = x;
! 			  result = MOVE_X_REACHED;
! 			  break;
! 			}
! 		      else if (atx_it.sp < 0)
! 			{
! 			  atx_it = *it;
! 			  atx_it.current_x = x;
! 			}
! 		    }
! 		  else
! 		    {
! 		      if (BUFFER_POS_REACHED_P ())
  			goto buffer_pos_reached;
+ 		      it->current_x = x;
+ 		      result = MOVE_X_REACHED;
+ 		      break;
  		    }
  		}
  
  	      if (/* Lines are continued.  */
***************
*** 6840,6852 ****
  		      /* Or it fits exactly and we're on a window
  			 system frame.  */
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f))))
  		{
  		  if (/* IT->hpos == 0 means the very first glyph
  			 doesn't fit on the line, e.g. a wide image.  */
  		      it->hpos == 0
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f)))
  		    {
  		      ++it->hpos;
  		      it->current_x = new_x;
--- 6862,6876 ----
  		      /* Or it fits exactly and we're on a window
  			 system frame.  */
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f)
! 			  && it->line_wrap == WINDOW_WRAP)))
  		{
  		  if (/* IT->hpos == 0 means the very first glyph
  			 doesn't fit on the line, e.g. a wide image.  */
  		      it->hpos == 0
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f)
! 			  && it->line_wrap == WINDOW_WRAP))
  		    {
  		      ++it->hpos;
  		      it->current_x = new_x;
***************
*** 6903,6908 ****
--- 6927,6933 ----
  		    {
  		      *it = wrap_it;
  		      atpos_it.sp = -1;
+ 		      atx_it.sp = -1;
  		    }
  
  		  TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
***************
*** 6995,7003 ****
  #undef BUFFER_POS_REACHED_P
  
    /* If we scanned beyond to_pos and didn't find a point to wrap at,
!      return iterator at to_pos.  */
    if (atpos_it.sp >= 0)
      *it = atpos_it;
  
    /* Restore the iterator settings altered at the beginning of this
       function.  */
--- 7020,7032 ----
  #undef BUFFER_POS_REACHED_P
  
    /* If we scanned beyond to_pos and didn't find a point to wrap at,
!      restore the saved iterator.  */
    if (atpos_it.sp >= 0)
      *it = atpos_it;
+   else if (atx_it.sp >= 0)
+     *it = atx_it;
+ 
+  done:
  
    /* Restore the iterator settings altered at the beginning of this
       function.  */
***************
*** 16622,16628 ****
  				}
  			    }
  #endif /* HAVE_WINDOW_SYSTEM */
! 			  if (wrap_row_used > 0)
  			    goto back_to_wrap;
  			}
  		    }
--- 16651,16667 ----
  				}
  			    }
  #endif /* HAVE_WINDOW_SYSTEM */
! 
! 			  /* If line-wrap is on, consider returning to
! 			     a previously set wrap point, if there is
! 			     one.  Be sure to handle the case where
! 			     the last character on the line is a
! 			     space, as well as the case where the
! 			     following character is also a space.  */
! 			  if (wrap_row_used > 0
! 			      && (!may_wrap
! 				  || (it->what == IT_CHARACTER
! 				      && (it->c == ' ' || it->c == '\t'))))
  			    goto back_to_wrap;
  			}
  		    }




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-03 19:20           ` visual-line-mode Chong Yidong
@ 2008-07-03 23:56             ` David Reitter
  2008-07-04 10:23               ` visual-line-mode Chong Yidong
  0 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-07-03 23:56 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

On 3 Jul 2008, at 20:20, Chong Yidong wrote:

> Could someone please test the following patch to xdisp.c?  It should  
> fix
> some bugs in the word-wrapping code, but there are probably still
> lurking issues.

OK, it seems that (vertical-motion 0) is reliable now with your patch,  
but (vertical-motion 1) will sometimes move point to the beginning of  
the last word in the line (or so), possibly when the visual line is  
fairly long.  It looks as if it anticipates the word to be wrapped,  
even though it isn't.

D


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-03 23:56             ` visual-line-mode David Reitter
@ 2008-07-04 10:23               ` Chong Yidong
  2008-07-04 10:58                 ` visual-line-mode Miles Bader
  2008-07-04 11:09                 ` visual-line-mode David Reitter
  0 siblings, 2 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-04 10:23 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

> OK, it seems that (vertical-motion 0) is reliable now with your patch,
> but (vertical-motion 1) will sometimes move point to the beginning of
> the last word in the line (or so), possibly when the visual line is
> fairly long.  It looks as if it anticipates the word to be wrapped,
> even though it isn't.

Please provide a detailed recipe.  (If the recipe refers to
`posn-point', that would be even better.)




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 10:23               ` visual-line-mode Chong Yidong
@ 2008-07-04 10:58                 ` Miles Bader
  2008-07-04 13:04                   ` visual-line-mode Chong Yidong
  2008-07-04 11:09                 ` visual-line-mode David Reitter
  1 sibling, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-07-04 10:58 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 1421 bytes --]

Chong Yidong <cyd@stupidchicken.com> writes:
>> OK, it seems that (vertical-motion 0) is reliable now with your patch,
>> but (vertical-motion 1) will sometimes move point to the beginning of
>> the last word in the line (or so), possibly when the visual line is
>> fairly long.  It looks as if it anticipates the word to be wrapped,
>> even though it isn't.
>
> Please provide a detailed recipe.  (If the recipe refers to
> `posn-point', that would be even better.)

1) Put the following (also attached) text (it should be one logical line)
   into a file:

15:11 *** NAMES snogglethorpe munichlinux Bzek jmaslibre twb xinming fukas melmothX xaiki vinc456 stanis_sh bonii LaoLang_cool akm1 meandtheshell edrx 

2) visit the file with emacs -Q (assuming your patch has been applied),
   and do M-: (setq word-wrap t) to turn on word-wrapping.

3) Now locate the cursor on the first SPC character.  Do M-: (posn-at-point).

   Note that the position is (5 . 0) in characters, and (5*W . 0) in pixels,
   where W is the basic character width (W = 10 for the usual default font).

4) Use `C-f' to move forward one character.  Do M-: (posn-at-point).

   Note that the position is now (7 . 0) in characters, and (7*W . 0) in
   pixels!  This is entirely unexpected, and does not happen if word-wrap is
   nil.

[Because of this funniness, movement with Stefan's line-move-visual patch
also acts weird on this text.]

-Miles


[-- Attachment #2: Long line which acts funny with word-wrap --]
[-- Type: application/octet-stream, Size: 152 bytes --]

15:11 *** NAMES snogglethorpe munichlinux Bzek jmaslibre twb xinming fukas melmothX xaiki vinc456 stanis_sh bonii LaoLang_cool akm1 meandtheshell edrx 

[-- Attachment #3: Type: text/plain, Size: 82 bytes --]



-- 
Zeal, n. A certain nervous disorder afflicting the young and inexperienced.

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 10:23               ` visual-line-mode Chong Yidong
  2008-07-04 10:58                 ` visual-line-mode Miles Bader
@ 2008-07-04 11:09                 ` David Reitter
  2008-07-04 12:39                   ` visual-line-mode Paul R
  1 sibling, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-07-04 11:09 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader


[-- Attachment #1.1: Type: text/plain, Size: 1642 bytes --]

On 4 Jul 2008, at 11:23, Chong Yidong wrote:

> David Reitter <david.reitter@gmail.com> writes:
>
>> OK, it seems that (vertical-motion 0) is reliable now with your  
>> patch,
>> but (vertical-motion 1) will sometimes move point to the beginning of
>> the last word in the line (or so), possibly when the visual line is
>> fairly long.  It looks as if it anticipates the word to be wrapped,
>> even though it isn't.
>
> Please provide a detailed recipe.  (If the recipe refers to
> `posn-point', that would be even better.)

It seems to require a variable-width font and a wrapped line that  
reached to the right border.

This is reproducible for me:

Emacs -Q,
(setq word-wrap t)
select variable-width font (I chose Arial 12pt on my OS X machine)
then paste the following text into the *scratch* buffer:

French-Colombian politician Ingrid Betancourt left Bogota bound for  
France and a meeting with President Nicolas Sarkozy one day after her  
jungle rescue from six years in rebel captivity.

NB, this is one sentence that should be without linebreaks.
Resize the frame so that you get line breaks after "France" and  
"jungle". "France" should reach all the way to the right edge of the  
window, as shown in the screenshot.
Place point on the first letter of "Bogota".

M-: (vertical-motion 1) RET

This jumps to the word "France" (the first letter), rather than to  
"and".

Put point back to "Bogota", widen the frame by one character, try  
again.  This time it works: we jump to "and".


I hope that's reproducible in Emacs 23 as well.
I can't find anything wrong with posn-point, but maybe I'm not trying  
the right things.




[-- Attachment #1.2: pastedGraphic.png --]
[-- Type: image/png, Size: 95266 bytes --]

[-- Attachment #1.3: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 11:09                 ` visual-line-mode David Reitter
@ 2008-07-04 12:39                   ` Paul R
  0 siblings, 0 replies; 73+ messages in thread
From: Paul R @ 2008-07-04 12:39 UTC (permalink / raw)
  To: David Reitter
  Cc: Chong Yidong, Miles Bader, Lennart Borgman (gmail),
	Stefan Monnier, Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:

> [snip] meeting with President Nicolas Sarkozy one day after [snip]
                                ^^^^^^^^^^^^^^^

Oh my god ! I thought emacs-devel was the ONLY place where I could
read some news without seeing his name, but no! Even this list seems
to be owned now ... :)

-- 
      Paul, from france




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 10:58                 ` visual-line-mode Miles Bader
@ 2008-07-04 13:04                   ` Chong Yidong
  2008-07-04 15:04                     ` visual-line-mode David Reitter
  0 siblings, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-04 13:04 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Okay, how about this amended patch?

*** trunk/src/xdisp.c.~1.1227.~	2008-07-04 06:35:40.000000000 -0400
--- trunk/src/xdisp.c	2008-07-04 09:02:58.000000000 -0400
***************
*** 6664,6670 ****
  {
    enum move_it_result result = MOVE_UNDEFINED;
    struct glyph_row *saved_glyph_row;
!   struct it wrap_it, atpos_it;
    int may_wrap = 0;
  
    /* Don't produce glyphs in produce_glyphs.  */
--- 6664,6670 ----
  {
    enum move_it_result result = MOVE_UNDEFINED;
    struct glyph_row *saved_glyph_row;
!   struct it wrap_it, atpos_it, atx_it;
    int may_wrap = 0;
  
    /* Don't produce glyphs in produce_glyphs.  */
***************
*** 6672,6682 ****
    it->glyph_row = NULL;
  
    /* Use wrap_it to save a copy of IT wherever a word wrap could
!      occur.  Use atpos_it to save a copy of IT at the desired
       position, if found, so that we can scan ahead and check if the
!      word later overshoots the window edge.  */
    wrap_it.sp = -1;
    atpos_it.sp = -1;
  
  #define BUFFER_POS_REACHED_P()					\
    ((op & MOVE_TO_POS) != 0					\
--- 6672,6684 ----
    it->glyph_row = NULL;
  
    /* Use wrap_it to save a copy of IT wherever a word wrap could
!      occur.  Use atpos_it to save a copy of IT at the desired buffer
       position, if found, so that we can scan ahead and check if the
!      word later overshoots the window edge.  Use atx_it similarly, for
!      pixel positions.  */
    wrap_it.sp = -1;
    atpos_it.sp = -1;
+   atx_it.sp = -1;
  
  #define BUFFER_POS_REACHED_P()					\
    ((op & MOVE_TO_POS) != 0					\
***************
*** 6705,6718 ****
  	{
  	  if (it->line_wrap == WORD_WRAP)
  	    {
- 	      /* If wrap_it is valid, the current position might be in
- 		 a word that is wrapped to the next line, so continue
- 		 to see if that happens.  */
  	      if (wrap_it.sp < 0)
  		{
  		  result = MOVE_POS_MATCH_OR_ZV;
  		  break;
  		}
  	      if (atpos_it.sp < 0)
  		atpos_it = *it;
  	    }
--- 6707,6720 ----
  	{
  	  if (it->line_wrap == WORD_WRAP)
  	    {
  	      if (wrap_it.sp < 0)
  		{
  		  result = MOVE_POS_MATCH_OR_ZV;
  		  break;
  		}
+ 	      /* If wrap_it is valid, the current position might be in
+ 		 a word that is wrapped to the next line, so continue
+ 		 to see if that happens.  */
  	      if (atpos_it.sp < 0)
  		atpos_it = *it;
  	    }
***************
*** 6759,6766 ****
  		  if (atpos_it.sp >= 0)
  		    {
  		      *it = atpos_it;
! 		      atpos_it.sp = -1;
! 		      goto buffer_pos_reached;
  		    }
  		  wrap_it = *it;
  		  may_wrap = 0;
--- 6761,6774 ----
  		  if (atpos_it.sp >= 0)
  		    {
  		      *it = atpos_it;
! 		      result = MOVE_POS_MATCH_OR_ZV;
! 		      goto done;
! 		    }
! 		  if (atx_it.sp >= 0)
! 		    {
! 		      *it = atx_it;
! 		      result = MOVE_X_REACHED;
! 		      goto done;
  		    }
  		  wrap_it = *it;
  		  may_wrap = 0;
***************
*** 6816,6836 ****
  	      /* We want to leave anything reaching TO_X to the caller.  */
  	      if ((op & MOVE_TO_X) && new_x > to_x)
  		{
! 		  if (BUFFER_POS_REACHED_P ())
  		    {
! 		      if (it->line_wrap == WORD_WRAP)
  			{
  			  if (wrap_it.sp < 0)
  			    goto buffer_pos_reached;
! 			  if (atpos_it.sp < 0)
! 			    atpos_it = *it;
  			}
! 		      else
  			goto buffer_pos_reached;
  		    }
- 		  it->current_x = x;
- 		  result = MOVE_X_REACHED;
- 		  break;
  		}
  
  	      if (/* Lines are continued.  */
--- 6824,6861 ----
  	      /* We want to leave anything reaching TO_X to the caller.  */
  	      if ((op & MOVE_TO_X) && new_x > to_x)
  		{
! 		  if (it->line_wrap == WORD_WRAP)
  		    {
! 		      if (BUFFER_POS_REACHED_P ())
  			{
  			  if (wrap_it.sp < 0)
  			    goto buffer_pos_reached;
! 			  else if (atpos_it.sp < 0)
! 			    {
! 			      atpos_it = *it;
! 			      atpos_it.current_x = x;
! 			    }
  			}
! 		      else if (wrap_it.sp < 0)
! 			{
! 			  it->current_x = x;
! 			  result = MOVE_X_REACHED;
! 			  break;
! 			}
! 		      else if (atx_it.sp < 0)
! 			{
! 			  atx_it = *it;
! 			  atx_it.current_x = x;
! 			}
! 		    }
! 		  else
! 		    {
! 		      if (BUFFER_POS_REACHED_P ())
  			goto buffer_pos_reached;
+ 		      it->current_x = x;
+ 		      result = MOVE_X_REACHED;
+ 		      break;
  		    }
  		}
  
  	      if (/* Lines are continued.  */
***************
*** 6840,6852 ****
  		      /* Or it fits exactly and we're on a window
  			 system frame.  */
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f))))
  		{
  		  if (/* IT->hpos == 0 means the very first glyph
  			 doesn't fit on the line, e.g. a wide image.  */
  		      it->hpos == 0
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f)))
  		    {
  		      ++it->hpos;
  		      it->current_x = new_x;
--- 6865,6879 ----
  		      /* Or it fits exactly and we're on a window
  			 system frame.  */
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f)
! 			  && it->line_wrap == WINDOW_WRAP)))
  		{
  		  if (/* IT->hpos == 0 means the very first glyph
  			 doesn't fit on the line, e.g. a wide image.  */
  		      it->hpos == 0
  		      || (new_x == it->last_visible_x
! 			  && FRAME_WINDOW_P (it->f)
! 			  && it->line_wrap == WINDOW_WRAP))
  		    {
  		      ++it->hpos;
  		      it->current_x = new_x;
***************
*** 6903,6908 ****
--- 6930,6936 ----
  		    {
  		      *it = wrap_it;
  		      atpos_it.sp = -1;
+ 		      atx_it.sp = -1;
  		    }
  
  		  TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
***************
*** 6918,6924 ****
  		      if (wrap_it.sp < 0)
  			goto buffer_pos_reached;
  		      if (atpos_it.sp < 0)
! 			atpos_it = *it;
  		    }
  		  else
  		    goto buffer_pos_reached;
--- 6946,6955 ----
  		      if (wrap_it.sp < 0)
  			goto buffer_pos_reached;
  		      if (atpos_it.sp < 0)
! 			{
! 			  atpos_it = *it;
! 			  atpos_it.current_x = x;
! 			}
  		    }
  		  else
  		    goto buffer_pos_reached;
***************
*** 6995,7003 ****
  #undef BUFFER_POS_REACHED_P
  
    /* If we scanned beyond to_pos and didn't find a point to wrap at,
!      return iterator at to_pos.  */
    if (atpos_it.sp >= 0)
      *it = atpos_it;
  
    /* Restore the iterator settings altered at the beginning of this
       function.  */
--- 7026,7038 ----
  #undef BUFFER_POS_REACHED_P
  
    /* If we scanned beyond to_pos and didn't find a point to wrap at,
!      restore the saved iterator.  */
    if (atpos_it.sp >= 0)
      *it = atpos_it;
+   else if (atx_it.sp >= 0)
+     *it = atx_it;
+ 
+  done:
  
    /* Restore the iterator settings altered at the beginning of this
       function.  */
***************
*** 16622,16628 ****
  				}
  			    }
  #endif /* HAVE_WINDOW_SYSTEM */
! 			  if (wrap_row_used > 0)
  			    goto back_to_wrap;
  			}
  		    }
--- 16657,16673 ----
  				}
  			    }
  #endif /* HAVE_WINDOW_SYSTEM */
! 
! 			  /* If line-wrap is on, consider returning to
! 			     a previously set wrap point, if there is
! 			     one.  Be sure to handle the case where
! 			     the last character on the line is a
! 			     space, as well as the case where the
! 			     following character is also a space.  */
! 			  if (wrap_row_used > 0
! 			      && (!may_wrap
! 				  || (it->what == IT_CHARACTER
! 				      && (it->c == ' ' || it->c == '\t'))))
  			    goto back_to_wrap;
  			}
  		    }




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 13:04                   ` visual-line-mode Chong Yidong
@ 2008-07-04 15:04                     ` David Reitter
  2008-07-04 15:49                       ` visual-line-mode Stefan Monnier
  2008-07-05 18:41                       ` visual-line-mode Chong Yidong
  0 siblings, 2 replies; 73+ messages in thread
From: David Reitter @ 2008-07-04 15:04 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 586 bytes --]

On 4 Jul 2008, at 14:04, Chong Yidong wrote:

> Okay, how about this amended patch?

OK, this works fine now.

The visual-line minor mode is attached again for people to try out  
once you've committed your patch.
Visual-line-mode works fine for me with your patches (on 22).

Note that this minor mode works correctly works with variable width  
fonts.  If we had a way to determine the buffer position for given  
pixel coordinates (something like posn-point, without requiring the  
event structure that contains the information), then I could improve  
this package further.

- D



[-- Attachment #2: visual-line.el --]
[-- Type: application/octet-stream, Size: 19975 bytes --]

;;; visual-line.el
;; Copyright (C) 2008 Free Software Foundation

;; Maintainer: David Reitter <david.reitter@gmail.com>
;; Authors: David Reitter 
;; Keywords: mail

;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Overview:
;;
;; `visual-line-mode' and `global-visual-line-mode' enable
;; navigation by visual lines.  Vertical movement commands such as
;; `next-line' and `previous-line' (normally bound to up/down arrow
;; keys) will move the point to the next line as shown on the
;; screen, even if that is the same line in the underlying buffer.
;; The point is moved to a position that is located (on the screen)
;; horizontally close (pixel-wise), rather than to an equivalent
;; by-character column.
;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Notable changes:
;;
;; Initial version:
;; This file was adapted from Aquamacs Emacs.
;; Lennart Borgmann contributed the code that creates a minor mode
;; for this.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Code Comments:
 
;; Note that `visual-line-up' and friends use two different methods to
;; figure out the best position to move to because of a slowness with
;; outline-(minor-)mode. One of the methods (basically binary search) is
;; much faster when a lot of hidden text is present, but a bit slower in
;; all other cases.


(defun visual-col-at-point ()
  "Returns the visual column at point.
The visual column is relative to the left window edge, not
to the beginning of the (unwrapped) line."
  (- (point)
     (save-excursion
       (vertical-motion 0)
       (point))))
;; seems slower (in situations with very long lines)
;;(or (car (nth 6 (posn-at-point))) 0))

(defun visual-pixel-col-at-point ()
  "Returns the pixel column at point.
This is the distance from the left edge of the window 
to the character at point."
  (or (car-safe 
       (pos-visible-in-window-p (point) nil 'partial))
      0))

(defvar visual-movement-temporary-goal-column nil)
(make-variable-buffer-local 'visual-movement-temporary-goal-column)

(defvar visual-previous-scroll-margin 'none)
(defun visual-restore-scroll-margin ()
  "Restore the scroll margin."
  (if (integerp visual-previous-scroll-margin)
      (setq scroll-margin visual-previous-scroll-margin))
  (remove-hook 'pre-command-hook 'visual-restore-scroll-margin))

(defcustom visual-scroll-margin nil
 "Number of lines of margin at top and bottom of a window.
For visual scrolling with up and down keys, this value
applies instead of `scroll-margin' if it is non-nil.

The reason this variable exists is that clicks in the first and last
line of a window will set the cursor within the standard scroll-margin,
causing the buffer to scroll immediately. This is usually undesired.
In this case, set `scroll-margin' to zero and `visual-scroll-margin'
to the desired margin."
 :group 'Windows)

(defun visual-line-up (num-lines)
 "Move cursor vertically up NUM-LINES lines.
Interactively, vscroll tall lines if `auto-window-vscroll' is
enabled.  If there is no character in the target line exactly
over the current horizontal pixel position, the cursor is
positioned close to the character in that line at the same position,
or at the end of the line if it is not long enough.

The command C-x C-n can be used to create
a semipermanent goal column for this command.
Then instead of trying to move exactly vertically (or as close as
possible),
this command moves to the specified goal column (or as close as
possible).
The goal column is stored in the variable `goal-column', which is nil
when there is no goal column.

This function differs from `previous-line' as it moves vertically
in the visual sense. The result differs when variable-width font is
used or when characters of non-standard width (e.g. TABs) are used.

If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead.  It is usually easier
to use and more reliable (no dependence on goal column, etc.)."
 (interactive "p")
 (if (bobp) (signal 'beginning-of-buffer nil))
 (let ((pixel-col (visual-pixel-col-at-point))
	(visual-col (visual-col-at-point))
	(old-point (point))
	(end-of-old-line))

   ;; temporary binding of scroll-margin
   ;; cannot do this with a temporary let binding
   (setq visual-previous-scroll-margin scroll-margin)
   (if visual-scroll-margin
	(setq scroll-margin visual-scroll-margin))
   (add-hook 'pre-command-hook 'visual-restore-scroll-margin)

   (save-excursion
     (vertical-motion 1)	;; trying going one down, to left
     (setq end-of-old-line (point)))

   (vertical-motion 0)

   (let* ((beg-of-old-line
           ;; move right, but not further than to end of line
	    (prog1 (point)
	      (vertical-motion (- num-lines))))	    ;; one up again
	   (beg-of-new-line (point))
	   (rel-beg-of-old-line  (- beg-of-old-line (point) 1)))

     ;; handle track-eol...
     (if (and track-eol (= old-point (1- end-of-old-line))
	       ;; Don't count beg of empty line as end of line
	       ;; unless we just did explicit end-of-line.
	       (or (not (= old-point beg-of-old-line))
		   (eq last-command 'end-of-line)))
	  (setq visual-movement-temporary-goal-column 9999))

     ;; approximate positioning
     (if (and (or goal-column visual-movement-temporary-goal-column)
	       (memq last-command '(visual-line-up
				    visual-line-down
				    visual-line-up-in-buffers
				    visual-line-down-in-buffers))
	       (= old-point (1- end-of-old-line)))
	  ;; jumping from end of line

         (forward-char (min (or goal-column
                                visual-movement-temporary-goal-column)
                            rel-beg-of-old-line))
	;; else, do complete positioning
	;; save original position
	(setq visual-movement-temporary-goal-column visual-col)
                                       ;	(forward-char (min visual-col rel-beg-of-old-line))

	;; this won't work because we don't have the
	;; absolute position, just the position within window
	;; (let ((p (pos-visible-in-window-p old-point nil 'p))
       ;; 	      (p2 (pos-visible-in-window-p beg-of-new-line nil 'p) ))
       ;; 	  (print (cons (car p) (cdr p2)))
       ;; 	  (posn-set-point (cons (car p) (cdr p2)))
       ;; 	  )
	(if (> (abs (- (point) beg-of-old-line)) 400)
	    ;; find-position-at-pixel-col is much faster when
	    ;; large portions of hidden text are to be crossed.
	    ;; this can happen in outline-(minor-)mode for instance.
	    (goto-char (find-position-at-pixel-col  pixel-col))
	  ;; approximate positioning
	  (forward-char (min visual-col rel-beg-of-old-line))
	  (if (>= (visual-pixel-col-at-point) pixel-col)
	      (progn
		(while (and
			(> (visual-pixel-col-at-point) pixel-col)
			(> (point) beg-of-new-line)) ;; do not cross line
		  (forward-char -1)))
	    (progn
	      (while (and
		      (< (visual-pixel-col-at-point) pixel-col)
		      (< (point) (1- beg-of-old-line))) ;; do not cross line
		(forward-char +1)))))

	))))

(defun visual-line-down (num-lines)
  "Move cursor vertically down NUM-LINES lines.
Interactively, vscroll tall lines if `auto-window-vscroll' is
enabled.  If there is no character in the target line exactly
under the current column, the cursor is positioned after the
character in that line which spans this column, or at the end of
the line if it is not long enough.  If there is no line in the
buffer after this one, behavior depends on the value of
`next-line-add-newlines'.  If non-nil, it inserts a newline
character to create a line, and moves the cursor to that line.
Otherwise it moves the cursor to the end of the buffer.

The command C-x C-n can be used to create a semipermanent goal
column for this command.  Then instead of trying to move exactly
vertically (or as close as possible), this command moves to the
specified goal column (or as close as possible).  The goal column
is stored in the variable `goal-column', which is nil when there
is no goal column.

This function differs from `next-line' as it moves vertically in
the visual sense. The result differs when variable-width font is
used or when characters of non-standard width (e.g. TABs) are
used.

If you are thinking of using this in a Lisp program, consider
using `forward-line' instead.  It is usually easier to use and
more reliable (no dependence on goal column, etc.)."
  (interactive "p")
  (if (and next-line-add-newlines (= num-lines 1))
      (if (save-excursion (end-of-line) (eobp))
	  ;; When adding a newline, don't expand an abbrev.
	  (let ((abbrev-mode nil))
	    (end-of-line)
	    (insert hard-newline)))
    (if (eobp) (signal 'end-of-buffer nil)))
  (let ((pixel-col (visual-pixel-col-at-point))
	(visual-col (visual-col-at-point))
	(old-point (point))
	(beg-of-line)
	(next-line-start)
	(rel-next-line-start))

    ;; temporary binding of scroll-margin
    ;; cannot do this with a temporary let binding
    (setq visual-previous-scroll-margin scroll-margin)
    (if visual-scroll-margin
	(setq scroll-margin visual-scroll-margin))
    (add-hook 'pre-command-hook 'visual-restore-scroll-margin)

    (vertical-motion num-lines) ;; down
    (save-excursion
      (setq beg-of-line (point))
      (vertical-motion +1) ;; down
      (setq next-line-start (point))
      (setq rel-next-line-start  (- (point) beg-of-line 1)))
    (unless (= beg-of-line (point-max))
      ;; handle track-eol...
      (if (and track-eol (= old-point (1- next-line-start))
	       ;; Don't count beg of empty line as end of line
	       ;; unless we just did explicit end-of-line.
	       (or (not (= 0 visual-col))
		   (eq last-command 'end-of-line)))
	  (setq visual-movement-temporary-goal-column 9999))
      ;; approximate positioning
      (if (and (or goal-column visual-movement-temporary-goal-column)
	       (memq last-command '(visual-line-up
				    visual-line-down
				    visual-line-up-in-buffers
				    visual-line-down-in-buffers))
	       (= old-point (- beg-of-line 1))) ;; jumping from end of line

	  (forward-char (min (or goal-column
				 visual-movement-temporary-goal-column)
			     rel-next-line-start))
	;; else, do complete positioning
	;; save original position
	(setq visual-movement-temporary-goal-column visual-col)
	;; find-position-at-pixel-col is much faster when
	;; large portions of hidden text are to be crossed.
	;; this can happen in outline-(minor-)mode for instance.
	(if (> (abs (- old-point next-line-start)) 400)
	    (goto-char (find-position-at-pixel-col  pixel-col))
	  (forward-char (min visual-col rel-next-line-start))
	  (if (> (visual-pixel-col-at-point) pixel-col)
	      (progn
		(while (and
			(> (visual-pixel-col-at-point) pixel-col)
			(> (point) beg-of-line)) ;; do not cross line
		  (forward-char -1)))
	    (progn
	      (while (and
		      (< (visual-pixel-col-at-point) pixel-col)
		      (< (point) (1- next-line-start))) ;; do not cross line
		(forward-char +1)))))))))

(defun find-position-at-pixel-col  (pixel-col)
  (let ((beg-of-line) (end-of-line))
    (vertical-motion 1)	;; trying going one down, to left
    (setq end-of-line (point))
    (if (eq (point) (point-max)) (vertical-motion 0) 
      (vertical-motion -1))
    (setq beg-of-line (point))
    (let ((op (point)))
      ;; move to beg of line
      (vertical-motion 0) ;; trying going one down, to left
      (forward-char (/ pixel-col (frame-char-width)))
      (find-position-at-pixel-col-recursive
       beg-of-line end-of-line pixel-col)
      (let* ((nearest-pos (point))
	     (smallest-distance
	      (abs (- pixel-col (visual-pixel-col-at-point)))))
	(let ((pdif (abs (- pixel-col
			    (progn (forward-char -1)
				   (visual-pixel-col-at-point))))))
	  (when (< pdif smallest-distance)
	    (setq nearest-pos (point))
	    (setq smallest-distance pdif)))
	(let ((pdif (abs (- pixel-col
			    (progn (forward-char 2)
				   (visual-pixel-col-at-point))))))
	  (when (< pdif smallest-distance)
	    (setq nearest-pos (point))
	    (setq smallest-distance pdif)))
	(goto-char nearest-pos))
      (point))))

(defun find-position-at-pixel-col-recursive
  (beg-of-line end-of-line pixel-col)
  ;; set it in the middle
  (if (eq beg-of-line end-of-line)
      (point)
    (let ((middle (+ beg-of-line 
		     (round (/ (- end-of-line beg-of-line) 2)))))
      (if (or (eq middle (point)) ;; wouldn't change point any more
	      (eq (visual-pixel-col-at-point) pixel-col))
	  (point)
	(goto-char middle)
	(if (> (visual-pixel-col-at-point) pixel-col)
	    (find-position-at-pixel-col-recursive
	     beg-of-line (point) pixel-col)
	  (find-position-at-pixel-col-recursive
	   (point) end-of-line pixel-col))))))


(defun beginning-of-visual-line ()
  "Move point to the beginning of the current visual line."
  (interactive)
  (if (bobp)
      (signal 'beginning-of-buffer nil))
  (vertical-motion 0))

(defun end-of-visual-line ()
  "Move point to the end of the current visual line."
  (interactive)
  (if (eobp)
      (signal 'end-of-buffer nil))
  (let ((end-of-line (line-end-position)))
    (vertical-motion 1)
    (unless (eobp)
      ;;or: (< (point) end-of-line) ;; jumping over wrapped text
      (backward-char 1))))

;; this code based on simple.el
(defun kill-visual-line (&optional arg)
  "Kill the rest of the visual line; if no nonblanks there, kill thru
newline.
With prefix argument, kill that many lines from point.
Negative arguments kill lines backward.
With zero argument, kills the text before point on hthe current line.

When calling from a program, nil means \"no arg\",
a number counts as a prefix arg.

To kill a whole line, when point is not at the beginning, type \
\\[beginning-of-line] \\[kill-line] \\[kill-line].

If `kill-whole-line' is non-nil, then this command kills the whole line
including its terminating newline, when used at the beginning of a line
with no argument.  As a consequence, you can always kill a whole line
by typing \\[beginning-of-line] \\[kill-line].

If you want to append the killed line to the last killed text,
use \\[append-next-kill] before \\[kill-line].

If the buffer is read-only, Emacs will beep and refrain from deleting
the line, but put the line in the kill ring anyway.  This means that
you can use this command to copy text from a read-only buffer.
\(If the variable `kill-read-only-ok' is non-nil, then this won't
even beep.)"
  (interactive "P")
  (kill-region (point)
	       ;; It is better to move point to the other end of the
	       ;; kill before killing.  That way, in a read-only
	       ;; buffer, point moves across the text that is copied
	       ;; to the kill ring.  The choice has no effect on undo
	       ;; now that undo records the value of point from before
	       ;; the command was run.
	       (progn
		 (if arg
		     (vertical-motion (prefix-numeric-value arg))
		   (if (eobp)
		       (signal 'end-of-buffer nil))
		   (let ((end
			  (save-excursion
			    (end-of-visual-line) (point))))
		     (if (or (save-excursion
			       ;; If trailing whitespace is visible,
			       ;; don't treat it as nothing.
			       (unless show-trailing-whitespace
				 (skip-chars-forward " \t" end))
			       (= (point) end))
			     (and kill-whole-line (bolp)))
			 (visual-line-down 1)
		       (goto-char end))))
		 (point))))

(defun kill-whole-visual-line (&optional arg)
  "Kill current visual line.
With prefix arg, kill that many lines starting from the current line.
If arg is negative, kill backward.  Also kill the preceding newline.
\(This is meant to make \\[repeat] work well with negative arguments.\)
If arg is zero, kill current line but exclude the trailing newline."
  (interactive "p")
  (if (and (> arg 0) (eobp) (save-excursion (vertical-motion 0) (eobp)))
      (signal 'end-of-buffer nil))
  (if (and (< arg 0) (bobp) (save-excursion (vertical-motion 1) (bobp)))
      (signal 'beginning-of-buffer nil))
  (unless (eq last-command 'kill-region)
    (kill-new "")
    (setq last-command 'kill-region))
  (cond ((zerop arg)
	 ;; We need to kill in two steps, because the previous command
	 ;; could have been a kill command, in which case the text
	 ;; before point needs to be prepended to the current kill
	 ;; ring entry and the text after point appended.  Also, we
	 ;; need to use save-excursion to avoid copying the same text
	 ;; twice to the kill ring in read-only buffers.
	 (save-excursion
	   ;; delete in one go
	   (kill-region (progn (vertical-motion 0) (point))
			(progn (vertical-motion 1) (point)))
	   ))
	((< arg 0)
	 (save-excursion
	   (kill-region (point) (progn (end-of-visual-line) (point))))
	 (kill-region (point)
		      (progn (vertical-motion (1+ arg))
			     (unless (bobp) (backward-char))
			     (point))))
	(t
	 (save-excursion
	   (kill-region (progn (vertical-motion 0) (point))
			(progn (vertical-motion arg) (point)))))))

(defun visual-line-up-in-buffers ()
 "Moves the cursor up one (visual) line.
If the `up' key would normally be bound to something else than
`previous-line' (as it is the case in minibuffers), the other binding
is called."
 (interactive)
 (let* (visual-line-mode  ;; turn off mode temporarily
	 (binding (key-binding [up])))
   (if (eq binding 'previous-line)
	(call-interactively (function visual-line-up))
     (call-interactively binding))))

(defun visual-line-down-in-buffers ()
 "Moves the cursor down one (visual) line.
If the `down' key would normally be bound to something else than
`next-line' (as it is the case in minibuffers), the other binding
is called."
 (interactive)
 (let* (visual-line-mode  ;; turn off mode temporarily
	 (binding (key-binding [down])))
   (if (eq binding 'next-line)
	(call-interactively (function visual-line-down))
     (call-interactively binding))))

;; mark functions for CUA
(dolist (cmd
	 '( beginning-of-visual-line
	    end-of-visual-line
	    visual-line-down visual-line-up
	    visual-line-up-in-buffers
	    visual-line-down-in-buffers))
 (put cmd 'CUA 'move))

(defalias 'original-kill-line 'kill-line)
(defalias 'original-next-line 'next-line)
(defalias 'original-previous-line 'previous-line)

(defun line-wrapped-p ()
  "Return non-nil if the current line is wrapped."
  (let ((here (point))
        result)
    (vertical-motion 0)
    (setq result (/= (line-beginning-position) (point)))
    (unless result
      (let ((line-end-pos (line-end-position)))
        (vertical-motion 1)
        (setq result (/= line-end-pos (- (point) 1)))))
    (goto-char here)
    result))

(defvar visual-line-map
 (let ((map (make-sparse-keymap)))
   (define-key map [remap next-line] 'visual-line-down)
   (define-key map [remap previous-line] 'visual-line-up)
   (define-key map [remap kill-line] 'kill-visual-line)
   (define-key map [(control shift ?k)] 'original-kill-line)
   (define-key map [remap move-beginning-of-line] 'beginning-of-visual-line)
   (define-key map [remap move-end-of-line]  'end-of-visual-line)
   map))

(define-minor-mode visual-line-mode
 "Define key binding for visual line moves."
 :keymap visual-line-map
 :group 'convenience)

(defun turn-on-visual-line-mode ()
 (visual-line-mode 1))

(define-globalized-minor-mode global-visual-line-mode
 visual-line-mode turn-on-visual-line-mode
 :lighter " vl")



(provide 'visual-line)

[-- Attachment #3: Type: text/plain, Size: 1 bytes --]



^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 15:04                     ` visual-line-mode David Reitter
@ 2008-07-04 15:49                       ` Stefan Monnier
  2008-07-04 16:21                         ` visual-line-mode David Reitter
  2008-07-05 18:41                       ` visual-line-mode Chong Yidong
  1 sibling, 1 reply; 73+ messages in thread
From: Stefan Monnier @ 2008-07-04 15:49 UTC (permalink / raw)
  To: David Reitter
  Cc: Chong Yidong, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

> If we had a way to determine the buffer position for given pixel
> coordinates (something like posn-point, without requiring the event
> structure that contains the information),

Does posn-at-x-y provide the info you need?


        Stefan





^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 15:49                       ` visual-line-mode Stefan Monnier
@ 2008-07-04 16:21                         ` David Reitter
  0 siblings, 0 replies; 73+ messages in thread
From: David Reitter @ 2008-07-04 16:21 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Chong Yidong, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

On 4 Jul 2008, at 16:49, Stefan Monnier wrote:

>> If we had a way to determine the buffer position for given pixel
>> coordinates (something like posn-point, without requiring the event
>> structure that contains the information),
>
> Does posn-at-x-y provide the info you need?

That's a pretty good suggestion, thanks.
This should make it possible to write a non-iterative algorithm, as  
below.

I'll see if I can make it work for the scrolling case and insert goal  
columns etc.

- D


(defun go-up (point)
   (interactive "p")
   (let ((x (car (posn-x-y (posn-at-point)))))
     (vertical-motion -1)
     (let ((y (cdr (posn-x-y (posn-at-point)))))
       (posn-set-point (posn-at-x-y x y)))))




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-04 15:04                     ` visual-line-mode David Reitter
  2008-07-04 15:49                       ` visual-line-mode Stefan Monnier
@ 2008-07-05 18:41                       ` Chong Yidong
  2008-07-06  1:29                         ` visual-line-mode Miles Bader
                                           ` (2 more replies)
  1 sibling, 3 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-05 18:41 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

> OK, this works fine now.

Good, I've checked it in (together with a couple other minor fixes).

> The visual-line minor mode is attached again for people to try out
> once you've committed your patch.  Visual-line-mode works fine for me
> with your patches (on 22).
>
> Note that this minor mode works correctly works with variable width
> fonts.  If we had a way to determine the buffer position for given
> pixel coordinates (something like posn-point, without requiring the
> event structure that contains the information), then I could improve
> this package further.

One thing that's not clear to me is whether your minor mode correctly
handles invisible/intangible text and point motion hooks.  One of the
reasons line-move-1 and line-move-finish is so complicated is,
unfortunately, the need to DTRT for these.  I don't see anything
analogous in your code; am I missing something?




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-05 18:41                       ` visual-line-mode Chong Yidong
@ 2008-07-06  1:29                         ` Miles Bader
  2008-07-09 14:28                         ` visual-line-mode David Reitter
  2008-07-09 14:31                         ` visual-line-mode David Reitter
  2 siblings, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-06  1:29 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Chong Yidong <cyd@stupidchicken.com> writes:
>> OK, this works fine now.
>
> Good, I've checked it in (together with a couple other minor fixes).

The new patch seems much, much better, but I did notice a few weird
behaviors with Stefan's line-move-visual patch -- while moving with
C-n/C-p in long wrapped line usually goes in a straight vertical line,
every once in a while it would jump horizontally for no obvious reason
(using a fixed-width font).

I'll try to make a more concise recipe later.

-Miles

-- 
.Numeric stability is probably not all that important when you're guessing.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-05 18:41                       ` visual-line-mode Chong Yidong
  2008-07-06  1:29                         ` visual-line-mode Miles Bader
@ 2008-07-09 14:28                         ` David Reitter
  2008-07-10  3:05                           ` visual-line-mode Chong Yidong
  2008-07-09 14:31                         ` visual-line-mode David Reitter
  2 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-07-09 14:28 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 1600 bytes --]

On 5 Jul 2008, at 19:41, Chong Yidong wrote:
>
> Good, I've checked it in (together with a couple other minor fixes).

Can you post a patch for these minor fixes?
I'm running this on 22 (because the trunk does not run on my system).

At least in the previous version, there's also a problem with posn-x- 
y, which returns a position too far when given coordinates that are to  
the right of a word-wrapped line (i.e. in the blank space).  This can  
also be seen if you just click into that space (mouse-set-point).

I can post a detailed recipe after I've made sure I've got the up-to- 
date patch.  My new code isn't iterative.  It's faster and shouldn't  
lead to excessive garbage collections as before.

> One thing that's not clear to me is whether your minor mode correctly
> handles invisible/intangible text and point motion hooks.  One of the
> reasons line-move-1 and line-move-finish is so complicated is,
> unfortunately, the need to DTRT for these.  I don't see anything
> analogous in your code; am I missing something?


OK, I'll bind `inhibit-point-motion-hooks' except for the last  
movement command.

Regarding invisible text, the original code went a long way to handle  
this efficiently.  With the new method (I'll post some code soon),  
this is handled elegantly and without any hassle thanks to posn-x-y.   
Regarding intangible text, this works fine with my working version.
I'm not sure about "fields", perhaps because I don't know much about  
their implementation.  Can you point me to a test case?  Customize  
buffers perhaps?

Thanks for pointing out these issues.



[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-05 18:41                       ` visual-line-mode Chong Yidong
  2008-07-06  1:29                         ` visual-line-mode Miles Bader
  2008-07-09 14:28                         ` visual-line-mode David Reitter
@ 2008-07-09 14:31                         ` David Reitter
  2 siblings, 0 replies; 73+ messages in thread
From: David Reitter @ 2008-07-09 14:31 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 1600 bytes --]

On 5 Jul 2008, at 19:41, Chong Yidong wrote:
>
> Good, I've checked it in (together with a couple other minor fixes).

Can you post a patch for these minor fixes?
I'm running this on 22 (because the trunk does not run on my system).

At least in the previous version, there's also a problem with posn-x- 
y, which returns a position too far when given coordinates that are to  
the right of a word-wrapped line (i.e. in the blank space).  This can  
also be seen if you just click into that space (mouse-set-point).

I can post a detailed recipe after I've made sure I've got the up-to- 
date patch.  My new code isn't iterative.  It's faster and shouldn't  
lead to excessive garbage collections as before.

> One thing that's not clear to me is whether your minor mode correctly
> handles invisible/intangible text and point motion hooks.  One of the
> reasons line-move-1 and line-move-finish is so complicated is,
> unfortunately, the need to DTRT for these.  I don't see anything
> analogous in your code; am I missing something?


OK, I'll bind `inhibit-point-motion-hooks' except for the last  
movement command.

Regarding invisible text, the original code went a long way to handle  
this efficiently.  With the new method (I'll post some code soon),  
this is handled elegantly and without any hassle thanks to posn-x-y.   
Regarding intangible text, this works fine with my working version.
I'm not sure about "fields", perhaps because I don't know much about  
their implementation.  Can you point me to a test case?  Customize  
buffers perhaps?

Thanks for pointing out these issues.



[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-09 14:28                         ` visual-line-mode David Reitter
@ 2008-07-10  3:05                           ` Chong Yidong
  2008-07-10 12:39                             ` visual-line-mode David Reitter
  0 siblings, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-10  3:05 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

> Can you post a patch for these minor fixes?
> I'm running this on 22 (because the trunk does not run on my system).

The patch is rather long, but it's on cvsweb:

http://cvs.savannah.gnu.org/viewvc/emacs/src/xdisp.c?root=emacs&r1=1.1227&r2=1.1228
http://cvs.savannah.gnu.org/viewvc/emacs/src/xdisp.c?root=emacs&r1=1.1229&r2=1.1230




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-06-29  6:30 visual-line-mode David Reitter
  2008-06-29  7:05 ` visual-line-mode Miles Bader
@ 2008-07-10  4:53 ` Chong Yidong
  1 sibling, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-10  4:53 UTC (permalink / raw)
  To: Emacs-Devel devel

I've checked in a change to the Options menu to reflect the fact
that there's now three possible states for line wrapping (word
wrap/window edge wrap/truncate lines), instead of two.

Also, I've reverted my previous change adding Longlines mode to
this menu.  (Hopefully, with a little more work the display-based
word wrap will make longline mode obsolete.)




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10  3:05                           ` visual-line-mode Chong Yidong
@ 2008-07-10 12:39                             ` David Reitter
  2008-07-10 13:55                               ` visual-line-mode Chong Yidong
                                                 ` (2 more replies)
  0 siblings, 3 replies; 73+ messages in thread
From: David Reitter @ 2008-07-10 12:39 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 1106 bytes --]

On 9 Jul 2008, at 23:05, Chong Yidong wrote:
>
> The patch is rather long, but it's on cvsweb:
>
> http://cvs.savannah.gnu.org/viewvc/emacs/src/xdisp.c?root=emacs&r1=1.1227&r2=1.1228
> http://cvs.savannah.gnu.org/viewvc/emacs/src/xdisp.c?root=emacs&r1=1.1229&r2=1.1230

OK, with this patch, my previous issues are still present:

 > There's also a problem with posn-x-y, which returns a position too  
far when given coordinates that are to the right of a word-wrapped  
line (i.e. in the blank space).  > This can also be seen if you just  
click into that space (mouse-set-point).

Also, I'd appreciate some assistance from somebody with this:

 > I'm not sure about "fields", perhaps because I don't know much  
about their implementation.  Can you point me to a test case?   
Customize buffers perhaps?

Incidentally: how would one turn on word-wrap for the echo area?
Word wrapping for `message' would be very useful.  (It could even the  
default.)

The latest version of visual-line.el can be found here:

http://aquamacs.cvs.sourceforge.net/*checkout*/aquamacs/aquamacs/src/site-lisp/visual-line.el

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 12:39                             ` visual-line-mode David Reitter
@ 2008-07-10 13:55                               ` Chong Yidong
  2008-08-03 13:47                                 ` visual-line-mode David Reitter
  2008-07-10 16:37                               ` visual-line-mode Chong Yidong
  2008-07-10 23:49                               ` visual-line-mode Chong Yidong
  2 siblings, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-10 13:55 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

>> There's also a problem with posn-x-y, which returns a position too
>> far when given coordinates that are to the right of a word-wrapped
>> line (i.e. in the blank space).  This can also be seen if you just
>> click into that space (mouse-set-point).

I'll take a look at this problem.

> Also, I'd appreciate some assistance from somebody with this:
>
>> I'm not sure about "fields", perhaps because I don't know much about
>> their implementation.  Can you point me to a test case?  Customize
>> buffers perhaps?

Basically, if you move point into a new field, line-move tries to put
point at the beginning of the field instead of its goal-column.  The
idea is that when you enter a new field, you want to start inputting
text at the beginning of the field instead of its middle.

In practice, maybe visual-line-mode probably shouldn't worry about
fields.  Respecting field boundaries in line-move has led to a ton of
complications, to try to DTRT with multi-line fields and non-contiguous
fields, just for this one small benefit.

> Incidentally: how would one turn on word-wrap for the echo area?  Word
> wrapping for `message' would be very useful.  (It could even be the
> default.)

This is controlled in xdisp.c.  Let's worry about it later.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 12:39                             ` visual-line-mode David Reitter
  2008-07-10 13:55                               ` visual-line-mode Chong Yidong
@ 2008-07-10 16:37                               ` Chong Yidong
  2008-07-10 17:32                                 ` visual-line-mode Miles Bader
  2008-07-10 18:08                                 ` visual-line-mode David Reitter
  2008-07-10 23:49                               ` visual-line-mode Chong Yidong
  2 siblings, 2 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-10 16:37 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

> The latest version of visual-line.el can be found here:

Could someone explain the difference between visual-line-mode and the
short patch that Stefan posted?




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 16:37                               ` visual-line-mode Chong Yidong
@ 2008-07-10 17:32                                 ` Miles Bader
  2008-07-10 17:40                                   ` visual-line-mode Miles Bader
  2008-07-10 20:23                                   ` visual-line-mode Stefan Monnier
  2008-07-10 18:08                                 ` visual-line-mode David Reitter
  1 sibling, 2 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-10 17:32 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Chong Yidong <cyd@stupidchicken.com> writes:
>> The latest version of visual-line.el can be found here:
>
> Could someone explain the difference between visual-line-mode and the
> short patch that Stefan posted?

My impression is that David was using an older version of emacs,
backporting your display-engine changes (aquamacs is based on carbon
emacs, which only works with emacs 22); maybe that doesn't have the
infrastructure necessary to use Stefan's patch.

BTW, while C-n and C-p work great with Stefan's patch (with both fixed-
and variable-pitch fonts), C-a and C-e act oddly (though they actually
do act somewhat differently when line-move-visual is t).  Still,
Stefan's patch seems like the right base.

-Miles

-- 
Cabbage, n. A familiar kitchen-garden vegetable about as large and wise as a
man's head.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 17:32                                 ` visual-line-mode Miles Bader
@ 2008-07-10 17:40                                   ` Miles Bader
  2008-07-10 20:23                                   ` visual-line-mode Stefan Monnier
  1 sibling, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-10 17:40 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Oh, another difference would seem to be that David's visual-line-mode
works by rebinding, whereas Stefan's patch changes the behavior of the
existing commands (based on that variable of course).

-Miles

-- 
Insurrection, n. An unsuccessful revolution.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 16:37                               ` visual-line-mode Chong Yidong
  2008-07-10 17:32                                 ` visual-line-mode Miles Bader
@ 2008-07-10 18:08                                 ` David Reitter
  2008-07-10 23:18                                   ` visual-line-mode Miles Bader
  1 sibling, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-07-10 18:08 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 431 bytes --]

On 10 Jul 2008, at 12:37, Chong Yidong wrote:

> David Reitter <david.reitter@gmail.com> writes:
>
>> The latest version of visual-line.el can be found here:
>
> Could someone explain the difference between visual-line-mode and the
> short patch that Stefan posted?


Apart from the issues pointed out by Miles, I believe that Stefan's  
patch does not support variable width fonts.  (Could someone who can  
run 23 try this?)

- D

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 17:32                                 ` visual-line-mode Miles Bader
  2008-07-10 17:40                                   ` visual-line-mode Miles Bader
@ 2008-07-10 20:23                                   ` Stefan Monnier
  2008-07-10 23:23                                     ` visual-line-mode Chong Yidong
  2008-07-11 21:10                                     ` visual-line-mode Chong Yidong
  1 sibling, 2 replies; 73+ messages in thread
From: Stefan Monnier @ 2008-07-10 20:23 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Chong Yidong, Lennart Borgman (gmail),
	Emacs-Devel devel

> BTW, while C-n and C-p work great with Stefan's patch (with both fixed-
> and variable-pitch fonts), C-a and C-e act oddly (though they actually
> do act somewhat differently when line-move-visual is t).

Indeed, my patch does not update C-a and C-e.  Not sure what you mean by
"oddly", tho.  I've been using my patch ever since I posted it and
haven't noticed anything strange with it.


        Stefan


PS: My patch is just a proof of concept.  It has a few bugs.  One of
them can be seen when you set truncate-lines, in which case it doesn't
preserve columns correctly (basically, its temporary-goal-column ends
up being computed from the beginning of the displayed part of the line,
so as long as hscroll is not changed, it works OK but as soon as
hscroll is modified, the result is incorrect).




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 18:08                                 ` visual-line-mode David Reitter
@ 2008-07-10 23:18                                   ` Miles Bader
  2008-07-10 23:35                                     ` visual-line-mode Chong Yidong
  0 siblings, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-07-10 23:18 UTC (permalink / raw)
  To: David Reitter
  Cc: Chong Yidong, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
>> Could someone explain the difference between visual-line-mode and the
>> short patch that Stefan posted?
>
> Apart from the issues pointed out by Miles, I believe that Stefan's
> patch does not support variable width fonts.  (Could someone who can
> run 23 try this?)

No, it works fine with variable-width fonts.

-Miles

-- 
Generous, adj. Originally this word meant noble by birth and was rightly
applied to a great multitude of persons. It now means noble by nature and is
taking a bit of a rest.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 20:23                                   ` visual-line-mode Stefan Monnier
@ 2008-07-10 23:23                                     ` Chong Yidong
  2008-07-10 23:44                                       ` visual-line-mode Miles Bader
  2008-07-11  1:36                                       ` visual-line-mode Stefan Monnier
  2008-07-11 21:10                                     ` visual-line-mode Chong Yidong
  1 sibling, 2 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-10 23:23 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> BTW, while C-n and C-p work great with Stefan's patch (with both fixed-
>> and variable-pitch fonts), C-a and C-e act oddly (though they actually
>> do act somewhat differently when line-move-visual is t).
>
> Indeed, my patch does not update C-a and C-e.  Not sure what you mean
> by "oddly", tho.  I've been using my patch ever since I posted it and
> haven't noticed anything strange with it.
>
> PS: My patch is just a proof of concept.  It has a few bugs.  One of
> them can be seen when you set truncate-lines, in which case it doesn't
> preserve columns correctly (basically, its temporary-goal-column ends
> up being computed from the beginning of the displayed part of the
> line, so as long as hscroll is not changed, it works OK but as soon as
> hscroll is modified, the result is incorrect).

I think that in order to be useful, this feature ought to be provided as
a minor mode that rebinds keys, not a direct modification of the motion
code like in your patch.  Then we can also handle C-k etc. properly.

Also, David Reitter's minor mode handles variable-width fonts.  AFAICT,
your patch doesn't support that, or at least not without a further
extension of vertical-motion to support a pixel goal.

So I think we ought to check in David's code.  Once that's done, we can
see about extending vertical-motion and making the minor mode use that,
for increased speed.

WDYT?




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 23:18                                   ` visual-line-mode Miles Bader
@ 2008-07-10 23:35                                     ` Chong Yidong
  0 siblings, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-10 23:35 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Miles Bader <miles@gnu.org> writes:

> David Reitter <david.reitter@gmail.com> writes:
>>> Could someone explain the difference between visual-line-mode and the
>>> short patch that Stefan posted?
>>
>> Apart from the issues pointed out by Miles, I believe that Stefan's
>> patch does not support variable width fonts.  (Could someone who can
>> run 23 try this?)
>
> No, it works fine with variable-width fonts.

Aha, so it does.  I think the docstring for vertical-motion in Emacs 23
is misleading: the new (COL . LINES) argument specifies a pixel
position, computed using the default column-width, rather than character
columns.  This should probably be noted.

So Stefan's basic approach to line-move is probably what we want to use
for Emacs 23.  Still, I think the correct approach is to merge in the
minor mode, then change it to use the new vertical-motion feature.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 23:23                                     ` visual-line-mode Chong Yidong
@ 2008-07-10 23:44                                       ` Miles Bader
  2008-07-10 23:49                                         ` visual-line-mode Chong Yidong
  2008-07-11 13:10                                         ` visual-line-mode David Reitter
  2008-07-11  1:36                                       ` visual-line-mode Stefan Monnier
  1 sibling, 2 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-10 23:44 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Chong Yidong <cyd@stupidchicken.com> writes:
> Also, David Reitter's minor mode handles variable-width fonts.  AFAICT,
> your patch doesn't support that, or at least not without a further
> extension of vertical-motion to support a pixel goal.

Actually Stefan's code seems to work fine with variable-width fonts.

> So I think we ought to check in David's code.  Once that's done, we can
> see about extending vertical-motion and making the minor mode use that,
> for increased speed.

I dunno, visual-line-mode is obviously a lot more code without a
proportionate gain in functionality; when there are wrapped lines, it's
so slow for me as to be almost unusable.

Given that Stefan's almost trivial patch works pretty well, it seems
possible that a mode similar to David's visual-line-mode, but much
smaller, could be written using Emacs-23-specific features.

-Miles

-- 
Erudition, n. Dust shaken out of a book into an empty skull.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 23:44                                       ` visual-line-mode Miles Bader
@ 2008-07-10 23:49                                         ` Chong Yidong
  2008-07-11 13:10                                         ` visual-line-mode David Reitter
  1 sibling, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-10 23:49 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Miles Bader <miles@gnu.org> writes:

> I dunno, visual-line-mode is obviously a lot more code without a
> proportionate gain in functionality; when there are wrapped lines, it's
> so slow for me as to be almost unusable.
>
> Given that Stefan's almost trivial patch works pretty well, it seems
> possible that a mode similar to David's visual-line-mode, but much
> smaller, could be written using Emacs-23-specific features.

Yeah, that's pretty much the plan.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 12:39                             ` visual-line-mode David Reitter
  2008-07-10 13:55                               ` visual-line-mode Chong Yidong
  2008-07-10 16:37                               ` visual-line-mode Chong Yidong
@ 2008-07-10 23:49                               ` Chong Yidong
  2 siblings, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-10 23:49 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

>> There's also a problem with posn-x-y, which returns a position too
>> far when given coordinates that are to the right of a word-wrapped
>> line (i.e. in the blank space).  This can also be seen if you just
>> click into that space (mouse-set-point).

I've just checked in a fix to CVS.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 23:23                                     ` visual-line-mode Chong Yidong
  2008-07-10 23:44                                       ` visual-line-mode Miles Bader
@ 2008-07-11  1:36                                       ` Stefan Monnier
  2008-07-11  2:30                                         ` visual-line-mode Miles Bader
  2008-07-11  4:36                                         ` visual-line-mode Chong Yidong
  1 sibling, 2 replies; 73+ messages in thread
From: Stefan Monnier @ 2008-07-11  1:36 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

> I think that in order to be useful, this feature ought to be provided as
> a minor mode that rebinds keys, not a direct modification of the motion
> code like in your patch.  Then we can also handle C-k etc. properly.

Could be.  Then again, it's probably easier to do it right by modifying
the code of kill-line (tho, to tell you the truth, I'm far from).

This said, I find that visual-line movement works well *all the time*
(literally).  I've never felt like turning it off and the few times I've
bumped into it unexpectedly, I was positively surprised.

OTOH, I don't think I'd like C-k to work on visual lines (I know I hate
this behavior in Firefox), so maybe we should distinguish the
screen-line movements (which I could even consider turning on by
default) from other screen-line operations.


        Stefan




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11  1:36                                       ` visual-line-mode Stefan Monnier
@ 2008-07-11  2:30                                         ` Miles Bader
  2008-07-11  4:36                                         ` visual-line-mode Chong Yidong
  1 sibling, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-11  2:30 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Chong Yidong, Lennart Borgman (gmail),
	Emacs-Devel devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:
> This said, I find that visual-line movement works well *all the time*
> (literally).  I've never felt like turning it off and the few times I've
> bumped into it unexpectedly, I was positively surprised.

Me too.  I've been using Stefan's patch (which just turns on
visual-movement globally) since he posted it, and aside from the
aformentioned weird behavior of C-a/C-e (which is clearly just a bug), I
find I don't even _notice_.

While it's true that redefining basic commands is frowned-upon in
general, C-a/C-e/C-n/C-p have long had special "interactive" versions
that do funny things to make the user happy, with lisp code using more
basic primitives.  I don't think it would be a stretch to just commit a
bug-fixed and extended version of Stefan's patch.

-miles

-- 
We live, as we dream -- alone....




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11  1:36                                       ` visual-line-mode Stefan Monnier
  2008-07-11  2:30                                         ` visual-line-mode Miles Bader
@ 2008-07-11  4:36                                         ` Chong Yidong
  2008-07-11 14:56                                           ` visual-line-mode David Reitter
  1 sibling, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-11  4:36 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> This said, I find that visual-line movement works well *all the time*
> (literally).  I've never felt like turning it off and the few times I've
> bumped into it unexpectedly, I was positively surprised.
>
> OTOH, I don't think I'd like C-k to work on visual lines (I know I hate
> this behavior in Firefox), so maybe we should distinguish the
> screen-line movements (which I could even consider turning on by
> default) from other screen-line operations.

I agree that it would be good to make this the default, if it works as
well as you say.  The visual editing mode, probably based on David
Reitter's code in some modified form, can go on top of it (like
longlines mode, I think it is useful for editing certain types of text,
though not all.)  We need to make it work properly with point-motion
hooks, though.  Would you like to do that?




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 23:44                                       ` visual-line-mode Miles Bader
  2008-07-10 23:49                                         ` visual-line-mode Chong Yidong
@ 2008-07-11 13:10                                         ` David Reitter
  2008-07-14  3:58                                           ` visual-line-mode Miles Bader
  1 sibling, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-07-11 13:10 UTC (permalink / raw)
  To: Miles Bader
  Cc: Chong Yidong, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 373 bytes --]

On 10 Jul 2008, at 19:44, Miles Bader wrote:
>
> I dunno, visual-line-mode is obviously a lot more code without a
> proportionate gain in functionality; when there are wrapped lines,  
> it's
> so slow for me as to be almost unusable.

You tried the iterative version.
The current version is not only much smaller, it is also non-iterative  
and should work without delays.

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11  4:36                                         ` visual-line-mode Chong Yidong
@ 2008-07-11 14:56                                           ` David Reitter
  2008-07-11 15:57                                             ` visual-line-mode Chong Yidong
  2008-07-11 20:36                                             ` visual-line-mode Miles Bader
  0 siblings, 2 replies; 73+ messages in thread
From: David Reitter @ 2008-07-11 14:56 UTC (permalink / raw)
  To: Chong Yidong
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

[-- Attachment #1: Type: text/plain, Size: 1220 bytes --]

On 11 Jul 2008, at 00:36, Chong Yidong wrote:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>> This said, I find that visual-line movement works well *all the time*
>> (literally).  I've never felt like turning it off and the few times  
>> I've
>> bumped into it unexpectedly, I was positively surprised.
>>
>> OTOH, I don't think I'd like C-k to work on visual lines (I know I  
>> hate
>> this behavior in Firefox), so maybe we should distinguish the
>> screen-line movements (which I could even consider turning on by
>> default) from other screen-line operations.
>
> I agree that it would be good to make this the default, if it works as
> well as you say.
>  The visual editing mode, probably based on David
> Reitter's code in some modified form, can go on top of it (like
> longlines mode, I think it is useful for editing certain types of  
> text,
> though not all.)  We need to make it work properly with point-motion
> hooks, though.  Would you like to do that?


OK, do I understand you right? Basic movement commands (when  
interactive) on by default as per Stefan's method (which I agree is  
better given the new feature of vertical-motion), and C-a/C-e/C-k in a  
minor mode as per my code.


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 14:56                                           ` visual-line-mode David Reitter
@ 2008-07-11 15:57                                             ` Chong Yidong
  2008-07-11 18:27                                               ` visual-line-mode Chong Yidong
  2008-07-11 20:36                                             ` visual-line-mode Miles Bader
  1 sibling, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-11 15:57 UTC (permalink / raw)
  To: David Reitter
  Cc: Emacs-Devel devel, Lennart Borgman (gmail), Stefan Monnier,
	Miles Bader

David Reitter <david.reitter@gmail.com> writes:

> OK, do I understand you right? Basic movement commands (when
> interactive) on by default as per Stefan's method (which I agree is
> better given the new feature of vertical-motion), and C-a/C-e/C-k in a
> minor mode as per my code.

Yes.  If the line-motion commands are integrated into the existing
simple.el code as Stefan suggested, the remaining code for the minor
mode may be small enough to fit into simple.el, without needing an
additional file.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 15:57                                             ` visual-line-mode Chong Yidong
@ 2008-07-11 18:27                                               ` Chong Yidong
  0 siblings, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-11 18:27 UTC (permalink / raw)
  To: David Reitter
  Cc: Miles Bader, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Chong Yidong <cyd@stupidchicken.com> writes:

> David Reitter <david.reitter@gmail.com> writes:
>
>> OK, do I understand you right? Basic movement commands (when
>> interactive) on by default as per Stefan's method (which I agree is
>> better given the new feature of vertical-motion), and C-a/C-e/C-k in a
>> minor mode as per my code.
>
> Yes.  If the line-motion commands are integrated into the existing
> simple.el code as Stefan suggested, the remaining code for the minor
> mode may be small enough to fit into simple.el, without needing an
> additional file.

Okay, I've installed Stefan's patch (with some fixes) on the trunk.
Let's wait a couple of days before committing the visual-editing
changes, to see if the patch causes any problems.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 14:56                                           ` visual-line-mode David Reitter
  2008-07-11 15:57                                             ` visual-line-mode Chong Yidong
@ 2008-07-11 20:36                                             ` Miles Bader
  2008-07-11 21:18                                               ` visual-line-mode Stefan Monnier
  1 sibling, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-07-11 20:36 UTC (permalink / raw)
  To: David Reitter
  Cc: Chong Yidong, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
> OK, do I understand you right? Basic movement commands (when
> interactive) on by default as per Stefan's method (which I agree is
> better given the new feature of vertical-motion), and C-a/C-e/C-k in a
> minor mode as per my code.

That doesn't make much sense -- _at least_ C-a/C-e need to act
consistently with C-n/C-p.  It's mind-boggling confusing when they
don't.

Other commands, I dunno, though I think C-k should as well (Stefan
apparently doesn't though).

-Miles

-- 
Consult, v.i. To seek another's disapproval of a course already decided on.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 20:23                                   ` visual-line-mode Stefan Monnier
  2008-07-10 23:23                                     ` visual-line-mode Chong Yidong
@ 2008-07-11 21:10                                     ` Chong Yidong
  2008-07-12  1:43                                       ` visual-line-mode Stefan Monnier
  1 sibling, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-11 21:10 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> PS: My patch is just a proof of concept.  It has a few bugs.  One of
> them can be seen when you set truncate-lines, in which case it doesn't
> preserve columns correctly (basically, its temporary-goal-column ends
> up being computed from the beginning of the displayed part of the line,
> so as long as hscroll is not changed, it works OK but as soon as
> hscroll is modified, the result is incorrect).

Does the following patch give good results/make sense?

*** trunk/src/indent.c.~1.209.~	2008-06-29 09:56:50.000000000 -0400
--- trunk/src/indent.c	2008-07-11 17:08:33.000000000 -0400
***************
*** 2058,2067 ****
--- 2058,2070 ----
        int it_start;
        int oselective;
        int it_overshoot_expected;
+       int first_x;
  
        SET_TEXT_POS (pt, PT, PT_BYTE);
        start_display (&it, w, pt);
  
+       first_x = it.first_visible_x;
+ 
        /* Scan from the start of the line containing PT.  If we don't
  	 do this, we start moving with IT->current_x == 0, while PT is
  	 really at some x > 0.  The effect is, in continuation lines, that
***************
*** 2119,2128 ****
  	move_it_by_lines (&it, XINT (lines), 0);
  
        if (!NILP (lcols))
! 	move_it_in_display_line
! 	  (&it, ZV,
! 	   (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
! 	   MOVE_TO_X);
  
        SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
      }
--- 2122,2135 ----
  	move_it_by_lines (&it, XINT (lines), 0);
  
        if (!NILP (lcols))
! 	{
! 	  move_it_in_display_line (&it, ZV, first_x, MOVE_TO_X);
! 	  it.current_x = 0;
! 	  move_it_in_display_line
! 	    (&it, ZV,
! 	     (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
! 	     MOVE_TO_X);
! 	}
  
        SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
      }




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 20:36                                             ` visual-line-mode Miles Bader
@ 2008-07-11 21:18                                               ` Stefan Monnier
  2008-07-11 21:23                                                 ` visual-line-mode David Kastrup
  0 siblings, 1 reply; 73+ messages in thread
From: Stefan Monnier @ 2008-07-11 21:18 UTC (permalink / raw)
  To: Miles Bader
  Cc: David Reitter, Chong Yidong, Lennart Borgman (gmail),
	Emacs-Devel devel

>> OK, do I understand you right? Basic movement commands (when
>> interactive) on by default as per Stefan's method (which I agree is
>> better given the new feature of vertical-motion), and C-a/C-e/C-k in a
>> minor mode as per my code.

> That doesn't make much sense -- _at least_ C-a/C-e need to act
> consistently with C-n/C-p.  It's mind-boggling confusing when they
> don't.

> Other commands, I dunno, though I think C-k should as well (Stefan
> apparently doesn't though).

I'm mostly using it on files with few line wrapping, so in this context,
visual-line movement for C-p and C-n is not harmful in my experience,
but for things like C-a, C-e, and C-k I find it annoying.  E.g. I expect
C-a C-k to kill the whole code line, not just the part that happens to
fit within my window's width.

Also C-k is odd when operating on a visual line: if the line is wrapped,
then after C-k you'd end up still having text after point, whereas
I usually expect that after C-k point is at EOL.

Maybe it's just me.


        Stefan




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 21:18                                               ` visual-line-mode Stefan Monnier
@ 2008-07-11 21:23                                                 ` David Kastrup
  2008-07-11 21:41                                                   ` visual-line-mode David Reitter
  2008-07-12  1:49                                                   ` visual-line-mode Stefan Monnier
  0 siblings, 2 replies; 73+ messages in thread
From: David Kastrup @ 2008-07-11 21:23 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Chong Yidong, Emacs-Devel devel,
	Lennart Borgman (gmail), Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> OK, do I understand you right? Basic movement commands (when
>>> interactive) on by default as per Stefan's method (which I agree is
>>> better given the new feature of vertical-motion), and C-a/C-e/C-k in
>>> a minor mode as per my code.
>
>> That doesn't make much sense -- _at least_ C-a/C-e need to act
>> consistently with C-n/C-p.  It's mind-boggling confusing when they
>> don't.
>
>> Other commands, I dunno, though I think C-k should as well (Stefan
>> apparently doesn't though).
>
> I'm mostly using it on files with few line wrapping, so in this
> context, visual-line movement for C-p and C-n is not harmful in my
> experience, but for things like C-a, C-e, and C-k I find it annoying.
> E.g. I expect C-a C-k to kill the whole code line, not just the part
> that happens to fit within my window's width.
>
> Also C-k is odd when operating on a visual line: if the line is
> wrapped, then after C-k you'd end up still having text after point,
> whereas I usually expect that after C-k point is at EOL.
>
> Maybe it's just me.

I think it depends on what you use it for.  If you are editing code,
there is usually little overflow, and the overflow you have ends at an
easily recognizable place, and the hard newlines carry meaning.

If you are editing a novel where every paragraph is written without
newlines, wrapping just being done to accommodate the editing window
(but irrelevant for the result), you want to be able to edit and
navigate with finer grained units than whole paragraphs.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 21:23                                                 ` visual-line-mode David Kastrup
@ 2008-07-11 21:41                                                   ` David Reitter
  2008-07-12  1:49                                                   ` visual-line-mode Stefan Monnier
  1 sibling, 0 replies; 73+ messages in thread
From: David Reitter @ 2008-07-11 21:41 UTC (permalink / raw)
  To: David Kastrup
  Cc: Chong Yidong, Emacs-Devel devel, Lennart Borgman (gmail),
	Stefan Monnier, Miles Bader

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

On 11 Jul 2008, at 17:23, David Kastrup wrote:
>
> I think it depends on what you use it for.  If you are editing code,
> there is usually little overflow, and the overflow you have ends at an
> easily recognizable place, and the hard newlines carry meaning.
>
> If you are editing a novel where every paragraph is written without
> newlines, wrapping just being done to accommodate the editing window
> (but irrelevant for the result), you want to be able to edit and
> navigate with finer grained units than whole paragraphs.

Agreed.  That's why a visual-line-mode makes sense on top of Stefan's  
patch.  It would be good to enable it by default in text modes.

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 21:10                                     ` visual-line-mode Chong Yidong
@ 2008-07-12  1:43                                       ` Stefan Monnier
  0 siblings, 0 replies; 73+ messages in thread
From: Stefan Monnier @ 2008-07-12  1:43 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

>> PS: My patch is just a proof of concept.  It has a few bugs.  One of
>> them can be seen when you set truncate-lines, in which case it doesn't
>> preserve columns correctly (basically, its temporary-goal-column ends
>> up being computed from the beginning of the displayed part of the line,
>> so as long as hscroll is not changed, it works OK but as soon as
>> hscroll is modified, the result is incorrect).

> Does the following patch give good results/make sense?

Not sure.  I'm not sure where is the bug, really.  If it's in
posn-point, or in vertical-motion, or simply in my Elisp code, or
a combination.  My gut feeling is that there's at least a bug in my
Elisp code and maybe also in the vertical-motion code (the part that
handles horizontal position, i.e. my new code there).

It looks like your patch presumes that the Elisp code is passing the
correct value, which I'm not sure is the case.  But it's probably going
in the right direction.


        Stefan




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 21:23                                                 ` visual-line-mode David Kastrup
  2008-07-11 21:41                                                   ` visual-line-mode David Reitter
@ 2008-07-12  1:49                                                   ` Stefan Monnier
  2008-07-12  8:09                                                     ` visual-line-mode David Kastrup
  2008-07-16  4:21                                                     ` visual-line-mode Chong Yidong
  1 sibling, 2 replies; 73+ messages in thread
From: Stefan Monnier @ 2008-07-12  1:49 UTC (permalink / raw)
  To: David Kastrup
  Cc: David Reitter, Chong Yidong, Emacs-Devel devel,
	Lennart Borgman (gmail), Miles Bader

> I think it depends on what you use it for.  If you are editing code,
> there is usually little overflow, and the overflow you have ends at an
> easily recognizable place, and the hard newlines carry meaning.

> If you are editing a novel where every paragraph is written without
> newlines, wrapping just being done to accommodate the editing window
> (but irrelevant for the result), you want to be able to edit and
> navigate with finer grained units than whole paragraphs.

Agreed.  That's why I think we need a separate minor mode for it.

So, if we consider the difference between TL (text lines) and VL (visual
lines), and also the difference between C-n/C-p and the other line
commands (C-a, C-e, C-k, others?):

It clearly makes sense to use TL for all commands (what we've done until
now), and it also makes sense to use VL for all commands (as provided by
David Reitter's code).  I don't think it makes sense to use TL for
C-n/C-p and VL for the rest.  But should we support the combination of
VL for C-n/C-p and TL for the rest?  That's what I've been using
recently and I like it, so I think it makes sense.  I'm even tempted to
make it the default.  But its internal inconsistence is
a bit troublesome.


        Stefan





^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-12  1:49                                                   ` visual-line-mode Stefan Monnier
@ 2008-07-12  8:09                                                     ` David Kastrup
  2008-07-12 16:35                                                       ` visual-line-mode Richard M Stallman
  2008-07-16  4:21                                                     ` visual-line-mode Chong Yidong
  1 sibling, 1 reply; 73+ messages in thread
From: David Kastrup @ 2008-07-12  8:09 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Chong Yidong, Emacs-Devel devel,
	Lennart Borgman (gmail), Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> It clearly makes sense to use TL for all commands (what we've done
> until now), and it also makes sense to use VL for all commands (as
> provided by David Reitter's code).  I don't think it makes sense to
> use TL for C-n/C-p and VL for the rest.  But should we support the
> combination of VL for C-n/C-p and TL for the rest?  That's what I've
> been using recently and I like it, so I think it makes sense.  I'm
> even tempted to make it the default.  But its internal inconsistence
> is a bit troublesome.

If you take a look at the documentation of next-line, you'll find that
it goes to considerable pain to navigate _visually_ already without your
patch.  It vscrolls tall lines, it tries maintaining the current column
and a few other things.

So it makes some sense to let them move visual lines.  That leaves us
without an approach to logical lines.  C-e C-f can be used to move to
the next line, but not if those are mapped to logical movement as well.

move-end-of-line and move-beginning-of-line inherently don't do visual
work.  So I think that for a default behavior, just affecting next-line,
previous-line, scroll-up, scroll-down and possibly other visual-content
related commands sounds reasonable and more or less in spirit to what is
there already.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-12  8:09                                                     ` visual-line-mode David Kastrup
@ 2008-07-12 16:35                                                       ` Richard M Stallman
  2008-07-12 17:42                                                         ` visual-line-mode Chong Yidong
  0 siblings, 1 reply; 73+ messages in thread
From: Richard M Stallman @ 2008-07-12 16:35 UTC (permalink / raw)
  To: David Kastrup
  Cc: david.reitter, cyd, lennart.borgman, emacs-devel, monnier, miles

How about using M-[ and M-] to move by real lines
in the modes where C-n and C-p move by visual lines?
In those modes, a real line is usually a paragraph,
so these commands seem appropriate.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-12 16:35                                                       ` visual-line-mode Richard M Stallman
@ 2008-07-12 17:42                                                         ` Chong Yidong
  0 siblings, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-07-12 17:42 UTC (permalink / raw)
  To: rms; +Cc: david.reitter, lennart.borgman, emacs-devel, monnier, miles

Richard M Stallman <rms@gnu.org> writes:

> How about using M-[ and M-] to move by real lines
> in the modes where C-n and C-p move by visual lines?
> In those modes, a real line is usually a paragraph,
> so these commands seem appropriate.

Sounds good.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-11 13:10                                         ` visual-line-mode David Reitter
@ 2008-07-14  3:58                                           ` Miles Bader
  2008-07-14  3:59                                             ` visual-line-mode Miles Bader
  0 siblings, 1 reply; 73+ messages in thread
From: Miles Bader @ 2008-07-14  3:58 UTC (permalink / raw)
  To: David Reitter
  Cc: Chong Yidong, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:
> You tried the iterative version.
> The current version is not only much smaller, it is also non-iterative
> and should work without delays.

Tried both, actually...

-Miles

-- 
Erudition, n. Dust shaken out of a book into an empty skull.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-14  3:58                                           ` visual-line-mode Miles Bader
@ 2008-07-14  3:59                                             ` Miles Bader
  0 siblings, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-14  3:59 UTC (permalink / raw)
  To: David Reitter
  Cc: Chong Yidong, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Miles Bader <miles.bader@necel.com> writes:
>> You tried the iterative version.
>> The current version is not only much smaller, it is also non-iterative
>> and should work without delays.
>
> Tried both, actually...

Well, tried both that you posted anyway.

-Miles

-- 
My spirit felt washed.  With blood.  [Eli Shin, on "The Passion of the Christ"]




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-12  1:49                                                   ` visual-line-mode Stefan Monnier
  2008-07-12  8:09                                                     ` visual-line-mode David Kastrup
@ 2008-07-16  4:21                                                     ` Chong Yidong
  2008-07-16  4:37                                                       ` visual-line-mode Miles Bader
  1 sibling, 1 reply; 73+ messages in thread
From: Chong Yidong @ 2008-07-16  4:21 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: David Reitter, Emacs-Devel devel, Lennart Borgman (gmail),
	Miles Bader

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> If you are editing a novel where every paragraph is written without
>> newlines, wrapping just being done to accommodate the editing window
>> (but irrelevant for the result), you want to be able to edit and
>> navigate with finer grained units than whole paragraphs.
>
> Agreed.  That's why I think we need a separate minor mode for it.

Could someone suggest another name for the minor mode?  visual-line-mode
does not seem quite accurate.




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-16  4:21                                                     ` visual-line-mode Chong Yidong
@ 2008-07-16  4:37                                                       ` Miles Bader
  0 siblings, 0 replies; 73+ messages in thread
From: Miles Bader @ 2008-07-16  4:37 UTC (permalink / raw)
  To: Chong Yidong
  Cc: David Reitter, Lennart Borgman (gmail), Stefan Monnier,
	Emacs-Devel devel

Chong Yidong <cyd@stupidchicken.com> writes:
>> Agreed.  That's why I think we need a separate minor mode for it.
>
> Could someone suggest another name for the minor mode?  visual-line-mode
> does not seem quite accurate.

Why not?

-Miles

-- 
"Though they may have different meanings, the cries of 'Yeeeee-haw!' and
 'Allahu akbar!' are, in spirit, not actually all that different."




^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: visual-line-mode
  2008-07-10 13:55                               ` visual-line-mode Chong Yidong
@ 2008-08-03 13:47                                 ` David Reitter
  2008-08-11 13:38                                   ` word-wrap in echo area (was Re: visual-line-mode) David Reitter
  0 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-08-03 13:47 UTC (permalink / raw)
  To: Chong Yidong; +Cc: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 361 bytes --]

On 10 Jul 2008, at 15:55, Chong Yidong wrote:

>> Incidentally: how would one turn on word-wrap for the echo area?   
>> Word
>> wrapping for `message' would be very useful.  (It could even be the
>> default.)
>
> This is controlled in xdisp.c.  Let's worry about it later.

Should we revisit and fix this issue now while it's early in the  
pretest phase?

- D

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* word-wrap in echo area  (was Re: visual-line-mode)
  2008-08-03 13:47                                 ` visual-line-mode David Reitter
@ 2008-08-11 13:38                                   ` David Reitter
  2008-08-11 16:03                                     ` word-wrap in echo area Chong Yidong
  0 siblings, 1 reply; 73+ messages in thread
From: David Reitter @ 2008-08-11 13:38 UTC (permalink / raw)
  To: Chong Yidong, Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 1097 bytes --]

On 3 Aug 2008, at 15:47, David Reitter wrote:

> On 10 Jul 2008, at 15:55, Chong Yidong wrote:
>
>>> Incidentally: how would one turn on word-wrap for the echo area?   
>>> Word
>>> wrapping for `message' would be very useful.  (It could even be the
>>> default.)
>>
>> This is controlled in xdisp.c.  Let's worry about it later.
>
> Should we revisit and fix this issue now while it's early in the  
> pretest phase?


It's a simple change.  Is this trouble-prone, or can it be installed  
now?


Index: xdisp.c
===================================================================
RCS file: /sources/emacs/emacs/src/xdisp.c,v
retrieving revision 1.1245
diff -c -r1.1245 xdisp.c
*** xdisp.c	8 Aug 2008 15:43:45 -0000	1.1245
--- xdisp.c	11 Aug 2008 13:33:36 -0000
***************
*** 8320,8325 ****
--- 8320,8326 ----
   	sprintf (name, " *Echo Area %d*", i);
   	echo_buffer[i] = Fget_buffer_create (build_string (name));
   	XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
+ 	XBUFFER (echo_buffer[i])->word_wrap = Qt;

   	for (j = 0; j < 2; ++j)
   	  if (EQ (old_buffer, echo_area_buffer[j]))


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2193 bytes --]

^ permalink raw reply	[flat|nested] 73+ messages in thread

* Re: word-wrap in echo area
  2008-08-11 13:38                                   ` word-wrap in echo area (was Re: visual-line-mode) David Reitter
@ 2008-08-11 16:03                                     ` Chong Yidong
  0 siblings, 0 replies; 73+ messages in thread
From: Chong Yidong @ 2008-08-11 16:03 UTC (permalink / raw)
  To: David Reitter; +Cc: Emacs-Devel devel

David Reitter <david.reitter@gmail.com> writes:

>>>> Incidentally: how would one turn on word-wrap for the echo area?
>>>> Word wrapping for `message' would be very useful.  (It could even
>>>> be the default.)
>
> It's a simple change.  Is this trouble-prone, or can it be installed
> now?
>
>
> Index: xdisp.c
> ===================================================================
> RCS file: /sources/emacs/emacs/src/xdisp.c,v
> retrieving revision 1.1245
> diff -c -r1.1245 xdisp.c
> *** xdisp.c	8 Aug 2008 15:43:45 -0000	1.1245
> --- xdisp.c	11 Aug 2008 13:33:36 -0000
> ***************
> *** 8320,8325 ****
> --- 8320,8326 ----
>   	sprintf (name, " *Echo Area %d*", i);
>   	echo_buffer[i] = Fget_buffer_create (build_string (name));
>   	XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
> + 	XBUFFER (echo_buffer[i])->word_wrap = Qt;

We shouldn't turn on word wrap unconditionally in the echo area, because
there are instances in which word wrap is undesirable.  For example,
when the buffer contains words that are (on average) half the window
width, word wrap actually makes text harder to read than ordinary line
wrapping.  Maybe this situation never occurs in the echo area; maybe
not; in any case, let's leave this till after the release.




^ permalink raw reply	[flat|nested] 73+ messages in thread

end of thread, other threads:[~2008-08-11 16:03 UTC | newest]

Thread overview: 73+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-29  6:30 visual-line-mode David Reitter
2008-06-29  7:05 ` visual-line-mode Miles Bader
2008-06-29  7:19   ` visual-line-mode Miles Bader
2008-06-29 14:01   ` visual-line-mode Stefan Monnier
2008-06-29 15:29     ` visual-line-mode Chong Yidong
2008-06-30  3:07     ` visual-line-mode Miles Bader
2008-06-30  3:15       ` visual-line-mode Chong Yidong
2008-06-30  5:13         ` visual-line-mode Miles Bader
2008-06-30  5:15           ` visual-line-mode Miles Bader
2008-06-30 10:39             ` visual-line-mode Miles Bader
2008-06-30 11:20               ` visual-line-mode Miles Bader
2008-06-30 14:01               ` visual-line-mode Chong Yidong
2008-06-30 16:10                 ` visual-line-mode Chong Yidong
2008-07-01  9:10               ` visual-line-mode David Reitter
2008-07-03 19:20           ` visual-line-mode Chong Yidong
2008-07-03 23:56             ` visual-line-mode David Reitter
2008-07-04 10:23               ` visual-line-mode Chong Yidong
2008-07-04 10:58                 ` visual-line-mode Miles Bader
2008-07-04 13:04                   ` visual-line-mode Chong Yidong
2008-07-04 15:04                     ` visual-line-mode David Reitter
2008-07-04 15:49                       ` visual-line-mode Stefan Monnier
2008-07-04 16:21                         ` visual-line-mode David Reitter
2008-07-05 18:41                       ` visual-line-mode Chong Yidong
2008-07-06  1:29                         ` visual-line-mode Miles Bader
2008-07-09 14:28                         ` visual-line-mode David Reitter
2008-07-10  3:05                           ` visual-line-mode Chong Yidong
2008-07-10 12:39                             ` visual-line-mode David Reitter
2008-07-10 13:55                               ` visual-line-mode Chong Yidong
2008-08-03 13:47                                 ` visual-line-mode David Reitter
2008-08-11 13:38                                   ` word-wrap in echo area (was Re: visual-line-mode) David Reitter
2008-08-11 16:03                                     ` word-wrap in echo area Chong Yidong
2008-07-10 16:37                               ` visual-line-mode Chong Yidong
2008-07-10 17:32                                 ` visual-line-mode Miles Bader
2008-07-10 17:40                                   ` visual-line-mode Miles Bader
2008-07-10 20:23                                   ` visual-line-mode Stefan Monnier
2008-07-10 23:23                                     ` visual-line-mode Chong Yidong
2008-07-10 23:44                                       ` visual-line-mode Miles Bader
2008-07-10 23:49                                         ` visual-line-mode Chong Yidong
2008-07-11 13:10                                         ` visual-line-mode David Reitter
2008-07-14  3:58                                           ` visual-line-mode Miles Bader
2008-07-14  3:59                                             ` visual-line-mode Miles Bader
2008-07-11  1:36                                       ` visual-line-mode Stefan Monnier
2008-07-11  2:30                                         ` visual-line-mode Miles Bader
2008-07-11  4:36                                         ` visual-line-mode Chong Yidong
2008-07-11 14:56                                           ` visual-line-mode David Reitter
2008-07-11 15:57                                             ` visual-line-mode Chong Yidong
2008-07-11 18:27                                               ` visual-line-mode Chong Yidong
2008-07-11 20:36                                             ` visual-line-mode Miles Bader
2008-07-11 21:18                                               ` visual-line-mode Stefan Monnier
2008-07-11 21:23                                                 ` visual-line-mode David Kastrup
2008-07-11 21:41                                                   ` visual-line-mode David Reitter
2008-07-12  1:49                                                   ` visual-line-mode Stefan Monnier
2008-07-12  8:09                                                     ` visual-line-mode David Kastrup
2008-07-12 16:35                                                       ` visual-line-mode Richard M Stallman
2008-07-12 17:42                                                         ` visual-line-mode Chong Yidong
2008-07-16  4:21                                                     ` visual-line-mode Chong Yidong
2008-07-16  4:37                                                       ` visual-line-mode Miles Bader
2008-07-11 21:10                                     ` visual-line-mode Chong Yidong
2008-07-12  1:43                                       ` visual-line-mode Stefan Monnier
2008-07-10 18:08                                 ` visual-line-mode David Reitter
2008-07-10 23:18                                   ` visual-line-mode Miles Bader
2008-07-10 23:35                                     ` visual-line-mode Chong Yidong
2008-07-10 23:49                               ` visual-line-mode Chong Yidong
2008-07-09 14:31                         ` visual-line-mode David Reitter
2008-07-04 11:09                 ` visual-line-mode David Reitter
2008-07-04 12:39                   ` visual-line-mode Paul R
2008-06-30  7:32   ` visual-line-mode David Reitter
2008-06-30  7:43     ` visual-line-mode Miles Bader
2008-06-30  7:58       ` visual-line-mode David Reitter
2008-06-30  8:05         ` visual-line-mode Miles Bader
2008-06-30  8:25           ` visual-line-mode David Reitter
2008-06-30  8:30             ` visual-line-mode Miles Bader
2008-07-10  4:53 ` visual-line-mode Chong Yidong

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).