X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/dacbc44ca3fc825c9e5ffa799f1a0937c1da0020..7e09ef09a479731d01b1ca46e94ddadd73ac98e3:/lisp/org/org-src.el diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index 501d30ab1d..5c2ceaf341 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -1,9 +1,9 @@ ;;; org-src.el --- Source code examples in Org ;; -;; Copyright (C) 2004-2013 Free Software Foundation, Inc. +;; Copyright (C) 2004-2015 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik -;; Bastien Guerry +;; Bastien Guerry ;; Dan Davison ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org @@ -64,6 +64,30 @@ there are kept outside the narrowed region." (const :tag "from `lang' element") (const :tag "from `style' element"))))) +(defcustom org-edit-src-turn-on-auto-save nil + "Non-nil means turn `auto-save-mode' on when editing a source block. +This will save the content of the source code editing buffer into +a newly created file, not the base buffer for this source block. + +If you want to regularly save the base buffer instead of the source +code editing buffer, see `org-edit-src-auto-save-idle-delay' instead." + :group 'org-edit-structure + :version "24.4" + :package-version '(Org . "8.0") + :type 'boolean) + +(defcustom org-edit-src-auto-save-idle-delay 0 + "Delay before saving a source code buffer back into its base buffer. +When a positive integer N, save after N seconds of idle time. +When 0 (the default), don't auto-save. + +If you want to save the source code buffer itself, don't use this. +Check `org-edit-src-turn-on-auto-save' instead." + :group 'org-edit-structure + :version "24.4" + :package-version '(Org . "8.0") + :type 'integer) + (defcustom org-coderef-label-format "(ref:%s)" "The default coderef format. This format string will be used to search for coderef labels in literal @@ -155,7 +179,7 @@ but which mess up the display of a snippet in Org exported files.") (defcustom org-src-lang-modes '(("ocaml" . tuareg) ("elisp" . emacs-lisp) ("ditaa" . artist) ("asymptote" . asy) ("dot" . fundamental) ("sqlite" . sql) - ("calc" . fundamental) ("C" . c) ("cpp" . c++) + ("calc" . fundamental) ("C" . c) ("cpp" . c++) ("C++" . c++) ("screen" . shell-script)) "Alist mapping languages to their major mode. The key is the language name, the value is the string that should @@ -174,6 +198,7 @@ For example, there is no ocaml-mode in Emacs, but the mode to use is (defvar org-src-mode-map (make-sparse-keymap)) (define-key org-src-mode-map "\C-c'" 'org-edit-src-exit) +(define-key org-src-mode-map "\C-c\C-k" 'org-edit-src-abort) (define-key org-src-mode-map "\C-x\C-s" 'org-edit-src-save) (defvar org-edit-src-force-single-line nil) @@ -186,11 +211,15 @@ For example, there is no ocaml-mode in Emacs, but the mode to use is (defvar org-edit-src-block-indentation nil) (defvar org-edit-src-saved-temp-window-config nil) -(defvar org-src-ask-before-returning-to-edit-buffer t +(defcustom org-src-ask-before-returning-to-edit-buffer t "If nil, when org-edit-src code is used on a block that already has an active edit buffer, it will switch to that edit buffer immediately; otherwise it will ask whether you want to return to -the existing edit buffer.") +the existing edit buffer." + :group 'org-edit-structure + :version "24.4" + :package-version '(Org . "8.0") + :type 'boolean) (defvar org-src-babel-info nil) @@ -202,6 +231,7 @@ This minor mode is turned on in two situations: There is a mode hook, and keybindings for `org-edit-src-exit' and `org-edit-src-save'") +(defvar org-edit-src-code-timer nil) (defun org-edit-src-code (&optional context code edit-buffer-name) "Edit the source CODE block at point. The code is copied to a separate buffer and the appropriate mode @@ -241,8 +271,8 @@ the display of windows containing the Org buffer and the code buffer." end (move-marker end (nth 1 info)) msg (if allow-write-back-p (substitute-command-keys - "Edit, then exit with C-c ' (C-c and single quote)") - "Exit with C-c ' (C-c and single quote)") + "Edit, then exit with C-c ' (C-c and single quote) -- C-c C-k to abort") + "Exit with C-c ' (C-c and single quote) -- C-c C-k to abort") code (or code (buffer-substring-no-properties beg end)) lang (or (cdr (assoc (nth 2 info) org-src-lang-modes)) (nth 2 info)) @@ -318,7 +348,7 @@ the display of windows containing the Org buffer and the code buffer." (condition-case e (funcall lang-f) (error - (error "Language mode `%s' fails with: %S" lang-f (nth 1 e))))) + (message "Language mode `%s' fails with: %S" lang-f (nth 1 e))))) (dolist (pair transmitted-variables) (org-set-local (car pair) (cadr pair))) ;; Remove protecting commas from visible part of buffer. @@ -336,11 +366,30 @@ the display of windows containing the Org buffer and the code buffer." (org-src-mode) (set-buffer-modified-p nil) (setq buffer-file-name nil) + (when org-edit-src-turn-on-auto-save + (setq buffer-auto-save-file-name + (concat (make-temp-name "org-src-") + (format-time-string "-%Y-%d-%m") ".txt"))) (and org-edit-src-persistent-message (org-set-local 'header-line-format msg)) (let ((edit-prep-func (intern (concat "org-babel-edit-prep:" lang)))) (when (fboundp edit-prep-func) - (funcall edit-prep-func full-info)))) + (funcall edit-prep-func full-info))) + (or org-edit-src-code-timer + (zerop org-edit-src-auto-save-idle-delay) + (setq org-edit-src-code-timer + (run-with-idle-timer + org-edit-src-auto-save-idle-delay t + (lambda () + (cond + ((org-string-match-p "\\`\\*Org Src" (buffer-name)) + (when (buffer-modified-p) (org-edit-src-save))) + ((not (org-some (lambda (b) + (org-string-match-p "\\`\\*Org Src" + (buffer-name b))) + (buffer-list))) + (cancel-timer org-edit-src-code-timer) + (setq org-edit-src-code-timer nil)))))))) t))) (defun org-edit-src-continue (e) @@ -420,7 +469,7 @@ the fragment in the Org-mode buffer." (col (current-column)) (case-fold-search t) (msg (substitute-command-keys - "Edit, then exit with C-c ' (C-c and single quote)")) + "Edit, then exit with C-c ' (C-c and single quote) -- C-c C-k to abort")) (org-mode-p (derived-mode-p 'org-mode)) (beg (make-marker)) (end (make-marker)) @@ -520,22 +569,12 @@ the language, a switch telling if the content should be in a single line." ("^[ \t]*#\\+begin_latex.*\n" "\n[ \t]*#\\+end_latex" "latex") ("^[ \t]*#\\+ascii:" "\n" "fundamental" single-line) ("^[ \t]*#\\+begin_ascii.*\n" "\n[ \t]*#\\+end_ascii" "fundamental") - ("^[ \t]*#\\+docbook:" "\n" "xml" single-line) ("^[ \t]*#\\+macro:[ \t]+\\S-+\\( \\|$\\)" "\n" "fundamental" macro-definition) - ("^[ \t]*#\\+begin_docbook.*\n" "\n[ \t]*#\\+end_docbook" "xml") ))) (pos (point)) re1 re2 single beg end lang lfmt match-re1 ind entry) (catch 'exit - (when (org-at-table.el-p) - (re-search-backward "^[\t]*[^ \t|\\+]" nil t) - (setq beg (1+ (point-at-eol))) - (goto-char beg) - (or (re-search-forward "^[\t]*[^ \t|\\+]" nil t) - (progn (goto-char (point-max)) (newline))) - (setq end (1- (point-at-bol))) - (throw 'exit (list beg end 'table.el nil nil 0))) (while (setq entry (pop re-list)) (setq re1 (car entry) re2 (nth 1 entry) lang (nth 2 entry) single (nth 3 entry)) @@ -566,7 +605,15 @@ the language, a switch telling if the content should be in a single line." (throw 'exit (list (match-end 0) end (org-edit-src-get-lang lang) - single lfmt ind)))))))))))) + single lfmt ind))))))))) + (when (org-at-table.el-p) + (re-search-backward "^[\t]*[^ \t|\\+]" nil t) + (setq beg (1+ (point-at-eol))) + (goto-char beg) + (or (re-search-forward "^[\t]*[^ \t|\\+]" nil t) + (progn (goto-char (point-max)) (newline))) + (setq end (1- (point-at-bol))) + (throw 'exit (list beg end 'table.el nil nil 0)))))) (defun org-edit-src-get-lang (lang) "Extract the src language." @@ -688,8 +735,8 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (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 indent))) + (while (re-search-forward "\\(^\\).+" nil t) + (replace-match indent nil nil nil 1))) (if (org-bound-and-true-p org-edit-src-picture) (setq total-nindent (+ total-nindent 2))) (setq code (buffer-string)) @@ -699,12 +746,17 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (set-buffer-modified-p nil)) (org-src-switch-to-buffer (marker-buffer beg) (or context 'exit)) (if (eq context 'save) (save-buffer) + (with-current-buffer buffer + (set-buffer-modified-p nil)) (kill-buffer buffer)) (goto-char beg) (when allow-write-back-p + (undo-boundary) (delete-region beg (max beg end)) (unless (string-match "\\`[ \t]*\\'" code) (insert code)) + ;; Make sure the overlay stays in place + (when (eq context 'save) (move-overlay ovl beg (point))) (goto-char beg) (if single (just-one-space))) (if (memq t (mapcar (lambda (overlay) @@ -714,8 +766,9 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." ;; Block is hidden; put point at start of block (beginning-of-line 0) ;; Block is visible, put point where it was in the code buffer - (org-goto-line (1- (+ (org-current-line) line))) - (org-move-to-column (if preserve-indentation col (+ col total-nindent delta)))) + (when allow-write-back-p + (org-goto-line (1- (+ (org-current-line) line))) + (org-move-to-column (if preserve-indentation col (+ col total-nindent delta))))) (unless (eq context 'save) (move-marker beg nil) (move-marker end nil))) @@ -724,6 +777,12 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (set-window-configuration org-edit-src-saved-temp-window-config) (setq org-edit-src-saved-temp-window-config nil)))) +(defun org-edit-src-abort () + "Abort editing of the src code and return to the Org buffer." + (interactive) + (let (org-edit-src-allow-write-back-p) + (org-edit-src-exit 'exit))) + (defmacro org-src-in-org-buffer (&rest body) `(let ((p (point)) (m (mark)) (ul buffer-undo-list) msg) (save-window-excursion @@ -743,9 +802,11 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (defun org-edit-src-save () "Save parent buffer with current state source-code buffer." (interactive) - (org-src-in-org-buffer (save-buffer))) + (if (string-match "Fixed Width" (buffer-name)) + (user-error "Use C-c ' to save and exit, C-c C-k to abort editing") + (org-src-in-org-buffer (save-buffer)))) -(declare-function org-babel-tangle "ob-tangle" (&optional only-this-block target-file lang)) +(declare-function org-babel-tangle "ob-tangle" (&optional arg target-file lang)) (defun org-src-tangle (arg) "Tangle the parent buffer." @@ -778,8 +839,9 @@ with \",*\", \",#+\", \",,*\" and \",,#+\"." (let ((session (cdr (assoc :session (nth 2 info))))) (and session (not (string= session "none")) (org-babel-comint-buffer-livep session) - ((lambda (f) (and (fboundp f) (funcall f session))) - (intern (format "org-babel-%s-associate-session" (nth 0 info))))))) + (let ((f (intern (format "org-babel-%s-associate-session" + (nth 0 info))))) + (and (fboundp f) (funcall f session)))))) (defun org-src-babel-configure-edit-buffer () (when org-src-babel-info @@ -829,9 +891,9 @@ issued in the language major mode buffer." (defun org-src-native-tab-command-maybe () "Perform language-specific TAB action. -Alter code block according to effect of TAB in the language major -mode." +Alter code block according to what TAB does in the language major mode." (and org-src-tab-acts-natively + (org-in-src-block-p) (not (equal this-command 'org-shifttab)) (let ((org-src-strip-leading-and-trailing-blank-lines nil)) (org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))))) @@ -856,7 +918,7 @@ fontification of code blocks see `org-src-fontify-block' and (delete-region (point-min) (point-max)) (insert string " ") ;; so there's a final property change (unless (eq major-mode lang-mode) (funcall lang-mode)) - (font-lock-fontify-buffer) + (org-font-lock-ensure) (setq pos (point-min)) (while (setq next (next-single-property-change pos 'face)) (put-text-property @@ -887,8 +949,9 @@ fontification of code blocks see `org-src-fontify-block' and LANG is a string, and the returned major mode is a symbol." (intern (concat - ((lambda (l) (if (symbolp l) (symbol-name l) l)) - (or (cdr (assoc lang org-src-lang-modes)) lang)) "-mode"))) + (let ((l (or (cdr (assoc lang org-src-lang-modes)) lang))) + (if (symbolp l) (symbol-name l) l)) + "-mode"))) (provide 'org-src)