ソースを参照

Implement editing source code examples in the native mode.

Carsten Dominik 17 年 前
コミット
6a2dbbec3f
5 ファイル変更145 行追加18 行削除
  1. 41 12
      ORGWEBPAGE/Changes.org
  2. 10 0
      doc/org.texi
  3. 5 0
      lisp/ChangeLog
  4. 2 1
      lisp/org-exp.el
  5. 87 5
      lisp/org.el

+ 41 - 12
ORGWEBPAGE/Changes.org

@@ -15,6 +15,13 @@
 :VISIBILITY: content
 :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
   
 - The default of the variable `org-tags-match-list-sublevels' is
@@ -30,7 +37,7 @@
 *** Statistics for TODO entries
 
 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
 direct child will trigger an update of this cookie.  Children
 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
 parent headline to DONE when all children are done.  I am not
 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.
 This hook will be called each time a TODO statistics cookie is
 updated, with the cursor in the corresponding line.  Each
@@ -56,28 +63,50 @@ implementation:
 (add-hook 'org-after-todo-statistics-hook 'org-summary-todo)
 #+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
 
 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)
 
 then all created UIDs will be stored in the entry as an =:ID:=
-property.  You should definitely do this if you plan to use
-synchronization.
+property.  This is off by default because it creates lots of
+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,
 because they are transformed to iCalendar format by icalendar.el
 which creates fresh UIDs each time, based on the current time.
 
-A single entry can give rise to multiple iCalendar entries (as a
-timestamp, a deadline, a scheduled item, and as a TODO
-item). Therefore, Org adds prefixes "TS-", "DL-" "CS-", and "TD-"
-to the UID during iCalendar export, depending on what triggered
-the inclusion of the entry.  In this way the UID remains unique,
-but a synchronization program can still figure out from which
-entry all the different instances originate.
+An interesting aspect of Org is that a single outline node can
+give rise to multiple iCalendar entries (as a timestamp, a
+deadline, a scheduled item, and as a TODO item). Therefore, Org
+adds prefixes "TS-", "DL-" "CS-", and "TD-" to the UID during
+iCalendar export, depending on what triggered the inclusion of
+the entry.  In this way the UID remains unique, but a
+synchronization program can still figure out from which entry all
+the different instances originate.
 
 *** New properties for customizing subtree export.
 

+ 10 - 0
doc/org.texi

@@ -6833,6 +6833,16 @@ example:
 #+END_SRC
 @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
 @subheading Include files
 @cindex include files, markup rules

+ 5 - 0
lisp/ChangeLog

@@ -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>
 
 	* org-publish.el (org-publish-project-alist): Fix typo in

+ 2 - 1
lisp/org-exp.el

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

+ 87 - 5
lisp/org.el

@@ -2744,8 +2744,6 @@ After a match, the following groups carry important information:
     ("content" org-startup-folded content)
     ("hidestars" org-hide-leading-stars t)
     ("showstars" org-hide-leading-stars nil)
-    ("indent" org-adapt-indentation t)
-    ("noindent" org-adapt-indentation nil)
     ("odd" org-odd-levels-only t)
     ("oddeven" org-odd-levels-only nil)
     ("align" org-startup-align-all-tables t)
@@ -5333,6 +5331,77 @@ If WITH-CASE is non-nil, the sorting will be case-sensitive."
 		  table)
 	  (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
@@ -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-sum)
 (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-create-or-convert-from-region)
 (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-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)
   "Set tags in headline, or update according to changed information at point.
 
@@ -12850,7 +12931,7 @@ See the individual commands for more information."
     ("Calculate"
      ["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 ="]
-     ["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 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/even levels" org-convert-to-oddeven-levels t])
     ("Editing"
-     ["Emphasis..." org-emphasize t])
+     ["Emphasis..." org-emphasize t]
+     ["Edit Source Example" org-edit-special t])
     ("Archive"
      ["Toggle ARCHIVE tag" org-toggle-archive-tag t]
 ;     ["Check and Tag Children" (org-toggle-archive-tag (4))