Browse Source

ob: Optimize `org-babel-lob-get-info'

* lisp/ob-core.el (org-babel-goto-named-src-block): Use parser instead
  of `org-babel-lob-one-liner-regexp'.
* lisp/ob-lob.el (org-babel-lob-execute-maybe): Ignore spurious check,
  now handled by the parser.
(org-babel-lob-get-info): Fully use parser.  Accept a new optional
argument to avoid parsing the same location twice.

* lisp/ob-exp.el (org-babel-exp-process-buffer):
* lisp/ob-ref.el (org-babel-ref-resolve): Optimize call to
  `org-babel-lob-get-info'.
Nicolas Goaziou 5 years ago
parent
commit
5f94f49db0
4 changed files with 41 additions and 50 deletions
  1. 16 25
      lisp/ob-core.el
  2. 2 2
      lisp/ob-exp.el
  3. 21 21
      lisp/ob-lob.el
  4. 2 2
      lisp/ob-ref.el

+ 16 - 25
lisp/ob-core.el

@@ -53,6 +53,7 @@
 (declare-function with-parsed-tramp-file-name "tramp" (filename var &rest body))
 (declare-function org-edit-src-code "org-src" (&optional code edit-buffer-name))
 (declare-function org-edit-src-exit "org-src"  ())
+(declare-function org-in-regexp "org" (regexp &optional nlines visually))
 (declare-function org-open-at-point "org" (&optional in-emacs reference-buffer))
 (declare-function org-save-outline-visibility "org-macs" (use-markers &rest body))
 (declare-function org-outline-overlay-data "org" (&optional use-markers))
@@ -78,7 +79,6 @@
 (declare-function orgtbl-to-generic "org-table" (table params))
 (declare-function orgtbl-to-orgtbl "org-table" (table params))
 (declare-function org-babel-tangle-comment-links "ob-tangle" (&optional info))
-(declare-function org-babel-lob-get-info "ob-lob" nil)
 (declare-function org-babel-ref-split-args "ob-ref" (arg-string))
 (declare-function org-babel-ref-parse "ob-ref" (assignment))
 (declare-function org-babel-ref-resolve "ob-ref" (ref))
@@ -1744,33 +1744,24 @@ If the point is not on a source block then return nil."
   (interactive
    (let ((completion-ignore-case t)
 	 (case-fold-search t)
-	 (under-point (thing-at-point 'line)))
+	 (all-block-names (org-babel-src-block-names)))
      (list (completing-read
-	    "source-block name: " (org-babel-src-block-names) nil t
-	    (cond
-	     ;; noweb
-	     ((string-match (org-babel-noweb-wrap) under-point)
-	      (let ((block-name (match-string 1 under-point)))
-		(string-match "[^(]*" block-name)
-		(match-string 0 block-name)))
-	     ;; #+call:
-	     ((string-match org-babel-lob-one-liner-regexp under-point)
-	      (let ((source-info (car (org-babel-lob-get-info))))
-		(if (string-match "^\\([^\\[]+?\\)\\(\\[.*\\]\\)?(" source-info)
-		    (let ((source-name (match-string 1 source-info)))
-		      source-name))))
-	     ;; #+results:
-	     ((string-match (concat "#\\+" org-babel-results-keyword
-				    "\\:\s+\\([^\\(]*\\)") under-point)
-	      (match-string 1 under-point))
-	     ;; symbol-at-point
-	     ((and (thing-at-point 'symbol))
-	      (org-babel-find-named-block (thing-at-point 'symbol))
-	      (thing-at-point 'symbol))
-	     (""))))))
+	    "source-block name: " all-block-names nil t
+	    (let* ((context (org-element-context))
+		   (type (org-element-type context)))
+	      (cond
+	       ((and (memq type '(inline-src-block src-block)) ;<<noweb>>
+		     (org-in-regexp (org-babel-noweb-wrap))))
+	       ((memq type '(babel-call inline-babel-call)) ;#+CALL:
+		(org-element-property :call context))
+	       ((org-element-property :results context)) ;#+RESULTS:
+	       ((let ((symbol (thing-at-point 'symbol))) ;Symbol.
+		  (and (member-ignore-case symbol all-block-names)
+		       symbol)))
+	       (t "")))))))
   (let ((point (org-babel-find-named-block name)))
     (if point
-        ;; taken from `org-open-at-point'
+        ;; Taken from `org-open-at-point'.
         (progn (org-mark-ring-push) (goto-char point) (org-show-context))
       (message "source-code block `%s' not found in this buffer" name))))
 

+ 2 - 2
lisp/ob-exp.el

@@ -32,7 +32,7 @@
 (defvar org-babel-ref-split-regexp)
 (defvar org-list-forbidden-blocks)
 
-(declare-function org-babel-lob-get-info "ob-lob" ())
+(declare-function org-babel-lob-get-info "ob-lob" (&optional datum))
 (declare-function org-babel-eval-wipe-error-buffer "ob-eval" ())
 (declare-function org-between-regexps-p "org"
 		  (start-re end-re &optional lim-up lim-down))
@@ -214,7 +214,7 @@ may make them unreachable."
 		       (delete-region begin end)
 		       (insert replacement)))))
 		((babel-call inline-babel-call)
-		 (let* ((lob-info (org-babel-lob-get-info))
+		 (let* ((lob-info (org-babel-lob-get-info element))
 			(results
 			 (org-babel-exp-do-export
 			  (list "emacs-lisp" "results"

+ 21 - 21
lisp/ob-lob.el

@@ -91,29 +91,29 @@ Detect if this is context for a Library Of Babel source block and
 if so then run the appropriate source block from the Library."
   (interactive)
   (let ((info (org-babel-lob-get-info)))
-    (if (and (nth 0 info) (not (org-babel-in-example-or-verbatim)))
-	(progn (org-babel-lob-execute info) t)
-      nil)))
+    (when info
+      (org-babel-lob-execute info)
+      t)))
 
 ;;;###autoload
-(defun org-babel-lob-get-info ()
-  "Return a Library of Babel function call as a string."
-  (when (save-excursion
-	  (beginning-of-line)
-	  (let ((case-fold-search t))
-	    (looking-at org-babel-lob-one-liner-regexp)))
-    (let ((context (save-match-data (org-element-context))))
-      (when (memq (org-element-type context) '(babel-call inline-babel-call))
-	(list (format "%s%s(%s)"
-		      (org-element-property :call context)
-		      (let ((in (org-element-property :inside-header context)))
-			(if in (format "[%s]" in) ""))
-		      (or (org-element-property :arguments context) ""))
-	      (org-element-property :end-header context)
-	      (length (if (= (length (match-string 12)) 0)
-			  (match-string-no-properties 2)
-			(match-string-no-properties 11)))
-	      (org-element-property :name context))))))
+(defun org-babel-lob-get-info (&optional datum)
+  "Return a Library of Babel function call as a string.
+Return nil when not on an appropriate location.  Build string
+from `inline-babel-call' or `babel-call' DATUM, when provided."
+  (let ((context (or datum (org-element-context))))
+    (when (memq (org-element-type context) '(babel-call inline-babel-call))
+      (list (format "%s%s(%s)"
+		    (org-element-property :call context)
+		    (let ((in (org-element-property :inside-header context)))
+		      (if in (format "[%s]" in) ""))
+		    (or (org-element-property :arguments context) ""))
+	    (org-element-property :end-header context)
+	    (string-width		;Indentation.
+	     (org-with-wide-buffer
+	      (goto-char (org-element-property :begin context))
+	      (buffer-substring-no-properties
+	       (line-beginning-position) (point))))
+	    (org-element-property :name context)))))
 
 (defvar org-babel-default-header-args:emacs-lisp) ; Defined in ob-emacs-lisp.el
 (defun org-babel-lob-execute (info)

+ 2 - 2
lisp/ob-ref.el

@@ -55,7 +55,7 @@
 (declare-function org-at-item-p "org-list" ())
 (declare-function org-at-table-p "org" (&optional table-type))
 (declare-function org-babel-lob-execute "ob-lob" (info))
-(declare-function org-babel-lob-get-info "ob-lob" nil)
+(declare-function org-babel-lob-get-info "ob-lob" (&optional datum))
 (declare-function org-element-at-point "org-element" ())
 (declare-function org-element-property "org-element" (property element))
 (declare-function org-element-type "org-element" (element))
@@ -177,7 +177,7 @@ the variable."
 			       (`babel-call
 				(throw :found
 				       (org-babel-lob-execute
-					(org-babel-lob-get-info))))
+					(org-babel-lob-get-info e))))
 			       (`src-block
 				(throw :found
 				       (org-babel-execute-src-block