Skip to content

Commit 42eb406

Browse files
committed
CLI accept interactive input, use jline
1 parent 9f3e812 commit 42eb406

File tree

3 files changed

+69
-12
lines changed

3 files changed

+69
-12
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ repositories {
6868
// Project dependencies
6969
dependencies {
7070
// Core dependencies
71+
implementation 'org.jline:jline-reader:3.30.4'
72+
implementation 'org.jline:jline-terminal:3.30.4'
7173
implementation 'org.ow2.asm:asm:9.8' // ByteCode manipulation
7274
implementation 'org.ow2.asm:asm-util:9.8' // ASM utilities
7375
implementation 'com.ibm.icu:icu4j:77.1' // Unicode support

pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@
1717
</properties>
1818

1919
<dependencies>
20+
<dependency>
21+
<groupId>org.jline</groupId>
22+
<artifactId>jline-reader</artifactId>
23+
<version>3.30.4</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.jline</groupId>
27+
<artifactId>jline-terminal</artifactId>
28+
<version>3.30.4</version>
29+
</dependency>
2030
<dependency>
2131
<groupId>org.ow2.asm</groupId>
2232
<artifactId>asm</artifactId>

src/main/java/org/perlonjava/ArgumentParser.java

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
import java.util.ArrayList;
1313
import java.util.Arrays;
1414
import java.util.List;
15+
import org.jline.reader.LineReader;
16+
import org.jline.reader.LineReaderBuilder;
17+
import org.jline.reader.EndOfFileException;
18+
import org.jline.reader.UserInterruptException;
19+
import org.jline.terminal.Terminal;
20+
import org.jline.terminal.TerminalBuilder;
1521

1622
import static org.perlonjava.Configuration.getPerlVersionBundle;
1723
import static org.perlonjava.Configuration.perlVersion;
@@ -40,27 +46,58 @@ public static CompilerOptions parseArguments(String[] args) {
4046
// If no code was provided and no filename, try reading from stdin
4147
if (parsedArgs.code == null) {
4248
try {
43-
// Try to read from stdin - this will work for pipes, redirections, and interactive input
4449
StringBuilder stdinContent = new StringBuilder();
45-
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
46-
47-
// Check if we're reading from a pipe/redirection vs interactive terminal
4850
boolean isInteractive = System.console() != null;
4951

5052
if (isInteractive) {
51-
// Interactive mode - prompt the user and read until EOF (Ctrl+D)
52-
System.err.println("Enter Perl code (press Ctrl+D when done):");
53-
}
53+
// Interactive mode with JLine for better editing experience
54+
try {
55+
Terminal terminal = TerminalBuilder.builder()
56+
.system(true)
57+
.build();
58+
59+
LineReader lineReader = LineReaderBuilder.builder()
60+
.terminal(terminal)
61+
.build();
62+
63+
System.err.println("Enter Perl code (press Ctrl+D when done, or type 'exit' to quit):");
64+
System.err.println("Use arrow keys to navigate, Ctrl+A/E for home/end");
65+
66+
String line;
67+
while (true) {
68+
try {
69+
line = lineReader.readLine("> ");
70+
if (line != null) {
71+
if ("exit".equals(line.trim())) {
72+
break;
73+
}
74+
stdinContent.append(line).append("\n");
75+
}
76+
} catch (EndOfFileException e) {
77+
// User pressed Ctrl+D
78+
break;
79+
} catch (UserInterruptException e) {
80+
// User pressed Ctrl+C
81+
System.err.println("\nInterrupted. Use 'exit' or Ctrl+D to quit.");
82+
break;
83+
}
84+
}
5485

55-
// Read from stdin regardless of whether it's interactive or not
56-
String line;
57-
while ((line = reader.readLine()) != null) {
58-
stdinContent.append(line).append("\n");
86+
terminal.close();
87+
} catch (Exception e) {
88+
// Fall back to basic readline if JLine fails
89+
System.err.println("Enhanced editing not available, falling back to basic mode.");
90+
System.err.println("Enter Perl code (press Ctrl+D when done):");
91+
fallbackReadlines(stdinContent);
92+
}
93+
} else {
94+
// Non-interactive mode (pipes, redirections)
95+
fallbackReadlines(stdinContent);
5996
}
6097

6198
if (stdinContent.length() > 0) {
6299
parsedArgs.code = stdinContent.toString();
63-
parsedArgs.fileName = "-"; // Indicate that code came from stdin
100+
parsedArgs.fileName = "-";
64101
}
65102
} catch (IOException e) {
66103
// If we can't read from stdin, continue with normal error handling
@@ -72,6 +109,14 @@ public static CompilerOptions parseArguments(String[] args) {
72109
return parsedArgs;
73110
}
74111

112+
private static void fallbackReadlines(StringBuilder stdinContent) throws IOException {
113+
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
114+
String line;
115+
while ((line = reader.readLine()) != null) {
116+
stdinContent.append(line).append("\n");
117+
}
118+
}
119+
75120
/**
76121
* Processes the command-line arguments, distinguishing between switch and non-switch arguments.
77122
*

0 commit comments

Comments
 (0)