12
12
import java .util .ArrayList ;
13
13
import java .util .Arrays ;
14
14
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 ;
15
21
16
22
import static org .perlonjava .Configuration .getPerlVersionBundle ;
17
23
import static org .perlonjava .Configuration .perlVersion ;
@@ -40,27 +46,58 @@ public static CompilerOptions parseArguments(String[] args) {
40
46
// If no code was provided and no filename, try reading from stdin
41
47
if (parsedArgs .code == null ) {
42
48
try {
43
- // Try to read from stdin - this will work for pipes, redirections, and interactive input
44
49
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
48
50
boolean isInteractive = System .console () != null ;
49
51
50
52
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 ("\n Interrupted. Use 'exit' or Ctrl+D to quit." );
82
+ break ;
83
+ }
84
+ }
54
85
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 );
59
96
}
60
97
61
98
if (stdinContent .length () > 0 ) {
62
99
parsedArgs .code = stdinContent .toString ();
63
- parsedArgs .fileName = "-" ; // Indicate that code came from stdin
100
+ parsedArgs .fileName = "-" ;
64
101
}
65
102
} catch (IOException e ) {
66
103
// If we can't read from stdin, continue with normal error handling
@@ -72,6 +109,14 @@ public static CompilerOptions parseArguments(String[] args) {
72
109
return parsedArgs ;
73
110
}
74
111
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
+
75
120
/**
76
121
* Processes the command-line arguments, distinguishing between switch and non-switch arguments.
77
122
*
0 commit comments