From: Dan Davison <davison@stats.ox.ac.uk>
To: emacs org-mode mailing list <emacs-orgmode@gnu.org>
Subject: [PATCH] org-src code indentation, etc
Date: Thu, 08 Oct 2009 12:44:34 -0400 [thread overview]
Message-ID: <878wfln8ct.fsf@stats.ox.ac.uk> (raw)
Branch ded-src-indent at
http://repo.or.cz/r/org-mode/babel.git
proposes two improvements to org-src-mode, one related improvement to
org-babel, and fixes two small bugs in org-mode. The diff is below for a
quick look. Carsten, if you approve, could you pull this from the git
repo? It should add 4 commits to current org.
Improvements to org-src-mode
- Point stays in same location relative to text when switching between
org and code buffers.
- A new customisable variable org-src-preserve-indentation allows the
user to prevent org from making any automatic alterations to code
indentation when moving between org and code buffers. One requirement
for this is when extracting source code embedded in an org buffer (see
below).
Org Bugs fixed
- 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.
- Also some docstring typos and a docstring correction, and some
variable name clarification.
Org-babel new feature
- Make the tangling (source code extraction) process respect the new
variable org-src-preserve-indentation. This allows python code to be
tangled correctly, regardless of how classes/methods/functions are
distributed among org code blocks. Previously, for example, a class
method in a separate source block would have been incorrectly indented
as a top-level function in tangled output.
In addition, there is an unimportant org-mode bug that is *not* yet
fixed
- If a source block contains an empty line and nothing else, repeated
invocations of org-edit-src-code followed by org-edit-src-exit will
add spaces to that line, indefinitely. This is because
org-do-remove-indentation does not do anything when the 'code'
consists only of space characters.
Dan
Please obtain commits from branch ded-src-indent at
http://repo.or.cz/r/org-mode/babel.git
--8<---------------cut here---------------start------------->8---
diff --git a/contrib/babel/lisp/org-babel.el b/contrib/babel/lisp/org-babel.el
index db09231..8b0b11e 100644
--- a/contrib/babel/lisp/org-babel.el
+++ b/contrib/babel/lisp/org-babel.el
@@ -366,13 +366,14 @@ may be specified in the properties of the current outline entry."
(defun org-babel-parse-src-block-match ()
(let* ((lang (org-babel-clean-text-properties (match-string 1)))
(lang-headers (intern (concat "org-babel-default-header-args:" lang)))
- (body (org-babel-clean-text-properties (match-string 4))))
+ (body (org-babel-clean-text-properties (match-string 4)))
+ (preserve-indentation org-src-preserve-indentation))
(list lang
;; get src block body removing properties, protective commas, and indentation
(with-temp-buffer
(save-match-data
(insert (org-babel-strip-protective-commas body))
- (org-do-remove-indentation)
+ (unless preserve-indentation (org-do-remove-indentation))
(buffer-string)))
(org-babel-merge-params
org-babel-default-header-args
diff --git a/lisp/org-src.el b/lisp/org-src.el
index 3427b7f..796e914 100644
--- a/lisp/org-src.el
+++ b/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.
+ "Indentation for the content of 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.
@@ -153,6 +164,7 @@ This will remove the original code in the Org buffer, and replace it with
the edited version."
(interactive)
(let ((line (org-current-line))
+ (col (current-column))
(case-fold-search t)
(msg (substitute-command-keys
"Edit, then exit with C-c ' (C-c and single quote)"))
@@ -160,7 +172,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 +184,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 +217,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
@@ -216,10 +231,12 @@ the edited version."
(while (re-search-forward "^," nil t)
(replace-match "")))
(org-goto-line (1+ (- line begline)))
+ (org-move-to-column
+ (if preserve-indentation col (max 0 (- col total-nindent))))
(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
@@ -263,13 +280,15 @@ exit with \\[org-edit-src-exit]. The edited text will then replace
the fragment in the Org-mode buffer."
(interactive)
(let ((line (org-current-line))
+ (col (current-column))
(case-fold-search t)
(msg (substitute-command-keys
"Edit, then exit with C-c ' (C-c and single quote)"))
(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 +333,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)
@@ -327,10 +346,13 @@ the fragment in the Org-mode buffer."
(while (re-search-forward "^[ \t]*: ?" nil t)
(replace-match ""))
(org-goto-line (1+ (- line begline)))
+ (org-move-to-column (max 0 (- col block-nindent 2)))
(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
@@ -341,7 +363,7 @@ the fragment in the Org-mode buffer."
(defun org-edit-src-find-region-and-lang ()
"Find the region and language for a local edit.
Return a list with beginning and end of the region, a string representing
-the language, a switch telling of the content should be in a single line."
+the language, a switch telling if the content should be in a single line."
(let ((re-list
(append
org-edit-src-region-extra
@@ -422,7 +444,7 @@ the language, a switch telling of the content should be in a single line."
(match-string 1 s))))
(defun org-edit-src-get-indentation (pos)
- "Extract the label format."
+ "Count leading whitespace characters on line"
(save-match-data
(goto-char pos)
(org-get-indentation)))
@@ -438,8 +460,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 col indent)
(untabify (point-min) (point-max))
(save-excursion
(goto-char (point-min))
@@ -448,7 +472,8 @@ the language, a switch telling of the content should be in a single line."
(if (re-search-forward "\n[ \t\n]*\\'" nil t) (replace-match ""))))
(setq line (if (org-bound-and-true-p org-edit-src-force-single-line)
1
- (org-current-line)))
+ (org-current-line))
+ col (current-column))
(when single
(goto-char (point-min))
(if (re-search-forward "\\s-+\\'" nil t) (replace-match ""))
@@ -467,16 +492,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))
@@ -487,6 +514,7 @@ the language, a switch telling of the content should be in a single line."
(goto-char beg)
(if single (just-one-space))
(org-goto-line (1- (+ (org-current-line) line)))
+ (org-move-to-column (if preserve-indentation col (+ col total-nindent)))
(move-marker beg nil)
(move-marker end nil)))
--8<---------------cut here---------------end--------------->8---
next reply other threads:[~2009-10-08 16:44 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-08 16:44 Dan Davison [this message]
2009-10-08 19:34 ` [PATCH] org-src code indentation, etc Carsten Dominik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=878wfln8ct.fsf@stats.ox.ac.uk \
--to=davison@stats.ox.ac.uk \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).