all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Chong Yidong <cyd@stupidchicken.com>
To: David Reitter <david.reitter@gmail.com>
Cc: emacs-devel@gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>,
	raman@users.sourceforge.net
Subject: Re: line-line-move-visual: was line motion problem
Date: Wed, 16 Jul 2008 14:26:44 -0400	[thread overview]
Message-ID: <87hcap3ct7.fsf@stupidchicken.com> (raw)
In-Reply-To: <87abghlqs2.fsf@stupidchicken.com> (Chong Yidong's message of "Wed, 16 Jul 2008 12:47:41 -0400")

Chong Yidong <cyd@stupidchicken.com> writes:

> I think we should have a defcustom that sets the default value of
> line-move-visual, and a minor mode (I guess it'll be called
> visual-line-mode, since there doesn't seem to be any better name) that
> provides the rest of the visual editing features.

The following patch implements this approach.  I've taken bits from
visual-line.el, and re-written other bits to make use of the new
features of vertical-motion in Emacs 23.

Could people try it out and see if it DTRT?

As Richard suggested, it binds M-[ and M-] to logical previous-line and
next-line.  I don't know, OTOH, where a logical kill-line should be
bound (visual-line.el bound it to C-K, but this doesn't seem optimal,
since OTOH we try not to use upcased keybindings where possible).


*** trunk/lisp/simple.el.~1.934.~	2008-07-15 14:47:32.000000000 -0400
--- trunk/lisp/simple.el	2008-07-16 14:23:26.000000000 -0400
***************
*** 3906,3916 ****
    :type 'boolean
    :group 'editing-basics)
  
! (defvar line-move-visual t
    "When non-nil, `line-move' moves point by visual lines.
  This movement is based on where the cursor is displayed on the
  screen, instead of relying on buffer contents alone.  It takes
! into account variable-width characters and line continuation.")
  
  ;; Returns non-nil if partial move was done.
  (defun line-move-partial (arg noerror to-end)
--- 3906,3919 ----
    :type 'boolean
    :group 'editing-basics)
  
! (defcustom line-move-visual t
    "When non-nil, `line-move' moves point by visual lines.
  This movement is based on where the cursor is displayed on the
  screen, instead of relying on buffer contents alone.  It takes
! into account variable-width characters and line continuation."
!   :type 'boolean
!   :group 'editing-basics)
! (make-variable-buffer-local 'line-move-visual)
  
  ;; Returns non-nil if partial move was done.
  (defun line-move-partial (arg noerror to-end)
***************
*** 4017,4022 ****
--- 4020,4027 ----
    (let ((inhibit-point-motion-hooks t)
  	(opoint (point))
  	(orig-arg arg))
+     (if (floatp temporary-goal-column)
+ 	(setq temporary-goal-column (truncate temporary-goal-column)))
      (unwind-protect
  	(progn
  	  (if (not (memq last-command '(next-line previous-line)))
***************
*** 4365,4371 ****
--- 4370,4499 ----
      )
    nil)
  \f
+ ;;; Editing based on visual lines, as opposed to logical lines.
+ 
+ (defun end-of-visual-line (&optional n)
+   "Move point to end of current visual line.
+ With argument N not nil or 1, move forward N - 1 visual lines first.
+ If point reaches the beginning or end of buffer, it stops there.
+ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
+   (interactive "^p")
+   (or n (setq n 1))
+   (if (/= n 1)
+       (let ((line-move-visual t))
+ 	(line-move (1- n) t)))
+   (vertical-motion (cons (window-width) 0)))
+ 
+ (defun beginning-of-visual-line (&optional n)
+   "Move point to beginning of current visual line.
+ With argument N not nil or 1, move forward N - 1 visual lines first.
+ If point reaches the beginning or end of buffer, it stops there.
+ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
+   (interactive "^p")
+   (or n (setq n 1))
+   (if (/= n 1)
+       (let ((line-move-visual t))
+ 	(line-move (1- n) t)))
+   (vertical-motion 0))
+ 
+ (defun kill-visual-line (&optional arg)
+   "Kill the rest of the visual line.
+ If there are only whitespace characters there, kill through the
+ newline as well.
+ 
+ With prefix argument, kill that many lines from point.
+ Negative arguments kill lines backward.
+ With zero argument, kill the text before point on the current line.
+ 
+ When calling from a program, nil means \"no arg\",
+ a number counts as a prefix arg.
+ 
+ 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")
+   (let ((opoint (point))
+ 	(line-move-visual t)
+ 	end)
+     ;; 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.
+     (if arg
+ 	(vertical-motion (prefix-numeric-value arg))
+       (if (eobp)
+ 	  (signal 'end-of-buffer nil))
+       (setq 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)))
+ 	  (line-move 1)
+ 	(goto-char end)))
+     (kill-region opoint (point))))
+ 
+ (defun next-logical-line (&optional arg try-vscroll)
+   "Move cursor vertically down ARG lines.
+ This is identical to `previous-line', except that it always moves
+ by logical lines instead of visual lines, ignoring the value of
+ `line-move-visual'."
+   (interactive "^p\np")
+   (let ((line-move-visual nil))
+     (with-no-warnings
+       (next-line arg try-vscroll))))
+ 
+ (defun previous-logical-line (&optional arg try-vscroll)
+   "Move cursor vertically up ARG lines.
+ This is identical to `previous-line', except that it always moves
+ by logical lines instead of visual lines, ignoring the value of
+ `line-move-visual'."
+   (interactive "^p\np")
+   (let ((line-move-visual nil))
+     (with-no-warnings
+       (previous-line arg try-vscroll))))
  
+ (defvar visual-line-mode-map
+   (let ((map (make-sparse-keymap)))
+     (define-key map [remap kill-line] 'kill-visual-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)
+     (define-key map "\M-[" 'previous-logical-line)
+     (define-key map "\M-]" 'next-logical-line)
+     map))
+ 
+ (define-minor-mode visual-line-mode
+   "Define key binding for visual line moves."
+   :keymap visual-line-mode-map
+   :group 'convenience
+   (if visual-line-mode
+       (progn
+ 	(setq line-move-visual t
+ 	      word-wrap t))
+     (kill-local-variable 'line-move-visual)
+     (kill-local-variable 'word-wrap)))
+ 
+ (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")
+ \f
  (defun scroll-other-window-down (lines)
    "Scroll the \"other window\" down.
  For more details, see the documentation for `scroll-other-window'."




  reply	other threads:[~2008-07-16 18:26 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-16 13:31 line-line-move-visual: was line motion problem T. V. Raman
2008-07-16 16:26 ` Stefan Monnier
2008-07-16 16:37   ` David Reitter
2008-07-16 16:47     ` Chong Yidong
2008-07-16 18:26       ` Chong Yidong [this message]
2008-07-17 23:44         ` Chong Yidong
2008-07-18  4:35           ` Miles Bader
2008-07-18 14:16             ` Stefan Monnier
2008-07-18 14:24               ` David Reitter
2008-07-18 15:21                 ` Stefan Monnier
2008-07-18 15:30                   ` Dan Nicolaescu
2008-07-18 15:50                     ` Stefan Monnier
2008-07-19  0:10                     ` Miles Bader
2008-07-21 15:49                     ` David Reitter
2008-07-21 16:01                       ` Chong Yidong
2008-07-21 17:31                         ` Miles Bader
2008-07-21 19:24                           ` Stefan Monnier
2008-07-21 20:18                             ` Miles Bader
2008-07-21 17:36                         ` David Reitter
2008-07-21 16:09                       ` Dan Nicolaescu
2008-07-21 17:30                         ` David Reitter
2008-07-21 17:33                         ` David Reitter
2008-07-21 23:05                       ` Vinicius Jose Latorre
2008-07-22  1:31                         ` Chong Yidong
2008-07-22  1:58                           ` Vinicius Jose Latorre
2008-07-22  2:20                             ` David Reitter
2008-07-23  1:53                               ` Vinicius Jose Latorre
2008-07-23  2:53                                 ` David Reitter
2008-07-23  3:19                                   ` Vinicius Jose Latorre
2008-07-23 10:58                                     ` David Reitter
2008-07-24  3:37                                       ` Vinicius Jose Latorre
     [not found]                                         ` <9B9CE742-E040-4484-9BDC-593DE5B6B037@gmail.com>
2008-07-26  0:15                                           ` Vinicius Jose Latorre
2008-07-26  0:32                                             ` Drew Adams
2008-07-26  2:11                                               ` Vinicius Jose Latorre
2008-07-26  2:39                                                 ` Drew Adams
2008-07-26 13:46                                                   ` Vinicius Jose Latorre
2008-07-26 10:44                                             ` David Reitter
2008-07-26 12:59                                               ` Vinicius Jose Latorre
2008-07-25 13:41                     ` T. V. Raman
2008-07-18 21:07                   ` David Reitter
2008-07-18 22:57                     ` Jason Rumney
2008-07-18 16:08             ` Chong Yidong
2008-07-18 18:36               ` Stefan Monnier
2008-07-20  3:34                 ` Chong Yidong
2008-07-20  3:43                 ` Chong Yidong
2008-07-20  4:15                   ` Miles Bader
2008-07-21  4:09                     ` Chong Yidong
2008-07-28 13:45           ` Juri Linkov
2008-07-28 14:11             ` Miles Bader
2008-07-28 14:35               ` Juri Linkov
2008-07-28 14:12             ` Chong Yidong
2008-07-25 13:39     ` T. V. Raman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87hcap3ct7.fsf@stupidchicken.com \
    --to=cyd@stupidchicken.com \
    --cc=david.reitter@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=raman@users.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.