0

I'm writing a simple ssh server with Apache Mina SSHD and I'm using JLine3 to handle input and output.
I'm testing Autosuggestion Tail Tip Widgets: it works but not as expected.

What I get:

enter image description here

What I want:

asciicast

I don't know why I don't get the result above.
I followed this guide.

This is my code:

public class ChatHandler implements Command, Runnable {
    private LineReader input;
    private Terminal output;
    private InputStream in;
    private OutputStream out;
    private ExitCallback callback;
    @Override
    public void run() {
        output.puts(Capability.clear_screen);
        for(int i=0;i<output.getHeight();i++)
            input.printAbove("");
        while (true)
        {
            input.readLine("Enter a line: ");
        }
    }
    @Override
    public void start(ChannelSession channel, Environment env) throws IOException {
        output = TerminalBuilder.builder()
                .system(false)
                .streams(in, out)
                .encoding(StandardCharsets.UTF_8)
                .size(new Size(Integer.parseInt(env.getEnv().get(Environment.ENV_COLUMNS)),
                        Integer.parseInt(env.getEnv().get(Environment.ENV_LINES))))
                .build();
        input = LineReaderBuilder.builder()
                    .completer(new AggregateCompleter(new ArgumentCompleter(Arrays.asList(
                               new StringsCompleter("/signin"),
                               new OptionCompleter(Arrays.asList(
                                       new StringsCompleter("username"),
                                       NullCompleter.INSTANCE),Collections.singleton(new OptDesc(null, null,"Register user")),1)))))
                    .terminal(output)
                    .option(Option.INSERT_BRACKET,true)
                    .option(Option.ERASE_LINE_ON_FINISH,true)
                    .option(Option.CASE_INSENSITIVE,true)
                    .variable(LineReader.SECONDARY_PROMPT_PATTERN,"")
                    .variable(LineReader.INDENTATION,4)
                    .build();

        Map<String, CmdDesc> tailTips = new HashMap<>();
        Map<String, List<AttributedString>> widgetOpts = new HashMap<>();
        List<AttributedString> mainDesc = Arrays.asList(new AttributedString("/signin username")
                               );
        widgetOpts.put("username", Arrays.asList(new AttributedString("Register user")));

        tailTips.put("/signin", new CmdDesc(mainDesc, ArgDesc.doArgNames(Arrays.asList("username")), widgetOpts));
        TailTipWidgets tailtipWidgets = new TailTipWidgets(input, tailTips,5,TipType.COMPLETER);
        tailtipWidgets.enable();

        InputRC.configure(input,ChatHandler.class.getResourceAsStream("/resources/keybind"));
        new Thread(this).start();
    }

    @Override
    public void destroy(ChannelSession channel) throws Exception {
    }

    @Override
    public void setInputStream(InputStream in) {
        this.in = in;
    }

    @Override
    public void setOutputStream(OutputStream out) {
        this.out = out;
    }

    @Override
    public void setErrorStream(OutputStream err) {
    }

    @Override
    public void setExitCallback(ExitCallback callback) {
        this.callback = callback;
    }
}

Thanks in advance.

dems98
  • 814
  • 3
  • 9
  • 22

1 Answers1

0

If the problem is the missing status bar below the prompt, I guess that it is because your terminal does not have the required capabilities to create it. Your terminal should have change_scroll_region, save_cursor, restore_cursor and cursor_address capabilities, see org.jline.utils.Status lines ~44-59.

        this.supported = terminal.getStringCapability(Capability.change_scroll_region) != null
            && terminal.getStringCapability(Capability.save_cursor) != null
            && terminal.getStringCapability(Capability.restore_cursor) != null
            && terminal.getStringCapability(Capability.cursor_address) != null;
mattirn
  • 26
  • 4
  • `output.puts(Capability.cursor_address)`; gives me this exception: `Exception in thread "Thread-4" java.io.IOError: java.lang.ArrayIndexOutOfBoundsException: 0 at org.jline.utils.Curses.tputs(Curses.java:62) at org.jline.terminal.impl.AbstractTerminal.puts(AbstractTerminal.java:182) at com.demetrio.socketchat.server.ChatHandler.run(ChatHandler.java:119) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.ArrayIndexOutOfBoundsException: 0 at org.jline.utils.Curses.doTputs(Curses.java:155) at org.jline.utils.Curses.tputs(Curses.java:60) ... 3 more` – dems98 May 14 '20 at 14:16
  • You need to add two integer parameters in your call i.e. a new cursor position: `terminal.puts(Capability.cursor_address, row, column)` – mattirn May 15 '20 at 14:27
  • What values do I have to put? I've tried several but none worked – dems98 May 15 '20 at 15:15
  • Upper left corner of the terminal is 1 ,1 and lower right corner maxRow, maxColumn. I'm afraid that your terminal does not support cursor_address capability. I have worked only on system terminals I have no idea how to make it working on non system terminal – mattirn May 15 '20 at 17:49
  • Ok, so I will not use this functionality. Thanks for the help. – dems98 May 15 '20 at 18:20