From mboxrd@z Thu Jan 1 00:00:00 1970 From: Livin Stephen Sharma Subject: Re: Using Org for browsing and managing buffers Date: Fri, 16 Apr 2010 12:41:08 +0530 Message-ID: References: <87aatda0gv.fsf@stats.ox.ac.uk> <877ho8tnru.fsf@stats.ox.ac.uk> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0348007293==" Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O2jax-0004UA-1U for emacs-orgmode@gnu.org; Fri, 16 Apr 2010 07:20:23 -0400 Received: from [140.186.70.92] (port=47522 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O2jar-0004Rk-TG for emacs-orgmode@gnu.org; Fri, 16 Apr 2010 07:20:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O2jah-0007sr-0C for emacs-orgmode@gnu.org; Fri, 16 Apr 2010 07:20:17 -0400 Received: from mail-pw0-f41.google.com ([209.85.160.41]:50437) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O2fi5-0004dN-Fx for emacs-orgmode@gnu.org; Fri, 16 Apr 2010 03:11:30 -0400 Received: by pwi2 with SMTP id 2so2280944pwi.0 for ; Fri, 16 Apr 2010 00:11:28 -0700 (PDT) In-Reply-To: <877ho8tnru.fsf@stats.ox.ac.uk> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Dan Davison Cc: emacs-org-mode-help gnu --===============0348007293== Content-Type: multipart/alternative; boundary=000e0cd5d184e888fe0484555178 --000e0cd5d184e888fe0484555178 Content-Type: text/plain; charset=ISO-8859-1 yep, now it works! Thanks About moving up/down: I was a bit surprised that 'p' was *not* a counterpart of 'n' (the latter works exactly like 'n' in Org-Agenda) Then I saw that in my setup (*no* customizations), there is some duplication in the functions mapped to 'p' and 'P': key binding --- ------- > SPC org-buffers-display-buffer . org-buffers-switch-to-buffer ? org-buffers-help B org-buffers-list:by H org-buffers-toggle-headings P org-buffers-toggle-properties T org-buffers-columns-view b org-buffers-list:by c org-buffers-columns-view d org-buffers-tag-for-deletion g org-buffers-list:refresh h org-buffers-toggle-headings o org-buffers-switch-to-buffer-other-window p org-buffers-toggle-properties q bury-buffer u org-buffers-remove-tags x org-buffers-execute-pending-operations org-buffers-follow-link On 16 April 2010 02:51, Dan Davison wrote: > Livin Stephen Sharma writes: > > > Am I the only one encountering: > > > > org-buffers-list: Invalid function: org-buffers-state-get > > I haven't seen that error, but I may have been doing something incorrect > (with macros). I've got rid of them now; let me know if you still get > the error. > > Code file: > http://github.com/dandavison/org-buffers/raw/master/org-buffers.el > Git repo: http://github.com/dandavison/org-buffers > > Thanks, > > Dan > > > > > > > > > > I do see many people are using this successfully > > :) > > > > Livin Stephen > > > > > > > > On Apr 09, 2010, at 06:47:20 , Dan Davison wrote: > > > > > > I've been working on an Org tool to browse Emacs buffers. Emacs has > the > > function list-buffers (C-x C-b), where you can view a list of > buffers, > > delete buffers, etc. This is intended to be a replacement for > > list-buffers, implemented in Org-mode. > > > > The code is attached, and there's a git repo at > > http://github.com/dandavison/org-buffers > > > > After putting the code in your load-path and doing > > (require 'org-buffers), use the function `org-buffers-list' to create > > the listing buffer. This is a read-only Org-mode buffer populated > with > > links to open buffers. Information is stored for each buffer using > > properties. By default, the buffers are grouped by major mode. Here's > a > > screenshot. > > > > http://www.princeton.edu/~ddavison/org-buffers/by-major-mode.png > > > > The buffer has some special key-bindings: > > > > +--------------------------------------------------------------+ > > | ? | Show all keybindings | > > |-----+--------------------------------------------------------| > > | g | Update buffer (prefix arg does hard reset) | > > |-----+--------------------------------------------------------| > > | b | Select a different property to group by | > > |-----+--------------------------------------------------------| > > | RET | follow link to buffer on this line | > > |-----+--------------------------------------------------------| > > | d | Mark buffer for deletion | > > |-----+--------------------------------------------------------| > > | u | Remove mark | > > |-----+--------------------------------------------------------| > > | x | Delete marked buffers | > > |-----+--------------------------------------------------------| > > | o | Like RET (see variable org-buffers-follow-link-method) | > > |-----+--------------------------------------------------------| > > | . | Like RET but switch to buffer in same window | > > |-----+--------------------------------------------------------| > > | h | toggle between headings and plain entries for buffers | > > |-----+--------------------------------------------------------| > > | p | toggle in-buffer properties on/off | > > |-----+--------------------------------------------------------| > > | c | Switch to column-view | > > +--------------------------------------------------------------+ > > > > If there's an active region, d and u operate on all buffers in the > > region. > > > > Some variables that can be configured: > > - org-buffers-buffer-properties > > - org-buffers-excluded-modes > > - org-buffers-excluded-buffers > > - org-buffers-follow-link-method > > - org-buffers-mode-hook > > - org-buffers-buffer-name > > > > Some possible extensions: > > - Browse recent files using recentf > > - Allow several buffers to be marked for side-by-side display > > - Maintain folding configuration across buffer updates > > - Make faster > > > > As always, any feedback, suggestions and patches will be very > welcome! > > > > Dan > > > > p.s. The column-view mode works for following links, but does need > > further attention. > > > > ;;; org-buffers.el --- An Org-mode tool for buffer management > > > > ;; Copyright (C) 2010 Dan Davison > > > > ;; Author: Dan Davison > > ;; Keywords: outlines, hypermedia, calendar, wp > > ;; Homepage: http://orgmode.org > > > > ;;; License: > > > > ;; This program is free software; you can redistribute it and/or > modify > > ;; it under the terms of the GNU General Public License as published > by > > ;; the Free Software Foundation; either version 3, or (at your > option) > > ;; any later version. > > ;; > > ;; This program 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 > > ;; along with GNU Emacs; see the file COPYING. If not, write to the > > ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, > > ;; Boston, MA 02110-1301, USA. > > > > ;;; Commentary: > > > > ;;; Code: > > > > (require 'org) > > (require 'cl) > > > > ;;; Variables > > (defvar org-buffers-buffer-name > > "*Buffers*" > > "Name of buffer in which buffer list is displayed") > > > > (defvar org-buffers-state > > '((:by . "major-mode") (:atom . heading) (:properties . nil)) > > "Association list specifiying the current state of org-buffers.") > > > > (defvar org-buffers-follow-link-method 'org-open-at-point > > "Method used to follow link with RET. Must be one of > > > > 'org-open-at-point :: use `org-open-at-point' to follow link. > > 'current-window :: use switch-to-buffer > > 'other-window :: use switch-to-buffer-other-window > > > > Setting this variable to 'current-window makes the behaviour more > > consistent with that of `Buffer-menu-mode' and `dired-mode'") > > > > (defvar org-buffers-buffer-properties > > '(("buffer-name" . (buffer-name)) > > ("major-mode" . (let ((mode (symbol-name major-mode))) > > (if (string-match "-mode$" mode) > > (replace-match "" nil t mode) mode))) > > ("buffer-file-name" . (buffer-file-name)) > > ("default-directory" . default-directory) > > ("buffer-modified-p" . (format "%s" (buffer-modified-p)))) > > "Association list specifying properties to be stored for each > > buffer. The car of each element is the name of the property, and > > the cdr is an expression which, when evaluated in the buffer, > > yields the property value.") > > > > (defcustom org-buffers-excluded-buffers > > `("*Completions*" ,org-buffers-buffer-name) > > "List of names of buffers that should not be listed by > > org-buffers-list." > > :group 'org-buffers) > > > > (defcustom org-buffers-excluded-modes nil > > "List of names of major-modes (strings) that should not be listed > > by org-buffers-list." > > :group 'org-buffers) > > > > ;;; Mode > > (defvar org-buffers-mode-map (make-sparse-keymap)) > > > > (defvar org-buffers-mode-hook nil > > "Hook for functions to be called after buffer listing is > > created. Note that the buffer is read-only, so if the hook > > function is to modify the buffer it should use a let binding to > > temporarily bind buffer-read-only to nil.") > > > > (define-minor-mode org-buffers-mode > > "An Org-mode tool for buffer management. > > \\{org-buffers-mode-map}" > > nil " buffers" nil > > (org-set-local 'org-tag-alist '(("delete" . ?d))) > > (org-set-local'org-tags-column -50) > > (org-set-local 'org-columns-default-format "%25buffer-name(Buffer) > > %25major-mode(Mode) %25default-directory(Dir) > %5buffer-modified-p(Modified) > > ") > > (add-hook 'kill-buffer-hook 'org-buffers-reset-state nil 'local)) > > > > (defun org-buffers-help () > > (interactive) > > (describe-function 'org-buffers-mode)) > > > > ;;; Keys > > (define-key org-buffers-mode-map [(return)] 'org-buffers-follow-link) > > (define-key org-buffers-mode-map "b" 'org-buffers-list:by) > > (define-key org-buffers-mode-map "c" 'org-buffers-columns-view) > > (define-key org-buffers-mode-map "d" 'org-buffers-tag-for-deletion) > > (define-key org-buffers-mode-map "g" 'org-buffers-list:refresh) > > (define-key org-buffers-mode-map "." 'org-buffers-switch-to-buffer) > > (define-key org-buffers-mode-map "h" 'org-buffers-toggle-headings) > > (define-key org-buffers-mode-map "o" > > 'org-buffers-switch-to-buffer-other-window) > > (define-key org-buffers-mode-map "p" 'org-buffers-toggle-properties) > > (define-key org-buffers-mode-map "u" 'org-buffers-remove-tags) > > (define-key org-buffers-mode-map "x" > > 'org-buffers-execute-pending-operations) > > (define-key org-buffers-mode-map "?" 'org-buffers-help) > > ;;; Listing and view cycling > > > > (defun org-buffers-list (&optional refresh frame) > > "Create an Org-mode listing of Emacs buffers. > > By default, buffers are grouped by major mode. Optional > > argument FRAME specifies the frame whose buffers should be > > listed." > > (interactive) > > (pop-to-buffer > > (or > > (and (not refresh) (get-buffer org-buffers-buffer-name)) > > (let ((org-buffers-p (equal (buffer-name) > org-buffers-buffer-name)) > > (by (or (org-buffers-state-get :by) "major-mode")) > > (atom (org-buffers-state-get :atom)) target) > > (when org-buffers-p > > (if (and (org-before-first-heading-p) (not (org-on-heading-p))) > > (outline-next-heading)) > > (setq target > > (condition-case nil (org-make-org-heading-search-string) (error > > nil)))) > > (with-current-buffer (get-buffer-create org-buffers-buffer-name) > > (setq buffer-read-only nil) > > (erase-buffer) > > (org-mode) > > (dolist > > (buffer > > (sort (remove-if 'org-buffers-exclude-p > > (mapcar 'buffer-name (buffer-list frame))) 'string<)) > > (org-insert-heading t) > > (insert > > (org-make-link-string (concat "buffer:" buffer) buffer) "\n") > > (dolist (pair (org-buffers-get-buffer-props buffer)) > > (org-set-property (car pair) (cdr pair)))) > > (org-buffers-set-state '((:atom . heading))) > > (goto-char (point-min)) > > (unless (equal by "NONE") (org-buffers-group-by by)) > > (if target (condition-case nil (org-link-search target) (error nil))) > > (beginning-of-line) > > (if (equal by "NONE") > > (org-overview) > > (case atom > > ('heading (progn (org-overview) (org-content))) > > ('line (progn (show-all) (org-buffers-toggle-headings))))) > > (save-excursion > > (mark-whole-buffer) > > (indent-region (point-min) (point-max))) > > (org-buffers-mode) > > (setq buffer-read-only t) > > (current-buffer)))))) > > > > (defun org-buffers-list:refresh (&optional arg) > > "Refresh org-buffers listing." > > (interactive "P") > > (if arg (org-buffers-reset-state)) > > (org-buffers-list 'refresh)) > > > > (defun org-buffers-list:by (&optional prop) > > "Group buffers according to value of property PROP." > > (interactive) > > (let ((buffer-read-only nil) > > (headings-p (org-buffers-state-eq :atom 'heading))) > > (unless (org-buffers-state-get :properties) > > (org-buffers-toggle-properties)) > > (org-buffers-set-state > > `((:by . > > ,(or prop > > (org-completing-read > > "Property to group by: " > > (cons "NONE" (mapcar 'car org-buffers-buffer-properties))))))) > > (org-buffers-list 'refresh) > > (unless headings-p (org-buffers-toggle-headings)))) > > > > (defun org-buffers-toggle-properties () > > "Toggle entry properties in org-buffers listing buffer. > > Removing properties may provide a less cluttered appearance for > > browsing. However, in-buffer properties will be restored during > > certain operations, such as `org-buffers-list:by'." > > (interactive) > > (if (org-buffers-state-get :properties) > > (progn (org-buffers-delete-properties) > > (show-all) > > (org-buffers-set-state '((:properties . nil)))) > > (org-buffers-set-state > > '((:atom . heading) (:properties . t))) > > (org-buffers-list 'refresh))) > > > > (defun org-buffers-toggle-headings () > > "Toggle viewing of buffers as org headings. > > Headings will be automatically restored during certain > > operations, such as setting deletion tags." > > (interactive) > > (let ((buffer-read-only nil) > > (headings-p (org-buffers-state-eq :atom 'heading)) > > (flat-p (org-buffers-state-eq :by "NONE"))) > > (if (and headings-p (org-buffers-state-get :properties)) > > (org-buffers-toggle-properties)) > > (save-excursion > > (goto-char (point-min)) > > (if (and (or headings-p (not flat-p)) > > (not (outline-on-heading-p))) > > (outline-next-heading)) > > (if flat-p > > (progn > > (push-mark (point) 'nomsg 'activate) > > (end-of-buffer) > > (org-ctrl-c-star) > > (pop-mark)) > > (while (not (eobp)) > > (push-mark > > (save-excursion (forward-line 1) (point)) 'nomsg 'activate) > > (org-forward-same-level 1) > > (org-ctrl-c-star) > > (pop-mark))) > > (mark-whole-buffer) > > (indent-region (point-min) (point-max))) > > (org-buffers-set-state > > `((:atom . ,(if headings-p 'line 'heading)))))) > > > > (defun org-buffers-delete-properties () > > (let ((buffer-read-only nil)) > > (save-excursion > > (goto-char (point-min)) > > (org-buffers-delete-regions > > (nreverse > > (org-buffers-map-entries 'org-buffers-get-property-block)))))) > > > > (defun org-buffers-get-property-block () > > "Return the (beg . end) range of the property drawer. > > Unlike the org version the limits include the keywords delimiting > > the drawer." > > (let ((beg (point)) > > (end (progn (outline-next-heading) (point)))) > > (goto-char beg) > > (if (re-search-forward org-property-drawer-re end t) > > (cons (match-beginning 1) (match-end 0))))) > > > > (defun org-buffers-group-by (property) > > "Group top level headings according to the value of PROPERTY." > > (let ((atom (org-buffers-state-get :atom))) > > (save-excursion > > (goto-char (point-min)) > > (mapc (lambda (subtree) ;; Create subtree for each value of > `property' > > (org-insert-heading t) > > (if (> (org-buffers-outline-level) 1) > > (org-promote)) > > (insert (car subtree) "\n") > > (org-insert-subheading t) > > (mapc 'org-buffers-insert-parsed-entry (cdr subtree))) > > (prog1 > > (mapcar (lambda (val) ;; Form list of parsed entries for each unique > value > > of `property' > > (cons val (org-buffers-parse-selected-entries property val))) > > (sort > > (delete-dups (org-buffers-map-entries (lambda () (org-entry-get nil > > property nil)))) > > 'string<)) > > (erase-buffer)))))) > > > > (defun org-buffers-exclude-p (buffer) > > "Return non-nil if BUFFER should not be listed." > > (or (member (with-current-buffer buffer major-mode) > > org-buffers-excluded-modes) > > (member buffer org-buffers-excluded-buffers) > > (string= (substring buffer 0 1) " "))) > > > > (defun org-buffers-reset-state () > > (org-buffers-set-state > > '((:by . "major-mode") (:atom . heading) (:properties . nil)))) > > > > (defun org-buffers-columns-view () > > "View buffers in Org-mode columns view. > > This is currently experimental. RET can be used to follow links > > in the first column, but certain other org-buffers keys conflict > > with column-view or otherwise do not work correctly." > > (interactive) > > (let ((by (org-buffers-state-get :by)) > > (buffer-read-only nil)) > > (unless (equal by "NONE") (org-buffers-list:by "NONE")) > > (unless (org-buffers-state-get :properties) > > (org-buffers-toggle-properties)) > > (unless (equal by "NONE") > > (goto-char (point-min)) > > (org-sort-entries-or-items nil ?r nil nil by) > > (org-overview)) > > (mark-whole-buffer) > > (org-columns))) > > > > ;;; Parsing and inserting entries > > (defun org-buffers-parse-selected-entries (prop val) > > "Parse all entries with property PROP value VAL." > > (delq nil > > (org-buffers-map-entries > > (lambda () (when (equal (org-entry-get nil prop) val) > > (cons (org-get-heading) (org-get-entry))))))) > > > > (defun org-buffers-insert-parsed-entry (entry) > > "Insert a parsed entry" > > (unless (org-at-heading-p) (org-insert-heading)) > > (insert (car entry) "\n") > > (if (org-buffers-state-get :properties) > > (insert (cdr entry)))) > > > > (defun org-buffers-get-buffer-props (buffer) > > "Create alist of properties of BUFFER, as strings." > > (with-current-buffer buffer > > (mapcar > > (lambda (pair) (cons (car pair) (eval (cdr pair)))) > > org-buffers-buffer-properties))) > > > > ;;; Follow-link behaviour > > > > (defun org-buffers-follow-link () > > "Follow link to buffer on this line. > > The buffer-switching behaviour of this function is determined by > > the variable `org-buffers-follow-link-method'. See also > > `org-buffers-switch-to-buffer' and > > `org-buffers-switch-to-buffer-other-window', whose behaviour is > > hard-wired." > > (interactive) > > (org-buffers-switch-to-buffer-generic > org-buffers-follow-link-method)) > > > > (defun org-buffers-switch-to-buffer () > > "Switch to this entry's buffer in current window." > > (interactive) > > (org-buffers-switch-to-buffer-generic 'current-window)) > > > > (defun org-buffers-switch-to-buffer-other-window () > > "Switch to this entry's buffer in other window." > > (interactive) > > (org-buffers-switch-to-buffer-generic 'other-window)) > > > > (defun org-buffers-switch-to-buffer-generic (method) > > (save-excursion > > (let ((atom (org-buffers-state-get :atom)) buffer) > > (cond > > ((eq atom 'heading) (org-back-to-heading)) > > (t (beginning-of-line))) > > (setq buffer (org-buffers-get-buffer-name)) > > (if (get-buffer buffer) > > (case method > > ('org-open-at-point (org-open-at-point)) > > ('current-window (switch-to-buffer buffer)) > > ('other-window (switch-to-buffer-other-window buffer))) > > (error "No such buffer: %s" buffer))))) > > > > (defun org-buffers-get-buffer-name () > > "Get buffer-name for current entry." > > (let ((headings-p (org-buffers-state-eq :atom 'heading))) > > (or (and headings-p (org-entry-get nil "buffer-name")) > > (and (save-excursion > > (if headings-p (org-back-to-heading)) > > (re-search-forward "\\[\\[buffer:\\([^\]]*\\)" (point-at-eol) > t)) > > (org-link-unescape (match-string 1)))))) > > > > ;;; Setting tags and executing operations > > > > (defun org-buffers-tag-for-deletion () > > "Mark buffer for deletion. > > If a region is selected, all buffers in the region are marked for > > deletion. Buffers marked for deletion can be deleted using > > `org-buffers-execute-pending-operations'." > > (interactive) > > (org-buffers-set-tags '("delete"))) > > > > (defun org-buffers-remove-tags () > > "Remove deletion marks from buffers. > > If a region is selected, marks are removed from all buffers in > > the region." > > (interactive) > > (org-buffers-set-tags nil)) > > > > (defun org-buffers-set-tags (data) > > "Set tags to DATA at all non top-level headings in region. > > DATA should be a list of strings. If DATA is nil, remove all tags > > at such headings." > > (let* ((buffer-read-only nil) > > (region-p (org-region-active-p)) > > (beg (if region-p (region-beginning) (point))) > > (end (if region-p (region-end) (point))) > > (headings-p (org-buffers-state-eq :atom 'heading))beg-line end-line) > > (save-excursion > > (setq beg-line (progn (goto-char beg) (org-current-line)) > > end-line (progn (goto-char end) (org-current-line))) > > (if headings-p > > (setq > > end (if (and region-p (not (eq end-line beg-line)) (not (eobp))) > > (progn (goto-char end) (org-back-to-heading) (point)) > > (progn (outline-end-of-heading) (point))) > > beg (progn (goto-char beg) (point-at-bol))) > > (org-buffers-toggle-headings) ;; doesn't alter line numbers > > (setq beg (progn (org-goto-line beg-line) (point-at-bol)) > > end (if (eq end-line beg-line) (point-at-eol) > > (progn (org-goto-line end-line) (point-at-bol))))) > > (narrow-to-region beg end) > > (goto-char (point-min)) > > (org-buffers-map-entries > > (lambda () > > (when (or (org-buffers-state-eq :by "NONE") > > (> (org-outline-level) 1)) > > (org-set-tags-to > > (if data (delete-duplicates (append data (org-get-tags)) :test > > 'string-equal)))))) > > (widen) > > (org-content)) > > (unless region-p > > (outline-next-heading) > > (unless (or (> (org-outline-level) 1) (org-buffers-state-eq :by > > "NONE")) > > (outline-next-heading))) > > (unless headings-p (org-buffers-toggle-headings)))) > > > > (defun org-buffers-execute-pending-operations () > > "Execute all pending operations. > > Currently the only type of operation supported is > > deletion. Buffers are tagged for deletion using > > `org-buffers-tag-for-deletion'. Remove such tags from buffers > > using `org-buffers-remove-tags'." > > (interactive) > > (let ((buffer-read-only nil) > > (headings-p (org-buffers-state-eq :atom 'heading)) buffer) > > (unless headings-p (org-buffers-toggle-headings)) > > (org-buffers-delete-regions > > (nreverse > > (org-buffers-map-entries > > (lambda () > > (if (setq buffer (org-buffers-get-buffer-name)) > > (if (not (kill-buffer buffer)) > > (error "Failed to kill buffer %s" buffer) > > (if (and (org-first-sibling-p) > > (not (save-excursion (org-goto-sibling)))) > > (org-up-heading-safe)) ;; Only child so delete parent also > > (cons (point) (1+ (org-end-of-subtree)))))) > > "+delete"))) > > (unless headings-p (org-buffers-toggle-headings)))) > > > > ;;; Utilities > > > > (defun org-buffers-map-entries (func &optional match) > > (org-scan-tags > > func (if match (cdr (org-make-tags-matcher match)) t))) > > > > (defun org-buffers-set-state (state) > > "Add STATE to global state list. > > New settings have precedence over existing ones." > > (mapc > > (lambda (pair) (unless (assoc (car pair) state) > > (add-to-list 'state pair))) > > org-buffers-state) > > (setq org-buffers-state state)) > > > > (defmacro org-buffers-delete-regions (regions) > > "Delete regions in list. > > REGIONS is a list of (beg . end) cons cells specifying buffer > > regions." > > `(mapc (lambda (pair) (if pair (delete-region (car pair) (cdr > pair)))) > > ,regions)) > > > > (defmacro org-buffers-state-get (key) > > `(cdr (assoc ,key org-buffers-state))) > > > > (defmacro org-buffers-state-eq (key val) > > `(equal (org-buffers-state-get ,key) ,val)) > > > > (defmacro org-buffers-outline-level () > > '(save-excursion (beginning-of-line) (org-outline-level))) > > > > ;;; Links to buffers > > > > (org-add-link-type "buffer" 'display-buffer) > > (add-hook 'org-store-link-functions 'org-buffers-store-link) > > > > (defun org-buffers-store-link (&optional force) > > "Store a link to an Emacs buffer. > > Returns nil by default, to avoid hijacking other link types." > > (if force > > (let* ((target (buffer-name)) > > (desc target) link) > > (org-store-link-props :type "buffer") > > (setq link (org-make-link "buffer:" target)) > > (org-add-link-props :link link :description desc) > > link))) > > > > (provide 'org-buffers) > > ;;; org-buffers.el ends here > > _______________________________________________ > > Emacs-orgmode mailing list > > Please use `Reply All' to send replies to the list. > > Emacs-orgmode@gnu.org > > http://lists.gnu.org/mailman/listinfo/emacs-orgmode > > > > > > _______________________________________________ > > Emacs-orgmode mailing list > > Please use `Reply All' to send replies to the list. > > Emacs-orgmode@gnu.org > > http://lists.gnu.org/mailman/listinfo/emacs-orgmode > --000e0cd5d184e888fe0484555178 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable yep, now it works!
Thanks

About moving up/down= :
=A0I was a bit surprised that 'p' was not a coun= terpart of 'n' (the latter works exactly like 'n' in Org-Ag= enda)

Then I saw that in my setup (*no* customizations), there is = some duplication in the functions mapped to 'p' and 'P':



key =A0 =A0 =A0 =A0 =A0 =A0 binding
--- =A0 =A0 =A0 =A0 =A0 =A0 -------

SPC org-= buffers-display-buffer
. org-bu= ffers-switch-to-buffer
? org-bu= ffers-help
B org-bu= ffers-list:by
H org-bu= ffers-toggle-headings
P = org-= buffers-toggle-properties
T org-bu= ffers-columns-view
b org-bu= ffers-list:by
c org-bu= ffers-columns-view
d org-bu= ffers-tag-for-deletion
g org-bu= ffers-list:refresh
h org-bu= ffers-toggle-headings
o org-bu= ffers-switch-to-buffer-other-window
p = org-= buffers-toggle-properties
q bury-b= uffer
u org-bu= ffers-remove-tags
x org-bu= ffers-execute-pending-operations
<return> org-buffers-follow-link



On 16 April 2010 02:51, Dan Davison <= span dir=3D"ltr"><davison@stat= s.ox.ac.uk> wrote:
Livin Stephen Sharma <= livin.stephen@gmail.com> = writes:

> Am I the only one encountering:
>
> =A0 =A0 org-buffers-list: Invalid function: org-buffers-state-get

I haven't seen that error, but I may have been doing something in= correct
(with macros). I've got rid of them now; let me know if you still get the error.

Code file: http://github.com/dandavison/org-buffers/r= aw/master/org-buffers.el
Git repo: =A0http://github.com/dandavison/org-buffers

Thanks,

Dan


>
>
>
> I do see many people are using this successfully
> :)
>
> Livin Stephen
>
>
>
> On Apr 09, 2010, at 06:47:20 , Dan Davison wrote:
>
>
> =A0 =A0 I've been working on an Org tool to browse Emacs buffers. = Emacs has the
> =A0 =A0 function list-buffers (C-x C-b), where you can view a list of = buffers,
> =A0 =A0 delete buffers, etc. This is intended to be a replacement for<= br> > =A0 =A0 list-buffers, implemented in Org-mode.
>
> =A0 =A0 The code is attached, and there's a git repo at
> =A0 =A0 http://github.com/dandavison/org-buffers
>
> =A0 =A0 After putting the code in your load-path and doing
> =A0 =A0 (require 'org-buffers), use the function `org-buffers-list= ' to create
> =A0 =A0 the listing buffer. This is a read-only Org-mode buffer popula= ted with
> =A0 =A0 links to open buffers. Information is stored for each buffer u= sing
> =A0 =A0 properties. By default, the buffers are grouped by major mode.= Here's a
> =A0 =A0 screenshot.
>
> =A0 =A0 http://www.princeton.edu/~ddavison/org-buf= fers/by-major-mode.png
>
> =A0 =A0 The buffer has some special key-bindings:
>
> =A0 =A0 +-------------------------------------------------------------= -+
> =A0 =A0 | ? =A0 | Show all keybindings =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | g =A0 | Update buffer (prefix arg does hard reset) =A0 =A0 = =A0 =A0 =A0 =A0 |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | b =A0 | Select a different property to group by =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0|
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | RET | follow link to buffer on this line =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | d =A0 | Mark buffer for deletion =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | u =A0 | Remove mark =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | x =A0 | Delete marked buffers =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | o =A0 | Like RET (see variable org-buffers-follow-link-metho= d) |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | . =A0 | Like RET but switch to buffer in same window =A0 =A0= =A0 =A0 =A0 |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | h =A0 | toggle between headings and plain entries for buffer= s =A0|
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | p =A0 | toggle in-buffer properties on/off =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 |
> =A0 =A0 |-----+-------------------------------------------------------= -|
> =A0 =A0 | c =A0 | Switch to column-view =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|
> =A0 =A0 +-------------------------------------------------------------= -+
>
> =A0 =A0 If there's an active region, d and u operate on all buffer= s in the
> =A0 =A0 region.
>
> =A0 =A0 Some variables that can be configured:
> =A0 =A0 - org-buffers-buffer-properties
> =A0 =A0 - org-buffers-excluded-modes
> =A0 =A0 - org-buffers-excluded-buffers
> =A0 =A0 - org-buffers-follow-link-method
> =A0 =A0 - org-buffers-mode-hook
> =A0 =A0 - org-buffers-buffer-name
>
> =A0 =A0 Some possible extensions:
> =A0 =A0 - Browse recent files using recentf
> =A0 =A0 - Allow several buffers to be marked for side-by-side display<= br> > =A0 =A0 - Maintain folding configuration across buffer updates
> =A0 =A0 - Make faster
>
> =A0 =A0 As always, any feedback, suggestions and patches will be very = welcome!
>
> =A0 =A0 Dan
>
> =A0 =A0 p.s. The column-view mode works for following links, but does = need
> =A0 =A0 further attention.
>
> =A0 =A0 ;;; org-buffers.el --- An Org-mode tool for buffer management<= br> >
> =A0 =A0 ;; Copyright (C) 2010 =A0Dan Davison
>
> =A0 =A0 ;; Author: Dan Davison <dandavison0 at gmail dot com> > =A0 =A0 ;; Keywords: outlines, hypermedia, calendar, wp
> =A0 =A0 ;; Homepage: = http://orgmode.org
>
> =A0 =A0 ;;; License:
>
> =A0 =A0 ;; This program is free software; you can redistribute it and/= or modify
> =A0 =A0 ;; it under the terms of the GNU General Public License as pub= lished by
> =A0 =A0 ;; the Free Software Foundation; either version 3, or (at your= option)
> =A0 =A0 ;; any later version.
> =A0 =A0 ;;
> =A0 =A0 ;; This program is distributed in the hope that it will be use= ful,
> =A0 =A0 ;; but WITHOUT ANY WARRANTY; without even the implied warranty= of
> =A0 =A0 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =A0See= the
> =A0 =A0 ;; GNU General Public License for more details.
> =A0 =A0 ;;
> =A0 =A0 ;; You should have received a copy of the GNU General Public L= icense
> =A0 =A0 ;; along with GNU Emacs; see the file COPYING. =A0If not, writ= e to the
> =A0 =A0 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth F= loor,
> =A0 =A0 ;; Boston, MA 02110-1301, USA.
>
> =A0 =A0 ;;; Commentary:
>
> =A0 =A0 ;;; Code:
>
> =A0 =A0 (require 'org)
> =A0 =A0 (require 'cl)
>
> =A0 =A0 ;;; Variables
> =A0 =A0 (defvar org-buffers-buffer-name
> =A0 =A0 =A0"*Buffers*"
> =A0 =A0 =A0"Name of buffer in which buffer list is displayed"= ;)
>
> =A0 =A0 (defvar org-buffers-state
> =A0 =A0 =A0'((:by . "major-mode") (:atom . heading) (:pr= operties . nil))
> =A0 =A0 =A0"Association list specifiying the current state of org= -buffers.")
>
> =A0 =A0 (defvar org-buffers-follow-link-method 'org-open-at-point<= br> > =A0 =A0 =A0"Method used to follow link with RET. Must be one of >
> =A0 =A0 'org-open-at-point :: use `org-open-at-point' to follo= w link.
> =A0 =A0 'current-window =A0 =A0:: use switch-to-buffer
> =A0 =A0 'other-window =A0 =A0 =A0:: use switch-to-buffer-other-win= dow
>
> =A0 =A0 Setting this variable to 'current-window makes the behavio= ur more
> =A0 =A0 consistent with that of `Buffer-menu-mode' and `dired-mode= '")
>
> =A0 =A0 (defvar org-buffers-buffer-properties
> =A0 =A0 =A0'(("buffer-name" . (buffer-name))
> =A0 =A0 =A0 =A0("major-mode" . (let ((mode (symbol-name majo= r-mode)))
> =A0 =A0 =A0 =A0 =A0(if (string-match "-mode$" mode)
> =A0 =A0 =A0(replace-match "" nil t mode) mode)))
> =A0 =A0 =A0 =A0("buffer-file-name" . (buffer-file-name))
> =A0 =A0 =A0 =A0("default-directory" . default-directory)
> =A0 =A0 =A0 =A0("buffer-modified-p" . (format "%s"= (buffer-modified-p))))
> =A0 =A0 =A0"Association list specifying properties to be stored f= or each
> =A0 =A0 buffer. The car of each element is the name of the property, a= nd
> =A0 =A0 the cdr is an expression which, when evaluated in the buffer,<= br> > =A0 =A0 yields the property value.")
>
> =A0 =A0 (defcustom org-buffers-excluded-buffers
> =A0 =A0 =A0`("*Completions*" ,org-buffers-buffer-name)
> =A0 =A0 =A0"List of names of buffers that should not be listed by=
> =A0 =A0 =A0org-buffers-list."
> =A0 =A0 =A0:group 'org-buffers)
>
> =A0 =A0 (defcustom org-buffers-excluded-modes nil
> =A0 =A0 =A0"List of names of major-modes (strings) that should no= t be listed
> =A0 =A0 =A0by org-buffers-list."
> =A0 =A0 =A0:group 'org-buffers)
>
> =A0 =A0 ;;; Mode
> =A0 =A0 (defvar org-buffers-mode-map (make-sparse-keymap))
>
> =A0 =A0 (defvar org-buffers-mode-hook nil
> =A0 =A0 =A0"Hook for functions to be called after buffer listing = is
> =A0 =A0 =A0created. Note that the buffer is read-only, so if the hook<= br> > =A0 =A0 =A0function is to modify the buffer it should use a let bindin= g to
> =A0 =A0 =A0temporarily bind buffer-read-only to nil.")
>
> =A0 =A0 (define-minor-mode org-buffers-mode
> =A0 =A0 =A0"An Org-mode tool for buffer management.
> =A0 =A0 \\{org-buffers-mode-map}"
> =A0 =A0 =A0nil " buffers" nil
> =A0 =A0 =A0(org-set-local 'org-tag-alist '(("delete"= . ?d)))
> =A0 =A0 =A0(org-set-local'org-tags-column -50)
> =A0 =A0 =A0(org-set-local 'org-columns-default-format "%25buf= fer-name(Buffer)
> =A0 =A0 %25major-mode(Mode) %25default-directory(Dir) %5buffer-modifie= d-p(Modified)
> =A0 =A0 ")
> =A0 =A0 =A0(add-hook 'kill-buffer-hook 'org-buffers-reset-stat= e nil 'local))
>
> =A0 =A0 (defun org-buffers-help ()
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(describe-function 'org-buffers-mode))
>
> =A0 =A0 ;;; Keys
> =A0 =A0 (define-key org-buffers-mode-map [(return)] 'org-buffers-f= ollow-link)
> =A0 =A0 (define-key org-buffers-mode-map "b" 'org-buffer= s-list:by)
> =A0 =A0 (define-key org-buffers-mode-map "c" 'org-buffer= s-columns-view)
> =A0 =A0 (define-key org-buffers-mode-map "d" 'org-buffer= s-tag-for-deletion)
> =A0 =A0 (define-key org-buffers-mode-map "g" 'org-buffer= s-list:refresh)
> =A0 =A0 (define-key org-buffers-mode-map "." 'org-buffer= s-switch-to-buffer)
> =A0 =A0 (define-key org-buffers-mode-map "h" 'org-buffer= s-toggle-headings)
> =A0 =A0 (define-key org-buffers-mode-map "o"
> =A0 =A0 'org-buffers-switch-to-buffer-other-window)
> =A0 =A0 (define-key org-buffers-mode-map "p" 'org-buffer= s-toggle-properties)
> =A0 =A0 (define-key org-buffers-mode-map "u" 'org-buffer= s-remove-tags)
> =A0 =A0 (define-key org-buffers-mode-map "x"
> =A0 =A0 'org-buffers-execute-pending-operations)
> =A0 =A0 (define-key org-buffers-mode-map "?" 'org-buffer= s-help)
> =A0 =A0 ;;; Listing and view cycling
>
> =A0 =A0 (defun org-buffers-list (&optional refresh frame)
> =A0 =A0 =A0"Create an Org-mode listing of Emacs buffers.
> =A0 =A0 By default, buffers are grouped by major mode. Optional
> =A0 =A0 argument FRAME specifies the frame whose buffers should be
> =A0 =A0 listed."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(pop-to-buffer
> =A0 =A0 =A0 (or
> =A0 =A0 =A0 =A0(and (not refresh) (get-buffer org-buffers-buffer-name)= )
> =A0 =A0 =A0 =A0(let ((org-buffers-p (equal (buffer-name) org-buffers-b= uffer-name))
> =A0 =A0 =A0(by (or (org-buffers-state-get :by) "major-mode")= )
> =A0 =A0 =A0(atom (org-buffers-state-get :atom)) target)
> =A0 =A0 =A0 =A0 =A0(when org-buffers-p
> =A0 =A0 (if (and (org-before-first-heading-p) (not (org-on-heading-p))= )
> =A0 =A0 =A0 =A0(outline-next-heading))
> =A0 =A0 (setq target
> =A0 =A0 =A0 =A0 =A0(condition-case nil (org-make-org-heading-search-st= ring) (error
> =A0 =A0 nil))))
> =A0 =A0 =A0 =A0 =A0(with-current-buffer (get-buffer-create org-buffers= -buffer-name)
> =A0 =A0 (setq buffer-read-only nil)
> =A0 =A0 (erase-buffer)
> =A0 =A0 (org-mode)
> =A0 =A0 (dolist
> =A0 =A0 =A0 =A0(buffer
> =A0 =A0 =A0 =A0 (sort (remove-if 'org-buffers-exclude-p
> =A0 =A0 =A0 =A0 =A0(mapcar 'buffer-name (buffer-list frame))) '= ;string<))
> =A0 =A0 =A0(org-insert-heading t)
> =A0 =A0 =A0(insert
> =A0 =A0 =A0 (org-make-link-string (concat "buffer:" buffer) = buffer) "\n")
> =A0 =A0 =A0(dolist (pair (org-buffers-get-buffer-props buffer))
> =A0 =A0 =A0 =A0(org-set-property (car pair) (cdr pair))))
> =A0 =A0 (org-buffers-set-state '((:atom . heading)))
> =A0 =A0 (goto-char (point-min))
> =A0 =A0 (unless (equal by "NONE") (org-buffers-group-by by))=
> =A0 =A0 (if target (condition-case nil (org-link-search target) (error= nil)))
> =A0 =A0 (beginning-of-line)
> =A0 =A0 (if (equal by "NONE")
> =A0 =A0 =A0 =A0(org-overview)
> =A0 =A0 =A0(case atom
> =A0 =A0 =A0 =A0('heading (progn (org-overview) (org-content)))
> =A0 =A0 =A0 =A0('line (progn (show-all) (org-buffers-toggle-headin= gs)))))
> =A0 =A0 (save-excursion
> =A0 =A0 =A0(mark-whole-buffer)
> =A0 =A0 =A0(indent-region (point-min) (point-max)))
> =A0 =A0 (org-buffers-mode)
> =A0 =A0 (setq buffer-read-only t)
> =A0 =A0 (current-buffer))))))
>
> =A0 =A0 (defun org-buffers-list:refresh (&optional arg)
> =A0 =A0 =A0"Refresh org-buffers listing."
> =A0 =A0 =A0(interactive "P")
> =A0 =A0 =A0(if arg (org-buffers-reset-state))
> =A0 =A0 =A0(org-buffers-list 'refresh))
>
> =A0 =A0 (defun org-buffers-list:by (&optional prop)
> =A0 =A0 =A0"Group buffers according to value of property PROP.&qu= ot;
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(let ((buffer-read-only nil)
> =A0 =A0 (headings-p (org-buffers-state-eq :atom 'heading)))
> =A0 =A0 =A0 =A0(unless (org-buffers-state-get :properties)
> =A0 =A0 =A0 =A0 =A0(org-buffers-toggle-properties))
> =A0 =A0 =A0 =A0(org-buffers-set-state
> =A0 =A0 =A0 =A0 `((:by .
> =A0 =A0 =A0 =A0,(or prop
> =A0 =A0 (org-completing-read
> =A0 =A0 =A0"Property to group by: "
> =A0 =A0 =A0(cons "NONE" (mapcar 'car org-buffers-buffer-= properties)))))))
> =A0 =A0 =A0 =A0(org-buffers-list 'refresh)
> =A0 =A0 =A0 =A0(unless headings-p (org-buffers-toggle-headings))))
>
> =A0 =A0 (defun org-buffers-toggle-properties ()
> =A0 =A0 =A0"Toggle entry properties in org-buffers listing buffer= .
> =A0 =A0 Removing properties may provide a less cluttered appearance fo= r
> =A0 =A0 browsing. However, in-buffer properties will be restored durin= g
> =A0 =A0 certain operations, such as `org-buffers-list:by'." > =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(if (org-buffers-state-get :properties)
> =A0 =A0 =A0 =A0 =A0(progn (org-buffers-delete-properties)
> =A0 =A0 =A0 =A0 (show-all)
> =A0 =A0 =A0 =A0 (org-buffers-set-state '((:properties . nil)))) > =A0 =A0 =A0 =A0(org-buffers-set-state
> =A0 =A0 =A0 =A0 '((:atom . heading) (:properties . t)))
> =A0 =A0 =A0 =A0(org-buffers-list 'refresh)))
>
> =A0 =A0 (defun org-buffers-toggle-headings ()
> =A0 =A0 =A0"Toggle viewing of buffers as org headings.
> =A0 =A0 Headings will be automatically restored during certain
> =A0 =A0 operations, such as setting deletion tags."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(let ((buffer-read-only nil)
> =A0 =A0 (headings-p (org-buffers-state-eq :atom 'heading))
> =A0 =A0 (flat-p (org-buffers-state-eq :by "NONE")))
> =A0 =A0 =A0 =A0(if (and headings-p (org-buffers-state-get :properties)= )
> =A0 =A0 (org-buffers-toggle-properties))
> =A0 =A0 =A0 =A0(save-excursion
> =A0 =A0 =A0 =A0 =A0(goto-char (point-min))
> =A0 =A0 =A0 =A0 =A0(if (and (or headings-p (not flat-p))
> =A0 =A0 =A0 =A0 =A0 (not (outline-on-heading-p)))
> =A0 =A0 =A0(outline-next-heading))
> =A0 =A0 =A0 =A0 =A0(if flat-p
> =A0 =A0 =A0(progn
> =A0 =A0 =A0 =A0(push-mark (point) 'nomsg 'activate)
> =A0 =A0 =A0 =A0(end-of-buffer)
> =A0 =A0 =A0 =A0(org-ctrl-c-star)
> =A0 =A0 =A0 =A0(pop-mark))
> =A0 =A0 (while (not (eobp))
> =A0 =A0 =A0(push-mark
> =A0 =A0 =A0 (save-excursion (forward-line 1) (point)) 'nomsg '= activate)
> =A0 =A0 =A0(org-forward-same-level 1)
> =A0 =A0 =A0(org-ctrl-c-star)
> =A0 =A0 =A0(pop-mark)))
> =A0 =A0 =A0 =A0 =A0(mark-whole-buffer)
> =A0 =A0 =A0 =A0 =A0(indent-region (point-min) (point-max)))
> =A0 =A0 =A0 =A0(org-buffers-set-state
> =A0 =A0 =A0 =A0 `((:atom . ,(if headings-p 'line 'heading)))))= )
>
> =A0 =A0 (defun org-buffers-delete-properties ()
> =A0 =A0 =A0(let ((buffer-read-only nil))
> =A0 =A0 =A0 =A0(save-excursion
> =A0 =A0 =A0 =A0 =A0(goto-char (point-min))
> =A0 =A0 =A0 =A0 =A0(org-buffers-delete-regions
> =A0 =A0 =A0 =A0 =A0 (nreverse
> =A0 =A0 (org-buffers-map-entries 'org-buffers-get-property-block))= ))))
>
> =A0 =A0 (defun org-buffers-get-property-block ()
> =A0 =A0 =A0"Return the (beg . end) range of the property drawer.<= br> > =A0 =A0 Unlike the org version the limits include the keywords delimit= ing
> =A0 =A0 the drawer."
> =A0 =A0 =A0(let ((beg (point))
> =A0 =A0 (end (progn (outline-next-heading) (point))))
> =A0 =A0 =A0 =A0(goto-char beg)
> =A0 =A0 =A0 =A0(if (re-search-forward org-property-drawer-re end t) > =A0 =A0 (cons (match-beginning 1) (match-end 0)))))
>
> =A0 =A0 (defun org-buffers-group-by (property)
> =A0 =A0 =A0"Group top level headings according to the value of PR= OPERTY."
> =A0 =A0 =A0(let ((atom (org-buffers-state-get :atom)))
> =A0 =A0 =A0 =A0(save-excursion
> =A0 =A0 =A0 =A0 =A0(goto-char (point-min))
> =A0 =A0 =A0 =A0 =A0(mapc (lambda (subtree) ;; Create subtree for each = value of `property'
> =A0 =A0 =A0 =A0 =A0(org-insert-heading t)
> =A0 =A0 =A0 =A0 =A0(if (> (org-buffers-outline-level) 1)
> =A0 =A0 =A0(org-promote))
> =A0 =A0 =A0 =A0 =A0(insert (car subtree) "\n")
> =A0 =A0 =A0 =A0 =A0(org-insert-subheading t)
> =A0 =A0 =A0 =A0 =A0(mapc 'org-buffers-insert-parsed-entry (cdr sub= tree)))
> =A0 =A0 =A0 =A0(prog1
> =A0 =A0 (mapcar (lambda (val) ;; Form list of parsed entries for each = unique value
> =A0 =A0 of `property'
> =A0 =A0 =A0(cons val (org-buffers-parse-selected-entries property val)= ))
> =A0 =A0 (sort
> =A0 =A0 (delete-dups (org-buffers-map-entries (lambda () (org-entry-ge= t nil
> =A0 =A0 property nil))))
> =A0 =A0 'string<))
> =A0 =A0 =A0 =A0 =A0(erase-buffer))))))
>
> =A0 =A0 (defun org-buffers-exclude-p (buffer)
> =A0 =A0 =A0"Return non-nil if BUFFER should not be listed."<= br> > =A0 =A0 =A0(or (member (with-current-buffer buffer major-mode)
> =A0 =A0 =A0 =A0 =A0org-buffers-excluded-modes)
> =A0 =A0 =A0 =A0 =A0(member buffer org-buffers-excluded-buffers)
> =A0 =A0 =A0 =A0 =A0(string=3D (substring buffer 0 1) " ")))<= br> >
> =A0 =A0 (defun org-buffers-reset-state ()
> =A0 =A0 =A0(org-buffers-set-state
> =A0 =A0 =A0 '((:by . "major-mode") (:atom . heading) (:p= roperties . nil))))
>
> =A0 =A0 (defun org-buffers-columns-view ()
> =A0 =A0 =A0"View buffers in Org-mode columns view.
> =A0 =A0 This is currently experimental. RET can be used to follow link= s
> =A0 =A0 in the first column, but certain other org-buffers keys confli= ct
> =A0 =A0 with column-view or otherwise do not work correctly."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(let ((by (org-buffers-state-get :by))
> =A0 =A0 (buffer-read-only nil))
> =A0 =A0 =A0 =A0(unless (equal by "NONE") (org-buffers-list:b= y "NONE"))
> =A0 =A0 =A0 =A0(unless (org-buffers-state-get :properties)
> =A0 =A0 =A0 =A0 =A0(org-buffers-toggle-properties))
> =A0 =A0 =A0 =A0(unless (equal by "NONE")
> =A0 =A0 =A0 =A0 =A0(goto-char (point-min))
> =A0 =A0 =A0 =A0 =A0(org-sort-entries-or-items nil ?r nil nil by)
> =A0 =A0 =A0 =A0 =A0(org-overview))
> =A0 =A0 =A0 =A0(mark-whole-buffer)
> =A0 =A0 =A0 =A0(org-columns)))
>
> =A0 =A0 ;;; Parsing and inserting entries
> =A0 =A0 (defun org-buffers-parse-selected-entries (prop val)
> =A0 =A0 =A0"Parse all entries with property PROP value VAL."=
> =A0 =A0 =A0(delq nil
> =A0 =A0 (org-buffers-map-entries
> =A0 =A0 (lambda () (when (equal (org-entry-get nil prop) val)
> =A0 =A0 =A0 =A0 =A0(cons (org-get-heading) (org-get-entry)))))))
>
> =A0 =A0 (defun org-buffers-insert-parsed-entry (entry)
> =A0 =A0 =A0"Insert a parsed entry"
> =A0 =A0 =A0(unless (org-at-heading-p) (org-insert-heading))
> =A0 =A0 =A0(insert (car entry) "\n")
> =A0 =A0 =A0(if (org-buffers-state-get :properties)
> =A0 =A0 =A0 =A0 =A0(insert (cdr entry))))
>
> =A0 =A0 (defun org-buffers-get-buffer-props (buffer)
> =A0 =A0 =A0"Create alist of properties of BUFFER, as strings.&quo= t;
> =A0 =A0 =A0(with-current-buffer buffer
> =A0 =A0 =A0 =A0(mapcar
> =A0 =A0 =A0 =A0 (lambda (pair) (cons (car pair) (eval (cdr pair)))) > =A0 =A0 =A0 =A0 org-buffers-buffer-properties)))
>
> =A0 =A0 ;;; Follow-link behaviour
>
> =A0 =A0 (defun org-buffers-follow-link ()
> =A0 =A0 =A0"Follow link to buffer on this line.
> =A0 =A0 The buffer-switching behaviour of this function is determined = by
> =A0 =A0 the variable `org-buffers-follow-link-method'. See also > =A0 =A0 `org-buffers-switch-to-buffer' and
> =A0 =A0 `org-buffers-switch-to-buffer-other-window', whose behavio= ur is
> =A0 =A0 hard-wired."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(org-buffers-switch-to-buffer-generic org-buffers-follow-li= nk-method))
>
> =A0 =A0 (defun org-buffers-switch-to-buffer ()
> =A0 =A0 "Switch to this entry's buffer in current window.&quo= t;
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(org-buffers-switch-to-buffer-generic 'current-window))=
>
> =A0 =A0 (defun org-buffers-switch-to-buffer-other-window ()
> =A0 =A0 =A0"Switch to this entry's buffer in other window.&qu= ot;
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(org-buffers-switch-to-buffer-generic 'other-window)) >
> =A0 =A0 (defun org-buffers-switch-to-buffer-generic (method)
> =A0 =A0 =A0(save-excursion
> =A0 =A0 =A0 =A0(let ((atom (org-buffers-state-get :atom)) buffer)
> =A0 =A0 =A0 =A0 =A0(cond
> =A0 =A0 =A0 =A0 =A0 ((eq atom 'heading) (org-back-to-heading))
> =A0 =A0 =A0 =A0 =A0 (t (beginning-of-line)))
> =A0 =A0 =A0 =A0 =A0(setq buffer (org-buffers-get-buffer-name))
> =A0 =A0 =A0 =A0 =A0(if (get-buffer buffer)
> =A0 =A0 =A0(case method
> =A0 =A0 =A0 =A0('org-open-at-point (org-open-at-point))
> =A0 =A0 =A0 =A0('current-window (switch-to-buffer buffer))
> =A0 =A0 =A0 =A0('other-window (switch-to-buffer-other-window buffe= r)))
> =A0 =A0 (error "No such buffer: %s" buffer)))))
>
> =A0 =A0 (defun org-buffers-get-buffer-name ()
> =A0 =A0 =A0"Get buffer-name for current entry."
> =A0 =A0 =A0(let ((headings-p (org-buffers-state-eq :atom 'heading)= ))
> =A0 =A0 =A0 =A0(or (and headings-p (org-entry-get nil "buffer-nam= e"))
> =A0 =A0 (and (save-excursion
> =A0 =A0 =A0 =A0 =A0 (if headings-p (org-back-to-heading))
> =A0 =A0 =A0 =A0 =A0 (re-search-forward "\\[\\[buffer:\\([^\]]*\\)= " (point-at-eol) t))
> =A0 =A0 =A0 =A0 (org-link-unescape (match-string 1))))))
>
> =A0 =A0 ;;; Setting tags and executing operations
>
> =A0 =A0 (defun org-buffers-tag-for-deletion ()
> =A0 =A0 =A0"Mark buffer for deletion.
> =A0 =A0 If a region is selected, all buffers in the region are marked = for
> =A0 =A0 deletion. Buffers marked for deletion can be deleted using
> =A0 =A0 `org-buffers-execute-pending-operations'."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(org-buffers-set-tags '("delete")))
>
> =A0 =A0 (defun org-buffers-remove-tags ()
> =A0 =A0 =A0"Remove deletion marks from buffers.
> =A0 =A0 If a region is selected, marks are removed from all buffers in=
> =A0 =A0 the region."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(org-buffers-set-tags nil))
>
> =A0 =A0 (defun org-buffers-set-tags (data)
> =A0 =A0 =A0"Set tags to DATA at all non top-level headings in reg= ion.
> =A0 =A0 DATA should be a list of strings. If DATA is nil, remove all t= ags
> =A0 =A0 at such headings."
> =A0 =A0 =A0(let* ((buffer-read-only nil)
> =A0 =A0 (region-p (org-region-active-p))
> =A0 =A0 (beg (if region-p (region-beginning) (point)))
> =A0 =A0 (end (if region-p (region-end) (point)))
> =A0 =A0 (headings-p (org-buffers-state-eq :atom 'heading))beg-line= end-line)
> =A0 =A0 =A0 =A0(save-excursion
> =A0 =A0 =A0 =A0 =A0(setq beg-line (progn (goto-char beg) (org-current-= line))
> =A0 =A0 =A0 =A0end-line (progn (goto-char end) (org-current-line))) > =A0 =A0 =A0 =A0 =A0(if headings-p
> =A0 =A0 =A0(setq
> =A0 =A0 =A0 end (if (and region-p (not (eq end-line beg-line)) (not (e= obp)))
> =A0 =A0 =A0 (progn (goto-char end) (org-back-to-heading) (point))
> =A0 =A0 (progn (outline-end-of-heading) (point)))
> =A0 =A0 =A0 beg (progn (goto-char beg) (point-at-bol)))
> =A0 =A0 (org-buffers-toggle-headings) ;; doesn't alter line number= s
> =A0 =A0 (setq beg (progn (org-goto-line beg-line) (point-at-bol))
> =A0 =A0 =A0 =A0 =A0end (if (eq end-line beg-line) (point-at-eol)
> =A0 =A0 =A0 =A0(progn (org-goto-line end-line) (point-at-bol)))))
> =A0 =A0 =A0 =A0 =A0(narrow-to-region beg end)
> =A0 =A0 =A0 =A0 =A0(goto-char (point-min))
> =A0 =A0 =A0 =A0 =A0(org-buffers-map-entries
> =A0 =A0 =A0 =A0 =A0 (lambda ()
> =A0 =A0 (when (or (org-buffers-state-eq :by "NONE")
> =A0 =A0 =A0 (> (org-outline-level) 1))
> =A0 =A0 =A0 (org-set-tags-to
> =A0 =A0 =A0 =A0(if data (delete-duplicates (append data (org-get-tags)= ) :test
> =A0 =A0 'string-equal))))))
> =A0 =A0 =A0 =A0 =A0(widen)
> =A0 =A0 =A0 =A0 =A0(org-content))
> =A0 =A0 =A0 =A0(unless region-p
> =A0 =A0 =A0 =A0 =A0(outline-next-heading)
> =A0 =A0 =A0 =A0 =A0(unless (or (> (org-outline-level) 1) (org-buffe= rs-state-eq :by
> =A0 =A0 "NONE"))
> =A0 =A0 (outline-next-heading)))
> =A0 =A0 =A0 =A0 =A0 =A0(unless headings-p (org-buffers-toggle-headings= ))))
>
> =A0 =A0 (defun org-buffers-execute-pending-operations ()
> =A0 =A0 =A0"Execute all pending operations.
> =A0 =A0 Currently the only type of operation supported is
> =A0 =A0 deletion. Buffers are tagged for deletion using
> =A0 =A0 `org-buffers-tag-for-deletion'. Remove such tags from buff= ers
> =A0 =A0 using `org-buffers-remove-tags'."
> =A0 =A0 =A0(interactive)
> =A0 =A0 =A0(let ((buffer-read-only nil)
> =A0 =A0 (headings-p (org-buffers-state-eq :atom 'heading)) buffer)=
> =A0 =A0 =A0 =A0(unless headings-p (org-buffers-toggle-headings))
> =A0 =A0 =A0 =A0(org-buffers-delete-regions
> =A0 =A0 =A0 =A0 (nreverse
> =A0 =A0 =A0 =A0 =A0(org-buffers-map-entries
> =A0 =A0 =A0 =A0 =A0 (lambda ()
> =A0 =A0 (if (setq buffer (org-buffers-get-buffer-name))
> =A0 =A0 =A0 =A0 (if (not (kill-buffer buffer))
> =A0 =A0 (error "Failed to kill buffer %s" buffer)
> =A0 =A0 =A0 =A0 =A0 (if (and (org-first-sibling-p)
> =A0 =A0 (not (save-excursion (org-goto-sibling))))
> =A0 =A0 =A0 (org-up-heading-safe)) ;; Only child so delete parent also=
> =A0 =A0 =A0 =A0 =A0 (cons (point) (1+ (org-end-of-subtree))))))
> =A0 =A0 =A0 =A0 =A0 "+delete")))
> =A0 =A0 =A0 =A0(unless headings-p (org-buffers-toggle-headings))))
>
> =A0 =A0 ;;; Utilities
>
> =A0 =A0 (defun org-buffers-map-entries (func &optional match)
> =A0 =A0 =A0(org-scan-tags
> =A0 =A0 =A0 func (if match (cdr (org-make-tags-matcher match)) t))) >
> =A0 =A0 (defun org-buffers-set-state (state)
> =A0 =A0 =A0"Add STATE to global state list.
> =A0 =A0 New settings have precedence over existing ones."
> =A0 =A0 =A0(mapc
> =A0 =A0 =A0 (lambda (pair) (unless (assoc (car pair) state)
> =A0 =A0 =A0 =A0(add-to-list 'state pair)))
> =A0 =A0 =A0 org-buffers-state)
> =A0 =A0 =A0(setq org-buffers-state state))
>
> =A0 =A0 (defmacro org-buffers-delete-regions (regions)
> =A0 =A0 =A0"Delete regions in list.
> =A0 =A0 REGIONS is a list of (beg . end) cons cells specifying buffer<= br> > =A0 =A0 regions."
> =A0 =A0 =A0`(mapc (lambda (pair) (if pair (delete-region (car pair) (c= dr pair))))
> =A0 =A0 ,regions))
>
> =A0 =A0 (defmacro org-buffers-state-get (key)
> =A0 =A0 =A0`(cdr (assoc ,key org-buffers-state)))
>
> =A0 =A0 (defmacro org-buffers-state-eq (key val)
> =A0 =A0 =A0`(equal (org-buffers-state-get ,key) ,val))
>
> =A0 =A0 (defmacro org-buffers-outline-level ()
> =A0 =A0 =A0'(save-excursion (beginning-of-line) (org-outline-level= )))
>
> =A0 =A0 ;;; Links to buffers
>
> =A0 =A0 (org-add-link-type "buffer" 'display-buffer)
> =A0 =A0 (add-hook 'org-store-link-functions 'org-buffers-store= -link)
>
> =A0 =A0 (defun org-buffers-store-link (&optional force)
> =A0 =A0 =A0"Store a link to an Emacs buffer.
> =A0 =A0 Returns nil by default, to avoid hijacking other link types.&q= uot;
> =A0 =A0 =A0(if force
> =A0 =A0 =A0 =A0 =A0(let* ((target (buffer-name))
> =A0 =A0 =A0 =A0 (desc target) link)
> =A0 =A0 (org-store-link-props :type "buffer")
> =A0 =A0 (setq link (org-make-link "buffer:" target))
> =A0 =A0 (org-add-link-props :link link :description desc)
> =A0 =A0 link)))
>
> =A0 =A0 (provide 'org-buffers)
> =A0 =A0 ;;; org-buffers.el ends here
> =A0 =A0 _______________________________________________
> =A0 =A0 Emacs-orgmode mailing list
> =A0 =A0 Please use `Reply All' to send replies to the list.
> =A0 =A0 Emacs-orgmode@gnu.org=
> =A0 =A0 http://lists.gnu.org/mailman/listinfo/emacs-orgmode=
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

--000e0cd5d184e888fe0484555178-- --===============0348007293== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-orgmode mailing list Please use `Reply All' to send replies to the list. Emacs-orgmode@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-orgmode --===============0348007293==--