1
0
mirror of https://git.savannah.gnu.org/git/emacs/org-mode.git synced 2024-11-25 07:27:57 +00:00

Implemented a module loading system.

This system works by configuring a variable that contains a list of
all available modules.  These will automatically be loaded when the
first buffer is turned into org-mode, or when a global command
is run that needs org-mode code available (such are
org-store-link.
This commit is contained in:
Carsten Dominik 2008-03-14 09:45:26 +01:00
parent 4d589476db
commit 5c339a3c14
9 changed files with 429 additions and 25 deletions

View File

@ -1,3 +1,11 @@
2008-03-14 Carsten Dominik <dominik@science.uva.nl>
* lisp/org-depend.el: Add `provide' for the module system.
* lisp/org-man.el: Add `provide' for the module system.
* lisp/org-interactive-query.el: Renamed from org-iq.el.
2008-03-05 Bastien Guerry <bzg@altern.org>
* lisp/org-elisp-symbol.el (org-elisp-symbol-store-link):

View File

@ -17,8 +17,7 @@ org-depend.el --- TODO dependencies for Org-mode
org-elisp-symbol.el --- Org links to emacs-lisp symbols
org-expiry.el --- expiry mechanism for Org entries
org-id.el --- Global id's for identifying entries
org-iq.el --- Interactive modification of tags query
org-irc.el --- Store links to IRC sessions.
org-interactive-query.el --- Interactive modification of tags query
org-iswitchb.el --- use iswitchb to select Org buffer
org-man.el --- Support for links to manpages in Org-mode
org-panel.el --- Simple routines for us with bad memory

View File

@ -232,4 +232,6 @@ this ID property, that entry is also checked."
(add-hook 'org-trigger-hook 'org-depend-trigger-todo)
(add-hook 'org-blocker-hook 'org-depend-block-todo)
(provide 'org-depend)
;;; org-depend.el ends here

View File

@ -0,0 +1,310 @@
;;; org-interactive-query.el --- Interactive modification of agenda query
;;
;; Copyright 2007 Free Software Foundation, Inc.
;;
;; Author: Christopher League <league at contrapunctus dot net>
;; Version: 1.0
;; Keywords: org, wp
;;
;; 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 this program; if not, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;
;;; Commentary:
;;
;; This ibrary implements interactive modification of a tags/todo query
;; in the org-agenda. It adds 4 keys to the agenda
;;
;; / add a keyword as a positive selection criterion
;; \ add a keyword as a newgative selection criterion
;; = clear a keyword from the selection string
;; ;
(require 'org)
(org-defkey org-agenda-mode-map "=" 'org-agenda-query-clear-cmd)
(org-defkey org-agenda-mode-map "/" 'org-agenda-query-and-cmd)
(org-defkey org-agenda-mode-map ";" 'org-agenda-query-or-cmd)
(org-defkey org-agenda-mode-map "\\" 'org-agenda-query-not-cmd)
;;; Agenda interactive query manipulation
(defcustom org-agenda-query-selection-single-key t
"Non-nil means, query manipulation exits after first change.
When nil, you have to press RET to exit it.
During query selection, you can toggle this flag with `C-c'.
This variable can also have the value `expert'. In this case, the window
displaying the tags menu is not even shown, until you press C-c again."
:group 'org-agenda
:type '(choice
(const :tag "No" nil)
(const :tag "Yes" t)
(const :tag "Expert" expert)))
(defun org-agenda-query-selection (current op table &optional todo-table)
"Fast query manipulation with single keys.
CURRENT is the current query string, OP is the initial
operator (one of \"+|-=\"), TABLE is an alist of tags and
corresponding keys, possibly with grouping information.
TODO-TABLE is a similar table with TODO keywords, should these
have keys assigned to them. If the keys are nil, a-z are
automatically assigned. Returns the new query string, or nil to
not change the current one."
(let* ((fulltable (append table todo-table))
(maxlen (apply 'max (mapcar
(lambda (x)
(if (stringp (car x)) (string-width (car x)) 0))
fulltable)))
(fwidth (+ maxlen 3 1 3))
(ncol (/ (- (window-width) 4) fwidth))
(expert (eq org-agenda-query-selection-single-key 'expert))
(exit-after-next org-agenda-query-selection-single-key)
(done-keywords org-done-keywords)
tbl char cnt e groups ingroup
tg c2 c c1 ntable rtn)
(save-window-excursion
(if expert
(set-buffer (get-buffer-create " *Org tags*"))
(delete-other-windows)
(split-window-vertically)
(org-switch-to-buffer-other-window (get-buffer-create " *Org tags*")))
(erase-buffer)
(org-set-local 'org-done-keywords done-keywords)
(insert "Query: " current "\n")
(org-agenda-query-op-line op)
(insert "\n\n")
(org-fast-tag-show-exit exit-after-next)
(setq tbl fulltable char ?a cnt 0)
(while (setq e (pop tbl))
(cond
((equal e '(:startgroup))
(push '() groups) (setq ingroup t)
(when (not (= cnt 0))
(setq cnt 0)
(insert "\n"))
(insert "{ "))
((equal e '(:endgroup))
(setq ingroup nil cnt 0)
(insert "}\n"))
(t
(setq tg (car e) c2 nil)
(if (cdr e)
(setq c (cdr e))
;; automatically assign a character.
(setq c1 (string-to-char
(downcase (substring
tg (if (= (string-to-char tg) ?@) 1 0)))))
(if (or (rassoc c1 ntable) (rassoc c1 table))
(while (or (rassoc char ntable) (rassoc char table))
(setq char (1+ char)))
(setq c2 c1))
(setq c (or c2 char)))
(if ingroup (push tg (car groups)))
(setq tg (org-add-props tg nil 'face
(cond
((not (assoc tg table))
(org-get-todo-face tg))
(t nil))))
(if (and (= cnt 0) (not ingroup)) (insert " "))
(insert "[" c "] " tg (make-string
(- fwidth 4 (length tg)) ?\ ))
(push (cons tg c) ntable)
(when (= (setq cnt (1+ cnt)) ncol)
(insert "\n")
(if ingroup (insert " "))
(setq cnt 0)))))
(setq ntable (nreverse ntable))
(insert "\n")
(goto-char (point-min))
(if (and (not expert) (fboundp 'fit-window-to-buffer))
(fit-window-to-buffer))
(setq rtn
(catch 'exit
(while t
(message "[a-z..]:Toggle [SPC]:clear [RET]:accept [TAB]:free%s%s"
(if groups " [!] no groups" " [!]groups")
(if expert " [C-c]:window" (if exit-after-next " [C-c]:single" " [C-c]:multi")))
(setq c (let ((inhibit-quit t)) (read-char-exclusive)))
(cond
((= c ?\r) (throw 'exit t))
((= c ?!)
(setq groups (not groups))
(goto-char (point-min))
(while (re-search-forward "[{}]" nil t) (replace-match " ")))
((= c ?\C-c)
(if (not expert)
(org-fast-tag-show-exit
(setq exit-after-next (not exit-after-next)))
(setq expert nil)
(delete-other-windows)
(split-window-vertically)
(org-switch-to-buffer-other-window " *Org tags*")
(and (fboundp 'fit-window-to-buffer)
(fit-window-to-buffer))))
((or (= c ?\C-g)
(and (= c ?q) (not (rassoc c ntable))))
(setq quit-flag t))
((= c ?\ )
(setq current "")
(if exit-after-next (setq exit-after-next 'now)))
((= c ?\[) ; clear left
(org-agenda-query-decompose current)
(setq current (concat "/" (match-string 2 current)))
(if exit-after-next (setq exit-after-next 'now)))
((= c ?\]) ; clear right
(org-agenda-query-decompose current)
(setq current (match-string 1 current))
(if exit-after-next (setq exit-after-next 'now)))
((= c ?\t)
(condition-case nil
(setq current (read-string "Query: " current))
(quit))
(if exit-after-next (setq exit-after-next 'now)))
;; operators
((or (= c ?/) (= c ?+)) (setq op "+"))
((or (= c ?\;) (= c ?|)) (setq op "|"))
((or (= c ?\\) (= c ?-)) (setq op "-"))
((= c ?=) (setq op "="))
;; todos
((setq e (rassoc c todo-table) tg (car e))
(setq current (org-agenda-query-manip
current op groups 'todo tg))
(if exit-after-next (setq exit-after-next 'now)))
;; tags
((setq e (rassoc c ntable) tg (car e))
(setq current (org-agenda-query-manip
current op groups 'tag tg))
(if exit-after-next (setq exit-after-next 'now))))
(if (eq exit-after-next 'now) (throw 'exit t))
(goto-char (point-min))
(beginning-of-line 1)
(delete-region (point) (point-at-eol))
(insert "Query: " current)
(beginning-of-line 2)
(delete-region (point) (point-at-eol))
(org-agenda-query-op-line op)
(goto-char (point-min)))))
(if rtn current nil))))
(defun org-agenda-query-op-line (op)
(insert "Operator: "
(org-agenda-query-op-entry (equal op "+") "/+" "and")
(org-agenda-query-op-entry (equal op "|") ";|" "or")
(org-agenda-query-op-entry (equal op "-") "\\-" "not")
(org-agenda-query-op-entry (equal op "=") "=" "clear")))
(defun org-agenda-query-op-entry (matchp chars str)
(if matchp
(org-add-props (format "[%s %s] " chars (upcase str))
nil 'face 'org-todo)
(format "[%s]%s " chars str)))
(defun org-agenda-query-decompose (current)
(string-match "\\([^/]*\\)/?\\(.*\\)" current))
(defun org-agenda-query-clear (current prefix tag)
(if (string-match (concat prefix "\\b" (regexp-quote tag) "\\b") current)
(replace-match "" t t current)
current))
(defun org-agenda-query-manip (current op groups kind tag)
"Apply an operator to a query string and a tag.
CURRENT is the current query string, OP is the operator, GROUPS is a
list of lists of tags that are mutually exclusive. KIND is 'tag for a
regular tag, or 'todo for a TODO keyword, and TAG is the tag or
keyword string."
;; If this tag is already in query string, remove it.
(setq current (org-agenda-query-clear current "[-\\+&|]?" tag))
(if (equal op "=") current
;; When using AND, also remove mutually exclusive tags.
(if (equal op "+")
(loop for g in groups do
(if (member tag g)
(mapc (lambda (x)
(setq current
(org-agenda-query-clear current "\\+" x)))
g))))
;; Decompose current query into q1 (tags) and q2 (TODOs).
(org-agenda-query-decompose current)
(let* ((q1 (match-string 1 current))
(q2 (match-string 2 current)))
(cond
((eq kind 'tag)
(concat q1 op tag "/" q2))
;; It's a TODO; when using AND, drop all other TODOs.
((equal op "+")
(concat q1 "/+" tag))
(t
(concat q1 "/" q2 op tag))))))
(defun org-agenda-query-global-todo-keys (&optional files)
"Return alist of all TODO keywords and their fast keys, in all FILES."
(let (alist)
(unless (and files (car files))
(setq files (org-agenda-files)))
(save-excursion
(loop for f in files do
(set-buffer (find-file-noselect f))
(loop for k in org-todo-key-alist do
(setq alist (org-agenda-query-merge-todo-key
alist k)))))
alist))
(defun org-agenda-query-merge-todo-key (alist entry)
(let (e)
(cond
;; if this is not a keyword (:startgroup, etc), ignore it
((not (stringp (car entry))))
;; if keyword already exists, replace char if it's null
((setq e (assoc (car entry) alist))
(when (null (cdr e)) (setcdr e (cdr entry))))
;; if char already exists, prepend keyword but drop char
((rassoc (cdr entry) alist)
(message "TRACE POSITION 2")
(setq alist (cons (cons (car entry) nil) alist)))
;; else, prepend COPY of entry
(t
(setq alist (cons (cons (car entry) (cdr entry)) alist)))))
alist)
(defun org-agenda-query-generic-cmd (op)
"Activate query manipulation with OP as initial operator."
(let ((q (org-agenda-query-selection org-agenda-query-string op
org-tag-alist
(org-agenda-query-global-todo-keys))))
(when q
(setq org-agenda-query-string q)
(org-agenda-redo))))
(defun org-agenda-query-clear-cmd ()
"Activate query manipulation, to clear a tag from the string."
(interactive)
(org-agenda-query-generic-cmd "="))
(defun org-agenda-query-and-cmd ()
"Activate query manipulation, initially using the AND (+) operator."
(interactive)
(org-agenda-query-generic-cmd "+"))
(defun org-agenda-query-or-cmd ()
"Activate query manipulation, initially using the OR (|) operator."
(interactive)
(org-agenda-query-generic-cmd "|"))
(defun org-agenda-query-not-cmd ()
"Activate query manipulation, initially using the NOT (-) operator."
(interactive)
(org-agenda-query-generic-cmd "-"))
(provide 'org-interactive-query)

View File

@ -306,3 +306,5 @@ keyword string."
"Activate query manipulation, initially using the NOT (-) operator."
(interactive)
(org-agenda-query-generic-cmd "-"))
(provide 'org-interactive-query)

View File

@ -1,4 +1,29 @@
;;; org-man.el - Support for links to manpages in Org-mode
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;; Version: 1.0
;;
;; This file is not yet part of GNU Emacs.
;;
;; GNU Emacs 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.
;; 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
;; 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:
(require 'org)

View File

@ -1,3 +1,12 @@
2008-03-14 Carsten Dominik <dominik@science.uva.nl>
* org.el (org-modules-loaded): New variable.
(org-load-modules-maybe, org-set-modules): New function.
(org-modules): New option.
(org-mode, org-cycle, orgstruct-mode, org-run-like-in-org-mode)
(orgtbl-mode, org-store-link, org-insert-link-global)
(org-open-at-point): Call `org-load-modules-maybe'.
2008-03-13 Phil Jackson <phil@shellarchive.co.uk>
* org-irc.el: New function to ensure port number is always

View File

@ -9,6 +9,19 @@
** Details
*** Loading modules
Org-mode has now a system for loading modules by simply
configuring an option that lists all the modules you want to
use. Customize the variable `org-modules'. That variable
lists modules that are part of the Org-mode core (and in this
way part of Emacs), as well as contributed packages that will
only be available when you have installed them properly (most
likely by downloading the distribution and adding
CONTRIB/lisp to your load path.
*** Misc
- When an entry already has a scheduling or deadline time
stamp, calling `C-c C-s' or `C-c C-d', respectively, will no
use that old date as the default, and you can can use the
@ -19,6 +32,8 @@
This was an omission in the earlier implementation, spotted
by Wanrong Lin. Thanks!
* Version 5.23
** Overview

80
org.el
View File

@ -156,28 +156,56 @@ With prefix arg HERE, insert it at point."
:group 'org
:type 'hook)
;(defcustom org-default-extensions '(org-irc)
; "Extensions that should always be loaded together with org.el.
;If the description starts with <A>, this means the extension
;will be autoloaded when needed, preloading is not necessary.
;FIXME: this does not ork correctly, ignore it for now."
; :group 'org
; :type
; '(set :greedy t
; (const :tag " Mouse support (org-mouse.el)" org-mouse)
; (const :tag "<A> Publishing (org-publish.el)" org-publish)
; (const :tag "<A> LaTeX export (org-export-latex.el)" org-export-latex)
; (const :tag " IRC/ERC links (org-irc.el)" org-irc)
; (const :tag " Apple Mail message links under OS X (org-mac-message.el)" org-mac-message)))
;
;(defun org-load-default-extensions ()
; "Load all extensions listed in `org-default-extensions'."
; (mapc (lambda (ext)
; (condition-case nil (require ext)
; (error (message "Problems while trying to load feature `%s'" ext))))
; org-default-extensions))
(defvar org-modules-loaded nil
"Have the modules been loaded already?")
;(eval-after-load "org" '(org-load-default-extensions))
(defun org-load-modules-maybe (&optional force)
"Load all extensions listed in `org-default-extensions'."
(when (or force (not org-modules-loaded))
(mapc (lambda (ext)
(condition-case nil (require ext)
(error (message "Problems while trying to load feature `%s'" ext))))
org-modules)
(setq org-modules-loaded t)))
(defun org-set-modules (var value)
"Set VAR to VALUE and call `org-load-modules-maybe' with the force flag."
(set var value)
(when (featurep 'org)
(org-load-modules-maybe 'force)))
(defcustom org-modules '(org-irc)
"Extensions that should always be loaded together with org.el.
If the description starts with <A>, this means the extension
will be autoloaded when needed, preloading is not necessary.
If a description starts with <C>, the file is not part of emacs
and loading it will require that you have downloaded and properly installed
the org-mode distribution."
:group 'org
:set 'org-set-modules
:type
'(set :greedy t
(const :tag "A export-latex: LaTeX export" org-export-latex)
(const :tag " irc: IRC/ERC links" org-irc)
(const :tag " mac-message: Apple Mail message links under OS X" org-mac-message)
(const :tag " mouse: Mouse support" org-mouse)
(const :tag "A publish: Publishing" org-publish)
(const :tag "C annotate-file: Annotate a file with org syntax" org-annotate-file)
(const :tag "C bibtex: Org links to BibTeX entries" org-bibtex)
(const :tag "C depend: TODO dependencies for Org-mode" org-depend)
(const :tag "C elisp-symbol: Org links to emacs-lisp symbols" org-elisp-symbol)
(const :tag "C expiry: Expiry mechanism for Org entries" org-expiry)
(const :tag "C id: Global id's for identifying entries" org-id)
(const :tag "C interactive-query: Interactive modification of tags query" org-interactive-query)
(const :tag "C iswitchb: Use iswitchb to select Org buffer" org-iswitchb)
(const :tag "C mairix: Hook mairix search into Org for different MUAs" org-mairix)
(const :tag "C man: Support for links to manpages in Org-mode" org-man)
(const :tag "C mew: Support for links to messages in Mew" org-mew)
(const :tag "C panel: Simple routines for us with bad memory" org-panel)
(const :tag "C registry: A registry for Org links" org-registry)
(const :tag "C org2rem: Convert org appointments into reminders" org2rem)
(const :tag "C screen: Visit screen sessions through Org-mode links" org-screen)
(const :tag "C toc: Table of contents for Org-mode buffer" org-toc)))
;; FIXME: Needs a separate group...
(defcustom org-completion-fallback-command 'hippie-expand
@ -5087,6 +5115,7 @@ The following commands are available:
(define-key org-mode-map [menu-bar hide] 'undefined)
(define-key org-mode-map [menu-bar show] 'undefined))
(org-load-modules-maybe)
(easy-menu-add org-org-menu)
(easy-menu-add org-tbl-menu)
(org-install-agenda-files-menu)
@ -5818,6 +5847,7 @@ If KWD is a number, get the corresponding match group."
no headline in line 1, this function will act as if called with prefix arg.
But only if also the variable `org-cycle-global-at-bob' is t."
(interactive "P")
(org-load-modules-maybe)
(let* ((outline-regexp
(if (and (org-mode-p) org-cycle-include-plain-lists)
"\\(?:\\*+ \\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) \\)"
@ -7918,6 +7948,7 @@ M-RET Insert new heading/item
S-M-RET Insert new TODO heading / Chekbox item
C-c C-c Set tags / toggle checkbox"
nil " OrgStruct" nil
(org-load-modules-maybe)
(and (orgstruct-setup) (defun orgstruct-setup () nil)))
;;;###autoload
@ -8057,6 +8088,7 @@ Possible values in the list of contexts are `table', `headline', and `item'."
;;;###autoload
(defun org-run-like-in-org-mode (cmd)
(org-load-modules-maybe)
(unless org-local-vars
(setq org-local-vars (org-get-local-variables)))
(eval (list 'let org-local-vars
@ -11459,6 +11491,7 @@ table editor in arbitrary modes.")
(defun orgtbl-mode (&optional arg)
"The `org-mode' table editor as a minor mode for use in other modes."
(interactive)
(org-load-modules-maybe)
(if (org-mode-p)
;; Exit without error, in case some hook functions calls this
;; by accident in org-mode.
@ -12177,7 +12210,7 @@ For some link types, a prefix arg is interpreted:
For links to usenet articles, arg negates `org-usenet-links-prefer-google'.
For file links, arg negates `org-context-in-file-links'."
(interactive "P")
(condition-case nil (require 'org-irc) (error nil))
(org-load-modules-maybe)
(setq org-store-link-plist nil) ; reset
(let (link cpltxt desc description search txt)
(cond
@ -12597,6 +12630,7 @@ This is the list that is used before handing over to the browser.")
"Insert a link like Org-mode does.
This command can be called in any mode to insert a link in Org-mode syntax."
(interactive)
(org-load-modules-maybe)
(org-run-like-in-org-mode 'org-insert-link))
(defun org-insert-link (&optional complete-file)
@ -12832,7 +12866,7 @@ the end of the current subtree.
Normally, files will be opened by an appropriate application. If the
optional argument IN-EMACS is non-nil, Emacs will visit the file."
(interactive "P")
(condition-case nil (require 'org-irc) (error nil))
(org-load-modules-maybe)
(move-marker org-open-link-marker (point))
(setq org-window-config-before-follow-link (current-window-configuration))
(org-remove-occur-highlights nil nil t)