summaryrefslogtreecommitdiff
path: root/lisp/org-src.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org-src.el')
-rw-r--r--lisp/org-src.el148
1 files changed, 85 insertions, 63 deletions
diff --git a/lisp/org-src.el b/lisp/org-src.el
index 89f3238..0e04d4b 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -1,6 +1,6 @@
;;; org-src.el --- Source code examples in Org -*- lexical-binding: t; -*-
;;
-;; Copyright (C) 2004-2016 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2017 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Bastien Guerry <bzg@gnu.org>
@@ -215,7 +215,7 @@ green, respectability.
(choice
(face :tag "Face")
(sexp :tag "Anonymous face"))))
- :version "25.2"
+ :version "26.1"
:package-version '(Org . "9.0"))
(defcustom org-src-tab-acts-natively nil
@@ -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)
@@ -522,9 +545,10 @@ as `org-src-fontify-natively' is non-nil."
(with-current-buffer
(get-buffer-create
(format " *org-src-fontification:%s*" lang-mode))
- (erase-buffer)
- ;; Add string and a final space to ensure property change.
- (insert string " ")
+ (let ((inhibit-modification-hooks nil))
+ (erase-buffer)
+ ;; Add string and a final space to ensure property change.
+ (insert string " "))
(unless (eq major-mode lang-mode) (funcall lang-mode))
(org-font-lock-ensure)
(let ((pos (point-min)) next)
@@ -645,7 +669,8 @@ See also `org-src-mode-hook'."
(setq buffer-offer-save t)
(setq buffer-file-name
(concat (buffer-file-name (marker-buffer org-src--beg-marker))
- "[" (buffer-name) "]")))
+ "[" (buffer-name) "]"))
+ (setq-local write-contents-functions '(org-edit-src-save)))
(setq buffer-read-only t))))
(add-hook 'org-src-mode-hook #'org-src-mode-configure-edit-buffer)
@@ -785,45 +810,46 @@ A coderef format regexp can only match at the end of a line."
(org-footnote-goto-definition label)
(backward-char)
(org-element-context)))
- (inline (eq (org-element-type definition) 'footnote-reference))
+ (inline? (eq 'footnote-reference (org-element-type definition)))
(contents
- (let ((c (org-with-wide-buffer
- (org-trim (buffer-substring-no-properties
- (org-element-property :begin definition)
- (org-element-property :end definition))))))
- (add-text-properties
- 0
- (progn (string-match (if inline "\\`\\[fn:.*?:" "\\`.*?\\]") c)
- (match-end 0))
- '(read-only "Cannot edit footnote label" front-sticky t
- rear-nonsticky t)
- c)
- (when inline
- (let ((l (length c)))
- (add-text-properties
- (1- l) l
- '(read-only "Cannot edit past footnote reference"
- front-sticky nil rear-nonsticky nil)
- c)))
- c)))
+ (org-with-wide-buffer
+ (buffer-substring-no-properties
+ (or (org-element-property :post-affiliated definition)
+ (org-element-property :begin definition))
+ (cond
+ (inline? (1+ (org-element-property :contents-end definition)))
+ ((org-element-property :contents-end definition))
+ (t (goto-char (org-element-property :post-affiliated definition))
+ (line-end-position)))))))
+ (add-text-properties
+ 0
+ (progn (string-match (if inline? "\\`\\[fn:.*?:" "\\`.*?\\]") contents)
+ (match-end 0))
+ '(read-only "Cannot edit footnote label" front-sticky t rear-nonsticky t)
+ contents)
+ (when inline?
+ (let ((l (length contents)))
+ (add-text-properties
+ (1- l) l
+ '(read-only "Cannot edit past footnote reference"
+ front-sticky nil rear-nonsticky nil)
+ contents)))
(org-src--edit-element
definition
(format "*Edit footnote [%s]*" label)
#'org-mode
- `(lambda ()
- (if ,(not inline) (delete-region (point) (search-forward "]"))
- (delete-region (point) (search-forward ":" nil t 2))
- (delete-region (1- (point-max)) (point-max))
- (when (re-search-forward "\n[ \t]*\n" nil t)
- (user-error "Inline definitions cannot contain blank lines"))
- ;; If footnote reference belongs to a table, make sure to
- ;; remove any newline characters in order to preserve
- ;; table's structure.
- (when ,(org-element-lineage definition '(table-cell))
- (while (search-forward "\n" nil t) (delete-char -1)))))
- (concat contents
- (and (not (org-element-property :contents-begin definition))
- " "))
+ (lambda ()
+ (if (not inline?) (delete-region (point) (search-forward "]"))
+ (delete-region (point) (search-forward ":" nil t 2))
+ (delete-region (1- (point-max)) (point-max))
+ (when (re-search-forward "\n[ \t]*\n" nil t)
+ (user-error "Inline definitions cannot contain blank lines"))
+ ;; If footnote reference belongs to a table, make sure to
+ ;; remove any newline characters in order to preserve
+ ;; table's structure.
+ (when (org-element-lineage definition '(table-cell))
+ (while (search-forward "\n" nil t) (replace-match "")))))
+ contents
'remote))
;; Report success.
t))
@@ -915,16 +941,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
@@ -1031,7 +1048,10 @@ Throw an error if there is no such buffer."
(insert edited-code)
(when (and expecting-bol (not (bolp))) (insert "\n")))
(save-buffer)
- (move-overlay overlay beg (point)))))
+ (move-overlay overlay beg (point))))
+ ;; `write-contents-functions' requires the function to return
+ ;; a non-nil value so that other functions are not called.
+ t)
(defun org-edit-src-exit ()
"Kill current sub-editing buffer and return to source buffer."
@@ -1046,8 +1066,10 @@ Throw an error if there is no such buffer."
(code (and write-back (org-src--contents-for-write-back))))
(set-buffer-modified-p nil)
;; Switch to source buffer. Kill sub-editing buffer.
- (let ((edit-buffer (current-buffer)))
- (org-src-switch-to-buffer (marker-buffer beg) 'exit)
+ (let ((edit-buffer (current-buffer))
+ (source-buffer (marker-buffer beg)))
+ (unless source-buffer (error "Source buffer disappeared. Aborting"))
+ (org-src-switch-to-buffer source-buffer 'exit)
(kill-buffer edit-buffer))
;; Insert modified code. Ensure it ends with a newline character.
(org-with-wide-buffer
@@ -1066,7 +1088,7 @@ Throw an error if there is no such buffer."
(cond
;; Block is hidden; move at start of block.
((cl-some (lambda (o) (eq (overlay-get o 'invisible) 'org-hide-block))
- (overlays-at (point)))
+ (overlays-at (point)))
(beginning-of-line 0))
(write-back (org-src--goto-coordinates coordinates beg end))))
;; Clean up left-over markers and restore window configuration.