Browse Source

Merge branch 'fix-indent' into maint

Nicolas Goaziou 9 years ago
parent
commit
1272458926
1 changed files with 47 additions and 81 deletions
  1. 47 81
      lisp/org-indent.el

+ 47 - 81
lisp/org-indent.el

@@ -52,20 +52,6 @@
   :tag "Org Indent"
   :tag "Org Indent"
   :group 'org)
   :group 'org)
 
 
-(defconst org-indent-max 40
-  "Maximum indentation in characters.")
-(defconst org-indent-max-levels 20
-  "Maximum added level through virtual indentation, in characters.
-
-It is computed by multiplying `org-indent-indentation-per-level'
-minus one by actual level of the headline minus one.")
-
-(defvar org-indent-strings nil
-  "Vector with all indentation strings.
-It will be set in `org-indent-initialize'.")
-(defvar org-indent-stars nil
-  "Vector with all indentation star strings.
-It will be set in `org-indent-initialize'.")
 (defvar org-indent-inlinetask-first-star (org-add-props "*" '(face org-warning))
 (defvar org-indent-inlinetask-first-star (org-add-props "*" '(face org-warning))
   "First star of inline tasks, with correct face.")
   "First star of inline tasks, with correct face.")
 (defvar org-indent-agent-timer nil
 (defvar org-indent-agent-timer nil
@@ -92,15 +78,12 @@ This is used locally in each buffer being initialized.")
 It is modified by `org-indent-notify-modified-headline'.")
 It is modified by `org-indent-notify-modified-headline'.")
 
 
 
 
-(defcustom org-indent-boundary-char ?\   ; comment to protect space char
+(defcustom org-indent-boundary-char ?\s
   "The end of the virtual indentation strings, a single-character string.
   "The end of the virtual indentation strings, a single-character string.
 The default is just a space, but if you wish, you can use \"|\" or so.
 The default is just a space, but if you wish, you can use \"|\" or so.
 This can be useful on a terminal window - under a windowing system,
 This can be useful on a terminal window - under a windowing system,
-it may be prettier to customize the org-indent face."
+it may be prettier to customize the `org-indent' face."
   :group 'org-indent
   :group 'org-indent
-  :set (lambda (var val)
-	 (set var val)
-	 (and org-indent-strings (org-indent-initialize)))
   :type 'character)
   :type 'character)
 
 
 (defcustom org-indent-mode-turns-off-org-adapt-indentation t
 (defcustom org-indent-mode-turns-off-org-adapt-indentation t
@@ -121,30 +104,12 @@ turn on `org-hide-leading-stars'."
   :group 'org-indent
   :group 'org-indent
   :type 'integer)
   :type 'integer)
 
 
-(defface org-indent
-  (org-compatible-face nil nil)
+(defface org-indent '((t (:inherit org-hide)))
   "Face for outline indentation.
   "Face for outline indentation.
 The default is to make it look like whitespace.  But you may find it
 The default is to make it look like whitespace.  But you may find it
 useful to make it ever so slightly different."
 useful to make it ever so slightly different."
   :group 'org-faces)
   :group 'org-faces)
 
 
-(defun org-indent-initialize ()
-  "Initialize the indentation strings."
-  (setq org-indent-strings (make-vector (1+ org-indent-max) nil))
-  (setq org-indent-stars (make-vector (1+ org-indent-max) nil))
-  (aset org-indent-strings 0 nil)
-  (aset org-indent-stars 0 nil)
-  (loop for i from 1 to org-indent-max do
-	(aset org-indent-strings i
-	      (org-add-props
-		  (concat (make-string (1- i) ?\ )
-			  (char-to-string org-indent-boundary-char))
-		  nil 'face 'org-indent)))
-  (loop for i from 1 to org-indent-max-levels do
-	(aset org-indent-stars i
-	      (org-add-props (make-string i ?*)
-		  nil 'face 'org-hide))))
-
 (defsubst org-indent-remove-properties (beg end)
 (defsubst org-indent-remove-properties (beg end)
   "Remove indentations between BEG and END."
   "Remove indentations between BEG and END."
   (org-with-silent-modifications
   (org-with-silent-modifications
@@ -174,7 +139,6 @@ during idle time."
    (org-indent-mode
    (org-indent-mode
     ;; mode was turned on.
     ;; mode was turned on.
     (org-set-local 'indent-tabs-mode nil)
     (org-set-local 'indent-tabs-mode nil)
-    (or org-indent-strings (org-indent-initialize))
     (org-set-local 'org-indent-initial-marker (copy-marker 1))
     (org-set-local 'org-indent-initial-marker (copy-marker 1))
     (when org-indent-mode-turns-off-org-adapt-indentation
     (when org-indent-mode-turns-off-org-adapt-indentation
       (org-set-local 'org-adapt-indentation nil))
       (org-set-local 'org-adapt-indentation nil))
@@ -281,34 +245,40 @@ a time value."
 	   (setq org-indent-agentized-buffers
 	   (setq org-indent-agentized-buffers
 		 (delq buffer org-indent-agentized-buffers))))))))
 		 (delq buffer org-indent-agentized-buffers))))))))
 
 
-(defsubst org-indent-set-line-properties (l w h)
+(defun org-indent-set-line-properties (level indentation &optional heading)
   "Set prefix properties on current line an move to next one.
   "Set prefix properties on current line an move to next one.
 
 
-Prefix properties `line-prefix' and `wrap-prefix' in current line
-are set to, respectively, length L and W.
-
-If H is non-nil, `line-prefix' will be starred.  If H is
-`inline', the first star will have `org-warning' face.
-
-Assume point is at beginning of line."
-  (let ((line (cond
-	       ((eq 'inline h)
-		(let ((stars (aref org-indent-stars
-				   (min l org-indent-max-levels))))
-		  (and stars
-		       (if (org-bound-and-true-p org-inlinetask-show-first-star)
-			   (concat org-indent-inlinetask-first-star
-				   (substring stars 1))
-			 stars))))
-	       (h (aref org-indent-stars
-			(min l org-indent-max-levels)))
-	       (t (aref org-indent-strings
-			(min l org-indent-max)))))
-	(wrap (aref org-indent-strings (min w org-indent-max))))
+LEVEL is the current level of heading.  INDENTATION is the
+expected indentation when wrapping line.
+
+When optional argument HEADING is non-nil, assume line is at
+a heading.  Moreover, if is is `inlinetask', the first star will
+have `org-warning' face."
+  (let* ((stars (if (<= level 1) ""
+		  (make-string (* org-indent-indentation-per-level
+				  (1- level))
+			       ?*)))
+	 (line
+	  (cond
+	   ((and (org-bound-and-true-p org-inlinetask-show-first-star)
+		 (eq heading 'inlinetask))
+	    (concat org-indent-inlinetask-first-star
+		    (org-add-props (substring stars 1) nil 'face 'org-hide)))
+	   (heading (org-add-props stars nil 'face 'org-hide))
+	   (t (concat (org-add-props (concat stars (make-string level ?*))
+			  nil 'face 'org-indent)
+		      (char-to-string org-indent-boundary-char)))))
+	 (wrap
+	  (org-add-props
+	      (concat stars
+		      (make-string level ?*)
+		      (if heading " "
+			(make-string (+ indentation (min level 1)) ?\s)))
+	      nil 'face 'org-indent)))
     ;; Add properties down to the next line to indent empty lines.
     ;; Add properties down to the next line to indent empty lines.
-    (add-text-properties (point) (min (1+ (point-at-eol)) (point-max))
+    (add-text-properties (line-beginning-position) (line-beginning-position 2)
 			 `(line-prefix ,line wrap-prefix ,wrap)))
 			 `(line-prefix ,line wrap-prefix ,wrap)))
-  (forward-line 1))
+  (forward-line))
 
 
 (defun org-indent-add-properties (beg end &optional delay)
 (defun org-indent-add-properties (beg end &optional delay)
   "Add indentation properties between BEG and END.
   "Add indentation properties between BEG and END.
@@ -328,12 +298,10 @@ stopped."
      ;;    inline task or not.
      ;;    inline task or not.
      (let* ((case-fold-search t)
      (let* ((case-fold-search t)
 	    (limited-re (org-get-limited-outline-regexp))
 	    (limited-re (org-get-limited-outline-regexp))
-	    (added-ind-per-lvl (abs (1- org-indent-indentation-per-level)))
 	    (pf (save-excursion
 	    (pf (save-excursion
 		  (and (ignore-errors (let ((outline-regexp limited-re))
 		  (and (ignore-errors (let ((outline-regexp limited-re))
 					(org-back-to-heading t)))
 					(org-back-to-heading t)))
-		       (+ (* org-indent-indentation-per-level
-			     (- (match-end 0) (match-beginning 0) 2)) 2))))
+		       (- (match-end 0) (match-beginning 0) 1))))
 	    (pf-inline (and (featurep 'org-inlinetask)
 	    (pf-inline (and (featurep 'org-inlinetask)
 			    (org-inlinetask-in-task-p)
 			    (org-inlinetask-in-task-p)
 			    (+ (* org-indent-indentation-per-level
 			    (+ (* org-indent-indentation-per-level
@@ -354,38 +322,36 @@ stopped."
 	   ((and delay (time-less-p time-limit (current-time)))
 	   ((and delay (time-less-p time-limit (current-time)))
 	    (setq org-indent-agent-resume-timer
 	    (setq org-indent-agent-resume-timer
 		  (run-with-idle-timer
 		  (run-with-idle-timer
-		   (time-add (current-idle-time)
-			     org-indent-agent-resume-delay)
+		   (time-add (current-idle-time) org-indent-agent-resume-delay)
 		   nil #'org-indent-initialize-agent))
 		   nil #'org-indent-initialize-agent))
 	    (throw 'interrupt (point)))
 	    (throw 'interrupt (point)))
 	   ;; Headline or inline task.
 	   ;; Headline or inline task.
 	   ((looking-at org-outline-regexp)
 	   ((looking-at org-outline-regexp)
-	    (let* ((nstars (- (match-end 0) (match-beginning 0) 1))
-		   (line (* added-ind-per-lvl (1- nstars)))
-		   (wrap (+ line (1+ nstars))))
+	    (let* ((nstars (- (match-end 0) (match-beginning 0) 1)))
 	      (cond
 	      (cond
 	       ;; Headline: new value for PF.
 	       ;; Headline: new value for PF.
 	       ((looking-at limited-re)
 	       ((looking-at limited-re)
-		(org-indent-set-line-properties line wrap t)
-		(setq pf wrap))
+		(org-indent-set-line-properties nstars 0 t)
+		(setq pf nstars))
 	       ;; End of inline task: PF-INLINE is now nil.
 	       ;; End of inline task: PF-INLINE is now nil.
 	       ((looking-at "\\*+ end[ \t]*$")
 	       ((looking-at "\\*+ end[ \t]*$")
-		(org-indent-set-line-properties line wrap 'inline)
+		(org-indent-set-line-properties nstars 0 'inlinetask)
 		(setq pf-inline nil))
 		(setq pf-inline nil))
 	       ;; Start of inline task.  Determine if it contains
 	       ;; Start of inline task.  Determine if it contains
 	       ;; text, or if it is only one line long.  Set
 	       ;; text, or if it is only one line long.  Set
 	       ;; PF-INLINE accordingly.
 	       ;; PF-INLINE accordingly.
-	       (t (org-indent-set-line-properties line wrap 'inline)
-		  (setq pf-inline (and (org-inlinetask-in-task-p) wrap))))))
+	       (t (org-indent-set-line-properties nstars 0 'inlinetask)
+		  (setq pf-inline (and (org-inlinetask-in-task-p) nstars))))))
 	   ;; List item: `wrap-prefix' is set where body starts.
 	   ;; List item: `wrap-prefix' is set where body starts.
 	   ((org-at-item-p)
 	   ((org-at-item-p)
 	    (let* ((line (or pf-inline pf 0))
 	    (let* ((line (or pf-inline pf 0))
-		   (wrap (+ (org-list-item-body-column (point)) line)))
-	      (org-indent-set-line-properties line wrap nil)))
+		   (wrap (org-list-item-body-column (point))))
+	      (org-indent-set-line-properties
+	       (or pf-inline pf 0)
+	       (org-list-item-body-column (point)))))
 	   ;; Normal line: use PF-INLINE, PF or nil as prefixes.
 	   ;; Normal line: use PF-INLINE, PF or nil as prefixes.
-	   (t (let* ((line (or pf-inline pf 0))
-		     (wrap (+ line (org-get-indentation))))
-		(org-indent-set-line-properties line wrap nil))))))))))
+	   (t (org-indent-set-line-properties
+	       (or pf-inline pf 0) (org-get-indentation))))))))))
 
 
 (defun org-indent-notify-modified-headline (beg end)
 (defun org-indent-notify-modified-headline (beg end)
   "Set `org-indent-modified-headline-flag' depending on context.
   "Set `org-indent-modified-headline-flag' depending on context.