jline2 выведите "^J", когда он должен напечатать "\n" на консоли telnet

Я использую JLine 2 (v2.13) в сочетании с Socket IO, чтобы создать консоль администратора для моего приложения, к которой можно получить доступ через обычный клиент telnet. Однако я обнаружил, что он печатает странные символы, когда должен выводить разрыв строки:

act.app.restart  restart app^Jact.job.list  List jobs

Правильный вывод должен быть:

act.app.restart  restart app
act.job.list     List jobs

Я проследил в код и нашел следующую строку кода, которая вызвала проблему:

Еще одна странная вещь, когда я нажимаю стрелку вверх, чтобы получить историю, консоль печатает ^[[A и больше ничего не происходит.

У кого-нибудь есть идеи?

Обновление: добавлен соответствующий исходный код

  1. Код, принимающий входящее telnet-соединение:

  1. Код, который создает ConsoleReader и отправляет команду:

Обновление 2

Извините, я исчез на некоторое время. Просто вернись, так как мой проект дает мне глоток свежего воздуха. Итак, вот что произошло: я создал PrintWriter и использовать его в качестве обходного пути для ^J вопрос:

Однако есть много других проблем, когда jline2 используется вместе с сеансом telnet:

  1. Тип <TAB> отображает вкладку вместо активации полного списка. Однако после того, как я нажимаю клавишу ввода, он дает мне полный список плюс сообщение об ошибке:
  2. Тип <UP> стрелка, отображает ^[[A, нажмите клавишу ввода, он выполнит мою последнюю команду. Однако я потерял редактирование командной строки

Проблема все еще существует, и я считаю, что должен быть способ ее решить, просто нужно какое-то руководство...

1 ответ

Редактировать: мой плохой, метод, который я показал, является частным. Тем не менее, это не ошибка - это код, делающий то, что должен делать. Два открытых метода, которые используют rawPrint (я поставил их в конце), используют его только для маскированного вывода и, очевидно, для завершения печати, поэтому ConsoleReader, вероятно, не поддерживает ваш сценарий использования - это может быть ошибка проектирования, но я думаю, что это означало быть таким. Проблемы со стрелками упоминаются в документах мимоходом как проблема конфигурации терминала.

ConsoleReader.java находится здесь: https://github.com/jline/jline2/blob/master/src/main/java/jline/console/ConsoleReader.java

Я думаю, что это последняя версия и т. Д.

Что вы делаете, это создаете ConsoleReader, вызывающий println() для него. LF отображается как ^J. Это не ошибка в том смысле, что метод делает то, что должен делать:

/*3478*/ public void println(final CharSequence s) throws IOException {
    print(s);
    println();
}

который в конечном итоге вызывает

/*3445*/private int print(final CharSequence buff, int start, int end, int cursorPos) throws IOException {
        checkNotNull(buff);
        for (int i = start; i < end; i++) {
            char c = buff.charAt(i);
            if (c == '\t') {
                int nb = nextTabStop(cursorPos);
                cursorPos += nb;
                while (nb-- > 0) {
                    out.write(' ');
                }
            } else if (c < 32) {
                out.write('^');
                out.write((char) (c + '@')); //LF -> ^J

Эта функция делает то, что вы хотите, но является частной:

/*3510*/ private void rawPrintln(final String s) throws IOException {
    rawPrint(s); //
    println();
}

/*3499*/ final void rawPrint(final String str) throws IOException {
    out.write(str);
    cursorOk = false;
}

Он может быть вызван через открытые методы putString(final CharSequence str) в строке 895 и printColumns(конечные элементы Collection) в строке 3715. putString вызывает его только при использовании маскированного вывода, поэтому он бесполезен для вас, и printColumns, кажется, предназначена для завершения,

Может быть, вы должны печатать строки отдельно и позволить ConsoleReader добавлять к ним новые строки? Технически, LF - это управляющий код, и имеет смысл запретить ConsoleReader печатать управляющие коды как есть. Просто разделите ваш ввод по строкам, напечатайте их по очереди.

Другие вопросы по тегам