Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prefill a line with jline

Using either JLine (or JLine2), is it possible to issue a call to readline on a ConsoleReader and have, in addition to the standard prompt, the buffer be pre-filled with a string of my choosing?

I have tried to do, e.g.:

reader.getCursorBuffer().write("Default");
reader.readLine("Prompt> ");

This seems to indeed write into the buffer, but the line only displays the prompt. If I press enter, readLine returns "Default" as I would expect. If I clear the screen, the buffer is redrawn and shown correctly.

My understanding is that I should somehow call reader.redrawLine() right after the call to readLine. This last one however is blocking, which makes it hard (not impossible, but it certainly feels wrong to use a second thread for that).

like image 407
Philippe Avatar asked Sep 04 '12 17:09

Philippe


Video Answer


2 Answers

I ran into exactly this use case today.

It's a bit of a hack, but I was able to preload text into the JLine buffer and then let the user edit it by doing this:

String preloadReadLine(ConsoleReader reader, String prompt, String preload)
    throws IOException
{
    reader.resetPromptLine(prompt, preload, 0);
    reader.print("\r");
    return reader.readLine(prompt);
}

Yeah, the printing of \r is a hack, but it seems to make the thing work.

I'm using JLine-2.13.

like image 134
Stuart Marks Avatar answered Sep 20 '22 10:09

Stuart Marks


I managed to do that using a thread (yes, it does feel wrong, but I found no other way).

I took inspiration from code found in JLine itself that also uses a thread for similar purposes.

In Scala:

      val thr = new Thread() {
        override def run() = {
          reader.putString("Default")
          reader.flush()
          // Another way is:
          // reader.getCursorBuffer.write("Default") // writes into the buffer without displaying
          // out.print("D*f*ult") // here you can choose to display something different
          // reader.flush()
        }
      }
      thr.setPriority(Thread.MAX_PRIORITY)
      thr.setDaemon(true)
      thr.start()
like image 37
LP_ Avatar answered Sep 20 '22 10:09

LP_