From ac819af76ba34ce303f2e6e57653650ca4c0a0f3 Mon Sep 17 00:00:00 2001 From: kares Date: Fri, 9 Nov 2018 15:05:46 +0100 Subject: [PATCH 1/5] prepare for 1.3.7 --- lib/readline/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/readline/version.rb b/lib/readline/version.rb index fb7a05b..292b86d 100644 --- a/lib/readline/version.rb +++ b/lib/readline/version.rb @@ -1,6 +1,6 @@ module Readline module Version - VERSION = "1.3.6" + VERSION = "1.3.7" JLINE_VERSION = "2.14.6" end end From bed8303c37c648c49e5f9441d4e941dac97bc141 Mon Sep 17 00:00:00 2001 From: kares Date: Thu, 8 Nov 2018 11:20:32 +0100 Subject: [PATCH 2/5] start using "JRuby" as app name (default is "JLine") --- src/main/java/org/jruby/ext/readline/Readline.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jruby/ext/readline/Readline.java b/src/main/java/org/jruby/ext/readline/Readline.java index 5e3e9f3..770077e 100644 --- a/src/main/java/org/jruby/ext/readline/Readline.java +++ b/src/main/java/org/jruby/ext/readline/Readline.java @@ -119,7 +119,7 @@ protected static void initReadline(final Ruby runtime, final ConsoleHolder holde final ConsoleReader readline; try { final Terminal terminal = TerminalFactory.create(); - readline = holder.readline = new ConsoleReader(null, runtime.getInputStream(), runtime.getOutputStream(), terminal); + readline = holder.readline = new ConsoleReader("JRuby", runtime.getInputStream(), runtime.getOutputStream(), terminal); } catch (IOException ioe) { throw runtime.newIOErrorFromException(ioe); } From 03475e4b294cbd48b6b60c5b33dce52facaf2147 Mon Sep 17 00:00:00 2001 From: kares Date: Thu, 8 Nov 2018 11:21:13 +0100 Subject: [PATCH 3/5] no need to handle literla next, really? --- src/main/java/org/jruby/ext/readline/Readline.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/jruby/ext/readline/Readline.java b/src/main/java/org/jruby/ext/readline/Readline.java index 770077e..496d421 100644 --- a/src/main/java/org/jruby/ext/readline/Readline.java +++ b/src/main/java/org/jruby/ext/readline/Readline.java @@ -127,6 +127,7 @@ protected static void initReadline(final Ruby runtime, final ConsoleHolder holde readline.setHistoryEnabled(false); readline.setPaginationEnabled(true); readline.setBellEnabled(true); + readline.setHandleLitteralNext(false); if (holder.currentCompletor == null) { holder.currentCompletor = new RubyFileNameCompletor(); From d7de58bba80cb1524f3a05a28fe970b18be66bbb Mon Sep 17 00:00:00 2001 From: kares Date: Thu, 8 Nov 2018 11:24:35 +0100 Subject: [PATCH 4/5] [fix] another try at restoring terminal settings since the previous attempt (on runtime tear-down) does not always work towards getting updates back: https://github.com/jruby/jruby/issues/5387 actually also resolves: https://github.com/jruby/jruby/issues/3181 --- .../java/org/jruby/ext/readline/Readline.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jruby/ext/readline/Readline.java b/src/main/java/org/jruby/ext/readline/Readline.java index 496d421..22e7a7b 100644 --- a/src/main/java/org/jruby/ext/readline/Readline.java +++ b/src/main/java/org/jruby/ext/readline/Readline.java @@ -221,16 +221,12 @@ private static IRubyObject readlineImpl(ThreadContext context, String prompt, fi holder.readline.setExpandEvents(false); String line; - while (true) { - try { - holder.readline.getTerminal().setEchoEnabled(false); - line = holder.readline.readLine(prompt); - break; - } catch (IOException ioe) { - throw runtime.newIOErrorFromException(ioe); - } finally { - holder.readline.getTerminal().setEchoEnabled(true); - } + try { + line = readlineLoop(holder.readline, prompt); + } catch (IOException ex) { + throw runtime.newIOErrorFromException(ex); + } catch (Exception ex) { + Helpers.throwException(ex); return null; // likely init/restore failure } if (line == null) return context.nil; @@ -248,6 +244,17 @@ private static IRubyObject readlineImpl(ThreadContext context, String prompt, fi return RubyString.newString(runtime, bytes); } + private static String readlineLoop(final ConsoleReader reader, final String prompt) throws Exception { + while (true) { + try { + reader.getTerminal().init(); + return reader.readLine(prompt); + } finally { + reader.getTerminal().restore(); + } + } + } + @JRubyMethod(name = "input=", module = true, visibility = PRIVATE) public static IRubyObject setInput(ThreadContext context, IRubyObject recv, IRubyObject input) { // FIXME: JRUBY-3604 From 161e54f5eacadf88ca55593f8b44c40b452697d2 Mon Sep 17 00:00:00 2001 From: kares Date: Fri, 9 Nov 2018 19:32:22 +0100 Subject: [PATCH 5/5] syncronize initialization a bit + minor cleanup --- .../java/org/jruby/ext/readline/Readline.java | 68 +++++++++++-------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/jruby/ext/readline/Readline.java b/src/main/java/org/jruby/ext/readline/Readline.java index 22e7a7b..eeffebc 100644 --- a/src/main/java/org/jruby/ext/readline/Readline.java +++ b/src/main/java/org/jruby/ext/readline/Readline.java @@ -85,6 +85,7 @@ public class Readline { } public static final char ESC_KEY_CODE = (char) 27; + public static class ConsoleHolder { public ConsoleReader readline; transient volatile Completer currentCompletor; @@ -116,27 +117,28 @@ public static void createReadline(final Ruby runtime) { // We lazily initialize this in case Readline.readline has been overridden in ruby (s_readline) protected static void initReadline(final Ruby runtime, final ConsoleHolder holder) { - final ConsoleReader readline; + final ConsoleReader reader; try { final Terminal terminal = TerminalFactory.create(); - readline = holder.readline = new ConsoleReader("JRuby", runtime.getInputStream(), runtime.getOutputStream(), terminal); + reader = new ConsoleReader("JRuby", runtime.getInputStream(), runtime.getOutputStream(), terminal); + holder.readline = reader; } catch (IOException ioe) { throw runtime.newIOErrorFromException(ioe); } - readline.setHistoryEnabled(false); - readline.setPaginationEnabled(true); - readline.setBellEnabled(true); - readline.setHandleLitteralNext(false); + reader.setHistoryEnabled(false); + reader.setPaginationEnabled(true); + reader.setBellEnabled(true); + reader.setHandleLitteralNext(false); if (holder.currentCompletor == null) { holder.currentCompletor = new RubyFileNameCompletor(); } - readline.addCompleter(holder.currentCompletor); - readline.setHistory(holder.history); + reader.addCompleter(holder.currentCompletor); + reader.setHistory(holder.history); // JRUBY-852, ignore escape key (it causes IRB to quit if we pass it out through readline) - readline.addTriggeredAction(ESC_KEY_CODE, new ActionListener() { + reader.addTriggeredAction(ESC_KEY_CODE, new ActionListener() { public void actionPerformed(ActionEvent e) { try { holder.readline.beep(); @@ -146,9 +148,9 @@ public void actionPerformed(ActionEvent e) { } }); - RubyModule Readline = runtime.getModule("Readline"); + RubyModule readline = runtime.getModule("Readline"); BlockCallback callback = new BlockCallback() { - public IRubyObject call(ThreadContext context, IRubyObject[] iRubyObjects, Block block) { + public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) { LOG.debug("finalizing readline (console) backend"); try { @@ -166,8 +168,8 @@ public IRubyObject call(ThreadContext context, IRubyObject[] iRubyObjects, Block return context.nil; } }; - Block block = CallBlock.newCallClosure(Readline, Readline, Signature.NO_ARGUMENTS, callback, runtime.getCurrentContext()); - Readline.addFinalizer(RubyProc.newProc(runtime, block, block.type)); + Block block = CallBlock.newCallClosure(readline, readline, Signature.NO_ARGUMENTS, callback, runtime.getCurrentContext()); + readline.addFinalizer(RubyProc.newProc(runtime, block, block.type)); } public static History getHistory(ConsoleHolder holder) { @@ -175,24 +177,34 @@ public static History getHistory(ConsoleHolder holder) { } public static ConsoleHolder getHolder(Ruby runtime) { - return (ConsoleHolder) (runtime.getModule("Readline").dataGetStruct()); + return getHolderImpl(runtime.getModule("Readline")); + } + + private static ConsoleHolder getHolderImpl(final RubyModule readline) { + return (ConsoleHolder) readline.dataGetStruct(); } public static ConsoleHolder getHolderWithReadline(Ruby runtime) { - ConsoleHolder holder = getHolder(runtime); + RubyModule readline = runtime.getModule("Readline"); + ConsoleHolder holder = getHolderImpl(readline); if (holder.readline == null) { - initReadline(runtime, holder); + synchronized (holder) { + if (holder.readline == null) { + initReadline(runtime, holder); + } + } } return holder; } public static void setCompletor(ConsoleHolder holder, Completer completor) { - if (holder.readline != null) { - holder.readline.removeCompleter(holder.currentCompletor); + final ConsoleReader reader = holder.readline; + if (reader != null) { + reader.removeCompleter(holder.currentCompletor); } holder.currentCompletor = completor; - if (holder.readline != null) { - holder.readline.addCompleter(holder.currentCompletor); + if (reader != null) { + reader.addCompleter(holder.currentCompletor); } } @@ -218,11 +230,13 @@ public static IRubyObject readline(ThreadContext context, IRubyObject recv, IRub private static IRubyObject readlineImpl(ThreadContext context, String prompt, final boolean addHistory) { final Ruby runtime = context.runtime; ConsoleHolder holder = getHolderWithReadline(runtime); - holder.readline.setExpandEvents(false); + final ConsoleReader reader = holder.readline; + + reader.setExpandEvents(false); String line; try { - line = readlineLoop(holder.readline, prompt); + line = readlineLoop(reader, prompt); } catch (IOException ex) { throw runtime.newIOErrorFromException(ex); } catch (Exception ex) { @@ -231,7 +245,7 @@ private static IRubyObject readlineImpl(ThreadContext context, String prompt, fi if (line == null) return context.nil; - if (addHistory) holder.readline.getHistory().add(line); + if (addHistory) reader.getHistory().add(line); // Enebo: This is a little weird and a little broken. We just ask // for the bytes and hope they match default_external. This will @@ -304,10 +318,10 @@ public static IRubyObject s_set_completion_proc(IRubyObject recv, IRubyObject pr public static IRubyObject s_get_screen_size(ThreadContext context, IRubyObject recv) { Ruby runtime = context.runtime; ConsoleHolder holder = getHolderWithReadline(runtime); - IRubyObject[] ary = new IRubyObject[2]; - ary[0] = runtime.newFixnum(holder.readline.getTerminal().getHeight()); - ary[1] = runtime.newFixnum(holder.readline.getTerminal().getWidth()); - return RubyArray.newArray(runtime, ary); + final Terminal terminal = holder.readline.getTerminal(); + IRubyObject h = runtime.newFixnum(terminal.getHeight()); + IRubyObject w = runtime.newFixnum(terminal.getWidth()); + return RubyArray.newArray(runtime, h, w); } @JRubyMethod(name = "set_screen_size", module = true, visibility = PRIVATE)