001 (ns beowulf.reader.char-reader
002 "Provide sensible line editing, auto completion, and history recall.
003
004 None of what's needed here is really working yet, and a pull request with
005 a working implementation would be greatly welcomed.
006
007 ## What's needed (rough specification)
008
009 1. Carriage return **does not** cause input to be returned, **unless**
010 a. the number of open brackets `(` and closing brackets `)` match; and
011 b. the number of open square brackets `[` and closing square brackets `]` also match;
012 2. <Ctrl-D> aborts editing and returns the string `STOP`;
013 3. <Up-arrow> and <down-arrow> scroll back and forward through history, but ideally I'd like
014 this to be the Lisp history (i.e. the history of S-Expressions actually read by `READ`,
015 rather than the strings which were supplied to `READ`);
016 4. <Tab> offers potential auto-completions taken from the value of `(OBLIST)`, ideally the
017 current value, not the value at the time the session started;
018 5. <Back-arrow> and <Forward-arrow> offer movement and editing within the line.
019
020 TODO: There are multiple problems with JLine; a better solution might be
021 to start from here:
022 https://stackoverflow.com/questions/7931988/how-to-manipulate-control-characters"
023 ;; (:import [org.jline.reader LineReader LineReaderBuilder]
024 ;; [org.jline.terminal TerminalBuilder])
025 )
026
027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
028 ;;;
029 ;;; Copyright (C) 2022-2023 Simon Brooke
030 ;;;
031 ;;; This program is free software; you can redistribute it and/or
032 ;;; modify it under the terms of the GNU General Public License
033 ;;; as published by the Free Software Foundation; either version 2
034 ;;; of the License, or (at your option) any later version.
035 ;;;
036 ;;; This program is distributed in the hope that it will be useful,
037 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
038 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
039 ;;; GNU General Public License for more details.
040 ;;;
041 ;;; You should have received a copy of the GNU General Public License
042 ;;; along with this program; if not, write to the Free Software
043 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
044 ;;;
045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
046
047 ;; It looks from the example given [here](https://github.com/jline/jline3/blob/master/demo/src/main/java/org/jline/demo/Repl.java)
048 ;; as though JLine could be used to build a perfect line-reader for Beowulf; but it also
049 ;; looks as though you'd need a DPhil in JLine to write it, and I don't have
050 ;; the time.
051
052 ;; (def get-reader
053 ;; "Return a reader, first constructing it if necessary.
054
055 ;; **NOTE THAT** this is not settled API. The existence and call signature of
056 ;; this function is not guaranteed in future versions."
057 ;; (memoize (fn []
058 ;; (let [term (.build (.system (TerminalBuilder/builder) true))]
059 ;; (.build (.terminal (LineReaderBuilder/builder) term))))))
060
061 ;; (defn read-chars
062 ;; "A drop-in replacement for `clojure.core/read-line`, except that line editing
063 ;; and history should be enabled.
064
065 ;; **NOTE THAT** this does not work yet, but it is in the API because I hope
066 ;; that it will work later!"
067 ;; []
068 ;; (let [eddie (get-reader)]
069 ;; (loop [s (.readLine eddie)]
070 ;; (if (and (= (count (re-seq #"\(" s))
071 ;; (count (re-seq #"\)" s)))
072 ;; (= (count (re-seq #"\[]" s))
073 ;; (count (re-seq #"\]" s))))
074 ;; s
075 ;; (recur (str s " " (.readLine eddie)))))))