2015-12-25 12 views
8

Ich benutze JLine 2 (v2.13) in Verbindung mit einem Socket IO um eine Admin-Konsole für meine App zu erstellen, auf die über eine zugegriffen werden kann gewöhnlicher Telnet-Client. Allerdings fand ich es seltsam Symbole druckt, wenn es einen Zeilenumbruch drucken soll:jline2 print "^ J", wenn es auf einer Telnet-Konsole " n" drucken soll

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

Die richtige Ausgabe sein sollte:

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

ich in den Code verfolgt und fand die folgende Zeile des Codes, die Mühe verursacht:

enter image description here

Eine weitere seltsame Sache ist, wenn ich den Pfeil nach oben drücken Sie die Geschichte zu bekommen, die Konsole druckt ^[[A und nichts anderes passiert.

Hat jemand eine Idee?

aktualisieren:

  1. Der Code der Annahme der eingehenden Telnet-Verbindung relevant Quellcode hinzugefügt:

enter image description here

  1. Der Code, erzeugt die ConsoleReader und sendet den Befehl:

enter image description here

Update 2

Sorry, ich habe für eine Weile verschwunden. Komm einfach zurück, denn mein Projekt gibt mir frischen Wind. So, hier ist was passiert: Ich habe eine PrintWriter erstellt und verwenden Sie es als Abhilfe für das ^J Ausgabe:

enter image description here

Allerdings gibt es viele andere Probleme, wenn jline2 zusammen mit Telnet-Sitzung verwendet wird:

  1. Typ <TAB> zeigt Registerkarte anstelle der vollständigen Liste zu aktivieren. Aber nachdem ich die Eingabetaste gedrückt habe, gibt es eine vollständige Liste mit einer Fehlermeldung:
  2. Geben Sie <UP> Pfeil, zeigt ^[[A, drücken Sie die Eingabetaste, es wird meinen letzten Befehl ausführen. Allerdings verlor ich die Befehlszeile Bearbeitung

Das Problem ist immer noch da und ich glaube, sollte es eine Möglichkeit geben, sie zu lösen brauchen nur etwas guide ...

+1

Haben Sie das Terminal für den von Ihnen verwendeten Client konfiguriert? Die Zeichen, die Sie sehen, sind wahrscheinlich Escape-Sequenzen, die verwendet werden, um den Cursor zu positionieren, was für den verwendeten Client Sinn machen sollte, es sei denn ANSI statt vt-100 oder Windows statt Unix. Stellen Sie sicher, dass Sie die Terminalanwendung ordnungsgemäß konfigurieren. Schauen Sie sich zum Beispiel in TerminalType AUTO um. –

+0

Ich bin auf Linux 17.3, verwenden Sie das einfache Telnet, um eine Verbindung mit dem Java-Server herzustellen. Und der Code, um die Telnet-Verbindungsanfrage zu beantworten, ist https://github.com/actframework/actframework/blob/master/src/main/java/act/app/CliServer.java#L56. –

+0

BTW, ich konnte die Klasse TerminalType in jline2 Quellcode nicht finden. Kannst du hier einen Link setzen? –

Antwort

0

Edit: Meine schlecht, die Methode, die ich gezeigt ist privat. Dennoch ist es kein Bug - der Code tut, was er tun soll.Die beiden öffentlichen Methoden, die rawPrint verwenden (ich setze sie am Ende), verwenden sie nur für maskierte Ausgaben und anscheinend für das Drucken von Vervollständigungen. Daher unterstützt ConsoleReader Ihren Anwendungsfall wahrscheinlich nicht - es könnte ein Designfehler sein, aber ich denke, es ist gemeint so zu sein. Die Probleme mit den Pfeiltasten werden in der Dokumentation als Problem mit der Terminalkonfiguration erwähnt.

ConsoleReader.java ist hier: https://github.com/jline/jline2/blob/master/src/main/java/jline/console/ConsoleReader.java

Ich denke, es ist die letzte Version, usw.

Was Sie tun, ist ein ConsoleReader die Berufung println() auf sie zu schaffen. LF wird als^J angezeigt. Dies ist kein Fehler in dem Sinne, dass die Methode tut, was es tun soll ist:

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

schließlich die

nennt
/*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 

Diese Funktion tut, was Sie wollen, aber ist privat:

/*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; 
} 

Es kann über die öffentlichen Methoden putString (letzte CharSequence str) in Zeile 895 und printColumns (endgültige Collection-Elemente) in Zeile 3715 aufgerufen werden. PutString ruft nur bei Verwendung maskierter Ausgabe auf, so ist es usel Ihnen und printColumns scheint für die Fertigstellung gedacht zu sein.

Vielleicht sollten Sie Zeilen separat drucken und ConsoleReader Zeilenumbrüche hinzufügen lassen? Technisch gesehen ist LF ein Steuercode und es ist sinnvoll ConsoleReader zu verbieten, Steuercodes so zu drucken wie sie sind. Teilen Sie Ihre Eingabe in Zeilen, drucken Sie sie einzeln aus.

+0

Ich habe bereits einen externen 'PrintWriter' verwendet, um das'^J' Problem vorübergehend zu umgehen. Allerdings gibt es mehr komische Dinge als '^ J'. Ich gebe ein '' ein, um 'Completer' zu aktivieren, aber es zeigt die Registerkarte an, und wenn ich Enter drücke, wird die vollständige Liste angezeigt und dann wird" Command not recognized: xxx "angezeigt. Ich tippe '' Pfeil, um meinen letzten Befehl zu bekommen, es zeigt '^ [[A', wenn ich' 'trete, führt es meinen letzten Befehl aus, jedoch habe ich meine Befehlszeilenbearbeitung verloren –