Browse Source

babel: enhanced code block movement functions

  Thanks to Austin Frank for suggesting these features and to Jonathan
  Arkell for an implementation suggestion

This commit
 - adds `org-babel-goto-named-result' for jumping to named results
 - adds TAB-completion to `org-babel-goto-named-src-block'
 - standardizes on "-src-" instead of "-source-" in all babel functions
 - adds `org-babel-[next/previous]-src-block' functions and keybindings
 - documents the above in orgcard.tex

* doc/orgcard.tex: update documentation of babel keybindings

* lisp/ob-exp.el (org-exp-res/src-name-cleanup): standardized on
  "-src-" instead of "-source-"

* lisp/ob-keys.el (org-babel-key-bindings): updating keybindings for
  new movement functions

* lisp/ob-lob.el (org-babel-lob-ingest): standardized on "-src-"
  instead of "-source-"

* lisp/ob-ref.el (org-babel-ref-resolve-reference): standardized on
  "-src-" instead of "-source-"

* lisp/ob-tangle.el (org-babel-tangle-collect-blocks): standardized on
  "-src-" instead of "-source-"

* lisp/ob.el (org-babel-src-name-regexp): standardized on "-src-"
  instead of "-source-"

  (org-babel-src-name-w-name-regexp): adding regexp for matching
  source names along with their names

  (org-babel-get-src-block-info): using new named source block regexp

  (org-babel-result-regexp): adding optional whitespace after result
  regexp

  (org-babel-result-w-name-regexp): adding regexp for matching results
  which have names

  (org-babel-named-src-block-regexp-for-name): standardized on "-src-"
  instead of "-source-"

  (org-babel-map-src-blocks): standardized on "-src-" instead of
  "-source-"

  (org-babel-where-is-src-block-head): standardized on "-src-" instead of
  "-source-"

  (org-babel-goto-named-src-block): standardized on "-src-" instead of
  "-source-", also added completing read

  (org-babel-src-block-names): collects source block names from a file
  or the current buffer

  (org-babel-goto-named-result): function for jumping to a named
  result

  (org-babel-result-names): returns results names from a file or the
  current buffer

  (org-babel-next-src-block): jump to the next source block

  (org-babel-previous-src-block): jump to the previous source block
Eric Schulte 14 years ago
parent
commit
433b374c10
7 changed files with 89 additions and 19 deletions
  1. 4 1
      doc/orgcard.tex
  2. 1 1
      lisp/ob-exp.el
  3. 10 4
      lisp/ob-keys.el
  4. 1 1
      lisp/ob-lob.el
  5. 1 1
      lisp/ob-ref.el
  6. 1 1
      lisp/ob-tangle.el
  7. 71 10
      lisp/ob.el

+ 4 - 1
doc/orgcard.tex

@@ -477,8 +477,11 @@ formula, \kbd{:=} a field formula.
 
 
 \key{execute code block at point}{C-c C-c}
 \key{execute code block at point}{C-c C-c}
 \key{open results of code block at point}{C-c C-o}
 \key{open results of code block at point}{C-c C-o}
-\key{preview body of code block at point}{C-c C-v p}
+\key{view expanded body of code block at point}{C-c C-v v}
 \key{go to named code block}{C-c C-v g}
 \key{go to named code block}{C-c C-v g}
+\key{go to named result}{C-c C-v r}
+\key{go to the next code block}{C-c C-v n}
+\key{go to the previous code block}{C-c C-v p}
 \key{execute all code blocks in current buffer}{C-c C-v b}
 \key{execute all code blocks in current buffer}{C-c C-v b}
 \key{execute all code blocks in current subtree}{C-c C-v s}
 \key{execute all code blocks in current subtree}{C-c C-v s}
 \key{tangle code blocks in current file}{C-c C-v t}
 \key{tangle code blocks in current file}{C-c C-v t}

+ 1 - 1
lisp/ob-exp.el

@@ -138,7 +138,7 @@ processing has taken place."
     (goto-char (point-min))
     (goto-char (point-min))
     (while (org-re-search-forward-unprotected
     (while (org-re-search-forward-unprotected
 	    (concat
 	    (concat
-	     "\\("org-babel-source-name-regexp"\\|"org-babel-result-regexp"\\)")
+	     "\\("org-babel-src-name-regexp"\\|"org-babel-result-regexp"\\)")
 	    nil t)
 	    nil t)
       (delete-region
       (delete-region
        (progn (beginning-of-line) (point))
        (progn (beginning-of-line) (point))

+ 10 - 4
lisp/ob-keys.el

@@ -51,13 +51,19 @@ functions.")
   (describe-bindings org-babel-key-prefix))
   (describe-bindings org-babel-key-prefix))
 
 
 (defvar org-babel-key-bindings
 (defvar org-babel-key-bindings
-  '(("e" . org-babel-execute-src-block)
+  '(("p" . org-babel-previous-src-block)
+    ("\C-p" . org-babel-previous-src-block)
+    ("n" . org-babel-next-src-block)
+    ("\C-n" . org-babel-next-src-block)
+    ("e" . org-babel-execute-src-block)
     ("\C-e" . org-babel-execute-src-block)
     ("\C-e" . org-babel-execute-src-block)
     ("o" . org-babel-open-src-block-result)
     ("o" . org-babel-open-src-block-result)
     ("\C-o" . org-babel-open-src-block-result)
     ("\C-o" . org-babel-open-src-block-result)
-    ("\C-p" . org-babel-expand-src-block)
-    ("p" . org-babel-expand-src-block)
-    ("g" . org-babel-goto-named-source-block)
+    ("\C-v" . org-babel-expand-src-block)
+    ("v" . org-babel-expand-src-block)
+    ("g" . org-babel-goto-named-src-block)
+    ("r" . org-babel-goto-named-result)
+    ("\C-r" . org-babel-goto-named-result)
     ("\C-b" . org-babel-execute-buffer)
     ("\C-b" . org-babel-execute-buffer)
     ("b" . org-babel-execute-buffer)
     ("b" . org-babel-execute-buffer)
     ("\C-s" . org-babel-execute-subtree)
     ("\C-s" . org-babel-execute-subtree)

+ 1 - 1
lisp/ob-lob.el

@@ -46,7 +46,7 @@ add files to this list use the `org-babel-lob-ingest' command."
 (defun org-babel-lob-ingest (&optional file)
 (defun org-babel-lob-ingest (&optional file)
   "Add all source-blocks defined in FILE to `org-babel-library-of-babel'."
   "Add all source-blocks defined in FILE to `org-babel-library-of-babel'."
   (interactive "f")
   (interactive "f")
-  (org-babel-map-source-blocks file
+  (org-babel-map-src-blocks file
     (let* ((info (org-babel-get-src-block-info))
     (let* ((info (org-babel-get-src-block-info))
 	   (source-name (intern (nth 4 info))))
 	   (source-name (intern (nth 4 info))))
       (when source-name
       (when source-name

+ 1 - 1
lisp/ob-ref.el

@@ -134,7 +134,7 @@ return nil."
 	(goto-char (point-min))
 	(goto-char (point-min))
 	(if (let ((result_regexp (concat "^[ \t]*#\\+\\(TBLNAME\\|RESNAME\\|RESULTS\\):[ \t]*"
 	(if (let ((result_regexp (concat "^[ \t]*#\\+\\(TBLNAME\\|RESNAME\\|RESULTS\\):[ \t]*"
 					 (regexp-quote ref) "[ \t]*$"))
 					 (regexp-quote ref) "[ \t]*$"))
-		  (regexp (concat org-babel-source-name-regexp
+		  (regexp (concat org-babel-src-name-regexp
 				  (regexp-quote ref) "\\(\(.*\)\\)?" "[ \t]*$")))
 				  (regexp-quote ref) "\\(\(.*\)\\)?" "[ \t]*$")))
 	      ;; goto ref in the current buffer
 	      ;; goto ref in the current buffer
 	      (or (and (not args)
 	      (or (and (not args)

+ 1 - 1
lisp/ob-tangle.el

@@ -200,7 +200,7 @@ the form used by `org-babel-spec-to-string' grouped by language.
 Optional argument LANG can be used to limit the collected source
 Optional argument LANG can be used to limit the collected source
 code blocks by language."
 code blocks by language."
   (let ((block-counter 0) blocks)
   (let ((block-counter 0) blocks)
-    (org-babel-map-source-blocks (buffer-file-name)
+    (org-babel-map-src-blocks (buffer-file-name)
       (setq block-counter (+ 1 block-counter))
       (setq block-counter (+ 1 block-counter))
       (let* ((link (progn (call-interactively 'org-store-link)
       (let* ((link (progn (call-interactively 'org-store-link)
                           (org-babel-clean-text-properties
                           (org-babel-clean-text-properties

+ 71 - 10
lisp/ob.el

@@ -38,6 +38,7 @@
 (declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
 (declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
 (declare-function tramp-file-name-user "tramp" (vec))
 (declare-function tramp-file-name-user "tramp" (vec))
 (declare-function tramp-file-name-host "tramp" (vec))
 (declare-function tramp-file-name-host "tramp" (vec))
+(declare-function org-icompleting-read "org" (&rest args))
 (declare-function org-edit-src-code "org" (context code edit-buffer-name))
 (declare-function org-edit-src-code "org" (context code edit-buffer-name))
 (declare-function org-open-at-point "org" (&optional in-emacs reference-buffer))
 (declare-function org-open-at-point "org" (&optional in-emacs reference-buffer))
 (declare-function org-save-outline-visibility "org" (use-markers &rest body))
 (declare-function org-save-outline-visibility "org" (use-markers &rest body))
@@ -94,10 +95,15 @@ the C-c C-c key binding."
   :group 'org-babel
   :group 'org-babel
   :type 'boolean)
   :type 'boolean)
 
 
-(defvar org-babel-source-name-regexp
+(defvar org-babel-src-name-regexp
   "^[ \t]*#\\+\\(srcname\\|source\\|function\\):[ \t]*"
   "^[ \t]*#\\+\\(srcname\\|source\\|function\\):[ \t]*"
   "Regular expression used to match a source name line.")
   "Regular expression used to match a source name line.")
 
 
+(defvar org-babel-src-name-w-name-regexp
+  (concat org-babel-src-name-regexp
+	  "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)")
+  "Regular expression matching source name lines with a name.")
+
 (defvar org-babel-src-block-regexp
 (defvar org-babel-src-block-regexp
   (concat
   (concat
    ;; (1) indentation                     (2) lang
    ;; (1) indentation                     (2) lang
@@ -137,9 +143,7 @@ added to the header-arguments-alist."
 	  (setq indent (car (last info)))
 	  (setq indent (car (last info)))
 	  (setq info (butlast info))
 	  (setq info (butlast info))
 	  (forward-line -1)
 	  (forward-line -1)
-	  (if (looking-at
-	       (concat org-babel-source-name-regexp
-		       "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)"))
+	  (if (looking-at org-babel-src-name-w-name-regexp)
 	      (progn
 	      (progn
 		(setq info (append info (list (org-babel-clean-text-properties
 		(setq info (append info (list (org-babel-clean-text-properties
 					       (match-string 2)))))
 					       (match-string 2)))))
@@ -253,11 +257,15 @@ header arguments as well.")
 (make-variable-buffer-local 'org-babel-current-buffer-properties)
 (make-variable-buffer-local 'org-babel-current-buffer-properties)
 
 
 (defvar org-babel-result-regexp
 (defvar org-babel-result-regexp
-  "^[ \t]*#\\+res\\(ults\\|name\\)\\(\\[\\([[:alnum:]]+\\)\\]\\)?\\:"
+  "^[ \t]*#\\+res\\(ults\\|name\\)\\(\\[\\([[:alnum:]]+\\)\\]\\)?\\:[ \t]*"
   "Regular expression used to match result lines.  If the
   "Regular expression used to match result lines.  If the
 results are associated with a hash key then the hash will be
 results are associated with a hash key then the hash will be
 saved in the second match data.")
 saved in the second match data.")
 
 
+(defvar org-babel-result-w-name-regexp
+  (concat org-babel-result-regexp
+	  "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)"))
+
 (defvar org-babel-min-lines-for-block-output 10
 (defvar org-babel-min-lines-for-block-output 10
   "If number of lines of output is equal to or exceeds this
   "If number of lines of output is equal to or exceeds this
 value, the output is placed in a #+begin_example...#+end_example
 value, the output is placed in a #+begin_example...#+end_example
@@ -277,7 +285,7 @@ can not be resolved.")
   "Hook for functions to be called after `org-babel-execute-src-block'")
   "Hook for functions to be called after `org-babel-execute-src-block'")
 (defun org-babel-named-src-block-regexp-for-name (name)
 (defun org-babel-named-src-block-regexp-for-name (name)
   "This generates a regexp used to match a src block named NAME."
   "This generates a regexp used to match a src block named NAME."
-  (concat org-babel-source-name-regexp (regexp-quote name) "[ \t\n]*"
+  (concat org-babel-src-name-regexp (regexp-quote name) "[ \t\n]*"
 	  (substring org-babel-src-block-regexp 1)))
 	  (substring org-babel-src-block-regexp 1)))
 
 
 ;;; functions
 ;;; functions
@@ -625,7 +633,7 @@ portions of results lines."
 	  (lambda () (org-add-hook 'change-major-mode-hook
 	  (lambda () (org-add-hook 'change-major-mode-hook
 			      'org-babel-show-result-all 'append 'local)))
 			      'org-babel-show-result-all 'append 'local)))
 
 
-(defmacro org-babel-map-source-blocks (file &rest body)
+(defmacro org-babel-map-src-blocks (file &rest body)
   "Evaluate BODY forms on each source-block in FILE."
   "Evaluate BODY forms on each source-block in FILE."
   (declare (indent 1))
   (declare (indent 1))
   `(let ((visited-p (get-file-buffer (expand-file-name ,file)))
   `(let ((visited-p (get-file-buffer (expand-file-name ,file)))
@@ -857,7 +865,7 @@ If the point is not on a source block then return nil."
     (or
     (or
      (save-excursion ;; on a source name line
      (save-excursion ;; on a source name line
        (beginning-of-line 1)
        (beginning-of-line 1)
-       (and (looking-at org-babel-source-name-regexp) (forward-line 1)
+       (and (looking-at org-babel-src-name-regexp) (forward-line 1)
             (looking-at org-babel-src-block-regexp)
             (looking-at org-babel-src-block-regexp)
             (point)))
             (point)))
      (save-excursion ;; on a #+begin_src line
      (save-excursion ;; on a #+begin_src line
@@ -874,9 +882,12 @@ If the point is not on a source block then return nil."
         (point))))))
         (point))))))
 
 
 ;;;###autoload
 ;;;###autoload
-(defun org-babel-goto-named-source-block (&optional name)
+(defun org-babel-goto-named-src-block (name)
   "Go to a named source-code block."
   "Go to a named source-code block."
-  (interactive "ssource-block name: ")
+  (interactive
+   (let ((completion-ignore-case t))
+     (list (org-icompleting-read "source-block name: "
+				 (org-babel-src-block-names) nil t))))
   (let ((point (org-babel-find-named-block name)))
   (let ((point (org-babel-find-named-block name)))
     (if point
     (if point
         ;; taken from `org-open-at-point'
         ;; taken from `org-open-at-point'
@@ -896,6 +907,29 @@ org-babel-named-src-block-regexp."
                 (re-search-backward regexp nil t))
                 (re-search-backward regexp nil t))
         (match-beginning 0)))))
         (match-beginning 0)))))
 
 
+(defun org-babel-src-block-names (&optional file)
+  "Returns the names of source blocks in FILE or the current buffer."
+  (save-excursion
+    (when file (find-file file)) (goto-char (point-min))
+    (let (names)
+      (while (re-search-forward org-babel-src-name-w-name-regexp nil t)
+	(setq names (cons (org-babel-clean-text-properties (match-string 2))
+			  names)))
+      names)))
+
+;;;###autoload
+(defun org-babel-goto-named-result (name)
+  "Go to a named result."
+  (interactive
+   (let ((completion-ignore-case t))
+     (list (org-icompleting-read "source-block name: "
+				 (org-babel-result-names) nil t))))
+  (let ((point (org-babel-find-named-result name)))
+    (if point
+        ;; taken from `org-open-at-point'
+        (progn (goto-char point) (org-show-context))
+      (message "result '%s' not found in this buffer" name))))
+
 (defun org-babel-find-named-result (name)
 (defun org-babel-find-named-result (name)
   "Return the location of the result named NAME in the current
   "Return the location of the result named NAME in the current
 buffer or nil if no such result exists."
 buffer or nil if no such result exists."
@@ -906,6 +940,33 @@ buffer or nil if no such result exists."
                    "[ \t]" (regexp-quote name) "[ \t\n\f\v\r]") nil t)
                    "[ \t]" (regexp-quote name) "[ \t\n\f\v\r]") nil t)
       (beginning-of-line 0) (point))))
       (beginning-of-line 0) (point))))
 
 
+(defun org-babel-result-names (&optional file)
+  "Returns the names of results in FILE or the current buffer."
+  (save-excursion
+    (when file (find-file file)) (goto-char (point-min))
+    (let (names)
+      (while (re-search-forward org-babel-result-w-name-regexp nil t)
+	(setq names (cons (org-babel-clean-text-properties (match-string 4))
+			  names)))
+      names)))
+
+;;;###autoload
+(defun org-babel-next-src-block (&optional arg)
+  "Jump to the next source block.
+With optional prefix argument ARG, jump forward ARG many source blocks."
+  (interactive "P")
+  (when (looking-at org-babel-src-block-regexp) (forward-char 1))
+  (re-search-forward org-babel-src-block-regexp nil nil (or arg 1))
+  (goto-char (match-beginning 0)) (org-show-context))
+
+;;;###autoload
+(defun org-babel-previous-src-block (&optional arg)
+  "Jump to the previous source block.
+With optional prefix argument ARG, jump backward ARG many source blocks."
+  (interactive "P")
+  (re-search-backward org-babel-src-block-regexp nil nil (or arg 1))
+  (goto-char (match-beginning 0)) (org-show-context))
+
 (defvar org-babel-lob-one-liner-regexp)
 (defvar org-babel-lob-one-liner-regexp)
 (defun org-babel-where-is-src-block-result (&optional insert info hash indent)
 (defun org-babel-where-is-src-block-result (&optional insert info hash indent)
   "Return the point at the beginning of the result of the current
   "Return the point at the beginning of the result of the current