Browse Source

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.
Carsten Dominik 17 years ago
parent
commit
5c339a3c14

+ 8 - 0
CONTRIB/ChangeLog

@@ -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>
 2008-03-05  Bastien Guerry  <bzg@altern.org>
 
 
 	* lisp/org-elisp-symbol.el (org-elisp-symbol-store-link):
 	* lisp/org-elisp-symbol.el (org-elisp-symbol-store-link):

+ 1 - 2
CONTRIB/README

@@ -17,8 +17,7 @@ org-depend.el        --- TODO dependencies for Org-mode
 org-elisp-symbol.el  --- Org links to emacs-lisp symbols
 org-elisp-symbol.el  --- Org links to emacs-lisp symbols
 org-expiry.el 	     --- expiry mechanism for Org entries
 org-expiry.el 	     --- expiry mechanism for Org entries
 org-id.el 	     --- Global id's for identifying 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-iswitchb.el      --- use iswitchb to select Org buffer
 org-man.el 	     --- Support for links to manpages in Org-mode
 org-man.el 	     --- Support for links to manpages in Org-mode
 org-panel.el 	     --- Simple routines for us with bad memory
 org-panel.el 	     --- Simple routines for us with bad memory

+ 2 - 0
CONTRIB/lisp/org-depend.el

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

+ 310 - 0
CONTRIB/lisp/org-interactive-query.el

@@ -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)

+ 2 - 0
CONTRIB/lisp/org-iq.el

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

+ 25 - 0
CONTRIB/lisp/org-man.el

@@ -1,4 +1,29 @@
 ;;; org-man.el - Support for links to manpages in Org-mode
 ;;; 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)
 (require 'org)
 
 

+ 9 - 0
ChangeLog

@@ -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>
 2008-03-13  Phil Jackson  <phil@shellarchive.co.uk>
 
 
 	* org-irc.el: New function to ensure port number is always
 	* org-irc.el: New function to ensure port number is always

+ 15 - 0
ORGWEBPAGE/Changes.org

@@ -9,6 +9,19 @@
 
 
 ** Details
 ** 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
    - When an entry already has a scheduling or deadline time
      stamp, calling `C-c C-s' or `C-c C-d', respectively, will no
      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
      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
      This was an omission in the earlier implementation, spotted
      by Wanrong Lin.  Thanks!
      by Wanrong Lin.  Thanks!
 
 
+
+
 * Version 5.23
 * Version 5.23
 
 
 ** Overview
 ** Overview

+ 58 - 24
org.el

@@ -156,28 +156,56 @@ With prefix arg HERE, insert it at point."
   :group 'org
   :group 'org
   :type 'hook)
   :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))
-
-;(eval-after-load "org" '(org-load-default-extensions))
+(defvar org-modules-loaded nil
+  "Have the modules been loaded already?")
+
+(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...
 ;; FIXME: Needs a separate group...
 (defcustom org-completion-fallback-command 'hippie-expand
 (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 hide] 'undefined)
     (define-key org-mode-map [menu-bar show] 'undefined))
     (define-key org-mode-map [menu-bar show] 'undefined))
 
 
+  (org-load-modules-maybe)
   (easy-menu-add org-org-menu)
   (easy-menu-add org-org-menu)
   (easy-menu-add org-tbl-menu)
   (easy-menu-add org-tbl-menu)
   (org-install-agenda-files-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.
   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."
   But only if also the variable `org-cycle-global-at-bob' is t."
   (interactive "P")
   (interactive "P")
+  (org-load-modules-maybe)
   (let* ((outline-regexp
   (let* ((outline-regexp
 	  (if (and (org-mode-p) org-cycle-include-plain-lists)
 	  (if (and (org-mode-p) org-cycle-include-plain-lists)
 	      "\\(?:\\*+ \\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) \\)"
 	      "\\(?:\\*+ \\|\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) \\)"
@@ -7918,6 +7948,7 @@ M-RET       Insert new heading/item
 S-M-RET     Insert new TODO heading / Chekbox item
 S-M-RET     Insert new TODO heading / Chekbox item
 C-c C-c     Set tags / toggle checkbox"
 C-c C-c     Set tags / toggle checkbox"
   nil " OrgStruct" nil
   nil " OrgStruct" nil
+  (org-load-modules-maybe)
   (and (orgstruct-setup) (defun orgstruct-setup () nil)))
   (and (orgstruct-setup) (defun orgstruct-setup () nil)))
 
 
 ;;;###autoload
 ;;;###autoload
@@ -8057,6 +8088,7 @@ Possible values in the list of contexts are `table', `headline', and `item'."
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-run-like-in-org-mode (cmd)
 (defun org-run-like-in-org-mode (cmd)
+  (org-load-modules-maybe)
   (unless org-local-vars
   (unless org-local-vars
     (setq org-local-vars (org-get-local-variables)))
     (setq org-local-vars (org-get-local-variables)))
   (eval (list 'let org-local-vars
   (eval (list 'let org-local-vars
@@ -11459,6 +11491,7 @@ table editor in arbitrary modes.")
 (defun orgtbl-mode (&optional arg)
 (defun orgtbl-mode (&optional arg)
   "The `org-mode' table editor as a minor mode for use in other modes."
   "The `org-mode' table editor as a minor mode for use in other modes."
   (interactive)
   (interactive)
+  (org-load-modules-maybe)
   (if (org-mode-p)
   (if (org-mode-p)
       ;; Exit without error, in case some hook functions calls this
       ;; Exit without error, in case some hook functions calls this
       ;; by accident in org-mode.
       ;; 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 links to usenet articles, arg negates `org-usenet-links-prefer-google'.
 For file links, arg negates `org-context-in-file-links'."
 For file links, arg negates `org-context-in-file-links'."
   (interactive "P")
   (interactive "P")
-  (condition-case nil (require 'org-irc) (error nil))
+  (org-load-modules-maybe)
   (setq org-store-link-plist nil)  ; reset
   (setq org-store-link-plist nil)  ; reset
   (let (link cpltxt desc description search txt)
   (let (link cpltxt desc description search txt)
     (cond
     (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.
   "Insert a link like Org-mode does.
 This command can be called in any mode to insert a link in Org-mode syntax."
 This command can be called in any mode to insert a link in Org-mode syntax."
   (interactive)
   (interactive)
+  (org-load-modules-maybe)
   (org-run-like-in-org-mode 'org-insert-link))
   (org-run-like-in-org-mode 'org-insert-link))
 
 
 (defun org-insert-link (&optional complete-file)
 (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
 Normally, files will be opened by an appropriate application.  If the
 optional argument IN-EMACS is non-nil, Emacs will visit the file."
 optional argument IN-EMACS is non-nil, Emacs will visit the file."
   (interactive "P")
   (interactive "P")
-  (condition-case nil (require 'org-irc) (error nil))
+  (org-load-modules-maybe)
   (move-marker org-open-link-marker (point))
   (move-marker org-open-link-marker (point))
   (setq org-window-config-before-follow-link (current-window-configuration))
   (setq org-window-config-before-follow-link (current-window-configuration))
   (org-remove-occur-highlights nil nil t)
   (org-remove-occur-highlights nil nil t)