Skip to content

Commit

Permalink
Demo: custom line reader for Console.readLine.
Browse files Browse the repository at this point in the history
  • Loading branch information
lahodaj committed Oct 18, 2024
1 parent 7f4ed50 commit dd196e8
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 23 deletions.
5 changes: 3 additions & 2 deletions src/java.base/share/classes/java/io/Console.java
Original file line number Diff line number Diff line change
Expand Up @@ -662,12 +662,13 @@ private static Console instantiateConsole() {
*/
c = AccessController.doPrivileged(new PrivilegedAction<Console>() {
public Console run() {
var consModName = System.getProperty("jdk.console",
JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME);
var consModName = "java.base";//System.getProperty("jdk.console",
// JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME);

for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) {
if (consModName.equals(jcp.getClass().getModule().getName())) {
var jc = jcp.console(istty, CHARSET);
System.err.println("jc: " + jc + ":" + JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME);
if (jc != null) {
return new ProxyingConsole(jc);
}
Expand Down
110 changes: 90 additions & 20 deletions src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,27 +227,97 @@ public Charset charset() {
private boolean shutdownHookInstalled;

private char[] readline(boolean zeroOut) throws IOException {
int len = reader.read(rcb, 0, rcb.length);
if (len < 0)
return null; //EOL
if (rcb[len-1] == '\r')
len--; //remove CR at end;
else if (rcb[len-1] == '\n') {
len--; //remove LF at end;
if (len > 0 && rcb[len-1] == '\r')
len--; //remove the CR, if there is one
}
char[] b = new char[len];
if (len > 0) {
System.arraycopy(rcb, 0, b, 0, len);
if (zeroOut) {
Arrays.fill(rcb, 0, len, ' ');
if (reader instanceof LineReader lr) {
lr.zeroOut();
String originalTerminalSettings = runStty("-g");
Thread restoreConsole = new Thread(() -> {
try {
runStty(originalTerminalSettings);
} catch (IOException ex) {
ex.printStackTrace();
}
});
try {
Runtime.getRuntime().addShutdownHook(restoreConsole);
runStty("5000:5:b0:a31:3:1c:7f:15:4:1:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0");
StringBuilder result = new StringBuilder();
int caret = 0;
int r;
READ: while (true) {
//paint:
System.out.print("\r");
System.out.print(result);
System.out.print("\033[J");
for (int i = result.length(); i > caret; i--) {
System.out.print("\033[D");
}

//read
r = reader.read();
switch (r) {
case -1: continue READ;
case '\r': break READ;
case 4: break READ; //EOF/Ctrl-D
case 127:
if (caret > 0) {
result.delete(caret - 1, caret);
caret--;
}
continue READ;
case '\033':
r = reader.read();
switch (r) {
case '[':
r = reader.read();
switch (r) {
case 'C': if (caret < result.length()) caret++; break;
case 'D': if (caret > 0) caret--; break;
case 'H': caret = 0; break;
case 'F': caret = result.length(); break;
case '3':
r = reader.read();
if (r != '~') {
//TODO
} else {
//delete
result.delete(caret, caret + 1);
}
continue READ;
default:
System.err.println("r: " + (char) r);
}
}
continue READ;
}

result.insert(caret, (char) r);
caret++;
}

//show the final state:
System.out.print("\r");
System.out.println(result);

return result.toString().toCharArray();
} finally {
restoreConsole.run();
Runtime.getRuntime().removeShutdownHook(restoreConsole);
}
}

private String runStty(String input) throws IOException {
StringBuilder output = new StringBuilder();
Process p = new ProcessBuilder("stty", input).inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE).start();
Reader inp = p.inputReader();
int r;
while ((r = inp.read()) != (-1)) {
if (r == '\n') break;
output.append((char) r);
}
try {
p.waitFor();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return b;
return output.toString();
}

private char[] grow() {
Expand Down Expand Up @@ -398,10 +468,10 @@ public void close() {
}
};
formatter = new Formatter(out);
reader = new LineReader(StreamDecoder.forInputStreamReader(
reader = /*new LineReader(*/StreamDecoder.forInputStreamReader(
new FileInputStream(FileDescriptor.in),
readLock,
charset));
charset);//);
rcb = new char[1024];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public interface JdkConsoleProvider {
/**
* The module name of the JdkConsole default provider.
*/
String DEFAULT_PROVIDER_MODULE_NAME = "jdk.internal.le";
String DEFAULT_PROVIDER_MODULE_NAME = "java.base";

/**
* {@return the Console instance, or {@code null} if not available}
Expand Down

0 comments on commit dd196e8

Please sign in to comment.