diff options
Diffstat (limited to 'lisp/org/org.el')
-rw-r--r-- | lisp/org/org.el | 2108 |
1 files changed, 1507 insertions, 601 deletions
diff --git a/lisp/org/org.el b/lisp/org/org.el index 7aa385fee9d..5b37e0aa260 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -6,7 +6,7 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 6.35i +;; Version: 7.01 ;; ;; This file is part of GNU Emacs. ;; @@ -72,8 +72,20 @@ (eval-when-compile (require 'cl) - (require 'gnus-sum) - (require 'calendar)) + (require 'gnus-sum)) + +(require 'calendar) +;; Emacs 22 calendar compatibility: Make sure the new variables are available +(when (fboundp 'defvaralias) + (unless (boundp 'calendar-view-holidays-initially-flag) + (defvaralias 'calendar-view-holidays-initially-flag + 'view-calendar-holidays-initially)) + (unless (boundp 'calendar-view-diary-initially-flag) + (defvaralias 'calendar-view-diary-initially-flag + 'view-diary-entries-initially)) + (unless (boundp 'diary-fancy-buffer) + (defvaralias 'diary-fancy-buffer 'fancy-diary-buffer))) + ;; For XEmacs, noutline is not yet provided by outline.el, so arrange for ;; the file noutline.el being loaded. (if (featurep 'xemacs) (condition-case nil (require 'noutline))) @@ -83,6 +95,7 @@ (require 'time-date) (unless (fboundp 'time-subtract) (defalias 'time-subtract 'subtract-time)) (require 'easymenu) +(require 'overlay) (require 'org-macs) (require 'org-entities) @@ -92,11 +105,86 @@ (require 'org-src) (require 'org-footnote) +;; babel +(require 'ob) +(require 'ob-table) +(require 'ob-lob) +(require 'ob-ref) +(require 'ob-tangle) +(require 'ob-comint) +(require 'ob-keys) + +;; load languages based on value of `org-babel-load-languages' +(defvar org-babel-load-languages) +;;;###autoload +(defun org-babel-do-load-languages (sym value) + "Load the languages defined in `org-babel-load-languages'." + (set-default sym value) + (mapc (lambda (pair) + (let ((active (cdr pair)) (lang (symbol-name (car pair)))) + (if active + (progn + (require (intern (concat "ob-" lang)))) + (progn + (funcall 'fmakunbound + (intern (concat "org-babel-execute:" lang))) + (funcall 'fmakunbound + (intern (concat "org-babel-expand-body:" lang))))))) + org-babel-load-languages)) + +(defcustom org-babel-load-languages '((emacs-lisp . t)) + "Languages which can be evaluated in Org-mode buffers. +This list can be used to load support for any of the languages +below, note that each language will depend on a different set of +system executables and/or Emacs modes. When a language is +\"loaded\", then code blocks in that language can be evaluated +with `org-babel-execute-src-block' bound by default to C-c +C-c (note the `org-babel-no-eval-on-ctrl-c-ctrl-c' variable can +be set to remove code block evaluation from the C-c C-c +keybinding. By default only Emacs Lisp (which has no +requirements) is loaded." + :group 'org-babel + :set 'org-babel-do-load-languages + :type '(alist :tag "Babel Languages" + :key-type + (choice + (const :tag "C" C) + (const :tag "R" R) + (const :tag "Asymptote" asymptote) + (const :tag "Clojure" clojure) + (const :tag "CSS" css) + (const :tag "Ditaa" ditaa) + (const :tag "Dot" dot) + (const :tag "Emacs Lisp" emacs-lisp) + (const :tag "Gnuplot" gnuplot) + (const :tag "Haskell" haskell) + (const :tag "Latex" latex) + (const :tag "Matlab" matlab) + (const :tag "Mscgen" mscgen) + (const :tag "Ocaml" ocaml) + (const :tag "Octave" octave) + (const :tag "Perl" perl) + (const :tag "Python" python) + (const :tag "Ruby" ruby) + (const :tag "Sass" sass) + (const :tag "Screen" screen) + (const :tag "Shell Script" sh) + (const :tag "Sql" sql) + (const :tag "Sqlite" sqlite)) + :value-type (boolean :tag "Activate" :value t))) + ;;;; Customization variables +(defcustom org-clone-delete-id nil + "Remove ID property of clones of a subtree. +When non-nil, clones of a subtree don't inherit the ID property. +Otherwise they inherit the ID property with a new unique +identifier." + :type 'boolean + :group 'org-id) ;;; Version -(defconst org-version "6.35i" +(defconst org-version "7.01" "The version number of the file org.el.") (defun org-version (&optional here) @@ -228,6 +316,7 @@ to add the symbol `xyz', and the package must have a call to (const :tag "C learn: SuperMemo's incremental learning algorithm" org-learn) (const :tag "C mairix: Hook mairix search into Org-mode for different MUAs" org-mairix) (const :tag "C mac-iCal Imports events from iCal.app to the Emacs diary" org-mac-iCal) + (const :tag "C mac-link-grabber Grab links and URLs from various Mac applications" org-mac-link-grabber) (const :tag "C man: Support for links to manpages in Org-mode" org-man) (const :tag "C mtags: Support for muse-like tags" org-mtags) (const :tag "C panel: Simple routines for us with bad memory" org-panel) @@ -239,13 +328,14 @@ to add the symbol `xyz', and the package must have a call to (const :tag "C sqlinsert: Convert Org-mode tables to SQL insertions" orgtbl-sqlinsert) (const :tag "C toc: Table of contents for Org-mode buffer" org-toc) (const :tag "C track: Keep up with Org-mode development" org-track) + (const :tag "C TaskJuggler: Export tasks to a TaskJuggler project" org-taskjuggler) (repeat :tag "External packages" :inline t (symbol :tag "Package")))) (defcustom org-support-shift-select nil "Non-nil means make shift-cursor commands select text when possible. In Emacs 23, when `shift-select-mode' is on, shifted cursor keys start -selecting a region, or enlarge thusly regions started in this way. +selecting a region, or enlarge regions started in this way. In Org-mode, in special contexts, these same keys are used for other purposes, important enough to compete with shift selection. Org tries to balance these needs by supporting `shift-select-mode' outside these @@ -324,6 +414,40 @@ the following lines anywhere in the buffer: (const :tag "Not" nil) (const :tag "Globally (slow on startup in large files)" t))) +(defcustom org-use-sub-superscripts t + "Non-nil means interpret \"_\" and \"^\" for export. +When this option is turned on, you can use TeX-like syntax for sub- and +superscripts. Several characters after \"_\" or \"^\" will be +considered as a single item - so grouping with {} is normally not +needed. For example, the following things will be parsed as single +sub- or superscripts. + + 10^24 or 10^tau several digits will be considered 1 item. + 10^-12 or 10^-tau a leading sign with digits or a word + x^2-y^3 will be read as x^2 - y^3, because items are + terminated by almost any nonword/nondigit char. + x_{i^2} or x^(2-i) braces or parenthesis do grouping. + +Still, ambiguity is possible - so when in doubt use {} to enclose the +sub/superscript. If you set this variable to the symbol `{}', +the braces are *required* in order to trigger interpretations as +sub/superscript. This can be helpful in documents that need \"_\" +frequently in plain text. + +Not all export backends support this, but HTML does. + +This option can also be set with the +OPTIONS line, e.g. \"^:nil\"." + :group 'org-startup + :group 'org-export-translation + :type '(choice + (const :tag "Always interpret" t) + (const :tag "Only with braces" {}) + (const :tag "Never interpret" nil))) + +(if (fboundp 'defvaralias) + (defvaralias 'org-export-with-sub-superscripts 'org-use-sub-superscripts)) + + (defcustom org-startup-with-beamer-mode nil "Non-nil means turn on `org-beamer-mode' on startup. This can also be configured on a per-file basis by adding one of @@ -371,10 +495,10 @@ become effective." :type 'boolean) (defcustom org-use-extra-keys nil - "Non-nil means use extra key sequence definitions for certain -commands. This happens automatically if you run XEmacs or if -window-system is nil. This variable lets you do the same -manually. You must set it before loading org. + "Non-nil means use extra key sequence definitions for certain commands. +This happens automatically if you run XEmacs or if `window-system' +is nil. This variable lets you do the same manually. You must +set it before loading org. Example: on Carbon Emacs 22 running graphically, with an external keyboard on a Powerbook, the default way of setting M-left might @@ -405,14 +529,17 @@ therefore you'll have to restart Emacs to apply it after changing." (defun org-key (key) "Select key according to `org-replace-disputed-keys' and `org-disputed-keys'. -Or return the original if not disputed." - (if org-replace-disputed-keys - (let* ((nkey (key-description key)) - (x (org-find-if (lambda (x) - (equal (key-description (car x)) nkey)) - org-disputed-keys))) - (if x (cdr x) key)) - key)) +Or return the original if not disputed. +Also apply the translations defined in `org-xemacs-key-equivalents'." + (when org-replace-disputed-keys + (let* ((nkey (key-description key)) + (x (org-find-if (lambda (x) + (equal (key-description (car x)) nkey)) + org-disputed-keys))) + (setq key (if x (cdr x) key)))) + (when (featurep 'xemacs) + (setq key (or (cdr (assoc key org-xemacs-key-equivalents)) key))) + key) (defun org-find-if (predicate seq) (catch 'exit @@ -625,7 +752,7 @@ The cdr is either a command to be called interactively, a function to be called, or a form to be evaluated. An entry that is just a list with a single string will be interpreted as a descriptive headline that will be added when listing the speed -copmmands in the Help buffer using the `?' speed command." +commands in the Help buffer using the `?' speed command." :group 'org-structure :type '(repeat :value ("k" . ignore) (choice :value ("k" . ignore) @@ -691,7 +818,8 @@ This can also be set in on a per-file basis with (defcustom org-cycle-global-at-bob nil "Cycle globally if cursor is at beginning of buffer and not at a headline. This makes it possible to do global cycling without having to use S-TAB or -C-u TAB. For this special case to work, the first line of the buffer +\\[universal-argument] TAB. For this special case to work, the first line \ +of the buffer must not be a headline - it may be empty or some other text. When used in this way, `org-cycle-hook' is disables temporarily, to make sure the cursor stays at the beginning of the buffer. @@ -705,7 +833,7 @@ of the buffer." When the cursor is at the end of an empty headline, i.e with only stars and maybe a TODO keyword, TAB will then switch the entry to become a child, -and then all possible anchestor states, before returning to the original state. +and then all possible ancestor states, before returning to the original state. This makes data entry extremely fast: M-RET to create a new headline, on TAB to make it a child, two or more tabs to make it a (grand-)uncle. @@ -868,6 +996,18 @@ When t, the following will happen while the cursor is in the headline: :group 'org-edit-structure :type 'boolean) +(defcustom org-ctrl-k-protect-subtree nil + "Non-nil means, do not delete a hidden subtree with C-k. +When set to the symbol `error', simply throw an error when C-k is +used to kill (part-of) a headline that has hidden text behind it. +Any other non-nil value will result in a query to the user, if it is +OK to kill that hidden subtree. When nil, kill without remorse." + :group 'org-edit-structure + :type '(choice + (const :tag "Do not protect hidden subtrees" nil) + (const :tag "Protect hidden subtrees with a security query" t) + (const :tag "Never kill a hidden subtree with C-k" error))) + (defcustom org-yank-folded-subtrees t "Non-nil means when yanking subtrees, fold them. If the kill is a single subtree, or a sequence of subtrees, i.e. if @@ -951,9 +1091,8 @@ See also the QUOTE keyword." :group 'org-edit-structure :type 'boolean) - (defcustom org-goto-auto-isearch t - "Non-nil means typing characters in org-goto starts incremental search." + "Non-nil means typing characters in `org-goto' starts incremental search." :group 'org-edit-structure :type 'boolean) @@ -1139,11 +1278,11 @@ Changing this variable requires a restart of Emacs to become effective." (const :tag "Footnotes" footnote))) (defcustom org-make-link-description-function nil - "Function to use to generate link descriptions from links. If -nil the link location will be used. This function must take two -parameters; the first is the link and the second the description -org-insert-link has generated, and should return the description -to use." + "Function to use to generate link descriptions from links. +If nil the link location will be used. This function must take +two parameters; the first is the link and the second the +description `org-insert-link' has generated, and should return the +description to use." :group 'org-link :type 'function) @@ -1280,8 +1419,7 @@ implementation is bad." :type 'boolean) (defcustom org-return-follows-link nil - "Non-nil means on links RET will follow the link. -Needs to be set before org.el is loaded." + "Non-nil means on links RET will follow the link." :group 'org-link-follow :type 'boolean) @@ -1294,15 +1432,16 @@ Needs to be set before org.el is loaded." :type 'boolean) (defcustom org-mark-ring-length 4 - "Number of different positions to be recorded in the ring + "Number of different positions to be recorded in the ring. Changing this requires a restart of Emacs to work correctly." :group 'org-link-follow :type 'integer) (defcustom org-link-frame-setup '((vm . vm-visit-folder-other-frame) - (gnus . gnus-other-frame) - (file . find-file-other-window)) + (gnus . org-gnus-no-new-news) + (file . find-file-other-window) + (wl . wl-other-frame)) "Setup the frame configuration for following links. When following a link with Emacs, it may often be useful to display this link in another window or frame. This variable can be used to @@ -1318,6 +1457,9 @@ For FILE, use any of `find-file' `find-file-other-window' `find-file-other-frame' +For Wanderlust use any of + `wl' + `wl-other-frame' For the calendar, use the variable `calendar-setup'. For BBDB, it is currently only possible to display the matches in another window." @@ -1337,13 +1479,18 @@ another window." (choice (const find-file) (const find-file-other-window) - (const find-file-other-frame))))) + (const find-file-other-frame))) + (cons (const wl) + (choice + (const wl) + (const wl-other-frame))))) (defcustom org-display-internal-link-with-indirect-buffer nil "Non-nil means use indirect buffer to display infile links. Activating internal links (from one location in a file to another location in the same file) normally just jumps to the location. When the link is -activated with a C-u prefix (or with mouse-3), the link is displayed in +activated with a \\[universal-argument] prefix (or with mouse-3), the link \ +is displayed in another window. When this option is set, the other window actually displays an indirect buffer clone of the current buffer, to avoid any visibility changes to the current buffer." @@ -1368,7 +1515,7 @@ window on that directory." (defcustom org-link-mailto-program '(browse-url "mailto:%a?subject=%s") "Function and arguments to call for following mailto links. -This is a list with the first element being a lisp function, and the +This is a list with the first element being a Lisp function, and the remaining elements being arguments to the function. In string arguments, %a will be replaced by the address, and %s will be replaced by the subject if one was given like in <mailto:arthur@galaxy.org::this subject>." @@ -1395,6 +1542,9 @@ single keystroke rather than having to type \"yes\"." (const :tag "with yes-or-no (safer)" yes-or-no-p) (const :tag "with y-or-n (faster)" y-or-n-p) (const :tag "no confirmation (dangerous)" nil))) +(put 'org-confirm-shell-link-function + 'safe-local-variable + '(lambda (x) (member x '(yes-or-no-p y-or-n-p)))) (defcustom org-confirm-elisp-link-function 'yes-or-no-p "Non-nil means ask for confirmation before executing Emacs Lisp links. @@ -1412,6 +1562,9 @@ single keystroke rather than having to type \"yes\"." (const :tag "with yes-or-no (safer)" yes-or-no-p) (const :tag "with y-or-n (faster)" y-or-n-p) (const :tag "no confirmation (dangerous)" nil))) +(put 'org-confirm-shell-link-function + 'safe-local-variable + '(lambda (x) (member x '(yes-or-no-p y-or-n-p)))) (defconst org-file-apps-defaults-gnu '((remote . emacs) @@ -1463,10 +1616,37 @@ you can use this variable to set the application for a given file extension. The entries in this list are cons cells where the car identifies files and the cdr the corresponding command. Possible values for the file identifier are - \"regex\" Regular expression matched against the file: link. For - backward compatibility, this can also be a string with only - alphanumeric characters, which is then interpreted as an - extension. + \"string\" A string as a file identifier can be interpreted in different + ways, depending on its contents: + + - Alphanumeric characters only: + Match links with this file extension. + Example: (\"pdf\" . \"evince %s\") + to open PDFs with evince. + + - Regular expression: Match links where the + filename matches the regexp. If you want to + use groups here, use shy groups. + + Example: (\"\\.x?html\\'\" . \"firefox %s\") + (\"\\(?:xhtml\\|html\\)\" . \"firefox %s\") + to open *.html and *.xhtml with firefox. + + - Regular expression which contains (non-shy) groups: + Match links where the whole link, including \"::\", and + anything after that, matches the regexp. + In a custom command string, %1, %2, etc. are replaced with + the parts of the link that were matched by the groups. + For backwards compatibility, if a command string is given + that does not use any of the group matches, this case is + handled identically to the second one (i.e. match against + file name only). + In a custom lisp form, you can access the group matches with + (match-string n link). + + Example: (\"\\.pdf::\\(\\d+\\)\\'\" . \"evince -p %1 %s\") + to open [[file:document.pdf::5]] with evince at page 5. + `directory' Matches a directory `remote' Matches a remote file, accessible through tramp or efs. Remote files most likely should be visited through Emacs @@ -1480,7 +1660,7 @@ file identifier are `system' The system command to open files, like `open' on Windows and Mac OS X, and mailcap under GNU/Linux. This is the command that will be selected if you call `C-c C-o' with a double - `C-u C-u' prefix. + \\[universal-argument] \\[universal-argument] prefix. Possible values for the command are: `emacs' The file will be visited by the current Emacs process. @@ -1495,13 +1675,9 @@ Possible values for the command are: does define this command, but you can overrule/replace it here. string A command to be executed by a shell; %s will be replaced - by the path to the file. If the file identifier is a regex, - %n will be replaced by the match of the nth match group. + by the path to the file. sexp A Lisp form which will be evaluated. The file path will - be available in the Lisp variable `file', the link itself - in the Lisp variable `link'. If the file identifier is a regex, - the original match data will be restored, so subexpression - matches are accessible using (match-string n link). + be available in the Lisp variable `file'. For more examples, see the system specific constants `org-file-apps-defaults-macosx' `org-file-apps-defaults-windowsnt' @@ -1523,6 +1699,8 @@ For more examples, see the system specific constants (string :tag "Command") (sexp :tag "Lisp form"))))) + + (defgroup org-refile nil "Options concerning refiling entries in Org-mode." :tag "Org Refile" @@ -1546,10 +1724,8 @@ following situations: (defcustom org-default-notes-file (convert-standard-filename "~/.notes") "Default target for storing notes. -Used by the hooks for remember.el. This can be a string, or nil to mean -the value of `remember-data-file'. -You can set this on a per-template basis with the variable -`org-remember-templates'." +Used as a fall back file for org-remember.el and org-capture.el, for +templates that do not specify a target file." :group 'org-refile :group 'org-remember :type '(choice @@ -1571,7 +1747,7 @@ outline-path-completion Headlines in the current buffer are offered via (const :tag "Outline-path-completion" outline-path-completion))) (defcustom org-goto-max-level 5 - "Maximum level to be considered when running org-goto with refile interface." + "Maximum target level when running `org-goto' with refile interface." :group 'org-refile :type 'integer) @@ -1640,7 +1816,7 @@ This is list of cons cells. Each cell contains: order in hierarchy, not to the number of stars. You can set the variable `org-refile-target-verify-function' to a function -to verify each headline found by the simple critery above. +to verify each headline found by the simple criteria above. When this variable is nil, all top-level headlines in the current buffer are used, equivalent to the value `((nil . (:level . 1))'." @@ -1672,6 +1848,17 @@ of the subtree." :group 'org-refile :type 'function) +(defcustom org-refile-use-cache nil + "Non-nil means cache refile targets to speed up the process. +The cache for a particular file will be updated automatically when +the buffer has been killed, or when any of the marker used for flagging +refile targets no longer points at a live buffer. +If you have added new entries to a buffer that might themselves be targets, +you need to clear the cache manually by pressing `C-0 C-c C-w' or, if you +find that easier, `C-u C-u C-u C-c C-w'." + :group 'org-refile + :type 'boolean) + (defcustom org-refile-use-outline-path nil "Non-nil means provide refile targets as paths. So a level 3 headline will be available as level1/level2/level3. @@ -1731,9 +1918,8 @@ heading." '( (:tag "Sequence (cycling hits every state)" sequence) (:tag "Type (cycling directly to DONE)" type)) - "The available interpretation symbols for customizing - `org-todo-keywords'. - Interested libraries should add to this list.") + "The available interpretation symbols for customizing `org-todo-keywords'. +Interested libraries should add to this list.") (defcustom org-todo-keywords '((sequence "TODO" "DONE")) "List of TODO entry keyword sequences and their interpretation. @@ -1759,7 +1945,7 @@ Each keyword can optionally specify a character for fast state selection \(in combination with the variable `org-use-fast-todo-selection') and specifiers for state change logging, using the same syntax that is used in the \"#+TODO:\" lines. For example, \"WAIT(w)\" says -that the WAIT state can be selected with the \"w\" key. \"WAIT(w!)\" +that the WAIT state can be selected with the \"w\" key. \"WAIT(w!)\" indicates to record a time stamp each time this state is selected. Each keyword may also specify if a timestamp or a note should be @@ -2103,6 +2289,7 @@ The value is an alist, with the car being a symbol indicating the note context, and the cdr is the heading to be used. The heading may also be the empty string. %t in the heading will be replaced by a time stamp. +%T will be an active time stamp instead the default inactive one %s will be replaced by the new TODO state, in double quotes. %S will be replaced by the old TODO state, in double quotes. %u will be replaced by the user name. @@ -2184,10 +2371,19 @@ When nil, the state change notes will be ordered according to time." :group 'org-progress :type 'boolean) +(defcustom org-todo-repeat-to-state nil + "The TODO state to which a repeater should return the repeating task. +By default this is the first task in a TODO sequence, or the previous state +in a TODO_TYP set. But you can specify another task here. +alternatively, set the :REPEAT_TO_STATE: property of the entry." + :group 'org-todo + :type '(choice (const :tag "Head of sequence" nil) + (string :tag "Specific state"))) + (defcustom org-log-repeat 'time "Non-nil means record moving through the DONE state when triggering repeat. An auto-repeating task is immediately switched back to TODO when -marked DONE. If you are not logging state changes (by adding \"@\" +marked DONE. If you are not logging state changes (by adding \"@\" or \"!\" to the TODO keyword definition), or set `org-log-done' to record a closing note, there will be no record of the task moving through DONE. This variable forces taking a note anyway. @@ -2276,12 +2472,12 @@ of N minutes, as given by the second value. When a setting is 0 or 1, insert the time unmodified. Useful rounding numbers should be factors of 60, so for example 5, 10, 15. -When this is larger than 1, you can still force an exact time-stamp by using -a double prefix argument to a time-stamp command like `C-c .' or `C-c !', +When this is larger than 1, you can still force an exact time stamp by using +a double prefix argument to a time stamp command like `C-c .' or `C-c !', and by using a prefix arg to `S-up/down' to specify the exact number of minutes to shift." :group 'org-time - :get '(lambda (var) ; Make sure all entries have 5 elements + :get '(lambda (var) ; Make sure both elements are there (if (integerp (default-value var)) (list (default-value var) 5) (default-value var))) @@ -2324,8 +2520,8 @@ commands, if custom time display is turned on at the time of export." f))) (defcustom org-time-clocksum-format "%d:%02d" - "The format string used when creating CLOCKSUM lines, or when -org-mode generates a time duration." + "The format string used when creating CLOCKSUM lines. +This is also used when org-mode generates a time duration." :group 'org-time :type 'string) @@ -2356,8 +2552,8 @@ Custom commands can set this variable in the options section." "Non-nil means assume future for incomplete date input from user. This affects the following situations: 1. The user gives a month but not a year. - For example, if it is april and you enter \"feb 2\", this will be read - as feb 2, *next* year. \"May 5\", however, will be this year. + For example, if it is April and you enter \"feb 2\", this will be read + as Feb 2, *next* year. \"May 5\", however, will be this year. 2. The user gives a day, but no month. For example, if today is the 15th, and you enter \"3\", Org-mode will read this as the third of *next* month. However, if you enter \"17\", @@ -2607,7 +2803,7 @@ is better to limit inheritance to certain tags using the variables (const :tag "List them, indented with leading dots" indented))) (defcustom org-tags-sort-function nil - "When set, tags are sorted using this function as a comparator" + "When set, tags are sorted using this function as a comparator." :group 'org-tags :type '(choice (const :tag "No sorting" nil) @@ -2638,7 +2834,7 @@ lined-up with respect to each other." (defcustom org-use-property-inheritance nil "Non-nil means properties apply also for sublevels. -This setting is chiefly used during property searches. Turning it on can +This setting is chiefly used during property searches. Turning it on can cause significant overhead when doing a search, which is why it is not on by default. @@ -2937,32 +3133,49 @@ will be appended." (defvar org-format-latex-header-extra nil) +(defun org-set-packages-alist (var val) + "Set the packages alist and make sure it has 3 elements per entry." + (set var (mapcar (lambda (x) + (if (and (consp x) (= (length x) 2)) + (list (car x) (nth 1 x) t) + x)) + val))) + +(defun org-get-packages-alist (var) + + "Get the packages alist and make sure it has 3 elements per entry." + (mapcar (lambda (x) + (if (and (consp x) (= (length x) 2)) + (list (car x) (nth 1 x) t) + x)) + (default-value var))) + ;; The following variables are defined here because is it also used ;; when formatting latex fragments. Originally it was part of the ;; LaTeX exporter, which is why the name includes "export". (defcustom org-export-latex-default-packages-alist - '(("AUTO" "inputenc") - ("T1" "fontenc") - ("" "fixltx2e") - ("" "graphicx") - ("" "longtable") - ("" "float") - ("" "wrapfig") - ("" "soul") - ("" "t1enc") - ("" "textcomp") - ("" "marvosym") - ("" "wasysym") - ("" "latexsym") - ("" "amssymb") - ("" "hyperref") + '(("AUTO" "inputenc" t) + ("T1" "fontenc" t) + ("" "fixltx2e" nil) + ("" "graphicx" t) + ("" "longtable" nil) + ("" "float" nil) + ("" "wrapfig" nil) + ("" "soul" t) + ("" "t1enc" t) + ("" "textcomp" t) + ("" "marvosym" t) + ("" "wasysym" t) + ("" "latexsym" t) + ("" "amssymb" t) + ("" "hyperref" nil) "\\tolerance=1000" ) "Alist of default packages to be inserted in the header. Change this only if one of the packages here causes an incompatibility with another package you are using. The packages in this list are needed by one part or another of Org-mode -to function properly. +to function properly. - inputenc, fontenc, t1enc: for basic font and character selection - textcomp, marvosymb, wasysym, latexsym, amssym: for various symbols used @@ -2976,31 +3189,42 @@ to function properly. Therefore you should not modify this variable unless you know what you are doing. The one reason to change it anyway is that you might be loading some other package that conflicts with one of the default packages. -Each cell is of the format \( \"options\" \"package\" \)." +Each cell is of the format \( \"options\" \"package\" snippet-flag\). +If SNIPPET-FLAG is t, the package also needs to be included when +compiling LaTeX snippets into images for inclusion into HTML." :group 'org-export-latex + :set 'org-set-packages-alist + :get 'org-get-packages-alist :type '(repeat - (choice - (string :tag "A line of LaTeX") + (choice (list :tag "options/package pair" (string :tag "options") - (string :tag "package"))))) + (string :tag "package") + (boolean :tag "Snippet")) + (string :tag "A line of LaTeX")))) (defcustom org-export-latex-packages-alist nil - "Alist of packages to be inserted in every LaTeX the header. + "Alist of packages to be inserted in every LaTeX header. These will be inserted after `org-export-latex-default-packages-alist'. -Each cell is of the format \( \"options\" \"package\" \). -Make sure that you only lis packages here which: +Each cell is of the format \( \"options\" \"package\" snippet-flag \). +SNIPPET-FLAG, when t, indicates that this package is also needed when +turning LaTeX snippets into images for inclusion into HTML. +Make sure that you only list packages here which: - you want in every file - do not conflict with the default packages in `org-export-latex-default-packages-alist' - do not conflict with the setup in `org-format-latex-header'." :group 'org-export-latex + :set 'org-set-packages-alist + :get 'org-get-packages-alist :type '(repeat - (choice - (string :tag "A line of LaTeX") + (choice (list :tag "options/package pair" (string :tag "options") - (string :tag "package"))))) + (string :tag "package") + (boolean :tag "Snippet")) + (string :tag "A line of LaTeX")))) + (defgroup org-appearance nil "Settings for Org-mode appearance." @@ -3073,8 +3297,25 @@ org-level-* faces." :group 'org-appearance :type 'boolean) +(defcustom org-pretty-entities nil + "Non-nil means show entities as UTF8 characters. +When nil, the \\name form remains in the buffer." + :group 'org-appearance + :type 'boolean) + +(defcustom org-pretty-entities-include-sub-superscripts t + "Non-nil means, pretty entity display includes formatting sub/superscripts." + :group 'org-appearance + :type 'boolean) + (defvar org-emph-re nil - "Regular expression for matching emphasis.") + "Regular expression for matching emphasis. +After a match, the match groups contain these elements: +1 The character before the proper match, or empty at beginning of line +2 The proper match, including the leading and trailing markers +3 The leading marker like * or /, indicating the type of highlighting +4 The text between the emphasis markers, not including the markers +5 The character after the match, empty at the end of a line") (defvar org-verbatim-re nil "Regular expression for matching verbatim text.") (defvar org-emphasis-regexp-components) ; defined just below @@ -3176,6 +3417,7 @@ example *bold*, _underlined_ and /italic/. This variable sets the marker characters, the face to be used by font-lock for highlighting in Org-mode Emacs buffers, and the HTML tags to be used for this. For LaTeX export, see the variable `org-export-latex-emphasis-alist'. +For DocBook export, see the variable `org-export-docbook-emphasis-alist'. Use customize to modify this, or restart Emacs after changing it." :group 'org-appearance :set 'org-set-emph-re @@ -3271,6 +3513,7 @@ Normal means no org-mode-specific context." (declare-function org-indent-mode "org-indent" (&optional arg)) (declare-function parse-time-string "parse-time" (string)) (declare-function org-attach-reveal "org-attach" (&optional if-exists)) +(declare-function org-export-latex-fix-inputenc "org-latex" ()) (defvar remember-data-file) (defvar texmathp-why) (declare-function speedbar-line-directory "speedbar" (&optional depth)) @@ -3287,18 +3530,18 @@ Normal means no org-mode-specific context." ;; by the functions setting up org-mode or checking for table context. (defconst org-table-any-line-regexp "^[ \t]*\\(|\\|\\+-[-+]\\)" - "Detects an org-type or table-type table.") + "Detect an org-type or table-type table.") (defconst org-table-line-regexp "^[ \t]*|" - "Detects an org-type table line.") + "Detect an org-type table line.") (defconst org-table-dataline-regexp "^[ \t]*|[^-]" - "Detects an org-type table line.") + "Detect an org-type table line.") (defconst org-table-hline-regexp "^[ \t]*|-" - "Detects an org-type table hline.") + "Detect an org-type table hline.") (defconst org-table1-hline-regexp "^[ \t]*\\+-[-+]" - "Detects a table-type table hline.") + "Detect a table-type table hline.") (defconst org-table-any-border-regexp "^[ \t]*[^|+ \t]" - "Searching from within a table (any type) this finds the first line -outside the table.") + "Detect the first line outside a table when searching from within it. +This works for both table types.") ;; Autoload the functions in org-table.el that are needed by functions here. @@ -3325,7 +3568,9 @@ outside the table.") org-table-rotate-recalc-marks org-table-sort-lines org-table-sum org-table-toggle-coordinate-overlays org-table-toggle-formula-debugger org-table-wrap-region - orgtbl-mode turn-on-orgtbl org-table-to-lisp))) + orgtbl-mode turn-on-orgtbl org-table-to-lisp + orgtbl-to-generic orgtbl-to-tsv orgtbl-to-csv orgtbl-to-latex + orgtbl-to-orgtbl orgtbl-to-html orgtbl-to-texinfo))) (defun org-at-table-p (&optional table-type) "Return t if the cursor is inside an org-type table. @@ -3365,7 +3610,7 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." (message "recognizing table.el table...") (table-recognize-table) (message "recognizing table.el table...done"))) - (error "This should not happen...")) + (error "This should not happen")) t) nil) nil)) @@ -3380,21 +3625,22 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." (defvar org-table-clean-did-remove-column nil) -(defun org-table-map-tables (function) +(defun org-table-map-tables (function &optional quietly) "Apply FUNCTION to the start of all tables in the buffer." (save-excursion (save-restriction (widen) (goto-char (point-min)) (while (re-search-forward org-table-any-line-regexp nil t) - (message "Mapping tables: %d%%" (/ (* 100.0 (point)) (buffer-size))) + (unless quietly + (message "Mapping tables: %d%%" (/ (* 100.0 (point)) (buffer-size)))) (beginning-of-line 1) (when (looking-at org-table-line-regexp) (save-excursion (funcall function)) (or (looking-at org-table-line-regexp) (forward-char 1))) (re-search-forward org-table-any-border-regexp nil 1)))) - (message "Mapping tables: done")) + (unless quietly (message "Mapping tables: done"))) ;; Declare and autoload functions from org-exp.el & Co @@ -3448,6 +3694,11 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." '(org-remember-insinuate org-remember-annotation org-remember-apply-template org-remember org-remember-handler))) +(eval-and-compile + (org-autoload "org-capture" + '(org-capture org-capture-insert-template-here + org-capture-import-remember-templates))) + ;; Autoload org-clock.el @@ -3814,7 +4065,7 @@ Also put tags into group 4 if tags are present.") "Matches any of the 3 keywords, together with the time stamp.") (make-variable-buffer-local 'org-keyword-time-not-clock-regexp) (defvar org-maybe-keyword-time-regexp nil - "Matches a timestamp, possibly preceeded by a keyword.") + "Matches a timestamp, possibly preceded by a keyword.") (make-variable-buffer-local 'org-maybe-keyword-time-regexp) (defvar org-planning-or-clock-line-re nil "Matches a line with planning or clock info.") @@ -3910,7 +4161,9 @@ After a match, the following groups carry important information: ("noptag" org-tag-persistent-alist nil) ("hideblocks" org-hide-block-startup t) ("nohideblocks" org-hide-block-startup nil) - ("beamer" org-startup-with-beamer-mode t)) + ("beamer" org-startup-with-beamer-mode t) + ("entitiespretty" org-pretty-entities t) + ("entitiesplain" org-pretty-entities nil)) "Variable associated with STARTUP options for org-mode. Each element is a list of three items: The startup options as written in the #+STARTUP line, the corresponding variable, and the value to @@ -3933,9 +4186,11 @@ means to push this value onto the list in the variable.") (let ((re (org-make-options-regexp '("CATEGORY" "TODO" "COLUMNS" "STARTUP" "ARCHIVE" "FILETAGS" "TAGS" "LINK" "PRIORITIES" - "CONSTANTS" "PROPERTY" "DRAWERS" "SETUPFILE" "LATEX_CLASS") + "CONSTANTS" "PROPERTY" "DRAWERS" "SETUPFILE" "LATEX_CLASS" + "OPTIONS") "\\(?:[a-zA-Z][0-9a-zA-Z_]*_TODO\\)")) (splitre "[ \t]+") + (scripts org-use-sub-superscripts) kwds kws0 kwsa key log value cat arch tags const links hw dws tail sep kws1 prio props ftags drawers beamer-p ext-setup-or-nil setup-contents (start 0)) @@ -3950,10 +4205,9 @@ means to push this value onto the list in the variable.") (re-search-forward re nil t))) (setq key (upcase (match-string 1 ext-setup-or-nil)) value (org-match-string-no-properties 2 ext-setup-or-nil)) + (if (stringp value) (setq value (org-trim value))) (cond ((equal key "CATEGORY") - (if (string-match "[ \t]+$" value) - (setq value (replace-match "" t t value))) (setq cat value)) ((member key '("SEQ_TODO" "TODO")) (push (cons 'sequence (org-split-string value splitre)) kwds)) @@ -4004,12 +4258,14 @@ means to push this value onto the list in the variable.") (set (make-local-variable var) (symbol-value var)) (add-to-list var val)))))) ((equal key "ARCHIVE") - (string-match " *$" value) - (setq arch (replace-match "" t t value)) + (setq arch value) (remove-text-properties 0 (length arch) '(face t fontified t) arch)) ((equal key "LATEX_CLASS") (setq beamer-p (equal value "beamer"))) + ((equal key "OPTIONS") + (if (string-match "\\([ \t]\\|\\`\\)\\^:\\(t\\|nil\\|{}\\)" value) + (setq scripts (read (match-string 2 value))))) ((equal key "SETUPFILE") (setq setup-contents (org-file-contents (expand-file-name @@ -4022,6 +4278,7 @@ means to push this value onto the list in the variable.") "\n" setup-contents "\n" (substring ext-setup-or-nil start))))) )))) + (org-set-local 'org-use-sub-superscripts scripts) (when cat (org-set-local 'org-category (intern cat)) (push (cons "CATEGORY" cat) props)) @@ -4148,7 +4405,11 @@ means to push this value onto the list in the variable.") org-complex-heading-regexp-format (concat "^\\(\\*+\\)[ \t]+\\(?:\\(" (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") - "\\)\\>\\)?\\(?:[ \t]*\\(\\[#.\\]\\)\\)?[ \t]*\\(%s\\)" + "\\)\\>\\)?" + "\\(?:[ \t]*\\(\\[#.\\]\\)\\)?" + "\\(?:[ \t]*\\(?:\\[[0-9%%/]+\\]\\)\\)?" ;; stats cookie + "[ \t]*\\(%s\\)" + "\\(?:[ \t]*\\(?:\\[[0-9%%/]+\\]\\)\\)?" ;; stats cookie "\\(?:[ \t]+\\(:[[:alnum:]_@:]+:\\)\\)?[ \t]*$") org-nl-done-regexp (concat "\n\\*+[ \t]+" @@ -4211,10 +4472,10 @@ means to push this value onto the list in the variable.") (not (file-readable-p file))) (if noerror (progn - (message "Cannot read file %s" file) + (message "Cannot read file \"%s\"" file) (ding) (sit-for 2) "") - (error "Cannot read file %s" file)) + (error "Cannot read file \"%s\"" file)) (with-temp-buffer (insert-file-contents file) (buffer-string)))) @@ -4287,7 +4548,7 @@ This is for getting out of special buffers like remember.") ;;;; Define the Org-mode (if (and (not (keymapp outline-mode-map)) (featurep 'allout)) - (error "Conflict with outdated version of allout.el. Load org.el before allout.el, or upgrade to newer allout, for example by switching to Emacs 22.")) + (error "Conflict with outdated version of allout.el. Load org.el before allout.el, or upgrade to newer allout, for example by switching to Emacs 22")) ;; We use a before-change function to check if a table might need @@ -4334,7 +4595,7 @@ The following commands are available: ;; we switch another buffer into org-mode. (if (featurep 'xemacs) (when (boundp 'outline-mode-menu-heading) - ;; Assume this is Greg's port, it used easymenu + ;; Assume this is Greg's port, it uses easymenu (easy-menu-remove outline-mode-menu-heading) (easy-menu-remove outline-mode-menu-show) (easy-menu-remove outline-mode-menu-hide)) @@ -4346,9 +4607,9 @@ The following commands are available: (easy-menu-add org-org-menu) (easy-menu-add org-tbl-menu) (org-install-agenda-files-menu) - (if org-descriptive-links (org-add-to-invisibility-spec '(org-link))) - (org-add-to-invisibility-spec '(org-cwidth)) - (org-add-to-invisibility-spec '(org-hide-block . t)) + (if org-descriptive-links (add-to-invisibility-spec '(org-link))) + (add-to-invisibility-spec '(org-cwidth)) + (add-to-invisibility-spec '(org-hide-block . t)) (when (featurep 'xemacs) (org-set-local 'line-move-ignore-invisible t)) (org-set-local 'outline-regexp org-outline-regexp) @@ -4371,7 +4632,6 @@ The following commands are available: (org-set-tag-faces 'org-tag-faces org-tag-faces)) ;; Calc embedded (org-set-local 'calc-embedded-open-mode "# ") - (modify-syntax-entry ?# "<") (modify-syntax-entry ?@ "w") (if org-startup-truncated (setq truncate-lines t)) (org-set-local 'font-lock-unfontify-region-function @@ -4386,6 +4646,9 @@ The following commands are available: (org-set-autofill-regexps) (setq indent-line-function 'org-indent-line-function) (org-update-radio-target-regexp) + ;; Beginning/end of defun + (org-set-local 'beginning-of-defun-function 'org-beginning-of-defun) + (org-set-local 'end-of-defun-function 'org-end-of-defun) ;; Make sure dependence stuff works reliably, even for users who set it ;; too late :-( (if org-enforce-todo-dependencies @@ -4400,7 +4663,7 @@ The following commands are available: 'org-block-todo-from-checkboxes)) ;; Comment characters -; (org-set-local 'comment-start "#") ;; FIXME: this breaks wrapping + (org-set-local 'comment-start "#") (org-set-local 'comment-padding " ") ;; Align options lines @@ -4434,7 +4697,7 @@ The following commands are available: (unless org-inhibit-startup (when org-startup-align-all-tables (let ((bmp (buffer-modified-p))) - (org-table-map-tables 'org-table-align) + (org-table-map-tables 'org-table-align 'quietly) (set-buffer-modified-p bmp))) (when org-startup-indented (require 'org-indent) @@ -4461,10 +4724,8 @@ The following commands are available: ;;;; Font-Lock stuff, including the activators (defvar org-mouse-map (make-sparse-keymap)) -(org-defkey org-mouse-map - (if (featurep 'xemacs) [button2] [mouse-2]) 'org-open-at-mouse) -(org-defkey org-mouse-map - (if (featurep 'xemacs) [button3] [mouse-3]) 'org-find-file-at-mouse) +(org-defkey org-mouse-map [mouse-2] 'org-open-at-mouse) +(org-defkey org-mouse-map [mouse-3] 'org-find-file-at-mouse) (when org-mouse-1-follows-link (org-defkey org-mouse-map [follow-link] 'mouse-face)) (when org-tab-follows-link @@ -4475,7 +4736,7 @@ The following commands are available: (defconst org-non-link-chars "]\t\n\r<>") (defvar org-link-types '("http" "https" "ftp" "mailto" "file" "news" - "shell" "elisp")) + "shell" "elisp" "doi")) (defvar org-link-types-re nil "Matches a link that has a url-like prefix like \"http:\"") (defvar org-link-re-with-space nil @@ -4499,10 +4760,51 @@ Here is what the match groups contain after a match: 4: [desc] 5: desc") (defvar org-bracket-link-analytic-regexp++ nil - "Like org-bracket-link-analytic-regexp, but include coderef internal type.") + "Like `org-bracket-link-analytic-regexp', but include coderef internal type.") (defvar org-any-link-re nil "Regular expression matching any link.") +(defcustom org-match-sexp-depth 3 + "Number of stacked braces for sub/superscript matching. +This has to be set before loading org.el to be effective." + :group 'org-export-translation ; ??????????????????????????/ + :type 'integer) + +(defun org-create-multibrace-regexp (left right n) + "Create a regular expression which will match a balanced sexp. +Opening delimiter is LEFT, and closing delimiter is RIGHT, both given +as single character strings. +The regexp returned will match the entire expression including the +delimiters. It will also define a single group which contains the +match except for the outermost delimiters. The maximum depth of +stacked delimiters is N. Escaping delimiters is not possible." + (let* ((nothing (concat "[^" left right "]*?")) + (or "\\|") + (re nothing) + (next (concat "\\(?:" nothing left nothing right "\\)+" nothing))) + (while (> n 1) + (setq n (1- n) + re (concat re or next) + next (concat "\\(?:" nothing left next right "\\)+" nothing))) + (concat left "\\(" re "\\)" right))) + +(defvar org-match-substring-regexp + (concat + "\\([^\\]\\)\\([_^]\\)\\(" + "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)" + "\\|" + "\\(" (org-create-multibrace-regexp "(" ")" org-match-sexp-depth) "\\)" + "\\|" + "\\(\\(?:\\*\\|[-+]?[^-+*!@#$%^_ \t\r\n,:\"?<>~;./{}=()]+\\)\\)\\)") + "The regular expression matching a sub- or superscript.") + +(defvar org-match-substring-with-braces-regexp + (concat + "\\([^\\]\\)\\([_^]\\)\\(" + "\\(" (org-create-multibrace-regexp "{" "}" org-match-sexp-depth) "\\)" + "\\)") + "The regular expression matching a sub- or superscript, forcing braces.") + (defun org-make-link-regexps () "Update the link regular expressions. This should be called after the variable `org-link-types' has changed." @@ -4607,7 +4909,7 @@ The time stamps may be either active or inactive.") (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0))) (add-text-properties (match-beginning 2) (match-end 2) - '(font-lock-multiline t)) + '(font-lock-multiline t org-emphasis t)) (when org-hide-emphasis-markers (add-text-properties (match-end 4) (match-beginning 5) '(invisible org-link)) @@ -4724,7 +5026,7 @@ will be prompted for." '(font-lock-fontified t face org-block)) t) ((and (match-end 4) (equal dc3 "begin")) - ;; Truely a block + ;; Truly a block (setq block-type (downcase (match-string 5)) quoting (member block-type org-protecting-blocks)) (when (re-search-forward @@ -4766,7 +5068,8 @@ will be prompted for." '(font-lock-fontified t face org-meta-line)) t) ((or (member dc1 '("begin:" "end:" "caption:" "label:" - "orgtbl:" "tblfm:" "tblname:")) + "orgtbl:" "tblfm:" "tblname:" "result:" + "results:" "source:" "srcname:" "call:")) (and (match-end 4) (equal dc3 "attr"))) (add-text-properties beg (match-end 0) @@ -4944,13 +5247,17 @@ will be prompted for." (if org-export-with-TeX-macros (list (concat "\\\\" (regexp-opt - (append (mapcar 'car (append org-entities-user - org-entities)) - (if (boundp 'org-latex-entities) - (mapcar (lambda (x) - (or (car-safe x) x)) - org-latex-entities) - nil)) + (append + + (delq nil + (mapcar 'car-safe + (append org-entities-user + org-entities))) + (if (boundp 'org-latex-entities) + (mapcar (lambda (x) + (or (car-safe x) x)) + org-latex-entities) + nil)) 'words))) ; FIXME )) ;; (list "\\\\\\(?:[a-zA-Z]+\\)"))) @@ -4989,7 +5296,7 @@ will be prompted for." rtn))) (defun org-restart-font-lock () - "Restart font-lock-mode, to force refontification." + "Restart `font-lock-mode', to force refontification." (when (and (boundp 'font-lock-mode) font-lock-mode) (font-lock-mode -1) (font-lock-mode 1))) @@ -5034,7 +5341,7 @@ between words." (defun org-outline-level () "Compute the outline level of the heading at point. This function assumes that the cursor is at the beginning of a line matched -by outline-regexp. Otherwise it returns garbage. +by `outline-regexp'. Otherwise it returns garbage. If this is called at a normal headline, the level is the number of stars. Use `org-reduced-level' to remove the effect of `org-odd-levels'. For plain list items, if they are matched by `outline-regexp', this returns @@ -5134,6 +5441,8 @@ For plain list items, if they are matched by `outline-regexp', this returns '(1 'org-archived prepend)) ;; Specials '(org-do-latex-and-special-faces) + '(org-fontify-entities) + '(org-raise-scripts) ;; Code '(org-activate-code (1 'org-code t)) ;; COMMENT @@ -5151,8 +5460,41 @@ For plain list items, if they are matched by `outline-regexp', this returns '(org-font-lock-keywords t nil nil backward-paragraph)) (kill-local-variable 'font-lock-keywords) nil)) +(defun org-toggle-pretty-entities () + "Toggle the composition display of entities as UTF8 characters." + (interactive) + (org-set-local 'org-pretty-entities (not org-pretty-entities)) + (org-restart-font-lock) + (if org-pretty-entities + (message "Entities are displayed as UTF8 characers") + (save-restriction + (widen) + (decompose-region (point-min) (point-max)) + (message "Entities are displayed plain")))) + +(defun org-fontify-entities (limit) + "Find an entity to fontify." + (let (ee) + (when org-pretty-entities + (catch 'match + (while (re-search-forward + "\\\\\\([a-zA-Z][a-zA-Z0-9]*\\)\\($\\|[^[:alnum:]\n]\\)" + limit t) + (if (and (not (org-in-indented-comment-line)) + (setq ee (org-entity-get (match-string 1))) + (= (length (nth 6 ee)) 1)) + (progn + (add-text-properties + (match-beginning 0) (match-end 1) + (list 'font-lock-fontified t)) + (compose-region (match-beginning 0) (match-end 1) + (nth 6 ee) nil) + (backward-char 1) + (throw 'match t)))) + nil)))) + (defun org-fontify-like-in-org-mode (s &optional odd-levels) - "Fontify string S like in Org-mode" + "Fontify string S like in Org-mode." (with-temp-buffer (insert s) (let ((org-odd-levels-only odd-levels)) @@ -5227,6 +5569,7 @@ If KWD is a number, get the corresponding match group." (inhibit-read-only t) (inhibit-point-motion-hooks t) (inhibit-modification-hooks t) deactivate-mark buffer-file-name buffer-file-truename) + (decompose-region beg end) (remove-text-properties beg end (if org-indent-mode @@ -5234,10 +5577,69 @@ If KWD is a number, get the corresponding match group." '(mouse-face t keymap t org-linked-text t invisible t intangible t line-prefix t wrap-prefix t - org-no-flyspell t) + org-no-flyspell t org-emphasis t) '(mouse-face t keymap t org-linked-text t invisible t intangible t - org-no-flyspell t))))) + org-no-flyspell t org-emphasis t))) + (org-remove-font-lock-display-properties beg end))) + +(defconst org-script-display '(((raise -0.3) (height 0.7)) + ((raise 0.3) (height 0.7)) + ((raise -0.5)) + ((raise 0.5))) + "Display properties for showing superscripts and subscripts.") + +(defun org-remove-font-lock-display-properties (beg end) + "Remove specific display properties that have been added by font lock. +The will remove the raise properties that are used to show superscripts +and subscripts." + (let (next prop) + (while (< beg end) + (setq next (next-single-property-change beg 'display nil end) + prop (get-text-property beg 'display)) + (if (member prop org-script-display) + (put-text-property beg next 'display nil)) + (setq beg next)))) + +(defun org-raise-scripts (limit) + "Add raise properties to sub/superscripts." + (when (and org-pretty-entities org-pretty-entities-include-sub-superscripts) + (if (re-search-forward + (if (eq org-use-sub-superscripts t) + org-match-substring-regexp + org-match-substring-with-braces-regexp) + limit t) + (let* ((pos (point)) table-p comment-p + (mpos (match-beginning 3)) + (emph-p (get-text-property mpos 'org-emphasis)) + (link-p (get-text-property mpos 'mouse-face)) + (keyw-p (eq 'org-special-keyword (get-text-property mpos 'face)))) + (goto-char (point-at-bol)) + (setq table-p (org-looking-at-p org-table-dataline-regexp) + comment-p (org-looking-at-p "[ \t]*#")) + (goto-char pos) + ;; FIXME: Should we go back one character here, for a_b^c + ;; (goto-char (1- pos)) ;???????????????????? + (if (or comment-p emph-p link-p keyw-p) + t + (put-text-property (match-beginning 3) (match-end 0) + 'display + (if (equal (char-after (match-beginning 2)) ?^) + (nth (if table-p 3 1) org-script-display) + (nth (if table-p 2 0) org-script-display))) + (add-text-properties (match-beginning 2) (match-end 2) + (list 'invisible t + 'org-dwidth t 'org-dwidth-n 1)) + (if (and (eq (char-after (match-beginning 3)) ?{) + (eq (char-before (match-end 3)) ?})) + (progn + (add-text-properties + (match-beginning 3) (1+ (match-beginning 3)) + (list 'invisible t 'org-dwidth t 'org-dwidth-n 1)) + (add-text-properties + (1- (match-end 3)) (match-end 3) + (list 'invisible t 'org-dwidth t 'org-dwidth-n 1)))) + t))))) ;;;; Visibility cycling, including org-goto and indirect buffer @@ -5284,7 +5686,7 @@ in special contexts. - When point is at the beginning of an empty headline and the variable `org-cycle-level-after-item/entry-creation' is set, cycle the level of the headline by demoting and promoting it to likely levels. This - speeds up creation document structure by presing TAB once or several + speeds up creation document structure by pressing TAB once or several times right after creating a new headline. - When there is a numeric prefix, go up to a heading with level ARG, do @@ -5462,7 +5864,6 @@ in special contexts. (while (and (not (eobp)) ;; this is like `next-line' (get-char-property (1- (point)) 'invisible)) (goto-char (next-single-char-property-change (point) 'invisible)) -;;;??? (or (bolp) (beginning-of-line 2)))) (and (eolp) (beginning-of-line 2)))) (setq eol (point))) (outline-end-of-heading) (setq eoh (point)) @@ -5524,7 +5925,7 @@ in special contexts. ;;;###autoload (defun org-global-cycle (&optional arg) "Cycle the global visibility. For details see `org-cycle'. -With C-u prefix arg, switch to startup visibility. +With \\[universal-argument] prefix arg, switch to startup visibility. With a numeric prefix, show all headlines up to that level." (interactive "P") (let ((org-cycle-include-plain-lists @@ -5553,7 +5954,7 @@ With a numeric prefix, show all headlines up to that level." (org-set-visibility-according-to-property 'no-cleanup) (org-cycle-hide-archived-subtrees 'all) (org-cycle-hide-drawers 'all) - (org-cycle-show-empty-lines 'all))) + (org-cycle-show-empty-lines t))) (defun org-set-visibility-according-to-property (&optional no-cleanup) "Switch subtree visibilities according to :VISIBILITY: property." @@ -5637,11 +6038,11 @@ This function is the default value of the hook `org-cycle-hook'." "Remove outline overlays that do not contain non-white stuff." (mapc (lambda (o) - (and (eq 'outline (org-overlay-get o 'invisible)) - (not (string-match "\\S-" (buffer-substring (org-overlay-start o) - (org-overlay-end o)))) - (org-delete-overlay o))) - (org-overlays-at pos))) + (and (eq 'outline (overlay-get o 'invisible)) + (not (string-match "\\S-" (buffer-substring (overlay-start o) + (overlay-end o)))) + (delete-overlay o))) + (overlays-at pos))) (defun org-clean-visibility-after-subtree-move () "Fix visibility issues after moving a subtree." @@ -5794,7 +6195,7 @@ Optional argument N means put the headline into the Nth line of the window." (defun org-outline-overlay-data (&optional use-markers) "Return a list of the locations of all outline overlays. The are overlays with the `invisible' property value `outline'. -The return valus is a list of cons cells, with start and stop +The return values is a list of cons cells, with start and stop positions for each overlay. If USE-MARKERS is set, return the positions as markers." (let (beg end) @@ -5803,15 +6204,15 @@ If USE-MARKERS is set, return the positions as markers." (widen) (delq nil (mapcar (lambda (o) - (when (eq (org-overlay-get o 'invisible) 'outline) - (setq beg (org-overlay-start o) - end (org-overlay-end o)) + (when (eq (overlay-get o 'invisible) 'outline) + (setq beg (overlay-start o) + end (overlay-end o)) (and beg end (> end beg) (if use-markers (cons (move-marker (make-marker) beg) (move-marker (make-marker) end)) (cons beg end))))) - (org-overlays-in (point-min) (point-max)))))))) + (overlays-in (point-min) (point-max)))))))) (defun org-set-outline-overlay-data (data) "Create visibility overlays for all positions in DATA. @@ -5822,8 +6223,8 @@ DATA should have been made by `org-outline-overlay-data'." (widen) (show-all) (mapc (lambda (c) - (setq o (org-make-overlay (car c) (cdr c))) - (org-overlay-put o 'invisible 'outline)) + (setq o (make-overlay (car c) (cdr c))) + (overlay-put o 'invisible 'outline)) data))))) (defmacro org-save-outline-visibility (use-markers &rest body) @@ -5833,6 +6234,7 @@ This means that the buffer may change while running BODY, but it also means that the buffer should stay alive during the operation, because otherwise all these markers will point nowhere." + (declare (indent 1)) `(let ((data (org-outline-overlay-data ,use-markers))) (unwind-protect (progn @@ -5857,9 +6259,8 @@ point nowhere." (make-variable-buffer-local 'org-hide-block-overlays) (defun org-block-map (function &optional start end) - "Call func at the head of all source blocks in the current -buffer. Optional arguments START and END can be used to limit -the range." + "Call FUNCTION at the head of all source blocks in the current buffer. +Optional arguments START and END can be used to limit the range." (let ((start (or start (point-min))) (end (or end (point-max)))) (save-excursion @@ -5882,7 +6283,8 @@ the range." (defun org-show-block-all () "Unfold all blocks in the current buffer." - (mapc 'org-delete-overlay org-hide-block-overlays) + (interactive) + (mapc 'delete-overlay org-hide-block-overlays) (setq org-hide-block-overlays nil)) (defun org-hide-block-toggle-maybe () @@ -5906,30 +6308,30 @@ the range." (end (match-end 0)) ;; end of entire body ov) (if (memq t (mapcar (lambda (overlay) - (eq (org-overlay-get overlay 'invisible) + (eq (overlay-get overlay 'invisible) 'org-hide-block)) - (org-overlays-at start))) + (overlays-at start))) (if (or (not force) (eq force 'off)) (mapc (lambda (ov) (when (member ov org-hide-block-overlays) (setq org-hide-block-overlays (delq ov org-hide-block-overlays))) - (when (eq (org-overlay-get ov 'invisible) + (when (eq (overlay-get ov 'invisible) 'org-hide-block) - (org-delete-overlay ov))) - (org-overlays-at start))) - (setq ov (org-make-overlay start end)) - (org-overlay-put ov 'invisible 'org-hide-block) + (delete-overlay ov))) + (overlays-at start))) + (setq ov (make-overlay start end)) + (overlay-put ov 'invisible 'org-hide-block) ;; make the block accessible to isearch - (org-overlay-put + (overlay-put ov 'isearch-open-invisible (lambda (ov) (when (member ov org-hide-block-overlays) (setq org-hide-block-overlays (delq ov org-hide-block-overlays))) - (when (eq (org-overlay-get ov 'invisible) + (when (eq (overlay-get ov 'invisible) 'org-hide-block) - (org-delete-overlay ov)))) + (delete-overlay ov)))) (push ov org-hide-block-overlays))) (error "Not looking at a source block")))) @@ -6146,10 +6548,12 @@ With numerical prefix ARG, go up to this level and then take that tree. If ARG is negative, go up that many levels. If `org-indirect-buffer-display' is not `new-frame', the command removes the indirect buffer previously made with this command, to avoid proliferation of -indirect buffers. However, when you call the command with a `C-u' prefix, or +indirect buffers. However, when you call the command with a \ +\\[universal-argument] prefix, or when `org-indirect-buffer-display' is `new-frame', the last buffer is kept so that you can work with several indirect buffers at the same time. -If `org-indirect-buffer-display' is `dedicated-frame', the C-u prefix also +If `org-indirect-buffer-display' is `dedicated-frame', the \ +\\[universal-argument] prefix also requests that a new frame be made for the new buffer, so that the dedicated frame is not changed." (interactive "P") @@ -6634,7 +7038,7 @@ After top level, it switches back to sibling level." (funcall fun))))) (defun org-fixup-indentation (diff) - "Change the indentation in the current entry by DIFF + "Change the indentation in the current entry by DIFF. However, if any line in the current entry has no indentation, or if it would end up with no indentation after the change, nothing at all is done." (save-excursion @@ -6672,10 +7076,11 @@ level 5 etc." (end-of-line 1)))))) (defun org-convert-to-oddeven-levels () - "Convert an org-mode file with only odd levels to one with odd and even levels. -This promotes level 3 to level 2, level 5 to level 3 etc. If the file contains a -section with an even level, conversion would destroy the structure of the file. An error -is signaled in this case." + "Convert an org-mode file with only odd levels to one with odd/even levels. +This promotes level 3 to level 2, level 5 to level 3 etc. If the +file contains a section with an even level, conversion would +destroy the structure of the file. An error is signaled in this +case." (interactive) (goto-char (point-min)) ;; First check if there are no even levels @@ -7014,18 +7419,22 @@ If yes, remember the marker and the distance to BEG." (if (org-on-heading-p) (backward-char 1)) (point)))))) +(eval-when-compile + (defvar org-property-drawer-re)) + (defun org-clone-subtree-with-time-shift (n &optional shift) "Clone the task (subtree) at point N times. The clones will be inserted as siblings. -In interactive use, the user will be prompted for the number of clones -to be produced, and for a time SHIFT, which may be a repeater as used -in time stamps, for example `+3d'. +In interactive use, the user will be prompted for the number of +clones to be produced, and for a time SHIFT, which may be a +repeater as used in time stamps, for example `+3d'. -When a valid repeater is given and the entry contains any time stamps, -the clones will become a sequence in time, with time stamps in the -subtree shifted for each clone produced. If SHIFT is nil or the -empty string, time stamps will be left alone. +When a valid repeater is given and the entry contains any time +stamps, the clones will become a sequence in time, with time +stamps in the subtree shifted for each clone produced. If SHIFT +is nil or the empty string, time stamps will be left alone. The +ID property of the original subtree is removed. If the original subtree did contain time stamps with a repeater, the following will happen: @@ -7039,7 +7448,7 @@ the following will happen: I this way you can spell out a number of instances of a repeating task, and still retain the repeater to cover future instances of the task." (interactive "nNumber of clones to produce: \nsDate shift per clone (e.g. +1w, empty to copy unchanged): ") - (let (beg end template task + (let (beg end template task idprop shift-n shift-what doshift nmin nmax (n-no-remove -1)) (if (not (and (integerp n) (> n 0))) (error "Invalid number of replications %s" n)) @@ -7056,6 +7465,7 @@ and still retain the repeater to cover future instances of the task." (setq nmin 1 nmax n) (org-back-to-heading t) (setq beg (point)) + (setq idprop (org-entry-get nil "ID")) (org-end-of-subtree t t) (or (bolp) (insert "\n")) (setq end (point)) @@ -7067,12 +7477,18 @@ and still retain the repeater to cover future instances of the task." (setq nmin 0 nmax (1+ nmax) n-no-remove nmax)) (goto-char end) (loop for n from nmin to nmax do - (if (not doshift) - (setq task template) - (with-temp-buffer - (insert template) - (org-mode) - (goto-char (point-min)) + ;; prepare clone + (with-temp-buffer + (insert template) + (org-mode) + (goto-char (point-min)) + (and idprop (if org-clone-delete-id + (org-entry-delete nil "ID") + (org-id-get-create t))) + (while (re-search-forward org-property-drawer-re nil t) + (org-remove-empty-drawer-at "PROPERTIES" (point))) + (goto-char (point-min)) + (when doshift (while (re-search-forward org-ts-regexp-both nil t) (org-timestamp-change (* n shift-n) shift-what)) (unless (= n n-no-remove) @@ -7081,8 +7497,8 @@ and still retain the repeater to cover future instances of the task." (save-excursion (goto-char (match-beginning 0)) (if (looking-at "<[^<>\n]+\\( +\\+[0-9]+[dwmy]\\)") - (delete-region (match-beginning 1) (match-end 1)))))) - (setq task (buffer-string)))) + (delete-region (match-beginning 1) (match-end 1))))))) + (setq task (buffer-string))) (insert task)) (goto-char beg))) @@ -7126,7 +7542,7 @@ Sorting can be alphabetically, numerically, by date/time as given by a time stamp, by a property or by priority. The command prompts for the sorting type unless it has been given to the -function through the SORTING-TYPE argument, which needs to a character, +function through the SORTING-TYPE argument, which needs to be a character, \(?n ?N ?a ?A ?t ?T ?s ?S ?d ?D ?p ?P ?r ?R ?f ?F). Here is the precise meaning of each character: @@ -7419,15 +7835,15 @@ If WITH-CASE is non-nil, the sorting will be case-sensitive." "Keymap for the minor `orgstruct-mode'.") (defvar org-local-vars nil - "List of local variables, for use by `orgstruct-mode'") + "List of local variables, for use by `orgstruct-mode'.") ;;;###autoload (define-minor-mode orgstruct-mode - "Toggle the minor more `orgstruct-mode'. -This mode is for using Org-mode structure commands in other modes. -The following key behave as if Org-mode was active, if the cursor -is on a headline, or on a plain list item (both in the definition -of Org-mode). + "Toggle the minor mode `orgstruct-mode'. +This mode is for using Org-mode structure commands in other +modes. The following keys behave as if Org-mode were active, if +the cursor is on a headline, or on a plain list item (both as +defined by Org-mode). M-up Move entry/item up M-down Move entry/item down @@ -7478,7 +7894,7 @@ major mode, for example with \\[normal-mode]." (org-set-local 'orgstruct-is-++ t)))) (defvar orgstruct-is-++ nil - "Is orgstruct-mode in ++ version in the current-buffer?") + "Is `orgstruct-mode' in ++ version in the current-buffer?") (make-variable-buffer-local 'orgstruct-is-++) ;;;###autoload @@ -7720,7 +8136,7 @@ If yes, it should return a non-nil value after a calling `org-store-link-props' with a list of properties and values. Special properties are: -:type The link prefix. like \"http\". This must be given. +:type The link prefix, like \"http\". This must be given. :link The link, like \"http://www.astro.uva.nl/~dominik\". This is obligatory as well. :description Optional default description for the second pair @@ -7806,7 +8222,9 @@ For file links, arg negates `org-context-in-file-links'." (get-text-property (point) 'org-marker)))) (when m (org-with-point-at m - (call-interactively 'org-store-link))))) + (if (interactive-p) + (call-interactively 'org-store-link) + (org-store-link nil)))))) ((eq major-mode 'calendar-mode) (let ((cd (calendar-cursor-to-date))) @@ -8117,6 +8535,12 @@ This is the list that is used before handing over to the browser.") (defun org-fixup-message-id-for-http (s) "Replace special characters in a message id, so it can be used in an http query." + (when (string-match "%" s) + (setq s (mapconcat (lambda (c) + (if (eq c ?%) + "%25" + (char-to-string c))) + s ""))) (while (string-match "<" s) (setq s (replace-match "%3C" t t s))) (while (string-match ">" s) @@ -8284,8 +8708,9 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (t (save-match-data (if (string-match (concat "^" (regexp-quote - (file-name-as-directory - (expand-file-name ".")))) + (expand-file-name + (file-name-as-directory + default-directory)))) (expand-file-name path)) ;; We are linking a file with relative path name. (setq path (substring (expand-file-name path) @@ -8316,7 +8741,7 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (setq file (read-file-name "File: ")) (let ((pwd (file-name-as-directory (expand-file-name "."))) (pwd1 (file-name-as-directory (abbreviate-file-name - default-directory)))) + (expand-file-name "."))))) (cond ((equal arg '(16)) (setq link (org-make-link @@ -8554,6 +8979,8 @@ optional argument IN-EMACS is non-nil, Emacs will visit the file. With a double prefix argument, try to open outside of Emacs, in the application the system uses for this file type." (interactive "P") + ;; if in a code block, then open the block's results + (unless (call-interactively #'org-babel-open-src-block-result) (org-load-modules-maybe) (move-marker org-open-link-marker (point)) (setq org-window-config-before-follow-link (current-window-configuration)) @@ -8660,6 +9087,11 @@ application the system uses for this file type." (browse-url (concat type ":" (org-link-escape path org-link-escape-chars-browser)))) + ((string= type "doi") + (browse-url (concat "http://dx.doi.org/" + (org-link-escape + path org-link-escape-chars-browser)))) + ((member type '("message")) (browse-url (concat type ":" path))) @@ -8730,7 +9162,7 @@ application the system uses for this file type." (t (browse-url-at-point))))))) (move-marker org-open-link-marker nil) - (run-hook-with-args 'org-follow-link-hook)) + (run-hook-with-args 'org-follow-link-hook))) (defun org-offer-links-in-entry (&optional nth zero) "Offer links in the current entry and follow the selected link. @@ -8800,10 +9232,10 @@ there is one, offer it as link number zero." (org-add-link-type "file+sys" 'org-open-file-with-system) (org-add-link-type "file+emacs" 'org-open-file-with-emacs) (defun org-open-file-with-system (path) - "Open file at PATH using the system way of opeing it." + "Open file at PATH using the system way of opening it." (org-open-file path 'system)) (defun org-open-file-with-emacs (path) - "Open file at PATH in emacs." + "Open file at PATH in Emacs." (org-open-file path 'emacs)) (defun org-remove-file-link-modifiers () "Remove the file link modifiers in `file+sys:' and `file+emacs:' links." @@ -8829,8 +9261,8 @@ These functions are called in turn with point at the location to which the link should point. A function in the hook should first test if it would like to -handle this file type, for example by checking the major-mode or -the file extension. If it decides not to handle this file, it +handle this file type, for example by checking the `major-mode' +or the file extension. If it decides not to handle this file, it should just return nil to give other functions a chance. If it does handle the file, it must return the search string to be used when following the link. The search string will be part of the @@ -8851,8 +9283,8 @@ buffer with \\[org-insert-link].") Functions added to this hook must accept a single argument, the search string that was part of the file link, the part after the double colon. The function must first check if it would like to -handle this search, for example by checking the major-mode or the -file extension. If it decides not to handle this search, it +handle this search, for example by checking the `major-mode' or +the file extension. If it decides not to handle this search, it should just return nil to give other functions a chance. If it does handle the search, it must return a non-nil value to keep other functions from trying. @@ -9124,20 +9556,23 @@ entry for this file type, and if yes, the corresponding command is launched. If no application is found, Emacs simply visits the file. With optional prefix argument IN-EMACS, Emacs will visit the file. -With a double C-c C-u prefix arg, Org tries to avoid opening in Emacs +With a double \\[universal-argument] \\[universal-argument] \ +prefix arg, Org tries to avoid opening in Emacs and to use an external application to visit the file. -Optional LINE specifies a line to go to, optional SEARCH a string to -search for. If LINE or SEARCH is given, but IN-EMACS is nil, it will -be assumed that org-open-file was called to open a file: link, and the -original link to match against org-file-apps will be reconstructed -from PATH and whichever of LINE or SEARCH is given. - +Optional LINE specifies a line to go to, optional SEARCH a string +to search for. If LINE or SEARCH is given, the file will be +opened in Emacs, unless an entry from org-file-apps that makes +use of groups in a regexp matches. If the file does not exist, an error is thrown." (let* ((file (if (equal path "") buffer-file-name (substitute-in-file-name (expand-file-name path)))) - (apps (append org-file-apps (org-default-apps))) + (file-apps (append org-file-apps (org-default-apps))) + (apps (org-remove-if + 'org-file-apps-entry-match-against-dlink-p file-apps)) + (apps-dlink (org-remove-if-not + 'org-file-apps-entry-match-against-dlink-p file-apps)) (remp (and (assq 'remote apps) (org-file-remote-p file))) (dirp (if remp nil (file-directory-p file))) (file (if (and dirp org-open-directory-means-index-dot-org) @@ -9169,21 +9604,19 @@ If the file does not exist, an error is thrown." (t (setq cmd (or (and remp (cdr (assoc 'remote apps))) (and dirp (cdr (assoc 'directory apps))) - ;; if we find a match in org-file-apps, store the match - ;; data for later - (let* ((re-list1 (org-apps-regexp-alist apps nil)) - (re-list2 - (if a-m-a-p - (org-apps-regexp-alist apps a-m-a-p) - re-list1)) - (private-match - (assoc-default dlink re-list1 'string-match)) - (general-match - (assoc-default dfile re-list2 'string-match))) - (if private-match + ; first, try matching against apps-dlink + ; if we get a match here, store the match data for later + (let ((match (assoc-default dlink apps-dlink + 'string-match))) + (if match (progn (setq link-match-data (match-data)) - private-match) - general-match)) + match) + (progn (setq in-emacs (or in-emacs line search)) + nil))) ; if we have no match in apps-dlink, + ; always open the file in emacs if line or search + ; is given (for backwards compatibility) + (assoc-default dfile (org-apps-regexp-alist apps a-m-a-p) + 'string-match) (cdr (assoc ext apps)) (cdr (assoc t apps)))))) (when (eq cmd 'system) @@ -9213,6 +9646,7 @@ If the file does not exist, an error is thrown." (shell-quote-argument (convert-standard-filename file))) t t cmd))) + ;; Replace "%1", "%2" etc. in command with group matches from regex (save-match-data (let ((match-index 1) @@ -9246,6 +9680,25 @@ If the file does not exist, an error is thrown." (not (equal old-pos (point)))) (org-mark-ring-push old-pos old-buffer)))) +(defun org-file-apps-entry-match-against-dlink-p (entry) + "This function returns non-nil if `entry' uses a regular +expression which should be matched against the whole link by +org-open-file. + +It assumes that is the case when the entry uses a regular +expression which has at least one grouping construct and the +action is either a lisp form or a command string containing +'%1', i.e. using at least one subexpression match as a +parameter." + (let ((selector (car entry)) + (action (cdr entry))) + (if (stringp selector) + (and (> (regexp-opt-depth selector) 0) + (or (and (stringp action) + (string-match "%[0-9]" action)) + (consp action))) + nil))) + (defun org-default-apps () "Return the default applications for this operating system." (cond @@ -9269,8 +9722,7 @@ be opened in Emacs." nil (if (string-match "\\W" (car x)) x - (cons (concat "\\." (car x) "\\(::.*\\)?\\'") - (cdr x))))) + (cons (concat "\\." (car x) "\\'") (cdr x))))) list)) (if add-auto-mode (mapcar (lambda (x) (cons (car x) 'emacs)) auto-mode-alist)))) @@ -9321,12 +9773,64 @@ on the system \"/user@host:\"." (defvar org-agenda-new-buffers nil "Buffers created to visit agenda files.") +(defvar org-refile-cache nil + "Cache for refile targets.") + + +(defvar org-refile-markers nil + "All the markers used for caching refile locations.") + +(defun org-refile-marker (pos) + "Get a new refile marker, but only if caching is in use." + (if (not org-refile-use-cache) + pos + (let ((m (make-marker))) + (move-marker m pos) + (push m org-refile-markers) + m))) + +(defun org-refile-cache-clear () + "Clear the refile cache and disable all the markers." + (mapc (lambda (m) (move-marker m nil)) org-refile-markers) + (setq org-refile-markers nil) + (setq org-refile-cache nil) + (message "Refile cache has been cleared")) + +(defun org-refile-cache-check-set (set) + "Check if all the markers in the cache still have live buffers." + (let (marker) + (catch 'exit + (while (and set (setq marker (nth 3 (pop set)))) + ;; if org-refile-use-outline-path is 'file, marker may be nil + (when (and marker (null (marker-buffer marker))) + (message "not found") (sit-for 3) + (throw 'exit nil))) + t))) + +(defun org-refile-cache-put (set &rest identifiers) + "Push the refile targets SET into the cache, under IDENTIFIERS." + (let* ((key (sha1 (prin1-to-string identifiers))) + (entry (assoc key org-refile-cache))) + (if entry + (setcdr entry set) + (push (cons key set) org-refile-cache)))) + +(defun org-refile-cache-get (&rest identifiers) + "Retrieve the cached value for refile targets given by IDENTIFIERS." + (cond + ((not org-refile-cache) nil) + ((not org-refile-use-cache) (org-refile-cache-clear) nil) + (t + (let ((set (cdr (assoc (sha1 (prin1-to-string identifiers)) + org-refile-cache)))) + (and set (org-refile-cache-check-set set) set))))) + (defun org-get-refile-targets (&optional default-buffer) "Produce a table with refile targets." (let ((case-fold-search nil) ;; otherwise org confuses "TODO" as a kw and "Todo" as a word (entries (or org-refile-targets '((nil . (:level . 1))))) - targets txt re files f desc descre fast-path-p level pos0) + targets tgs txt re files f desc descre fast-path-p level pos0) (message "Getting targets...") (with-current-buffer (or default-buffer (current-buffer)) (while (setq entry (pop entries)) @@ -9365,46 +9869,64 @@ on the system \"/user@host:\"." (while (setq f (pop files)) (with-current-buffer (if (bufferp f) f (org-get-agenda-file-buffer f)) - (if (bufferp f) (setq f (buffer-file-name (buffer-base-buffer f)))) - (setq f (and f (expand-file-name f))) - (if (eq org-refile-use-outline-path 'file) - (push (list (file-name-nondirectory f) f nil nil) targets)) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward descre nil t) - (goto-char (setq pos0 (point-at-bol))) - (catch 'next - (when org-refile-target-verify-function - (save-match-data - (or (funcall org-refile-target-verify-function) - (throw 'next t)))) - (when (looking-at org-complex-heading-regexp) - (setq level (org-reduced-level (- (match-end 1) (match-beginning 1))) - txt (org-link-display-format (match-string 4)) - re (concat "^" (regexp-quote - (buffer-substring (match-beginning 1) - (match-end 4))))) - (if (match-end 5) (setq re (concat re "[ \t]+" - (regexp-quote - (match-string 5))))) - (setq re (concat re "[ \t]*$")) - (when org-refile-use-outline-path - (setq txt (mapconcat 'org-protect-slash - (append - (if (eq org-refile-use-outline-path 'file) - (list (file-name-nondirectory - (buffer-file-name (buffer-base-buffer)))) - (if (eq org-refile-use-outline-path 'full-file-path) - (list (buffer-file-name (buffer-base-buffer))))) - (org-get-outline-path fast-path-p level txt) - (list txt)) - "/"))) - (push (list txt f re (point)) targets))) - (when (= (point) pos0) - ;; verification function has not moved point - (goto-char (point-at-eol)))))))))) + (or + (setq tgs (org-refile-cache-get (buffer-file-name) descre)) + (progn + (if (bufferp f) (setq f (buffer-file-name + (buffer-base-buffer f)))) + (setq f (and f (expand-file-name f))) + (if (eq org-refile-use-outline-path 'file) + (push (list (file-name-nondirectory f) f nil nil) tgs)) + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (while (re-search-forward descre nil t) + (goto-char (setq pos0 (point-at-bol))) + (catch 'next + (when org-refile-target-verify-function + (save-match-data + (or (funcall org-refile-target-verify-function) + (throw 'next t)))) + (when (looking-at org-complex-heading-regexp) + (setq level (org-reduced-level + (- (match-end 1) (match-beginning 1))) + txt (org-link-display-format (match-string 4)) + re (concat "^" (regexp-quote + (buffer-substring + (match-beginning 1) + (match-end 4))))) + (if (match-end 5) (setq re (concat + re "[ \t]+" + (regexp-quote + (match-string 5))))) + (setq re (concat re "[ \t]*$")) + (when org-refile-use-outline-path + (setq txt (mapconcat + 'org-protect-slash + (append + (if (eq org-refile-use-outline-path + 'file) + (list (file-name-nondirectory + (buffer-file-name + (buffer-base-buffer)))) + (if (eq org-refile-use-outline-path + 'full-file-path) + (list (buffer-file-name + (buffer-base-buffer))))) + (org-get-outline-path fast-path-p + level txt) + (list txt)) + "/"))) + (push (list txt f re (org-refile-marker (point))) + tgs))) + (when (= (point) pos0) + ;; verification function has not moved point + (goto-char (point-at-eol)))))))) + (when org-refile-use-cache + (org-refile-cache-put tgs (buffer-file-name) descre)) + (setq targets (append tgs targets)) + )))) (message "Getting targets...done") (nreverse targets))) @@ -9417,13 +9939,14 @@ on the system \"/user@host:\"." (defun org-get-outline-path (&optional fastp level heading) "Return the outline path to the current entry, as a list. -The parameters FASTP, LEVEL, and HEADING are for use be a scanner + +The parameters FASTP, LEVEL, and HEADING are for use by a scanner routine which makes outline path derivations for an entire file, -avoiding backtracing." +avoiding backtracing. Refile target collection makes use of that." (if fastp (progn (if (> level 19) - (error "Outline path failure, more than 19 levels.")) + (error "Outline path failure, more than 19 levels")) (loop for i from level upto 19 do (aset org-olpa i nil)) (prog1 @@ -9439,7 +9962,7 @@ avoiding backtracing." rtn))))) (defun org-format-outline-path (path &optional width prefix) - "Format the outlie path PATH for display. + "Format the outline path PATH for display. Width is the maximum number of characters that is available. Prefix is a prefix to be included in the returned string, such as the file name." @@ -9501,6 +10024,7 @@ such as the file name." Note that this is still *before* the stuff will be removed from the *old* location.") +(defvar org-capture-last-stored-marker) (defun org-refile (&optional goto default-buffer rfloc) "Move the entry at point to another heading. The list of target headings is compiled using the information in @@ -9512,119 +10036,130 @@ Depending on `org-reverse-note-order', the new subitem will either be the first or the last subitem. If there is an active region, all entries in that region will be moved. -However, the region must fulfil the requirement that the first heading +However, the region must fulfill the requirement that the first heading is the first one sets the top-level of the moved text - at most siblings below it are allowed. With prefix arg GOTO, the command will only visit the target location, not actually move anything. -With a double prefix `C-u C-u', go to the location where the last refiling +With a double prefix arg \\[universal-argument] \\[universal-argument], \ +go to the location where the last refiling operation has put the subtree. With a prefix argument of `2', refile to the running clock. RFLOC can be a refile location obtained in a different way. -See also `org-refile-use-outline-path' and `org-completion-use-ido'" +See also `org-refile-use-outline-path' and `org-completion-use-ido'. + +If you are using target caching (see `org-refile-use-cache'), +You have to clear the target cache in order to find new targets. +This can be done with a 0 prefix: `C-0 C-c C-w'" (interactive "P") - (let* ((cbuf (current-buffer)) - (regionp (org-region-active-p)) - (region-start (and regionp (region-beginning))) - (region-end (and regionp (region-end))) - (region-length (and regionp (- region-end region-start))) - (filename (buffer-file-name (buffer-base-buffer cbuf))) - pos it nbuf file re level reversed) - (setq last-command nil) - (when regionp - (goto-char region-start) - (or (bolp) (goto-char (point-at-bol))) - (setq region-start (point)) - (unless (org-kill-is-subtree-p - (buffer-substring region-start region-end)) - (error "The region is not a (sequence of) subtree(s)"))) - (if (equal goto '(16)) - (org-refile-goto-last-stored) - (when (or - (and (equal goto 2) - org-clock-hd-marker (marker-buffer org-clock-hd-marker) - (prog1 - (setq it (list (or org-clock-heading "running clock") - (buffer-file-name - (marker-buffer org-clock-hd-marker)) - "" - (marker-position org-clock-hd-marker))) - (setq goto nil))) - (setq it (or rfloc - (save-excursion - (org-refile-get-location - (if goto "Goto: " "Refile to: ") default-buffer - org-refile-allow-creating-parent-nodes))))) - (setq file (nth 1 it) - re (nth 2 it) - pos (nth 3 it)) - (if (and (not goto) - pos - (equal (buffer-file-name) file) - (if regionp - (and (>= pos region-start) - (<= pos region-end)) - (and (>= pos (point)) - (< pos (save-excursion - (org-end-of-subtree t t)))))) - (error "Cannot refile to position inside the tree or region")) - - (setq nbuf (or (find-buffer-visiting file) - (find-file-noselect file))) - (if goto - (progn - (switch-to-buffer nbuf) - (goto-char pos) - (org-show-context 'org-goto)) - (if regionp + (if (member goto '(0 (64))) + (org-refile-cache-clear) + (let* ((cbuf (current-buffer)) + (regionp (org-region-active-p)) + (region-start (and regionp (region-beginning))) + (region-end (and regionp (region-end))) + (region-length (and regionp (- region-end region-start))) + (filename (buffer-file-name (buffer-base-buffer cbuf))) + pos it nbuf file re level reversed) + (setq last-command nil) + (when regionp + (goto-char region-start) + (or (bolp) (goto-char (point-at-bol))) + (setq region-start (point)) + (unless (org-kill-is-subtree-p + (buffer-substring region-start region-end)) + (error "The region is not a (sequence of) subtree(s)"))) + (if (equal goto '(16)) + (org-refile-goto-last-stored) + (when (or + (and (equal goto 2) + org-clock-hd-marker (marker-buffer org-clock-hd-marker) + (prog1 + (setq it (list (or org-clock-heading "running clock") + (buffer-file-name + (marker-buffer org-clock-hd-marker)) + "" + (marker-position org-clock-hd-marker))) + (setq goto nil))) + (setq it (or rfloc + (save-excursion + (org-refile-get-location + (if goto "Goto: " "Refile to: ") default-buffer + org-refile-allow-creating-parent-nodes))))) + (setq file (nth 1 it) + re (nth 2 it) + pos (nth 3 it)) + (if (and (not goto) + pos + (equal (buffer-file-name) file) + (if regionp + (and (>= pos region-start) + (<= pos region-end)) + (and (>= pos (point)) + (< pos (save-excursion + (org-end-of-subtree t t)))))) + (error "Cannot refile to position inside the tree or region")) + + (setq nbuf (or (find-buffer-visiting file) + (find-file-noselect file))) + (if goto (progn - (org-kill-new (buffer-substring region-start region-end)) - (org-save-markers-in-region region-start region-end)) - (org-copy-subtree 1 nil t)) - (with-current-buffer (setq nbuf (or (find-buffer-visiting file) - (find-file-noselect file))) - (setq reversed (org-notes-order-reversed-p)) - (save-excursion - (save-restriction - (widen) - (if pos - (progn - (goto-char pos) - (looking-at outline-regexp) - (setq level (org-get-valid-level (funcall outline-level) 1)) - (goto-char - (if reversed - (or (outline-next-heading) (point-max)) - (or (save-excursion (org-get-next-sibling)) - (org-end-of-subtree t t) - (point-max))))) - (setq level 1) - (if (not reversed) - (goto-char (point-max)) - (goto-char (point-min)) - (or (outline-next-heading) (goto-char (point-max))))) - (if (not (bolp)) (newline)) - (org-paste-subtree level) - (when org-log-refile - (org-add-log-setup 'refile nil nil 'findpos - org-log-refile) - (unless (eq org-log-refile 'note) - (save-excursion (org-add-log-note)))) - (and org-auto-align-tags (org-set-tags nil t)) - (bookmark-set "org-refile-last-stored") - (if (fboundp 'deactivate-mark) (deactivate-mark)) - (run-hooks 'org-after-refile-insert-hook)))) - (if regionp - (delete-region (point) (+ (point) region-length)) - (org-cut-subtree)) - (when (featurep 'org-inlinetask) - (org-inlinetask-remove-END-maybe)) - (setq org-markers-to-move nil) - (message "Refiled to \"%s\"" (car it)))))) - (org-reveal)) + (switch-to-buffer nbuf) + (goto-char pos) + (org-show-context 'org-goto)) + (if regionp + (progn + (org-kill-new (buffer-substring region-start region-end)) + (org-save-markers-in-region region-start region-end)) + (org-copy-subtree 1 nil t)) + (with-current-buffer (setq nbuf (or (find-buffer-visiting file) + (find-file-noselect file))) + (setq reversed (org-notes-order-reversed-p)) + (save-excursion + (save-restriction + (widen) + (if pos + (progn + (goto-char pos) + (looking-at outline-regexp) + (setq level (org-get-valid-level (funcall outline-level) 1)) + (goto-char + (if reversed + (or (outline-next-heading) (point-max)) + (or (save-excursion (org-get-next-sibling)) + (org-end-of-subtree t t) + (point-max))))) + (setq level 1) + (if (not reversed) + (goto-char (point-max)) + (goto-char (point-min)) + (or (outline-next-heading) (goto-char (point-max))))) + (if (not (bolp)) (newline)) + (org-paste-subtree level) + (when org-log-refile + (org-add-log-setup 'refile nil nil 'findpos + org-log-refile) + (unless (eq org-log-refile 'note) + (save-excursion (org-add-log-note)))) + (and org-auto-align-tags (org-set-tags nil t)) + (bookmark-set "org-refile-last-stored") + ;; If we are refiling for capture, make sure that the + ;; last-capture pointers point here + (when (org-bound-and-true-p org-refile-for-capture) + (bookmark-set "org-capture-last-stored-marker") + (move-marker org-capture-last-stored-marker (point))) + (if (fboundp 'deactivate-mark) (deactivate-mark)) + (run-hooks 'org-after-refile-insert-hook)))) + (if regionp + (delete-region (point) (+ (point) region-length)) + (org-cut-subtree)) + (when (featurep 'org-inlinetask) + (org-inlinetask-remove-END-maybe)) + (setq org-markers-to-move nil) + (message "Refiled to \"%s\" in file %s" (car it) file))))))) (defun org-refile-goto-last-stored () "Go to the location where the last refile was stored." @@ -9837,7 +10372,7 @@ blocks in the buffer." (org-update-dblock))) (defun org-update-dblock () - "Update the dynamic block at point + "Update the dynamic block at point. This means to empty the block, parse for parameters and then call the correct writing function." (save-window-excursion @@ -9932,12 +10467,12 @@ This function can be used in a hook." ) "Structure completion elements. This is a list of abbreviation keys and values. The value gets inserted -it you type @samp{.} followed by the key and then the completion key, +if you type `<' followed by the key and then press the completion key, usually `M-TAB'. %file will be replaced by a file name after prompting for the file using completion. There are two templates for each key, the first uses the original Org syntax, the second uses Emacs Muse-like syntax tags. These Muse-like tags become -the default when the /org-mtags.el/ module has been loaded. See also the +the default when the /org-mtags.el/ module has been loaded. See also the variable `org-mtags-prefer-muse-templates'. This is an experimental feature, it is undecided if it is going to stay in." :group 'org-completion @@ -10157,15 +10692,13 @@ this is nil.") (defvar org-todo-setup-filter-hook nil "Hook for functions that pre-filter todo specs. - -Each function takes a todo spec and returns either `nil' or the spec +Each function takes a todo spec and returns either nil or the spec transformed into canonical form." ) (defvar org-todo-get-default-hook nil "Hook for functions that get a default item for todo. - Each function takes arguments (NEW-MARK OLD-MARK) and returns either -`nil' or a string to be used for the todo mark." ) +nil or a string to be used for the todo mark." ) (defvar org-agenda-headline-snapshot-before-repeat) @@ -10182,10 +10715,12 @@ So for this example: when the item starts with TODO, it is changed to DONE. When it starts with DONE, the DONE is removed. And when neither TODO nor DONE are present, add TODO at the beginning of the heading. -With C-u prefix arg, use completion to determine the new state. +With \\[universal-argument] prefix arg, use completion to determine the new \ +state. With numeric prefix arg, switch to that state. -With a double C-u prefix, switch to the next set of TODO keywords (nextset). -With a triple C-u prefix, circumvent any state blocking. +With a double \\[universal-argument] prefix, switch to the next set of TODO \ +keywords (nextset). +With a triple \\[universal-argument] prefix, circumvent any state blocking. For calling through lisp, arg is also interpreted in the following way: 'none -> empty state @@ -10213,7 +10748,7 @@ For calling through lisp, arg is also interpreted in the following way: (looking-at " *")) (let* ((match-data (match-data)) (startpos (point-at-bol)) - (logging (save-match-data (org-entry-get nil "LOGGING" t))) + (logging (save-match-data (org-entry-get nil "LOGGING" t t))) (org-log-done org-log-done) (org-log-repeat org-log-repeat) (org-todo-log-states org-todo-log-states) @@ -10429,7 +10964,7 @@ changes. Such blocking occurs when: (let* ((pos (point)) (parent-pos (and (org-up-heading-safe) (point)))) (if (not parent-pos) (throw 'dont-block t)) ; no parent - (when (and (org-entry-get (point) "ORDERED") + (when (and (org-not-nil (org-entry-get (point) "ORDERED")) (forward-line 1) (re-search-forward org-not-done-heading-regexp pos t)) (throw 'dont-block nil)) ; block, there is an older sibling not done. @@ -10441,7 +10976,7 @@ changes. Such blocking occurs when: (setq pos (point)) (setq parent-pos (and (org-up-heading-safe) (point))) (if (not parent-pos) (throw 'dont-block t)) ; no parent - (when (and (org-entry-get (point) "ORDERED") + (when (and (org-not-nil (org-entry-get (point) "ORDERED")) (forward-line 1) (re-search-forward org-not-done-heading-regexp pos t)) (throw 'dont-block nil)))))))) ; block, older sibling not done. @@ -10835,12 +11370,17 @@ This function is run automatically after each state change to a DONE state." (org-log-done nil) (org-todo-log-states nil) (nshiftmax 10) (nshift 0) - re type n what ts time) + re type n what ts time to-state) (when repeat (if (eq org-log-repeat t) (setq org-log-repeat 'state)) - (org-todo (if (eq interpret 'type) last-state head)) - (org-entry-put nil "LAST_REPEAT" (format-time-string - (org-time-stamp-format t t))) + (setq to-state (or (org-entry-get nil "REPEAT_TO_STATE") + org-todo-repeat-to-state)) + (unless (and to-state (member to-state org-todo-keywords-1)) + (setq to-state (if (eq interpret 'type) last-state head))) + (org-todo to-state) + (when (or org-log-repeat (org-entry-get nil "CLOCK")) + (org-entry-put nil "LAST_REPEAT" (format-time-string + (org-time-stamp-format t t)))) (when org-log-repeat (if (or (memq 'org-add-log-note (default-value 'post-command-hook)) (memq 'org-add-log-note post-command-hook)) @@ -11004,7 +11544,7 @@ returns nil." (apply 'encode-time (org-parse-time-string time))))) (defun org-get-deadline-time (pom &optional inherit) - "Get the deadine as a time tuple, of a format suitable for + "Get the deadline as a time tuple, of a format suitable for calling org-deadline with, or if there is no scheduling, returns nil." (let ((time (org-entry-get pom "DEADLINE" inherit))) @@ -11122,7 +11662,7 @@ be removed." (end-of-line 1)) (goto-char (point-min)) (widen) - (if (and (looking-at "[ \t]+\n") + (if (and (looking-at "[ \t]*\n") (equal (char-before) ?\n)) (delete-region (1- (point)) (point-at-eol))) ts)))))) @@ -11272,6 +11812,9 @@ EXTRA is additional text that will be inserted into the notes buffer." (cons "%t" (format-time-string (org-time-stamp-format 'long 'inactive) (current-time))) + (cons "%T" (format-time-string + (org-time-stamp-format 'long nil) + (current-time))) (cons "%s" (if org-log-note-state (concat "\"" org-log-note-state "\"") "")) @@ -11326,7 +11869,8 @@ POS may also be a marker." This command can create sparse trees. You first need to select the type of match used to create the tree: -t Show entries with a specific TODO keyword. +t Show all TODO entries. +T Show entries with a specific TODO keyword. m Show entries selected by a tags/property match. p Enter a property name and its value (both with completion on existing names/values) and show entries with that property. @@ -11336,7 +11880,7 @@ b Show deadlines and scheduled items before a date. a Show deadlines and scheduled items after a date." (interactive "P") (let (ans kwd value) - (message "Sparse tree: [/]regexp [t]odo-kwd [m]atch [p]roperty [d]eadlines [b]efore-date [a]fter-date") + (message "Sparse tree: [/]regexp [t]odo [T]odo-kwd [m]atch [p]roperty [d]eadlines\n [b]efore-date [a]fter-date") (setq ans (read-char-exclusive)) (cond ((equal ans ?d) @@ -11346,6 +11890,8 @@ a Show deadlines and scheduled items after a date." ((equal ans ?a) (call-interactively 'org-check-after-date)) ((equal ans ?t) + (org-show-todo-tree nil)) + ((equal ans ?T) (org-show-todo-tree '(4))) ((member ans '(?T ?m)) (call-interactively 'org-match-sparse-tree)) @@ -11417,7 +11963,7 @@ that the match should indeed be shown." cnt)) (defun org-show-context (&optional key) - "Make sure point and context and visible. + "Make sure point and context are visible. How much context is shown depends upon the variables `org-show-hierarchy-above', `org-show-following-heading'. and `org-show-siblings'." @@ -11460,7 +12006,8 @@ not t for the search context. With optional argument SIBLINGS, on each level of the hierarchy all siblings are shown. This repairs the tree structure to what it would look like when opened with hierarchical calls to `org-cycle'. -With double optional argument `C-u C-u', go to the parent and show the +With double optional argument \\[universal-argument] \\[universal-argument], \ +go to the parent and show the entire tree." (interactive "P") (run-hooks 'org-reveal-start-hook) @@ -11476,8 +12023,8 @@ entire tree." (defun org-highlight-new-match (beg end) "Highlight from BEG to END and mark the highlight is an occur headline." - (let ((ov (org-make-overlay beg end))) - (org-overlay-put ov 'face 'secondary-selection) + (let ((ov (make-overlay beg end))) + (overlay-put ov 'face 'secondary-selection) (push ov org-occur-highlights))) (defun org-remove-occur-highlights (&optional beg end noremove) @@ -11486,7 +12033,7 @@ BEG and END are ignored. If NOREMOVE is nil, remove this function from the `before-change-functions' in the current buffer." (interactive) (unless org-inhibit-highlight-removal - (mapc 'org-delete-overlay org-occur-highlights) + (mapc 'delete-overlay org-occur-highlights) (setq org-occur-highlights nil) (setq org-occur-parameters nil) (unless noremove @@ -11989,7 +12536,7 @@ epoch to the beginning of today (00:00)." (delq nil list)) (defvar org-add-colon-after-tag-completion nil) ;; dynamically scoped param -(defvar org-tags-overlay (org-make-overlay 1 1)) +(defvar org-tags-overlay (make-overlay 1 1)) (org-detach-overlay org-tags-overlay) (defun org-get-local-tags-at (&optional pos) @@ -12142,6 +12689,16 @@ If DATA is nil or the empty string, any tags will be removed." (if (looking-at ".*?\\([ \t]+\\)$") (delete-region (match-beginning 1) (match-end 1)))))) +(defun org-align-all-tags () + "Align the tags i all headings." + (interactive) + (save-excursion + (or (ignore-errors (org-back-to-heading t)) + (outline-next-heading)) + (if (org-on-heading-p) + (org-set-tags t) + (message "No headings")))) + (defun org-set-tags (&optional arg just-align) "Set the tags for the current headline. With prefix ARG, realign all tags in headings in the current buffer." @@ -12355,7 +12912,7 @@ Returns the new tags string, or nil to not change the current settings." (if (> (current-column) org-tags-column) " " (make-string (- org-tags-column (current-column)) ?\ )))))) - (org-move-overlay org-tags-overlay ov-start ov-end) + (move-overlay org-tags-overlay ov-start ov-end) (save-window-excursion (if expert (set-buffer (get-buffer-create " *Org tags*")) @@ -12663,7 +13220,7 @@ but in some other way.") "LOCATION" "LOGGING" "COLUMNS" "VISIBILITY" "TABLE_EXPORT_FORMAT" "TABLE_EXPORT_FILE" "EXPORT_FILE_NAME" "EXPORT_TITLE" "EXPORT_AUTHOR" "EXPORT_DATE" - "ORDERED" "NOBLOCKING" "COOKIE_DATA" "LOG_INTO_DRAWER" + "ORDERED" "NOBLOCKING" "COOKIE_DATA" "LOG_INTO_DRAWER" "REPEAT_TO_STATE" "CLOCK_MODELINE_TOTAL" "STYLE" "HTML_CONTAINER_CLASS") "Some properties that are used by Org-mode for various purposes. Being in this list makes sure that they are offered for completion.") @@ -12753,12 +13310,11 @@ allowed value." (save-excursion (beginning-of-line 1) (when (looking-at (org-re "^[ \t]*\\(:\\([[:alpha:]][[:alnum:]_-]*\\):\\)[ \t]*\\(.*\\)")) - (let ((match (match-data)) ;; Keep match-data for use by calling - (p (point)) ;; procedures. - (range (unless (org-before-first-heading-p) - (org-get-property-block)))) - (prog1 (and range (<= (car range) p) (< p (cdr range))) - (set-match-data match)))))) + (save-match-data ;; Used by calling procedures + (let ((p (point)) + (range (unless (org-before-first-heading-p) + (org-get-property-block)))) + (and range (<= (car range) p) (< p (cdr range)))))))) (defun org-get-property-block (&optional beg end force) "Return the (beg . end) range of the body of the property drawer. @@ -12806,7 +13362,7 @@ things up because then unnecessary parsing is avoided." (let ((clockstr (substring org-clock-string 0 -1)) (excluded '("TODO" "TAGS" "ALLTAGS" "PRIORITY" "BLOCKED")) (case-fold-search nil) - beg end range props sum-props key value string clocksum) + beg end range props sum-props key key1 value string clocksum) (save-excursion (when (condition-case nil (and (org-mode-p) (org-back-to-heading t)) @@ -12837,23 +13393,35 @@ things up because then unnecessary parsing is avoided." (when (or (not specific) (string= specific "BLOCKED")) (push (cons "BLOCKED" (if (org-entry-blocked-p) "t" "")) props)) (when (or (not specific) - (member specific org-all-time-keywords) - (member specific '("TIMESTAMP" "TIMESTAMP_IA"))) + (member specific + '("SCHEDULED" "DEADLINE" "CLOCK" "CLOSED" + "TIMESTAMP" "TIMESTAMP_IA"))) (while (re-search-forward org-maybe-keyword-time-regexp end t) - (setq key (if (match-end 1) (substring (org-match-string-no-properties 1) 0 -1)) + (setq key (if (match-end 1) + (substring (org-match-string-no-properties 1) + 0 -1)) string (if (equal key clockstr) (org-no-properties (org-trim - (buffer-substring - (match-beginning 3) (goto-char (point-at-eol))))) - (substring (org-match-string-no-properties 3) 1 -1))) - (unless key - (if (= (char-after (match-beginning 3)) ?\[) - (setq key "TIMESTAMP_IA") - (setq key "TIMESTAMP"))) - (when (or (equal key clockstr) (not (assoc key props))) + (buffer-substring + (match-beginning 3) (goto-char + (point-at-eol))))) + (substring (org-match-string-no-properties 3) + 1 -1))) + ;; Get the correct property name from the key. This is + ;; necessary if the user has configured time keywords. + (setq key1 (concat key ":")) + (cond + ((not key) + (setq key + (if (= (char-after (match-beginning 3)) ?\[) + "TIMESTAMP_IA" "TIMESTAMP"))) + ((equal key1 org-scheduled-string) (setq key "SCHEDULED")) + ((equal key1 org-deadline-string) (setq key "DEADLINE")) + ((equal key1 org-closed-string) (setq key "CLOSED")) + ((equal key1 org-clock-string) (setq key "CLOCK"))) + (when (or (equal key "CLOCK") (not (assoc key props))) (push (cons key string) props)))) - ) (when (memq which '(all standard)) @@ -12880,19 +13448,23 @@ things up because then unnecessary parsing is avoided." (push (cons "CATEGORY" value) props)) (append sum-props (nreverse props))))))) -(defun org-entry-get (pom property &optional inherit) +(defun org-entry-get (pom property &optional inherit literal-nil) "Get value of PROPERTY for entry at point-or-marker POM. If INHERIT is non-nil and the entry does not have the property, then also check higher levels of the hierarchy. If INHERIT is the symbol `selective', use inheritance only if the setting in `org-use-property-inheritance' selects PROPERTY for inheritance. If the property is present but empty, the return value is the empty string. -If the property is not present at all, nil is returned." +If the property is not present at all, nil is returned. + +If LITERAL-NIL is set, return the string value \"nil\" as a string, +do not interpret it as the list atom nil. This is used for inheritance +when a \"nil\" value can supersede a non-nil value higher up the hierarchy." (org-with-point-at pom (if (and inherit (if (eq inherit 'selective) (org-property-inherit-p property) t)) - (org-entry-get-with-inheritance property) + (org-entry-get-with-inheritance property literal-nil) (if (member property org-special-properties) ;; We need a special property. Use `org-entry-properties' to ;; retrieve it, but specify the wanted property @@ -12905,7 +13477,9 @@ If the property is not present at all, nil is returned." (cdr range) t)) ;; Found the property, return it. (if (match-end 1) - (org-match-string-no-properties 1) + (if literal-nil + (org-match-string-no-properties 1) + (org-not-nil (org-match-string-no-properties 1))) ""))))))) (defun org-property-or-variable-value (var &optional inherit) @@ -13000,8 +13574,12 @@ no match, the marker will point nowhere. Note that also `org-entry-get' calls this function, if the INHERIT flag is set.") -(defun org-entry-get-with-inheritance (property) - "Get entry property, and search higher levels if not present." +(defun org-entry-get-with-inheritance (property &optional literal-nil) + "Get entry property, and search higher levels if not present. +The search will stop at the first ancestor which has the property defined. +If the value found is \"nil\", return nil to show that the property +should be considered as undefined (this is the meaning of nil here). +However, if LITERAL-NIL is set, return the string value \"nil\" instead." (move-marker org-entry-property-inherited-from nil) (let (tmp) (save-excursion @@ -13009,15 +13587,16 @@ is set.") (widen) (catch 'ex (while t - (when (setq tmp (org-entry-get nil property)) + (when (setq tmp (org-entry-get nil property nil 'literal-nil)) (org-back-to-heading t) (move-marker org-entry-property-inherited-from (point)) (throw 'ex tmp)) (or (org-up-heading-safe) (throw 'ex nil))))) - (or tmp - (cdr (assoc property org-file-properties)) - (cdr (assoc property org-global-properties)) - (cdr (assoc property org-global-properties-fixed)))))) + (setq tmp (or tmp + (cdr (assoc property org-file-properties)) + (cdr (assoc property org-global-properties)) + (cdr (assoc property org-global-properties-fixed)))) + (if literal-nil tmp (org-not-nil tmp))))) (defvar org-property-changed-functions nil "Hook called when the value of a property has changed. @@ -13216,7 +13795,8 @@ in the current file." "In the current entry, delete PROPERTY." (interactive (let* ((completion-ignore-case t) - (prop (org-icompleting-read "Property: " (org-entry-properties nil 'standard)))) + (prop (org-icompleting-read "Property: " + (org-entry-properties nil 'standard)))) (list prop))) (message "Property %s %s" property (if (org-entry-delete nil property) @@ -13330,6 +13910,51 @@ completion." (skip-chars-forward " \t") (run-hook-with-args 'org-property-changed-functions key nval))) +(defun org-find-olp (path &optional this-buffer) + "Return a marker pointing to the entry at outline path OLP. +If anything goes wrong, throw an error. +You can wrap this call to catch the error like this: + + (condition-case msg + (org-mobile-locate-entry (match-string 4)) + (error (nth 1 msg))) + +The return value will then be either a string with the error message, +or a marker if everything is OK. + +If THIS-BUFFER is set, the outline path does not contain a file, +only headings." + (let* ((file (if this-buffer buffer-file-name (pop path))) + (buffer (if this-buffer (current-buffer) (find-file-noselect file))) + (level 1) + (lmin 1) + (lmax 1) + limit re end found pos heading cnt) + (unless buffer (error "File not found :%s" file)) + (with-current-buffer buffer + (save-excursion + (save-restriction + (widen) + (setq limit (point-max)) + (goto-char (point-min)) + (while (setq heading (pop path)) + (setq re (format org-complex-heading-regexp-format + (regexp-quote heading))) + (setq cnt 0 pos (point)) + (while (re-search-forward re end t) + (setq level (- (match-end 1) (match-beginning 1))) + (if (and (>= level lmin) (<= level lmax)) + (setq found (match-beginning 0) cnt (1+ cnt)))) + (when (= cnt 0) (error "Heading not found on level %d: %s" + lmax heading)) + (when (> cnt 1) (error "Heading not unique on level %d: %s" + lmax heading)) + (goto-char found) + (setq lmin (1+ level) lmax (+ lmin (if org-odd-levels-only 1 0))) + (setq end (save-excursion (org-end-of-subtree t t)))) + (when (org-on-heading-p) + (move-marker (make-marker) (point)))))))) + (defun org-find-entry-with-id (ident) "Locate the entry that contains the ID property with exact value IDENT. IDENT can be a string, a symbol or a number, this function will search for @@ -13436,8 +14061,8 @@ So these are more for recording a certain time/date." (interactive "P") (org-time-stamp arg 'inactive)) -(defvar org-date-ovl (org-make-overlay 1 1)) -(org-overlay-put org-date-ovl 'face 'org-warning) +(defvar org-date-ovl (make-overlay 1 1)) +(overlay-put org-date-ovl 'face 'org-warning) (org-detach-overlay org-date-ovl) (defvar org-ans1) ; dynamically scoped parameter @@ -13458,10 +14083,15 @@ The prompt will suggest to enter an ISO date, but you can also enter anything which will at least partially be understood by `parse-time-string'. Unrecognized parts of the date will default to the current day, month, year, hour and minute. If this command is called to replace a timestamp at point, -of to enter the second timestamp of a range, the default time is taken from the -existing stamp. For example, +of to enter the second timestamp of a range, the default time is taken +from the existing stamp. Furthermore, the command prefers the future, +so if you are giving a date where the year is not given, and the day-month +combination is already past in the current year, it will assume you +mean next year. For details, see the manual. A few examples: + 3-2-5 --> 2003-02-05 feb 15 --> currentyear-02-15 + 2/15 --> currentyear-02-15 sep 12 9 --> 2009-09-12 12:45 --> today 12:45 22 sept 0:34 --> currentyear-09-22 0:34 @@ -13514,11 +14144,10 @@ user." (setq def (apply 'encode-time defdecode) defdecode (decode-time def))))) (calendar-frame-setup nil) + (calendar-setup nil) (calendar-move-hook nil) (calendar-view-diary-initially-flag nil) - (view-diary-entries-initially nil) (calendar-view-holidays-initially-flag nil) - (view-calendar-holidays-initially nil) (timestr (format-time-string (if with-time "%Y-%m-%d %H:%M" "%Y-%m-%d") def)) (prompt (concat (if prompt (concat prompt " ") "") @@ -13539,10 +14168,8 @@ user." (map (copy-keymap calendar-mode-map)) (minibuffer-local-map (copy-keymap minibuffer-local-map))) (org-defkey map (kbd "RET") 'org-calendar-select) - (org-defkey map (if (featurep 'xemacs) [button1] [mouse-1]) - 'org-calendar-select-mouse) - (org-defkey map (if (featurep 'xemacs) [button2] [mouse-2]) - 'org-calendar-select-mouse) + (org-defkey map [mouse-1] 'org-calendar-select-mouse) + (org-defkey map [mouse-2] 'org-calendar-select-mouse) (org-defkey minibuffer-local-map [(meta shift left)] (lambda () (interactive) (org-eval-in-calendar '(calendar-backward-month 1)))) @@ -13585,6 +14212,14 @@ user." (org-defkey minibuffer-local-map "<" (lambda () (interactive) (org-eval-in-calendar '(scroll-calendar-right 1)))) + (org-defkey minibuffer-local-map "\C-v" + (lambda () (interactive) + (org-eval-in-calendar + '(calendar-scroll-left-three-months 1)))) + (org-defkey minibuffer-local-map "\M-v" + (lambda () (interactive) + (org-eval-in-calendar + '(calendar-scroll-right-three-months 1)))) (run-hooks 'org-read-date-minibuffer-setup-hook) (unwind-protect (progn @@ -13599,7 +14234,7 @@ user." (remove-hook 'post-command-hook 'org-read-date-display) (use-local-map old-map) (when org-read-date-overlay - (org-delete-overlay org-read-date-overlay) + (delete-overlay org-read-date-overlay) (setq org-read-date-overlay nil))))))) (t ; Naked prompt only @@ -13607,7 +14242,7 @@ user." (setq ans (read-string prompt default-input 'org-read-date-history timestr)) (when org-read-date-overlay - (org-delete-overlay org-read-date-overlay) + (delete-overlay org-read-date-overlay) (setq org-read-date-overlay nil))))) (setq final (org-read-date-analyze ans def defdecode)) @@ -13629,7 +14264,7 @@ user." "Display the current date prompt interpretation in the minibuffer." (when org-read-date-display-live (when org-read-date-overlay - (org-delete-overlay org-read-date-overlay)) + (delete-overlay org-read-date-overlay)) (let ((p (point))) (end-of-line 1) (while (not (equal (buffer-substring @@ -13657,11 +14292,11 @@ user." (when org-read-date-analyze-futurep (setq txt (concat txt " (=>F)"))) (setq org-read-date-overlay - (org-make-overlay (1- (point-at-eol)) (point-at-eol))) + (make-overlay (1- (point-at-eol)) (point-at-eol))) (org-overlay-display org-read-date-overlay txt 'secondary-selection)))) (defun org-read-date-analyze (ans def defdecode) - "Analyse the combined answer of the date prompt." + "Analyze the combined answer of the date prompt." ;; FIXME: cleanup and comment (let ((nowdecode (decode-time (current-time))) delta deltan deltaw deltadef year month day @@ -13703,7 +14338,7 @@ user." t nil ans))) ;; Help matching american dates, like 5/30 or 5/30/7 (when (string-match - "^ *\\([0-3]?[0-9]\\)/\\([0-1]?[0-9]\\)\\(/\\([0-9]+\\)\\)?\\([^/0-9]\\|$\\)" ans) + "^ *\\(0?[1-9]\\|1[012]\\)/\\(0?[1-9]\\|[12][0-9]\\|3[01]\\)\\(/\\([0-9]+\\)\\)?\\([^/0-9]\\|$\\)" ans) (setq year (if (match-end 4) (string-to-number (match-string 4 ans)) (progn (setq kill-year t) @@ -13893,7 +14528,7 @@ Also, store the cursor date in variable org-ans2." (let* ((date (calendar-cursor-to-date)) (time (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))) (setq org-ans2 (format-time-string "%Y-%m-%d" time)))) - (org-move-overlay org-date-ovl (1- (point)) (1+ (point)) (current-buffer)) + (move-overlay org-date-ovl (1- (point)) (1+ (point)) (current-buffer)) (select-window sw) (org-select-frame-set-input-focus sf))) @@ -14187,7 +14822,7 @@ days in order to avoid rounding problems." (defun org-time-string-to-absolute (s &optional daynr prefer show-all) "Convert a time stamp to an absolute day number. -If there is a specifyer for a cyclic time stamp, get the closest date to +If there is a specifier for a cyclic time stamp, get the closest date to DAYNR. PREFER and SHOW-ALL are passed through to `org-closest-date'. the variable date is bound by the calendar when this is called." @@ -14300,7 +14935,7 @@ When SHOW-ALL is nil, only return the current occurrence of a time stamp." (if (string-match "\\(\\+[0-9]+\\)\\([dwmy]\\)" change) (setq dn (string-to-number (match-string 1 change)) dw (cdr (assoc (match-string 2 change) a1))) - (error "Invalid change specifyer: %s" change)) + (error "Invalid change specifier: %s" change)) (if (eq dw 'week) (setq dw 'day dn (* 7 dn))) (cond ((eq dw 'day) @@ -14346,7 +14981,7 @@ When SHOW-ALL is nil, only return the current occurrence of a time stamp." (t (if (= cday n1) n1 n2))))))) (defun org-date-to-gregorian (date) - "Turn any specification of DATE into a gregorian date for the calendar." + "Turn any specification of DATE into a Gregorian date for the calendar." (cond ((integerp date) (calendar-gregorian-from-absolute date)) ((and (listp date) (= (length date) 3)) date) ((stringp date) @@ -14378,7 +15013,7 @@ If the cursor is on the year, change the year. If it is on the month or the day, change that. With prefix ARG, change by that many units." (interactive "p") - (org-timestamp-change (prefix-numeric-value arg))) + (org-timestamp-change (prefix-numeric-value arg) nil 'updown)) (defun org-timestamp-down (&optional arg) "Decrease the date item at the cursor by one. @@ -14386,7 +15021,7 @@ If the cursor is on the year, change the year. If it is on the month or the day, change that. With prefix ARG, change by that many units." (interactive "p") - (org-timestamp-change (- (prefix-numeric-value arg)))) + (org-timestamp-change (- (prefix-numeric-value arg)) nil 'updown)) (defun org-timestamp-up-day (&optional arg) "Increase the date in the time stamp by one day. @@ -14395,7 +15030,7 @@ With prefix ARG, change that many days." (if (and (not (org-at-timestamp-p t)) (org-on-heading-p)) (org-todo 'up) - (org-timestamp-change (prefix-numeric-value arg) 'day))) + (org-timestamp-change (prefix-numeric-value arg) 'day 'updown))) (defun org-timestamp-down-day (&optional arg) "Decrease the date in the time stamp by one day. @@ -14404,7 +15039,7 @@ With prefix ARG, change that many days." (if (and (not (org-at-timestamp-p t)) (org-on-heading-p)) (org-todo 'down) - (org-timestamp-change (- (prefix-numeric-value arg)) 'day))) + (org-timestamp-change (- (prefix-numeric-value arg)) 'day) 'updown)) (defun org-at-timestamp-p (&optional inactive-ok) "Determine if the cursor is in or at a timestamp." @@ -14449,7 +15084,7 @@ With prefix ARG, change that many days." (message "Timestamp is now %sactive" (if (equal (char-after beg) ?<) "" "in"))))) -(defun org-timestamp-change (n &optional what) +(defun org-timestamp-change (n &optional what updown) "Change the date in the time stamp at point. The date will be changed by N times WHAT. WHAT can be `day', `month', `year', `minute', `second'. If WHAT is not given, the cursor position @@ -14480,8 +15115,10 @@ in the timestamp determines what will be changed." (if (string-match "^.\\{10\\}.*?[0-9]+:[0-9][0-9]" ts) (setq with-hm t)) (setq time0 (org-parse-time-string ts)) - (when (and (eq org-ts-what 'minute) - (eq current-prefix-arg nil)) + (when (and updown + (eq org-ts-what 'minute) + (not current-prefix-arg)) + ;; This looks like s-up and s-down. Change by one rounding step. (setq n (* dm (cond ((> n 0) 1) ((< n 0) -1) (t 0)))) (when (not (= 0 (setq rem (% (nth 1 time0) dm)))) (setcar (cdr time0) (+ (nth 1 time0) @@ -14578,9 +15215,7 @@ A prefix ARG can be used to force the current date." (let ((tsr org-ts-regexp) diff (calendar-move-hook nil) (calendar-view-holidays-initially-flag nil) - (view-calendar-holidays-initially nil) - (calendar-view-diary-initially-flag nil) - (view-diary-entries-initially nil)) + (calendar-view-diary-initially-flag nil)) (if (or (org-at-timestamp-p) (save-excursion (beginning-of-line 1) @@ -14670,21 +15305,31 @@ changes from another. I believe the procedure must be like this: ;;;; Agenda files ;;;###autoload -(defun org-iswitchb (&optional arg) - "Use `org-icompleting-read' to prompt for an Org buffer to switch to. +(defun org-switchb (&optional arg) + "Switch between Org buffers. With a prefix argument, restrict available to files. -With two prefix arguments, restrict available buffers to agenda files." +With two prefix arguments, restrict available buffers to agenda files. + +Defaults to `iswitchb' for buffer name completion. +Set `org-completion-use-ido' to make it use ido instead." (interactive "P") (let ((blist (cond ((equal arg '(4)) (org-buffer-list 'files)) ((equal arg '(16)) (org-buffer-list 'agenda)) - (t (org-buffer-list))))) + (t (org-buffer-list)))) + (org-completion-use-iswitchb org-completion-use-iswitchb) + (org-completion-use-ido org-completion-use-ido)) + (unless (or org-completion-use-ido org-completion-use-iswitchb) + (setq org-completion-use-iswitchb t)) (switch-to-buffer (org-icompleting-read "Org buffer: " - (mapcar 'list (mapcar 'buffer-name blist)) - nil t)))) + (mapcar 'list (mapcar 'buffer-name blist)) + nil t)))) +;;; Define some older names previously used for this functionality +;;;###autoload +(defalias 'org-ido-switchb 'org-switchb) ;;;###autoload -(defalias 'org-ido-switchb 'org-iswitchb) +(defalias 'org-iswitchb 'org-switchb) (defun org-buffer-list (&optional predicate exclude-tmp) "Return a list of Org buffers. @@ -14755,6 +15400,13 @@ used by the agenda files. If ARCHIVE is `ifmode', do this only if (setq files (org-add-archive-files files))) files)) +(defun org-agenda-file-p (&optional file) + "Return non-nil, if FILE is an agenda file. +If FILE is omitted, use the file associated with the current +buffer." + (member (or file (buffer-file-name)) + (org-agenda-files t))) + (defun org-edit-agenda-file-list () "Edit the list of agenda files. Depending on setup, this either uses customize to edit the variable @@ -15068,10 +15720,6 @@ looks only before point, not after." (org-in-regexp "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*"))) -(defun test () - (interactive) - (message "%s" (org-inside-latex-macro-p))) - (defun org-try-cdlatex-tab () "Check if it makes sense to execute `cdlatex-tab', and do it if yes. It makes sense to do so if `org-cdlatex-mode' is active and if the cursor is @@ -15113,7 +15761,7 @@ Revert to the normal definition outside of these fragments." (defun org-remove-latex-fragment-image-overlays () "Remove all overlays with LaTeX fragment images in current buffer." - (mapc 'org-delete-overlay org-latex-fragment-image-overlays) + (mapc 'delete-overlay org-latex-fragment-image-overlays) (setq org-latex-fragment-image-overlays nil)) (defun org-preview-latex-fragment (&optional subtree) @@ -15122,7 +15770,8 @@ If the cursor is in a LaTeX fragment, create the image and overlay it over the source code. If there is no fragment at point, display all fragments in the current text, from one headline to the next. With prefix SUBTREE, display all fragments in the current subtree. With a -double prefix `C-u C-u', or when the cursor is before the first headline, +double prefix arg \\[universal-argument] \\[universal-argument], or when \ +the cursor is before the first headline, display all fragments in the buffer. The images can be removed again with \\[org-ctrl-c-ctrl-c]." (interactive "P") @@ -15168,7 +15817,8 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." ("$$" "\\$\\$[^\000]*?\\$\\$" 0 nil)) "Regular expressions for matching embedded LaTeX.") -(defun org-format-latex (prefix &optional dir overlays msg at forbuffer) +(defun org-format-latex (prefix &optional dir overlays msg at + forbuffer protect-only) "Replace LaTeX fragments with links to an image, and produce images. Some of the options can be changed using the variable `org-format-latex-options'." @@ -15198,60 +15848,63 @@ Some of the options can be changed using the variable (not (eq (get-char-property (match-beginning n) 'org-overlay-type) 'org-latex-overlay)))) - (setq txt (match-string n) - beg (match-beginning n) end (match-end n) - cnt (1+ cnt)) - (let (print-length print-level) ; make sure full list is printed - (setq hash (sha1 (prin1-to-string - (list org-format-latex-header - org-format-latex-header-extra - org-export-latex-default-packages-alist - org-export-latex-packages-alist - org-format-latex-options - forbuffer txt))) - linkfile (format "%s_%s.png" prefix hash) - movefile (format "%s_%s.png" absprefix hash))) - (setq link (concat block "[[file:" linkfile "]]" block)) - (if msg (message msg cnt)) - (goto-char beg) - (unless checkdir ; make sure the directory exists - (setq checkdir t) - (or (file-directory-p todir) (make-directory todir))) - - (unless executables-checked - (org-check-external-command - "latex" "needed to convert LaTeX fragments to images") - (org-check-external-command - "dvipng" "needed to convert LaTeX fragments to images") - (setq executables-checked t)) - - (unless (file-exists-p movefile) - (org-create-formula-image - txt movefile opt forbuffer)) - (if overlays - (progn - (mapc (lambda (o) - (if (eq (org-overlay-get o 'org-overlay-type) - 'org-latex-overlay) - (org-delete-overlay o))) - (org-overlays-in beg end)) - (setq ov (org-make-overlay beg end)) - (org-overlay-put ov 'org-overlay-type 'org-latex-overlay) - (if (featurep 'xemacs) - (progn - (org-overlay-put ov 'invisible t) - (org-overlay-put - ov 'end-glyph - (make-glyph (vector 'png :file movefile)))) - (org-overlay-put - ov 'display - (list 'image :type 'png :file movefile :ascent 'center))) - (push ov org-latex-fragment-image-overlays) - (goto-char end)) - (delete-region beg end) - (insert (org-add-props link - (list 'org-latex-src - (replace-regexp-in-string "\"" "" txt))))))))))) + (if protect-only + (add-text-properties (match-beginning n) (match-end n) + '(org-protected t)) + (setq txt (match-string n) + beg (match-beginning n) end (match-end n) + cnt (1+ cnt)) + (let (print-length print-level) ; make sure full list is printed + (setq hash (sha1 (prin1-to-string + (list org-format-latex-header + org-format-latex-header-extra + org-export-latex-default-packages-alist + org-export-latex-packages-alist + org-format-latex-options + forbuffer txt))) + linkfile (format "%s_%s.png" prefix hash) + movefile (format "%s_%s.png" absprefix hash))) + (setq link (concat block "[[file:" linkfile "]]" block)) + (if msg (message msg cnt)) + (goto-char beg) + (unless checkdir ; make sure the directory exists + (setq checkdir t) + (or (file-directory-p todir) (make-directory todir))) + + (unless executables-checked + (org-check-external-command + "latex" "needed to convert LaTeX fragments to images") + (org-check-external-command + "dvipng" "needed to convert LaTeX fragments to images") + (setq executables-checked t)) + + (unless (file-exists-p movefile) + (org-create-formula-image + txt movefile opt forbuffer)) + (if overlays + (progn + (mapc (lambda (o) + (if (eq (overlay-get o 'org-overlay-type) + 'org-latex-overlay) + (delete-overlay o))) + (overlays-in beg end)) + (setq ov (make-overlay beg end)) + (overlay-put ov 'org-overlay-type 'org-latex-overlay) + (if (featurep 'xemacs) + (progn + (overlay-put ov 'invisible t) + (overlay-put + ov 'end-glyph + (make-glyph (vector 'png :file movefile)))) + (overlay-put + ov 'display + (list 'image :type 'png :file movefile :ascent 'center))) + (push ov org-latex-fragment-image-overlays) + (goto-char end)) + (delete-region beg end) + (insert (org-add-props link + (list 'org-latex-src + (replace-regexp-in-string "\"" "" txt)))))))))))) ;; This function borrows from Ganesh Swami's latex2png.el (defun org-create-formula-image (string tofile options buffer) @@ -15280,7 +15933,7 @@ Some of the options can be changed using the variable (insert (org-splice-latex-header org-format-latex-header org-export-latex-default-packages-alist - org-export-latex-packages-alist + org-export-latex-packages-alist t org-format-latex-header-extra)) (insert "\n\\begin{document}\n" string "\n\\end{document}\n") (require 'org-latex) @@ -15314,13 +15967,13 @@ Some of the options can be changed using the variable (delete-file (concat texfilebase e))) pngfile)))) -(defun org-splice-latex-header (tpl def-pkg pkg &optional extra) +(defun org-splice-latex-header (tpl def-pkg pkg snippets-p &optional extra) "Fill a LaTeX header template TPL. In the template, the following place holders will be recognized: [DEFAULT-PACKAGES] \\usepackage statements for DEF-PKG [NO-DEFAULT-PACKAGES] do not include DEF-PKG - [PACKAGES] \\usepackage statements for PKG + [PACKAGES] \\usepackage statements for PKG [NO-PACKAGES] do not include PKG [EXTRA] the string EXTRA [NO-EXTRA] do not include EXTRA @@ -15329,19 +15982,22 @@ For backward compatibility, if both the positive and the negative place holder is missing, the positive one (without the \"NO-\") will be assumed to be present at the end of the template. DEF-PKG and PKG are assumed to be alists of options/packagename lists. -EXTRA is a string." +EXTRA is a string. +SNIPPETS-P indicates if this is run to create snippet images for HTML." (let (rpl (end "")) (if (string-match "^[ \t]*\\[\\(NO-\\)?DEFAULT-PACKAGES\\][ \t]*\n?" tpl) (setq rpl (if (or (match-end 1) (not def-pkg)) - "" (org-latex-packages-to-string def-pkg t)) + "" (org-latex-packages-to-string def-pkg snippets-p t)) tpl (replace-match rpl t t tpl)) - (if def-pkg (setq end (org-latex-packages-to-string def-pkg)))) - + (if def-pkg (setq end (org-latex-packages-to-string def-pkg snippets-p)))) + (if (string-match "\\[\\(NO-\\)?PACKAGES\\][ \t]*\n?" tpl) (setq rpl (if (or (match-end 1) (not pkg)) - "" (org-latex-packages-to-string pkg t)) + "" (org-latex-packages-to-string pkg snippets-p t)) tpl (replace-match rpl t t tpl)) - (if pkg (setq end (concat end "\n" (org-latex-packages-to-string pkg))))) + (if pkg (setq end + (concat end "\n" + (org-latex-packages-to-string pkg snippets-p))))) (if (string-match "\\[\\(NO-\\)?EXTRA\\][ \t]*\n?" tpl) (setq rpl (if (or (match-end 1) (not extra)) @@ -15354,11 +16010,13 @@ EXTRA is a string." (concat tpl "\n" end) tpl))) -(defun org-latex-packages-to-string (pkg &optional newline) +(defun org-latex-packages-to-string (pkg &optional snippets-p newline) "Turn an alist of packages into a string with the \\usepackage macros." (setq pkg (mapconcat (lambda(p) (cond ((stringp p) p) + ((and snippets-p (>= (length p) 3) (not (nth 2 p))) + (format "%% Package %s omitted" (cadr p))) ((equal "" (car p)) (format "\\usepackage{%s}" (cadr p))) (t @@ -15378,6 +16036,80 @@ EXTRA is a string." "Return string to be used as color value for an RGB component." (format "%g" (/ value 65535.0))) +;; Image display + + +(defvar org-inline-image-overlays nil) +(make-variable-buffer-local 'org-inline-image-overlays) + +(defun org-toggle-inline-images (&optional include-linked) + "Toggle the display of inline images. +INCLUDE-LINKED is passed to `org-display-inline-images'." + (interactive "P") + (if org-inline-image-overlays + (progn + (org-remove-inline-images) + (message "Inline image display turned off")) + (org-display-inline-images include-linked) + (if org-inline-image-overlays + (message "%d images displayed inline" + (length org-inline-image-overlays)) + (message "No images to display inline")))) + +(defun org-display-inline-images (&optional include-linked refresh beg end) + "Display inline images. +Normally only links without a description part are inlined, because this +is how it will work for export. When INCLUDE-LINKED is set, also links +with a description part will be inlined. This can be nice for a quick +look at those images, but it does not reflect what exported files will look +like. +When REFRESH is set, refresh existing images between BEG and END. +This will create new image displays only if necessary. +BEG and END default to the buffer boundaries." + (interactive "P") + (unless refresh + (org-remove-inline-images) + (clear-image-cache)) + (save-excursion + (save-restriction + (widen) + (setq beg (or beg (point-min)) end (or end (point-max))) + (goto-char (point-min)) + (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([-+~.:/\\_0-9a-zA-Z ]+" + (substring (org-image-file-name-regexp) 0 -2) + "\\)\\]" (if include-linked "" "\\]"))) + old file ov img) + (while (re-search-forward re end t) + (setq old (get-char-property-and-overlay (match-beginning 1) + 'org-image-overlay)) + (setq file (expand-file-name + (concat (or (match-string 3) "") (match-string 4)))) + (when (file-exists-p file) + (if (and (car-safe old) refresh) + (image-refresh (overlay-get (cdr old) 'display)) + (setq img (create-image file)) + (when img + (setq ov (make-overlay (match-beginning 0) (match-end 0))) + (overlay-put ov 'display img) + (overlay-put ov 'face 'default) + (overlay-put ov 'org-image-overlay t) + (overlay-put ov 'modification-hooks + (list 'org-display-inline-modification-hook)) + (push ov org-inline-image-overlays))))))))) + +(defun org-display-inline-modification-hook (ov after beg end &optional len) + "Remove inline-display overlay if a corresponding region is modified." + (let ((inhibit-modification-hooks t)) + (when (and ov after) + (delete ov org-inline-image-overlays) + (delete-overlay ov)))) + +(defun org-remove-inline-images () + "Remove inline display of images." + (interactive) + (mapc 'delete-overlay org-inline-image-overlays) + (setq org-inline-image-overlays nil)) + ;;;; Key bindings ;; Make `C-c C-x' a prefix key @@ -15419,6 +16151,12 @@ EXTRA is a string." (org-defkey org-mode-map [(control shift right)] 'org-shiftcontrolright) (org-defkey org-mode-map [(control shift left)] 'org-shiftcontrolleft) +;; Babel keys +(define-key org-mode-map org-babel-key-prefix org-babel-map) +(mapc (lambda (pair) + (define-key org-babel-map (car pair) (cdr pair))) + org-babel-key-bindings) + ;;; Extra keys for tty access. ;; We only set them when really needed because otherwise the ;; menus don't show the simple keys @@ -15476,7 +16214,6 @@ EXTRA is a string." (org-defkey org-mode-map "\C-c\C-s" 'org-schedule) (org-defkey org-mode-map "\C-c\C-d" 'org-deadline) (org-defkey org-mode-map "\C-c;" 'org-toggle-comment) -(org-defkey org-mode-map "\C-c\C-v" 'org-show-todo-tree) (org-defkey org-mode-map "\C-c\C-w" 'org-refile) (org-defkey org-mode-map "\C-c/" 'org-sparse-tree) ; Minor-mode reserved (org-defkey org-mode-map "\C-c\\" 'org-match-sparse-tree) ; Minor-mode res. @@ -15547,6 +16284,8 @@ EXTRA is a string." (org-defkey org-mode-map "\C-c\C-x\C-r" 'org-clock-report) (org-defkey org-mode-map "\C-c\C-x\C-u" 'org-dblock-update) (org-defkey org-mode-map "\C-c\C-x\C-l" 'org-preview-latex-fragment) +(org-defkey org-mode-map "\C-c\C-x\C-v" 'org-toggle-inline-images) +(org-defkey org-mode-map "\C-c\C-x\\" 'org-toggle-pretty-entities) (org-defkey org-mode-map "\C-c\C-x\C-b" 'org-toggle-checkbox) (org-defkey org-mode-map "\C-c\C-xp" 'org-set-property) (org-defkey org-mode-map "\C-c\C-xe" 'org-set-effort) @@ -15639,7 +16378,7 @@ EXTRA is a string." "Show the available speed commands." (interactive) (if (not org-use-speed-commands) - (error "Speed commands are not activated, customize `org-use-speed-commands'.") + (error "Speed commands are not activated, customize `org-use-speed-commands'") (with-output-to-temp-buffer "*Help*" (princ "User-defined Speed commands\n===========================\n") (mapc 'org-print-speed-command org-speed-commands-user) @@ -15832,8 +16571,9 @@ See `org-ctrl-c-ctrl-c-hook' for more information. This hook runs as the first action when TAB is pressed, even before `org-cycle' messes around with the `outline-regexp' to cater for inline tasks and plain list item folding. -If any function in this hook returns t, not other actions like table -field motion visibility cycling will be done.") +If any function in this hook returns t, any other actions that +would have been caused by TAB (such as table field motion or visibility +cycling) will not occur.") (defvar org-tab-after-check-for-table-hook nil "Hook for functions to attach themselves to TAB. @@ -15884,6 +16624,34 @@ See `org-ctrl-c-ctrl-c-hook' for more information.") (defvar org-metareturn-hook nil "Hook for functions attaching themselves to `M-RET'. See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftup-hook nil + "Hook for functions attaching themselves to `S-up'. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftup-final-hook nil + "Hook for functions attaching themselves to `S-up'. +This one runs after all other options except shift-select have been excluded. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftdown-hook nil + "Hook for functions attaching themselves to `S-down'. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftdown-final-hook nil + "Hook for functions attaching themselves to `S-down'. +This one runs after all other options except shift-select have been excluded. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftleft-hook nil + "Hook for functions attaching themselves to `S-left'. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftleft-final-hook nil + "Hook for functions attaching themselves to `S-left'. +This one runs after all other options except shift-select have been excluded. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftright-hook nil + "Hook for functions attaching themselves to `S-right'. +See `org-ctrl-c-ctrl-c-hook' for more information.") +(defvar org-shiftright-final-hook nil + "Hook for functions attaching themselves to `S-right'. +This one runs after all other options except shift-select have been excluded. +See `org-ctrl-c-ctrl-c-hook' for more information.") (defun org-modifier-cursor-error () "Throw an error, a modified cursor command was applied in wrong context." @@ -15924,7 +16692,7 @@ See the individual commands for more information." ((run-hook-with-args-until-success 'org-shiftmetaleft-hook)) ((org-at-table-p) (call-interactively 'org-table-delete-column)) ((org-on-heading-p) (call-interactively 'org-promote-subtree)) - ((org-at-item-p) (call-interactively 'org-outdent-item)) + ((org-at-item-p) (call-interactively 'org-outdent-item-tree)) (t (org-modifier-cursor-error)))) (defun org-shiftmetaright () @@ -15937,7 +16705,7 @@ See the individual commands for more information." ((run-hook-with-args-until-success 'org-shiftmetaright-hook)) ((org-at-table-p) (call-interactively 'org-table-insert-column)) ((org-on-heading-p) (call-interactively 'org-demote-subtree)) - ((org-at-item-p) (call-interactively 'org-indent-item)) + ((org-at-item-p) (call-interactively 'org-indent-item-tree)) (t (org-modifier-cursor-error)))) (defun org-shiftmetaup (&optional arg) @@ -15966,6 +16734,10 @@ commands for more information." ((org-at-item-p) (call-interactively 'org-move-item-down)) (t (org-modifier-cursor-error)))) +(defsubst org-hidden-tree-error () + (error + "Hidden subtree, open with TAB or use subtree command M-S-<left>/<right>")) + (defun org-metaleft (&optional arg) "Promote heading or move table column to left. Calls `org-do-promote' or `org-table-move-column', depending on context. @@ -15980,12 +16752,14 @@ See the individual commands for more information." (save-excursion (goto-char (region-beginning)) (org-on-heading-p)))) + (when (org-check-for-hidden 'headlines) (org-hidden-tree-error)) (call-interactively 'org-do-promote)) ((or (org-at-item-p) (and (org-region-active-p) (save-excursion (goto-char (region-beginning)) (org-at-item-p)))) + (when (org-check-for-hidden 'items) (org-hidden-tree-error)) (call-interactively 'org-outdent-item)) (t (call-interactively 'backward-word)))) @@ -16003,15 +16777,44 @@ See the individual commands for more information." (save-excursion (goto-char (region-beginning)) (org-on-heading-p)))) + (when (org-check-for-hidden 'headlines) (org-hidden-tree-error)) (call-interactively 'org-do-demote)) ((or (org-at-item-p) (and (org-region-active-p) (save-excursion (goto-char (region-beginning)) (org-at-item-p)))) + (when (org-check-for-hidden 'items) (org-hidden-tree-error)) (call-interactively 'org-indent-item)) (t (call-interactively 'forward-word)))) +(defun org-check-for-hidden (what) + "Check if there are hidden headlines/items in the current visual line. +WHAT can be either `headlines' or `items'. If the current line is +an outline or item heading and it has a folded subtree below it, +this function returns t, nil otherwise." + (let ((re (cond + ((eq what 'headlines) (concat "^" org-outline-regexp)) + ((eq what 'items) (concat "^" (org-item-re t))) + (t (error "This should not happen")))) + beg end) + (save-excursion + (catch 'exit + (unless (org-region-active-p) + (setq beg (point-at-bol)) + (beginning-of-line 2) + (while (and (not (eobp)) ;; this is like `next-line' + (get-char-property (1- (point)) 'invisible)) + (beginning-of-line 2)) + (setq end (point)) + (goto-char beg) + (goto-char (point-at-eol)) + (setq end (max end (point))) + (while (re-search-forward re end t) + (if (get-char-property (match-beginning 0) 'invisible) + (throw 'exit t)))) + nil)))) + (defun org-metaup (&optional arg) "Move subtree up or move table row up. Calls `org-move-subtree-up' or `org-table-move-row' or @@ -16044,6 +16847,7 @@ Calls `org-timestamp-up' or `org-priority-up', or `org-previous-item', depending on context. See the individual commands for more information." (interactive "P") (cond + ((run-hook-with-args-until-success 'org-shiftup-hook)) ((and org-support-shift-select (org-region-active-p)) (org-call-for-shift-select 'previous-line)) ((org-at-timestamp-p t) @@ -16056,6 +16860,7 @@ depending on context. See the individual commands for more information." ((and (not org-support-shift-select) (org-at-item-p)) (call-interactively 'org-previous-item)) ((org-clocktable-try-shift 'up arg)) + ((run-hook-with-args-until-success 'org-shiftup-final-hook)) (org-support-shift-select (org-call-for-shift-select 'previous-line)) (t (org-shiftselect-error)))) @@ -16066,6 +16871,7 @@ Calls `org-timestamp-down' or `org-priority-down', or `org-next-item' depending on context. See the individual commands for more information." (interactive "P") (cond + ((run-hook-with-args-until-success 'org-shiftdown-hook)) ((and org-support-shift-select (org-region-active-p)) (org-call-for-shift-select 'next-line)) ((org-at-timestamp-p t) @@ -16078,6 +16884,7 @@ depending on context. See the individual commands for more information." ((and (not org-support-shift-select) (org-at-item-p)) (call-interactively 'org-next-item)) ((org-clocktable-try-shift 'down arg)) + ((run-hook-with-args-until-success 'org-shiftdown-final-hook)) (org-support-shift-select (org-call-for-shift-select 'next-line)) (t (org-shiftselect-error)))) @@ -16093,6 +16900,7 @@ Depending on context, this does one of the following: - on a clocktable definition line, move time block into the future" (interactive "P") (cond + ((run-hook-with-args-until-success 'org-shiftright-hook)) ((and org-support-shift-select (org-region-active-p)) (org-call-for-shift-select 'forward-char)) ((org-at-timestamp-p t) (call-interactively 'org-timestamp-up-day)) @@ -16112,6 +16920,7 @@ Depending on context, this does one of the following: (org-at-property-p)) (call-interactively 'org-property-next-allowed-value)) ((org-clocktable-try-shift 'right arg)) + ((run-hook-with-args-until-success 'org-shiftright-final-hook)) (org-support-shift-select (org-call-for-shift-select 'forward-char)) (t (org-shiftselect-error)))) @@ -16127,6 +16936,7 @@ Depending on context, this does one of the following: - on a clocktable definition line, move time block into the past" (interactive "P") (cond + ((run-hook-with-args-until-success 'org-shiftleft-hook)) ((and org-support-shift-select (org-region-active-p)) (org-call-for-shift-select 'backward-char)) ((org-at-timestamp-p t) (call-interactively 'org-timestamp-down-day)) @@ -16146,6 +16956,7 @@ Depending on context, this does one of the following: (org-at-property-p)) (call-interactively 'org-property-previous-allowed-value)) ((org-clocktable-try-shift 'left arg)) + ((run-hook-with-args-until-success 'org-shiftleft-final-hook)) (org-support-shift-select (org-call-for-shift-select 'backward-char)) (t (org-shiftselect-error)))) @@ -16208,24 +17019,33 @@ See the individual commands for more information." (org-table-paste-rectangle) (org-paste-subtree arg))) -(defun org-edit-special () +(defun org-edit-special (&optional arg) "Call a special editor for the stuff at point. When at a table, call the formula editor with `org-table-edit-formulas'. When at the first line of an src example, call `org-edit-src-code'. When in an #+include line, visit the include file. Otherwise call `ffap' to visit the file at point." (interactive) - (cond - ((org-at-table.el-p) - (org-edit-src-code)) - ((org-at-table-p) - (call-interactively 'org-table-edit-formulas)) + ;; possibly prep session before editing source + (when arg + (let* ((info (org-babel-get-src-block-info)) + (lang (nth 0 info)) + (params (nth 2 info)) + (session (cdr (assoc :session params)))) + (when (and info session) ;; we are in a source-code block with a session + (funcall + (intern (concat "org-babel-prep-session:" lang)) session params)))) + (cond ;; proceed with `org-edit-special' ((save-excursion (beginning-of-line 1) (looking-at "\\(?:#\\+\\(?:setupfile\\|include\\):?[ \t]+\"?\\|[ \t]*<include\\>.*?file=\"\\)\\([^\"\n>]+\\)")) (find-file (org-trim (match-string 1)))) ((org-edit-src-code)) ((org-edit-fixed-width-region)) + ((org-at-table.el-p) + (org-edit-src-code)) + ((org-at-table-p) + (call-interactively 'org-table-edit-formulas)) (t (call-interactively 'ffap)))) @@ -16269,7 +17089,13 @@ This command does many different things, depending on context: - If the cursor is on a numbered item in a plain list, renumber the ordered list. -- If the cursor is on a checkbox, toggle it." +- If the cursor is on a checkbox, toggle it. + +- If the cursor is on a code block, evaluate it. The variable + `org-confirm-babel-evaluate' can be used to control prompting + before code block evaluation, by default every code block + evaluation requires confirmation. Code block evaluation can be + inhibited by setting `org-babel-no-eval-on-ctrl-c-ctrl-c'." (interactive "P") (let ((org-enable-table-editor t)) (cond @@ -16304,11 +17130,13 @@ This command does many different things, depending on context: (org-footnote-at-definition-p)) (call-interactively 'org-footnote-action)) ((org-at-item-checkbox-p) - (call-interactively 'org-toggle-checkbox)) + (call-interactively 'org-toggle-checkbox) + (org-list-send-list 'maybe)) ((org-at-item-p) (if arg (call-interactively 'org-toggle-checkbox) - (call-interactively 'org-maybe-renumber-ordered-list))) + (call-interactively 'org-maybe-renumber-ordered-list)) + (org-list-send-list 'maybe)) ((save-excursion (beginning-of-line 1) (looking-at org-dblock-start-re)) ;; Dynamic block (beginning-of-line 1) @@ -16343,7 +17171,9 @@ Also updates the keyword regular expressions." "If this is a Note buffer, abort storing the note. Else call `show-branches'." (interactive) (if (not org-finish-function) - (call-interactively 'show-branches) + (progn + (hide-subtree) + (call-interactively 'show-branches)) (let ((org-note-abort t)) (funcall org-finish-function)))) @@ -16638,7 +17468,7 @@ See the individual commands for more information." ["Previous link" org-previous-link t] "--" ["Descriptive Links" - (progn (org-add-to-invisibility-spec '(org-link)) (org-restart-font-lock)) + (progn (add-to-invisibility-spec '(org-link)) (org-restart-font-lock)) :style radio :selected (member '(org-link) buffer-invisibility-spec)] ["Literal Links" @@ -16655,8 +17485,8 @@ See the individual commands for more information." ["Complete Keyword" org-complete (assq :todo-keyword (org-context))] ["Next keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-on-heading-p))] ["Previous keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-on-heading-p))]) - ["Show TODO Tree" org-show-todo-tree t] - ["Global TODO list" org-todo-list t] + ["Show TODO Tree" org-show-todo-tree :active t :keys "C-c / t"] + ["Global TODO list" org-todo-list :active t :keys "C-c a t"] "--" ["Enforce dependencies" (customize-variable 'org-enforce-todo-dependencies) :selected org-enforce-todo-dependencies :style toggle :active t] @@ -16752,7 +17582,7 @@ See the individual commands for more information." :style toggle :selected (and (boundp 'org-export-with-LaTeX-fragments) org-export-with-LaTeX-fragments)] "--" - ["Template for BEAMER" org-beamer-settings-template t]) + ["Template for BEAMER" org-insert-beamer-options-template t]) "--" ("MobileOrg" ["Push Files and Views" org-mobile-push t] @@ -16885,8 +17715,18 @@ With prefix arg UNCOMPILED, load the uncompiled versions." (dir-org-contrib (ignore-errors (file-name-directory (org-find-library-name "org-contribdir")))) + (babel-files + (mapcar (lambda (el) (concat "ob" (when el (format "-%s" el)) ".el")) + (append (list nil "comint" "eval" "exp" "keys" + "lob" "ref" "table" "tangle") + (delq nil + (mapcar + (lambda (lang) + (when (cdr lang) (symbol-name (car lang)))) + org-babel-load-languages))))) (files (append (directory-files dir-org t file-re) + babel-files (and dir-org-contrib (directory-files dir-org-contrib t file-re)))) (remove-re (concat (if (featurep 'xemacs) @@ -16953,9 +17793,7 @@ With prefix arg UNCOMPILED, load the uncompiled versions." "Display the given MESSAGE as a warning." (if (fboundp 'display-warning) (display-warning 'org message - (if (featurep 'xemacs) - 'warning - :warning)) + (if (featurep 'xemacs) 'warning :warning)) (let ((buf (get-buffer-create "*Org warnings*"))) (with-current-buffer buf (goto-char (point-max)) @@ -16969,6 +17807,13 @@ With prefix arg UNCOMPILED, load the uncompiled versions." "Is point in a line starting with `#'?" (equal (char-after (point-at-bol)) ?#)) +(defun org-in-indented-comment-line () + "Is point in a line starting with `#' after some white space?" + (save-excursion + (save-match-data + (goto-char (point-at-bol)) + (looking-at "[ \t]*#")))) + (defun org-in-verbatim-emphasis () (save-match-data (and (org-in-regexp org-emph-re 2) (member (match-string 3) '("=" "~"))))) @@ -17276,11 +18121,11 @@ and :keyword." (mapcar (lambda (x) (if (memq x org-latex-fragment-image-overlays) x)) - (org-overlays-at (point)))))) + (overlays-at (point)))))) (push (list :latex-fragment - (org-overlay-start o) (org-overlay-end o)) clist) + (overlay-start o) (overlay-end o)) clist) (push (list :latex-preview - (org-overlay-start o) (org-overlay-end o)) clist)) + (overlay-start o) (overlay-end o)) clist)) ((org-inside-LaTeX-fragment-p) ;; FIXME: positions wrong. (push (list :latex-fragment (point) (point)) clist))) @@ -17319,7 +18164,7 @@ really on, so that the block visually is on the match." nil)))) (defun org-in-regexps-block-p (start-re end-re) - "Returns t if the current point is between matches of START-RE and END-RE. + "Return t if the current point is between matches of START-RE and END-RE. This will also return to if point is on one of the two matches." (interactive) (let ((p (point))) @@ -17396,6 +18241,33 @@ for the search purpose." (setq list (delete (pop elts) list))) list) +(defun org-count (cl-item cl-seq) + "Count the number of occurrences of ITEM in SEQ. +Taken from `count' in cl-seq.el with all keyword arguments removed." + (let ((cl-end (length cl-seq)) (cl-start 0) (cl-count 0) cl-x) + (when (consp cl-seq) (setq cl-seq (nthcdr cl-start cl-seq))) + (while (< cl-start cl-end) + (setq cl-x (if (consp cl-seq) (pop cl-seq) (aref cl-seq cl-start))) + (if (equal cl-item cl-x) (setq cl-count (1+ cl-count))) + (setq cl-start (1+ cl-start))) + cl-count)) + +(defun org-remove-if (predicate seq) + "Remove everything from SEQ that fulfills PREDICATE." + (let (res e) + (while seq + (setq e (pop seq)) + (if (not (funcall predicate e)) (push e res))) + (nreverse res))) + +(defun org-remove-if-not (predicate seq) + "Remove everything from SEQ that does not fulfill PREDICATE." + (let (res e) + (while seq + (setq e (pop seq)) + (if (funcall predicate e) (push e res))) + (nreverse res))) + (defun org-back-over-empty-lines () "Move backwards over whitespace, to the beginning of the first empty line. Returns the number of empty lines passed." @@ -17411,7 +18283,7 @@ Returns the number of empty lines passed." (defun org-point-in-group (point group &optional context) "Check if POINT is in match-group GROUP. If CONTEXT is non-nil, return a list with CONTEXT and the boundaries of the -match. If the match group does ot exist or point is not inside it, +match. If the match group does not exist or point is not inside it, return nil." (and (match-beginning group) (>= point (match-beginning group)) @@ -17422,7 +18294,8 @@ return nil." (defun org-switch-to-buffer-other-window (&rest args) "Switch to buffer in a second window on the current frame. -In particular, do not allow pop-up frames." +In particular, do not allow pop-up frames. +Returns the newly created buffer." (let (pop-up-frames special-display-buffer-names special-display-regexps special-display-function) (apply 'switch-to-buffer-other-window args))) @@ -17473,17 +18346,27 @@ TABLE is an association list with keys like \"%a\" and string values. The sequences in STRING may contain normal field width and padding information, for example \"%-5s\". Replacements happen in the sequence given by TABLE, so values can contain further %-escapes if they are define later in TABLE." - (let ((case-fold-search nil) - e re rpl) - (while (setq e (pop table)) + (let ((tbl (copy-alist table)) + (case-fold-search nil) + (pchg 0) + e re rpl) + (while (setq e (pop tbl)) (setq re (concat "%-?[0-9.]*" (substring (car e) 1))) + (when (and (cdr e) (string-match re (cdr e))) + (let ((sref (substring (cdr e) (match-beginning 0) (match-end 0))) + (safe "SREF")) + (add-text-properties 0 3 (list 'sref sref) safe) + (setcdr e (replace-match safe t t (cdr e))))) (while (string-match re string) - (setq rpl (format (concat (substring (match-string 0 string) 0 -1) "s") - (cdr e))) - (setq string (replace-match rpl t t string)))) + (setq rpl (format (concat (substring (match-string 0 string) 0 -1) "s") + (cdr e))) + (setq string (replace-match rpl t t string)))) + (while (setq pchg (next-property-change pchg string)) + (let ((sref (get-text-property pchg 'sref string))) + (when (and sref (string-match "SREF" string pchg)) + (setq string (replace-match sref t t string))))) string)) - (defun org-sublist (list start end) "Return a section of LIST, from START to END. Counting starts at 1." @@ -17678,7 +18561,7 @@ the functionality can be provided as a fall-back.") (org-set-local 'fill-paragraph-function 'org-fill-paragraph) ;; Adaptive filling: To get full control, first make sure that ;; `adaptive-fill-regexp' never matches. Then install our own matcher. - (unless (local-variable-p 'adaptive-fill-regexp) + (unless (local-variable-p 'adaptive-fill-regexp (current-buffer)) (org-set-local 'org-adaptive-fill-regexp-backup adaptive-fill-regexp)) (org-set-local 'adaptive-fill-regexp "\000") @@ -17829,8 +18712,8 @@ beyond the end of the headline." (if (bobp) nil (backward-char 1) - (if (org-invisible-p) - (while (and (not (bobp)) (org-invisible-p)) + (if (org-truely-invisible-p) + (while (and (not (bobp)) (org-truely-invisible-p)) (backward-char 1) (beginning-of-line 1)) (forward-char 1)))) @@ -17926,6 +18809,11 @@ depending on context." ((or (not org-special-ctrl-k) (bolp) (not (org-on-heading-p))) + (if (and (get-char-property (min (point-max) (point-at-eol)) 'invisible) + org-ctrl-k-protect-subtree) + (if (or (eq org-ctrl-k-protect-subtree 'error) + (not (y-or-n-p "Kill hidden subtree along with headline? "))) + (error "C-k aborted - would kill hidden subtree"))) (call-interactively 'kill-line)) ((looking-at (org-re ".*?\\S-\\([ \t]+\\(:[[:alnum:]_@:]+:\\)\\)[ \t]*$")) (kill-region (point) (match-beginning 1)) @@ -17953,7 +18841,8 @@ org-yank-adjusted-subtrees *visible* surrounding headings. Any prefix to this command will cause `yank' to be called directly with -no special treatment. In particular, a simple `C-u' prefix will just +no special treatment. In particular, a simple \\[universal-argument] prefix \ +will just plainly yank the text as it is. \[1] The test checks if the first non-white line is a heading @@ -18043,6 +18932,17 @@ interactive command with similar behavior." (outline-invisible-p) (get-char-property (point) 'invisible))) +(defun org-truely-invisible-p () + "Check if point is at a character currently not visible. +This version does not only check the character property, but also +`visible-mode'." + ;; Early versions of noutline don't have `outline-invisible-p'. + (if (org-bound-and-true-p visible-mode) + nil + (if (fboundp 'outline-invisible-p) + (outline-invisible-p) + (get-char-property (point) 'invisible)))) + (defun org-invisible-p2 () "Check if point is at a character currently not visible." (save-excursion @@ -18059,6 +18959,13 @@ interactive command with similar behavior." (error (error "Before first headline at position %d in buffer %s" (point) (current-buffer))))) +(defun org-beginning-of-defun () + "Go to the beginning of the subtree, i.e. back to the heading." + (org-back-to-heading)) +(defun org-end-of-defun () + "Go to the end of the subtree." + (org-end-of-subtree nil t)) + (defun org-before-first-heading-p () "Before first heading?" (save-excursion @@ -18403,11 +19310,11 @@ if no description is present" ;; Speedbar support -(defvar org-speedbar-restriction-lock-overlay (org-make-overlay 1 1) +(defvar org-speedbar-restriction-lock-overlay (make-overlay 1 1) "Overlay marking the agenda restriction line in speedbar.") -(org-overlay-put org-speedbar-restriction-lock-overlay +(overlay-put org-speedbar-restriction-lock-overlay 'face 'org-agenda-restriction-lock) -(org-overlay-put org-speedbar-restriction-lock-overlay +(overlay-put org-speedbar-restriction-lock-overlay 'help-echo "Agendas are currently limited to this item.") (org-detach-overlay org-speedbar-restriction-lock-overlay) @@ -18440,8 +19347,8 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]." (error "Cannot restrict to non-Org-mode file")) (org-agenda-set-restriction-lock 'file))) (t (error "Don't know how to restrict Org-mode's agenda"))) - (org-move-overlay org-speedbar-restriction-lock-overlay - (point-at-bol) (point-at-eol)) + (move-overlay org-speedbar-restriction-lock-overlay + (point-at-bol) (point-at-eol)) (setq current-prefix-arg nil) (org-agenda-maybe-redo))) @@ -18455,7 +19362,6 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]." (add-hook 'speedbar-visiting-tag-hook (lambda () (and (org-mode-p) (org-show-context 'org-goto)))))) - ;;; Fixes and Hacks for problems with other packages ;; Make flyspell not check words in links, to not mess up our keymap |