diff options
Diffstat (limited to 'lisp/org.el')
-rw-r--r-- | lisp/org.el | 1275 |
1 files changed, 767 insertions, 508 deletions
diff --git a/lisp/org.el b/lisp/org.el index 798816b..6d34bce 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -416,8 +416,7 @@ For export specific modules, see also `org-export-backends'." (const :tag "C jira: Add a jira:ticket protocol to Org-mode" org-jira) (const :tag "C learn: SuperMemo's incremental learning algorithm" org-learn) (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 mac-message: Links to messages in Apple Mail" org-mac-message) + (const :tag "C mac-link: Grab links and url from various mac Applications" org-mac-link) (const :tag "C mairix: Hook mairix search into Org-mode for different MUAs" org-mairix) (const :tag "C man: Support for links to manpages in Org-mode" org-man) (const :tag "C mew: Links to Mew folders/messages" org-mew) @@ -436,8 +435,9 @@ For export specific modules, see also `org-export-backends'." (const :tag "C wl: Links to Wanderlust folders/messages" org-wl) (repeat :tag "External packages" :inline t (symbol :tag "Package")))) -(defvar org-export-registered-backends) ; From ox.el +(defvar org-export--registered-backends) ; From ox.el. (declare-function org-export-derived-backend-p "ox" (backend &rest backends)) +(declare-function org-export-backend-name "ox" (backend)) (defcustom org-export-backends '(ascii html icalendar latex) "List of export back-ends that should be always available. @@ -451,30 +451,29 @@ needed. This variable needs to be set before org.el is loaded. If you need to make a change while Emacs is running, use the customize -interface or run the following code, where VALUE stands for the -new value of the variable, after updating it: +interface or run the following code, where VAL stands for the new +value of the variable, after updating it: \(progn - \(setq org-export-registered-backends + \(setq org-export--registered-backends \(org-remove-if-not \(lambda (backend) - \(or (memq backend val) - \(catch 'parentp - \(mapc - \(lambda (b) - \(and (org-export-derived-backend-p b (car backend)) - \(throw 'parentp t))) - val) - nil))) - org-export-registered-backends)) - \(let ((new-list (mapcar 'car org-export-registered-backends))) + \(let ((name (org-export-backend-name backend))) + \(or (memq name val) + \(catch 'parentp + \(dolist (b val) + \(and (org-export-derived-backend-p b name) + \(throw 'parentp t))))))) + org-export--registered-backends)) + \(let ((new-list (mapcar 'org-export-backend-name + org-export--registered-backends))) \(dolist (backend val) \(cond \((not (load (format \"ox-%s\" backend) t t)) \(message \"Problems while trying to load export back-end `%s'\" backend)) \((not (memq backend new-list)) (push backend new-list)))) - \(set-default var new-list))) + \(set-default 'org-export-backends new-list))) Adding a back-end to this list will also pull the back-end it depends on, if any." @@ -488,21 +487,20 @@ depends on, if any." ;; Any back-end not required anymore (not present in VAL and not ;; a parent of any back-end in the new value) is removed from the ;; list of registered back-ends. - (setq org-export-registered-backends + (setq org-export--registered-backends (org-remove-if-not (lambda (backend) - (or (memq backend val) - (catch 'parentp - (mapc - (lambda (b) - (and (org-export-derived-backend-p b (car backend)) - (throw 'parentp t))) - val) - nil))) - org-export-registered-backends)) + (let ((name (org-export-backend-name backend))) + (or (memq name val) + (catch 'parentp + (dolist (b val) + (and (org-export-derived-backend-p b name) + (throw 'parentp t))))))) + org-export--registered-backends)) ;; Now build NEW-LIST of both new back-ends and required ;; parents. - (let ((new-list (mapcar 'car org-export-registered-backends))) + (let ((new-list (mapcar 'org-export-backend-name + org-export--registered-backends))) (dolist (backend val) (cond ((not (load (format "ox-%s" backend) t t)) @@ -1033,6 +1031,21 @@ commands in the Help buffer using the `?' speed command." (function) (sexp)))))) +(defcustom org-bookmark-names-plist + '(:last-capture "org-capture-last-stored" + :last-refile "org-refile-last-stored" + :last-capture-marker "org-capture-last-stored-marker") + "Names for bookmarks automatically set by some Org commands. +This can provide strings as names for a number of bookmakrs Org sets +automatically. The following keys are currently implemented: + :last-capture + :last-capture-marker + :last-refile +When a key does not show up in the property list, the corresponding bookmark +is not set." + :group 'org-structure + :type 'plist) + (defgroup org-cycle nil "Options concerning visibility cycling in Org-mode." :tag "Org Cycle" @@ -1278,6 +1291,11 @@ OK to kill that hidden subtree. When nil, kill without remorse." (const :tag "Protect hidden subtrees with a security query" t) (const :tag "Never kill a hidden subtree with C-k" error))) +(defcustom org-special-ctrl-o t + "Non-nil means, make `C-o' insert a row in tables." + :group 'org-edit-structure + :type 'boolean) + (defcustom org-catch-invisible-edits nil "Check if in invisible region before inserting or deleting a character. Valid values are: @@ -1596,7 +1614,7 @@ two parameters: the first one is the link, the second one is the description generated by `org-insert-link'. The function should return the description to use." :group 'org-link - :type 'function) + :type '(choice (const nil) (function))) (defgroup org-link-store nil "Options concerning storing links in Org-mode." @@ -1685,7 +1703,7 @@ Org contains a function for this, so if you set this variable to `org-translate-link-from-planner', you should be able follow many links created by planner." :group 'org-link-follow - :type 'function) + :type '(choice (const nil) (function))) (defcustom org-follow-link-hook nil "Hook that is run after a link has been followed." @@ -1767,6 +1785,11 @@ another window." (const vm-visit-folder) (const vm-visit-folder-other-window) (const vm-visit-folder-other-frame))) + (cons (const vm-imap) + (choice + (const vm-visit-imap-folder) + (const vm-visit-imap-folder-other-window) + (const vm-visit-imap-folder-other-frame))) (cons (const gnus) (choice (const gnus) @@ -2165,7 +2188,9 @@ should be continued. For example, the function may decide that the entire subtree of the current entry should be excluded and move point to the end of the subtree." :group 'org-refile - :type 'function) + :type '(choice + (const nil) + (function))) (defcustom org-refile-use-cache nil "Non-nil means cache refile targets to speed up the process. @@ -2808,7 +2833,9 @@ The user can set a different function here, which should take a string as an argument and return the numeric priority." :group 'org-priorities :version "24.1" - :type 'function) + :type '(choice + (const nil) + (function))) (defgroup org-time nil "Options concerning time stamps and deadlines in Org-mode." @@ -3271,7 +3298,7 @@ automatically if necessary." :type '(choice (const :tag "Always" t) (const :tag "Never" nil) - (const :tag "When selection characters are configured" 'auto))) + (const :tag "When selection characters are configured" auto))) (defcustom org-fast-tag-selection-single-key nil "Non-nil means fast tag selection exits after first change. @@ -3492,7 +3519,7 @@ value The value that should be modified. The function should return the value that should be displayed, or nil if the normal value should be used." :group 'org-properties - :type 'function) + :type '(choice (const nil) (function))) (defcustom org-effort-property "Effort" "The property that is being used to keep track of effort estimates. @@ -3754,11 +3781,9 @@ images at the same place." (defcustom org-format-latex-header "\\documentclass{article} \\usepackage[usenames]{color} -\\usepackage{amsmath} -\\usepackage[mathscr]{eucal} -\\pagestyle{empty} % do not remove \[PACKAGES] \[DEFAULT-PACKAGES] +\\pagestyle{empty} % do not remove % The settings below are copied from fullpage.sty \\setlength{\\textwidth}{\\paperwidth} \\addtolength{\\textwidth}{-3cm} @@ -3805,13 +3830,13 @@ header, or they will be appended." ("" "longtable" nil) ("" "float" nil) ("" "wrapfig" nil) + ("" "rotating" nil) ("normalem" "ulem" t) + ("" "amsmath" t) ("" "textcomp" t) ("" "marvosym" t) ("" "wasysym" t) - ("" "latexsym" t) ("" "amssymb" t) - ("" "amstext" nil) ("" "hyperref" nil) "\\tolerance=1000") "Alist of default packages to be inserted in the header. @@ -3823,15 +3848,16 @@ The packages in this list are needed by one part or another of Org mode to function properly: - inputenc, fontenc: for basic font and character selection -- amstext: for subscript and superscript -- textcomp, marvosymb, wasysym, latexsym, amssym: for various - symbols used for interpreting the entities in `org-entities'. - You can skip some of these packages if you don't use any of the - symbols in it. -- ulem: for underline and strike-through +- fixltx2e: Important patches of LaTeX itself - graphicx: for including images +- longtable: For multipage tables - float, wrapfig: for figure placement -- longtable: for long tables +- rotating: for sideways figures and tables +- ulem: for underline and strike-through +- amsmath: for subscript and superscript and math environments +- textcomp, marvosymb, wasysym, amssymb: for various symbols used + for interpreting the entities in `org-entities'. You can skip + some of these packages if you don't use any of their symbols. - hyperref: for cross references Therefore you should not modify this variable unless you know @@ -4285,7 +4311,6 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." (looking-at org-table-hline-regexp)) nil)) -(defvar org-table-clean-did-remove-column nil) (defun org-table-map-tables (function &optional quietly) "Apply FUNCTION to the start of all tables in the buffer." (save-excursion @@ -4305,12 +4330,6 @@ If TABLE-TYPE is non-nil, also check for table.el-type tables." (re-search-forward org-table-any-border-regexp nil 1)))) (unless quietly (message "Mapping tables: done"))) -;; Declare and autoload functions from ox.el and al. - -(declare-function org-export-get-environment "ox" - (&optional backend subtreep ext-plist)) -(declare-function org-latex-guess-inputenc "ox-latex" (header)) - ;; Declare and autoload functions from org-agenda.el (eval-and-compile @@ -4493,7 +4512,7 @@ Otherwise, these types are allowed: inactive: only inactive timestamps (<...) scheduled: only scheduled timestamps deadline: only deadline timestamps" - :type '(choice (const :tag "Scheduled or deadline" 'scheduled-or-deadline) + :type '(choice (const :tag "Scheduled or deadline" scheduled-or-deadline) (const :tag "All timestamps" all) (const :tag "Only active timestamps" active) (const :tag "Only inactive timestamps" inactive) @@ -4836,7 +4855,7 @@ Support for group tags is controlled by the option ;; Process the tags. (when (and (not tags) org-tag-alist) (setq tags - (mapcar + (mapcar (lambda (tg) (cond ((eq (car tg) :startgroup) "{") ((eq (car tg) :endgroup) "}") ((eq (car tg) :grouptags) ":") @@ -5327,8 +5346,6 @@ The following commands are available: (org-set-local 'outline-regexp org-outline-regexp) (org-set-local 'outline-level 'org-outline-level) (setq bidi-paragraph-direction 'left-to-right) - ;; FIXME Circumvent a bug in outline.el (Emacs <24.4) - (set (make-local-variable 'paragraph-start) "\\|[ \t]*$\\|\\*+ ") (when (and org-ellipsis (fboundp 'set-display-table-slot) (boundp 'buffer-display-table) (fboundp 'make-glyph-code)) @@ -6133,8 +6150,22 @@ Use `org-reduced-level' to remove the effect of `org-odd-levels'." (defvar org-font-lock-keywords nil) -(defconst org-property-re (org-re "^[ \t]*\\(:\\([-[:alnum:]_]+\\+?\\):\\)[ \t]*\\([^ \t\r\n].*\\)") - "Regular expression matching a property line.") +(defsubst org-re-property (property &optional literal) + "Return a regexp matching a PROPERTY line. +Match group 3 will be set to the value if it exists." + (concat "^\\(?4:[ \t]*\\)\\(?1::\\(?2:" + (if literal property (regexp-quote property)) + "\\):\\)[ \t]+\\(?3:[^ \t\r\n].*?\\)\\(?5:[ \t]*\\)$")) + +(defconst org-property-re + (org-re-property ".*?" 'literal) + "Regular expression matching a property line. +There are four matching groups: +1: :PROPKEY: including the leading and trailing colon, +2: PROPKEY without the leading and trailing colon, +3: PROPVAL without leading or trailing spaces, +4: the indentation of the current line, +5: trailing whitespace.") (defvar org-font-lock-hook nil "Functions to be called for special font lock stuff.") @@ -6481,6 +6512,11 @@ and subscripts." (defvar org-inlinetask-min-level) +(defun org-unlogged-message (&rest args) + "Display a message, but avoid logging it in the *Messages* buffer." + (let ((message-log-max nil)) + (apply 'message args))) + ;;;###autoload (defun org-cycle (&optional arg) "TAB-action and visibility cycling for Org-mode. @@ -6535,8 +6571,7 @@ in special contexts. (and org-cycle-level-after-item/entry-creation (or (org-cycle-level) (org-cycle-item-indentation)))) - (let* (message-log-max ; Don't populate the *Messages* buffer - (limit-level + (let* ((limit-level (or org-cycle-max-level (and (boundp 'org-inlinetask-min-level) org-inlinetask-min-level @@ -6567,11 +6602,11 @@ in special contexts. ((equal arg '(16)) (setq last-command 'dummy) (org-set-startup-visibility) - (message "Startup visibility, plus VISIBILITY properties")) + (org-unlogged-message "Startup visibility, plus VISIBILITY properties")) ((equal arg '(64)) (show-all) - (message "Entire buffer visible, including drawers")) + (org-unlogged-message "Entire buffer visible, including drawers")) ;; Table: enter it or move to the next field. ((org-at-table-p 'any) @@ -6651,17 +6686,16 @@ in special contexts. (defun org-cycle-internal-global () "Do the global cycling action." ;; Hack to avoid display of messages for .org attachments in Gnus - (let (message-log-max ; Don't populate the *Messages* buffer - (ga (string-match "\\*fontification" (buffer-name)))) + (let ((ga (string-match "\\*fontification" (buffer-name)))) (cond ((and (eq last-command this-command) (eq org-cycle-global-status 'overview)) ;; We just created the overview - now do table of contents ;; This can be slow in very large buffers, so indicate action (run-hook-with-args 'org-pre-cycle-hook 'contents) - (unless ga (message "CONTENTS...")) + (unless ga (org-unlogged-message "CONTENTS...")) (org-content) - (unless ga (message "CONTENTS...done")) + (unless ga (org-unlogged-message "CONTENTS...done")) (setq org-cycle-global-status 'contents) (run-hook-with-args 'org-cycle-hook 'contents)) @@ -6670,7 +6704,7 @@ in special contexts. ;; We just showed the table of contents - now show everything (run-hook-with-args 'org-pre-cycle-hook 'all) (show-all) - (unless ga (message "SHOW ALL")) + (unless ga (org-unlogged-message "SHOW ALL")) (setq org-cycle-global-status 'all) (run-hook-with-args 'org-cycle-hook 'all)) @@ -6678,14 +6712,13 @@ in special contexts. ;; Default action: go to overview (run-hook-with-args 'org-pre-cycle-hook 'overview) (org-overview) - (unless ga (message "OVERVIEW")) + (unless ga (org-unlogged-message "OVERVIEW")) (setq org-cycle-global-status 'overview) (run-hook-with-args 'org-cycle-hook 'overview))))) (defun org-cycle-internal-local () "Do the local cycling action." - (let (message-log-max ; Don't populate the *Messages* buffer - (goal-column 0) eoh eol eos has-children children-skipped struct) + (let ((goal-column 0) eoh eol eos has-children children-skipped struct) ;; First, determine end of headline (EOH), end of subtree or item ;; (EOS), and if item or heading has children (HAS-CHILDREN). (save-excursion @@ -6725,7 +6758,7 @@ in special contexts. ;; Nothing is hidden behind this heading (unless (org-before-first-heading-p) (run-hook-with-args 'org-pre-cycle-hook 'empty)) - (message "EMPTY ENTRY") + (org-unlogged-message "EMPTY ENTRY") (setq org-cycle-subtree-status nil) (save-excursion (goto-char eos) @@ -6760,7 +6793,7 @@ in special contexts. (mapc (lambda (e) (org-list-set-item-visibility e struct 'folded)) (org-list-get-all-items (point) struct prevs)) (goto-char (if (< end eos) end eos))))))) - (message "CHILDREN") + (org-unlogged-message "CHILDREN") (save-excursion (goto-char eos) (outline-next-heading) @@ -6776,7 +6809,8 @@ in special contexts. (unless (org-before-first-heading-p) (run-hook-with-args 'org-pre-cycle-hook 'subtree)) (outline-flag-region eoh eos nil) - (message (if children-skipped "SUBTREE (NO CHILDREN)" "SUBTREE")) + (org-unlogged-message + (if children-skipped "SUBTREE (NO CHILDREN)" "SUBTREE")) (setq org-cycle-subtree-status 'subtree) (unless (org-before-first-heading-p) (run-hook-with-args 'org-cycle-hook 'subtree))) @@ -6784,7 +6818,7 @@ in special contexts. ;; Default action: hide the subtree. (run-hook-with-args 'org-pre-cycle-hook 'folded) (outline-flag-region eoh eos t) - (message "FOLDED") + (org-unlogged-message "FOLDED") (setq org-cycle-subtree-status 'folded) (unless (org-before-first-heading-p) (run-hook-with-args 'org-cycle-hook 'folded)))))) @@ -6804,7 +6838,7 @@ With a numeric prefix, show all headlines up to that level." (setq org-cycle-global-status 'contents)) ((equal arg '(4)) (org-set-startup-visibility) - (message "Startup visibility, plus VISIBILITY properties.")) + (org-unlogged-message "Startup visibility, plus VISIBILITY properties.")) (t (org-cycle '(4)))))) @@ -6865,7 +6899,7 @@ of the first headline in the buffer. This is important, because if the first headline is not level one, then (hide-sublevels 1) gives confusing results." (interactive) - (let ((l (org-current-line)) + (let ((pos (point)) (level (save-excursion (goto-char (point-min)) (if (re-search-forward (concat "^" outline-regexp) nil t) @@ -6874,7 +6908,7 @@ results." (funcall outline-level)))))) (and level (hide-sublevels level)) (recenter '(4)) - (org-goto-line l))) + (goto-char pos))) (defun org-content (&optional arg) "Show all headlines in the buffer, like a table of contents. @@ -7514,168 +7548,149 @@ the current headline. If point is not at the beginning, split the line and create a new headline with the text in the current line after point \(see `org-M-RET-may-split-line' on how to modify this behavior). +If point is at the beginning of a normal line, turn this line into +a heading. + When INVISIBLE-OK is set, stop at invisible headlines when going back. This is important for non-interactive uses of the command." (interactive "P") (if (org-called-interactively-p 'any) (org-reveal)) - (cond - ((or (= (buffer-size) 0) - (and (not (save-excursion - (and (ignore-errors (org-back-to-heading invisible-ok)) - (org-at-heading-p)))) - (or arg (not (org-in-item-p))))) - (insert - (if (org-previous-line-empty-p) "" "\n") - (if (org-in-src-block-p) ",* " "* ")) - (run-hooks 'org-insert-heading-hook)) - ((or arg - (and (not (org-in-item-p)) org-insert-heading-respect-content) - (not (org-insert-item - (save-excursion - (beginning-of-line) - (looking-at org-list-full-item-re) - (match-string 3))))) - (let (begn endn) - (when (org-buffer-narrowed-p) - (setq begn (point-min) endn (point-max)) - (widen)) - (let* ((empty-line-p nil) - (eops (equal arg '(16))) ; insert at end of parent subtree - (org-insert-heading-respect-content - (or (not (null arg)) org-insert-heading-respect-content)) - (level nil) - (on-heading (org-at-heading-p)) - ;; Get a level to fall back on - (fix-level - (save-excursion - (org-back-to-heading t) - (looking-at org-outline-regexp) - (make-string (1- (length (match-string 0))) ?*))) - (on-empty-line - (save-excursion (beginning-of-line 1) (looking-at "^\\s-*$"))) - (head (save-excursion - (condition-case nil - (progn - (org-back-to-heading invisible-ok) - (when (and (not on-heading) - (featurep 'org-inlinetask) - (integerp org-inlinetask-min-level) - (>= (length (match-string 0)) - org-inlinetask-min-level)) - ;; Find a heading level before the inline task - (while (and (setq level (org-up-heading-safe)) - (>= level org-inlinetask-min-level))) - (if (org-at-heading-p) - (org-back-to-heading invisible-ok) - (error "This should not happen"))) - (unless (and (save-excursion - (save-match-data - (org-backward-heading-same-level 1 invisible-ok)) - (= (point) (match-beginning 0))) - (not (org-previous-line-empty-p t))) - (setq empty-line-p (org-previous-line-empty-p))) - (match-string 0)) - (error (or fix-level "* "))))) - (blank-a (cdr (assq 'heading org-blank-before-new-entry))) - (blank (if (eq blank-a 'auto) empty-line-p blank-a)) - pos hide-previous previous-pos) - (if ;; At the beginning of a heading, open a new line for insertion - (and (bolp) (org-at-heading-p) - (not eops) - (or (bobp) - (save-excursion (backward-char 1) (not (outline-invisible-p))))) - (open-line (if blank 2 1)) - (save-excursion - (setq previous-pos (point-at-bol)) - (end-of-line) - (setq hide-previous (outline-invisible-p))) - (and org-insert-heading-respect-content - (save-excursion - (while (outline-invisible-p) - (org-show-subtree) - (org-up-heading-safe)))) - (let ((split - (and (org-get-alist-option org-M-RET-may-split-line 'headline) - (save-excursion - (let ((p (point))) - (goto-char (point-at-bol)) - (and (looking-at org-complex-heading-regexp) - (match-beginning 4) - (> p (match-beginning 4))))))) - tags pos) - (cond - ;; Insert a new line, possibly at end of parent subtree - ((and (not arg) (not on-heading) (not on-empty-line) - (not (save-excursion - (beginning-of-line 1) - (or (looking-at org-list-full-item-re) - ;; Don't convert :end: lines to headline - (looking-at "^\\s-*:end:") - (looking-at "^\\s-*#\\+end_?"))))) - (beginning-of-line 1)) - (org-insert-heading-respect-content - (if (not eops) - (progn - (org-end-of-subtree nil t) - (and (looking-at "^\\*") (backward-char 1)) - (while (and (not (bobp)) - ;; Don't delete spaces in empty headlines - (not (looking-back org-outline-regexp)) - (member (char-before) '(?\ ?\t ?\n))) - (backward-delete-char 1))) - (let ((p (point))) - (org-up-heading-safe) - (if (= p (point)) - (goto-char (point-max)) - (org-end-of-subtree nil t)))) - (when (featurep 'org-inlinetask) - (while (and (not (eobp)) - (looking-at "\\(\\*+\\)[ \t]+") - (>= (length (match-string 1)) - org-inlinetask-min-level)) - (org-end-of-subtree nil t))) - (or (bolp) (newline)) - (or (org-previous-line-empty-p) - (and blank (newline))) - (if (or empty-line-p eops) (open-line 1))) - ;; Insert a headling containing text after point - ((org-at-heading-p) - (when hide-previous - (show-children) - (org-show-entry)) - (looking-at ".*?\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)?[ \t]*$") - (setq tags (and (match-end 2) (match-string 2))) - (and (match-end 1) - (delete-region (match-beginning 1) (match-end 1))) - (setq pos (point-at-bol)) - (or split (end-of-line 1)) - (delete-horizontal-space) - (if (string-match "\\`\\*+\\'" - (buffer-substring (point-at-bol) (point))) - (insert " ")) - (newline (if blank 2 1)) - (when tags + (let ((itemp (org-in-item-p)) + (may-split (org-get-alist-option org-M-RET-may-split-line 'headline)) + (respect-content (or org-insert-heading-respect-content + (equal arg '(16)))) + (initial-content "") + (adjust-empty-lines t)) + + (cond + + ((or (= (buffer-size) 0) + (and (not (save-excursion + (and (ignore-errors (org-back-to-heading invisible-ok)) + (org-at-heading-p)))) + (or arg (not itemp)))) + ;; At beginning of buffer or so hight up that only a heading makes sense. + (insert + (if (or (bobp) (org-previous-line-empty-p)) "" "\n") + (if (org-in-src-block-p) ",* " "* ")) + (run-hooks 'org-insert-heading-hook)) + + ((and itemp (not (equal arg '(4)))) + ;; Insert an item + (org-insert-item)) + + (t + ;; Insert a heading + (save-restriction + (widen) + (let* ((level nil) + (on-heading (org-at-heading-p)) + (empty-line-p (if on-heading + (org-previous-line-empty-p) + ;; We will decide later + nil)) + ;; Get a level string to fall back on + (fix-level (save-excursion - (goto-char pos) - (end-of-line 1) - (insert " " tags) - (org-set-tags nil 'align)))) - (t - (or split (end-of-line 1)) - (newline (cond ((and blank (not on-empty-line)) 2) - (blank 1) - (on-empty-line 0) (t 1))))))) - (insert head) (just-one-space) - (setq pos (point)) - (end-of-line 1) - (unless (= (point) pos) (just-one-space) (backward-delete-char 1)) - (when (and org-insert-heading-respect-content hide-previous) - (save-excursion - (goto-char previous-pos) - (hide-subtree))) - (when (and begn endn) - (narrow-to-region (min (point) begn) (max (point) endn))) - (run-hooks 'org-insert-heading-hook)))))) + (org-back-to-heading t) + (if (org-previous-line-empty-p) (setq empty-line-p t)) + (looking-at org-outline-regexp) + (make-string (1- (length (match-string 0))) ?*))) + (stars + (save-excursion + (condition-case nil + (progn + (org-back-to-heading invisible-ok) + (when (and (not on-heading) + (featurep 'org-inlinetask) + (integerp org-inlinetask-min-level) + (>= (length (match-string 0)) + org-inlinetask-min-level)) + ;; Find a heading level before the inline task + (while (and (setq level (org-up-heading-safe)) + (>= level org-inlinetask-min-level))) + (if (org-at-heading-p) + (org-back-to-heading invisible-ok) + (error "This should not happen"))) + (unless (and (save-excursion + (save-match-data + (org-backward-heading-same-level + 1 invisible-ok)) + (= (point) (match-beginning 0))) + (not (org-previous-line-empty-p t))) + (setq empty-line-p (or empty-line-p + (org-previous-line-empty-p)))) + (match-string 0)) + (error (or fix-level "* "))))) + (blank-a (cdr (assq 'heading org-blank-before-new-entry))) + (blank (if (eq blank-a 'auto) empty-line-p blank-a)) + pos hide-previous previous-pos) + + ;; If we insert after content, move there and clean up whitespace + (when respect-content + (org-end-of-subtree nil t) + (skip-chars-backward " \r\n") + (and (looking-at "[ \t]+") (replace-match "")) + (forward-char 1) + (when (looking-at "^\\*") + (backward-char 1) + (insert "\n"))) + + ;; If we are splitting, grab the text that should be moved to the new headline + (when may-split + (if (org-on-heading-p) + ;; This is a heading, we split intelligently (keeping tags) + (let ((pos (point))) + (goto-char (point-at-bol)) + (unless (looking-at org-complex-heading-regexp) + (error "This should not happen")) + (when (and (match-beginning 4) + (> pos (match-beginning 4)) + (< pos (match-end 4))) + (setq initial-content (buffer-substring pos (match-end 4))) + (goto-char pos) + (delete-region (point) (match-end 4)) + (if (looking-at "[ \t]*$") + (replace-match "") + (insert (make-string (length initial-content) ?\ ))) + (setq initial-content (org-trim initial-content))) + (goto-char pos)) + ;; a normal line + (unless (bolp) + (setq initial-content (buffer-substring (point) (point-at-eol))) + (delete-region (point) (point-at-eol)) + (setq initial-content (org-trim initial-content))))) + + ;; If we are at the beginning of the line, insert before it. Else after + (cond + ((and (bolp) (looking-at "[ \t]*$"))) + ((and (bolp) (not (looking-at "[ \t]*$"))) + (open-line 1)) + (t + (goto-char (point-at-eol)) + (insert "\n"))) + + ;; Insert the new heading + (insert stars) + (just-one-space) + (insert initial-content) + (when adjust-empty-lines + (if (or (not blank) + (and blank (not (org-previous-line-empty-p)))) + (org-N-empty-lines-before-current (if blank 1 0)))) + (run-hooks 'org-insert-heading-hook))))))) + +(defun org-N-empty-lines-before-current (N) + "Make the number of empty lines before current exactly N. +So this will delete or add empty lines." + (save-excursion + (goto-char (point-at-bol)) + (if (looking-back "\\s-+" nil 'greedy) + (replace-match "")) + (or (bobp) (insert "\n")) + (while (> N 0) + (insert "\n") + (setq N (1- N))))) (defun org-get-heading (&optional no-tags no-todo) "Return the heading of the current entry, without the stars. @@ -7748,7 +7763,7 @@ This is a list with the following elements: "Insert heading with `org-insert-heading-respect-content' set to t." (interactive "P") (let ((org-insert-heading-respect-content t)) - (org-insert-heading arg invisible-ok))) + (org-insert-heading '(4) invisible-ok))) (defun org-insert-todo-heading-respect-content (&optional force-state) "Insert TODO heading with `org-insert-heading-respect-content' set to t." @@ -8888,6 +8903,8 @@ buffer. It will also recognize item context in multiline items." org-fb-vars)) (orgstruct-mode 1) (setq org-fb-vars nil) + (unless org-local-vars + (setq org-local-vars (org-get-local-variables))) (let (var val) (mapc (lambda (x) @@ -8962,26 +8979,30 @@ buffer. It will also recognize item context in multiline items." (let ((f (or (car-safe cell) cell)) (disable-when-heading-prefix (cdr-safe cell))) (when (fboundp f) - (dolist (binding (nconc (where-is-internal f org-mode-map) - (where-is-internal f outline-mode-map))) - ;; TODO use local-function-key-map - (dolist (rep '(("<tab>" . "TAB") - ("<return>" . "RET") - ("<escape>" . "ESC") - ("<delete>" . "DEL"))) - (setq binding (read-kbd-macro - (let ((case-fold-search)) - (replace-regexp-in-string - (regexp-quote (cdr rep)) - (car rep) - (key-description binding)))))) - (let ((key (lookup-key orgstruct-mode-map binding))) - (when (or (not key) (numberp key)) - (condition-case nil - (org-defkey orgstruct-mode-map - binding - (orgstruct-make-binding f binding disable-when-heading-prefix)) - (error nil)))))))) + (let ((new-bindings)) + (dolist (binding (nconc (where-is-internal f org-mode-map) + (where-is-internal f outline-mode-map))) + (push binding new-bindings) + ;; TODO use local-function-key-map + (dolist (rep '(("<tab>" . "TAB") + ("<return>" . "RET") + ("<escape>" . "ESC") + ("<delete>" . "DEL"))) + (setq binding (read-kbd-macro + (let ((case-fold-search)) + (replace-regexp-in-string + (regexp-quote (cdr rep)) + (car rep) + (key-description binding))))) + (pushnew binding new-bindings :test 'equal))) + (dolist (binding new-bindings) + (let ((key (lookup-key orgstruct-mode-map binding))) + (when (or (not key) (numberp key)) + (condition-case nil + (org-defkey orgstruct-mode-map + binding + (orgstruct-make-binding f binding disable-when-heading-prefix)) + (error nil))))))))) (run-hooks 'orgstruct-setup-hook)) (defun orgstruct-make-binding (fun key disable-when-heading-prefix) @@ -9028,7 +9049,10 @@ if `orgstruct-heading-prefix-regexp' is non-nil." (not (let* ,bindings (org-context-p 'headline 'item - ,(when (memq fun '(org-insert-heading)) + ,(when (memq fun + '(org-insert-heading + org-insert-heading-respect-content + org-meta-return)) '(when orgstruct-is-++ 'item-body)))))))) (if fallback @@ -9713,7 +9737,7 @@ according to FMT (default from `org-email-link-description-format')." This is the list that is used for internal purposes.") (defconst org-link-escape-chars-browser - '(?\ ) + '(?\ ?\") "List of escapes for characters that are problematic in links. This is the list that is used before handing over to the browser.") @@ -10443,16 +10467,24 @@ application the system uses for this file type." (apply cmd (nreverse args1)))) ((member type '("http" "https" "ftp" "news")) - (browse-url (concat type ":" (if (org-string-match-p "[[:nonascii:] ]" path) - (org-link-escape - path org-link-escape-chars-browser) - path)))) + (browse-url + (concat type ":" + (if (org-string-match-p + (concat "[[:nonascii:]" + org-link-escape-chars-browser "]") + path) + (org-link-escape path org-link-escape-chars-browser) + path)))) ((string= type "doi") - (browse-url (concat org-doi-server-url (if (org-string-match-p "[[:nonascii:] ]" path) - (org-link-escape - path org-link-escape-chars-browser) - path)))) + (browse-url + (concat org-doi-server-url + (if (org-string-match-p + (concat "[[:nonascii:]" + org-link-escape-chars-browser "]") + path) + (org-link-escape path org-link-escape-chars-browser) + path)))) ((member type '("message")) (browse-url (concat type ":" path))) @@ -10508,8 +10540,14 @@ application the system uses for this file type." (error "Abort")))) ((and (string= type "thisfile") - (run-hook-with-args-until-success - 'org-open-link-functions path))) + (or (run-hook-with-args-until-success + 'org-open-link-functions path) + (and (string-match "^id:" link) + (or (featurep 'org-id) (require 'org-id)) + (progn + (funcall (nth 1 (assoc "id" org-link-protocols)) + (substring path 3)) + t))))) ((string= type "thisfile") (if arg @@ -11406,7 +11444,6 @@ the different parts of the path and defaults to \"/\". If JUST-RETURN-STRING is non-nil, return a string, don't display a message." (interactive "P") (let* (case-fold-search - message-log-max ; Don't populate the *Messages* buffer (bfn (buffer-file-name (buffer-base-buffer))) (path (and (derived-mode-p 'org-mode) (org-get-outline-path))) res) @@ -11423,7 +11460,7 @@ If JUST-RETURN-STRING is non-nil, return a string, don't display a message." separator)) (if just-return-string (org-no-properties res) - (message "%s" res)))) + (org-unlogged-message "%s" res)))) (defvar org-refile-history nil "History for refiling operations.") @@ -11462,7 +11499,13 @@ and not actually move anything. 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. + +With a numeric prefix argument of `2', refile to the running clock. + +With a numeric prefix argument of `3', emulate `org-refile-keep' +being set to `t' and copy to the target location, don't move it. +Beware that keeping refiled entries may result in duplicated ID +properties. RFLOC can be a refile location obtained in a different way. @@ -11485,6 +11528,7 @@ prefix argument (`C-u C-u C-u C-c C-w')." (region-start (and regionp (region-beginning))) (region-end (and regionp (region-end))) (filename (buffer-file-name (buffer-base-buffer cbuf))) + (org-refile-keep (if (equal goto 3) t org-refile-keep)) pos it nbuf file re level reversed) (setq last-command nil) (when regionp @@ -11543,7 +11587,7 @@ prefix argument (`C-u C-u C-u C-c C-w')." (setq nbuf (or (find-buffer-visiting file) (find-file-noselect file))) - (if goto + (if (and goto (not (equal goto 3))) (progn (org-pop-to-buffer-same-window nbuf) (goto-char pos) @@ -11584,13 +11628,19 @@ prefix argument (`C-u C-u C-u C-c C-w')." (and org-auto-align-tags (let ((org-loop-over-headlines-in-active-region nil)) (org-set-tags nil t))) - (with-demoted-errors - (bookmark-set "org-refile-last-stored")) + (let ((bookmark-name (plist-get org-bookmark-names-plist + :last-refile))) + (when bookmark-name + (with-demoted-errors + (bookmark-set bookmark-name)))) ;; 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) - (with-demoted-errors - (bookmark-set "org-capture-last-stored-marker")) + (let ((bookmark-name (plist-get org-bookmark-names-plist + :last-capture-marker))) + (when bookmark-name + (with-demoted-errors + (bookmark-set bookmark-name)))) (move-marker org-capture-last-stored-marker (point))) (if (fboundp 'deactivate-mark) (deactivate-mark)) (run-hooks 'org-after-refile-insert-hook)))) @@ -11913,22 +11963,21 @@ This function can be used in a hook." ;;;; Completion +(declare-function org-export-backend-name "org-export" (cl-x)) +(declare-function org-export-backend-options "org-export" (cl-x)) (defun org-get-export-keywords () "Return a list of all currently understood export keywords. Export keywords include options, block names, attributes and keywords relative to each registered export back-end." - (delq nil - (let (keywords) - (mapc - (lambda (back-end) - (let ((props (cdr back-end))) - ;; Back-end name (for keywords, like #+LATEX:) - (push (upcase (symbol-name (car back-end))) keywords) - ;; Back-end options. - (mapc (lambda (option) (push (cadr option) keywords)) - (plist-get (cdr back-end) :options-alist)))) - (org-bound-and-true-p org-export-registered-backends)) - keywords))) + (let (keywords) + (dolist (backend + (org-bound-and-true-p org-export--registered-backends) + (delq nil keywords)) + ;; Back-end name (for keywords, like #+LATEX:) + (push (upcase (symbol-name (org-export-backend-name backend))) keywords) + (dolist (option-entry (org-export-backend-options backend)) + ;; Back-end options. + (push (nth 1 option-entry) keywords))))) (defconst org-options-keywords '("ARCHIVE:" "AUTHOR:" "BIND:" "CATEGORY:" "COLUMNS:" "CREATOR:" "DATE:" @@ -14006,10 +14055,19 @@ See also `org-scan-tags'. minus tag mm tagsmatch todomatch tagsmatcher todomatcher kwd matcher orterms term orlist re-p str-p level-p level-op time-p - prop-p pn pv po gv rest) + prop-p pn pv po gv rest (start 0) (ss 0)) ;; Expand group tags (setq match (org-tags-expand match)) - (if (string-match "/+" match) + + ;; Check if there is a TODO part of this match, which would be the + ;; part after a "/". TO make sure that this slash is not part of + ;; a property value to be matched against, we also check that there + ;; is no " after that slash. + ;; First, find the last slash + (while (string-match "/+" match ss) + (setq start (match-beginning 0) ss (match-end 0))) + (if (and (string-match "/+" match start) + (not (save-match-data (string-match "\"" match start)))) ;; match contains also a todo-matching request (progn (setq tagsmatch (substring match 0 (match-beginning 0)) @@ -15002,16 +15060,6 @@ Being in this list makes sure that they are offered for completion.") org-property-end-re "\\)\n?") "Matches an entire clock drawer.") -(defsubst org-re-property (property) - "Return a regexp matching a PROPERTY line. -Match group 1 will be set to the value." - (concat "^[ \t]*:" (regexp-quote property) ":[ \t]*\\(\\S-.*\\)")) - -(defsubst org-re-property-keyword (property) - "Return a regexp matching a PROPERTY line, possibly with no -value for the property." - (concat "^[ \t]*:" (regexp-quote property) ":[ \t]*\\(\\S-.*\\)?")) - (defun org-property-action () "Do an action on properties." (interactive) @@ -15092,13 +15140,9 @@ When INCREMENT is non-nil, set the property to the next allowed value." (defun org-at-property-p () "Is cursor inside a property drawer?" (save-excursion - (beginning-of-line 1) - (when (looking-at (org-re "^[ \t]*\\(:\\([[:alpha:]][[:alnum:]_-]*\\):\\)[ \t]*\\(.*\\)")) - (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)))))))) + (when (equal 'node-property (car (org-element-at-point))) + (beginning-of-line 1) + (looking-at org-property-re)))) (defun org-get-property-block (&optional beg end force) "Return the (beg . end) range of the body of the property drawer. @@ -15223,11 +15267,10 @@ things up because then unnecessary parsing is avoided." (setq range (org-get-property-block beg end)) (when range (goto-char (car range)) - (while (re-search-forward - (org-re "^[ \t]*:\\([[:alpha:]][[:alnum:]_-]*\\):[ \t]*\\(\\S-.*\\)?") + (while (re-search-forward org-property-re (cdr range) t) - (setq key (org-match-string-no-properties 1) - value (org-trim (or (org-match-string-no-properties 2) ""))) + (setq key (org-match-string-no-properties 2) + value (org-trim (or (org-match-string-no-properties 3) ""))) (unless (member key excluded) (push (cons key (or value "")) props))))) (if clocksum @@ -15276,8 +15319,8 @@ when a \"nil\" value can supersede a non-nil value higher up the hierarchy." (setq props (org-update-property-plist key - (if (match-end 1) - (org-match-string-no-properties 1) "") + (if (match-end 3) + (org-match-string-no-properties 3) "") props))))) val) (goto-char (car range)) @@ -15466,7 +15509,7 @@ and the new value.") (setq range (org-get-property-block beg end 'force)) (goto-char (car range)) (if (re-search-forward - (org-re-property-keyword property) (cdr range) t) + (org-re-property property) (cdr range) t) (progn (delete-region (match-beginning 0) (match-end 0)) (goto-char (match-beginning 0))) @@ -15496,10 +15539,9 @@ formats in the current buffer." (while (re-search-forward org-property-start-re nil t) (setq range (org-get-property-block)) (goto-char (car range)) - (while (re-search-forward - (org-re "^[ \t]*:\\([-[:alnum:]_]+\\):") + (while (re-search-forward org-property-re (cdr range) t) - (add-to-list 'rtn (org-match-string-no-properties 1))) + (add-to-list 'rtn (org-match-string-no-properties 2))) (outline-next-heading)))) (when include-specials @@ -15537,7 +15579,7 @@ formats in the current buffer." (let ((re (org-re-property key)) values) (while (re-search-forward re nil t) - (add-to-list 'values (org-trim (match-string 1)))) + (add-to-list 'values (org-trim (match-string 3)))) (delete "" values))))) (defun org-insert-property-drawer () @@ -15566,7 +15608,9 @@ formats in the current buffer." (beginning-of-line 1))) (org-skip-over-state-notes) (skip-chars-backward " \t\n\r") - (if (eq (char-before) ?*) (forward-char 1)) + (if (and (eq (char-before) ?*) (not (eq (char-after) ?\n))) + (forward-char 1)) + (goto-char (point-at-eol)) (let ((inhibit-read-only t)) (insert "\n:PROPERTIES:\n:END:")) (beginning-of-line 0) (org-indent-to-column indent) @@ -15999,7 +16043,10 @@ If there is already a timestamp at the cursor, it will be modified. With two universal prefix arguments, insert an active timestamp -with the current time without prompting the user." +with the current time without prompting the user. + +When called from lisp, the timestamp is inactive if INACTIVE is +non-nil." (interactive "P") (let* ((ts nil) (default-time @@ -16046,7 +16093,7 @@ with the current time without prompting the user." " " repeater ">")))) (message "Timestamp updated")) ((equal arg '(16)) - (org-insert-time-stamp (current-time) t)) + (org-insert-time-stamp (current-time) t inactive)) (t (setq time (let ((this-command this-command)) (org-read-date arg 'totime nil nil default-time default-input inactive))) @@ -16068,7 +16115,7 @@ with the current time without prompting the user." (setq dh (- h2 h1) dm (- m2 m1)) (if (< dm 0) (setq dm (+ dm 60) dh (1- dh))) (concat t1 "+" (number-to-string dh) - (if (/= 0 dm) (concat ":" (number-to-string dm)))))))) + (and (/= 0 dm) (format ":%02d" dm))))))) (defun org-time-stamp-inactive (&optional arg) "Insert an inactive time stamp. @@ -16098,7 +16145,8 @@ So these are more for recording a certain time/date." (defvar org-read-date-inactive) (defvar org-read-date-minibuffer-local-map - (let ((map (make-sparse-keymap))) + (let* ((org-replace-disputed-keys nil) + (map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) (org-defkey map (kbd ".") (lambda () (interactive) @@ -17647,6 +17695,21 @@ is not set, the tables are not re-aligned, etc." :version "24.3" :group 'org-agenda) +(defcustom org-agenda-ignore-drawer-properties nil + "Avoid updating text properties when building the agenda. +Properties are used to prepare buffers for effort estimates, appointments, +and subtree-local categories. +If you don't use these in the agenda, you can add them to this list and +agenda building will be a bit faster. +The value is a list, with zero or more of the symbols `effort', `appt', +or `category'." + :type '(set :greedy t + (const effort) + (const appt) + (const category)) + :version "24.3" + :group 'org-agenda) + (defun org-duration-string-to-minutes (s &optional output-to-string) "Convert a duration string S to minutes. @@ -18008,9 +18071,12 @@ When a buffer is unmodified, it is just killed. When modified, it is saved ;; this is only run for setting agenda tags from setup ;; file (org-set-regexps-and-options))) - (org-refresh-category-properties) - (org-refresh-properties org-effort-property 'org-effort) - (org-refresh-properties "APPT_WARNTIME" 'org-appt-warntime) + (or (memq 'category org-agenda-ignore-drawer-properties) + (org-refresh-category-properties)) + (or (memq 'effort org-agenda-ignore-drawer-properties) + (org-refresh-properties org-effort-property 'org-effort)) + (or (memq 'appt org-agenda-ignore-drawer-properties) + (org-refresh-properties "APPT_WARNTIME" 'org-appt-warntime)) (setq org-todo-keywords-for-agenda (append org-todo-keywords-for-agenda org-todo-keywords-1)) (setq org-done-keywords-for-agenda @@ -18222,37 +18288,38 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." (interactive "P") (unless buffer-file-name (user-error "Can't preview LaTeX fragment in a non-file buffer")) - (org-remove-latex-fragment-image-overlays) - (save-excursion - (save-restriction - (let (beg end at msg) - (cond - ((or (equal subtree '(16)) - (not (save-excursion - (re-search-backward org-outline-regexp-bol nil t)))) - (setq beg (point-min) end (point-max) - msg "Creating images for buffer...%s")) - ((equal subtree '(4)) - (org-back-to-heading) - (setq beg (point) end (org-end-of-subtree t) - msg "Creating images for subtree...%s")) - (t - (if (setq at (org-inside-LaTeX-fragment-p)) - (goto-char (max (point-min) (- (cdr at) 2))) - (org-back-to-heading)) - (setq beg (point) end (progn (outline-next-heading) (point)) - msg (if at "Creating image...%s" - "Creating images for entry...%s")))) - (message msg "") - (narrow-to-region beg end) - (goto-char beg) - (org-format-latex - (concat org-latex-preview-ltxpng-directory (file-name-sans-extension - (file-name-nondirectory - buffer-file-name))) - default-directory 'overlays msg at 'forbuffer - org-latex-create-formula-image-program) - (message msg "done. Use `C-c C-c' to remove images."))))) + (when (display-graphic-p) + (org-remove-latex-fragment-image-overlays) + (save-excursion + (save-restriction + (let (beg end at msg) + (cond + ((or (equal subtree '(16)) + (not (save-excursion + (re-search-backward org-outline-regexp-bol nil t)))) + (setq beg (point-min) end (point-max) + msg "Creating images for buffer...%s")) + ((equal subtree '(4)) + (org-back-to-heading) + (setq beg (point) end (org-end-of-subtree t) + msg "Creating images for subtree...%s")) + (t + (if (setq at (org-inside-LaTeX-fragment-p)) + (goto-char (max (point-min) (- (cdr at) 2))) + (org-back-to-heading)) + (setq beg (point) end (progn (outline-next-heading) (point)) + msg (if at "Creating image...%s" + "Creating images for entry...%s")))) + (message msg "") + (narrow-to-region beg end) + (goto-char beg) + (org-format-latex + (concat org-latex-preview-ltxpng-directory (file-name-sans-extension + (file-name-nondirectory + buffer-file-name))) + default-directory 'overlays msg at 'forbuffer + org-latex-create-formula-image-program) + (message msg "done. Use `C-c C-c' to remove images.")))))) (defun org-format-latex (prefix &optional dir overlays msg at forbuffer processing-type) @@ -18485,20 +18552,25 @@ share a good deal of logic." "Invalid value of `org-latex-create-formula-image-program'"))) string tofile options buffer)) +(declare-function org-export-get-backend "ox" (name)) (declare-function org-export--get-global-options "ox" (&optional backend)) (declare-function org-export--get-inbuffer-options "ox" (&optional backend)) +(declare-function org-latex-guess-inputenc "ox-latex" (header)) +(declare-function org-latex-guess-babel-language "ox-latex" (header info)) (defun org-create-formula--latex-header () "Return LaTeX header appropriate for previewing a LaTeX snippet." - (org-latex-guess-inputenc - (org-splice-latex-header - org-format-latex-header - org-latex-default-packages-alist - org-latex-packages-alist t - (plist-get - (org-combine-plists - (org-export--get-global-options 'latex) - (org-export--get-inbuffer-options 'latex)) - :latex-header)))) + (let ((info (org-combine-plists (org-export--get-global-options + (org-export-get-backend 'latex)) + (org-export--get-inbuffer-options + (org-export-get-backend 'latex))))) + (org-latex-guess-babel-language + (org-latex-guess-inputenc + (org-splice-latex-header + org-format-latex-header + org-latex-default-packages-alist + org-latex-packages-alist t + (plist-get info :latex-header))) + info))) ;; This function borrows from Ganesh Swami's latex2png.el (defun org-create-formula-image-with-dvipng (string tofile options buffer) @@ -18581,7 +18653,7 @@ share a good deal of logic." (font-height (face-font 'default)) (face-attribute 'default :height nil))) (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0)) - (dpi (number-to-string (* scale (floor (* 0.9 (if buffer fnh 140.)))))) + (dpi (number-to-string (* scale (floor (if buffer fnh 120.))))) (fg (or (plist-get options (if buffer :foreground :html-foreground)) "black")) (bg (or (plist-get options (if buffer :background :html-background)) @@ -18774,53 +18846,54 @@ 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) - (if (fboundp 'clear-image-cache) (clear-image-cache))) - (save-excursion - (save-restriction - (widen) - (setq beg (or beg (point-min)) end (or end (point-max))) - (goto-char beg) - (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?" - (substring (org-image-file-name-regexp) 0 -2) - "\\)\\]" (if include-linked "" "\\]"))) - (case-fold-search t) - old file ov img type attrwidth width) - (while (re-search-forward re end t) - (setq old (get-char-property-and-overlay (match-beginning 1) - 'org-image-overlay) - file (expand-file-name - (concat (or (match-string 3) "") (match-string 4)))) - (when (image-type-available-p 'imagemagick) - (setq attrwidth (if (or (listp org-image-actual-width) - (null org-image-actual-width)) - (save-excursion - (save-match-data - (when (re-search-backward - "#\\+attr.*:width[ \t]+\\([^ ]+\\)" - (save-excursion - (re-search-backward "^[ \t]*$\\|\\`" nil t)) t) - (string-to-number (match-string 1)))))) - width (cond ((eq org-image-actual-width t) nil) - ((null org-image-actual-width) attrwidth) - ((numberp org-image-actual-width) - org-image-actual-width) - ((listp org-image-actual-width) - (or attrwidth (car org-image-actual-width)))) - type (if width 'imagemagick))) - (when (file-exists-p file) - (if (and (car-safe old) refresh) - (image-refresh (overlay-get (cdr old) 'display)) - (setq img (save-match-data (create-image file type nil :width width))) - (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-remove-overlay)) - (push ov org-inline-image-overlays))))))))) + (when (display-graphic-p) + (unless refresh + (org-remove-inline-images) + (if (fboundp 'clear-image-cache) (clear-image-cache))) + (save-excursion + (save-restriction + (widen) + (setq beg (or beg (point-min)) end (or end (point-max))) + (goto-char beg) + (let ((re (concat "\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\([^]\n]+?" + (substring (org-image-file-name-regexp) 0 -2) + "\\)\\]" (if include-linked "" "\\]"))) + (case-fold-search t) + old file ov img type attrwidth width) + (while (re-search-forward re end t) + (setq old (get-char-property-and-overlay (match-beginning 1) + 'org-image-overlay) + file (expand-file-name + (concat (or (match-string 3) "") (match-string 4)))) + (when (image-type-available-p 'imagemagick) + (setq attrwidth (if (or (listp org-image-actual-width) + (null org-image-actual-width)) + (save-excursion + (save-match-data + (when (re-search-backward + "#\\+attr.*:width[ \t]+\\([^ ]+\\)" + (save-excursion + (re-search-backward "^[ \t]*$\\|\\`" nil t)) t) + (string-to-number (match-string 1)))))) + width (cond ((eq org-image-actual-width t) nil) + ((null org-image-actual-width) attrwidth) + ((numberp org-image-actual-width) + org-image-actual-width) + ((listp org-image-actual-width) + (or attrwidth (car org-image-actual-width)))) + type (if width 'imagemagick))) + (when (file-exists-p file) + (if (and (car-safe old) refresh) + (image-refresh (overlay-get (cdr old) 'display)) + (setq img (save-match-data (create-image file type nil :width width))) + (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-remove-overlay)) + (push ov org-inline-image-overlays)))))))))) (define-obsolete-function-alias 'org-display-inline-modification-hook 'org-display-inline-remove-overlay "24.3") @@ -19036,6 +19109,8 @@ BEG and END default to the buffer boundaries." (org-defkey org-mode-map "\C-c\C-k" 'org-kill-note-or-show-branches) (org-defkey org-mode-map "\C-c#" 'org-update-statistics-cookies) (org-defkey org-mode-map [remap open-line] 'org-open-line) +(org-defkey org-mode-map [remap forward-paragraph] 'org-forward-paragraph) +(org-defkey org-mode-map [remap backward-paragraph] 'org-backward-paragraph) (org-defkey org-mode-map "\C-m" 'org-return) (org-defkey org-mode-map "\C-j" 'org-return-indent) (org-defkey org-mode-map "\C-c?" 'org-table-field-info) @@ -20153,6 +20228,12 @@ This command does many different things, depending on context: (when (and (eq (org-element-type parent) 'item) (= (point-at-bol) (org-element-property :begin parent))) (setq context parent type 'item)))) + ;; When heading text is a link, treat the heading, not the link, + ;; as the current element + (when (eq type 'link) + (let ((parent (org-element-property :parent context))) + (when (and (eq (org-element-type parent) 'headline)) + (setq context parent type 'headline)))) ;; Act according to type of element or object at point. (case type (clock (org-clock-update-time-maybe)) @@ -20298,11 +20379,16 @@ Also updates the keyword regular expressions." (funcall org-finish-function)))) (defun org-open-line (n) - "Insert a new row in tables, call `open-line' elsewhere." + "Insert a new row in tables, call `open-line' elsewhere. +If `org-special-ctrl-o' is nil, just call `open-line' everywhere." (interactive "*p") - (if (org-at-table-p) - (org-table-insert-row) - (open-line n))) + (cond + ((not org-special-ctrl-o) + (open-line n)) + ((org-at-table-p) + (org-table-insert-row)) + (t + (open-line n)))) (defun org-return (&optional indent) "Goto next table row or insert a newline. @@ -20621,17 +20707,22 @@ number of stars to add." (defun org-meta-return (&optional arg) "Insert a new heading or wrap a region in a table. -Calls `org-insert-heading' or `org-table-wrap-region', depending on context. -See the individual commands for more information." +Calls `org-insert-heading' or `org-table-wrap-region', depending +on context. See the individual commands for more information." (interactive "P") (org-check-before-invisible-edit 'insert) - (cond - ((run-hook-with-args-until-success 'org-metareturn-hook)) - ((or (org-at-drawer-p) (org-in-drawer-p) (org-at-property-p)) - (newline-and-indent)) - ((org-at-table-p) - (call-interactively 'org-table-wrap-region)) - (t (call-interactively 'org-insert-heading)))) + (or (run-hook-with-args-until-success 'org-metareturn-hook) + (let* ((element (org-element-at-point)) + (type (org-element-type element))) + (when (eq type 'table-row) + (setq element (org-element-property :parent element)) + (setq type 'table)) + (if (and (eq type 'table) + (eq (org-element-property :type element) 'org) + (>= (point) (org-element-property :contents-begin element)) + (< (point) (org-element-property :contents-end element))) + (call-interactively 'org-table-wrap-region) + (call-interactively 'org-insert-heading))))) ;;; Menu entries @@ -21733,6 +21824,20 @@ Taken from `reduce' in cl-seq.el with all keyword arguments but (setq cl-accum (funcall cl-func cl-accum (pop cl-seq)))) cl-accum)) +(defun org-every (pred seq) + "Return true if PREDICATE is true of every element of SEQ. +Adapted from `every' in cl.el." + (catch 'org-every + (mapc (lambda (e) (unless (funcall pred e) (throw 'org-every nil))) seq) + t)) + +(defun org-some (pred seq) + "Return true if PREDICATE is true of any element of SEQ. +Adapted from `some' in cl.el." + (catch 'org-some + (mapc (lambda (e) (when (funcall pred e) (throw 'org-some t))) seq) + nil)) + (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." @@ -21997,11 +22102,10 @@ hierarchy of headlines by UP levels before marking the subtree." ;; Special polishing for properties, see `org-property-format' (setq column (current-column)) (beginning-of-line 1) - (if (looking-at - "\\([ \t]*\\)\\(:[-_0-9a-zA-Z]+:\\)[ \t]*\\(\\S-.*\\(\\S-\\|$\\)\\)") - (replace-match (concat (match-string 1) + (if (looking-at org-property-re) + (replace-match (concat (match-string 4) (format org-property-format - (match-string 2) (match-string 3))) + (match-string 1) (match-string 3))) t t)) (org-move-to-column column)))) @@ -22074,28 +22178,26 @@ hierarchy of headlines by UP levels before marking the subtree." ;; `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 () - (interactive) + (require 'org-element) ;; Prevent auto-fill from inserting unwanted new items. (when (boundp 'fill-nobreak-predicate) (org-set-local 'fill-nobreak-predicate (org-uniquify (append fill-nobreak-predicate - '(org-fill-paragraph-separate-nobreak-p - org-fill-line-break-nobreak-p + '(org-fill-line-break-nobreak-p org-fill-paragraph-with-timestamp-nobreak-p))))) + (let ((paragraph-ending (substring org-element-paragraph-separate 1))) + (org-set-local 'paragraph-start paragraph-ending) + (org-set-local 'paragraph-separate paragraph-ending)) (org-set-local 'fill-paragraph-function 'org-fill-paragraph) (org-set-local 'auto-fill-inhibit-regexp nil) (org-set-local 'adaptive-fill-function 'org-adaptive-fill-function) (org-set-local 'normal-auto-fill-function 'org-auto-fill-function) (org-set-local 'comment-line-break-function 'org-comment-line-break-function)) -(defvar org-element-paragraph-separate) ; org-element.el -(defun org-fill-paragraph-separate-nobreak-p () - "Non-nil when a new line at point would end current paragraph." - (looking-at (substring org-element-paragraph-separate 1))) - (defun org-fill-line-break-nobreak-p () "Non-nil when a new line at point would create an Org line break." (save-excursion @@ -22115,70 +22217,73 @@ hierarchy of headlines by UP levels before marking the subtree." Return fill prefix, as a string, or nil if current line isn't meant to be filled. For convenience, if `adaptive-fill-regexp' matches in paragraphs or comments, use it." - (let (prefix) - (catch 'exit - (when (derived-mode-p 'message-mode) - (save-excursion - (beginning-of-line) - (cond ((or (not (message-in-body-p)) - (looking-at orgtbl-line-start-regexp)) - (throw 'exit nil)) - ((looking-at message-cite-prefix-regexp) - (throw 'exit (match-string-no-properties 0))) - ((looking-at org-outline-regexp) - (throw 'exit (make-string (length (match-string 0)) ? )))))) - (org-with-wide-buffer - (let* ((p (line-beginning-position)) - (element (save-excursion - (beginning-of-line) - (or (ignore-errors (org-element-at-point)) - (user-error "An element cannot be parsed line %d" - (line-number-at-pos (point)))))) - (type (org-element-type element)) - (post-affiliated (org-element-property :post-affiliated element))) - (unless (and post-affiliated (< p post-affiliated)) - (case type - (comment + (catch 'exit + (when (derived-mode-p 'message-mode) + (save-excursion + (beginning-of-line) + (cond ((or (not (message-in-body-p)) + (looking-at orgtbl-line-start-regexp)) + (throw 'exit nil)) + ((looking-at message-cite-prefix-regexp) + (throw 'exit (match-string-no-properties 0))) + ((looking-at org-outline-regexp) + (throw 'exit (make-string (length (match-string 0)) ? )))))) + (org-with-wide-buffer + (let* ((p (line-beginning-position)) + (element (save-excursion + (beginning-of-line) + (or (ignore-errors (org-element-at-point)) + (user-error "An element cannot be parsed line %d" + (line-number-at-pos (point)))))) + (type (org-element-type element)) + (post-affiliated (org-element-property :post-affiliated element))) + (unless (and post-affiliated (< p post-affiliated)) + (case type + (comment + (save-excursion + (beginning-of-line) + (looking-at "[ \t]*") + (concat (match-string 0) "# "))) + (footnote-definition "") + ((item plain-list) + (make-string (org-list-item-body-column + (or post-affiliated + (org-element-property :begin element))) + ? )) + (paragraph + ;; Fill prefix is usually the same as the current line, + ;; unless the paragraph is at the beginning of an item. + (let ((parent (org-element-property :parent element))) (save-excursion (beginning-of-line) - (looking-at "[ \t]*#") - (goto-char (match-end 0)) - (let ((comment-prefix (match-string 0))) - (if (looking-at adaptive-fill-regexp) - (concat comment-prefix (match-string 0)) - comment-prefix)))) - (footnote-definition "") - ((item plain-list) - (make-string (org-list-item-body-column - (or post-affiliated - (org-element-property :begin element))) - ? )) - (paragraph - ;; Fill prefix is usually the same as the current line, - ;; unless the paragraph is at the beginning of an item. - (let ((parent (org-element-property :parent element))) - (save-excursion - (beginning-of-line) - (cond ((eq (org-element-type parent) 'item) - (make-string (org-list-item-body-column - (org-element-property :begin parent)) - ? )) - ((looking-at adaptive-fill-regexp) (match-string 0)) - ((looking-at "[ \t]+") (match-string 0)) - (t ""))))) - (comment-block - ;; Only fill contents if P is within block boundaries. - (let* ((cbeg (save-excursion (goto-char post-affiliated) - (forward-line) - (point))) - (cend (save-excursion - (goto-char (org-element-property :end element)) - (skip-chars-backward " \r\t\n") - (line-beginning-position)))) - (when (and (>= p cbeg) (< p cend)) - (if (save-excursion (beginning-of-line) (looking-at "[ \t]+")) - (match-string 0) - ""))))))))))) + (cond ((eq (org-element-type parent) 'item) + (make-string (org-list-item-body-column + (org-element-property :begin parent)) + ? )) + ((and adaptive-fill-regexp + ;; Locally disable + ;; `adaptive-fill-function' to let + ;; `fill-context-prefix' handle + ;; `adaptive-fill-regexp' variable. + (let (adaptive-fill-function) + (fill-context-prefix + post-affiliated + (org-element-property :end element))))) + ((looking-at "[ \t]+") (match-string 0)) + (t ""))))) + (comment-block + ;; Only fill contents if P is within block boundaries. + (let* ((cbeg (save-excursion (goto-char post-affiliated) + (forward-line) + (point))) + (cend (save-excursion + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-beginning-position)))) + (when (and (>= p cbeg) (< p cend)) + (if (save-excursion (beginning-of-line) (looking-at "[ \t]+")) + (match-string 0) + "")))))))))) (declare-function message-goto-body "message" ()) (defvar message-cite-prefix-regexp) ; From message.el @@ -22588,7 +22693,7 @@ to work in this buffer and calls `reftex-citation' to insert a citation into the buffer. Export of such citations to both LaTeX and HTML is handled by the contributed -package org-exp-bibtex by Taru Karttunen." +package ox-bibtex by Taru Karttunen." (interactive) (let ((reftex-docstruct-symbol 'rds) (reftex-cite-format "\\cite{%l}") @@ -22619,7 +22724,7 @@ beyond the end of the headline." (special (if (consp org-special-ctrl-a/e) (car org-special-ctrl-a/e) org-special-ctrl-a/e)) - refpos) + deactivate-mark refpos) (if (org-bound-and-true-p visual-line-mode) (beginning-of-visual-line 1) (beginning-of-line 1)) @@ -22671,7 +22776,10 @@ beyond the end of the headline." (when (and (= (point) pos) (eq last-command this-command)) (goto-char after-bullet)))))))) (org-no-warnings - (and (featurep 'xemacs) (setq zmacs-region-stays t))))) + (and (featurep 'xemacs) (setq zmacs-region-stays t)))) + (setq disable-point-adjustment + (or (not (invisible-p (point))) + (not (invisible-p (max (point-min) (1- (point)))))))) (defun org-end-of-line (&optional arg) "Go to the end of the line. @@ -22684,7 +22792,8 @@ the cursor is already beyond the end of the headline." (move-fun (cond ((org-bound-and-true-p visual-line-mode) 'end-of-visual-line) ((fboundp 'move-end-of-line) 'move-end-of-line) - (t 'end-of-line)))) + (t 'end-of-line))) + deactivate-mark) (if (or (not special) arg) (call-interactively move-fun) (let* ((element (save-excursion (beginning-of-line) (org-element-at-point))) @@ -22708,7 +22817,10 @@ the cursor is already beyond the end of the headline." ;; after it. Use `end-of-line' to stay on current line. (call-interactively 'end-of-line)) (t (call-interactively move-fun))))) - (org-no-warnings (and (featurep 'xemacs) (setq zmacs-region-stays t))))) + (org-no-warnings (and (featurep 'xemacs) (setq zmacs-region-stays t)))) + (setq disable-point-adjustment + (or (not (invisible-p (point))) + (not (invisible-p (max (point-min) (1- (point)))))))) (define-key org-mode-map "\C-a" 'org-beginning-of-line) (define-key org-mode-map "\C-e" 'org-end-of-line) @@ -23182,6 +23294,152 @@ When BLOCK-REGEXP is non-nil, use this regexp to find blocks." (interactive "p") (org-next-block arg t block-regexp)) +(defun org-forward-paragraph () + "Move forward to beginning of next paragraph or equivalent. + +The function moves point to the beginning of the next visible +structural element, which can be a paragraph, a table, a list +item, etc. It also provides some special moves for convenience: + + - On an affiliated keyword, jump to the beginning of the + relative element. + - On an item or a footnote definition, move to the second + element inside, if any. + - On a table or a property drawer, jump after it. + - On a verse or source block, stop after blank lines." + (interactive) + (when (eobp) (user-error "Cannot move further down")) + (let* ((deactivate-mark nil) + (element (org-element-at-point)) + (type (org-element-type element)) + (post-affiliated (org-element-property :post-affiliated element)) + (contents-begin (org-element-property :contents-begin element)) + (contents-end (org-element-property :contents-end element)) + (end (let ((end (org-element-property :end element)) (parent element)) + (while (and (setq parent (org-element-property :parent parent)) + (= (org-element-property :contents-end parent) end)) + (setq end (org-element-property :end parent))) + end))) + (cond ((not element) + (skip-chars-forward " \r\t\n") + (or (eobp) (beginning-of-line))) + ;; On affiliated keywords, move to element's beginning. + ((and post-affiliated (< (point) post-affiliated)) + (goto-char post-affiliated)) + ;; At a table row, move to the end of the table. Similarly, + ;; at a node property, move to the end of the property + ;; drawer. + ((memq type '(node-property table-row)) + (goto-char (org-element-property + :end (org-element-property :parent element)))) + ((memq type '(property-drawer table)) (goto-char end)) + ;; Consider blank lines as separators in verse and source + ;; blocks to ease editing. + ((memq type '(src-block verse-block)) + (when (eq type 'src-block) + (setq contents-end + (save-excursion (goto-char end) + (skip-chars-backward " \r\t\n") + (line-beginning-position)))) + (beginning-of-line) + (when (looking-at "[ \t]*$") (skip-chars-forward " \r\t\n")) + (if (not (re-search-forward "^[ \t]*$" contents-end t)) + (goto-char end) + (skip-chars-forward " \r\t\n") + (if (= (point) contents-end) (goto-char end) + (beginning-of-line)))) + ;; With no contents, just skip element. + ((not contents-begin) (goto-char end)) + ;; If contents are invisible, skip the element altogether. + ((outline-invisible-p (line-end-position)) + (case type + (headline + (org-with-limited-levels (outline-next-visible-heading 1))) + ;; At a plain list, make sure we move to the next item + ;; instead of skipping the whole list. + (plain-list (forward-char) + (org-forward-paragraph)) + (otherwise (goto-char end)))) + ((>= (point) contents-end) (goto-char end)) + ((>= (point) contents-begin) + ;; This can only happen on paragraphs and plain lists. + (case type + (paragraph (goto-char end)) + ;; At a plain list, try to move to second element in + ;; first item, if possible. + (plain-list (end-of-line) + (org-forward-paragraph)))) + ;; When contents start on the middle of a line (e.g. in + ;; items and footnote definitions), try to reach first + ;; element starting after current line. + ((> (line-end-position) contents-begin) + (end-of-line) + (org-forward-paragraph)) + (t (goto-char contents-begin))))) + +(defun org-backward-paragraph () + "Move backward to start of previous paragraph or equivalent. + +The function moves point to the beginning of the current +structural element, which can be a paragraph, a table, a list +item, etc., or to the beginning of the previous visible one if +point is already there. It also provides some special moves for +convenience: + + - On an affiliated keyword, jump to the first one. + - On a table or a property drawer, move to its beginning. + - On a verse or source block, stop before blank lines." + (interactive) + (when (bobp) (user-error "Cannot move further up")) + (let* ((deactivate-mark nil) + (element (org-element-at-point)) + (type (org-element-type element)) + (contents-begin (org-element-property :contents-begin element)) + (contents-end (org-element-property :contents-end element)) + (post-affiliated (org-element-property :post-affiliated element)) + (begin (org-element-property :begin element))) + (cond + ((not element) (goto-char (point-min))) + ((= (point) begin) + (backward-char) + (org-backward-paragraph)) + ((and post-affiliated (<= (point) post-affiliated)) (goto-char begin)) + ((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)) + ((memq type '(src-block verse-block)) + (when (eq type 'src-block) + (setq contents-begin + (save-excursion (goto-char begin) (forward-line) (point)))) + (if (= (point) contents-begin) (goto-char post-affiliated) + ;; Inside a verse block, see blank lines as paragraph + ;; separators. + (let ((origin (point))) + (skip-chars-backward " \r\t\n" contents-begin) + (when (re-search-backward "^[ \t]*$" contents-begin 'move) + (skip-chars-forward " \r\t\n" origin) + (if (= (point) origin) (goto-char contents-begin) + (beginning-of-line)))))) + ((not contents-begin) (goto-char (or post-affiliated 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 + (org-element-property + :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) + (goto-char (1- contents-end)) + (org-backward-paragraph)) + (t (goto-char (or post-affiliated begin)))) + ;; Ensure we never leave point invisible. + (when (outline-invisible-p (point)) (beginning-of-visual-line)))) + (defun org-forward-element () "Move forward by one element. Move to the next element at the same level, when possible." @@ -23611,7 +23869,8 @@ To get rid of the restriction, use \\[org-agenda-remove-restriction-lock]." (not (member-ignore-case word (org-get-export-keywords))) (not (member-ignore-case word (mapcar 'car org-element-block-name-alist))) - (not (member-ignore-case word '("BEGIN" "END" "ATTR")))))) + (not (member-ignore-case word '("BEGIN" "END" "ATTR"))) + (not (org-in-src-block-p))))) (defun org-remove-flyspell-overlays-in (beg end) "Remove flyspell overlays in region." |