Forráskód Böngészése

Optionally prevent altering indentation of source code.

New customizable variable org-src-preserve-indentation, if non-nil,
prevents automatic removal of rectangular blocks of leading whitespace
in source code blocks. This is necessary when embedding python code in
an org file with a view to extracting all python blocks into a single
file (because whitespace indentation is critical in python code). The
changes in this commit also fix two bugs:

- Setting org-edit-src-content-indentation to zero resulted in an
  infinite loop in org-edit-src-exit.

- Fixed width regions are defined by lines starting with a colon, with
  optional leading whitespace. However, if there was any leading
  whitespace, org-edit-src-exit behaved incorrectly, causing the leading
  whitespace to grow.
Dan Davison 15 éve
szülő
commit
d1eacbcbe8
1 módosított fájl, 36 hozzáadás és 15 törlés
  1. 36 15
      lisp/org-src.el

+ 36 - 15
lisp/org-src.el

@@ -81,11 +81,22 @@ These are the regions where each line starts with a colon."
 	  (const fundamental-mode)
 	  (function :tag "Other (specify)")))
 
+(defcustom org-src-preserve-indentation nil
+  "If non-nil, leading whitespace characters in source code
+  blocks are preserved. Otherwise, after editing with
+  \\[org-edit-src-code], the minimum (across-lines) number of
+  leading whitespace characters are removed from all lines, and
+  the code block is then uniformly indented according to the
+  value of `org-edit-src-content-indentation'."
+  :group 'org-edit-structure
+  :type 'boolean)
+
 (defcustom org-edit-src-content-indentation 2
   "Indentation for the content is a source code block.
 This should be the number of spaces added to the indentation of the #+begin
 line in order to compute the indentation of the block content after
-editing it with \\[org-edit-src-code]."
+editing it with \\[org-edit-src-code]. Has no effect if
+`org-src-preserve-indentation' is non-nil."
   :group 'org-edit-structure
   :type 'integer)
 
@@ -135,7 +146,7 @@ For example, there is no ocaml-mode in Emacs, but the mode to use is
 (defvar org-edit-src-beg-marker nil)
 (defvar org-edit-src-end-marker nil)
 (defvar org-edit-src-overlay nil)
-(defvar org-edit-src-nindent nil)
+(defvar org-edit-src-block-indentation nil)
 
 (define-minor-mode org-src-mode
   "Minor mode for language major mode buffers generated by org.
@@ -160,7 +171,8 @@ the edited version."
 	(org-mode-p (eq major-mode 'org-mode))
 	(beg (make-marker))
 	(end (make-marker))
-	nindent	ovl lang lang-f single lfmt code begline buffer)
+	(preserve-indentation org-src-preserve-indentation)
+	block-nindent total-nindent ovl lang lang-f single lfmt code begline buffer)
     (if (not info)
 	nil
       (setq beg (move-marker beg (nth 0 info))
@@ -171,7 +183,7 @@ the edited version."
 	    lang (if (symbolp lang) (symbol-name lang) lang)
 	    single (nth 3 info)
 	    lfmt (nth 4 info)
-	    nindent (nth 5 info)
+	    block-nindent (nth 5 info)
 	    lang-f (intern (concat lang "-mode"))
 	    begline (save-excursion (goto-char beg) (org-current-line)))
       (unless (functionp lang-f)
@@ -204,11 +216,13 @@ the edited version."
 	(insert code)
 	(remove-text-properties (point-min) (point-max)
 				'(display nil invisible nil intangible nil))
-	(org-do-remove-indentation)
+	(unless preserve-indentation
+	  (setq total-nindent (or (org-do-remove-indentation) 0)))
 	(let ((org-inhibit-startup t))
 	  (funcall lang-f))
 	(set (make-local-variable 'org-edit-src-force-single-line) single)
 	(set (make-local-variable 'org-edit-src-from-org-mode) org-mode-p)
+	(set (make-local-variable 'org-src-preserve-indentation) preserve-indentation)
 	(when lfmt
 	  (set (make-local-variable 'org-coderef-label-format) lfmt))
 	(when org-mode-p
@@ -219,7 +233,7 @@ the edited version."
 	(org-set-local 'org-edit-src-beg-marker beg)
 	(org-set-local 'org-edit-src-end-marker end)
 	(org-set-local 'org-edit-src-overlay ovl)
-	(org-set-local 'org-edit-src-nindent nindent)
+	(org-set-local 'org-edit-src-block-indentation block-nindent)
 	(org-src-mode)
 	(set-buffer-modified-p nil)
 	(and org-edit-src-persistent-message
@@ -269,7 +283,8 @@ the fragment in the Org-mode buffer."
 	(org-mode-p (eq major-mode 'org-mode))
 	(beg (make-marker))
 	(end (make-marker))
-	nindent ovl beg1 end1 code begline buffer)
+	(preserve-indentation org-src-preserve-indentation)
+	block-nindent ovl beg1 end1 code begline buffer)
     (beginning-of-line 1)
     (if (looking-at "[ \t]*[^:\n \t]")
 	nil
@@ -314,7 +329,7 @@ the fragment in the Org-mode buffer."
 	(insert code)
 	(remove-text-properties (point-min) (point-max)
 				'(display nil invisible nil intangible nil))
-	(setq nindent (org-do-remove-indentation))
+	(setq block-nindent (or (org-do-remove-indentation) 0))
 	(cond
 	 ((eq org-edit-fixed-width-region-mode 'artist-mode)
 	  (fundamental-mode)
@@ -330,7 +345,9 @@ the fragment in the Org-mode buffer."
 	(org-set-local 'org-edit-src-beg-marker beg)
 	(org-set-local 'org-edit-src-end-marker end)
 	(org-set-local 'org-edit-src-overlay ovl)
-	(org-set-local 'org-edit-src-nindent nindent)
+	(org-set-local 'org-edit-src-block-indentation block-nindent)
+	(org-set-local 'org-edit-src-content-indentation 0)
+	(org-set-local 'org-src-preserve-indentation nil)
 	(org-src-mode)
 	(set-buffer-modified-p nil)
 	(and org-edit-src-persistent-message
@@ -438,8 +455,10 @@ the language, a switch telling of the content should be in a single line."
 	 (buffer (current-buffer))
 	 (single (org-bound-and-true-p org-edit-src-force-single-line))
 	 (macro (eq single 'macro-definition))
-	 (nindent org-edit-src-nindent)
-	 code line)
+	 (total-nindent (+ (or org-edit-src-block-indentation 0)
+			   org-edit-src-content-indentation))
+	 (preserve-indentation org-src-preserve-indentation)
+	 code line indent)
     (untabify (point-min) (point-max))
     (save-excursion
       (goto-char (point-min))
@@ -467,16 +486,18 @@ the language, a switch telling of the content should be in a single line."
 	      (if (org-mode-p) "^\\(.\\)" "^\\([*]\\|[ \t]*#\\+\\)") nil t)
 	(replace-match ",\\1")))
     (when (org-bound-and-true-p org-edit-src-picture)
+      (setq preserve-indentation nil)
       (untabify (point-min) (point-max))
       (goto-char (point-min))
       (while (re-search-forward "^" nil t)
 	(replace-match ": ")))
-    (when (and nindent (not single))
-      (setq nindent (make-string (+ org-edit-src-content-indentation nindent)
-				 ?\ ))
+    (unless (or single preserve-indentation (= total-nindent 0))
+      (setq indent (make-string total-nindent ?\ ))
       (goto-char (point-min))
       (while (re-search-forward "^" nil t)
-      (replace-match nindent)))
+	(replace-match indent)))
+    (if (org-bound-and-true-p org-edit-src-picture)
+	(setq total-nindent (+ total-nindent 2)))
     (setq code (buffer-string))
     (set-buffer-modified-p nil)
     (switch-to-buffer (marker-buffer beg))