|
@@ -692,13 +692,31 @@ around it."
|
|
|
(unless (local-variable-p 'org-colview-initial-truncate-line-value)
|
|
|
(org-set-local 'org-colview-initial-truncate-line-value
|
|
|
truncate-lines))
|
|
|
- (setq truncate-lines t)
|
|
|
+ (setq truncate-lines t)
|
|
|
(mapc (lambda (x)
|
|
|
(goto-line (car x))
|
|
|
(org-columns-display-here (cdr x)))
|
|
|
cache)))))
|
|
|
|
|
|
-(defun org-columns-new (&optional prop title width op fmt &rest rest)
|
|
|
+(defvar org-columns-compile-map
|
|
|
+ '(("none" none +)
|
|
|
+ (":" add_times +)
|
|
|
+ ("+" add_numbers +)
|
|
|
+ ("$" currency +)
|
|
|
+ ("X" checkbox +)
|
|
|
+ ("X/" checkbox-n-of-m +)
|
|
|
+ ("X%" checkbox-percent +)
|
|
|
+ ("max" max_numbers max)
|
|
|
+ ("min" min_numbers min)
|
|
|
+ ("mean" mean_numbers (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
|
|
|
+ (":max" max_times max)
|
|
|
+ (":min" min_times min)
|
|
|
+ (":mean" mean_times (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
|
|
|
+ "Operator <-> format,fuction map.
|
|
|
+Used to compile/uncompile columns format and completing read in
|
|
|
+interactive function org-columns-new.")
|
|
|
+
|
|
|
+(defun org-columns-new (&optional prop title width op fmt fun &rest rest)
|
|
|
"Insert a new column, to the left of the current column."
|
|
|
(interactive)
|
|
|
(let ((editp (and prop (assoc prop org-columns-current-fmt-compiled)))
|
|
@@ -712,19 +730,18 @@ around it."
|
|
|
(setq width (string-to-number width))
|
|
|
(setq width nil))
|
|
|
(setq fmt (org-ido-completing-read "Summary [none]: "
|
|
|
- '(("none") ("add_numbers") ("currency") ("add_times") ("checkbox") ("checkbox-n-of-m") ("checkbox-percent"))
|
|
|
- nil t))
|
|
|
- (if (string-match "\\S-" fmt)
|
|
|
- (setq fmt (intern fmt))
|
|
|
- (setq fmt nil))
|
|
|
+ (mapcar (lambda (x) (list (symbol-name (cadr x)))) org-columns-compile-map)
|
|
|
+ nil t))
|
|
|
+ (setq fmt (intern fmt)
|
|
|
+ fun (cadr (assoc fmt (mapcar 'cdr org-columns-compile-map))))
|
|
|
(if (eq fmt 'none) (setq fmt nil))
|
|
|
(if editp
|
|
|
(progn
|
|
|
(setcar editp prop)
|
|
|
- (setcdr editp (list title width nil fmt)))
|
|
|
+ (setcdr editp (list title width nil fmt nil fun)))
|
|
|
(setq cell (nthcdr (1- (current-column))
|
|
|
org-columns-current-fmt-compiled))
|
|
|
- (setcdr cell (cons (list prop title width nil fmt)
|
|
|
+ (setcdr cell (cons (list prop title width nil fmt nil fun)
|
|
|
(cdr cell))))
|
|
|
(org-columns-store-format)
|
|
|
(org-columns-redo)))
|
|
@@ -869,12 +886,13 @@ Don't set this, this is meant for dynamic scoping.")
|
|
|
(interactive)
|
|
|
(let* ((re (concat "^" outline-regexp))
|
|
|
(lmax 30) ; Does anyone use deeper levels???
|
|
|
- (lsum (make-vector lmax 0))
|
|
|
+ (lvals (make-vector lmax nil))
|
|
|
(lflag (make-vector lmax nil))
|
|
|
(level 0)
|
|
|
(ass (assoc property org-columns-current-fmt-compiled))
|
|
|
(format (nth 4 ass))
|
|
|
(printf (nth 5 ass))
|
|
|
+ (fun (nth 6 ass))
|
|
|
(beg org-columns-top-level-marker)
|
|
|
last-level val valflag flag end sumpos sum-alist sum str str1 useval)
|
|
|
(save-excursion
|
|
@@ -892,7 +910,7 @@ Don't set this, this is meant for dynamic scoping.")
|
|
|
(cond
|
|
|
((< level last-level)
|
|
|
;; put the sum of lower levels here as a property
|
|
|
- (setq sum (aref lsum last-level) ; current sum
|
|
|
+ (setq sum (apply fun (aref lvals last-level))
|
|
|
flag (aref lflag last-level) ; any valid entries from children?
|
|
|
str (org-columns-number-to-string sum format printf)
|
|
|
str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
|
|
@@ -908,18 +926,18 @@ Don't set this, this is meant for dynamic scoping.")
|
|
|
(org-entry-put nil property (if flag str val)))
|
|
|
;; add current to current level accumulator
|
|
|
(when (or flag valflag)
|
|
|
- (aset lsum level (+ (aref lsum level)
|
|
|
- (if flag sum (org-column-string-to-number
|
|
|
- (if flag str val) format))))
|
|
|
+ (push (if flag sum
|
|
|
+ (org-column-string-to-number (if flag str val) format))
|
|
|
+ (aref lvals level))
|
|
|
(aset lflag level t))
|
|
|
;; clear accumulators for deeper levels
|
|
|
(loop for l from (1+ level) to (1- lmax) do
|
|
|
- (aset lsum l 0)
|
|
|
+ (aset lvals l nil)
|
|
|
(aset lflag l nil)))
|
|
|
((>= level last-level)
|
|
|
;; add what we have here to the accumulator for this level
|
|
|
- (aset lsum level (+ (aref lsum level)
|
|
|
- (org-column-string-to-number (or val "0") format)))
|
|
|
+ (push (org-column-string-to-number (or val "0") format)
|
|
|
+ (aref lvals level))
|
|
|
(and valflag (aset lflag level t)))
|
|
|
(t (error "This should not happen")))))))
|
|
|
|
|
@@ -958,7 +976,7 @@ Don't set this, this is meant for dynamic scoping.")
|
|
|
(defun org-columns-number-to-string (n fmt &optional printf)
|
|
|
"Convert a computed column number to a string value, according to FMT."
|
|
|
(cond
|
|
|
- ((eq fmt 'add_times)
|
|
|
+ ((memq fmt '(add_times max_times min_times mean_times))
|
|
|
(let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
|
|
|
(format org-time-clocksum-format h m)))
|
|
|
((eq fmt 'checkbox)
|
|
@@ -992,21 +1010,17 @@ Don't set this, this is meant for dynamic scoping.")
|
|
|
|
|
|
(defun org-columns-uncompile-format (cfmt)
|
|
|
"Turn the compiled columns format back into a string representation."
|
|
|
- (let ((rtn "") e s prop title op width fmt printf)
|
|
|
+ (let ((rtn "") e s prop title op op-match width fmt printf)
|
|
|
(while (setq e (pop cfmt))
|
|
|
(setq prop (car e)
|
|
|
title (nth 1 e)
|
|
|
width (nth 2 e)
|
|
|
op (nth 3 e)
|
|
|
fmt (nth 4 e)
|
|
|
- printf (nth 5 e))
|
|
|
- (cond
|
|
|
- ((eq fmt 'add_times) (setq op ":"))
|
|
|
- ((eq fmt 'checkbox) (setq op "X"))
|
|
|
- ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
|
|
|
- ((eq fmt 'checkbox-percent) (setq op "X%"))
|
|
|
- ((eq fmt 'add_numbers) (setq op "+"))
|
|
|
- ((eq fmt 'currency) (setq op "$")))
|
|
|
+ printf (nth 5 e)
|
|
|
+ fun (nth 6 e))
|
|
|
+ (when (setq op-match (rassoc (list fmt fun) org-columns-compile-map))
|
|
|
+ (setq op (car op-match)))
|
|
|
(if (and op printf) (setq op (concat op ";" printf)))
|
|
|
(if (equal title prop) (setq title nil))
|
|
|
(setq s (concat "%" (if width (number-to-string width))
|
|
@@ -1025,8 +1039,9 @@ title the title field for the columns
|
|
|
width the column width in characters, can be nil for automatic
|
|
|
operator the operator if any
|
|
|
format the output format for computed results, derived from operator
|
|
|
-printf a printf format for computed values"
|
|
|
- (let ((start 0) width prop title op f printf)
|
|
|
+printf a printf format for computed values
|
|
|
+fun the lisp function to compute values, derived from operator"
|
|
|
+ (let ((start 0) width prop title op op-match f printf fun)
|
|
|
(setq org-columns-current-fmt-compiled nil)
|
|
|
(while (string-match
|
|
|
(org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
|
|
@@ -1037,20 +1052,16 @@ printf a printf format for computed values"
|
|
|
title (or (match-string 3 fmt) prop)
|
|
|
op (match-string 4 fmt)
|
|
|
f nil
|
|
|
- printf nil)
|
|
|
+ printf nil
|
|
|
+ fun '+)
|
|
|
(if width (setq width (string-to-number width)))
|
|
|
(when (and op (string-match ";" op))
|
|
|
(setq printf (substring op (match-end 0))
|
|
|
op (substring op 0 (match-beginning 0))))
|
|
|
- (cond
|
|
|
- ((equal op "+") (setq f 'add_numbers))
|
|
|
- ((equal op "$") (setq f 'currency))
|
|
|
- ((equal op ":") (setq f 'add_times))
|
|
|
- ((equal op "X") (setq f 'checkbox))
|
|
|
- ((equal op "X/") (setq f 'checkbox-n-of-m))
|
|
|
- ((equal op "X%") (setq f 'checkbox-percent))
|
|
|
- )
|
|
|
- (push (list prop title width op f printf) org-columns-current-fmt-compiled))
|
|
|
+ (when (setq op-match (assoc op org-columns-compile-map))
|
|
|
+ (setq f (cadr op-match)
|
|
|
+ fun (caddr op-match)))
|
|
|
+ (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
|
|
|
(setq org-columns-current-fmt-compiled
|
|
|
(nreverse org-columns-current-fmt-compiled))))
|
|
|
|