Add a simple and hacky implemenation of org-babel mode

This commit is contained in:
Konstantin Nazarov 2024-10-12 19:13:42 +01:00
parent ad4f0a43d4
commit 13db2dd4b9
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
2 changed files with 128 additions and 18 deletions

99
ob-valeri.el Normal file
View file

@ -0,0 +1,99 @@
;;; ob-valeri.el --- org-babel functions for valeri evaluation
(require 'ob)
(require 'valeri-mode)
(defvar valeri-eoe-indicator "valeri-eoe")
(defvar org-babel-valeri-prompt "valeri> "
"String used for unique prompt.")
(defvar org-babel-valeri-command "valeri"
"Name of command to use for executing Valeri code.
It's possible to override it by using a header argument `:valeri'")
(defun org-babel-valeri-initiate-session (&optional session params)
"Initiate a valeri session.
If there is not a current inferior-process-buffer in SESSION
then create one. Return the initialized session.
Session settings (`:valeri' header arg value) are taken from PARAMS."
(unless (string= session "none")
(org-require-package 'valeri-mode)
(let* ((command (cdr (or (assq :valeri params)
'(nil . "valeri"))))
(buffer (get-buffer (format "*%s*" session)))
(new-session? (not buffer))
(session-buffer (or buffer (save-window-excursion
(run-valeri-or-pop-to-buffer
(if (functionp command)
(funcall command)
command)
(or session "valeri")
)
(current-buffer)))))
(if (org-babel-comint-buffer-livep session-buffer)
(progn
(sit-for .25)
;; Setup machine-readable prompt: no echo, prompts matching
;; uniquely by regexp.
(when new-session?
(with-current-buffer session-buffer
(setq-local
org-babel-comint-prompt-regexp-fallback comint-prompt-regexp
comint-prompt-regexp (concat "^" org-babel-valeri-prompt))
(comint-send-input nil t)
))
session-buffer)
(sit-for .5)
(org-babel-valeri-initiate-session session)))))
(defun org-babel-valeri-evaluate (buffer body)
"Pass BODY to the Valeri process in BUFFER."
(let ((escaped-body (format "\x1b[200~%s\x1b[201~" body))
(eoe-string (format "\n(println \"%s\")\n" valeri-eoe-indicator)))
(mapconcat
#'identity
(butlast
(split-string
(mapconcat
#'org-trim
(org-babel-comint-with-output
(buffer valeri-eoe-indicator t escaped-body)
(insert (org-babel-chomp escaped-body) eoe-string)
(comint-send-input nil t))
"\n") "[\r\n]")) "\n")
)
)
(defun org-babel-execute:valeri (body params)
"Execute Valeri BODY according to PARAMS.
This function is called by `org-babel-execute-src-block'."
(let* ((session (org-babel-valeri-initiate-session
(cdr (assq :session params)) params))
(org-babel-valeri-command
(or (cdr (assq :valeri params))
org-babel-valeri-command))
(result
(org-babel-valeri-evaluate session body)))
result
))
(defun org-babel-prep-session:valeri (session params)
"Prepare SESSION according to the header arguments specified in PARAMS."
;; (message "params=%S" params) ;; debugging
(let* ((session (org-babel-valeri-initiate-session session))
)
session))
(defun org-babel-load-session:valeri (session body params)
"Load BODY into SESSION."
(save-window-excursion
(let ((buffer (org-babel-prep-session:valeri session params)))
(with-current-buffer buffer
(goto-char (process-mark (get-buffer-process (current-buffer))))
(insert (org-babel-chomp body)))
buffer)))
(provide 'ob-valeri)
;;; ob-valeri.el ends here

View file

@ -43,30 +43,12 @@ Should be a list of strings."
"Buffer-local flag saying if this is a Valeri REPL buffer.") "Buffer-local flag saying if this is a Valeri REPL buffer.")
(make-variable-buffer-local 'valeri--repl-buffer-p) (make-variable-buffer-local 'valeri--repl-buffer-p)
(defvar valeri-eoe-indicator "valeri-eoe")
(defun valeri-get-create-process () (defun valeri-get-create-process ()
"Return active Valeri process creating one if necessary." "Return active Valeri process creating one if necessary."
(valeri-start-process) (valeri-start-process)
valeri-process) valeri-process)
(defun valeri-send-string (buffer body)
"Pass BODY to the Valeri process in BUFFER."
(let ((escaped-body (format "\x1b[200~%s\x1b[201~" body))
(eoe-string (format "\n(println \"%s\")\n" valeri-eoe-indicator)))
(mapconcat
#'identity
(butlast
(split-string
(mapconcat
#'org-trim
(org-babel-comint-with-output
(buffer valeri-eoe-indicator t escaped-body)
(insert (org-babel-chomp escaped-body) eoe-string)
(comint-send-input nil t))
"\n") "[\r\n]")) "\n")
)
)
;;;###autoload ;;;###autoload
(define-derived-mode valeri-mode lisp-mode "Valeri" (define-derived-mode valeri-mode lisp-mode "Valeri"
@ -135,6 +117,35 @@ When called interactively, switch to the process buffer."
(rx eos)) (rx eos))
output)) output))
(defun valeri-choose-buffer-name (name)
(generate-new-buffer-name (format "*%s*" name)))
(defun run-valeri-new (command &optional name)
"Create a new inferior Valeri process in a new or existing buffer.
COMMAND is the command to call. NAME will be used for the name of
the buffer, defaults to \"valeri\"."
(setq name (or name "valeri"))
(let ((commandlist (split-string-and-unquote command))
(buffer (current-buffer))
(process-environment (copy-sequence process-environment)))
(set-buffer (apply 'make-comint-in-buffer
name
(valeri-choose-buffer-name name)
(car commandlist)
nil (cdr commandlist)))
)
(pop-to-buffer (current-buffer)))
(defun run-valeri-or-pop-to-buffer (command &optional name buffer)
(if (not (and buffer
(comint-check-proc buffer)))
(run-valeri-new command name)
(pop-to-buffer buffer)
))
(provide 'valeri-mode) (provide 'valeri-mode)