When gosh
is invoked without any script files,
it goes into interactive read-eval-print loop (REPL).
To exit the interpreter, type EOF (usually Control-D in Unix terminals)
or evaluate (exit)
.
In the interactive session, gosh
loads and
imports gauche.interactive
module (see gauche.interactive
- Utilities for interactive session) into user
module, for the
convenience. Also, if there’s a file .gaucherc under
the user’s home directory.
You may put settings there that would help interactive debugging.
(As of Gauche release 0.7.3,
.gaucherc is no longer loaded when gosh
is run
in script mode.)
Note that .gaucherc is always loaded in the user
module,
even if gosh
is invoked with -r7
option. The file
itself is a Gauche-specific feature, so you don’t need to consider
portability in it.
I recommend you to run gosh
inside Emacs, for it has
rich features useful to interact with internal Scheme process.
Put the following line to your .emacs file:
(setq scheme-program-name "gosh -i")
And you can run gosh
by M-x run-scheme.
If you run gosh
in the terminal with capability of cursor control,
a basic line-editing feature is available in the REPL session.
See Input editing, for the details.
If you want to use multibyte characters in the interaction,
make sure your terminal’s settings is in sync with gosh
’s
internal character encodings.
• Working in REPL: | ||
• Input editing: |
When you enter REPL, Gauche prompts you to enter a Scheme expression:
gosh>
(If you enable input editing, the prompt shows gosh$
instead
of gosh>
. See Input editing, for the details.)
After you complete a Scheme expression and type ENTER, the result of evaluation is printed.
gosh> (+ 1 2) 3 gosh>
The REPL session binds the last three results of evaluation
in the global variables *1
, *2
and *3
.
You can use the previous results via those history variables
in subsequent expressions.
gosh> *1 3 gosh> (+ *2 3) 6
If the Scheme expression yields multiple values (see Multiple values), they are printed one by one.
gosh> (min&max 1 -1 8 3) -1 8 gosh>
The history variable *1
, *2
and *3
only
binds the first value. A list of all values are bound to
*1+
, *2+
and *3+
.
gosh> *1 -1 gosh> *2+ (-1 8)
(Note that, when you evaluate *1
in the above example, the
history is shifted—so you need to use *2+
to refer to the
result of (min&max 1 -1 8 3)
.)
The *history
procedure shows the value of history variables:
gosh> (*history) *1: (-1 8) *2: -1 *3: -1 gosh>
As a special case, if an evaluation yields zero values, history
isn’t updated. The *history
procedure returns
no values, so merely looking at the history won’t change the history
itself.
gosh> (*history) *1: (-1 8) *2: -1 *3: -1 gosh> (values) gosh> (*history) *1: (-1 8) *2: -1 *3: -1
Finally, a global variable *e
is bound to the last uncaught
error condition object.
gosh> (filter odd? '(1 2 x 4 5)) *** ERROR: integer required, but got x Stack Trace: _______________________________________ 0 (eval expr env) At line 173 of "/usr/share/gauche-0.9/0.9.3.3/lib/gauche/interactive.scm" gosh> *e #<error "integer required, but got x">
(The error stack trace may differ depending on your installation.)
In REPL prompt, you can also enter special top-level commands for common tasks. Top-level commands are not Scheme expressions, not even S-expressions. They work like traditional line-oriented shell commands instead.
Top-level commands are prefixed by comma to be distinguished from
ordinary Scheme expressions. To see what commands are available,
just type ,help
and return.
gosh> ,help You're in REPL (read-eval-print-loop) of Gauche shell. Type a Scheme expression to evaluate. A word preceded with comma has special meaning. Type ,help <cmd> to see the detailed help for <cmd>. Commands can be abbreviated as far as it is not ambiguous. ,apropos|a Show the names of global bindings that match the regexp. ,cd Change the current directory. ,describe|d Describe the object. ,help|h Show the help message of the command. ,history Show REPL history. ,info|doc Show info document for an entry of NAME, or search entries by REGEXP. ,load|l Load the specified file. ,print-all|pa Print previous result (*1) without abbreviation. ,print-mode|pm View/set print-mode of REPL. ,pwd Print working directory. ,reload|r Reload the specified module, using gauche.reload. ,sh Run command via shell. ,source Show source code of the procedure if it's available. ,use|u Use the specified module. Same as (use module option ...).
To see the help of each individual commands, give the command name
(without comma) to the help
command:
gosh> ,help d Usage: d|describe [object] Describe the object. Without arguments, describe the last REPL result.
The ,d
(or ,describe
) top-level command describes
the given Scheme object
or the last result if no object is given. Let’s try some:
gosh> (sys-stat "/home") #<<sys-stat> 0x2d6adc0> gosh> ,d #<<sys-stat> 0x2d6adc0> is an instance of class <sys-stat> slots: type : directory perm : 493 mode : 16877 ino : 2 dev : 2081 rdev : 0 nlink : 9 uid : 0 gid : 0 size : 208 atime : 1459468837 mtime : 1401239524 ctime : 1401239524
In the above example, first we evaluated (sys-stat "/home")
,
which returns <sys-stat>
object. The subsequent ,d
top-level
command describes the returned <sys-stat>
object.
The description depends on the type of objects. Some types of objects shows extra information. If you describe an exact integer, it shows alternative interpretations of the number:
gosh> ,d 1401239524 1401239524 is an instance of class <integer> (#x538537e4, ~ 1.3Gi, 2014-05-28T01:12:04Z as unix-time) gosh> ,d 48 48 is an instance of class <integer> (#x30, #\0 as char, 1970-01-01T00:00:48Z as unix-time)
If you describe a symbol, its known bindings is shown.
gosh> ,d 'filter filter is an instance of class <symbol> Known bindings for variable filter: In module `gauche': #<closure (filter pred lis)> In module `gauche.collection': #<generic filter (2)>
If you describe a procedure, and its source code location is known,
that is also shown (see the Defined at...
line):
gosh> ,d string-interpolate #<closure (string-interpolate str :optional (legacy? #f))> is an instance of class <procedure> Defined at "../lib/gauche/interpolate.scm":64 slots: required : 1 optional : #t optcount : 1 locked : #f currying : #f constant : #f info : (string-interpolate str :optional (legacy? #f)) setter : #f
Let’s see a couple of other top-level commands. The ,info
command shows the manual entry of the given procedure, variable, syntax,
module or a class. (The text is searched from the installed
info document of Gauche. If you get an error, check if the
info document is properly installed.)
gosh> ,info append -- Function: append list ... [R7RS base] Returns a list consisting of the elements of the first LIST followed by the elements of the other lists. The resulting list is always newly allocated, except that it shares structure with the last list argument. The last argument may actually be any object; an improper list results if the last argument is not a proper list. gosh> ,info srfi.19 -- Module: srfi.19 This SRFI defines various representations of time and date, and conversion methods among them. On Gauche, time object is supported natively by '<time>' class (*note Time::). Date object is supported by '<date>' class described below. gosh> ,info <list> -- Builtin Class: <list> An abstract class represents lists. A parent class of '<null>' and '<pair>'. Inherits '<sequence>'. Note that a circular list is also an instance of the '<list>' class, while 'list?' returns false on the circular lists and dotted lists. (use srfi.1) (list? (circular-list 1 2)) => #f (is-a? (circular-list 1 2) <list>) => #t
You can also give a regexp pattern to ,info
command
(see Regular expressions).
It shows the entries in the document that match the pattern.
gosh> ,info #/^string-.*\?/ string-ci<=? Full string case conversion:44 String comparison:19 string-ci<? Full string case conversion:43 String comparison:18 string-ci=? Full string case conversion:42 String comparison:17 string-ci>=? Full string case conversion:46 String comparison:21 string-ci>? Full string case conversion:45 String comparison:20 string-immutable? String Predicates:9 string-incomplete? String Predicates:12 string-null? SRFI-13 String predicates:6 string-prefix-ci? SRFI-13 String prefixes & suffixes:28 string-prefix? SRFI-13 String prefixes & suffixes:26 string-suffix-ci? SRFI-13 String prefixes & suffixes:29 string-suffix? SRFI-13 String prefixes & suffixes:27
The ,a
command (or ,apropos
) shows the global identifiers
matches the given name or regexp:
gosh> ,a filter filter (gauche) filter! (gauche) filter$ (gauche) filter-map (gauche)
Note: The apropos
command looks for symbols from the
current process—that is, it only shows names that have been loaded
and imported.
But it also mean it can show any name as far as it exists in the
current process, regardless of whether it’s a documented API or an
internal entry.
On the other hand, the info
command searches info document, regardless of the named entity
has loaded into the current process or not. It doesn’t show
undocumented APIs.
You can think that apropos
is an introspection tool,
while info
is a document browsing tool.
When the result of evaluation is a huge nested structure,
it may take too long to display the result. Gauche actually set
a limit of length and depth in displaying structures, so you might
occasionally see the very long or deep list is trucated, with
… to show there are more items, or #
to show a subtree
is omitted
(Try evaluating (make-list 100)
on REPL).
You can type ,pa
(or ,print-all
) toplevel REPL command
to fully redisplay the previous result without omission.
By default, REPL prints out the result using pretty print:
gosh> ,u sxml.ssax gosh> (call-with-input-file "src/Info.plist" (cut ssax:xml->sxml <> '())) (*TOP* (*PI* xml "version=\"1.0\" encoding=\"UTF-8\"") (plist (|@| (version "1.0")) (dict (key "CFBundleDevelopmentRegion") (string "English") (key "CFBundleExecutable") (string "Gauche") (key "CFBundleIconFile") (string) (key "CFBundleIdentifier") (string "com.schemearts.gauche") (key "CFBundleInfoDictionaryVersion") (string "6.0") (key "CFBundlePackageType") (string "FMWK") (key "CFBundleSignature") (string "????") (key "CFBundleVersion") (string "1.0") (key "NSPrincipalClass") (string))))
If you want to turn off pretty printing for some reason,
type ,pm pretty #f
(or ,print-mode pretty #f
) on the
toplevel prompt, or start gosh
with the environment variable
GAUCHE_REPL_NO_PPRINT
set.
Type ,pm default
to make print mode back to default.
For more details, type ,help pm
.
Note: If you invoke gosh
with -q
option, which tells
gosh
not to load the initialization files, you still get
a REPL prompt but no fancy features such as history variables
are available. Those convenience features are implemented in
gauche.interactive
module, which isn’t loaded with -q
option.
When you run gosh
in a terminal capable of cursor control,
you can edit input expressions.
If input editing mode is on, the REPL prompt ends with $
, such
as gosh$
, instead of gosh>
.
(NB: Currently Gauche only supports terminals with vt100-like escape sequence, or Windows console. If the terminal type isn’t recognized as one of them, it falls back to non-editing mode. You can tell which mode it is from the prompt.)
The input editing feature is still under development. If you stumbled
with a serious bug, you can turn it off by setting an environment
variable GAUCHE_NO_READ_EDIT
, or giving -fno-read-edit
option
to gosh
, or type ,edit off
on REPL.
The key binding is similar to Emacs. Eventually we’ll provide customization feature. Before going into details, here’s a few quick useful tips.
C-l
(control+l) to clear and
redisplay.
,edit off
toplevel command.
C-M-x
(control-meta-x) to force sending the current input to the
evaluator.
M-h h
to see a brief summary of editor features,
M-h b
to see the list of keymap, or
M-h k
+ keystroke to see the help of the key.
(C-h
is the same as backspace).
gosh
, then resume it by shell’s job control feature
(e.g. C-z
, then fg
).
type ENTER to regain editing screen.
C-f
(forward) and C-b
(backward) moves the cursor forward
and backward character-wise. C-p
(previous) and C-n
(next)
moves character to previous or next line, if the input already has
multiple lines, or moves to previous or next history.
M-f
and M-b
move the cursor forward and backward, word-wise.
C-a
and C-e
to move to the beginning and end of the line,
M-<
and M->
to move to the beginning and end of of the input.
C-_
is undo the edit. You can keep typing C-_
to
undo the edits you’ve made.
We follow the Emacs model of undo
semantics, which allows “undoing undoes”.
For the detailed algorithm, see the comment at the bottom of
lib/text/line-edit.scm
in the source tree.
C-k
removes characters from the cursor to the end of line.
If the cursor is at the end of the line though, it removes the newline
character (so that next line is combined to the current line).
M-d
removes a word that contains the cursor, or a word
immediately after the cursor if it is not on a word.
C-@
set a mark to the current cursor position. C-w
removes
chracters between the cursor and the mark.
The characters removed by those commands are saved
in the buffer called “kill-ring”.
They can be recalled at the cursor position by C-y
(yank).
If you press M-y
immediately followed by C-y
, you can
go back to the older killed characters.
Typing TAB in or immediately after a partially typed word completes it. If there are multiple candidates, it completes up to the commom prefix, and typing TAB again shows the list of candidates.
What’s to be completed depends on the context. If it is at the toplevel
command (a word after a comma on a prompt),
it complets toplevel commands. If it is argument
of ,load
toplevel command, it completes pathnames.
If it is argument of ,use
or ,reload
toplevel commands,
it completes module names. In other contexts, it completes global bindings
visible from the current module.
For symbols and module names, segmented completion is possible; e.g.
c-w-c-c
completes to call-with-current-continuation
.
Currently the completion mechanism is hardcoded. We may add a way to customize it in future.
RET
(or C-m
) inserts a newline if the input isn’t
a complete S-expresson. If the input is already a complete S-expression,
however, it sends the entire input to the evaluator, no matter where
the cursor is. If you want to insert a newline in a complete S-expression,
you can use C-j
.
M-C-x
sends the current input regardless that the input is
a complete S-expression or not.
Input history is remembered and recalled by M-p
(prev-history)
and M-n
(next-history).
The cursor movement command C-p
and C-n
also moves to
the previous or next history if it is pressed when the cursor is
at the beginning or the end of the input lines.
The input interrupted by C-c
isn’t remembered.
By default, the input is saved to a file ~/.gosh_history when the
REPL is terminated normally, and reloaded when the next REPL is invoked.
The name of the history file can be changed by the environment variable
GAUCHE_HISTORY_FILE
. If the environment variable is defined to an
empty string, however, the history won’t be saved.
C-g
cancels the current multi-key sequences.
C-c
cancels the current input.
C-t
transpose characters at and before the cursor.
C-q
reads the next keystroke and insert it into the input as is.
M-(
inserts a pair of parentheses, and locate a cursor inside them.
C-l
clears the screen and redraws the current input buffer.