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