summaryrefslogtreecommitdiff
path: root/lisp/org/org-compat.el
diff options
context:
space:
mode:
authorBastien <bzg@gnu.org>2019-12-03 23:27:04 +0100
committerBastien <bzg@gnu.org>2019-12-03 23:27:04 +0100
commit165f7383822086d465519ebe6e4283723923f097 (patch)
tree820be9480e3d571d766483f564c963037192f6ec /lisp/org/org-compat.el
parent821de968434d2096bdea67dd24301bf6b517aef1 (diff)
downloademacs-165f7383822086d465519ebe6e4283723923f097.tar.gz
emacs-165f7383822086d465519ebe6e4283723923f097.tar.bz2
emacs-165f7383822086d465519ebe6e4283723923f097.zip
Update Org to 9.3
Diffstat (limited to 'lisp/org/org-compat.el')
-rw-r--r--lisp/org/org-compat.el731
1 files changed, 631 insertions, 100 deletions
diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
index bb927fedf93..4446a169d7a 100644
--- a/lisp/org/org-compat.el
+++ b/lisp/org/org-compat.el
@@ -25,34 +25,114 @@
;;; Commentary:
;; This file contains code needed for compatibility with older
-;; versions of GNU Emacs.
+;; versions of GNU Emacs and integration with other packages.
;;; Code:
(require 'cl-lib)
(require 'org-macs)
+(declare-function org-agenda-diary-entry "org-agenda")
+(declare-function org-agenda-maybe-redo "org-agenda" ())
+(declare-function org-agenda-remove-restriction-lock "org-agenda" (&optional noupdate))
+(declare-function org-align-tags "org" (&optional all))
+(declare-function org-at-heading-p "org" (&optional ignored))
(declare-function org-at-table.el-p "org" ())
(declare-function org-element-at-point "org-element" ())
+(declare-function org-element-context "org-element" (&optional element))
+(declare-function org-element-lineage "org-element" (blob &optional types with-self))
(declare-function org-element-type "org-element" (element))
+(declare-function org-element-property "org-element" (property element))
(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading))
-(declare-function org-link-set-parameters "org" (type &rest rest))
+(declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment))
+(declare-function org-get-tags "org" (&optional pos local))
+(declare-function org-link-display-format "ol" (s))
+(declare-function org-link-set-parameters "ol" (type &rest rest))
+(declare-function org-log-into-drawer "org" ())
+(declare-function org-make-tag-string "org" (tags))
+(declare-function org-reduced-level "org" (l))
+(declare-function org-show-context "org" (&optional key))
(declare-function org-table-end "org-table" (&optional table-type))
(declare-function outline-next-heading "outline" ())
+(declare-function speedbar-line-directory "speedbar" (&optional depth))
(declare-function table--at-cell-p "table" (position &optional object at-column))
+(defvar calendar-mode-map)
+(defvar org-complex-heading-regexp)
+(defvar org-agenda-diary-file)
+(defvar org-agenda-overriding-restriction)
+(defvar org-agenda-restriction-lock-overlay)
(defvar org-table-any-border-regexp)
(defvar org-table-dataline-regexp)
(defvar org-table-tab-recognizes-table.el)
(defvar org-table1-hline-regexp)
+
+;;; Emacs < 27.1 compatibility
+
+(unless (fboundp 'proper-list-p)
+ ;; `proper-list-p' was added in Emacs 27.1. The function below is
+ ;; taken from Emacs subr.el 200195e824b^.
+ (defun proper-list-p (object)
+ "Return OBJECT's length if it is a proper list, nil otherwise.
+A proper list is neither circular nor dotted (i.e., its last cdr
+is nil)."
+ (and (listp object) (ignore-errors (length object)))))
+
+(if (fboundp 'xor)
+ ;; `xor' was added in Emacs 27.1.
+ (defalias 'org-xor #'xor)
+ (defsubst org-xor (a b)
+ "Exclusive `or'."
+ (if a (not b) b)))
+
+(unless (fboundp 'pcomplete-uniquify-list)
+ ;; The misspelled variant was made obsolete in Emacs 27.1
+ (defalias 'pcomplete-uniquify-list 'pcomplete-uniqify-list))
+
+(if (fboundp 'time-convert)
+ (progn
+ (defsubst org-time-convert-to-integer (time)
+ (time-convert time 'integer))
+ (defsubst org-time-convert-to-list (time)
+ (time-convert time 'list)))
+ (defun org-time-convert-to-integer (time)
+ (floor (float-time time)))
+ (defun org-time-convert-to-list (time)
+ (seconds-to-time (float-time time))))
+
+
+;;; Emacs < 26.1 compatibility
+
+(if (fboundp 'line-number-display-width)
+ (defalias 'org-line-number-display-width 'line-number-display-width)
+ (defun org-line-number-display-width (&rest _) 0))
+
+(if (fboundp 'buffer-hash)
+ (defalias 'org-buffer-hash 'buffer-hash)
+ (defun org-buffer-hash () (md5 (current-buffer))))
+
+(unless (fboundp 'file-attribute-modification-time)
+ (defsubst file-attribute-modification-time (attributes)
+ "The modification time in ATTRIBUTES returned by `file-attributes'.
+This is the time of the last change to the file's contents, and
+is a list of integers (HIGH LOW USEC PSEC) in the same style
+as (current-time)."
+ (nth 5 attributes)))
+
+(unless (fboundp 'file-attribute-size)
+ (defsubst file-attribute-size (attributes)
+ "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
+This is a floating point number if the size is too large for an integer."
+ (nth 7 attributes)))
+
+
;;; Emacs < 25.1 compatibility
(when (< emacs-major-version 25)
(defalias 'outline-hide-entry 'hide-entry)
(defalias 'outline-hide-sublevels 'hide-sublevels)
(defalias 'outline-hide-subtree 'hide-subtree)
- (defalias 'outline-show-all 'show-all)
(defalias 'outline-show-branches 'show-branches)
(defalias 'outline-show-children 'show-children)
(defalias 'outline-show-entry 'show-entry)
@@ -72,11 +152,49 @@
(and (memq system-type '(windows-nt ms-dos))
(= lastc ?\\))))))
+;; `string-collate-lessp' is new in Emacs 25.
+(if (fboundp 'string-collate-lessp)
+ (defalias 'org-string-collate-lessp
+ 'string-collate-lessp)
+ (defun org-string-collate-lessp (s1 s2 &rest _)
+ "Return non-nil if STRING1 is less than STRING2 in lexicographic order.
+Case is significant."
+ (string< s1 s2)))
+
+;; The time- functions below translate nil to `current-time` and
+;; accept an integer as of Emacs 25. `decode-time` and
+;; `format-time-string` accept nil on Emacs 24 but don't accept an
+;; integer until Emacs 25.
+(if (< emacs-major-version 25)
+ (let ((convert
+ (lambda (time)
+ (cond ((not time) (current-time))
+ ((numberp time) (seconds-to-time time))
+ (t time)))))
+ (defun org-decode-time (&optional time)
+ (decode-time (funcall convert time)))
+ (defun org-format-time-string (format-string &optional time universal)
+ (format-time-string format-string (funcall convert time) universal))
+ (defun org-time-add (a b)
+ (time-add (funcall convert a) (funcall convert b)))
+ (defun org-time-subtract (a b)
+ (time-subtract (funcall convert a) (funcall convert b)))
+ (defun org-time-since (time)
+ (time-since (funcall convert time)))
+ (defun org-time-less-p (t1 t2)
+ (time-less-p (funcall convert t1) (funcall convert t2))))
+ (defalias 'org-decode-time 'decode-time)
+ (defalias 'org-format-time-string 'format-time-string)
+ (defalias 'org-time-add 'time-add)
+ (defalias 'org-time-subtract 'time-subtract)
+ (defalias 'org-time-since 'time-since)
+ (defalias 'org-time-less-p 'time-less-p))
+
;;; Obsolete aliases (remove them after the next major release).
;;;; XEmacs compatibility, now removed.
-(define-obsolete-function-alias 'org-activate-mark 'activate-mark)
+(define-obsolete-function-alias 'org-activate-mark 'activate-mark "Org 9.0")
(define-obsolete-function-alias 'org-add-hook 'add-hook "Org 9.0")
(define-obsolete-function-alias 'org-bound-and-true-p 'bound-and-true-p "Org 9.0")
(define-obsolete-function-alias 'org-decompose-region 'decompose-region "Org 9.0")
@@ -91,6 +209,7 @@
(define-obsolete-function-alias 'org-match-string-no-properties 'match-string-no-properties "Org 9.0")
(define-obsolete-function-alias 'org-propertize 'propertize "Org 9.0")
(define-obsolete-function-alias 'org-select-frame-set-input-focus 'select-frame-set-input-focus "Org 9.0")
+(define-obsolete-function-alias 'org-file-remote-p 'file-remote-p "Org 9.2")
(defmacro org-re (s)
"Replace posix classes in regular expression S."
@@ -177,6 +296,24 @@ Counting starts at 1."
'org-activate-links "Org 9.0")
(define-obsolete-function-alias 'org-activate-plain-links 'ignore "Org 9.0")
(define-obsolete-function-alias 'org-activate-angle-links 'ignore "Org 9.0")
+(define-obsolete-function-alias 'org-remove-double-quotes 'org-strip-quotes "Org 9.0")
+(define-obsolete-function-alias 'org-get-indentation
+ 'current-indentation "Org 9.2")
+(define-obsolete-function-alias 'org-capture-member 'org-capture-get "Org 9.2")
+(define-obsolete-function-alias 'org-remove-from-invisibility-spec
+ 'remove-from-invisibility-spec "Org 9.2")
+
+(define-obsolete-variable-alias 'org-effort-durations 'org-duration-units
+ "Org 9.2")
+
+(define-obsolete-function-alias 'org-toggle-latex-fragment 'org-latex-preview
+ "Org 9.3")
+
+(define-obsolete-function-alias 'org-remove-latex-fragment-image-overlays
+ 'org-clear-latex-preview "Org 9.3")
+
+(define-obsolete-variable-alias 'org-attach-directory
+ 'org-attach-id-dir "Org 9.3")
(defun org-in-fixed-width-region-p ()
"Non-nil if point in a fixed-width region."
@@ -228,9 +365,10 @@ See `org-link-parameters' for documentation on the other parameters."
(make-obsolete 'org-add-link-type "use `org-link-set-parameters' instead." "Org 9.0")
+;;;; Functions unused in Org core.
(defun org-table-recognize-table.el ()
"If there is a table.el table nearby, recognize it and move into it."
- (when (and org-table-tab-recognizes-table.el (org-at-table.el-p))
+ (when (org-at-table.el-p)
(beginning-of-line)
(unless (or (looking-at org-table-dataline-regexp)
(not (looking-at org-table1-hline-regexp)))
@@ -246,19 +384,33 @@ See `org-link-parameters' for documentation on the other parameters."
(message "recognizing table.el table...done")))
(error "This should not happen"))))
-;; Not used by Org core since commit 6d1e3082, Feb 2010.
+;; Not used since commit 6d1e3082, Feb 2010.
(make-obsolete 'org-table-recognize-table.el
- "please notify the org mailing list if you use this function."
+ "please notify Org mailing list if you use this function."
"Org 9.0")
+(defmacro org-preserve-lc (&rest body)
+ (declare (debug (body))
+ (obsolete "please notify Org mailing list if you use this function."
+ "Org 9.2"))
+ (org-with-gensyms (line col)
+ `(let ((,line (org-current-line))
+ (,col (current-column)))
+ (unwind-protect
+ (progn ,@body)
+ (org-goto-line ,line)
+ (org-move-to-column ,col)))))
+
+(defun org-version-check (version &rest _)
+ "Non-nil if VERSION is lower (older) than `emacs-version'."
+ (declare (obsolete "use `version<' or `fboundp' instead."
+ "Org 9.2"))
+ (version< version emacs-version))
+
(defun org-remove-angle-brackets (s)
(org-unbracket-string "<" ">" s))
(make-obsolete 'org-remove-angle-brackets 'org-unbracket-string "Org 9.0")
-(defun org-remove-double-quotes (s)
- (org-unbracket-string "\"" "\"" s))
-(make-obsolete 'org-remove-double-quotes 'org-unbracket-string "Org 9.0")
-
(defcustom org-publish-sitemap-file-entry-format "%t"
"Format string for site-map file entry.
You could use brackets to delimit on what part the link will be.
@@ -344,16 +496,137 @@ use of this function is for the stuck project list."
(define-obsolete-variable-alias 'org-texinfo-def-table-markup
'org-texinfo-table-default-markup "Org 9.1")
-;;; The function was made obsolete by commit 65399674d5 of 2013-02-22.
-;;; This make-obsolete call was added 2016-09-01.
+(define-obsolete-variable-alias 'org-agenda-overriding-columns-format
+ 'org-overriding-columns-format "Org 9.2.2")
+
+(define-obsolete-variable-alias 'org-doi-server-url
+ 'org-link-doi-server-url "Org 9.3")
+
+(define-obsolete-variable-alias 'org-email-link-description-format
+ 'org-link-email-description-format "Org 9.3")
+
+(define-obsolete-variable-alias 'org-make-link-description-function
+ 'org-link-make-description-function "Org 9.3")
+
+(define-obsolete-variable-alias 'org-from-is-user-regexp
+ 'org-link-from-user-regexp "Org 9.3")
+
+(define-obsolete-variable-alias 'org-descriptive-links
+ 'org-link-descriptive "Org 9.3")
+
+(define-obsolete-variable-alias 'org-context-in-file-links
+ 'org-link-context-for-files "Org 9.3")
+
+(define-obsolete-variable-alias 'org-keep-stored-link-after-insertion
+ 'org-link-keep-stored-after-insertion "Org 9.3")
+
+(define-obsolete-variable-alias 'org-display-internal-link-with-indirect-buffer
+ 'org-link-use-indirect-buffer-for-internals "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-shell-link-function
+ 'org-link-shell-confirm-function "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-shell-link-not-regexp
+ 'org-link-shell-skip-confirm-regexp "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-elisp-link-function
+ 'org-link-elisp-confirm-function "Org 9.3")
+
+(define-obsolete-variable-alias 'org-confirm-elisp-link-not-regexp
+ 'org-link-elisp-skip-confirm-regexp "Org 9.3")
+
+(define-obsolete-function-alias 'org-file-complete-link
+ 'org-link-complete-file "Org 9.3")
+
+(define-obsolete-function-alias 'org-email-link-description
+ 'org-link-email-description "Org 9.3")
+
+(define-obsolete-function-alias 'org-make-link-string
+ 'org-link-make-string "Org 9.3")
+
+(define-obsolete-function-alias 'org-store-link-props
+ 'org-link-store-props "Org 9.3")
+
+(define-obsolete-function-alias 'org-add-link-props
+ 'org-link-add-props "Org 9.3")
+
+(define-obsolete-function-alias 'org-make-org-heading-search-string
+ 'org-link-heading-search-string "Org 9.3")
+
+(define-obsolete-function-alias 'org-make-link-regexps
+ 'org-link-make-regexps "Org 9.3")
+
+(define-obsolete-variable-alias 'org-angle-link-re
+ 'org-link-angle-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-plain-link-re
+ 'org-link-plain-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-bracket-link-regexp
+ 'org-link-bracket-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-bracket-link-analytic-regexp
+ 'org-link-bracket-re "Org 9.3")
+
+(define-obsolete-variable-alias 'org-any-link-re
+ 'org-link-any-re "Org 9.3")
+
+(define-obsolete-function-alias 'org-open-link-from-string
+ 'org-link-open-from-string "Org 9.3")
+
+(define-obsolete-function-alias 'org-add-angle-brackets
+ 'org-link-add-angle-brackets "Org 9.3")
+
+;; The function was made obsolete by commit 65399674d5 of 2013-02-22.
+;; This make-obsolete call was added 2016-09-01.
(make-obsolete 'org-capture-import-remember-templates
"use the `org-capture-templates' variable instead."
"Org 9.0")
+(defun org-show-block-all ()
+ "Unfold all blocks in the current buffer."
+ (interactive)
+ (remove-overlays nil nil 'invisible 'org-hide-block))
+
+(make-obsolete 'org-show-block-all
+ "use `org-show-all' instead."
+ "Org 9.2")
+
+(define-obsolete-function-alias 'org-get-tags-at 'org-get-tags "Org 9.2")
+
+(defun org-get-local-tags ()
+ "Get a list of tags defined in the current headline."
+ (declare (obsolete "use `org-get-tags' instead." "Org 9.2"))
+ (org-get-tags nil 'local))
+
+(defun org-get-local-tags-at (&optional pos)
+ "Get a list of tags defined in the current headline."
+ (declare (obsolete "use `org-get-tags' instead." "Org 9.2"))
+ (org-get-tags pos 'local))
+
+(defun org-get-tags-string ()
+ "Get the TAGS string in the current headline."
+ (declare (obsolete "use `org-make-tag-string' instead." "Org 9.2"))
+ (org-make-tag-string (org-get-tags nil t)))
+
+(define-obsolete-function-alias 'org-set-tags-to 'org-set-tags "Org 9.2")
+
+(defun org-align-all-tags ()
+ "Align the tags in all headings."
+ (declare (obsolete "use `org-align-tags' instead." "Org 9.2"))
+ (org-align-tags t))
+
+(defmacro org-with-silent-modifications (&rest body)
+ (declare (obsolete "use `with-silent-modifications' instead." "Org 9.2")
+ (debug (body)))
+ `(with-silent-modifications ,@body))
+
+(define-obsolete-function-alias 'org-babel-strip-quotes
+ 'org-strip-quotes "Org 9.2")
;;;; Obsolete link types
-(eval-after-load 'org
+(eval-after-load 'ol
'(progn
(org-link-set-parameters "file+emacs") ;since Org 9.0
(org-link-set-parameters "file+sys"))) ;since Org 9.0
@@ -362,38 +635,6 @@ use of this function is for the stuck project list."
;;; Miscellaneous functions
-;; `xor' was added in Emacs 27.1.
-(defalias 'org-xor
- (if (fboundp 'xor)
- #'xor
- (lambda (a b)
- "Exclusive or."
- (if a (not b) b))))
-
-(defun org-version-check (version feature level)
- (let* ((v1 (mapcar 'string-to-number (split-string version "[.]")))
- (v2 (mapcar 'string-to-number (split-string emacs-version "[.]")))
- (rmaj (or (nth 0 v1) 99))
- (rmin (or (nth 1 v1) 99))
- (rbld (or (nth 2 v1) 99))
- (maj (or (nth 0 v2) 0))
- (min (or (nth 1 v2) 0))
- (bld (or (nth 2 v2) 0)))
- (if (or (< maj rmaj)
- (and (= maj rmaj)
- (< min rmin))
- (and (= maj rmaj)
- (= min rmin)
- (< bld rbld)))
- (if (eq level :predicate)
- ;; just return if we have the version
- nil
- (let ((msg (format "Emacs %s or greater is recommended for %s"
- version feature)))
- (display-warning 'org msg level)
- t))
- t)))
-
(defun org-get-x-clipboard (value)
"Get the value of the X or Windows clipboard."
(cond ((and (eq window-system 'x)
@@ -407,38 +648,13 @@ use of this function is for the stuck project list."
((and (eq window-system 'w32) (fboundp 'w32-get-clipboard-data))
(w32-get-clipboard-data))))
-(defun org-add-props (string plist &rest props)
- "Add text properties to entire string, from beginning to end.
-PLIST may be a list of properties, PROPS are individual properties and values
-that will be added to PLIST. Returns the string that was modified."
- (add-text-properties
- 0 (length string) (if props (append plist props) plist) string)
- string)
-(put 'org-add-props 'lisp-indent-function 2)
-
-(defun org-fit-window-to-buffer (&optional window max-height min-height
- shrink-only)
- "Fit WINDOW to the buffer, but only if it is not a side-by-side window.
-WINDOW defaults to the selected window. MAX-HEIGHT and MIN-HEIGHT are
-passed through to `fit-window-to-buffer'. If SHRINK-ONLY is set, call
-`shrink-window-if-larger-than-buffer' instead, the height limit is
-ignored in this case."
- (cond ((if (fboundp 'window-full-width-p)
- (not (window-full-width-p window))
- ;; do nothing if another window would suffer
- (> (frame-width) (window-width window))))
- ((and (fboundp 'fit-window-to-buffer) (not shrink-only))
- (fit-window-to-buffer window max-height min-height))
- ((fboundp 'shrink-window-if-larger-than-buffer)
- (shrink-window-if-larger-than-buffer window)))
- (or window (selected-window)))
-
;; `set-transient-map' is only in Emacs >= 24.4
(defalias 'org-set-transient-map
(if (fboundp 'set-transient-map)
'set-transient-map
'set-temporary-overlay-map))
+
;;; Region compatibility
(defvar org-ignore-region nil
@@ -455,20 +671,13 @@ Unlike to `use-region-p', this function also checks
(> (point) (region-beginning)))
(exchange-point-and-mark)))
+
;;; Invisibility compatibility
-(defun org-remove-from-invisibility-spec (arg)
- "Remove elements from `buffer-invisibility-spec'."
- (if (fboundp 'remove-from-invisibility-spec)
- (remove-from-invisibility-spec arg)
- (if (consp buffer-invisibility-spec)
- (setq buffer-invisibility-spec
- (delete arg buffer-invisibility-spec)))))
-
(defun org-in-invisibility-spec-p (arg)
"Is ARG a member of `buffer-invisibility-spec'?"
- (if (consp buffer-invisibility-spec)
- (member arg buffer-invisibility-spec)))
+ (when (consp buffer-invisibility-spec)
+ (member arg buffer-invisibility-spec)))
(defun org-move-to-column (column &optional force _buffer)
"Move to column COLUMN.
@@ -487,8 +696,8 @@ Pass COLUMN and FORCE to `move-to-column'."
(let ((start 0) (n 1))
(while (string-match "\n" s start)
(setq start (match-end 0) n (1+ n)))
- (if (and (> (length s) 0) (= (aref s (1- (length s))) ?\n))
- (setq n (1- n)))
+ (when (and (> (length s) 0) (= (aref s (1- (length s))) ?\n))
+ (setq n (1- n)))
n))
(defun org-kill-new (string &rest args)
@@ -511,16 +720,6 @@ Pass COLUMN and FORCE to `move-to-column'."
"Return the local name component of FILE."
(or (file-remote-p file 'localname) file))))
-(defmacro org-no-popups (&rest body)
- "Suppress popup windows.
-Let-bind some variables to nil around BODY to achieve the desired
-effect, which variables to use depends on the Emacs version."
- (if (org-version-check "24.2.50" "" :predicate)
- `(let (pop-up-frames display-buffer-alist)
- ,@body)
- `(let (pop-up-frames special-display-buffer-names special-display-regexps special-display-function)
- ,@body)))
-
;;;###autoload
(defmacro org-check-version ()
"Try very hard to provide sensible version strings."
@@ -539,13 +738,10 @@ effect, which variables to use depends on the Emacs version."
(defun org-release () "N/A")
(defun org-git-version () "N/A !!check installation!!"))))))
-(defmacro org-with-silent-modifications (&rest body)
- (if (fboundp 'with-silent-modifications)
- `(with-silent-modifications ,@body)
- `(org-unmodified ,@body)))
-(def-edebug-spec org-with-silent-modifications (body))
-;; Functions for Emacs < 24.4 compatibility
+
+;;; Functions for Emacs < 24.4 compatibility
+
(defun org-define-error (name message)
"Define NAME as a new error signal.
MESSAGE is a string that will be output to the echo area if such
@@ -566,6 +762,341 @@ attention to case differences."
(eq t (compare-strings suffix nil nil
string start-pos nil ignore-case))))))
+
+;;; Integration with and fixes for other packages
+
+(defgroup org-imenu-and-speedbar nil
+ "Options concerning imenu and speedbar in Org mode."
+ :tag "Org Imenu and Speedbar"
+ :group 'org-structure)
+
+(defcustom org-imenu-depth 2
+ "The maximum level for Imenu access to Org headlines.
+This also applied for speedbar access."
+ :group 'org-imenu-and-speedbar
+ :type 'integer)
+
+;;;; Imenu
+
+(defvar-local org-imenu-markers nil
+ "All markers currently used by Imenu.")
+
+(defun org-imenu-get-tree ()
+ "Produce the index for Imenu."
+ (dolist (x org-imenu-markers) (move-marker x nil))
+ (setq org-imenu-markers nil)
+ (org-with-wide-buffer
+ (goto-char (point-max))
+ (let* ((re (concat "^" (org-get-limited-outline-regexp)))
+ (subs (make-vector (1+ org-imenu-depth) nil))
+ (last-level 0))
+ (while (re-search-backward re nil t)
+ (let ((level (org-reduced-level (funcall outline-level)))
+ (headline (org-no-properties
+ (org-link-display-format (org-get-heading t t t t)))))
+ (when (and (<= level org-imenu-depth) (org-string-nw-p headline))
+ (let* ((m (point-marker))
+ (item (propertize headline 'org-imenu-marker m 'org-imenu t)))
+ (push m org-imenu-markers)
+ (if (>= level last-level)
+ (push (cons item m) (aref subs level))
+ (push (cons item
+ (cl-mapcan #'identity (cl-subseq subs (1+ level))))
+ (aref subs level))
+ (cl-loop for i from (1+ level) to org-imenu-depth
+ do (aset subs i nil)))
+ (setq last-level level)))))
+ (aref subs 1))))
+
+(eval-after-load "imenu"
+ '(progn
+ (add-hook 'imenu-after-jump-hook
+ (lambda ()
+ (when (derived-mode-p 'org-mode)
+ (org-show-context 'org-goto))))
+ (add-hook 'org-mode-hook
+ (lambda ()
+ (setq imenu-create-index-function 'org-imenu-get-tree)))))
+
+;;;; Speedbar
+
+(defvar org-speedbar-restriction-lock-overlay (make-overlay 1 1)
+ "Overlay marking the agenda restriction line in speedbar.")
+(overlay-put org-speedbar-restriction-lock-overlay
+ 'face 'org-agenda-restriction-lock)
+(overlay-put org-speedbar-restriction-lock-overlay
+ 'help-echo "Agendas are currently limited to this item.")
+(delete-overlay org-speedbar-restriction-lock-overlay)
+
+(defun org-speedbar-set-agenda-restriction ()
+ "Restrict future agenda commands to the location at point in speedbar.
+If there is already a restriction lock at the location, remove it.
+
+To get rid of the restriction, use `\\[org-agenda-remove-restriction-lock]'."
+ (interactive)
+ (require 'org-agenda)
+ (let (p m tp np dir txt)
+ (cond
+ ((setq p (text-property-any (point-at-bol) (point-at-eol)
+ 'org-imenu t))
+ (setq m (get-text-property p 'org-imenu-marker))
+ (with-current-buffer (marker-buffer m)
+ (goto-char m)
+ (if (and org-agenda-overriding-restriction
+ (member org-agenda-restriction-lock-overlay
+ (overlays-at (point))))
+ (org-agenda-remove-restriction-lock 'noupdate)
+ (org-agenda-set-restriction-lock 'subtree))))
+ ((setq p (text-property-any (point-at-bol) (point-at-eol)
+ 'speedbar-function 'speedbar-find-file))
+ (setq tp (previous-single-property-change
+ (1+ p) 'speedbar-function)
+ np (next-single-property-change
+ tp 'speedbar-function)
+ dir (speedbar-line-directory)
+ txt (buffer-substring-no-properties (or tp (point-min))
+ (or np (point-max))))
+ (with-current-buffer (find-file-noselect
+ (let ((default-directory dir))
+ (expand-file-name txt)))
+ (unless (derived-mode-p 'org-mode)
+ (user-error "Cannot restrict to non-Org mode file"))
+ (org-agenda-set-restriction-lock 'file)))
+ (t (user-error "Don't know how to restrict Org mode agenda")))
+ (move-overlay org-speedbar-restriction-lock-overlay
+ (point-at-bol) (point-at-eol))
+ (setq current-prefix-arg nil)
+ (org-agenda-maybe-redo)))
+
+(defvar speedbar-file-key-map)
+(declare-function speedbar-add-supported-extension "speedbar" (extension))
+(eval-after-load "speedbar"
+ '(progn
+ (speedbar-add-supported-extension ".org")
+ (define-key speedbar-file-key-map "<" 'org-speedbar-set-agenda-restriction)
+ (define-key speedbar-file-key-map "\C-c\C-x<" 'org-speedbar-set-agenda-restriction)
+ (define-key speedbar-file-key-map ">" 'org-agenda-remove-restriction-lock)
+ (define-key speedbar-file-key-map "\C-c\C-x>" 'org-agenda-remove-restriction-lock)
+ (add-hook 'speedbar-visiting-tag-hook
+ (lambda () (and (derived-mode-p 'org-mode) (org-show-context 'org-goto))))))
+
+;;;; Add Log
+
+(defun org-add-log-current-headline ()
+ "Return current headline or nil.
+This function ignores inlinetasks. It is meant to be used as
+`add-log-current-defun-function' value."
+ (org-with-limited-levels (org-get-heading t t t t)))
+
+;;;; Flyspell
+
+(defun org--flyspell-object-check-p (element)
+ "Non-nil when Flyspell can check object at point.
+ELEMENT is the element at point."
+ (let ((object (save-excursion
+ (when (looking-at-p "\\>") (backward-char))
+ (org-element-context element))))
+ (cl-case (org-element-type object)
+ ;; Prevent checks in links due to keybinding conflict with
+ ;; Flyspell.
+ ((code entity export-snippet inline-babel-call
+ inline-src-block line-break latex-fragment link macro
+ statistics-cookie target timestamp verbatim)
+ nil)
+ (footnote-reference
+ ;; Only in inline footnotes, within the definition.
+ (and (eq (org-element-property :type object) 'inline)
+ (< (save-excursion
+ (goto-char (org-element-property :begin object))
+ (search-forward ":" nil t 2))
+ (point))))
+ (otherwise t))))
+
+(defun org-mode-flyspell-verify ()
+ "Function used for `flyspell-generic-check-word-predicate'."
+ (if (org-at-heading-p)
+ ;; At a headline or an inlinetask, check title only. This is
+ ;; faster than relying on `org-element-at-point'.
+ (and (save-excursion (beginning-of-line)
+ (and (let ((case-fold-search t))
+ (not (looking-at-p "\\*+ END[ \t]*$")))
+ (let ((case-fold-search nil))
+ (looking-at org-complex-heading-regexp))))
+ (match-beginning 4)
+ (>= (point) (match-beginning 4))
+ (or (not (match-beginning 5))
+ (< (point) (match-beginning 5))))
+ (let* ((element (org-element-at-point))
+ (post-affiliated (org-element-property :post-affiliated element)))
+ (cond
+ ;; Ignore checks in all affiliated keywords but captions.
+ ((< (point) post-affiliated)
+ (and (save-excursion
+ (beginning-of-line)
+ (let ((case-fold-search t)) (looking-at "[ \t]*#\\+CAPTION:")))
+ (> (point) (match-end 0))
+ (org--flyspell-object-check-p element)))
+ ;; Ignore checks in LOGBOOK (or equivalent) drawer.
+ ((let ((log (org-log-into-drawer)))
+ (and log
+ (let ((drawer (org-element-lineage element '(drawer))))
+ (and drawer
+ (eq (compare-strings
+ log nil nil
+ (org-element-property :drawer-name drawer) nil nil t)
+ t)))))
+ nil)
+ (t
+ (cl-case (org-element-type element)
+ ((comment quote-section) t)
+ (comment-block
+ ;; Allow checks between block markers, not on them.
+ (and (> (line-beginning-position) post-affiliated)
+ (save-excursion
+ (end-of-line)
+ (skip-chars-forward " \r\t\n")
+ (< (point) (org-element-property :end element)))))
+ ;; Arbitrary list of keywords where checks are meaningful.
+ ;; Make sure point is on the value part of the element.
+ (keyword
+ (and (member (org-element-property :key element)
+ '("DESCRIPTION" "TITLE"))
+ (save-excursion
+ (search-backward ":" (line-beginning-position) t))))
+ ;; Check is globally allowed in paragraphs verse blocks and
+ ;; table rows (after affiliated keywords) but some objects
+ ;; must not be affected.
+ ((paragraph table-row verse-block)
+ (let ((cbeg (org-element-property :contents-begin element))
+ (cend (org-element-property :contents-end element)))
+ (and cbeg (>= (point) cbeg) (< (point) cend)
+ (org--flyspell-object-check-p element))))))))))
+(put 'org-mode 'flyspell-mode-predicate 'org-mode-flyspell-verify)
+
+(defun org-remove-flyspell-overlays-in (beg end)
+ "Remove flyspell overlays in region."
+ (and (bound-and-true-p flyspell-mode)
+ (fboundp 'flyspell-delete-region-overlays)
+ (flyspell-delete-region-overlays beg end)))
+
+(defvar flyspell-delayed-commands)
+(eval-after-load "flyspell"
+ '(add-to-list 'flyspell-delayed-commands 'org-self-insert-command))
+
+;;;; Bookmark
+
+(defun org-bookmark-jump-unhide ()
+ "Unhide the current position, to show the bookmark location."
+ (and (derived-mode-p 'org-mode)
+ (or (org-invisible-p)
+ (save-excursion (goto-char (max (point-min) (1- (point))))
+ (org-invisible-p)))
+ (org-show-context 'bookmark-jump)))
+
+;; Make `bookmark-jump' shows the jump location if it was hidden.
+(eval-after-load "bookmark"
+ '(if (boundp 'bookmark-after-jump-hook)
+ ;; We can use the hook
+ (add-hook 'bookmark-after-jump-hook 'org-bookmark-jump-unhide)
+ ;; Hook not available, use advice
+ (defadvice bookmark-jump (after org-make-visible activate)
+ "Make the position visible."
+ (org-bookmark-jump-unhide))))
+
+;;;; Calendar
+
+(defcustom org-calendar-to-agenda-key 'default
+ "Key to be installed in `calendar-mode-map' for switching to the agenda.
+
+The command `org-calendar-goto-agenda' will be bound to this key.
+
+When set to `default', bind the function to `c', but only if it is
+available in the Calendar keymap. This is the default choice because
+`c' can then be used to switch back and forth between agenda and calendar.
+
+When nil, `org-calendar-goto-agenda' is not bound to any key."
+ :group 'org-agenda
+ :type '(choice
+ (const :tag "Bind to `c' if available" default)
+ (key-sequence :tag "Other binding")
+ (const :tag "No binding" nil))
+ :safe (lambda (v) (or (symbolp v) (stringp v)))
+ :package-version '(Org . "9.2"))
+
+(defcustom org-calendar-insert-diary-entry-key [?i]
+ "The key to be installed in `calendar-mode-map' for adding diary entries.
+This option is irrelevant until `org-agenda-diary-file' has been configured
+to point to an Org file. When that is the case, the command
+`org-agenda-diary-entry' will be bound to the key given here, by default
+`i'. In the calendar, `i' normally adds entries to `diary-file'. So
+if you want to continue doing this, you need to change this to a different
+key."
+ :group 'org-agenda
+ :type 'sexp)
+
+(defun org--setup-calendar-bindings ()
+ "Bind Org functions in Calendar keymap."
+ (pcase org-calendar-to-agenda-key
+ (`nil nil)
+ ((and key (pred stringp))
+ (local-set-key (kbd key) #'org-calendar-goto-agenda))
+ ((guard (not (lookup-key calendar-mode-map "c")))
+ (local-set-key "c" #'org-calendar-goto-agenda))
+ (_ nil))
+ (unless (eq org-agenda-diary-file 'diary-file)
+ (local-set-key org-calendar-insert-diary-entry-key
+ #'org-agenda-diary-entry)))
+
+(eval-after-load "calendar"
+ '(add-hook 'calendar-mode-hook #'org--setup-calendar-bindings))
+
+;;;; Saveplace
+
+;; Make sure saveplace shows the location if it was hidden
+(eval-after-load "saveplace"
+ '(defadvice save-place-find-file-hook (after org-make-visible activate)
+ "Make the position visible."
+ (org-bookmark-jump-unhide)))
+
+;;;; Ecb
+
+;; Make sure ecb shows the location if it was hidden
+(eval-after-load "ecb"
+ '(defadvice ecb-method-clicked (after esf/org-show-context activate)
+ "Make hierarchy visible when jumping into location from ECB tree buffer."
+ (when (derived-mode-p 'org-mode)
+ (org-show-context))))
+
+;;;; Simple
+
+(defun org-mark-jump-unhide ()
+ "Make the point visible with `org-show-context' after jumping to the mark."
+ (when (and (derived-mode-p 'org-mode)
+ (org-invisible-p))
+ (org-show-context 'mark-goto)))
+
+(eval-after-load "simple"
+ '(defadvice pop-to-mark-command (after org-make-visible activate)
+ "Make the point visible with `org-show-context'."
+ (org-mark-jump-unhide)))
+
+(eval-after-load "simple"
+ '(defadvice exchange-point-and-mark (after org-make-visible activate)
+ "Make the point visible with `org-show-context'."
+ (org-mark-jump-unhide)))
+
+(eval-after-load "simple"
+ '(defadvice pop-global-mark (after org-make-visible activate)
+ "Make the point visible with `org-show-context'."
+ (org-mark-jump-unhide)))
+
+;;;; Session
+
+;; Make "session.el" ignore our circular variable.
+(defvar session-globals-exclude)
+(eval-after-load "session"
+ '(add-to-list 'session-globals-exclude 'org-mark-ring))
+
(provide 'org-compat)
;;; org-compat.el ends here