Skip to content

Terminals

mattirn edited this page Aug 29, 2020 · 10 revisions

JLine provides a terminal abstraction using the Terminal interface which provides the following features:

  • Signals support
  • Input stream, output stream, non blocking reader, writer
  • Tty size and parameters
  • Infocmp capabilities

There are two different types of terminals

  • System terminals that handle an OS terminal window
  • Virtual terminals to support incoming connections

System terminals

There is only a single system terminal for a given JVM, the one that has been used to launch the JVM. The terminal is the same terminal which is accessible using the Console JDK API.

The easiest way to obtain such a Terminal object in JLine is by using the TerminalBuilder class:

  Terminal terminal = TerminalBuilder.terminal();

or

  Terminal terminal = TerminalBuilder.builder()
                          .system(true)
                          .build();

The TerminalBuilder will figure out the current Operating System and which actual Terminal implementation to use. Note that on the Windows platform you need to have either Jansi or JNA library in your classpath.

The builder can be further customised in particular to handle signals, see Signal support and Infocmp terminal type. Terminal type can be customized using environment variable TERM. JLine has available the following terminal types:

OS/Terminal Infocmp terminal type
ANSI ansi
Dumb dumb, dumb-color
rxvt rxvt, rxvt-basic, rxvt-unicode, rxvt-unicode-256color
Screen screen, screen-256color
Windows/ConEmu windows-conemu
Windows/cmd windows, windows-256color, windows-vtp
xterm xterm, xterm-256color

Virtual terminals

Virtual terminals are used when there's no OS terminal to wrap. A common use case is when setting up some kind of server with SSH or Telnet support. Each incoming connection will need a virtual terminal.

Those terminals can be created using the following pattern:

  Terminal terminal = TerminalBuilder.builder()
                          .system(false)
                          .streams(input, output)
                          .build();

The builder can also be given the initial size and attributes of the terminal if they are known:

  int columns = ...;
  int rows = ...;
  Attributes attributes = new Attributes();
  // set attributes...
  Terminal terminal = TerminalBuilder.builder()
                          .system(false)
                          .streams(input, output)
                          .size(new Size(columns, rows))
                          .attributes(attributes)
                          .build();

Signal support

JLine terminals support signals. Signals can be raised and handled very easily.

System terminals can be built to intercept the native signals and forward them to the default handler.

  Terminal terminal = TerminalBuilder.builder()
                          .system(true)
                          .signalHandler(Terminal.SignalHandler.SIG_IGN)
                          .build();

The LineReader does support signals and handle them accordingly.

Terminal building options

Option System Virtual Description
name x x Name of the terminal, defaults to "JLine terminal"
type x x Infocmp type of the terminal, defaults to System.getenv("TERM")
encoding x x Encoding of the terminal, defaults to Charset.defaultCharset().name()
system x x Forces or prohibits the use of a system terminal
streams x Use the given streams for the input / output streams of the terminal
jna x x Allow or prohibits using JNA based terminals, defaults to wether the JNA library is available or not
dumb x Creates a dumb terminal if known terminals are not supported, else an exception is thrown
attributes x Initial attributes of the terminal
size x Initial size of the terminal
nativeSignals x Handle JVM signals from the system terminal through the created terminal
signalHandler x Default signal handler

Using terminals

TODO...