;;; adaptive-wrap.el --- Smart line-wrapping with wrap-prefix
-;; Copyright (C) 2011 Stefan Monnier
+;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
;; Author: Stephen Berman <stephen.berman@gmx.net>
;; Stefan Monnier <monnier@iro.umontreal.ca>
-;; Version: 0.1
+;; Version: 0.5
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;;; Code:
+(require 'easymenu)
+
+(defcustom adaptive-wrap-extra-indent 0
+ "Number of extra spaces to indent in `adaptive-wrap-prefix-mode'.
+
+`adaptive-wrap-prefix-mode' indents the visual lines to
+the level of the actual line plus `adaptive-wrap-extra-indent'.
+A negative value will do a relative de-indent.
+
+Examples:
+
+actual indent = 2
+extra indent = -1
+
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris
+ nisi ut aliquip ex ea commodo consequat.
+
+actual indent = 2
+extra indent = 2
+
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris
+ nisi ut aliquip ex ea commodo consequat."
+ :type 'integer
+ :group 'visual-line)
+(make-variable-buffer-local 'adaptive-wrap-extra-indent)
+
+(defun adaptive-wrap-fill-context-prefix (beg en)
+ "Like `fill-context-prefix', but with length adjusted by `adaptive-wrap-extra-indent'."
+ ;; Note: fill-context-prefix may return nil; See:
+ ;; http://article.gmane.org/gmane.emacs.devel/156285
+ (let* ((fcp (or (fill-context-prefix beg en) ""))
+ (fcp-len (string-width fcp))
+ (fill-char (if (< 0 fcp-len)
+ (string-to-char (substring fcp -1))
+ ?\ )))
+ (cond
+ ((= 0 adaptive-wrap-extra-indent)
+ fcp)
+ ((< 0 adaptive-wrap-extra-indent)
+ (concat fcp
+ (make-string adaptive-wrap-extra-indent fill-char)))
+ ((< 0 (+ adaptive-wrap-extra-indent fcp-len))
+ (substring fcp
+ 0
+ (+ adaptive-wrap-extra-indent fcp-len)))
+ (t
+ ""))))
+
(defun adaptive-wrap-prefix-function (beg end)
"Indent the region between BEG and END with adaptive filling."
(goto-char beg)
(while (< (point) end)
- (let ((blp (line-beginning-position)))
+ (let ((lbp (line-beginning-position)))
(put-text-property (point)
(progn (search-forward "\n" end 'move) (point))
'wrap-prefix
- (fill-context-prefix blp (point))))))
+ (adaptive-wrap-fill-context-prefix lbp (point))))))
;;;###autoload
(define-minor-mode adaptive-wrap-prefix-mode
"Wrap the buffer text with adaptive filling."
:lighter ""
+ :group 'visual-line
(if adaptive-wrap-prefix-mode
- (jit-lock-register #'adaptive-wrap-prefix-function)
+ (progn
+ ;; HACK ATTACK! We need to run after font-lock, but jit-lock-register
+ ;; doesn't accept an `append' argument, so we add ourselves beforehand,
+ ;; to make sure we're at the end of the hook (bug#15155).
+ (add-hook 'jit-lock-functions
+ #'adaptive-wrap-prefix-function 'append t)
+ (jit-lock-register #'adaptive-wrap-prefix-function))
(jit-lock-unregister #'adaptive-wrap-prefix-function)
(with-silent-modifications
(save-restriction
(widen)
(remove-text-properties (point-min) (point-max) '(wrap-prefix nil))))))
+(define-key-after (lookup-key menu-bar-options-menu [line-wrapping])
+ [adaptive-wrap]
+ '(menu-item "Adaptive Wrap" adaptive-wrap-prefix-mode
+ :visible (menu-bar-menu-frame-live-and-visible-p)
+ :help "Show wrapped long lines with an adjustable prefix"
+ :button (:toggle . (bound-and-true-p adaptive-wrap-prefix-mode)))
+ word-wrap)
(provide 'adaptive-wrap)
;;; adaptive-wrap.el ends here