+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 `next-line', except that it always moves
+by logical lines instead of visual lines, ignoring the value of
+the variable `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
+the variable `line-move-visual'."
+ (interactive "^p\np")
+ (let ((line-move-visual nil))
+ (with-no-warnings
+ (previous-line arg try-vscroll))))
+
+(defgroup visual-line nil
+ "Editing based on visual lines."
+ :group 'convenience
+ :version "23.1")
+
+(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)
+ ;; These keybindings interfere with xterm function keys. Are
+ ;; there any other suitable bindings?
+ ;; (define-key map "\M-[" 'previous-logical-line)
+ ;; (define-key map "\M-]" 'next-logical-line)
+ map))
+
+(defcustom visual-line-fringe-indicators '(nil nil)
+ "How fringe indicators are shown for wrapped lines in `visual-line-mode'.
+The value should be a list of the form (LEFT RIGHT), where LEFT
+and RIGHT are symbols representing the bitmaps to display, to
+indicate wrapped lines, in the left and right fringes respectively.
+See also `fringe-indicator-alist'.
+The default is not to display fringe indicators for wrapped lines.
+This variable does not affect fringe indicators displayed for
+other purposes."
+ :type '(list (choice (const :tag "Hide left indicator" nil)
+ (const :tag "Left curly arrow" left-curly-arrow)
+ (symbol :tag "Other bitmap"))
+ (choice (const :tag "Hide right indicator" nil)
+ (const :tag "Right curly arrow" right-curly-arrow)
+ (symbol :tag "Other bitmap")))
+ :set (lambda (symbol value)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (and (boundp 'visual-line-mode)
+ (symbol-value 'visual-line-mode))
+ (setq fringe-indicator-alist
+ (cons (cons 'continuation value)
+ (assq-delete-all
+ 'continuation
+ (copy-tree fringe-indicator-alist)))))))
+ (set-default symbol value)))
+
+(defvar visual-line--saved-state nil)
+
+(define-minor-mode visual-line-mode
+ "Redefine simple editing commands to act on visual lines, not logical lines.
+This also turns on `word-wrap' in the buffer."
+ :keymap visual-line-mode-map
+ :group 'visual-line
+ :lighter " wrap"
+ (if visual-line-mode
+ (progn
+ (set (make-local-variable 'visual-line--saved-state) nil)
+ ;; Save the local values of some variables, to be restored if
+ ;; visual-line-mode is turned off.
+ (dolist (var '(line-move-visual truncate-lines
+ truncate-partial-width-windows
+ word-wrap fringe-indicator-alist))
+ (if (local-variable-p var)
+ (push (cons var (symbol-value var))
+ visual-line--saved-state)))
+ (set (make-local-variable 'line-move-visual) t)
+ (set (make-local-variable 'truncate-partial-width-windows) nil)
+ (setq truncate-lines nil
+ word-wrap t
+ fringe-indicator-alist
+ (cons (cons 'continuation visual-line-fringe-indicators)
+ fringe-indicator-alist)))
+ (kill-local-variable 'line-move-visual)
+ (kill-local-variable 'word-wrap)
+ (kill-local-variable 'truncate-lines)
+ (kill-local-variable 'truncate-partial-width-windows)
+ (kill-local-variable 'fringe-indicator-alist)
+ (dolist (saved visual-line--saved-state)
+ (set (make-local-variable (car saved)) (cdr saved)))
+ (kill-local-variable 'visual-line--saved-state)))
+
+(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