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
и больше ничего не происходит.
У кого-нибудь есть идеи?
Обновление: добавлен соответствующий исходный код
- Код, принимающий входящее telnet-соединение:
- Код, который создает
ConsoleReader
и отправляет команду:
Обновление 2
Извините, я исчез на некоторое время. Просто вернись, так как мой проект дает мне глоток свежего воздуха. Итак, вот что произошло: я создал PrintWriter
и использовать его в качестве обходного пути для ^J
вопрос:
Однако есть много других проблем, когда jline2
используется вместе с сеансом telnet:
- Тип
<TAB>
отображает вкладку вместо активации полного списка. Однако после того, как я нажимаю клавишу ввода, он дает мне полный список плюс сообщение об ошибке: - Тип
<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 печатать управляющие коды как есть. Просто разделите ваш ввод по строкам, напечатайте их по очереди.