Browse Source

Cleaner handling of inline tasks under org-indent-mode

* lisp/org-indent.el (org-indent-inlinetask-first-star): new variable.
(org-indent-add-properties): set the first star of inline-tasks'
virtual indentation in `org-warning' face.
* lisp/org-inlinetask.el (org-inlinetask-insert-task): create a new
  inline-task slightly differently, so virtual indentation can be
  applied normally.
Nicolas Goaziou 9 years ago
parent
commit
0fd4c59367
2 changed files with 37 additions and 19 deletions
  1. 19 9
      lisp/org-indent.el
  2. 18 10
      lisp/org-inlinetask.el

+ 19 - 9
lisp/org-indent.el

@@ -61,8 +61,10 @@ 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))
+  "First star of inline tasks, with correct face.")
 (defvar org-indent-initial-marker nil
-  "Position of initialization process before interrupt.")
+  "Position of initialization before interrupt.")
 (defvar org-indent-initial-timer nil
   "Timer used for initialization.")
 (defvar org-indent-initial-lock nil
@@ -262,13 +264,21 @@ you want to use this feature."
 	     (function
 	      ;; Set prefix properties `line-prefix' and `wrap-prefix'
 	      ;; in current line to, respectively, length L and W and
-	      ;; move forward. If H is non-nil, `line-prefix' will be
-	      ;; starred. Assume point is at bol.
+	      ;; move forward.  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 bol.
 	      (lambda (l w h)
-		(let ((line (if h (aref org-indent-stars
-					(min l org-indent-max-levels))
-			      (aref org-indent-strings
-				    (min l org-indent-max))))
+		(let ((line (cond
+			     ((eq 'inline h)
+			      (let ((stars (aref org-indent-stars
+						 (min l org-indent-max-levels))))
+				(and stars
+				     (concat org-indent-inlinetask-first-star
+					     (substring stars 1)))))
+			     (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))))
 		  (add-text-properties (point) (point-at-eol)
 				       `(line-prefix ,line wrap-prefix ,wrap)))
@@ -294,11 +304,11 @@ you want to use this feature."
 	       (setq pf wrap))
 	      ;; End of inline task: PF-INLINE is now nil.
 	      ((looking-at "\\*+ end[ \t]*$")
-	       (funcall set-prop-and-move line wrap t)
+	       (funcall set-prop-and-move line wrap 'inline)
 	       (setq pf-inline nil))
 	      ;; Start of inline task. Determine if it contains text,
 	      ;; or is only one line long. Set PF-INLINE accordingly.
-	      (t (funcall set-prop-and-move line wrap t)
+	      (t (funcall set-prop-and-move line wrap 'inline)
 		 (setq pf-inline (and (org-inlinetask-in-task-p) wrap))))))
 	  ;; List item: `wrap-prefix' is set where body starts.
 	  ((org-at-item-p)

+ 18 - 10
lisp/org-inlinetask.el

@@ -188,14 +188,15 @@ If prefix arg NO-STATE is set, ignore `org-inlinetask-default-state'."
 	     (not (and (org-inlinetask-at-task-p) (bolp))))
     (error "Cannot nest inline tasks"))
   (or (bolp) (newline))
-  (let ((indent org-inlinetask-min-level))
-    (if org-odd-levels-only
-        (setq indent (- (* 2 indent) 1)))
-    (insert (make-string indent ?*)
-            (if (or no-state (not org-inlinetask-default-state))
-		" \n"
-	      (concat " " org-inlinetask-default-state " \n"))
-            (make-string indent ?*) " END\n"))
+  (let* ((indent (if org-odd-levels-only
+		     (1- (* 2 org-inlinetask-min-level))
+		   org-inlinetask-min-level))
+	 (indent-string (concat (make-string indent ?*) " ")))
+    (insert indent-string
+	    (if (or no-state (not org-inlinetask-default-state))
+		"\n"
+	      (concat org-inlinetask-default-state " \n"))
+	    indent-string "END\n"))
   (end-of-line -1))
 (define-key org-mode-map "\C-c\C-xt" 'org-inlinetask-insert-task)
 
@@ -403,6 +404,7 @@ Either remove headline and meta data, or do special formatting."
     (goto-char (match-end 0))
     (current-column)))
 
+(defvar org-indent-indentation-per-level) ; defined in org-indent.el
 (defun org-inlinetask-fontify (limit)
   "Fontify the inline tasks."
   (let* ((nstars (if org-odd-levels-only
@@ -410,10 +412,16 @@ Either remove headline and meta data, or do special formatting."
 		   (or org-inlinetask-min-level 200)))
 	 (re (concat "^\\(\\*\\)\\(\\*\\{"
 		    (format "%d" (- nstars 3))
-		    ",\\}\\)\\(\\*\\* .*\\)")))
+		    ",\\}\\)\\(\\*\\* .*\\)"))
+	 ;; Virtual indentation will add the warning face on the first
+	 ;; star. Thus, in that case, only hide it.
+	 (start-face (if (and (org-bound-and-true-p org-indent-mode)
+			      (> org-indent-indentation-per-level 1))
+			 'org-hide
+		       'org-warning)))
     (while (re-search-forward re limit t)
       (add-text-properties (match-beginning 1) (match-end 1)
-			   '(face org-warning font-lock-fontified t))
+			   `(face ,start-face font-lock-fontified t))
       (add-text-properties (match-beginning 2) (match-end 2)
 			   '(face org-hide font-lock-fontified t))
       (add-text-properties (match-beginning 3) (match-end 3)