aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/repl_ln.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure/contrib/repl_ln.clj')
-rw-r--r--src/clojure/contrib/repl_ln.clj274
1 files changed, 0 insertions, 274 deletions
diff --git a/src/clojure/contrib/repl_ln.clj b/src/clojure/contrib/repl_ln.clj
deleted file mode 100644
index 7b8ef052..00000000
--- a/src/clojure/contrib/repl_ln.clj
+++ /dev/null
@@ -1,274 +0,0 @@
-;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and
-;; distribution terms for this software are covered by the Eclipse Public
-;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
-;; be found in the file epl-v10.html at the root of this distribution. By
-;; using this software in any fashion, you are agreeing to be bound by the
-;; terms of this license. You must not remove this notice, or any other,
-;; from this software.
-;;
-;; A repl with that provides support for lines and line numbers in the
-;; input stream.
-;;
-;; scgilardi (gmail)
-;; Created 28 November 2008
-
-(ns
- #^{:author "Stephen C. Gilardi",
- :doc "A repl with that provides support for lines and line numbers in the
- input stream."}
- clojure.contrib.repl-ln
- (:gen-class)
- (:import (clojure.lang Compiler LineNumberingPushbackReader RT Var)
- (java.io InputStreamReader OutputStreamWriter PrintWriter)
- java.util.Date)
- (:require clojure.main)
- (:use [clojure.contrib.def
- :only (defmacro- defonce- defstruct- defvar-)]))
-
-;; Private
-
-(declare repl)
-
-(defstruct- repl-info
- :name :started :name-fmt :prompt-fmt :serial :thread :depth)
-
-(defvar- +name-formats+
- {"%S" "%1$d" "%T" "%2$d" "%D" "%3$d"}
- "For set-name, maps our dynamic value codes to arg positions in
- the call to format in repl-name")
-
-(defvar- +prompt-formats+
- {"%S" "%1$d" "%T" "%2$d" "%D" "%3$d" "%L" "%4$d" "%N" "%5$s"}
- "For set-prompt, maps our dynamic value codes to arg positions in
- the call to format in repl-prompt")
-
-(defvar- +info-format+
- ["Name: %s"
- "Started: %s"
- "Name-fmt: \"%s\""
- "Prompt-fmt: \"%s\""
- "Serial: %d"
- "Thread: %d"
- "Depth: %d"
- "Line: %d"])
-
-(defvar- +info-defaults+
- (struct-map repl-info
- :name-fmt "repl-%S"
- :prompt-fmt "%S:%L %N=> "
- :depth 0)
- "Default/root values for repl info")
-
-(defonce- *serial-number* (atom 0)
- "Serial number counter")
-
-(defonce- *info* +info-defaults+
- "Public info for this repl")
-
-(defonce- *private* {}
- "Private info for this repl")
-
-(defmacro- update
- "Replaces the map thread-locally bound to map-var with a copy that
- includes updated and/or new values from keys and vals."
- [map-var & key-vals]
- `(set! ~map-var (assoc ~map-var ~@key-vals)))
-
-(defn- repl-name
- "Returns the repl name based on this repl's name-fmt"
- []
- (let [{:keys [name-fmt]} *private*
- {:keys [serial thread depth]} *info*]
- (format name-fmt serial thread depth)))
-
-(defn- prompt-hook
- []
- (let [prompt (*private* :prompt)]
- (var-set Compiler/LINE (.getLineNumber *in*))
- (prompt)))
-
-(defn- process-inits
- "Processes initial pairs of args of the form:
-
- -i filepath, or
- --init filepath
-
- by loading the referenced files, then accepts an optional terminating arg
- of the form:
-
- -r, or
- --repl
-
- Returns a seq of any remaining args."
- [args]
- (loop [[init filename & more :as args] args]
- (if (#{"-i" "--init"} init)
- (do
- (clojure.main/load-script filename)
- (recur more))
- (if (#{"-r" "--repl"} init)
- (rest args)
- args))))
-
-(defn- process-command-line
- "Args are strings passed in from the command line. Loads any requested
- init files and binds *command-line-args* to a seq of the remaining args"
- [args]
- (set! *command-line-args* (process-inits args)))
-
-(defn stream-repl
- "Repl entry point that provides convenient overriding of input, output,
- and err streams via sequential keyword-value pairs. Default values
- for :in, :out, and :err are streams associated with System/in,
- System/out, and System/err using UTF-8 encoding. Also supports all the
- options provided by clojure.contrib.repl-ln/repl."
- [& options]
- (let [enc RT/UTF8
- {:keys [in out err]
- :or {in (LineNumberingPushbackReader.
- (InputStreamReader. System/in enc))
- out (OutputStreamWriter. System/out enc)
- err (PrintWriter. (OutputStreamWriter. System/err enc))}}
- (apply hash-map options)]
- (binding [*in* in *out* out *err* err]
- (apply repl options))))
-
-(defn- -main
- "Main entry point, starts a repl enters the user namespace and processes
- command line args."
- [& args]
- (repl :init
- (fn []
- (println "Clojure" (clojure-version))
- (in-ns 'user)
- (process-command-line args))))
-
-;; Public
-
-(defn repl-prompt
- "Returns the current repl prompt based on this repl's prompt-fmt"
- []
- (let [{:keys [prompt-fmt]} *private*
- {:keys [serial thread depth]} *info*
- line (.getLineNumber *in*)
- namespace (ns-name *ns*)]
- (format prompt-fmt serial thread depth line namespace)))
-
-(defn set-repl-name
- "Sets the repl name format to the string name-fmt. Include the following
- codes in the name to make the corresponding dynamic values part of it:
-
- %S - repl serial number
- %T - thread id
- %D - nesting depth in this thread
-
- With no arguments, resets the repl name to its default: \"repl-%S\""
- ([]
- (set-repl-name (+info-defaults+ :name-fmt)))
- ([name-fmt]
- (update *info* :name-fmt name-fmt)
- (loop [[[code fmt] & more] (seq +name-formats+)
- name-fmt name-fmt]
- (if code
- (recur more (.replace name-fmt code fmt))
- (update *private* :name-fmt name-fmt)))
- (let [name (repl-name)]
- (update *info* :name name)
- (var-set Compiler/SOURCE name))
- nil))
-
-(defn set-repl-prompt
- "Sets the repl prompt. Include the following codes in the prompt to make
- the corresponding dynamic values part of it:
-
- %S - repl serial number
- %T - thread id
- %D - nesting depth in this thread
- %L - input line number
- %N - namespace name
-
- With no arguments, resets the repl pompt to its default: \"%S:%L %N=> \""
- ([]
- (set-repl-prompt (+info-defaults+ :prompt-fmt)))
- ([prompt-fmt]
- (update *info* :prompt-fmt prompt-fmt)
- (loop [[[code fmt] & more] (seq +prompt-formats+)
- prompt-fmt prompt-fmt]
- (if code
- (recur more (.replace prompt-fmt code fmt))
- (update *private* :prompt-fmt prompt-fmt)))
- nil))
-
-(defn repl-info
- "Returns a map of info about the current repl"
- []
- (let [line (.getLineNumber *in*)]
- (assoc *info* :line line)))
-
-(defn print-repl-info
- "Prints info about the current repl"
- []
- (let [{:keys [name started name-fmt prompt-fmt serial thread depth line]}
- (repl-info)]
- (printf
- (apply str (interleave +info-format+ (repeat "\n")))
- name started name-fmt prompt-fmt serial thread depth line)))
-
-(defn repl
- "A repl that supports line numbers. For definitions and evaluations made
- at the repl, the repl-name and line number will be reported as the
- origin. Use set-repl-name and set-repl-prompt to customize the repl name
- and prompt. This repl supports all of the keyword arguments documented
- for clojure.main/repl with the following change and additions:
-
- - :prompt has a new default
- default: #(clojure.core/print (repl-prompt))
-
- - :name-fmt, Name format string
- default: the name-fmt of the parent repl, or \"repl-%S\"
-
- - :prompt-fmt, Prompt format string
- default: the prompt-fmt of the parent repl, or \"%S:%L %N=> \""
- [& options]
- (let [{:keys [init need-prompt prompt flush read eval print caught
- name-fmt prompt-fmt]
- :or {init #()
- need-prompt (if (instance? LineNumberingPushbackReader *in*)
- #(.atLineStart *in*)
- #(identity true))
- prompt #(clojure.core/print (repl-prompt))
- flush flush
- read clojure.main/repl-read
- eval eval
- print prn
- caught clojure.main/repl-caught
- name-fmt (*info* :name-fmt)
- prompt-fmt (*info* :prompt-fmt)}}
- (apply hash-map options)]
- (try
- (Var/pushThreadBindings
- {Compiler/SOURCE (var-get Compiler/SOURCE)
- Compiler/LINE (var-get Compiler/LINE)
- (var *info*) *info*
- (var *private*) {}})
- (update *info*
- :started (Date.)
- :serial (swap! *serial-number* inc)
- :thread (.getId (Thread/currentThread))
- :depth (inc (*info* :depth)))
- (update *private*
- :prompt prompt)
- (set-repl-name name-fmt)
- (set-repl-prompt prompt-fmt)
- (clojure.main/repl
- :init init
- :need-prompt need-prompt
- :prompt prompt-hook
- :flush flush
- :read read
- :eval eval
- :print print
- :caught caught)
- (finally
- (Var/popThreadBindings)
- (prn)))))