Class AbstractWindowsTerminal<Console>
- Type Parameters:
Console- the Windows console type used by the specific implementation
- All Implemented Interfaces:
Closeable,Flushable,AutoCloseable,TerminalExt,Terminal
- Direct Known Subclasses:
NativeWinSysTerminal
The AbstractWindowsTerminal class provides a foundation for terminal implementations on Windows operating systems. It addresses Windows-specific limitations and peculiarities, particularly related to console handling, character encoding, and ANSI sequence support.
Due to Windows limitations, particularly the historically limited support for ANSI sequences, this implementation uses Windows-specific APIs to handle terminal operations such as setting character attributes, moving the cursor, erasing content, and other terminal functions. This approach provides better compatibility and performance compared to emulating ANSI sequences on Windows.
UTF-8 support has also been historically problematic on Windows, with the code page meant to emulate UTF-8 being somewhat broken. To work around these issues, this implementation uses the Windows API WriteConsoleW directly. As a result, the writer() method becomes the primary output mechanism, while the output() stream is bridged to the writer using a WriterOutputStream wrapper.
Key features provided by this class include:
- Windows console API integration
- Color attribute handling
- Cursor positioning and manipulation
- Proper UTF-8 and Unicode support
- Input processing for Windows console events
This class is designed to be extended by concrete implementations that use specific Windows API access mechanisms (e.g., JNA, JNI, FFM).
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.jline.terminal.Terminal
Terminal.MouseTracking, Terminal.Signal, Terminal.SignalHandler -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected static final int[]ANSI colors mapping.protected final Attributesprotected static final intprotected static final intprotected static final intprotected static final intprotected final ShutdownHooks.Taskprotected static final intprotected static final intprotected static final intprotected static final intprotected static final intprotected static final intprotected static final intstatic final intprotected static final intprotected booleanprotected static final intprotected static final intprotected static final intprotected static final intprotected final Consoleprotected final NonBlockingInputStreamprotected final Objectprotected final Map<Terminal.Signal, Object> protected final intprotected final intprotected final Consoleprotected final OutputStreamprotected booleanprotected Threadprotected final NonBlockingReaderprotected booleanprotected final Writerprotected Terminal.MouseTrackingstatic final Stringstatic final Stringstatic final Stringstatic final Stringprotected final PrintWriterFields inherited from class org.jline.terminal.impl.AbstractTerminal
bools, currentMouseTracking, encoding, handlers, ints, name, onClose, palette, status, strings, typeFields inherited from interface org.jline.terminal.Terminal
TYPE_DUMB, TYPE_DUMB_COLOR -
Constructor Summary
ConstructorsConstructorDescriptionAbstractWindowsTerminal(TerminalProvider provider, SystemStream systemStream, Writer writer, String name, String type, Charset encoding, boolean nativeSignals, Terminal.SignalHandler signalHandler, Console inConsole, int inConsoleMode, Console outConsole, int outConsoleMode) -
Method Summary
Modifier and TypeMethodDescriptionbooleanWhether this terminal supportsTerminal.pause()andTerminal.resume()calls.protected intconvertAttributeToRgb(int attribute, boolean foreground) Convert Windows console attribute to RGB color.protected intctrl(char key) protected voiddoClose()Returns the current terminal attributes.protected abstract intgetConsoleMode(Console console) abstract intGet the default background color for Windows terminals.abstract intGet the default foreground color for Windows terminals.protected StringgetEscapeSequence(short keyCode, int keyState) Returns the terminal provider that created this terminal.protected StringReturns the system stream associated with this terminal, if any.handle(Terminal.Signal signal, Terminal.SignalHandler handler) Registers a handler for the givenTerminal.Signal.booleanReturns whether the terminal has support for focus tracking.input()Retrieve the input stream for this terminal.output()Retrieve the output stream for this terminal.voidpause()Temporarily stops reading the input stream.voidpause(boolean wait) Stop reading the input stream and optionally wait for the underlying threads to finish.booleanpaused()Check whether the terminal is currently reading the input stream or not.protected abstract booleanRead a single input event from the input buffer and process it.voidprocessInputChar(char c) protected voidprocessKeyEvent(boolean isKeyDown, short virtualKeyCode, char ch, int controlKeyState) protected voidpump()reader()Retrieve theReaderfor this terminal.voidresume()Resumes reading the input stream after it has been paused.voidsetAttributes(Attributes attr) Sets the terminal attributes to the specified values.protected abstract voidsetConsoleMode(Console console, int mode) voidSets the size of the terminal.booleantrackFocus(boolean tracking) Enables or disables focus tracking mode.booleantrackMouse(Terminal.MouseTracking tracking) Enables or disables mouse tracking with the specified mode.protected voidwriter()Retrieve theWriterfor this terminal.Methods inherited from class org.jline.terminal.impl.AbstractTerminal
checkInterrupted, close, echo, echo, echoSignal, encoding, enterRawMode, flush, getBooleanCapability, getCurrentMouseTracking, getCursorPosition, getKind, getName, getNumericCapability, getPalette, getStatus, getStatus, getStringCapability, getType, hasMouseSupport, parseInfoCmp, puts, raise, readMouseEvent, readMouseEvent, readMouseEvent, readMouseEvent, setOnClose, toStringMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.jline.terminal.Terminal
getBufferSize, getHeight, getSize, getWidth
-
Field Details
-
TYPE_WINDOWS
- See Also:
-
TYPE_WINDOWS_256_COLOR
- See Also:
-
FOREGROUND_BLUE
protected static final int FOREGROUND_BLUE- See Also:
-
FOREGROUND_GREEN
protected static final int FOREGROUND_GREEN- See Also:
-
FOREGROUND_RED
protected static final int FOREGROUND_RED- See Also:
-
FOREGROUND_INTENSITY
protected static final int FOREGROUND_INTENSITY- See Also:
-
BACKGROUND_BLUE
protected static final int BACKGROUND_BLUE- See Also:
-
BACKGROUND_GREEN
protected static final int BACKGROUND_GREEN- See Also:
-
BACKGROUND_RED
protected static final int BACKGROUND_RED- See Also:
-
BACKGROUND_INTENSITY
protected static final int BACKGROUND_INTENSITY- See Also:
-
TYPE_WINDOWS_CONEMU
- See Also:
-
TYPE_WINDOWS_VTP
- See Also:
-
ENABLE_VIRTUAL_TERMINAL_PROCESSING
public static final int ENABLE_VIRTUAL_TERMINAL_PROCESSING- See Also:
-
ENABLE_PROCESSED_INPUT
protected static final int ENABLE_PROCESSED_INPUT- See Also:
-
ENABLE_LINE_INPUT
protected static final int ENABLE_LINE_INPUT- See Also:
-
ENABLE_ECHO_INPUT
protected static final int ENABLE_ECHO_INPUT- See Also:
-
ENABLE_WINDOW_INPUT
protected static final int ENABLE_WINDOW_INPUT- See Also:
-
ENABLE_MOUSE_INPUT
protected static final int ENABLE_MOUSE_INPUT- See Also:
-
ENABLE_INSERT_MODE
protected static final int ENABLE_INSERT_MODE- See Also:
-
ENABLE_QUICK_EDIT_MODE
protected static final int ENABLE_QUICK_EDIT_MODE- See Also:
-
ENABLE_EXTENDED_FLAGS
protected static final int ENABLE_EXTENDED_FLAGS- See Also:
-
slaveInputPipe
-
input
-
output
-
reader
-
writer
-
nativeHandlers
-
closer
-
attributes
-
inConsole
-
outConsole
-
originalInConsoleMode
protected final int originalInConsoleMode -
originalOutConsoleMode
protected final int originalOutConsoleMode -
lock
-
paused
protected boolean paused -
pump
-
tracking
-
focusTracking
protected boolean focusTracking -
skipNextLf
protected boolean skipNextLf -
ANSI_COLORS
protected static final int[] ANSI_COLORSANSI colors mapping.
-
-
Constructor Details
-
AbstractWindowsTerminal
public AbstractWindowsTerminal(TerminalProvider provider, SystemStream systemStream, Writer writer, String name, String type, Charset encoding, boolean nativeSignals, Terminal.SignalHandler signalHandler, Console inConsole, int inConsoleMode, Console outConsole, int outConsoleMode) throws IOException - Throws:
IOException
-
-
Method Details
-
handle
Description copied from interface:TerminalRegisters a handler for the givenTerminal.Signal.This method allows the application to specify custom behavior when a particular signal is raised. The handler's
Terminal.SignalHandler.handle(Signal)method will be called whenever the specified signal is raised.Note that the JVM does not easily allow catching the
Terminal.Signal.QUITsignal (Ctrl+\), which typically causes a thread dump to be displayed. This signal handling is mainly effective when connecting through an SSH socket to a virtual terminal.Example usage:
Terminal terminal = TerminalBuilder.terminal(); // Handle window resize events terminal.handle(Signal.WINCH, signal -> { Size size = terminal.getSize(); terminal.writer().println("\nTerminal resized to " + size.getColumns() + "x" + size.getRows()); terminal.flush(); }); // Ignore interrupt signal terminal.handle(Signal.INT, SignalHandler.SIG_IGN);- Specified by:
handlein interfaceTerminal- Overrides:
handlein classAbstractTerminal- Parameters:
signal- the signal to register a handler forhandler- the handler to be called when the signal is raised- Returns:
- the previous signal handler that was registered for this signal
- See Also:
-
reader
Description copied from interface:TerminalRetrieve theReaderfor this terminal. This is the standard way to read input from this terminal. The reader is non blocking.- Returns:
- The non blocking reader
-
writer
Description copied from interface:TerminalRetrieve theWriterfor this terminal. This is the standard way to write to this terminal.- Returns:
- The writer
-
input
Description copied from interface:TerminalRetrieve the input stream for this terminal. In some rare cases, there may be a need to access the terminal input stream directly. In the usual cases, use theTerminal.reader()instead.- Returns:
- The input stream
- See Also:
-
output
Description copied from interface:TerminalRetrieve the output stream for this terminal. In some rare cases, there may be a need to access the terminal output stream directly. In the usual cases, use theTerminal.writer()instead.- Returns:
- The output stream
- See Also:
-
getAttributes
Description copied from interface:TerminalReturns the current terminal attributes.Terminal attributes control various aspects of terminal behavior, including:
- Input processing - How input characters are processed (e.g., character mapping, parity checking)
- Output processing - How output characters are processed (e.g., newline translation)
- Control settings - Hardware settings like baud rate and character size
- Local settings - Terminal behavior settings like echo, canonical mode, and signal generation
- Control characters - Special characters like EOF, interrupt, and erase
The returned
Attributesobject is a copy of the terminal's current attributes and can be safely modified without affecting the terminal until it is applied usingTerminal.setAttributes(Attributes). This allows for making multiple changes to the attributes before applying them all at once.Example usage:
Terminal terminal = TerminalBuilder.terminal(); // Get current attributes Attributes attrs = terminal.getAttributes(); // Modify attributes attrs.setLocalFlag(LocalFlag.ECHO, false); // Disable echo attrs.setInputFlag(InputFlag.ICRNL, false); // Disable CR to NL mapping attrs.setControlChar(ControlChar.VMIN, 1); // Set minimum input to 1 character attrs.setControlChar(ControlChar.VTIME, 0); // Set timeout to 0 deciseconds // Apply modified attributes terminal.setAttributes(attrs);
- Returns:
- a copy of the terminal's current attributes
- See Also:
-
setAttributes
Description copied from interface:TerminalSets the terminal attributes to the specified values.This method applies the specified attributes to the terminal, changing its behavior according to the settings in the
Attributesobject. The terminal makes a copy of the provided attributes, so further modifications to theattrobject will not affect the terminal until this method is called again.Terminal attributes control various aspects of terminal behavior, including input and output processing, control settings, local settings, and special control characters. Changing these attributes allows for fine-grained control over how the terminal processes input and output.
Common attribute modifications include:
- Disabling echo for password input
- Enabling/disabling canonical mode for line-by-line or character-by-character input
- Disabling signal generation for custom handling of Ctrl+C and other control sequences
- Changing control characters like the interrupt character or end-of-file character
For convenience, the
Terminal.enterRawMode()method provides a pre-configured set of attributes suitable for full-screen interactive applications.Example usage:
Terminal terminal = TerminalBuilder.terminal(); // Save original attributes for later restoration Attributes originalAttrs = terminal.getAttributes(); try { // Create and configure new attributes Attributes attrs = new Attributes(originalAttrs); attrs.setLocalFlag(LocalFlag.ECHO, false); // Disable echo for password input attrs.setLocalFlag(LocalFlag.ICANON, false); // Disable canonical mode // Apply the new attributes terminal.setAttributes(attrs); // Use terminal with modified attributes... } finally { // Restore original attributes terminal.setAttributes(originalAttrs); }- Parameters:
attr- the attributes to apply to the terminal- See Also:
-
updateConsoleMode
protected void updateConsoleMode() -
ctrl
protected int ctrl(char key) -
setSize
Description copied from interface:TerminalSets the size of the terminal.This method attempts to resize the terminal to the specified dimensions. Note that not all terminals support resizing, and the actual size after this operation may differ from the requested size depending on terminal capabilities and constraints.
For virtual terminals or terminal emulators, this may update the internal size representation. For physical terminals, this may send appropriate escape sequences to adjust the viewable area.
- Parameters:
size- the new terminal size (columns and rows)- See Also:
-
doClose
- Overrides:
doClosein classAbstractTerminal- Throws:
IOException
-
processKeyEvent
protected void processKeyEvent(boolean isKeyDown, short virtualKeyCode, char ch, int controlKeyState) throws IOException - Throws:
IOException
-
getEscapeSequence
-
getRawSequence
-
hasFocusSupport
public boolean hasFocusSupport()Description copied from interface:TerminalReturns whether the terminal has support for focus tracking.Focus tracking allows the terminal to report when it gains or loses focus. This can be useful for applications that need to change their behavior or appearance based on whether they are currently in focus.
Not all terminals support focus tracking, so this method should be called before attempting to enable focus tracking with
Terminal.trackFocus(boolean).When focus tracking is enabled and supported, the terminal will send special escape sequences to the input stream when focus is gained ("\33[I") or lost ("\33[O"). Applications can detect these sequences to respond to focus changes.
Example usage:
Terminal terminal = TerminalBuilder.terminal(); if (terminal.hasFocusSupport()) { // Enable focus tracking terminal.trackFocus(true); // Now the application can detect focus changes // by looking for "\33[I" and "\33[O" in the input stream } else { System.out.println("Focus tracking not supported by this terminal"); }- Specified by:
hasFocusSupportin interfaceTerminal- Overrides:
hasFocusSupportin classAbstractTerminal- Returns:
trueif the terminal supports focus tracking,falseotherwise- See Also:
-
trackFocus
public boolean trackFocus(boolean tracking) Description copied from interface:TerminalEnables or disables focus tracking mode.Focus tracking allows applications to detect when the terminal window gains or loses focus. When focus tracking is enabled, the terminal will send special escape sequences to the input stream whenever the focus state changes:
- When the terminal gains focus: "\33[I" (ESC [ I)
- When the terminal loses focus: "\33[O" (ESC [ O)
Applications can monitor the input stream for these sequences to detect focus changes and respond accordingly, such as by changing the cursor appearance, pausing animations, or adjusting the display.
Not all terminals support focus tracking. Use
Terminal.hasFocusSupport()to check whether focus tracking is supported before enabling it.Example usage:
Terminal terminal = TerminalBuilder.terminal(); if (terminal.hasFocusSupport()) { // Enable focus tracking boolean enabled = terminal.trackFocus(true); if (enabled) { System.out.println("Focus tracking enabled"); // Set up input processing to detect focus change sequences } }- Specified by:
trackFocusin interfaceTerminal- Overrides:
trackFocusin classAbstractTerminal- Parameters:
tracking-trueto enable focus tracking,falseto disable it- Returns:
trueif focus tracking is supported and the operation succeeded,falseotherwise- See Also:
-
getDefaultForegroundColor
public abstract int getDefaultForegroundColor()Get the default foreground color for Windows terminals.- Specified by:
getDefaultForegroundColorin interfaceTerminal- Overrides:
getDefaultForegroundColorin classAbstractTerminal- Returns:
- the RGB value of the default foreground color, or -1 if not available
- See Also:
-
getDefaultBackgroundColor
public abstract int getDefaultBackgroundColor()Get the default background color for Windows terminals.- Specified by:
getDefaultBackgroundColorin interfaceTerminal- Overrides:
getDefaultBackgroundColorin classAbstractTerminal- Returns:
- the RGB value of the default background color, or -1 if not available
- See Also:
-
convertAttributeToRgb
protected int convertAttributeToRgb(int attribute, boolean foreground) Convert Windows console attribute to RGB color.- Parameters:
attribute- the Windows console attributeforeground- true for foreground color, false for background color- Returns:
- the RGB value of the color
-
canPauseResume
public boolean canPauseResume()Description copied from interface:TerminalWhether this terminal supportsTerminal.pause()andTerminal.resume()calls.- Specified by:
canPauseResumein interfaceTerminal- Overrides:
canPauseResumein classAbstractTerminal- Returns:
- whether this terminal supports
Terminal.pause()andTerminal.resume()calls. - See Also:
-
pause
public void pause()Description copied from interface:TerminalTemporarily stops reading the input stream.This method pauses the terminal's input processing, which can be useful when transferring control to a subprocess or when the terminal needs to be in a specific state for certain operations. While paused, the terminal will not process input or handle signals that would normally be triggered by special characters in the input stream.
This method returns immediately without waiting for the terminal to actually pause. To wait until the terminal has fully paused, use
Terminal.pause(boolean)with a value oftrue.Example usage:
Terminal terminal = TerminalBuilder.terminal(); // Pause terminal input processing before running a subprocess terminal.pause(); // Run subprocess that takes control of the terminal Process process = new ProcessBuilder("vim").inheritIO().start(); process.waitFor(); // Resume terminal input processing terminal.resume();- Specified by:
pausein interfaceTerminal- Overrides:
pausein classAbstractTerminal- See Also:
-
pause
Description copied from interface:TerminalStop reading the input stream and optionally wait for the underlying threads to finish.- Specified by:
pausein interfaceTerminal- Overrides:
pausein classAbstractTerminal- Parameters:
wait-trueto wait until the terminal is actually paused- Throws:
InterruptedException- if the call has been interrupted
-
resume
public void resume()Description copied from interface:TerminalResumes reading the input stream after it has been paused.This method restarts the terminal's input processing after it has been temporarily stopped using
Terminal.pause()orTerminal.pause(boolean). Once resumed, the terminal will continue to process input and handle signals triggered by special characters in the input stream.Calling this method when the terminal is not paused has no effect.
Example usage:
Terminal terminal = TerminalBuilder.terminal(); // Pause terminal input processing terminal.pause(); // Perform operations while terminal input is paused... // Resume terminal input processing terminal.resume();
- Specified by:
resumein interfaceTerminal- Overrides:
resumein classAbstractTerminal- See Also:
-
paused
public boolean paused()Description copied from interface:TerminalCheck whether the terminal is currently reading the input stream or not. In order to process signal as quickly as possible, the terminal need to read the input stream and buffer it internally so that it can detect specific characters in the input stream (Ctrl+C, Ctrl+D, etc...) and raise the appropriate signals. However, there are some cases where this processing should be disabled, for example when handing the terminal control to a subprocess.- Specified by:
pausedin interfaceTerminal- Overrides:
pausedin classAbstractTerminal- Returns:
- whether the terminal is currently reading the input stream or not
- See Also:
-
pump
protected void pump() -
processInputChar
- Throws:
IOException
-
trackMouse
Description copied from interface:TerminalEnables or disables mouse tracking with the specified mode.This method configures the terminal to report mouse events according to the specified tracking mode. When mouse tracking is enabled, the terminal will send special escape sequences to the input stream whenever mouse events occur. These sequences begin with the
InfoCmp.Capability.key_mousesequence, followed by data that describes the specific mouse event.The tracking mode determines which mouse events are reported:
Terminal.MouseTracking.Off- Disables mouse trackingTerminal.MouseTracking.Normal- Reports button press and release eventsTerminal.MouseTracking.Button- Reports button press, release, and motion events while buttons are pressedTerminal.MouseTracking.Any- Reports all mouse events, including movement without buttons pressed
To process mouse events, applications should:
- Enable mouse tracking by calling this method with the desired mode
- Monitor the input stream for the
InfoCmp.Capability.key_mousesequence - When this sequence is detected, call
Terminal.readMouseEvent()to decode the event - Process the returned
MouseEventas needed
Example usage:
Terminal terminal = TerminalBuilder.terminal(); if (terminal.hasMouseSupport()) { // Enable tracking of all mouse events boolean supported = terminal.trackMouse(MouseTracking.Any); if (supported) { System.out.println("Mouse tracking enabled"); // Set up input processing to detect and handle mouse events } }- Specified by:
trackMousein interfaceTerminal- Overrides:
trackMousein classAbstractTerminal- Parameters:
tracking- the mouse tracking mode to enable, orTerminal.MouseTracking.Offto disable tracking- Returns:
trueif the requested mouse tracking mode is supported,falseotherwise- See Also:
-
getConsoleMode
-
setConsoleMode
-
processConsoleInput
Read a single input event from the input buffer and process it.- Returns:
- true if new input was generated from the event
- Throws:
IOException- if anything wrong happens
-
getProvider
Description copied from interface:TerminalExtReturns the terminal provider that created this terminal.The terminal provider is responsible for creating and managing terminal instances on a specific platform. This method allows access to the provider that created this terminal, which can be useful for accessing provider-specific functionality or for creating additional terminals with the same provider.
- Returns:
- the
TerminalProviderthat created this terminal, ornullif the terminal was created with no provider - See Also:
-
getSystemStream
Description copied from interface:TerminalExtReturns the system stream associated with this terminal, if any.This method indicates whether the terminal is bound to a standard system stream (standard input, standard output, or standard error). Terminals that are connected to system streams typically represent the actual terminal window or console that the application is running in.
- Returns:
- the underlying system stream, which may be
SystemStream.Input,SystemStream.Output,SystemStream.Error, ornullif this terminal is not bound to a system stream - See Also:
-