rackety readline doc

This commit is contained in:
Matthew Flatt 2010-05-02 12:25:21 -06:00
parent b5705d9d96
commit 6a7aaf48cc

View File

@ -1,88 +1,88 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual @(require scribble/manual
(for-label scheme/base (for-label racket/base
readline readline
readline/pread readline/pread
readline/readline readline/readline
scheme/contract racket/contract
(except-in scheme/foreign ->))) (except-in ffi/unsafe ->)))
@(define readline "Readline") @(define readline "Readline")
@(define Readline "Readline") @(define Readline "Readline")
@title{@bold{Readline}: Terminal Interaction} @title{@bold{Readline}: Terminal Interaction}
The @filepath{readline} collection (not to be confused with MzScheme's The @filepath{readline} collection (not to be confused with Racket's
@scheme[read-line] function) provides glue for using GNU's @|readline| @racket[read-line] function) provides glue for using GNU's @|readline|
library with the MzScheme @scheme[read-eval-print-loop]. library with the Racket @racket[read-eval-print-loop].
@section{Normal Use of @|Readline|} @section{Normal Use of @|Readline|}
@defmodule*[(readline readline/rep-start)] @defmodule*[(readline readline/rep-start)]
The @schememodname[readline] library installs a @|readline|-based The @racketmodname[readline] library installs a @|readline|-based
input port, and hooks the prompt-and-read part of MzScheme's input port, and hooks the prompt-and-read part of Racket's
@scheme[read-eval-print-loop] to interact with it @racket[read-eval-print-loop] to interact with it
You can start MzScheme with You can start Racket with
@commandline{mzscheme -il readline} @commandline{racket -il readline}
or evaluate or evaluate
@schemeblock[ @racketblock[
(require readline) (require readline)
] ]
in the MzScheme @scheme[read-eval-print-loop] to load @|readline| in the Racket @racket[read-eval-print-loop] to load @|readline|
manually. You can also put (require readline) in your manually. You can also put (require readline) in your
@filepath{~/.mzschemerc}, so that MzScheme automatically loads @filepath{~/.racketrc}, so that Racket automatically loads
@|readline| support in interactive mode. @|readline| support in interactive mode.
If you want to enable @|readline| support only sometimes---such as If you want to enable @|readline| support only sometimes---such as
only when you use an @exec{xterm}, and not when you use an Emacs only when you use an @exec{xterm}, and not when you use an Emacs
shell---then you can use @scheme[dynamic-require], as in the following shell---then you can use @racket[dynamic-require], as in the following
example: example:
@schemeblock[ @racketblock[
(when (regexp-match? #rx"xterm" (when (regexp-match? #rx"xterm"
(getenv "TERM")) (getenv "TERM"))
(dynamic-require 'readline #f)) (dynamic-require 'readline #f))
] ]
The @schememodname[readline] library automatically checks whether the The @racketmodname[readline] library automatically checks whether the
current input port is a terminal, as determined by current input port is a terminal, as determined by
@scheme[terminal-port?], and it installs @|readline| only to replace @racket[terminal-port?], and it installs @|readline| only to replace
terminal ports. The @schememodname[readline/rep-start] module terminal ports. The @racketmodname[readline/rep-start] module
installs @|readline| without a terminal check. installs @|readline| without a terminal check.
By default, @|readline|'s completion is set to use the visible By default, @|readline|'s completion is set to use the visible
bindings in the current namespace. This is far from ideal, but it's bindings in the current namespace. This is far from ideal, but it's
better than @|readline|'s default filename completion which is rarely better than @|readline|'s default filename completion which is rarely
useful. In addition, the @|readline| history is stored across useful. In addition, the @|readline| history is stored across
invocations in MzScheme's preferences file, assuming that MzScheme invocations in Racket's preferences file, assuming that Racket
exits normally. exits normally.
@defproc[(install-readline!) void?]{ @defproc[(install-readline!) void?]{
Adds @scheme[(require readline/rep)] to the result of Adds @racket[(require readline/rep)] to the result of
@scheme[(find-system-path 'init-file)], which is @racket[(find-system-path 'init-file)], which is
@filepath{~/.mzschemerc} under Unix. Consequently, @|readline| will be @filepath{~/.racketrc} under Unix. Consequently, @|readline| will be
loaded whenever MzScheme is started in interactive mode. The loaded whenever Racket is started in interactive mode. The
declaration is added only if it is not already present, as determined declaration is added only if it is not already present, as determined
by @scheme[read]ing and checking all top-level expressions in the by @racket[read]ing and checking all top-level expressions in the
file. file.
For more fine-grained control, such as conditionally loading For more fine-grained control, such as conditionally loading
@|readline| based on an environment variable, edit @|readline| based on an environment variable, edit
@filepath{~/.mzschemerc} manually.} @filepath{~/.racketrc} manually.}
@section{Interacting with the @|Readline|-Enabled Input Port } @section{Interacting with the @|Readline|-Enabled Input Port }
@defmodule[readline/pread]{ The @schememodname[readline/pread] library @defmodule[readline/pread]{ The @racketmodname[readline/pread] library
provides customization, and support for prompt-reading after provides customization, and support for prompt-reading after
@schememodname[readline] installs the new input port.} @racketmodname[readline] installs the new input port.}
The reading facility that the new input port provides can be The reading facility that the new input port provides can be
customized with the following parameters. customized with the following parameters.
@ -91,58 +91,59 @@ customized with the following parameters.
@defparam[current-prompt bstr bytes?]{ @defparam[current-prompt bstr bytes?]{
A parameter that determines the prompt that is used, as a byte string. A parameter that determines the prompt that is used, as a byte string.
Defaults to @scheme[#"> "].} Defaults to @racket[#"> "].}
@;{
@defboolparam[show-all-prompts on?]{ @defboolparam[show-all-prompts on?]{
A parameter. If @scheme[#f], no prompt is shown until you write input A parameter. If @racket[#f], no prompt is shown until you write input
that is completely readable. For example, when you type that is completely readable. For example, when you type
@schemeblock[ @racketblock[
(foo bar) (+ 1 (foo bar) (+ 1
2) 2)
] ]
you will see a single prompt in the beginning. you will see a single prompt in the beginning.
The problem is that the first expression can be @scheme[(read-line)], The problem is that the first expression can be @racket[(read-line)],
which normally consumes the rest of the text on the @emph{same} line. which normally consumes the rest of the text on the @emph{same} line.
The default value of this parameter is therefore @scheme[#t], making The default value of this parameter is therefore @racket[#t], making
it mimic plain I/O interactions.} it mimic plain I/O interactions.}
}
@defparam[max-history n exact-nonnegative-integer?]{ @defparam[max-history n exact-nonnegative-integer?]{
A parameter that determines the number of history entries to save, A parameter that determines the number of history entries to save,
defaults to @scheme[100].} defaults to @racket[100].}
@defparam[keep-duplicates keep? (one-of/c #f 'unconsecutive #t)]{ @defparam[keep-duplicates keep? (one-of/c #f 'unconsecutive #t)]{
A parameter. If @scheme[#f] (the default), then when a line is equal A parameter. If @racket[#f] (the default), then when a line is equal
to a previous one, the previous one is removed. If it set to to a previous one, the previous one is removed. If it set to
@scheme['unconsecutive] then this happens only for an line that @racket['unconsecutive] then this happens only for an line that
duplicates the previous one, and if it is @scheme[#f] then all duplicates the previous one, and if it is @racket[#f] then all
duplicates are kept.} duplicates are kept.}
@defboolparam[keep-blanks keep?]{ @defboolparam[keep-blanks keep?]{
A parameter. If @scheme[#f] (the default), blank input lines are not A parameter. If @racket[#f] (the default), blank input lines are not
kept in history.} kept in history.}
@defparam[readline-prompt status (or/c false/c bytes? (one-of/c 'space))]{ @defparam[readline-prompt status (or/c false/c bytes? (one-of/c 'space))]{
The new input port that you get when you require The new input port that you get when you require
@schememodname[readline] is a custom port that uses @|readline| for @racketmodname[readline] is a custom port that uses @|readline| for
all inputs. The problem is when you want to display a prompt and then all inputs. The problem is when you want to display a prompt and then
read some input, @|readline| will get confused if it is not used when the read some input, @|readline| will get confused if it is not used when the
cursor is at the beginning of the line (which is why it has a cursor is at the beginning of the line (which is why it has a
@scheme[_prompt] argument.) To use this prompt: @racket[_prompt] argument.) To use this prompt:
@schemeblock[ @racketblock[
(parameterize ([readline-prompt some-byte-string]) (parameterize ([readline-prompt some-byte-string])
...code-that-reads...) ...code-that-reads...)
] ]
@ -150,20 +151,20 @@ cursor is at the beginning of the line (which is why it has a
This expression makes the first call to @|readline| use the prompt, and This expression makes the first call to @|readline| use the prompt, and
subsequent calls will use an all-spaces prompt of the same length (for subsequent calls will use an all-spaces prompt of the same length (for
example, when you're reading an S-expression). The normal value of example, when you're reading an S-expression). The normal value of
@scheme[readline-prompt] is @scheme[#f] for an empty prompt (and @racket[readline-prompt] is @racket[#f] for an empty prompt (and
spaces after the prompt is used, which is why you should use spaces after the prompt is used, which is why you should use
@scheme[parameterize] to restore it to @scheme[#f]). @racket[parameterize] to restore it to @racket[#f]).
A proper solution would be to install a custom output port, too, which A proper solution would be to install a custom output port, too, which
keeps track of text that is displayed without a trailing newline. As keeps track of text that is displayed without a trailing newline. As
a cheaper solution, if line-counting is enabled for the terminal's a cheaper solution, if line-counting is enabled for the terminal's
output-port, then a newline is printed before reading if the column is output-port, then a newline is printed before reading if the column is
not 0. (The @schememodname[readline] library enables line-counting not 0. (The @racketmodname[readline] library enables line-counting
for the output port.) for the output port.)
@bold{Warning:} The @|readline| library uses the output port directly. @bold{Warning:} The @|readline| library uses the output port directly.
You should not use it when @scheme[current-input-port] has been You should not use it when @racket[current-input-port] has been
modified, or when it was not a terminal port when MzScheme was started modified, or when it was not a terminal port when Racket was started
(eg, when reading input from a pipe). Expect some problems if you (eg, when reading input from a pipe). Expect some problems if you
ignore this warning (not too bad, mostly problems with detecting an ignore this warning (not too bad, mostly problems with detecting an
EOF).} EOF).}
@ -181,7 +182,7 @@ Prints the given prompt string and reads a line.}
@defproc[(readline-bytes [prompt bytes?]) bytes?]{ @defproc[(readline-bytes [prompt bytes?]) bytes?]{
Like @scheme[readline], but using raw byte-strings for the prompt and Like @racket[readline], but using raw byte-strings for the prompt and
returning a byte string.} returning a byte string.}
@ -203,16 +204,16 @@ Returns the length of the history list.}
@defproc[(history-get [idx integer?]) string?]{ @defproc[(history-get [idx integer?]) string?]{
Returns the history string at the @scheme[idx] position. @scheme[idx] Returns the history string at the @racket[idx] position. @racket[idx]
can be negative, which will make it count from the last (i.e, can be negative, which will make it count from the last (i.e,
@scheme[-1] returns the last item, @scheme[-2] returns the @racket[-1] returns the last item, @racket[-2] returns the
second-to-last, etc.)} second-to-last, etc.)}
@defproc[(history-delete [idx integer?]) string?]{ @defproc[(history-delete [idx integer?]) string?]{
Deletes the history string at the @scheme[idx] position. The position Deletes the history string at the @racket[idx] position. The position
is specified in the same way as the argument for @scheme[history-get].} is specified in the same way as the argument for @racket[history-get].}
@defproc[(set-completion-function! [proc ((or/c string? bytes?) @defproc[(set-completion-function! [proc ((or/c string? bytes?)
@ -221,16 +222,16 @@ is specified in the same way as the argument for @scheme[history-get].}
void?]{ void?]{
Sets @|readline|'s @tt{rl_completion_entry_function} to Sets @|readline|'s @tt{rl_completion_entry_function} to
@scheme[proc]. The @scheme[type] argument, whose possible values are @racket[proc]. The @racket[type] argument, whose possible values are
from @schememodname[scheme/foreign], determines the type of value from @racketmodname[ffi/unsafe], determines the type of value supplied
supplied to the @scheme[proc].} to the @racket[proc].}
@section{License Issues} @section{License Issues}
GNU's @|readline| library is covered by the GPL, and that applies to code GNU's @|readline| library is covered by the GPL, and that applies to
that links with it. PLT Scheme is LGPL, so this code is not used by code that links with it. Racket is licensed with the LGPL, so the
default; you should explicitly enable it if you want to. Also, be @|readline| code is not used by default; you should explicitly enable
aware that if you write code that uses this library, it will make your it if you want to. Also, be aware that if you write code that uses
code link to the @|readline| library when invoked, with the usual GPL this library, it will make your code link to the @|readline| library
implications. when invoked, with the usual GPL implications.