Jack Kamm <jackk...@gmail.com> writes: > Ihor Radchenko <yanta...@posteo.net> writes: > >> What we can do is to introduce a new backend template function >> org-babel-session-buffer:<lang> that will be passed a session name and >> src block params and return the session buffer name. >> >> If such function is not defined, we fall back to assumption that session >> buffer is named the same as the session. >> >> WDYT? > > Sounds good -- I think this is the best solution.
See the updated patchset.
>From b877a440c65cb83bd29182daf4c13cd9b14ed182 Mon Sep 17 00:00:00 2001 Message-ID: <b877a440c65cb83bd29182daf4c13cd9b14ed182.1707228351.git.yanta...@posteo.net> From: Ihor Radchenko <yanta...@posteo.net> Date: Sat, 3 Feb 2024 16:47:57 +0100 Subject: [PATCH 1/3] org-babel-execute-src-block: Force :dir according to live session * lisp/ob-core.el (org-babel-execute-src-block): Force eval directory to follow live session buffer, if any. This is consistent with what we promise in the manual section "16.4 Environment of a Code Block">Choosing a working directory. Link: https://orgmode.org/list/87mssi8ht2....@gmail.com --- lisp/ob-core.el | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 1de3af6ad..fd8d06c5d 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -840,14 +840,17 @@ (defun org-babel-execute-src-block (&optional arg info params executor-type) (dir (cdr (assq :dir params))) (mkdirp (cdr (assq :mkdirp params))) (default-directory - (cond - ((not dir) default-directory) - ((member mkdirp '("no" "nil" nil)) - (file-name-as-directory (expand-file-name dir))) - (t - (let ((d (file-name-as-directory (expand-file-name dir)))) - (make-directory d 'parents) - d)))) + (cond + ((not dir) default-directory) + ((when-let ((session (cdr (assq :session params)))) + (when (org-babel-comint-buffer-livep session) + (buffer-local-value 'default-directory (get-buffer session))))) + ((member mkdirp '("no" "nil" nil)) + (file-name-as-directory (expand-file-name dir))) + (t + (let ((d (file-name-as-directory (expand-file-name dir)))) + (make-directory d 'parents) + d)))) (cmd (intern (concat "org-babel-execute:" lang))) result exec-start-time) (unless (fboundp cmd) -- 2.43.0
>From a31c7b3f5f730b63d3753e07a7a5bb5e73a97ce4 Mon Sep 17 00:00:00 2001 Message-ID: <a31c7b3f5f730b63d3753e07a7a5bb5e73a97ce4.1707228351.git.yanta...@posteo.net> In-Reply-To: <b877a440c65cb83bd29182daf4c13cd9b14ed182.1707228351.git.yanta...@posteo.net> References: <b877a440c65cb83bd29182daf4c13cd9b14ed182.1707228351.git.yanta...@posteo.net> From: Jack Kamm <jackk...@gmail.com> Date: Wed, 31 Jan 2024 20:06:00 -0800 Subject: [PATCH 2/3] ob-comint: Make file results from async sessions respect :dir header * lisp/ob-comint.el (org-babel-comint-async-filter): Set default-directory before calling `org-babel-insert-result' https://list.orgmode.org/875xz9o4nj.fsf@localhost/T/#t --- lisp/ob-comint.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lisp/ob-comint.el b/lisp/ob-comint.el index 7d258ea0e..349524701 100644 --- a/lisp/ob-comint.el +++ b/lisp/ob-comint.el @@ -224,6 +224,8 @@ (defun org-babel-comint-async-filter (string) (file-callback org-babel-comint-async-file-callback) (combined-string (concat org-babel-comint-async-dangling string)) (new-dangling combined-string) + ;; Assumes comint filter called with session buffer current + (session-dir default-directory) ;; list of UUID's matched by `org-babel-comint-async-indicator' uuid-list) (with-temp-buffer @@ -248,7 +250,8 @@ (defun org-babel-comint-async-filter (string) (let* ((info (org-babel-get-src-block-info)) (params (nth 2 info)) (result-params - (cdr (assq :result-params params)))) + (cdr (assq :result-params params))) + (default-directory session-dir)) (org-babel-insert-result (funcall file-callback (nth @@ -291,7 +294,8 @@ (defun org-babel-comint-async-filter (string) (let* ((info (org-babel-get-src-block-info)) (params (nth 2 info)) (result-params - (cdr (assq :result-params params)))) + (cdr (assq :result-params params))) + (default-directory session-dir)) (org-babel-insert-result res-str result-params info)) t)))) -- 2.43.0
>From 5afbd3b5dce89d3da9f0532c6358392175a93a9f Mon Sep 17 00:00:00 2001 Message-ID: <5afbd3b5dce89d3da9f0532c6358392175a93a9f.1707228351.git.yanta...@posteo.net> In-Reply-To: <b877a440c65cb83bd29182daf4c13cd9b14ed182.1707228351.git.yanta...@posteo.net> References: <b877a440c65cb83bd29182daf4c13cd9b14ed182.1707228351.git.yanta...@posteo.net> From: Ihor Radchenko <yanta...@posteo.net> Date: Tue, 6 Feb 2024 15:02:48 +0100 Subject: [PATCH 3/3] org-babel: New babel backend API function org-babel-session-buffer:<lang> * lisp/ob-core.el (org-babel-session-buffer): New API function that return session buffer, if such buffer exists and is live. (org-babel-execute-src-block): Use `org-babel-session-buffer'. * lisp/ob-lua.el (org-babel-session-buffer:lua): * lisp/ob-python.el (org-babel-session-buffer:python): Provide API to retrieve session buffer name. (org-babel-python-initiate-session-by-key): Use `org-babel-session-buffer:python'. * etc/ORG-NEWS (Org babel backends are now expected to define an additional API function ~org-babel-session-buffer:<lang>~): Declare the API addition. Link: https://orgmode.org/list/87r0hr9f3b.fsf@localhost --- etc/ORG-NEWS | 11 +++++++++++ lisp/ob-core.el | 32 +++++++++++++++++++++++++++----- lisp/ob-lua.el | 5 +++++ lisp/ob-python.el | 8 ++++++-- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 965872d23..246d83ffe 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -13,6 +13,17 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org. * Version 9.7 (not released yet) ** Important announcements and breaking changes +*** Org babel backends are now expected to define an additional API function ~org-babel-session-buffer:<lang>~ + +Org babel now uses session buffer (if it exists) to retrieve +~default-directory~ environment during src block evaluation. + +By default, buffer named like session is checked. All the backends +that create sessions inside buffers named differently should provide a +function ~org-babel-session-buffer:<lang>~. The function must accept +two arguments - session name and info list (as returned by +~org-babel-get-src-block-info~); and return the session buffer name. + *** Org mode now fontifies whole table lines (including newline) according to ~org-table~ face Previously, leading indentation and trailing newline in table rows diff --git a/lisp/ob-core.el b/lisp/ob-core.el index fd8d06c5d..a812887fa 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -767,8 +767,31 @@ (defun org-babel--file-desc (params result) (`(:file-desc) result) (`(:file-desc . ,(and (pred stringp) val)) val))) -(defvar *this*) ; Dynamically bound in `org-babel-execute-src-block' - ; and `org-babel-read' +(defvar *this*) +;; Dynamically bound in `org-babel-execute-src-block' +;; and `org-babel-read' + +(defun org-babel-session-buffer (&optional info) + "Return buffer name for session associated with current code block. +Return nil when no such live buffer with process exists. +When INFO is non-nil, it should be a list returned by +`org-babel-get-src-block-info'. +This function uses org-babel-session-buffer:<lang> function to +retrieve backend-specific session buffer name." + (when-let* ((info (or info (org-babel-get-src-block-info 'no-eval))) + (lang (nth 0 info)) + (session (cdr (assq :session (nth 2 info)))) + (cmd (intern (concat "org-babel-session-buffer:" lang))) + buffer-name) + (setq buffer-name + (if (fboundp cmd) + (funcall cmd session info) + ;; Use session name as buffer name by default. + session)) + (when buffer-name + (require 'ob-comint) + (when (org-babel-comint-buffer-livep buffer-name) + buffer-name)))) ;;;###autoload (defun org-babel-execute-src-block (&optional arg info params executor-type) @@ -842,9 +865,8 @@ (defun org-babel-execute-src-block (&optional arg info params executor-type) (default-directory (cond ((not dir) default-directory) - ((when-let ((session (cdr (assq :session params)))) - (when (org-babel-comint-buffer-livep session) - (buffer-local-value 'default-directory (get-buffer session))))) + ((when-let ((session (org-babel-session-buffer info))) + (buffer-local-value 'default-directory (get-buffer session)))) ((member mkdirp '("no" "nil" nil)) (file-name-as-directory (expand-file-name dir))) (t diff --git a/lisp/ob-lua.el b/lisp/ob-lua.el index a2b830ca3..b241fccdc 100644 --- a/lisp/ob-lua.el +++ b/lisp/ob-lua.el @@ -184,6 +184,11 @@ (defun org-babel-lua-with-earmuffs (session) name (format "*%s*" name)))) +(defun org-babel-session-buffer:lua (session &optional _) + "Return session buffer name for SESSION." + (or (org-babel-lua-session-buffer session) + (org-babel-lua-with-earmuffs session))) + (defun org-babel-lua-without-earmuffs (session) "Remove stars around *SESSION*, leaving SESSION." (let ((name (if (stringp session) session (format "%s" session)))) diff --git a/lisp/ob-python.el b/lisp/ob-python.el index cfc0fdcb6..89cdf4c47 100644 --- a/lisp/ob-python.el +++ b/lisp/ob-python.el @@ -260,6 +260,11 @@ (defun org-babel-python-without-earmuffs (session) (substring name 1 (- (length name) 1)) name))) +(defun org-babel-session-buffer:python (session &optional _) + "Return session buffer name for SESSION." + (or (org-babel-python-session-buffer session) + (org-babel-python-with-earmuffs session))) + (defun org-babel-python--python-util-comint-end-of-output-p () "Return non-nil if the last prompt matches input prompt. Backport of `python-util-comint-end-of-output-p' to emacs28. To @@ -302,8 +307,7 @@ (defun org-babel-python-initiate-session-by-key (&optional session) initialized session." (save-window-excursion (let* ((session (if session (intern session) :default)) - (py-buffer (or (org-babel-python-session-buffer session) - (org-babel-python-with-earmuffs session))) + (py-buffer (org-babel-session-buffer:python session)) (python-shell-buffer-name (org-babel-python-without-earmuffs py-buffer)) (existing-session-p (comint-check-proc py-buffer)) -- 2.43.0
-- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92>