From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dan Davison Subject: [PATCH] org-src code indentation, etc Date: Thu, 08 Oct 2009 12:44:34 -0400 Message-ID: <878wfln8ct.fsf@stats.ox.ac.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mvw6d-000185-9J for emacs-orgmode@gnu.org; Thu, 08 Oct 2009 12:44:43 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mvw6Y-00013F-7l for emacs-orgmode@gnu.org; Thu, 08 Oct 2009 12:44:42 -0400 Received: from [199.232.76.173] (port=40349 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mvw6X-00013A-W9 for emacs-orgmode@gnu.org; Thu, 08 Oct 2009 12:44:38 -0400 Received: from markov.stats.ox.ac.uk ([163.1.210.1]:63742) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mvw6X-000230-CZ for emacs-orgmode@gnu.org; Thu, 08 Oct 2009 12:44:37 -0400 Received: from blackcap.stats.ox.ac.uk (blackcap.stats [163.1.210.5]) by markov.stats.ox.ac.uk (8.13.6/8.13.6) with ESMTP id n98GiaaG002133 for ; Thu, 8 Oct 2009 17:44:36 +0100 (BST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs org-mode mailing list 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---