2015-12-25 238 views
8

我使用JLine 2(v2.13)与Socket IO一起为我的应用创建管理控制台,可以通过普通的telnet客户端。不过,我发现它打印出奇怪的符号时,应打印出一个换行符:jline2在Telnet控制台上打印“ n”时打印出“^ J”

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

正确的输出应该是:

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

我跟踪到了代码,发现下面的代码行造成的麻烦:

enter image description here

另一个奇怪的事情是,当我按向上箭头拿到历史,控制台打印出^[[A,没有其他事情发生。

有没有人有任何想法?

更新:加入相关的源码

  1. 代码接受传入telnet连接:

enter image description here

  • 的创建代码ConsoleReader并发出命令:
  • enter image description here

    更新2

    对不起,我已经消失了一段时间。回到我的项目让我呼吸新鲜空气。因此,这里所发生的事情:我创建了一个PrintWriter,并用它作为^J问题的解决方法:

    enter image description here

    但是还有很多其他的问题,当jline2与telnet会话一起使用

    1. 类型<TAB>显示选项卡而不是激活完整列表。不过之后我打回车键它给了我一个完整的列表,以及一个错误信息: enter image description here
    2. 类型<UP>箭头,显示^[[A,打回车键就会执行我的最后一个命令。但是我失去了命令行编辑

    问题仍然存在,我认为应该有解决它只是需要一些引导的方式...

    +1

    您是否为您正在使用的客户端配置了终端?您看到的字符可能是用于定位光标的转义序列,除非存在不匹配,例如ANSI而不是vt-100或Windows而不是unix,否则这应该对您正在使用的客户端有意义。确保您正确配置终端应用程序。例如,查看TerminalType AUTO。 –

    +0

    我在linux mint 17.3上,使用普通的telnet连接到Java服务器。响应telnet连接请求的代码是https://github.com/actframework/actframework/blob/master/src/main/java/act/app/CliServer.java#L56。 –

    +0

    顺便说一句,我无法在jline2源代码中找到类TerminalType。你能把链接放在这里吗? –

    回答

    0

    编辑:我的坏,方法我显示是私人的。不过,这不是一个错误 - 它的代码正在做它应该做的事情。使用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(最终CharSequence str)在行895和printColumns(最终集合项目)在行3715调用。putString只在使用屏蔽输出时调用它,因此它是有用的对你来说,和printColumns似乎是为了完成。

    也许你应该分别打印行,让ConsoleReader给他们添加换行符?从技术上讲,LF是一个控制代码,禁止ConsoleReader按原样打印控制代码是有意义的。只需将您的输入分成几行,逐一打印出来。

    +0

    我已经使用外部'PrintWriter'来临时解决'^ J'问题。然而,比'^ J'更奇怪的东西。我输入''激活'Completer',但它显示标签,当我按下Enter时,它显示完整列表,然后显示“Command not recognized:xxx”。我输入''箭头来获得我的最后一个命令,它显示'^ [[A',当我击中''时,它执行我的最后一个命令,但是我失去了我的命令行编辑 –