CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-codehaus-groovy--groovy-groovysh

Interactive command-line shell (REPL) for evaluating Groovy expressions with advanced editing, completion, and command features

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities

The Groovy Shell utilities package provides helper classes for package navigation, script analysis, lexical processing, and various shell support functions. These utilities support the core shell functionality and provide extension points for advanced features.

Capabilities

Package Navigation Support

Helper classes for exploring and navigating Java/Groovy package structures.

/**
 * Interface for exploring package contents
 */
interface PackageHelper {
    /**
     * Get contents of a package
     * @param packagename - Package name to explore (e.g., "java.util")
     * @return Set of class names and sub-packages in the package
     */
    Set<String> getContents(String packagename)
}

/**
 * Implementation of PackageHelper using ClassLoader inspection
 */
class PackageHelperImpl implements PackageHelper {
    /**
     * Get package contents using ClassLoader
     * @param packagename - Package name to explore
     * @return Set of available classes and sub-packages
     */
    Set<String> getContents(String packagename)
    
    /**
     * Create package helper
     * @param classLoader - ClassLoader to use for package exploration
     */
    PackageHelperImpl(ClassLoader classLoader)
}

Usage Examples:

import org.apache.groovy.groovysh.util.PackageHelperImpl

// Create package helper
def packageHelper = new PackageHelperImpl(shell.classLoader)

// Explore java.util package
def contents = packageHelper.getContents('java.util')
println "java.util contains: ${contents}"
// Output: [ArrayList, HashMap, List, Map, concurrent, ...]

// Explore sub-packages
def concurrentContents = packageHelper.getContents('java.util.concurrent')
println "java.util.concurrent contains: ${concurrentContents}"
// Output: [Future, ExecutorService, ThreadPoolExecutor, ...]

// Use with shell completion
shell.packageHelper = packageHelper

Script Variable Analysis

Utilities for analyzing Groovy scripts to extract variable information.

/**
 * Analyzes Groovy scripts to extract bound variables
 */
class ScriptVariableAnalyzer {
    /**
     * Analyze script text to find bound variables
     * @param scriptText - Groovy script source code
     * @param classLoader - ClassLoader for compilation context
     * @return Set of variable names bound by the script
     */
    static Set<String> getBoundVars(String scriptText, ClassLoader classLoader)
}

Usage Examples:

import org.apache.groovy.groovysh.util.ScriptVariableAnalyzer

// Analyze script for variables
def scriptText = '''
def x = 10
def y = "hello"
class MyClass {
    def method() { return 42 }
}
z = new Date()
'''

def boundVars = ScriptVariableAnalyzer.getBoundVars(scriptText, shell.classLoader)
println "Bound variables: ${boundVars}"
// Output: [x, y, MyClass, z]

// Use for shell variable tracking
def currentScript = shell.buffers.current().join('\n')
def variables = ScriptVariableAnalyzer.getBoundVars(currentScript, shell.classLoader)

Command Argument Processing

Utilities for parsing and processing shell command arguments.

/**
 * Utility for parsing command line arguments
 */
class CommandArgumentParser {
    /**
     * Parse command line into arguments respecting quotes and escapes
     * @param line - Command line string to parse
     * @return List of parsed arguments
     */
    static List<String> parseLine(String line)
    
    /**
     * Parse command line with maximum token limit
     * @param line - Command line string to parse
     * @param maxTokens - Maximum number of tokens to parse
     * @return List of parsed arguments (last token may contain remaining text)
     */
    static List<String> parseLine(String line, int maxTokens)
}

Usage Examples:

import org.apache.groovy.groovysh.util.CommandArgumentParser

// Parse simple arguments
def args = CommandArgumentParser.parseLine(':load file1.groovy file2.groovy')
println "Args: ${args}"
// Output: [':load', 'file1.groovy', 'file2.groovy']

// Parse arguments with quotes
args = CommandArgumentParser.parseLine(':save "my file.groovy" --format=pretty')
println "Args: ${args}"
// Output: [':save', 'my file.groovy', '--format=pretty']

// Parse with token limit
args = CommandArgumentParser.parseLine(':help this is a long description', 2)
println "Args: ${args}"  
// Output: [':help', 'this is a long description']

// Use in custom commands
class MyCommand extends CommandSupport {
    Object execute(List<String> args) {
        // args are already parsed by CommandArgumentParser
        if (args.size() < 2) {
            fail("Usage: :mycmd <file> [options...]")
        }
        def filename = args[0]
        def options = args[1..-1]
        // Process command...
    }
}

Lexical Analysis Support

Utilities for lexical analysis of Groovy source code.

/**
 * Lexer that counts curly braces for parsing incomplete expressions
 */
class CurlyCountingGroovyLexer {
    /**
     * Create lexer for source code
     * @param src - Source code to analyze
     * @return Lexer instance
     */
    static CurlyCountingGroovyLexer createGroovyLexer(String src)
    
    /**
     * Get current parenthesis/brace nesting level
     * @return Nesting level (positive = unclosed braces)
     */
    int getParenLevel()
}

Usage Examples:

import org.apache.groovy.groovysh.util.CurlyCountingGroovyLexer

// Analyze code for brace matching
def code = '''
if (true) {
    def x = [1, 2, 3].collect {
        it * 2
    }
'''

def lexer = CurlyCountingGroovyLexer.createGroovyLexer(code)
def parenLevel = lexer.getParenLevel()
println "Unclosed braces: ${parenLevel}"
// Output: Unclosed braces: 1 (missing closing brace for if statement)

// Use for completion detection
def isComplete = (parenLevel == 0)
if (!isComplete) {
    println "Expression is incomplete, expecting ${parenLevel} closing brace(s)"
}

Command Registration Utilities

Utilities for registering default and custom commands with the shell.

/**
 * Registers default shell commands
 */
class DefaultCommandsRegistrar {
    /**
     * Register all default commands with the shell
     */
    void register()
    
    /**
     * Create registrar for shell
     * @param shell - Shell instance to register commands with
     */
    DefaultCommandsRegistrar(Groovysh shell)
}

/**
 * Registers commands from XML configuration files
 */
class XmlCommandRegistrar {
    /**
     * Register commands defined in XML resource
     * @param xmlResource - URL to XML configuration file
     */
    void register(URL xmlResource)
    
    /**
     * Create XML command registrar
     * @param shell - Shell instance
     * @param classLoader - ClassLoader for loading command classes
     */
    XmlCommandRegistrar(Groovysh shell, ClassLoader classLoader)
}

Usage Examples:

import org.apache.groovy.groovysh.util.DefaultCommandsRegistrar
import org.apache.groovy.groovysh.util.XmlCommandRegistrar

// Register default commands (typically done automatically)
def registrar = new DefaultCommandsRegistrar(shell)
registrar.register()

// Register custom commands from XML
def xmlRegistrar = new XmlCommandRegistrar(shell, shell.classLoader)
def xmlUrl = new URL('file:///path/to/custom-commands.xml')
xmlRegistrar.register(xmlUrl)

// XML format example:
// <?xml version="1.0"?>
// <commands>
//   <command class="com.example.CustomCommand"/>
//   <command class="com.example.AnotherCommand"/>
// </commands>

Input/Output Enhancement

Enhanced input stream wrapper with character insertion capabilities.

/**
 * Enhanced input stream wrapper with character insertion support
 */
class WrappedInputStream extends FilterInputStream {
    /**
     * Insert characters into the input stream at current position
     * @param chars - Characters to insert
     */
    void insert(String chars)
    
    /** Standard InputStream methods are available */
    int read()
    int read(byte[] b)
    int read(byte[] b, int off, int len)
    long skip(long n)
    int available()
    void close()
    void mark(int readlimit)
    void reset()
    boolean markSupported()
    
    /**
     * Create wrapped input stream
     * @param input - Input stream to wrap
     */
    WrappedInputStream(InputStream input)
}

Usage Examples:

import org.apache.groovy.groovysh.util.WrappedInputStream

// Wrap System.in for enhanced input
def wrappedInput = new WrappedInputStream(System.in)

// Insert text programmatically (useful for macros, etc.)
wrappedInput.insert('println "Hello World"\n')

// Use with console reader
def reader = new ConsoleReader(wrappedInput, System.out)

Security Management

Security manager for preventing System.exit() during shell operation.

/**
 * Security manager that prevents System.exit() calls during shell operation
 */
class NoExitSecurityManager extends SecurityManager {
    /**
     * Override exit check to prevent shell termination
     * @param status - Exit status (ignored)
     * @throws SecurityException always thrown to prevent exit
     */
    void checkExit(int status)
    
    /**
     * Allow other security operations  
     * @param perm - Permission to check
     */
    void checkPermission(Permission perm)
}

Usage Examples:

import org.apache.groovy.groovysh.util.NoExitSecurityManager

// Install security manager to prevent exit
def originalSecurityManager = System.getSecurityManager()
System.setSecurityManager(new NoExitSecurityManager())

try {
    // Run shell or execute user code
    shell.run()
} finally {
    // Restore original security manager
    System.setSecurityManager(originalSecurityManager)
}

// Prevent scripts from calling System.exit()
shell.execute('System.exit(0)')  // Will throw SecurityException instead of exiting

Simple Completion Utility

Basic completer implementation for fixed candidate lists.

/**
 * Simple completer for fixed list of candidates
 */
class SimpleCompleter implements Completer {
    /**
     * Perform completion against fixed candidate list
     * @param buffer - Input buffer
     * @param cursor - Cursor position
     * @param candidates - List to populate with matches
     * @return Start position for completion
     */
    int complete(String buffer, int cursor, List<CharSequence> candidates)
    
    /**
     * Create completer with fixed candidates
     * @param candidates - Array of completion candidates
     */
    SimpleCompleter(String... candidates)
}

Usage Examples:

import org.apache.groovy.groovysh.util.SimpleCompleter

// Create completer for SQL keywords
def sqlCompleter = new SimpleCompleter(
    'SELECT', 'INSERT', 'UPDATE', 'DELETE',
    'CREATE', 'DROP', 'ALTER', 'FROM', 'WHERE',
    'JOIN', 'INNER', 'LEFT', 'RIGHT', 'OUTER'
)

// Use with command
class SqlCommand extends CommandSupport {
    SqlCommand(shell) {
        super(shell, ':sql', ':s')
    }
    
    List<Completer> createCompleters() {
        return [sqlCompleter]
    }
    
    Object execute(List<String> args) {
        // Execute SQL...
    }
}

// Create completer for file extensions
def extensionCompleter = new SimpleCompleter(
    '.groovy', '.java', '.gradle', '.xml', '.properties'
)

Utility Integration Examples

Complete Shell Setup with Utilities:

import org.apache.groovy.groovysh.*
import org.apache.groovy.groovysh.util.*

// Create shell with utilities
def shell = new Groovysh()

// Set up package helper
shell.packageHelper = new PackageHelperImpl(shell.classLoader)

// Install security manager
def originalSM = System.getSecurityManager()
System.setSecurityManager(new NoExitSecurityManager())

// Register default commands
def registrar = new DefaultCommandsRegistrar(shell)
registrar.register()

// Add custom utilities
class UtilityCommand extends CommandSupport {
    UtilityCommand(shell) {
        super(shell, ':util', ':u')
    }
    
    Object execute(List<String> args) {
        if (args.size() == 0) {
            fail("Usage: :util <analyze|packages|vars>")
        }
        
        switch (args[0]) {
            case 'analyze':
                // Analyze current buffer
                def script = shell.buffers.current().join('\n')
                def vars = ScriptVariableAnalyzer.getBoundVars(script, shell.classLoader)
                shell.io.out.println("Variables: ${vars}")
                break
                
            case 'packages':
                // Show package contents
                if (args.size() < 2) {
                    fail("Usage: :util packages <package.name>")
                }
                def contents = shell.packageHelper.getContents(args[1])
                shell.io.out.println("Package ${args[1]}: ${contents}")
                break
                
            case 'vars':
                // Show bound variables
                def binding = shell.interp.context
                shell.io.out.println("Bound variables: ${binding.variables.keySet()}")
                break
                
            default:
                fail("Unknown utility: ${args[0]}")
        }
    }
    
    List<Completer> createCompleters() {
        return [new SimpleCompleter('analyze', 'packages', 'vars')]
    }
}

shell.register(new UtilityCommand(shell))

// Run shell
try {
    shell.run()
} finally {
    System.setSecurityManager(originalSM)
}

The utilities package provides essential support functions that enable advanced shell features like package exploration, variable analysis, secure execution, and flexible command registration. These utilities can be combined to create powerful shell extensions and custom development tools.

Install with Tessl CLI

npx tessl i tessl/maven-org-codehaus-groovy--groovy-groovysh

docs

command-system.md

completion-system.md

index.md

shell-features.md

utilities.md

tile.json