Browse Source

org-colview: Properly apply operator format strings on leaf nodes

* lisp/org-colview.el (org-columns--displayed-value): When value is
a number and a format string is specified, apply it.
* testing/lisp/test-org-colview.el (test-org-colview/columns-summary):
  Add tests.

Reported-by: Hendrik Tews <hendrik@askra.de>
<http://permalink.gmane.org/gmane.emacs.orgmode/113547>
Nicolas Goaziou 3 years ago
parent
commit
ec5df01bd8
2 changed files with 44 additions and 12 deletions
  1. 23 12
      lisp/org-colview.el
  2. 21 0
      testing/lisp/test-org-colview.el

+ 23 - 12
lisp/org-colview.el

@@ -223,21 +223,32 @@ See `org-columns-summary-types' for details.")
 
 (defun org-columns--displayed-value (spec value)
   "Return displayed value for specification SPEC in current entry.
-
 SPEC is a column format specification as stored in
 `org-columns-current-fmt-compiled'.  VALUE is the real value to
 display, as a string."
-  (cond
-   ((and (functionp org-columns-modify-value-for-display-function)
-	 (funcall org-columns-modify-value-for-display-function
-		  (nth 1 spec)
-		  value)))
-   ((equal (car spec) "ITEM")
-    (concat (make-string (1- (org-current-level))
-			 (if org-hide-leading-stars ?\s ?*))
-	    "* "
-	    (org-columns-compact-links value)))
-   (value)))
+  (or (and (functionp org-columns-modify-value-for-display-function)
+	   (funcall org-columns-modify-value-for-display-function
+		    (nth 1 spec)	;column name
+		    value))
+      (pcase spec
+	(`("ITEM" . ,_)
+	 (concat (make-string (1- (org-current-level))
+			      (if org-hide-leading-stars ?\s ?*))
+		 "* "
+		 (org-columns-compact-links value)))
+	(`(,_ ,_ ,_ ,_ nil) value)
+	;; If PRINTF is set, and we are displaying a number, obey to
+	;; it.  Otherwise, raise an error.
+	(`(,_ ,name ,_ ,_ ,printf)
+	 (when (or (not (string-match-p "[0-9]" value))
+		   (and (string-match-p "[1-9]" value)
+			(= 0 (string-to-number value))))
+	   (user-error "Invalid value: %S.  \
+Format string in operator implies column %S only contains numbers"
+		       value
+		       name))
+	 (format printf (string-to-number value)))
+	(_ (error "Invalid column specification format: %S" spec)))))
 
 (defun org-columns--collect-values (&optional compiled-fmt)
   "Collect values for columns on the current line.

+ 21 - 0
testing/lisp/test-org-colview.el

@@ -212,6 +212,27 @@
 :END:"
       (let ((org-columns-default-format "%A{$}")) (org-columns))
       (get-char-property (point) 'org-columns-value-modified))))
+  ;; Obey to format string even in leaf values.
+  (should
+   (equal
+    "1.0"
+    (org-test-with-temp-text
+	"* H
+:PROPERTIES:
+:A: 1
+:END:"
+      (let ((org-columns-default-format "%A{+;%.1f}")) (org-columns))
+      (get-char-property (point) 'org-columns-value-modified))))
+  ;; Raise an error when format strings are applied to non-numbers.
+  (should-error
+   (org-test-with-temp-text
+       "* H
+** S1
+:PROPERTIES:
+:A: foo
+:END:"
+     (let ((org-columns-default-format "%A{+;%.2f}")) (org-columns))
+     (get-char-property (point) 'org-columns-value-modified)))
   ;; {:} sums times.  Plain numbers are hours.
   (should
    (equal