330 lines
23 KiB
HTML
330 lines
23 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/char_reader.clj </title>
|
|
</head>
|
|
<body>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
001 (ns beowulf.reader.char-reader
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
002 "Provide sensible line editing, auto completion, and history recall.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
003
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
004 None of what's needed here is really working yet, and a pull request with
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
005 a working implementation would be greatly welcomed.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
006
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
007 ## What's needed (rough specification)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
008
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
009 1. Carriage return **does not** cause input to be returned, **unless**
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
010 a. the number of open brackets `(` and closing brackets `)` match; and
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
011 b. the number of open square brackets `[` and closing square brackets `]` also match;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
012 2. <Ctrl-D> aborts editing and returns the string `STOP`;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
013 3. <Up-arrow> and <down-arrow> scroll back and forward through history, but ideally I'd like
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
014 this to be the Lisp history (i.e. the history of S-Expressions actually read by `READ`,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
015 rather than the strings which were supplied to `READ`);
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
016 4. <Tab> offers potential auto-completions taken from the value of `(OBLIST)`, ideally the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
017 current value, not the value at the time the session started;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
018 5. <Back-arrow> and <Forward-arrow> offer movement and editing within the line.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
019
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
020 TODO: There are multiple problems with JLine; a better solution might be
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
021 to start from here:
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
022 https://stackoverflow.com/questions/7931988/how-to-manipulate-control-characters"
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
023 (:require [beowulf.oblist :refer [*options* oblist]])
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
024 (:import [org.jline.reader.impl.completer StringsCompleter]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
025 [org.jline.reader.impl DefaultParser DefaultParser$Bracket]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
026 [org.jline.reader LineReaderBuilder]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
027 [org.jline.terminal TerminalBuilder]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
028 [org.jline.widget AutopairWidgets AutosuggestionWidgets]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
029
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
031 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
032 ;;; Copyright (C) 2022-2023 Simon Brooke
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
033 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
034 ;;; This program is free software; you can redistribute it and/or
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
035 ;;; modify it under the terms of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
036 ;;; as published by the Free Software Foundation; either version 2
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
037 ;;; of the License, or (at your option) any later version.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
038 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
039 ;;; This program is distributed in the hope that it will be useful,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
040 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
041 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
042 ;;; GNU General Public License for more details.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
043 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
044 ;;; You should have received a copy of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
045 ;;; along with this program; if not, write to the Free Software
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
046 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
047 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
049
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
050 ;; It looks from the example given [here](https://github.com/jline/jline3/blob/master/demo/src/main/java/org/jline/demo/Repl.java)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
051 ;; as though JLine could be used to build a perfect line-reader for Beowulf; but it also
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
052 ;; looks as though you'd need a DPhil in JLine to write it, and I don't have
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
053 ;; the time.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
054
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
055 (defn build-completer
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
056 "Build a completer which takes tokens from the oblist.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
057
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
058 This is sort-of working, in as much as hitting <TAB> on a blank line will
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
059 show a table of values from the oblist, but hitting <TAB> after you've
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
060 started input does not show potential completions for tokens you've started."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
061 []
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 12 forms covered">
|
|
062 (StringsCompleter. (map #(str (first %)) @oblist)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
063
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
064 ;; This breaks; it is not correctly resolving the Enum, although I can't work out
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
065 ;; why not.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
066 ;; (defn build-parser
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
067 ;; []
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
068 ;; (println "Building parser")
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
069 ;; (let [parser (DefaultParser.)]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
070 ;; (doall
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
071 ;; (.setEofOnUnclosedBracket
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
072 ;; parser DefaultParser$Bracket/ROUND))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
073
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
074 (def get-reader
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
075 "Return a reader, first constructing it if necessary.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
076
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
077 **NOTE THAT** this is not settled API. The existence and call signature of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
078 this function is not guaranteed in future versions."
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
079 (memoize (fn []
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
080 (let [term (.build (.system (TerminalBuilder/builder) true))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
081 reader (-> (LineReaderBuilder/builder)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
082 (.terminal term)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
083 (.completer (build-completer))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
084 ;; #(.parser % (build-parser))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
085 (.build))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
086 ;; apw (AutopairWidgets. reader false)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
087 ;; asw (AutosuggestionWidgets. reader)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
088 ]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
089 ;; (.enable apw)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
090 ;; (.enable asw)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
091 reader))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
092
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
093 (defn read-chars
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
094 "A drop-in replacement for `clojure.core/read-line`, except that line editing
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
095 and history should be enabled.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
096
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
097 **NOTE THAT** this does not fully work yet, but it is in the API because I
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
098 hope that it will work later!"
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
099 [prompt]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
100 (let [eddie (get-reader)]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
101 (loop [s (.readLine eddie (str prompt " "))]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 12 forms covered">
|
|
102 (if (and (= (count (re-seq #"\(" s))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
103 (count (re-seq #"\)" s)))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
104 (= (count (re-seq #"\[]" s))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
105 (count (re-seq #"\]" s))))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
106 s
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
107 (recur (str s " " (.readLine eddie ":: ")))))))
|
|
</span><br/>
|
|
</body>
|
|
</html>
|