update packages and add valign
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
;;; ob-comint.el --- Babel Functions for Interaction with Comint Buffers -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2009-2025 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2009-2026 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric Schulte
|
||||
;; Keywords: literate programming, reproducible research, comint
|
||||
@@ -36,8 +36,13 @@
|
||||
|
||||
(require 'ob-core)
|
||||
(require 'org-compat)
|
||||
(require 'org-element-ast)
|
||||
|
||||
(require 'comint)
|
||||
|
||||
(declare-function org-element-context "org-element" (&optional element))
|
||||
(defvar org-element-inline-src-block-regexp)
|
||||
|
||||
(defun org-babel-comint-buffer-livep (buffer)
|
||||
"Check if BUFFER is a comint buffer with a live process."
|
||||
(let ((buffer (when buffer (get-buffer buffer))))
|
||||
@@ -58,7 +63,8 @@ executed inside the protection of `save-excursion' and
|
||||
(let ((comint-input-filter (lambda (_input) nil)))
|
||||
,@body))))))
|
||||
|
||||
(defvar-local org-babel-comint-prompt-regexp-old nil
|
||||
(defvaralias 'org-babel-comint-prompt-regexp-old 'org-babel-comint-prompt-regexp-fallback)
|
||||
(defvar org-babel-comint-prompt-regexp-fallback nil
|
||||
"Fallback regexp used to detect prompt.")
|
||||
|
||||
(defcustom org-babel-comint-fallback-regexp-threshold 5.0
|
||||
@@ -69,11 +75,11 @@ This is useful when prompt unexpectedly changes."
|
||||
:package-version '(Org . "9.7"))
|
||||
|
||||
(defun org-babel-comint--set-fallback-prompt ()
|
||||
"Swap `comint-prompt-regexp' and `org-babel-comint-prompt-regexp-old'."
|
||||
(when org-babel-comint-prompt-regexp-old
|
||||
"Swap `comint-prompt-regexp' and `org-babel-comint-prompt-regexp-fallback'."
|
||||
(when org-babel-comint-prompt-regexp-fallback
|
||||
(let ((tmp comint-prompt-regexp))
|
||||
(setq comint-prompt-regexp org-babel-comint-prompt-regexp-old
|
||||
org-babel-comint-prompt-regexp-old tmp))))
|
||||
(setq comint-prompt-regexp org-babel-comint-prompt-regexp-fallback
|
||||
org-babel-comint-prompt-regexp-fallback tmp))))
|
||||
|
||||
(defun org-babel-comint--prompt-filter (string &optional prompt-regexp)
|
||||
"Remove PROMPT-REGEXP from STRING.
|
||||
@@ -100,15 +106,33 @@ PROMPT-REGEXP defaults to `comint-prompt-regexp'."
|
||||
(setq string (substring string (match-end 0))))
|
||||
string)
|
||||
|
||||
(defun org-babel-comint--remove-prompts-p (prompt-handling)
|
||||
"Helper to decide whether to remove prompts from comint output.
|
||||
Parses the symbol in PROMPT-HANDLING, which can be
|
||||
`filter-prompts', in which case prompts should be removed; or
|
||||
`disable-prompt-filtering', in which case prompt filtering is
|
||||
skipped. For backward-compatibility, the default value of `nil'
|
||||
is equivalent to `filter-prompts'."
|
||||
(cond
|
||||
((eq prompt-handling 'disable-prompt-filtering) nil)
|
||||
((eq prompt-handling 'filter-prompts) t)
|
||||
((eq prompt-handling nil) t)
|
||||
(t (error (format "Unrecognized prompt handling behavior %s"
|
||||
prompt-handling)))))
|
||||
|
||||
(defmacro org-babel-comint-with-output (meta &rest body)
|
||||
"Evaluate BODY in BUFFER and return process output.
|
||||
Will wait until EOE-INDICATOR appears in the output, then return
|
||||
all process output. If REMOVE-ECHO and FULL-BODY are present and
|
||||
non-nil, then strip echo'd body from the returned output. META
|
||||
should be a list containing the following where the last two
|
||||
elements are optional.
|
||||
non-nil, then strip echo'd body from the returned output.
|
||||
PROMPT-HANDLING may be either of the symbols `filter-prompts', in
|
||||
which case the output is split by `comint-prompt-regexp' and
|
||||
returned as a list; or, `disable-prompt-filtering', which
|
||||
suppresses this behavior and returns the full output as a string.
|
||||
META should be a list containing the following where the last
|
||||
three elements are optional.
|
||||
|
||||
(BUFFER EOE-INDICATOR REMOVE-ECHO FULL-BODY)
|
||||
(BUFFER EOE-INDICATOR REMOVE-ECHO FULL-BODY PROMPT-HANDLING)
|
||||
|
||||
This macro ensures that the filter is removed in case of an error
|
||||
or user `keyboard-quit' during execution of body."
|
||||
@@ -116,7 +140,8 @@ or user `keyboard-quit' during execution of body."
|
||||
(let ((buffer (nth 0 meta))
|
||||
(eoe-indicator (nth 1 meta))
|
||||
(remove-echo (nth 2 meta))
|
||||
(full-body (nth 3 meta)))
|
||||
(full-body (nth 3 meta))
|
||||
(prompt-handling (nth 4 meta)))
|
||||
`(org-babel-comint-in-buffer ,buffer
|
||||
(let* ((string-buffer "")
|
||||
(comint-output-filter-functions
|
||||
@@ -124,7 +149,7 @@ or user `keyboard-quit' during execution of body."
|
||||
(setq string-buffer (concat string-buffer text)))
|
||||
comint-output-filter-functions))
|
||||
dangling-text)
|
||||
;; got located, and save dangling text
|
||||
;; got located, and save dangling text
|
||||
(goto-char (process-mark (get-buffer-process (current-buffer))))
|
||||
(let ((start (point))
|
||||
(end (point-max)))
|
||||
@@ -134,38 +159,37 @@ or user `keyboard-quit' during execution of body."
|
||||
,@body
|
||||
;; wait for end-of-evaluation indicator
|
||||
(let ((start-time (current-time)))
|
||||
(while (progn
|
||||
(goto-char comint-last-input-end)
|
||||
(not (save-excursion
|
||||
(and (re-search-forward
|
||||
(regexp-quote ,eoe-indicator) nil t)
|
||||
(re-search-forward
|
||||
comint-prompt-regexp nil t)))))
|
||||
(while (not (save-excursion
|
||||
(and (string-match
|
||||
(regexp-quote ,eoe-indicator) string-buffer)
|
||||
(string-match
|
||||
comint-prompt-regexp string-buffer))))
|
||||
(accept-process-output
|
||||
(get-buffer-process (current-buffer))
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(when (and org-babel-comint-prompt-regexp-old
|
||||
(when (and org-babel-comint-prompt-regexp-fallback
|
||||
(> (float-time (time-since start-time))
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(progn
|
||||
(goto-char comint-last-input-end)
|
||||
(save-excursion
|
||||
(and
|
||||
(re-search-forward
|
||||
(regexp-quote ,eoe-indicator) nil t)
|
||||
(re-search-forward
|
||||
org-babel-comint-prompt-regexp-old nil t)))))
|
||||
(string-match
|
||||
(regexp-quote ,eoe-indicator) string-buffer)
|
||||
(string-match
|
||||
org-babel-comint-prompt-regexp-fallback string-buffer)))))
|
||||
(org-babel-comint--set-fallback-prompt))))
|
||||
;; replace cut dangling text
|
||||
(goto-char (process-mark (get-buffer-process (current-buffer))))
|
||||
(goto-char (process-mark (get-buffer-process (current-buffer))))
|
||||
(insert dangling-text)
|
||||
|
||||
;; remove echo'd FULL-BODY from input
|
||||
(and ,remove-echo ,full-body
|
||||
(setq string-buffer (org-babel-comint--echo-filter string-buffer ,full-body)))
|
||||
|
||||
;; Filter out prompts.
|
||||
(org-babel-comint--prompt-filter string-buffer)))))
|
||||
(if (org-babel-comint--remove-prompts-p ,prompt-handling)
|
||||
(org-babel-comint--prompt-filter string-buffer)
|
||||
string-buffer)))))
|
||||
|
||||
(defun org-babel-comint-input-command (buffer cmd)
|
||||
"Pass CMD to BUFFER.
|
||||
@@ -189,14 +213,14 @@ statement (not large blocks of code)."
|
||||
(accept-process-output
|
||||
(get-buffer-process buffer)
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(when (and org-babel-comint-prompt-regexp-old
|
||||
(when (and org-babel-comint-prompt-regexp-fallback
|
||||
(> (float-time (time-since start-time))
|
||||
org-babel-comint-fallback-regexp-threshold)
|
||||
(progn
|
||||
(goto-char comint-last-input-end)
|
||||
(save-excursion
|
||||
(re-search-forward
|
||||
org-babel-comint-prompt-regexp-old nil t))))
|
||||
org-babel-comint-prompt-regexp-fallback nil t))))
|
||||
(org-babel-comint--set-fallback-prompt))))))
|
||||
|
||||
(defun org-babel-comint-eval-invisibly-and-wait-for-file
|
||||
@@ -293,8 +317,7 @@ STRING contains the output originally inserted into the comint buffer."
|
||||
(with-current-buffer buf
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (search-forward tmp-file nil t)
|
||||
(org-babel-previous-src-block)
|
||||
(when (org-babel-comint-async--find-src tmp-file)
|
||||
(let* ((info (org-babel-get-src-block-info))
|
||||
(params (nth 2 info))
|
||||
(result-params
|
||||
@@ -344,8 +367,7 @@ STRING contains the output originally inserted into the comint buffer."
|
||||
until (with-current-buffer buf
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (search-forward uuid nil t)
|
||||
(org-babel-previous-src-block)
|
||||
(when (org-babel-comint-async--find-src uuid)
|
||||
(let* ((info (org-babel-get-src-block-info))
|
||||
(params (nth 2 info))
|
||||
(result-params
|
||||
@@ -357,6 +379,41 @@ STRING contains the output originally inserted into the comint buffer."
|
||||
;; Remove uuid from the list to search for
|
||||
(setq uuid-list (delete uuid uuid-list)))))))))
|
||||
|
||||
(defun org-babel-comint-async--find-src (uuid-or-tmpfile)
|
||||
"Find source block associated with an async comint result.
|
||||
UUID-OR-TMPFILE is the uuid or tmpfile associated with the result.
|
||||
Returns non-nil if the source block is succesfully found, and moves
|
||||
point there.
|
||||
|
||||
This function assumes that UUID-OR-TMPFILE was previously inserted as
|
||||
the source block's result, as a placeholder until the true result
|
||||
becomes ready. It may fail to find the source block if the buffer was
|
||||
modified so that UUID-OR-TMPFILE is no longer the result of the source
|
||||
block, or if it has been copied elsewhere into the buffer (this is a
|
||||
limitation of the current async implementation)."
|
||||
(goto-char (point-min))
|
||||
(when (search-forward uuid-or-tmpfile nil t)
|
||||
(let ((uuid-pos (point)))
|
||||
(and (re-search-backward
|
||||
;; find the nearest preceding src or inline-src block
|
||||
(rx (or (regexp org-babel-src-block-regexp)
|
||||
(regexp org-element-inline-src-block-regexp)))
|
||||
nil t)
|
||||
;; check it's actually a src block and not verbatim text
|
||||
(org-element-type-p (org-element-context)
|
||||
'(inline-src-block src-block))
|
||||
;; Check result contains the uuid. There isn't a simple way
|
||||
;; to extract the result value that works in all cases
|
||||
;; (e.g. inline blocks or results drawers), so instead
|
||||
;; check the result region contains the found uuid position
|
||||
(let ((result-where (org-babel-where-is-src-block-result)))
|
||||
(when result-where
|
||||
(save-excursion
|
||||
(goto-char result-where)
|
||||
(and
|
||||
(>= uuid-pos (org-element-property :begin (org-element-context)))
|
||||
(< uuid-pos (org-element-property :end (org-element-context)))))))))))
|
||||
|
||||
(defun org-babel-comint-async-register
|
||||
(session-buffer org-buffer indicator-regexp
|
||||
chunk-callback file-callback
|
||||
@@ -378,12 +435,7 @@ is equivalent to `filter-prompts'."
|
||||
org-babel-comint-async-chunk-callback chunk-callback
|
||||
org-babel-comint-async-file-callback file-callback)
|
||||
(setq org-babel-comint-async-remove-prompts-p
|
||||
(cond
|
||||
((eq prompt-handling 'disable-prompt-filtering) nil)
|
||||
((eq prompt-handling 'filter-prompts) t)
|
||||
((eq prompt-handling nil) t)
|
||||
(t (error (format "Unrecognized prompt handling behavior %s"
|
||||
prompt-handling)))))
|
||||
(org-babel-comint--remove-prompts-p prompt-handling))
|
||||
(unless (memq org-buffer org-babel-comint-async-buffers)
|
||||
(setq org-babel-comint-async-buffers
|
||||
(cons org-buffer org-babel-comint-async-buffers)))
|
||||
|
||||
Reference in New Issue
Block a user