diff options
author | Stuart Sierra <mail@stuartsierra.com> | 2010-01-20 15:39:56 -0500 |
---|---|---|
committer | Stuart Sierra <mail@stuartsierra.com> | 2010-01-20 15:39:56 -0500 |
commit | 2ede388a9267d175bfaa7781ee9d57532eb4f20f (patch) | |
tree | bb42002af196405d7e25cc4e30b4c1c9de5c06d5 /src/clojure/contrib/repl_ln.clj | |
parent | 1bc820d96048a6536706ff999e9892649b53c700 (diff) |
Move source files into Maven-style directory structure.
Diffstat (limited to 'src/clojure/contrib/repl_ln.clj')
-rw-r--r-- | src/clojure/contrib/repl_ln.clj | 274 |
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))))) |