org-colview: Allow simultaneous columns views

* lisp/org-colview.el (org-columns-overlays):
(org-columns-begin-marker):
(org-columns-top-level-marker): Make variables buffer local.

(org-columns-remove-overlays): Assume columns view are to be removed
in current buffer.

(org-columns-edit-allowed): Small refactoring.  Raise an error when
called although no columns view is active in current buffer.

(org-columns-goto-top-level):
(org-columns):
(org-agenda-columns): Do not assume `org-columns-begin-marker' and
`org-columns-top-level-marker' are markers.

(org-columns-store-format):
(org-columns-redo): Skip if no columns view is current active.

(org-agenda-colview-compute): Do not let-bind
`org-columns-begin-marker' and `org-columns-top-level-marker'.
This commit is contained in:
Nicolas Goaziou 2017-07-25 09:49:23 +02:00
parent 6bfe8728e3
commit 0623c1c753
2 changed files with 90 additions and 86 deletions

View File

@ -370,6 +370,10 @@ Call ~org-agenda-set-restriction-lock~ from the agenda.
** Miscellaneous ** Miscellaneous
*** Allow multiple columns view
Columns view is not limited to a single buffer anymore.
*** Org Attach obeys ~dired-dwim-target~ *** Org Attach obeys ~dired-dwim-target~
When a Dired buffer is opened next to the Org document being edited, When a Dired buffer is opened next to the Org document being edited,

View File

@ -94,12 +94,9 @@ in `org-columns-summary-types-default', which see."
;;; Column View ;;; Column View
(defvar org-columns-overlays nil (defvar-local org-columns-overlays nil
"Holds the list of current column overlays.") "Holds the list of current column overlays.")
(defvar org-columns--time 0.0
"Number of seconds since the epoch, as a floating point number.")
(defvar-local org-columns-current-fmt nil (defvar-local org-columns-current-fmt nil
"Local variable, holds the currently active column format.") "Local variable, holds the currently active column format.")
@ -110,12 +107,15 @@ This is the compiled version of the format.")
(defvar-local org-columns-current-maxwidths nil (defvar-local org-columns-current-maxwidths nil
"Currently active maximum column widths, as a vector.") "Currently active maximum column widths, as a vector.")
(defvar org-columns-begin-marker (make-marker) (defvar-local org-columns-begin-marker nil
"Points to the position where last a column creation command was called.") "Points to the position where last a column creation command was called.")
(defvar org-columns-top-level-marker (make-marker) (defvar-local org-columns-top-level-marker nil
"Points to the position where current columns region starts.") "Points to the position where current columns region starts.")
(defvar org-columns--time 0.0
"Number of seconds since the epoch, as a floating point number.")
(defvar org-columns-map (make-sparse-keymap) (defvar org-columns-map (make-sparse-keymap)
"The keymap valid in column display.") "The keymap valid in column display.")
@ -458,23 +458,22 @@ for the duration of the command.")
(defun org-columns-remove-overlays () (defun org-columns-remove-overlays ()
"Remove all currently active column overlays." "Remove all currently active column overlays."
(interactive) (interactive)
(when (marker-buffer org-columns-begin-marker) (when org-columns-overlays
(with-current-buffer (marker-buffer org-columns-begin-marker)
(when (local-variable-p 'org-previous-header-line-format) (when (local-variable-p 'org-previous-header-line-format)
(setq header-line-format org-previous-header-line-format) (setq header-line-format org-previous-header-line-format)
(kill-local-variable 'org-previous-header-line-format) (kill-local-variable 'org-previous-header-line-format)
(remove-hook 'post-command-hook 'org-columns-hscroll-title 'local)) (remove-hook 'post-command-hook 'org-columns-hscroll-title 'local))
(move-marker org-columns-begin-marker nil) (set-marker org-columns-begin-marker nil)
(move-marker org-columns-top-level-marker nil) (set-marker org-columns-top-level-marker nil)
(org-with-silent-modifications (org-with-silent-modifications
(mapc 'delete-overlay org-columns-overlays) (mapc #'delete-overlay org-columns-overlays)
(setq org-columns-overlays nil) (setq org-columns-overlays nil)
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
(remove-text-properties (point-min) (point-max) '(read-only t)))) (remove-text-properties (point-min) (point-max) '(read-only t))))
(when org-columns-flyspell-was-active (when org-columns-flyspell-was-active
(flyspell-mode 1)) (flyspell-mode 1))
(when (local-variable-p 'org-colview-initial-truncate-line-value) (when (local-variable-p 'org-colview-initial-truncate-line-value)
(setq truncate-lines org-colview-initial-truncate-line-value))))) (setq truncate-lines org-colview-initial-truncate-line-value))))
(defun org-columns-compact-links (s) (defun org-columns-compact-links (s)
"Replace [[link][desc]] with [desc] or [link]." "Replace [[link][desc]] with [desc] or [link]."
@ -613,20 +612,20 @@ Where possible, use the standard interface for changing this line."
(let* ((pom (or (org-get-at-bol 'org-marker) (let* ((pom (or (org-get-at-bol 'org-marker)
(org-get-at-bol 'org-hd-marker) (org-get-at-bol 'org-hd-marker)
(point))) (point)))
(key (get-char-property (point) 'org-columns-key)) (key (concat (or (get-char-property (point) 'org-columns-key)
(key1 (concat key "_ALL")) (user-error "No column to edit at point"))
(allowed (org-entry-get pom key1 t)) "_ALL"))
nval) (allowed (org-entry-get pom key t))
(new-value (read-string "Allowed: " allowed)))
;; FIXME: Cover editing TODO, TAGS etc in-buffer settings.???? ;; FIXME: Cover editing TODO, TAGS etc in-buffer settings.????
;; FIXME: Write back to #+PROPERTY setting if that is needed. ;; FIXME: Write back to #+PROPERTY setting if that is needed.
(setq nval (read-string "Allowed: " allowed))
(org-entry-put (org-entry-put
(cond ((marker-position org-entry-property-inherited-from) (cond ((marker-position org-entry-property-inherited-from)
org-entry-property-inherited-from) org-entry-property-inherited-from)
((marker-position org-columns-top-level-marker) ((marker-position org-columns-top-level-marker)
org-columns-top-level-marker) org-columns-top-level-marker)
(t pom)) (t pom))
key1 nval))) key new-value)))
(defun org-columns--call (fun) (defun org-columns--call (fun)
"Call function FUN while preserving heading visibility. "Call function FUN while preserving heading visibility.
@ -760,6 +759,8 @@ current specifications. This function also sets
(defun org-columns-goto-top-level () (defun org-columns-goto-top-level ()
"Move to the beginning of the column view area. "Move to the beginning of the column view area.
Also sets `org-columns-top-level-marker' to the new position." Also sets `org-columns-top-level-marker' to the new position."
(unless (markerp org-columns-top-level-marker)
(setq org-columns-top-level-marker (make-marker)))
(goto-char (goto-char
(move-marker (move-marker
org-columns-top-level-marker org-columns-top-level-marker
@ -782,7 +783,9 @@ When COLUMNS-FMT-STRING is non-nil, use it as the column format."
(interactive "P") (interactive "P")
(org-columns-remove-overlays) (org-columns-remove-overlays)
(when global (goto-char (point-min))) (when global (goto-char (point-min)))
(if (markerp org-columns-begin-marker)
(move-marker org-columns-begin-marker (point)) (move-marker org-columns-begin-marker (point))
(setq org-columns-begin-marker (point-marker)))
(org-columns-goto-top-level) (org-columns-goto-top-level)
;; Initialize `org-columns-current-fmt' and ;; Initialize `org-columns-current-fmt' and
;; `org-columns-current-fmt-compiled'. ;; `org-columns-current-fmt-compiled'.
@ -940,9 +943,8 @@ starting the current column display, or in a #+COLUMNS line of
the current buffer." the current buffer."
(let ((fmt (org-columns-uncompile-format org-columns-current-fmt-compiled))) (let ((fmt (org-columns-uncompile-format org-columns-current-fmt-compiled)))
(setq-local org-columns-current-fmt fmt) (setq-local org-columns-current-fmt fmt)
(when (marker-position org-columns-top-level-marker) (when org-columns-overlays
(org-with-wide-buffer (org-with-point-at org-columns-top-level-marker
(goto-char org-columns-top-level-marker)
(if (and (org-at-heading-p) (org-entry-get nil "COLUMNS")) (if (and (org-at-heading-p) (org-entry-get nil "COLUMNS"))
(org-entry-put nil "COLUMNS" fmt) (org-entry-put nil "COLUMNS" fmt)
(goto-char (point-min)) (goto-char (point-min))
@ -994,18 +996,17 @@ the current buffer."
(defun org-columns-redo () (defun org-columns-redo ()
"Construct the column display again." "Construct the column display again."
(interactive) (interactive)
(when org-columns-overlays
(message "Recomputing columns...") (message "Recomputing columns...")
(org-with-wide-buffer (org-with-point-at org-columns-begin-marker
(when (marker-position org-columns-begin-marker)
(goto-char org-columns-begin-marker))
(org-columns-remove-overlays) (org-columns-remove-overlays)
(if (derived-mode-p 'org-mode) (if (derived-mode-p 'org-mode)
;; Since we already know the columns format, provide it instead ;; Since we already know the columns format, provide it
;; of computing again. ;; instead of computing again.
(call-interactively #'org-columns org-columns-current-fmt) (call-interactively #'org-columns org-columns-current-fmt)
(org-agenda-redo) (org-agenda-redo)
(call-interactively #'org-agenda-columns))) (call-interactively #'org-agenda-columns)))
(message "Recomputing columns...done")) (message "Recomputing columns...done")))
(defun org-columns-uncompile-format (compiled) (defun org-columns-uncompile-format (compiled)
"Turn the compiled columns format back into a string representation. "Turn the compiled columns format back into a string representation.
@ -1489,7 +1490,9 @@ PARAMS is a property list of parameters:
"Turn on or update column view in the agenda." "Turn on or update column view in the agenda."
(interactive) (interactive)
(org-columns-remove-overlays) (org-columns-remove-overlays)
(if (markerp org-columns-begin-marker)
(move-marker org-columns-begin-marker (point)) (move-marker org-columns-begin-marker (point))
(setq org-columns-begin-marker (point-marker)))
(let* ((org-columns--time (float-time (current-time))) (let* ((org-columns--time (float-time (current-time)))
(fmt (fmt
(cond (cond
@ -1608,11 +1611,8 @@ This will add overlays to the date lines, to show the summary for each day."
(defun org-agenda-colview-compute (fmt) (defun org-agenda-colview-compute (fmt)
"Compute the relevant columns in the contributing source buffers." "Compute the relevant columns in the contributing source buffers."
(let ((files org-agenda-contributing-files) (dolist (file org-agenda-contributing-files)
(org-columns-begin-marker (make-marker)) (let ((b (find-buffer-visiting file)))
(org-columns-top-level-marker (make-marker)))
(dolist (f files)
(let ((b (find-buffer-visiting f)))
(with-current-buffer (or (buffer-base-buffer b) b) (with-current-buffer (or (buffer-base-buffer b) b)
(org-with-wide-buffer (org-with-wide-buffer
(org-with-silent-modifications (org-with-silent-modifications
@ -1627,7 +1627,7 @@ This will add overlays to the date lines, to show the summary for each day."
((and (nth 3 spec) ((and (nth 3 spec)
(let ((a (assoc prop org-columns-current-fmt-compiled))) (let ((a (assoc prop org-columns-current-fmt-compiled)))
(equal (nth 3 a) (nth 3 spec)))) (equal (nth 3 a) (nth 3 spec))))
(org-columns-compute prop))))))))))) (org-columns-compute prop))))))))))
(provide 'org-colview) (provide 'org-colview)