perf(org-babel): split buffer once for named-block lookups

ober

aedaa9b53b47b00f4a5f4cc91f0f8eeadbc26779

diff --git a/src/jerboa-emacs/org-babel.ss b/src/jerboa-emacs/org-babel.ss
index de9eaf8..1b2e877 100644
--- a/src/jerboa-emacs/org-babel.ss
+++ b/src/jerboa-emacs/org-babel.ss
@@ -338,60 +338,69 @@
   "Resolve a :var reference. If ref-name matches a #+NAME: src block,
    execute it and return output. If it matches a named table, convert
    to list format. Otherwise return ref-name as literal."
-  ;; First check for a named src block
-  (let ((block-body (org-babel-find-named-block text ref-name)))
+  ;; Split the buffer once and thread the line vector through the lookups.
+  (let* ((lines (list->vector (string-split text #\newline)))
+         (block-body (org-babel-find-named-block* lines ref-name)))
     (if block-body
       ;; Found a named src block — find its language and execute
-      (let ((block-lang (org-babel-find-named-block-lang text ref-name)))
+      (let ((block-lang (org-babel-find-named-block-lang* lines ref-name)))
         (if block-lang
           (let ((result (org-babel-execute block-lang block-body
                           (make-hash-table))))
             (string-trim result))
           ref-name))
       ;; Check for a named table
-      (let ((table-data (org-babel-find-named-table text ref-name)))
+      (let ((table-data (org-babel-find-named-table* lines ref-name)))
         (if table-data
           table-data
           ref-name)))))
 
 (def (org-babel-find-named-block-lang text name)
   "Find the language of a named src block."
-  (let* ((lines (string-split text #\newline))
-         (total (length lines)))
+  (org-babel-find-named-block-lang*
+    (list->vector (string-split text #\newline)) name))
+
+(def (org-babel-find-named-block-lang* lines name)
+  "Find the language of a named src block. LINES is a vector of lines."
+  (let ((total (vector-length lines)))
     (let loop ((i 0))
       (cond
         ((>= i total) #f)
-        ((let ((line (list-ref lines i)))
+        ((let ((line (vector-ref lines i)))
            (let ((m (pregexp-match "^#\\+[Nn][Aa][Mm][Ee]:\\s*(.+)" line)))
              (and m (string=? (string-trim (list-ref m 1)) name)
                   (< (+ i 1) total)
-                  (org-block-begin? (list-ref lines (+ i 1))))))
+                  (org-block-begin? (vector-ref lines (+ i 1))))))
          ;; Found it — parse the BEGIN_SRC line for language
-         (let ((parsed (org-babel-parse-begin-line (list-ref lines (+ i 1)))))
+         (let ((parsed (org-babel-parse-begin-line (vector-ref lines (+ i 1)))))
            (and parsed (car parsed))))
         (else (loop (+ i 1)))))))
 
 (def (org-babel-find-named-table text name)
   "Find a named org table and convert to a language-appropriate string.
    Returns comma-separated rows with pipe-separated cells, or #f."
-  (let* ((lines (string-split text #\newline))
-         (total (length lines)))
+  (org-babel-find-named-table*
+    (list->vector (string-split text #\newline)) name))
+
+(def (org-babel-find-named-table* lines name)
+  "Find a named org table. LINES is a vector of lines."
+  (let ((total (vector-length lines)))
     (let loop ((i 0))
       (cond
         ((>= i total) #f)
-        ((let ((line (list-ref lines i)))
+        ((let ((line (vector-ref lines i)))
            (let ((m (pregexp-match "^#\\+[Nn][Aa][Mm][Ee]:\\s*(.+)" line)))
              (and m (string=? (string-trim (list-ref m 1)) name)
                   (< (+ i 1) total)
-                  (org-table-line-check? (list-ref lines (+ i 1))))))
+                  (org-table-line-check? (vector-ref lines (+ i 1))))))
          ;; Found named table — collect rows
          (let table-loop ((j (+ i 1)) (rows '()))
            (if (or (>= j total)
-                   (not (org-table-line-check? (list-ref lines j))))
+                   (not (org-table-line-check? (vector-ref lines j))))
              ;; Convert to data string: list of lists
              (org-babel-table-to-string (reverse rows))
              ;; Skip separator lines (|---|---|)
-             (let ((line (list-ref lines j)))
+             (let ((line (vector-ref lines j)))
                (if (pregexp-match "^\\s*\\|[-+]+\\|" line)
                  (table-loop (+ j 1) rows)
                  (table-loop (+ j 1) (cons (org-babel-parse-table-row line) rows)))))))
@@ -590,24 +599,28 @@
 
 (def (org-babel-find-named-block text name)
   "Find a named src block in text and return its body."
-  (let* ((lines (string-split text #\newline))
-         (total (length lines)))
+  (org-babel-find-named-block*
+    (list->vector (string-split text #\newline)) name))
+
+(def (org-babel-find-named-block* lines name)
+  "Find a named src block in LINES (a vector) and return its body."
+  (let ((total (vector-length lines)))
     (let loop ((i 0))
       (cond
         ((>= i total) #f)
-        ((let ((line (list-ref lines i)))
+        ((let ((line (vector-ref lines i)))
            (let ((m (pregexp-match "^#\\+[Nn][Aa][Mm][Ee]:\\s*(.+)" line)))
              (and m (string=? (string-trim (list-ref m 1)) name)
                   (< (+ i 1) total)
-                  (org-block-begin? (list-ref lines (+ i 1))))))
+                  (org-block-begin? (vector-ref lines (+ i 1))))))
          ;; Found it — extract body
          (let ((begin-line (+ i 1)))
            (let body-loop ((j (+ begin-line 1)) (acc '()))
              (cond
                ((>= j total) (string-join (reverse acc) "\n"))
-               ((org-block-end? (list-ref lines j))
+               ((org-block-end? (vector-ref lines j))
                 (string-join (reverse acc) "\n"))
-               (else (body-loop (+ j 1) (cons (list-ref lines j) acc)))))))
+               (else (body-loop (+ j 1) (cons (vector-ref lines j) acc)))))))
         (else (loop (+ i 1)))))))
 
 ;;;============================================================================