2015-10-26 00:56:00 +00:00
|
|
|
|
;;; org-colview.el --- Column View in Org -*- lexical-binding: t; -*-
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
2016-01-09 22:12:03 +00:00
|
|
|
|
;; Copyright (C) 2004-2016 Free Software Foundation, Inc.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
;; Author: Carsten Dominik <carsten at orgmode dot org>
|
|
|
|
|
;; Keywords: outlines, hypermedia, calendar, wp
|
|
|
|
|
;; Homepage: http://orgmode.org
|
|
|
|
|
;;
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
;;
|
2008-05-06 12:45:52 +00:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
2008-04-09 13:42:36 +00:00
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
2008-05-06 12:45:52 +00:00
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2008-05-06 12:45:52 +00:00
|
|
|
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
2008-12-17 08:08:06 +00:00
|
|
|
|
;; This file contains the column view for Org.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2016-02-13 09:12:57 +00:00
|
|
|
|
(require 'cl-lib)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(require 'org)
|
|
|
|
|
|
2008-05-30 07:30:43 +00:00
|
|
|
|
(declare-function org-agenda-redo "org-agenda" ())
|
2009-11-13 22:22:18 +00:00
|
|
|
|
(declare-function org-agenda-do-context-action "org-agenda" ())
|
2012-08-05 16:59:51 +00:00
|
|
|
|
(declare-function org-clock-sum-today "org-clock" (&optional headline-filter))
|
2016-02-17 22:24:51 +00:00
|
|
|
|
(declare-function org-element-extract-element "org-element" (element))
|
|
|
|
|
(declare-function org-element-interpret-data "org-element" (data))
|
|
|
|
|
(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))
|
|
|
|
|
(declare-function org-element-parse-secondary-string "org-element" (string restriction &optional parent))
|
|
|
|
|
(declare-function org-element-restriction "org-element" (element))
|
2008-05-30 07:30:43 +00:00
|
|
|
|
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(defvar org-agenda-columns-add-appointments-to-effort-sum)
|
|
|
|
|
(defvar org-agenda-columns-compute-summary-properties)
|
|
|
|
|
(defvar org-agenda-columns-show-summaries)
|
|
|
|
|
(defvar org-agenda-view-columns-initially)
|
|
|
|
|
|
2016-02-13 11:21:08 +00:00
|
|
|
|
;;; Configuration
|
|
|
|
|
|
|
|
|
|
(defcustom org-columns-modify-value-for-display-function nil
|
|
|
|
|
"Function that modifies values for display in column view.
|
|
|
|
|
For example, it can be used to cut out a certain part from a time stamp.
|
|
|
|
|
The function must take 2 arguments:
|
|
|
|
|
|
|
|
|
|
column-title The title of the column (*not* the property name)
|
|
|
|
|
value The value that should be modified.
|
|
|
|
|
|
|
|
|
|
The function should return the value that should be displayed,
|
|
|
|
|
or nil if the normal value should be used."
|
|
|
|
|
:group 'org-properties
|
|
|
|
|
:type '(choice (const nil) (function)))
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
;;; Column View
|
|
|
|
|
|
|
|
|
|
(defvar org-columns-overlays nil
|
|
|
|
|
"Holds the list of current column overlays.")
|
|
|
|
|
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(defvar org-columns--time 0.0
|
|
|
|
|
"Number of seconds since the epoch, as a floating point number.")
|
2015-10-26 00:56:00 +00:00
|
|
|
|
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(defvar-local org-columns-current-fmt nil
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Local variable, holds the currently active column format.")
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(defvar-local org-columns-current-fmt-compiled nil
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Local variable, holds the currently active column format.
|
|
|
|
|
This is the compiled version of the format.")
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(defvar-local org-columns-current-maxwidths nil
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Loval variable, holds the currently active maximum column widths.")
|
|
|
|
|
(defvar org-columns-begin-marker (make-marker)
|
|
|
|
|
"Points to the position where last a column creation command was called.")
|
|
|
|
|
(defvar org-columns-top-level-marker (make-marker)
|
|
|
|
|
"Points to the position where current columns region starts.")
|
|
|
|
|
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(defconst org-columns--fractional-duration-re
|
|
|
|
|
(concat "[0-9.]+ *" (regexp-opt (mapcar #'car org-effort-durations)))
|
|
|
|
|
"Regexp matching a duration.")
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defvar org-columns-map (make-sparse-keymap)
|
|
|
|
|
"The keymap valid in column display.")
|
|
|
|
|
|
|
|
|
|
(defun org-columns-content ()
|
|
|
|
|
"Switch to contents view while in columns view."
|
|
|
|
|
(interactive)
|
|
|
|
|
(org-overview)
|
|
|
|
|
(org-content))
|
|
|
|
|
|
|
|
|
|
(org-defkey org-columns-map "c" 'org-columns-content)
|
|
|
|
|
(org-defkey org-columns-map "o" 'org-overview)
|
|
|
|
|
(org-defkey org-columns-map "e" 'org-columns-edit-value)
|
|
|
|
|
(org-defkey org-columns-map "\C-c\C-t" 'org-columns-todo)
|
|
|
|
|
(org-defkey org-columns-map "\C-c\C-c" 'org-columns-set-tags-or-toggle)
|
|
|
|
|
(org-defkey org-columns-map "\C-c\C-o" 'org-columns-open-link)
|
|
|
|
|
(org-defkey org-columns-map "v" 'org-columns-show-value)
|
|
|
|
|
(org-defkey org-columns-map "q" 'org-columns-quit)
|
|
|
|
|
(org-defkey org-columns-map "r" 'org-columns-redo)
|
|
|
|
|
(org-defkey org-columns-map "g" 'org-columns-redo)
|
|
|
|
|
(org-defkey org-columns-map [left] 'backward-char)
|
|
|
|
|
(org-defkey org-columns-map "\M-b" 'backward-char)
|
|
|
|
|
(org-defkey org-columns-map "a" 'org-columns-edit-allowed)
|
|
|
|
|
(org-defkey org-columns-map "s" 'org-columns-edit-attributes)
|
2009-03-05 08:50:38 +00:00
|
|
|
|
(org-defkey org-columns-map "\M-f"
|
|
|
|
|
(lambda () (interactive) (goto-char (1+ (point)))))
|
|
|
|
|
(org-defkey org-columns-map [right]
|
|
|
|
|
(lambda () (interactive) (goto-char (1+ (point)))))
|
|
|
|
|
(org-defkey org-columns-map [down]
|
|
|
|
|
(lambda () (interactive)
|
|
|
|
|
(let ((col (current-column)))
|
2009-03-10 16:45:22 +00:00
|
|
|
|
(beginning-of-line 2)
|
|
|
|
|
(while (and (org-invisible-p2) (not (eobp)))
|
|
|
|
|
(beginning-of-line 2))
|
2009-11-12 08:04:48 +00:00
|
|
|
|
(move-to-column col)
|
2009-11-13 13:48:00 +00:00
|
|
|
|
(if (eq major-mode 'org-agenda-mode)
|
|
|
|
|
(org-agenda-do-context-action)))))
|
2009-03-05 08:50:38 +00:00
|
|
|
|
(org-defkey org-columns-map [up]
|
|
|
|
|
(lambda () (interactive)
|
|
|
|
|
(let ((col (current-column)))
|
2009-03-10 16:45:22 +00:00
|
|
|
|
(beginning-of-line 0)
|
|
|
|
|
(while (and (org-invisible-p2) (not (bobp)))
|
|
|
|
|
(beginning-of-line 0))
|
2009-11-12 08:04:48 +00:00
|
|
|
|
(move-to-column col)
|
2009-11-13 13:48:00 +00:00
|
|
|
|
(if (eq major-mode 'org-agenda-mode)
|
|
|
|
|
(org-agenda-do-context-action)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(org-defkey org-columns-map [(shift right)] 'org-columns-next-allowed-value)
|
|
|
|
|
(org-defkey org-columns-map "n" 'org-columns-next-allowed-value)
|
|
|
|
|
(org-defkey org-columns-map [(shift left)] 'org-columns-previous-allowed-value)
|
|
|
|
|
(org-defkey org-columns-map "p" 'org-columns-previous-allowed-value)
|
|
|
|
|
(org-defkey org-columns-map "<" 'org-columns-narrow)
|
|
|
|
|
(org-defkey org-columns-map ">" 'org-columns-widen)
|
|
|
|
|
(org-defkey org-columns-map [(meta right)] 'org-columns-move-right)
|
|
|
|
|
(org-defkey org-columns-map [(meta left)] 'org-columns-move-left)
|
|
|
|
|
(org-defkey org-columns-map [(shift meta right)] 'org-columns-new)
|
|
|
|
|
(org-defkey org-columns-map [(shift meta left)] 'org-columns-delete)
|
2008-06-09 07:53:19 +00:00
|
|
|
|
(dotimes (i 10)
|
|
|
|
|
(org-defkey org-columns-map (number-to-string i)
|
2009-08-28 12:50:51 +00:00
|
|
|
|
`(lambda () (interactive)
|
|
|
|
|
(org-columns-next-allowed-value nil ,i))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(easy-menu-define org-columns-menu org-columns-map "Org Column Menu"
|
|
|
|
|
'("Column"
|
|
|
|
|
["Edit property" org-columns-edit-value t]
|
|
|
|
|
["Next allowed value" org-columns-next-allowed-value t]
|
|
|
|
|
["Previous allowed value" org-columns-previous-allowed-value t]
|
|
|
|
|
["Show full value" org-columns-show-value t]
|
|
|
|
|
["Edit allowed values" org-columns-edit-allowed t]
|
|
|
|
|
"--"
|
|
|
|
|
["Edit column attributes" org-columns-edit-attributes t]
|
|
|
|
|
["Increase column width" org-columns-widen t]
|
|
|
|
|
["Decrease column width" org-columns-narrow t]
|
|
|
|
|
"--"
|
|
|
|
|
["Move column right" org-columns-move-right t]
|
|
|
|
|
["Move column left" org-columns-move-left t]
|
|
|
|
|
["Add column" org-columns-new t]
|
|
|
|
|
["Delete column" org-columns-delete t]
|
|
|
|
|
"--"
|
|
|
|
|
["CONTENTS" org-columns-content t]
|
|
|
|
|
["OVERVIEW" org-overview t]
|
|
|
|
|
["Refresh columns display" org-columns-redo t]
|
|
|
|
|
"--"
|
|
|
|
|
["Open link" org-columns-open-link t]
|
|
|
|
|
"--"
|
|
|
|
|
["Quit" org-columns-quit t]))
|
|
|
|
|
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(defun org-columns--displayed-value (property value)
|
|
|
|
|
"Return displayed value for PROPERTY in current entry.
|
|
|
|
|
|
|
|
|
|
VALUE is the real value of the property, as a string.
|
|
|
|
|
|
|
|
|
|
This function assumes `org-columns-current-fmt-compiled' is
|
|
|
|
|
initialized."
|
|
|
|
|
(pcase (assoc-string property org-columns-current-fmt-compiled t)
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(`(,_ ,_ ,_ ,_ ,fmt ,printf ,_)
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(cond
|
|
|
|
|
((and (functionp org-columns-modify-value-for-display-function)
|
|
|
|
|
(funcall
|
|
|
|
|
org-columns-modify-value-for-display-function
|
|
|
|
|
(nth 1 (assoc-string property org-columns-current-fmt-compiled t))
|
|
|
|
|
value)))
|
|
|
|
|
((equal (upcase property) "ITEM")
|
|
|
|
|
(concat (make-string (1- (org-current-level))
|
|
|
|
|
(if org-hide-leading-stars ?\s ?*))
|
|
|
|
|
"* "
|
|
|
|
|
(org-columns-compact-links value)))
|
|
|
|
|
(printf (org-columns-number-to-string
|
|
|
|
|
(org-columns-string-to-number value fmt) fmt printf))
|
|
|
|
|
(value)))))
|
|
|
|
|
|
|
|
|
|
(defun org-columns--collect-values (&optional agenda)
|
|
|
|
|
"Collect values for columns on the current line.
|
|
|
|
|
|
|
|
|
|
When optional argument AGENDA is non-nil, assume the value is
|
|
|
|
|
meant for the agenda, i.e., caller is `org-agenda-columns'.
|
|
|
|
|
|
|
|
|
|
Return a list of triplets (PROPERTY VALUE DISPLAYED) suitable for
|
|
|
|
|
`org-columns--display-here'.
|
|
|
|
|
|
|
|
|
|
This function assumes `org-columns-current-fmt-compiled' is
|
|
|
|
|
initialized."
|
|
|
|
|
(mapcar
|
|
|
|
|
(lambda (spec)
|
|
|
|
|
(let* ((p (car spec))
|
|
|
|
|
(v (or (cdr (assoc-string
|
|
|
|
|
p (get-text-property (point) 'org-summaries) t))
|
|
|
|
|
(org-entry-get (point) p 'selective t)
|
|
|
|
|
(and agenda
|
|
|
|
|
;; Effort property is not defined. Try to use
|
|
|
|
|
;; appointment duration.
|
|
|
|
|
org-agenda-columns-add-appointments-to-effort-sum
|
|
|
|
|
(string= (upcase p) (upcase org-effort-property))
|
|
|
|
|
(get-text-property (point) 'duration)
|
|
|
|
|
(org-propertize
|
|
|
|
|
(org-minutes-to-clocksum-string
|
|
|
|
|
(get-text-property (point) 'duration))
|
|
|
|
|
'face 'org-warning))
|
|
|
|
|
"")))
|
|
|
|
|
(list p v (org-columns--displayed-value p v))))
|
|
|
|
|
org-columns-current-fmt-compiled))
|
|
|
|
|
|
|
|
|
|
(defun org-columns--autowidth-alist (cache)
|
|
|
|
|
"Derive the maximum column widths from the format and the cache.
|
|
|
|
|
Return an alist (PROPERTY . WIDTH), with PROPERTY as a string and
|
|
|
|
|
WIDTH as an integer greater than 0."
|
|
|
|
|
(mapcar
|
|
|
|
|
(lambda (spec)
|
|
|
|
|
(pcase spec
|
|
|
|
|
(`(,property ,name ,width . ,_)
|
|
|
|
|
(if width (cons property width)
|
|
|
|
|
;; No width is specified in the columns format. Compute it
|
|
|
|
|
;; by checking all possible values for PROPERTY.
|
|
|
|
|
(let ((width (length name)))
|
|
|
|
|
(dolist (entry cache (cons property width))
|
|
|
|
|
(let ((value (nth 2 (assoc-string property (cdr entry) t))))
|
|
|
|
|
(setq width (max (length value) width)))))))))
|
|
|
|
|
org-columns-current-fmt-compiled))
|
2015-08-11 17:10:09 +00:00
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-new-overlay (beg end &optional string face)
|
|
|
|
|
"Create a new column overlay and add it to the list."
|
2010-04-18 14:37:42 +00:00
|
|
|
|
(let ((ov (make-overlay beg end)))
|
|
|
|
|
(overlay-put ov 'face (or face 'secondary-selection))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(org-overlay-display ov string face)
|
|
|
|
|
(push ov org-columns-overlays)
|
|
|
|
|
ov))
|
|
|
|
|
|
2016-02-17 21:38:39 +00:00
|
|
|
|
(defun org-columns--overlay-text (value fmt width property original)
|
|
|
|
|
"Return text "
|
|
|
|
|
(format fmt
|
|
|
|
|
(let ((v (org-columns-add-ellipses value width)))
|
|
|
|
|
(pcase (upcase property)
|
|
|
|
|
("PRIORITY"
|
|
|
|
|
(propertize v 'face (org-get-priority-face original)))
|
|
|
|
|
("TAGS"
|
|
|
|
|
(if (not org-tags-special-faces-re)
|
|
|
|
|
(propertize v 'face 'org-tag)
|
|
|
|
|
(replace-regexp-in-string
|
|
|
|
|
org-tags-special-faces-re
|
|
|
|
|
(lambda (m) (propertize m 'face (org-get-tag-face m)))
|
|
|
|
|
v nil nil 1)))
|
|
|
|
|
("TODO" (propertize v 'face (org-get-todo-face original)))
|
|
|
|
|
(_ v)))))
|
|
|
|
|
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(defun org-columns--display-here (columns &optional dateline)
|
|
|
|
|
"Overlay the current line with column display.
|
|
|
|
|
COLUMNS is an alist (PROPERTY VALUE DISPLAYED). Optional
|
|
|
|
|
argument DATELINE is non-nil when the face used should be
|
|
|
|
|
`org-agenda-column-dateline'."
|
2015-07-18 07:39:23 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
2016-02-05 23:04:35 +00:00
|
|
|
|
(let* ((level-face (and (looking-at "\\(\\**\\)\\(\\* \\)")
|
2015-07-18 07:39:23 +00:00
|
|
|
|
(org-get-level-face 2)))
|
|
|
|
|
(ref-face (or level-face
|
|
|
|
|
(and (eq major-mode 'org-agenda-mode)
|
|
|
|
|
(org-get-at-bol 'face))
|
|
|
|
|
'default))
|
|
|
|
|
(color (list :foreground (face-attribute ref-face :foreground)))
|
|
|
|
|
(font (list :height (face-attribute 'default :height)
|
|
|
|
|
:family (face-attribute 'default :family)))
|
|
|
|
|
(face (list color font 'org-column ref-face))
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(face1 (list color font 'org-agenda-column-dateline ref-face)))
|
2015-07-18 07:39:23 +00:00
|
|
|
|
;; Each column is an overlay on top of a character. So there has
|
|
|
|
|
;; to be at least as many characters available on the line as
|
|
|
|
|
;; columns to display.
|
|
|
|
|
(let ((columns (length org-columns-current-fmt-compiled))
|
|
|
|
|
(chars (- (line-end-position) (line-beginning-position))))
|
|
|
|
|
(when (> columns chars)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(end-of-line)
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(insert (make-string (- columns chars) ?\s))))))
|
2016-02-14 09:17:14 +00:00
|
|
|
|
;; Display columns. Create and install the overlay for the
|
2015-07-18 07:39:23 +00:00
|
|
|
|
;; current column on the next character.
|
2016-02-17 16:30:32 +00:00
|
|
|
|
(let ((limit (+ (- (length columns) 1) (line-beginning-position))))
|
|
|
|
|
(dolist (column columns)
|
|
|
|
|
(pcase column
|
|
|
|
|
(`(,property ,original ,value)
|
|
|
|
|
(let* ((width
|
|
|
|
|
(cdr
|
|
|
|
|
(assoc-string property org-columns-current-maxwidths t)))
|
|
|
|
|
(fmt (format (if (= (point) limit) "%%-%d.%ds |"
|
|
|
|
|
"%%-%d.%ds | ")
|
|
|
|
|
width width))
|
|
|
|
|
(ov (org-columns-new-overlay
|
2016-02-17 21:38:39 +00:00
|
|
|
|
(point) (1+ (point))
|
|
|
|
|
(org-columns--overlay-text
|
|
|
|
|
value fmt width property original)
|
|
|
|
|
(if dateline face1 face))))
|
2016-02-17 16:30:32 +00:00
|
|
|
|
(overlay-put ov 'keymap org-columns-map)
|
|
|
|
|
(overlay-put ov 'org-columns-key property)
|
|
|
|
|
(overlay-put ov 'org-columns-value original)
|
|
|
|
|
(overlay-put ov 'org-columns-value-modified value)
|
|
|
|
|
(overlay-put ov 'org-columns-format fmt)
|
|
|
|
|
(overlay-put ov 'line-prefix "")
|
|
|
|
|
(overlay-put ov 'wrap-prefix "")
|
|
|
|
|
(forward-char))))))
|
2015-07-18 07:39:23 +00:00
|
|
|
|
;; Make the rest of the line disappear.
|
|
|
|
|
(let ((ov (org-columns-new-overlay (point) (line-end-position))))
|
|
|
|
|
(overlay-put ov 'invisible t)
|
|
|
|
|
(overlay-put ov 'keymap org-columns-map)
|
|
|
|
|
(overlay-put ov 'line-prefix "")
|
|
|
|
|
(overlay-put ov 'wrap-prefix ""))
|
|
|
|
|
(let ((ov (make-overlay (1- (line-end-position))
|
|
|
|
|
(line-beginning-position 2))))
|
|
|
|
|
(overlay-put ov 'keymap org-columns-map)
|
|
|
|
|
(push ov org-columns-overlays))
|
2013-02-25 10:44:27 +00:00
|
|
|
|
(org-with-silent-modifications
|
2015-07-18 07:39:23 +00:00
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(put-text-property
|
|
|
|
|
(line-end-position 0)
|
|
|
|
|
(line-beginning-position 2)
|
|
|
|
|
'read-only
|
|
|
|
|
(substitute-command-keys
|
|
|
|
|
"Type \\<org-columns-map>\\[org-columns-edit-value] \
|
|
|
|
|
to edit property")))))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
2008-05-30 07:30:43 +00:00
|
|
|
|
(defun org-columns-add-ellipses (string width)
|
|
|
|
|
"Truncate STRING with WIDTH characters, with ellipses."
|
2008-12-04 14:33:43 +00:00
|
|
|
|
(cond
|
2008-05-30 07:30:43 +00:00
|
|
|
|
((<= (length string) width) string)
|
|
|
|
|
((<= width (length org-columns-ellipses))
|
|
|
|
|
(substring org-columns-ellipses 0 width))
|
|
|
|
|
(t (concat (substring string 0 (- width (length org-columns-ellipses)))
|
|
|
|
|
org-columns-ellipses))))
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defvar org-columns-full-header-line-format nil
|
2008-12-16 14:49:08 +00:00
|
|
|
|
"The full header line format, will be shifted by horizontal scrolling." )
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defvar org-previous-header-line-format nil
|
|
|
|
|
"The header line format before column view was turned on.")
|
|
|
|
|
(defvar org-columns-inhibit-recalculation nil
|
|
|
|
|
"Inhibit recomputing of columns on column view startup.")
|
2008-04-24 06:33:49 +00:00
|
|
|
|
(defvar org-columns-flyspell-was-active nil
|
|
|
|
|
"Remember the state of `flyspell-mode' before column view.
|
|
|
|
|
Flyspell-mode can cause problems in columns view, so it is turned off
|
2008-04-24 08:29:47 +00:00
|
|
|
|
for the duration of the command.")
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(defvar header-line-format)
|
|
|
|
|
(defvar org-columns-previous-hscroll 0)
|
2009-08-28 12:50:51 +00:00
|
|
|
|
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(defun org-columns--display-here-title ()
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Overlay the newline before the current line with the table title."
|
|
|
|
|
(interactive)
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(let ((title ""))
|
|
|
|
|
(dolist (column org-columns-current-fmt-compiled)
|
|
|
|
|
(pcase column
|
|
|
|
|
(`(,property ,name . ,_)
|
|
|
|
|
(let* ((width
|
|
|
|
|
(cdr (assoc-string property org-columns-current-maxwidths t)))
|
|
|
|
|
(fmt (format "%%-%d.%ds | " width width)))
|
|
|
|
|
(setq title (concat title (format fmt (or name property))))))))
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(setq-local org-previous-header-line-format header-line-format)
|
2016-02-17 16:30:32 +00:00
|
|
|
|
(setq org-columns-full-header-line-format
|
|
|
|
|
(concat
|
|
|
|
|
(org-add-props " " nil 'display '(space :align-to 0))
|
|
|
|
|
(org-add-props (substring title 0 -1) nil 'face 'org-column-title)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq org-columns-previous-hscroll -1)
|
|
|
|
|
(org-add-hook 'post-command-hook 'org-columns-hscoll-title nil 'local)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-hscoll-title ()
|
2010-07-15 20:26:51 +00:00
|
|
|
|
"Set the `header-line-format' so that it scrolls along with the table."
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(sit-for .0001) ; need to force a redisplay to update window-hscroll
|
|
|
|
|
(when (not (= (window-hscroll) org-columns-previous-hscroll))
|
|
|
|
|
(setq header-line-format
|
|
|
|
|
(concat (substring org-columns-full-header-line-format 0 1)
|
|
|
|
|
(substring org-columns-full-header-line-format
|
|
|
|
|
(1+ (window-hscroll))))
|
|
|
|
|
org-columns-previous-hscroll (window-hscroll))
|
|
|
|
|
(force-mode-line-update)))
|
|
|
|
|
|
2009-03-21 14:59:56 +00:00
|
|
|
|
(defvar org-colview-initial-truncate-line-value nil
|
|
|
|
|
"Remember the value of `truncate-lines' across colview.")
|
|
|
|
|
|
2013-11-15 05:53:59 +00:00
|
|
|
|
;;;###autoload
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-remove-overlays ()
|
|
|
|
|
"Remove all currently active column overlays."
|
|
|
|
|
(interactive)
|
|
|
|
|
(when (marker-buffer org-columns-begin-marker)
|
|
|
|
|
(with-current-buffer (marker-buffer org-columns-begin-marker)
|
|
|
|
|
(when (local-variable-p 'org-previous-header-line-format)
|
|
|
|
|
(setq header-line-format org-previous-header-line-format)
|
|
|
|
|
(kill-local-variable 'org-previous-header-line-format)
|
|
|
|
|
(remove-hook 'post-command-hook 'org-columns-hscoll-title 'local))
|
|
|
|
|
(move-marker org-columns-begin-marker nil)
|
|
|
|
|
(move-marker org-columns-top-level-marker nil)
|
2013-02-25 10:44:27 +00:00
|
|
|
|
(org-with-silent-modifications
|
|
|
|
|
(mapc 'delete-overlay org-columns-overlays)
|
|
|
|
|
(setq org-columns-overlays nil)
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(remove-text-properties (point-min) (point-max) '(read-only t))))
|
2008-04-24 06:33:49 +00:00
|
|
|
|
(when org-columns-flyspell-was-active
|
2009-03-21 14:59:56 +00:00
|
|
|
|
(flyspell-mode 1))
|
|
|
|
|
(when (local-variable-p 'org-colview-initial-truncate-line-value)
|
|
|
|
|
(setq truncate-lines org-colview-initial-truncate-line-value)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
2008-05-29 04:55:01 +00:00
|
|
|
|
(defun org-columns-compact-links (s)
|
|
|
|
|
"Replace [[link][desc]] with [desc] or [link]."
|
|
|
|
|
(while (string-match org-bracket-link-regexp s)
|
|
|
|
|
(setq s (replace-match
|
|
|
|
|
(concat "[" (match-string (if (match-end 3) 3 1) s) "]")
|
|
|
|
|
t t s)))
|
|
|
|
|
s)
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-show-value ()
|
|
|
|
|
"Show the full value of the property."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((value (get-char-property (point) 'org-columns-value)))
|
|
|
|
|
(message "Value is: %s" (or value ""))))
|
|
|
|
|
|
2008-04-18 03:42:38 +00:00
|
|
|
|
(defvar org-agenda-columns-active) ;; defined in org-agenda.el
|
2009-08-28 12:50:51 +00:00
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-quit ()
|
|
|
|
|
"Remove the column overlays and in this way exit column editing."
|
|
|
|
|
(interactive)
|
2013-02-25 10:44:27 +00:00
|
|
|
|
(org-with-silent-modifications
|
|
|
|
|
(org-columns-remove-overlays)
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(remove-text-properties (point-min) (point-max) '(read-only t))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(when (eq major-mode 'org-agenda-mode)
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(setq org-agenda-columns-active nil)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(message
|
|
|
|
|
"Modification not yet reflected in Agenda buffer, use `r' to refresh")))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-check-computed ()
|
|
|
|
|
"Check if this column value is computed.
|
|
|
|
|
If yes, throw an error indicating that changing it does not make sense."
|
|
|
|
|
(let ((val (get-char-property (point) 'org-columns-value)))
|
|
|
|
|
(when (and (stringp val)
|
|
|
|
|
(get-char-property 0 'org-computed val))
|
|
|
|
|
(error "This value is computed from the entry's children"))))
|
|
|
|
|
|
2015-10-26 00:56:00 +00:00
|
|
|
|
(defun org-columns-todo (&optional _arg)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Change the TODO state during column view."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(org-columns-edit-value "TODO"))
|
|
|
|
|
|
2015-10-26 00:56:00 +00:00
|
|
|
|
(defun org-columns-set-tags-or-toggle (&optional _arg)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Toggle checkbox at point, or set tags for current headline."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (string-match "\\`\\[[ xX-]\\]\\'"
|
|
|
|
|
(get-char-property (point) 'org-columns-value))
|
|
|
|
|
(org-columns-next-allowed-value)
|
|
|
|
|
(org-columns-edit-value "TAGS")))
|
|
|
|
|
|
Backport changes from Emacs revs 115081 and 115082
2013-11-12 Stefan Monnier <monnier@iro.umontreal.ca>
Address some byte-compiler warnings.
* ob-abc.el (org-babel-expand-body:abc): Use dolist.
(org-babel-execute:abc): Fix regexp quoting.
* ob-calc.el (org--var-syms): Rename from `var-syms'.
* ob-lilypond.el (ly-compile-lilyfile): Remove redundant let-binding.
* ob-table.el (sbe): Move debug declaration.
* org-clock.el (org--msg-extra): Rename from `msg-extra'.
* org.el (org-version): Avoid var name starting with _.
(org-inhibit-startup, org-called-with-limited-levels)
(org-link-search-inhibit-query, org-time-was-given)
(org-end-time-was-given, org-def, org-defdecode, org-with-time):
* org-colview.el (org-agenda-overriding-columns-format):
* org-agenda.el (org-agenda-multi, org-depend-tag-blocked)
(org-agenda-show-log-scoped):
* ob-python.el (py-which-bufname, python-shell-buffer-name):
* ob-haskell.el (org-export-copy-to-kill-ring):
* ob-exp.el (org-link-search-inhibit-query):
* ob-R.el (ess-eval-visibly-p):
* ob-core.el (org-src-window-setup): Declare before use.
(org-babel-expand-noweb-references): Remove unused `blocks-in-buffer'.
* ox-odt.el (org-odt-hfy-face-to-css):
* org-src.el (org-src-associate-babel-session, org-src-get-lang-mode):
* org-bibtex.el (org-bibtex-get, org-bibtex-ask, org-bibtex)
(org-bibtex-check):
* ob-tangle.el (org-babel-tangle, org-babel-spec-to-string)
(org-babel-tangle-single-block, org-babel-tangle-comment-links):
* ob-table.el (sbe):
* ob-sqlite.el (org-babel-sqlite-expand-vars):
* ob-sql.el (org-babel-sql-expand-vars):
* ob-shen.el (org-babel-execute:shen):
* ob-sh.el (org-babel-execute:sh, org-babel-sh-evaluate):
* ob-scala.el (org-babel-scala-evaluate):
* ob-ruby.el (org-babel-ruby-table-or-string)
(org-babel-ruby-evaluate):
* ob-python.el (org-babel-python-table-or-string)
(org-babel-python-evaluate-external-process)
(org-babel-python-evaluate-session):
* ob-picolisp.el (org-babel-execute:picolisp):
* ob-perl.el (org-babel-perl-evaluate):
* ob-maxima.el (org-babel-execute:maxima):
* ob-lisp.el (org-babel-execute:lisp):
* ob-java.el (org-babel-execute:java):
* ob-io.el (org-babel-io-evaluate):
* ob-haskell.el (org-babel-execute:haskell):
* ob-fortran.el (org-babel-execute:fortran):
* ob-exp.el (org-babel-exp-code):
* ob-emacs-lisp.el (org-babel-execute:emacs-lisp):
* ob-ditaa.el (org-babel-execute:ditaa):
* ob-core.el (org-babel-execute-src-block, org-babel-sha1-hash)
(org-babel-parse-header-arguments, org-babel-reassemble-table)
(org-babel-goto-src-block-head, org-babel-mark-block)
(org-babel-expand-noweb-references, org-babel-script-escape)
(org-babel-process-file-name):
* ob-clojure.el (org-babel-execute:clojure):
* ob-calc.el (org-babel-execute:calc):
* ob-awk.el (org-babel-execute:awk):
* ob-abc.el (org-babel-execute:abc):
* ob-R.el (org-babel-expand-body:R):
* ob-C.el (org-babel-C-execute): Avoid deprecated ((lambda) ...).
2013-11-12 Glenn Morris <rgm@gnu.org>
* ox-html.el (org-html-scripts): Add 2013 to copyright years.
(org-html-infojs-template): Copyright holder to FSF.
2013-11-12 19:57:31 +00:00
|
|
|
|
(defvar org-agenda-overriding-columns-format nil
|
|
|
|
|
"When set, overrides any other format definition for the agenda.
|
|
|
|
|
Don't set this, this is meant for dynamic scoping.")
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-edit-value (&optional key)
|
|
|
|
|
"Edit the value of the property at point in column view.
|
|
|
|
|
Where possible, use the standard interface for changing this line."
|
|
|
|
|
(interactive)
|
|
|
|
|
(org-columns-check-computed)
|
2009-02-20 08:12:10 +00:00
|
|
|
|
(let* ((col (current-column))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(key (or key (get-char-property (point) 'org-columns-key)))
|
|
|
|
|
(value (get-char-property (point) 'org-columns-value))
|
|
|
|
|
(bol (point-at-bol)) (eol (point-at-eol))
|
|
|
|
|
(pom (or (get-text-property bol 'org-hd-marker)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(point))) ; keep despite of compiler waring
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(org-columns--time (float-time (current-time)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
nval eval allowed)
|
|
|
|
|
(cond
|
|
|
|
|
((equal key "CLOCKSUM")
|
|
|
|
|
(error "This special column cannot be edited"))
|
|
|
|
|
((equal key "ITEM")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(org-edit-headline))))
|
|
|
|
|
((equal key "TODO")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2012-08-11 17:10:44 +00:00
|
|
|
|
(call-interactively 'org-todo))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
((equal key "PRIORITY")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(call-interactively 'org-priority))))
|
|
|
|
|
((equal key "TAGS")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(let ((org-fast-tag-selection-single-key
|
|
|
|
|
(if (eq org-fast-tag-selection-single-key 'expert)
|
|
|
|
|
t org-fast-tag-selection-single-key)))
|
|
|
|
|
(call-interactively 'org-set-tags)))))
|
|
|
|
|
((equal key "DEADLINE")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(call-interactively 'org-deadline))))
|
|
|
|
|
((equal key "SCHEDULED")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(call-interactively 'org-schedule))))
|
2009-12-11 07:44:35 +00:00
|
|
|
|
((equal key "BEAMER_env")
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-with-point-at ,pom
|
2010-07-31 15:37:16 +00:00
|
|
|
|
(call-interactively 'org-beamer-select-environment))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(t
|
|
|
|
|
(setq allowed (org-property-get-allowed-values pom key 'table))
|
|
|
|
|
(if allowed
|
2015-12-22 13:49:23 +00:00
|
|
|
|
(setq nval (completing-read
|
2009-12-11 07:44:35 +00:00
|
|
|
|
"Value: " allowed nil
|
|
|
|
|
(not (get-text-property 0 'org-unrestricted
|
|
|
|
|
(caar allowed)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq nval (read-string "Edit: " value)))
|
|
|
|
|
(setq nval (org-trim nval))
|
|
|
|
|
(when (not (equal nval value))
|
2015-12-04 11:00:23 +00:00
|
|
|
|
(setq eval `(org-entry-put ,pom ,key ,nval)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(when eval
|
2008-04-18 13:24:58 +00:00
|
|
|
|
(cond
|
|
|
|
|
((equal major-mode 'org-agenda-mode)
|
2008-05-29 05:21:07 +00:00
|
|
|
|
(org-columns-eval eval)
|
2008-04-18 13:24:58 +00:00
|
|
|
|
;; The following let preserves the current format, and makes sure
|
2011-11-28 14:11:52 +00:00
|
|
|
|
;; that in only a single file things need to be updated.
|
2008-04-18 13:24:58 +00:00
|
|
|
|
(let* ((org-agenda-overriding-columns-format org-columns-current-fmt)
|
|
|
|
|
(buffer (marker-buffer pom))
|
|
|
|
|
(org-agenda-contributing-files
|
|
|
|
|
(list (with-current-buffer buffer
|
|
|
|
|
(buffer-file-name (buffer-base-buffer))))))
|
|
|
|
|
(org-agenda-columns)))
|
|
|
|
|
(t
|
|
|
|
|
(let ((inhibit-read-only t))
|
2013-02-25 10:44:27 +00:00
|
|
|
|
(org-with-silent-modifications
|
|
|
|
|
(remove-text-properties
|
|
|
|
|
(max (point-min) (1- bol)) eol '(read-only t)))
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(org-columns-eval eval))
|
2008-04-24 14:44:12 +00:00
|
|
|
|
(org-move-to-column col)
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(org-columns-update key))))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(defun org-edit-headline () ; FIXME: this is not columns specific. Make interactive????? Use from agenda????
|
|
|
|
|
"Edit the current headline, the part without TODO keyword, TAGS."
|
|
|
|
|
(org-back-to-heading)
|
|
|
|
|
(when (looking-at org-todo-line-regexp)
|
2008-05-30 04:04:29 +00:00
|
|
|
|
(let ((pos (point))
|
|
|
|
|
(pre (buffer-substring (match-beginning 0) (match-beginning 3)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(txt (match-string 3))
|
|
|
|
|
(post "")
|
|
|
|
|
txt2)
|
2010-08-21 00:30:31 +00:00
|
|
|
|
(if (string-match (org-re "[ \t]+:[[:alnum:]:_@#%]+:[ \t]*$") txt)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq post (match-string 0 txt)
|
|
|
|
|
txt (substring txt 0 (match-beginning 0))))
|
|
|
|
|
(setq txt2 (read-string "Edit: " txt))
|
|
|
|
|
(when (not (equal txt txt2))
|
2008-05-30 04:04:29 +00:00
|
|
|
|
(goto-char pos)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(insert pre txt2 post)
|
|
|
|
|
(delete-region (point) (point-at-eol))
|
|
|
|
|
(org-set-tags nil t)))))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-edit-allowed ()
|
|
|
|
|
"Edit the list of allowed values for the current property."
|
|
|
|
|
(interactive)
|
2009-09-25 08:48:59 +00:00
|
|
|
|
(let* ((pom (or (org-get-at-bol 'org-marker)
|
|
|
|
|
(org-get-at-bol 'org-hd-marker)
|
2008-04-15 09:02:10 +00:00
|
|
|
|
(point)))
|
|
|
|
|
(key (get-char-property (point) 'org-columns-key))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(key1 (concat key "_ALL"))
|
2008-04-15 09:02:10 +00:00
|
|
|
|
(allowed (org-entry-get pom key1 t))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
nval)
|
|
|
|
|
;; FIXME: Cover editing TODO, TAGS etc in-buffer settings.????
|
2008-04-15 09:02:10 +00:00
|
|
|
|
;; FIXME: Write back to #+PROPERTY setting if that is needed.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq nval (read-string "Allowed: " allowed))
|
|
|
|
|
(org-entry-put
|
|
|
|
|
(cond ((marker-position org-entry-property-inherited-from)
|
|
|
|
|
org-entry-property-inherited-from)
|
|
|
|
|
((marker-position org-columns-top-level-marker)
|
2008-04-15 09:02:10 +00:00
|
|
|
|
org-columns-top-level-marker)
|
|
|
|
|
(t pom))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
key1 nval)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-eval (form)
|
|
|
|
|
(let (hidep)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line 1)
|
|
|
|
|
;; `next-line' is needed here, because it skips invisible line.
|
|
|
|
|
(condition-case nil (org-no-warnings (next-line 1)) (error nil))
|
2012-01-02 18:52:35 +00:00
|
|
|
|
(setq hidep (org-at-heading-p 1)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(eval form)
|
2015-09-27 15:45:07 +00:00
|
|
|
|
(and hidep (outline-hide-entry))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(defun org-columns-previous-allowed-value ()
|
|
|
|
|
"Switch to the previous allowed value for this column."
|
|
|
|
|
(interactive)
|
|
|
|
|
(org-columns-next-allowed-value t))
|
|
|
|
|
|
2008-06-09 07:53:19 +00:00
|
|
|
|
(defun org-columns-next-allowed-value (&optional previous nth)
|
|
|
|
|
"Switch to the next allowed value for this column.
|
|
|
|
|
When PREVIOUS is set, go to the previous value. When NTH is
|
|
|
|
|
an integer, select that value."
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(org-columns-check-computed)
|
|
|
|
|
(let* ((col (current-column))
|
|
|
|
|
(key (get-char-property (point) 'org-columns-key))
|
|
|
|
|
(value (get-char-property (point) 'org-columns-value))
|
|
|
|
|
(bol (point-at-bol)) (eol (point-at-eol))
|
|
|
|
|
(pom (or (get-text-property bol 'org-hd-marker)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(point))) ; keep despite of compiler waring
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(allowed (or (org-property-get-allowed-values pom key)
|
|
|
|
|
(and (memq
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(nth 4 (assoc-string key
|
|
|
|
|
org-columns-current-fmt-compiled
|
|
|
|
|
t))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
'(checkbox checkbox-n-of-m checkbox-percent))
|
2008-09-18 08:24:57 +00:00
|
|
|
|
'("[ ]" "[X]"))
|
|
|
|
|
(org-colview-construct-allowed-dates value)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
nval)
|
2008-06-09 07:53:19 +00:00
|
|
|
|
(when (integerp nth)
|
|
|
|
|
(setq nth (1- nth))
|
|
|
|
|
(if (= nth -1) (setq nth 9)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(when (equal key "ITEM")
|
|
|
|
|
(error "Cannot edit item headline from here"))
|
2012-08-30 14:42:13 +00:00
|
|
|
|
(unless (or allowed (member key '("SCHEDULED" "DEADLINE" "CLOCKSUM")))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(error "Allowed values for this property have not been defined"))
|
2012-08-30 14:42:13 +00:00
|
|
|
|
(if (member key '("SCHEDULED" "DEADLINE" "CLOCKSUM"))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq nval (if previous 'earlier 'later))
|
|
|
|
|
(if previous (setq allowed (reverse allowed)))
|
2008-06-09 07:53:19 +00:00
|
|
|
|
(cond
|
|
|
|
|
(nth
|
|
|
|
|
(setq nval (nth nth allowed))
|
|
|
|
|
(if (not nval)
|
|
|
|
|
(error "There are only %d allowed values for property `%s'"
|
|
|
|
|
(length allowed) key)))
|
|
|
|
|
((member value allowed)
|
|
|
|
|
(setq nval (or (car (cdr (member value allowed)))
|
|
|
|
|
(car allowed)))
|
|
|
|
|
(if (equal nval value)
|
2008-06-16 16:23:18 +00:00
|
|
|
|
(error "Only one allowed value for this property")))
|
|
|
|
|
(t (setq nval (car allowed)))))
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(cond
|
|
|
|
|
((equal major-mode 'org-agenda-mode)
|
2016-01-20 23:51:13 +00:00
|
|
|
|
(org-columns-eval `(org-entry-put ,pom ,key ,nval))
|
2008-04-18 13:24:58 +00:00
|
|
|
|
;; The following let preserves the current format, and makes sure
|
2011-11-28 14:11:52 +00:00
|
|
|
|
;; that in only a single file things need to be updated.
|
2008-04-18 13:24:58 +00:00
|
|
|
|
(let* ((org-agenda-overriding-columns-format org-columns-current-fmt)
|
|
|
|
|
(buffer (marker-buffer pom))
|
|
|
|
|
(org-agenda-contributing-files
|
|
|
|
|
(list (with-current-buffer buffer
|
|
|
|
|
(buffer-file-name (buffer-base-buffer))))))
|
|
|
|
|
(org-agenda-columns)))
|
|
|
|
|
(t
|
|
|
|
|
(let ((inhibit-read-only t))
|
2016-01-20 23:51:13 +00:00
|
|
|
|
(remove-text-properties (max (1- bol) (point-min)) eol '(read-only t))
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(org-columns-eval `(org-entry-put ,pom ,key ,nval)))
|
2008-04-24 14:44:12 +00:00
|
|
|
|
(org-move-to-column col)
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(org-columns-update key)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
2008-09-18 08:24:57 +00:00
|
|
|
|
(defun org-colview-construct-allowed-dates (s)
|
|
|
|
|
"Construct a list of three dates around the date in S.
|
|
|
|
|
This respects the format of the time stamp in S, active or non-active,
|
|
|
|
|
and also including time or not. S must be just a time stamp, no text
|
|
|
|
|
around it."
|
2009-01-16 11:50:09 +00:00
|
|
|
|
(when (and s (string-match (concat "^" org-ts-regexp3 "$") s))
|
2008-09-18 08:24:57 +00:00
|
|
|
|
(let* ((time (org-parse-time-string s 'nodefaults))
|
|
|
|
|
(active (equal (string-to-char s) ?<))
|
2008-09-19 06:30:22 +00:00
|
|
|
|
(fmt (funcall (if (nth 1 time) 'cdr 'car) org-time-stamp-formats))
|
|
|
|
|
time-before time-after)
|
2008-09-18 08:24:57 +00:00
|
|
|
|
(unless active (setq fmt (concat "[" (substring fmt 1 -1) "]")))
|
|
|
|
|
(setf (car time) (or (car time) 0))
|
|
|
|
|
(setf (nth 1 time) (or (nth 1 time) 0))
|
|
|
|
|
(setf (nth 2 time) (or (nth 2 time) 0))
|
|
|
|
|
(setq time-before (copy-sequence time))
|
|
|
|
|
(setq time-after (copy-sequence time))
|
|
|
|
|
(setf (nth 3 time-before) (1- (nth 3 time)))
|
|
|
|
|
(setf (nth 3 time-after) (1+ (nth 3 time)))
|
|
|
|
|
(mapcar (lambda (x) (format-time-string fmt (apply 'encode-time x)))
|
|
|
|
|
(list time-before time time-after)))))
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-open-link (&optional arg)
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((value (get-char-property (point) 'org-columns-value)))
|
|
|
|
|
(org-open-link-from-string value arg)))
|
|
|
|
|
|
2013-11-15 05:53:59 +00:00
|
|
|
|
;;;###autoload
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-get-format-and-top-level ()
|
2012-08-12 21:00:55 +00:00
|
|
|
|
(let ((fmt (org-columns-get-format)))
|
2012-08-12 09:48:44 +00:00
|
|
|
|
(org-columns-goto-top-level)
|
|
|
|
|
fmt))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-get-format (&optional fmt-string)
|
|
|
|
|
(interactive)
|
2012-08-12 21:00:55 +00:00
|
|
|
|
(let (fmt-as-property fmt)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(when (condition-case nil (org-back-to-heading) (error nil))
|
2012-08-12 09:48:44 +00:00
|
|
|
|
(setq fmt-as-property (org-entry-get nil "COLUMNS" t)))
|
|
|
|
|
(setq fmt (or fmt-string fmt-as-property org-columns-default-format))
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(setq-local org-columns-current-fmt fmt)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(org-columns-compile-format fmt)
|
|
|
|
|
fmt))
|
|
|
|
|
|
2012-08-12 09:48:44 +00:00
|
|
|
|
(defun org-columns-goto-top-level ()
|
2015-08-12 12:49:02 +00:00
|
|
|
|
"Move to the beginning of the column view area.
|
|
|
|
|
Also sets `org-columns-top-level-marker' to the new position."
|
|
|
|
|
(goto-char
|
|
|
|
|
(move-marker
|
|
|
|
|
org-columns-top-level-marker
|
|
|
|
|
(cond ((org-before-first-heading-p) (point-min))
|
|
|
|
|
((org-entry-get nil "COLUMNS" t) org-entry-property-inherited-from)
|
|
|
|
|
(t (org-back-to-heading) (point))))))
|
2012-08-12 09:48:44 +00:00
|
|
|
|
|
Update autoloads.
* org.el: Don't dynamically autoload already autoloaded
functions.
(org-clock-update-time-maybe): Move to org-clock.el.
* org-exp.el (org-insert-export-options-template): Remove
autoload cookie.
* org-clock.el (org-resolve-clocks, org-clock-in)
(org-clock-out, org-clock-cancel, org-clock-goto)
(org-clock-sum, org-clock-display, org-clock-report)
(org-dblock-write:clocktable): Add autoload cookie.
(org-clock-update-time-maybe): Moved from org.el.
* org-beamer.el (org-beamer-sectioning, org-beamer-mode): Ditto.
* org-ascii.el (org-export-ascii-preprocess): Ditto.
* org-archive.el (org-archive-subtree)
(org-archive-to-archive-sibling, org-toggle-archive-tag): Add
autoload cookie.
* org-colview.el (org-columns, org-dblock-write:columnview)
(org-insert-columns-dblock, org-agenda-columns): Ditto.
* org-table.el (org-table-create-with-table.el)
(org-table-create-or-convert-from-region, org-table-create)
(org-table-convert-region, org-table-import)
(org-table-export, org-table-align)
(org-table-justify-field-maybe, org-table-next-field)
(org-table-previous-field, org-table-next-row)
(org-table-copy-down, org-table-field-info)
(org-table-current-dline, org-table-goto-column)
(org-table-insert-column, org-table-delete-column)
(org-table-move-column-right, org-table-move-column-left)
(org-table-move-column, org-table-move-row-down)
(org-table-move-row-up, org-table-move-row)
(org-table-insert-row, org-table-insert-hline)
(org-table-hline-and-move, org-table-kill-row)
(org-table-sort-lines, org-table-cut-region)
(org-table-copy-region, org-table-paste-rectangle)
(org-table-convert, org-table-wrap-region)
(org-table-edit-field, org-table-sum)
(org-table-get-stored-formulas)
(org-table-maybe-eval-formula)
(org-table-rotate-recalc-marks)
(org-table-maybe-recalculate-line, org-table-eval-formula)
(org-table-recalculate, org-table-iterate)
(org-table-edit-formulas)
(org-table-toggle-coordinate-overlays)
(org-table-toggle-formula-debugger, orgtbl-to-generic)
(orgtbl-to-tsv, orgtbl-to-csv, orgtbl-to-latex)
(orgtbl-to-html, orgtbl-to-texinfo, orgtbl-to-orgtbl): Ditto.
2012-10-02 08:52:17 +00:00
|
|
|
|
;;;###autoload
|
2016-02-14 21:25:49 +00:00
|
|
|
|
(defun org-columns (&optional global columns-fmt-string)
|
|
|
|
|
"Turn on column view on an Org mode file.
|
|
|
|
|
|
|
|
|
|
Column view applies to the whole buffer if point is before the
|
|
|
|
|
first headline. Otherwise, it applies to the first ancestor
|
|
|
|
|
setting \"COLUMNS\" property. If there is none, it defaults to
|
|
|
|
|
the current headline. With a \\[universal-argument] prefix \
|
|
|
|
|
argument, turn on column
|
|
|
|
|
view for the whole buffer unconditionally.
|
|
|
|
|
|
2012-08-12 09:48:44 +00:00
|
|
|
|
When COLUMNS-FMT-STRING is non-nil, use it as the column format."
|
2016-02-14 21:25:49 +00:00
|
|
|
|
(interactive "P")
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(org-columns-remove-overlays)
|
|
|
|
|
(move-marker org-columns-begin-marker (point))
|
2015-06-02 15:02:55 +00:00
|
|
|
|
(org-columns-goto-top-level)
|
|
|
|
|
;; Initialize `org-columns-current-fmt' and
|
|
|
|
|
;; `org-columns-current-fmt-compiled'.
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(let ((org-columns--time (float-time (current-time))))
|
|
|
|
|
(org-columns-get-format columns-fmt-string)
|
|
|
|
|
(unless org-columns-inhibit-recalculation (org-columns-compute-all))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(when (and (not global) (org-at-heading-p))
|
|
|
|
|
(narrow-to-region (point) (org-end-of-subtree t t)))
|
|
|
|
|
(when (assoc-string "CLOCKSUM" org-columns-current-fmt-compiled t)
|
|
|
|
|
(org-clock-sum))
|
|
|
|
|
(when (assoc-string "CLOCKSUM_T" org-columns-current-fmt-compiled t)
|
|
|
|
|
(org-clock-sum-today))
|
|
|
|
|
(let ((cache
|
|
|
|
|
;; Collect contents of columns ahead of time so as to
|
|
|
|
|
;; compute their maximum width.
|
|
|
|
|
(org-map-entries
|
|
|
|
|
(lambda () (cons (point) (org-columns--collect-values)))
|
|
|
|
|
nil nil (and org-columns-skip-archived-trees 'archive))))
|
|
|
|
|
(when cache
|
|
|
|
|
(setq-local org-columns-current-maxwidths
|
|
|
|
|
(org-columns--autowidth-alist cache))
|
|
|
|
|
(org-columns--display-here-title)
|
|
|
|
|
(when (setq-local org-columns-flyspell-was-active
|
|
|
|
|
(org-bound-and-true-p flyspell-mode))
|
|
|
|
|
(flyspell-mode 0))
|
|
|
|
|
(unless (local-variable-p 'org-colview-initial-truncate-line-value)
|
|
|
|
|
(setq-local org-colview-initial-truncate-line-value
|
|
|
|
|
truncate-lines))
|
|
|
|
|
(setq truncate-lines t)
|
|
|
|
|
(dolist (entry cache)
|
|
|
|
|
(goto-char (car entry))
|
|
|
|
|
(org-columns--display-here (cdr entry)))))))))
|
|
|
|
|
|
|
|
|
|
(defconst org-columns-compile-map
|
2009-11-11 04:53:17 +00:00
|
|
|
|
'(("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)
|
2016-02-17 14:16:22 +00:00
|
|
|
|
("mean" mean_numbers (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
|
2009-11-11 04:53:17 +00:00
|
|
|
|
(":max" max_times max)
|
|
|
|
|
(":min" min_times min)
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(":mean" mean_times (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
|
|
|
|
|
("@min" min_age min)
|
|
|
|
|
("@max" max_age max)
|
|
|
|
|
("@mean" mean_age (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
|
2016-02-17 20:35:34 +00:00
|
|
|
|
("est+" estimate org-columns--estimate-combine))
|
2016-02-17 14:36:31 +00:00
|
|
|
|
"Operator <-> format,function map.
|
2009-05-21 05:54:54 +00:00
|
|
|
|
Used to compile/uncompile columns format and completing read in
|
2010-07-15 20:26:51 +00:00
|
|
|
|
interactive function `org-columns-new'.
|
2009-11-01 00:00:31 +00:00
|
|
|
|
|
|
|
|
|
operator string used in #+COLUMNS definition describing the
|
2009-11-11 04:53:17 +00:00
|
|
|
|
summary type
|
2009-11-01 00:00:31 +00:00
|
|
|
|
format symbol describing summary type selected interactively in
|
2010-07-15 20:26:51 +00:00
|
|
|
|
`org-columns-new' and internally in
|
|
|
|
|
`org-columns-number-to-string' and
|
|
|
|
|
`org-columns-string-to-number'
|
2009-11-01 00:00:31 +00:00
|
|
|
|
function called with a list of values as argument to calculate
|
2016-02-17 14:36:31 +00:00
|
|
|
|
the summary value")
|
2009-05-21 05:54:54 +00:00
|
|
|
|
|
2015-10-26 00:56:00 +00:00
|
|
|
|
(defun org-columns-new (&optional prop title width _op fmt fun &rest _rest)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Insert a new column, to the left of the current column."
|
|
|
|
|
(interactive)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(let ((editp (and prop
|
|
|
|
|
(assoc-string prop org-columns-current-fmt-compiled t)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
cell)
|
2015-12-22 13:49:23 +00:00
|
|
|
|
(setq prop (completing-read
|
|
|
|
|
"Property: " (mapcar #'list (org-buffer-property-keys t nil t))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
nil nil prop))
|
|
|
|
|
(setq title (read-string (concat "Column title [" prop "]: ") (or title prop)))
|
|
|
|
|
(setq width (read-string "Column width: " (if width (number-to-string width))))
|
|
|
|
|
(if (string-match "\\S-" width)
|
|
|
|
|
(setq width (string-to-number width))
|
|
|
|
|
(setq width nil))
|
2015-12-22 13:49:23 +00:00
|
|
|
|
(setq fmt (completing-read
|
2009-08-03 15:30:30 +00:00
|
|
|
|
"Summary [none]: "
|
|
|
|
|
(mapcar (lambda (x) (list (symbol-name (cadr x))))
|
|
|
|
|
org-columns-compile-map)
|
|
|
|
|
nil t))
|
2009-05-21 05:54:54 +00:00
|
|
|
|
(setq fmt (intern fmt)
|
2009-11-01 00:00:31 +00:00
|
|
|
|
fun (cdr (assoc fmt (mapcar 'cdr org-columns-compile-map))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(if (eq fmt 'none) (setq fmt nil))
|
|
|
|
|
(if editp
|
|
|
|
|
(progn
|
|
|
|
|
(setcar editp prop)
|
2009-05-21 05:54:54 +00:00
|
|
|
|
(setcdr editp (list title width nil fmt nil fun)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq cell (nthcdr (1- (current-column))
|
|
|
|
|
org-columns-current-fmt-compiled))
|
2009-10-30 03:16:18 +00:00
|
|
|
|
(setcdr cell (cons (list prop title width nil fmt nil
|
2009-11-01 00:00:31 +00:00
|
|
|
|
(car fun) (cadr fun))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(cdr cell))))
|
|
|
|
|
(org-columns-store-format)
|
|
|
|
|
(org-columns-redo)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-delete ()
|
|
|
|
|
"Delete the column at point from columns view."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((n (current-column))
|
|
|
|
|
(title (nth 1 (nth n org-columns-current-fmt-compiled))))
|
|
|
|
|
(when (y-or-n-p
|
|
|
|
|
(format "Are you sure you want to remove column \"%s\"? " title))
|
|
|
|
|
(setq org-columns-current-fmt-compiled
|
|
|
|
|
(delq (nth n org-columns-current-fmt-compiled)
|
|
|
|
|
org-columns-current-fmt-compiled))
|
|
|
|
|
(org-columns-store-format)
|
|
|
|
|
(org-columns-redo)
|
|
|
|
|
(if (>= (current-column) (length org-columns-current-fmt-compiled))
|
|
|
|
|
(backward-char 1)))))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-edit-attributes ()
|
|
|
|
|
"Edit the attributes of the current column."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((n (current-column))
|
|
|
|
|
(info (nth n org-columns-current-fmt-compiled)))
|
|
|
|
|
(apply 'org-columns-new info)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-widen (arg)
|
|
|
|
|
"Make the column wider by ARG characters."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(let* ((n (current-column))
|
|
|
|
|
(entry (nth n org-columns-current-fmt-compiled))
|
|
|
|
|
(width (or (nth 2 entry)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(cdr (assoc-string (car entry)
|
|
|
|
|
org-columns-current-maxwidths
|
|
|
|
|
t)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq width (max 1 (+ width arg)))
|
|
|
|
|
(setcar (nthcdr 2 entry) width)
|
|
|
|
|
(org-columns-store-format)
|
|
|
|
|
(org-columns-redo)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-narrow (arg)
|
2008-12-16 14:49:08 +00:00
|
|
|
|
"Make the column narrower by ARG characters."
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(interactive "p")
|
|
|
|
|
(org-columns-widen (- arg)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-move-right ()
|
|
|
|
|
"Swap this column with the one to the right."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((n (current-column))
|
|
|
|
|
(cell (nthcdr n org-columns-current-fmt-compiled))
|
|
|
|
|
e)
|
|
|
|
|
(when (>= n (1- (length org-columns-current-fmt-compiled)))
|
|
|
|
|
(error "Cannot shift this column further to the right"))
|
|
|
|
|
(setq e (car cell))
|
|
|
|
|
(setcar cell (car (cdr cell)))
|
|
|
|
|
(setcdr cell (cons e (cdr (cdr cell))))
|
|
|
|
|
(org-columns-store-format)
|
|
|
|
|
(org-columns-redo)
|
|
|
|
|
(forward-char 1)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-move-left ()
|
|
|
|
|
"Swap this column with the one to the left."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((n (current-column)))
|
|
|
|
|
(when (= n 0)
|
|
|
|
|
(error "Cannot shift this column further to the left"))
|
|
|
|
|
(backward-char 1)
|
|
|
|
|
(org-columns-move-right)
|
|
|
|
|
(backward-char 1)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-store-format ()
|
|
|
|
|
"Store the text version of the current columns format in appropriate place.
|
|
|
|
|
This is either in the COLUMNS property of the node starting the current column
|
|
|
|
|
display, or in the #+COLUMNS line of the current buffer."
|
|
|
|
|
(let (fmt (cnt 0))
|
|
|
|
|
(setq fmt (org-columns-uncompile-format org-columns-current-fmt-compiled))
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(setq-local org-columns-current-fmt fmt)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(if (marker-position org-columns-top-level-marker)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char org-columns-top-level-marker)
|
|
|
|
|
(if (and (org-at-heading-p)
|
|
|
|
|
(org-entry-get nil "COLUMNS"))
|
|
|
|
|
(org-entry-put nil "COLUMNS" fmt)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
;; Overwrite all #+COLUMNS lines....
|
2014-03-12 18:54:05 +00:00
|
|
|
|
(while (re-search-forward "^[ \t]*#\\+COLUMNS:.*" nil t)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq cnt (1+ cnt))
|
|
|
|
|
(replace-match (concat "#+COLUMNS: " fmt) t t))
|
|
|
|
|
(unless (> cnt 0)
|
|
|
|
|
(goto-char (point-min))
|
2012-01-02 18:52:35 +00:00
|
|
|
|
(or (org-at-heading-p t) (outline-next-heading))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(insert-before-markers "#+COLUMNS: " fmt "\n")))
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(setq-local org-columns-default-format fmt))))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(defun org-columns-compute-all ()
|
|
|
|
|
"Compute all columns that have operators defined."
|
2013-02-25 10:44:27 +00:00
|
|
|
|
(org-with-silent-modifications
|
|
|
|
|
(remove-text-properties (point-min) (point-max) '(org-summaries t)))
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(let ((org-columns--time (float-time (current-time))))
|
2016-02-15 23:02:48 +00:00
|
|
|
|
(dolist (spec org-columns-current-fmt-compiled)
|
|
|
|
|
(pcase spec
|
|
|
|
|
(`(,property ,_ ,_ ,operator . ,_)
|
|
|
|
|
(when operator (save-excursion (org-columns-compute property))))))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(defun org-columns-update (property)
|
|
|
|
|
"Recompute PROPERTY, and update the columns display for it."
|
|
|
|
|
(org-columns-compute property)
|
2016-02-17 21:38:39 +00:00
|
|
|
|
(org-with-wide-buffer
|
|
|
|
|
(let ((p (upcase property)))
|
|
|
|
|
(dolist (ov org-columns-overlays)
|
|
|
|
|
(when (let ((key (overlay-get ov 'org-columns-key)))
|
|
|
|
|
(and key (equal (upcase key) p) (overlay-start ov)))
|
|
|
|
|
(goto-char (overlay-start ov))
|
|
|
|
|
(let ((value (cdr
|
|
|
|
|
(assoc-string
|
|
|
|
|
property
|
|
|
|
|
(get-text-property (line-beginning-position)
|
|
|
|
|
'org-summaries)
|
|
|
|
|
t))))
|
|
|
|
|
(when value
|
|
|
|
|
(let ((displayed (org-columns--displayed-value property value))
|
|
|
|
|
(format (overlay-get ov 'org-columns-format))
|
|
|
|
|
(width (cdr (assoc-string property
|
|
|
|
|
org-columns-current-maxwidths
|
|
|
|
|
t))))
|
|
|
|
|
(overlay-put ov 'org-columns-value value)
|
|
|
|
|
(overlay-put ov 'org-columns-value-modified displayed)
|
|
|
|
|
(overlay-put ov
|
|
|
|
|
'display
|
|
|
|
|
(org-columns--overlay-text
|
|
|
|
|
displayed format width property value))))))))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
2012-03-23 21:04:36 +00:00
|
|
|
|
(defvar org-inlinetask-min-level
|
|
|
|
|
(if (featurep 'org-inlinetask) org-inlinetask-min-level 15))
|
2013-11-15 05:53:59 +00:00
|
|
|
|
|
|
|
|
|
;;;###autoload
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-compute (property)
|
|
|
|
|
"Sum the values of property PROPERTY hierarchically, for the entire buffer."
|
|
|
|
|
(interactive)
|
Don't use `outline-regexp' anymore.
Use `org-outline-regexp' instead or `outline-regexp'. Also use the
new defconst `org-outline-regexp-bol' to match `org-outline-regexp'
at the beginning of line.
* org.el (org-outline-regexp-bol): New defconst.
(org-outline-level, org-set-font-lock-defaults, org-cycle)
(org-overview, org-content, org-flag-drawer)
(org-first-headline-recenter, org-insert-todo-heading)
(org-map-region, org-move-subtree-down, org-paste-subtree)
(org-kill-is-subtree-p, org-context-p, org-refile)
(org-refile-new-child, org-toggle-comment, org-todo)
(org-add-planning-info, org-add-log-setup, org-scan-tags)
(org-set-tags, org-insert-property-drawer)
(org-prepare-agenda-buffers, org-preview-latex-fragment)
(org-speed-command-default-hook, org-check-for-hidden)
(org-toggle-item, org-toggle-heading)
(org-indent-line-function, org-set-autofill-regexps)
(org-fill-paragraph, org-toggle-fixed-width-section)
(org-yank-generic, org-yank-folding-would-swallow-text)
(org-first-sibling-p, org-goto-sibling)
(org-goto-first-child, org-show-entry): Use
`org-outline-regexp' and `org-outline-regexp-bol'.
* org-remember.el (org-remember-handler): Use
`org-outline-regexp-bol'.
* org-mouse.el (org-mouse-match-todo-keyword, org-mode-hook)
(org-mouse-move-tree, org-mouse-transform-to-outline): Use
`org-outline-regexp' and `org-outline-regexp-bol'.
* org-macs.el (org-with-limited-levels)
(org-get-limited-outline-regexp): Use `org-outline-regexp'.
* org-indent.el (org-indent-outline-re)
(org-indent-refresh-section, org-indent-refresh-to): Use
`org-outline-regexp' and `org-outline-regexp-bol'.
* org-html.el (org-export-as-html): Use
`org-outline-regexp-bol'.
* org-footnote.el (org-footnote-at-definition-p)
(org-footnote-normalize): Use `org-outline-regexp' and
`org-outline-regexp-bol'.
* org-exp.el (org-export-preprocess-string): Don't redefine
`outline-regexp'.
* org-docbook.el (org-export-as-docbook): Use
`org-outline-regexp-bol'.
* org-colview.el (org-columns, org-columns-compute): Use
`org-outline-regexp' and `org-outline-regexp-bol'.
* org-colview-xemacs.el (org-columns, org-columns-compute):
Use `org-outline-regexp-bol'.
* org-clock.el (org-clock-insert-selection-line)
(org-clock-in, org-clock-out, org-dblock-write:clocktable):
Use `org-outline-regexp' and `org-outline-regexp-bol'.
* org-ascii.el (org-export-as-ascii)
(org-export-ascii-push-links): Use `org-outline-regexp' and
`org-outline-regexp-bol'.
* org-archive.el (org-archive-to-archive-sibling)
(org-archive-all-done): Use `org-outline-regexp' and
`org-outline-regexp-bol'.
* org-agenda.el (org-agenda, org-search-view)
(org-agenda-list-stuck-projects, org-agenda-get-timestamps)
(org-agenda-get-progress, org-agenda-get-blocks): Use
`org-outline-regexp' and `org-outline-regexp-bol'.
2011-07-17 19:17:08 +00:00
|
|
|
|
(let* ((re org-outline-regexp-bol)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(lmax 30) ; Does anyone use deeper levels???
|
2009-05-21 05:54:54 +00:00
|
|
|
|
(lvals (make-vector lmax nil))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(lflag (make-vector lmax nil))
|
|
|
|
|
(level 0)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(ass (assoc-string property org-columns-current-fmt-compiled t))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(format (nth 4 ass))
|
|
|
|
|
(printf (nth 5 ass))
|
2009-05-21 05:54:54 +00:00
|
|
|
|
(fun (nth 6 ass))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(beg org-columns-top-level-marker)
|
2012-03-23 21:04:36 +00:00
|
|
|
|
(inminlevel org-inlinetask-min-level)
|
|
|
|
|
(last-level org-inlinetask-min-level)
|
|
|
|
|
val valflag flag end sumpos sum-alist sum str str1 useval)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
;; Find the region to compute
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
(setq end (condition-case nil (org-end-of-subtree t) (error (point-max))))
|
|
|
|
|
(goto-char end)
|
|
|
|
|
;; Walk the tree from the back and do the computations
|
|
|
|
|
(while (re-search-backward re beg t)
|
|
|
|
|
(setq sumpos (match-beginning 0)
|
2012-03-23 21:04:36 +00:00
|
|
|
|
last-level (if (not (or (zerop level) (eq level inminlevel)))
|
|
|
|
|
level last-level)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
level (org-outline-level)
|
|
|
|
|
val (org-entry-get nil property)
|
2016-02-17 20:35:34 +00:00
|
|
|
|
valflag (org-string-nw-p val))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(cond
|
|
|
|
|
((< level last-level)
|
2014-12-16 22:48:41 +00:00
|
|
|
|
;; Put the sum of lower levels here as a property. If
|
2016-02-17 20:35:34 +00:00
|
|
|
|
;; values are estimates, use an appropriate sum function.
|
|
|
|
|
(setq sum (funcall (if (eq fun 'org-columns--estimate-combine)
|
|
|
|
|
#'org-columns--estimate-combine
|
|
|
|
|
#'+)
|
|
|
|
|
(if (and (/= last-level inminlevel)
|
|
|
|
|
(aref lvals last-level))
|
|
|
|
|
(apply fun (aref lvals last-level))
|
|
|
|
|
0)
|
|
|
|
|
(if (aref lvals inminlevel)
|
|
|
|
|
(apply fun (aref lvals inminlevel))
|
|
|
|
|
0))
|
2012-03-23 21:04:36 +00:00
|
|
|
|
flag (or (aref lflag last-level) ; any valid entries from children?
|
|
|
|
|
(aref lflag inminlevel)) ; or inline tasks?
|
2008-04-09 13:42:36 +00:00
|
|
|
|
str (org-columns-number-to-string sum format printf)
|
|
|
|
|
str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
|
|
|
|
|
useval (if flag str1 (if valflag val ""))
|
|
|
|
|
sum-alist (get-text-property sumpos 'org-summaries))
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(let ((old (assoc-string property sum-alist t)))
|
|
|
|
|
(if old (setcdr old useval)
|
|
|
|
|
(push (cons property useval) sum-alist)
|
|
|
|
|
(org-with-silent-modifications
|
|
|
|
|
(add-text-properties sumpos (1+ sumpos)
|
|
|
|
|
(list 'org-summaries sum-alist)))))
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(when (and val (not (equal val (if flag str val))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(org-entry-put nil property (if flag str val)))
|
2009-08-28 12:50:51 +00:00
|
|
|
|
;; add current to current level accumulator
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(when (or flag valflag)
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(push (if flag sum (org-columns-string-to-number val format))
|
2009-05-21 05:54:54 +00:00
|
|
|
|
(aref lvals level))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(aset lflag level t))
|
|
|
|
|
;; clear accumulators for deeper levels
|
|
|
|
|
(loop for l from (1+ level) to (1- lmax) do
|
2009-05-21 05:54:54 +00:00
|
|
|
|
(aset lvals l nil)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(aset lflag l nil)))
|
|
|
|
|
((>= level last-level)
|
|
|
|
|
;; add what we have here to the accumulator for this level
|
2009-05-21 08:47:56 +00:00
|
|
|
|
(when valflag
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(push (org-columns-string-to-number val format) (aref lvals level))
|
2009-05-21 08:47:56 +00:00
|
|
|
|
(aset lflag level t)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(t (error "This should not happen")))))))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-redo ()
|
|
|
|
|
"Construct the column display again."
|
|
|
|
|
(interactive)
|
|
|
|
|
(message "Recomputing columns...")
|
2008-05-29 06:50:44 +00:00
|
|
|
|
(let ((line (org-current-line))
|
|
|
|
|
(col (current-column)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(if (marker-position org-columns-begin-marker)
|
|
|
|
|
(goto-char org-columns-begin-marker))
|
|
|
|
|
(org-columns-remove-overlays)
|
Use (derived-mode-p 'org-mode) instead of (eq major-mode 'org-mode).
* org.el (org-show-hierarchy-above, org-cycle)
(org-global-cycle, org-files-list, org-store-link)
(org-link-search, org-open-file, org-display-outline-path)
(org-refile-get-location, org-update-all-dblocks)
(org-change-tag-in-region, org-entry-properties)
(org-save-all-org-buffers, org-revert-all-org-buffers)
(org-buffer-list, org-cdlatex-mode)
(org-install-agenda-files-menu, org-end-of-subtree)
(org-speedbar-set-agenda-restriction): Use (derived-mode-p
'org-mode) instead of (eq major-mode 'org-mode).
* org-timer.el (org-timer-set-timer): Ditto.
* org-table.el (orgtbl-mode, org-table-align, orgtbl-mode): Ditto.
* org-src.el (org-edit-src-exit, org-edit-src-code)
(org-edit-fixed-width-region, org-edit-src-exit): Ditto.
* org-remember.el (org-remember-handler): Ditto.
* org-mouse.el (dnd-open-file, org-mouse-insert-item): Ditto.
* org-macs.el (org-get-limited-outline-regexp): Ditto.
* org-lparse.el (org-replace-region-by): Ditto.
* org-latex.el (org-latex-to-pdf-process)
(org-replace-region-by-latex): Ditto.
* org-indent.el (org-indent-indent-buffer): Ditto.
* org-id.el (org-id-store-link, org-id-update-id-locations)
(org-id-store-link): Ditto.
* org-html.el (org-export-html-preprocess)
(org-replace-region-by-html): Ditto.
* org-footnote.el (org-footnote-normalize)
(org-footnote-goto-definition)
(org-footnote-create-definition, org-footnote-normalize): Ditto.
* org-docbook.el (org-replace-region-by-docbook): Ditto.
* org-ctags.el (find-tag): Ditto.
* org-colview.el (org-columns-redo)
(org-columns-display-here, org-columns-edit-value)
(org-columns-redo): Ditto.
* org-colview-xemacs.el (org-columns-redo)
(org-columns-display-here, org-columns-edit-value)
(org-columns-redo): Ditto.
* org-capture.el (org-capture-insert-template-here)
(org-capture, org-capture-finalize)
(org-capture-set-target-location)
(org-capture-insert-template-here): Ditto.
* org-ascii.el (org-replace-region-by-ascii): Ditto.
* org-archive.el (org-archive-subtree): Ditto.
* org-agenda.el (org-agenda)
(org-agenda-get-restriction-and-command)
(org-agenda-get-some-entry-text, org-search-view)
(org-tags-view, org-agenda-get-day-entries)
(org-agenda-format-item, org-agenda-goto, org-agenda-kill)
(org-agenda-archive-with, org-agenda-switch-to): Ditto.
2012-04-20 18:03:45 +00:00
|
|
|
|
(if (derived-mode-p 'org-mode)
|
2008-05-29 06:50:44 +00:00
|
|
|
|
(call-interactively 'org-columns)
|
|
|
|
|
(org-agenda-redo)
|
|
|
|
|
(call-interactively 'org-agenda-columns)))
|
2009-08-27 08:24:09 +00:00
|
|
|
|
(org-goto-line line)
|
2008-05-29 06:50:44 +00:00
|
|
|
|
(move-to-column col))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(message "Recomputing columns...done"))
|
|
|
|
|
|
2013-11-15 05:53:59 +00:00
|
|
|
|
;;;###autoload
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-columns-number-to-string (n fmt &optional printf)
|
2016-02-15 23:02:48 +00:00
|
|
|
|
"Convert a computed column number N to a string value.
|
|
|
|
|
FMT is a symbol describing the summary type. Optional argument
|
|
|
|
|
PRINTF, when non-nil, is a format string used to print N."
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(cond
|
2016-02-17 20:35:34 +00:00
|
|
|
|
((eq fmt 'estimate)
|
|
|
|
|
(let ((fmt (or printf "%.0f")))
|
|
|
|
|
(mapconcat (lambda (n) (format fmt n)) (if (consp n) n (list n n)) "-")))
|
2009-05-21 08:47:56 +00:00
|
|
|
|
((not (numberp n)) "")
|
2009-05-21 05:54:54 +00:00
|
|
|
|
((memq fmt '(add_times max_times min_times mean_times))
|
2012-11-11 22:20:24 +00:00
|
|
|
|
(org-hours-to-clocksum-string n))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
((eq fmt 'checkbox)
|
|
|
|
|
(cond ((= n (floor n)) "[X]")
|
|
|
|
|
((> n 1.) "[-]")
|
|
|
|
|
(t "[ ]")))
|
|
|
|
|
((memq fmt '(checkbox-n-of-m checkbox-percent))
|
2016-02-15 23:02:48 +00:00
|
|
|
|
(let* ((n1 (floor n))
|
|
|
|
|
(n2 (+ (floor (+ .5 (* 1000000 (- n n1)))) n1)))
|
|
|
|
|
(cond ((not (eq fmt 'checkbox-percent)) (format "[%d/%d]" n1 n2))
|
|
|
|
|
((or (= n1 0) (= n2 0)) "[0%]")
|
|
|
|
|
(t (format "[%d%%]" (round (* 100.0 n1) n2))))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(printf (format printf n))
|
2016-02-15 23:02:48 +00:00
|
|
|
|
((eq fmt 'currency) (format "%.2f" n))
|
2009-10-30 03:16:18 +00:00
|
|
|
|
((memq fmt '(min_age max_age mean_age))
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(format-seconds "%dd %.2hh %mm %ss" n))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(t (number-to-string n))))
|
|
|
|
|
|
2016-02-17 20:35:34 +00:00
|
|
|
|
(defun org-columns--estimate-combine (&rest estimates)
|
|
|
|
|
"Combine a list of estimates, using mean and variance.
|
|
|
|
|
The mean and variance of the result will be the sum of the means
|
|
|
|
|
and variances (respectively) of the individual estimates."
|
|
|
|
|
(let ((mean 0)
|
|
|
|
|
(var 0))
|
|
|
|
|
(dolist (e estimates)
|
|
|
|
|
(pcase e
|
|
|
|
|
(`(,low ,high)
|
|
|
|
|
(let ((m (/ (+ low high) 2.0)))
|
|
|
|
|
(cl-incf mean m)
|
|
|
|
|
(cl-incf var (- (/ (+ (* low low) (* high high)) 2.0) (* m m)))))
|
|
|
|
|
(value (cl-incf mean value))))
|
|
|
|
|
(let ((sd (sqrt var)))
|
|
|
|
|
(list (- mean sd) (+ mean sd)))))
|
|
|
|
|
|
2009-08-28 12:50:51 +00:00
|
|
|
|
(defun org-columns-string-to-number (s fmt)
|
2016-02-17 14:16:22 +00:00
|
|
|
|
"Convert a column value S to a number.
|
|
|
|
|
FMT is a symbol describing the summary type."
|
|
|
|
|
(cond
|
|
|
|
|
((not s) nil)
|
|
|
|
|
((memq fmt '(min_age max_age mean_age))
|
|
|
|
|
(cond
|
|
|
|
|
((string= s "") org-columns--time)
|
|
|
|
|
((string-match "\\`\\(?: *\\([0-9]+\\)d\\)?\\(?: *\\([0-9]+\\)h\\)?\
|
|
|
|
|
\\(?: *\\([0-9]+\\)m\\)?\\(?: *\\([0-9]+\\)s\\)?\\'" s)
|
|
|
|
|
(let ((d (if (match-end 1) (string-to-number (match-string 1 s)) 0))
|
|
|
|
|
(h (if (match-end 2) (string-to-number (match-string 2 s)) 0))
|
|
|
|
|
(m (if (match-end 3) (string-to-number (match-string 3 s)) 0))
|
|
|
|
|
(s (if (match-end 4) (string-to-number (match-string 4 s)) 0)))
|
|
|
|
|
(+ (* 60 (+ (* 60 (+ (* 24 d) h)) m)) s)))
|
|
|
|
|
(t
|
|
|
|
|
(- org-columns--time
|
|
|
|
|
(float-time (apply #'encode-time (org-parse-time-string s)))))))
|
|
|
|
|
((string-match-p ":" s) ;Interpret HH:MM:SS.
|
|
|
|
|
(let ((sum 0.0))
|
|
|
|
|
(dolist (n (nreverse (split-string s ":")) sum)
|
|
|
|
|
(setq sum (+ (string-to-number n) (/ sum 60))))))
|
|
|
|
|
((memq fmt '(checkbox checkbox-n-of-m checkbox-percent))
|
|
|
|
|
(if (equal s "[X]") 1. 0.000001))
|
2016-02-17 20:35:34 +00:00
|
|
|
|
((eq fmt 'estimate)
|
|
|
|
|
(if (not (string-match "\\(.*\\)-\\(.*\\)" s))
|
|
|
|
|
(string-to-number s)
|
|
|
|
|
(list (string-to-number (match-string 1 s))
|
|
|
|
|
(string-to-number (match-string 2 s)))))
|
2016-02-17 14:16:22 +00:00
|
|
|
|
((string-match-p org-columns--fractional-duration-re s)
|
|
|
|
|
(let ((s (concat "0:" (org-duration-string-to-minutes s t)))
|
|
|
|
|
(sum 0.0))
|
|
|
|
|
(dolist (n (nreverse (split-string s ":")) sum)
|
|
|
|
|
(setq sum (+ (string-to-number n) (/ sum 60))))))
|
|
|
|
|
(t (string-to-number s))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
|
|
|
|
(defun org-columns-uncompile-format (cfmt)
|
|
|
|
|
"Turn the compiled columns format back into a string representation."
|
2015-10-26 00:56:00 +00:00
|
|
|
|
(let ((rtn "") e s prop title op width fmt printf ee map)
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(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)
|
2015-10-26 00:56:00 +00:00
|
|
|
|
printf (nth 5 e))
|
2013-11-26 17:23:35 +00:00
|
|
|
|
(setq map (copy-sequence org-columns-compile-map))
|
2013-11-26 12:14:06 +00:00
|
|
|
|
(while (setq ee (pop map))
|
|
|
|
|
(if (equal fmt (nth 1 ee))
|
|
|
|
|
(setq op (car ee) map nil)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(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))
|
|
|
|
|
prop
|
|
|
|
|
(if title (concat "(" title ")"))
|
|
|
|
|
(if op (concat "{" op "}"))))
|
|
|
|
|
(setq rtn (concat rtn " " s)))
|
|
|
|
|
(org-trim rtn)))
|
|
|
|
|
|
|
|
|
|
(defun org-columns-compile-format (fmt)
|
2015-06-02 19:14:55 +00:00
|
|
|
|
"Turn a column format string FMT into an alist of specifications.
|
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
The alist has one entry for each column in the format. The elements of
|
|
|
|
|
that list are:
|
|
|
|
|
property the property
|
|
|
|
|
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
|
2009-05-21 05:54:54 +00:00
|
|
|
|
printf a printf format for computed values
|
2009-08-28 12:50:51 +00:00
|
|
|
|
fun the lisp function to compute summary values, derived from operator
|
2015-06-02 19:14:55 +00:00
|
|
|
|
|
|
|
|
|
This function updates `org-columns-current-fmt-compiled'."
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(setq org-columns-current-fmt-compiled nil)
|
|
|
|
|
(let ((start 0))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(while (string-match
|
2016-02-17 14:36:31 +00:00
|
|
|
|
"%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\
|
|
|
|
|
\\(?:{\\([^}]+\\)}\\)?\\s-*"
|
2008-04-09 13:42:36 +00:00
|
|
|
|
fmt start)
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(setq start (match-end 0))
|
|
|
|
|
(let* ((width (and (match-end 1) (string-to-number (match-string 1 fmt))))
|
|
|
|
|
(prop (match-string 2 fmt))
|
|
|
|
|
(title (or (match-string 3 fmt) prop))
|
|
|
|
|
(op (match-string 4 fmt))
|
|
|
|
|
(f nil)
|
|
|
|
|
(printf nil)
|
|
|
|
|
(fun '+))
|
|
|
|
|
(when (and op (string-match ";" op))
|
|
|
|
|
(setq printf (substring op (match-end 0)))
|
|
|
|
|
(setq op (substring op 0 (match-beginning 0))))
|
|
|
|
|
(let ((op-match (assoc op org-columns-compile-map)))
|
|
|
|
|
(when op-match
|
|
|
|
|
(setq f (nth 1 op-match))
|
|
|
|
|
(setq fun (nth 2 op-match))))
|
|
|
|
|
(push (list prop title width op f printf fun)
|
|
|
|
|
org-columns-current-fmt-compiled)))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(setq org-columns-current-fmt-compiled
|
|
|
|
|
(nreverse org-columns-current-fmt-compiled))))
|
|
|
|
|
|
|
|
|
|
|
2016-02-14 13:06:32 +00:00
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
;;; Dynamic block for Column view
|
|
|
|
|
|
2016-02-14 13:06:32 +00:00
|
|
|
|
(defun org-columns--capture-view (maxlevel skip-empty format local)
|
|
|
|
|
"Get the column view of the current buffer.
|
|
|
|
|
|
|
|
|
|
MAXLEVEL sets the level limit. SKIP-EMPTY tells whether to skip
|
2008-04-09 13:42:36 +00:00
|
|
|
|
empty rows, an empty row being one where all the column view
|
2016-02-14 13:06:32 +00:00
|
|
|
|
specifiers but ITEM are empty. FORMAT is a format string for
|
|
|
|
|
columns, or nil. When LOCAL is non-nil, only capture headings in
|
|
|
|
|
current subtree.
|
|
|
|
|
|
|
|
|
|
This function returns a list containing the title row and all
|
|
|
|
|
other rows. Each row is a list of fields, as strings, or
|
|
|
|
|
`hline'."
|
|
|
|
|
(org-columns (not local) format)
|
|
|
|
|
(goto-char org-columns-top-level-marker)
|
|
|
|
|
(let ((columns (length org-columns-current-fmt-compiled))
|
|
|
|
|
(has-item (assoc-string "ITEM" org-columns-current-fmt-compiled t))
|
|
|
|
|
table)
|
|
|
|
|
(org-map-entries
|
|
|
|
|
(lambda ()
|
|
|
|
|
(when (get-char-property (point) 'org-columns-key)
|
|
|
|
|
(let (row)
|
|
|
|
|
(dotimes (i columns)
|
|
|
|
|
(let* ((col (+ (line-beginning-position) i))
|
|
|
|
|
(p (get-char-property col 'org-columns-key)))
|
|
|
|
|
(push (org-quote-vert
|
|
|
|
|
(get-char-property col
|
|
|
|
|
(if (string= (upcase p) "ITEM")
|
|
|
|
|
'org-columns-value
|
|
|
|
|
'org-columns-value-modified)))
|
|
|
|
|
row)))
|
|
|
|
|
(unless (and skip-empty
|
|
|
|
|
(let ((r (delete-dups (remove "" row))))
|
|
|
|
|
(or (null r) (and has-item (= (length r) 1)))))
|
|
|
|
|
(push (cons (org-reduced-level (org-current-level)) (nreverse row))
|
|
|
|
|
table)))))
|
|
|
|
|
(and maxlevel (format "LEVEL<=%d" maxlevel))
|
|
|
|
|
(and local 'tree)
|
|
|
|
|
'archive 'comment)
|
|
|
|
|
(org-columns-quit)
|
|
|
|
|
;; Add column titles and a horizontal rule in front of the table.
|
|
|
|
|
(cons (mapcar #'cadr org-columns-current-fmt-compiled)
|
|
|
|
|
(cons 'hline (nreverse table)))))
|
|
|
|
|
|
|
|
|
|
(defun org-columns--clean-item (item)
|
|
|
|
|
"Remove sensitive contents from string ITEM.
|
|
|
|
|
This includes objects that may not be duplicated within
|
|
|
|
|
a document, e.g., a target, or those forbidden in tables, e.g.,
|
|
|
|
|
an inline src-block."
|
|
|
|
|
(let ((data (org-element-parse-secondary-string
|
|
|
|
|
item (org-element-restriction 'headline))))
|
|
|
|
|
(org-element-map data
|
|
|
|
|
'(footnote-reference inline-babel-call inline-src-block target
|
|
|
|
|
radio-target statistics-cookie)
|
|
|
|
|
#'org-element-extract-element)
|
|
|
|
|
(org-no-properties (org-element-interpret-data data))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
Update autoloads.
* org.el: Don't dynamically autoload already autoloaded
functions.
(org-clock-update-time-maybe): Move to org-clock.el.
* org-exp.el (org-insert-export-options-template): Remove
autoload cookie.
* org-clock.el (org-resolve-clocks, org-clock-in)
(org-clock-out, org-clock-cancel, org-clock-goto)
(org-clock-sum, org-clock-display, org-clock-report)
(org-dblock-write:clocktable): Add autoload cookie.
(org-clock-update-time-maybe): Moved from org.el.
* org-beamer.el (org-beamer-sectioning, org-beamer-mode): Ditto.
* org-ascii.el (org-export-ascii-preprocess): Ditto.
* org-archive.el (org-archive-subtree)
(org-archive-to-archive-sibling, org-toggle-archive-tag): Add
autoload cookie.
* org-colview.el (org-columns, org-dblock-write:columnview)
(org-insert-columns-dblock, org-agenda-columns): Ditto.
* org-table.el (org-table-create-with-table.el)
(org-table-create-or-convert-from-region, org-table-create)
(org-table-convert-region, org-table-import)
(org-table-export, org-table-align)
(org-table-justify-field-maybe, org-table-next-field)
(org-table-previous-field, org-table-next-row)
(org-table-copy-down, org-table-field-info)
(org-table-current-dline, org-table-goto-column)
(org-table-insert-column, org-table-delete-column)
(org-table-move-column-right, org-table-move-column-left)
(org-table-move-column, org-table-move-row-down)
(org-table-move-row-up, org-table-move-row)
(org-table-insert-row, org-table-insert-hline)
(org-table-hline-and-move, org-table-kill-row)
(org-table-sort-lines, org-table-cut-region)
(org-table-copy-region, org-table-paste-rectangle)
(org-table-convert, org-table-wrap-region)
(org-table-edit-field, org-table-sum)
(org-table-get-stored-formulas)
(org-table-maybe-eval-formula)
(org-table-rotate-recalc-marks)
(org-table-maybe-recalculate-line, org-table-eval-formula)
(org-table-recalculate, org-table-iterate)
(org-table-edit-formulas)
(org-table-toggle-coordinate-overlays)
(org-table-toggle-formula-debugger, orgtbl-to-generic)
(orgtbl-to-tsv, orgtbl-to-csv, orgtbl-to-latex)
(orgtbl-to-html, orgtbl-to-texinfo, orgtbl-to-orgtbl): Ditto.
2012-10-02 08:52:17 +00:00
|
|
|
|
;;;###autoload
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(defun org-dblock-write:columnview (params)
|
|
|
|
|
"Write the column view table.
|
|
|
|
|
PARAMS is a property list of parameters:
|
|
|
|
|
|
|
|
|
|
:id the :ID: property of the entry where the columns view
|
2009-08-28 12:50:51 +00:00
|
|
|
|
should be built. When the symbol `local', call locally.
|
|
|
|
|
When `global' call column view with the cursor at the beginning
|
|
|
|
|
of the buffer (usually this means that the whole buffer switches
|
|
|
|
|
to column view). When \"file:path/to/file.org\", invoke column
|
|
|
|
|
view at the start of that file. Otherwise, the ID is located
|
|
|
|
|
using `org-id-find'.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
:hlines When t, insert a hline before each item. When a number, insert
|
2009-08-28 12:50:51 +00:00
|
|
|
|
a hline before each level <= that number.
|
2016-02-14 13:06:32 +00:00
|
|
|
|
:indent When non-nil, indent each ITEM field according to its level.
|
2008-04-09 13:42:36 +00:00
|
|
|
|
:vlines When t, make each column a colgroup to enforce vertical lines.
|
|
|
|
|
:maxlevel When set to a number, don't capture headlines below this level.
|
|
|
|
|
:skip-empty-rows
|
2012-08-12 09:48:44 +00:00
|
|
|
|
When t, skip rows where all specifiers other than ITEM are empty.
|
2016-02-14 13:06:32 +00:00
|
|
|
|
:width apply widths specified in columns format using <N> specifiers.
|
2012-08-12 09:48:44 +00:00
|
|
|
|
:format When non-nil, specify the column view format to use."
|
2016-02-14 13:06:32 +00:00
|
|
|
|
(let ((table
|
|
|
|
|
(let ((id (plist-get params :id))
|
|
|
|
|
view-file view-pos)
|
|
|
|
|
(pcase id
|
|
|
|
|
(`global nil)
|
|
|
|
|
((or `local `nil) (setq view-pos (point)))
|
|
|
|
|
((and (let id-string (format "%s" id))
|
|
|
|
|
(guard (string-match "^file:\\(.*\\)" id-string)))
|
|
|
|
|
(setq view-file (match-string-no-properties 1 id-string))
|
|
|
|
|
(unless (file-exists-p view-file)
|
|
|
|
|
(user-error "No such file: %S" id-string)))
|
|
|
|
|
((and (let idpos (org-find-entry-with-id id)) idpos)
|
|
|
|
|
(setq view-pos idpos))
|
|
|
|
|
((let `(,filename . ,position) (org-id-find id))
|
|
|
|
|
(setq view-file filename)
|
|
|
|
|
(setq view-pos position))
|
|
|
|
|
(_ (user-error "Cannot find entry with :ID: %s" id)))
|
|
|
|
|
(with-current-buffer (if view-file (get-file-buffer view-file)
|
|
|
|
|
(current-buffer))
|
|
|
|
|
(org-with-wide-buffer
|
|
|
|
|
(when view-pos (goto-char view-pos))
|
|
|
|
|
(org-columns--capture-view (plist-get params :maxlevel)
|
|
|
|
|
(plist-get params :skip-empty-rows)
|
|
|
|
|
(plist-get params :format)
|
|
|
|
|
view-pos))))))
|
|
|
|
|
(when table
|
|
|
|
|
;; Prune level information from the table. Also normalize
|
|
|
|
|
;; headings: remove stars, add indentation entities, if
|
|
|
|
|
;; required, and possibly precede some of them with a horizontal
|
|
|
|
|
;; rule.
|
2016-02-11 23:38:52 +00:00
|
|
|
|
(let ((item-index
|
|
|
|
|
(let ((p (assoc-string "ITEM" org-columns-current-fmt-compiled t)))
|
|
|
|
|
(and p (cl-position p
|
|
|
|
|
org-columns-current-fmt-compiled
|
|
|
|
|
:test #'equal))))
|
|
|
|
|
(hlines (plist-get params :hlines))
|
2016-02-14 13:06:32 +00:00
|
|
|
|
(indent (plist-get params :indent))
|
|
|
|
|
new-table)
|
|
|
|
|
;; Copy header and first rule.
|
|
|
|
|
(push (pop table) new-table)
|
|
|
|
|
(push (pop table) new-table)
|
|
|
|
|
(dolist (row table (setq table (nreverse new-table)))
|
|
|
|
|
(let ((level (car row)))
|
|
|
|
|
(when (and (not (eq (car new-table) 'hline))
|
|
|
|
|
(or (eq hlines t)
|
|
|
|
|
(and (numberp hlines) (<= level hlines))))
|
|
|
|
|
(push 'hline new-table))
|
|
|
|
|
(when item-index
|
|
|
|
|
(let ((item (org-columns--clean-item (nth item-index (cdr row)))))
|
|
|
|
|
(setf (nth item-index (cdr row))
|
|
|
|
|
(if (and indent (> level 1))
|
|
|
|
|
(concat "\\_" (make-string (* 2 (1- level)) ?\s) item)
|
|
|
|
|
item))))
|
|
|
|
|
(push (cdr row) new-table))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(when (plist-get params :width)
|
2016-02-14 13:06:32 +00:00
|
|
|
|
(setq table
|
|
|
|
|
(append table
|
|
|
|
|
(list
|
|
|
|
|
(mapcar (lambda (spec)
|
|
|
|
|
(let ((w (nth 2 spec)))
|
|
|
|
|
(if w (format "<%d>" (max 3 w)) "")))
|
|
|
|
|
org-columns-current-fmt-compiled)))))
|
|
|
|
|
(when (plist-get params :vlines)
|
|
|
|
|
(setq table
|
|
|
|
|
(let ((size (length org-columns-current-fmt-compiled)))
|
|
|
|
|
(append (mapcar (lambda (x) (if (eq 'hline x) x (cons "" x)))
|
|
|
|
|
table)
|
|
|
|
|
(list (cons "/" (make-list size "<>")))))))
|
|
|
|
|
(let ((content-lines (org-split-string (plist-get params :content) "\n"))
|
|
|
|
|
recalc)
|
|
|
|
|
;; Insert affiliated keywords before the table.
|
|
|
|
|
(when content-lines
|
|
|
|
|
(while (string-match-p "\\`[ \t]*#\\+" (car content-lines))
|
|
|
|
|
(insert (pop content-lines) "\n")))
|
|
|
|
|
(save-excursion
|
|
|
|
|
;; Insert table at point.
|
|
|
|
|
(insert
|
|
|
|
|
(mapconcat (lambda (row)
|
|
|
|
|
(if (eq row 'hline) "|-|"
|
|
|
|
|
(format "|%s|" (mapconcat #'identity row "|"))))
|
|
|
|
|
table
|
|
|
|
|
"\n"))
|
|
|
|
|
;; Insert TBLFM lines following table.
|
|
|
|
|
(let ((case-fold-search t))
|
|
|
|
|
(dolist (line content-lines)
|
|
|
|
|
(when (string-match-p "\\`[ \t]*#\\+TBLFM:" line)
|
|
|
|
|
(insert "\n" line)
|
|
|
|
|
(unless recalc (setq recalc t))))))
|
|
|
|
|
(when recalc (org-table-recalculate 'all t))
|
2008-09-08 07:43:41 +00:00
|
|
|
|
(org-table-align)))))
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
Update autoloads.
* org.el: Don't dynamically autoload already autoloaded
functions.
(org-clock-update-time-maybe): Move to org-clock.el.
* org-exp.el (org-insert-export-options-template): Remove
autoload cookie.
* org-clock.el (org-resolve-clocks, org-clock-in)
(org-clock-out, org-clock-cancel, org-clock-goto)
(org-clock-sum, org-clock-display, org-clock-report)
(org-dblock-write:clocktable): Add autoload cookie.
(org-clock-update-time-maybe): Moved from org.el.
* org-beamer.el (org-beamer-sectioning, org-beamer-mode): Ditto.
* org-ascii.el (org-export-ascii-preprocess): Ditto.
* org-archive.el (org-archive-subtree)
(org-archive-to-archive-sibling, org-toggle-archive-tag): Add
autoload cookie.
* org-colview.el (org-columns, org-dblock-write:columnview)
(org-insert-columns-dblock, org-agenda-columns): Ditto.
* org-table.el (org-table-create-with-table.el)
(org-table-create-or-convert-from-region, org-table-create)
(org-table-convert-region, org-table-import)
(org-table-export, org-table-align)
(org-table-justify-field-maybe, org-table-next-field)
(org-table-previous-field, org-table-next-row)
(org-table-copy-down, org-table-field-info)
(org-table-current-dline, org-table-goto-column)
(org-table-insert-column, org-table-delete-column)
(org-table-move-column-right, org-table-move-column-left)
(org-table-move-column, org-table-move-row-down)
(org-table-move-row-up, org-table-move-row)
(org-table-insert-row, org-table-insert-hline)
(org-table-hline-and-move, org-table-kill-row)
(org-table-sort-lines, org-table-cut-region)
(org-table-copy-region, org-table-paste-rectangle)
(org-table-convert, org-table-wrap-region)
(org-table-edit-field, org-table-sum)
(org-table-get-stored-formulas)
(org-table-maybe-eval-formula)
(org-table-rotate-recalc-marks)
(org-table-maybe-recalculate-line, org-table-eval-formula)
(org-table-recalculate, org-table-iterate)
(org-table-edit-formulas)
(org-table-toggle-coordinate-overlays)
(org-table-toggle-formula-debugger, orgtbl-to-generic)
(orgtbl-to-tsv, orgtbl-to-csv, orgtbl-to-latex)
(orgtbl-to-html, orgtbl-to-texinfo, orgtbl-to-orgtbl): Ditto.
2012-10-02 08:52:17 +00:00
|
|
|
|
;;;###autoload
|
2016-02-17 14:54:07 +00:00
|
|
|
|
(defun org-columns-insert-dblock ()
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Create a dynamic block capturing a column view table."
|
|
|
|
|
(interactive)
|
2016-02-17 14:54:07 +00:00
|
|
|
|
(let ((id (completing-read
|
2008-04-09 13:42:36 +00:00
|
|
|
|
"Capture columns (local, global, entry with :ID: property) [local]: "
|
|
|
|
|
(append '(("global") ("local"))
|
2015-12-22 13:49:23 +00:00
|
|
|
|
(mapcar #'list (org-property-values "ID"))))))
|
2016-02-17 14:54:07 +00:00
|
|
|
|
(org-create-dblock
|
|
|
|
|
(list :name "columnview"
|
|
|
|
|
:hlines 1
|
|
|
|
|
:id (cond ((string= id "global") 'global)
|
|
|
|
|
((member id '("" "local")) 'local)
|
|
|
|
|
(id)))))
|
|
|
|
|
(org-update-dblock))
|
|
|
|
|
|
|
|
|
|
(define-obsolete-function-alias 'org-insert-columns-dblock
|
|
|
|
|
'org-columns-insert-dblock "Org 9.0")
|
2008-04-09 13:42:36 +00:00
|
|
|
|
|
2016-02-14 13:06:32 +00:00
|
|
|
|
|
|
|
|
|
|
2008-04-15 12:01:59 +00:00
|
|
|
|
;;; Column view in the agenda
|
|
|
|
|
|
Update autoloads.
* org.el: Don't dynamically autoload already autoloaded
functions.
(org-clock-update-time-maybe): Move to org-clock.el.
* org-exp.el (org-insert-export-options-template): Remove
autoload cookie.
* org-clock.el (org-resolve-clocks, org-clock-in)
(org-clock-out, org-clock-cancel, org-clock-goto)
(org-clock-sum, org-clock-display, org-clock-report)
(org-dblock-write:clocktable): Add autoload cookie.
(org-clock-update-time-maybe): Moved from org.el.
* org-beamer.el (org-beamer-sectioning, org-beamer-mode): Ditto.
* org-ascii.el (org-export-ascii-preprocess): Ditto.
* org-archive.el (org-archive-subtree)
(org-archive-to-archive-sibling, org-toggle-archive-tag): Add
autoload cookie.
* org-colview.el (org-columns, org-dblock-write:columnview)
(org-insert-columns-dblock, org-agenda-columns): Ditto.
* org-table.el (org-table-create-with-table.el)
(org-table-create-or-convert-from-region, org-table-create)
(org-table-convert-region, org-table-import)
(org-table-export, org-table-align)
(org-table-justify-field-maybe, org-table-next-field)
(org-table-previous-field, org-table-next-row)
(org-table-copy-down, org-table-field-info)
(org-table-current-dline, org-table-goto-column)
(org-table-insert-column, org-table-delete-column)
(org-table-move-column-right, org-table-move-column-left)
(org-table-move-column, org-table-move-row-down)
(org-table-move-row-up, org-table-move-row)
(org-table-insert-row, org-table-insert-hline)
(org-table-hline-and-move, org-table-kill-row)
(org-table-sort-lines, org-table-cut-region)
(org-table-copy-region, org-table-paste-rectangle)
(org-table-convert, org-table-wrap-region)
(org-table-edit-field, org-table-sum)
(org-table-get-stored-formulas)
(org-table-maybe-eval-formula)
(org-table-rotate-recalc-marks)
(org-table-maybe-recalculate-line, org-table-eval-formula)
(org-table-recalculate, org-table-iterate)
(org-table-edit-formulas)
(org-table-toggle-coordinate-overlays)
(org-table-toggle-formula-debugger, orgtbl-to-generic)
(orgtbl-to-tsv, orgtbl-to-csv, orgtbl-to-latex)
(orgtbl-to-html, orgtbl-to-texinfo, orgtbl-to-orgtbl): Ditto.
2012-10-02 08:52:17 +00:00
|
|
|
|
;;;###autoload
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(defun org-agenda-columns ()
|
2008-04-18 13:24:58 +00:00
|
|
|
|
"Turn on or update column view in the agenda."
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(org-columns-remove-overlays)
|
|
|
|
|
(move-marker org-columns-begin-marker (point))
|
2016-02-17 14:16:22 +00:00
|
|
|
|
(let ((org-columns--time (float-time (current-time)))
|
2015-06-02 19:56:50 +00:00
|
|
|
|
(fmt
|
|
|
|
|
(cond
|
|
|
|
|
((org-bound-and-true-p org-agenda-overriding-columns-format))
|
|
|
|
|
((let ((m (org-get-at-bol 'org-hd-marker)))
|
|
|
|
|
(and m
|
|
|
|
|
(or (org-entry-get m "COLUMNS" t)
|
|
|
|
|
(with-current-buffer (marker-buffer m)
|
|
|
|
|
org-columns-default-format)))))
|
|
|
|
|
((and (local-variable-p 'org-columns-current-fmt)
|
|
|
|
|
org-columns-current-fmt))
|
|
|
|
|
((let ((m (next-single-property-change (point-min) 'org-hd-marker)))
|
|
|
|
|
(and m
|
|
|
|
|
(let ((m (get-text-property m 'org-hd-marker)))
|
|
|
|
|
(or (org-entry-get m "COLUMNS" t)
|
|
|
|
|
(with-current-buffer (marker-buffer m)
|
|
|
|
|
org-columns-default-format))))))
|
|
|
|
|
(t org-columns-default-format))))
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(setq-local org-columns-current-fmt fmt)
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(org-columns-compile-format fmt)
|
2008-04-17 16:26:27 +00:00
|
|
|
|
(when org-agenda-columns-compute-summary-properties
|
|
|
|
|
(org-agenda-colview-compute org-columns-current-fmt-compiled))
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(save-excursion
|
2015-06-02 19:56:50 +00:00
|
|
|
|
;; Collect properties for each headline in current view.
|
2008-04-15 12:01:59 +00:00
|
|
|
|
(goto-char (point-min))
|
2015-06-02 19:56:50 +00:00
|
|
|
|
(let (cache)
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(while (not (eobp))
|
|
|
|
|
(let ((m (or (org-get-at-bol 'org-hd-marker)
|
|
|
|
|
(org-get-at-bol 'org-marker))))
|
|
|
|
|
(when m
|
|
|
|
|
(push (cons (line-beginning-position)
|
|
|
|
|
(org-with-point-at m
|
|
|
|
|
(org-columns--collect-values 'agenda)))
|
|
|
|
|
cache)))
|
|
|
|
|
(forward-line))
|
2015-06-02 19:56:50 +00:00
|
|
|
|
(when cache
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(setq-local org-columns-current-maxwidths
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(org-columns--autowidth-alist cache))
|
|
|
|
|
(org-columns--display-here-title)
|
2015-11-05 16:47:38 +00:00
|
|
|
|
(when (setq-local org-columns-flyspell-was-active
|
2016-02-05 23:04:35 +00:00
|
|
|
|
(org-bound-and-true-p flyspell-mode))
|
2015-06-02 19:56:50 +00:00
|
|
|
|
(flyspell-mode 0))
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(dolist (entry cache)
|
|
|
|
|
(goto-char (car entry))
|
|
|
|
|
(org-columns--display-here (cdr entry)))
|
2015-06-02 19:56:50 +00:00
|
|
|
|
(when org-agenda-columns-show-summaries
|
|
|
|
|
(org-agenda-colview-summarize cache)))))))
|
2008-04-15 12:01:59 +00:00
|
|
|
|
|
|
|
|
|
(defun org-agenda-colview-summarize (cache)
|
|
|
|
|
"Summarize the summarizable columns in column view in the agenda.
|
|
|
|
|
This will add overlays to the date lines, to show the summary for each day."
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(let ((fmt (mapcar
|
|
|
|
|
(lambda (spec)
|
|
|
|
|
(pcase spec
|
|
|
|
|
(`(,property ,title ,width . ,_)
|
|
|
|
|
(if (member-ignore-case property '("CLOCKSUM" "CLOCKSUM_T"))
|
|
|
|
|
(list property title width ":" 'add_times nil '+ nil)
|
|
|
|
|
spec))))
|
|
|
|
|
org-columns-current-fmt-compiled))
|
|
|
|
|
entries)
|
|
|
|
|
;; Ensure there's at least one summation column.
|
|
|
|
|
(when (cl-some (lambda (spec) (nth 4 spec)) fmt)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(while (not (bobp))
|
|
|
|
|
(when (or (get-text-property (point) 'org-date-line)
|
|
|
|
|
(eq (get-text-property (point) 'face)
|
|
|
|
|
'org-agenda-structure))
|
|
|
|
|
;; OK, this is a date line that should be used.
|
|
|
|
|
(let (rest)
|
|
|
|
|
(dolist (c cache (setq cache rest))
|
|
|
|
|
(if (> (car c) (point))
|
|
|
|
|
(push c entries)
|
|
|
|
|
(push c rest))))
|
|
|
|
|
;; Now ENTRIES contains entries below the current one.
|
|
|
|
|
;; CACHE is the rest. Compute the summaries for the
|
|
|
|
|
;; properties we want, set nil properties for the rest.
|
|
|
|
|
(when (setq entries (mapcar 'cdr entries))
|
|
|
|
|
(org-columns--display-here
|
|
|
|
|
(mapcar
|
|
|
|
|
(lambda (spec)
|
|
|
|
|
(pcase spec
|
|
|
|
|
(`(,(and prop (guard (equal (upcase prop) "ITEM"))) . ,_)
|
|
|
|
|
;; Replace ITEM with current date. Preserve
|
|
|
|
|
;; properties for fontification.
|
|
|
|
|
(let ((date (buffer-substring
|
|
|
|
|
(line-beginning-position)
|
|
|
|
|
(line-end-position))))
|
|
|
|
|
(list prop date date)))
|
|
|
|
|
(`(,prop ,_ ,_ ,_ nil . ,_)
|
|
|
|
|
(list prop "" ""))
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(`(,prop ,_ ,_ ,_ ,stype ,_ ,sumfunc)
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(let (lsum)
|
|
|
|
|
(dolist (entry entries (setq lsum (delq nil lsum)))
|
|
|
|
|
;; Use real values for summary, not those
|
|
|
|
|
;; prepared for display.
|
|
|
|
|
(let ((v (nth 1 (assoc-string prop entry t))))
|
|
|
|
|
(when v
|
2016-02-17 14:36:31 +00:00
|
|
|
|
(push (org-columns-string-to-number v stype) lsum))))
|
2016-02-14 09:17:14 +00:00
|
|
|
|
(setq lsum
|
|
|
|
|
(let ((l (length lsum)))
|
|
|
|
|
(cond ((> l 1)
|
|
|
|
|
(org-columns-number-to-string
|
|
|
|
|
(apply sumfunc lsum) stype))
|
|
|
|
|
((= l 1)
|
|
|
|
|
(org-columns-number-to-string
|
|
|
|
|
(car lsum) stype))
|
|
|
|
|
(t ""))))
|
|
|
|
|
(put-text-property 0 (length lsum) 'face 'bold lsum)
|
|
|
|
|
(list prop lsum lsum)))))
|
|
|
|
|
fmt)
|
|
|
|
|
'dateline)
|
|
|
|
|
(setq-local org-agenda-columns-active t)))
|
|
|
|
|
(forward-line -1)))))
|
2008-04-15 12:01:59 +00:00
|
|
|
|
|
|
|
|
|
(defun org-agenda-colview-compute (fmt)
|
|
|
|
|
"Compute the relevant columns in the contributing source buffers."
|
2008-04-17 16:26:27 +00:00
|
|
|
|
(let ((files org-agenda-contributing-files)
|
|
|
|
|
(org-columns-begin-marker (make-marker))
|
|
|
|
|
(org-columns-top-level-marker (make-marker))
|
|
|
|
|
f fm a b)
|
|
|
|
|
(while (setq f (pop files))
|
|
|
|
|
(setq b (find-buffer-visiting f))
|
|
|
|
|
(with-current-buffer (or (buffer-base-buffer b) b)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
2013-02-25 10:44:27 +00:00
|
|
|
|
(org-with-silent-modifications
|
|
|
|
|
(remove-text-properties (point-min) (point-max) '(org-summaries t)))
|
2008-04-17 16:26:27 +00:00
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(org-columns-get-format-and-top-level)
|
|
|
|
|
(while (setq fm (pop fmt))
|
2012-08-05 09:12:04 +00:00
|
|
|
|
(cond ((equal (car fm) "CLOCKSUM")
|
|
|
|
|
(org-clock-sum))
|
|
|
|
|
((equal (car fm) "CLOCKSUM_T")
|
|
|
|
|
(org-clock-sum-today))
|
|
|
|
|
((and (nth 4 fm)
|
2015-01-07 17:08:51 +00:00
|
|
|
|
(setq a (assoc-string (car fm)
|
|
|
|
|
org-columns-current-fmt-compiled
|
|
|
|
|
t))
|
2012-08-05 09:12:04 +00:00
|
|
|
|
(equal (nth 4 a) (nth 4 fm)))
|
|
|
|
|
(org-columns-compute (car fm)))))))))))
|
2008-04-15 12:01:59 +00:00
|
|
|
|
|
2009-08-28 12:50:51 +00:00
|
|
|
|
|
2008-04-09 13:42:36 +00:00
|
|
|
|
(provide 'org-colview)
|
|
|
|
|
|
2008-04-29 05:15:41 +00:00
|
|
|
|
;;; org-colview.el ends here
|