From 8c31e6b732a45c0ddbbf0a0db7a2cb4ef3af0414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= Date: Wed, 23 Jun 2021 15:25:58 +0200 Subject: [PATCH] org-src.el: Do not indent blank lines, except current one * lisp/org-src.el (org-src--contents-for-write-back): Do not indent blank lines, except for the current line maybe. (org-src--preserve-blank-line): New variable, whether to preserve indentation of the current blank line. (org-src--edit-element): Set `org-src--preserve-blank-line'. * lisp/org.el (org-indent-line): When tab acts natively, do some preindentation, which signals `org-src--edit-element' to preserve the indentation of current blank line. Removing all the whitespace was the original behaviour for all blank lines, before `857ae366b3`. --- lisp/org-src.el | 34 +++++++++++++++++++++++++++------- lisp/org.el | 15 +++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lisp/org-src.el b/lisp/org-src.el index 79f002e56..c6311adbb 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -299,6 +299,9 @@ is 0.") "File name associated to Org source buffer, or nil.") (put 'org-src-source-file-name 'permanent-local t) +(defvar-local org-src--preserve-blank-line nil) +(put 'org-src--preserve-blank-line 'permanent-local t) + (defun org-src--construct-edit-buffer-name (org-buffer-name lang) "Construct the buffer name for a source editing buffer." (concat "*Org Src " org-buffer-name "[ " lang " ]*")) @@ -443,14 +446,21 @@ Assume point is in the corresponding edit buffer." 0)))) (use-tabs? (and (> org-src--tab-width 0) t)) (source-tab-width org-src--tab-width) - (contents (org-with-wide-buffer (buffer-string))) - (write-back org-src--allow-write-back)) + (contents (org-with-wide-buffer + (let ((eol (line-end-position))) + (list (buffer-substring (point-min) eol) + (buffer-substring eol (point-max)))))) + (write-back org-src--allow-write-back) + (preserve-blank-line org-src--preserve-blank-line) + marker) (with-current-buffer write-back-buf ;; Reproduce indentation parameters from source buffer. (setq indent-tabs-mode use-tabs?) (when (> source-tab-width 0) (setq tab-width source-tab-width)) ;; Apply WRITE-BACK function on edit buffer contents. - (insert (org-no-properties contents)) + (insert (org-no-properties (car contents))) + (setq marker (point-marker)) + (insert (org-no-properties (car (cdr contents)))) (goto-char (point-min)) (when (functionp write-back) (save-excursion (funcall write-back))) ;; Add INDENTATION-OFFSET to every line in buffer, @@ -458,10 +468,14 @@ Assume point is in the corresponding edit buffer." (when (> indentation-offset 0) (while (not (eobp)) (skip-chars-forward " \t") - (let ((i (current-column))) - (delete-region (line-beginning-position) (point)) - (indent-to (+ i indentation-offset))) - (forward-line)))))) + (when (or (not (eolp)) ; not a blank line + (and (eq (point) (marker-position marker)) ; current line + preserve-blank-line)) + (let ((i (current-column))) + (delete-region (line-beginning-position) (point)) + (indent-to (+ i indentation-offset)))) + (forward-line))) + (set-marker marker nil)))) (defun org-src--edit-element (datum name &optional initialize write-back contents remote) @@ -506,6 +520,11 @@ Leave point in edit buffer." (block-ind (org-with-point-at (org-element-property :begin datum) (current-indentation))) (content-ind org-edit-src-content-indentation) + (blank-line (save-excursion (beginning-of-line) + (looking-at-p "^[[:space:]]*$"))) + (empty-line (and blank-line (looking-at-p "^$"))) + (preserve-blank-line (or (and blank-line (not empty-line)) + (and empty-line (= (+ block-ind content-ind) 0)))) (preserve-ind (and (memq type '(example-block src-block)) (or (org-element-property :preserve-indent datum) @@ -554,6 +573,7 @@ Leave point in edit buffer." (setq org-src--overlay overlay) (setq org-src--allow-write-back write-back) (setq org-src-source-file-name source-file-name) + (setq org-src--preserve-blank-line preserve-blank-line) ;; Start minor mode. (org-src-mode) ;; Clear undo information so we cannot undo back to the diff --git a/lisp/org.el b/lisp/org.el index 1bd9e02eb..3bc4d0383 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -19164,6 +19164,21 @@ Also align node properties according to `org-property-format'." (org-with-point-at (org-element-property :end element) (skip-chars-backward " \t\n") (line-beginning-position)))) + ;; At the beginning of a blank line, do some preindentation. This + ;; signals org-src--edit-element to preserve the indentation on exit + (when (and (looking-at-p "^[[:space:]]*$") + (not org-src-preserve-indentation)) + (let ((element (org-element-at-point)) + block-content-ind some-ind) + (org-with-point-at (org-element-property :begin element) + (setq block-content-ind (+ (current-indentation) + org-edit-src-content-indentation)) + (forward-line) + (save-match-data (re-search-forward "^[ \t]*\\S-" nil t)) + (backward-char) + (setq some-ind (if (looking-at-p "#\\+end_src") + block-content-ind (current-indentation)))) + (indent-line-to (min block-content-ind some-ind)))) (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))) (t (let ((column (org--get-expected-indentation element nil))) -- 2.32.0