-
Notifications
You must be signed in to change notification settings - Fork 218
REPL Console
Builtin support for console variables, scripts, custom pipes, widgets and object printing.
- ScriptEngine manages JVM scripting language variables and script execution.
-
ConsoleEngine extends CommandRegistry interface. Manages console variables, console script execution and object printing. ConsoleEngineImpl have implementation of console commands:
show
,del
,prnt
,pipe
,alias
,unalias
andslurp
. -
SystemRegistry extends CommandRegistry interface. Aggregates
CommandRegisteries
, compile command pipe lines and dispatch command executions to the command registeries. SystemRegistryImpl implements commands:help
andexit
.
-
PATH
a list of directories from where scripts are searched -
NANORC
nanorc configuration file -
PRNT_OPTIONS
prnt
command default options -
CONSOLE_OPTIONS
console options -
_
the last result of the command execution -
exception
the last exception -
output
redirected print output if command also returns value -
_args
command parameter list for the groovy script. This is to be used inside a script. -
_buffer
closure that will calllineReader.getBuffer()
, available for widget functions. -
_reader
lineReader
, available for widget functions -
_widget
closure that will calllineReader.callWidget()
, available for widget functions -
_widgetFunction
function that will be launched when executing widget -
_pipe<N>
temporary variables used to execute command pipe line -
_executionResult
command execution result -
_return
used to return execution result from console script
- Variables whose name start with underscore character
_
are temporary variables that are deleted in REPL-loop. - Variables whose name is in CAMEL_CASE format are not deleted when using wild card in delete command like
del *
Variable expansion substitutes variable reference with its value. Examples:
groovy-repl> # create a map and print it
groovy-repl> user=[name:'Pippo',age:10]
groovy-repl> prnt $user
name Pippo
age 10
groovy-repl> prnt ${user}.name
Pippo
Note that command object parameters can also be written directly using either Groovy object notation or JSON:
groovy-repl> prnt -s JSON [user:'pippo',age:10]
{
"user": "pippo",
"age": 10
}
groovy-repl> prnt -s JSON {user:pippo,age:10}
{
"user": "pippo",
"age": 10
}
Implementation brings in life two type of scripts: console and groovy scripts.
Script parameters are accessed inside a script as usual using the variables $1
, $2
, $3
, and so on.
In console script application commands are entered just like you do interactively. Note that inside a code block command line must be either of the forms :command arg1 arg2
or var=:command arg1 arg2
. Use exit
command to exit and return value from script. Console scripts have two built-in options: -?
for script help and -v
for verbose execution. Console script output cannot be redirected.
A temporary list variable _args
will be created to assign command parameters to the script.
Application commands can be executed inside a script using a statements like
SystemRegistry.get().invoke('prnt', '-s', 'JSON', map)
. Groovy scripts have built-in help option -?
.
The main purpose of the pipes is to make things more concise and create a more familiar REPL console for those who have used to work in bash/zsh. Pipe operator implementation has been inspired by Ammonite.
Output redirection
Command output/return value can be redirected to variable by entering command like:
groovy-repl> resp=widget -l
groovy-repl> resp
_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-redisplay (_tailtip-redisplay)
_tailtip-self-insert (_tailtip-self-insert)
_tailtip-toggle (_tailTipToggle)
tailtip-toggle (tailtip-toggle)
tailtip-window (tailtip-window)
test-widget (_testWidget)
Note that no spaces are allowed between variable/command and equal sign.
Command output can be redirected to file using standard redirection operators >
and >>
.
Logical pipe operators
The and operator (&&
) would execute the second command only, if the execution of first command succeeds.
The or Operator (||
) allows you to execute the second command only if the execution of first command fails.
Note that all the pipe operators must be enclosed by space characters and the command line cannot be enclosed by parenthesis or quotes.
groovy-repl> # this is evaluated by the console engine
groovy-repl> true && false || true
true
false
true
groovy-repl> # the command lines below are evaluated entirely by Groovy engine
groovy-repl> (true && false || true)
true
groovy-repl> true&&false||true
true
Flip pipe operator
The flip pipe operator |;
flips around the command and argument:
groovy-repl> widget -l |; prnt -s JSON
[
"_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-redisplay (_tailtip-redisplay)",
"_tailtip-self-insert (_tailtip-self-insert)",
"_tailtip-toggle (_tailTipToggle)",
"hello-world (helloWorld)",
"tailtip-toggle (tailtip-toggle)",
"tailtip-window (tailtip-window)",
"test-widget (_testWidget)"
]
Named pipe operator
Actually only reserved pipe operator |
that will be used by custom named pipes and pipe line aliases.
Pipe operator name convention: If pipe operator name contains only alphanumeric characters it is named pipe operator and it will be used with operator |
.
#
# custom Groovy pipes
#
pipe |. '.collect{' '}'
pipe |: '.collectEntries{' '}'
pipe |:: '.collectMany{' '}'
pipe |? '.findAll{' '}'
pipe |?1 '.find{' '}'
pipe |& '.' ' '
#
# named pipe and two pipe line aliases
#
pipe grep '.collect{it.toString()}.findAll{it=~/' '/}'
alias null '|& identity{}'
alias xargs '|; %{0} %{1} %{2} %{3} %{4} %{5} %{6} %{7} %{8} %{9}'
Note that pipe line alias value starts with known pipe operator.
In widget function you will have available temporary variables: _reader
(lineReader
), _buffer
(closure that will call lineReader.getBuffer()
) and _widget
(closure that will call lineReader.callWidget()
).
#
# create test-widget and bind it to ctrl-alt-x
# It will read widget name from buffer and execute it
#
def testWidget() {
def name = _buffer().toString().split('\\s+')[0]
_widget "$name"
}
widget -N test-widget testWidget
keymap '^[^x' test-widget
See the same example using Java.
REPL demo implemention and sample scripts. To run the demo, simply use the following command after having build JLine
./build repl