如何在scala中编写支持readline的交互式shell?
我想用scala编写交互式shell,支持readline(Ctrl-l、箭头键、行编辑、历史记录等) 我知道如何在python中实现这一点:如何在scala中编写支持readline的交互式shell?,shell,scala,interactive,readline,Shell,Scala,Interactive,Readline,我想用scala编写交互式shell,支持readline(Ctrl-l、箭头键、行编辑、历史记录等) 我知道如何在python中实现这一点: # enable support for Ctrl-l, arrow keys, line editing, history, etc. import readline finished = False while not finished: try: line = raw_input('> ') if line:
# enable support for Ctrl-l, arrow keys, line editing, history, etc.
import readline
finished = False
while not finished:
try:
line = raw_input('> ')
if line:
if line == 'q':
finished = True
else:
print line
except KeyboardInterrupt:
print 'Ctrl-c'; finished = True
except EOFError:
print 'Ctrl-d'; finished = True
我想编写一个简单的scala程序,其行为与完全相同。到目前为止,我最接近的解决方案是以下scala:
// used to support Ctrl-l, arrow keys, line editing, history, etc.
import scala.tools.jline
val consoleReader = new jline.console.ConsoleReader()
var finished = false
while (!finished) {
val line = consoleReader.readLine("> ")
if (line == null) {
println("Ctrl-d")
finished = true
} else if (line.size > 0) {
if (line == "q") {
finished = true
} else {
println(line)
}
}
}
开放性问题包括:
- 如何处理ctrl-c
- 是否可以以类似于python的方式使用异常
- 这是最佳解决方案还是可以改进
jline
事件的层次结构,例如:
sealed trait JLineEvent
case class Line(value: String) extends JLineEvent
case object EmptyLine extends JLineEvent
case object EOF extends JLineEvent
然后,您可以将while
循环封装在一个函数中,该函数的参数为JLineEvent
:
def console( handler: JLineEvent => Boolean ) {
val consoleReader = new jline.console.ConsoleReader()
var finished = false
while (!finished) {
val line = consoleReader.readLine("> ")
if (line == null) {
finished = handler( EOF )
} else if (line.size == 0) {
finished = handler( EmptyLine )
} else if (line.size > 0) {
finished = handler( Line( line ) )
}
}
最后,您可以使用适当的函数调用它:
console {
case EOF =>
println("Ctrl-d")
true
case Line(s) if s == "q" =>
true
case Line(s) =>
println(line)
false
case _ =>
false
}
对于捕获ctrl+C
,关闭挂钩可能是一种解决方案