//////////////////////////////////////////

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.

//////////////////////////////////////////

= Groovysh, the Groovy shell

== Groovy : Groovy Shell

NOTE: The groovysh is undergoing a major re-vamp and some of this information may not yet have been updated to reflect the latest changes.

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

[[GroovyShell-Features]]
=== Features

* Rich cross-platform line editing, history and completion thanks
to https://github.com/jline/jline3[JLine3].
* ANSI colors (prompt, exception traces, etc).
* Simple, yet robust, command system with online help, user alias
support and more.
* User profile support

[[GroovyShell-Command-lineOptionsandArguments]]
=== Command-line Options and Arguments

The shell supports several options to control verbosity, ANSI coloring
and other features.

[source,shell]
-----------------------------------------------------------------
./bin/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, --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
                            (jdk8+ only)
  -pr, --enable-preview   Enable preview Java features (jdk12+ only)
  -q, --quiet             Suppress superfluous output
  -T, --terminal=<TYPE>   Specify the terminal TYPE to use
  -v, --verbose           Enable verbose output
  -V, --version           Display the version
-----------------------------------------------------------------

[[GroovyShell-EvaluatingExpressions]]
=== Evaluating Expressions

[[GroovyShell-SimpleExpressions]]
==== Simple Expressions

[source,jshell]
---------------
groovy> println "Hello"
Hello
---------------

[[GroovyShell-EvaluationResult]]
==== Evaluation Result

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

[[GroovyShell-Multi-lineExpressions]]
==== 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.

[[GroovyShell-DefineaClass]]
===== Define a Class

[source,jshell]
---------------------
groovy> class Foo {
add: } >   def bar() {
add: }}>     println "baz"
add: }}>   }
add: } > }
---------------------

[[GroovyShell-UsetheClass]]
===== Use the Class

[source,jshell]
---------------
groovy> foo = new Foo()
groovy> foo.bar()
baz
---------------

[[GroovyShell-Variables]]
==== Variables

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

This *will* set a shell variable:

[source,groovy]
-----------
foo = "bar"
-----------

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

[source,groovy]
---------------
def foo = "bar"
---------------

This behavior can be changed by activating <<GroovyShell-InterpreterMode,interpreter mode>>.

[[GroovyShell-Functions]]
==== Functions

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

Defining a function is easy:

[source,jshell]
----------------------------------
groovy> def hello(name) {
add: }>   println("Hello $name")
add: }> }
----------------------------------

And then using it is as one might expect:

[source,jshell]
--------------
groovy> hello "Jason"
Hello Jason
--------------

Internally the shell creates a closure to encapsulate the function and
then binds the closure to a variable. So variables and functions share
the same namespace.

[[GroovyShell-Commands]]
=== Commands

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

Commands all have a _name_ and a _shortcut_ (which is something like
`\h`). Commands may also have some predefined system _aliases_. Users
may also create their own aliases.

[[GroovyShell-RecognizedCommands]]
==== Recognized Commands

[[GroovyShell-help]]
===== `/help`

Display the list of commands (and aliases) or the help text for specific command.

[[GroovyShell-TheCommandList]]
The Command List

----------------------------------------------------------------------------------
groovy> /help
    /!           execute shell command
    /alias       create command alias
    /classloader display/manage Groovy classLoader data
    /clear       clear terminal
    /colors      view 256-color table and ANSI-styles
    /console     launch Groovy console
    /del         delete console variables, methods, classes and imports
    /doc         open document on browser
    /echo        echos a value
    /grab        add maven repository dependencies to classpath
    /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 a file into the buffer
    /methods     show/delete methods
    /nano        edit files
    /pipe        create/delete pipe operator
    /prnt        print object
    /reset       clear the buffer
    /save        save the buffer to a file
    /setopt      set options
    /setvar      set lineReader variable value
    /show        list console variables
    /ttop        display and update sorted information about threads
    /types       show/delete types
    /unalias     remove command alias
    /unsetopt    unset options
    /vars        show/delete variable declarations
    /widget      manipulate widgets
    /exit         exit from app/script
    /help         command help
    /slurp        slurp file or string variable context to object
----------------------------------------------------------------------------------

[[GroovyShell-HelpforaCommand]]
Help for a Command

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
------------------------------------------------------------

[[GroovyShell-exit]]
===== `/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.)

[[GroovyShell-echo]]

[[GroovyShell-import]]
===== `import`

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

[source,jshell]
--------------
groovy> import java.util.concurrent.BlockingDeque
--------------

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.

[source,jshell]
--------------
groovy> import java.util.concurrent.<TAB>
others
atomic                        locks
Classes
AbstractExecutorService       ConcurrentSkipListMap         ForkJoinPool
ArrayBlockingQueue            ConcurrentSkipListSet         ForkJoinTask
...
--------------

[[GroovyShell-imports]]
===== `/imports`

You can use this to list and delete existing imports.

[source,jshell]
--------------
groovy> /imports
import java.util.concurrent.BlockingQueue
--------------

[[GroovyShell-grab]]
===== `/grab`

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

[source,jshell]
----
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 repository (~/.m2). Expect this to change in the future.

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

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

[[GroovyShell-display]]
===== `/less`

Display the contents of all existing import, type, method and variable snippets.

[[GroovyShell-Example]]
Example

-----------------------
groovy:000> class Foo {
groovy:001> def bar
groovy:002> def baz() {
groovy:003> :display
 001> class Foo {
 002> def bar
 003> def baz() {
-----------------------

[[GroovyShell-clear]]
===== `clear`

Clears the current buffer, resetting the prompt counter to 000. Can be used to recover from compilation errors.

[[GroovyShell-show]]
===== `show`

Show variables, classes or preferences or imports.

[[GroovyShell-showvariables]]
`show variables`

--------------------------
groovy:000> :show variables
Variables:
  _ = true
--------------------------

[[GroovyShell-showclasses]]
`show classes`

[[GroovyShell-showimports]]
`show imports`

[[GroovyShell-showpreferences]]
`show preferences`

[[GroovyShell-showall]]
`show all`

[[GroovyShell-inspect]]
===== `inspect`

Opens the GUI object browser to inspect a variable or the result of the
last evaluation.

[[GroovyShell-purge]]
===== `purge`

Purges objects from the shell.

[[GroovyShell-purgevariables]]
`purge variables`

[[GroovyShell-purgeclasses]]
`purge classes`

[[GroovyShell-purgeimports]]
`purge imports`

[[GroovyShell-purgepreferences]]
`purge preferences`

[[GroovyShell-purgeall]]
`purge all`

[[GroovyShell-edit]]
===== `edit`

Edit the current buffer in an external editor.

Currently only works on UNIX systems which have the `EDITOR` environment
variable set, or have configured the `editor` preference.

[[GroovyShell-load]]
===== `load`

Load one or more files (or urls) into the buffer.

[[GroovyShell-save]]
===== `save`

Saves the buffer’s contents to a file.

[[GroovyShell-record]]
===== `record`

Record the current session to a file.

[[GroovyShell-recordstart]]
`record start`

[[GroovyShell-recordstop]]
`record stop`

[[GroovyShell-recordstatus]]
`record status`

[[GroovyShell-history]]
===== `history`

Display, manage and recall edit-line history.

[[GroovyShell-historyshow]]
`history show`

[[GroovyShell-historyrecall]]
`history recall`

[[GroovyShell-historyflush]]
`history flush`

[[GroovyShell-historyclear]]
`history clear`

[[GroovyShell-alias]]
===== `alias`

Create an alias.

[[GroovyShell-doc]]
===== `doc`

Opens a browser with documentation for the provided class.

For example, we can get both the Javadoc and GDK enhancements doc for `java.util.List` (shown running on JDK17):

[subs=attributes]
----
groovy:000> :doc java.util.List
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html
https://docs.groovy-lang.org/{groovy-full-version}/html/groovy-jdk/java/util/List.html
----

This will print the documentation URLs found and open two windows (or tabs, depending on your browser):

* one for the JDK documentation
* one for the GDK documentation

By default, for Java classes, the `java.base` module is assumed. You can specify an optional module
for other cases (shown running on JDK17):

----
groovy:000> :doc java.scripting javax.script.ScriptContext
https://docs.oracle.com/en/java/javase/17/docs/api/java.scripting/javax/script/ScriptContext.html
----

For backwards compatibility, if no module is specified when searching for Java classes, and no class is found in the `java.base` module, an additional attempt is made to find documentation for the class in the JDK8 (pre-module) Javadoc:

----
groovy:000> :doc javax.script.ScriptContext
https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptContext.html
----

To get the Groovydoc for `groovy.ant.AntBuilder` and `groovy.xml.XmlSlurper`:

[subs=attributes]
----
groovy:000> :doc groovy.ant.AntBuilder
https://docs.groovy-lang.org/{groovy-full-version}/html/gapi/groovy/ant/AntBuilder.html
groovy:000> :doc groovy.xml.XmlSlurper
https://docs.groovy-lang.org/{groovy-full-version}/html/gapi/groovy/xml/XmlSlurper.html
----

To get both the Groovydoc and GDK enhancements doc for `groovy.lang.Closure` and `groovy.sql.GroovyResultSet`:

[subs=attributes]
----
groovy:000> :doc groovy.lang.Closure
https://docs.groovy-lang.org/{groovy-full-version}/html/gapi/groovy/lang/Closure.html
https://docs.groovy-lang.org/{groovy-full-version}/html/groovy-jdk/groovy/lang/Closure.html
groovy:000> :doc groovy.sql.GroovyResultSet
https://docs.groovy-lang.org/{groovy-full-version}/html/gapi/groovy/sql/GroovyResultSet.html
https://docs.groovy-lang.org/{groovy-full-version}/html/groovy-jdk/groovy/sql/GroovyResultSet.html
----

Documentation is also available for the GDK enhancements to primitive arrays and arrays of arrays:

[subs=attributes]
----
groovy:000> :doc int[]
https://docs.groovy-lang.org/{groovy-full-version}/html/groovy-jdk/primitives-and-primitive-arrays/int%5B%5D.html
groovy:000> :doc double[][]
https://docs.groovy-lang.org/{groovy-full-version}/html/groovy-jdk/primitives-and-primitive-arrays/double%5B%5D%5B%5D.html
----

NOTE: In contexts where opening a browser may not be desirable, e.g. on a CI server,
this command can be disabled by setting the `groovysh.disableDocCommand` system property to `true`.

[[GroovyShell-set]]
===== `set`

Set or list preferences.

[[GroovyShell-Preferences]]
=== Preferences

Some aspects of `groovysh` behaviors can be customized by setting
preferences. Preferences are set using the `set` command or the `:=`
shortcut.

[[GroovyShell-RecognizedPreferences]]
==== Recognized Preferences

[[GroovyShell-InterpreterMode]]
===== `interpreterMode`

Allows the use of typed variables (i.e. `def` or other type information):

----
groovy:000> def x = 3
===> 3
groovy:000> x
===> 3
----

It's especially useful for copy&pasting code from tutorials etc. into the running session.

[[GroovyShell-verbosity]]
===== `verbosity`

Set the shell’s verbosity level. Expected to be one of:

* `DEBUG`
* `VERBOSE`
* `INFO`
* `QUIET`

Default is `INFO`.

If this preference is set to an invalid value, then the previous setting
will be used, or if there is none, then the preference is removed and
the default is used.

===== `colors`

Set the shell’s use of colors.

Default is `true`.

[[GroovyShell-show-last-result]]
===== `show-last-result`

Show the last result after an execution.

Default is `true`.

[[GroovyShell-sanitize-stack-trace]]
===== `sanitize-stack-trace`

Sanitize (trim-down/filter) stack traces.

Default is `true`.

[[GroovyShell-editor]]
===== `editor`

Configures the editor used by the `edit` command.

Default is the value of the system environment variable `EDITOR`.

To use TextEdit, the default text editor on macOS, configure:
set editor /Applications/TextEdit.app/Contents/MacOS/TextEdit

[[GroovyShell-SettingaPreference]]
==== Setting a Preference

-------------------
groovy:000> :set verbosity DEBUG
-------------------

[[GroovyShell-ListingPreferences]]
==== Listing Preferences

To list the current _set_ preferences (and their values):

----------------
groovy:000> :show preferences
----------------

Limitation: At the moment, there is no way to list all the
known/available preferences to be set.

[[GroovyShell-ClearingPreferencesieResettingtoDefaults]]
==== Clearing Preferences (i.e. Resetting to Defaults)

-----------------
groovy:000> :purge preferences
-----------------

[[GroovyShell-UserProfileScriptsandState]]
=== User Profile Scripts and State

[[GroovyShell-ProfileScripts]]
==== Profile Scripts

[[GroovyShell-HOMEgroovygroovyshprofile]]
===== `$HOME/.groovy/groovysh.profile`

This script, if it exists, is loaded when the shell starts up.

[[GroovyShell-HOMEgroovygroovyshrc]]
===== `$HOME/.groovy/groovysh.rc`

This script, if it exists, is loaded when the shell enters interactive
mode.

[[GroovyShell-State]]
==== State

[[GroovyShell-HOMEgroovygroovyshhistory]]
===== `$HOME/.groovy/groovysh.history`

Edit-line history is stored in this file.

[[GroovyShell-register]]
=== Custom commands

The `register` command allows you to register custom commands in the shell. For example, writing the following
will register the `Stats` command:

----
groovy:000> :register Stats
----

where the `Stats` class is a class extending the `org.apache.groovy.groovysh.CommandSupport` class. For example:

[source,groovy]
----

class Stats extends CommandSupport {
    protected Stats(final Groovysh shell) {
        super(shell, 'stats', 'T')
    }

    public Object execute(List args) {
        println "Free memory: ${Runtime.runtime.freeMemory()}"
    }

}
----

Then the command can be called using:

----
groovy:000> :stats
stats
Free memory: 139474880
groovy:000>
----

Note that the command class must be found on classpath: you cannot define a new command from within the shell.

[[GroovyShell-Troubleshooting]]
=== Troubleshooting

Please https://issues.apache.org/jira/browse/GROOVY[report] any problems you
run into. Please be sure to mark the JIRA issue with the `Groovysh`
component.

[[GroovyShell-PlatformProblems]]
==== Platform Problems

[[GroovyShell-ProblemsloadingtheJLineDLL]]
===== Problems loading the JLine DLL

On Windows, https://github.com/jline/jline2[JLine2] (which is used for the fancy
shell input/history/completion fluff), uses a *tiny* DLL file to trick
the *evil* Windows faux-shell (`CMD.EXE` or `COMMAND.COM`) into
providing Java with unbuffered input. In some rare cases, this might
fail to load or initialize.

One solution is to disable the frills and use the unsupported terminal
instance. You can do that on the command-line using the `--terminal`
flag and set it to one of:

* `none`
* `false`
* `off`
* `jline.UnsupportedTerminal`

------------------------
groovysh --terminal=none
------------------------

[[GroovyShell-ProblemswithCygwinonWindows]]
===== Problems with Cygwin on Windows

Some people have issues when running groovysh with cygwin. If you have
troubles, the following may help:

------------------------
stty -icanon min 1 -echo
groovysh --terminal=unix
stty icanon echo
------------------------

[[GroovyShell-GMavenPlus]]
== GMavenPlus Maven Plugin
https://github.com/groovy/GMavenPlus[GMavenPlus] is a Maven plugin with goals
that support launching a Groovy Shell or Groovy Console bound to a Maven
project.

[[GroovyShell-GradleGroovyshPlugin]]
== Gradle Groovysh Plugin
https://github.com/tkruse/gradle-groovysh-plugin[Gradle Groovysh Plugin] is a Gradle plugin that provides gradle tasks to start a Groovy Shell bound to a Gradle project.
