forked from mirrors/org-mode
org-src.el: Use native value of `indent-tabs-mode' for indentation
* lisp/org.el (org-indent-line): Simplify native indentation inside src block. Ensure we add the org indentation if the line is empty. * lisp/org-macs.el (org-do-remove-indentation): Preserve indentation (spaces vs tabs) past the common indentation to remove. Do not empty blank lines. * lisp/org-src.el (org-src--contents-for-write-back): Preserve the native indentation (spaces vs tabs). If necessary, add a common org indentation to the block according to org's `indent-tabs-mode'. (org-src-font-lock-fontify-block): Display the native indentation tab characters with a fixed width, according to the native tab width value, to preserve vertical alignement in the org buffer. * testing/lisp/test-org-src.el (test-org-src/indented-blocks): Update tests. Indentation no longer obeys `indent-tabs-mode' from the org buffer, but is separated in an eventual org part, and the native part. Link: https://list.orgmode.org/87a5wcez7e.fsf@localhost/T/#t
This commit is contained in:
parent
501be358bb
commit
2e2ed40553
|
@ -402,9 +402,12 @@ line. Return nil if it fails."
|
|||
(when skip-fl (forward-line))
|
||||
(while (not (eobp))
|
||||
(let ((ind (progn (skip-chars-forward " \t") (current-column))))
|
||||
(cond ((eolp) (delete-region (line-beginning-position) (point)))
|
||||
((< ind n) (throw :exit nil))
|
||||
(t (indent-line-to (- ind n))))
|
||||
(cond ((< ind n)
|
||||
(if (eolp) (delete-region (line-beginning-position) (point))
|
||||
(throw :exit nil)))
|
||||
(t (delete-region (line-beginning-position)
|
||||
(progn (move-to-column n t)
|
||||
(point)))))
|
||||
(forward-line)))
|
||||
;; Signal success.
|
||||
t))))
|
||||
|
|
|
@ -326,9 +326,6 @@ 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.
|
||||
Format is \"*Org Src ORG-BUFFER-NAME[ LANG ]*\"."
|
||||
|
@ -481,12 +478,17 @@ Assume point is in the corresponding edit buffer."
|
|||
(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.
|
||||
marker indent-str)
|
||||
;; Compute the exact sequence of tabs and spaces used to indent up
|
||||
;; to `indentation-offset' in the Org buffer.
|
||||
(setq indent-str
|
||||
(with-temp-buffer
|
||||
;; Reproduce indentation parameters from org buffer.
|
||||
(setq indent-tabs-mode use-tabs?)
|
||||
(when (> source-tab-width 0) (setq tab-width source-tab-width))
|
||||
(indent-to indentation-offset)
|
||||
(buffer-string)))
|
||||
(with-current-buffer write-back-buf
|
||||
;; Apply WRITE-BACK function on edit buffer contents.
|
||||
(insert (org-no-properties (car contents)))
|
||||
(setq marker (point-marker))
|
||||
|
@ -496,15 +498,14 @@ Assume point is in the corresponding edit buffer."
|
|||
;; Add INDENTATION-OFFSET to every line in buffer,
|
||||
;; unless indentation is meant to be preserved.
|
||||
(when (> indentation-offset 0)
|
||||
;; LaTeX-fragments are inline. Do not add indentation to their
|
||||
;; first line.
|
||||
(when preserve-fl (forward-line))
|
||||
(while (not (eobp))
|
||||
(skip-chars-forward " \t")
|
||||
(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))))
|
||||
;; Keep empty src lines empty, even when src block is
|
||||
;; indented on Org side.
|
||||
;; See https://list.orgmode.org/725763.1632663635@apollo2.minshall.org/T/
|
||||
(when (not (eolp)) (insert indent-str)) ; not an empty line
|
||||
(forward-line)))
|
||||
(set-marker marker nil))))
|
||||
|
||||
|
@ -557,11 +558,6 @@ Leave point in edit buffer."
|
|||
(org-element-parent datum) nil))
|
||||
(t (org-current-text-indentation)))))
|
||||
(content-ind org-edit-src-content-indentation)
|
||||
(blank-line (save-excursion (forward-line 0)
|
||||
(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)
|
||||
|
@ -611,7 +607,6 @@ 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
|
||||
|
@ -645,7 +640,7 @@ Leave point in edit buffer."
|
|||
"Fontify code block between START and END using LANG's syntax.
|
||||
This function is called by Emacs' automatic fontification, as long
|
||||
as `org-src-fontify-natively' is non-nil."
|
||||
(let ((modified (buffer-modified-p)))
|
||||
(let ((modified (buffer-modified-p)) native-tab-width)
|
||||
(remove-text-properties start end '(face nil))
|
||||
(let ((lang-mode (org-src-get-lang-mode lang)))
|
||||
(when (fboundp lang-mode)
|
||||
|
@ -659,6 +654,7 @@ as `org-src-fontify-natively' is non-nil."
|
|||
;; Add string and a final space to ensure property change.
|
||||
(insert string " "))
|
||||
(unless (eq major-mode lang-mode) (funcall lang-mode))
|
||||
(setq native-tab-width tab-width)
|
||||
(font-lock-ensure)
|
||||
(let ((pos (point-min)) next)
|
||||
(while (setq next (next-property-change pos))
|
||||
|
@ -716,6 +712,21 @@ as `org-src-fontify-natively' is non-nil."
|
|||
(when (or (facep src-face) (listp src-face))
|
||||
(font-lock-append-text-property start end 'face src-face))
|
||||
(font-lock-append-text-property start end 'face 'org-block))
|
||||
;; Display native tab indentation characters as spaces
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(let ((indent-offset
|
||||
(if org-src-preserve-indentation 0
|
||||
(+ (progn (backward-char)
|
||||
(org-current-text-indentation))
|
||||
org-edit-src-content-indentation))))
|
||||
(while (re-search-forward "^[ ]*\t" end t)
|
||||
(let* ((b (and (eq indent-offset (move-to-column indent-offset))
|
||||
(point)))
|
||||
(e (progn (skip-chars-forward "\t") (point)))
|
||||
(s (and b (make-string (* (- e b) native-tab-width) ? ))))
|
||||
(when (and b (< b e)) (add-text-properties b e `(display ,s)))
|
||||
(forward-char)))))
|
||||
;; Clear abbreviated link folding.
|
||||
(org-fold-region start end nil 'org-link)
|
||||
(add-text-properties
|
||||
|
|
23
lisp/org.el
23
lisp/org.el
|
@ -19153,21 +19153,14 @@ Also align node properties according to `org-property-format'."
|
|||
(org-with-point-at (org-element-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 (block-content-ind some-ind)
|
||||
(org-with-point-at (org-element-begin element)
|
||||
(setq block-content-ind (+ (org-current-text-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 (org-current-text-indentation))))
|
||||
(indent-line-to (min block-content-ind some-ind))))
|
||||
(org-babel-do-key-sequence-in-edit-buffer (kbd "TAB")))
|
||||
(let ((block-content-ind
|
||||
(when (not org-src-preserve-indentation)
|
||||
(org-with-point-at (org-element-property :begin element)
|
||||
(+ (org-current-text-indentation)
|
||||
org-edit-src-content-indentation)))))
|
||||
(org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))
|
||||
(when (and block-content-ind (looking-at-p "^$"))
|
||||
(indent-line-to block-content-ind))))
|
||||
(t
|
||||
(let ((column (org--get-expected-indentation element nil)))
|
||||
;; Preserve current column.
|
||||
|
|
|
@ -345,11 +345,11 @@ This is a tab:\t.
|
|||
(insert " Foo")
|
||||
(org-edit-src-exit)
|
||||
(buffer-string)))))
|
||||
;; Global indentation obeys `indent-tabs-mode' from the original
|
||||
;; buffer.
|
||||
(should
|
||||
;; Global indentation does not obey `indent-tabs-mode' from the
|
||||
;; original buffer.
|
||||
(should-not
|
||||
(string-match-p
|
||||
"^\t+\s*argument2"
|
||||
"\t"
|
||||
(org-test-with-temp-text
|
||||
"
|
||||
- Item
|
||||
|
@ -364,14 +364,15 @@ This is a tab:\t.
|
|||
(org-edit-special)
|
||||
(org-edit-src-exit)
|
||||
(buffer-string)))))
|
||||
;; Tab character is preserved
|
||||
(should
|
||||
(string-match-p
|
||||
"^\s+argument2"
|
||||
"\targument2"
|
||||
(org-test-with-temp-text
|
||||
"
|
||||
- Item
|
||||
#+BEGIN_SRC emacs-lisp<point>
|
||||
(progn\n (function argument1\n\t\targument2))
|
||||
(progn\n (function argument1\n \targument2))
|
||||
#+END_SRC"
|
||||
(setq-local indent-tabs-mode nil)
|
||||
(let ((org-edit-src-content-indentation 2)
|
||||
|
@ -379,43 +380,59 @@ This is a tab:\t.
|
|||
(org-edit-special)
|
||||
(org-edit-src-exit)
|
||||
(buffer-string)))))
|
||||
;; Global indentation also obeys `tab-width' from original buffer.
|
||||
;; Indentation does not obey `tab-width' from org buffer.
|
||||
(should
|
||||
(string-match-p
|
||||
"^\t\\{3\\}\s\\{2\\}argument2"
|
||||
"^ \targument2"
|
||||
(org-test-with-temp-text
|
||||
"
|
||||
- Item
|
||||
#+BEGIN_SRC emacs-lisp<point>
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(progn
|
||||
(function argument1
|
||||
argument2))
|
||||
#+END_SRC"
|
||||
(list argument1\n \t<point>argument2))
|
||||
#+END_SRC"
|
||||
(setq-local indent-tabs-mode t)
|
||||
(setq-local tab-width 4)
|
||||
(let ((org-edit-src-content-indentation 0)
|
||||
(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
|
||||
"^\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)
|
||||
(lisp-indent-line)
|
||||
(org-edit-src-exit)
|
||||
(buffer-string))))))
|
||||
(buffer-string)))))
|
||||
;; Tab characters are displayed with `tab-width' from the native
|
||||
;; edit buffer.
|
||||
(should
|
||||
(equal
|
||||
10
|
||||
(org-test-with-temp-text
|
||||
"
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(progn
|
||||
(list argument1\n \t<point>argument2))
|
||||
#+END_SRC"
|
||||
(setq-local indent-tabs-mode t)
|
||||
(setq-local tab-width 4)
|
||||
(let ((org-edit-src-content-indentation 2)
|
||||
(org-src-preserve-indentation nil))
|
||||
(font-lock-ensure)
|
||||
(current-column)))))
|
||||
;; The initial tab characters respect org's `tab-width'.
|
||||
(should
|
||||
(equal
|
||||
10
|
||||
(org-test-with-temp-text
|
||||
"
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
\t(progn
|
||||
\t (list argument1\n\t\t<point>argument2))
|
||||
#+END_SRC"
|
||||
(setq-local indent-tabs-mode t)
|
||||
(setq-local tab-width 2)
|
||||
(let ((org-edit-src-content-indentation 2)
|
||||
(org-src-preserve-indentation nil))
|
||||
(font-lock-ensure)
|
||||
(current-column))))))
|
||||
|
||||
(ert-deftest test-org-src/indented-latex-fragments ()
|
||||
"Test editing multiline indented LaTeX fragment."
|
||||
|
|
Loading…
Reference in New Issue