Implement editing source code examples in the native mode.

This commit is contained in:
Carsten Dominik 2008-05-25 09:07:23 +02:00
parent 9bd2896c94
commit 6a2dbbec3f
5 changed files with 145 additions and 18 deletions

View File

@ -15,6 +15,13 @@
:VISIBILITY: content :VISIBILITY: content
:END: :END:
** Overview
- Statistics cookies [/] and [%] for TODO entries
- Editing source code example in the proper mode
- iCalendar now defines proper UIDs for entries
- New properties for customizing subtree export
** Incompatible changes ** Incompatible changes
- The default of the variable `org-tags-match-list-sublevels' is - The default of the variable `org-tags-match-list-sublevels' is
@ -30,7 +37,7 @@
*** Statistics for TODO entries *** Statistics for TODO entries
The [/] and [%] cookies have already provided statistics for The [/] and [%] cookies have already provided statistics for
checkboxes. Now they do the same also for TODO entries. So if a checkboxes. Now they do the same also for TODO entries. If a
headline contains either cookie, changing the TODO state of any headline contains either cookie, changing the TODO state of any
direct child will trigger an update of this cookie. Children direct child will trigger an update of this cookie. Children
that are neither TODO nor DONE are ignored. that are neither TODO nor DONE are ignored.
@ -38,7 +45,7 @@ that are neither TODO nor DONE are ignored.
There have already been requests to automatically switch the There have already been requests to automatically switch the
parent headline to DONE when all children are done. I am not parent headline to DONE when all children are done. I am not
making this a default feature, because one needs to make many making this a default feature, because one needs to make many
decisions about which keyword to use etc. Instead of a complex decisions about which keyword to use, etc. Instead of a complex
customization variable, I am providing a hook that can be used. customization variable, I am providing a hook that can be used.
This hook will be called each time a TODO statistics cookie is This hook will be called each time a TODO statistics cookie is
updated, with the cursor in the corresponding line. Each updated, with the cursor in the corresponding line. Each
@ -56,28 +63,50 @@ implementation:
(add-hook 'org-after-todo-statistics-hook 'org-summary-todo) (add-hook 'org-after-todo-statistics-hook 'org-summary-todo)
#+end_src #+end_src
*** Editing source code example in the proper mode
If you are writing a document with source code examples, you can
include these examples into a =#+BEGIN_SRC lang ... #+END_SRC= or
(with the org-mtags module loaded) a =<src...= structure. =lang=
stands for the Emacs mode used for editing the language, this
could be =emacs-lisp= for Emacs Lisp mode examples, or =org= for
Org mode examples. You can now use the key "C-c '" (that is C-c
followed by the single quote) to edit the example in its native
mode. This works by creating an indirect buffer, narrowing it to
the example and setting the appropriate mode. You need to exit
editing by killing that indirect buffer, with =C-x k=. This is
important, because lines that have syntactic meaning in Org will
be quoted when the indirect buffer is killed.
I guess it would be nice to exit with =C-c C-c=, but who knows
what this key is supposed to do in a random mode.
*** iCalendar now defines proper UIDs for entries *** iCalendar now defines proper UIDs for entries
This is necessary for synchronization services. The UIDs are This is necessary for synchronization services. The UIDs are
created using the the org-id.el module. If you set the variable created using the the org-id.el module which is now part of the
Or core. If you set the variable
: (setq org-icalendar-store-UID t) : (setq org-icalendar-store-UID t)
then all created UIDs will be stored in the entry as an =:ID:= then all created UIDs will be stored in the entry as an =:ID:=
property. You should definitely do this if you plan to use property. This is off by default because it creates lots of
synchronization. property drawers even if you only play with iCalendar export.
But if you plan to use synchronization, you really need to turn
this on.
Diary sexp entries do not yet receive proper persistent UIDs, Diary sexp entries do not yet receive proper persistent UIDs,
because they are transformed to iCalendar format by icalendar.el because they are transformed to iCalendar format by icalendar.el
which creates fresh UIDs each time, based on the current time. which creates fresh UIDs each time, based on the current time.
A single entry can give rise to multiple iCalendar entries (as a An interesting aspect of Org is that a single outline node can
timestamp, a deadline, a scheduled item, and as a TODO give rise to multiple iCalendar entries (as a timestamp, a
item). Therefore, Org adds prefixes "TS-", "DL-" "CS-", and "TD-" deadline, a scheduled item, and as a TODO item). Therefore, Org
to the UID during iCalendar export, depending on what triggered adds prefixes "TS-", "DL-" "CS-", and "TD-" to the UID during
the inclusion of the entry. In this way the UID remains unique, iCalendar export, depending on what triggered the inclusion of
but a synchronization program can still figure out from which the entry. In this way the UID remains unique, but a
entry all the different instances originate. synchronization program can still figure out from which entry all
the different instances originate.
*** New properties for customizing subtree export. *** New properties for customizing subtree export.

View File

@ -6833,6 +6833,16 @@ example:
#+END_SRC #+END_SRC
@end example @end example
@table @kbd
@kindex C-c '
@item C-c '
Edit the source code example at point in its native mode. This works by
switching to an indirect buffer, narrowing the buffer and switching to the
other mode. You need to exit by killing the indirect buffer using @kbd{C-x
k}.
@end table
@node Include files, Tables exported, Literal examples, Markup rules @node Include files, Tables exported, Literal examples, Markup rules
@subheading Include files @subheading Include files
@cindex include files, markup rules @cindex include files, markup rules

View File

@ -1,3 +1,8 @@
2008-05-25 Carsten Dominik <dominik@science.uva.nl>
* org.el (org-edit-src-example, org-find-src-example-start)
(org-protect-source-example, org-edit-special): New functions.
2008-05-24 Carsten Dominik <dominik@science.uva.nl> 2008-05-24 Carsten Dominik <dominik@science.uva.nl>
* org-publish.el (org-publish-project-alist): Fix typo in * org-publish.el (org-publish-project-alist): Fix typo in

View File

@ -1736,7 +1736,8 @@ backends, it converts the segment into an EXAMPLE segment."
;; Free up the protected stuff ;; Free up the protected stuff
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "^," nil t) (while (re-search-forward "^," nil t)
(replace-match "")) (replace-match "")
(end-of-line 1))
(if (functionp mode) (if (functionp mode)
(funcall mode) (funcall mode)
(fundamental-mode)) (fundamental-mode))

View File

@ -2744,8 +2744,6 @@ After a match, the following groups carry important information:
("content" org-startup-folded content) ("content" org-startup-folded content)
("hidestars" org-hide-leading-stars t) ("hidestars" org-hide-leading-stars t)
("showstars" org-hide-leading-stars nil) ("showstars" org-hide-leading-stars nil)
("indent" org-adapt-indentation t)
("noindent" org-adapt-indentation nil)
("odd" org-odd-levels-only t) ("odd" org-odd-levels-only t)
("oddeven" org-odd-levels-only nil) ("oddeven" org-odd-levels-only nil)
("align" org-startup-align-all-tables t) ("align" org-startup-align-all-tables t)
@ -5333,6 +5331,77 @@ If WITH-CASE is non-nil, the sorting will be case-sensitive."
table) table)
(lambda (a b) (funcall comparefun (car a) (car b)))))) (lambda (a b) (funcall comparefun (car a) (car b))))))
;;; Editing source examples
(defun org-edit-src-example ()
"Edit the source code example at point.
An indirect buffer is created, and that buffer is then narrowed to the
example at point and switched to the correct language mode. When done,
exit by killing the buffer with \\[kill-buffer]. It is important to exit
in this way because some Org quoting of the example will take place."
(interactive)
(let ((line (org-current-line))
(case-fold-search t)
(msg (substitute-command-keys
"Edit, then kill this indirect buffer with \\[kill-buffer]"))
beg end)
(if (not (org-find-src-example-start))
;; not at an example
nil
(if (not (save-excursion
(goto-char (point-at-bol))
(or (looking-at "#\\+begin_src[ \t]+\\([^ \t\n]+\\)")
(looking-at "[ \t]*<src .*?lang=\"\\(.*?\\)\""))))
(error "This should not happen"))
(setq beg (point-at-bol 2)
lang (match-string 1)
lang-f (intern (concat lang "-mode")))
(unless (functionp lang-f)
"No such language mode: %s" lang-f)
(unless (re-search-forward "^\\(#\\+end_src\\|[ \t]*</src>\\)" nil t)
(error "Cannot find end of src"))
(setq end (match-beginning 0))
(goto-line line)
(if (get-buffer "*Org Edit Src Example*")
(kill-buffer "*Org Edit Src Example*"))
(switch-to-buffer (make-indirect-buffer (current-buffer)
"*Org Edit Src Example*"))
(narrow-to-region beg end)
(funcall lang-f)
(goto-char (point-min))
(while (re-search-forward "^," nil t)
(replace-match ""))
(goto-char (point-min))
(goto-line line)
(org-add-hook 'kill-buffer-hook 'org-protect-source-example nil 'loc)
(org-set-local 'header-line-format msg)
(message "%s" msg)
t)))
(defun org-find-src-example-start ()
"If point is in a src example, move to the beginning of it.
If not, just return nil."
(let ((re "^\\(#\\+begin_src\\|[ \t]*<src\\)")
(pos (point))
p1)
(beginning-of-line 1)
(if (looking-at re)
(point)
(if (and (setq p1 (re-search-backward re nil t))
(re-search-forward "^\\(#\\+end_src\\|[ \t]*</src\\)" nil t)
(>= (point-at-eol) pos))
(goto-char p1)
(goto-char pos)
nil))))
(defun org-protect-source-example ()
"Protect example lines with Org syntax."
(unless (> (point-min) 1)
(error "This buffer is not narrowed, something is wrong..."))
(goto-char (point-min))
(while (re-search-forward (if (org-mode-p) "^\\(.\\)" "^\\([*#]\\)") nil t)
(replace-match ",\\1")))
;;;; Plain list items, including checkboxes ;;;; Plain list items, including checkboxes
;;; Plain list items ;;; Plain list items
@ -12202,7 +12271,7 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]."
(org-defkey org-mode-map "\C-c " 'org-table-blank-field) (org-defkey org-mode-map "\C-c " 'org-table-blank-field)
(org-defkey org-mode-map "\C-c+" 'org-table-sum) (org-defkey org-mode-map "\C-c+" 'org-table-sum)
(org-defkey org-mode-map "\C-c=" 'org-table-eval-formula) (org-defkey org-mode-map "\C-c=" 'org-table-eval-formula)
(org-defkey org-mode-map "\C-c'" 'org-table-edit-formulas) (org-defkey org-mode-map "\C-c'" 'org-edit-special)
(org-defkey org-mode-map "\C-c`" 'org-table-edit-field) (org-defkey org-mode-map "\C-c`" 'org-table-edit-field)
(org-defkey org-mode-map "\C-c|" 'org-table-create-or-convert-from-region) (org-defkey org-mode-map "\C-c|" 'org-table-create-or-convert-from-region)
(org-defkey org-mode-map [(control ?#)] 'org-table-rotate-recalc-marks) (org-defkey org-mode-map [(control ?#)] 'org-table-rotate-recalc-marks)
@ -12570,6 +12639,18 @@ See the individual commands for more information."
(org-table-paste-rectangle) (org-table-paste-rectangle)
(org-paste-subtree arg))) (org-paste-subtree arg)))
(defun org-edit-special ()
"Call a special editor for the stuff at point.
When at a table, call the formula editor with `org-table-edit-formulas'.
When at the first line of an src example, call `org-edit-src-example'."
(interactive)
(if (org-at-table-p)
(call-interactively 'org-table-edit-formulas)
(or (org-edit-src-example)
(error "%s"
(substitute-command-keys
"\\[org-edit-special] can do nothing useful here.")))))
(defun org-ctrl-c-ctrl-c (&optional arg) (defun org-ctrl-c-ctrl-c (&optional arg)
"Set tags in headline, or update according to changed information at point. "Set tags in headline, or update according to changed information at point.
@ -12850,7 +12931,7 @@ See the individual commands for more information."
("Calculate" ("Calculate"
["Set Column Formula" org-table-eval-formula (org-at-table-p)] ["Set Column Formula" org-table-eval-formula (org-at-table-p)]
["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="] ["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="]
["Edit Formulas" org-table-edit-formulas (org-at-table-p)] ["Edit Formulas" org-edit-special (org-at-table-p)]
"--" "--"
["Recalculate line" org-table-recalculate (org-at-table-p)] ["Recalculate line" org-table-recalculate (org-at-table-p)]
["Recalculate all" (lambda () (interactive) (org-table-recalculate '(4))) :active (org-at-table-p) :keys "C-u C-c *"] ["Recalculate all" (lambda () (interactive) (org-table-recalculate '(4))) :active (org-at-table-p) :keys "C-u C-c *"]
@ -12915,7 +12996,8 @@ See the individual commands for more information."
["Convert to odd levels" org-convert-to-odd-levels t] ["Convert to odd levels" org-convert-to-odd-levels t]
["Convert to odd/even levels" org-convert-to-oddeven-levels t]) ["Convert to odd/even levels" org-convert-to-oddeven-levels t])
("Editing" ("Editing"
["Emphasis..." org-emphasize t]) ["Emphasis..." org-emphasize t]
["Edit Source Example" org-edit-special t])
("Archive" ("Archive"
["Toggle ARCHIVE tag" org-toggle-archive-tag t] ["Toggle ARCHIVE tag" org-toggle-archive-tag t]
; ["Check and Tag Children" (org-toggle-archive-tag (4)) ; ["Check and Tag Children" (org-toggle-archive-tag (4))