elisp: lay out subprocess standard i/o library

Implementation of stdio-read-line is working.
This commit is contained in:
Michael Volz 2025-01-24 17:12:43 +01:00
parent cc755ee405
commit 7a504bc311
3 changed files with 76 additions and 0 deletions

15
elisp/jx.el Normal file
View file

@ -0,0 +1,15 @@
;;; jx.el -- JsonInteractiveExperience for emacs -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'stdio)
(defun jx-test ()
"Test the jx stuff."
(interactive)
(let ((process (stdio-call (list "cat" "testfile"))))
(while-let ((line (stdio-read-line process)))
(message (format "jx-test: %s" line)))))
(provide 'jx)
;;; jx.el ends here

58
elisp/stdio.el Normal file
View file

@ -0,0 +1,58 @@
;;; stdio.el -- stdio routines for emacs lisp -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'cl-lib)
(cl-defstruct (stdio-process (:constructor stdio-process-create)
(:copier nil))
emacs-process buffer)
(defun stdio-make-filter (process)
"Return a filter function for PROCESS."
(lambda (_ input)
(setf (stdio-process-buffer process)
(concat (stdio-process-buffer process)
input))))
(defvar stdio--process-counter 0)
(defun stdio--make-process-name ()
"Generate a new uniqe process name."
(let* ((num stdio--process-counter)
(name (format "stdio-subp-%d" num)))
(setq stdio--process-counter (+ stdio--process-counter 1))
name))
(defun stdio-call (command)
"Call COMMAND, return stdio-process."
(let* ((process (stdio-process-create))
(emacs-process (make-process
:name (stdio--make-process-name)
:command command
:coding 'utf-8-unix
:noquery nil
:connection-type 'pipe
:filter (stdio-make-filter process)
)))
(setf (stdio-process-emacs-process process) emacs-process)
process))
(defun stdio-read-line (process)
"Read next line from PROCESS."
(if-let ((stdin-buf (stdio-process-buffer process))
(newline-pos (string-search "\n" stdin-buf))
(line (substring stdin-buf 0 newline-pos))
(rest (substring stdin-buf (+ 1 newline-pos))))
(progn
(setf (stdio-process-buffer process) rest)
line)
;; no newline character found
(if (accept-process-output (stdio-process-emacs-process process))
(stdio-read-line process)
;; no more output from process
(when (> (length stdin-buf) 0)
(progn (setf (stdio-process-buffer process) "")
stdin-buf)))))
(provide 'stdio)
;;; stdio.el ends here

3
elisp/testfile Normal file
View file

@ -0,0 +1,3 @@
eins
zwei
drei