summaryrefslogtreecommitdiff
path: root/lisp/org/org.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org/org.el')
-rw-r--r--lisp/org/org.el192
1 files changed, 106 insertions, 86 deletions
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 35405b4bf81..07727f68c40 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -182,7 +182,8 @@ Stars are put in group 1 and the trimmed body in group 2.")
(declare-function org-export-get-environment "ox" (&optional backend subtreep ext-plist))
(declare-function org-latex-make-preamble "ox-latex" (info &optional template snippet?))
-(defvar ffap-url-regexp) ;Silence byte-compiler
+(defvar ffap-url-regexp)
+(defvar org-element-paragraph-separate)
(defsubst org-uniquify (list)
"Non-destructively remove duplicate elements from LIST."
@@ -1284,7 +1285,7 @@ star at the beginning of the headline, you can do this:
This list will be checked before `org-speed-commands-default'
when the variable `org-use-speed-commands' is non-nil
and when the cursor is at the beginning of a headline.
-The car if each entry is a string with a single letter, which must
+The car of each entry is a string with a single letter, which must
be assigned to `self-insert-command' in the global map.
The cdr is either a command to be called interactively, a function
to be called, or a form to be evaluated.
@@ -5290,7 +5291,8 @@ is available. This option applies only if FILE is a URL."
;; Move point to after the url-retrieve header.
(search-forward "\n\n" nil :move)
;; Search for the success code only in the url-retrieve header.
- (if (save-excursion (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror))
+ (if (save-excursion
+ (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror))
;; Update the cache `org--file-cache' and return contents.
(puthash file
(buffer-substring-no-properties (point) (point-max))
@@ -5300,13 +5302,14 @@ is available. This option applies only if FILE is a URL."
file))))
(t
(with-temp-buffer
- (condition-case err
+ (condition-case nil
(progn
(insert-file-contents file)
(buffer-string))
(file-error
(funcall (if noerror #'message #'user-error)
- (error-message-string err)))))))))
+ "Unable to read file %S"
+ file))))))))
(defun org-extract-log-state-settings (x)
"Extract the log state setting from a TODO keyword string.
@@ -5750,18 +5753,27 @@ This should be called after the variable `org-link-parameters' has changed."
(verbatim? (member marker '("~" "="))))
(when (save-excursion
(goto-char (match-beginning 0))
- ;; Do not match headline stars. Do not consider
- ;; stars of a headline as closing marker for bold
- ;; markup either. Do not match table hlines.
(and
- (not (looking-at-p org-outline-regexp-bol))
+ ;; Do not match table hlines.
(not (and (equal marker "+")
(org-match-line
- "^[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$")))
+ "[ \t]*\\(|[-+]+|?\\|\\+[-+]+\\+\\)[ \t]*$")))
+ ;; Do not match headline stars. Do not consider
+ ;; stars of a headline as closing marker for bold
+ ;; markup either.
+ (not (and (equal marker "*")
+ (save-excursion
+ (forward-char)
+ (skip-chars-backward "*")
+ (looking-at-p org-outline-regexp-bol))))
+ ;; Match full emphasis markup regexp.
(looking-at (if verbatim? org-verbatim-re org-emph-re))
- (not (string-match-p
- (concat org-outline-regexp-bol "\\'")
- (match-string 0)))))
+ ;; Do not span over paragraph boundaries.
+ (not (string-match-p org-element-paragraph-separate
+ (match-string 2)))
+ ;; Do not span over cells in table rows.
+ (not (and (save-match-data (org-match-line "[ \t]*|"))
+ (string-match-p "|" (match-string 4))))))
(pcase-let ((`(,_ ,face ,_) (assoc marker org-emphasis-alist)))
(font-lock-prepend-text-property
(match-beginning 2) (match-end 2) 'face face)
@@ -7945,8 +7957,7 @@ unchecked check box."
(org-insert-heading (or (and (equal arg '(16)) '(16))
force-heading))
(save-excursion
- (org-back-to-heading)
- (outline-previous-heading)
+ (org-forward-heading-same-level -1)
(let ((case-fold-search nil)) (looking-at org-todo-line-regexp)))
(let* ((new-mark-x
(if (or (equal arg '(4))
@@ -9636,28 +9647,37 @@ active region."
(move-beginning-of-line 2)
(set-mark (point)))))
(setq org-store-link-plist nil)
- (let (link cpltxt desc description search
- txt custom-id agenda-link sfuns sfunsn)
+ (let (link cpltxt desc description search txt custom-id agenda-link)
(cond
-
- ;; Store a link using an external link type
+ ;; Store a link using an external link type, if any function is
+ ;; available. If more than one can generate a link from current
+ ;; location, ask which one to use.
((and (not (equal arg '(16)))
- (setq sfuns
- (delq
- nil (mapcar (lambda (f)
- (let (fs) (if (funcall f) (push f fs))))
- (org-store-link-functions)))
- sfunsn (mapcar (lambda (fu) (symbol-name (car fu))) sfuns))
- (or (and (cdr sfuns)
- (funcall (intern
- (completing-read
- "Which function for creating the link? "
- sfunsn nil t (car sfunsn)))))
- (funcall (caar sfuns)))
- (setq link (plist-get org-store-link-plist :link)
- desc (or (plist-get org-store-link-plist
- :description)
- link))))
+ (let ((results-alist nil))
+ (dolist (f (org-store-link-functions))
+ (when (funcall f)
+ ;; XXX: return value is not link's plist, so we
+ ;; store the new value before it is modified. It
+ ;; would be cleaner to ask store link functions to
+ ;; return the plist instead.
+ (push (cons f (copy-sequence org-store-link-plist))
+ results-alist)))
+ (pcase results-alist
+ (`nil nil)
+ (`((,_ . ,_)) t) ;single choice: nothing to do
+ (`((,name . ,_) . ,_)
+ ;; Reinstate link plist associated to the chosen
+ ;; function.
+ (apply #'org-store-link-props
+ (cdr (assoc-string
+ (completing-read
+ "Which function for creating the link? "
+ (mapcar #'car results-alist) nil t name)
+ results-alist)))
+ t))))
+ (setq link (plist-get org-store-link-plist :link))
+ (setq desc (or (plist-get org-store-link-plist :description)
+ link)))
;; Store a link from a source code buffer.
((org-src-edit-buffer-p)
@@ -9845,7 +9865,9 @@ active region."
(car org-stored-links)))))
(defun org-store-link-props (&rest plist)
- "Store link properties, extract names, addresses and dates."
+ "Store link properties.
+The properties are pre-processed by extracting names, addresses
+and dates."
(let ((x (plist-get plist :from)))
(when x
(let ((adr (mail-extract-address-components x)))
@@ -14610,7 +14632,7 @@ it as a time string and apply `float-time' to it. If S is nil, just return 0."
((numberp s) s)
((stringp s)
(condition-case nil
- (float-time (apply #'encode-time (org-parse-time-string s nil t)))
+ (float-time (apply #'encode-time (org-parse-time-string s)))
(error 0.)))
(t 0.)))
@@ -17369,8 +17391,8 @@ both scheduled and deadline timestamps."
'timestamp)
(org-at-planning-p))
(time-less-p
- (org-time-string-to-time match t)
- (org-time-string-to-time d t)))))))
+ (org-time-string-to-time match)
+ (org-time-string-to-time d)))))))
(message "%d entries before %s"
(org-occur regexp nil callback)
d)))
@@ -17391,8 +17413,8 @@ both scheduled and deadline timestamps."
'timestamp)
(org-at-planning-p))
(not (time-less-p
- (org-time-string-to-time match t)
- (org-time-string-to-time d t))))))))
+ (org-time-string-to-time match)
+ (org-time-string-to-time d))))))))
(message "%d entries after %s"
(org-occur regexp nil callback)
d)))
@@ -17415,11 +17437,11 @@ both scheduled and deadline timestamps."
'timestamp)
(org-at-planning-p))
(not (time-less-p
- (org-time-string-to-time match t)
- (org-time-string-to-time start-date t)))
+ (org-time-string-to-time match)
+ (org-time-string-to-time start-date)))
(time-less-p
- (org-time-string-to-time match t)
- (org-time-string-to-time end-date t))))))))
+ (org-time-string-to-time match)
+ (org-time-string-to-time end-date))))))))
(message "%d entries between %s and %s"
(org-occur regexp nil callback) start-date end-date)))
@@ -17504,19 +17526,13 @@ days in order to avoid rounding problems."
(push m l))
(apply 'format fmt (nreverse l))))
-(defun org-time-string-to-time (s &optional zone)
- "Convert timestamp string S into internal time.
-The optional ZONE is omitted or nil for Emacs local time, t for
-Universal Time, ‘wall’ for system wall clock time, or a string as
-in the TZ environment variable."
- (apply #'encode-time (org-parse-time-string s nil zone)))
+(defun org-time-string-to-time (s)
+ "Convert timestamp string S into internal time."
+ (apply #'encode-time (org-parse-time-string s)))
-(defun org-time-string-to-seconds (s &optional zone)
- "Convert a timestamp string S into a number of seconds.
-The optional ZONE is omitted or nil for Emacs local time, t for
-Universal Time, ‘wall’ for system wall clock time, or a string as
-in the TZ environment variable."
- (float-time (org-time-string-to-time s zone)))
+(defun org-time-string-to-seconds (s)
+ "Convert a timestamp string S into a number of seconds."
+ (float-time (org-time-string-to-time s)))
(org-define-error 'org-diary-sexp-no-match "Unable to match diary sexp")
@@ -17733,17 +17749,13 @@ day number."
(list (nth 4 d) (nth 3 d) (nth 5 d))))
((listp d) (list (nth 4 d) (nth 3 d) (nth 5 d)))))
-(defun org-parse-time-string (s &optional nodefault zone)
+(defun org-parse-time-string (s &optional nodefault)
"Parse the standard Org time string.
This should be a lot faster than the normal `parse-time-string'.
If time is not given, defaults to 0:00. However, with optional
-NODEFAULT, hour and minute fields will be nil if not given.
-
-The optional ZONE is omitted or nil for Emacs local time, t for
-Universal Time, ‘wall’ for system wall clock time, or a string as
-in the TZ environment variable."
+NODEFAULT, hour and minute fields will be nil if not given."
(cond ((string-match org-ts-regexp0 s)
(list 0
(when (or (match-beginning 8) (not nodefault))
@@ -17753,7 +17765,7 @@ in the TZ environment variable."
(string-to-number (match-string 4 s))
(string-to-number (match-string 3 s))
(string-to-number (match-string 2 s))
- nil nil zone))
+ nil nil nil))
((string-match "^<[^>]+>$" s)
;; FIXME: `decode-time' needs to be called with ZONE as its
;; second argument. However, this requires at least Emacs
@@ -19327,9 +19339,9 @@ boundaries."
;; "file:" links. Also check link abbreviations since
;; some might expand to "file" links.
(file-types-re (format "[][]\\[\\(?:file\\|[./~]%s\\)"
- (and link-abbrevs
- (format "\\|\\(?:%s:\\)"
- (regexp-opt link-abbrevs))))))
+ (if (not link-abbrevs) ""
+ (format "\\|\\(?:%s:\\)"
+ (regexp-opt link-abbrevs))))))
(while (re-search-forward file-types-re end t)
(let ((link (save-match-data (org-element-context))))
;; Check if we're at an inline image, i.e., an image file
@@ -20782,8 +20794,8 @@ This command does many different things, depending on context:
'(babel-call clock dynamic-block footnote-definition
footnote-reference inline-babel-call inline-src-block
inlinetask item keyword node-property paragraph
- plain-list property-drawer radio-target src-block
- statistics-cookie table table-cell table-row
+ plain-list planning property-drawer radio-target
+ src-block statistics-cookie table table-cell table-row
timestamp)
t))
(type (org-element-type context)))
@@ -20935,7 +20947,8 @@ Use `\\[org-edit-special]' to edit table.el tables"))
(cond (arg (call-interactively #'org-table-recalculate))
((org-table-maybe-recalculate-line))
(t (org-table-align))))))
- (`timestamp (org-timestamp-change 0 'day))
+ ((or `timestamp (and `planning (guard (org-at-timestamp-p 'lax))))
+ (org-timestamp-change 0 'day))
((and `nil (guard (org-at-heading-p)))
;; When point is on an unsupported object type, we can miss
;; the fact that it also is at a heading. Handle it here.
@@ -21027,13 +21040,17 @@ object (e.g., within a comment). In these case, you need to use
(let ((context (if org-return-follows-link (org-element-context)
(org-element-at-point))))
(cond
- ;; In a table, call `org-table-next-row'.
+ ;; In a table, call `org-table-next-row'. However, before first
+ ;; column or after last one, split the table.
((or (and (eq (org-element-type context) 'table)
(>= (point) (org-element-property :contents-begin context))
(< (point) (org-element-property :contents-end context)))
(org-element-lineage context '(table-row table-cell) t))
- (org-table-justify-field-maybe)
- (call-interactively #'org-table-next-row))
+ (if (or (looking-at-p "[ \t]*$")
+ (save-excursion (skip-chars-backward " \t") (bolp)))
+ (insert "\n")
+ (org-table-justify-field-maybe)
+ (call-interactively #'org-table-next-row)))
;; On a link or a timestamp, call `org-open-at-point' if
;; `org-return-follows-link' allows it. Tolerate fuzzy
;; locations, e.g., in a comment, as `org-open-at-point'.
@@ -21374,7 +21391,7 @@ an argument, unconditionally call `org-insert-heading'."
["Next keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))]
["Previous keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))])
["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"]
+ ["Global TODO list" org-todo-list :active t :keys "\\[org-agenda] t"]
"--"
["Enforce dependencies" (customize-variable 'org-enforce-todo-dependencies)
:selected org-enforce-todo-dependencies :style toggle :active t]
@@ -21453,8 +21470,8 @@ an argument, unconditionally call `org-insert-heading'."
"--"
["Export/Publish..." org-export-dispatch t]
("LaTeX"
- ["Org CDLaTeX mode" org-cdlatex-mode :style toggle
- :selected org-cdlatex-mode]
+ ["Org CDLaTeX mode" org-cdlatex-mode :active (require 'cdlatex nil t)
+ :style toggle :selected org-cdlatex-mode]
["Insert Environment" cdlatex-environment (fboundp 'cdlatex-environment)]
["Insert math symbol" cdlatex-math-symbol (fboundp 'cdlatex-math-symbol)]
["Modify math symbol" org-cdlatex-math-modify
@@ -21464,7 +21481,7 @@ an argument, unconditionally call `org-insert-heading'."
("MobileOrg"
["Push Files and Views" org-mobile-push t]
["Get Captured and Flagged" org-mobile-pull t]
- ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "C-c a ?"]
+ ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "\\[org-agenda] ?"]
"--"
["Setup" (progn (require 'org-mobile) (customize-group 'org-mobile)) t])
"--"
@@ -21568,7 +21585,9 @@ Your bug report will be posted to the Org mailing list.
["Cycle through agenda files" org-cycle-agenda-files t]
["Occur in all agenda files" org-occur-in-agenda-files t]
"--")
- (mapcar 'org-file-menu-entry (org-agenda-files t))))))))
+ (mapcar 'org-file-menu-entry
+ ;; Prevent initialization from failing.
+ (ignore-errors (org-agenda-files t)))))))))
;;;; Documentation
@@ -22764,7 +22783,6 @@ assumed to be significant there."
;; `org-setup-filling' installs filling and auto-filling related
;; variables during `org-mode' initialization.
-(defvar org-element-paragraph-separate) ; org-element.el
(defun org-setup-filling ()
(require 'org-element)
;; Prevent auto-fill from inserting unwanted new items.
@@ -23617,7 +23635,9 @@ depending on context."
(skip-chars-forward " \r\t\n"))))
(narrow-to-region (org-element-property :contents-begin element)
contents-end))
- (call-interactively #'forward-sentence))))))
+ ;; End of heading is considered as the end of a sentence.
+ (let ((sentence-end (concat (sentence-end) "\\|^\\*+ .*$")))
+ (call-interactively #'forward-sentence)))))))
(define-key org-mode-map "\M-a" 'org-backward-sentence)
(define-key org-mode-map "\M-e" 'org-forward-sentence)
@@ -24230,10 +24250,11 @@ convenience:
(backward-char)
(org-backward-paragraph))
((<= (point) post-affiliated) (goto-char begin))
+ ;; Special behavior: on a table or a property drawer, move to
+ ;; its beginning.
((memq type '(node-property table-row))
(goto-char (org-element-property
:post-affiliated (org-element-property :parent element))))
- ((memq type '(property-drawer table)) (goto-char begin))
(special?
(if (<= (point) contents-begin) (goto-char post-affiliated)
;; Inside a verse block, see blank lines as paragraph
@@ -24244,8 +24265,7 @@ convenience:
(skip-chars-forward " \r\t\n" origin)
(if (= (point) origin) (goto-char contents-begin)
(beginning-of-line))))))
- ((eq type 'paragraph)
- (goto-char contents-begin)
+ ((eq type 'paragraph) (goto-char contents-begin)
;; When at first paragraph in an item or a footnote definition,
;; move directly to beginning of line.
(let ((parent-contents
@@ -24253,9 +24273,9 @@ convenience:
:contents-begin (org-element-property :parent element))))
(when (and parent-contents (= parent-contents contents-begin))
(beginning-of-line))))
- ;; At the end of a greater element, move to the beginning of the
- ;; last element within.
- ((>= (point) contents-end)
+ ;; At the end of a greater element, move to the beginning of
+ ;; the last element within.
+ ((and contents-end (>= (point) contents-end))
(goto-char (1- contents-end))
(org-backward-paragraph))
(t (goto-char (or post-affiliated begin))))