-
Notifications
You must be signed in to change notification settings - Fork 13
/
utility-functions.lisp
97 lines (82 loc) · 3.31 KB
/
utility-functions.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
;; Copyright (c) 2003 Nikodemus Siivola
;;
;; Permission is hereby granted, free of charge, to any person obtaining
;; a copy of this software and associated documentation files (the
;; "Software"), to deal in the Software without restriction, including
;; without limitation the rights to use, copy, modify, merge, publish,
;; distribute, sublicense, and/or sell copies of the Software, and to
;; permit persons to whom the Software is furnished to do so, subject to
;; the following conditions:
;;
;; The above copyright notice and this permission notice shall be included
;; in all copies or substantial portions of the Software.
;;
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
(in-package :linedit)
(declaim (type simple-string *word-delimiters*))
(defparameter *word-delimiters* "()[]{}',` \"")
(defvar *debug* nil)
(defun required ()
(error "Required argument missing."))
(defun concat (&rest strings)
(apply #'concatenate 'simple-string strings))
(defun word-delimiter-p (char)
(declare (simple-string *word-delimiters*)
(character char))
(find char *word-delimiters*))
(defun make-whitespace (n)
(make-string n :initial-element #\space))
(defun whitespacep (char)
(member char '(#\space #\newline #\tab #\return #\page)))
(defun at-delimiter-p (string index)
(and (< index (length string))
(word-delimiter-p (char string index))))
(defun start-debug (pathname &rest open-args)
"Start linedit debugging output to pathname, with additional
open-args passed to `open'."
(setf *debug* (apply #'open pathname
:direction :output
(append open-args '(:if-exists :append
:if-does-not-exist :create)))))
(defun end-debug ()
"End linedit debugging output."
(close *debug*)
(setf *debug* nil))
(defun dbg (format-string &rest format-args)
(when *debug*
(apply #'format *debug* format-string format-args)
(finish-output *debug*)))
(defun min* (&rest args)
"Like min, except ignores NILs."
(apply #'min (remove-if #'null args)))
(defun yes-or-no (control &rest args)
"Like Y-OR-N-P, but using linedit functionality."
;; Don't save the query response.
(let ((*history* nil)
(*killring* nil))
(loop
(let ((result (linedit :prompt (format nil "~? (y or n) " control args))))
(cond
((zerop (length result)))
((char-equal (elt result 0) #\y)
(return-from yes-or-no t))
((char-equal (elt result 0) #\n)
(return-from yes-or-no nil)))
(format *terminal-io* "Please type \"y\" for yes or \"n\" for no.~%")
(finish-output *terminal-io*)))))
(defun eof-handler (lisp-name quit-fn)
(handler-case
(cond ((yes-or-no "Really quit ~A?" lisp-name)
(fresh-line)
(funcall quit-fn))
(t
(return-from eof-handler "#.''end-of-file")))
(end-of-file ()
(fresh-line)
(funcall quit-fn))))