Skip to content

Instantly share code, notes, and snippets.

@chrisdone-artificial
Last active July 20, 2023 13:58
Show Gist options
  • Save chrisdone-artificial/58fa0d59ade02528530fcc69e4a4c226 to your computer and use it in GitHub Desktop.
Save chrisdone-artificial/58fa0d59ade02528530fcc69e4a4c226 to your computer and use it in GitHub Desktop.
shoe.el
(define-derived-mode shoe-mode
fundamental-mode "Shoe"
"Auto-paging shell mode..
\\{shoe-mode-map}"
(linum-mode -1))
(defconst shoe-dir "~/.shoe")
(defvar shoe-shell-program "/bin/bash")
(define-key shoe-mode-map (kbd "RET") 'shoe-run-at-point)
(define-key shoe-mode-map (kbd "C-c C-k") 'shoe-clear)
(defun shoe-clear ()
(interactive))
(defun shoe-run-at-point ()
"Run whatever is there at the point."
(interactive)
(let ((existing-output-file
(get-text-property (line-beginning-position) 'shoe-output-file)))
(if existing-output-file
(find-file existing-output-file)
(when (get-text-property (line-beginning-position) 'shoe-run)
(error "You're already on a run."))
(when (= (line-beginning-position) (line-end-position))
(error "Nothing to run!"))
(let* ((timestamp (shoe-timestamp))
(run (let ((dir (concat shoe-dir "/" timestamp)))
(progn (make-directory dir t)
dir)))
(process-name (concat "shoe:" timestamp))
(script-file-name (concat run "/script.sh"))
(stdout-file-name (concat run "/stdout"))
(stderr-file-name (concat run "/stderr"))
(process-buffer (current-buffer)))
(put-text-property (line-beginning-position) (line-end-position) 'shoe-run run)
(write-region (line-beginning-position) (line-end-position) script-file-name nil :do-nothing)
(let* ((process (make-process
:name process-name
:buffer process-buffer
:filter 'shoe-filter
:sentinel 'shoe-sentinel
:connection-type 'pipe
:command (list shoe-shell-program
"-c"
(concat shoe-shell-program
" " script-file-name
" 1>" stdout-file-name
" 2>" stderr-file-name))))
(timer (run-with-idle-timer 1 t 'shoe-refresh process))
(marker (make-marker)))
(put-text-property (line-beginning-position) (line-end-position) 'shoe-process process)
(set-marker marker (line-end-position))
(process-put process 'run run)
(process-put process 'start (line-end-position))
(process-put process 'marker marker)
(process-put process 'timer timer))))))
(defun shoe-page-output (process stdout stderr &optional extra)
(with-current-buffer (process-buffer process)
(save-excursion
(let* ((start (process-get process 'start))
(run (process-get process 'run))
(end (marker-position (process-get process 'marker))))
(delete-region start end)
(goto-char start)
(insert "\n"
(concat
(propertize stdout 'face 'zenburn-blue 'shoe-output t 'shoe-output-file (concat run "/stdout"))
(propertize stderr 'face 'zenburn-red 'shoe-output t 'shoe-output-file (concat run "/stderr"))
(propertize (or extra "")
'face 'zenburn-green
'shoe-output 1)))
(set-marker (process-get process 'marker) (point))
(insert "\n")))))
(defun shoe-refresh (process &optional extra)
(let* ((run (process-get process 'run))
(stdout-file-name (concat run "/stdout"))
(stderr-file-name (concat run "/stderr"))
(stdout-output (shell-command-to-string (concat "tail -n 5 " stdout-file-name)))
(stderr-output (shell-command-to-string (concat "tail -n 5 " stderr-file-name))))
(shoe-page-output process stdout-output stderr-output extra)))
(defun shoe-filter (&rest args))
(defun shoe-sentinel (process status)
(cancel-timer (process-get process 'timer))
(shoe-refresh process (replace-regexp-in-string "\n" "" status)))
(defun shoe ()
"Open a shoe-mode buffer."
(interactive)
(with-current-buffer (get-buffer-create "*shoe*")
(shoe-mode)
(switch-to-buffer-other-window (current-buffer))
nil))
(defun shoe-timestamp ()
"Get the current timestamp."
(format-time-string "%Y%0m%0d/%0H%0M%0S-%0N"))
(provide 'shoe)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment