diff options
author | Bastien <bzg@gnu.org> | 2019-12-03 23:27:04 +0100 |
---|---|---|
committer | Bastien <bzg@gnu.org> | 2019-12-03 23:27:04 +0100 |
commit | 165f7383822086d465519ebe6e4283723923f097 (patch) | |
tree | 820be9480e3d571d766483f564c963037192f6ec /lisp/org/org-compat.el | |
parent | 821de968434d2096bdea67dd24301bf6b517aef1 (diff) | |
download | emacs-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.el | 731 |
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 |