iUse /usr/bin/less for text file - clic - Clic is an command line interactive client for gopher written in Common LISP Err bitreich.org 70 hgit clone git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/ URL:git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/ bitreich.org 70 1Log /scm/clic/log.gph bitreich.org 70 1Files /scm/clic/files.gph bitreich.org 70 1Refs /scm/clic/refs.gph bitreich.org 70 1Tags /scm/clic/tag bitreich.org 70 1README /scm/clic/file/README.md.gph bitreich.org 70 1LICENSE /scm/clic/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit a14e99ad9030bfb5141e762542098fe8ea902363 /scm/clic/commit/a14e99ad9030bfb5141e762542098fe8ea902363.gph bitreich.org 70 1parent efe07395e09bc6d6495dd651671c5d48e4a502ee /scm/clic/commit/efe07395e09bc6d6495dd651671c5d48e4a502ee.gph bitreich.org 70 hAuthor: Solene Rapenne URL:mailto:solene@perso.pw bitreich.org 70 iDate: Thu, 28 Dec 2017 16:48:32 +0100 Err bitreich.org 70 i Err bitreich.org 70 iUse /usr/bin/less for text file Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M clic.lisp | 107 +++++++++++++++++++------------ Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 66 insertions(+), 41 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/clic.lisp b/clic.lisp /scm/clic/file/clic.lisp.gph bitreich.org 70 i@@ -47,6 +47,8 @@ Err bitreich.org 70 i Err bitreich.org 70 i ;;; array of lines in buffer Err bitreich.org 70 i (defparameter *buffer* nil) Err bitreich.org 70 i+;;; array of lines of last menu Err bitreich.org 70 i+(defparameter *previous-buffer* nil) Err bitreich.org 70 i Err bitreich.org 70 i ;;; a list containing the last viewed pages Err bitreich.org 70 i (defparameter *history* '()) Err bitreich.org 70 i@@ -245,6 +247,9 @@ Err bitreich.org 70 i (format stream "~a~%" uri) Err bitreich.org 70 i (force-output stream) Err bitreich.org 70 i Err bitreich.org 70 i+ ;; save current buffer to display it back if needed Err bitreich.org 70 i+ (setf *previous-buffer* *buffer*) Err bitreich.org 70 i+ Err bitreich.org 70 i ;; for each line we receive we display it Err bitreich.org 70 i (loop for line = (read-line stream nil nil) Err bitreich.org 70 i while line Err bitreich.org 70 i@@ -255,10 +260,8 @@ Err bitreich.org 70 i "browse to the N-th link" Err bitreich.org 70 i (let ((destination (gethash key *links*))) Err bitreich.org 70 i (when destination Err bitreich.org 70 i- (print destination) Err bitreich.org 70 i (cond Err bitreich.org 70 i- Err bitreich.org 70 i- ;; visit a gopher link Err bitreich.org 70 i+ ;; visit a gopher link (type 0 or 1) Err bitreich.org 70 i ((location-p destination) Err bitreich.org 70 i (visit destination)) Err bitreich.org 70 i Err bitreich.org 70 i@@ -420,45 +423,67 @@ Err bitreich.org 70 i (defun display-buffer(type) Err bitreich.org 70 i "display the buffer" Err bitreich.org 70 i Err bitreich.org 70 i- ;; stdout is a terminal or not ? Err bitreich.org 70 i+ ;;;; stdout is a terminal or not ? Err bitreich.org 70 i (if (ttyp) Err bitreich.org 70 i- ;; yes it is Err bitreich.org 70 i- (let ((rows (- (c-termsize) 1))) ; -1 for command bar Err bitreich.org 70 i- Err bitreich.org 70 i- ;; we store the user input outside of the loop Err bitreich.org 70 i- ;; so if the user doesn't want to scroll Err bitreich.org 70 i- ;; we break the loop and then execute the command Err bitreich.org 70 i- (let ((input nil)) Err bitreich.org 70 i- (loop for line across *buffer* Err bitreich.org 70 i- counting line into row Err bitreich.org 70 i- do Err bitreich.org 70 i- ;; display lines Err bitreich.org 70 i- (cond Err bitreich.org 70 i- ((string= "1" type) Err bitreich.org 70 i- (formatted-output line)) Err bitreich.org 70 i- ((string= "0" type) Err bitreich.org 70 i- (format t "~a~%" line))) Err bitreich.org 70 i- Err bitreich.org 70 i- ;; split and ask to scroll or to type a command Err bitreich.org 70 i- (when (= row rows) Err bitreich.org 70 i- (setf row 0) Err bitreich.org 70 i- (format t "~a press enter or a shell command ~a : " Err bitreich.org 70 i- (get-color 'bg-black) Err bitreich.org 70 i- (get-color 'reset)) Err bitreich.org 70 i- (force-output) Err bitreich.org 70 i- (let ((first-input (read-char))) Err bitreich.org 70 i- (when (not (char= #\NewLine first-input)) Err bitreich.org 70 i- (unread-char first-input) Err bitreich.org 70 i- (let ((input-text (format nil "~a" (read-line nil nil)))) Err bitreich.org 70 i- (setf input input-text) Err bitreich.org 70 i- (loop-finish)))))) Err bitreich.org 70 i- Err bitreich.org 70 i- ;; in case of shell command, do it Err bitreich.org 70 i- (if input Err bitreich.org 70 i- (user-input input) Err bitreich.org 70 i- (when (< (length *buffer*) rows) Err bitreich.org 70 i- (dotimes (i (- rows (length *buffer*))) Err bitreich.org 70 i- (format t "~%")))))) Err bitreich.org 70 i+ ;;;; we are in interactive mode Err bitreich.org 70 i+ (cond Err bitreich.org 70 i+ ;;;; output is a text file ? Err bitreich.org 70 i+ ;;;; call the $PAGER ! Err bitreich.org 70 i+ ((string= "0" type) Err bitreich.org 70 i+ (pop *history*) ;; it's not a menu, we need to remove it from history Err bitreich.org 70 i+ ;;; generate a string from *buffer* array Err bitreich.org 70 i+ (let ((text (string-right-trim ; remove last newline Err bitreich.org 70 i+ (string #\Newline) Err bitreich.org 70 i+ (format nil "~{~a~%~}" ; concatenate lines Err bitreich.org 70 i+ (loop for line across *buffer* Err bitreich.org 70 i+ collect line))))) Err bitreich.org 70 i+ ;; create input stream used as stdin for $PAGER Err bitreich.org 70 i+ (let ((input (make-string-input-stream text))) Err bitreich.org 70 i+ (uiop:run-program (list #+ecl Err bitreich.org 70 i+ (si:getenv "PAGER") Err bitreich.org 70 i+ #+sbcl Err bitreich.org 70 i+ (sb-unix::posix-getenv "PAGER")) Err bitreich.org 70 i+ :input input Err bitreich.org 70 i+ :output :interactive)) Err bitreich.org 70 i+ ;; display last menu Err bitreich.org 70 i+ (setf *buffer* *previous-buffer*) Err bitreich.org 70 i+ (display-buffer "1"))) Err bitreich.org 70 i+ Err bitreich.org 70 i+ ;;;; output is a menu ? Err bitreich.org 70 i+ ;;;; display the menu and split it in pages if needed Err bitreich.org 70 i+ ((string= "1" type) Err bitreich.org 70 i+ Err bitreich.org 70 i+ ;; we store the user input outside of the loop Err bitreich.org 70 i+ ;; so if the user doesn't want to scroll Err bitreich.org 70 i+ ;; we break the loop and then execute the command Err bitreich.org 70 i+ (let ((input nil)) Err bitreich.org 70 i+ (let ((rows (- (c-termsize) 1))) ; -1 for command bar Err bitreich.org 70 i+ Err bitreich.org 70 i+ (loop for line across *buffer* Err bitreich.org 70 i+ counting line into row Err bitreich.org 70 i+ do Err bitreich.org 70 i+ (formatted-output line) Err bitreich.org 70 i+ Err bitreich.org 70 i+ ;; split and ask to scroll or to type a command Err bitreich.org 70 i+ (when (= row rows) Err bitreich.org 70 i+ (setf row 0) Err bitreich.org 70 i+ (format t "~a press enter or a shell command ~a : " Err bitreich.org 70 i+ (get-color 'bg-black) Err bitreich.org 70 i+ (get-color 'reset)) Err bitreich.org 70 i+ (force-output) Err bitreich.org 70 i+ (let ((first-input (read-char))) Err bitreich.org 70 i+ (when (not (char= #\NewLine first-input)) Err bitreich.org 70 i+ (unread-char first-input) Err bitreich.org 70 i+ (let ((input-text (format nil "~a" (read-line nil nil)))) Err bitreich.org 70 i+ (setf input input-text) Err bitreich.org 70 i+ (loop-finish)))))) Err bitreich.org 70 i+ Err bitreich.org 70 i+ ;; in case of shell command, do it Err bitreich.org 70 i+ (if input Err bitreich.org 70 i+ (user-input input) Err bitreich.org 70 i+ (when (< (length *buffer*) rows) Err bitreich.org 70 i+ (dotimes (i (- rows (length *buffer*))) Err bitreich.org 70 i+ (format t "~%")))))))) Err bitreich.org 70 i Err bitreich.org 70 i ;; not interactive Err bitreich.org 70 i ;; display and quit Err bitreich.org 70 .