summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2017-04-29 11:48:45 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-04-29 11:48:45 +0200
commit2a3443f14240dc2de2604ec98e7bb801c9e97615 (patch)
tree20688327a544dc2c6389cfd64740f81858e7a0ae
parentb60edc480d44366e364a46702c9f787f743cdfce (diff)
parent91236a3db3d99cbb4c011726929106fd2689c36d (diff)
downloadorg-mode-2a3443f14240dc2de2604ec98e7bb801c9e97615.tar.gz
Merge branch 'maint'
-rw-r--r--lisp/org-src.el52
-rw-r--r--testing/lisp/test-org-src.el99
2 files changed, 132 insertions, 19 deletions
diff --git a/lisp/org-src.el b/lisp/org-src.el
index b0f952f..850525b 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -240,6 +240,12 @@ issued in the language major mode buffer."
(defvar org-src--preserve-indentation nil)
(defvar org-src--remote nil)
(defvar org-src--saved-temp-window-config nil)
+(defvar org-src--source-type nil
+ "Type of element being edited, as a symbol.")
+(defvar org-src--tab-width nil
+ "Contains `tab-width' value from Org source buffer.
+However, if `indent-tabs-mode' is nil in that buffer, its value
+is 0.")
(defun org-src--construct-edit-buffer-name (org-buffer-name lang)
"Construct the buffer name for a source editing buffer."
@@ -387,20 +393,34 @@ spaces after it as being outside."
(defun org-src--contents-for-write-back ()
"Return buffer contents in a format appropriate for write back.
Assume point is in the corresponding edit buffer."
- (let ((indentation (or org-src--block-indentation 0))
- (preserve-indentation org-src--preserve-indentation)
+ (let ((indentation-offset
+ (if org-src--preserve-indentation 0
+ (+ (or org-src--block-indentation 0)
+ (if (memq org-src--source-type '(example-block src-block))
+ org-edit-src-content-indentation
+ 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))
(with-temp-buffer
+ ;; Reproduce indentation parameters from source buffer.
+ (setq-local indent-tabs-mode use-tabs?)
+ (when (> source-tab-width 0) (setq-local tab-width source-tab-width))
+ ;; Apply WRITE-BACK function on edit buffer contents.
(insert (org-no-properties contents))
(goto-char (point-min))
- (when (functionp write-back) (funcall write-back))
- (unless (or preserve-indentation (= indentation 0))
- (let ((ind (make-string indentation ?\s)))
- (goto-char (point-min))
- (while (not (eobp))
- (when (looking-at-p "[ \t]*\\S-") (insert ind))
- (forward-line))))
+ (when (functionp write-back) (save-excursion (funcall write-back)))
+ ;; Add INDENTATION-OFFSET to every non-empty line in buffer,
+ ;; unless indentation is meant to be preserved.
+ (when (> indentation-offset 0)
+ (while (not (eobp))
+ (skip-chars-forward " \t")
+ (unless (eolp) ;ignore blank lines
+ (let ((i (current-column)))
+ (delete-region (line-beginning-position) (point))
+ (indent-to (+ i indentation-offset))))
+ (forward-line)))
(buffer-string))))
(defun org-src--edit-element
@@ -438,6 +458,7 @@ Leave point in edit buffer."
(with-current-buffer old-edit-buffer (org-src--remove-overlay))
(kill-buffer old-edit-buffer))
(let* ((org-mode-p (derived-mode-p 'org-mode))
+ (source-tab-width (if indent-tabs-mode tab-width 0))
(type (org-element-type datum))
(ind (org-with-wide-buffer
(goto-char (org-element-property :begin datum))
@@ -477,10 +498,12 @@ Leave point in edit buffer."
;; Transmit buffer-local variables for exit function. It must
;; be done after initializing major mode, as this operation
;; may reset them otherwise.
+ (setq-local org-src--tab-width source-tab-width)
(setq-local org-src--from-org-mode org-mode-p)
(setq-local org-src--beg-marker beg)
(setq-local org-src--end-marker end)
(setq-local org-src--remote remote)
+ (setq-local org-src--source-type type)
(setq-local org-src--block-indentation ind)
(setq-local org-src--preserve-indentation preserve-ind)
(setq-local org-src--overlay overlay)
@@ -939,16 +962,7 @@ name of the sub-editing buffer."
(org-src--construct-edit-buffer-name (buffer-name) lang))
lang-f
(and (null code)
- `(lambda ()
- (unless ,(or org-src-preserve-indentation
- (org-element-property :preserve-indent element))
- (when (> org-edit-src-content-indentation 0)
- (while (not (eobp))
- (unless (looking-at "[ \t]*$")
- (indent-line-to (+ (org-get-indentation)
- org-edit-src-content-indentation)))
- (forward-line))))
- (org-escape-code-in-region (point-min) (point-max))))
+ (lambda () (org-escape-code-in-region (point-min) (point-max))))
(and code (org-unescape-code-in-string code)))
;; Finalize buffer.
(setq-local org-coderef-label-format
diff --git a/testing/lisp/test-org-src.el b/testing/lisp/test-org-src.el
index 1386f22..853e15b 100644
--- a/testing/lisp/test-org-src.el
+++ b/testing/lisp/test-org-src.el
@@ -266,5 +266,104 @@ This is a tab:\t.
(string-match-p (org-src-coderef-regexp "; ref:%s" "label2")
"#+BEGIN_SRC emacs-lisp\n0; ref:label\n#+END_SRC")))
+(ert-deftest test-org-src/indented-blocks ()
+ "Test editing indented blocks."
+ ;; Editing a block should preserve its global indentation, unless
+ ;; `org-src-preserve-indentation' is non-nil.
+ (should
+ (equal
+ "- Item\n #+BEGIN_SRC emacs-lisp\n Foo\n #+END_SRC"
+ (org-test-with-temp-text
+ "- Item\n<point> #+BEGIN_SRC emacs-lisp\n (+ 1 1)\n #+END_SRC"
+ (let ((org-edit-src-content-indentation 2)
+ (org-src-preserve-indentation nil))
+ (org-edit-special)
+ (erase-buffer)
+ (insert "Foo")
+ (org-edit-src-exit)
+ (buffer-string)))))
+ (should
+ (equal
+ "- Item\n #+BEGIN_SRC emacs-lisp\n Foo\n #+END_SRC"
+ (org-test-with-temp-text
+ "- Item\n<point> #+BEGIN_SRC emacs-lisp\n (+ 1 1)\n #+END_SRC"
+ (let ((org-src-preserve-indentation t))
+ (org-edit-special)
+ (erase-buffer)
+ (insert " Foo")
+ (org-edit-src-exit)
+ (buffer-string)))))
+ ;; Global indentation obeys `indent-tabs-mode' from the original
+ ;; buffer.
+ (should
+ (string-match-p
+ "^\t+\s*argument2"
+ (org-test-with-temp-text
+ "
+- Item
+ #+BEGIN_SRC emacs-lisp<point>
+ (progn
+ (function argument1
+ argument2))
+ #+END_SRC"
+ (setq-local indent-tabs-mode t)
+ (let ((org-edit-src-content-indentation 2)
+ (org-src-preserve-indentation nil))
+ (org-edit-special)
+ (org-edit-src-exit)
+ (buffer-string)))))
+ (should
+ (string-match-p
+ "^\s+argument2"
+ (org-test-with-temp-text
+ "
+- Item
+ #+BEGIN_SRC emacs-lisp<point>
+ (progn\n (function argument1\n\t\targument2))
+ #+END_SRC"
+ (setq-local indent-tabs-mode nil)
+ (let ((org-edit-src-content-indentation 2)
+ (org-src-preserve-indentation nil))
+ (org-edit-special)
+ (org-edit-src-exit)
+ (buffer-string)))))
+ ;; Global indentation also obeys `tab-width' from original buffer.
+ (should
+ (string-match-p
+ "^\t\\{3\\}\s\\{2\\}argument2"
+ (org-test-with-temp-text
+ "
+- Item
+ #+BEGIN_SRC emacs-lisp<point>
+ (progn
+ (function argument1
+ argument2))
+ #+END_SRC"
+ (setq-local indent-tabs-mode t)
+ (setq-local tab-width 4)
+ (let ((org-edit-src-content-indentation 0)
+ (org-src-preserve-indentation nil))
+ (org-edit-special)
+ (org-edit-src-exit)
+ (buffer-string)))))
+ (should
+ (string-match-p
+ "^\t\s\\{6\\}argument2"
+ (org-test-with-temp-text
+ "
+- Item
+ #+BEGIN_SRC emacs-lisp<point>
+ (progn
+ (function argument1
+ argument2))
+ #+END_SRC"
+ (setq-local indent-tabs-mode t)
+ (setq-local tab-width 8)
+ (let ((org-edit-src-content-indentation 0)
+ (org-src-preserve-indentation nil))
+ (org-edit-special)
+ (org-edit-src-exit)
+ (buffer-string))))))
+
(provide 'test-org-src)
;;; test-org-src.el ends here