This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 8927ad375f GROOVY-8162: Update Groovysh to JLine3 (add support for /cd)
8927ad375f is described below

commit 8927ad375f4cb8b675c7a952371024b07e6ac535
Author: Paul King <[email protected]>
AuthorDate: Mon Aug 11 23:58:38 2025 +1000

    GROOVY-8162: Update Groovysh to JLine3 (add support for /cd)
---
 .../groovy/org/apache/groovy/groovysh/Main.groovy  | 41 +++++++++++++++-------
 .../groovysh/jline/GroovyPosixContext.groovy       | 38 ++++++++++++++++++++
 2 files changed, 67 insertions(+), 12 deletions(-)

diff --git 
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
 
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
index 8adc4cfeed..66ee577d0d 100644
--- 
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
+++ 
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
@@ -24,6 +24,7 @@ import org.apache.groovy.groovysh.jline.GroovyBuiltins
 import org.apache.groovy.groovysh.jline.GroovyCommands
 import org.apache.groovy.groovysh.jline.GroovyConsoleEngine
 import org.apache.groovy.groovysh.jline.GroovyEngine
+import org.apache.groovy.groovysh.jline.GroovyPosixContext
 import org.apache.groovy.groovysh.jline.GroovySystemRegistry
 import org.apache.groovy.groovysh.util.DocFinder
 import org.codehaus.groovy.tools.shell.util.MessageSource
@@ -85,27 +86,28 @@ class Main {
     @SuppressWarnings("resource")
     protected static class ExtraConsoleCommands extends JlineCommandRegistry 
implements CommandRegistry {
         private final LineReader reader
-        private final Supplier<Path> workDir
         private final Map<String, Object> variables
-        private final PosixCommandsRegistry posix
+        private PosixCommandsRegistry posix
         private final Map<String, String[]> usage = [:]
 
-        ExtraConsoleCommands(Supplier<Path> workDir, Map<String, Object> 
variables, LineReader reader) {
+        ExtraConsoleCommands(Path workDir, Map<String, Object> variables, 
LineReader reader) {
             super()
-            this.workDir = workDir
             this.variables = variables
             this.reader = reader
             def terminal = reader.terminal
-            posix = new PosixCommandsRegistry(
+            def context = new GroovyPosixContext(
                 terminal.input(),
                 new PrintStream(terminal.output()),
                 new PrintStream(terminal.output()),
-                workDir.get(),
+                workDir,
                 terminal,
-                variables::get)
+                variables::get
+            )
+            posix = new PosixCommandsRegistry(context)
             def cmds = [
                 '/clear': new CommandMethods((Function) this::clear, 
this::defaultCompleter),
                 '/pwd'  : new CommandMethods((Function) this::pwd, 
this::defaultCompleter),
+                '/cd'   : new CommandMethods((Function) this::cd, 
this::defaultCompleter),
                 '/date' : new CommandMethods((Function) this::date, 
this::defaultCompleter),
                 '/echo' : new CommandMethods((Function) this::echo, 
this::defaultCompleter),
                 "/!"    : new CommandMethods((Function) this::shell, 
this::defaultCompleter)
@@ -116,11 +118,17 @@ class Main {
                 posix.register(cmd, PosixCommands::"$orig")
                 cmds.put(cmd, new CommandMethods((Function) this::posix, 
this::optFileCompleter))
             }
+            posix.register('cd', PosixCommands::cd)
+            posix.register('/cd', PosixCommands::cd)
             posix.register('/pwd', PosixCommands::pwd)
             posix.register('/date', PosixCommands::date)
             registerCommands(cmds)
         }
 
+        Path currentDir() {
+            posix.context.currentDir
+        }
+
         private String[] adjustUsage(String from, String to) {
             try {
                 posix.execute(from, [from, '--help'] as String[])
@@ -139,13 +147,22 @@ class Main {
         }
 
         private List<Completer> optFileCompleter(String command) {
-            [new ArgumentCompleter(NullCompleter.INSTANCE, new 
Completers.OptionCompleter(new Completers.FilesCompleter(workDir), 
this::commandOptions, 1))]
+            [new ArgumentCompleter(NullCompleter.INSTANCE, new 
Completers.OptionCompleter(new Completers.FilesCompleter(this::currentDir), 
this::commandOptions, 1))]
         }
 
         private void pwd(CommandInput input) {
             posix(adjustUsage('pwd', '/pwd'), input)
         }
 
+        private void cd(CommandInput input) {
+            try {
+                parseOptions(adjustUsage('cd', '/cd'), input.args())
+                PosixCommands.cd(posix.context, ['/cd', *input.args()] as 
String[], { Path newPath -> posix.context.currentDir = newPath })
+            } catch (Exception e) {
+                saveException(e)
+            }
+        }
+
         private void date(CommandInput input) {
             posix(adjustUsage('date', '/date'), input)
         }
@@ -276,7 +293,6 @@ class Main {
         }
 
         try {
-            Supplier<Path> workDir = () -> 
Paths.get(System.getProperty('user.dir'))
             DefaultParser parser = new DefaultParser(
                 regexCommand: /\/?[a-zA-Z!]\S*/,
                 eofOnUnclosedQuote: true,
@@ -310,8 +326,6 @@ class Main {
             def argsHighlighter = SyntaxHighlighter.build(jnanorc, "ARGS")
             def groovyHighlighter = SyntaxHighlighter.build(jnanorc, "Groovy")
 
-            CommandRegistry groovy = new GroovyCommands(scriptEngine, workDir, 
printer, groovyHighlighter)
-
             LineReader reader = LineReaderBuilder.builder()
                 .terminal(terminal)
                 .parser(parser)
@@ -329,7 +343,10 @@ class Main {
                     LineReader.BLINK_MATCHING_PAREN, 0) // if enabled cursor 
remains in begin parenthesis (gitbash)
             }
 
-            def extra = new ExtraConsoleCommands(workDir, 
scriptEngine.variables, reader)
+            def extra = new 
ExtraConsoleCommands(Paths.get(System.getProperty('user.dir')), 
scriptEngine.variables, reader)
+            Supplier<Path> workDir = extra::currentDir
+
+            CommandRegistry groovy = new GroovyCommands(scriptEngine, workDir, 
printer, groovyHighlighter)
 
             ConsoleEngine consoleEngine = new 
GroovyConsoleEngine(scriptEngine, printer, workDir, configPath, reader)
             consoleEngine.setConsoleOption('docs', new DocFinder())
diff --git 
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyPosixContext.groovy
 
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyPosixContext.groovy
new file mode 100644
index 0000000000..f7f0ff19d1
--- /dev/null
+++ 
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyPosixContext.groovy
@@ -0,0 +1,38 @@
+/*
+ *  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.
+ */
+package org.apache.groovy.groovysh.jline
+
+import org.jline.builtins.PosixCommands
+import org.jline.terminal.Terminal
+
+import java.nio.file.Path
+import java.util.function.Function
+
+class GroovyPosixContext extends PosixCommands.Context {
+    Path currentDir
+
+    GroovyPosixContext(InputStream inputStream, PrintStream out, PrintStream 
err, Path currentDir, Terminal terminal, Function<String, Object> variables) {
+        super(inputStream, out, err, null, terminal, variables)
+        this.currentDir = currentDir
+    }
+
+    Path currentDir() {
+        currentDir
+    }
+}

Reply via email to