From 1967aa43e5f14a06cfaff0b2d0e30d57893d0491 Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Thu, 13 Jul 2023 11:51:15 +0300 Subject: [PATCH] org-src-preserve-indentation: Refactor handling src block flags * lisp/org-src.el (org-src-preserve-indentation-p): New function checking whether block should preserve indentation. This function abstracts away the check for block type, indentation flag, and customized `org-src-preserve-indentation' value. (org-src--edit-element): * lisp/ob-core.el (org-babel--normalize-body): (org-babel-read-element): (org-babel-update-block-body): * lisp/ob-exp.el (org-babel-exp-process-buffer): * lisp/org-element.el (org-element-example-block-interpreter): (org-element-src-block-interpreter): * lisp/org.el (org-fixup-indentation): (org-indent-region): * lisp/ox.el (org-export-unravel-code): Use the new function instead of duplicating code. * lisp/ob-haskell.el (org-babel-haskell-export-to-lhs): Add FIXME. We do not have access to the block element here and cannot easily check the flag. * lisp/ob-tangle.el (org-babel-tangle-single-block): * lisp/org-src.el (org-src-font-lock-fontify-block): * lisp/org.el (org-indent-line): Check block flag in addition to `org-src-preserve-indentation'. This commit unifies logic deciding whether to preserve block indentation into a single place to avoid confusion. --- lisp/ob-core.el | 14 ++++---------- lisp/ob-exp.el | 25 +++++++++++-------------- lisp/ob-haskell.el | 1 + lisp/ob-tangle.el | 3 +-- lisp/org-element.el | 10 +++------- lisp/org-src.el | 27 ++++++++++++++++----------- lisp/org.el | 24 ++++++++---------------- lisp/ox.el | 4 +--- 8 files changed, 45 insertions(+), 63 deletions(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 47410b53f..e470efa9e 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -43,7 +43,6 @@ (defvar org-edit-src-content-indentation) (defvar org-link-file-path-type) (defvar org-src-lang-modes) -(defvar org-src-preserve-indentation) (defvar org-babel-tangle-uncomment-comments) (declare-function org-attach-dir "org-attach" (&optional create-if-not-exists-p no-fs-check)) @@ -60,6 +59,7 @@ (declare-function org-cycle "org-cycle" (&optional arg)) (declare-function org-edit-src-code "org-src" (&optional code edit-buffer-name)) (declare-function org-edit-src-exit "org-src" ()) +(declare-function org-src-preserve-indentation-p "org-src" (node)) (declare-function org-element-at-point "org-element" (&optional pom cached-only)) (declare-function org-element-at-point-no-context "org-element" (&optional pom)) (declare-function org-element-context "org-element" (&optional element)) @@ -661,9 +661,7 @@ Remove final newline character and spurious indentation." ;; src-block are not meaningful, since they could come from ;; some paragraph filling. Treat them as a white space. (replace-regexp-in-string "\n[ \t]*" " " body)) - ((or org-src-preserve-indentation - (org-element-property :preserve-indent datum)) - body) + ((org-src-preserve-indentation-p datum) body) (t (org-remove-indentation body))))) ;;; functions @@ -2245,9 +2243,7 @@ Return nil if ELEMENT cannot be read." (`plain-list (org-babel-read-list)) ((or `example-block `src-block) (let ((v (org-element-property :value element))) - (if (or org-src-preserve-indentation - (org-element-property :preserve-indent element)) - v + (if (org-src-preserve-indentation-p element) v (org-remove-indentation v)))) (`export-block (org-remove-indentation (org-element-property :value element))) @@ -2820,9 +2816,7 @@ specified as an an \"attachment:\" style link." (let* ((ind (org-current-text-indentation)) (body-start (line-beginning-position 2)) (body (org-element-normalize-string - (if (or org-src-preserve-indentation - (org-element-property :preserve-indent element)) - new-body + (if (org-src-preserve-indentation-p element) new-body (with-temp-buffer (insert (org-remove-indentation new-body)) (indent-rigidly diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el index 1cd842523..0aac1da03 100644 --- a/lisp/ob-exp.el +++ b/lisp/ob-exp.el @@ -43,8 +43,7 @@ drop-locals)) (declare-function org-in-commented-heading-p "org" (&optional no-inheritance element)) (declare-function org-in-archived-heading-p "org" (&optional no-inheritance element)) - -(defvar org-src-preserve-indentation) +(declare-function org-src-preserve-indentation-p "org-src" (node)) (defcustom org-export-use-babel t "Switch controlling code evaluation and header processing during export. @@ -282,25 +281,23 @@ this template." (forward-line 0) (delete-region begin (point))) (t - (if (or org-src-preserve-indentation - (org-element-property - :preserve-indent element)) + (if (org-src-preserve-indentation-p element) ;; Indent only code block ;; markers. (with-temp-buffer - ;; Do not use tabs for block - ;; indentation. - (when (fboundp 'indent-tabs-mode) + ;; Do not use tabs for block + ;; indentation. + (when (fboundp 'indent-tabs-mode) (indent-tabs-mode -1) ;; FIXME: Emacs 26 ;; compatibility. (setq-local indent-tabs-mode nil)) - (insert replacement) - (skip-chars-backward " \r\t\n") - (indent-line-to ind) - (goto-char 1) - (indent-line-to ind) - (setq replacement (buffer-string))) + (insert replacement) + (skip-chars-backward " \r\t\n") + (indent-line-to ind) + (goto-char 1) + (indent-line-to ind) + (setq replacement (buffer-string))) ;; Indent everything. (with-temp-buffer ;; Do not use tabs for block diff --git a/lisp/ob-haskell.el b/lisp/ob-haskell.el index 909de19ab..5babb2bb9 100644 --- a/lisp/ob-haskell.el +++ b/lisp/ob-haskell.el @@ -236,6 +236,7 @@ constructs (header arguments, no-web syntax etc...) are ignored." (command (concat org-babel-haskell-lhs2tex-command " " (org-babel-process-file-name lhs-file) " > " (org-babel-process-file-name tex-file))) + ;; FIXME: What if src block has :preserve-indentation flag? (preserve-indentp org-src-preserve-indentation) indentation) ;; escape haskell source-code blocks diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index 25129616f..b6ae4b55a 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -590,8 +590,7 @@ non-nil, return the full association list to be used by link source-name params - (if org-src-preserve-indentation - (org-trim body t) + (if (org-src-preserve-indentation-p) (org-trim body t) (org-trim (org-remove-indentation body))) comment))) (if only-this-block diff --git a/lisp/org-element.el b/lisp/org-element.el index 63f0e8a97..b69436f59 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -77,6 +77,7 @@ (declare-function org-at-heading-p "org" (&optional _)) (declare-function org-escape-code-in-string "org-src" (s)) +(declare-function org-src-preserve-indentation-p "org-src" (node)) (declare-function org-macro-escape-arguments "org-macro" (&rest args)) (declare-function org-macro-extract-arguments "org-macro" (s)) (declare-function org-reduced-level "org" (l)) @@ -93,7 +94,6 @@ (defvar org-property-drawer-re) (defvar org-property-format) (defvar org-property-re) -(defvar org-src-preserve-indentation) (defvar org-tags-column) (defvar org-todo-regexp) (defvar org-ts-regexp-both) @@ -2332,9 +2332,7 @@ Return a new syntax node of `example-block' type containing `:begin', (value (let ((val (org-element-property :value example-block))) (cond - ((or org-src-preserve-indentation - (org-element-property :preserve-indent example-block)) - val) + ((org-src-preserve-indentation-p example-block) val) ((= 0 org-edit-src-content-indentation) (org-remove-indentation val)) (t @@ -2867,9 +2865,7 @@ Assume point is at the beginning of the block." (value (let ((val (org-element-property :value src-block))) (cond - ((or org-src-preserve-indentation - (org-element-property :preserve-indent src-block)) - val) + ((org-src-preserve-indentation-p src-block) val) ((zerop org-edit-src-content-indentation) (org-remove-indentation val)) (t diff --git a/lisp/org-src.el b/lisp/org-src.el index 7edbe0570..ade847e8a 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -454,12 +454,20 @@ DATUM is an element or an object. Consider blank lines or white spaces after it as being outside." (and (>= (point) (org-element-begin datum)) (<= (point) - (org-with-wide-buffer - (goto-char (org-element-end datum)) - (skip-chars-backward " \r\t\n") - (if (eq (org-element-class datum) 'element) - (line-end-position) - (point)))))) + (org-with-wide-buffer + (goto-char (org-element-end datum)) + (skip-chars-backward " \r\t\n") + (if (eq (org-element-class datum) 'element) + (line-end-position) + (point)))))) + +(defun org-src-preserve-indentation-p (&optional node) + "Non-nil when indentation should be preserved within NODE. +When NODE is not passed, assume element at point." + (let ((node (or node (org-element-at-point)))) + (and (org-element-type-p node '(example-block src-block)) + (or (org-element-property :preserve-indent node) + org-src-preserve-indentation)))) (defun org-src--contents-for-write-back (write-back-buf) "Populate WRITE-BACK-BUF with contents in the appropriate format. @@ -558,10 +566,7 @@ Leave point in edit buffer." (org-element-parent datum) nil)) (t (org-current-text-indentation))))) (content-ind org-edit-src-content-indentation) - (preserve-ind - (and (memq type '(example-block src-block)) - (or (org-element-property :preserve-indent datum) - org-src-preserve-indentation))) + (preserve-ind (org-src-preserve-indentation-p datum)) ;; Store relative positions of mark (if any) and point ;; within the edited area. (point-coordinates (and (not remote) @@ -716,7 +721,7 @@ as `org-src-fontify-natively' is non-nil." (save-excursion (goto-char start) (let ((indent-offset - (if org-src-preserve-indentation 0 + (if (org-src-preserve-indentation-p) 0 (+ (progn (backward-char) (org-current-text-indentation)) org-edit-src-content-indentation)))) diff --git a/lisp/org.el b/lisp/org.el index 590f8ab96..3e60bb569 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6886,14 +6886,11 @@ Assume point is at a heading or an inlinetask beginning." (forward-line 0) (or (and (looking-at-p "[ \t]*#\\+BEGIN_\\(EXAMPLE\\|SRC\\)") (let ((e (org-element-at-point))) - (and (org-element-type-p - e '(example-block src-block)) - (or org-src-preserve-indentation - (org-element-property :preserve-indent e)) - (goto-char (org-element-end e)) - (progn (skip-chars-backward " \r\t\n") - (forward-line 0) - t)))) + (and (org-src-preserve-indentation-p e) + (goto-char (org-element-end e)) + (progn (skip-chars-backward " \r\t\n") + (forward-line 0) + t)))) (forward-line)))))))) ;; Shift lines but footnote definitions, inlinetasks boundaries ;; by DIFF. Also skip contents of source or example blocks @@ -6911,10 +6908,7 @@ Assume point is at a heading or an inlinetask beginning." (forward-line 0) (or (and (looking-at-p "[ \t]*#\\+BEGIN_\\(EXAMPLE\\|SRC\\)") (let ((e (org-element-at-point))) - (and (org-element-type-p - e '(example-block src-block)) - (or org-src-preserve-indentation - (org-element-property :preserve-indent e)) + (and (org-src-preserve-indentation-p e) (goto-char (org-element-end e)) (progn (skip-chars-backward " \r\t\n") (forward-line 0) @@ -19154,7 +19148,7 @@ Also align node properties according to `org-property-format'." (skip-chars-backward " \t\n") (line-beginning-position)))) (let ((block-content-ind - (when (not org-src-preserve-indentation) + (when (not (org-src-preserve-indentation-p element)) (org-with-point-at (org-element-property :begin element) (+ (org-current-text-indentation) org-edit-src-content-indentation))))) @@ -19208,9 +19202,7 @@ assumed to be significant there." ;; boundaries can. ((or (memq type '(export-block latex-environment)) (and (eq type 'example-block) - (not - (or org-src-preserve-indentation - (org-element-property :preserve-indent element))))) + (not (org-src-preserve-indentation-p element)))) (let ((offset (- ind (current-indentation)))) (unless (zerop offset) (indent-rigidly (org-element-begin element) diff --git a/lisp/ox.el b/lisp/ox.el index cb2b26176..8b1983de1 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4989,9 +4989,7 @@ reference on that line (string)." ;; to the code proper. (code (replace-regexp-in-string "\n\\'" "" - (if (or org-src-preserve-indentation - (org-element-property :preserve-indent element)) - value + (if (org-src-preserve-indentation-p element) value (org-remove-indentation value)))) ;; Build a regexp matching a loc with a reference. (ref-re (org-src-coderef-regexp (org-src-coderef-format element))))