Remove xrepl from the release branch.

This commit is contained in:
Eli Barzilay 2011-07-19 17:03:17 -04:00
parent ccd9ab07a7
commit 32b53e6549
8 changed files with 0 additions and 2038 deletions

View File

@ -511,9 +511,6 @@ mz-extras :+= (collects: "rnrs/")
;; -------------------- readline ;; -------------------- readline
mz-extras :+= (package: "readline/") mz-extras :+= (package: "readline/")
;; -------------------- readline
mz-extras :+= (package: "xrepl/")
;; -------------------- wxme ;; -------------------- wxme
mz-extras :+= (collects: "wxme/") mz-extras :+= (collects: "wxme/")

View File

@ -1979,7 +1979,6 @@ path/s is either such a string or a list of them.
"collects/tests/xml" responsible (jay) "collects/tests/xml" responsible (jay)
"collects/tests/xml/test-clark.rkt" drdr:command-line #f drdr:timeout 300 "collects/tests/xml/test-clark.rkt" drdr:command-line #f drdr:timeout 300
"collects/tests/xml/xml-snip-bug.rkt" drdr:command-line (gracket "-t" *) "collects/tests/xml/xml-snip-bug.rkt" drdr:command-line (gracket "-t" *)
"collects/tests/xrepl" responsible (eli)
"collects/tests/zo-size.rkt" responsible (jay) "collects/tests/zo-size.rkt" responsible (jay)
"collects/tex2page" responsible (jay) "collects/tex2page" responsible (jay)
"collects/texpict" responsible (mflatt robby) "collects/texpict" responsible (mflatt robby)
@ -2070,7 +2069,6 @@ path/s is either such a string or a list of them.
"collects/xml/text-box-tool.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/text-box-tool.rkt" drdr:command-line (gracket-text "-t" *)
"collects/xml/text-snipclass.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/text-snipclass.rkt" drdr:command-line (gracket-text "-t" *)
"collects/xml/xml-snipclass.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/xml-snipclass.rkt" drdr:command-line (gracket-text "-t" *)
"collects/xrepl" responsible (eli)
"doc/release-notes/COPYING-libscheme.txt" responsible (mflatt) "doc/release-notes/COPYING-libscheme.txt" responsible (mflatt)
"doc/release-notes/COPYING.txt" responsible (mflatt) "doc/release-notes/COPYING.txt" responsible (mflatt)
"doc/release-notes/drracket" responsible (robby) "doc/release-notes/drracket" responsible (robby)

View File

@ -1,94 +0,0 @@
#lang at-exp racket/base
(define verbose? (make-parameter #t))
(define global-ns (current-namespace))
(define stderr (current-error-port))
(define (test-xrepl . args)
(define show-all? (verbose?))
(define-values [Ii Io] (make-pipe))
(define-values [Oi Oo] (make-pipe))
(define repl-thread
(parameterize ([current-input-port Ii]
[current-output-port Oo]
[current-error-port Oo]
[current-namespace (make-empty-namespace)]
[error-print-context-length 0] ; easier output
[exit-handler (λ (_) (kill-thread repl-thread))])
(thread (λ ()
(namespace-attach-module global-ns 'racket/base)
(namespace-require 'racket)
(dynamic-require 'xrepl #f)
(read-eval-print-loop)))))
(define (repl-> expected)
(define output (read-string (string-length expected) Oi))
(if (equal? output expected)
(when show-all? (display output))
(error 'xrepl "test failure, expected ~s, got ~s" expected output)))
(let loop ([strs args] [input? #f])
(cond
[(and (pair? strs) (equal? "" (car strs)))
(loop (cdr strs) input?)]
[(and (thread-dead? repl-thread) (null? strs))
(printf "All tests passed.\n")]
[(thread-dead? repl-thread)
(error 'xrepl "test failure, repl thread died unexpectedly")]
[(null? strs)
(if (sync/timeout 1 repl-thread)
(loop strs input?)
(error 'xrepl "test failure, repl thread is alive at end of tests"))]
[(eq? '« (car strs))
(when input? (error 'xrepl "bad test: unterminated `«'"))
(loop (cdr strs) #t)]
[(eq? '» (car strs))
(unless input? (error 'xrepl "bad test: redundant `»'"))
(loop (cdr strs) 'newline)]
[(regexp-match #rx"^(.*?)(?: *⇒[^\n]*)(.*)" (car strs))
=> (λ (m) (loop (list* (cadr m) (caddr m) (cdr strs)) input?))]
[(regexp-match #rx"^(.*?)([«»])(.*)" (car strs))
=> (λ (m) (loop (list* (cadr m) (string->symbol (caddr m)) (cadddr m)
(cdr strs))
input?))]
[(eq? 'newline input?)
(unless (regexp-match? #rx"^\n" (car strs))
(error 'xrepl "bad test: `»' followed by a non-newline"))
(newline Io) (flush-output Io)
(when show-all? (newline) (flush-output))
(loop (cons (substring (car strs) 1) (cdr strs)) #f)]
[input?
(display (car strs) Io)
(when show-all? (display (car strs)) (flush-output))
(loop (cdr strs) #t)]
[else
(repl-> (car strs))
(loop (cdr strs) #f)])))
@test-xrepl|={
-> «(- 2 1)»
1
-> «(values 2 3)»
2
3
-> «(values 4)»
4
-> «(list ^ ^^ ^^^ ^^^^)»
'(4 3 2 1)
-> «(module foo racket (define x 123))»
-> «,en foo»
'foo> «x»
123
'foo> «,top»
-> «(define enter! 123)»
-> «(enter! 'foo)»
procedure application: expected procedure, given: 123; arguments were: 'foo
-> «,en foo» but this still works
'foo> «,top»
-> «,switch foo»
; *** Initializing a new `foo' namespace with "racket/main.rkt" ***
; *** Switching to the `foo' namespace ***
foo::-> «,switch
; *** Switching to the `*' namespace ***
-> «,ex»
|=@||}=|

View File

@ -1,80 +0,0 @@
#lang racket/base
(require scribble/manual scribble/core scribble/decode
racket/list racket/sandbox)
(provide (all-from-out scribble/manual)
RL GUIDE cmd defcmd check-all-documented)
(define RL '(lib "readline/readline.scrbl"))
(define GUIDE '(lib "scribblings/guide/guide.scrbl"))
(define commands
(let ([c #f])
(λ ()
(unless c
(define e (call-with-trusted-sandbox-configuration
(λ () (make-evaluator 'racket/base))))
(e '(require xrepl/xrepl))
(e '(current-namespace (module->namespace 'xrepl/xrepl)))
(set! c (e '(for/list ([c (in-list commands-list)])
(list (car (command-names c))
(cdr (command-names c))
(command-argline c)
(command-blurb c)))))
(kill-evaluator e))
c)))
(define documented '())
(define (cmd* name0 . more)
(define name (if (symbol? name0) name0 (string->symbol name0)))
(define full-name
(or (and (assq name (commands)) name)
(for/or ([c (in-list (commands))]) (and (memq name (cadr c)) (car c)))
(error 'cmd "unknown command: ~s" name)))
(define content
(litchar (let ([s (format ",~a" name)])
(if (pair? more) (apply string-append s " " more) s))))
(link-element "plainlink" content `(xrepl ,(format "~a" full-name))))
(define-syntax-rule (cmd name more ...) (cmd* 'name more ...))
(define (cmd-index name)
(define namestr (format ",~a" name))
(define tag `(xrepl ,(format "~a" name)))
(define content (cmd* name))
(define ielem
(index-element #f content tag (list namestr) (list content)
'xrepl-command))
(toc-target-element #f (list ielem) tag))
(define (defcmd* name . text)
(set! documented (cons name documented))
(define-values [other-names argline blurb]
(apply values (cond [(assq name (commands)) => cdr]
[else (error 'defcmd "unknown command: ~s" name)])))
(define header
(list (cmd-index name) (litchar (string-append " " (or argline "")))))
(define desc
(list (hspace 2) (make-element 'italic blurb)))
(define synonyms
(and (pair? other-names)
(list (hspace 2)
"[Synonyms: "
(add-between (map (λ (n) (litchar (format ",~a" n)))
other-names)
" ")
"]")))
(splice
(list* (tabular #:style 'boxed `((,header) (,desc)
,@(if synonyms `((,synonyms)) `())))
"\n" "\n" text)))
(define-syntax-rule (defcmd name text ...) (defcmd* 'name text ...))
(define (check-all-documented)
(unless (= (length documented) (length (remove-duplicates documented)))
(error 'xrepl-docs "some commands were documented multiple times"))
(let ([missing (remove* documented (map car (commands)))])
(when (pair? missing)
(error 'xrepl-docs "missing command documentation: ~s" missing))))

View File

@ -1,5 +0,0 @@
#lang setup/infotab
(define name "eXtended REPL")
(define scribblings '(("xrepl.scrbl" () (tool-library))))

View File

@ -1,13 +0,0 @@
#lang racket/base
;; This file is intended to be loaded from your init file (evaluatue
;; (find-system-path 'init-file) to see where that is on your OS.)
(require "xrepl.rkt")
;; may want to disable inlining to allow redefinitions
;; (compile-enforce-module-constants #f)
;; create the command repl reader, and value-saving evaluator
(current-prompt-read (make-xrepl-reader))
(current-eval (make-xrepl-evaluator (current-eval)))

File diff suppressed because it is too large Load Diff

View File

@ -1,496 +0,0 @@
#lang scribble/doc
@(require scribble/manual "doc-utils.rkt"
scribble/decode (only-in scribble/core)
(for-label racket readline racket/help racket/enter
racket/trace profile))
@title{XREPL: eXtended REPL}
@author+email["Eli Barzilay" "eli@barzilay.org"]
@defmodule[xrepl]{
The @filepath{xrepl} collection extends the @exec{racket} @tech[#:doc
GUIDE]{REPL} significantly, turning it into a more useful tool for
interactive exploration and development. This includes ``meta
commands'', using readline, keeping past evaluation results, and
more.}
@; ---------------------------------------------------------------------
@section{Installing XREPL}
To use XREPL, start @exec{racket} and enter @racket[(require xrepl)].
You will know that it works when the prompt changes to a @litchar{->},
and, if you're working on a capable terminal, you will now have readline
editing. You can also start @exec{racket} and ask for XREPL to be
loaded using command-line arguments:
@commandline{racket -il xrepl}
If you want to enable XREPL automatically, add this expression to your
Racket initialization file.
@margin-note*{To load XREPL conditionally (e.g., not in older Racket
versions), you can use @racket[(dynamic-require 'xrepl #f)]. This
is a plain expression that can be placed inside @racket[when] and
elsewhere.}
An easy way to do the necessary editing is to enter @cmd[install!],
which will inspect and edit your initialization file (it will describe
the change and ask for your permission). Alternatively, you can edit
the file directly: on Unix, it is @filepath{~/.racketrc}, and for
other platforms evaluate @racket[(find-system-path 'init-file)] to see
where it is.
XREPL will set up a readline-based reader, so you do not need to load
that yourself. If your initialization file was previously set to load
readline via @racket[install-readline!], the @cmd[install!] command
will (notify you and) remove it. If you added it yourself, consider
removing it. (This is not strictly needed, but XREPL is slightly
better at detecting when to use readline.)
@; ---------------------------------------------------------------------
@section{Meta REPL Commands}
Most of the XREPL extensions are implemented as meta commands. These
commands are entered at the REPL, prefixed by a @litchar{,} and followed
by the command name. Note that several commands correspond directly to
Racket functions (e.g., @cmd[exit]) --- but since they work outside of
your REPL, they can be used even if the matching bindings are not
available.
@; ---------------------------------
@subsection{Generic Commands}
@defcmd[help]{
Without an argument, displays a list of all known commands. Specify a
command to get help specific to that command.
}
@defcmd[exit]{
Exits Racket, optionally with an error code (see @racket[exit]).
}
@defcmd[cd]{
Sets the @racket[current-directory] to the given path. If no path is
specified, use your home directory. Path arguments are passed through
@racket[expand-user-path] so you can use @litchar{~}. An argument of
@litchar{-} means ``the previous path''.
}
@defcmd[pwd]{
Reports the value of @racket[current-directory].
}
@defcmd[shell]{
Use @cmd[shell] (or @cmd[sh]) to run a generic shell command (via
@racket[system]). For convenience, a few synonyms are provided ---
they run the specified executables (still using @racket[system]).
When the REPL is in the context of a module with a known source file,
the shell command can use the @envvar{F} environment variable as the
path to the file. Otherwise, @envvar{F} is set to an empty string.
}
@defcmd[edit]{
Runs an editor, as specified by your @envvar{EDITOR} environment
variable, with the given file/s arguments. If no files are specified
and the REPL is currently inside a module's namespace, then the file
for that module is used. If the @envvar{EDITOR} environment variable
is not set, use the @cmd[drracket] command instead.
}
@defcmd[drracket]{
Runs DrRacket with the specified file/s. If no files are given, and
the REPL is currently inside a module, the file for that module is
used.
DrRacket is launched directly, without starting a new subprocess, and
it is then kept running in a hidden window so further invocations are
immediate. (When this command is used for the first time, you will
see DrRacket start as usual, and then its window will disappear ---
that window is keeping DrRacket ready for quick editing.)
In addition to file arguments, arguments can specify one of a few
flags for additional operations:
@itemize[
@item{@litchar{-new}: opens a new editing window. This is the default
when no files are given and the REPL is not inside a module,}
@item{@litchar{-open}: opens the specified file/s (or the current
module's file). This is the default when files are given or when
inside a module.}
@item{@litchar{-quit}: exits the running DrRacket instance. Quitting
DrRacket is usually not necessary. Therefore, if you try to quit it
from the DrRacket window, it will instead just close the window but
DrRacket will still be running in the background. Use this command
in case there is some exceptional problem that requires actually
quitting the IDE. (Once you do so, future uses of this command will
start a fresh instance.)}]
}
@; ---------------------------------
@subsection{Binding Information}
@defcmd[apropos]{
Searches for known bindings in the current namespace. The arguments
specify which binding to look for: use a symbol (without a
@litchar{'}) to look for bindings that contain that name, and use a
regexp (e.g., @racket[#rx"..."]) to use a regexp for the search.
Multiple arguments are and-ed together.
If no arguments are given, @emph{all} bindings are listed.
}
@defcmd[describe]{
For each of the specified names, describe where where it is coming
from and how it was defined if it names a known binding. In addition,
desribe the module (list its imports and exports) that is named by
arguments that are known module names.
By default, bindings are searched for at the runtime level (phase 0).
You can add a different phase level for identifier lookups as a first
argument. In this case, only a binding can be described, even if the
same name is a known module.
}
@defcmd[doc]{
Uses Racket's @racket[help] to browse the documentation, look for a
binding, etc. Note that this can be used even in languages that don't
have the @racket[help] binding.
}
@; ---------------------------------
@subsection{Requiring and Loading Files}
@defcmd[require]{
Most arguments are passed to @racket[require] as is. As a
convenience, if an argument specifies an existing file name, then use
its string form to specify the require, or use a @racket[file] in case
of an absolute path. In addition, an argument that names a known
symbolic module name (e.g., one that was defined on the REPL, or a
builtin module like @racket[#%network]), then its quoted form is used.
(Note that these shorthands do not work inside require subforms like
@racket[only-in].)
}
@defcmd[require-reloadable]{
Same as @cmd[require], but arranges to load the code in a way that
makes it possible to reload it later, or if a module was already
loaded (using this command) then reload it. Note that the arguments
should be simple specifications, without any require macros. If no
arguments are given, use arguments from the last use of this command
(if any).
Module reloading is enabled by turnning off the
@racket[compile-enforce-module-constants] parameter --- note that this
prohibits some opimizations, since the compiler assumes that all
bindings may change.
}
@defcmd[enter]{
Uses @racket[enter!] to have the REPL go `inside' a given module's
namespace. A module name can specify an existing file as with the
@cmd[require-reloadable] command. If no module is given, and the REPL
is already in some module's namespace, then `enter!' is used with that
module, causing it to reload if needed. Using @racket[#f] makes it go
back to the toplevel namespace.
Note that this can be used even in languages that don't have the
@racket[enter!] binding. In addition, @racket[enter!] is used in a
way that does not make it require itself into the target namespace.
}
@defcmd[toplevel]{
Makes the REPL go back to the toplevel namespace. Same as using the
@cmd[enter] command with a @racket[#f] argument.
}
@defcmd[load]{
Uses @racket[load] to load the specified file(s).
}
@; ---------------------------------
@subsection{Debugging}
@defcmd[time]{
Times execution of an expression (or expressions). This is similar to
@racket{time} but the information that is displayed is a bit easier to
read.
In addition, you can provide an initial number to specify repeating
the evaluation a number of times. In this case, each iteration is
preceded by two garbage collections, and when the iteration is done
its timing information and evaluation result(s) are displayed. When
the requested number of repetitions is done, some extreme results are
removed (top and bottom 2/7ths), and the remaining results are be
averaged. Finally, the resulting value(s) are from the last run are
returned (and can be accessed via the bindings for the last few
results, see @secref["past-vals"]).
}
@defcmd[trace]{
Traces the named function (or functions), using @racket[trace].
}
@defcmd[untrace]{
Untraces the named function (or functions), using @racket[untrace].
}
@defcmd[errortrace]{
@racketmodname[errortrace] is a useful Racket library which can
provide a number of useful services like precise profiling, test
coverage, and accurate error information. However, using it can be a
little tricky. @cmd[errortrace] and a few related commands fill this
gap, making @racketmodname[errortrace] easier to use.
@cmd[errortrace] controls global use of @racketmodname[errortrace].
With a flag argument of @litchar{+} errortrace instrumentation is
turned on, with @litchar{-} it is turned off, and with no arguments it
is toggled. In addition, a @litchar{?} flag displays instrumentation
state.
Remember that @racketmodname[errortrace] instrumentation hooks into
the Racket compiler, and applies only to source code that gets loaded
from source and therefore compiled. Therefore, you should use it
@emph{before} loading the code that you want to instrument.
}
@defcmd[profile]{
This command can perform profiling of code in one of two very
different ways: either statistical profiling via the
@racketmodname[profile] library, or using the exact profiler feature
of @racketmodname[errortrace].
When given a parenthesized expression, @cmd[profile] will run it via
the statistical profiler, as with the @racket[profile] form, reporting
results as usual. This profiler adds almost no overhead, and it
requires no special setup. In particular, it does not require
pre-compiling code in a special way. However, there are some
imprecise elements to this profiling: the profiler samples stack
snapshots periodically which can miss certain calls, and it is also
sensitive to some compiler optimizations like inlining procedures and
thereby not showing them in the displayed analysis. See
@other-doc['(lib "profile/scribblings/profile.scrbl")] for more
information.
In the second mode of operation, @cmd[profile] uses the precise
@racketmodname[errortrace] profiler. This profiler produces precise
results, but like other uses of the @racketmodname[errortrace], it
must be enabled before loading the code that is to be profiled. It
can add noticeable overhead (potentially affecting the reported
runtimes), but the results are accurate in the sense that no procedure
is skipped. (For additional details, see
@other-doc['(lib "errortrace/scribblings/errortrace.scrbl")].)
In this mode, the arguments are flags that control the profiler. A
@litchar{+} flag turns the profiler on --- and as usual with
@racketmodname[errortrace] functionality, this applies to code that is
compiled from now on. A @litchar{-} flag turns this instrumentation
off, and without any flags it is toggled. Once the profiler is
enabled, you can run some code and then use this command to report
profiling results: use @litchar{*} to show profiling results by time,
and @litchar{#} for the results by counts. Once you've seen the
results, you can evaluate additional code to collect more profiling
information, or you can reset the results with a @litchar{!} flag.
You can also combine several flags to perform the associated
operations, for example, @cmd[prof]{*!-} will show the accumulated
results, clear them, and turn profiler instrumentation off.
Note that using @emph{any} of these flags turns errortrace
instrumentation on, even @cmd[prof]{-} (or no flags). Use the
@cmd[errortrace] command to turn off instrumentation completely.
}
@defcmd[execution-counts]{
This command makes it easy to use the execution counts functionality
of @racketmodname[errortrace]. Given a file name (or names),
@cmd[execution-counts] will enable errortrace instrumentation for
coverage, require the file(s), display the results, disables coverage,
and disables instrumentation (if it wasn't previously turned on).
This is useful as an indication of how well the test coverage is for
some file.
}
@defcmd[coverage]{
Runs a given file and displays coverage information for the run. This
is somewhat similar to the @cmd[execution-counts] command, but instead
of using @racketmodname[errortrace] directly, it runs the file in a
(trusted) sandbox, using the @racketmodname[racket/sandbox] library
and its ability to provide coverage information.
}
@; ---------------------------------
@subsection{Miscellaneous Commands}
@defcmd[switch-namespace]{
This powerful command controls the REPL's namespace. While
@cmd[enter] can be used to make the REPL go into the namespace of a
specific module, the @cmd[switch-namespace] command can switch between
@emph{toplevel namespaces}, allowing you to get multiple separate
``workspaces''.
Namespaces are given names that are symbols or integers, where
@litchar{*} is the name for the first initial namespace, serving as
the default one. These names are not bindings --- they are only used
to label the known namespaces.
The most basic usage for this command is to simply specify a new name.
A namespace that corresponds to that name will be created and the REPL
will switch to that namespace. The prompt will now indicate this
namespace's name. The name is usually insignificant, except when it
is a @racket[require]-able module: in this case, the new namespace is
initialized to use that module's bindings. For example,
@cmd[switch]{racket/base} creates a new namespace that is called
@litchar{racket/base} and initializes it with
@racketmodname[racket/base]. For all other names, the new namespace
is initialized the same as the current one.
Additional @cmd[switch] uses:
@itemize[
@item{@cmd[switch]{!} --- reset the current namespace, recreating it
using the same initial library. Note that it is forbidden to reset
the default initial namespace, the one named @litchar{*} --- this
namespace corresponds to the one that Racket was started with, and
where XREPL was initialized. There is no technical reason for
forbidding this, but doing so is not useful as no resources will
actually be freed.}
@item{@cmd[switch]{! <module>} --- resets the current namespace with
the explicitly given simple module spec.}
@item{@cmd[switch]{<name> !} --- switch to a newly made namespace. If
a namespace by that name already existed, it is rest.}
@item{@cmd[switch]{<name> ! <module>} --- same, but reset to the given
module instead of what it previously used.}
@item{@cmd[switch]{- <name>} --- drop the specified namespace, making
it possible to garbage-collect away any associated resources. You
cannot drop the current namespace or the default one (@litchar{*}).}
@item{@cmd[switch]{?} --- list all known namespaces.}]
Do not confuse namespaces with sandboxes or custodians. The
@cmd{switch} command changes @emph{only} the
@racket[current-namespace] --- it does not install a new custodian or
restricts evaluation in any way. Note that it is possible to pass
around values from one namespace to another via past result reference;
see @secref["past-vals"].
}
@defcmd[syntax]{
Manipulate syntaxes and inspect their expansion.
Useful operations revolve around a ``currently set syntax''. With no
arguments, the currently set syntax is displayed; an argument of
@litchar{^} sets the current syntax from the last input to the REPL;
and an argument that holds any other s-expression will set it as the
current syntax.
Syntax operations are specified via flags:
@itemize[
@item{@litchar{+} uses @racket[expand-once] on the current syntax and
prints the resulting syntax. In addition, the result becomes the
new ``current'' syntax, so you can use this as a poor-man's syntax
stepper. (Note that in some rare cases expansion via a sequence of
@racket[expand-once] might differ from the actual expansion.)}
@item{@litchar{!} uses @racket[expand] to completely expand the
current syntax.}
@item{@litchar{*} uses the macro debugger's textual output to show
expansion steps for the current syntax, leaving macros from
@racketmodname[racket/base] intact. Does not change the current
syntax.
See @other-doc['(lib "macro-debugger/macro-debugger.scrbl")] for
details.}
@item{@litchar{**} uses the macro debugger similarly to @litchar{*},
but expands @racketmodname[racket/base] macros too, showing the
resulting full expansion process.}]
Several input flags and/or syntaxes can be spacified in succession as
arguments to @cmd{syntax}. For example, @cmd[stx]{(when 1 2) ** !}.
}
@defcmd[log]{
Starts (or stops) logging events at a specific level. The level can
be:
@itemize[
@item{a known level name (currently one of @litchar{fatal},
@litchar{error}, @litchar{warning}, @litchar{info},
@litchar{debug}),}
@item{@racket[#f] for no logging,}
@item{@racket[#t] for maximum logging,}
@item{an integer level specification, with @racket[0] for no logging
and bigger ones for additional verbosity.}]
}
@defcmd[install!]{
Convenient utility command to install XREPL in your Racket
initialization file. This is done carefully, you will be notified of
potential issues, and asked to authorize changes.
}
@; ---------------------------------------------------------------------
@section[#:tag "past-vals"]{Past Evaluation Results}
XREPL makes the last few interaction results available for evaluation
via special toplevel variables: @racketidfont{^}, @racketidfont{^^},
..., @racketidfont{^^^^^}. The first, @racketidfont{^}, refers to the
last result, @racketidfont{^^} to the previous one and so on.
As with the usual REPL printouts, @void-const results are not kept. In
case of multiple results, they are spliced in reverse, so
@racketidfont{^} refers to the last result of the last evaluation. For
example:
@verbatim[#:indent 4]{
-> 1
1
-> (values 2 3)
2
3
-> (values 4)
4
-> (list ^ ^^ ^^^ ^^^^)
'(4 3 2 1)}
The rationale for this is that @racketidfont{^} always refers to the
last @emph{printed} result, @racketidfont{^^} to the one before that,
etc.
These bindings are made available only if they are not already defined,
and if they are not modified. This means that if you have code that
uses these names, it will continue to work as usual.
@; ---------------------------------------------------------------------
@section{Hacking XREPL}
XREPL is mainly a convenience tool, and as such you might want to hack
it to better suite your needs. Currently, there is no convenient way to
customize and extend it, but this will be added in the future.
Meanwhile, if you're interested in tweaking XREPL, the @cmd[enter]
command can be used as usual to go into its implementation. For
example --- change an XREPL parameter:
@verbatim[#:indent 4]{
-> ,en xrepl/xrepl
xrepl/xrepl> ,e
xrepl/xrepl> (saved-values-char #\~)
xrepl/xrepl> ,top
-> 123
123
-> ~
123}
or add a command:
@verbatim[#:indent 4]{
-> ,en xrepl/xrepl
xrepl/xrepl> (defcommand eli "stuff" "eli says" ["Make eli say stuff"]
(printf "Eli says: ~a\n" (getarg 'line)))
xrepl/xrepl> ,top
-> ,eli moo
Eli says: moo}
While this is not intended as @emph{the} way to extend and customize
XREPL, it is a useful debugging tool should you want to do so.
If you have any useful tweaks and extensions, please mail the author or
the Racket developer's
@hyperlink["http://racket-lang.org/community.html"]{mailing list}.
@; ---------------------------------------------------------------------
@section{License Issues}
Under most circumstances XREPL uses the @racketmodname[readline]
library, and therefore a similar license caveat applies: XREPL cannot be
enabled by default because of the @seclink["readline-license" #:doc
RL]{readline licensing}, you have to explicitly do so yourself to use
it. (Note that XREPL is intended to be used only for enhanced
interaction, not as a library; so there are no additional issues.)
@; ---------------------------------------------------------------------
@(check-all-documented)