#|
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))))