#|
You might need to
pkg_add ecl tmux rlwrap
The gist is if we
$ rlwrap ecl
> (compile-file "tmux.ecl" :load t)
> (tmux:start-session 'foo)
> (print (tmux:ls))
> (tmux:send-keys 'foo "date")
> (print (tmux:capturep 'foo))
> (tmux:kill-session 'foo)
> (ext:quit)
Sensible things happen.
My intent is to expose only a very small subset of tmux
useful  to interfacing  with SDF commode chat remotely.
Every #'ext:system and #'ext:run-program  could be made
#'uiop:run-program from (require 'asdf) but that's left
as an exercise to the reader.
|#


(defpackage tmux
(:export :start-session :send-keys :capturep
        :kill-session :ls :help :example))

(in-package tmux)

(defun start-session (name) "
(start-session name)
is like
tmux new-session -s 'NAME' -d
"
(ext:system
 (format nil "tmux new-session -s '~a' -d"
        name)))

(defun send-keys (session string &optional (pane 0)) "
(send-keys session \"date\")
is like
tmux send-keys -tSESSION:0 'date' C-m
"
(ext:system
 (format nil "tmux send-keys -t~a:~d '~a' C-m"
        session pane string)))

(defun capturep (session &optional (pane 0)) "
(capturep \"mysession\")
is like
tmux capturep -tmysession:0 -p
(returns a list of non-empty line strings)
"
(let ((cap (with-output-to-string (*standard-output*)
            (ext:run-program "tmux"
             `("capturep"
               ,(format nil "-t~a:~d" session pane)
               "-p")
             :output t))))
 (with-input-from-string (in cap)
  (loop for line = (read-line in nil nil)
   while line
   nconcing (unless (string= "" line) `(,line))))))

(defun ls () "
(ls)
is like
tmux ls
Returns a list of non-empty string output lines.
"
(let ((cap (with-output-to-string (*standard-output*)
            (ext:run-program "tmux" '("ls")
             :output t))))
 (with-input-from-string (in cap)
  (loop for line = (read-line in nil nil)
   while line
   nconcing (unless (string= "" line) `(,line))))))

(defun kill-session (name) "
(kill-session 'foo)
is like
tmux kill-session FOO
"
(let ((cap (with-output-to-string (*standard-output*)
            (ext:run-program "tmux"
             `("kill-session" ,(format nil "-t~a" name))
             :output t))))
 (with-input-from-string (in cap)
  (loop for line = (read-line in nil nil)
   while line
   nconcing (unless (string= "" line) `(,line))))))

(defun example () "
Starts a session named FOO
sends the date command to it
prints the capturep thereof
kills the session named FOO
"
(princ (ls)) (terpri)
(start-session 'foo)
(princ (ls)) (terpri)
(send-keys 'foo "date") (terpri)
(princ (capturep 'foo)) (terpri)
(kill-session 'foo))

(defun help ()
(format t "~{~a~%~}"
 '((example) (send-keys session string &optional (pane 0)) (tmux-ls) (start-session name) (capturep session &optional (pane 0)) (kill-session name))))