Add patch against org core regarding source code edit buffers, with explanation.
This commit is contained in:
parent
66949199a7
commit
a41feacbef
200
org-babel.org
200
org-babel.org
|
@ -260,8 +260,204 @@ but with preference given to
|
|||
** TODO take default values for header args from properties
|
||||
Use file-wide and subtree wide properties to set default values for
|
||||
header args.
|
||||
** TODO support for working with =*Org Edit Src Example*= buffers [2/5]
|
||||
*** TODO name edit buffer according to #+srcname (and language?)
|
||||
|
||||
[DED] One thing I'm finding when working with R is that an org file
|
||||
may contain many source blocks, but that I just want to evaluate a
|
||||
subset of them. Typically this is in order to take up where I left
|
||||
off: I need to recreate a bunch of variables in the session
|
||||
environment. I'm thinking maybe we want to use a tag-based
|
||||
mechanism similar to :export: and :noexport: to control evaluation
|
||||
on a per-subtree basis.
|
||||
|
||||
** TODO support for working with =*Org Edit Src Example*= buffers [3/5]
|
||||
*** Patch against org source.
|
||||
I've worked on several related changes to source code edit buffer
|
||||
behaviour in the org core. My current patch (below) does the
|
||||
following. Detailed explanation / working notes are below.
|
||||
- C-x s offers to save edit buffers
|
||||
- C-x C-c offers to save edit buffers
|
||||
- C-x k warns that you're killing an edit buffer
|
||||
- If you do kill an edit buffer, the overlay in the parent buffer is removed
|
||||
- Edit buffers are named *Org Src <orgbuf>[<lang>]*, where
|
||||
<orgbuf> is the name of the org-mode buffer containing this
|
||||
source code block, and lang is the language major mode. The
|
||||
latter might be unnecessary?
|
||||
|
||||
#+begin_example
|
||||
diff --git a/lisp/org-src.el b/lisp/org-src.el
|
||||
index 2083c77..2be21e6 100644
|
||||
--- a/lisp/org-src.el
|
||||
+++ b/lisp/org-src.el
|
||||
@@ -113,7 +113,7 @@ but which mess up the display of a snippet in Org exported files.")
|
||||
|
||||
(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-x\C-s" 'org-edit-src-save)
|
||||
+;; (define-key org-src-mode-map "\C-x\C-s" 'org-edit-src-save)
|
||||
(defvar org-edit-src-force-single-line nil)
|
||||
(defvar org-edit-src-from-org-mode nil)
|
||||
(defvar org-edit-src-picture nil)
|
||||
@@ -168,7 +168,8 @@ the edited version."
|
||||
(if (boundp 'org-edit-src-overlay)
|
||||
(org-delete-overlay org-edit-src-overlay)))
|
||||
(kill-buffer buffer))
|
||||
- (setq buffer (generate-new-buffer "*Org Edit Src Example*"))
|
||||
+ (setq buffer (generate-new-buffer
|
||||
+ (concat "*Org Src " (file-name-nondirectory buffer-file-name) "[" lang "]*")))
|
||||
(setq ovl (org-make-overlay beg end))
|
||||
(org-overlay-put ovl 'face 'secondary-selection)
|
||||
(org-overlay-put ovl 'edit-buffer buffer)
|
||||
@@ -186,8 +187,7 @@ the edited version."
|
||||
'(display nil invisible nil intangible nil))
|
||||
(org-do-remove-indentation)
|
||||
(let ((org-inhibit-startup t))
|
||||
- (funcall lang-f)
|
||||
- (org-src-mode))
|
||||
+ (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)
|
||||
(when lfmt
|
||||
@@ -201,6 +201,7 @@ the edited version."
|
||||
(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-src-mode)
|
||||
(and org-edit-src-persistent-message
|
||||
(org-set-local 'header-line-format msg)))
|
||||
(message "%s" msg)
|
||||
@@ -400,12 +401,13 @@ the language, a switch telling of the content should be in a single line."
|
||||
(defun org-edit-src-exit ()
|
||||
"Exit special edit and protect problematic lines."
|
||||
(interactive)
|
||||
- (unless (string-match "\\`*Org Edit " (buffer-name (current-buffer)))
|
||||
- (error "This is not an sub-editing buffer, something is wrong..."))
|
||||
+ (unless org-edit-src-from-org-mode
|
||||
+ (error "This is not a sub-editing buffer, something is wrong..."))
|
||||
(let ((beg org-edit-src-beg-marker)
|
||||
(end org-edit-src-end-marker)
|
||||
(ovl org-edit-src-overlay)
|
||||
(buffer (current-buffer))
|
||||
+ (buffer-file-name nil)
|
||||
(nindent org-edit-src-nindent)
|
||||
code line)
|
||||
(untabify (point-min) (point-max))
|
||||
@@ -464,6 +466,17 @@ the language, a switch telling of the content should be in a single line."
|
||||
(goto-char (min p (point-max)))
|
||||
(message (or msg ""))))
|
||||
|
||||
+(defun org-src-mode-configure-buffer ()
|
||||
+ (setq buffer-offer-save t)
|
||||
+ (setq buffer-file-name
|
||||
+ (concat (buffer-file-name (marker-buffer org-edit-src-beg-marker))
|
||||
+ "[" (buffer-name) "]"))
|
||||
+ (setq write-contents-functions '(org-edit-src-save))
|
||||
+ (org-add-hook 'kill-buffer-hook
|
||||
+ '(lambda () (org-delete-overlay org-edit-src-overlay)) nil 'local))
|
||||
+
|
||||
+(org-add-hook 'org-src-mode-hook 'org-src-mode-configure-buffer)
|
||||
+
|
||||
(provide 'org-src)
|
||||
|
||||
;; arch-tag: 6a1fc84f-dec7-47be-a416-64be56bea5d8
|
||||
|
||||
#+end_example
|
||||
|
||||
**** Detailed working notes to go with that patch
|
||||
***** Recap of current org-src-mode
|
||||
|
||||
If you use C-c ' to work on code in a begin_source block, the code
|
||||
buffer is put in minor mode org-src-mode, which features the
|
||||
following two useful key-bindings:
|
||||
|
||||
| C-x s | org-edit-src-save | save the code in the source code block in the parent org file |
|
||||
| C-c ' | org-edit-src-exit | return to the parent org file with new code |
|
||||
|
||||
Furthermore, while the edit buffer is alive, the originating code
|
||||
block is subject to a special overlay which links to the edit
|
||||
buffer when you click on it.
|
||||
|
||||
This is all excellent, and I use it daily, but I think there's
|
||||
still a couple of improvements that we should make.
|
||||
|
||||
***** Proposed bug I
|
||||
C-x k kills the buffer without questions; the overlay remains, but
|
||||
now links to a deleted buffer.
|
||||
***** Proposed bug II
|
||||
C-x C-c kills a modified edit buffer silently, without offering to
|
||||
save your work. I have lost work like that a number of times
|
||||
recently.
|
||||
***** Proposed bug III
|
||||
C-x s does not offer to save a modified edit buffer
|
||||
***** Notes on solution
|
||||
****** write-contents-functions
|
||||
A good start seems to be to use org-src-mode-hook to add
|
||||
org-edit-src-save to the write-contents-functions list. This
|
||||
means that when it comes to saving, org-edit-src-save will be
|
||||
called and no subsequent attempt will be made to save the buffer
|
||||
in the normal way. (This should obviate the remapping of C-x C-s
|
||||
to org-edit-src-save in org-src.el)
|
||||
****** buffer-offer-save
|
||||
We also want to set this to t.
|
||||
|
||||
****** Where does this get us?
|
||||
|
||||
- C-x s still does *not* offer to save the edit buffer. That's
|
||||
because buffer-file-name is nil.
|
||||
|
||||
- C-x C-c does ask us whether we want to save the
|
||||
edit buffer. However, since buffer-file-name is nil it asks us
|
||||
for a file name. The check in org-edit-src-exit throws an error
|
||||
unless the buffer is named '* Org Edit '...
|
||||
|
||||
- C-x k kills the buffer silently, leaving a broken overlay
|
||||
link. If buffer-file-name were set, it would have warned that
|
||||
the buffer was modified.
|
||||
|
||||
****** buffer-file-name
|
||||
So, that all suggests that we need to set buffer-file-name, even
|
||||
though we don't really want to associate this buffer with a file
|
||||
in the normal way. As for the file name, my current suggestion
|
||||
is parent-org-filename[edit-buffer-name].
|
||||
|
||||
[I had to move the (org-src-mode) call to the end of
|
||||
org-edit-src-code to make sure that the required variables were
|
||||
defined when the hook was called.]
|
||||
|
||||
****** And so where are we now?
|
||||
- C-x s *does* offer to save the edit buffer, but in saving
|
||||
produces a warning that the edit buffer is modified.
|
||||
- C-x k now gives a warning that the edit buffer is modified
|
||||
(even if it's not).
|
||||
- C-x C-c is working as desired, except that again we get
|
||||
warnings that the edit buffer is modified, once when we save,
|
||||
and again just before exiting emacs.
|
||||
- And C-c ' now issues a warning that the edit buffer is
|
||||
modified when we leave it, which we don't want.
|
||||
****** So, we need to get rid of the buffer modification warnings.
|
||||
I've made buffer-file-name nil inside the let binding in
|
||||
org-edit-src-exit.
|
||||
****** And?
|
||||
- C-x s behaves as desired, except that as was already the case,
|
||||
the edit buffer is always considered modified, and so repeated
|
||||
invocations keep saving it.
|
||||
- As was already the case, C-x k always gives a warning that the
|
||||
edit buffer has been modified.
|
||||
- C-x C-c is as desired (offers to save the edit buffer) except
|
||||
that it warns of the modified buffer just before exiting.
|
||||
- C-c ' is as it should be (silent)
|
||||
***** Conclusion
|
||||
We've got the desired behaviour, at the cost of being forced to
|
||||
assign a buffer-file-name to the edit buffer. The consequence is
|
||||
that the edit buffer is considered to always be modified, since
|
||||
a file of that name is never actually written to (doesn't even
|
||||
exist). I couldn't see a way to trick emacs into believing that
|
||||
the buffer was unmodified since last save. But in any case, I
|
||||
think there's an argument that these modifications warnings are
|
||||
a good thing, because one should not leave active edit buffers
|
||||
around: you should always have exited with C-c ' first.
|
||||
|
||||
*** DONE name edit buffer according to #+srcname (and language?)
|
||||
See above patch agains org.
|
||||
*** TODO optionally evaluate header references when we switch to =*Org Edit Src*= buffer
|
||||
That seems to imply that the header references need to be evaluated
|
||||
and transformed into the target language object when we hit C-c ' to
|
||||
|
|
Loading…
Reference in New Issue