# Groovysh, the Groovy shell

version 6.0.0-RC-1

## 1. Groovy : Groovy Shell

The Groovy Shell, aka. `groovysh` is a command-line application which allows easy access to evaluate Groovy expressions, define classes and run simple experiments.

### 1.1. Features

- Rich cross-platform line editing, history and completion thanks to JLine3.

- ANSI colors (prompt, exception traces, etc).

- Simple, yet robust, command system with online help, user alias support and more.

### 1.2. Command-line Options and Arguments

The shell supports several options to control various features.

    > groovysh --help

    Usage: groovysh [options] [...]
    The Groovy Shell, aka groovysh, is a command-line application which allows easy
    access to evaluate Groovy expressions, define classes and run simple experiments.
      -c, --encoding=<CHARSET>   The encoding to use
      -C, --color[=<FLAG>]       Enable or disable use of ANSI colors
          -cp, -classpath, --classpath
                                 Specify where to find the class files - must be
                                   first argument
      -d, --debug                Enable debug output
      -D, --define=<name=value>  Define a system property
      -e, --evaluate=<CODE>      Evaluate the code first when starting interactive
                                   session
      -h, --help                 Display this help message
          -pa, --parameters      Generate metadata for reflection on method
                                   parameter names
          -pr, --enable-preview  Enable preview Java features (jdk12+ only) - must
                                   be after classpath but before other arguments
      -q, --quiet                Suppress superfluous output
      -T, --terminal=<TYPE>      Specify the terminal TYPE to use
      -v, --verbose              Enable verbose output
      -V, --version              Display the version

Here is an example showing the `-q`|`--quiet` and `-e`|`--evaluate` options:

### 1.3. Repl model

The Groovy Shell is a Read-Eval-Print Loop (REPL) which allows you to interactively evaluate Groovy expressions and statements, define classes and other types, invoke commands, and run simple experiments.

When you input a line, the shell will try to determine if the input you have given is a complete valid expression, statement, or definition. If not complete, it will prompt you for more input. If it is complete, it will execute the input, and print the result, if any, to the console. Each input you enter is executed in isolation.

There are some exceptions to this conceptual model. Any import statements entered will be remembered and used for all subsequent evaluations. Similarly, with some caveats we’ll discuss next, any previously defined classes, methods, and potentially variables will be available.

The shell has the concept of shared variables. Given that subsequent statements are run in isolation, you should store any results needed for later use in shared variables.

Many Groovy tutorials and examples use the `def` keyword or a type to define variables. Script examples might distinguish between local variables with a type and script binding variables where no type, nor the `def` or `var` type placeholders, are given. The script binding is the exact equivalent to the shell’s shared variables.

Because such statements are so common, the shell has a special mode called interpreter mode which allows you to use typed variables. The following table summarizes the differences between the two modes:

interpreterMode | off | on
--- | --- | ---
imports | remembered
types | available
methods | converted to closure shared variables | remembered
shared variables | available
local variables | forgotten | remembered

Conceptually, for things that are remembered in the above table, it is as if you included the related code at the start of each of your inputs.

The shell also has the concept of the "current buffer". This is the collection of all type, method, imports, and variable definitions. The ordering of these snippets is retained, which is important for the shell, since it is only executing one snippet at a time, it typically requires everything needed for a snippet to be pre-defined. This is different to a compiler which might compile multiple source files at once, and resolve references between types as needed.

### 1.4. Evaluating Expressions

#### 1.4.1. Simple Expressions

    groovy> println "Hello"
    Hello

#### 1.4.2. Evaluation Result

When a complete expression is found, it is compiled and evaluated. The result of the evaluation is stored into the `_` variable.

#### 1.4.3. Multi-line Expressions

Multi-line/complex expressions (like closure or class definitions) may be defined over several lines. When the shell detects that it has a complete expression it will compile and evaluate it.

#### 1.4.4. Defining types

You can define all the normal types, e.g. a class:

    groovy> class Foo {
    add: } >   def bar() {
    add: }}>     println "baz"
    add: }}>   }
    add: } > }

And use it in the normal way.

    groovy> foo = new Foo()
    groovy> foo.bar()
    baz

Defined classes are known to the shell and can be used in completion:

#### 1.4.5. Variables

Shell variables are all untyped (i.e. no `def` or other type information).

This will set a shell variable:

    foo = "bar"

But, this will evaluate a local variable and will not be saved to the shell’s environment:

    def foo = "bar"

This behavior can be changed by activating interpreter mode.

Variables definitions having the same name as existing definitions will replace the old definition with the new one.

#### 1.4.6. Methods

Methods can be defined in the shell, and will be saved for later use.

Defining a method is easy:

    groovy> def hello(name) {
    add: }>   println("Hello $name")
    add: }> }

And then using it is as one might expect:

    groovy> hello "Jason"
    Hello Jason

If a method definition has the same signature as an existing definition, the old definition will be replaced with the new one.

When in interpreterMode, methods are remembered and given as extra statements when executing the next input.

When not in interpreterMode, the shell internally creates a closure to encapsulate the method and stores it in the shared variables. In this case, variables and methods share the same namespace.

#### 1.4.7. Exceptions

If an exception is thrown, the shell will print the exception message and set a special `exception` shared variable.

### 1.5. Commands

The shell has a number of different commands, which provide rich access to the shell’s environment.

Commands all have a name, e.g. `/help` and `/prnt`. Commands may also have some predefined system aliases, e.g. `/h`. Users may also create their own aliases. This section will list commands in alphabetical order, but you can also use the `/help` command to list the available commands:

    groovy> /help
        /!           execute shell command
        /alias       create command alias
        /cat         concatenate and print FILES
        /cd          change directory
        /classloader display/manage Groovy classLoader data
        /clear       clear terminal
        /colors      view 256-color table and ANSI-styles
        /console     launch Groovy console
        /date        display date
        /del         delete console variables, methods, classes and imports
        /doc         open document on browser
        /echo        echos a value
        /exit        exit from app/script
        /grab        add maven repository dependencies to classpath
        /grep        search for PATTERN in each FILE or standard input.
        /head        display first lines of files
        /help        command help
        /highlighter manage nanorc theme system
        /history     list history of commands
        /imports     show/delete import statements
        /inspect     display/browse object info on terminal/object browser
        /keymap      manipulate keymaps
        /less        file pager
        /load        load state/a file into the buffer
        /ls          list files
        /methods     show/delete methods
        /nano        edit files
        /pipe        create/delete pipe operator
        /prnt        print object
        /pwd         print working directory
        /reset       clear the buffer
        /save        save state/the buffer to a file
        /setopt      set options
        /setvar      set lineReader variable value
        /show        list console variables
        /slurp       slurp file or string variable context to object
        /sort        writes sorted standard input to standard output.
        /tail        display last lines of files
        /ttop        display and update sorted information about threads
        /types       show/delete types
        /unalias     remove command alias
        /unsetopt    unset options
        /vars        show/delete variable declarations
        /wc          word, line, character, and byte count
        /widget      manipulate widgets

While in the interactive shell, you can ask for help for any command to get more details about its syntax or function. You can use `/help <command>` or `<command> --help`. Here is an example of what happens when you ask for help for the `/help` command:

    groovy> /help /help
    help -  command help
    Usage: help [TOPIC...]
      -? --help                      Displays command help
         --groups                    Commands are grouped by registries
      -i --info                      List commands with a short command info

#### 1.5.1. `/alias`

Create an alias for a commandline fragment. The fragment could be Groovy code or a shell command. When evaluating a commandline, the alias will be replaced with the fragment:

The `/cat` command is already available. As can be seen here, aliases are replaced before command selection, so with the above alias in place, we actually invoke `/less -F` command, which has syntax highlighting, instead of the builtin `/cat` which doesn’t.

The fragment is expected to be at the start of a line but other text may follow:

Aliases are persisted in a `.groovysh/aliases.json` file in the user home directory.

See also the `/unalias` command, which allows aliases to be removed.

#### 1.5.2. `/cat`

Concatenate and print files:

    groovy> /cat answers.json answers.toml
    {
        "answer": {
            "universe":
            42
        }
    }
    [answer]
    universe = 42

See also the `/less` command, which can be used to display the contents of a file a page at a time with syntax highlighting.

#### 1.5.3. `/cd`

Change the current working directory. `groovysh` keeps track of a current working directory. You can view it with `/pwd` and change it with `/cd`.

The `groovysh` file commands (`/cat`, `/less`, `/head`, `/slurp`, `/load`, `/ls`, etc.) will use the current working directory.

| The JVM running `groovysh` also has its own concept of the current working directory, which is the directory in which `groovysh` was started, so `/!ls` and `/ls` may not show the same files. Using `/!cd` only changes the working directory within the context of that one shell command.

There is a predefined shared variable `PWD` which can assist with invoking shell commands. So, on unix platforms, `/ls` will list the same files as `/!ls $PWD`.

See also the `/pwd` command, which prints the current working directory.

#### 1.5.4. `/classloader`

Display and manage the Groovy classloader data.

Let’s `/grab` a dependency, define a class using it, and then use the `/classloader` command to see the classloader data:

#### 1.5.5. `/clear`

Clears the screen.

#### 1.5.6. `/colors`

Displays the available colors.

This can be useful when configuring the console options, for example the `PRNT_COLORS`:

As this example shows, you can mix color names (like black and magenta), theme colors (like NUMBER), and color numbers (like 75).

Here is an example for `HELP_COLORS`:

Here is an example for `LS_COLORS`:

See the REPL Console Customization documentation for more details about such customization.

#### 1.5.7. `/console`

Displays the current buffer in the GroovyConsole.

#### 1.5.8. `/date`

Groovy has numerous classes for working with dates and time.

Here are some examples using the legacy date/calendar classes:

    groovy> println new Date()
    Tue Aug 19 14:35:22 AEST 2025
    groovy> printf '%1ta %1$tb %1$td %1$tT %1$tZ %1$tY%n', new Date()
    Tue Aug 19 14:35:22 AEST 2025
    groovy> println Calendar.instance.time
    Tue Aug 19 14:35:22 AEST 2025
    groovy> println new Date().format('dd-MMM-yyyy HH:mm')
    19-Aug-2025 14:35

Here are some examples using the `java.time` classes:

    groovy> println LocalDateTime.now()
    2025-08-19T14:17:35.383665
    groovy> println Instant.now()
    2025-08-19T04:17:35.590829Z
    groovy> printf '%1ta %1$tb %1$td %1$tT %1$tY%n', LocalDateTime.now()
    Tue Aug 19 14:47:35 2025
    groovy> println LocalDateTime.now().format('dd-MMM-yyyy HH:mm')
    19-Aug-2025 14:47

The `/date` command is an alternative for those familiar with the unix `date` commandL:

    groovy> /date -R
    Tue, 19 Aug 2025 14:17:05 +10
    groovy> /date --rfc-3339=seconds
    2025-08-19 14:17:05+10
    groovy> /date --rfc-3339=time
    Aug Tue 19 14:17:05 2025

#### 1.5.9. `/del`

Deletes objects from the shell. The command looks for any variable, method, type, shared data, or import with the given name and deletes it.

Here we create two variables, `x` and `y`, then delete the `x` variable:

See also, the `/vars`, `/methods`, `/types`, and `/imports` commands. These offer a `-d`|`--delete` option to delete the respective objects with completion.

#### 1.5.10. `/doc`

Open documentation in a browser.

Documentation can be found for Groovy classes like this:

    groovy> /doc groovy.lang.Tuple

For Java classes, the `/doc` command will look for the class in the JDK documentation as well as in the groovy-jdk if Groovy has any extensions for that class:

    groovy> /doc java.util.List

Documentation is also extensible, so you can add your own documentation using regex patterns. For example, if you add the following line to your `~/.groovy/groovysh_init.groovy` file:

    CONSOLE_OPTIONS.docs.groovy='https://groovy-lang.org/documentation.html'
    CONSOLE_OPTIONS.docs.'org/jline/.*'='https://www.javadoc.io/doc/org.jline/jline/latest/'

Then, the following commands will open the Groovy documentation page and the JLine documentation for `Terminal` respectively in your browser:

    groovy> /doc groovy
    groovy> /doc org.jline.terminal.Terminal

#### 1.5.11. `/echo`

The `/echo` command outputs its arguments to the console. Arguments are output verbatim, but variable expansion is also supported.

See also the `/prnt` command, which is similar but may perform additional formatting on the output(s).

#### 1.5.12. `/exit`

Exit the shell.

This is the only way to exit the shell. Well, you can still `CTRL-Z` on unix platforms, but things like `CTRL_C` are trapped. (See JLine3 documentation for more details.)

#### 1.5.13. `/grab`

Grab a dependency (Maven, Ivy, etc.) from Internet sources or cache, and add it to the Groovy Shell environment.

    groovy> /grab org.apache.commons:commons-collections4:4.5.0
    groovy> import org.apache.commons.collections4.bidimap.TreeBidiMap
    groovy> TreeBidiMap t = [apple: 'red']
    {apple=red}
    groovy> t.inverseBidiMap()
    {red=apple}

Completion is available. Currently, completion options are populated by known artifacts in the local Maven (~/.m2) and Grape (~/.groovy/grapes) repositories. In the future, completion from a remote repositories may be supported.

    groovy> /grab org.apache.commons:commons-<TAB>
    commons-collections4:     commons-dbcp2:            commons-lang3:
    commons-compress:         commons-digester3:        commons-math3:
    commons-configuration2:   commons-email:            commons-parent:
    commons-crypto:           commons-exec:             commons-pool2:
    commons-csv:              commons-imaging:          commons-text:

This command can be given at any time to add new dependencies.

#### 1.5.14. `/grep`

The `/grep` command searches for patterns in files or standard input.

#### 1.5.15. `/head`

The `/head` command displays the start of a file.

    groovy> /head -n2 fruit.txt
    apple
    banana

#### 1.5.16. `/highlighter`

The `/highlighter` command manages the nanorc theme system. Useful options include `--list` (show available themes), `--view=THEME` (preview a theme), `--switch=THEME` (change the active theme by rewriting your user-config `jnanorc`), and `--refresh` (reapply highlighting after a switch).

Note: `--view` and `--switch` take full filenames including the `.nanorctheme` extension, not bare theme names. `/highlighter --list` shows the canonical form:

    groovy> /highlighter --list
    /Users/<you>/.groovy:
    dark.nanorctheme
    light.nanorctheme
    groovy> /highlighter --switch=light.nanorctheme
    groovy> /highlighter --refresh

Theme switching operates on user-config copies of `jnanorc` (used by the line reader and most commands) and `jlessrc` (used by `/less`); if a file is missing, that path silently no-ops on `--switch`. So a partial setup with only `jnanorc` will switch the prompt highlighting but leave `/less` permanently on whichever theme the classpath copy of `jlessrc` ships with.

Once you create user-config copies, JLine resolves both the `theme` directive and the `include .nanorc` entries *relative to the user-config directory — the classpath copies are no longer consulted. So you also need the per-language syntax files (`groovy.nanorc`, `java.nanorc`, `json.nanorc`, `xml.nanorc`, `yaml.nanorc`, etc.) in the same directory, or you’ll see the theme palette loaded but no actual highlighting (every file rendered as plain text). Easiest setup is to copy the entire `nanorc/` resource directory in one go:

    cp <groovysh-src>/src/main/resources/nanorc/* ~/.groovy/

#### 1.5.17. `/history`

Display, manage and recall edit-line history. The `/history` command has numerous options which let you list (with various options), save, read, and clear the edit-line history.

    groovy> /history -?
    history -  list history of commands
    Usage: history [-dnrfEie] [-m match] [first] [last]
           history -ARWI [filename]
           history -s [old=new] [command]
           history --clear
           history --save
      -? --help                      Displays command help
         --clear                     Clear history
         --save                      Save history
      -m match                       If option -m is present the first argument is taken as a pattern
                                     and only the history events matching the pattern will be shown
      -d                             Print timestamps for each event
      -f                             Print full time date stamps in the US format
      -E                             Print full time date stamps in the European format
      -i                             Print full time date stamps in ISO8601 format
      -n                             Suppresses command numbers
      -r                             Reverses the order of the commands
      -A                             Appends the history out to the given file
      -R                             Reads the history from the given file
      -W                             Writes the history out to the given file
      -I                             If added to -R, only the events that are not contained within the internal list are added
                                     If added to -W or -A, only the events that are new since the last incremental operation
                                     to the file are added
      [first] [last]                 These optional arguments may be specified as a number or as a string. A negative number
                                     is used as an offset to the current history event number. A string specifies the most
                                     recent event beginning with the given string.
      -e                             Uses the nano editor to edit the commands before executing
      -s                             Re-executes the command without invoking an editor

Here is an example of using the `/history` command:

#### 1.5.18. `import`

Add a custom import which will be included for all shell evaluations.

    groovy> import java.util.concurrent.BlockingDeque

Module imports (JEP 476) are also supported, which import all exported packages from a named module:

    groovy> import module java.sql
    groovy> Connection.name
    ===> java.sql.Connection

This command can be given at any time to add new imports.

Completion is available and prompts a level at a time using the package structure of all known classes.

    groovy> import java.util.concurrent.<TAB>
    others
    atomic                        locks
    Classes
    AbstractExecutorService       ConcurrentSkipListMap         ForkJoinPool
    ArrayBlockingQueue            ConcurrentSkipListSet         ForkJoinTask
    ...

Once an import statement has been executed, relevant classes will become available for completion:

#### 1.5.19. `/imports`

You can use this to list and delete existing imports.

    groovy> /imports
    import java.util.concurrent.BlockingQueue

#### 1.5.20. `/img`

The `/img` command displays an image inline using JLine’s terminal-graphics support (Sixel, Kitty, or iTerm2 protocols, auto-detected). The argument is either a local file path, an `http(s)://` URL, or a Groovy variable reference using the standard `$` syntax.

    groovy> /img chart.png
    groovy> /img --width=80 https://example.com/diagram.png
    groovy> img = new java.awt.image.BufferedImage(200, 100, 1)  // some BufferedImage
    groovy> /img $img

When the argument resolves to a Groovy value (rather than a path), `/img` will accept any of:

- a `java.awt.image.BufferedImage` — used as-is

- a `java.awt.image.RenderedImage` — drawn into a `BufferedImage`

- anything with a `createBufferedImage(int, int)` method (e.g. `org.jfree.chart.JFreeChart`) — duck-typed, no compile-time dependency

- anything with a `toBufferedImage(int, int)` method (e.g. Smile’s `smile.plot.swing.Figure`) — duck-typed sibling for libraries that follow the `to…` rather than `create…` naming convention

- a `javax.swing.JComponent` (e.g. Smile’s `Canvas` and `MultiFigurePane`) — laid out and painted to a `BufferedImage` at the requested size

So once you’ve grabbed JFreeChart you can render charts in the REPL without saving to a file:

    groovy> /grab org.jfree:jfreechart:1.5.6
    groovy> import org.jfree.data.category.DefaultCategoryDataset
    groovy> ds = new DefaultCategoryDataset()
    groovy> ds.addValue(3d, 'Series', 'Mon'); ds.addValue(5d, 'Series', 'Tue')
    groovy> ds.addValue(7d, 'Series', 'Wed'); ds.addValue(4d, 'Series', 'Thu')
    groovy> import org.jfree.chart.ChartFactory
    groovy> chart = ChartFactory.createBarChart('demo', 'day', 'count', ds)
    groovy> /img $chart --width=600 --height=400

Smile is similar — `Figure.toBufferedImage(int, int)` matches the second duck-type, so a fresh `Figure` can be handed straight to `/img`. The following draws the classic Iris scatter plot:

    groovy> /grab com.github.haifengl:smile-io:3.1.0
    groovy> import smile.io.Read
    groovy> iris = Read.arff('iris.arff')
    groovy> import smile.plot.swing.ScatterPlot
    groovy> figure = ScatterPlot.of(iris, 'sepallength', 'sepalwidth', 'class', '*' as char).figure()
    groovy> figure.setAxisLabels('sepallength', 'sepalwidth')
    groovy> /img $figure --width=600 --height=400

Smile’s `Canvas` and `MultiFigurePane` are themselves `JComponent` subclasses, so the SPLOM (scatter-plot matrix) goes through the `JComponent` path with no extra wrapping:

    groovy> import smile.plot.swing.MultiFigurePane
    groovy> splom = MultiFigurePane.splom(iris, '*' as char, 'class')
    groovy> /img $splom --width=900 --height=900

Orson Charts gives 3D chart shapes (pie, bar, scatter, surface, …). `Chart3D` doesn’t expose `createBufferedImage` directly, but pairs with `Chart3DPanel` (a `JComponent`) which reaches `/img` through the same JComponent path as Smile’s SPLOM. Pairing that with Apache Commons CSV — handed a `population.csv` whose columns are `country` and `millions` — gives a 3D pie of the world’s ten most populous countries:

    groovy> /grab org.apache.commons:commons-csv:1.14.1
    groovy> import static org.apache.commons.csv.CSVFormat.RFC4180 as CSV
    groovy> parser = CSV.builder().setHeader().setSkipHeaderRecord(true).build()
    groovy> records = parser.parse(new FileReader('population.csv'))
    groovy> /grab org.jfree:org.jfree.chart3d:2.1.1
    groovy> import module org.jfree.chart3d
    groovy> data = new StandardPieDataset3D()
    groovy> records.each { data.add(it.country, it.millions as double) }
    groovy> chart = Chart3DFactory.createPieChart('Top 10 by population (millions)', null, data)
    groovy> panel = new Chart3DPanel(chart)
    groovy> /img $panel --width=700 --height=420

XChart’s `BitmapEncoder.getBufferedImage(chart)` yields a plain `BufferedImage`, which is the simplest path of all — assign it to a variable and hand it straight to `/img`. Combining that with the `/slurp` command (which prefers `groovy-csv’s `CsvSlurper` and falls back to Apache Commons CSV) gives a declarative CSV-to-chart pipeline. Reading a `co2-mlo.csv` whose columns are `Year` and `Mean` (annual mean Mauna Loa CO2 in ppm) draws the iconic Keeling-curve line:

    groovy> /grab org.knowm.xchart:xchart:3.8.8
    groovy> rows = /slurp co2-mlo.csv
    groovy> import org.knowm.xchart.XYChartBuilder
    groovy> chart = new XYChartBuilder().title('Mauna Loa annual mean CO2').xAxisTitle('Year').yAxisTitle('CO2 (ppm)').width(600).height(400).build()
    groovy> chart.addSeries('CO2', rows.collect { it.Year as int }, rows.collect { it.Mean as double })
    groovy> import org.knowm.xchart.BitmapEncoder
    groovy> img = BitmapEncoder.getBufferedImage(chart)
    groovy> /img $img

The `--width` and `--height` options have two distinct meanings depending on the input. For raw-pixel inputs (file path, `http(s)://` URL, `BufferedImage`, `RenderedImage`), they control the rendered size in terminal character cells. For inputs that generate the image at the requested size (`createBufferedImage(int,int)`, `toBufferedImage(int,int)`, `JComponent`), they are source-image pixels — the terminal then renders the image at its natural fit. Aspect ratio is preserved by default (override with `--no-preserve-aspect-ratio`).

If the active terminal doesn’t speak any of the supported graphics protocols (common cases: macOS Terminal.app, VS Code’s built-in terminal, JetBrains terminals, plain Windows console), `/img` prints a `[image: WxH, label]` summary line instead. Pass `--gui` to open a Swing window with the image regardless of terminal capability.

The command requires the `java.desktop` module at runtime; on a JVM where that module is unavailable, `/img` is not registered.

#### 1.5.21. `/inspect`

Display or browse object info on the terminal or object browser.

Using the `--gui/-g` option displays the object in Groovy’s object browser:

#### 1.5.22. `/less`

Display the contents of a file (usually a page at a time). Formatting of common file types is supported.

If no filename is given, the contents of the current buffer are displayed.

#### 1.5.23. `/load`

Load a file into the buffer.

If no filename is given as an argument, the current shared variables are loaded from the `.groovy/groovysh.ser` file in the user home directory.

#### 1.5.24. `/ls`

The `/ls` command lists files.

    groovy> /ls subprojects
                         groovy-dateutil      groovy-swing
    ..                   groovy-docgenerator  groovy-templates
    binary-compatibility groovy-ginq          groovy-test
    groovy-all           groovy-groovydoc     groovy-test-junit5
    groovy-ant           groovy-groovysh      groovy-testng
    groovy-astbuilder    groovy-jmx           groovy-toml
    groovy-binary        groovy-json          groovy-typecheckers
    groovy-bom           groovy-jsr223        groovy-xml
    groovy-cli-commons   groovy-macro         groovy-yaml
    groovy-cli-picocli   groovy-macro-library performance
    groovy-console       groovy-nio           stress
    groovy-contracts     groovy-servlet       tests-preview
    groovy-datetime      groovy-sql

Wildcard support is available, so you can use `/ls *.groovy` to list all Groovy files in the current directory. File patterns which involve asterisks as well as slashes can sometimes be confused with Groovy’s comment syntax, so quote the pattern if in doubt:

    groovy> /ls '**/bu*.gradle'
    bootstrap/build.gradle                        subprojects/groovy-datetime/build.gradle      subprojects/groovy-swing/build.gradle
    build-logic/build.gradle                      subprojects/groovy-dateutil/build.gradle      subprojects/groovy-templates/build.gradle
    build.gradle                                  subprojects/groovy-docgenerator/build.gradle  subprojects/groovy-test-junit5/build.gradle
    gradle/build-scans.gradle                     subprojects/groovy-ginq/build.gradle          subprojects/groovy-test/build.gradle
    subprojects/binary-compatibility/build.gradle subprojects/groovy-groovydoc/build.gradle     subprojects/groovy-testng/build.gradle
    subprojects/groovy-all/build.gradle           subprojects/groovy-groovysh/build.gradle      subprojects/groovy-toml/build.gradle
    subprojects/groovy-ant/build.gradle           subprojects/groovy-jmx/build.gradle           subprojects/groovy-typecheckers/build.gradle
    subprojects/groovy-astbuilder/build.gradle    subprojects/groovy-json/build.gradle          subprojects/groovy-xml/build.gradle
    subprojects/groovy-binary/build.gradle        subprojects/groovy-jsr223/build.gradle        subprojects/groovy-yaml/build.gradle
    subprojects/groovy-bom/build.gradle           subprojects/groovy-macro-library/build.gradle subprojects/performance/build.gradle
    subprojects/groovy-cli-commons/build.gradle   subprojects/groovy-macro/build.gradle         subprojects/stress/build.gradle
    subprojects/groovy-cli-picocli/build.gradle   subprojects/groovy-nio/build.gradle           subprojects/tests-preview/build.gradle
    subprojects/groovy-console/build.gradle       subprojects/groovy-servlet/build.gradle
    subprojects/groovy-contracts/build.gradle     subprojects/groovy-sql/build.gradle

#### 1.5.25. `/nano`

Edit files or the current buffer.

The `/nano` command has numerous options:

You can use the `/nano` command to edit files or the current buffer:

If editing the current buffer, when you exit and then save, the buffer will be reloaded with the edited contents.

#### 1.5.26. `/pipe`

The `/pipe` command lets you create and delete custom pipe operators.

There are several builtin pipe and pipe-like operators:

- The pipe and operator (|&&) executes the right hand side only if the execution of the left hand side succeeds

- The pipe or operator (|||) executes the right hand side only if the execution of the left hand side fails

- The pipe flip operator (|;) flips the left and right hand side expressions

- The output redirect operator (|>) redirects the output to a file

- The append output redirect operator (|>>) redirects the output by appending to a file

For the pipe and and or operators, succeeds means executing without throwing an exception and returning a non-null, non-empty, non-zero result, i.e. `true` according to Groovy truth.

Here are some examples for and and or:

Pipe operators are handled by the shell. The left and right hand sides will be either repl commands or code passed to the Groovy engine for execution.

The pipe flip operator is most commonly used with commands:

    groovy> /widget -l |; /prnt -s JSON
    [
        "_autosuggest-end-of-line (_autosuggest-end-of-line)",
        "_autosuggest-forward-char (_autosuggest-forward-char)",
        ...
    ]

    groovy> /ls --1 subprojects |; /head -n12 |; /tail -n5
    groovy-bom
    groovy-cli-commons
    groovy-cli-picocli
    groovy-console
    groovy-contracts

It is less common, but it can also be used with code:

    groovy> 4 |; 8 -
    4
    groovy> 4 |; 8 *
    32
    groovy> 4 |; 8 /
    2
    groovy> 4 |; 8 +
    12
    groovy> 4 |; 8 %
    0
    groovy> 4 |; 8 **
    4096

You can also define your own custom pipe operators, defined using `/pipe [OPERATOR] [PREFIX] [POSTFIX]`, as these examples show:

JLine functionality includes support for named pipes and pipe aliases.

Here is a named pipe for finding fruit with small names:

    groovy> /pipe smallFruit '.findAll{ it.size() <' '}'
    groovy> fruit | smallFruit 6
    [apple, date]

Here is a pipe alias:

    groovy> /alias sizes '|. it.size()'
    groovy> fruit | sizes
    [5, 6, 6, 4, 10]

The pipe alias always has the pipe it is aliasing at the start, `|.` in the above example.

| Care should be taken when using named pipes along with Groovy code that uses Groovy’s pipe operator (`|`), AKA binary OR operator, as this can lead to conflicts. Is the expression `x | y` the binary OR of two variables, or making use of a named pipe with name `y`? Spaces in Groovy are normally not significant, but the Groovy Shell is using JLine console functionality which requires spaces around the pipe operator before a named pipe and is bracket aware. So, `x| y`, `x |y`, `x|y`, and `(x | y)` will be passed to Groovy for execution. The Groovy Shell also passes `x | y` to Groovy if `y` is not a known named pipe.
    groovy> x = 4
    groovy> y = 8
    groovy> x | y
    12
    groovy> /pipe y '+1' ''
    groovy> x | y
    5
Getting back to how you can avoid conflicts, one convention you could use to avoid conflicts is to use brackets or avoid spaces when wanting the binary OR operator, and use spaces and no brackets when wanting to use a named pipe. Another alternative, is to define a custom pipe name instead of a named pipe:
    groovy> /pipe |smallFruit '.findAll{ it.size() <' '}'
    groovy> fruit |smallFruit 6
    [apple, date, fig, grape]
    groovy> /pipe
    smallFruit  [.findAll{ it.size() <, }]
    |smallFruit [.findAll{ it.size() <, }]
Here, the custom pipe named `|smallFruit`, is different to the named pipe `smallFruit`. The former mustn’t have a space, the latter must have one. If you use only the first of these, you can have a convention of using spaces when you want a binary OR.

As a final example, let’s use a custom pipe with the output redirection operators to find fruit with large names:

#### 1.5.27. `/prnt`

The `/prnt` command outputs its argument to the console. Both variable expansion and formatting are supported.

See also the `/echo` command, which is similar but takes multiple arguments. It also supports variable expansion but doesn’t support formatting.

#### 1.5.28. `/pwd`

The `/pwd` command prints the current working directory.

    groovy> /pwd
    /Users/paulk/Projects/groovy

#### 1.5.29. `/reset`

Clears the current buffer and shared variables.

#### 1.5.30. `/save`

Saves the buffer’s contents to a file.

If no filename is given as an argument, the current shared variables are saved into the `.groovy/groovysh.ser` file in the user home directory.

#### 1.5.31. `/setopt`

Set options.

    groovy> /setopt -?
    setopt -  set options
    Usage: setopt [-m] option ...
    setopt
    -? --help                      Displays command help
    -m                             Use pattern matching

If no option is given, the current set options are displayed.

    groovy> /setopt
    disable-event-expansion
    use-forward-slash
    insert-bracket
    no-empty-word-options
    groovy>

See also `/unsetopt` to unset options.

#### 1.5.32. `/setvar`

Set linereader variable values.

    groovy> /setvar
    history-file: /Users/paulk/.groovy/groovysh_history
    indentation: 2
    list-max: 100
    secondary-prompt-pattern: %M%P >
    groovy>

#### 1.5.33. `/show`

Show the shared variables (the binding). These include your shared variables as well as a few used for configuring various shell features.

#### 1.5.34. `/slurp`

Slurp files to shared variables. Groovy has a bunch of slurpers for various formats like XML, JSON, YAML, etc. You can use those in your code if you like, but the `/slurp` command can be a convenience shortcut. It supports most of the common formats, including JSON, XML, YAML, CSV, TOML, Markdown and property files.

As you can see in the usage information at the end of the above image, you can also provide an encoding and a format. If no encoding is given, `UTF_8` is the default. If no format is given, the shell will try to determine the format from the extension of the file (if given). If no format or file extension is given, the `/slurp` command makes a rudimentary attempt to determine the format by looking at the content, e.g. the json format is determined in the following example:

That content-based fallback parses; it never evaluates. It recognises JSON and otherwise hands back the text unchanged, so a document cannot decide for itself that it should be run. Evaluating content is a separate, explicit request: pass `-f GROOVY`, or name a local `.groovy` file.

For a URL, the extension of the URL path selects the format in the same way as a filename does, but only ever a data format — `GROOVY` is not inferred from an address, because the extension is part of the URL you typed while the bytes are whatever the server chooses to return.

| `-f GROOVY` against a URL runs whatever that server returns, with your privileges, in this session. It is not a safer way to evaluate remote content than the old content sniffing was — it is the authorised way, and the difference is only that you chose it rather than the payload choosing for you. Redirects are followed, so the address you typed is not necessarily where the code came from; `/slurp` prints the URL it was actually served from before evaluating it. Treat it as you would piping a download straight into a shell, and prefer fetching the content first (without `-f`) so you can read it before deciding to run it.

Although the details of the exact object returned are an implementation detail which may change in the future, the current behavior is as follows:

Format | Notes
--- | ---
JSON | Uses JsonSlurper, returns a lazy Map.
TOML | Uses TomlSlurper, returns a lazy Map.
YAML | Uses YamlSlurper, returns a lazy Map.
XML | Uses XmlParser, returns a Node.
PROPERTIES | Returns a Properties file, which is a Map-like object.
CSV | Uses Apache Commons CSV if on the classpath. Assumes a header row which is used to create a list (the rows) of maps from column name to value.
MARKDOWN | Uses MarkdownSlurper from `groovy-markdown` if on the classpath. Returns a `MarkdownDocument` (an `Iterable<Map<String, Object>>` of structured elements). Triggered by `.md` and `.markdown` extensions.
TEXT | Reads the file as raw lines (or argument as a line).
GROOVY | Evaluates the content as a Groovy script and returns its result. Selected by `-f GROOVY`, or by a local `.groovy` file extension. Never selected automatically from content, nor from a URL.
NONE | If you want the raw text rather than parsed content.

If these do change in the future, the replacement will be a compatible implementation, that follows the normal GPath conventions.

If you want more advanced control over the slurping, you can use Groovy’s "Slurper" classes directly, e.g. `new XmlSlurper().parseText(…​)`.

#### 1.5.35. `/sort`

The `/sort` command sorts files or standard input.

#### 1.5.36. `/tail`

The `/tail` command displays the end of a file.

    groovy> /tail -n2 fruit.txt
    date
    elderberry

#### 1.5.37. `/types`

Show the declared types (enums, interfaces, classes, traits, annotation definitions, and records).

Types can be deleted using `/types -d` (completion is available) but see also the `/del` command:

#### 1.5.38. `/ttop`

Display information about threads.

Various options are available:

    groovy> /ttop --help
    ttop -  display and update sorted information about threads
    Usage: ttop [OPTIONS]
      -? --help                   Show help
      -o --order=ORDER            Comma separated list of sorting keys
      -t --stats=STATS            Comma separated list of stats to display
      -s --seconds=SECONDS        Delay between updates in seconds
      -m --millis=MILLIS          Delay between updates in milliseconds
      -n --nthreads=NTHREADS      Only display up to NTHREADS threads

#### 1.5.39. `/unsetopt`

Unset options.

    groovy> /unsetopt -?
    unsetopt -  unset options
    Usage: unsetopt [-m] option ...
           unsetopt
      -? --help                      Displays command help
      -m                             Use pattern matching

If no option is given, the current unset options are displayed.

    groovy> /unsetopt
    complete-in-word
    complete-matcher-camelcase
    no-complete-matcher-typo
    history-verify
    no-history-ignore-space
    no-history-ignore-dups
    no-history-reduce-blanks
    no-history-beep
    no-history-incremental
    no-history-timestamped
    no-auto-group
    no-auto-menu
    no-auto-list
    auto-menu-list
    recognize-exact
    no-group
    group-persist
    case-insensitive
    list-ambiguous
    list-packed
    list-rows-first
    glob-complete
    menu-complete
    auto-fresh-line
    delay-line-wrap
    no-auto-param-slash
    no-auto-remove-slash
    insert-tab
    mouse
    disable-highlighter
    no-bracketed-paste
    erase-line-on-finish
    case-insensitive-search
    disable-undo
    groovy>

See also `/setopt` to set options.

#### 1.5.40. `/wc`

The `/wc` command displays word, line, character, and byte counts.

    groovy> /wc LICENSE
         262    1754   13493 LICENSE

#### 1.5.41. `/unalias`

Allows aliases to be removed.

Removed aliases will also be removed from persistent storage.

### 1.6. State

#### 1.6.1. History

History is stored in the file `$HOME/.groovy/groovysh_history`.

### 1.7. Widgets

JLine provides a powerful widget system that lets you extend the functionality of its line reader. A number of builtin widgets are available including `end-of-line`, `beginning-of-line`, `forward-word`, `backward-word`, `kill-word`, `backward-kill-word`, `capitalize-word`, `transpose-words`, and `yank-pop`, just to name a few. You can use the `/keymap` command to see the key bindings for these widgets.

Groovy also includes JLine’s tailtip and autosuggest widget functionality. You can see the related widgets by using the `/widget -l` command, which lists custom widgets.

    groovy> /widget -l
    _autosuggest-end-of-line (_autosuggest-end-of-line)
    _autosuggest-forward-char (_autosuggest-forward-char)
    _autosuggest-forward-word (_autosuggest-forward-word)
    _tailtip-accept-line (_tailtip-accept-line)
    _tailtip-backward-delete-char (_tailtip-backward-delete-char)
    _tailtip-delete-char (_tailtip-delete-char)
    _tailtip-expand-or-complete (_tailtip-expand-or-complete)
    _tailtip-kill-line (_tailtip-kill-line)
    _tailtip-kill-whole-line (_tailtip-kill-whole-line)
    _tailtip-redisplay (_tailtip-redisplay)
    _tailtip-self-insert (_tailtip-self-insert)
    autosuggest-toggle (autosuggest-toggle)
    tailtip-toggle (tailtip-toggle)
    tailtip-window (tailtip-window)

These are available but not enabled by default. You can enable them using the related toggle widgets. You can see what key bindings are associated with these widgets by using the `/keymap` command.

    groovy> /keymap
    ...
    "^[s" tailtip-toggle
    "^[v" autosuggest-toggle
    ...

Normally, completions are shown when you hit the 'TAB' key, but with the tailtip widget enabled, you can see completions as you type., as well as additional usage information given in the tailtip window as seen here for a command:

And here for some code:

With the autosuggest widget enabled, you can see suggestions for what to type next as you type, based on your history, as seen here:

You can accept the entire suggestion or a word at a time. Both widgets can be enabled.

### 1.8. Advanced Topics

#### 1.8.1. REPL Model Details

The style of coding you use in a REPL is slightly different from what you might use in a script. The style you use may also depend on whether you are using the Groovy Shell in interpreter mode or not.

##### Using binding (shared) variables

Regardless of interpreter mode you can use shared variables:

    groovy> fruit = []
    groovy> fruit << 'peach'
    [peach]
    groovy> fruit << 'pear'
    [peach, pear]
    groovy> assert fruit == ['peach', 'pear']

Use the `/show` command to see the shared variables.

##### Using local variables

You should treat local variables as if you were using immutable data structures. An input which mutates a local variable will likely be undone by subsequent statements.

Only in interpreter mode:

    groovy> def noFruit = []
    []
    groovy> def oneFruit = noFruit << 'peach'
    [peach]
    groovy> def twoFruit = oneFruit << 'pear'
    [peach, pear]
    groovy> assert twoFruit == ['peach', 'pear']

By the time you get to the last statement, the previous three local variable definitions are remembered, so the assertion will pass.

Avoid this (relevant to interpreter mode):

    groovy> def fruit = []
    []
    groovy> fruit << 'peach'
    [peach]
    groovy> fruit << 'pear'
    [pear]
    groovy> assert fruit == []

The `def fruit = []` will be remembered before executing each of the next three statements.

#### 1.8.2. Gotchas

The Groovy Shell attempts to blend a Groovy programming environment with a shell-like scripting environment. Sometimes the two are at odds. As one example, don’t try `/ls /tmp/.txt`. The `/` will be interpreted as the start of a comment. Instead, quote the argument like this `/ls '/tmp/*.txt'`.

#### 1.8.3. Platform Problems

The Groovy Shell relies heavily on the JLine3 library for its platform support. If you have specific platform problems, please refer to the JLine documentation.