From aaa90b3005c85852971203ce6feb88e7091e167b Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 9 May 2024 13:54:04 +0000 Subject: [PATCH] 8327476: Upgrade JLine to 3.26.1 Reviewed-by: ihse, vromero --- make/conf/module-loader-map.conf | 1 + make/modules/jdk.internal.le/Lib.gmk | 45 - .../jline/terminal/impl/jna/JDKNativePty.java | 50 - .../jline/terminal/impl/jna/JDKNativePty.java | 51 - .../terminal/impl/jna/linux/CLibrary.java | 389 ------ .../terminal/impl/jna/linux/CLibraryImpl.java | 61 - .../impl/jna/linux/LinuxNativePty.java | 122 -- .../impl/jna/linux/UtilLibraryImpl.java | 37 - .../linux/native/lible/CLibrary.cpp | 207 --- .../jline/terminal/impl/jna/JDKNativePty.java | 51 - .../jline/terminal/impl/jna/osx/CLibrary.java | 394 ------ .../terminal/impl/jna/osx/CLibraryImpl.java | 66 - .../terminal/impl/jna/osx/NativeLong.java | 43 - .../terminal/impl/jna/osx/OsXNativePty.java | 106 -- .../macosx/native/lible/CLibrary.cpp | 211 --- .../org/jline/keymap/BindingReader.java | 8 +- .../jdk/internal/org/jline/keymap/KeyMap.java | 11 +- .../internal/org/jline/reader/Binding.java | 7 +- .../jdk/internal/org/jline/reader/Buffer.java | 10 +- .../internal/org/jline/reader/Candidate.java | 20 +- .../internal/org/jline/reader/Completer.java | 5 +- .../jline/reader/CompletingParsedLine.java | 5 +- .../org/jline/reader/CompletionMatcher.java | 12 +- .../internal/org/jline/reader/EOFError.java | 20 +- .../jdk/internal/org/jline/reader/Editor.java | 4 +- .../org/jline/reader/EndOfFileException.java | 5 +- .../internal/org/jline/reader/Expander.java | 3 +- .../org/jline/reader/Highlighter.java | 2 +- .../internal/org/jline/reader/History.java | 12 +- .../internal/org/jline/reader/LineReader.java | 53 +- .../org/jline/reader/LineReaderBuilder.java | 11 +- .../jdk/internal/org/jline/reader/Macro.java | 5 +- .../org/jline/reader/MaskingCallback.java | 3 +- .../internal/org/jline/reader/ParsedLine.java | 3 +- .../jdk/internal/org/jline/reader/Parser.java | 6 +- .../org/jline/reader/PrintAboveWriter.java | 2 +- .../internal/org/jline/reader/Reference.java | 5 +- .../org/jline/reader/SyntaxError.java | 18 +- .../jline/reader/UserInterruptException.java | 12 +- .../jdk/internal/org/jline/reader/Widget.java | 3 +- .../org/jline/reader/impl/BufferImpl.java | 15 +- .../reader/impl/CompletionMatcherImpl.java | 83 +- .../jline/reader/impl/DefaultExpander.java | 33 +- .../jline/reader/impl/DefaultHighlighter.java | 8 +- .../org/jline/reader/impl/DefaultParser.java | 144 +- .../org/jline/reader/impl/InputRC.java | 394 ++++++ .../org/jline/reader/impl/KillRing.java | 2 +- .../org/jline/reader/impl/LineReaderImpl.java | 1200 ++++++++++------- .../org/jline/reader/impl/ReaderUtils.java | 8 +- .../reader/impl/SimpleMaskingCallback.java | 9 +- .../org/jline/reader/impl/UndoTree.java | 4 +- .../impl/completer/AggregateCompleter.java | 11 +- .../impl/completer/ArgumentCompleter.java | 11 +- .../reader/impl/completer/EnumCompleter.java | 5 +- .../impl/completer/FileNameCompleter.java | 20 +- .../reader/impl/completer/NullCompleter.java | 9 +- .../impl/completer/StringsCompleter.java | 7 +- .../impl/completer/SystemCompleter.java | 27 +- .../reader/impl/history/DefaultHistory.java | 77 +- .../org/jline/terminal/Attributes.java | 146 +- .../internal/org/jline/terminal/Cursor.java | 2 +- .../org/jline/terminal/MouseEvent.java | 15 +- .../jdk/internal/org/jline/terminal/Size.java | 8 +- .../internal/org/jline/terminal/Terminal.java | 59 +- .../org/jline/terminal/TerminalBuilder.java | 608 ++++++--- .../terminal/impl/AbstractPosixTerminal.java | 16 +- .../org/jline/terminal/impl/AbstractPty.java | 164 ++- .../jline/terminal/impl/AbstractTerminal.java | 39 +- .../impl/AbstractWindowsConsoleWriter.java | 9 +- .../impl/AbstractWindowsTerminal.java | 158 ++- .../jline/terminal/impl/CursorSupport.java | 13 +- .../org/jline/terminal/impl/Diag.java | 64 +- .../org/jline/terminal/impl/DumbTerminal.java | 69 +- .../terminal/impl/DumbTerminalProvider.java | 92 ++ .../jline/terminal/impl/ExternalTerminal.java | 81 +- .../terminal/impl/LineDisciplineTerminal.java | 132 +- .../org/jline/terminal/impl/MouseSupport.java | 22 +- .../terminal/impl/NativeSignalHandler.java | 5 +- .../jline/terminal/impl/PosixPtyTerminal.java | 34 +- .../jline/terminal/impl/PosixSysTerminal.java | 16 +- .../terminal/impl/{ => exec}/ExecPty.java | 111 +- .../impl/exec/ExecTerminalProvider.java | 228 +++- .../org/jline/terminal/impl/ffm/CLibrary.java | 1170 ++++++++++++++++ .../jline/terminal/impl/ffm/FfmNativePty.java | 175 +++ .../impl/ffm/FfmTerminalProvider.java | 133 ++ .../org/jline/terminal/impl/ffm/Kernel32.java | 927 +++++++++++++ .../impl/ffm/NativeWinConsoleWriter.java | 35 + .../impl/ffm/NativeWinSysTerminal.java | 302 +++++ .../terminal/impl/ffm/WindowsAnsiWriter.java | 407 ++++++ .../terminal/impl/jna/LastErrorException.java | 36 - .../internal/org/jline/terminal/spi/Pty.java | 5 +- .../org/jline/terminal/spi/SystemStream.java | 15 + .../org/jline/terminal/spi/TerminalExt.java | 31 + .../jline/terminal/spi/TerminalProvider.java | 67 +- .../internal/org/jline/utils/AnsiWriter.java | 155 +-- .../jline/utils/AttributedCharSequence.java | 40 +- .../org/jline/utils/AttributedString.java | 33 +- .../jline/utils/AttributedStringBuilder.java | 129 +- .../org/jline/utils/AttributedStyle.java | 88 +- .../org/jline/utils/ClosedException.java | 5 +- .../org/jline/utils/ColorPalette.java | 25 +- .../jdk/internal/org/jline/utils/Colors.java | 165 ++- .../jdk/internal/org/jline/utils/Curses.java | 33 +- .../internal/org/jline/utils/DiffHelper.java | 39 +- .../jdk/internal/org/jline/utils/Display.java | 98 +- .../internal/org/jline/utils/ExecHelper.java | 8 +- .../jline/utils/FastBufferedOutputStream.java | 61 + .../jdk/internal/org/jline/utils/InfoCmp.java | 968 ++++++------- .../org/jline/utils/InputStreamReader.java | 32 +- .../internal/org/jline/utils/Levenshtein.java | 8 +- .../jdk/internal/org/jline/utils/Log.java | 11 +- .../internal/org/jline/utils/NonBlocking.java | 21 +- .../jline/utils/NonBlockingInputStream.java | 8 +- .../utils/NonBlockingInputStreamImpl.java | 40 +- .../utils/NonBlockingPumpInputStream.java | 12 +- .../jline/utils/NonBlockingPumpReader.java | 9 +- .../org/jline/utils/NonBlockingReader.java | 6 +- .../jline/utils/NonBlockingReaderImpl.java | 47 +- .../jdk/internal/org/jline/utils/OSUtils.java | 122 +- .../internal/org/jline/utils/PumpReader.java | 5 +- .../org/jline/utils/ShutdownHooks.java | 17 +- .../jdk/internal/org/jline/utils/Signals.java | 13 +- .../jdk/internal/org/jline/utils/Status.java | 295 ++-- .../org/jline/utils/StyleResolver.java | 14 +- .../jdk/internal/org/jline/utils/Timeout.java | 3 +- .../jdk/internal/org/jline/utils/WCWidth.java | 159 ++- .../org/jline/utils/WriterOutputStream.java | 12 +- .../org/jline/utils/windows-conemu.caps | 3 + src/jdk.internal.le/share/legal/jline.md | 4 +- .../jline/terminal/impl/jna/JnaNativePty.java | 204 --- .../impl/jna/JnaTerminalProvider.java | 105 -- .../impl/jna/JnaTerminalProvider.java | 106 -- .../terminal/impl/jna/win/IntByReference.java | 35 - .../impl/jna/win/JnaWinConsoleWriter.java | 37 - .../impl/jna/win/JnaWinSysTerminal.java | 228 ---- .../jline/terminal/impl/jna/win/Kernel32.java | 634 --------- .../terminal/impl/jna/win/Kernel32Impl.java | 85 -- .../jline/terminal/impl/jna/win/Pointer.java | 34 - .../impl/jna/win/WindowsAnsiWriter.java | 353 ----- .../windows/native/lible/Kernel32.cpp | 710 ---------- .../jline/AbstractWindowsTerminalTest.java | 14 +- .../jdk/internal/jline/KeyConversionTest.java | 13 +- .../jdk/jshell/ExecPtyGetFlagsToSetTest.java | 11 +- 143 files changed, 7616 insertions(+), 7181 deletions(-) delete mode 100644 make/modules/jdk.internal.le/Lib.gmk delete mode 100644 src/jdk.internal.le/aix/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java delete mode 100644 src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java delete mode 100644 src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibrary.java delete mode 100644 src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibraryImpl.java delete mode 100644 src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/LinuxNativePty.java delete mode 100644 src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/UtilLibraryImpl.java delete mode 100644 src/jdk.internal.le/linux/native/lible/CLibrary.cpp delete mode 100644 src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java delete mode 100644 src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary.java delete mode 100644 src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibraryImpl.java delete mode 100644 src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/NativeLong.java delete mode 100644 src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/OsXNativePty.java delete mode 100644 src/jdk.internal.le/macosx/native/lible/CLibrary.cpp create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/InputRC.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminalProvider.java rename src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/{ => exec}/ExecPty.java (71%) create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/CLibrary.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmNativePty.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmTerminalProvider.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinConsoleWriter.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/WindowsAnsiWriter.java delete mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/jna/LastErrorException.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/SystemStream.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalExt.java create mode 100644 src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/FastBufferedOutputStream.java delete mode 100644 src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaNativePty.java delete mode 100644 src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/IntByReference.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32Impl.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Pointer.java delete mode 100644 src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java delete mode 100644 src/jdk.internal.le/windows/native/lible/Kernel32.cpp diff --git a/make/conf/module-loader-map.conf b/make/conf/module-loader-map.conf index 5b72bf78aa0..e904031186d 100644 --- a/make/conf/module-loader-map.conf +++ b/make/conf/module-loader-map.conf @@ -120,6 +120,7 @@ NATIVE_ACCESS_MODULES= \ jdk.dynalink \ jdk.httpserver \ jdk.incubator.vector \ + jdk.internal.le \ jdk.internal.vm.ci \ jdk.jfr \ jdk.jsobject \ diff --git a/make/modules/jdk.internal.le/Lib.gmk b/make/modules/jdk.internal.le/Lib.gmk deleted file mode 100644 index e81137e0d53..00000000000 --- a/make/modules/jdk.internal.le/Lib.gmk +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -include LibCommon.gmk - -ifeq ($(call isTargetOs, aix), false) - ############################################################################## - ## Build lible - ############################################################################## - - $(eval $(call SetupJdkLibrary, BUILD_LIBLE, \ - NAME := le, \ - LINK_TYPE := C++, \ - OPTIMIZATION := LOW, \ - EXTRA_HEADER_DIRS := \ - java.base:libjava \ - java.base:libjvm, \ - LD_SET_ORIGIN := false, \ - LIBS_windows := user32.lib, \ - )) - - TARGETS += $(BUILD_LIBLE) -endif diff --git a/src/jdk.internal.le/aix/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java b/src/jdk.internal.le/aix/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java deleted file mode 100644 index fe5e10e7e5d..00000000000 --- a/src/jdk.internal.le/aix/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna; - -import java.io.IOException; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.spi.TerminalProvider; - -class JDKNativePty { - - static JnaNativePty current(TerminalProvider.Stream console) throws IOException { - throw new UnsupportedOperationException("Not supported."); - } - - static JnaNativePty open(Attributes attr, Size size) throws IOException { - throw new UnsupportedOperationException("Not supported."); - } - - static int isatty(int fd) { - throw new UnsupportedOperationException("Not supported."); - } - - static String ttyname(int fd) { - throw new UnsupportedOperationException("Not supported."); - } - -} diff --git a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java b/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java deleted file mode 100644 index 199e80d9dde..00000000000 --- a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna; - -import java.io.IOException; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.impl.jna.linux.LinuxNativePty; -import jdk.internal.org.jline.terminal.spi.TerminalProvider; - -class JDKNativePty { - - static JnaNativePty current(TerminalProvider.Stream console) throws IOException { - return LinuxNativePty.current(console); - } - - static JnaNativePty open(Attributes attr, Size size) throws IOException { - return LinuxNativePty.open(attr, size); - } - - static int isatty(int fd) { - return LinuxNativePty.isatty(fd); - } - - static String ttyname(int fd) { - return LinuxNativePty.ttyname(fd); - } - -} diff --git a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibrary.java b/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibrary.java deleted file mode 100644 index 5a3a43c6f5e..00000000000 --- a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibrary.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.impl.jna.linux; - -import java.util.Arrays; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.List; - -//import com.sun.jna.LastErrorException; -//import com.sun.jna.Platform; -//import com.sun.jna.Structure; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Attributes.ControlChar; -import jdk.internal.org.jline.terminal.Attributes.ControlFlag; -import jdk.internal.org.jline.terminal.Attributes.InputFlag; -import jdk.internal.org.jline.terminal.Attributes.LocalFlag; -import jdk.internal.org.jline.terminal.Attributes.OutputFlag; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; - -public interface CLibrary {//extends com.sun.jna.Library { - - void tcgetattr(int fd, termios termios) throws LastErrorException; - - void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; - - void ioctl(int fd, int cmd, winsize data) throws LastErrorException; - - int isatty(int fd); - - void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; - - class winsize { //extends Structure { - public short ws_row; - public short ws_col; - public short ws_xpixel; - public short ws_ypixel; - - public winsize() { - } - - public winsize(Size ws) { - ws_row = (short) ws.getRows(); - ws_col = (short) ws.getColumns(); - } - - public Size toSize() { - return new Size(ws_col, ws_row); - } - -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(// -// "ws_row",// -// "ws_col",// -// "ws_xpixel",// -// "ws_ypixel"// -// ); -// } - - } - - class termios {// extends Structure { - - public int c_iflag; - public int c_oflag; - public int c_cflag; - public int c_lflag; - public byte c_line; - public byte[] c_cc = new byte[32]; - public int c_ispeed; - public int c_ospeed; - -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(// -// "c_iflag",// -// "c_oflag",// -// "c_cflag",// -// "c_lflag",// -// "c_line",// -// "c_cc",// -// "c_ispeed",// -// "c_ospeed"// -// ); -// } - - public termios() { - } - - public termios(Attributes t) { - // Input flags - c_iflag = setFlag(t.getInputFlag(InputFlag.IGNBRK), IGNBRK, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.BRKINT), BRKINT, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IGNPAR), IGNPAR, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.PARMRK), PARMRK, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.INPCK), INPCK, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.ISTRIP), ISTRIP, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.INLCR), INLCR, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IGNCR), IGNCR, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.ICRNL), ICRNL, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IXON), IXON, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IXOFF), IXOFF, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IXANY), IXANY, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IMAXBEL), IMAXBEL, c_iflag); - c_iflag = setFlag(t.getInputFlag(InputFlag.IUTF8), IUTF8, c_iflag); - // Output flags - c_oflag = setFlag(t.getOutputFlag(OutputFlag.OPOST), OPOST, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLCR), ONLCR, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.OCRNL), OCRNL, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONOCR), ONOCR, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLRET), ONLRET, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.OFILL), OFILL, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.NLDLY), NLDLY, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.TABDLY), TABDLY, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.CRDLY), CRDLY, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.FFDLY), FFDLY, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.BSDLY), BSDLY, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.VTDLY), VTDLY, c_oflag); - c_oflag = setFlag(t.getOutputFlag(OutputFlag.OFDEL), OFDEL, c_oflag); - // Control flags - c_cflag = setFlag(t.getControlFlag(ControlFlag.CS5), CS5, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.CS6), CS6, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.CS7), CS7, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.CS8), CS8, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.CSTOPB), CSTOPB, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.CREAD), CREAD, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.PARENB), PARENB, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.PARODD), PARODD, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.HUPCL), HUPCL, c_cflag); - c_cflag = setFlag(t.getControlFlag(ControlFlag.CLOCAL), CLOCAL, c_cflag); - // Local flags - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOKE), ECHOKE, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOE), ECHOE, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOK), ECHOK, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHO), ECHO, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHONL), ECHONL, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOPRT), ECHOPRT, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOCTL), ECHOCTL, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ISIG), ISIG, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.ICANON), ICANON, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.EXTPROC), EXTPROC, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.TOSTOP), TOSTOP, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.FLUSHO), FLUSHO, c_lflag); - c_lflag = setFlag(t.getLocalFlag(LocalFlag.NOFLSH), NOFLSH, c_lflag); - // Control chars - c_cc[VEOF] = (byte) t.getControlChar(ControlChar.VEOF); - c_cc[VEOL] = (byte) t.getControlChar(ControlChar.VEOL); - c_cc[VEOL2] = (byte) t.getControlChar(ControlChar.VEOL2); - c_cc[VERASE] = (byte) t.getControlChar(ControlChar.VERASE); - c_cc[VWERASE] = (byte) t.getControlChar(ControlChar.VWERASE); - c_cc[VKILL] = (byte) t.getControlChar(ControlChar.VKILL); - c_cc[VREPRINT] = (byte) t.getControlChar(ControlChar.VREPRINT); - c_cc[VINTR] = (byte) t.getControlChar(ControlChar.VINTR); - c_cc[VQUIT] = (byte) t.getControlChar(ControlChar.VQUIT); - c_cc[VSUSP] = (byte) t.getControlChar(ControlChar.VSUSP); - c_cc[VSTART] = (byte) t.getControlChar(ControlChar.VSTART); - c_cc[VSTOP] = (byte) t.getControlChar(ControlChar.VSTOP); - c_cc[VLNEXT] = (byte) t.getControlChar(ControlChar.VLNEXT); - c_cc[VDISCARD] = (byte) t.getControlChar(ControlChar.VDISCARD); - c_cc[VMIN] = (byte) t.getControlChar(ControlChar.VMIN); - c_cc[VTIME] = (byte) t.getControlChar(ControlChar.VTIME); - } - - private int setFlag(boolean flag, int value, int org) { - return flag ? (org | value) : org; - } - - public Attributes toAttributes() { - Attributes attr = new Attributes(); - // Input flags - EnumSet iflag = attr.getInputFlags(); - addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); - addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); - addFlag(c_iflag, iflag, InputFlag.BRKINT, BRKINT); - addFlag(c_iflag, iflag, InputFlag.IGNPAR, IGNPAR); - addFlag(c_iflag, iflag, InputFlag.PARMRK, PARMRK); - addFlag(c_iflag, iflag, InputFlag.INPCK, INPCK); - addFlag(c_iflag, iflag, InputFlag.ISTRIP, ISTRIP); - addFlag(c_iflag, iflag, InputFlag.INLCR, INLCR); - addFlag(c_iflag, iflag, InputFlag.IGNCR, IGNCR); - addFlag(c_iflag, iflag, InputFlag.ICRNL, ICRNL); - addFlag(c_iflag, iflag, InputFlag.IXON, IXON); - addFlag(c_iflag, iflag, InputFlag.IXOFF, IXOFF); - addFlag(c_iflag, iflag, InputFlag.IXANY, IXANY); - addFlag(c_iflag, iflag, InputFlag.IMAXBEL, IMAXBEL); - addFlag(c_iflag, iflag, InputFlag.IUTF8, IUTF8); - // Output flags - EnumSet oflag = attr.getOutputFlags(); - addFlag(c_oflag, oflag, OutputFlag.OPOST, OPOST); - addFlag(c_oflag, oflag, OutputFlag.ONLCR, ONLCR); - addFlag(c_oflag, oflag, OutputFlag.OCRNL, OCRNL); - addFlag(c_oflag, oflag, OutputFlag.ONOCR, ONOCR); - addFlag(c_oflag, oflag, OutputFlag.ONLRET, ONLRET); - addFlag(c_oflag, oflag, OutputFlag.OFILL, OFILL); - addFlag(c_oflag, oflag, OutputFlag.NLDLY, NLDLY); - addFlag(c_oflag, oflag, OutputFlag.TABDLY, TABDLY); - addFlag(c_oflag, oflag, OutputFlag.CRDLY, CRDLY); - addFlag(c_oflag, oflag, OutputFlag.FFDLY, FFDLY); - addFlag(c_oflag, oflag, OutputFlag.BSDLY, BSDLY); - addFlag(c_oflag, oflag, OutputFlag.VTDLY, VTDLY); - addFlag(c_oflag, oflag, OutputFlag.OFDEL, OFDEL); - // Control flags - EnumSet cflag = attr.getControlFlags(); - addFlag(c_cflag, cflag, ControlFlag.CS5, CS5); - addFlag(c_cflag, cflag, ControlFlag.CS6, CS6); - addFlag(c_cflag, cflag, ControlFlag.CS7, CS7); - addFlag(c_cflag, cflag, ControlFlag.CS8, CS8); - addFlag(c_cflag, cflag, ControlFlag.CSTOPB, CSTOPB); - addFlag(c_cflag, cflag, ControlFlag.CREAD, CREAD); - addFlag(c_cflag, cflag, ControlFlag.PARENB, PARENB); - addFlag(c_cflag, cflag, ControlFlag.PARODD, PARODD); - addFlag(c_cflag, cflag, ControlFlag.HUPCL, HUPCL); - addFlag(c_cflag, cflag, ControlFlag.CLOCAL, CLOCAL); - // Local flags - EnumSet lflag = attr.getLocalFlags(); - addFlag(c_lflag, lflag, LocalFlag.ECHOKE, ECHOKE); - addFlag(c_lflag, lflag, LocalFlag.ECHOE, ECHOE); - addFlag(c_lflag, lflag, LocalFlag.ECHOK, ECHOK); - addFlag(c_lflag, lflag, LocalFlag.ECHO, ECHO); - addFlag(c_lflag, lflag, LocalFlag.ECHONL, ECHONL); - addFlag(c_lflag, lflag, LocalFlag.ECHOPRT, ECHOPRT); - addFlag(c_lflag, lflag, LocalFlag.ECHOCTL, ECHOCTL); - addFlag(c_lflag, lflag, LocalFlag.ISIG, ISIG); - addFlag(c_lflag, lflag, LocalFlag.ICANON, ICANON); - addFlag(c_lflag, lflag, LocalFlag.EXTPROC, EXTPROC); - addFlag(c_lflag, lflag, LocalFlag.TOSTOP, TOSTOP); - addFlag(c_lflag, lflag, LocalFlag.FLUSHO, FLUSHO); - addFlag(c_lflag, lflag, LocalFlag.NOFLSH, NOFLSH); - // Control chars - EnumMap cc = attr.getControlChars(); - cc.put(ControlChar.VEOF, (int) c_cc[VEOF]); - cc.put(ControlChar.VEOL, (int) c_cc[VEOL]); - cc.put(ControlChar.VEOL2, (int) c_cc[VEOL2]); - cc.put(ControlChar.VERASE, (int) c_cc[VERASE]); - cc.put(ControlChar.VWERASE, (int) c_cc[VWERASE]); - cc.put(ControlChar.VKILL, (int) c_cc[VKILL]); - cc.put(ControlChar.VREPRINT, (int) c_cc[VREPRINT]); - cc.put(ControlChar.VINTR, (int) c_cc[VINTR]); - cc.put(ControlChar.VQUIT, (int) c_cc[VQUIT]); - cc.put(ControlChar.VSUSP, (int) c_cc[VSUSP]); - cc.put(ControlChar.VSTART, (int) c_cc[VSTART]); - cc.put(ControlChar.VSTOP, (int) c_cc[VSTOP]); - cc.put(ControlChar.VLNEXT, (int) c_cc[VLNEXT]); - cc.put(ControlChar.VDISCARD, (int) c_cc[VDISCARD]); - cc.put(ControlChar.VMIN, (int) c_cc[VMIN]); - cc.put(ControlChar.VTIME, (int) c_cc[VTIME]); - // Return - return attr; - } - - private > void addFlag(int value, EnumSet flags, T flag, int v) { - if ((value & v) != 0) { - flags.add(flag); - } - } - } - - // CONSTANTS - - int TIOCGWINSZ = /*Platform.isMIPS() || Platform.isPPC() || Platform.isSPARC() ? 0x40087468 : */0x00005413; - int TIOCSWINSZ = /*Platform.isMIPS() || Platform.isPPC() || Platform.isSPARC() ? 0x80087467 : */0x00005414; - - int VINTR = 0; - int VQUIT = 1; - int VERASE = 2; - int VKILL = 3; - int VEOF = 4; - int VTIME = 5; - int VMIN = 6; - int VSWTC = 7; - int VSTART = 8; - int VSTOP = 9; - int VSUSP = 10; - int VEOL = 11; - int VREPRINT = 12; - int VDISCARD = 13; - int VWERASE = 14; - int VLNEXT = 15; - int VEOL2 = 16; - - int IGNBRK = 0x0000001; - int BRKINT = 0x0000002; - int IGNPAR = 0x0000004; - int PARMRK = 0x0000008; - int INPCK = 0x0000010; - int ISTRIP = 0x0000020; - int INLCR = 0x0000040; - int IGNCR = 0x0000080; - int ICRNL = 0x0000100; - int IUCLC = 0x0000200; - int IXON = 0x0000400; - int IXANY = 0x0000800; - int IXOFF = 0x0001000; - int IMAXBEL = 0x0002000; - int IUTF8 = 0x0004000; - - int OPOST = 0x0000001; - int OLCUC = 0x0000002; - int ONLCR = 0x0000004; - int OCRNL = 0x0000008; - int ONOCR = 0x0000010; - int ONLRET = 0x0000020; - int OFILL = 0x0000040; - int OFDEL = 0x0000080; - int NLDLY = 0x0000100; - int NL0 = 0x0000000; - int NL1 = 0x0000100; - int CRDLY = 0x0000600; - int CR0 = 0x0000000; - int CR1 = 0x0000200; - int CR2 = 0x0000400; - int CR3 = 0x0000600; - int TABDLY = 0x0001800; - int TAB0 = 0x0000000; - int TAB1 = 0x0000800; - int TAB2 = 0x0001000; - int TAB3 = 0x0001800; - int XTABS = 0x0001800; - int BSDLY = 0x0002000; - int BS0 = 0x0000000; - int BS1 = 0x0002000; - int VTDLY = 0x0004000; - int VT0 = 0x0000000; - int VT1 = 0x0004000; - int FFDLY = 0x0008000; - int FF0 = 0x0000000; - int FF1 = 0x0008000; - - int CBAUD = 0x000100f; - int B0 = 0x0000000; - int B50 = 0x0000001; - int B75 = 0x0000002; - int B110 = 0x0000003; - int B134 = 0x0000004; - int B150 = 0x0000005; - int B200 = 0x0000006; - int B300 = 0x0000007; - int B600 = 0x0000008; - int B1200 = 0x0000009; - int B1800 = 0x000000a; - int B2400 = 0x000000b; - int B4800 = 0x000000c; - int B9600 = 0x000000d; - int B19200 = 0x000000e; - int B38400 = 0x000000f; - int EXTA = B19200; - int EXTB = B38400; - int CSIZE = 0x0000030; - int CS5 = 0x0000000; - int CS6 = 0x0000010; - int CS7 = 0x0000020; - int CS8 = 0x0000030; - int CSTOPB = 0x0000040; - int CREAD = 0x0000080; - int PARENB = 0x0000100; - int PARODD = 0x0000200; - int HUPCL = 0x0000400; - int CLOCAL = 0x0000800; - - int ISIG = 0x0000001; - int ICANON = 0x0000002; - int XCASE = 0x0000004; - int ECHO = 0x0000008; - int ECHOE = 0x0000010; - int ECHOK = 0x0000020; - int ECHONL = 0x0000040; - int NOFLSH = 0x0000080; - int TOSTOP = 0x0000100; - int ECHOCTL = 0x0000200; - int ECHOPRT = 0x0000400; - int ECHOKE = 0x0000800; - int FLUSHO = 0x0001000; - int PENDIN = 0x0002000; - int IEXTEN = 0x0008000; - int EXTPROC = 0x0010000; - - int TCSANOW = 0x0; - int TCSADRAIN = 0x1; - int TCSAFLUSH = 0x2; - -} diff --git a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibraryImpl.java b/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibraryImpl.java deleted file mode 100644 index 732f2d15d1e..00000000000 --- a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/CLibraryImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna.linux; - -import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; - -public final class CLibraryImpl implements CLibrary { - - static { - System.loadLibrary("le"); - initIDs(); - } - - private static native void initIDs(); - - @Override - public native void tcgetattr(int fd, termios termios) throws LastErrorException; - - @Override - public native void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; - - @Override - public void ioctl(int fd, int cmd, winsize data) throws LastErrorException { - if (cmd == CLibrary.TIOCGWINSZ || cmd == CLibrary.TIOCSWINSZ) { - ioctl0(fd, cmd, data); - } else { - throw new UnsupportedOperationException("Command: " + cmd + ", not supported."); - } - } - - private native void ioctl0(int fd, int cmd, winsize data) throws LastErrorException; - - @Override - public native int isatty(int fd); - - @Override - public native void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; - -} diff --git a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/LinuxNativePty.java b/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/LinuxNativePty.java deleted file mode 100644 index b2cd60c08e7..00000000000 --- a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/LinuxNativePty.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.impl.jna.linux; - -import java.io.FileDescriptor; -import java.io.IOException; - -//import com.sun.jna.LastErrorException; -//import com.sun.jna.Native; -//import com.sun.jna.Platform; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.impl.jna.JnaNativePty; -import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; -import jdk.internal.org.jline.terminal.spi.TerminalProvider; - -import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.TCSADRAIN; -import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.TIOCGWINSZ; -import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.TIOCSWINSZ; -import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.termios; -import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.winsize; - -public class LinuxNativePty extends JnaNativePty { - -// private static final CLibrary C_LIBRARY = Native.load(Platform.C_LIBRARY_NAME, CLibrary.class); - private static final CLibrary C_LIBRARY = new CLibraryImpl(); - - public interface UtilLibrary {// extends com.sun.jna.Library { - - void openpty(int[] master, int[] slave, byte[] name, CLibrary.termios t, CLibrary.winsize s) throws LastErrorException; - -// UtilLibrary INSTANCE = Native.load("util", UtilLibrary.class); - UtilLibrary INSTANCE = new UtilLibraryImpl(); - } - - public static LinuxNativePty current(TerminalProvider.Stream consoleStream) throws IOException { - switch (consoleStream) { - case Output: - return new LinuxNativePty(-1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0)); - case Error: - return new LinuxNativePty(-1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0)); - default: - throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream); - } - } - - public static LinuxNativePty open(Attributes attr, Size size) throws IOException { - int[] master = new int[1]; - int[] slave = new int[1]; - byte[] buf = new byte[64]; - UtilLibrary.INSTANCE.openpty(master, slave, buf, - attr != null ? new termios(attr) : null, - size != null ? new winsize(size) : null); - int len = 0; - while (buf[len] != 0) { - len++; - } - String name = new String(buf, 0, len); - return new LinuxNativePty(master[0], newDescriptor(master[0]), slave[0], newDescriptor(slave[0]), name); - } - - public LinuxNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) { - super(master, masterFD, slave, slaveFD, name); - } - - public LinuxNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, int slaveOut, FileDescriptor slaveOutFD, String name) { - super(master, masterFD, slave, slaveFD, slaveOut, slaveOutFD, name); - } - - @Override - public Attributes getAttr() throws IOException { - termios termios = new termios(); - C_LIBRARY.tcgetattr(getSlave(), termios); - return termios.toAttributes(); - } - - @Override - protected void doSetAttr(Attributes attr) throws IOException { - termios termios = new termios(attr); - termios org = new termios(); - C_LIBRARY.tcgetattr(getSlave(), org); - org.c_iflag = termios.c_iflag; - org.c_oflag = termios.c_oflag; - org.c_lflag = termios.c_lflag; - System.arraycopy(termios.c_cc, 0, org.c_cc, 0, termios.c_cc.length); - C_LIBRARY.tcsetattr(getSlave(), TCSADRAIN, org); - } - - @Override - public Size getSize() throws IOException { - winsize sz = new winsize(); - C_LIBRARY.ioctl(getSlave(), TIOCGWINSZ, sz); - return sz.toSize(); - } - - @Override - public void setSize(Size size) throws IOException { - winsize sz = new winsize(size); - C_LIBRARY.ioctl(getSlave(), TIOCSWINSZ, sz); - } - - public static int isatty(int fd) { - return C_LIBRARY.isatty(fd); - } - - public static String ttyname(int slave) { - byte[] buf = new byte[64]; - C_LIBRARY.ttyname_r(slave, buf, buf.length); - int len = 0; - while (buf[len] != 0) { - len++; - } - return new String(buf, 0, len); - } - -} diff --git a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/UtilLibraryImpl.java b/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/UtilLibraryImpl.java deleted file mode 100644 index 0bc8fa3994e..00000000000 --- a/src/jdk.internal.le/linux/classes/jdk/internal/org/jline/terminal/impl/jna/linux/UtilLibraryImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna.linux; - -import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; -import jdk.internal.org.jline.terminal.impl.jna.linux.LinuxNativePty.UtilLibrary; - -public final class UtilLibraryImpl implements UtilLibrary { - - @Override - public void openpty(int[] master, int[] slave, byte[] name, CLibrary.termios t, CLibrary.winsize s) throws LastErrorException { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/jdk.internal.le/linux/native/lible/CLibrary.cpp b/src/jdk.internal.le/linux/native/lible/CLibrary.cpp deleted file mode 100644 index 3215e1f5013..00000000000 --- a/src/jdk.internal.le/linux/native/lible/CLibrary.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl.h" - -#include -#include -#include -#include -#include - -static jclass lastErrorExceptionClass; -static jmethodID lastErrorExceptionConstructor; - -static jclass termios_j; -static jfieldID c_iflag; -static jfieldID c_oflag; -static jfieldID c_cflag; -static jfieldID c_lflag; -static jfieldID c_line; -static jfieldID c_cc; -static jfieldID c_ispeed; -static jfieldID c_ospeed; - -static jclass winsize_j; -static jfieldID ws_row; -static jfieldID ws_col; -static jfieldID ws_xpixel; -static jfieldID ws_ypixel; - -static void throw_errno(JNIEnv *env); - -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_initIDs - (JNIEnv *env, jclass unused) { - jclass cls; - cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/LastErrorException"); - CHECK_NULL(cls); - lastErrorExceptionClass = (jclass) env->NewGlobalRef(cls); - lastErrorExceptionConstructor = env->GetMethodID(lastErrorExceptionClass, "", "(J)V"); - CHECK_NULL(lastErrorExceptionConstructor); - - cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/linux/CLibrary$termios"); - CHECK_NULL(cls); - termios_j = (jclass) env->NewGlobalRef(cls); - c_iflag = env->GetFieldID(termios_j, "c_iflag", "I"); - CHECK_NULL(c_iflag); - c_oflag = env->GetFieldID(termios_j, "c_oflag", "I"); - CHECK_NULL(c_oflag); - c_cflag = env->GetFieldID(termios_j, "c_cflag", "I"); - CHECK_NULL(c_cflag); - c_lflag = env->GetFieldID(termios_j, "c_lflag", "I"); - CHECK_NULL(c_lflag); - c_line = env->GetFieldID(termios_j, "c_line", "B"); - CHECK_NULL(c_line); - c_cc = env->GetFieldID(termios_j, "c_cc", "[B"); - CHECK_NULL(c_cc); - c_ispeed = env->GetFieldID(termios_j, "c_ispeed", "I"); - CHECK_NULL(c_ispeed); - c_ospeed = env->GetFieldID(termios_j, "c_ospeed", "I"); - CHECK_NULL(c_ospeed); - - cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/linux/CLibrary$winsize"); - CHECK_NULL(cls); - winsize_j = (jclass) env->NewGlobalRef(cls); - ws_row = env->GetFieldID(winsize_j, "ws_row", "S"); - CHECK_NULL(ws_row); - ws_col = env->GetFieldID(winsize_j, "ws_col", "S"); - CHECK_NULL(ws_col); - ws_xpixel= env->GetFieldID(winsize_j, "ws_xpixel", "S"); - CHECK_NULL(ws_xpixel); - ws_ypixel= env->GetFieldID(winsize_j, "ws_ypixel", "S"); - CHECK_NULL(ws_ypixel); -} - -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_tcgetattr - (JNIEnv *env, jobject, jint fd, jobject result) { - termios data; - - if (tcgetattr(fd, &data) != 0) { - throw_errno(env); - return ; - } - - env->SetIntField(result, c_iflag, data.c_iflag); - env->SetIntField(result, c_oflag, data.c_oflag); - env->SetIntField(result, c_cflag, data.c_cflag); - env->SetIntField(result, c_lflag, data.c_lflag); - env->SetIntField(result, c_line, data.c_line); - jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(result, c_cc); - env->SetByteArrayRegion(c_ccValue, 0, NCCS, (signed char *) data.c_cc);//TODO: cast? - env->SetIntField(result, c_ispeed, cfgetispeed(&data)); - env->SetIntField(result, c_ospeed, cfgetospeed(&data)); -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl - * Method: tcsetattr - * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/linux/CLibrary/termios;)V - */ -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_tcsetattr - (JNIEnv *env, jobject, jint fd, jint cmd, jobject input) { - termios data; - - data.c_iflag = env->GetIntField(input, c_iflag); - data.c_oflag = env->GetIntField(input, c_oflag); - data.c_cflag = env->GetIntField(input, c_cflag); - data.c_lflag = env->GetIntField(input, c_lflag); - data.c_line = env->GetIntField(input, c_line); - jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(input, c_cc); - env->GetByteArrayRegion(c_ccValue, 0, NCCS, (jbyte *) data.c_cc); - cfsetispeed(&data, env->GetIntField(input, c_ispeed)); - cfsetospeed(&data, env->GetIntField(input, c_ospeed)); - - if (tcsetattr(fd, cmd, &data) != 0) { - throw_errno(env); - } -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl - * Method: ioctl0 - * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/linux/CLibrary/winsize;)V - */ -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_ioctl0 - (JNIEnv *env, jobject, jint fd, jint cmd, jobject data) { - winsize ws; - - ws.ws_row = env->GetShortField(data, ws_row); - ws.ws_col = env->GetShortField(data, ws_col); - ws.ws_xpixel = env->GetShortField(data, ws_xpixel); - ws.ws_ypixel = env->GetShortField(data, ws_ypixel); - - if (ioctl(fd, cmd, &ws) != 0) { - throw_errno(env); - return ; - } - - env->SetShortField(data, ws_row, ws.ws_row); - env->SetShortField(data, ws_col, ws.ws_col); - env->SetShortField(data, ws_xpixel, ws.ws_xpixel); - env->SetShortField(data, ws_ypixel, ws.ws_ypixel); -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl - * Method: isatty - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_isatty - (JNIEnv *, jobject, jint fd) { - return isatty(fd); -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl - * Method: ttyname_r - * Signature: (I[BI)V - */ -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_ttyname_1r - (JNIEnv *env, jobject, jint fd, jbyteArray buf, jint len) { - char *data = new char[len]; - int error = ttyname_r(fd, data, len); - - if (error != 0) { - delete[] data; - throw_errno(env); - return ; - } - - env->SetByteArrayRegion(buf, 0, len, (jbyte *) data); - delete[] data; -} - -/* - * Throws LastErrorException based on the errno: - */ -static void throw_errno(JNIEnv *env) { - jobject exc = env->NewObject(lastErrorExceptionClass, - lastErrorExceptionConstructor, - errno); - env->Throw((jthrowable) exc); -} diff --git a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java b/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java deleted file mode 100644 index 24b6213ca89..00000000000 --- a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna; - -import java.io.IOException; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.impl.jna.osx.OsXNativePty; -import jdk.internal.org.jline.terminal.spi.TerminalProvider; - -class JDKNativePty { - - static JnaNativePty current(TerminalProvider.Stream console) throws IOException { - return OsXNativePty.current(console); - } - - static JnaNativePty open(Attributes attr, Size size) throws IOException { - return OsXNativePty.open(attr, size); - } - - static int isatty(int fd) { - return OsXNativePty.isatty(fd); - } - - static String ttyname(int fd) { - return OsXNativePty.ttyname(fd); - } - -} diff --git a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary.java b/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary.java deleted file mode 100644 index 02c2b9224e4..00000000000 --- a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.impl.jna.osx; - -import java.util.Arrays; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.List; - -//import com.sun.jna.LastErrorException; -//import com.sun.jna.NativeLong; -//import com.sun.jna.Structure; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Attributes.ControlChar; -import jdk.internal.org.jline.terminal.Attributes.ControlFlag; -import jdk.internal.org.jline.terminal.Attributes.InputFlag; -import jdk.internal.org.jline.terminal.Attributes.LocalFlag; -import jdk.internal.org.jline.terminal.Attributes.OutputFlag; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; - -public interface CLibrary {//extends com.sun.jna.Library { - - void tcgetattr(int fd, termios termios) throws LastErrorException; - - void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; - - void ioctl(int fd, NativeLong cmd, winsize data) throws LastErrorException; - - int isatty(int fd); - - void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; - - void openpty(int[] master, int[] slave, byte[] name, termios t, winsize s) throws LastErrorException; - - class winsize { //extends Structure { - public short ws_row; - public short ws_col; - public short ws_xpixel; - public short ws_ypixel; - - public winsize() { - } - - public winsize(Size ws) { - ws_row = (short) ws.getRows(); - ws_col = (short) ws.getColumns(); - } - - public Size toSize() { - return new Size(ws_col, ws_row); - } - -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(// -// "ws_row",// -// "ws_col",// -// "ws_xpixel",// -// "ws_ypixel"// -// ); -// } - - } - - class termios { //extends Structure { - - public NativeLong c_iflag; - public NativeLong c_oflag; - public NativeLong c_cflag; - public NativeLong c_lflag; - public byte[] c_cc = new byte[20]; - public NativeLong c_ispeed; - public NativeLong c_ospeed; - -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(// -// "c_iflag",// -// "c_oflag",// -// "c_cflag",// -// "c_lflag",// -// "c_cc",// -// "c_ispeed",// -// "c_ospeed"// -// ); -// } - - { - c_iflag = new NativeLong(0); - c_oflag = new NativeLong(0); - c_cflag = new NativeLong(0); - c_lflag = new NativeLong(0); - c_ispeed = new NativeLong(0); - c_ospeed = new NativeLong(0); - } - - public termios() { - } - - public termios(Attributes t) { - // Input flags - setFlag(t.getInputFlag(InputFlag.IGNBRK), IGNBRK, c_iflag); - setFlag(t.getInputFlag(InputFlag.BRKINT), BRKINT, c_iflag); - setFlag(t.getInputFlag(InputFlag.IGNPAR), IGNPAR, c_iflag); - setFlag(t.getInputFlag(InputFlag.PARMRK), PARMRK, c_iflag); - setFlag(t.getInputFlag(InputFlag.INPCK), INPCK, c_iflag); - setFlag(t.getInputFlag(InputFlag.ISTRIP), ISTRIP, c_iflag); - setFlag(t.getInputFlag(InputFlag.INLCR), INLCR, c_iflag); - setFlag(t.getInputFlag(InputFlag.IGNCR), IGNCR, c_iflag); - setFlag(t.getInputFlag(InputFlag.ICRNL), ICRNL, c_iflag); - setFlag(t.getInputFlag(InputFlag.IXON), IXON, c_iflag); - setFlag(t.getInputFlag(InputFlag.IXOFF), IXOFF, c_iflag); - setFlag(t.getInputFlag(InputFlag.IXANY), IXANY, c_iflag); - setFlag(t.getInputFlag(InputFlag.IMAXBEL), IMAXBEL, c_iflag); - setFlag(t.getInputFlag(InputFlag.IUTF8), IUTF8, c_iflag); - // Output flags - setFlag(t.getOutputFlag(OutputFlag.OPOST), OPOST, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.ONLCR), ONLCR, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.OXTABS), OXTABS, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.ONOEOT), ONOEOT, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.OCRNL), OCRNL, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.ONOCR), ONOCR, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.ONLRET), ONLRET, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.OFILL), OFILL, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.NLDLY), NLDLY, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.TABDLY), TABDLY, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.CRDLY), CRDLY, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.FFDLY), FFDLY, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.BSDLY), BSDLY, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.VTDLY), VTDLY, c_oflag); - setFlag(t.getOutputFlag(OutputFlag.OFDEL), OFDEL, c_oflag); - // Control flags - setFlag(t.getControlFlag(ControlFlag.CIGNORE), CIGNORE, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CS5), CS5, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CS6), CS6, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CS7), CS7, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CS8), CS8, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CSTOPB), CSTOPB, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CREAD), CREAD, c_cflag); - setFlag(t.getControlFlag(ControlFlag.PARENB), PARENB, c_cflag); - setFlag(t.getControlFlag(ControlFlag.PARODD), PARODD, c_cflag); - setFlag(t.getControlFlag(ControlFlag.HUPCL), HUPCL, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CLOCAL), CLOCAL, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CCTS_OFLOW), CCTS_OFLOW, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CRTS_IFLOW), CRTS_IFLOW, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CDTR_IFLOW), CDTR_IFLOW, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CDSR_OFLOW), CDSR_OFLOW, c_cflag); - setFlag(t.getControlFlag(ControlFlag.CCAR_OFLOW), CCAR_OFLOW, c_cflag); - // Local flags - setFlag(t.getLocalFlag(LocalFlag.ECHOKE), ECHOKE, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ECHOE), ECHOE, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ECHOK), ECHOK, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ECHO), ECHO, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ECHONL), ECHONL, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ECHOPRT), ECHOPRT, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ECHOCTL), ECHOCTL, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ISIG), ISIG, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ICANON), ICANON, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.ALTWERASE), ALTWERASE, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.IEXTEN), IEXTEN, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.EXTPROC), EXTPROC, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.TOSTOP), TOSTOP, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.FLUSHO), FLUSHO, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.NOKERNINFO), NOKERNINFO, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.PENDIN), PENDIN, c_lflag); - setFlag(t.getLocalFlag(LocalFlag.NOFLSH), NOFLSH, c_lflag); - // Control chars - c_cc[VEOF] = (byte) t.getControlChar(ControlChar.VEOF); - c_cc[VEOL] = (byte) t.getControlChar(ControlChar.VEOL); - c_cc[VEOL2] = (byte) t.getControlChar(ControlChar.VEOL2); - c_cc[VERASE] = (byte) t.getControlChar(ControlChar.VERASE); - c_cc[VWERASE] = (byte) t.getControlChar(ControlChar.VWERASE); - c_cc[VKILL] = (byte) t.getControlChar(ControlChar.VKILL); - c_cc[VREPRINT] = (byte) t.getControlChar(ControlChar.VREPRINT); - c_cc[VINTR] = (byte) t.getControlChar(ControlChar.VINTR); - c_cc[VQUIT] = (byte) t.getControlChar(ControlChar.VQUIT); - c_cc[VSUSP] = (byte) t.getControlChar(ControlChar.VSUSP); - c_cc[VDSUSP] = (byte) t.getControlChar(ControlChar.VDSUSP); - c_cc[VSTART] = (byte) t.getControlChar(ControlChar.VSTART); - c_cc[VSTOP] = (byte) t.getControlChar(ControlChar.VSTOP); - c_cc[VLNEXT] = (byte) t.getControlChar(ControlChar.VLNEXT); - c_cc[VDISCARD] = (byte) t.getControlChar(ControlChar.VDISCARD); - c_cc[VMIN] = (byte) t.getControlChar(ControlChar.VMIN); - c_cc[VTIME] = (byte) t.getControlChar(ControlChar.VTIME); - c_cc[VSTATUS] = (byte) t.getControlChar(ControlChar.VSTATUS); - } - - private void setFlag(boolean flag, long value, NativeLong org) { - org.setValue(flag ? org.longValue() | value : org.longValue()); - } - - public Attributes toAttributes() { - Attributes attr = new Attributes(); - // Input flags - EnumSet iflag = attr.getInputFlags(); - addFlag(c_iflag.longValue(), iflag, InputFlag.IGNBRK, IGNBRK); - addFlag(c_iflag.longValue(), iflag, InputFlag.IGNBRK, IGNBRK); - addFlag(c_iflag.longValue(), iflag, InputFlag.BRKINT, BRKINT); - addFlag(c_iflag.longValue(), iflag, InputFlag.IGNPAR, IGNPAR); - addFlag(c_iflag.longValue(), iflag, InputFlag.PARMRK, PARMRK); - addFlag(c_iflag.longValue(), iflag, InputFlag.INPCK, INPCK); - addFlag(c_iflag.longValue(), iflag, InputFlag.ISTRIP, ISTRIP); - addFlag(c_iflag.longValue(), iflag, InputFlag.INLCR, INLCR); - addFlag(c_iflag.longValue(), iflag, InputFlag.IGNCR, IGNCR); - addFlag(c_iflag.longValue(), iflag, InputFlag.ICRNL, ICRNL); - addFlag(c_iflag.longValue(), iflag, InputFlag.IXON, IXON); - addFlag(c_iflag.longValue(), iflag, InputFlag.IXOFF, IXOFF); - addFlag(c_iflag.longValue(), iflag, InputFlag.IXANY, IXANY); - addFlag(c_iflag.longValue(), iflag, InputFlag.IMAXBEL, IMAXBEL); - addFlag(c_iflag.longValue(), iflag, InputFlag.IUTF8, IUTF8); - // Output flags - EnumSet oflag = attr.getOutputFlags(); - addFlag(c_oflag.longValue(), oflag, OutputFlag.OPOST, OPOST); - addFlag(c_oflag.longValue(), oflag, OutputFlag.ONLCR, ONLCR); - addFlag(c_oflag.longValue(), oflag, OutputFlag.OXTABS, OXTABS); - addFlag(c_oflag.longValue(), oflag, OutputFlag.ONOEOT, ONOEOT); - addFlag(c_oflag.longValue(), oflag, OutputFlag.OCRNL, OCRNL); - addFlag(c_oflag.longValue(), oflag, OutputFlag.ONOCR, ONOCR); - addFlag(c_oflag.longValue(), oflag, OutputFlag.ONLRET, ONLRET); - addFlag(c_oflag.longValue(), oflag, OutputFlag.OFILL, OFILL); - addFlag(c_oflag.longValue(), oflag, OutputFlag.NLDLY, NLDLY); - addFlag(c_oflag.longValue(), oflag, OutputFlag.TABDLY, TABDLY); - addFlag(c_oflag.longValue(), oflag, OutputFlag.CRDLY, CRDLY); - addFlag(c_oflag.longValue(), oflag, OutputFlag.FFDLY, FFDLY); - addFlag(c_oflag.longValue(), oflag, OutputFlag.BSDLY, BSDLY); - addFlag(c_oflag.longValue(), oflag, OutputFlag.VTDLY, VTDLY); - addFlag(c_oflag.longValue(), oflag, OutputFlag.OFDEL, OFDEL); - // Control flags - EnumSet cflag = attr.getControlFlags(); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CIGNORE, CIGNORE); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CS5, CS5); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CS6, CS6); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CS7, CS7); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CS8, CS8); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CSTOPB, CSTOPB); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CREAD, CREAD); - addFlag(c_cflag.longValue(), cflag, ControlFlag.PARENB, PARENB); - addFlag(c_cflag.longValue(), cflag, ControlFlag.PARODD, PARODD); - addFlag(c_cflag.longValue(), cflag, ControlFlag.HUPCL, HUPCL); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CLOCAL, CLOCAL); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CCTS_OFLOW, CCTS_OFLOW); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CRTS_IFLOW, CRTS_IFLOW); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CDSR_OFLOW, CDSR_OFLOW); - addFlag(c_cflag.longValue(), cflag, ControlFlag.CCAR_OFLOW, CCAR_OFLOW); - // Local flags - EnumSet lflag = attr.getLocalFlags(); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOKE, ECHOKE); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOE, ECHOE); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOK, ECHOK); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHO, ECHO); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHONL, ECHONL); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOPRT, ECHOPRT); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOCTL, ECHOCTL); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ISIG, ISIG); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ICANON, ICANON); - addFlag(c_lflag.longValue(), lflag, LocalFlag.ALTWERASE, ALTWERASE); - addFlag(c_lflag.longValue(), lflag, LocalFlag.IEXTEN, IEXTEN); - addFlag(c_lflag.longValue(), lflag, LocalFlag.EXTPROC, EXTPROC); - addFlag(c_lflag.longValue(), lflag, LocalFlag.TOSTOP, TOSTOP); - addFlag(c_lflag.longValue(), lflag, LocalFlag.FLUSHO, FLUSHO); - addFlag(c_lflag.longValue(), lflag, LocalFlag.NOKERNINFO, NOKERNINFO); - addFlag(c_lflag.longValue(), lflag, LocalFlag.PENDIN, PENDIN); - addFlag(c_lflag.longValue(), lflag, LocalFlag.NOFLSH, NOFLSH); - // Control chars - EnumMap cc = attr.getControlChars(); - cc.put(ControlChar.VEOF, (int) c_cc[VEOF]); - cc.put(ControlChar.VEOL, (int) c_cc[VEOL]); - cc.put(ControlChar.VEOL2, (int) c_cc[VEOL2]); - cc.put(ControlChar.VERASE, (int) c_cc[VERASE]); - cc.put(ControlChar.VWERASE, (int) c_cc[VWERASE]); - cc.put(ControlChar.VKILL, (int) c_cc[VKILL]); - cc.put(ControlChar.VREPRINT, (int) c_cc[VREPRINT]); - cc.put(ControlChar.VINTR, (int) c_cc[VINTR]); - cc.put(ControlChar.VQUIT, (int) c_cc[VQUIT]); - cc.put(ControlChar.VSUSP, (int) c_cc[VSUSP]); - cc.put(ControlChar.VDSUSP, (int) c_cc[VDSUSP]); - cc.put(ControlChar.VSTART, (int) c_cc[VSTART]); - cc.put(ControlChar.VSTOP, (int) c_cc[VSTOP]); - cc.put(ControlChar.VLNEXT, (int) c_cc[VLNEXT]); - cc.put(ControlChar.VDISCARD, (int) c_cc[VDISCARD]); - cc.put(ControlChar.VMIN, (int) c_cc[VMIN]); - cc.put(ControlChar.VTIME, (int) c_cc[VTIME]); - cc.put(ControlChar.VSTATUS, (int) c_cc[VSTATUS]); - // Return - return attr; - } - - private > void addFlag(long value, EnumSet flags, T flag, int v) { - if ((value & v) != 0) { - flags.add(flag); - } - } - } - - // CONSTANTS - - long TIOCGWINSZ = 0x40087468L; - long TIOCSWINSZ = 0x80087467L; - - int TCSANOW = 0x00000000; - - int VEOF = 0; - int VEOL = 1; - int VEOL2 = 2; - int VERASE = 3; - int VWERASE = 4; - int VKILL = 5; - int VREPRINT = 6; - int VINTR = 8; - int VQUIT = 9; - int VSUSP = 10; - int VDSUSP = 11; - int VSTART = 12; - int VSTOP = 13; - int VLNEXT = 14; - int VDISCARD = 15; - int VMIN = 16; - int VTIME = 17; - int VSTATUS = 18; - - int IGNBRK = 0x00000001; - int BRKINT = 0x00000002; - int IGNPAR = 0x00000004; - int PARMRK = 0x00000008; - int INPCK = 0x00000010; - int ISTRIP = 0x00000020; - int INLCR = 0x00000040; - int IGNCR = 0x00000080; - int ICRNL = 0x00000100; - int IXON = 0x00000200; - int IXOFF = 0x00000400; - int IXANY = 0x00000800; - int IMAXBEL = 0x00002000; - int IUTF8 = 0x00004000; - - int OPOST = 0x00000001; - int ONLCR = 0x00000002; - int OXTABS = 0x00000004; - int ONOEOT = 0x00000008; - int OCRNL = 0x00000010; - int ONOCR = 0x00000020; - int ONLRET = 0x00000040; - int OFILL = 0x00000080; - int NLDLY = 0x00000300; - int TABDLY = 0x00000c04; - int CRDLY = 0x00003000; - int FFDLY = 0x00004000; - int BSDLY = 0x00008000; - int VTDLY = 0x00010000; - int OFDEL = 0x00020000; - - int CIGNORE = 0x00000001; - int CS5 = 0x00000000; - int CS6 = 0x00000100; - int CS7 = 0x00000200; - int CS8 = 0x00000300; - int CSTOPB = 0x00000400; - int CREAD = 0x00000800; - int PARENB = 0x00001000; - int PARODD = 0x00002000; - int HUPCL = 0x00004000; - int CLOCAL = 0x00008000; - int CCTS_OFLOW = 0x00010000; - int CRTS_IFLOW = 0x00020000; - int CDTR_IFLOW = 0x00040000; - int CDSR_OFLOW = 0x00080000; - int CCAR_OFLOW = 0x00100000; - - int ECHOKE = 0x00000001; - int ECHOE = 0x00000002; - int ECHOK = 0x00000004; - int ECHO = 0x00000008; - int ECHONL = 0x00000010; - int ECHOPRT = 0x00000020; - int ECHOCTL = 0x00000040; - int ISIG = 0x00000080; - int ICANON = 0x00000100; - int ALTWERASE = 0x00000200; - int IEXTEN = 0x00000400; - int EXTPROC = 0x00000800; - int TOSTOP = 0x00400000; - int FLUSHO = 0x00800000; - int NOKERNINFO = 0x02000000; - int PENDIN = 0x20000000; - int NOFLSH = 0x80000000; - -} diff --git a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibraryImpl.java b/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibraryImpl.java deleted file mode 100644 index da3099bb984..00000000000 --- a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/CLibraryImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna.osx; - -import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; - -public final class CLibraryImpl implements CLibrary { - - static { - System.loadLibrary("le"); - initIDs(); - } - - private static native void initIDs(); - - @Override - public native void tcgetattr(int fd, termios termios) throws LastErrorException; - - @Override - public native void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; - - @Override - public void ioctl(int fd, NativeLong cmd, winsize data) throws LastErrorException { - if (cmd.longValue() == CLibrary.TIOCGWINSZ || cmd.longValue() == CLibrary.TIOCSWINSZ) { - ioctl0(fd, cmd.longValue(), data); - } else { - throw new UnsupportedOperationException("Command: " + cmd + ", not supported."); - } - } - - private native void ioctl0(int fd, long cmd, winsize data) throws LastErrorException; - - @Override - public native int isatty(int fd); - - @Override - public native void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; - - @Override - public void openpty(int[] master, int[] slave, byte[] name, termios t, winsize s) throws LastErrorException { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/NativeLong.java b/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/NativeLong.java deleted file mode 100644 index 7d9ab39bc33..00000000000 --- a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/NativeLong.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna.osx; - -class NativeLong { - - public long value; - - public NativeLong(long value) { - this.value = value; - } - - public void setValue(long value) { - this.value = value; - } - - public long longValue() { - return value; - } - -} diff --git a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/OsXNativePty.java b/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/OsXNativePty.java deleted file mode 100644 index 12aaff4f1f1..00000000000 --- a/src/jdk.internal.le/macosx/classes/jdk/internal/org/jline/terminal/impl/jna/osx/OsXNativePty.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.impl.jna.osx; - -import java.io.FileDescriptor; -import java.io.IOException; - -//import com.sun.jna.Native; -//import com.sun.jna.NativeLong; -//import com.sun.jna.Platform; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.impl.jna.JnaNativePty; -import jdk.internal.org.jline.terminal.spi.TerminalProvider; - -import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.TCSANOW; -import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.TIOCGWINSZ; -import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.TIOCSWINSZ; -import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.termios; -import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.winsize; - -public class OsXNativePty extends JnaNativePty { - -// private static final CLibrary C_LIBRARY = Native.load(Platform.C_LIBRARY_NAME, CLibrary.class); - private static final CLibrary C_LIBRARY = new CLibraryImpl();//Native.load(Platform.C_LIBRARY_NAME, CLibrary.class); - - public static OsXNativePty current(TerminalProvider.Stream consoleStream) throws IOException { - switch (consoleStream) { - case Output: - return new OsXNativePty(-1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0)); - case Error: - return new OsXNativePty(-1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0)); - default: - throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream); - } - } - - public static OsXNativePty open(Attributes attr, Size size) throws IOException { - int[] master = new int[1]; - int[] slave = new int[1]; - byte[] buf = new byte[64]; - C_LIBRARY.openpty(master, slave, buf, - attr != null ? new termios(attr) : null, - size != null ? new winsize(size) : null); - int len = 0; - while (buf[len] != 0) { - len++; - } - String name = new String(buf, 0, len); - return new OsXNativePty(master[0], newDescriptor(master[0]), slave[0], newDescriptor(slave[0]), name); - } - - public OsXNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) { - super(master, masterFD, slave, slaveFD, name); - } - - public OsXNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, int slaveOut, FileDescriptor slaveOutFD, String name) { - super(master, masterFD, slave, slaveFD, slaveOut, slaveOutFD, name); - } - - @Override - public Attributes getAttr() throws IOException { - termios termios = new termios(); - C_LIBRARY.tcgetattr(getSlave(), termios); - return termios.toAttributes(); - } - - @Override - protected void doSetAttr(Attributes attr) throws IOException { - termios termios = new termios(attr); - C_LIBRARY.tcsetattr(getSlave(), TCSANOW, termios); - } - - @Override - public Size getSize() throws IOException { - winsize sz = new winsize(); - C_LIBRARY.ioctl(getSlave(), new NativeLong(TIOCGWINSZ), sz); - return sz.toSize(); - } - - @Override - public void setSize(Size size) throws IOException { - winsize sz = new winsize(size); - C_LIBRARY.ioctl(getSlave(), new NativeLong(TIOCSWINSZ), sz); - } - - public static int isatty(int fd) { - return C_LIBRARY.isatty(fd); - } - - public static String ttyname(int fd) { - byte[] buf = new byte[64]; - C_LIBRARY.ttyname_r(fd, buf, buf.length); - int len = 0; - while (buf[len] != 0) { - len++; - } - return new String(buf, 0, len); - } -} diff --git a/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp b/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp deleted file mode 100644 index 3bc481f4afa..00000000000 --- a/src/jdk.internal.le/macosx/native/lible/CLibrary.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "jni.h" -#include "jni_util.h" -#include "jvm.h" -#include "jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl.h" - -#include -#include -#include -#include -#include - -static jclass lastErrorExceptionClass; -static jmethodID lastErrorExceptionConstructor; - -static jclass termios_j; -static jfieldID c_iflag; -static jfieldID c_oflag; -static jfieldID c_cflag; -static jfieldID c_lflag; -static jfieldID c_cc; -static jfieldID c_ispeed; -static jfieldID c_ospeed; - -static jclass winsize_j; -static jfieldID ws_row; -static jfieldID ws_col; -static jfieldID ws_xpixel; -static jfieldID ws_ypixel; - -static jclass nativelong_j; -static jfieldID nativelong_value; - -static void throw_errno(JNIEnv *env); - -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_initIDs - (JNIEnv *env, jclass) { - jclass cls; - cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/LastErrorException"); - CHECK_NULL(cls); - lastErrorExceptionClass = (jclass) env->NewGlobalRef(cls); - lastErrorExceptionConstructor = env->GetMethodID(lastErrorExceptionClass, "", "(J)V"); - CHECK_NULL(lastErrorExceptionConstructor); - - cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary$termios"); - CHECK_NULL(cls); - termios_j = (jclass) env->NewGlobalRef(cls); - CHECK_NULL(termios_j); - c_iflag = env->GetFieldID(termios_j, "c_iflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;"); - CHECK_NULL(c_iflag); - c_oflag = env->GetFieldID(termios_j, "c_oflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;"); - CHECK_NULL(c_oflag); - c_cflag = env->GetFieldID(termios_j, "c_cflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;"); - CHECK_NULL(c_cflag); - c_lflag = env->GetFieldID(termios_j, "c_lflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;"); - CHECK_NULL(c_lflag); - c_cc = env->GetFieldID(termios_j, "c_cc", "[B"); - CHECK_NULL(c_cc); - c_ispeed = env->GetFieldID(termios_j, "c_ispeed", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;"); - CHECK_NULL(c_ispeed); - c_ospeed = env->GetFieldID(termios_j, "c_ospeed", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;"); - CHECK_NULL(c_ospeed); - - cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary$winsize"); - CHECK_NULL(cls); - winsize_j = (jclass) env->NewGlobalRef(cls); - ws_row = env->GetFieldID(winsize_j, "ws_row", "S"); - CHECK_NULL(ws_row); - ws_col = env->GetFieldID(winsize_j, "ws_col", "S"); - CHECK_NULL(ws_col); - ws_xpixel= env->GetFieldID(winsize_j, "ws_xpixel", "S"); - CHECK_NULL(ws_xpixel); - ws_ypixel= env->GetFieldID(winsize_j, "ws_ypixel", "S"); - CHECK_NULL(ws_ypixel); - - nativelong_j = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/osx/NativeLong"); - CHECK_NULL(nativelong_j); - nativelong_value = env->GetFieldID(nativelong_j, "value", "J"); - CHECK_NULL(nativelong_value); -} - -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_tcgetattr - (JNIEnv *env, jobject, jint fd, jobject result) { - termios data; - - if (tcgetattr(fd, &data) != 0) { - throw_errno(env); - return ; - } - - env->SetLongField(env->GetObjectField(result, c_iflag), nativelong_value, data.c_iflag); - env->SetLongField(env->GetObjectField(result, c_oflag), nativelong_value, data.c_oflag); - env->SetLongField(env->GetObjectField(result, c_cflag), nativelong_value, data.c_cflag); - env->SetLongField(env->GetObjectField(result, c_lflag), nativelong_value, data.c_lflag); - jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(result, c_cc); - env->SetByteArrayRegion(c_ccValue, 0, NCCS, (signed char *) data.c_cc); - env->SetLongField(env->GetObjectField(result, c_ispeed), nativelong_value, data.c_ispeed); - env->SetLongField(env->GetObjectField(result, c_ospeed), nativelong_value, data.c_ospeed); -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl - * Method: tcsetattr - * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/osx/CLibrary/termios;)V - */ -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_tcsetattr - (JNIEnv *env, jobject, jint fd, jint cmd, jobject input) { - termios data; - - data.c_iflag = env->GetLongField(env->GetObjectField(input, c_iflag), nativelong_value); - data.c_oflag = env->GetLongField(env->GetObjectField(input, c_oflag), nativelong_value); - data.c_cflag = env->GetLongField(env->GetObjectField(input, c_cflag), nativelong_value); - data.c_lflag = env->GetLongField(env->GetObjectField(input, c_lflag), nativelong_value); - jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(input, c_cc); - env->GetByteArrayRegion(c_ccValue, 0, NCCS, (jbyte *) data.c_cc); - data.c_ispeed = env->GetLongField(env->GetObjectField(input, c_ispeed), nativelong_value); - data.c_ospeed = env->GetLongField(env->GetObjectField(input, c_ospeed), nativelong_value); - - if (tcsetattr(fd, cmd, &data) != 0) { - throw_errno(env); - } -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl - * Method: ioctl0 - * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/osx/CLibrary/winsize;)V - */ -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_ioctl0 - (JNIEnv *env, jobject, jint fd, jlong cmd, jobject data) { - winsize ws; - - ws.ws_row = env->GetShortField(data, ws_row); - ws.ws_col = env->GetShortField(data, ws_col); - ws.ws_xpixel = env->GetShortField(data, ws_xpixel); - ws.ws_ypixel = env->GetShortField(data, ws_ypixel); - - if (ioctl(fd, cmd, &ws) != 0) { - throw_errno(env); - return ; - } - - env->SetShortField(data, ws_row, ws.ws_row); - env->SetShortField(data, ws_col, ws.ws_col); - env->SetShortField(data, ws_xpixel, ws.ws_xpixel); - env->SetShortField(data, ws_ypixel, ws.ws_ypixel); -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl - * Method: isatty - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_isatty - (JNIEnv *, jobject, jint fd) { - return isatty(fd); -} - -/* - * Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl - * Method: ttyname_r - * Signature: (I[BI)V - */ -JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_ttyname_1r - (JNIEnv *env, jobject, jint fd, jbyteArray buf, jint len) { - char *data = new char[len]; - int error = ttyname_r(fd, data, len); - - if (error != 0) { - delete[] data; - throw_errno(env); - return ; - } - - env->SetByteArrayRegion(buf, 0, len, (jbyte *) data); - delete[] data; -} - -/* - * Throws LastErrorException based on the errno: - */ -static void throw_errno(JNIEnv *env) { - jobject exc = env->NewObject(lastErrorExceptionClass, - lastErrorExceptionConstructor, - errno); - env->Throw((jthrowable) exc); -} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/BindingReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/BindingReader.java index 46a45ae396d..74d3a46ecf2 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/BindingReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/BindingReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -66,7 +66,7 @@ public class BindingReader { T o = null; int[] remaining = new int[1]; boolean hasRead = false; - for (;;) { + for (; ; ) { if (local != null) { o = local.getBound(opBuffer, remaining); } @@ -78,8 +78,7 @@ public class BindingReader { if (remaining[0] >= 0) { runMacro(opBuffer.substring(opBuffer.length() - remaining[0])); opBuffer.setLength(opBuffer.length() - remaining[0]); - } - else { + } else { long ambiguousTimeout = keys.getAmbiguousTimeout(); if (ambiguousTimeout > 0 && peekCharacter(ambiguousTimeout) != NonBlockingReader.READ_EXPIRED) { o = null; @@ -234,5 +233,4 @@ public class BindingReader { public String getLastBinding() { return lastBinding; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/KeyMap.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/KeyMap.java index 43c3a1b4fd1..a8a90ea5e0d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/KeyMap.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/keymap/KeyMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,8 +8,6 @@ */ package jdk.internal.org.jline.keymap; -import java.io.IOException; -import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -218,7 +216,6 @@ public class KeyMap { return seqs; } - public static String esc() { return "\033"; } @@ -264,7 +261,6 @@ public class KeyMap { // Methods // - public T getUnicode() { return unicode; } @@ -306,9 +302,7 @@ public class KeyMap { } for (int c = 0; c < keyMap.mapping.length; c++) { if (keyMap.mapping[c] instanceof KeyMap) { - doGetBoundKeys((KeyMap) keyMap.mapping[c], - prefix + (char) (c), - bound); + doGetBoundKeys((KeyMap) keyMap.mapping[c], prefix + (char) (c), bound); } else if (keyMap.mapping[c] != null) { bound.put(prefix + (char) (c), (T) keyMap.mapping[c]); } @@ -456,5 +450,4 @@ public class KeyMap { } } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java index 0070b55c22d..15e7a49a643 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,9 +14,8 @@ package jdk.internal.org.jline.reader; * @see Macro * @see Reference * @see Widget - * @see jdk.internal.org.jline.keymap.KeyMap + * @see org.jline.keymap.KeyMap * * @author Guillaume Nodet */ -public interface Binding { -} +public interface Binding {} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Buffer.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Buffer.java index c47746f566c..8d65891d9d9 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Buffer.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Buffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -84,8 +84,8 @@ public interface Buffer { void copyFrom(Buffer buffer); - // JDK specific modification - default void zeroOut() { - throw new UnsupportedOperationException(); - } + /** + * Clear any internal buffer. + */ + void zeroOut(); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java index 0e95538492d..e28e72ffb23 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -47,7 +47,15 @@ public class Candidate implements Comparable { * @param complete the complete flag * @param sort the sort flag */ - public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete, int sort) { + public Candidate( + String value, + String displ, + String group, + String descr, + String suffix, + String key, + boolean complete, + int sort) { this.value = Objects.requireNonNull(value); this.displ = Objects.requireNonNull(displ); this.group = group; @@ -69,7 +77,8 @@ public class Candidate implements Comparable { * @param key the key * @param complete the complete flag */ - public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete) { + public Candidate( + String value, String displ, String group, String descr, String suffix, String key, boolean complete) { this(value, displ, group, descr, suffix, key, complete, 0); } @@ -159,11 +168,10 @@ public class Candidate implements Comparable { return sort; } - @Override public int compareTo(Candidate o) { // If both candidates have same sort, use default behavior - if( sort == o.sort() ) { + if (sort == o.sort()) { return value.compareTo(o.value); } else { return Integer.compare(sort, o.sort()); @@ -180,7 +188,7 @@ public class Candidate implements Comparable { @Override public int hashCode() { - return Objects.hash(value); + return Objects.hashCode(value); } @Override diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Completer.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Completer.java index b87db7afbf0..7a5937460d8 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Completer.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Completer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -18,8 +18,7 @@ import java.util.List; * @author Guillaume Nodet * @since 2.3 */ -public interface Completer -{ +public interface Completer { /** * Populates candidates with a list of possible completions for the command line. * diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java index 52a36b83896..93558001af1 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -10,7 +10,7 @@ package jdk.internal.org.jline.reader; /** * An extension of {@link ParsedLine} that, being aware of the quoting and escaping rules - * of the {@link jdk.internal.org.jline.reader.Parser} that produced it, knows if and how a completion candidate + * of the {@link org.jline.reader.Parser} that produced it, knows if and how a completion candidate * should be escaped/quoted. * * @author Eric Bottard @@ -22,5 +22,4 @@ public interface CompletingParsedLine extends ParsedLine { int rawWordCursor(); int rawWordLength(); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java index 58117c8f213..4a2334642ca 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -23,8 +23,13 @@ public interface CompletionMatcher { * @param errors number of errors accepted in matching * @param originalGroupName value of JLineReader variable original-group-name */ - void compile(Map options, boolean prefix, CompletingParsedLine line - , boolean caseInsensitive, int errors, String originalGroupName); + void compile( + Map options, + boolean prefix, + CompletingParsedLine line, + boolean caseInsensitive, + int errors, + String originalGroupName); /** * @@ -44,5 +49,4 @@ public interface CompletionMatcher { * @return a common prefix of matched candidates */ String getCommonPrefix(); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EOFError.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EOFError.java index 382db8bc49f..8a4f516174e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EOFError.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EOFError.java @@ -1,20 +1,10 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * Copyright (c) 2023, the original author(s). * - * http://www.apache.org/licenses/LICENSE-2.0 + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * https://opensource.org/licenses/BSD-3-Clause */ package jdk.internal.org.jline.reader; @@ -45,7 +35,7 @@ public class EOFError extends SyntaxError { return missing; } - public int getOpenBrackets(){ + public int getOpenBrackets() { return openBrackets; } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Editor.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Editor.java index e99706ed5d5..b2fadd3bd52 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Editor.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Editor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -13,6 +13,8 @@ import java.util.List; public interface Editor { public void open(List files) throws IOException; + public void run() throws IOException; + public void setRestricted(boolean restricted); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java index 9f70420d9df..1e50a7ea1ae 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/EndOfFileException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -17,8 +17,7 @@ public class EndOfFileException extends RuntimeException { private static final long serialVersionUID = 528485360925144689L; private String partialLine; - public EndOfFileException() { - } + public EndOfFileException() {} public EndOfFileException(String message) { super(message); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Expander.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Expander.java index 0562e92ed96..614c89b3e61 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Expander.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Expander.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -13,5 +13,4 @@ public interface Expander { String expandHistory(History history, String line); String expandVar(String word); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java index 136fb20324b..dad62551ee0 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java index 7a669edddb5..0cb46a1ee9d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -21,8 +21,7 @@ import java.util.ListIterator; * @author Jason Dillon * @since 2.3 */ -public interface History extends Iterable -{ +public interface History extends Iterable { /** * Initialize the history for the given reader. @@ -75,7 +74,6 @@ public interface History extends Iterable */ void purge() throws IOException; - int size(); default boolean isEmpty() { @@ -110,8 +108,7 @@ public interface History extends Iterable // Entries // - interface Entry - { + interface Entry { int index(); Instant time(); @@ -132,14 +129,17 @@ public interface History extends Iterable default Iterator reverseIterator(int index) { return new Iterator() { private final ListIterator it = iterator(index + 1); + @Override public boolean hasNext() { return it.hasPrevious(); } + @Override public Entry next() { return it.previous(); } + @Override public void remove() { it.remove(); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java index bc719e9b46a..bc513f5f636 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2023, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -21,7 +21,7 @@ import jdk.internal.org.jline.utils.AttributedString; /** Read lines from the console, with input editing. * - *

Thread safety

+ *

Thread safety

* The LineReader implementations are not thread safe, * thus you should not attempt to use a single reader in several threads. * Any attempt to call one of the readLine call while one is @@ -31,7 +31,7 @@ import jdk.internal.org.jline.utils.AttributedString; * {@link #printAbove(String)} or {@link #printAbove(AttributedString)} at * any time to allow text to be printed above the current prompt. * - *

Prompt strings

+ *

Prompt strings

* It is traditional for an interactive console-based program * to print a short prompt string to signal that the user is expected * to type a command. JLine supports 3 kinds of prompt string: @@ -81,7 +81,6 @@ import jdk.internal.org.jline.utils.AttributedString; * * */ - public interface LineReader { /** @@ -284,6 +283,7 @@ public interface LineReader { String MAIN = "main"; String EMACS = "emacs"; String SAFE = ".safe"; + String DUMB = "dumb"; String MENU = "menu"; // @@ -301,6 +301,7 @@ public interface LineReader { * they are displayed in a list below the field to be completed */ String MENU_LIST_MAX = "menu-list-max"; + String DISABLE_HISTORY = "disable-history"; String DISABLE_COMPLETION = "disable-completion"; String EDITING_MODE = "editing-mode"; @@ -317,18 +318,23 @@ public interface LineReader { String ORIGINAL_GROUP_NAME = "ORIGINAL_GROUP_NAME"; /** Completion style for displaying groups name */ String COMPLETION_STYLE_GROUP = "COMPLETION_STYLE_GROUP"; + String COMPLETION_STYLE_LIST_GROUP = "COMPLETION_STYLE_LIST_GROUP"; /** Completion style for displaying the current selected item */ String COMPLETION_STYLE_SELECTION = "COMPLETION_STYLE_SELECTION"; + String COMPLETION_STYLE_LIST_SELECTION = "COMPLETION_STYLE_LIST_SELECTION"; /** Completion style for displaying the candidate description */ String COMPLETION_STYLE_DESCRIPTION = "COMPLETION_STYLE_DESCRIPTION"; + String COMPLETION_STYLE_LIST_DESCRIPTION = "COMPLETION_STYLE_LIST_DESCRIPTION"; /** Completion style for displaying the matching part of candidates */ String COMPLETION_STYLE_STARTING = "COMPLETION_STYLE_STARTING"; + String COMPLETION_STYLE_LIST_STARTING = "COMPLETION_STYLE_LIST_STARTING"; /** Completion style for displaying the list */ String COMPLETION_STYLE_BACKGROUND = "COMPLETION_STYLE_BACKGROUND"; + String COMPLETION_STYLE_LIST_BACKGROUND = "COMPLETION_STYLE_LIST_BACKGROUND"; /** * Set the template for prompts for secondary (continuation) lines. @@ -390,6 +396,26 @@ public interface LineReader { */ String SUGGESTIONS_MIN_BUFFER_SIZE = "suggestions-min-buffer-size"; + /** + * Max number of times a command can be repeated. + */ + String MAX_REPEAT_COUNT = "max-repeat-count"; + + /** + * Number of spaces to display a tabulation, the default is 4. + */ + String TAB_WIDTH = "tab-width"; + + /** + * Name of inputrc to read at line reader creation time. + */ + String INPUT_RC_FILE_NAME = "input-rc-file-name"; + + /** + * Prefix to automatically delegate variables to system properties + */ + String SYSTEM_PROPERTY_PREFIX = "system-property-prefix"; + Map> defaultKeyMaps(); enum Option { @@ -469,8 +495,7 @@ public interface LineReader { EMPTY_WORD_OPTIONS(true), /** Disable the undo feature */ - DISABLE_UNDO - ; + DISABLE_UNDO; private final boolean def; @@ -611,7 +636,8 @@ public interface LineReader { * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) * @throws java.io.IOError in case of other i/o errors */ - String readLine(String prompt, String rightPrompt, Character mask, String buffer) throws UserInterruptException, EndOfFileException; + String readLine(String prompt, String rightPrompt, Character mask, String buffer) + throws UserInterruptException, EndOfFileException; /** * Read a line from the in {@link InputStream}, and return the line @@ -631,7 +657,8 @@ public interface LineReader { * @throws EndOfFileException if an EOF has been found (using Ctrl-D for example) * @throws java.io.IOError in case of other i/o errors */ - String readLine(String prompt, String rightPrompt, MaskingCallback maskingCallback, String buffer) throws UserInterruptException, EndOfFileException; + String readLine(String prompt, String rightPrompt, MaskingCallback maskingCallback, String buffer) + throws UserInterruptException, EndOfFileException; /** * Prints a line above the prompt and redraw everything. @@ -702,7 +729,7 @@ public interface LineReader { void runMacro(String macro); /** - * Read a mouse event when the {@link jdk.internal.org.jline.utils.InfoCmp.Capability#key_mouse} sequence + * Read a mouse event when the {@link org.jline.utils.InfoCmp.Capability#key_mouse} sequence * has just been read on the input stream. * Compared to {@link Terminal#readMouseEvent()}, this method takes into account keys * that have been pushed back using {@link #runMacro(String)}. @@ -751,8 +778,8 @@ public interface LineReader { SuggestionType getAutosuggestion(); - // JDK specific modification - default void zeroOut() { - throw new UnsupportedOperationException(); - } + /** + * Clear any internal buffers. + */ + void zeroOut(); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java index 14d5a0e8b1c..942bba3605d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -38,8 +38,7 @@ public final class LineReaderBuilder { Expander expander; CompletionMatcher completionMatcher; - private LineReaderBuilder() { - } + private LineReaderBuilder() {} public LineReaderBuilder terminal(Terminal terminal) { this.terminal = terminal; @@ -88,8 +87,9 @@ public final class LineReaderBuilder { try { if (!Boolean.getBoolean(LineReader.PROP_SUPPORT_PARSEDLINE) && !(parser.parse("", 0) instanceof CompletingParsedLine)) { - Log.warn("The Parser of class " + parser.getClass().getName() + " does not support the CompletingParsedLine interface. " + - "Completion with escaped or quoted words won't work correctly."); + Log.warn("The Parser of class " + parser.getClass().getName() + + " does not support the CompletingParsedLine interface. " + + "Completion with escaped or quoted words won't work correctly."); } } catch (Throwable t) { // Ignore @@ -153,5 +153,4 @@ public final class LineReaderBuilder { } return reader; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Macro.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Macro.java index e66efcc5f92..b00769aff52 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Macro.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Macro.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -35,7 +35,6 @@ public class Macro implements Binding { @Override public String toString() { - return "Macro[" + - sequence + ']'; + return "Macro[" + sequence + ']'; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/MaskingCallback.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/MaskingCallback.java index 03501aaf07c..3b624e306f2 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/MaskingCallback.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/MaskingCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -31,5 +31,4 @@ public interface MaskingCallback { * @return the modified line */ String history(String line); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ParsedLine.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ParsedLine.java index 683c4b48d77..3d87e6b80b2 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ParsedLine.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/ParsedLine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -64,5 +64,4 @@ public interface ParsedLine { * @return the cursor position within the line */ int cursor(); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java index 1f7df67d573..5db53818f67 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -35,7 +35,7 @@ public interface Parser { default String getCommand(final String line) { String out; - Pattern patternCommand = Pattern.compile("^\\s*" + REGEX_VARIABLE + "=(" + REGEX_COMMAND + ")(\\s+|$)"); + Pattern patternCommand = Pattern.compile("^\\s*" + REGEX_VARIABLE + "=(" + REGEX_COMMAND + ")(\\s+|$)"); Matcher matcher = patternCommand.matcher(line); if (matcher.find()) { out = matcher.group(1); @@ -50,7 +50,7 @@ public interface Parser { default String getVariable(final String line) { String out = null; - Pattern patternCommand = Pattern.compile("^\\s*(" + REGEX_VARIABLE + ")\\s*=[^=~].*"); + Pattern patternCommand = Pattern.compile("^\\s*(" + REGEX_VARIABLE + ")\\s*=[^=~].*"); Matcher matcher = patternCommand.matcher(line); if (matcher.find()) { out = matcher.group(1); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java index 63c9decd194..e23988310a5 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/PrintAboveWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Reference.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Reference.java index f799a3da220..2fb1aaa671b 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Reference.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Reference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -38,7 +38,6 @@ public class Reference implements Binding { @Override public String toString() { - return "Reference[" + - name + ']'; + return "Reference[" + name + ']'; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/SyntaxError.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/SyntaxError.java index e46143e4c39..eaf3e1d7580 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/SyntaxError.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/SyntaxError.java @@ -1,20 +1,10 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * Copyright (c) 2023, the original author(s). * - * http://www.apache.org/licenses/LICENSE-2.0 + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * https://opensource.org/licenses/BSD-3-Clause */ package jdk.internal.org.jline.reader; diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java index b5510cab5c9..68bec8041fa 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,23 +14,19 @@ package jdk.internal.org.jline.reader; * interrupt character (ctrl-C). The partially entered line is * available via the {@link #getPartialLine()} method. */ -public class UserInterruptException - extends RuntimeException -{ +public class UserInterruptException extends RuntimeException { private static final long serialVersionUID = 6172232572140736750L; private final String partialLine; - public UserInterruptException(String partialLine) - { + public UserInterruptException(String partialLine) { this.partialLine = partialLine; } /** * @return the partially entered line when ctrl-C was pressed */ - public String getPartialLine() - { + public String getPartialLine() { return partialLine; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Widget.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Widget.java index d5add7fb1a7..ae831c5eaad 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Widget.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Widget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -15,5 +15,4 @@ package jdk.internal.org.jline.reader; public interface Widget extends Binding { boolean apply(); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/BufferImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/BufferImpl.java index d0c4c2cb7ae..a6295dbb487 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/BufferImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/BufferImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -20,8 +20,7 @@ import jdk.internal.org.jline.reader.Buffer; * @author Jason Dillon * @since 2.0 */ -public class BufferImpl implements Buffer -{ +public class BufferImpl implements Buffer { private int cursor = 0; private int cursorCol = -1; private int[] buffer; @@ -46,7 +45,7 @@ public class BufferImpl implements Buffer this.g1 = buffer.g1; } - public BufferImpl copy () { + public BufferImpl copy() { return new BufferImpl(this); } @@ -107,7 +106,7 @@ public class BufferImpl implements Buffer * @param c the character to insert */ public void write(int c) { - write(new int[] { c }); + write(new int[] {c}); } /** @@ -121,7 +120,7 @@ public class BufferImpl implements Buffer if (overTyping) { delete(1); } - write(new int[] { c }); + write(new int[] {c}); } /** @@ -224,8 +223,7 @@ public class BufferImpl implements Buffer if ((cursor + where) < 0) { where = -cursor; - } - else if ((cursor + where) > length()) { + } else if ((cursor + where) > length()) { where = length() - cursor; } @@ -371,7 +369,6 @@ public class BufferImpl implements Buffer } } - // JDK specific modification @Override public void zeroOut() { Arrays.fill(buffer, 0); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java index f829f13d51b..761ee1815c3 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,26 +8,25 @@ */ package jdk.internal.org.jline.reader.impl; -import jdk.internal.org.jline.reader.Candidate; -import jdk.internal.org.jline.reader.CompletingParsedLine; -import jdk.internal.org.jline.reader.CompletionMatcher; -import jdk.internal.org.jline.reader.LineReader; -import jdk.internal.org.jline.utils.AttributedString; - import java.util.*; import java.util.function.Function; import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; +import jdk.internal.org.jline.reader.Candidate; +import jdk.internal.org.jline.reader.CompletingParsedLine; +import jdk.internal.org.jline.reader.CompletionMatcher; +import jdk.internal.org.jline.reader.LineReader; +import jdk.internal.org.jline.utils.AttributedString; + public class CompletionMatcherImpl implements CompletionMatcher { protected Predicate exact; protected List>, Map>>> matchers; private Map> matching; private boolean caseInsensitive; - public CompletionMatcherImpl() { - } + public CompletionMatcherImpl() {} protected void reset(boolean caseInsensitive) { this.caseInsensitive = caseInsensitive; @@ -37,8 +36,13 @@ public class CompletionMatcherImpl implements CompletionMatcher { } @Override - public void compile(Map options, boolean prefix, CompletingParsedLine line - , boolean caseInsensitive, int errors, String originalGroupName) { + public void compile( + Map options, + boolean prefix, + CompletingParsedLine line, + boolean caseInsensitive, + int errors, + String originalGroupName) { reset(caseInsensitive); defaultMatchers(options, prefix, line, caseInsensitive, errors, originalGroupName); } @@ -47,15 +51,18 @@ public class CompletionMatcherImpl implements CompletionMatcher { public List matches(List candidates) { matching = Collections.emptyMap(); Map> sortedCandidates = sort(candidates); - for (Function>, - Map>> matcher : matchers) { + for (Function>, Map>> matcher : matchers) { matching = matcher.apply(sortedCandidates); if (!matching.isEmpty()) { break; } } - return !matching.isEmpty() ? matching.entrySet().stream().flatMap(e -> e.getValue().stream()).distinct().collect(Collectors.toList()) - : new ArrayList<>(); + return !matching.isEmpty() + ? matching.entrySet().stream() + .flatMap(e -> e.getValue().stream()) + .distinct() + .collect(Collectors.toList()) + : new ArrayList<>(); } @Override @@ -63,10 +70,12 @@ public class CompletionMatcherImpl implements CompletionMatcher { if (matching == null) { throw new IllegalStateException(); } - return matching.values().stream().flatMap(Collection::stream) + return matching.values().stream() + .flatMap(Collection::stream) .filter(Candidate::complete) .filter(c -> exact.test(c.value())) - .findFirst().orElse(null); + .findFirst() + .orElse(null); } @Override @@ -84,8 +93,13 @@ public class CompletionMatcherImpl implements CompletionMatcher { /** * Default JLine matchers */ - protected void defaultMatchers(Map options, boolean prefix, CompletingParsedLine line - , boolean caseInsensitive, int errors, String originalGroupName) { + protected void defaultMatchers( + Map options, + boolean prefix, + CompletingParsedLine line, + boolean caseInsensitive, + int errors, + String originalGroupName) { // Find matchers // TODO: glob completion String wd = line.word(); @@ -94,8 +108,7 @@ public class CompletionMatcherImpl implements CompletionMatcher { if (prefix) { matchers = new ArrayList<>(Arrays.asList( simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).startsWith(wp)), - simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wp)) - )); + simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wp)))); if (LineReader.Option.COMPLETE_MATCHER_TYPO.isSet(options)) { matchers.add(typoMatcher(wp, errors, caseInsensitive, originalGroupName)); } @@ -109,14 +122,14 @@ public class CompletionMatcherImpl implements CompletionMatcher { Pattern p1 = Pattern.compile(Pattern.quote(wp) + ".*" + Pattern.quote(ws) + ".*"); Pattern p2 = Pattern.compile(".*" + Pattern.quote(wp) + ".*" + Pattern.quote(ws) + ".*"); matchers = new ArrayList<>(Arrays.asList( - simpleMatcher(s -> p1.matcher(caseInsensitive ? s.toLowerCase() : s).matches()), - simpleMatcher(s -> p2.matcher(caseInsensitive ? s.toLowerCase() : s).matches()) - )); + simpleMatcher(s -> p1.matcher(caseInsensitive ? s.toLowerCase() : s) + .matches()), + simpleMatcher(s -> p2.matcher(caseInsensitive ? s.toLowerCase() : s) + .matches()))); } else { matchers = new ArrayList<>(Arrays.asList( simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).startsWith(wdi)), - simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wdi)) - )); + simpleMatcher(s -> (caseInsensitive ? s.toLowerCase() : s).contains(wdi)))); } if (LineReader.Option.COMPLETE_MATCHER_CAMELCASE.isSet(options)) { matchers.add(simpleMatcher(s -> camelMatch(wd, 0, s, 0))); @@ -128,18 +141,20 @@ public class CompletionMatcherImpl implements CompletionMatcher { } } - protected Function>, - Map>> simpleMatcher(Predicate predicate) { + protected Function>, Map>> simpleMatcher( + Predicate predicate) { return m -> m.entrySet().stream() .filter(e -> predicate.test(e.getKey())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } - protected Function>, - Map>> typoMatcher(String word, int errors, boolean caseInsensitive, String originalGroupName) { + protected Function>, Map>> typoMatcher( + String word, int errors, boolean caseInsensitive, String originalGroupName) { return m -> { Map> map = m.entrySet().stream() - .filter(e -> ReaderUtils.distance(word, caseInsensitive ? e.getKey().toLowerCase() : e.getKey()) < errors) + .filter(e -> ReaderUtils.distance( + word, caseInsensitive ? e.getKey().toLowerCase() : e.getKey()) + < errors) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); if (map.size() > 1) { map.computeIfAbsent(word, w -> new ArrayList<>()) @@ -178,7 +193,8 @@ public class CompletionMatcherImpl implements CompletionMatcher { Map> sortedCandidates = new HashMap<>(); for (Candidate candidate : candidates) { sortedCandidates - .computeIfAbsent(AttributedString.fromAnsi(candidate.value()).toString(), s -> new ArrayList<>()) + .computeIfAbsent( + AttributedString.fromAnsi(candidate.value()).toString(), s -> new ArrayList<>()) .add(candidate); } return sortedCandidates; @@ -206,5 +222,4 @@ public class CompletionMatcherImpl implements CompletionMatcher { } return new String(s1, 0, len); } - -} \ No newline at end of file +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultExpander.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultExpander.java index b534b96ff2f..e5e7735a384 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultExpander.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultExpander.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -32,27 +32,25 @@ public class DefaultExpander implements Expander { if (unicode > 0) { escaped = (--unicode >= 0); sb.append(c); - } - else if (escaped) { + } else if (escaped) { if (c == 'u') { unicode = 4; } else { escaped = false; } sb.append(c); - } - else if (c == '\'') { + } else if (c == '\'') { inQuote = !inQuote; sb.append(c); - } - else if (inQuote) { + } else if (inQuote) { sb.append(c); - } - else { + } else { switch (c) { case '\\': - // any '\!' should be considered an expansion escape, so skip expansion and strip the escape character - // a leading '\^' should be considered an expansion escape, so skip expansion and strip the escape character + // any '\!' should be considered an expansion escape, so skip expansion and strip the escape + // character + // a leading '\^' should be considered an expansion escape, so skip expansion and strip the + // escape character // otherwise, add the escape escaped = true; sb.append(c); @@ -91,7 +89,8 @@ public class DefaultExpander implements Expander { if (history.size() == 0) { throw new IllegalArgumentException("!$: event not found"); } - String previous = history.get(history.index() - 1).trim(); + String previous = + history.get(history.index() - 1).trim(); int lastSpace = previous.lastIndexOf(' '); if (lastSpace != -1) { rep = previous.substring(lastSpace + 1); @@ -128,14 +127,18 @@ public class DefaultExpander implements Expander { try { idx = Integer.parseInt(line.substring(i1, i)); } catch (NumberFormatException e) { - throw new IllegalArgumentException((neg ? "!-" : "!") + line.substring(i1, i) + ": event not found"); + throw new IllegalArgumentException( + (neg ? "!-" : "!") + line.substring(i1, i) + ": event not found"); } if (neg && idx > 0 && idx <= history.size()) { rep = history.get(history.index() - idx); - } else if (!neg && idx > history.index() - history.size() && idx <= history.index()) { + } else if (!neg + && idx > history.index() - history.size() + && idx <= history.index()) { rep = history.get(idx - 1); } else { - throw new IllegalArgumentException((neg ? "!-" : "!") + line.substring(i1, i) + ": event not found"); + throw new IllegalArgumentException( + (neg ? "!-" : "!") + line.substring(i1, i) + ": event not found"); } break; default: diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java index ac286ad734f..55d39efde27 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -10,9 +10,9 @@ package jdk.internal.org.jline.reader.impl; import java.util.regex.Pattern; +import jdk.internal.org.jline.reader.Highlighter; import jdk.internal.org.jline.reader.LineReader; import jdk.internal.org.jline.reader.LineReader.RegionType; -import jdk.internal.org.jline.reader.Highlighter; import jdk.internal.org.jline.utils.AttributedString; import jdk.internal.org.jline.utils.AttributedStringBuilder; import jdk.internal.org.jline.utils.AttributedStyle; @@ -57,7 +57,8 @@ public class DefaultHighlighter implements Highlighter { while (negativeStart > 0 && reader.getBuffer().atChar(negativeStart - 1) != '\n') { negativeStart--; } - while (negativeEnd < reader.getBuffer().length() - 1 && reader.getBuffer().atChar(negativeEnd + 1) != '\n') { + while (negativeEnd < reader.getBuffer().length() - 1 + && reader.getBuffer().atChar(negativeEnd + 1) != '\n') { negativeEnd++; } } @@ -104,5 +105,4 @@ public class DefaultHighlighter implements Highlighter { } return sb.toAttributedString(); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java index d9b3a9948d5..26cdf6abc51 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -21,18 +21,18 @@ import jdk.internal.org.jline.reader.Parser; public class DefaultParser implements Parser { public enum Bracket { - ROUND, // () - CURLY, // {} - SQUARE, // [] - ANGLE // <> + ROUND, // () + CURLY, // {} + SQUARE, // [] + ANGLE // <> } public static class BlockCommentDelims { private final String start; private final String end; + public BlockCommentDelims(String start, String end) { - if (start == null || end == null - || start.isEmpty() || end.isEmpty() || start.equals(end)) { + if (start == null || end == null || start.isEmpty() || end.isEmpty() || start.equals(end)) { throw new IllegalArgumentException("Bad block comment delimiter!"); } this.start = start; @@ -185,22 +185,22 @@ public class DefaultParser implements Parser { int i = 0; for (Bracket b : bs) { switch (b) { - case ROUND: - openingBrackets[i] = '('; - closingBrackets[i] = ')'; - break; - case CURLY: - openingBrackets[i] = '{'; - closingBrackets[i] = '}'; - break; - case SQUARE: - openingBrackets[i] = '['; - closingBrackets[i] = ']'; - break; - case ANGLE: - openingBrackets[i] = '<'; - closingBrackets[i] = '>'; - break; + case ROUND: + openingBrackets[i] = '('; + closingBrackets[i] = ')'; + break; + case CURLY: + openingBrackets[i] = '{'; + closingBrackets[i] = '}'; + break; + case SQUARE: + openingBrackets[i] = '['; + closingBrackets[i] = ']'; + break; + case ANGLE: + openingBrackets[i] = '<'; + closingBrackets[i] = '>'; + break; } i++; } @@ -229,7 +229,6 @@ public class DefaultParser implements Parser { return name != null && regexVariable != null && name.matches(regexVariable); } - @Override public String getCommand(final String line) { String out = ""; @@ -296,7 +295,7 @@ public class DefaultParser implements Parser { if (quoteStart < 0 && isQuoteChar(line, i) && !lineCommented && !blockCommented) { // Start a quote block quoteStart = i; - if (current.length()==0) { + if (current.length() == 0) { quotedWord = true; if (context == ParseContext.SPLIT_LINE) { current.append(line.charAt(i)); @@ -324,13 +323,15 @@ public class DefaultParser implements Parser { } } else { // Delimiter - rawWordLength = handleDelimiterAndGetRawWordLength(current, words, rawWordStart, rawWordCursor, rawWordLength, i); + rawWordLength = handleDelimiterAndGetRawWordLength( + current, words, rawWordStart, rawWordCursor, rawWordLength, i); rawWordStart = i + 1; } } else { if (quoteStart < 0 && !blockCommented && (lineCommented || isLineCommentStarted(line, i))) { lineCommented = true; - } else if (quoteStart < 0 && !lineCommented + } else if (quoteStart < 0 + && !lineCommented && (blockCommented || isCommentDelim(line, i, blockCommentStart))) { if (blockCommented) { if (blockCommentEnd != null && isCommentDelim(line, i, blockCommentEnd)) { @@ -339,12 +340,12 @@ public class DefaultParser implements Parser { } } else { blockCommented = true; - rawWordLength = handleDelimiterAndGetRawWordLength(current, words, rawWordStart, rawWordCursor, rawWordLength, i); + rawWordLength = handleDelimiterAndGetRawWordLength( + current, words, rawWordStart, rawWordCursor, rawWordLength, i); i += blockCommentStart == null ? 0 : blockCommentStart.length() - 1; rawWordStart = i + 1; } - } else if (quoteStart < 0 && !lineCommented - && isCommentDelim(line, i, blockCommentEnd)) { + } else if (quoteStart < 0 && !lineCommented && isCommentDelim(line, i, blockCommentEnd)) { current.append(line.charAt(i)); blockCommentInRightOrder = false; } else if (!isEscapeChar(line, i)) { @@ -377,16 +378,14 @@ public class DefaultParser implements Parser { throw new EOFError(-1, -1, "Escaped new line", "newline"); } if (eofOnUnclosedQuote && quoteStart >= 0) { - throw new EOFError(-1, -1, "Missing closing quote", line.charAt(quoteStart) == '\'' - ? "quote" : "dquote"); + throw new EOFError( + -1, -1, "Missing closing quote", line.charAt(quoteStart) == '\'' ? "quote" : "dquote"); } if (blockCommented) { - throw new EOFError(-1, -1, "Missing closing block comment delimiter", - "add: " + blockCommentEnd); + throw new EOFError(-1, -1, "Missing closing block comment delimiter", "add: " + blockCommentEnd); } if (!blockCommentInRightOrder) { - throw new EOFError(-1, -1, "Missing opening block comment delimiter", - "missing: " + blockCommentStart); + throw new EOFError(-1, -1, "Missing opening block comment delimiter", "missing: " + blockCommentStart); } if (bracketChecker.isClosingBracketMissing() || bracketChecker.isOpeningBracketMissing()) { String message = null; @@ -398,8 +397,13 @@ public class DefaultParser implements Parser { message = "Missing opening bracket"; missing = "missing: " + bracketChecker.getMissingOpeningBracket(); } - throw new EOFError(-1, -1, message, missing, - bracketChecker.getOpenBrackets(), bracketChecker.getNextClosingBracket()); + throw new EOFError( + -1, + -1, + message, + missing, + bracketChecker.getOpenBrackets(), + bracketChecker.getNextClosingBracket()); } } @@ -420,7 +424,13 @@ public class DefaultParser implements Parser { return !isQuoted(buffer, pos) && !isEscaped(buffer, pos) && isDelimiterChar(buffer, pos); } - private int handleDelimiterAndGetRawWordLength(StringBuilder current, List words, int rawWordStart, int rawWordCursor, int rawWordLength, int pos) { + private int handleDelimiterAndGetRawWordLength( + StringBuilder current, + List words, + int rawWordStart, + int rawWordCursor, + int rawWordLength, + int pos) { if (current.length() > 0) { words.add(current.toString()); current.setLength(0); // reset the arg @@ -470,7 +480,7 @@ public class DefaultParser implements Parser { public boolean isLineCommentStarted(final CharSequence buffer, final int pos) { if (lineCommentDelims != null) { - for (String comment: lineCommentDelims) { + for (String comment : lineCommentDelims) { if (isCommentDelim(buffer, pos, comment)) { return true; } @@ -584,8 +594,8 @@ public class DefaultParser implements Parser { } else { bid = bracketId(closingBrackets, buffer, pos); if (bid >= 0) { - if (!nested.isEmpty() && bid == nested.get(nested.size()-1)) { - nested.remove(nested.size()-1); + if (!nested.isEmpty() && bid == nested.get(nested.size() - 1)) { + nested.remove(nested.size() - 1); } else { missingOpeningBracket = bid; } @@ -634,7 +644,7 @@ public class DefaultParser implements Parser { } private int bracketId(final char[] brackets, final CharSequence buffer, final int pos) { - for (int i=0; i < brackets.length; i++) { + for (int i = 0; i < brackets.length; i++) { if (buffer.charAt(pos) == brackets[i]) { return i; } @@ -648,8 +658,7 @@ public class DefaultParser implements Parser { * * @author Marc Prud'hommeaux */ - public class ArgumentList implements ParsedLine, CompletingParsedLine - { + public class ArgumentList implements ParsedLine, CompletingParsedLine { private final String line; private final List words; @@ -667,11 +676,21 @@ public class DefaultParser implements Parser { private final int rawWordLength; @Deprecated - public ArgumentList(final String line, final List words, - final int wordIndex, final int wordCursor, - final int cursor) { - this(line, words, wordIndex, wordCursor, cursor, - null, wordCursor, words.get(wordIndex).length()); + public ArgumentList( + final String line, + final List words, + final int wordIndex, + final int wordCursor, + final int cursor) { + this( + line, + words, + wordIndex, + wordCursor, + cursor, + null, + wordCursor, + words.get(wordIndex).length()); } /** @@ -685,10 +704,15 @@ public class DefaultParser implements Parser { * @param rawWordCursor the cursor position inside the raw word (i.e. including quotes and escape characters) * @param rawWordLength the raw word length, including quotes and escape characters */ - public ArgumentList(final String line, final List words, - final int wordIndex, final int wordCursor, - final int cursor, final String openingQuote, - final int rawWordCursor, final int rawWordLength) { + public ArgumentList( + final String line, + final List words, + final int wordIndex, + final int wordCursor, + final int cursor, + final String openingQuote, + final int rawWordCursor, + final int rawWordLength) { this.line = line; this.words = Collections.unmodifiableList(Objects.requireNonNull(words)); this.wordIndex = wordIndex; @@ -732,8 +756,8 @@ public class DefaultParser implements Parser { Predicate needToBeEscaped; String quote = openingQuote; boolean middleQuotes = false; - if (openingQuote==null) { - for (int i=0; i < sb.length(); i++) { + if (openingQuote == null) { + for (int i = 0; i < sb.length(); i++) { if (isQuoteChar(sb, i)) { middleQuotes = true; break; @@ -746,7 +770,8 @@ public class DefaultParser implements Parser { // Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does. // Also, close the quote at the end if (openingQuote != null) { - needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote); + needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) + || String.valueOf(sb.charAt(i)).equals(openingQuote); } // Completion is protected by middle quotes: // Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does. @@ -756,8 +781,8 @@ public class DefaultParser implements Parser { // No quote protection, need to escape everything: delimiter chars (spaces), quote chars // and escapes themselves else { - needToBeEscaped = i -> isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i)) - || isRawQuoteChar(sb.charAt(i)); + needToBeEscaped = i -> + isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i)) || isRawQuoteChar(sb.charAt(i)); } for (int i = 0; i < sb.length(); i++) { if (needToBeEscaped.test(i)) { @@ -792,5 +817,4 @@ public class DefaultParser implements Parser { return rawWordLength; } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/InputRC.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/InputRC.java new file mode 100644 index 00000000000..0c3aee057a4 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/InputRC.java @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2002-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.reader.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import jdk.internal.org.jline.reader.LineReader; +import jdk.internal.org.jline.reader.Macro; +import jdk.internal.org.jline.reader.Reference; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.utils.Log; + +public final class InputRC { + + public static void configure(LineReader reader, URL url) throws IOException { + try (InputStream is = url.openStream()) { + configure(reader, is); + } + } + + public static void configure(LineReader reader, InputStream is) throws IOException { + try (InputStreamReader r = new InputStreamReader(is)) { + configure(reader, r); + } + } + + public static void configure(LineReader reader, Reader r) throws IOException { + BufferedReader br; + if (r instanceof BufferedReader) { + br = (BufferedReader) r; + } else { + br = new BufferedReader(r); + } + + Terminal terminal = reader.getTerminal(); + + if (Terminal.TYPE_DUMB.equals(terminal.getType()) || Terminal.TYPE_DUMB_COLOR.equals(terminal.getType())) { + reader.getVariables().putIfAbsent(LineReader.EDITING_MODE, "dumb"); + } else { + reader.getVariables().putIfAbsent(LineReader.EDITING_MODE, "emacs"); + } + + reader.setKeyMap(LineReader.MAIN); + new InputRC(reader).parse(br); + if ("vi".equals(reader.getVariable(LineReader.EDITING_MODE))) { + reader.getKeyMaps().put(LineReader.MAIN, reader.getKeyMaps().get(LineReader.VIINS)); + } else if ("emacs".equals(reader.getVariable(LineReader.EDITING_MODE))) { + reader.getKeyMaps().put(LineReader.MAIN, reader.getKeyMaps().get(LineReader.EMACS)); + } else if ("dumb".equals(reader.getVariable(LineReader.EDITING_MODE))) { + reader.getKeyMaps().put(LineReader.MAIN, reader.getKeyMaps().get(LineReader.DUMB)); + } + } + + private final LineReader reader; + + private InputRC(LineReader reader) { + this.reader = reader; + } + + private void parse(BufferedReader br) throws IOException, IllegalArgumentException { + String line; + boolean parsing = true; + List ifsStack = new ArrayList<>(); + while ((line = br.readLine()) != null) { + try { + line = line.trim(); + if (line.length() == 0) { + continue; + } + if (line.charAt(0) == '#') { + continue; + } + int i = 0; + if (line.charAt(i) == '$') { + String cmd; + String args; + ++i; + while (i < line.length() && (line.charAt(i) == ' ' || line.charAt(i) == '\t')) { + i++; + } + int s = i; + while (i < line.length() && (line.charAt(i) != ' ' && line.charAt(i) != '\t')) { + i++; + } + cmd = line.substring(s, i); + while (i < line.length() && (line.charAt(i) == ' ' || line.charAt(i) == '\t')) { + i++; + } + s = i; + while (i < line.length() && (line.charAt(i) != ' ' && line.charAt(i) != '\t')) { + i++; + } + args = line.substring(s, i); + if ("if".equalsIgnoreCase(cmd)) { + ifsStack.add(parsing); + if (!parsing) { + continue; + } + if (args.startsWith("term=")) { + // TODO + } else if (args.startsWith("mode=")) { + String mode = (String) reader.getVariable(LineReader.EDITING_MODE); + parsing = args.substring("mode=".length()).equalsIgnoreCase(mode); + } else { + parsing = args.equalsIgnoreCase(reader.getAppName()); + } + } else if ("else".equalsIgnoreCase(cmd)) { + if (ifsStack.isEmpty()) { + throw new IllegalArgumentException("$else found without matching $if"); + } + boolean invert = true; + for (boolean b : ifsStack) { + if (!b) { + invert = false; + break; + } + } + if (invert) { + parsing = !parsing; + } + } else if ("endif".equalsIgnoreCase(cmd)) { + if (ifsStack.isEmpty()) { + throw new IllegalArgumentException("endif found without matching $if"); + } + parsing = ifsStack.remove(ifsStack.size() - 1); + } else if ("include".equalsIgnoreCase(cmd)) { + // TODO + } + continue; + } + if (!parsing) { + continue; + } + if (line.charAt(i++) == '"') { + boolean esc = false; + for (; ; i++) { + if (i >= line.length()) { + throw new IllegalArgumentException("Missing closing quote on line '" + line + "'"); + } + if (esc) { + esc = false; + } else if (line.charAt(i) == '\\') { + esc = true; + } else if (line.charAt(i) == '"') { + break; + } + } + } + while (i < line.length() && line.charAt(i) != ':' && line.charAt(i) != ' ' && line.charAt(i) != '\t') { + i++; + } + String keySeq = line.substring(0, i); + boolean equivalency = i + 1 < line.length() && line.charAt(i) == ':' && line.charAt(i + 1) == '='; + i++; + if (equivalency) { + i++; + } + if (keySeq.equalsIgnoreCase("set")) { + String key; + String val; + while (i < line.length() && (line.charAt(i) == ' ' || line.charAt(i) == '\t')) { + i++; + } + int s = i; + while (i < line.length() && (line.charAt(i) != ' ' && line.charAt(i) != '\t')) { + i++; + } + key = line.substring(s, i); + while (i < line.length() && (line.charAt(i) == ' ' || line.charAt(i) == '\t')) { + i++; + } + s = i; + while (i < line.length() && (line.charAt(i) != ' ' && line.charAt(i) != '\t')) { + i++; + } + val = line.substring(s, i); + setVar(reader, key, val); + } else { + while (i < line.length() && (line.charAt(i) == ' ' || line.charAt(i) == '\t')) { + i++; + } + int start = i; + if (i < line.length() && (line.charAt(i) == '\'' || line.charAt(i) == '\"')) { + char delim = line.charAt(i++); + boolean esc = false; + for (; ; i++) { + if (i >= line.length()) { + break; + } + if (esc) { + esc = false; + } else if (line.charAt(i) == '\\') { + esc = true; + } else if (line.charAt(i) == delim) { + break; + } + } + } + for (; i < line.length() && line.charAt(i) != ' ' && line.charAt(i) != '\t'; i++) + ; + String val = line.substring(Math.min(start, line.length()), Math.min(i, line.length())); + if (keySeq.charAt(0) == '"') { + keySeq = translateQuoted(keySeq); + } else { + // Bind key name + String keyName = + keySeq.lastIndexOf('-') > 0 ? keySeq.substring(keySeq.lastIndexOf('-') + 1) : keySeq; + char key = getKeyFromName(keyName); + keyName = keySeq.toLowerCase(); + keySeq = ""; + if (keyName.contains("meta-") || keyName.contains("m-")) { + keySeq += "\u001b"; + } + if (keyName.contains("control-") || keyName.contains("c-") || keyName.contains("ctrl-")) { + key = (char) (Character.toUpperCase(key) & 0x1f); + } + keySeq += key; + } + if (val.length() > 0 && (val.charAt(0) == '\'' || val.charAt(0) == '\"')) { + reader.getKeys().bind(new Macro(translateQuoted(val)), keySeq); + } else { + reader.getKeys().bind(new Reference(val), keySeq); + } + } + } catch (IllegalArgumentException e) { + Log.warn("Unable to parse user configuration: ", e); + } + } + } + + private static String translateQuoted(String keySeq) { + int i; + String str = keySeq.substring(1, keySeq.length() - 1); + StringBuilder sb = new StringBuilder(); + for (i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '\\') { + boolean ctrl = str.regionMatches(i, "\\C-", 0, 3) || str.regionMatches(i, "\\M-\\C-", 0, 6); + boolean meta = str.regionMatches(i, "\\M-", 0, 3) || str.regionMatches(i, "\\C-\\M-", 0, 6); + i += (meta ? 3 : 0) + (ctrl ? 3 : 0) + (!meta && !ctrl ? 1 : 0); + if (i >= str.length()) { + break; + } + c = str.charAt(i); + if (meta) { + sb.append("\u001b"); + } + if (ctrl) { + c = c == '?' ? 0x7f : (char) (Character.toUpperCase(c) & 0x1f); + } + if (!meta && !ctrl) { + switch (c) { + case 'a': + c = 0x07; + break; + case 'b': + c = '\b'; + break; + case 'd': + c = 0x7f; + break; + case 'e': + c = 0x1b; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = 0x0b; + break; + case '\\': + c = '\\'; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + c = 0; + for (int j = 0; j < 3; j++, i++) { + if (i >= str.length()) { + break; + } + int k = Character.digit(str.charAt(i), 8); + if (k < 0) { + break; + } + c = (char) (c * 8 + k); + } + c &= 0xFF; + break; + case 'x': + i++; + c = 0; + for (int j = 0; j < 2; j++, i++) { + if (i >= str.length()) { + break; + } + int k = Character.digit(str.charAt(i), 16); + if (k < 0) { + break; + } + c = (char) (c * 16 + k); + } + c &= 0xFF; + break; + case 'u': + i++; + c = 0; + for (int j = 0; j < 4; j++, i++) { + if (i >= str.length()) { + break; + } + int k = Character.digit(str.charAt(i), 16); + if (k < 0) { + break; + } + c = (char) (c * 16 + k); + } + break; + } + } + sb.append(c); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + private static char getKeyFromName(String name) { + if ("DEL".equalsIgnoreCase(name) || "Rubout".equalsIgnoreCase(name)) { + return 0x7f; + } else if ("ESC".equalsIgnoreCase(name) || "Escape".equalsIgnoreCase(name)) { + return '\033'; + } else if ("LFD".equalsIgnoreCase(name) || "NewLine".equalsIgnoreCase(name)) { + return '\n'; + } else if ("RET".equalsIgnoreCase(name) || "Return".equalsIgnoreCase(name)) { + return '\r'; + } else if ("SPC".equalsIgnoreCase(name) || "Space".equalsIgnoreCase(name)) { + return ' '; + } else if ("Tab".equalsIgnoreCase(name)) { + return '\t'; + } else { + return name.charAt(0); + } + } + + static void setVar(LineReader reader, String key, String val) { + if (LineReader.KEYMAP.equalsIgnoreCase(key)) { + reader.setKeyMap(val); + return; + } + + for (LineReader.Option option : LineReader.Option.values()) { + if (option.name().toLowerCase(Locale.ENGLISH).replace('_', '-').equals(val)) { + if ("on".equalsIgnoreCase(val)) { + reader.setOpt(option); + } else if ("off".equalsIgnoreCase(val)) { + reader.unsetOpt(option); + } + return; + } + } + + reader.setVariable(key, val); + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/KillRing.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/KillRing.java index f89ed35d04e..2510fd9e320 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/KillRing.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/KillRing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java index a41f7d19bf8..da69d08b23c 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2022, the original author or authors. + * Copyright (c) 2002-2023, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -18,6 +18,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.lang.reflect.Constructor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.Instant; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -56,6 +59,7 @@ import static jdk.internal.org.jline.keymap.KeyMap.del; import static jdk.internal.org.jline.keymap.KeyMap.esc; import static jdk.internal.org.jline.keymap.KeyMap.range; import static jdk.internal.org.jline.keymap.KeyMap.translate; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_DISABLE_ALTERNATE_CHARSET; /** * A reader for terminal applications. It supports custom tab-completion, @@ -66,23 +70,27 @@ import static jdk.internal.org.jline.keymap.KeyMap.translate; * @author Guillaume Nodet */ @SuppressWarnings("StatementWithEmptyBody") -public class LineReaderImpl implements LineReader, Flushable -{ +public class LineReaderImpl implements LineReader, Flushable { public static final char NULL_MASK = 0; + /** + * @deprecated use {@link #DEFAULT_TAB_WIDTH} and {@link #getTabWidth()} + */ + @Deprecated public static final int TAB_WIDTH = 4; + public static final int DEFAULT_TAB_WIDTH = 4; public static final String DEFAULT_WORDCHARS = "*?_-.[]~=/&;!#$%^(){}<>"; public static final String DEFAULT_REMOVE_SUFFIX_CHARS = " \t\n;&|"; public static final String DEFAULT_COMMENT_BEGIN = "#"; public static final String DEFAULT_SEARCH_TERMINATORS = "\033\012"; public static final String DEFAULT_BELL_STYLE = ""; - public static final int DEFAULT_LIST_MAX = 100; - public static final int DEFAULT_MENU_LIST_MAX = Integer.MAX_VALUE; - public static final int DEFAULT_ERRORS = 2; - public static final long DEFAULT_BLINK_MATCHING_PAREN = 500L; - public static final long DEFAULT_AMBIGUOUS_BINDING = 1000L; + public static final int DEFAULT_LIST_MAX = 100; + public static final int DEFAULT_MENU_LIST_MAX = Integer.MAX_VALUE; + public static final int DEFAULT_ERRORS = 2; + public static final long DEFAULT_BLINK_MATCHING_PAREN = 500L; + public static final long DEFAULT_AMBIGUOUS_BINDING = 1000L; public static final String DEFAULT_SECONDARY_PROMPT_PATTERN = "%M> "; public static final String DEFAULT_OTHERS_GROUP_NAME = "others"; public static final String DEFAULT_ORIGINAL_GROUP_NAME = "original"; @@ -96,9 +104,10 @@ public class LineReaderImpl implements LineReader, Flushable public static final String DEFAULT_COMPLETION_STYLE_LIST_GROUP = "fg:black,bold"; public static final String DEFAULT_COMPLETION_STYLE_LIST_SELECTION = DEFAULT_COMPLETION_STYLE_SELECTION; public static final String DEFAULT_COMPLETION_STYLE_LIST_BACKGROUND = "bg:bright-magenta"; - public static final int DEFAULT_INDENTATION = 0; - public static final int DEFAULT_FEATURES_MAX_BUFFER_SIZE = 1000; - public static final int DEFAULT_SUGGESTIONS_MIN_BUFFER_SIZE = 1; + public static final int DEFAULT_INDENTATION = 0; + public static final int DEFAULT_FEATURES_MAX_BUFFER_SIZE = 1000; + public static final int DEFAULT_SUGGESTIONS_MIN_BUFFER_SIZE = 1; + public static final String DEFAULT_SYSTEM_PROPERTY_PREFIX = "org.jline.reader.props."; private static final int MIN_ROWS = 3; @@ -109,6 +118,7 @@ public class LineReaderImpl implements LineReader, Flushable public static final String FOCUS_IN_SEQ = "\033[I"; public static final String FOCUS_OUT_SEQ = "\033[O"; + public static final int DEFAULT_MAX_REPEAT_COUNT = 9999; /** * Possible states in which the current readline operation may be in. @@ -197,27 +207,28 @@ public class LineReaderImpl implements LineReader, Flushable protected int searchIndex = -1; protected boolean doAutosuggestion; - // Reading buffers protected final BindingReader bindingReader; - /** * VI character find */ protected int findChar; + protected int findDir; protected int findTailAdd; /** * VI history string search */ private int searchDir; + private String searchString; /** * Region state */ protected int regionMark; + protected RegionType regionActive; private boolean forceChar; @@ -232,7 +243,7 @@ public class LineReaderImpl implements LineReader, Flushable protected KillRing killRing = new KillRing(); - protected UndoTree undo = new UndoTree<>(this::setBuffer); + protected UndoTree undo; protected boolean isUndo; /** @@ -242,7 +253,7 @@ public class LineReaderImpl implements LineReader, Flushable /* * Current internal state of the line reader */ - protected State state = State.DONE; + protected State state = State.DONE; protected final AtomicBoolean startedReading = new AtomicBoolean(); protected boolean reading; @@ -278,7 +289,10 @@ public class LineReaderImpl implements LineReader, Flushable */ protected List commandsBuffer = new ArrayList<>(); - int candidateStartPosition = 0; + protected int candidateStartPosition = 0; + + protected String alternateIn; + protected String alternateOut; public LineReaderImpl(Terminal terminal) throws IOException { this(terminal, terminal.getName(), null); @@ -288,6 +302,7 @@ public class LineReaderImpl implements LineReader, Flushable this(terminal, appName, null); } + @SuppressWarnings("this-escape") public LineReaderImpl(Terminal terminal, String appName, Map variables) { Objects.requireNonNull(terminal, "terminal can not be null"); this.terminal = terminal; @@ -300,11 +315,40 @@ public class LineReaderImpl implements LineReader, Flushable } else { this.variables = new HashMap<>(); } - this.keyMaps = defaultKeyMaps(); + String prefix = getString(SYSTEM_PROPERTY_PREFIX, DEFAULT_SYSTEM_PROPERTY_PREFIX); + if (prefix != null) { + Properties sysProps = System.getProperties(); + for (String s : sysProps.stringPropertyNames()) { + if (s.startsWith(prefix)) { + String key = s.substring(prefix.length()); + InputRC.setVar(this, key, sysProps.getProperty(s)); + } + } + } + this.keyMaps = defaultKeyMaps(); + if (!Boolean.getBoolean(PROP_DISABLE_ALTERNATE_CHARSET)) { + this.alternateIn = Curses.tputs(terminal.getStringCapability(Capability.enter_alt_charset_mode)); + this.alternateOut = Curses.tputs(terminal.getStringCapability(Capability.exit_alt_charset_mode)); + } + + undo = new UndoTree<>(this::setBuffer); builtinWidgets = builtinWidgets(); widgets = new HashMap<>(builtinWidgets); bindingReader = new BindingReader(terminal.reader()); + + String inputRc = getString(INPUT_RC_FILE_NAME, null); + if (inputRc != null) { + Path inputRcPath = Paths.get(inputRc); + if (Files.exists(inputRcPath)) { + try (InputStream is = Files.newInputStream(inputRcPath)) { + InputRC.configure(this, is); + } catch (Exception e) { + Log.debug("Error reading inputRc config file: ", inputRc, e); + } + } + } + doDisplay(); } @@ -489,7 +533,8 @@ public class LineReaderImpl implements LineReader, Flushable * @param buffer A string that will be set for editing. * @return A line that is read from the terminal, can never be null. */ - public String readLine(String prompt, Character mask, String buffer) throws UserInterruptException, EndOfFileException { + public String readLine(String prompt, Character mask, String buffer) + throws UserInterruptException, EndOfFileException { return readLine(prompt, null, mask, buffer); } @@ -503,7 +548,8 @@ public class LineReaderImpl implements LineReader, Flushable * @param buffer A string that will be set for editing. * @return A line that is read from the terminal, can never be null. */ - public String readLine(String prompt, String rightPrompt, Character mask, String buffer) throws UserInterruptException, EndOfFileException { + public String readLine(String prompt, String rightPrompt, Character mask, String buffer) + throws UserInterruptException, EndOfFileException { return readLine(prompt, rightPrompt, mask != null ? new SimpleMaskingCallback(mask) : null, buffer); } @@ -517,7 +563,8 @@ public class LineReaderImpl implements LineReader, Flushable * @param buffer A string that will be set for editing. * @return A line that is read from the terminal, can never be null. */ - public String readLine(String prompt, String rightPrompt, MaskingCallback maskingCallback, String buffer) throws UserInterruptException, EndOfFileException { + public String readLine(String prompt, String rightPrompt, MaskingCallback maskingCallback, String buffer) + throws UserInterruptException, EndOfFileException { // prompt may be null // maskingCallback may be null // buffer may be null @@ -618,23 +665,14 @@ public class LineReaderImpl implements LineReader, Flushable // Move into application mode if (!dumb) { terminal.puts(Capability.keypad_xmit); - if (isSet(Option.AUTO_FRESH_LINE)) - callWidget(FRESH_LINE); - if (isSet(Option.MOUSE)) - terminal.trackMouse(Terminal.MouseTracking.Normal); - if (isSet(Option.BRACKETED_PASTE)) - terminal.writer().write(BRACKETED_PASTE_ON); - } else { - // For dumb terminals, we need to make sure that CR are ignored - Attributes attr = new Attributes(originalAttributes); - attr.setInputFlag(Attributes.InputFlag.IGNCR, true); - terminal.setAttributes(attr); + if (isSet(Option.AUTO_FRESH_LINE)) callWidget(FRESH_LINE); + if (isSet(Option.MOUSE)) terminal.trackMouse(Terminal.MouseTracking.Normal); + if (isSet(Option.BRACKETED_PASTE)) terminal.writer().write(BRACKETED_PASTE_ON); } callWidget(CALLBACK_INIT); - if (!isSet(Option.DISABLE_UNDO)) - undo.newState(buf.copy()); + if (!isSet(Option.DISABLE_UNDO)) undo.newState(buf.copy()); // Draw initial prompt redrawLine(); @@ -654,7 +692,8 @@ public class LineReaderImpl implements LineReader, Flushable throw new EndOfFileException().partialLine(buf.length() > 0 ? buf.toString() : null); } Log.trace("Binding: ", o); - if (buf.length() == 0 && getLastBinding().charAt(0) == originalAttributes.getControlChar(ControlChar.VEOF)) { + if (buf.length() == 0 + && getLastBinding().charAt(0) == originalAttributes.getControlChar(ControlChar.VEOF)) { throw new EndOfFileException(); } @@ -675,12 +714,17 @@ public class LineReaderImpl implements LineReader, Flushable try { lock.lock(); // Get executable widget - Buffer copy = buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) ? buf.copy() : null; + Buffer copy = buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) + ? buf.copy() + : null; Widget w = getWidget(o); if (!w.apply()) { beep(); } - if (!isSet(Option.DISABLE_UNDO) && !isUndo && copy != null && buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) + if (!isSet(Option.DISABLE_UNDO) + && !isUndo + && copy != null + && buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) && !copy.toString().equals(buf.toString())) { undo.newState(buf.copy()); } @@ -718,13 +762,18 @@ public class LineReaderImpl implements LineReader, Flushable } else { throw e; } - } - finally { + } finally { + AtomicBoolean interrupted = new AtomicBoolean(Thread.interrupted()); try { lock.lock(); this.reading = false; + Terminal.SignalHandler tmpHandler = terminal.handle(Signal.INT, s -> interrupted.set(true)); + if (previousIntrHandler == null) { + previousIntrHandler = tmpHandler; + } + cleanup(); if (originalAttributes != null) { terminal.setAttributes(originalAttributes); @@ -741,13 +790,15 @@ public class LineReaderImpl implements LineReader, Flushable } finally { lock.unlock(); startedReading.set(false); + if (interrupted.get()) { + Thread.currentThread().interrupt(); + } } } } private boolean isTerminalDumb() { - return Terminal.TYPE_DUMB.equals(terminal.getType()) - || Terminal.TYPE_DUMB_COLOR.equals(terminal.getType()); + return Terminal.TYPE_DUMB.equals(terminal.getType()) || Terminal.TYPE_DUMB_COLOR.equals(terminal.getType()); } private void doDisplay() { @@ -757,8 +808,7 @@ public class LineReaderImpl implements LineReader, Flushable display = new Display(terminal, false); display.resize(size.getRows(), size.getColumns()); - if (isSet(Option.DELAY_LINE_WRAP)) - display.setDelayLineWrap(true); + if (isSet(Option.DELAY_LINE_WRAP)) display.setDelayLineWrap(true); } @Override @@ -965,8 +1015,10 @@ public class LineReaderImpl implements LineReader, Flushable if (!YANK_POP.equals(ref) && !YANK.equals(ref)) { killRing.resetLastYank(); } - if (!KILL_LINE.equals(ref) && !KILL_WHOLE_LINE.equals(ref) - && !BACKWARD_KILL_WORD.equals(ref) && !KILL_WORD.equals(ref)) { + if (!KILL_LINE.equals(ref) + && !KILL_WHOLE_LINE.equals(ref) + && !BACKWARD_KILL_WORD.equals(ref) + && !KILL_WORD.equals(ref)) { killRing.resetLastKill(); } } @@ -1083,7 +1135,7 @@ public class LineReaderImpl implements LineReader, Flushable if (isSet(Option.BRACKETED_PASTE)) { terminal.writer().write(BRACKETED_PASTE_OFF); } - Constructor ctor = Class.forName("jdk.internal.org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); + Constructor ctor = Class.forName("org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); Editor editor = (Editor) ctor.newInstance(terminal, new File(file.getParent())); editor.setRestricted(true); editor.open(Collections.singletonList(file.getName())); @@ -1097,6 +1149,10 @@ public class LineReaderImpl implements LineReader, Flushable } } + protected int getTabWidth() { + return getInt(LineReader.TAB_WIDTH, DEFAULT_TAB_WIDTH); + } + // // Widget implementation // @@ -1137,26 +1193,27 @@ public class LineReaderImpl implements LineReader, Flushable } // we only add it to the history if the buffer is not empty - if (historyLine != null && historyLine.length() > 0 ) { + if (historyLine != null && historyLine.length() > 0) { history.add(Instant.now(), historyLine); } return str; } - protected void handleSignal(Signal signal) { + protected synchronized void handleSignal(Signal signal) { doAutosuggestion = false; if (signal == Signal.WINCH) { - Status status = Status.getStatus(terminal, false); - if (status != null) { - status.hardReset(); - } size.copy(terminal.getBufferSize()); display.resize(size.getRows(), size.getColumns()); - // restores prompt but also prevents scrolling in consoleZ, see #492 - // redrawLine(); + Status status = Status.getStatus(terminal, false); + if (status != null) { + status.resize(size); + status.reset(); + } + terminal.puts(Capability.carriage_return); + terminal.puts(Capability.clr_eos); + redrawLine(); redisplay(); - } - else if (signal == Signal.CONT) { + } else if (signal == Signal.CONT) { terminal.enterRawMode(); size.copy(terminal.getBufferSize()); display.resize(size.getRows(), size.getColumns()); @@ -1200,13 +1257,11 @@ public class LineReaderImpl implements LineReader, Flushable // public void setPrompt(final String prompt) { - this.prompt = (prompt == null ? AttributedString.EMPTY - : expandPromptPattern(prompt, 0, "", 0)); + this.prompt = (prompt == null ? AttributedString.EMPTY : expandPromptPattern(prompt, 0, "", 0)); } public void setRightPrompt(final String rightPrompt) { - this.rightPrompt = (rightPrompt == null ? AttributedString.EMPTY - : expandPromptPattern(rightPrompt, 0, "", 0)); + this.rightPrompt = (rightPrompt == null ? AttributedString.EMPTY : expandPromptPattern(rightPrompt, 0, "", 0)); } protected void setBuffer(Buffer buffer) { @@ -1233,7 +1288,7 @@ public class LineReaderImpl implements LineReader, Flushable * @param op The incoming operation to remap * @return The remaped operation */ - protected String viDeleteChangeYankToRemap (String op) { + protected String viDeleteChangeYankToRemap(String op) { switch (op) { case SEND_BREAK: case BACKWARD_CHAR: @@ -1292,7 +1347,6 @@ public class LineReaderImpl implements LineReader, Flushable return VICMD.equals(keyMap); } - // // Movement // @@ -1332,7 +1386,6 @@ public class LineReaderImpl implements LineReader, Flushable return true; } - // // Word movement // @@ -1365,9 +1418,7 @@ public class LineReaderImpl implements LineReader, Flushable buf.move(1); } } else { - while (buf.cursor() < buf.length() - && !isViAlphaNum(buf.currChar()) - && !isWhitespace(buf.currChar())) { + while (buf.cursor() < buf.length() && !isViAlphaNum(buf.currChar()) && !isWhitespace(buf.currChar())) { buf.move(1); } } @@ -1375,9 +1426,7 @@ public class LineReaderImpl implements LineReader, Flushable return true; } int nl = buf.currChar() == '\n' ? 1 : 0; - while (buf.cursor() < buf.length() - && nl < 2 - && isWhitespace(buf.currChar())) { + while (buf.cursor() < buf.length() && nl < 2 && isWhitespace(buf.currChar())) { buf.move(1); nl += buf.currChar() == '\n' ? 1 : 0; } @@ -1397,9 +1446,7 @@ public class LineReaderImpl implements LineReader, Flushable return true; } int nl = buf.currChar() == '\n' ? 1 : 0; - while (buf.cursor() < buf.length() - && nl < 2 - && isWhitespace(buf.currChar())) { + while (buf.cursor() < buf.length() && nl < 2 && isWhitespace(buf.currChar())) { buf.move(1); nl += buf.currChar() == '\n' ? 1 : 0; } @@ -1451,7 +1498,9 @@ public class LineReaderImpl implements LineReader, Flushable } } else { buf.move(1); - while (buf.cursor() < buf.length() && !isViAlphaNum(buf.nextChar()) && !isWhitespace(buf.nextChar())) { + while (buf.cursor() < buf.length() + && !isViAlphaNum(buf.nextChar()) + && !isWhitespace(buf.nextChar())) { buf.move(1); } } @@ -1720,9 +1769,7 @@ public class LineReaderImpl implements LineReader, Flushable buf.move(1); } while (buf.cursor() < buf.length() && isWord(buf.currChar())) { - buf.currChar(first - ? Character.toUpperCase(buf.currChar()) - : Character.toLowerCase(buf.currChar())); + buf.currChar(first ? Character.toUpperCase(buf.currChar()) : Character.toLowerCase(buf.currChar())); buf.move(1); first = false; } @@ -1810,7 +1857,8 @@ public class LineReaderImpl implements LineReader, Flushable sta1--; } end1 = sta1; - while (end1 < lend && !isDelimiter(buf.atChar(++end1))); + while (end1 < lend && !isDelimiter(buf.atChar(++end1))) + ; if (neg) { end2 = sta1 - 1; while (end2 > lstart && isDelimiter(buf.atChar(end2 - 1))) { @@ -1819,9 +1867,11 @@ public class LineReaderImpl implements LineReader, Flushable if (end2 < lstart) { // No word before, use the word after sta2 = end1; - while (isDelimiter(buf.atChar(++sta2))); + while (isDelimiter(buf.atChar(++sta2))) + ; end2 = sta2; - while (end2 < lend && !isDelimiter(buf.atChar(++end2))); + while (end2 < lend && !isDelimiter(buf.atChar(++end2))) + ; } else { sta2 = end2; while (sta2 > lstart && !isDelimiter(buf.atChar(sta2 - 1))) { @@ -1830,7 +1880,8 @@ public class LineReaderImpl implements LineReader, Flushable } } else { sta2 = end1; - while (sta2 < lend && isDelimiter(buf.atChar(++sta2))); + while (sta2 < lend && isDelimiter(buf.atChar(++sta2))) + ; if (sta2 == lend) { // No word after, use the word before end2 = sta1; @@ -1843,19 +1894,24 @@ public class LineReaderImpl implements LineReader, Flushable } } else { end2 = sta2; - while (end2 < lend && !isDelimiter(buf.atChar(++end2))) ; + while (end2 < lend && !isDelimiter(buf.atChar(++end2))) + ; } } if (sta1 < sta2) { - String res = buf.substring(0, sta1) + buf.substring(sta2, end2) - + buf.substring(end1, sta2) + buf.substring(sta1, end1) + String res = buf.substring(0, sta1) + + buf.substring(sta2, end2) + + buf.substring(end1, sta2) + + buf.substring(sta1, end1) + buf.substring(end2); buf.clear(); buf.write(res); buf.cursor(neg ? end1 : end2); } else { - String res = buf.substring(0, sta2) + buf.substring(sta1, end1) - + buf.substring(end2, sta1) + buf.substring(sta2, end2) + String res = buf.substring(0, sta2) + + buf.substring(sta1, end1) + + buf.substring(end2, sta1) + + buf.substring(sta2, end2) + buf.substring(end1); buf.clear(); buf.write(res); @@ -1988,11 +2044,11 @@ public class LineReaderImpl implements LineReader, Flushable while (count-- > 0) { do { buf.move(findDir); - } while (buf.cursor() > 0 && buf.cursor() < buf.length() + } while (buf.cursor() > 0 + && buf.cursor() < buf.length() && buf.currChar() != findChar && buf.currChar() != '\n'); - if (buf.cursor() <= 0 || buf.cursor() >= buf.length() - || buf.currChar() == '\n') { + if (buf.cursor() <= 0 || buf.cursor() >= buf.length() || buf.currChar() == '\n') { buf.cursor(cursor); return false; } @@ -2211,18 +2267,17 @@ public class LineReaderImpl implements LineReader, Flushable * character or if there was no matching bracket. */ protected boolean doViMatchBracket() { - int pos = buf.cursor(); + int pos = buf.cursor(); if (pos == buf.length()) { return false; } - int type = getBracketType(buf.atChar(pos)); - int move = (type < 0) ? -1 : 1; - int count = 1; + int type = getBracketType(buf.atChar(pos)); + int move = (type < 0) ? -1 : 1; + int count = 1; - if (type == 0) - return false; + if (type == 0) return false; while (count > 0) { pos += move; @@ -2235,8 +2290,7 @@ public class LineReaderImpl implements LineReader, Flushable int curType = getBracketType(buf.atChar(pos)); if (curType == type) { ++count; - } - else if (curType == -type) { + } else if (curType == -type) { --count; } } @@ -2245,8 +2299,7 @@ public class LineReaderImpl implements LineReader, Flushable * Slight adjustment for delete-to, yank-to, change-to to ensure * that the matching paren is consumed */ - if (move > 0 && isInViMoveOperation()) - ++pos; + if (move > 0 && isInViMoveOperation()) ++pos; buf.cursor(pos); return true; @@ -2259,14 +2312,20 @@ public class LineReaderImpl implements LineReader, Flushable * @return 1 is square, 2 curly, 3 parent, or zero for none. The value * will be negated if it is the closing form of the bracket. */ - protected int getBracketType (int ch) { + protected int getBracketType(int ch) { switch (ch) { - case '[': return 1; - case ']': return -1; - case '{': return 2; - case '}': return -2; - case '(': return 3; - case ')': return -3; + case '[': + return 1; + case ']': + return -1; + case '{': + return 2; + case '}': + return -2; + case '(': + return 3; + case ')': + return -3; default: return 0; } @@ -2331,7 +2390,7 @@ public class LineReaderImpl implements LineReader, Flushable buf.clear(); println(); redrawLine(); -// state = State.INTERRUPT; + // state = State.INTERRUPT; return false; } return true; @@ -2378,6 +2437,10 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean digitArgument() { String s = getLastBinding(); repeatCount = (repeatCount * 10) + s.charAt(s.length() - 1) - '0'; + int maxRepeatCount = getInt(MAX_REPEAT_COUNT, DEFAULT_MAX_REPEAT_COUNT); + if (repeatCount > maxRepeatCount) { + throw new IllegalArgumentException("digit argument should be less than " + maxRepeatCount); + } isArgDigit = true; return true; } @@ -2438,10 +2501,12 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean viYankWholeLine() { int s, e; int p = buf.cursor(); - while (buf.move(-1) == -1 && buf.prevChar() != '\n') ; + while (buf.move(-1) == -1 && buf.prevChar() != '\n') + ; s = buf.cursor(); for (int i = 0; i < repeatCount; i++) { - while (buf.move(1) == 1 && buf.prevChar() != '\n') ; + while (buf.move(1) == 1 && buf.prevChar() != '\n') + ; } e = buf.cursor(); yankBuffer = buf.substring(s, e); @@ -2554,15 +2619,19 @@ public class LineReaderImpl implements LineReader, Flushable return doSearchHistory(true); } - static class Pair { - final U u; final V v; + static class Pair { + final U u; + final V v; + public Pair(U u, V v) { this.u = u; this.v = v; } + public U getU() { return u; } + public V getV() { return v; } @@ -2575,7 +2644,8 @@ public class LineReaderImpl implements LineReader, Flushable KeyMap terminators = new KeyMap<>(); getString(SEARCH_TERMINATORS, DEFAULT_SEARCH_TERMINATORS) - .codePoints().forEach(c -> bind(terminators, ACCEPT_LINE, new String(Character.toChars(c)))); + .codePoints() + .forEach(c -> bind(terminators, ACCEPT_LINE, new String(Character.toChars(c)))); Buffer originalBuffer = buf.copy(); searchIndex = -1; @@ -2583,8 +2653,8 @@ public class LineReaderImpl implements LineReader, Flushable searchBackward = backward; searchFailing = false; post = () -> new AttributedString((searchFailing ? "failing" + " " : "") - + (searchBackward ? "bck-i-search" : "fwd-i-search") - + ": " + searchTerm + "_"); + + (searchBackward ? "bck-i-search" : "fwd-i-search") + + ": " + searchTerm + "_"); redisplay(); try { @@ -2630,8 +2700,9 @@ public class LineReaderImpl implements LineReader, Flushable searchFailing = false; } else { boolean caseInsensitive = isSet(Option.CASE_INSENSITIVE_SEARCH); - Pattern pat = Pattern.compile(pattern, caseInsensitive ? Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE - : Pattern.UNICODE_CASE); + Pattern pat = Pattern.compile( + pattern, + caseInsensitive ? Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE : Pattern.UNICODE_CASE); Pair pair = null; if (searchBackward) { boolean nextOnly = next; @@ -2641,7 +2712,11 @@ public class LineReaderImpl implements LineReader, Flushable .orElse(null); if (pair == null) { pair = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(history.reverseIterator(searchIndex < 0 ? history.last() : searchIndex - 1), Spliterator.ORDERED), false) + Spliterators.spliteratorUnknownSize( + history.reverseIterator( + searchIndex < 0 ? history.last() : searchIndex - 1), + Spliterator.ORDERED), + false) .flatMap(e -> matches(pat, e.line(), e.index()).stream()) .findFirst() .orElse(null); @@ -2654,7 +2729,11 @@ public class LineReaderImpl implements LineReader, Flushable .orElse(null); if (pair == null) { pair = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(history.iterator((searchIndex < 0 ? history.last() : searchIndex) + 1), Spliterator.ORDERED), false) + Spliterators.spliteratorUnknownSize( + history.iterator( + (searchIndex < 0 ? history.last() : searchIndex) + 1), + Spliterator.ORDERED), + false) .flatMap(e -> matches(pat, e.line(), e.index()).stream()) .findFirst() .orElse(null); @@ -2714,7 +2793,10 @@ public class LineReaderImpl implements LineReader, Flushable sb.append("\\E"); inQuote = false; } - sb.append("[").append(Character.toLowerCase(c)).append(Character.toUpperCase(c)).append("]"); + sb.append("[") + .append(Character.toLowerCase(c)) + .append(Character.toUpperCase(c)) + .append("]"); } else { if (!inQuote) { sb.append("\\Q"); @@ -2742,8 +2824,7 @@ public class LineReaderImpl implements LineReader, Flushable } protected boolean historySearchForward() { - if (historyBuffer == null || buf.length() == 0 - || !buf.toString().equals(history.current())) { + if (historyBuffer == null || buf.length() == 0 || !buf.toString().equals(history.current())) { historyBuffer = buf.copy(); searchBuffer = getFirstWord(); } @@ -2791,8 +2872,7 @@ public class LineReaderImpl implements LineReader, Flushable } protected boolean historySearchBackward() { - if (historyBuffer == null || buf.length() == 0 - || !buf.toString().equals(history.current())) { + if (historyBuffer == null || buf.length() == 0 || !buf.toString().equals(history.current())) { historyBuffer = buf.copy(); searchBuffer = getFirstWord(); } @@ -2984,7 +3064,7 @@ public class LineReaderImpl implements LineReader, Flushable } void indention(int nb, StringBuilder sb) { - int indent = getInt(INDENTATION, DEFAULT_INDENTATION)*nb; + int indent = getInt(INDENTATION, DEFAULT_INDENTATION) * nb; for (int i = 0; i < indent; i++) { sb.append(' '); } @@ -3017,7 +3097,6 @@ public class LineReaderImpl implements LineReader, Flushable return true; } - // // History Control // @@ -3108,13 +3187,11 @@ public class LineReaderImpl implements LineReader, Flushable } protected boolean viUpLineOrHistory() { - return upLine() - || upHistory() && viFirstNonBlank(); + return upLine() || upHistory() && viFirstNonBlank(); } protected boolean viDownLineOrHistory() { - return downLine() - || downHistory() && viFirstNonBlank(); + return downLine() || downHistory() && viFirstNonBlank(); } protected boolean upLine() { @@ -3175,8 +3252,7 @@ public class LineReaderImpl implements LineReader, Flushable } protected boolean viChangeEol() { - return viChange(buf.cursor(), buf.length()) - && setKeyMap(VIINS); + return viChange(buf.cursor(), buf.length()) && setKeyMap(VIINS); } protected boolean viKillEol() { @@ -3199,7 +3275,8 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean viJoin() { if (buf.down()) { - while (buf.move(-1) == -1 && buf.prevChar() != '\n') ; + while (buf.move(-1) == -1 && buf.prevChar() != '\n') + ; buf.backspace(); buf.write(' '); buf.move(-1); @@ -3253,14 +3330,16 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean beginningOfLine() { while (count-- > 0) { - while (buf.move(-1) == -1 && buf.prevChar() != '\n') ; + while (buf.move(-1) == -1 && buf.prevChar() != '\n') + ; } return true; } protected boolean endOfLine() { while (count-- > 0) { - while (buf.move(1) == 1 && buf.currChar() != '\n') ; + while (buf.move(1) == 1 && buf.currChar() != '\n') + ; } return true; } @@ -3384,7 +3463,7 @@ public class LineReaderImpl implements LineReader, Flushable // what is really happening is that if we are in "move-mode" then the // cursor can't be moved off the end of the line, but in "edit-mode" it // is ok, but I have no easy way of knowing which mode we are in. - if (! isChange && startPos > 0 && startPos == buf.length()) { + if (!isChange && startPos > 0 && startPos == buf.length()) { buf.move(-1); } return true; @@ -3424,14 +3503,16 @@ public class LineReaderImpl implements LineReader, Flushable } protected boolean viOpenLineAbove() { - while (buf.move(-1) == -1 && buf.prevChar() != '\n') ; + while (buf.move(-1) == -1 && buf.prevChar() != '\n') + ; buf.write('\n'); buf.move(-1); return setKeyMap(VIINS); } protected boolean viOpenLineBelow() { - while (buf.move(1) == 1 && buf.currChar() != '\n') ; + while (buf.move(1) == 1 && buf.currChar() != '\n') + ; buf.write('\n'); return setKeyMap(VIINS); } @@ -3443,11 +3524,12 @@ public class LineReaderImpl implements LineReader, Flushable */ protected boolean viPutAfter() { if (yankBuffer.indexOf('\n') >= 0) { - while (buf.move(1) == 1 && buf.currChar() != '\n'); + while (buf.move(1) == 1 && buf.currChar() != '\n') + ; buf.move(1); putString(yankBuffer); - buf.move(- yankBuffer.length()); - } else if (yankBuffer.length () != 0) { + buf.move(-yankBuffer.length()); + } else if (yankBuffer.length() != 0) { if (buf.cursor() < buf.length()) { buf.move(1); } @@ -3461,10 +3543,11 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean viPutBefore() { if (yankBuffer.indexOf('\n') >= 0) { - while (buf.move(-1) == -1 && buf.prevChar() != '\n'); + while (buf.move(-1) == -1 && buf.prevChar() != '\n') + ; putString(yankBuffer); - buf.move(- yankBuffer.length()); - } else if (yankBuffer.length () != 0) { + buf.move(-yankBuffer.length()); + } else if (yankBuffer.length() != 0) { if (buf.cursor() > 0) { buf.move(-1); } @@ -3681,7 +3764,7 @@ public class LineReaderImpl implements LineReader, Flushable addBuiltinWidget(widgets, MENU_EXPAND_OR_COMPLETE, this::menuExpandOrComplete); addBuiltinWidget(widgets, NEG_ARGUMENT, this::negArgument); addBuiltinWidget(widgets, OVERWRITE_MODE, this::overwriteMode); -// addBuiltinWidget(widgets, QUIT, this::quit); + // addBuiltinWidget(widgets, QUIT, this::quit); addBuiltinWidget(widgets, QUOTED_INSERT, this::quotedInsert); addBuiltinWidget(widgets, REDISPLAY, this::redisplay); addBuiltinWidget(widgets, REDRAW_LINE, this::redrawLine); @@ -3774,6 +3857,7 @@ public class LineReaderImpl implements LineReader, Flushable public String toString() { return name; } + @Override public boolean apply() { return widget.apply(); @@ -3797,14 +3881,11 @@ public class LineReaderImpl implements LineReader, Flushable Status status = Status.getStatus(terminal, false); if (status != null) { - if (terminal.getType().startsWith(AbstractWindowsTerminal.TYPE_WINDOWS)) { - status.resize(); - } status.redraw(); } if (size.getRows() > 0 && size.getRows() < MIN_ROWS) { - AttributedStringBuilder sb = new AttributedStringBuilder().tabs(TAB_WIDTH); + AttributedStringBuilder sb = new AttributedStringBuilder().tabs(getTabWidth()); sb.append(prompt); concat(getHighlightedBuffer(buf.toString()).columnSplitLength(Integer.MAX_VALUE), sb); @@ -3877,14 +3958,15 @@ public class LineReaderImpl implements LineReader, Flushable int cursorNewLinesId = -1; int cursorColPos = -1; if (size.getColumns() > 0) { - AttributedStringBuilder sb = new AttributedStringBuilder().tabs(TAB_WIDTH); + AttributedStringBuilder sb = new AttributedStringBuilder().tabs(getTabWidth()); sb.append(prompt); String buffer = buf.upToCursor(); if (maskingCallback != null) { buffer = maskingCallback.display(buffer); } sb.append(insertSecondaryPrompts(new AttributedString(buffer), secondaryPrompts, false)); - List promptLines = sb.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); + List promptLines = + sb.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); if (!promptLines.isEmpty()) { cursorNewLinesId = promptLines.size() - 1; cursorColPos = promptLines.get(promptLines.size() - 1).columnLength(); @@ -3904,7 +3986,7 @@ public class LineReaderImpl implements LineReader, Flushable int lineId = newLines.size() - displaySize + 1; int endId = displaySize; int startId = 1; - if (lineId > cursorNewLinesId) { + if (lineId > cursorNewLinesId) { lineId = cursorNewLinesId; endId = displaySize - 1; startId = 0; @@ -3949,10 +4031,9 @@ public class LineReaderImpl implements LineReader, Flushable } History history = getHistory(); StringBuilder sb = new StringBuilder(); - for (char c: buffer.replace("\\", "\\\\").toCharArray()) { - if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '*' - || c == '$' || c == '.' || c == '?' || c == '+' || c == '|' || c == '<' || c == '>' || c == '!' - || c == '-') { + for (char c : buffer.replace("\\", "\\\\").toCharArray()) { + if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '*' || c == '$' + || c == '.' || c == '?' || c == '+' || c == '|' || c == '<' || c == '>' || c == '!' || c == '-') { sb.append('\\'); } sb.append(c); @@ -3984,7 +4065,7 @@ public class LineReaderImpl implements LineReader, Flushable AttributedString attBuf = getHighlightedBuffer(buf.toString()); AttributedString tNewBuf = insertSecondaryPrompts(attBuf, secondaryPrompts); - AttributedStringBuilder full = new AttributedStringBuilder().tabs(TAB_WIDTH); + AttributedStringBuilder full = new AttributedStringBuilder().tabs(getTabWidth()); full.append(prompt); full.append(tNewBuf); if (doAutosuggestion && !isTerminalDumb()) { @@ -4040,15 +4121,15 @@ public class LineReaderImpl implements LineReader, Flushable if (maskingCallback != null) { buffer = maskingCallback.display(buffer); } - if (highlighter != null && !isSet(Option.DISABLE_HIGHLIGHTER) + if (highlighter != null + && !isSet(Option.DISABLE_HIGHLIGHTER) && buffer.length() < getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE)) { return highlighter.highlight(this, buffer); } return new AttributedString(buffer); } - private AttributedString expandPromptPattern(String pattern, int padToWidth, - String message, int line) { + private AttributedString expandPromptPattern(String pattern, int padToWidth, String message, int line) { ArrayList parts = new ArrayList<>(); boolean isHidden = false; int padPartIndex = -1; @@ -4065,7 +4146,8 @@ public class LineReaderImpl implements LineReader, Flushable if (ch == '%' && i < plen) { int count = 0; boolean countSeen = false; - decode: while (true) { + decode: + while (true) { ch = pattern.charAt(i++); switch (ch) { case '{': @@ -4073,7 +4155,7 @@ public class LineReaderImpl implements LineReader, Flushable String str = sb.toString(); AttributedString astr; if (!isHidden) { - astr = AttributedString.fromAnsi(str); + astr = fromAnsi(str); cols += astr.columnLength(); } else { astr = new AttributedString(str, AttributedStyle.HIDDEN); @@ -4096,12 +4178,10 @@ public class LineReaderImpl implements LineReader, Flushable sb.append(getInt(LINE_OFFSET, 0) + line); break decode; case 'M': - if (message != null) - sb.append(message); + if (message != null) sb.append(message); break decode; case 'P': - if (countSeen && count >= 0) - padToWidth = count; + if (countSeen && count >= 0) padToWidth = count; if (i < plen) { padChar = pattern.charAt(i++); // FIXME check surrogate @@ -4140,25 +4220,28 @@ public class LineReaderImpl implements LineReader, Flushable break decode; } } - } else - sb.append(ch); + } else sb.append(ch); } if (padToWidth > cols && padToWidth > 0) { int padCharCols = WCWidth.wcwidth(padChar); int padCount = (padToWidth - cols) / padCharCols; sb = padPartString; - while (--padCount >= 0) - sb.insert(padPos, (char) padChar); // FIXME if wide - parts.set(padPartIndex, AttributedString.fromAnsi(sb.toString())); + while (--padCount >= 0) sb.insert(padPos, (char) padChar); // FIXME if wide + parts.set(padPartIndex, fromAnsi(sb.toString())); } return AttributedString.join(null, parts); } + private AttributedString fromAnsi(String str) { + return AttributedString.fromAnsi(str, Collections.singletonList(0), alternateIn, alternateOut); + } + private AttributedString insertSecondaryPrompts(AttributedString str, List prompts) { return insertSecondaryPrompts(str, prompts, true); } - private AttributedString insertSecondaryPrompts(AttributedString strAtt, List prompts, boolean computePrompts) { + private AttributedString insertSecondaryPrompts( + AttributedString strAtt, List prompts, boolean computePrompts) { Objects.requireNonNull(prompts); List lines = strAtt.columnSplitLength(Integer.MAX_VALUE); AttributedStringBuilder sb = new AttributedStringBuilder(); @@ -4171,7 +4254,9 @@ public class LineReaderImpl implements LineReader, Flushable if (computePrompts && secondaryPromptPattern.contains("%P")) { width = prompt.columnLength(); if (width > size.getColumns() || prompt.contains('\n')) { - width = new TerminalLine(prompt.toString(), 0, size.getColumns()).getEndLine().length(); + width = new TerminalLine(prompt.toString(), 0, size.getColumns()) + .getEndLine() + .length(); } for (int line = 0; line < lines.size() - 1; line++) { AttributedString prompt; @@ -4227,11 +4312,9 @@ public class LineReaderImpl implements LineReader, Flushable private AttributedString addRightPrompt(AttributedString prompt, AttributedString line) { int width = prompt.columnLength(); - boolean endsWithNl = line.length() > 0 - && line.charAt(line.length() - 1) == '\n'; + boolean endsWithNl = line.length() > 0 && line.charAt(line.length() - 1) == '\n'; // columnLength counts -1 for the final newline; adjust for that - int nb = size.getColumns() - width - - (line.columnLength() + (endsWithNl ? 1 : 0)); + int nb = size.getColumns() - width - (line.columnLength() + (endsWithNl ? 1 : 0)); if (nb >= 3) { AttributedStringBuilder sb = new AttributedStringBuilder(size.getColumns()); sb.append(line, 0, endsWithNl ? line.length() - 1 : line.length()); @@ -4253,8 +4336,8 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean insertTab() { return isSet(Option.INSERT_TAB) - && getLastBinding().equals("\t") - && buf.toString().matches("(^|[\\s\\S]*\n)[\r\n\t ]*"); + && getLastBinding().equals("\t") + && buf.toString().matches("(^|[\\s\\S]*\n)[\r\n\t ]*"); } protected boolean expandHistory() { @@ -4465,7 +4548,8 @@ public class LineReaderImpl implements LineReader, Flushable if (op != null) { String chars = getString(REMOVE_SUFFIX_CHARS, DEFAULT_REMOVE_SUFFIX_CHARS); String ref = op instanceof Reference ? ((Reference) op).name() : null; - if (SELF_INSERT.equals(ref) && chars.indexOf(getLastBinding().charAt(0)) >= 0 + if (SELF_INSERT.equals(ref) + && chars.indexOf(getLastBinding().charAt(0)) >= 0 || ACCEPT_LINE.equals(ref)) { buf.backspace(completion.suffix().length()); if (getLastBinding().charAt(0) != ' ') { @@ -4533,27 +4617,35 @@ public class LineReaderImpl implements LineReader, Flushable public String word() { return line.word(); } + public int wordCursor() { return line.wordCursor(); } + public int wordIndex() { return line.wordIndex(); } + public List words() { return line.words(); } + public String line() { return line.line(); } + public int cursor() { return line.cursor(); } + public CharSequence escape(CharSequence candidate, boolean complete) { return candidate; } + public int rawWordCursor() { return wordCursor(); } + public int rawWordLength() { return word().length(); } @@ -4564,8 +4656,7 @@ public class LineReaderImpl implements LineReader, Flushable protected Comparator getCandidateComparator(boolean caseInsensitive, String word) { String wdi = caseInsensitive ? word.toLowerCase() : word; ToIntFunction wordDistance = w -> ReaderUtils.distance(wdi, caseInsensitive ? w.toLowerCase() : w); - return Comparator - .comparing(Candidate::value, Comparator.comparingInt(wordDistance)) + return Comparator.comparing(Candidate::value, Comparator.comparingInt(wordDistance)) .thenComparing(Comparator.naturalOrder()); } @@ -4577,9 +4668,10 @@ public class LineReaderImpl implements LineReader, Flushable return getString(ORIGINAL_GROUP_NAME, DEFAULT_ORIGINAL_GROUP_NAME); } - protected Comparator getGroupComparator() { - return Comparator.comparingInt(s -> getOthersGroupName().equals(s) ? 1 : getOriginalGroupName().equals(s) ? -1 : 0) + return Comparator.comparingInt(s -> getOthersGroupName().equals(s) + ? 1 + : getOriginalGroupName().equals(s) ? -1 : 0) .thenComparing(String::toLowerCase, Comparator.naturalOrder()); } @@ -4600,11 +4692,9 @@ public class LineReaderImpl implements LineReader, Flushable // the same description candidates.sort(Comparator.comparing(Candidate::value)); Candidate first = candidates.get(0); - String disp = candidates.stream() - .map(Candidate::displ) - .collect(Collectors.joining(" ")); - possible.add(new Candidate(first.value(), disp, first.group(), - first.descr(), first.suffix(), null, first.complete())); + String disp = candidates.stream().map(Candidate::displ).collect(Collectors.joining(" ")); + possible.add(new Candidate( + first.value(), disp, first.group(), first.descr(), first.suffix(), null, first.complete())); } } } @@ -4636,8 +4726,10 @@ public class LineReaderImpl implements LineReader, Flushable } private int promptLines() { - AttributedString text = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); - return text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); + AttributedString text = + insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); + return text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()) + .size(); } private class MenuSupport implements Supplier { @@ -4651,7 +4743,8 @@ public class LineReaderImpl implements LineReader, Flushable int columns; String completed; - public MenuSupport(List original, String completed, BiFunction escaper) { + public MenuSupport( + List original, String completed, BiFunction escaper) { this.possible = new ArrayList<>(); this.escaper = escaper; this.selection = -1; @@ -4714,7 +4807,7 @@ public class LineReaderImpl implements LineReader, Flushable if (selection - row + axis > options) { // selection is the last row/column // so there are fewer options than other rows - axis = options%axis; + axis = options % axis; } selection = selection - row + ((axis + row + step) % axis); update(); @@ -4772,7 +4865,9 @@ public class LineReaderImpl implements LineReader, Flushable AttributedString post = pr.post; if (post.length() > 0 && post.charAt(post.length() - 1) != '\n') { post = new AttributedStringBuilder(post.length() + 1) - .append(post).append("\n").toAttributedString(); + .append(post) + .append("\n") + .toAttributedString(); } List lines = post.columnSplitLength(size.getColumns(), true, display.delayLineWrap()); List sub = new ArrayList<>(lines.subList(topLine, topLine + displayed)); @@ -4785,7 +4880,8 @@ public class LineReaderImpl implements LineReader, Flushable .append(" of ") .append(Integer.toString(lines.size())) .append("\n") - .style(AttributedStyle.DEFAULT).toAttributedString()); + .style(AttributedStyle.DEFAULT) + .toAttributedString()); computed = AttributedString.join(AttributedString.EMPTY, sub); } else { computed = pr.post; @@ -4798,10 +4894,10 @@ public class LineReaderImpl implements LineReader, Flushable public AttributedString get() { return computed; } - } - protected boolean doMenu(List original, String completed, BiFunction escaper) { + protected boolean doMenu( + List original, String completed, BiFunction escaper) { // Reorder candidates according to display order final List possible = new ArrayList<>(); boolean caseInsensitive = isSet(Option.CASE_INSENSITIVE); @@ -4854,7 +4950,7 @@ public class LineReaderImpl implements LineReader, Flushable if (completion.suffix() != null) { String chars = getString(REMOVE_SUFFIX_CHARS, DEFAULT_REMOVE_SUFFIX_CHARS); if (SELF_INSERT.equals(ref) - && chars.indexOf(getLastBinding().charAt(0)) >= 0 + && chars.indexOf(getLastBinding().charAt(0)) >= 0 || BACKWARD_DELETE_CHAR.equals(ref)) { buf.backspace(completion.suffix().length()); } @@ -4866,8 +4962,8 @@ public class LineReaderImpl implements LineReader, Flushable } if (!ACCEPT_LINE.equals(ref) && !(SELF_INSERT.equals(ref) - && completion.suffix() != null - && completion.suffix().startsWith(getLastBinding()))) { + && completion.suffix() != null + && completion.suffix().startsWith(getLastBinding()))) { pushBackBinding(true); } post = null; @@ -4888,29 +4984,40 @@ public class LineReaderImpl implements LineReader, Flushable return doList(new ArrayList<>(), "", false, null, false); } - protected boolean doList(List possible - , String completed, boolean runLoop, BiFunction escaper) { + protected boolean doList( + List possible, + String completed, + boolean runLoop, + BiFunction escaper) { return doList(possible, completed, runLoop, escaper, false); } - protected boolean doList(List possible - , String completed - , boolean runLoop, BiFunction escaper, boolean forSuggestion) { + protected boolean doList( + List possible, + String completed, + boolean runLoop, + BiFunction escaper, + boolean forSuggestion) { // If we list only and if there's a big // number of items, we should ask the user // for confirmation, display the list // and redraw the line at the bottom mergeCandidates(possible); - AttributedString text = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); - int promptLines = text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); + AttributedString text = + insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); + int promptLines = text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()) + .size(); PostResult postResult = computePost(possible, null, null, completed); int lines = postResult.lines; int listMax = getInt(LIST_MAX, DEFAULT_LIST_MAX); - if (listMax > 0 && possible.size() >= listMax - || lines >= size.getRows() - promptLines) { + int possibleSize = possible.size(); + if (possibleSize == 0 || size.getRows() == 0) { + return false; + } + if (listMax > 0 && possibleSize >= listMax || lines >= size.getRows() - promptLines) { if (!forSuggestion) { // prompt - post = () -> new AttributedString(getAppName() + ": do you wish to see all " + possible.size() + post = () -> new AttributedString(getAppName() + ": do you wish to see all " + possibleSize + " possibilities (" + lines + " lines)?"); redisplay(true); int c = readCharacter(); @@ -4930,8 +5037,7 @@ public class LineReaderImpl implements LineReader, Flushable String current = completed + sb.toString(); List cands; if (sb.length() > 0) { - completionMatcher.compile(options, false, new CompletingWord(current), caseInsensitive, 0 - , null); + completionMatcher.compile(options, false, new CompletingWord(current), caseInsensitive, 0, null); cands = completionMatcher.matches(possible).stream() .sorted(getCandidateComparator(caseInsensitive, current)) .collect(Collectors.toList()); @@ -4944,8 +5050,10 @@ public class LineReaderImpl implements LineReader, Flushable candidateStartPosition = candidateStartPosition(cands); } post = () -> { - AttributedString t = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); - int pl = t.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); + AttributedString t = insertSecondaryPrompts( + AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); + int pl = t.columnSplitLength(size.getColumns(), false, display.delayLineWrap()) + .size(); PostResult pr = computePost(cands, null, null, current); if (pr.lines >= size.getRows() - pl) { post = null; @@ -4954,7 +5062,8 @@ public class LineReaderImpl implements LineReader, Flushable redisplay(false); buf.cursor(oldCursor); println(); - List ls = pr.post.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); + List ls = + pr.post.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); Display d = new Display(terminal, false); d.resize(size.getRows(), size.getColumns()); d.update(ls, -1); @@ -5074,25 +5183,41 @@ public class LineReaderImpl implements LineReader, Flushable } } - protected PostResult computePost(List possible, Candidate selection, List ordered, String completed) { - return computePost(possible, selection, ordered, completed, display::wcwidth, size.getColumns(), isSet(Option.AUTO_GROUP), isSet(Option.GROUP), isSet(Option.LIST_ROWS_FIRST)); + protected PostResult computePost( + List possible, Candidate selection, List ordered, String completed) { + return computePost( + possible, + selection, + ordered, + completed, + display::wcwidth, + size.getColumns(), + isSet(Option.AUTO_GROUP), + isSet(Option.GROUP), + isSet(Option.LIST_ROWS_FIRST)); } - protected PostResult computePost(List possible, Candidate selection, List ordered, String completed, Function wcwidth, int width, boolean autoGroup, boolean groupName, boolean rowsFirst) { + protected PostResult computePost( + List possible, + Candidate selection, + List ordered, + String completed, + Function wcwidth, + int width, + boolean autoGroup, + boolean groupName, + boolean rowsFirst) { List strings = new ArrayList<>(); - boolean customOrder = possible.stream().anyMatch(c -> c.sort() != 0); if (groupName) { Comparator groupComparator = getGroupComparator(); - Map> sorted; - sorted = groupComparator != null - ? new TreeMap<>(groupComparator) - : new LinkedHashMap<>(); + Map> sorted; + sorted = groupComparator != null ? new TreeMap<>(groupComparator) : new LinkedHashMap<>(); for (Candidate cand : possible) { String group = cand.group(); - sorted.computeIfAbsent(group != null ? group : "", s -> new LinkedHashMap<>()) - .put((customOrder ? cand.sort() : cand.value()), cand); + sorted.computeIfAbsent(group != null ? group : "", s -> new ArrayList<>()) + .add(cand); } - for (Map.Entry> entry : sorted.entrySet()) { + for (Map.Entry> entry : sorted.entrySet()) { String group = entry.getKey(); if (group.isEmpty() && sorted.size() > 1) { group = getOthersGroupName(); @@ -5100,27 +5225,30 @@ public class LineReaderImpl implements LineReader, Flushable if (!group.isEmpty() && autoGroup) { strings.add(group); } - strings.add(new ArrayList<>(entry.getValue().values())); + List candidates = entry.getValue(); + Collections.sort(candidates); + strings.add(candidates); if (ordered != null) { - ordered.addAll(entry.getValue().values()); + ordered.addAll(candidates); } } } else { Set groups = new LinkedHashSet<>(); - TreeMap sorted = new TreeMap<>(); + List sorted = new ArrayList<>(); for (Candidate cand : possible) { String group = cand.group(); if (group != null) { groups.add(group); } - sorted.put((customOrder ? cand.sort() : cand.value()), cand); + sorted.add(cand); } if (autoGroup) { strings.addAll(groups); } - strings.add(new ArrayList<>(sorted.values())); + Collections.sort(sorted); + strings.add(sorted); if (ordered != null) { - ordered.addAll(sorted.values()); + ordered.addAll(sorted); } } return toColumns(strings, selection, completed, wcwidth, width, rowsFirst); @@ -5163,12 +5291,15 @@ public class LineReaderImpl implements LineReader, Flushable } private int candidateStartPosition(List cands) { - List values = cands.stream().map(c -> AttributedString.stripAnsi(c.displ())) - .filter(c -> !c.matches("\\w+") && c.length() > 1).collect(Collectors.toList()); + List values = cands.stream() + .map(c -> AttributedString.stripAnsi(c.displ())) + .filter(c -> !c.matches("\\w+") && c.length() > 1) + .collect(Collectors.toList()); Set notDelimiters = new HashSet<>(); - values.forEach(v -> v.substring(0, v.length() - 1).chars() + values.forEach(v -> v.substring(0, v.length() - 1) + .chars() .filter(c -> !Character.isDigit(c) && !Character.isAlphabetic(c)) - .forEach(c -> notDelimiters.add(Character.toString((char)c)))); + .forEach(c -> notDelimiters.add(Character.toString((char) c)))); int width = size.getColumns(); int promptLength = prompt != null ? prompt.length() : 0; if (promptLength > 0) { @@ -5179,8 +5310,7 @@ public class LineReaderImpl implements LineReader, Flushable int out = tl.getStartPos(); String buffer = tl.getEndLine(); for (int i = buffer.length(); i > 0; i--) { - if (buffer.substring(0, i).matches(".*\\W") - && !notDelimiters.contains(buffer.substring(i - 1, i))) { + if (buffer.substring(0, i).matches(".*\\W") && !notDelimiters.contains(buffer.substring(i - 1, i))) { out += i; break; } @@ -5189,7 +5319,13 @@ public class LineReaderImpl implements LineReader, Flushable } @SuppressWarnings("unchecked") - protected PostResult toColumns(List items, Candidate selection, String completed, Function wcwidth, int width, boolean rowsFirst) { + protected PostResult toColumns( + List items, + Candidate selection, + String completed, + Function wcwidth, + int width, + boolean rowsFirst) { int[] out = new int[2]; // TODO: support Option.LIST_PACKED // Compute column width @@ -5199,8 +5335,7 @@ public class LineReaderImpl implements LineReader, Flushable if (item instanceof String) { int len = wcwidth.apply((String) item); maxWidth = Math.max(maxWidth, len); - } - else if (item instanceof List) { + } else if (item instanceof List) { for (Candidate cand : (List) item) { listSize++; int len = wcwidth.apply(cand.displ()); @@ -5218,7 +5353,10 @@ public class LineReaderImpl implements LineReader, Flushable AttributedStringBuilder sb = new AttributedStringBuilder(); if (listSize > 0) { if (isSet(Option.AUTO_MENU_LIST) - && listSize < Math.min(getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), visibleDisplayRows() - promptLines())) { + && listSize + < Math.min( + getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), + visibleDisplayRows() - promptLines())) { maxWidth = Math.max(maxWidth, MENU_LIST_WIDTH); sb.tabs(Math.max(Math.min(candidateStartPosition, width - maxWidth - 1), 1)); width = maxWidth + 2; @@ -5251,8 +5389,16 @@ public class LineReaderImpl implements LineReader, Flushable } @SuppressWarnings("unchecked") - protected void toColumns(Object items, int width, int maxWidth, AttributedStringBuilder sb, Candidate selection, String completed - , boolean rowsFirst, boolean doMenuList, int[] out) { + protected void toColumns( + Object items, + int width, + int maxWidth, + AttributedStringBuilder sb, + Candidate selection, + String completed, + boolean rowsFirst, + boolean doMenuList, + int[] out) { if (maxWidth <= 0 || width <= 0) { return; } @@ -5305,18 +5451,20 @@ public class LineReaderImpl implements LineReader, Flushable if (idx < candidates.size()) { Candidate cand = candidates.get(idx); boolean hasRightItem = j < columns - 1 && index.applyAsInt(i, j + 1) < candidates.size(); - AttributedString left = AttributedString.fromAnsi(cand.displ()); - AttributedString right = AttributedString.fromAnsi(cand.descr()); + AttributedString left = fromAnsi(cand.displ()); + AttributedString right = fromAnsi(cand.descr()); int lw = left.columnLength(); int rw = 0; if (right != null) { - int rem = maxWidth - (lw + MARGIN_BETWEEN_DISPLAY_AND_DESC - + DESC_PREFIX.length() + DESC_SUFFIX.length()); + int rem = maxWidth + - (lw + + MARGIN_BETWEEN_DISPLAY_AND_DESC + + DESC_PREFIX.length() + + DESC_SUFFIX.length()); rw = right.columnLength(); if (rw > rem) { right = AttributedStringBuilder.append( - right.columnSubSequence(0, rem - WCWidth.wcwidth('\u2026')), - "\u2026"); + right.columnSubSequence(0, rem - WCWidth.wcwidth('\u2026')), "\u2026"); rw = right.columnLength(); } right = AttributedStringBuilder.append(DESC_PREFIX, right, DESC_SUFFIX); @@ -5325,8 +5473,9 @@ public class LineReaderImpl implements LineReader, Flushable if (cand == selection) { out[1] = i; asb.style(getCompletionStyleSelection(doMenuList)); - if (left.toString().regionMatches( - isSet(Option.CASE_INSENSITIVE), 0, completed, 0, completed.length())) { + if (left.toString() + .regionMatches( + isSet(Option.CASE_INSENSITIVE), 0, completed, 0, completed.length())) { asb.append(left.toString(), 0, completed.length()); asb.append(left.toString(), completed.length(), left.length()); } else { @@ -5340,8 +5489,9 @@ public class LineReaderImpl implements LineReader, Flushable } asb.style(AttributedStyle.DEFAULT); } else { - if (left.toString().regionMatches( - isSet(Option.CASE_INSENSITIVE), 0, completed, 0, completed.length())) { + if (left.toString() + .regionMatches( + isSet(Option.CASE_INSENSITIVE), 0, completed, 0, completed.length())) { asb.style(getCompletionStyleStarting(doMenuList)); asb.append(left, 0, completed.length()); asb.style(AttributedStyle.DEFAULT); @@ -5447,7 +5597,7 @@ public class LineReaderImpl implements LineReader, Flushable } protected AttributedStyle buildStyle(String str) { - return AttributedString.fromAnsi("\u001b[" + str + "m ").styleAt(0); + return fromAnsi("\u001b[" + str + "m ").styleAt(0); } /** @@ -5477,14 +5627,14 @@ public class LineReaderImpl implements LineReader, Flushable } if (next && !history.next()) { return false; - } - else if (!next && !history.previous()) { + } else if (!next && !history.previous()) { return false; } - setBuffer(modifiedHistory.containsKey(history.index()) - ? modifiedHistory.get(history.index()) - : history.current()); + setBuffer( + modifiedHistory.containsKey(history.index()) + ? modifiedHistory.get(history.index()) + : history.current()); return true; } @@ -5515,7 +5665,6 @@ public class LineReaderImpl implements LineReader, Flushable redrawLine(); } - // // Actions // @@ -5725,8 +5874,7 @@ public class LineReaderImpl implements LineReader, Flushable public boolean mouse() { MouseEvent event = readMouseEvent(); - if (event.getType() == MouseEvent.Type.Released - && event.getButton() == MouseEvent.Button.Button1) { + if (event.getType() == MouseEvent.Type.Released && event.getButton() == MouseEvent.Button.Button1) { StringBuilder tsb = new StringBuilder(); Cursor cursor = terminal.getCursorPosition(c -> tsb.append((char) c)); bindingReader.runMacro(tsb.toString()); @@ -5734,15 +5882,20 @@ public class LineReaderImpl implements LineReader, Flushable List secondaryPrompts = new ArrayList<>(); getDisplayedBufferWithPrompts(secondaryPrompts); - AttributedStringBuilder sb = new AttributedStringBuilder().tabs(TAB_WIDTH); + AttributedStringBuilder sb = new AttributedStringBuilder().tabs(getTabWidth()); sb.append(prompt); sb.append(insertSecondaryPrompts(new AttributedString(buf.upToCursor()), secondaryPrompts, false)); - List promptLines = sb.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); + List promptLines = + sb.columnSplitLength(size.getColumns(), false, display.delayLineWrap()); int currentLine = promptLines.size() - 1; int wantedLine = Math.max(0, Math.min(currentLine + event.getY() - cursor.getY(), secondaryPrompts.size())); - int pl0 = currentLine == 0 ? prompt.columnLength() : secondaryPrompts.get(currentLine - 1).columnLength(); - int pl1 = wantedLine == 0 ? prompt.columnLength() : secondaryPrompts.get(wantedLine - 1).columnLength(); + int pl0 = currentLine == 0 + ? prompt.columnLength() + : secondaryPrompts.get(currentLine - 1).columnLength(); + int pl1 = wantedLine == 0 + ? prompt.columnLength() + : secondaryPrompts.get(wantedLine - 1).columnLength(); int adjust = pl1 - pl0; buf.moveXY(event.getX() - cursor.getX() - adjust, event.getY() - cursor.getY()); } @@ -5814,13 +5967,11 @@ public class LineReaderImpl implements LineReader, Flushable bell_preference = BellType.VISIBLE; break; case "on": - bell_preference = getBoolean(PREFER_VISIBLE_BELL, false) - ? BellType.VISIBLE : BellType.AUDIBLE; + bell_preference = getBoolean(PREFER_VISIBLE_BELL, false) ? BellType.VISIBLE : BellType.AUDIBLE; break; } if (bell_preference == BellType.VISIBLE) { - if (terminal.puts(Capability.flash_screen) - || terminal.puts(Capability.bell)) { + if (terminal.puts(Capability.flash_screen) || terminal.puts(Capability.bell)) { flush(); } } else if (bell_preference == BellType.AUDIBLE) { @@ -5869,8 +6020,7 @@ public class LineReaderImpl implements LineReader, Flushable protected boolean isWord(int c) { String wordchars = getString(WORDCHARS, DEFAULT_WORDCHARS); - return Character.isLetterOrDigit(c) - || (c < 128 && wordchars.indexOf((char) c) >= 0); + return Character.isLetterOrDigit(c) || (c < 128 && wordchars.indexOf((char) c) >= 0); } String getString(String name, String def) { @@ -5899,6 +6049,8 @@ public class LineReaderImpl implements LineReader, Flushable keyMaps.put(VIOPP, viOpp()); keyMaps.put(VISUAL, visual()); keyMaps.put(SAFE, safe()); + keyMaps.put(DUMB, dumb()); + if (getBoolean(BIND_TTY_SPECIAL_CHARS, true)) { Attributes attr = terminal.getAttributes(); bindConsoleChars(keyMaps.get(EMACS), attr); @@ -5909,240 +6061,241 @@ public class LineReaderImpl implements LineReader, Flushable keyMap.setUnicode(new Reference(SELF_INSERT)); keyMap.setAmbiguousTimeout(getLong(AMBIGUOUS_BINDING, DEFAULT_AMBIGUOUS_BINDING)); } - // By default, link main to emacs - keyMaps.put(MAIN, keyMaps.get(EMACS)); + // By default, link main to emacs unless the temrinal is dumb + keyMaps.put(MAIN, keyMaps.get(isTerminalDumb() ? DUMB : EMACS)); + return keyMaps; } public KeyMap emacs() { KeyMap emacs = new KeyMap<>(); bindKeys(emacs); - bind(emacs, SET_MARK_COMMAND, ctrl('@')); - bind(emacs, BEGINNING_OF_LINE, ctrl('A')); - bind(emacs, BACKWARD_CHAR, ctrl('B')); - bind(emacs, DELETE_CHAR_OR_LIST, ctrl('D')); - bind(emacs, END_OF_LINE, ctrl('E')); - bind(emacs, FORWARD_CHAR, ctrl('F')); - bind(emacs, SEND_BREAK, ctrl('G')); - bind(emacs, BACKWARD_DELETE_CHAR, ctrl('H')); - bind(emacs, EXPAND_OR_COMPLETE, ctrl('I')); - bind(emacs, ACCEPT_LINE, ctrl('J')); - bind(emacs, KILL_LINE, ctrl('K')); - bind(emacs, CLEAR_SCREEN, ctrl('L')); - bind(emacs, ACCEPT_LINE, ctrl('M')); - bind(emacs, DOWN_LINE_OR_HISTORY, ctrl('N')); - bind(emacs, ACCEPT_LINE_AND_DOWN_HISTORY, ctrl('O')); - bind(emacs, UP_LINE_OR_HISTORY, ctrl('P')); - bind(emacs, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); - bind(emacs, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); - bind(emacs, TRANSPOSE_CHARS, ctrl('T')); - bind(emacs, KILL_WHOLE_LINE, ctrl('U')); - bind(emacs, QUOTED_INSERT, ctrl('V')); - bind(emacs, BACKWARD_KILL_WORD, ctrl('W')); - bind(emacs, YANK, ctrl('Y')); - bind(emacs, CHARACTER_SEARCH, ctrl(']')); - bind(emacs, UNDO, ctrl('_')); - bind(emacs, SELF_INSERT, range(" -~")); - bind(emacs, INSERT_CLOSE_PAREN, ")"); - bind(emacs, INSERT_CLOSE_SQUARE, "]"); - bind(emacs, INSERT_CLOSE_CURLY, "}"); - bind(emacs, BACKWARD_DELETE_CHAR, del()); - bind(emacs, VI_MATCH_BRACKET, translate("^X^B")); - bind(emacs, SEND_BREAK, translate("^X^G")); - bind(emacs, EDIT_AND_EXECUTE_COMMAND, translate("^X^E")); - bind(emacs, VI_FIND_NEXT_CHAR, translate("^X^F")); - bind(emacs, VI_JOIN, translate("^X^J")); - bind(emacs, KILL_BUFFER, translate("^X^K")); - bind(emacs, INFER_NEXT_HISTORY, translate("^X^N")); - bind(emacs, OVERWRITE_MODE, translate("^X^O")); - bind(emacs, REDO, translate("^X^R")); - bind(emacs, UNDO, translate("^X^U")); - bind(emacs, VI_CMD_MODE, translate("^X^V")); - bind(emacs, EXCHANGE_POINT_AND_MARK, translate("^X^X")); - bind(emacs, DO_LOWERCASE_VERSION, translate("^XA-^XZ")); - bind(emacs, WHAT_CURSOR_POSITION, translate("^X=")); - bind(emacs, KILL_LINE, translate("^X^?")); - bind(emacs, SEND_BREAK, alt(ctrl('G'))); - bind(emacs, BACKWARD_KILL_WORD, alt(ctrl('H'))); - bind(emacs, SELF_INSERT_UNMETA, alt(ctrl('M'))); - bind(emacs, COMPLETE_WORD, alt(esc())); - bind(emacs, CHARACTER_SEARCH_BACKWARD, alt(ctrl(']'))); - bind(emacs, COPY_PREV_WORD, alt(ctrl('_'))); - bind(emacs, SET_MARK_COMMAND, alt(' ')); - bind(emacs, NEG_ARGUMENT, alt('-')); - bind(emacs, DIGIT_ARGUMENT, range("\\E0-\\E9")); - bind(emacs, BEGINNING_OF_HISTORY, alt('<')); - bind(emacs, LIST_CHOICES, alt('=')); - bind(emacs, END_OF_HISTORY, alt('>')); - bind(emacs, LIST_CHOICES, alt('?')); - bind(emacs, DO_LOWERCASE_VERSION, range("^[A-^[Z")); - bind(emacs, ACCEPT_AND_HOLD, alt('a')); - bind(emacs, BACKWARD_WORD, alt('b')); - bind(emacs, CAPITALIZE_WORD, alt('c')); - bind(emacs, KILL_WORD, alt('d')); - bind(emacs, KILL_WORD, translate("^[[3;5~")); // ctrl-delete - bind(emacs, FORWARD_WORD, alt('f')); - bind(emacs, DOWN_CASE_WORD, alt('l')); - bind(emacs, HISTORY_SEARCH_FORWARD, alt('n')); - bind(emacs, HISTORY_SEARCH_BACKWARD, alt('p')); - bind(emacs, TRANSPOSE_WORDS, alt('t')); - bind(emacs, UP_CASE_WORD, alt('u')); - bind(emacs, YANK_POP, alt('y')); - bind(emacs, BACKWARD_KILL_WORD, alt(del())); + bind(emacs, SET_MARK_COMMAND, ctrl('@')); + bind(emacs, BEGINNING_OF_LINE, ctrl('A')); + bind(emacs, BACKWARD_CHAR, ctrl('B')); + bind(emacs, DELETE_CHAR_OR_LIST, ctrl('D')); + bind(emacs, END_OF_LINE, ctrl('E')); + bind(emacs, FORWARD_CHAR, ctrl('F')); + bind(emacs, SEND_BREAK, ctrl('G')); + bind(emacs, BACKWARD_DELETE_CHAR, ctrl('H')); + bind(emacs, EXPAND_OR_COMPLETE, ctrl('I')); + bind(emacs, ACCEPT_LINE, ctrl('J')); + bind(emacs, KILL_LINE, ctrl('K')); + bind(emacs, CLEAR_SCREEN, ctrl('L')); + bind(emacs, ACCEPT_LINE, ctrl('M')); + bind(emacs, DOWN_LINE_OR_HISTORY, ctrl('N')); + bind(emacs, ACCEPT_LINE_AND_DOWN_HISTORY, ctrl('O')); + bind(emacs, UP_LINE_OR_HISTORY, ctrl('P')); + bind(emacs, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); + bind(emacs, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); + bind(emacs, TRANSPOSE_CHARS, ctrl('T')); + bind(emacs, KILL_WHOLE_LINE, ctrl('U')); + bind(emacs, QUOTED_INSERT, ctrl('V')); + bind(emacs, BACKWARD_KILL_WORD, ctrl('W')); + bind(emacs, YANK, ctrl('Y')); + bind(emacs, CHARACTER_SEARCH, ctrl(']')); + bind(emacs, UNDO, ctrl('_')); + bind(emacs, SELF_INSERT, range(" -~")); + bind(emacs, INSERT_CLOSE_PAREN, ")"); + bind(emacs, INSERT_CLOSE_SQUARE, "]"); + bind(emacs, INSERT_CLOSE_CURLY, "}"); + bind(emacs, BACKWARD_DELETE_CHAR, del()); + bind(emacs, VI_MATCH_BRACKET, translate("^X^B")); + bind(emacs, SEND_BREAK, translate("^X^G")); + bind(emacs, EDIT_AND_EXECUTE_COMMAND, translate("^X^E")); + bind(emacs, VI_FIND_NEXT_CHAR, translate("^X^F")); + bind(emacs, VI_JOIN, translate("^X^J")); + bind(emacs, KILL_BUFFER, translate("^X^K")); + bind(emacs, INFER_NEXT_HISTORY, translate("^X^N")); + bind(emacs, OVERWRITE_MODE, translate("^X^O")); + bind(emacs, REDO, translate("^X^R")); + bind(emacs, UNDO, translate("^X^U")); + bind(emacs, VI_CMD_MODE, translate("^X^V")); + bind(emacs, EXCHANGE_POINT_AND_MARK, translate("^X^X")); + bind(emacs, DO_LOWERCASE_VERSION, translate("^XA-^XZ")); + bind(emacs, WHAT_CURSOR_POSITION, translate("^X=")); + bind(emacs, KILL_LINE, translate("^X^?")); + bind(emacs, SEND_BREAK, alt(ctrl('G'))); + bind(emacs, BACKWARD_KILL_WORD, alt(ctrl('H'))); + bind(emacs, SELF_INSERT_UNMETA, alt(ctrl('M'))); + bind(emacs, COMPLETE_WORD, alt(esc())); + bind(emacs, CHARACTER_SEARCH_BACKWARD, alt(ctrl(']'))); + bind(emacs, COPY_PREV_WORD, alt(ctrl('_'))); + bind(emacs, SET_MARK_COMMAND, alt(' ')); + bind(emacs, NEG_ARGUMENT, alt('-')); + bind(emacs, DIGIT_ARGUMENT, range("\\E0-\\E9")); + bind(emacs, BEGINNING_OF_HISTORY, alt('<')); + bind(emacs, LIST_CHOICES, alt('=')); + bind(emacs, END_OF_HISTORY, alt('>')); + bind(emacs, LIST_CHOICES, alt('?')); + bind(emacs, DO_LOWERCASE_VERSION, range("^[A-^[Z")); + bind(emacs, ACCEPT_AND_HOLD, alt('a')); + bind(emacs, BACKWARD_WORD, alt('b')); + bind(emacs, CAPITALIZE_WORD, alt('c')); + bind(emacs, KILL_WORD, alt('d')); + bind(emacs, KILL_WORD, translate("^[[3;5~")); // ctrl-delete + bind(emacs, FORWARD_WORD, alt('f')); + bind(emacs, DOWN_CASE_WORD, alt('l')); + bind(emacs, HISTORY_SEARCH_FORWARD, alt('n')); + bind(emacs, HISTORY_SEARCH_BACKWARD, alt('p')); + bind(emacs, TRANSPOSE_WORDS, alt('t')); + bind(emacs, UP_CASE_WORD, alt('u')); + bind(emacs, YANK_POP, alt('y')); + bind(emacs, BACKWARD_KILL_WORD, alt(del())); bindArrowKeys(emacs); - bind(emacs, FORWARD_WORD, translate("^[[1;5C")); // ctrl-left - bind(emacs, BACKWARD_WORD, translate("^[[1;5D")); // ctrl-right - bind(emacs, FORWARD_WORD, alt(key(Capability.key_right))); - bind(emacs, BACKWARD_WORD, alt(key(Capability.key_left))); - bind(emacs, FORWARD_WORD, alt(translate("^[[C"))); - bind(emacs, BACKWARD_WORD, alt(translate("^[[D"))); + bind(emacs, FORWARD_WORD, translate("^[[1;5C")); // ctrl-left + bind(emacs, BACKWARD_WORD, translate("^[[1;5D")); // ctrl-right + bind(emacs, FORWARD_WORD, alt(key(Capability.key_right))); + bind(emacs, BACKWARD_WORD, alt(key(Capability.key_left))); + bind(emacs, FORWARD_WORD, alt(translate("^[[C"))); + bind(emacs, BACKWARD_WORD, alt(translate("^[[D"))); return emacs; } public KeyMap viInsertion() { KeyMap viins = new KeyMap<>(); bindKeys(viins); - bind(viins, SELF_INSERT, range("^@-^_")); - bind(viins, LIST_CHOICES, ctrl('D')); - bind(viins, SEND_BREAK, ctrl('G')); - bind(viins, BACKWARD_DELETE_CHAR, ctrl('H')); - bind(viins, EXPAND_OR_COMPLETE, ctrl('I')); - bind(viins, ACCEPT_LINE, ctrl('J')); - bind(viins, CLEAR_SCREEN, ctrl('L')); - bind(viins, ACCEPT_LINE, ctrl('M')); - bind(viins, MENU_COMPLETE, ctrl('N')); - bind(viins, REVERSE_MENU_COMPLETE, ctrl('P')); - bind(viins, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); - bind(viins, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); - bind(viins, TRANSPOSE_CHARS, ctrl('T')); - bind(viins, KILL_WHOLE_LINE, ctrl('U')); - bind(viins, QUOTED_INSERT, ctrl('V')); - bind(viins, BACKWARD_KILL_WORD, ctrl('W')); - bind(viins, YANK, ctrl('Y')); - bind(viins, VI_CMD_MODE, ctrl('[')); - bind(viins, UNDO, ctrl('_')); - bind(viins, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('X') + "r"); - bind(viins, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('X') + "s"); - bind(viins, SELF_INSERT, range(" -~")); - bind(viins, INSERT_CLOSE_PAREN, ")"); - bind(viins, INSERT_CLOSE_SQUARE, "]"); - bind(viins, INSERT_CLOSE_CURLY, "}"); - bind(viins, BACKWARD_DELETE_CHAR, del()); + bind(viins, SELF_INSERT, range("^@-^_")); + bind(viins, LIST_CHOICES, ctrl('D')); + bind(viins, SEND_BREAK, ctrl('G')); + bind(viins, BACKWARD_DELETE_CHAR, ctrl('H')); + bind(viins, EXPAND_OR_COMPLETE, ctrl('I')); + bind(viins, ACCEPT_LINE, ctrl('J')); + bind(viins, CLEAR_SCREEN, ctrl('L')); + bind(viins, ACCEPT_LINE, ctrl('M')); + bind(viins, MENU_COMPLETE, ctrl('N')); + bind(viins, REVERSE_MENU_COMPLETE, ctrl('P')); + bind(viins, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); + bind(viins, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); + bind(viins, TRANSPOSE_CHARS, ctrl('T')); + bind(viins, KILL_WHOLE_LINE, ctrl('U')); + bind(viins, QUOTED_INSERT, ctrl('V')); + bind(viins, BACKWARD_KILL_WORD, ctrl('W')); + bind(viins, YANK, ctrl('Y')); + bind(viins, VI_CMD_MODE, ctrl('[')); + bind(viins, UNDO, ctrl('_')); + bind(viins, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('X') + "r"); + bind(viins, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('X') + "s"); + bind(viins, SELF_INSERT, range(" -~")); + bind(viins, INSERT_CLOSE_PAREN, ")"); + bind(viins, INSERT_CLOSE_SQUARE, "]"); + bind(viins, INSERT_CLOSE_CURLY, "}"); + bind(viins, BACKWARD_DELETE_CHAR, del()); bindArrowKeys(viins); return viins; } public KeyMap viCmd() { KeyMap vicmd = new KeyMap<>(); - bind(vicmd, LIST_CHOICES, ctrl('D')); - bind(vicmd, EMACS_EDITING_MODE, ctrl('E')); - bind(vicmd, SEND_BREAK, ctrl('G')); - bind(vicmd, VI_BACKWARD_CHAR, ctrl('H')); - bind(vicmd, ACCEPT_LINE, ctrl('J')); - bind(vicmd, KILL_LINE, ctrl('K')); - bind(vicmd, CLEAR_SCREEN, ctrl('L')); - bind(vicmd, ACCEPT_LINE, ctrl('M')); - bind(vicmd, VI_DOWN_LINE_OR_HISTORY, ctrl('N')); - bind(vicmd, VI_UP_LINE_OR_HISTORY, ctrl('P')); - bind(vicmd, QUOTED_INSERT, ctrl('Q')); - bind(vicmd, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); - bind(vicmd, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); - bind(vicmd, TRANSPOSE_CHARS, ctrl('T')); - bind(vicmd, KILL_WHOLE_LINE, ctrl('U')); - bind(vicmd, QUOTED_INSERT, ctrl('V')); - bind(vicmd, BACKWARD_KILL_WORD, ctrl('W')); - bind(vicmd, YANK, ctrl('Y')); - bind(vicmd, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('X') + "r"); - bind(vicmd, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('X') + "s"); - bind(vicmd, SEND_BREAK, alt(ctrl('G'))); - bind(vicmd, BACKWARD_KILL_WORD, alt(ctrl('H'))); - bind(vicmd, SELF_INSERT_UNMETA, alt(ctrl('M'))); - bind(vicmd, COMPLETE_WORD, alt(esc())); - bind(vicmd, CHARACTER_SEARCH_BACKWARD, alt(ctrl(']'))); - bind(vicmd, SET_MARK_COMMAND, alt(' ')); -// bind(vicmd, INSERT_COMMENT, alt('#')); -// bind(vicmd, INSERT_COMPLETIONS, alt('*')); - bind(vicmd, DIGIT_ARGUMENT, alt('-')); - bind(vicmd, BEGINNING_OF_HISTORY, alt('<')); - bind(vicmd, LIST_CHOICES, alt('=')); - bind(vicmd, END_OF_HISTORY, alt('>')); - bind(vicmd, LIST_CHOICES, alt('?')); - bind(vicmd, DO_LOWERCASE_VERSION, range("^[A-^[Z")); - bind(vicmd, BACKWARD_WORD, alt('b')); - bind(vicmd, CAPITALIZE_WORD, alt('c')); - bind(vicmd, KILL_WORD, alt('d')); - bind(vicmd, FORWARD_WORD, alt('f')); - bind(vicmd, DOWN_CASE_WORD, alt('l')); - bind(vicmd, HISTORY_SEARCH_FORWARD, alt('n')); - bind(vicmd, HISTORY_SEARCH_BACKWARD, alt('p')); - bind(vicmd, TRANSPOSE_WORDS, alt('t')); - bind(vicmd, UP_CASE_WORD, alt('u')); - bind(vicmd, YANK_POP, alt('y')); - bind(vicmd, BACKWARD_KILL_WORD, alt(del())); + bind(vicmd, LIST_CHOICES, ctrl('D')); + bind(vicmd, EMACS_EDITING_MODE, ctrl('E')); + bind(vicmd, SEND_BREAK, ctrl('G')); + bind(vicmd, VI_BACKWARD_CHAR, ctrl('H')); + bind(vicmd, ACCEPT_LINE, ctrl('J')); + bind(vicmd, KILL_LINE, ctrl('K')); + bind(vicmd, CLEAR_SCREEN, ctrl('L')); + bind(vicmd, ACCEPT_LINE, ctrl('M')); + bind(vicmd, VI_DOWN_LINE_OR_HISTORY, ctrl('N')); + bind(vicmd, VI_UP_LINE_OR_HISTORY, ctrl('P')); + bind(vicmd, QUOTED_INSERT, ctrl('Q')); + bind(vicmd, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); + bind(vicmd, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); + bind(vicmd, TRANSPOSE_CHARS, ctrl('T')); + bind(vicmd, KILL_WHOLE_LINE, ctrl('U')); + bind(vicmd, QUOTED_INSERT, ctrl('V')); + bind(vicmd, BACKWARD_KILL_WORD, ctrl('W')); + bind(vicmd, YANK, ctrl('Y')); + bind(vicmd, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('X') + "r"); + bind(vicmd, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('X') + "s"); + bind(vicmd, SEND_BREAK, alt(ctrl('G'))); + bind(vicmd, BACKWARD_KILL_WORD, alt(ctrl('H'))); + bind(vicmd, SELF_INSERT_UNMETA, alt(ctrl('M'))); + bind(vicmd, COMPLETE_WORD, alt(esc())); + bind(vicmd, CHARACTER_SEARCH_BACKWARD, alt(ctrl(']'))); + bind(vicmd, SET_MARK_COMMAND, alt(' ')); + // bind(vicmd, INSERT_COMMENT, alt('#')); + // bind(vicmd, INSERT_COMPLETIONS, alt('*')); + bind(vicmd, DIGIT_ARGUMENT, alt('-')); + bind(vicmd, BEGINNING_OF_HISTORY, alt('<')); + bind(vicmd, LIST_CHOICES, alt('=')); + bind(vicmd, END_OF_HISTORY, alt('>')); + bind(vicmd, LIST_CHOICES, alt('?')); + bind(vicmd, DO_LOWERCASE_VERSION, range("^[A-^[Z")); + bind(vicmd, BACKWARD_WORD, alt('b')); + bind(vicmd, CAPITALIZE_WORD, alt('c')); + bind(vicmd, KILL_WORD, alt('d')); + bind(vicmd, FORWARD_WORD, alt('f')); + bind(vicmd, DOWN_CASE_WORD, alt('l')); + bind(vicmd, HISTORY_SEARCH_FORWARD, alt('n')); + bind(vicmd, HISTORY_SEARCH_BACKWARD, alt('p')); + bind(vicmd, TRANSPOSE_WORDS, alt('t')); + bind(vicmd, UP_CASE_WORD, alt('u')); + bind(vicmd, YANK_POP, alt('y')); + bind(vicmd, BACKWARD_KILL_WORD, alt(del())); - bind(vicmd, FORWARD_CHAR, " "); - bind(vicmd, VI_INSERT_COMMENT, "#"); - bind(vicmd, END_OF_LINE, "$"); - bind(vicmd, VI_MATCH_BRACKET, "%"); - bind(vicmd, VI_DOWN_LINE_OR_HISTORY, "+"); - bind(vicmd, VI_REV_REPEAT_FIND, ","); - bind(vicmd, VI_UP_LINE_OR_HISTORY, "-"); - bind(vicmd, VI_REPEAT_CHANGE, "."); - bind(vicmd, VI_HISTORY_SEARCH_BACKWARD, "/"); - bind(vicmd, VI_DIGIT_OR_BEGINNING_OF_LINE, "0"); - bind(vicmd, DIGIT_ARGUMENT, range("1-9")); - bind(vicmd, VI_REPEAT_FIND, ";"); - bind(vicmd, LIST_CHOICES, "="); - bind(vicmd, VI_HISTORY_SEARCH_FORWARD, "?"); - bind(vicmd, VI_ADD_EOL, "A"); - bind(vicmd, VI_BACKWARD_BLANK_WORD, "B"); - bind(vicmd, VI_CHANGE_EOL, "C"); - bind(vicmd, VI_KILL_EOL, "D"); - bind(vicmd, VI_FORWARD_BLANK_WORD_END, "E"); - bind(vicmd, VI_FIND_PREV_CHAR, "F"); - bind(vicmd, VI_FETCH_HISTORY, "G"); - bind(vicmd, VI_INSERT_BOL, "I"); - bind(vicmd, VI_JOIN, "J"); - bind(vicmd, VI_REV_REPEAT_SEARCH, "N"); - bind(vicmd, VI_OPEN_LINE_ABOVE, "O"); - bind(vicmd, VI_PUT_BEFORE, "P"); - bind(vicmd, VI_REPLACE, "R"); - bind(vicmd, VI_KILL_LINE, "S"); - bind(vicmd, VI_FIND_PREV_CHAR_SKIP, "T"); - bind(vicmd, REDO, "U"); - bind(vicmd, VISUAL_LINE_MODE, "V"); - bind(vicmd, VI_FORWARD_BLANK_WORD, "W"); - bind(vicmd, VI_BACKWARD_DELETE_CHAR, "X"); - bind(vicmd, VI_YANK_WHOLE_LINE, "Y"); - bind(vicmd, VI_FIRST_NON_BLANK, "^"); - bind(vicmd, VI_ADD_NEXT, "a"); - bind(vicmd, VI_BACKWARD_WORD, "b"); - bind(vicmd, VI_CHANGE, "c"); - bind(vicmd, VI_DELETE, "d"); - bind(vicmd, VI_FORWARD_WORD_END, "e"); - bind(vicmd, VI_FIND_NEXT_CHAR, "f"); - bind(vicmd, WHAT_CURSOR_POSITION, "ga"); - bind(vicmd, VI_BACKWARD_BLANK_WORD_END, "gE"); - bind(vicmd, VI_BACKWARD_WORD_END, "ge"); - bind(vicmd, VI_BACKWARD_CHAR, "h"); - bind(vicmd, VI_INSERT, "i"); - bind(vicmd, DOWN_LINE_OR_HISTORY, "j"); - bind(vicmd, UP_LINE_OR_HISTORY, "k"); - bind(vicmd, VI_FORWARD_CHAR, "l"); - bind(vicmd, VI_REPEAT_SEARCH, "n"); - bind(vicmd, VI_OPEN_LINE_BELOW, "o"); - bind(vicmd, VI_PUT_AFTER, "p"); - bind(vicmd, VI_REPLACE_CHARS, "r"); - bind(vicmd, VI_SUBSTITUTE, "s"); - bind(vicmd, VI_FIND_NEXT_CHAR_SKIP, "t"); - bind(vicmd, UNDO, "u"); - bind(vicmd, VISUAL_MODE, "v"); - bind(vicmd, VI_FORWARD_WORD, "w"); - bind(vicmd, VI_DELETE_CHAR, "x"); - bind(vicmd, VI_YANK, "y"); - bind(vicmd, VI_GOTO_COLUMN, "|"); - bind(vicmd, VI_SWAP_CASE, "~"); - bind(vicmd, VI_BACKWARD_CHAR, del()); + bind(vicmd, FORWARD_CHAR, " "); + bind(vicmd, VI_INSERT_COMMENT, "#"); + bind(vicmd, END_OF_LINE, "$"); + bind(vicmd, VI_MATCH_BRACKET, "%"); + bind(vicmd, VI_DOWN_LINE_OR_HISTORY, "+"); + bind(vicmd, VI_REV_REPEAT_FIND, ","); + bind(vicmd, VI_UP_LINE_OR_HISTORY, "-"); + bind(vicmd, VI_REPEAT_CHANGE, "."); + bind(vicmd, VI_HISTORY_SEARCH_BACKWARD, "/"); + bind(vicmd, VI_DIGIT_OR_BEGINNING_OF_LINE, "0"); + bind(vicmd, DIGIT_ARGUMENT, range("1-9")); + bind(vicmd, VI_REPEAT_FIND, ";"); + bind(vicmd, LIST_CHOICES, "="); + bind(vicmd, VI_HISTORY_SEARCH_FORWARD, "?"); + bind(vicmd, VI_ADD_EOL, "A"); + bind(vicmd, VI_BACKWARD_BLANK_WORD, "B"); + bind(vicmd, VI_CHANGE_EOL, "C"); + bind(vicmd, VI_KILL_EOL, "D"); + bind(vicmd, VI_FORWARD_BLANK_WORD_END, "E"); + bind(vicmd, VI_FIND_PREV_CHAR, "F"); + bind(vicmd, VI_FETCH_HISTORY, "G"); + bind(vicmd, VI_INSERT_BOL, "I"); + bind(vicmd, VI_JOIN, "J"); + bind(vicmd, VI_REV_REPEAT_SEARCH, "N"); + bind(vicmd, VI_OPEN_LINE_ABOVE, "O"); + bind(vicmd, VI_PUT_BEFORE, "P"); + bind(vicmd, VI_REPLACE, "R"); + bind(vicmd, VI_KILL_LINE, "S"); + bind(vicmd, VI_FIND_PREV_CHAR_SKIP, "T"); + bind(vicmd, REDO, "U"); + bind(vicmd, VISUAL_LINE_MODE, "V"); + bind(vicmd, VI_FORWARD_BLANK_WORD, "W"); + bind(vicmd, VI_BACKWARD_DELETE_CHAR, "X"); + bind(vicmd, VI_YANK_WHOLE_LINE, "Y"); + bind(vicmd, VI_FIRST_NON_BLANK, "^"); + bind(vicmd, VI_ADD_NEXT, "a"); + bind(vicmd, VI_BACKWARD_WORD, "b"); + bind(vicmd, VI_CHANGE, "c"); + bind(vicmd, VI_DELETE, "d"); + bind(vicmd, VI_FORWARD_WORD_END, "e"); + bind(vicmd, VI_FIND_NEXT_CHAR, "f"); + bind(vicmd, WHAT_CURSOR_POSITION, "ga"); + bind(vicmd, VI_BACKWARD_BLANK_WORD_END, "gE"); + bind(vicmd, VI_BACKWARD_WORD_END, "ge"); + bind(vicmd, VI_BACKWARD_CHAR, "h"); + bind(vicmd, VI_INSERT, "i"); + bind(vicmd, DOWN_LINE_OR_HISTORY, "j"); + bind(vicmd, UP_LINE_OR_HISTORY, "k"); + bind(vicmd, VI_FORWARD_CHAR, "l"); + bind(vicmd, VI_REPEAT_SEARCH, "n"); + bind(vicmd, VI_OPEN_LINE_BELOW, "o"); + bind(vicmd, VI_PUT_AFTER, "p"); + bind(vicmd, VI_REPLACE_CHARS, "r"); + bind(vicmd, VI_SUBSTITUTE, "s"); + bind(vicmd, VI_FIND_NEXT_CHAR_SKIP, "t"); + bind(vicmd, UNDO, "u"); + bind(vicmd, VISUAL_MODE, "v"); + bind(vicmd, VI_FORWARD_WORD, "w"); + bind(vicmd, VI_DELETE_CHAR, "x"); + bind(vicmd, VI_YANK, "y"); + bind(vicmd, VI_GOTO_COLUMN, "|"); + bind(vicmd, VI_SWAP_CASE, "~"); + bind(vicmd, VI_BACKWARD_CHAR, del()); bindArrowKeys(vicmd); return vicmd; @@ -6150,38 +6303,46 @@ public class LineReaderImpl implements LineReader, Flushable public KeyMap menu() { KeyMap menu = new KeyMap<>(); - bind(menu, MENU_COMPLETE, "\t"); - bind(menu, REVERSE_MENU_COMPLETE, key(Capability.back_tab)); - bind(menu, ACCEPT_LINE, "\r", "\n"); + bind(menu, MENU_COMPLETE, "\t"); + bind(menu, REVERSE_MENU_COMPLETE, key(Capability.back_tab)); + bind(menu, ACCEPT_LINE, "\r", "\n"); bindArrowKeys(menu); return menu; } public KeyMap safe() { KeyMap safe = new KeyMap<>(); - bind(safe, SELF_INSERT, range("^@-^?")); - bind(safe, ACCEPT_LINE, "\r", "\n"); - bind(safe, SEND_BREAK, ctrl('G')); + bind(safe, SELF_INSERT, range("^@-^?")); + bind(safe, ACCEPT_LINE, "\r", "\n"); + bind(safe, SEND_BREAK, ctrl('G')); return safe; } + public KeyMap dumb() { + KeyMap dumb = new KeyMap<>(); + bind(dumb, SELF_INSERT, range("^@-^?")); + bind(dumb, ACCEPT_LINE, "\r", "\n"); + bind(dumb, BEEP, ctrl('G')); + return dumb; + } + public KeyMap visual() { KeyMap visual = new KeyMap<>(); - bind(visual, UP_LINE, key(Capability.key_up), "k"); - bind(visual, DOWN_LINE, key(Capability.key_down), "j"); - bind(visual, this::deactivateRegion, esc()); - bind(visual, EXCHANGE_POINT_AND_MARK, "o"); - bind(visual, PUT_REPLACE_SELECTION, "p"); - bind(visual, VI_DELETE, "x"); - bind(visual, VI_OPER_SWAP_CASE, "~"); + bind(visual, UP_LINE, key(Capability.key_up), "k"); + bind(visual, DOWN_LINE, key(Capability.key_down), "j"); + bind(visual, this::deactivateRegion, esc()); + bind(visual, EXCHANGE_POINT_AND_MARK, "o"); + bind(visual, PUT_REPLACE_SELECTION, "p"); + bind(visual, VI_DELETE, "x"); + bind(visual, VI_OPER_SWAP_CASE, "~"); return visual; } public KeyMap viOpp() { KeyMap viOpp = new KeyMap<>(); - bind(viOpp, UP_LINE, key(Capability.key_up), "k"); - bind(viOpp, DOWN_LINE, key(Capability.key_down), "j"); - bind(viOpp, VI_CMD_MODE, esc()); + bind(viOpp, UP_LINE, key(Capability.key_up), "k"); + bind(viOpp, DOWN_LINE, key(Capability.key_down), "j"); + bind(viOpp, VI_CMD_MODE, esc()); return viOpp; } @@ -6210,19 +6371,19 @@ public class LineReaderImpl implements LineReader, Flushable } private void bindArrowKeys(KeyMap map) { - bind(map, UP_LINE_OR_SEARCH, key(Capability.key_up)); - bind(map, DOWN_LINE_OR_SEARCH, key(Capability.key_down)); - bind(map, BACKWARD_CHAR, key(Capability.key_left)); - bind(map, FORWARD_CHAR, key(Capability.key_right)); - bind(map, BEGINNING_OF_LINE, key(Capability.key_home)); - bind(map, END_OF_LINE, key(Capability.key_end)); - bind(map, DELETE_CHAR, key(Capability.key_dc)); - bind(map, KILL_WHOLE_LINE, key(Capability.key_dl)); - bind(map, OVERWRITE_MODE, key(Capability.key_ic)); - bind(map, MOUSE, key(Capability.key_mouse)); - bind(map, BEGIN_PASTE, BRACKETED_PASTE_BEGIN); - bind(map, FOCUS_IN, FOCUS_IN_SEQ); - bind(map, FOCUS_OUT, FOCUS_OUT_SEQ); + bind(map, UP_LINE_OR_SEARCH, key(Capability.key_up)); + bind(map, DOWN_LINE_OR_SEARCH, key(Capability.key_down)); + bind(map, BACKWARD_CHAR, key(Capability.key_left)); + bind(map, FORWARD_CHAR, key(Capability.key_right)); + bind(map, BEGINNING_OF_LINE, key(Capability.key_home)); + bind(map, END_OF_LINE, key(Capability.key_end)); + bind(map, DELETE_CHAR, key(Capability.key_dc)); + bind(map, KILL_WHOLE_LINE, key(Capability.key_dl)); + bind(map, OVERWRITE_MODE, key(Capability.key_ic)); + bind(map, MOUSE, key(Capability.key_mouse)); + bind(map, BEGIN_PASTE, BRACKETED_PASTE_BEGIN); + bind(map, FOCUS_IN, FOCUS_IN_SEQ); + bind(map, FOCUS_OUT, FOCUS_OUT_SEQ); } /** @@ -6231,14 +6392,10 @@ public class LineReaderImpl implements LineReader, Flushable */ private void bindConsoleChars(KeyMap keyMap, Attributes attr) { if (attr != null) { - rebind(keyMap, BACKWARD_DELETE_CHAR, - del(), (char) attr.getControlChar(ControlChar.VERASE)); - rebind(keyMap, BACKWARD_KILL_WORD, - ctrl('W'), (char) attr.getControlChar(ControlChar.VWERASE)); - rebind(keyMap, KILL_WHOLE_LINE, - ctrl('U'), (char) attr.getControlChar(ControlChar.VKILL)); - rebind(keyMap, QUOTED_INSERT, - ctrl('V'), (char) attr.getControlChar(ControlChar.VLNEXT)); + rebind(keyMap, BACKWARD_DELETE_CHAR, del(), (char) attr.getControlChar(ControlChar.VERASE)); + rebind(keyMap, BACKWARD_KILL_WORD, ctrl('W'), (char) attr.getControlChar(ControlChar.VWERASE)); + rebind(keyMap, KILL_WHOLE_LINE, ctrl('U'), (char) attr.getControlChar(ControlChar.VKILL)); + rebind(keyMap, QUOTED_INSERT, ctrl('V'), (char) attr.getControlChar(ControlChar.VLNEXT)); } } @@ -6250,7 +6407,6 @@ public class LineReaderImpl implements LineReader, Flushable } } - // JDK specific modification @Override public void zeroOut() { buf.zeroOut(); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java index 0ae9475bd57..cdc60dccccf 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/ReaderUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -13,7 +13,7 @@ import jdk.internal.org.jline.utils.Levenshtein; public class ReaderUtils { - private ReaderUtils() { } + private ReaderUtils() {} public static boolean isSet(LineReader reader, LineReader.Option option) { return reader != null && reader.isSet(option); @@ -30,8 +30,7 @@ public class ReaderUtils { return (Boolean) v; } else if (v != null) { String s = v.toString(); - return s.isEmpty() || s.equalsIgnoreCase("on") - || s.equalsIgnoreCase("1") || s.equalsIgnoreCase("true"); + return s.isEmpty() || s.equalsIgnoreCase("on") || s.equalsIgnoreCase("1") || s.equalsIgnoreCase("true"); } return def; } @@ -77,5 +76,4 @@ public class ReaderUtils { return Levenshtein.distance(word, cand); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/SimpleMaskingCallback.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/SimpleMaskingCallback.java index fd6c2663c05..423497f3dc4 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/SimpleMaskingCallback.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/SimpleMaskingCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,10 +8,10 @@ */ package jdk.internal.org.jline.reader.impl; -import jdk.internal.org.jline.reader.MaskingCallback; - import java.util.Objects; +import jdk.internal.org.jline.reader.MaskingCallback; + /** * Simple {@link MaskingCallback} that will replace all the characters in the line with the given mask. * If the given mask is equal to {@link LineReaderImpl#NULL_MASK} then the line will be replaced with an empty String. @@ -29,7 +29,7 @@ public final class SimpleMaskingCallback implements MaskingCallback { return ""; } else { StringBuilder sb = new StringBuilder(line.length()); - for (int i = line.length(); i-- > 0;) { + for (int i = line.length(); i-- > 0; ) { sb.append((char) mask); } return sb.toString(); @@ -40,5 +40,4 @@ public final class SimpleMaskingCallback implements MaskingCallback { public String history(String line) { return null; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/UndoTree.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/UndoTree.java index 0a467f9d7ba..3b193f9eb65 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/UndoTree.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/UndoTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -20,6 +20,7 @@ public class UndoTree { private final Node parent; private Node current; + @SuppressWarnings("this-escape") public UndoTree(Consumer s) { state = s; parent = new Node(null); @@ -71,5 +72,4 @@ public class UndoTree { state = s; } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/AggregateCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/AggregateCompleter.java index e8e41088c59..145823c53ce 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/AggregateCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/AggregateCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -24,9 +24,7 @@ import jdk.internal.org.jline.reader.ParsedLine; * @author Jason Dillon * @since 2.3 */ -public class AggregateCompleter - implements Completer -{ +public class AggregateCompleter implements Completer { private final Collection completers; /** @@ -78,9 +76,6 @@ public class AggregateCompleter */ @Override public String toString() { - return getClass().getSimpleName() + "{" + - "completers=" + completers + - '}'; + return getClass().getSimpleName() + "{" + "completers=" + completers + '}'; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/ArgumentCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/ArgumentCompleter.java index f84c8a9002a..f0efa292252 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/ArgumentCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/ArgumentCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -29,8 +29,7 @@ import jdk.internal.org.jline.reader.ParsedLine; * @author Jason Dillon * @since 2.3 */ -public class ArgumentCompleter implements Completer -{ +public class ArgumentCompleter implements Completer { private final List completers = new ArrayList<>(); private boolean strict = true; @@ -108,12 +107,12 @@ public class ArgumentCompleter implements Completer // if we are beyond the end of the completers, just use the last one if (line.wordIndex() >= completers.size()) { completer = completers.get(completers.size() - 1); - } - else { + } else { completer = completers.get(line.wordIndex()); } - // ensure that all the previous completers are successful before allowing this completer to pass (only if strict). + // ensure that all the previous completers are successful before allowing this completer to pass (only if + // strict). for (int i = strictCommand ? 0 : 1; isStrict() && (i < line.wordIndex()); i++) { int idx = i >= completers.size() ? (completers.size() - 1) : i; if (idx == 0 && !strictCommand) { diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/EnumCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/EnumCompleter.java index 6a18d3cfd93..a701f2e3560 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/EnumCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/EnumCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -19,8 +19,7 @@ import jdk.internal.org.jline.reader.Completer; * @author Jason Dillon * @since 2.3 */ -public class EnumCompleter extends StringsCompleter -{ +public class EnumCompleter extends StringsCompleter { public EnumCompleter(Class> source) { Objects.requireNonNull(source); for (Enum n : source.getEnumConstants()) { diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java index 3d173f72ec7..32bf6e3493e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -9,6 +9,7 @@ package jdk.internal.org.jline.reader.impl.completer; import java.io.IOException; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -41,11 +42,10 @@ import jdk.internal.org.jline.utils.AttributedStyle; * @author Marc Prud'hommeaux * @author Jason Dillon * @since 2.3 - * @deprecated use jdk.internal.org.jline.builtins.Completers$FileNameCompleter instead + * @deprecated use org.jline.builtins.Completers$FileNameCompleter instead */ @Deprecated -public class FileNameCompleter implements Completer -{ +public class FileNameCompleter implements Completer { public void complete(LineReader reader, ParsedLine commandLine, final List candidates) { assert commandLine != null; @@ -72,20 +72,21 @@ public class FileNameCompleter implements Completer curBuf = ""; current = getUserDir(); } - try { - Files.newDirectoryStream(current, this::accept).forEach(p -> { + try (DirectoryStream directoryStream = Files.newDirectoryStream(current, this::accept)) { + directoryStream.forEach(p -> { String value = curBuf + p.getFileName().toString(); if (Files.isDirectory(p)) { candidates.add(new Candidate( value + (reader.isSet(Option.AUTO_PARAM_SLASH) ? sep : ""), getDisplay(reader.getTerminal(), p), - null, null, + null, + null, reader.isSet(Option.AUTO_REMOVE_SLASH) ? sep : null, null, false)); } else { - candidates.add(new Candidate(value, getDisplay(reader.getTerminal(), p), - null, null, null, null, true)); + candidates.add( + new Candidate(value, getDisplay(reader.getTerminal(), p), null, null, null, null, true)); } }); } catch (IOException e) { @@ -125,5 +126,4 @@ public class FileNameCompleter implements Completer } return name; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/NullCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/NullCompleter.java index f3efefdc929..21ce836a32f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/NullCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/NullCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -22,11 +22,8 @@ import jdk.internal.org.jline.reader.ParsedLine; * @author Jason Dillon * @since 2.3 */ -public final class NullCompleter - implements Completer -{ +public final class NullCompleter implements Completer { public static final NullCompleter INSTANCE = new NullCompleter(); - public void complete(LineReader reader, final ParsedLine line, final List candidates) { - } + public void complete(LineReader reader, final ParsedLine line, final List candidates) {} } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java index 8baac657b93..c791ef68e72 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/StringsCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -27,8 +27,7 @@ import jdk.internal.org.jline.utils.AttributedString; * @author Jason Dillon * @since 2.3 */ -public class StringsCompleter implements Completer -{ +public class StringsCompleter implements Completer { protected Collection candidates; protected Supplier> stringsSupplier; @@ -54,7 +53,7 @@ public class StringsCompleter implements Completer } } - public StringsCompleter(Candidate ... candidates) { + public StringsCompleter(Candidate... candidates) { this(Arrays.asList(candidates)); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java index a17a356bf0e..2fe6f8df492 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -22,8 +22,8 @@ import jdk.internal.org.jline.utils.AttributedString; * @author Matti Rinta-Nikkola */ public class SystemCompleter implements Completer { - private Map> completers = new HashMap<>(); - private Map aliasCommand = new HashMap<>(); + private Map> completers = new HashMap<>(); + private Map aliasCommand = new HashMap<>(); private StringsCompleter commands; private boolean compiled = false; @@ -44,9 +44,9 @@ public class SystemCompleter implements Completer { commands.complete(reader, commandLine, candidates); } else if (reader.getParser().validVariableName(buffer.substring(0, eq))) { String curBuf = buffer.substring(0, eq + 1); - for (String c: completers.keySet()) { - candidates.add(new Candidate(AttributedString.stripAnsi(curBuf+c) - , c, null, null, null, null, true)); + for (String c : completers.keySet()) { + candidates.add( + new Candidate(AttributedString.stripAnsi(curBuf + c), c, null, null, null, null, true)); } } } else { @@ -81,7 +81,7 @@ public class SystemCompleter implements Completer { } public void add(List commands, Completer completer) { - for (String c: commands) { + for (String c : commands) { add(c, completer); } } @@ -104,22 +104,22 @@ public class SystemCompleter implements Completer { if (other.isCompiled()) { throw new IllegalStateException(); } - for (Map.Entry> entry: other.getCompleters().entrySet()) { - for (Completer c: entry.getValue()) { + for (Map.Entry> entry : other.getCompleters().entrySet()) { + for (Completer c : entry.getValue()) { add(entry.getKey(), c); } } addAliases(other.getAliases()); } - public void addAliases(Map aliasCommand) { + public void addAliases(Map aliasCommand) { if (compiled) { throw new IllegalStateException(); } this.aliasCommand.putAll(aliasCommand); } - private Map getAliases() { + private Map getAliases() { return aliasCommand; } @@ -128,7 +128,7 @@ public class SystemCompleter implements Completer { return; } Map> compiledCompleters = new HashMap<>(); - for (Map.Entry> entry: completers.entrySet()) { + for (Map.Entry> entry : completers.entrySet()) { if (entry.getValue().size() == 1) { compiledCompleters.put(entry.getKey(), entry.getValue()); } else { @@ -143,8 +143,7 @@ public class SystemCompleter implements Completer { compiled = true; } - public Map> getCompleters() { + public Map> getCompleters() { return completers; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java index cdd1bc520dd..c696b33ba9e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -41,9 +41,9 @@ public class DefaultHistory implements History { private int offset = 0; private int index = 0; - public DefaultHistory() { - } + public DefaultHistory() {} + @SuppressWarnings("this-escape") public DefaultHistory(LineReader reader) { attach(reader); } @@ -67,8 +67,7 @@ public class DefaultHistory implements History { this.reader = reader; try { load(); - } - catch (IllegalArgumentException | IOException e) { + } catch (IllegalArgumentException | IOException e) { Log.warn("Failed to load history", e); } } @@ -117,13 +116,13 @@ public class DefaultHistory implements History { } } - private String doHistoryFileDataKey (Path path){ + private String doHistoryFileDataKey(Path path) { return path != null ? path.toAbsolutePath().toString() : null; } private HistoryFileData getHistoryFileData(Path path) { String key = doHistoryFileDataKey(path); - if (!historyFiles.containsKey(key)){ + if (!historyFiles.containsKey(key)) { historyFiles.put(key, new HistoryFileData()); } return historyFiles.get(key); @@ -133,7 +132,7 @@ public class DefaultHistory implements History { historyFiles.put(doHistoryFileDataKey(path), historyFileData); } - private boolean isLineReaderHistory (Path path) throws IOException { + private boolean isLineReaderHistory(Path path) throws IOException { Path lrp = getPath(); if (lrp == null) { return path == null; @@ -141,23 +140,23 @@ public class DefaultHistory implements History { return Files.isSameFile(lrp, path); } - private void setLastLoaded(Path path, int lastloaded){ + private void setLastLoaded(Path path, int lastloaded) { getHistoryFileData(path).setLastLoaded(lastloaded); } - private void setEntriesInFile(Path path, int entriesInFile){ + private void setEntriesInFile(Path path, int entriesInFile) { getHistoryFileData(path).setEntriesInFile(entriesInFile); } - private void incEntriesInFile(Path path, int amount){ + private void incEntriesInFile(Path path, int amount) { getHistoryFileData(path).incEntriesInFile(amount); } - private int getLastLoaded(Path path){ + private int getLastLoaded(Path path) { return getHistoryFileData(path).getLastLoaded(); } - private int getEntriesInFile(Path path){ + private int getEntriesInFile(Path path) { return getHistoryFileData(path).getEntriesInFile(); } @@ -168,9 +167,8 @@ public class DefaultHistory implements History { protected void addHistoryLine(Path path, String line, boolean checkDuplicates) { if (reader.isSet(LineReader.Option.HISTORY_TIMESTAMPED)) { int idx = line.indexOf(':'); - final String badHistoryFileSyntax = "Bad history file syntax! " + - "The history file `" + path + "` may be an older history: " + - "please remove it or use a different history file."; + final String badHistoryFileSyntax = "Bad history file syntax! " + "The history file `" + path + + "` may be an older history: " + "please remove it or use a different history file."; if (idx < 0) { throw new IllegalArgumentException(badHistoryFileSyntax); } @@ -183,8 +181,7 @@ public class DefaultHistory implements History { String unescaped = unescape(line.substring(idx + 1)); internalAdd(time, unescaped, checkDuplicates); - } - else { + } else { internalAdd(Instant.now(), unescape(line), checkDuplicates); } } @@ -210,8 +207,7 @@ public class DefaultHistory implements History { @Override public void append(Path file, boolean incremental) throws IOException { - internalWrite(file != null ? file : getPath(), - incremental ? getLastLoaded(file) : 0); + internalWrite(file != null ? file : getPath(), incremental ? getLastLoaded(file) : 0); } @Override @@ -227,8 +223,11 @@ public class DefaultHistory implements History { Files.createDirectories(parent); } // Append new items to the history file - try (BufferedWriter writer = Files.newBufferedWriter(path.toAbsolutePath(), - StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE)) { + try (BufferedWriter writer = Files.newBufferedWriter( + path.toAbsolutePath(), + StandardOpenOption.WRITE, + StandardOpenOption.APPEND, + StandardOpenOption.CREATE)) { for (Entry entry : items.subList(from, items.size())) { if (isPersistable(entry)) { writer.append(format(entry)); @@ -248,18 +247,23 @@ public class DefaultHistory implements History { Log.trace("Trimming history path: ", path); // Load all history entries LinkedList allItems = new LinkedList<>(); - try (BufferedReader reader = Files.newBufferedReader(path)) { - reader.lines().forEach(l -> { - int idx = l.indexOf(':'); - Instant time = Instant.ofEpochMilli(Long.parseLong(l.substring(0, idx))); - String line = unescape(l.substring(idx + 1)); - allItems.add(createEntry(allItems.size(), time, line)); + try (BufferedReader historyFileReader = Files.newBufferedReader(path)) { + historyFileReader.lines().forEach(l -> { + if (reader.isSet(LineReader.Option.HISTORY_TIMESTAMPED)) { + int idx = l.indexOf(':'); + Instant time = Instant.ofEpochMilli(Long.parseLong(l.substring(0, idx))); + String line = unescape(l.substring(idx + 1)); + allItems.add(createEntry(allItems.size(), time, line)); + } else { + allItems.add(createEntry(allItems.size(), Instant.now(), unescape(l))); + } }); } // Remove duplicates List trimmedItems = doTrimHistory(allItems, max); // Write history - Path temp = Files.createTempFile(path.toAbsolutePath().getParent(), path.getFileName().toString(), ".tmp"); + Path temp = Files.createTempFile( + path.toAbsolutePath().getParent(), path.getFileName().toString(), ".tmp"); try (BufferedWriter writer = Files.newBufferedWriter(temp, StandardOpenOption.WRITE)) { for (Entry entry : trimmedItems) { writer.append(format(entry)); @@ -351,7 +355,7 @@ public class DefaultHistory implements History { public String get(final int index) { int idx = index - offset; if (idx >= items.size() || idx < 0) { - throw new IllegalArgumentException("IndexOutOfBounds: Index:" + idx +", Size:" + items.size()); + throw new IllegalArgumentException("IndexOutOfBounds: Index:" + idx + ", Size:" + items.size()); } return items.get(idx).line(); } @@ -382,8 +386,7 @@ public class DefaultHistory implements History { if (isSet(reader, LineReader.Option.HISTORY_INCREMENTAL)) { try { save(); - } - catch (IOException e) { + } catch (IOException e) { Log.warn("Failed to save history", e); } } @@ -417,7 +420,7 @@ public class DefaultHistory implements History { protected void internalAdd(Instant time, String line, boolean checkDuplicates) { Entry entry = new EntryImpl(offset + items.size(), time, line); if (checkDuplicates) { - for (Entry e: items) { + for (Entry e : items) { if (e.line().trim().equals(line.trim())) { return; } @@ -430,7 +433,7 @@ public class DefaultHistory implements History { private void maybeResize() { while (size() > getInt(reader, LineReader.HISTORY_SIZE, DEFAULT_HISTORY_SIZE)) { items.removeFirst(); - for (HistoryFileData hfd: historyFiles.values()) { + for (HistoryFileData hfd : historyFiles.values()) { hfd.decLastLoaded(); } offset++; @@ -633,8 +636,7 @@ public class DefaultHistory implements History { private int lastLoaded = 0; private int entriesInFile = 0; - public HistoryFileData() { - } + public HistoryFileData() {} public HistoryFileData(int lastLoaded, int entriesInFile) { this.lastLoaded = lastLoaded; @@ -667,8 +669,5 @@ public class DefaultHistory implements History { public void incEntriesInFile(int amount) { entriesInFile = entriesInFile + amount; } - } - } - diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Attributes.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Attributes.java index b1bab287e79..04959488cf1 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Attributes.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Attributes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -43,63 +43,65 @@ public class Attributes { * Input flags - software input processing */ public enum InputFlag { - IGNBRK, /* ignore BREAK condition */ - BRKINT, /* map BREAK to SIGINTR */ - IGNPAR, /* ignore (discard) parity errors */ - PARMRK, /* mark parity and framing errors */ - INPCK, /* enable checking of parity errors */ - ISTRIP, /* strip 8th bit off chars */ - INLCR, /* map NL into CR */ - IGNCR, /* ignore CR */ - ICRNL, /* map CR to NL (ala CRMOD) */ - IXON, /* enable output flow control */ - IXOFF, /* enable input flow control */ - IXANY, /* any char will restart after stop */ - IMAXBEL, /* ring bell on input queue full */ - IUTF8 /* maintain state for UTF-8 VERASE */ + IGNBRK, /* ignore BREAK condition */ + BRKINT, /* map BREAK to SIGINTR */ + IGNPAR, /* ignore (discard) parity errors */ + PARMRK, /* mark parity and framing errors */ + INPCK, /* enable checking of parity errors */ + ISTRIP, /* strip 8th bit off chars */ + INLCR, /* map NL into CR */ + IGNCR, /* ignore CR */ + ICRNL, /* map CR to NL (ala CRMOD) */ + IXON, /* enable output flow control */ + IXOFF, /* enable input flow control */ + IXANY, /* any char will restart after stop */ + IMAXBEL, /* ring bell on input queue full */ + IUTF8, /* maintain state for UTF-8 VERASE */ + + INORMEOL /* normalize end-of-line */ } /* * Output flags - software output processing */ public enum OutputFlag { - OPOST, /* enable following output processing */ - ONLCR, /* map NL to CR-NL (ala CRMOD) */ - OXTABS, /* expand tabs to spaces */ - ONOEOT, /* discard EOT's (^D) on output) */ - OCRNL, /* map CR to NL on output */ - ONOCR, /* no CR output at column 0 */ - ONLRET, /* NL performs CR function */ - OFILL, /* use fill characters for delay */ - NLDLY, /* \n delay */ - TABDLY, /* horizontal tab delay */ - CRDLY, /* \r delay */ - FFDLY, /* form feed delay */ - BSDLY, /* \b delay */ - VTDLY, /* vertical tab delay */ - OFDEL /* fill is DEL, else NUL */ + OPOST, /* enable following output processing */ + ONLCR, /* map NL to CR-NL (ala CRMOD) */ + OXTABS, /* expand tabs to spaces */ + ONOEOT, /* discard EOT's (^D) on output) */ + OCRNL, /* map CR to NL on output */ + ONOCR, /* no CR output at column 0 */ + ONLRET, /* NL performs CR function */ + OFILL, /* use fill characters for delay */ + NLDLY, /* \n delay */ + TABDLY, /* horizontal tab delay */ + CRDLY, /* \r delay */ + FFDLY, /* form feed delay */ + BSDLY, /* \b delay */ + VTDLY, /* vertical tab delay */ + OFDEL /* fill is DEL, else NUL */ } /* * Control flags - hardware control of terminal */ public enum ControlFlag { - CIGNORE, /* ignore control flags */ - CS5, /* 5 bits (pseudo) */ - CS6, /* 6 bits */ - CS7, /* 7 bits */ - CS8, /* 8 bits */ - CSTOPB, /* send 2 stop bits */ - CREAD, /* enable receiver */ - PARENB, /* parity enable */ - PARODD, /* odd parity, else even */ - HUPCL, /* hang up on last close */ - CLOCAL, /* ignore modem status lines */ - CCTS_OFLOW, /* CTS flow control of output */ - CRTS_IFLOW, /* RTS flow control of input */ - CDTR_IFLOW, /* DTR flow control of input */ - CDSR_OFLOW, /* DSR flow control of output */ - CCAR_OFLOW /* DCD flow control of output */ + CIGNORE, /* ignore control flags */ + CS5, /* 5 bits (pseudo) */ + CS6, /* 6 bits */ + CS7, /* 7 bits */ + CS8, /* 8 bits */ + CSTOPB, /* send 2 stop bits */ + CREAD, /* enable receiver */ + PARENB, /* parity enable */ + PARODD, /* odd parity, else even */ + HUPCL, /* hang up on last close */ + CLOCAL, /* ignore modem status lines */ + CCTS_OFLOW, /* CTS flow control of output */ + CRTS_IFLOW, /* RTS flow control of input */ + CDTR_IFLOW, /* DTR flow control of input */ + CDSR_OFLOW, /* DSR flow control of output */ + CCAR_OFLOW /* DCD flow control of output */ } /* @@ -110,23 +112,23 @@ public class Attributes { * input flag. */ public enum LocalFlag { - ECHOKE, /* visual erase for line kill */ - ECHOE, /* visually erase chars */ - ECHOK, /* echo NL after line kill */ - ECHO, /* enable echoing */ - ECHONL, /* echo NL even if ECHO is off */ - ECHOPRT, /* visual erase mode for hardcopy */ - ECHOCTL, /* echo control chars as ^(Char) */ - ISIG, /* enable signals INTR, QUIT, [D]SUSP */ - ICANON, /* canonicalize input lines */ - ALTWERASE, /* use alternate WERASE algorithm */ - IEXTEN, /* enable DISCARD and LNEXT */ - EXTPROC, /* external processing */ - TOSTOP, /* stop background jobs from output */ - FLUSHO, /* output being flushed (state) */ - NOKERNINFO, /* no kernel output from VSTATUS */ - PENDIN, /* XXX retype pending input (state) */ - NOFLSH /* don't flush after interrupt */ + ECHOKE, /* visual erase for line kill */ + ECHOE, /* visually erase chars */ + ECHOK, /* echo NL after line kill */ + ECHO, /* enable echoing */ + ECHONL, /* echo NL even if ECHO is off */ + ECHOPRT, /* visual erase mode for hardcopy */ + ECHOCTL, /* echo control chars as ^(Char) */ + ISIG, /* enable signals INTR, QUIT, [D]SUSP */ + ICANON, /* canonicalize input lines */ + ALTWERASE, /* use alternate WERASE algorithm */ + IEXTEN, /* enable DISCARD and LNEXT */ + EXTPROC, /* external processing */ + TOSTOP, /* stop background jobs from output */ + FLUSHO, /* output being flushed (state) */ + NOKERNINFO, /* no kernel output from VSTATUS */ + PENDIN, /* XXX retype pending input (state) */ + NOFLSH /* don't flush after interrupt */ } final EnumSet iflag = EnumSet.noneOf(InputFlag.class); @@ -135,9 +137,9 @@ public class Attributes { final EnumSet lflag = EnumSet.noneOf(LocalFlag.class); final EnumMap cchars = new EnumMap<>(ControlChar.class); - public Attributes() { - } + public Attributes() {} + @SuppressWarnings("this-escape") public Attributes(Attributes attr) { copy(attr); } @@ -310,13 +312,12 @@ public class Attributes { @Override public String toString() { - return "Attributes[" + - "lflags: " + append(lflag) + ", " + - "iflags: " + append(iflag) + ", " + - "oflags: " + append(oflag) + ", " + - "cflags: " + append(cflag) + ", " + - "cchars: " + append(EnumSet.allOf(ControlChar.class), this::display) + - "]"; + return "Attributes[" + "lflags: " + + append(lflag) + ", " + "iflags: " + + append(iflag) + ", " + "oflags: " + + append(oflag) + ", " + "cflags: " + + append(cflag) + ", " + "cchars: " + + append(EnumSet.allOf(ControlChar.class), this::display) + "]"; } private String display(ControlChar c) { @@ -345,5 +346,4 @@ public class Attributes { private > String append(EnumSet set, Function toString) { return set.stream().map(toString).collect(Collectors.joining(" ")); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Cursor.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Cursor.java index c561349cb0f..9bc3d902849 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Cursor.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Cursor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/MouseEvent.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/MouseEvent.java index df59e3f41b2..059b43c51ae 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/MouseEvent.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/MouseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -71,12 +71,11 @@ public class MouseEvent { @Override public String toString() { - return "MouseEvent[" + - "type=" + type + - ", button=" + button + - ", modifiers=" + modifiers + - ", x=" + x + - ", y=" + y + - ']'; + return "MouseEvent[" + "type=" + + type + ", button=" + + button + ", modifiers=" + + modifiers + ", x=" + + x + ", y=" + + y + ']'; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Size.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Size.java index 29870ad626c..fde3bf35959 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Size.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Size.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -13,9 +13,9 @@ public class Size { private int rows; private int cols; - public Size() { - } + public Size() {} + @SuppressWarnings("this-escape") public Size(int columns, int rows) { this(); setColumns(columns); @@ -50,7 +50,7 @@ public class Size { * @return the cursor position */ public int cursorPos(int row, int col) { - return row * (cols+1) + col; + return row * (cols + 1) + col; } public void copy(Size size) { diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Terminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Terminal.java index 38ffb029f60..054915e133d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Terminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/Terminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -34,6 +34,7 @@ public interface Terminal extends Closeable, Flushable { * Type used for dumb terminals. */ String TYPE_DUMB = "dumb"; + String TYPE_DUMB_COLOR = "dumb-color"; String getName(); @@ -42,6 +43,9 @@ public interface Terminal extends Closeable, Flushable { // Signal support // + /** + * Types of signals. + */ enum Signal { INT, QUIT, @@ -51,16 +55,55 @@ public interface Terminal extends Closeable, Flushable { WINCH } + /** + * The SignalHandler defines the interface used to trap signals and perform specific behaviors. + * @see Terminal.Signal + * @see Terminal#handle(Signal, SignalHandler) + */ interface SignalHandler { + /** + * The {@code SIG_DFL} value can be used to specify that the JVM default behavior + * should be used to handle this signal. + */ SignalHandler SIG_DFL = NativeSignalHandler.SIG_DFL; + + /** + * The {@code SIG_IGN} value can be used to ignore this signal and not perform + * any special processing. + */ SignalHandler SIG_IGN = NativeSignalHandler.SIG_IGN; + /** + * Handle the signal. + * @param signal the signal + */ void handle(Signal signal); } + /** + * Registers a handler for the given {@link Signal}. + *

+ * Note that the JVM does not easily allow catching the {@link Signal#QUIT} signal, which causes a thread dump + * to be displayed. This signal is mainly used when connecting through an SSH socket to a virtual terminal. + * + * @param signal the signal to register a handler for + * @param handler the handler + * @return the previous signal handler + */ SignalHandler handle(Signal signal, SignalHandler handler); + /** + * Raise the specific signal. + * This is not method usually called by non system terminals. + * When accessing a terminal through a SSH or Telnet connection, signals may be + * conveyed by the protocol and thus need to be raised when reaching the terminal code. + * The terminals do that automatically when the terminal input stream has a character + * mapped to {@link Attributes.ControlChar#VINTR}, {@link Attributes.ControlChar#VQUIT}, + * or {@link Attributes.ControlChar#VSUSP}. + * + * @param signal the signal to raise + */ void raise(Signal signal); // @@ -180,8 +223,21 @@ public interface Terminal extends Closeable, Flushable { boolean echo(boolean echo); + /** + * Returns the terminal attributes. + * The returned object can be safely modified + * further used in a call to {@link #setAttributes(Attributes)}. + * + * @return the terminal attributes. + */ Attributes getAttributes(); + /** + * Set the terminal attributes. + * The terminal will perform a copy of the given attributes. + * + * @param attr the new attributes + */ void setAttributes(Attributes attr); /** @@ -334,5 +390,4 @@ public interface Terminal extends Closeable, Flushable { * Color support */ ColorPalette getPalette(); - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java index 014ad78b794..3b02ec2d8d8 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,9 +8,6 @@ */ package jdk.internal.org.jline.terminal; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -19,11 +16,16 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.ServiceLoader; +import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; @@ -31,8 +33,10 @@ import java.util.stream.Stream; import jdk.internal.org.jline.terminal.impl.AbstractPosixTerminal; import jdk.internal.org.jline.terminal.impl.AbstractTerminal; -import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; import jdk.internal.org.jline.terminal.impl.DumbTerminal; +import jdk.internal.org.jline.terminal.impl.DumbTerminalProvider; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalExt; import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.Log; import jdk.internal.org.jline.utils.OSUtils; @@ -49,16 +53,30 @@ public final class TerminalBuilder { public static final String PROP_ENCODING = "org.jline.terminal.encoding"; public static final String PROP_CODEPAGE = "org.jline.terminal.codepage"; public static final String PROP_TYPE = "org.jline.terminal.type"; - public static final String PROP_JNA = "org.jline.terminal.jna"; - public static final String PROP_JANSI = "org.jline.terminal.jansi"; - public static final String PROP_EXEC = "org.jline.terminal.exec"; - public static final String PROP_DUMB = "org.jline.terminal.dumb"; + public static final String PROP_PROVIDER = "org.jline.terminal.provider"; + public static final String PROP_PROVIDERS = "org.jline.terminal.providers"; + public static final String PROP_PROVIDER_FFM = "ffm"; + public static final String PROP_PROVIDER_JNI = "jni"; + public static final String PROP_PROVIDER_JANSI = "jansi"; + public static final String PROP_PROVIDER_JNA = "jna"; + public static final String PROP_PROVIDER_EXEC = "exec"; + public static final String PROP_PROVIDER_DUMB = "dumb"; + public static final String PROP_PROVIDERS_DEFAULT = String.join( + ",", PROP_PROVIDER_FFM, PROP_PROVIDER_JNI, PROP_PROVIDER_JANSI, PROP_PROVIDER_JNA, PROP_PROVIDER_EXEC); + public static final String PROP_FFM = "org.jline.terminal." + PROP_PROVIDER_FFM; + public static final String PROP_JNI = "org.jline.terminal." + PROP_PROVIDER_JNI; + public static final String PROP_JANSI = "org.jline.terminal." + PROP_PROVIDER_JANSI; + public static final String PROP_JNA = "org.jline.terminal." + PROP_PROVIDER_JNA; + public static final String PROP_EXEC = "org.jline.terminal." + PROP_PROVIDER_EXEC; + public static final String PROP_DUMB = "org.jline.terminal." + PROP_PROVIDER_DUMB; public static final String PROP_DUMB_COLOR = "org.jline.terminal.dumb.color"; public static final String PROP_OUTPUT = "org.jline.terminal.output"; public static final String PROP_OUTPUT_OUT = "out"; public static final String PROP_OUTPUT_ERR = "err"; public static final String PROP_OUTPUT_OUT_ERR = "out-err"; public static final String PROP_OUTPUT_ERR_OUT = "err-out"; + public static final String PROP_OUTPUT_FORCED_OUT = "forced-out"; + public static final String PROP_OUTPUT_FORCED_ERR = "forced-err"; // // Other system properties controlling various jline parts @@ -68,6 +86,32 @@ public final class TerminalBuilder { public static final String PROP_COLOR_DISTANCE = "org.jline.utils.colorDistance"; public static final String PROP_DISABLE_ALTERNATE_CHARSET = "org.jline.utils.disableAlternateCharset"; + // + // System properties controlling how FileDescriptor are create. + // The value can be a comma separated list of defined mechanisms. + // + public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE = "org.jline.terminal.pty.fileDescriptorCreationMode"; + public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE_NATIVE = "native"; + public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE_REFLECTION = "reflection"; + public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE_DEFAULT = + String.join(",", PROP_FILE_DESCRIPTOR_CREATION_MODE_REFLECTION, PROP_FILE_DESCRIPTOR_CREATION_MODE_NATIVE); + + // + // System properties controlling how RedirectPipe are created. + // The value can be a comma separated list of defined mechanisms. + // + public static final String PROP_REDIRECT_PIPE_CREATION_MODE = "org.jline.terminal.exec.redirectPipeCreationMode"; + public static final String PROP_REDIRECT_PIPE_CREATION_MODE_NATIVE = "native"; + public static final String PROP_REDIRECT_PIPE_CREATION_MODE_REFLECTION = "reflection"; + public static final String PROP_REDIRECT_PIPE_CREATION_MODE_DEFAULT = + String.join(",", PROP_REDIRECT_PIPE_CREATION_MODE_REFLECTION, PROP_REDIRECT_PIPE_CREATION_MODE_NATIVE); + + public static final Set DEPRECATED_PROVIDERS = + Collections.unmodifiableSet(new HashSet<>(Arrays.asList(PROP_PROVIDER_JNA, PROP_PROVIDER_JANSI))); + + public static final String PROP_DISABLE_DEPRECATED_PROVIDER_WARNING = + "org.jline.terminal.disableDeprecatedProviderWarning"; + // // Terminal output control // @@ -75,7 +119,9 @@ public final class TerminalBuilder { SysOut, SysErr, SysOutOrSysErr, - SysErrOrSysOut + SysErrOrSysOut, + ForcedSysOut, + ForcedSysErr } /** @@ -115,20 +161,23 @@ public final class TerminalBuilder { private int codepage; private Boolean system; private SystemOutput systemOutput; + private String provider; + private String providers; private Boolean jna; private Boolean jansi; + private Boolean jni; private Boolean exec; + private Boolean ffm; private Boolean dumb; private Boolean color; private Attributes attributes; private Size size; - private boolean nativeSignals = false; + private boolean nativeSignals = true; private Function inputStreamWrapper = in -> in; private Terminal.SignalHandler signalHandler = Terminal.SignalHandler.SIG_DFL; private boolean paused = false; - private TerminalBuilder() { - } + private TerminalBuilder() {} public TerminalBuilder name(String name) { this.name = name; @@ -160,6 +209,16 @@ public final class TerminalBuilder { return this; } + public TerminalBuilder provider(String provider) { + this.provider = provider; + return this; + } + + public TerminalBuilder providers(String providers) { + this.providers = providers; + return this; + } + public TerminalBuilder jna(boolean jna) { this.jna = jna; return this; @@ -170,11 +229,21 @@ public final class TerminalBuilder { return this; } + public TerminalBuilder jni(boolean jni) { + this.jni = jni; + return this; + } + public TerminalBuilder exec(boolean exec) { this.exec = exec; return this; } + public TerminalBuilder ffm(boolean ffm) { + this.ffm = ffm; + return this; + } + public TerminalBuilder dumb(boolean dumb) { this.dumb = dumb; return this; @@ -280,6 +349,12 @@ public final class TerminalBuilder { return this; } + /** + * Determines the default value for signal handlers. + * All signals will be mapped to the given handler. + * @param signalHandler the default signal handler + * @return The builder + */ public TerminalBuilder signalHandler(Terminal.SignalHandler signalHandler) { this.signalHandler = signalHandler; return this; @@ -305,6 +380,11 @@ public final class TerminalBuilder { return this; } + /** + * Builds the terminal. + * @return the newly created terminal, never {@code null} + * @throws IOException if an error occurs + */ public Terminal build() throws IOException { Terminal override = TERMINAL_OVERRIDE.get(); Terminal terminal = override != null ? override : doBuild(); @@ -313,7 +393,8 @@ public final class TerminalBuilder { } Log.debug(() -> "Using terminal " + terminal.getClass().getSimpleName()); if (terminal instanceof AbstractPosixTerminal) { - Log.debug(() -> "Using pty " + ((AbstractPosixTerminal) terminal).getPty().getClass().getSimpleName()); + Log.debug(() -> "Using pty " + + ((AbstractPosixTerminal) terminal).getPty().getClass().getSimpleName()); } return terminal; } @@ -323,6 +404,242 @@ public final class TerminalBuilder { if (name == null) { name = "JLine terminal"; } + Charset encoding = computeEncoding(); + String type = computeType(); + + String provider = this.provider; + if (provider == null) { + provider = System.getProperty(PROP_PROVIDER, null); + } + + boolean forceDumb = + (DumbTerminal.TYPE_DUMB.equals(type) || type != null && type.startsWith(DumbTerminal.TYPE_DUMB_COLOR)) + || (provider != null && provider.equals(PROP_PROVIDER_DUMB)); + Boolean dumb = this.dumb; + if (dumb == null) { + dumb = getBoolean(PROP_DUMB, null); + } + IllegalStateException exception = new IllegalStateException("Unable to create a terminal"); + List providers = getProviders(provider, exception); + Terminal terminal = null; + if ((system != null && system) || (system == null && in == null && out == null)) { + if (system != null + && ((in != null && !in.equals(System.in)) + || (out != null && !out.equals(System.out) && !out.equals(System.err)))) { + throw new IllegalArgumentException("Cannot create a system terminal using non System streams"); + } + if (attributes != null || size != null) { + Log.warn("Attributes and size fields are ignored when creating a system terminal"); + } + SystemOutput systemOutput = computeSystemOutput(); + Map system = Stream.of(SystemStream.values()) + .collect(Collectors.toMap( + stream -> stream, stream -> providers.stream().anyMatch(p -> p.isSystemStream(stream)))); + SystemStream systemStream = select(system, systemOutput); + + if (!forceDumb && system.get(SystemStream.Input) && systemStream != null) { + if (attributes != null || size != null) { + Log.warn("Attributes and size fields are ignored when creating a system terminal"); + } + boolean ansiPassThrough = OSUtils.IS_CONEMU; + // Cygwin defaults to XTERM, but actually supports 256 colors, + // so if the value comes from the environment, change it to xterm-256color + if ((OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) + && "xterm".equals(type) + && this.type == null + && System.getProperty(PROP_TYPE) == null) { + type = "xterm-256color"; + } + for (TerminalProvider prov : providers) { + if (terminal == null) { + try { + terminal = prov.sysTerminal( + name, + type, + ansiPassThrough, + encoding, + nativeSignals, + signalHandler, + paused, + systemStream, + inputStreamWrapper); + } catch (Throwable t) { + Log.debug("Error creating " + prov.name() + " based terminal: ", t.getMessage(), t); + exception.addSuppressed(t); + } + } + } + if (terminal == null && OSUtils.IS_WINDOWS && providers.isEmpty() && (dumb == null || !dumb)) { + throw new IllegalStateException( + "Unable to create a system terminal. On Windows, either JLine's native libraries, JNA " + + "or Jansi library is required. Make sure to add one of those in the classpath.", + exception); + } + } + if (terminal instanceof AbstractTerminal) { + AbstractTerminal t = (AbstractTerminal) terminal; + if (SYSTEM_TERMINAL.compareAndSet(null, t)) { + t.setOnClose(() -> SYSTEM_TERMINAL.compareAndSet(t, null)); + } else { + exception.addSuppressed(new IllegalStateException("A system terminal is already running. " + + "Make sure to use the created system Terminal on the LineReaderBuilder if you're using one " + + "or that previously created system Terminals have been correctly closed.")); + terminal.close(); + terminal = null; + } + } + if (terminal == null && (forceDumb || dumb == null || dumb)) { + if (!forceDumb && dumb == null) { + if (Log.isDebugEnabled()) { + Log.warn("input is tty: " + system.get(SystemStream.Input)); + Log.warn("output is tty: " + system.get(SystemStream.Output)); + Log.warn("error is tty: " + system.get(SystemStream.Error)); + Log.warn("Creating a dumb terminal", exception); + } else { + Log.warn( + "Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)"); + } + } + type = getDumbTerminalType(dumb, systemStream); + terminal = new DumbTerminalProvider() + .sysTerminal(name, type, false, encoding, nativeSignals, signalHandler, paused, systemStream, inputStreamWrapper); + if (OSUtils.IS_WINDOWS) { + Attributes attr = terminal.getAttributes(); + attr.setInputFlag(Attributes.InputFlag.IGNCR, true); + terminal.setAttributes(attr); + } + } + } else { + for (TerminalProvider prov : providers) { + if (terminal == null) { + try { + terminal = prov.newTerminal( + name, type, in, out, encoding, signalHandler, paused, attributes, size); + } catch (Throwable t) { + Log.debug("Error creating " + prov.name() + " based terminal: ", t.getMessage(), t); + exception.addSuppressed(t); + } + } + } + } + if (terminal == null) { + throw exception; + } + if (terminal instanceof TerminalExt) { + TerminalExt te = (TerminalExt) terminal; + if (DEPRECATED_PROVIDERS.contains(te.getProvider().name()) + && !getBoolean(PROP_DISABLE_DEPRECATED_PROVIDER_WARNING, false)) { + Log.warn("The terminal provider " + te.getProvider().name() + + " has been deprecated, check your configuration. This warning can be disabled by setting the system property " + + PROP_DISABLE_DEPRECATED_PROVIDER_WARNING + " to true."); + } + } + return terminal; + } + + private String getDumbTerminalType(Boolean dumb, SystemStream systemStream) { + // forced colored dumb terminal + Boolean color = this.color; + if (color == null) { + color = getBoolean(PROP_DUMB_COLOR, null); + } + if (dumb == null) { + // detect emacs using the env variable + if (color == null) { + String emacs = System.getenv("INSIDE_EMACS"); + if (emacs != null && emacs.contains("comint")) { + color = true; + } + } + // detect Intellij Idea + if (color == null) { + // using the env variable on windows + String ideHome = System.getenv("IDE_HOME"); + if (ideHome != null) { + color = true; + } else { + // using the parent process command on unix/mac + String command = getParentProcessCommand(); + if (command != null && command.endsWith("/idea")) { + color = true; + } + } + } + if (color == null) { + color = systemStream != null && System.getenv("TERM") != null; + } + } else { + if (color == null) { + color = false; + } + } + return color ? Terminal.TYPE_DUMB_COLOR : Terminal.TYPE_DUMB; + } + + public SystemOutput computeSystemOutput() { + SystemOutput systemOutput = null; + if (out != null) { + if (out.equals(System.out)) { + systemOutput = SystemOutput.SysOut; + } else if (out.equals(System.err)) { + systemOutput = SystemOutput.SysErr; + } + } + if (systemOutput == null) { + systemOutput = this.systemOutput; + } + if (systemOutput == null) { + String str = System.getProperty(PROP_OUTPUT); + if (str != null) { + switch (str.trim().toLowerCase(Locale.ROOT)) { + case PROP_OUTPUT_OUT: + systemOutput = SystemOutput.SysOut; + break; + case PROP_OUTPUT_ERR: + systemOutput = SystemOutput.SysErr; + break; + case PROP_OUTPUT_OUT_ERR: + systemOutput = SystemOutput.SysOutOrSysErr; + break; + case PROP_OUTPUT_ERR_OUT: + systemOutput = SystemOutput.SysErrOrSysOut; + break; + case PROP_OUTPUT_FORCED_OUT: + systemOutput = SystemOutput.ForcedSysOut; + break; + case PROP_OUTPUT_FORCED_ERR: + systemOutput = SystemOutput.ForcedSysErr; + break; + default: + Log.debug("Unsupported value for " + PROP_OUTPUT + ": " + str + ". Supported values are: " + + String.join( + ", ", + PROP_OUTPUT_OUT, + PROP_OUTPUT_ERR, + PROP_OUTPUT_OUT_ERR, + PROP_OUTPUT_ERR_OUT) + + "."); + } + } + } + if (systemOutput == null) { + systemOutput = SystemOutput.SysOutOrSysErr; + } + return systemOutput; + } + + public String computeType() { + String type = this.type; + if (type == null) { + type = System.getProperty(PROP_TYPE); + } + if (type == null) { + type = System.getenv("TERM"); + } + return type; + } + + public Charset computeEncoding() { Charset encoding = this.encoding; if (encoding == null) { String charsetName = System.getProperty(PROP_ENCODING); @@ -344,206 +661,84 @@ public final class TerminalBuilder { encoding = StandardCharsets.UTF_8; } } - String type = this.type; - if (type == null) { - type = System.getProperty(PROP_TYPE); - } - if (type == null) { - type = System.getenv("TERM"); - } - Boolean jna = this.jna; - if (jna == null) { - jna = getBoolean(PROP_JNA, true); - } - Boolean jansi = this.jansi; - if (jansi == null) { - jansi = getBoolean(PROP_JANSI, true); - } - Boolean exec = this.exec; - if (exec == null) { - exec = getBoolean(PROP_EXEC, true); - } - Boolean dumb = this.dumb; - if (dumb == null) { - dumb = getBoolean(PROP_DUMB, null); - } - IllegalStateException exception = new IllegalStateException("Unable to create a terminal"); - List providers = new ArrayList<>(); - if (jna) { - try { - TerminalProvider provider = TerminalProvider.load("jna"); - providers.add(provider); - } catch (Throwable t) { - Log.debug("Unable to load JNA support: ", t); - exception.addSuppressed(t); - } - } - if (jansi) { - try { - TerminalProvider provider = TerminalProvider.load("jansi"); - providers.add(provider); - } catch (Throwable t) { - Log.debug("Unable to load JANSI support: ", t); - exception.addSuppressed(t); - } - } - if (exec) - { - try { - TerminalProvider provider = TerminalProvider.load("exec"); - providers.add(provider); - } catch (Throwable t) { - Log.debug("Unable to load EXEC support: ", t); - exception.addSuppressed(t); - } - } - - Terminal terminal = null; - if ((system != null && system) || (system == null && in == null && out == null)) { - if (system != null && ((in != null && !in.equals(System.in)) || - (out != null && !out.equals(System.out) && !out.equals(System.err)))) { - throw new IllegalArgumentException("Cannot create a system terminal using non System streams"); - } - if (attributes != null || size != null) { - Log.warn("Attributes and size fields are ignored when creating a system terminal"); - } - if (out != null) { - if (out.equals(System.out)) { - systemOutput = SystemOutput.SysOut; - } else if (out.equals(System.err)) { - systemOutput = SystemOutput.SysErr; - } - } - if (systemOutput == null) { - String str = System.getProperty(PROP_OUTPUT); - if (str != null) { - switch (str.trim().toLowerCase(Locale.ROOT)) { - case PROP_OUTPUT_OUT: systemOutput = SystemOutput.SysOut; break; - case PROP_OUTPUT_ERR: systemOutput = SystemOutput.SysErr; break; - case PROP_OUTPUT_OUT_ERR: systemOutput = SystemOutput.SysOutOrSysErr; break; - case PROP_OUTPUT_ERR_OUT: systemOutput = SystemOutput.SysErrOrSysOut; break; - default: - Log.debug("Unsupported value for " + PROP_OUTPUT + ": " + str + ". Supported values are: " - + String.join(", ", PROP_OUTPUT_OUT, PROP_OUTPUT_ERR, PROP_OUTPUT_OUT_ERR,PROP_OUTPUT_ERR_OUT) - + "."); - } - } - } - if (systemOutput == null) { - systemOutput = SystemOutput.SysOutOrSysErr; - } - Map system = Stream.of(TerminalProvider.Stream.values()) - .collect(Collectors.toMap(stream -> stream, stream -> providers.stream().anyMatch(p -> p.isSystemStream(stream)))); - TerminalProvider.Stream console = select(system, systemOutput); - - if (system.get(TerminalProvider.Stream.Input) && console != null) { - if (attributes != null || size != null) { - Log.warn("Attributes and size fields are ignored when creating a system terminal"); - } - boolean ansiPassThrough = OSUtils.IS_CONEMU; - // Cygwin defaults to XTERM, but actually supports 256 colors, - // so if the value comes from the environment, change it to xterm-256color - if ((OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) && "xterm".equals(type) - && this.type == null && System.getProperty(PROP_TYPE) == null) { - type = "xterm-256color"; - } - for ( TerminalProvider provider : providers) { - if (terminal == null) { - try { - terminal = provider.sysTerminal(name, type, ansiPassThrough, encoding, - nativeSignals, signalHandler, paused, console, inputStreamWrapper); - } catch (Throwable t) { - Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - } - if (terminal == null && OSUtils.IS_WINDOWS && !jna && !jansi && (dumb == null || !dumb)) { - throw new IllegalStateException("Unable to create a system terminal. On windows, either " - + "JNA or JANSI library is required. Make sure to add one of those in the classpath."); - } - } - if (terminal instanceof AbstractTerminal) { - AbstractTerminal t = (AbstractTerminal) terminal; - if (SYSTEM_TERMINAL.compareAndSet(null, t)) { - t.setOnClose(() -> SYSTEM_TERMINAL.compareAndSet(t, null)); - } else { - exception.addSuppressed(new IllegalStateException("A system terminal is already running. " + - "Make sure to use the created system Terminal on the LineReaderBuilder if you're using one " + - "or that previously created system Terminals have been correctly closed.")); - terminal.close(); - terminal = null; - } - } - if (terminal == null && (dumb == null || dumb)) { - // forced colored dumb terminal - Boolean color = this.color; - if (color == null) { - color = getBoolean(PROP_DUMB_COLOR, false); - // detect emacs using the env variable - if (!color) { - String emacs = System.getenv("INSIDE_EMACS"); - color = emacs != null && emacs.contains("comint"); - } - // detect Intellij Idea - if (!color) { - String command = getParentProcessCommand(); - color = command != null && command.contains("idea"); - } - if (!color) { - color = system.get(TerminalProvider.Stream.Output) && System.getenv("TERM") != null; - } - if (!color && dumb == null) { - if (Log.isDebugEnabled()) { - Log.warn("input is tty: {}", system.get(TerminalProvider.Stream.Input)); - Log.warn("output is tty: {}", system.get(TerminalProvider.Stream.Output)); - Log.warn("error is tty: {}", system.get(TerminalProvider.Stream.Error)); - Log.warn("Creating a dumb terminal", exception); - } else { - Log.warn("Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)"); - } - } - } - terminal = new DumbTerminal(name, color ? Terminal.TYPE_DUMB_COLOR : Terminal.TYPE_DUMB, - new FileInputStream(FileDescriptor.in), - //JDK change: always write into stdout: - new FileOutputStream(FileDescriptor.out), - encoding, signalHandler); - } - } else { - for ( TerminalProvider provider : providers) { - if (terminal == null) { - try { - terminal = provider.newTerminal(name, type, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused, attributes, size); - } catch (Throwable t) { - Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - } - } - if (terminal == null) { - throw exception; - } - return terminal; + return encoding; } - private TerminalProvider.Stream select(Map system, SystemOutput systemOutput) { + /** + * Get the list of available terminal providers. + * This list is sorted according to the {@link #PROP_PROVIDERS} system property. + * @param provider if not {@code null}, only this provider will be checked + * @param exception if a provider throws an exception, it will be added to this exception as a suppressed exception + * @return a list of terminal providers + */ + public List getProviders(String provider, IllegalStateException exception) { + List providers = new ArrayList<>(); + // Check ffm provider + checkProvider(provider, exception, providers, ffm, PROP_FFM, PROP_PROVIDER_FFM); + // Check jni provider + checkProvider(provider, exception, providers, jni, PROP_JNI, PROP_PROVIDER_JNI); + // Check jansi provider + checkProvider(provider, exception, providers, jansi, PROP_JANSI, PROP_PROVIDER_JANSI); + // Check jna provider + checkProvider(provider, exception, providers, jna, PROP_JNA, PROP_PROVIDER_JNA); + // Check exec provider + checkProvider(provider, exception, providers, exec, PROP_EXEC, PROP_PROVIDER_EXEC); + // Order providers + List order = Arrays.asList( + (this.providers != null ? this.providers : System.getProperty(PROP_PROVIDERS, PROP_PROVIDERS_DEFAULT)) + .split(",")); + providers.sort(Comparator.comparing(l -> { + int idx = order.indexOf(l.name()); + return idx >= 0 ? idx : Integer.MAX_VALUE; + })); + String names = providers.stream().map(TerminalProvider::name).collect(Collectors.joining(", ")); + Log.debug("Available providers: " + names); + return providers; + } + + private void checkProvider( + String provider, + IllegalStateException exception, + List providers, + Boolean load, + String property, + String name) { + Boolean doLoad = provider != null ? (Boolean) name.equals(provider) : load; + if (doLoad == null) { + doLoad = getBoolean(property, true); + } + if (doLoad) { + try { + TerminalProvider prov = TerminalProvider.load(name); + prov.isSystemStream(SystemStream.Output); + providers.add(prov); + } catch (Throwable t) { + Log.debug("Unable to load " + name + " provider: ", t); + exception.addSuppressed(t); + } + } + } + + private SystemStream select(Map system, SystemOutput systemOutput) { switch (systemOutput) { case SysOut: - return select(system, TerminalProvider.Stream.Output); + return select(system, SystemStream.Output); case SysErr: - return select(system, TerminalProvider.Stream.Error); + return select(system, SystemStream.Error); case SysOutOrSysErr: - return select(system, TerminalProvider.Stream.Output, TerminalProvider.Stream.Error); + return select(system, SystemStream.Output, SystemStream.Error); case SysErrOrSysOut: - return select(system, TerminalProvider.Stream.Error, TerminalProvider.Stream.Output); + return select(system, SystemStream.Error, SystemStream.Output); + case ForcedSysOut: + return SystemStream.Output; + case ForcedSysErr: + return SystemStream.Error; } return null; } - private static TerminalProvider.Stream select(Map system, TerminalProvider.Stream... streams) { - for (TerminalProvider.Stream s : streams) { + private static SystemStream select(Map system, SystemStream... streams) { + for (SystemStream s : streams) { if (system.get(s)) { return s; } @@ -558,7 +753,9 @@ public final class TerminalBuilder { Object parent = ((Optional) phClass.getMethod("parent").invoke(current)).orElse(null); Method infoMethod = phClass.getMethod("info"); Object info = infoMethod.invoke(parent); - Object command = ((Optional) infoMethod.getReturnType().getMethod("command").invoke(info)).orElse(null); + Object command = ((Optional) + infoMethod.getReturnType().getMethod("command").invoke(info)) + .orElse(null); return (String) command; } catch (Throwable t) { return null; @@ -583,7 +780,7 @@ public final class TerminalBuilder { private static final int UTF8_CODE_PAGE = 65001; private static Charset getCodepageCharset(int codepage) { - //http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html + // http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html if (codepage == UTF8_CODE_PAGE) { return StandardCharsets.UTF_8; } @@ -630,5 +827,4 @@ public final class TerminalBuilder { public static void setTerminalOverride(final Terminal terminal) { TERMINAL_OVERRIDE.set(terminal); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java index b5f55b80f1e..5d000d07083 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -18,6 +18,8 @@ import jdk.internal.org.jline.terminal.Attributes; import jdk.internal.org.jline.terminal.Cursor; import jdk.internal.org.jline.terminal.Size; import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; public abstract class AbstractPosixTerminal extends AbstractTerminal { @@ -28,7 +30,8 @@ public abstract class AbstractPosixTerminal extends AbstractTerminal { this(name, type, pty, null, SignalHandler.SIG_DFL); } - public AbstractPosixTerminal(String name, String type, Pty pty, Charset encoding, SignalHandler signalHandler) throws IOException { + public AbstractPosixTerminal(String name, String type, Pty pty, Charset encoding, SignalHandler signalHandler) + throws IOException { super(name, type, encoding, signalHandler); Objects.requireNonNull(pty); this.pty = pty; @@ -82,4 +85,13 @@ public abstract class AbstractPosixTerminal extends AbstractTerminal { return CursorSupport.getCursorPosition(this, discarded); } + @Override + public TerminalProvider getProvider() { + return getPty().getProvider(); + } + + @Override + public SystemStream getSystemStream() { + return getPty().getSystemStream(); + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java index 0feab84fc7e..3fbe63f3c5d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,20 +8,39 @@ */ package jdk.internal.org.jline.terminal.impl; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.spi.Pty; -import jdk.internal.org.jline.utils.NonBlockingInputStream; - +import java.io.FileDescriptor; +import java.io.FilterInputStream; import java.io.IOError; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; +import java.lang.reflect.Field; +//import jdk.internal.org.jline.nativ.JLineLibrary; +//import jdk.internal.org.jline.nativ.JLineNativeLoader; +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.NonBlockingInputStream; + +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_FILE_DESCRIPTOR_CREATION_MODE; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_FILE_DESCRIPTOR_CREATION_MODE_DEFAULT; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_FILE_DESCRIPTOR_CREATION_MODE_NATIVE; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_FILE_DESCRIPTOR_CREATION_MODE_REFLECTION; import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_NON_BLOCKING_READS; public abstract class AbstractPty implements Pty { + protected final TerminalProvider provider; + protected final SystemStream systemStream; private Attributes current; + private boolean skipNextLf; + + public AbstractPty(TerminalProvider provider, SystemStream systemStream) { + this.provider = provider; + this.systemStream = systemStream; + } @Override public void setAttr(Attributes attr) throws IOException { @@ -32,10 +51,32 @@ public abstract class AbstractPty implements Pty { @Override public InputStream getSlaveInput() throws IOException { InputStream si = doGetSlaveInput(); + InputStream nsi = new FilterInputStream(si) { + @Override + public int read() throws IOException { + for (; ; ) { + int c = super.read(); + if (current.getInputFlag(Attributes.InputFlag.INORMEOL)) { + if (c == '\r') { + skipNextLf = true; + c = '\n'; + } else if (c == '\n') { + if (skipNextLf) { + skipNextLf = false; + continue; + } + } else { + skipNextLf = false; + } + } + return c; + } + } + }; if (Boolean.parseBoolean(System.getProperty(PROP_NON_BLOCKING_READS, "true"))) { - return new PtyInputStream(si); + return new PtyInputStream(nsi); } else { - return si; + return nsi; } } @@ -49,6 +90,16 @@ public abstract class AbstractPty implements Pty { } } + @Override + public TerminalProvider getProvider() { + return provider; + } + + @Override + public SystemStream getSystemStream() { + return systemStream; + } + class PtyInputStream extends NonBlockingInputStream { final InputStream in; int c = 0; @@ -102,4 +153,103 @@ public abstract class AbstractPty implements Pty { } } + private static FileDescriptorCreator fileDescriptorCreator; + + protected static FileDescriptor newDescriptor(int fd) { + if (fileDescriptorCreator == null) { + String str = + System.getProperty(PROP_FILE_DESCRIPTOR_CREATION_MODE, PROP_FILE_DESCRIPTOR_CREATION_MODE_DEFAULT); + String[] modes = str.split(","); + IllegalStateException ise = new IllegalStateException("Unable to create FileDescriptor"); + for (String mode : modes) { + try { + switch (mode) { + case PROP_FILE_DESCRIPTOR_CREATION_MODE_NATIVE: + fileDescriptorCreator = null;//new NativeFileDescriptorCreator(); + break; + case PROP_FILE_DESCRIPTOR_CREATION_MODE_REFLECTION: + fileDescriptorCreator = new ReflectionFileDescriptorCreator(); + break; + } + } catch (Throwable t) { + // ignore + ise.addSuppressed(t); + } + if (fileDescriptorCreator != null) { + break; + } + } + if (fileDescriptorCreator == null) { + throw ise; + } + } + return fileDescriptorCreator.newDescriptor(fd); + } + + interface FileDescriptorCreator { + FileDescriptor newDescriptor(int fd); + } + + /* + * Class that could be used on OpenJDK 17. However, it requires the following JVM option + * --add-exports java.base/jdk.internal.access=ALL-UNNAMED + * so the benefit does not seem important enough to warrant the problems caused + * by access the jdk.internal.access package at compile time, which itself requires + * custom compiler options and a different maven module, or at least a different compile + * phase with a JDK 17 compiler. + * So, just keep the ReflectionFileDescriptorCreator for now. + * + static class Jdk17FileDescriptorCreator implements FileDescriptorCreator { + private final jdk.internal.access.JavaIOFileDescriptorAccess fdAccess; + Jdk17FileDescriptorCreator() { + fdAccess = jdk.internal.access.SharedSecrets.getJavaIOFileDescriptorAccess(); + } + + @Override + public FileDescriptor newDescriptor(int fd) { + FileDescriptor descriptor = new FileDescriptor(); + fdAccess.set(descriptor, fd); + return descriptor; + } + } + */ + + /** + * Reflection based file descriptor creator. + * This requires the following option + * --add-opens java.base/java.io=ALL-UNNAMED + */ + static class ReflectionFileDescriptorCreator implements FileDescriptorCreator { + private final Field fileDescriptorField; + + ReflectionFileDescriptorCreator() throws Exception { + Field field = FileDescriptor.class.getDeclaredField("fd"); + field.setAccessible(true); + fileDescriptorField = field; + } + + @Override + public FileDescriptor newDescriptor(int fd) { + FileDescriptor descriptor = new FileDescriptor(); + try { + fileDescriptorField.set(descriptor, fd); + } catch (IllegalAccessException e) { + // This should not happen as the field has been set accessible + throw new IllegalStateException(e); + } + return descriptor; + } + } + +// static class NativeFileDescriptorCreator implements FileDescriptorCreator { +// NativeFileDescriptorCreator() { +// // Force load the library +// JLineNativeLoader.initialize(); +// } +// +// @Override +// public FileDescriptor newDescriptor(int fd) { +// return JLineLibrary.newFileDescriptor(fd); +// } +// } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java index 8a464a67265..2608e2e5f37 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -27,7 +27,7 @@ import jdk.internal.org.jline.terminal.Attributes.InputFlag; import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.Cursor; import jdk.internal.org.jline.terminal.MouseEvent; -import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.spi.TerminalExt; import jdk.internal.org.jline.utils.ColorPalette; import jdk.internal.org.jline.utils.Curses; import jdk.internal.org.jline.utils.InfoCmp; @@ -35,7 +35,7 @@ import jdk.internal.org.jline.utils.InfoCmp.Capability; import jdk.internal.org.jline.utils.Log; import jdk.internal.org.jline.utils.Status; -public abstract class AbstractTerminal implements Terminal { +public abstract class AbstractTerminal implements TerminalExt { protected final String name; protected final String type; @@ -44,7 +44,7 @@ public abstract class AbstractTerminal implements Terminal { protected final Set bools = new HashSet<>(); protected final Map ints = new HashMap<>(); protected final Map strings = new HashMap<>(); - protected final ColorPalette palette = new ColorPalette(this); + protected final ColorPalette palette; protected Status status; protected Runnable onClose; @@ -52,10 +52,13 @@ public abstract class AbstractTerminal implements Terminal { this(name, type, null, SignalHandler.SIG_DFL); } - public AbstractTerminal(String name, String type, Charset encoding, SignalHandler signalHandler) throws IOException { + @SuppressWarnings("this-escape") + public AbstractTerminal(String name, String type, Charset encoding, SignalHandler signalHandler) + throws IOException { this.name = name; this.type = type != null ? type : "ansi"; this.encoding = encoding != null ? encoding : System.out.charset(); + this.palette = new ColorPalette(this); for (Signal signal : Signal.values()) { handlers.put(signal, signalHandler); } @@ -85,12 +88,13 @@ public abstract class AbstractTerminal implements Terminal { public void raise(Signal signal) { Objects.requireNonNull(signal); SignalHandler handler = handlers.get(signal); - if (handler != SignalHandler.SIG_DFL && handler != SignalHandler.SIG_IGN) { + if (handler == SignalHandler.SIG_DFL) { + if (status != null && signal == Signal.WINCH) { + status.resize(); + } + } else if (handler != SignalHandler.SIG_IGN) { handler.handle(signal); } - if (status != null && signal == Signal.WINCH) { - status.resize(); - } } public final void close() throws IOException { @@ -105,8 +109,7 @@ public abstract class AbstractTerminal implements Terminal { protected void doClose() throws IOException { if (status != null) { - status.update(null); - flush(); + status.close(); } } @@ -126,7 +129,7 @@ public abstract class AbstractTerminal implements Terminal { if (cc != null) { int vcc = getAttributes().getControlChar(cc); if (vcc > 0 && vcc < 32) { - writer().write(new char[]{'^', (char) (vcc + '@')}, 0, 2); + writer().write(new char[] {'^', (char) (vcc + '@')}, 0, 2); } } } @@ -217,8 +220,7 @@ public abstract class AbstractTerminal implements Terminal { } private MouseEvent lastMouseEvent = new MouseEvent( - MouseEvent.Type.Moved, MouseEvent.Button.NoButton, - EnumSet.noneOf(MouseEvent.Modifier.class), 0, 0); + MouseEvent.Type.Moved, MouseEvent.Button.NoButton, EnumSet.noneOf(MouseEvent.Modifier.class), 0, 0); @Override public boolean hasMouseSupport() { @@ -268,16 +270,13 @@ public abstract class AbstractTerminal implements Terminal { } @Override - public void pause() { - } + public void pause() {} @Override - public void pause(boolean wait) throws InterruptedException { - } + public void pause(boolean wait) throws InterruptedException {} @Override - public void resume() { - } + public void resume() {} @Override public boolean paused() { diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsConsoleWriter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsConsoleWriter.java index 0c36902a1a7..301b89eb796 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsConsoleWriter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsConsoleWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -29,11 +29,8 @@ public abstract class AbstractWindowsConsoleWriter extends Writer { } @Override - public void flush() { - } + public void flush() {} @Override - public void close() { - } - + public void close() {} } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java index 57cfb5d50b4..03c42fb19f7 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2023, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,8 +8,20 @@ */ package jdk.internal.org.jline.terminal.impl; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + import jdk.internal.org.jline.terminal.Attributes; import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.Curses; import jdk.internal.org.jline.utils.InfoCmp; import jdk.internal.org.jline.utils.Log; @@ -21,17 +33,6 @@ import jdk.internal.org.jline.utils.ShutdownHooks; import jdk.internal.org.jline.utils.Signals; import jdk.internal.org.jline.utils.WriterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - /** * The AbstractWindowsTerminal is used as the base class for windows terminal. * Due to windows limitations, mostly the missing support for ansi sequences, @@ -44,7 +45,7 @@ import java.util.function.Function; * the writer() becomes the primary output, while the output() is bridged * to the writer() using a WriterOutputStream wrapper. */ -public abstract class AbstractWindowsTerminal extends AbstractTerminal { +public abstract class AbstractWindowsTerminal extends AbstractTerminal { public static final String TYPE_WINDOWS = "windows"; public static final String TYPE_WINDOWS_256_COLOR = "windows-256color"; @@ -56,12 +57,13 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { private static final int UTF8_CODE_PAGE = 65001; protected static final int ENABLE_PROCESSED_INPUT = 0x0001; - protected static final int ENABLE_LINE_INPUT = 0x0002; - protected static final int ENABLE_ECHO_INPUT = 0x0004; - protected static final int ENABLE_WINDOW_INPUT = 0x0008; - protected static final int ENABLE_MOUSE_INPUT = 0x0010; - protected static final int ENABLE_INSERT_MODE = 0x0020; + protected static final int ENABLE_LINE_INPUT = 0x0002; + protected static final int ENABLE_ECHO_INPUT = 0x0004; + protected static final int ENABLE_WINDOW_INPUT = 0x0008; + protected static final int ENABLE_MOUSE_INPUT = 0x0010; + protected static final int ENABLE_INSERT_MODE = 0x0020; protected static final int ENABLE_QUICK_EDIT_MODE = 0x0040; + protected static final int ENABLE_EXTENDED_FLAGS = 0x0080; protected final Writer slaveInputPipe; protected final InputStream input; @@ -71,7 +73,12 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { protected final Map nativeHandlers = new HashMap<>(); protected final ShutdownHooks.Task closer; protected final Attributes attributes = new Attributes(); - protected final int originalConsoleMode; + protected final Console inConsole; + protected final Console outConsole; + protected final int originalInConsoleMode; + protected final int originalOutConsoleMode; + private final TerminalProvider provider; + private final SystemStream systemStream; protected final Object lock = new Object(); protected boolean paused = true; @@ -80,21 +87,42 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { protected MouseTracking tracking = MouseTracking.Off; protected boolean focusTracking = false; private volatile boolean closing; + protected boolean skipNextLf; - public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException { + @SuppressWarnings("this-escape") + public AbstractWindowsTerminal( + TerminalProvider provider, + SystemStream systemStream, + Writer writer, + String name, + String type, + Charset encoding, + boolean nativeSignals, + SignalHandler signalHandler, + Console inConsole, + int inConsoleMode, + Console outConsole, + int outConsoleMode, + Function inputStreamWrapper) + throws IOException { super(name, type, encoding, signalHandler); + this.provider = provider; + this.systemStream = systemStream; NonBlockingPumpReader reader = NonBlocking.nonBlockingPumpReader(); this.slaveInputPipe = reader.getWriter(); this.input = inputStreamWrapper.apply(NonBlocking.nonBlockingStream(reader, encoding())); this.reader = NonBlocking.nonBlocking(name, input, encoding()); this.writer = new PrintWriter(writer); this.output = new WriterOutputStream(writer, encoding()); + this.inConsole = inConsole; + this.outConsole = outConsole; parseInfoCmp(); // Attributes - originalConsoleMode = getConsoleMode(); + this.originalInConsoleMode = inConsoleMode; + this.originalOutConsoleMode = outConsoleMode; attributes.setLocalFlag(Attributes.LocalFlag.ISIG, true); attributes.setControlChar(Attributes.ControlChar.VINTR, ctrl('C')); - attributes.setControlChar(Attributes.ControlChar.VEOF, ctrl('D')); + attributes.setControlChar(Attributes.ControlChar.VEOF, ctrl('D')); attributes.setControlChar(Attributes.ControlChar.VSUSP, ctrl('Z')); // Handle signals if (nativeSignals) { @@ -148,7 +176,7 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { } public Attributes getAttributes() { - int mode = getConsoleMode(); + int mode = getConsoleMode(inConsole); if ((mode & ENABLE_ECHO_INPUT) != 0) { attributes.setLocalFlag(Attributes.LocalFlag.ECHO, true); } @@ -173,8 +201,11 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { } if (tracking != MouseTracking.Off) { mode |= ENABLE_MOUSE_INPUT; + // mouse events not send with quick edit mode + // to disable ENABLE_QUICK_EDIT_MODE just set extended flag + mode |= ENABLE_EXTENDED_FLAGS; } - setConsoleMode(mode); + setConsoleMode(inConsole, mode); } protected int ctrl(char key) { @@ -197,23 +228,26 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { } reader.close(); writer.close(); - setConsoleMode(originalConsoleMode); + setConsoleMode(inConsole, originalInConsoleMode); + setConsoleMode(outConsole, originalOutConsoleMode); } static final int SHIFT_FLAG = 0x01; - static final int ALT_FLAG = 0x02; - static final int CTRL_FLAG = 0x04; + static final int ALT_FLAG = 0x02; + static final int CTRL_FLAG = 0x04; - static final int RIGHT_ALT_PRESSED = 0x0001; - static final int LEFT_ALT_PRESSED = 0x0002; - static final int RIGHT_CTRL_PRESSED = 0x0004; - static final int LEFT_CTRL_PRESSED = 0x0008; - static final int SHIFT_PRESSED = 0x0010; - static final int NUMLOCK_ON = 0x0020; - static final int SCROLLLOCK_ON = 0x0040; - static final int CAPSLOCK_ON = 0x0080; + static final int RIGHT_ALT_PRESSED = 0x0001; + static final int LEFT_ALT_PRESSED = 0x0002; + static final int RIGHT_CTRL_PRESSED = 0x0004; + static final int LEFT_CTRL_PRESSED = 0x0008; + static final int SHIFT_PRESSED = 0x0010; + static final int NUMLOCK_ON = 0x0020; + static final int SCROLLLOCK_ON = 0x0040; + static final int CAPSLOCK_ON = 0x0080; - protected void processKeyEvent(final boolean isKeyDown, final short virtualKeyCode, char ch, final int controlKeyState) throws IOException { + protected void processKeyEvent( + final boolean isKeyDown, final short virtualKeyCode, char ch, final int controlKeyState) + throws IOException { final boolean isCtrl = (controlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) > 0; final boolean isAlt = (controlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) > 0; final boolean isShift = (controlKeyState & SHIFT_PRESSED) > 0; @@ -222,11 +256,13 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { // Pressing "Alt Gr" is translated to Alt-Ctrl, hence it has to be checked that Ctrl is _not_ pressed, // otherwise inserting of "Alt Gr" codes on non-US keyboards would yield errors if (ch != 0 - && (controlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | SHIFT_PRESSED)) - == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) { + && (controlKeyState + & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) { processInputChar(ch); } else { - final String keySeq = getEscapeSequence(virtualKeyCode, (isCtrl ? CTRL_FLAG : 0) + (isAlt ? ALT_FLAG : 0) + (isShift ? SHIFT_FLAG : 0)); + final String keySeq = getEscapeSequence( + virtualKeyCode, (isCtrl ? CTRL_FLAG : 0) + (isAlt ? ALT_FLAG : 0) + (isShift ? SHIFT_FLAG : 0)); if (keySeq != null) { for (char c : keySeq.toCharArray()) { processInputChar(c); @@ -240,7 +276,7 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { * 4). Ctrl + Space(0x20) : uchar=0x20 * 5). Ctrl + : uchar=0 * 6). Ctrl + Alt + : uchar=0 - */ + */ if (ch > 0) { if (isAlt) { processInputChar('\033'); @@ -254,10 +290,10 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { } else { processInputChar(ch); } - } else if (isCtrl) { //Handles the ctrl key events(uchar=0) + } else if (isCtrl) { // Handles the ctrl key events(uchar=0) if (virtualKeyCode >= 'A' && virtualKeyCode <= 'Z') { ch = (char) (virtualKeyCode - 0x40); - } else if (virtualKeyCode == 191) { //? + } else if (virtualKeyCode == 191) { // ? ch = 127; } if (ch > 0) { @@ -275,7 +311,7 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { else { // support ALT+NumPad input method if (virtualKeyCode == 0x12 /*VK_MENU ALT key*/ && ch > 0) { - processInputChar(ch); // no such combination in Windows + processInputChar(ch); // no such combination in Windows } } } @@ -468,7 +504,19 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { raise(Signal.INFO); } } - if (c == '\r') { + if (attributes.getInputFlag(Attributes.InputFlag.INORMEOL)) { + if (c == '\r') { + skipNextLf = true; + c = '\n'; + } else if (c == '\n') { + if (skipNextLf) { + skipNextLf = false; + return; + } + } else { + skipNextLf = false; + } + } else if (c == '\r') { if (attributes.getInputFlag(Attributes.InputFlag.IGNCR)) { return; } @@ -478,10 +526,10 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { } else if (c == '\n' && attributes.getInputFlag(Attributes.InputFlag.INLCR)) { c = '\r'; } -// if (attributes.getLocalFlag(Attributes.LocalFlag.ECHO)) { -// processOutputByte(c); -// masterOutput.flush(); -// } + // if (attributes.getLocalFlag(Attributes.LocalFlag.ECHO)) { + // processOutputByte(c); + // masterOutput.flush(); + // } slaveInputPipe.write(c); } @@ -492,9 +540,9 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { return true; } - protected abstract int getConsoleMode(); + protected abstract int getConsoleMode(Console console); - protected abstract void setConsoleMode(int mode); + protected abstract void setConsoleMode(Console console, int mode); /** * Read a single input event from the input buffer and process it. @@ -504,5 +552,13 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal { */ protected abstract boolean processConsoleInput() throws IOException; -} + @Override + public TerminalProvider getProvider() { + return provider; + } + @Override + public SystemStream getSystemStream() { + return systemStream; + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/CursorSupport.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/CursorSupport.java index ef22cd0a7d8..14253d8c1d1 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/CursorSupport.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/CursorSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,17 +8,17 @@ */ package jdk.internal.org.jline.terminal.impl; -import jdk.internal.org.jline.terminal.Cursor; -import jdk.internal.org.jline.terminal.Terminal; -import jdk.internal.org.jline.utils.Curses; -import jdk.internal.org.jline.utils.InfoCmp; - import java.io.IOError; import java.io.IOException; import java.util.function.IntConsumer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import jdk.internal.org.jline.terminal.Cursor; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.utils.Curses; +import jdk.internal.org.jline.utils.InfoCmp; + public class CursorSupport { public static Cursor getCursorPosition(Terminal terminal, IntConsumer discarded) { @@ -105,5 +105,4 @@ public class CursorSupport { throw new IOError(e); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java index dfa784c29f3..dc54ea2157d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, the original author or authors. + * Copyright (c) 2022, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit; import jdk.internal.org.jline.terminal.Attributes; import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.spi.SystemStream; import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.OSUtils; @@ -26,7 +27,7 @@ public class Diag { diag(System.out); } - static void diag(PrintStream out) { + public static void diag(PrintStream out) { out.println("System properties"); out.println("================="); out.println("os.name = " + System.getProperty("os.name")); @@ -50,6 +51,17 @@ public class Diag { out.println("IS_OSX = " + OSUtils.IS_OSX); out.println(); + // FFM + out.println("FFM Support"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("ffm"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("FFM support not available: " + t); + } + out.println(); + out.println("JnaSupport"); out.println("================="); try { @@ -60,13 +72,23 @@ public class Diag { } out.println(); - out.println("JansiSupport"); + out.println("Jansi2Support"); out.println("================="); try { TerminalProvider provider = TerminalProvider.load("jansi"); testProvider(out, provider); } catch (Throwable t) { - out.println("Jansi support not available: " + t); + out.println("Jansi 2 support not available: " + t); + } + out.println(); + + out.println("JniSupport"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("jni"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("JNI support not available: " + t); } out.println(); @@ -83,32 +105,45 @@ public class Diag { private static void testProvider(PrintStream out, TerminalProvider provider) { try { - out.println("StdIn stream = " + provider.isSystemStream(TerminalProvider.Stream.Input)); - out.println("StdOut stream = " + provider.isSystemStream(TerminalProvider.Stream.Output)); - out.println("StdErr stream = " + provider.isSystemStream(TerminalProvider.Stream.Error)); + out.println("StdIn stream = " + provider.isSystemStream(SystemStream.Input)); + out.println("StdOut stream = " + provider.isSystemStream(SystemStream.Output)); + out.println("StdErr stream = " + provider.isSystemStream(SystemStream.Error)); } catch (Throwable t2) { out.println("Unable to check stream: " + t2); } try { - out.println("StdIn stream name = " + provider.systemStreamName(TerminalProvider.Stream.Input)); - out.println("StdOut stream name = " + provider.systemStreamName(TerminalProvider.Stream.Output)); - out.println("StdErr stream name = " + provider.systemStreamName(TerminalProvider.Stream.Error)); + out.println("StdIn stream name = " + provider.systemStreamName(SystemStream.Input)); + out.println("StdOut stream name = " + provider.systemStreamName(SystemStream.Output)); + out.println("StdErr stream name = " + provider.systemStreamName(SystemStream.Error)); } catch (Throwable t2) { out.println("Unable to check stream names: " + t2); } - try (Terminal terminal = provider.sysTerminal("diag", "xterm", false, StandardCharsets.UTF_8, - false, Terminal.SignalHandler.SIG_DFL, false, TerminalProvider.Stream.Output, input -> input) ) { + try (Terminal terminal = provider.sysTerminal( + "diag", + "xterm", + false, + StandardCharsets.UTF_8, + false, + Terminal.SignalHandler.SIG_DFL, + false, + SystemStream.Output, + input -> input)) { if (terminal != null) { Attributes attr = terminal.enterRawMode(); try { out.println("Terminal size: " + terminal.getSize()); - ForkJoinTask t = new ForkJoinPool(1).submit(() -> terminal.reader().read(1) ); + ForkJoinTask t = + new ForkJoinPool(1).submit(() -> terminal.reader().read(1)); int r = t.get(1000, TimeUnit.MILLISECONDS); StringBuilder sb = new StringBuilder(); sb.append("The terminal seems to work: "); sb.append("terminal ").append(terminal.getClass().getName()); if (terminal instanceof AbstractPosixTerminal) { - sb.append(" with pty ").append(((AbstractPosixTerminal) terminal).getPty().getClass().getName()); + sb.append(" with pty ") + .append(((AbstractPosixTerminal) terminal) + .getPty() + .getClass() + .getName()); } out.println(sb); } catch (Throwable t3) { @@ -129,5 +164,4 @@ public class Diag { static S load(Class clazz) { return ServiceLoader.load(clazz, clazz.getClassLoader()).iterator().next(); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminal.java index 0b8cb57cbbf..2922132c1bf 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,38 +14,58 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.Charset; +import java.util.function.Function; import jdk.internal.org.jline.terminal.Attributes; import jdk.internal.org.jline.terminal.Attributes.ControlChar; import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.NonBlocking; import jdk.internal.org.jline.utils.NonBlockingInputStream; import jdk.internal.org.jline.utils.NonBlockingReader; public class DumbTerminal extends AbstractTerminal { + private final TerminalProvider provider; + private final SystemStream systemStream; private final NonBlockingInputStream input; private final OutputStream output; private final NonBlockingReader reader; private final PrintWriter writer; private final Attributes attributes; private final Size size; + private boolean skipNextLf; - public DumbTerminal(InputStream in, OutputStream out) throws IOException { - this(TYPE_DUMB, TYPE_DUMB, in, out, null); + public DumbTerminal(InputStream in, OutputStream out, Function inputStreamWrapper) throws IOException { + this(TYPE_DUMB, TYPE_DUMB, in, out, null, inputStreamWrapper); } - public DumbTerminal(String name, String type, InputStream in, OutputStream out, Charset encoding) throws IOException { - this(name, type, in, out, encoding, SignalHandler.SIG_DFL); + public DumbTerminal(String name, String type, InputStream in, OutputStream out, Charset encoding, Function inputStreamWrapper) + throws IOException { + this(null, null, name, type, in, out, encoding, SignalHandler.SIG_DFL, inputStreamWrapper); } - public DumbTerminal(String name, String type, InputStream in, OutputStream out, Charset encoding, SignalHandler signalHandler) throws IOException { + @SuppressWarnings("this-escape") + public DumbTerminal( + TerminalProvider provider, + SystemStream systemStream, + String name, + String type, + InputStream in, + OutputStream out, + Charset encoding, + SignalHandler signalHandler, + Function inputStreamWrapper) + throws IOException { super(name, type, encoding, signalHandler); - NonBlockingInputStream nbis = NonBlocking.nonBlocking(getName(), in); + this.provider = provider; + this.systemStream = systemStream; + NonBlockingInputStream nbis = NonBlocking.nonBlocking(getName(), inputStreamWrapper.apply(in)); this.input = new NonBlockingInputStream() { @Override public int read(long timeout, boolean isPeek) throws IOException { - for (;;) { + for (; ; ) { int c = nbis.read(timeout, isPeek); if (attributes.getLocalFlag(Attributes.LocalFlag.ISIG)) { if (c == attributes.getControlChar(ControlChar.VINTR)) { @@ -62,7 +82,19 @@ public class DumbTerminal extends AbstractTerminal { continue; } } - if (c == '\r') { + if (attributes.getInputFlag(Attributes.InputFlag.INORMEOL)) { + if (c == '\r') { + skipNextLf = true; + c = '\n'; + } else if (c == '\n') { + if (skipNextLf) { + skipNextLf = false; + continue; + } + } else { + skipNextLf = false; + } + } else if (c == '\r') { if (attributes.getInputFlag(Attributes.InputFlag.IGNCR)) { continue; } @@ -80,10 +112,10 @@ public class DumbTerminal extends AbstractTerminal { this.reader = NonBlocking.nonBlocking(getName(), input, encoding()); this.writer = new PrintWriter(new OutputStreamWriter(output, encoding())); this.attributes = new Attributes(); - this.attributes.setControlChar(ControlChar.VERASE, (char) 127); + this.attributes.setControlChar(ControlChar.VERASE, (char) 127); this.attributes.setControlChar(ControlChar.VWERASE, (char) 23); - this.attributes.setControlChar(ControlChar.VKILL, (char) 21); - this.attributes.setControlChar(ControlChar.VLNEXT, (char) 22); + this.attributes.setControlChar(ControlChar.VKILL, (char) 21); + this.attributes.setControlChar(ControlChar.VLNEXT, (char) 22); this.size = new Size(); parseInfoCmp(); } @@ -107,9 +139,7 @@ public class DumbTerminal extends AbstractTerminal { } public Attributes getAttributes() { - Attributes attr = new Attributes(); - attr.copy(attributes); - return attr; + return new Attributes(attributes); } public void setAttributes(Attributes attr) { @@ -126,4 +156,13 @@ public class DumbTerminal extends AbstractTerminal { size.copy(sz); } + @Override + public TerminalProvider getProvider() { + return provider; + } + + @Override + public SystemStream getSystemStream() { + return systemStream; + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminalProvider.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminalProvider.java new file mode 100644 index 00000000000..8ff97353065 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/DumbTerminalProvider.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl; + +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.TerminalBuilder; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; + +public class DumbTerminalProvider implements TerminalProvider { + + @Override + public String name() { + return TerminalBuilder.PROP_PROVIDER_DUMB; + } + + @Override + public Terminal sysTerminal( + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + Terminal.SignalHandler signalHandler, + boolean paused, + SystemStream systemStream, + Function inputStreamWrapper) + throws IOException { + return new DumbTerminal( + this, + systemStream, + name, + type, + new FileInputStream(FileDescriptor.in), + new FileOutputStream(systemStream == SystemStream.Error ? FileDescriptor.err : FileDescriptor.out), + encoding, + signalHandler, + inputStreamWrapper); + } + + @Override + public Terminal newTerminal( + String name, + String type, + InputStream masterInput, + OutputStream masterOutput, + Charset encoding, + Terminal.SignalHandler signalHandler, + boolean paused, + Attributes attributes, + Size size) + throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isSystemStream(SystemStream stream) { + return false; + } + + @Override + public String systemStreamName(SystemStream stream) { + return null; + } + + @Override + public int systemStreamWidth(SystemStream stream) { + return 0; + } + + @Override + public String toString() { + return "TerminalProvider[" + name() + "]"; + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExternalTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExternalTerminal.java index 2814b52c7cc..5033fd61279 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExternalTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExternalTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,10 +8,6 @@ */ package jdk.internal.org.jline.terminal.impl; -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Cursor; -import jdk.internal.org.jline.terminal.Size; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -19,6 +15,11 @@ import java.nio.charset.Charset; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.IntConsumer; +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Cursor; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; + /** * Console implementation with embedded line disciplined. * @@ -32,45 +33,59 @@ import java.util.function.IntConsumer; */ public class ExternalTerminal extends LineDisciplineTerminal { + private final TerminalProvider provider; protected final AtomicBoolean closed = new AtomicBoolean(); protected final InputStream masterInput; protected final Object lock = new Object(); protected boolean paused = true; protected Thread pumpThread; - public ExternalTerminal(String name, String type, - InputStream masterInput, - OutputStream masterOutput, - Charset encoding) throws IOException { - this(name, type, masterInput, masterOutput, encoding, SignalHandler.SIG_DFL); + public ExternalTerminal( + String name, String type, InputStream masterInput, OutputStream masterOutput, Charset encoding) + throws IOException { + this(null, name, type, masterInput, masterOutput, encoding, SignalHandler.SIG_DFL); } - public ExternalTerminal(String name, String type, - InputStream masterInput, - OutputStream masterOutput, - Charset encoding, - SignalHandler signalHandler) throws IOException { - this(name, type, masterInput, masterOutput, encoding, signalHandler, false); + public ExternalTerminal( + TerminalProvider provider, + String name, + String type, + InputStream masterInput, + OutputStream masterOutput, + Charset encoding, + SignalHandler signalHandler) + throws IOException { + this(provider, name, type, masterInput, masterOutput, encoding, signalHandler, false); } - public ExternalTerminal(String name, String type, - InputStream masterInput, - OutputStream masterOutput, - Charset encoding, - SignalHandler signalHandler, - boolean paused) throws IOException { - this(name, type, masterInput, masterOutput, encoding, signalHandler, paused, null, null); + public ExternalTerminal( + TerminalProvider provider, + String name, + String type, + InputStream masterInput, + OutputStream masterOutput, + Charset encoding, + SignalHandler signalHandler, + boolean paused) + throws IOException { + this(provider, name, type, masterInput, masterOutput, encoding, signalHandler, paused, null, null); } - public ExternalTerminal(String name, String type, - InputStream masterInput, - OutputStream masterOutput, - Charset encoding, - SignalHandler signalHandler, - boolean paused, - Attributes attributes, - Size size) throws IOException { + @SuppressWarnings("this-escape") + public ExternalTerminal( + TerminalProvider provider, + String name, + String type, + InputStream masterInput, + OutputStream masterOutput, + Charset encoding, + SignalHandler signalHandler, + boolean paused, + Attributes attributes, + Size size) + throws IOException { super(name, type, masterOutput, encoding, signalHandler); + this.provider = provider; this.masterInput = masterInput; if (attributes != null) { setAttributes(attributes); @@ -171,4 +186,8 @@ public class ExternalTerminal extends LineDisciplineTerminal { return CursorSupport.getCursorPosition(this, discarded); } + @Override + public TerminalProvider getProvider() { + return provider; + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/LineDisciplineTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/LineDisciplineTerminal.java index 0f290379bbf..4e7a396bbc3 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/LineDisciplineTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/LineDisciplineTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,6 +14,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.Charset; +import java.util.EnumSet; import java.util.Objects; import jdk.internal.org.jline.terminal.Attributes; @@ -23,6 +24,8 @@ import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.Attributes.OutputFlag; import jdk.internal.org.jline.terminal.Size; import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.NonBlocking; import jdk.internal.org.jline.utils.NonBlockingPumpInputStream; import jdk.internal.org.jline.utils.NonBlockingReader; @@ -45,21 +48,6 @@ import jdk.internal.org.jline.utils.NonBlockingReader; */ public class LineDisciplineTerminal extends AbstractTerminal { - private static final String DEFAULT_TERMINAL_ATTRIBUTES = - "speed 9600 baud; 24 rows; 80 columns;\n" + - "lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl\n" + - "\t-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo\n" + - "\t-extproc\n" + - "iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8\n" + - "\t-ignbrk brkint -inpck -ignpar -parmrk\n" + - "oflags: opost onlcr -oxtabs -onocr -onlret\n" + - "cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow\n" + - "\t-dtrflow -mdmbuf\n" + - "cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ;\n" + - "\teol2 = ; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;\n" + - "\tmin = 1; quit = ^\\; reprint = ^R; start = ^Q; status = ^T;\n" + - "\tstop = ^S; susp = ^Z; time = 0; werase = ^W;\n"; - private static final int PIPE_SIZE = 1024; /* @@ -84,20 +72,20 @@ public class LineDisciplineTerminal extends AbstractTerminal { * Console data */ protected final Attributes attributes; + protected final Size size; - public LineDisciplineTerminal(String name, - String type, - OutputStream masterOutput, - Charset encoding) throws IOException { + protected boolean skipNextLf; + + public LineDisciplineTerminal(String name, String type, OutputStream masterOutput, Charset encoding) + throws IOException { this(name, type, masterOutput, encoding, SignalHandler.SIG_DFL); } - public LineDisciplineTerminal(String name, - String type, - OutputStream masterOutput, - Charset encoding, - SignalHandler signalHandler) throws IOException { + @SuppressWarnings("this-escape") + public LineDisciplineTerminal( + String name, String type, OutputStream masterOutput, Charset encoding, SignalHandler signalHandler) + throws IOException { super(name, type, encoding, signalHandler); NonBlockingPumpInputStream input = NonBlocking.nonBlockingPumpInputStream(PIPE_SIZE); this.slaveInputPipe = input.getOutputStream(); @@ -106,11 +94,66 @@ public class LineDisciplineTerminal extends AbstractTerminal { this.slaveOutput = new FilteringOutputStream(); this.slaveWriter = new PrintWriter(new OutputStreamWriter(slaveOutput, encoding())); this.masterOutput = masterOutput; - this.attributes = ExecPty.doGetAttr(DEFAULT_TERMINAL_ATTRIBUTES); + this.attributes = getDefaultTerminalAttributes(); this.size = new Size(160, 50); parseInfoCmp(); } + private static Attributes getDefaultTerminalAttributes() { + // speed 9600 baud; 24 rows; 80 columns; + // lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl + // -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo + // -extproc + // iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8 + // -ignbrk brkint -inpck -ignpar -parmrk + // oflags: opost onlcr -oxtabs -onocr -onlret + // cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow + // -dtrflow -mdmbuf + // cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ; + // eol2 = ; erase = ^?; intr = ^C; kill = ^U; lnext = ^V; + // min = 1; quit = ^\\; reprint = ^R; start = ^Q; status = ^T; + // stop = ^S; susp = ^Z; time = 0; werase = ^W; + Attributes attr = new Attributes(); + attr.setLocalFlags(EnumSet.of( + LocalFlag.ICANON, + LocalFlag.ISIG, + LocalFlag.IEXTEN, + LocalFlag.ECHO, + LocalFlag.ECHOE, + LocalFlag.ECHOKE, + LocalFlag.ECHOCTL, + LocalFlag.PENDIN)); + attr.setInputFlags(EnumSet.of( + InputFlag.ICRNL, + InputFlag.IXON, + InputFlag.IXANY, + InputFlag.IMAXBEL, + InputFlag.IUTF8, + InputFlag.BRKINT)); + attr.setOutputFlags(EnumSet.of(OutputFlag.OPOST, OutputFlag.ONLCR)); + attr.setControlChar(ControlChar.VDISCARD, ctrl('O')); + attr.setControlChar(ControlChar.VDSUSP, ctrl('Y')); + attr.setControlChar(ControlChar.VEOF, ctrl('D')); + attr.setControlChar(ControlChar.VERASE, ctrl('?')); + attr.setControlChar(ControlChar.VINTR, ctrl('C')); + attr.setControlChar(ControlChar.VKILL, ctrl('U')); + attr.setControlChar(ControlChar.VLNEXT, ctrl('V')); + attr.setControlChar(ControlChar.VMIN, 1); + attr.setControlChar(ControlChar.VQUIT, ctrl('\\')); + attr.setControlChar(ControlChar.VREPRINT, ctrl('R')); + attr.setControlChar(ControlChar.VSTART, ctrl('Q')); + attr.setControlChar(ControlChar.VSTATUS, ctrl('T')); + attr.setControlChar(ControlChar.VSTOP, ctrl('S')); + attr.setControlChar(ControlChar.VSUSP, ctrl('Z')); + attr.setControlChar(ControlChar.VTIME, 0); + attr.setControlChar(ControlChar.VWERASE, ctrl('W')); + return attr; + } + + private static int ctrl(char c) { + return c == '?' ? 177 : c - 64; + } + public NonBlockingReader reader() { return slaveReader; } @@ -130,9 +173,7 @@ public class LineDisciplineTerminal extends AbstractTerminal { } public Attributes getAttributes() { - Attributes attr = new Attributes(); - attr.copy(attributes); - return attr; + return new Attributes(attributes); } public void setAttributes(Attributes attr) { @@ -149,9 +190,9 @@ public class LineDisciplineTerminal extends AbstractTerminal { size.copy(sz); } - @Override + @Override public void raise(Signal signal) { - Objects.requireNonNull(signal); + Objects.requireNonNull(signal); // Do not call clear() atm as this can cause // deadlock between reading / writing threads // TODO: any way to fix that ? @@ -214,7 +255,19 @@ public class LineDisciplineTerminal extends AbstractTerminal { raise(Signal.INFO); } } - if (c == '\r') { + if (attributes.getInputFlag(InputFlag.INORMEOL)) { + if (c == '\r') { + skipNextLf = true; + c = '\n'; + } else if (c == '\n') { + if (skipNextLf) { + skipNextLf = false; + return false; + } + } else { + skipNextLf = false; + } + } else if (c == '\r') { if (attributes.getInputFlag(InputFlag.IGNCR)) { return false; } @@ -273,6 +326,16 @@ public class LineDisciplineTerminal extends AbstractTerminal { } } + @Override + public TerminalProvider getProvider() { + return null; + } + + @Override + public SystemStream getSystemStream() { + return null; + } + private class FilteringOutputStream extends OutputStream { @Override public void write(int b) throws IOException { @@ -284,13 +347,12 @@ public class LineDisciplineTerminal extends AbstractTerminal { public void write(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); - } else if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0)) { + } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } - for (int i = 0 ; i < len ; i++) { + for (int i = 0; i < len; i++) { processOutputByte(b[off + i]); } flush(); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/MouseSupport.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/MouseSupport.java index 89ae6e5b74a..eef25c90d8f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/MouseSupport.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/MouseSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,11 +8,6 @@ */ package jdk.internal.org.jline.terminal.impl; -import jdk.internal.org.jline.terminal.MouseEvent; -import jdk.internal.org.jline.terminal.Terminal; -import jdk.internal.org.jline.utils.InfoCmp; -import jdk.internal.org.jline.utils.InputStreamReader; - import java.io.EOFException; import java.io.IOError; import java.io.IOException; @@ -20,6 +15,11 @@ import java.nio.charset.StandardCharsets; import java.util.EnumSet; import java.util.function.IntSupplier; +import jdk.internal.org.jline.terminal.MouseEvent; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.utils.InfoCmp; +import jdk.internal.org.jline.utils.InputStreamReader; + public class MouseSupport { public static boolean hasMouseSupport(Terminal terminal) { @@ -78,7 +78,8 @@ public class MouseSupport { case 0: button = MouseEvent.Button.Button1; if (last.getButton() == button - && (last.getType() == MouseEvent.Type.Pressed || last.getType() == MouseEvent.Type.Dragged)) { + && (last.getType() == MouseEvent.Type.Pressed + || last.getType() == MouseEvent.Type.Dragged)) { type = MouseEvent.Type.Dragged; } else { type = MouseEvent.Type.Pressed; @@ -87,7 +88,8 @@ public class MouseSupport { case 1: button = MouseEvent.Button.Button2; if (last.getButton() == button - && (last.getType() == MouseEvent.Type.Pressed || last.getType() == MouseEvent.Type.Dragged)) { + && (last.getType() == MouseEvent.Type.Pressed + || last.getType() == MouseEvent.Type.Dragged)) { type = MouseEvent.Type.Dragged; } else { type = MouseEvent.Type.Pressed; @@ -96,7 +98,8 @@ public class MouseSupport { case 2: button = MouseEvent.Button.Button3; if (last.getButton() == button - && (last.getType() == MouseEvent.Type.Pressed || last.getType() == MouseEvent.Type.Dragged)) { + && (last.getType() == MouseEvent.Type.Pressed + || last.getType() == MouseEvent.Type.Dragged)) { type = MouseEvent.Type.Dragged; } else { type = MouseEvent.Type.Pressed; @@ -134,5 +137,4 @@ public class MouseSupport { throw new IOError(e); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/NativeSignalHandler.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/NativeSignalHandler.java index 00c584c6cb9..bba177794a5 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/NativeSignalHandler.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/NativeSignalHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -17,8 +17,7 @@ public final class NativeSignalHandler implements SignalHandler { public static final NativeSignalHandler SIG_IGN = new NativeSignalHandler(); - private NativeSignalHandler() { - } + private NativeSignalHandler() {} public void handle(Signal signal) { throw new UnsupportedOperationException(); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java index f85e3fe0b0c..d34103e4d5e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -38,15 +38,34 @@ public class PosixPtyTerminal extends AbstractPosixTerminal { private Thread outputPumpThread; private boolean paused = true; - public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding) throws IOException { + public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding) + throws IOException { this(name, type, pty, in, out, encoding, SignalHandler.SIG_DFL); } - public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, SignalHandler signalHandler) throws IOException { + public PosixPtyTerminal( + String name, + String type, + Pty pty, + InputStream in, + OutputStream out, + Charset encoding, + SignalHandler signalHandler) + throws IOException { this(name, type, pty, in, out, encoding, signalHandler, false); } - public PosixPtyTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, SignalHandler signalHandler, boolean paused) throws IOException { + @SuppressWarnings("this-escape") + public PosixPtyTerminal( + String name, + String type, + Pty pty, + InputStream in, + OutputStream out, + Charset encoding, + SignalHandler signalHandler, + boolean paused) + throws IOException { super(name, type, pty, encoding, signalHandler); this.in = Objects.requireNonNull(in); this.out = Objects.requireNonNull(out); @@ -113,7 +132,7 @@ public class PosixPtyTerminal extends AbstractPosixTerminal { if (p1 != null) { p1.join(); } - if (p2 !=null) { + if (p2 != null) { p2.join(); } } @@ -167,7 +186,7 @@ public class PosixPtyTerminal extends AbstractPosixTerminal { private void pumpIn() { try { - for (;;) { + for (; ; ) { synchronized (lock) { if (paused) { inputPumpThread = null; @@ -193,7 +212,7 @@ public class PosixPtyTerminal extends AbstractPosixTerminal { private void pumpOut() { try { - for (;;) { + for (; ; ) { synchronized (lock) { if (paused) { outputPumpThread = null; @@ -221,5 +240,4 @@ public class PosixPtyTerminal extends AbstractPosixTerminal { // Ignore } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java index a55f3d4a748..135ed0bb0c0 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -18,8 +18,9 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import jdk.internal.org.jline.utils.NonBlocking; import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.utils.FastBufferedOutputStream; +import jdk.internal.org.jline.utils.NonBlocking; import jdk.internal.org.jline.utils.NonBlockingInputStream; import jdk.internal.org.jline.utils.NonBlockingReader; import jdk.internal.org.jline.utils.ShutdownHooks; @@ -35,12 +36,14 @@ public class PosixSysTerminal extends AbstractPosixTerminal { protected final Map nativeHandlers = new HashMap<>(); protected final Task closer; - public PosixSysTerminal(String name, String type, Pty pty, Charset encoding, - boolean nativeSignals, SignalHandler signalHandler, - Function inputStreamWrapper) throws IOException { + @SuppressWarnings("this-escape") + public PosixSysTerminal( + String name, String type, Pty pty, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, + Function inputStreamWrapper) + throws IOException { super(name, type, pty, encoding, signalHandler); this.input = NonBlocking.nonBlocking(getName(), inputStreamWrapper.apply(pty.getSlaveInput())); - this.output = pty.getSlaveOutput(); + this.output = new FastBufferedOutputStream(pty.getSlaveOutput()); this.reader = NonBlocking.nonBlocking(getName(), input, encoding()); this.writer = new PrintWriter(new OutputStreamWriter(output, encoding())); parseInfoCmp(); @@ -98,5 +101,4 @@ public class PosixSysTerminal extends AbstractPosixTerminal { // Do not call reader.close() reader.shutdown(); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java similarity index 71% rename from src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java rename to src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java index 5377b4acdb8..c0a35cbd6a2 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java @@ -1,18 +1,18 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. * * https://opensource.org/licenses/BSD-3-Clause */ -package jdk.internal.org.jline.terminal.impl; +package jdk.internal.org.jline.terminal.impl.exec; +import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.FileDescriptor; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -26,8 +26,10 @@ import jdk.internal.org.jline.terminal.Attributes.InputFlag; import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.Attributes.OutputFlag; import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.terminal.impl.AbstractPty; import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.OSUtils; import static jdk.internal.org.jline.utils.ExecHelper.exec; @@ -35,28 +37,26 @@ import static jdk.internal.org.jline.utils.ExecHelper.exec; public class ExecPty extends AbstractPty implements Pty { private final String name; - private final TerminalProvider.Stream console; - public static Pty current(TerminalProvider.Stream console) throws IOException { + public static Pty current(TerminalProvider provider, SystemStream systemStream) throws IOException { try { String result = exec(true, OSUtils.TTY_COMMAND); - if (console != TerminalProvider.Stream.Output && console != TerminalProvider.Stream.Error) { - throw new IllegalArgumentException("console should be Output or Error: " + console); + if (systemStream != SystemStream.Output && systemStream != SystemStream.Error) { + throw new IllegalArgumentException("systemStream should be Output or Error: " + systemStream); } - return new ExecPty(result.trim(), console); + return new ExecPty(provider, systemStream, result.trim()); } catch (IOException e) { throw new IOException("Not a tty", e); } } - protected ExecPty(String name, TerminalProvider.Stream console) { + protected ExecPty(TerminalProvider provider, SystemStream systemStream, String name) { + super(provider, systemStream); this.name = name; - this.console = console; } @Override - public void close() throws IOException { - } + public void close() throws IOException {} public String getName() { return name; @@ -74,18 +74,16 @@ public class ExecPty extends AbstractPty implements Pty { @Override protected InputStream doGetSlaveInput() throws IOException { - return console != null - ? new FileInputStream(FileDescriptor.in) - : new FileInputStream(getName()); + return systemStream != null ? new FileInputStream(FileDescriptor.in) : new FileInputStream(getName()); } @Override public OutputStream getSlaveOutput() throws IOException { - return console == TerminalProvider.Stream.Output + return systemStream == SystemStream.Output ? new FileOutputStream(FileDescriptor.out) - : console == TerminalProvider.Stream.Error - ? new FileOutputStream(FileDescriptor.err) - : new FileOutputStream(getName()); + : systemStream == SystemStream.Error + ? new FileOutputStream(FileDescriptor.err) + : new FileOutputStream(getName()); } @Override @@ -99,18 +97,30 @@ public class ExecPty extends AbstractPty implements Pty { List commands = getFlagsToSet(attr, getAttr()); if (!commands.isEmpty()) { commands.add(0, OSUtils.STTY_COMMAND); - if (console == null) { + if (systemStream == null) { commands.add(1, OSUtils.STTY_F_OPTION); commands.add(2, getName()); } - exec(console != null, commands.toArray(new String[0])); + try { + exec(systemStream != null, commands.toArray(new String[0])); + } catch (IOException e) { + // Handle partial failures with GNU stty, see #97 + if (e.toString().contains("unable to perform all requested operations")) { + commands = getFlagsToSet(attr, getAttr()); + if (!commands.isEmpty()) { + throw new IOException("Could not set the following flags: " + String.join(", ", commands), e); + } + } else { + throw e; + } + } } } protected List getFlagsToSet(Attributes attr, Attributes current) { List commands = new ArrayList<>(); for (InputFlag flag : InputFlag.values()) { - if (attr.getInputFlag(flag) != current.getInputFlag(flag)) { + if (attr.getInputFlag(flag) != current.getInputFlag(flag) && flag != InputFlag.INORMEOL) { commands.add((attr.getInputFlag(flag) ? flag.name() : "-" + flag.name()).toLowerCase()); } } @@ -137,11 +147,9 @@ public class ExecPty extends AbstractPty implements Pty { commands.add(cchar.name().toLowerCase().substring(1)); if (cchar == ControlChar.VMIN || cchar == ControlChar.VTIME) { commands.add(Integer.toString(v)); - } - else if (v == 0) { + } else if (v == 0) { commands.add(undef); - } - else { + } else { if (v >= 128) { v -= 128; str += "M-"; @@ -165,12 +173,12 @@ public class ExecPty extends AbstractPty implements Pty { } protected String doGetConfig() throws IOException { - return console != null - ? exec(true, OSUtils.STTY_COMMAND, "-a") + return systemStream != null + ? exec(true, OSUtils.STTY_COMMAND, "-a") : exec(false, OSUtils.STTY_COMMAND, OSUtils.STTY_F_OPTION, getName(), "-a"); } - static Attributes doGetAttr(String cfg) throws IOException { + public static Attributes doGetAttr(String cfg) throws IOException { Attributes attributes = new Attributes(); for (InputFlag flag : InputFlag.values()) { Boolean value = doGetFlag(cfg, flag); @@ -201,16 +209,19 @@ public class ExecPty extends AbstractPty implements Pty { if ("reprint".endsWith(name)) { name = "(?:reprint|rprnt)"; } - Matcher matcher = Pattern.compile("[\\s;]" + name + "\\s*=\\s*(.+?)[\\s;]").matcher(cfg); + Matcher matcher = + Pattern.compile("[\\s;]" + name + "\\s*=\\s*(.+?)[\\s;]").matcher(cfg); if (matcher.find()) { - attributes.setControlChar(cchar, parseControlChar(matcher.group(1).toUpperCase())); + attributes.setControlChar( + cchar, parseControlChar(matcher.group(1).toUpperCase())); } } return attributes; } private static Boolean doGetFlag(String cfg, Enum flag) { - Matcher matcher = Pattern.compile("(?:^|[\\s;])(\\-?" + flag.name().toLowerCase() + ")(?:[\\s;]|$)").matcher(cfg); + Matcher matcher = Pattern.compile("(?:^|[\\s;])(\\-?" + flag.name().toLowerCase() + ")(?:[\\s;]|$)") + .matcher(cfg); return matcher.find() ? !matcher.group(1).startsWith("-") : null; } @@ -259,9 +270,7 @@ public class ExecPty extends AbstractPty implements Pty { static int doGetInt(String name, String cfg) throws IOException { String[] patterns = new String[] { - "\\b([0-9]+)\\s+" + name + "\\b", - "\\b" + name + "\\s+([0-9]+)\\b", - "\\b" + name + "\\s*=\\s*([0-9]+)\\b" + "\\b([0-9]+)\\s+" + name + "\\b", "\\b" + name + "\\s+([0-9]+)\\b", "\\b" + name + "\\s*=\\s*([0-9]+)\\b" }; for (String pattern : patterns) { Matcher matcher = Pattern.compile(pattern).matcher(cfg); @@ -274,23 +283,29 @@ public class ExecPty extends AbstractPty implements Pty { @Override public void setSize(Size size) throws IOException { - if (console != null) { - exec(true, - OSUtils.STTY_COMMAND, - "columns", Integer.toString(size.getColumns()), - "rows", Integer.toString(size.getRows())); + if (systemStream != null) { + exec( + true, + OSUtils.STTY_COMMAND, + "columns", + Integer.toString(size.getColumns()), + "rows", + Integer.toString(size.getRows())); } else { - exec(false, - OSUtils.STTY_COMMAND, - OSUtils.STTY_F_OPTION, getName(), - "columns", Integer.toString(size.getColumns()), - "rows", Integer.toString(size.getRows())); + exec( + false, + OSUtils.STTY_COMMAND, + OSUtils.STTY_F_OPTION, + getName(), + "columns", + Integer.toString(size.getColumns()), + "rows", + Integer.toString(size.getRows())); } } @Override public String toString() { - return "ExecPty[" + getName() + (console != null ? ", system]" : "]"); + return "ExecPty[" + getName() + (systemStream != null ? ", system]" : "]"); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java index 8bdeede2e1b..418d3452d4a 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, the original author or authors. + * Copyright (c) 2022, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -17,117 +17,249 @@ import java.lang.reflect.Field; import java.nio.charset.Charset; import java.util.function.Function; +//import jdk.internal.org.jline.nativ.JLineLibrary; +//import jdk.internal.org.jline.nativ.JLineNativeLoader; import jdk.internal.org.jline.terminal.Attributes; import jdk.internal.org.jline.terminal.Size; import jdk.internal.org.jline.terminal.Terminal; -import jdk.internal.org.jline.terminal.impl.ExecPty; +import jdk.internal.org.jline.terminal.TerminalBuilder; import jdk.internal.org.jline.terminal.impl.ExternalTerminal; import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.SystemStream; import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.ExecHelper; +import jdk.internal.org.jline.utils.Log; import jdk.internal.org.jline.utils.OSUtils; -public class ExecTerminalProvider implements TerminalProvider -{ +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_REDIRECT_PIPE_CREATION_MODE; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_REDIRECT_PIPE_CREATION_MODE_DEFAULT; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_REDIRECT_PIPE_CREATION_MODE_NATIVE; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_REDIRECT_PIPE_CREATION_MODE_REFLECTION; + +public class ExecTerminalProvider implements TerminalProvider { + + private static boolean warned; public String name() { - return "exec"; + return TerminalBuilder.PROP_PROVIDER_EXEC; } - public Pty current(Stream consoleStream) throws IOException { - return ExecPty.current(consoleStream); + public Pty current(SystemStream systemStream) throws IOException { + return ExecPty.current(this, systemStream); } @Override - public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, - boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, - Stream consoleStream, Function inputStreamWrapper) throws IOException { + public Terminal sysTerminal( + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + Terminal.SignalHandler signalHandler, + boolean paused, + SystemStream systemStream, + Function inputStreamWrapper) + throws IOException { if (OSUtils.IS_WINDOWS) { - return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + return winSysTerminal( + name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, systemStream, inputStreamWrapper); } else { - return posixSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + return posixSysTerminal( + name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, systemStream, inputStreamWrapper); } } - public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, - boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, - Stream consoleStream, Function inputStreamWrapper ) throws IOException { + public Terminal winSysTerminal( + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + Terminal.SignalHandler signalHandler, + boolean paused, + SystemStream systemStream, + Function inputStreamWrapper) + throws IOException { if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { - Pty pty = current(consoleStream); + Pty pty = current(systemStream); return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); } else { return null; } } - public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, - boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, - Stream consoleStream, Function inputStreamWrapper) throws IOException { - Pty pty = current(consoleStream); + public Terminal posixSysTerminal( + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + Terminal.SignalHandler signalHandler, + boolean paused, + SystemStream systemStream, + Function inputStreamWrapper) + throws IOException { + Pty pty = current(systemStream); return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); } @Override - public Terminal newTerminal(String name, String type, InputStream in, OutputStream out, - Charset encoding, Terminal.SignalHandler signalHandler, boolean paused, - Attributes attributes, Size size) throws IOException - { - return new ExternalTerminal(name, type, in, out, encoding, signalHandler, paused, attributes, size); + public Terminal newTerminal( + String name, + String type, + InputStream in, + OutputStream out, + Charset encoding, + Terminal.SignalHandler signalHandler, + boolean paused, + Attributes attributes, + Size size) + throws IOException { + return new ExternalTerminal(this, name, type, in, out, encoding, signalHandler, paused, attributes, size); } @Override - public boolean isSystemStream(Stream stream) { + public boolean isSystemStream(SystemStream stream) { try { - return isWindowsSystemStream(stream) || isPosixSystemStream(stream); + return isPosixSystemStream(stream) || isWindowsSystemStream(stream); } catch (Throwable t) { return false; } } - public boolean isWindowsSystemStream(Stream stream) { - return systemStreamName( stream ) != null; + public boolean isWindowsSystemStream(SystemStream stream) { + return systemStreamName(stream) != null; } - public boolean isPosixSystemStream(Stream stream) { + public boolean isPosixSystemStream(SystemStream stream) { try { Process p = new ProcessBuilder(OSUtils.TEST_COMMAND, "-t", Integer.toString(stream.ordinal())) - .inheritIO().start(); + .inheritIO() + .start(); return p.waitFor() == 0; } catch (Throwable t) { + Log.debug("ExecTerminalProvider failed 'test -t' for " + stream, t); // ignore } return false; } @Override - public String systemStreamName(Stream stream) { + public String systemStreamName(SystemStream stream) { try { - ProcessBuilder.Redirect input = stream == Stream.Input - ? ProcessBuilder.Redirect.INHERIT - : getRedirect(stream == Stream.Output ? FileDescriptor.out : FileDescriptor.err); - Process p = new ProcessBuilder(OSUtils.TTY_COMMAND).redirectInput(input).start(); + ProcessBuilder.Redirect input = stream == SystemStream.Input + ? ProcessBuilder.Redirect.INHERIT + : newDescriptor(stream == SystemStream.Output ? FileDescriptor.out : FileDescriptor.err); + Process p = + new ProcessBuilder(OSUtils.TTY_COMMAND).redirectInput(input).start(); String result = ExecHelper.waitAndCapture(p); if (p.exitValue() == 0) { return result.trim(); } } catch (Throwable t) { + if ("java.lang.reflect.InaccessibleObjectException" + .equals(t.getClass().getName()) + && !warned) { + Log.warn( + "The ExecTerminalProvider requires the JVM options: '--add-opens java.base/java.lang=ALL-UNNAMED'"); + warned = true; + } // ignore } return null; } - private ProcessBuilder.Redirect getRedirect(FileDescriptor fd) throws ReflectiveOperationException { - // This is not really allowed, but this is the only way to redirect the output or error stream - // to the input. This is definitely not something you'd usually want to do, but in the case of - // the `tty` utility, it provides a way to get - Class rpi = Class.forName("java.lang.ProcessBuilder$RedirectPipeImpl"); - Constructor cns = rpi.getDeclaredConstructor(); - cns.setAccessible(true); - ProcessBuilder.Redirect input = (ProcessBuilder.Redirect) cns.newInstance(); - Field f = rpi.getDeclaredField("fd"); - f.setAccessible(true); - f.set(input, fd); - return input; + @Override + public int systemStreamWidth(SystemStream stream) { + try (ExecPty pty = new ExecPty(this, stream, null)) { + return pty.getSize().getColumns(); + } catch (Throwable t) { + return -1; + } + } + + private static RedirectPipeCreator redirectPipeCreator; + + protected static ProcessBuilder.Redirect newDescriptor(FileDescriptor fd) { + if (redirectPipeCreator == null) { + String str = System.getProperty(PROP_REDIRECT_PIPE_CREATION_MODE, PROP_REDIRECT_PIPE_CREATION_MODE_DEFAULT); + String[] modes = str.split(","); + IllegalStateException ise = new IllegalStateException("Unable to create RedirectPipe"); + for (String mode : modes) { + try { + switch (mode) { + case PROP_REDIRECT_PIPE_CREATION_MODE_NATIVE: + redirectPipeCreator = null;//new NativeRedirectPipeCreator(); + break; + case PROP_REDIRECT_PIPE_CREATION_MODE_REFLECTION: + redirectPipeCreator = new ReflectionRedirectPipeCreator(); + break; + } + } catch (Throwable t) { + // ignore + ise.addSuppressed(t); + } + if (redirectPipeCreator != null) { + break; + } + } + if (redirectPipeCreator == null) { + throw ise; + } + } + return redirectPipeCreator.newRedirectPipe(fd); + } + + interface RedirectPipeCreator { + ProcessBuilder.Redirect newRedirectPipe(FileDescriptor fd); + } + + /** + * Reflection based file descriptor creator. + * This requires the following option + * --add-opens java.base/java.lang=ALL-UNNAMED + */ + static class ReflectionRedirectPipeCreator implements RedirectPipeCreator { + private final Constructor constructor; + private final Field fdField; + + @SuppressWarnings("unchecked") + ReflectionRedirectPipeCreator() throws Exception { + Class rpi = Class.forName("java.lang.ProcessBuilder$RedirectPipeImpl"); + constructor = (Constructor) rpi.getDeclaredConstructor(); + constructor.setAccessible(true); + fdField = rpi.getDeclaredField("fd"); + fdField.setAccessible(true); + } + + @Override + public ProcessBuilder.Redirect newRedirectPipe(FileDescriptor fd) { + try { + ProcessBuilder.Redirect input = constructor.newInstance(); + fdField.set(input, fd); + return input; + } catch (ReflectiveOperationException e) { + // This should not happen as the field has been set accessible + throw new IllegalStateException(e); + } + } + } + +// static class NativeRedirectPipeCreator implements RedirectPipeCreator { +// public NativeRedirectPipeCreator() { +// // Force load the library +// JLineNativeLoader.initialize(); +// } +// +// @Override +// public ProcessBuilder.Redirect newRedirectPipe(FileDescriptor fd) { +// return JLineLibrary.newRedirectPipe(fd); +// } +// } + + @Override + public String toString() { + return "TerminalProvider[" + name() + "]"; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/CLibrary.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/CLibrary.java new file mode 100644 index 00000000000..453ce290d3c --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/CLibrary.java @@ -0,0 +1,1170 @@ +/* + * Copyright (c) 2022-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.foreign.*; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; +import java.util.Optional; +//import java.util.logging.Level; +//import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.OSUtils; + +@SuppressWarnings("restricted") +class CLibrary { + +// private static final Logger logger = Logger.getLogger("org.jline"); + + // Window sizes. + // @see IOCTL_TTY(2) man-page + static class winsize { + static final GroupLayout LAYOUT; + private static final VarHandle ws_col; + private static final VarHandle ws_row; + + static { + LAYOUT = MemoryLayout.structLayout( + ValueLayout.JAVA_SHORT.withName("ws_row"), + ValueLayout.JAVA_SHORT.withName("ws_col"), + ValueLayout.JAVA_SHORT, + ValueLayout.JAVA_SHORT); + ws_row = FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("ws_row")); + ws_col = FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("ws_col")); + } + + private final java.lang.foreign.MemorySegment seg; + + winsize() { + seg = java.lang.foreign.Arena.ofAuto().allocate(LAYOUT); + } + + winsize(short ws_col, short ws_row) { + this(); + ws_col(ws_col); + ws_row(ws_row); + } + + java.lang.foreign.MemorySegment segment() { + return seg; + } + + short ws_col() { + return (short) ws_col.get(seg); + } + + void ws_col(short col) { + ws_col.set(seg, col); + } + + short ws_row() { + return (short) ws_row.get(seg); + } + + void ws_row(short row) { + ws_row.set(seg, row); + } + } + + // termios structure for termios functions, describing a general terminal interface that is + // provided to control asynchronous communications ports + // @see TERMIOS(3) man-page + static class termios { + static final GroupLayout LAYOUT; + private static final VarHandle c_iflag; + private static final VarHandle c_oflag; + private static final VarHandle c_cflag; + private static final VarHandle c_lflag; + private static final long c_cc_offset; + private static final VarHandle c_ispeed; + private static final VarHandle c_ospeed; + + static { + if (OSUtils.IS_OSX) { + LAYOUT = MemoryLayout.structLayout( + ValueLayout.JAVA_LONG.withName("c_iflag"), + ValueLayout.JAVA_LONG.withName("c_oflag"), + ValueLayout.JAVA_LONG.withName("c_cflag"), + ValueLayout.JAVA_LONG.withName("c_lflag"), + MemoryLayout.sequenceLayout(32, ValueLayout.JAVA_BYTE).withName("c_cc"), + ValueLayout.JAVA_LONG.withName("c_ispeed"), + ValueLayout.JAVA_LONG.withName("c_ospeed")); + } else if (OSUtils.IS_LINUX) { + LAYOUT = MemoryLayout.structLayout( + ValueLayout.JAVA_INT.withName("c_iflag"), + ValueLayout.JAVA_INT.withName("c_oflag"), + ValueLayout.JAVA_INT.withName("c_cflag"), + ValueLayout.JAVA_INT.withName("c_lflag"), + ValueLayout.JAVA_BYTE.withName("c_line"), + MemoryLayout.sequenceLayout(32, ValueLayout.JAVA_BYTE).withName("c_cc"), + MemoryLayout.paddingLayout(3), + ValueLayout.JAVA_INT.withName("c_ispeed"), + ValueLayout.JAVA_INT.withName("c_ospeed")); + } else { + throw new IllegalStateException("Unsupported system!"); + } + c_iflag = adjust2LinuxHandle( + FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("c_iflag"))); + c_oflag = adjust2LinuxHandle( + FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("c_oflag"))); + c_cflag = adjust2LinuxHandle( + FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("c_cflag"))); + c_lflag = adjust2LinuxHandle( + FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("c_lflag"))); + c_cc_offset = LAYOUT.byteOffset(MemoryLayout.PathElement.groupElement("c_cc")); + c_ispeed = adjust2LinuxHandle( + FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("c_ispeed"))); + c_ospeed = adjust2LinuxHandle( + FfmTerminalProvider.lookupVarHandle(LAYOUT, MemoryLayout.PathElement.groupElement("c_ospeed"))); + } + + private static VarHandle adjust2LinuxHandle(VarHandle v) { + if (OSUtils.IS_LINUX) { + MethodHandle id = MethodHandles.identity(int.class); + v = MethodHandles.filterValue( + v, + MethodHandles.explicitCastArguments(id, MethodType.methodType(int.class, long.class)), + MethodHandles.explicitCastArguments(id, MethodType.methodType(long.class, int.class))); + } + + return v; + } + + private final java.lang.foreign.MemorySegment seg; + + termios() { + seg = java.lang.foreign.Arena.ofAuto().allocate(LAYOUT); + } + + termios(Attributes t) { + this(); + // Input flags + long c_iflag = 0; + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IGNBRK), IGNBRK, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.BRKINT), BRKINT, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IGNPAR), IGNPAR, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.PARMRK), PARMRK, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.INPCK), INPCK, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.ISTRIP), ISTRIP, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.INLCR), INLCR, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IGNCR), IGNCR, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.ICRNL), ICRNL, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IXON), IXON, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IXOFF), IXOFF, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IXANY), IXANY, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IMAXBEL), IMAXBEL, c_iflag); + c_iflag = setFlag(t.getInputFlag(Attributes.InputFlag.IUTF8), IUTF8, c_iflag); + c_iflag(c_iflag); + // Output flags + long c_oflag = 0; + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.OPOST), OPOST, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.ONLCR), ONLCR, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.OXTABS), OXTABS, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.ONOEOT), ONOEOT, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.OCRNL), OCRNL, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.ONOCR), ONOCR, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.ONLRET), ONLRET, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.OFILL), OFILL, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.NLDLY), NLDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.TABDLY), TABDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.CRDLY), CRDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.FFDLY), FFDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.BSDLY), BSDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.VTDLY), VTDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(Attributes.OutputFlag.OFDEL), OFDEL, c_oflag); + c_oflag(c_oflag); + // Control flags + long c_cflag = 0; + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CIGNORE), CIGNORE, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CS5), CS5, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CS6), CS6, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CS7), CS7, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CS8), CS8, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CSTOPB), CSTOPB, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CREAD), CREAD, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.PARENB), PARENB, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.PARODD), PARODD, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.HUPCL), HUPCL, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CLOCAL), CLOCAL, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CCTS_OFLOW), CCTS_OFLOW, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CRTS_IFLOW), CRTS_IFLOW, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CDTR_IFLOW), CDTR_IFLOW, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CDSR_OFLOW), CDSR_OFLOW, c_cflag); + c_cflag = setFlag(t.getControlFlag(Attributes.ControlFlag.CCAR_OFLOW), CCAR_OFLOW, c_cflag); + c_cflag(c_cflag); + // Local flags + long c_lflag = 0; + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHOKE), ECHOKE, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHOE), ECHOE, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHOK), ECHOK, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHO), ECHO, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHONL), ECHONL, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHOPRT), ECHOPRT, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ECHOCTL), ECHOCTL, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ISIG), ISIG, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ICANON), ICANON, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.ALTWERASE), ALTWERASE, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.IEXTEN), IEXTEN, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.EXTPROC), EXTPROC, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.TOSTOP), TOSTOP, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.FLUSHO), FLUSHO, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.NOKERNINFO), NOKERNINFO, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.PENDIN), PENDIN, c_lflag); + c_lflag = setFlag(t.getLocalFlag(Attributes.LocalFlag.NOFLSH), NOFLSH, c_lflag); + c_lflag(c_lflag); + // Control chars + byte[] c_cc = new byte[20]; + c_cc[VEOF] = (byte) t.getControlChar(Attributes.ControlChar.VEOF); + c_cc[VEOL] = (byte) t.getControlChar(Attributes.ControlChar.VEOL); + c_cc[VEOL2] = (byte) t.getControlChar(Attributes.ControlChar.VEOL2); + c_cc[VERASE] = (byte) t.getControlChar(Attributes.ControlChar.VERASE); + c_cc[VWERASE] = (byte) t.getControlChar(Attributes.ControlChar.VWERASE); + c_cc[VKILL] = (byte) t.getControlChar(Attributes.ControlChar.VKILL); + c_cc[VREPRINT] = (byte) t.getControlChar(Attributes.ControlChar.VREPRINT); + c_cc[VINTR] = (byte) t.getControlChar(Attributes.ControlChar.VINTR); + c_cc[VQUIT] = (byte) t.getControlChar(Attributes.ControlChar.VQUIT); + c_cc[VSUSP] = (byte) t.getControlChar(Attributes.ControlChar.VSUSP); + if (VDSUSP != (-1)) { + c_cc[VDSUSP] = (byte) t.getControlChar(Attributes.ControlChar.VDSUSP); + } + c_cc[VSTART] = (byte) t.getControlChar(Attributes.ControlChar.VSTART); + c_cc[VSTOP] = (byte) t.getControlChar(Attributes.ControlChar.VSTOP); + c_cc[VLNEXT] = (byte) t.getControlChar(Attributes.ControlChar.VLNEXT); + c_cc[VDISCARD] = (byte) t.getControlChar(Attributes.ControlChar.VDISCARD); + c_cc[VMIN] = (byte) t.getControlChar(Attributes.ControlChar.VMIN); + c_cc[VTIME] = (byte) t.getControlChar(Attributes.ControlChar.VTIME); + if (VSTATUS != (-1)) { + c_cc[VSTATUS] = (byte) t.getControlChar(Attributes.ControlChar.VSTATUS); + } + c_cc().copyFrom(java.lang.foreign.MemorySegment.ofArray(c_cc)); + } + + java.lang.foreign.MemorySegment segment() { + return seg; + } + + long c_iflag() { + return (long) c_iflag.get(seg); + } + + void c_iflag(long f) { + c_iflag.set(seg, f); + } + + long c_oflag() { + return (long) c_oflag.get(seg); + } + + void c_oflag(long f) { + c_oflag.set(seg, f); + } + + long c_cflag() { + return (long) c_cflag.get(seg); + } + + void c_cflag(long f) { + c_cflag.set(seg, f); + } + + long c_lflag() { + return (long) c_lflag.get(seg); + } + + void c_lflag(long f) { + c_lflag.set(seg, f); + } + + java.lang.foreign.MemorySegment c_cc() { + return seg.asSlice(c_cc_offset, 20); + } + + long c_ispeed() { + return (long) c_ispeed.get(seg); + } + + void c_ispeed(long f) { + c_ispeed.set(seg, f); + } + + long c_ospeed() { + return (long) c_ospeed.get(seg); + } + + void c_ospeed(long f) { + c_ospeed.set(seg, f); + } + + private static long setFlag(boolean flag, long value, long org) { + return flag ? org | value : org; + } + + private static > void addFlag(long value, EnumSet flags, T flag, int v) { + if ((value & v) != 0) { + flags.add(flag); + } + } + + public Attributes asAttributes() { + Attributes attr = new Attributes(); + // Input flags + long c_iflag = c_iflag(); + EnumSet iflag = attr.getInputFlags(); + addFlag(c_iflag, iflag, Attributes.InputFlag.IGNBRK, IGNBRK); + addFlag(c_iflag, iflag, Attributes.InputFlag.IGNBRK, IGNBRK); + addFlag(c_iflag, iflag, Attributes.InputFlag.BRKINT, BRKINT); + addFlag(c_iflag, iflag, Attributes.InputFlag.IGNPAR, IGNPAR); + addFlag(c_iflag, iflag, Attributes.InputFlag.PARMRK, PARMRK); + addFlag(c_iflag, iflag, Attributes.InputFlag.INPCK, INPCK); + addFlag(c_iflag, iflag, Attributes.InputFlag.ISTRIP, ISTRIP); + addFlag(c_iflag, iflag, Attributes.InputFlag.INLCR, INLCR); + addFlag(c_iflag, iflag, Attributes.InputFlag.IGNCR, IGNCR); + addFlag(c_iflag, iflag, Attributes.InputFlag.ICRNL, ICRNL); + addFlag(c_iflag, iflag, Attributes.InputFlag.IXON, IXON); + addFlag(c_iflag, iflag, Attributes.InputFlag.IXOFF, IXOFF); + addFlag(c_iflag, iflag, Attributes.InputFlag.IXANY, IXANY); + addFlag(c_iflag, iflag, Attributes.InputFlag.IMAXBEL, IMAXBEL); + addFlag(c_iflag, iflag, Attributes.InputFlag.IUTF8, IUTF8); + // Output flags + long c_oflag = c_oflag(); + EnumSet oflag = attr.getOutputFlags(); + addFlag(c_oflag, oflag, Attributes.OutputFlag.OPOST, OPOST); + addFlag(c_oflag, oflag, Attributes.OutputFlag.ONLCR, ONLCR); + addFlag(c_oflag, oflag, Attributes.OutputFlag.OXTABS, OXTABS); + addFlag(c_oflag, oflag, Attributes.OutputFlag.ONOEOT, ONOEOT); + addFlag(c_oflag, oflag, Attributes.OutputFlag.OCRNL, OCRNL); + addFlag(c_oflag, oflag, Attributes.OutputFlag.ONOCR, ONOCR); + addFlag(c_oflag, oflag, Attributes.OutputFlag.ONLRET, ONLRET); + addFlag(c_oflag, oflag, Attributes.OutputFlag.OFILL, OFILL); + addFlag(c_oflag, oflag, Attributes.OutputFlag.NLDLY, NLDLY); + addFlag(c_oflag, oflag, Attributes.OutputFlag.TABDLY, TABDLY); + addFlag(c_oflag, oflag, Attributes.OutputFlag.CRDLY, CRDLY); + addFlag(c_oflag, oflag, Attributes.OutputFlag.FFDLY, FFDLY); + addFlag(c_oflag, oflag, Attributes.OutputFlag.BSDLY, BSDLY); + addFlag(c_oflag, oflag, Attributes.OutputFlag.VTDLY, VTDLY); + addFlag(c_oflag, oflag, Attributes.OutputFlag.OFDEL, OFDEL); + // Control flags + long c_cflag = c_cflag(); + EnumSet cflag = attr.getControlFlags(); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CIGNORE, CIGNORE); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CS5, CS5); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CS6, CS6); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CS7, CS7); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CS8, CS8); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CSTOPB, CSTOPB); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CREAD, CREAD); + addFlag(c_cflag, cflag, Attributes.ControlFlag.PARENB, PARENB); + addFlag(c_cflag, cflag, Attributes.ControlFlag.PARODD, PARODD); + addFlag(c_cflag, cflag, Attributes.ControlFlag.HUPCL, HUPCL); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CLOCAL, CLOCAL); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CCTS_OFLOW, CCTS_OFLOW); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CRTS_IFLOW, CRTS_IFLOW); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CDSR_OFLOW, CDSR_OFLOW); + addFlag(c_cflag, cflag, Attributes.ControlFlag.CCAR_OFLOW, CCAR_OFLOW); + // Local flags + long c_lflag = c_lflag(); + EnumSet lflag = attr.getLocalFlags(); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHOKE, ECHOKE); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHOE, ECHOE); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHOK, ECHOK); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHO, ECHO); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHONL, ECHONL); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHOPRT, ECHOPRT); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ECHOCTL, ECHOCTL); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ISIG, ISIG); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ICANON, ICANON); + addFlag(c_lflag, lflag, Attributes.LocalFlag.ALTWERASE, ALTWERASE); + addFlag(c_lflag, lflag, Attributes.LocalFlag.IEXTEN, IEXTEN); + addFlag(c_lflag, lflag, Attributes.LocalFlag.EXTPROC, EXTPROC); + addFlag(c_lflag, lflag, Attributes.LocalFlag.TOSTOP, TOSTOP); + addFlag(c_lflag, lflag, Attributes.LocalFlag.FLUSHO, FLUSHO); + addFlag(c_lflag, lflag, Attributes.LocalFlag.NOKERNINFO, NOKERNINFO); + addFlag(c_lflag, lflag, Attributes.LocalFlag.PENDIN, PENDIN); + addFlag(c_lflag, lflag, Attributes.LocalFlag.NOFLSH, NOFLSH); + // Control chars + byte[] c_cc = c_cc().toArray(ValueLayout.JAVA_BYTE); + EnumMap cc = attr.getControlChars(); + cc.put(Attributes.ControlChar.VEOF, (int) c_cc[VEOF]); + cc.put(Attributes.ControlChar.VEOL, (int) c_cc[VEOL]); + cc.put(Attributes.ControlChar.VEOL2, (int) c_cc[VEOL2]); + cc.put(Attributes.ControlChar.VERASE, (int) c_cc[VERASE]); + cc.put(Attributes.ControlChar.VWERASE, (int) c_cc[VWERASE]); + cc.put(Attributes.ControlChar.VKILL, (int) c_cc[VKILL]); + cc.put(Attributes.ControlChar.VREPRINT, (int) c_cc[VREPRINT]); + cc.put(Attributes.ControlChar.VINTR, (int) c_cc[VINTR]); + cc.put(Attributes.ControlChar.VQUIT, (int) c_cc[VQUIT]); + cc.put(Attributes.ControlChar.VSUSP, (int) c_cc[VSUSP]); + if (VDSUSP != (-1)) { + cc.put(Attributes.ControlChar.VDSUSP, (int) c_cc[VDSUSP]); + } + cc.put(Attributes.ControlChar.VSTART, (int) c_cc[VSTART]); + cc.put(Attributes.ControlChar.VSTOP, (int) c_cc[VSTOP]); + cc.put(Attributes.ControlChar.VLNEXT, (int) c_cc[VLNEXT]); + cc.put(Attributes.ControlChar.VDISCARD, (int) c_cc[VDISCARD]); + cc.put(Attributes.ControlChar.VMIN, (int) c_cc[VMIN]); + cc.put(Attributes.ControlChar.VTIME, (int) c_cc[VTIME]); + if (VSTATUS != (-1)) { + cc.put(Attributes.ControlChar.VSTATUS, (int) c_cc[VSTATUS]); + } + // Return + return attr; + } + } + + static MethodHandle ioctl; + static MethodHandle isatty; + static MethodHandle openpty; + static MethodHandle tcsetattr; + static MethodHandle tcgetattr; + static MethodHandle ttyname_r; + static LinkageError openptyError; + + static { + // methods + Linker linker = Linker.nativeLinker(); + SymbolLookup lookup = SymbolLookup.loaderLookup().or(linker.defaultLookup()); + // https://man7.org/linux/man-pages/man2/ioctl.2.html + ioctl = linker.downcallHandle( + lookup.find("ioctl").get(), + FunctionDescriptor.of( + ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.JAVA_LONG, ValueLayout.ADDRESS), + Linker.Option.firstVariadicArg(2)); + // https://www.man7.org/linux/man-pages/man3/isatty.3.html + isatty = linker.downcallHandle( + lookup.find("isatty").get(), FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT)); + // https://man7.org/linux/man-pages/man3/tcsetattr.3p.html + tcsetattr = linker.downcallHandle( + lookup.find("tcsetattr").get(), + FunctionDescriptor.of( + ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS)); + // https://man7.org/linux/man-pages/man3/tcgetattr.3p.html + tcgetattr = linker.downcallHandle( + lookup.find("tcgetattr").get(), + FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS)); + // https://man7.org/linux/man-pages/man3/ttyname.3.html + ttyname_r = linker.downcallHandle( + lookup.find("ttyname_r").get(), + FunctionDescriptor.of( + ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_LONG)); + // https://man7.org/linux/man-pages/man3/openpty.3.html + LinkageError error = null; + Optional openPtyAddr = lookup.find("openpty"); + if (openPtyAddr.isPresent()) { + openpty = linker.downcallHandle( + openPtyAddr.get(), + FunctionDescriptor.of( + ValueLayout.JAVA_INT, + ValueLayout.ADDRESS, + ValueLayout.ADDRESS, + ValueLayout.ADDRESS, + ValueLayout.ADDRESS, + ValueLayout.ADDRESS)); + openptyError = null; + } else { + openpty = null; + openptyError = error; + } + } + + private static String readFully(InputStream in) throws IOException { + int readLen = 0; + ByteArrayOutputStream b = new ByteArrayOutputStream(); + byte[] buf = new byte[32]; + while ((readLen = in.read(buf, 0, buf.length)) >= 0) { + b.write(buf, 0, readLen); + } + return b.toString(); + } + + static Size getTerminalSize(int fd) { + try { + winsize ws = new winsize(); + int res = (int) ioctl.invoke(fd, (long) TIOCGWINSZ, ws.segment()); + return new Size(ws.ws_col(), ws.ws_row()); + } catch (Throwable e) { + throw new RuntimeException("Unable to call ioctl(TIOCGWINSZ)", e); + } + } + + static void setTerminalSize(int fd, Size size) { + try { + winsize ws = new winsize(); + ws.ws_row((short) size.getRows()); + ws.ws_col((short) size.getColumns()); + int res = (int) ioctl.invoke(fd, TIOCSWINSZ, ws.segment()); + } catch (Throwable e) { + throw new RuntimeException("Unable to call ioctl(TIOCSWINSZ)", e); + } + } + + static Attributes getAttributes(int fd) { + try { + termios t = new termios(); + int res = (int) tcgetattr.invoke(fd, t.segment()); + return t.asAttributes(); + } catch (Throwable e) { + throw new RuntimeException("Unable to call tcgetattr()", e); + } + } + + static void setAttributes(int fd, Attributes attr) { + try { + termios t = new termios(attr); + int res = (int) tcsetattr.invoke(fd, TCSANOW, t.segment()); + } catch (Throwable e) { + throw new RuntimeException("Unable to call tcsetattr()", e); + } + } + + static boolean isTty(int fd) { + try { + return (int) isatty.invoke(fd) == 1; + } catch (Throwable e) { + throw new RuntimeException("Unable to call isatty()", e); + } + } + + static String ttyName(int fd) { + try { + java.lang.foreign.MemorySegment buf = + java.lang.foreign.Arena.ofAuto().allocate(64); + int res = (int) ttyname_r.invoke(fd, buf, buf.byteSize()); + byte[] data = buf.toArray(ValueLayout.JAVA_BYTE); + int len = 0; + while (data[len] != 0) { + len++; + } + return new String(data, 0, len); + } catch (Throwable e) { + throw new RuntimeException("Unable to call ttyname_r()", e); + } + } + + static Pty openpty(TerminalProvider provider, Attributes attr, Size size) { + if (openptyError != null) { + throw openptyError; + } + try { + java.lang.foreign.MemorySegment buf = + java.lang.foreign.Arena.ofAuto().allocate(64); + java.lang.foreign.MemorySegment master = + java.lang.foreign.Arena.ofAuto().allocate(ValueLayout.JAVA_INT); + java.lang.foreign.MemorySegment slave = + java.lang.foreign.Arena.ofAuto().allocate(ValueLayout.JAVA_INT); + int res = (int) openpty.invoke( + master, + slave, + buf, + attr != null ? new termios(attr).segment() : java.lang.foreign.MemorySegment.NULL, + size != null + ? new winsize((short) size.getRows(), (short) size.getColumns()).segment() + : java.lang.foreign.MemorySegment.NULL); + byte[] str = buf.toArray(ValueLayout.JAVA_BYTE); + int len = 0; + while (str[len] != 0) { + len++; + } + String device = new String(str, 0, len); + return new FfmNativePty( + provider, null, master.get(ValueLayout.JAVA_INT, 0), slave.get(ValueLayout.JAVA_INT, 0), device); + } catch (Throwable e) { + throw new RuntimeException("Unable to call openpty()", e); + } + } + + // CONSTANTS + + private static final int TIOCGWINSZ; + private static final int TIOCSWINSZ; + + private static final int TCSANOW; + private static int TCSADRAIN; + private static int TCSAFLUSH; + + private static final int VEOF; + private static final int VEOL; + private static final int VEOL2; + private static final int VERASE; + private static final int VWERASE; + private static final int VKILL; + private static final int VREPRINT; + private static final int VERASE2; + private static final int VINTR; + private static final int VQUIT; + private static final int VSUSP; + private static final int VDSUSP; + private static final int VSTART; + private static final int VSTOP; + private static final int VLNEXT; + private static final int VDISCARD; + private static final int VMIN; + private static final int VSWTC; + private static final int VTIME; + private static final int VSTATUS; + + private static final int IGNBRK; + private static final int BRKINT; + private static final int IGNPAR; + private static final int PARMRK; + private static final int INPCK; + private static final int ISTRIP; + private static final int INLCR; + private static final int IGNCR; + private static final int ICRNL; + private static int IUCLC; + private static final int IXON; + private static final int IXOFF; + private static final int IXANY; + private static final int IMAXBEL; + private static int IUTF8; + + private static final int OPOST; + private static int OLCUC; + private static final int ONLCR; + private static int OXTABS; + private static int NLDLY; + private static int NL0; + private static int NL1; + private static final int TABDLY; + private static int TAB0; + private static int TAB1; + private static int TAB2; + private static int TAB3; + private static int CRDLY; + private static int CR0; + private static int CR1; + private static int CR2; + private static int CR3; + private static int FFDLY; + private static int FF0; + private static int FF1; + private static int XTABS; + private static int BSDLY; + private static int BS0; + private static int BS1; + private static int VTDLY; + private static int VT0; + private static int VT1; + private static int CBAUD; + private static int B0; + private static int B50; + private static int B75; + private static int B110; + private static int B134; + private static int B150; + private static int B200; + private static int B300; + private static int B600; + private static int B1200; + private static int B1800; + private static int B2400; + private static int B4800; + private static int B9600; + private static int B19200; + private static int B38400; + private static int EXTA; + private static int EXTB; + private static int OFDEL; + private static int ONOEOT; + private static final int OCRNL; + private static int ONOCR; + private static final int ONLRET; + private static int OFILL; + + private static int CIGNORE; + private static int CSIZE; + private static final int CS5; + private static final int CS6; + private static final int CS7; + private static final int CS8; + private static final int CSTOPB; + private static final int CREAD; + private static final int PARENB; + private static final int PARODD; + private static final int HUPCL; + private static final int CLOCAL; + private static int CCTS_OFLOW; + private static int CRTS_IFLOW; + private static int CDTR_IFLOW; + private static int CDSR_OFLOW; + private static int CCAR_OFLOW; + + private static final int ECHOKE; + private static final int ECHOE; + private static final int ECHOK; + private static final int ECHO; + private static final int ECHONL; + private static final int ECHOPRT; + private static final int ECHOCTL; + private static final int ISIG; + private static final int ICANON; + private static int XCASE; + private static int ALTWERASE; + private static final int IEXTEN; + private static final int EXTPROC; + private static final int TOSTOP; + private static final int FLUSHO; + private static int NOKERNINFO; + private static final int PENDIN; + private static final int NOFLSH; + + static { + String osName = System.getProperty("os.name"); + if (osName.startsWith("Linux")) { + String arch = System.getProperty("os.arch"); + boolean isMipsPpcOrSparc = arch.equals("mips") + || arch.equals("mips64") + || arch.equals("mipsel") + || arch.equals("mips64el") + || arch.startsWith("ppc") + || arch.startsWith("sparc"); + TIOCGWINSZ = isMipsPpcOrSparc ? 0x40087468 : 0x00005413; + TIOCSWINSZ = isMipsPpcOrSparc ? 0x80087467 : 0x00005414; + + TCSANOW = 0x0; + TCSADRAIN = 0x1; + TCSAFLUSH = 0x2; + + VINTR = 0; + VQUIT = 1; + VERASE = 2; + VKILL = 3; + VEOF = 4; + VTIME = 5; + VMIN = 6; + VSWTC = 7; + VSTART = 8; + VSTOP = 9; + VSUSP = 10; + VEOL = 11; + VREPRINT = 12; + VDISCARD = 13; + VWERASE = 14; + VLNEXT = 15; + VEOL2 = 16; + VERASE2 = -1; + VDSUSP = -1; + VSTATUS = -1; + + IGNBRK = 0x0000001; + BRKINT = 0x0000002; + IGNPAR = 0x0000004; + PARMRK = 0x0000008; + INPCK = 0x0000010; + ISTRIP = 0x0000020; + INLCR = 0x0000040; + IGNCR = 0x0000080; + ICRNL = 0x0000100; + IUCLC = 0x0000200; + IXON = 0x0000400; + IXANY = 0x0000800; + IXOFF = 0x0001000; + IMAXBEL = 0x0002000; + IUTF8 = 0x0004000; + + OPOST = 0x0000001; + OLCUC = 0x0000002; + ONLCR = 0x0000004; + OCRNL = 0x0000008; + ONOCR = 0x0000010; + ONLRET = 0x0000020; + OFILL = 0x0000040; + OFDEL = 0x0000080; + NLDLY = 0x0000100; + NL0 = 0x0000000; + NL1 = 0x0000100; + CRDLY = 0x0000600; + CR0 = 0x0000000; + CR1 = 0x0000200; + CR2 = 0x0000400; + CR3 = 0x0000600; + TABDLY = 0x0001800; + TAB0 = 0x0000000; + TAB1 = 0x0000800; + TAB2 = 0x0001000; + TAB3 = 0x0001800; + XTABS = 0x0001800; + BSDLY = 0x0002000; + BS0 = 0x0000000; + BS1 = 0x0002000; + VTDLY = 0x0004000; + VT0 = 0x0000000; + VT1 = 0x0004000; + FFDLY = 0x0008000; + FF0 = 0x0000000; + FF1 = 0x0008000; + + CBAUD = 0x000100f; + B0 = 0x0000000; + B50 = 0x0000001; + B75 = 0x0000002; + B110 = 0x0000003; + B134 = 0x0000004; + B150 = 0x0000005; + B200 = 0x0000006; + B300 = 0x0000007; + B600 = 0x0000008; + B1200 = 0x0000009; + B1800 = 0x000000a; + B2400 = 0x000000b; + B4800 = 0x000000c; + B9600 = 0x000000d; + B19200 = 0x000000e; + B38400 = 0x000000f; + EXTA = B19200; + EXTB = B38400; + CSIZE = 0x0000030; + CS5 = 0x0000000; + CS6 = 0x0000010; + CS7 = 0x0000020; + CS8 = 0x0000030; + CSTOPB = 0x0000040; + CREAD = 0x0000080; + PARENB = 0x0000100; + PARODD = 0x0000200; + HUPCL = 0x0000400; + CLOCAL = 0x0000800; + + ISIG = 0x0000001; + ICANON = 0x0000002; + XCASE = 0x0000004; + ECHO = 0x0000008; + ECHOE = 0x0000010; + ECHOK = 0x0000020; + ECHONL = 0x0000040; + NOFLSH = 0x0000080; + TOSTOP = 0x0000100; + ECHOCTL = 0x0000200; + ECHOPRT = 0x0000400; + ECHOKE = 0x0000800; + FLUSHO = 0x0001000; + PENDIN = 0x0002000; + IEXTEN = 0x0008000; + EXTPROC = 0x0010000; + } else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) { + int _TIOC = ('T' << 8); + TIOCGWINSZ = (_TIOC | 104); + TIOCSWINSZ = (_TIOC | 103); + + TCSANOW = 0x0; + TCSADRAIN = 0x1; + TCSAFLUSH = 0x2; + + VINTR = 0; + VQUIT = 1; + VERASE = 2; + VKILL = 3; + VEOF = 4; + VTIME = 5; + VMIN = 6; + VSWTC = 7; + VSTART = 8; + VSTOP = 9; + VSUSP = 10; + VEOL = 11; + VREPRINT = 12; + VDISCARD = 13; + VWERASE = 14; + VLNEXT = 15; + VEOL2 = 16; + VERASE2 = -1; + VDSUSP = -1; + VSTATUS = -1; + + IGNBRK = 0x0000001; + BRKINT = 0x0000002; + IGNPAR = 0x0000004; + PARMRK = 0x0000010; + INPCK = 0x0000020; + ISTRIP = 0x0000040; + INLCR = 0x0000100; + IGNCR = 0x0000200; + ICRNL = 0x0000400; + IUCLC = 0x0001000; + IXON = 0x0002000; + IXANY = 0x0004000; + IXOFF = 0x0010000; + IMAXBEL = 0x0020000; + IUTF8 = 0x0040000; + + OPOST = 0x0000001; + OLCUC = 0x0000002; + ONLCR = 0x0000004; + OCRNL = 0x0000010; + ONOCR = 0x0000020; + ONLRET = 0x0000040; + OFILL = 0x0000100; + OFDEL = 0x0000200; + NLDLY = 0x0000400; + NL0 = 0x0000000; + NL1 = 0x0000400; + CRDLY = 0x0003000; + CR0 = 0x0000000; + CR1 = 0x0001000; + CR2 = 0x0002000; + CR3 = 0x0003000; + TABDLY = 0x0014000; + TAB0 = 0x0000000; + TAB1 = 0x0004000; + TAB2 = 0x0010000; + TAB3 = 0x0014000; + XTABS = 0x0014000; + BSDLY = 0x0020000; + BS0 = 0x0000000; + BS1 = 0x0020000; + VTDLY = 0x0040000; + VT0 = 0x0000000; + VT1 = 0x0040000; + FFDLY = 0x0100000; + FF0 = 0x0000000; + FF1 = 0x0100000; + + CBAUD = 0x0010017; + B0 = 0x0000000; + B50 = 0x0000001; + B75 = 0x0000002; + B110 = 0x0000003; + B134 = 0x0000004; + B150 = 0x0000005; + B200 = 0x0000006; + B300 = 0x0000007; + B600 = 0x0000010; + B1200 = 0x0000011; + B1800 = 0x0000012; + B2400 = 0x0000013; + B4800 = 0x0000014; + B9600 = 0x0000015; + B19200 = 0x0000016; + B38400 = 0x0000017; + EXTA = 0xB19200; + EXTB = 0xB38400; + CSIZE = 0x0000060; + CS5 = 0x0000000; + CS6 = 0x0000020; + CS7 = 0x0000040; + CS8 = 0x0000060; + CSTOPB = 0x0000100; + CREAD = 0x0000200; + PARENB = 0x0000400; + PARODD = 0x0001000; + HUPCL = 0x0002000; + CLOCAL = 0x0004000; + + ISIG = 0x0000001; + ICANON = 0x0000002; + XCASE = 0x0000004; + ECHO = 0x0000010; + ECHOE = 0x0000020; + ECHOK = 0x0000040; + ECHONL = 0x0000100; + NOFLSH = 0x0000200; + TOSTOP = 0x0000400; + ECHOCTL = 0x0001000; + ECHOPRT = 0x0002000; + ECHOKE = 0x0004000; + FLUSHO = 0x0010000; + PENDIN = 0x0040000; + IEXTEN = 0x0100000; + EXTPROC = 0x0200000; + } else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) { + TIOCGWINSZ = 0x40087468; + TIOCSWINSZ = 0x80087467; + + TCSANOW = 0x00000000; + + VEOF = 0; + VEOL = 1; + VEOL2 = 2; + VERASE = 3; + VWERASE = 4; + VKILL = 5; + VREPRINT = 6; + VINTR = 8; + VQUIT = 9; + VSUSP = 10; + VDSUSP = 11; + VSTART = 12; + VSTOP = 13; + VLNEXT = 14; + VDISCARD = 15; + VMIN = 16; + VTIME = 17; + VSTATUS = 18; + VERASE2 = -1; + VSWTC = -1; + + IGNBRK = 0x00000001; + BRKINT = 0x00000002; + IGNPAR = 0x00000004; + PARMRK = 0x00000008; + INPCK = 0x00000010; + ISTRIP = 0x00000020; + INLCR = 0x00000040; + IGNCR = 0x00000080; + ICRNL = 0x00000100; + IXON = 0x00000200; + IXOFF = 0x00000400; + IXANY = 0x00000800; + IMAXBEL = 0x00002000; + IUTF8 = 0x00004000; + + OPOST = 0x00000001; + ONLCR = 0x00000002; + OXTABS = 0x00000004; + ONOEOT = 0x00000008; + OCRNL = 0x00000010; + ONOCR = 0x00000020; + ONLRET = 0x00000040; + OFILL = 0x00000080; + NLDLY = 0x00000300; + TABDLY = 0x00000c04; + CRDLY = 0x00003000; + FFDLY = 0x00004000; + BSDLY = 0x00008000; + VTDLY = 0x00010000; + OFDEL = 0x00020000; + + CIGNORE = 0x00000001; + CS5 = 0x00000000; + CS6 = 0x00000100; + CS7 = 0x00000200; + CS8 = 0x00000300; + CSTOPB = 0x00000400; + CREAD = 0x00000800; + PARENB = 0x00001000; + PARODD = 0x00002000; + HUPCL = 0x00004000; + CLOCAL = 0x00008000; + CCTS_OFLOW = 0x00010000; + CRTS_IFLOW = 0x00020000; + CDTR_IFLOW = 0x00040000; + CDSR_OFLOW = 0x00080000; + CCAR_OFLOW = 0x00100000; + + ECHOKE = 0x00000001; + ECHOE = 0x00000002; + ECHOK = 0x00000004; + ECHO = 0x00000008; + ECHONL = 0x00000010; + ECHOPRT = 0x00000020; + ECHOCTL = 0x00000040; + ISIG = 0x00000080; + ICANON = 0x00000100; + ALTWERASE = 0x00000200; + IEXTEN = 0x00000400; + EXTPROC = 0x00000800; + TOSTOP = 0x00400000; + FLUSHO = 0x00800000; + NOKERNINFO = 0x02000000; + PENDIN = 0x20000000; + NOFLSH = 0x80000000; + } else if (osName.startsWith("FreeBSD")) { + TIOCGWINSZ = 0x40087468; + TIOCSWINSZ = 0x80087467; + + TCSANOW = 0x0; + TCSADRAIN = 0x1; + TCSAFLUSH = 0x2; + + VEOF = 0; + VEOL = 1; + VEOL2 = 2; + VERASE = 3; + VWERASE = 4; + VKILL = 5; + VREPRINT = 6; + VERASE2 = 7; + VINTR = 8; + VQUIT = 9; + VSUSP = 10; + VDSUSP = 11; + VSTART = 12; + VSTOP = 13; + VLNEXT = 14; + VDISCARD = 15; + VMIN = 16; + VTIME = 17; + VSTATUS = 18; + VSWTC = -1; + + IGNBRK = 0x0000001; + BRKINT = 0x0000002; + IGNPAR = 0x0000004; + PARMRK = 0x0000008; + INPCK = 0x0000010; + ISTRIP = 0x0000020; + INLCR = 0x0000040; + IGNCR = 0x0000080; + ICRNL = 0x0000100; + IXON = 0x0000200; + IXOFF = 0x0000400; + IXANY = 0x0000800; + IMAXBEL = 0x0002000; + + OPOST = 0x0000001; + ONLCR = 0x0000002; + TABDLY = 0x0000004; + TAB0 = 0x0000000; + TAB3 = 0x0000004; + ONOEOT = 0x0000008; + OCRNL = 0x0000010; + ONLRET = 0x0000040; + + CIGNORE = 0x0000001; + CSIZE = 0x0000300; + CS5 = 0x0000000; + CS6 = 0x0000100; + CS7 = 0x0000200; + CS8 = 0x0000300; + CSTOPB = 0x0000400; + CREAD = 0x0000800; + PARENB = 0x0001000; + PARODD = 0x0002000; + HUPCL = 0x0004000; + CLOCAL = 0x0008000; + + ECHOKE = 0x0000001; + ECHOE = 0x0000002; + ECHOK = 0x0000004; + ECHO = 0x0000008; + ECHONL = 0x0000010; + ECHOPRT = 0x0000020; + ECHOCTL = 0x0000040; + ISIG = 0x0000080; + ICANON = 0x0000100; + ALTWERASE = 0x000200; + IEXTEN = 0x0000400; + EXTPROC = 0x0000800; + TOSTOP = 0x0400000; + FLUSHO = 0x0800000; + PENDIN = 0x2000000; + NOFLSH = 0x8000000; + } else { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmNativePty.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmNativePty.java new file mode 100644 index 00000000000..1f8b668115a --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmNativePty.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2022-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.impl.AbstractPty; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; + +class FfmNativePty extends AbstractPty { + private final int master; + private final int slave; + private final int slaveOut; + private final String name; + private final FileDescriptor masterFD; + private final FileDescriptor slaveFD; + private final FileDescriptor slaveOutFD; + + public FfmNativePty(TerminalProvider provider, SystemStream systemStream, int master, int slave, String name) { + this( + provider, + systemStream, + master, + newDescriptor(master), + slave, + newDescriptor(slave), + slave, + newDescriptor(slave), + name); + } + + public FfmNativePty( + TerminalProvider provider, + SystemStream systemStream, + int master, + FileDescriptor masterFD, + int slave, + FileDescriptor slaveFD, + int slaveOut, + FileDescriptor slaveOutFD, + String name) { + super(provider, systemStream); + this.master = master; + this.slave = slave; + this.slaveOut = slaveOut; + this.name = name; + this.masterFD = masterFD; + this.slaveFD = slaveFD; + this.slaveOutFD = slaveOutFD; + } + + @Override + public void close() throws IOException { + if (master > 0) { + getMasterInput().close(); + } + if (slave > 0) { + getSlaveInput().close(); + } + } + + public int getMaster() { + return master; + } + + public int getSlave() { + return slave; + } + + public int getSlaveOut() { + return slaveOut; + } + + public String getName() { + return name; + } + + public FileDescriptor getMasterFD() { + return masterFD; + } + + public FileDescriptor getSlaveFD() { + return slaveFD; + } + + public FileDescriptor getSlaveOutFD() { + return slaveOutFD; + } + + public InputStream getMasterInput() { + return new FileInputStream(getMasterFD()); + } + + public OutputStream getMasterOutput() { + return new FileOutputStream(getMasterFD()); + } + + protected InputStream doGetSlaveInput() { + return new FileInputStream(getSlaveFD()); + } + + public OutputStream getSlaveOutput() { + return new FileOutputStream(getSlaveOutFD()); + } + + @Override + public Attributes getAttr() throws IOException { + return CLibrary.getAttributes(slave); + } + + @Override + protected void doSetAttr(Attributes attr) throws IOException { + CLibrary.setAttributes(slave, attr); + } + + @Override + public Size getSize() throws IOException { + return CLibrary.getTerminalSize(slave); + } + + @Override + public void setSize(Size size) throws IOException { + CLibrary.setTerminalSize(slave, size); + } + + @Override + public String toString() { + return "FfmNativePty[" + getName() + "]"; + } + + public static boolean isPosixSystemStream(SystemStream stream) { + switch (stream) { + case Input: + return CLibrary.isTty(0); + case Output: + return CLibrary.isTty(1); + case Error: + return CLibrary.isTty(2); + default: + throw new IllegalArgumentException(); + } + } + + public static String posixSystemStreamName(SystemStream stream) { + switch (stream) { + case Input: + return CLibrary.ttyName(0); + case Output: + return CLibrary.ttyName(1); + case Error: + return CLibrary.ttyName(2); + default: + throw new IllegalArgumentException(); + } + } + + public static int systemStreamWidth(SystemStream systemStream) { + int fd = systemStream == SystemStream.Output ? 1 : 2; + return CLibrary.getTerminalSize(fd).getColumns(); + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmTerminalProvider.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmTerminalProvider.java new file mode 100644 index 00000000000..76f07926b12 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/FfmTerminalProvider.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2022-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemoryLayout.PathElement; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.nio.charset.Charset; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.TerminalBuilder; +import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal; +import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; +import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.OSUtils; + +public class FfmTerminalProvider implements TerminalProvider { + + public FfmTerminalProvider() { + if (!FfmTerminalProvider.class.getModule().isNativeAccessEnabled()) { + throw new UnsupportedOperationException( + "Native access is not enabled for the current module: " + FfmTerminalProvider.class.getModule()); + } + } + + @Override + public String name() { + return TerminalBuilder.PROP_PROVIDER_FFM; + } + + @Override + public Terminal sysTerminal( + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + Terminal.SignalHandler signalHandler, + boolean paused, + SystemStream systemStream, + Function inputStreamWrapper) + throws IOException { + if (OSUtils.IS_WINDOWS) { + return NativeWinSysTerminal.createTerminal( + this, systemStream, name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, inputStreamWrapper); + } else { + Pty pty = new FfmNativePty( + this, + systemStream, + -1, + null, + 0, + FileDescriptor.in, + systemStream == SystemStream.Output ? 1 : 2, + systemStream == SystemStream.Output ? FileDescriptor.out : FileDescriptor.err, + CLibrary.ttyName(0)); + return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); + } + } + + @Override + public Terminal newTerminal( + String name, + String type, + InputStream in, + OutputStream out, + Charset encoding, + Terminal.SignalHandler signalHandler, + boolean paused, + Attributes attributes, + Size size) + throws IOException { + Pty pty = CLibrary.openpty(this, attributes, size); + return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused); + } + + @Override + public boolean isSystemStream(SystemStream stream) { + if (OSUtils.IS_WINDOWS) { + return isWindowsSystemStream(stream); + } else { + return isPosixSystemStream(stream); + } + } + + public boolean isWindowsSystemStream(SystemStream stream) { + return NativeWinSysTerminal.isWindowsSystemStream(stream); + } + + public boolean isPosixSystemStream(SystemStream stream) { + return FfmNativePty.isPosixSystemStream(stream); + } + + @Override + public String systemStreamName(SystemStream stream) { + return FfmNativePty.posixSystemStreamName(stream); + } + + @Override + public int systemStreamWidth(SystemStream stream) { + return FfmNativePty.systemStreamWidth(stream); + } + + @Override + public String toString() { + return "TerminalProvider[" + name() + "]"; + } + + static VarHandle lookupVarHandle(MemoryLayout layout, PathElement... element) { + VarHandle h = layout.varHandle(element); + + // the last parameter of the VarHandle is additional offset, hardcode zero: + h = MethodHandles.insertCoordinates(h, h.coordinateTypes().size() - 1, 0L); + + return h; + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java new file mode 100644 index 00000000000..0c485819f57 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java @@ -0,0 +1,927 @@ +/* + * Copyright (c) 2009-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.IOException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +@SuppressWarnings({"unused", "restricted"}) +final class Kernel32 { + + public static final int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; + + public static final int INVALID_HANDLE_VALUE = -1; + public static final int STD_INPUT_HANDLE = -10; + public static final int STD_OUTPUT_HANDLE = -11; + public static final int STD_ERROR_HANDLE = -12; + + public static final int ENABLE_PROCESSED_INPUT = 0x0001; + public static final int ENABLE_LINE_INPUT = 0x0002; + public static final int ENABLE_ECHO_INPUT = 0x0004; + public static final int ENABLE_WINDOW_INPUT = 0x0008; + public static final int ENABLE_MOUSE_INPUT = 0x0010; + public static final int ENABLE_INSERT_MODE = 0x0020; + public static final int ENABLE_QUICK_EDIT_MODE = 0x0040; + public static final int ENABLE_EXTENDED_FLAGS = 0x0080; + + public static final int RIGHT_ALT_PRESSED = 0x0001; + public static final int LEFT_ALT_PRESSED = 0x0002; + public static final int RIGHT_CTRL_PRESSED = 0x0004; + public static final int LEFT_CTRL_PRESSED = 0x0008; + public static final int SHIFT_PRESSED = 0x0010; + + public static final int FOREGROUND_BLUE = 0x0001; + public static final int FOREGROUND_GREEN = 0x0002; + public static final int FOREGROUND_RED = 0x0004; + public static final int FOREGROUND_INTENSITY = 0x0008; + public static final int BACKGROUND_BLUE = 0x0010; + public static final int BACKGROUND_GREEN = 0x0020; + public static final int BACKGROUND_RED = 0x0040; + public static final int BACKGROUND_INTENSITY = 0x0080; + + // Button state + public static final int FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001; + public static final int RIGHTMOST_BUTTON_PRESSED = 0x0002; + public static final int FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004; + public static final int FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008; + public static final int FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010; + + // Event flags + public static final int MOUSE_MOVED = 0x0001; + public static final int DOUBLE_CLICK = 0x0002; + public static final int MOUSE_WHEELED = 0x0004; + public static final int MOUSE_HWHEELED = 0x0008; + + // Event types + public static final short KEY_EVENT = 0x0001; + public static final short MOUSE_EVENT = 0x0002; + public static final short WINDOW_BUFFER_SIZE_EVENT = 0x0004; + public static final short MENU_EVENT = 0x0008; + public static final short FOCUS_EVENT = 0x0010; + + public static int WaitForSingleObject(java.lang.foreign.MemorySegment hHandle, int dwMilliseconds) { + MethodHandle mh$ = requireNonNull(WaitForSingleObject$MH, "WaitForSingleObject"); + try { + return (int) mh$.invokeExact(hHandle, dwMilliseconds); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static java.lang.foreign.MemorySegment GetStdHandle(int nStdHandle) { + MethodHandle mh$ = requireNonNull(GetStdHandle$MH, "GetStdHandle"); + try { + return (java.lang.foreign.MemorySegment) mh$.invokeExact(nStdHandle); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int FormatMessageW( + int dwFlags, + java.lang.foreign.MemorySegment lpSource, + int dwMessageId, + int dwLanguageId, + java.lang.foreign.MemorySegment lpBuffer, + int nSize, + java.lang.foreign.MemorySegment Arguments) { + MethodHandle mh$ = requireNonNull(FormatMessageW$MH, "FormatMessageW"); + try { + return (int) mh$.invokeExact(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int SetConsoleTextAttribute(java.lang.foreign.MemorySegment hConsoleOutput, short wAttributes) { + MethodHandle mh$ = requireNonNull(SetConsoleTextAttribute$MH, "SetConsoleTextAttribute"); + try { + return (int) mh$.invokeExact(hConsoleOutput, wAttributes); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int SetConsoleMode(java.lang.foreign.MemorySegment hConsoleHandle, int dwMode) { + MethodHandle mh$ = requireNonNull(SetConsoleMode$MH, "SetConsoleMode"); + try { + return (int) mh$.invokeExact(hConsoleHandle, dwMode); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int GetConsoleMode( + java.lang.foreign.MemorySegment hConsoleHandle, java.lang.foreign.MemorySegment lpMode) { + MethodHandle mh$ = requireNonNull(GetConsoleMode$MH, "GetConsoleMode"); + try { + return (int) mh$.invokeExact(hConsoleHandle, lpMode); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int SetConsoleTitleW(java.lang.foreign.MemorySegment lpConsoleTitle) { + MethodHandle mh$ = requireNonNull(SetConsoleTitleW$MH, "SetConsoleTitleW"); + try { + return (int) mh$.invokeExact(lpConsoleTitle); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int SetConsoleCursorPosition(java.lang.foreign.MemorySegment hConsoleOutput, COORD dwCursorPosition) { + MethodHandle mh$ = requireNonNull(SetConsoleCursorPosition$MH, "SetConsoleCursorPosition"); + try { + return (int) mh$.invokeExact(hConsoleOutput, dwCursorPosition.seg); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int FillConsoleOutputCharacterW( + java.lang.foreign.MemorySegment hConsoleOutput, + char cCharacter, + int nLength, + COORD dwWriteCoord, + java.lang.foreign.MemorySegment lpNumberOfCharsWritten) { + MethodHandle mh$ = requireNonNull(FillConsoleOutputCharacterW$MH, "FillConsoleOutputCharacterW"); + try { + return (int) mh$.invokeExact(hConsoleOutput, cCharacter, nLength, dwWriteCoord.seg, lpNumberOfCharsWritten); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int FillConsoleOutputAttribute( + java.lang.foreign.MemorySegment hConsoleOutput, + short wAttribute, + int nLength, + COORD dwWriteCoord, + java.lang.foreign.MemorySegment lpNumberOfAttrsWritten) { + MethodHandle mh$ = requireNonNull(FillConsoleOutputAttribute$MH, "FillConsoleOutputAttribute"); + try { + return (int) mh$.invokeExact(hConsoleOutput, wAttribute, nLength, dwWriteCoord.seg, lpNumberOfAttrsWritten); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int WriteConsoleW( + java.lang.foreign.MemorySegment hConsoleOutput, + java.lang.foreign.MemorySegment lpBuffer, + int nNumberOfCharsToWrite, + java.lang.foreign.MemorySegment lpNumberOfCharsWritten, + java.lang.foreign.MemorySegment lpReserved) { + MethodHandle mh$ = requireNonNull(WriteConsoleW$MH, "WriteConsoleW"); + try { + return (int) mh$.invokeExact( + hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int ReadConsoleInputW( + java.lang.foreign.MemorySegment hConsoleInput, + java.lang.foreign.MemorySegment lpBuffer, + int nLength, + java.lang.foreign.MemorySegment lpNumberOfEventsRead) { + MethodHandle mh$ = requireNonNull(ReadConsoleInputW$MH, "ReadConsoleInputW"); + try { + return (int) mh$.invokeExact(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int PeekConsoleInputW( + java.lang.foreign.MemorySegment hConsoleInput, + java.lang.foreign.MemorySegment lpBuffer, + int nLength, + java.lang.foreign.MemorySegment lpNumberOfEventsRead) { + MethodHandle mh$ = requireNonNull(PeekConsoleInputW$MH, "PeekConsoleInputW"); + try { + return (int) mh$.invokeExact(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int GetConsoleScreenBufferInfo( + java.lang.foreign.MemorySegment hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo) { + MethodHandle mh$ = requireNonNull(GetConsoleScreenBufferInfo$MH, "GetConsoleScreenBufferInfo"); + try { + return (int) mh$.invokeExact(hConsoleOutput, lpConsoleScreenBufferInfo.seg); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int ScrollConsoleScreenBuffer( + java.lang.foreign.MemorySegment hConsoleOutput, + SMALL_RECT lpScrollRectangle, + SMALL_RECT lpClipRectangle, + COORD dwDestinationOrigin, + CHAR_INFO lpFill) { + MethodHandle mh$ = requireNonNull(ScrollConsoleScreenBufferW$MH, "ScrollConsoleScreenBuffer"); + try { + return (int) + mh$.invokeExact(hConsoleOutput, lpScrollRectangle, lpClipRectangle, dwDestinationOrigin, lpFill); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int GetLastError() { + MethodHandle mh$ = requireNonNull(GetLastError$MH, "GetLastError"); + try { + return (int) mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static int GetFileType(java.lang.foreign.MemorySegment hFile) { + MethodHandle mh$ = requireNonNull(GetFileType$MH, "GetFileType"); + try { + return (int) mh$.invokeExact(hFile); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static java.lang.foreign.MemorySegment _get_osfhandle(int fd) { + MethodHandle mh$ = requireNonNull(_get_osfhandle$MH, "_get_osfhandle"); + try { + return (java.lang.foreign.MemorySegment) mh$.invokeExact(fd); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + + public static INPUT_RECORD[] readConsoleInputHelper(java.lang.foreign.MemorySegment handle, int count, boolean peek) + throws IOException { + return readConsoleInputHelper(java.lang.foreign.Arena.ofAuto(), handle, count, peek); + } + + public static INPUT_RECORD[] readConsoleInputHelper( + java.lang.foreign.Arena arena, java.lang.foreign.MemorySegment handle, int count, boolean peek) + throws IOException { + java.lang.foreign.MemorySegment inputRecordPtr = arena.allocate(INPUT_RECORD.LAYOUT, count); + java.lang.foreign.MemorySegment length = arena.allocate(java.lang.foreign.ValueLayout.JAVA_INT, 1); + int res = peek + ? PeekConsoleInputW(handle, inputRecordPtr, count, length) + : ReadConsoleInputW(handle, inputRecordPtr, count, length); + if (res == 0) { + throw new IOException("ReadConsoleInputW failed: " + getLastErrorMessage()); + } + int len = length.get(java.lang.foreign.ValueLayout.JAVA_INT, 0); + return inputRecordPtr + .elements(INPUT_RECORD.LAYOUT) + .map(INPUT_RECORD::new) + .limit(len) + .toArray(INPUT_RECORD[]::new); + } + + public static String getLastErrorMessage() { + int errorCode = GetLastError(); + return getErrorMessage(errorCode); + } + + public static String getErrorMessage(int errorCode) { + int bufferSize = 160; + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment data = arena.allocate(bufferSize); + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM, + java.lang.foreign.MemorySegment.NULL, + errorCode, + 0, + data, + bufferSize, + java.lang.foreign.MemorySegment.NULL); + return new String(data.toArray(java.lang.foreign.ValueLayout.JAVA_BYTE), StandardCharsets.UTF_16LE).trim(); + } + } + + private static final java.lang.foreign.SymbolLookup SYMBOL_LOOKUP; + + static { + System.loadLibrary("msvcrt"); + System.loadLibrary("Kernel32"); + SYMBOL_LOOKUP = java.lang.foreign.SymbolLookup.loaderLookup(); + } + + static MethodHandle downcallHandle(String name, java.lang.foreign.FunctionDescriptor fdesc) { + return SYMBOL_LOOKUP + .find(name) + .map(addr -> java.lang.foreign.Linker.nativeLinker().downcallHandle(addr, fdesc)) + .orElse(null); + } + + static final java.lang.foreign.ValueLayout.OfBoolean C_BOOL$LAYOUT = java.lang.foreign.ValueLayout.JAVA_BOOLEAN; + static final java.lang.foreign.ValueLayout.OfByte C_CHAR$LAYOUT = java.lang.foreign.ValueLayout.JAVA_BYTE; + static final java.lang.foreign.ValueLayout.OfChar C_WCHAR$LAYOUT = java.lang.foreign.ValueLayout.JAVA_CHAR; + static final java.lang.foreign.ValueLayout.OfShort C_SHORT$LAYOUT = java.lang.foreign.ValueLayout.JAVA_SHORT; + static final java.lang.foreign.ValueLayout.OfShort C_WORD$LAYOUT = java.lang.foreign.ValueLayout.JAVA_SHORT; + static final java.lang.foreign.ValueLayout.OfInt C_DWORD$LAYOUT = java.lang.foreign.ValueLayout.JAVA_INT; + static final java.lang.foreign.ValueLayout.OfInt C_INT$LAYOUT = java.lang.foreign.ValueLayout.JAVA_INT; + static final java.lang.foreign.ValueLayout.OfLong C_LONG$LAYOUT = java.lang.foreign.ValueLayout.JAVA_LONG; + static final java.lang.foreign.ValueLayout.OfLong C_LONG_LONG$LAYOUT = java.lang.foreign.ValueLayout.JAVA_LONG; + static final java.lang.foreign.ValueLayout.OfFloat C_FLOAT$LAYOUT = java.lang.foreign.ValueLayout.JAVA_FLOAT; + static final java.lang.foreign.ValueLayout.OfDouble C_DOUBLE$LAYOUT = java.lang.foreign.ValueLayout.JAVA_DOUBLE; + static final java.lang.foreign.AddressLayout C_POINTER$LAYOUT = java.lang.foreign.ValueLayout.ADDRESS; + + static final MethodHandle WaitForSingleObject$MH = downcallHandle( + "WaitForSingleObject", + java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT, C_INT$LAYOUT)); + static final MethodHandle GetStdHandle$MH = + downcallHandle("GetStdHandle", java.lang.foreign.FunctionDescriptor.of(C_POINTER$LAYOUT, C_INT$LAYOUT)); + static final MethodHandle FormatMessageW$MH = downcallHandle( + "FormatMessageW", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, + C_INT$LAYOUT, + C_POINTER$LAYOUT, + C_INT$LAYOUT, + C_INT$LAYOUT, + C_POINTER$LAYOUT, + C_INT$LAYOUT, + C_POINTER$LAYOUT)); + static final MethodHandle SetConsoleTextAttribute$MH = downcallHandle( + "SetConsoleTextAttribute", + java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT, C_SHORT$LAYOUT)); + static final MethodHandle SetConsoleMode$MH = downcallHandle( + "SetConsoleMode", java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT, C_INT$LAYOUT)); + static final MethodHandle GetConsoleMode$MH = downcallHandle( + "GetConsoleMode", + java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT, C_POINTER$LAYOUT)); + + static final MethodHandle SetConsoleTitleW$MH = + downcallHandle("SetConsoleTitleW", java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT)); + static final MethodHandle SetConsoleCursorPosition$MH = downcallHandle( + "SetConsoleCursorPosition", + java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT, COORD.LAYOUT)); + static final MethodHandle FillConsoleOutputCharacterW$MH = downcallHandle( + "FillConsoleOutputCharacterW", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, C_POINTER$LAYOUT, C_WCHAR$LAYOUT, C_INT$LAYOUT, COORD.LAYOUT, C_POINTER$LAYOUT)); + static final MethodHandle FillConsoleOutputAttribute$MH = downcallHandle( + "FillConsoleOutputAttribute", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, C_POINTER$LAYOUT, C_SHORT$LAYOUT, C_INT$LAYOUT, COORD.LAYOUT, C_POINTER$LAYOUT)); + static final MethodHandle WriteConsoleW$MH = downcallHandle( + "WriteConsoleW", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, + C_POINTER$LAYOUT, + C_POINTER$LAYOUT, + C_INT$LAYOUT, + C_POINTER$LAYOUT, + C_POINTER$LAYOUT)); + + static final MethodHandle ReadConsoleInputW$MH = downcallHandle( + "ReadConsoleInputW", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, C_POINTER$LAYOUT, C_POINTER$LAYOUT, C_INT$LAYOUT, C_POINTER$LAYOUT)); + static final MethodHandle PeekConsoleInputW$MH = downcallHandle( + "PeekConsoleInputW", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, C_POINTER$LAYOUT, C_POINTER$LAYOUT, C_INT$LAYOUT, C_POINTER$LAYOUT)); + + static final MethodHandle GetConsoleScreenBufferInfo$MH = downcallHandle( + "GetConsoleScreenBufferInfo", + java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT, C_POINTER$LAYOUT)); + + static final MethodHandle ScrollConsoleScreenBufferW$MH = downcallHandle( + "ScrollConsoleScreenBufferW", + java.lang.foreign.FunctionDescriptor.of( + C_INT$LAYOUT, + C_POINTER$LAYOUT, + C_POINTER$LAYOUT, + C_POINTER$LAYOUT, + COORD.LAYOUT, + C_POINTER$LAYOUT)); + static final MethodHandle GetLastError$MH = + downcallHandle("GetLastError", java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT)); + static final MethodHandle GetFileType$MH = + downcallHandle("GetFileType", java.lang.foreign.FunctionDescriptor.of(C_INT$LAYOUT, C_POINTER$LAYOUT)); + static final MethodHandle _get_osfhandle$MH = + downcallHandle("_get_osfhandle", java.lang.foreign.FunctionDescriptor.of(C_POINTER$LAYOUT, C_INT$LAYOUT)); + + public static final class INPUT_RECORD { + static final java.lang.foreign.MemoryLayout LAYOUT = java.lang.foreign.MemoryLayout.structLayout( + java.lang.foreign.ValueLayout.JAVA_SHORT.withName("EventType"), + java.lang.foreign.ValueLayout.JAVA_SHORT, // padding + java.lang.foreign.MemoryLayout.unionLayout( + KEY_EVENT_RECORD.LAYOUT.withName("KeyEvent"), + MOUSE_EVENT_RECORD.LAYOUT.withName("MouseEvent"), + WINDOW_BUFFER_SIZE_RECORD.LAYOUT.withName("WindowBufferSizeEvent"), + MENU_EVENT_RECORD.LAYOUT.withName("MenuEvent"), + FOCUS_EVENT_RECORD.LAYOUT.withName("FocusEvent")) + .withName("Event")); + static final VarHandle EventType$VH = varHandle(LAYOUT, "EventType"); + static final long Event$OFFSET = byteOffset(LAYOUT, "Event"); + + private final java.lang.foreign.MemorySegment seg; + + public INPUT_RECORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public INPUT_RECORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public INPUT_RECORD(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public short eventType() { + return (short) EventType$VH.get(seg); + } + + public KEY_EVENT_RECORD keyEvent() { + return new KEY_EVENT_RECORD(seg, Event$OFFSET); + } + + public MOUSE_EVENT_RECORD mouseEvent() { + return new MOUSE_EVENT_RECORD(seg, Event$OFFSET); + } + + public FOCUS_EVENT_RECORD focusEvent() { + return new FOCUS_EVENT_RECORD(seg, Event$OFFSET); + } + } + + public static final class MENU_EVENT_RECORD { + + static final java.lang.foreign.GroupLayout LAYOUT = + java.lang.foreign.MemoryLayout.structLayout(C_DWORD$LAYOUT.withName("dwCommandId")); + static final VarHandle COMMAND_ID = varHandle(LAYOUT, "dwCommandId"); + + private final java.lang.foreign.MemorySegment seg; + + public MENU_EVENT_RECORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public MENU_EVENT_RECORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public MENU_EVENT_RECORD(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public int commandId() { + return (int) MENU_EVENT_RECORD.COMMAND_ID.get(seg); + } + + public void commandId(int commandId) { + MENU_EVENT_RECORD.COMMAND_ID.set(seg, commandId); + } + } + + public static final class FOCUS_EVENT_RECORD { + + static final java.lang.foreign.GroupLayout LAYOUT = + java.lang.foreign.MemoryLayout.structLayout(C_INT$LAYOUT.withName("bSetFocus")); + static final VarHandle SET_FOCUS = varHandle(LAYOUT, "bSetFocus"); + + private final java.lang.foreign.MemorySegment seg; + + public FOCUS_EVENT_RECORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public FOCUS_EVENT_RECORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public FOCUS_EVENT_RECORD(java.lang.foreign.MemorySegment seg) { + this.seg = Objects.requireNonNull(seg); + } + + public FOCUS_EVENT_RECORD(java.lang.foreign.MemorySegment seg, long offset) { + this.seg = Objects.requireNonNull(seg).asSlice(offset, LAYOUT.byteSize()); + } + + public boolean setFocus() { + return ((int) FOCUS_EVENT_RECORD.SET_FOCUS.get(seg) != 0); + } + + public void setFocus(boolean setFocus) { + FOCUS_EVENT_RECORD.SET_FOCUS.set(seg, setFocus ? 1 : 0); + } + } + + public static final class WINDOW_BUFFER_SIZE_RECORD { + + static final java.lang.foreign.GroupLayout LAYOUT = + java.lang.foreign.MemoryLayout.structLayout(COORD.LAYOUT.withName("size")); + static final long SIZE_OFFSET = byteOffset(LAYOUT, "size"); + + private final java.lang.foreign.MemorySegment seg; + + public WINDOW_BUFFER_SIZE_RECORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public WINDOW_BUFFER_SIZE_RECORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public WINDOW_BUFFER_SIZE_RECORD(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public COORD size() { + return new COORD(seg, SIZE_OFFSET); + } + + public String toString() { + return "WINDOW_BUFFER_SIZE_RECORD{size=" + this.size() + '}'; + } + } + + public static final class MOUSE_EVENT_RECORD { + + static final java.lang.foreign.MemoryLayout LAYOUT = java.lang.foreign.MemoryLayout.structLayout( + COORD.LAYOUT.withName("dwMousePosition"), + C_DWORD$LAYOUT.withName("dwButtonState"), + C_DWORD$LAYOUT.withName("dwControlKeyState"), + C_DWORD$LAYOUT.withName("dwEventFlags")); + static final long MOUSE_POSITION_OFFSET = byteOffset(LAYOUT, "dwMousePosition"); + static final VarHandle BUTTON_STATE = varHandle(LAYOUT, "dwButtonState"); + static final VarHandle CONTROL_KEY_STATE = varHandle(LAYOUT, "dwControlKeyState"); + static final VarHandle EVENT_FLAGS = varHandle(LAYOUT, "dwEventFlags"); + + private final java.lang.foreign.MemorySegment seg; + + public MOUSE_EVENT_RECORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public MOUSE_EVENT_RECORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public MOUSE_EVENT_RECORD(java.lang.foreign.MemorySegment seg) { + this.seg = Objects.requireNonNull(seg); + } + + public MOUSE_EVENT_RECORD(java.lang.foreign.MemorySegment seg, long offset) { + this.seg = Objects.requireNonNull(seg).asSlice(offset, LAYOUT.byteSize()); + } + + public COORD mousePosition() { + return new COORD(seg, MOUSE_POSITION_OFFSET); + } + + public int buttonState() { + return (int) BUTTON_STATE.get(seg); + } + + public int controlKeyState() { + return (int) CONTROL_KEY_STATE.get(seg); + } + + public int eventFlags() { + return (int) EVENT_FLAGS.get(seg); + } + + public String toString() { + return "MOUSE_EVENT_RECORD{mousePosition=" + mousePosition() + ", buttonState=" + buttonState() + + ", controlKeyState=" + controlKeyState() + ", eventFlags=" + eventFlags() + '}'; + } + } + + public static final class KEY_EVENT_RECORD { + + static final java.lang.foreign.MemoryLayout LAYOUT = java.lang.foreign.MemoryLayout.structLayout( + java.lang.foreign.ValueLayout.JAVA_INT.withName("bKeyDown"), + java.lang.foreign.ValueLayout.JAVA_SHORT.withName("wRepeatCount"), + java.lang.foreign.ValueLayout.JAVA_SHORT.withName("wVirtualKeyCode"), + java.lang.foreign.ValueLayout.JAVA_SHORT.withName("wVirtualScanCode"), + java.lang.foreign.MemoryLayout.unionLayout( + java.lang.foreign.ValueLayout.JAVA_CHAR.withName("UnicodeChar"), + java.lang.foreign.ValueLayout.JAVA_BYTE.withName("AsciiChar")) + .withName("uChar"), + java.lang.foreign.ValueLayout.JAVA_INT.withName("dwControlKeyState")); + static final VarHandle bKeyDown$VH = varHandle(LAYOUT, "bKeyDown"); + static final VarHandle wRepeatCount$VH = varHandle(LAYOUT, "wRepeatCount"); + static final VarHandle wVirtualKeyCode$VH = varHandle(LAYOUT, "wVirtualKeyCode"); + static final VarHandle wVirtualScanCode$VH = varHandle(LAYOUT, "wVirtualScanCode"); + static final VarHandle UnicodeChar$VH = varHandle(LAYOUT, "uChar", "UnicodeChar"); + static final VarHandle AsciiChar$VH = varHandle(LAYOUT, "uChar", "AsciiChar"); + static final VarHandle dwControlKeyState$VH = varHandle(LAYOUT, "dwControlKeyState"); + + final java.lang.foreign.MemorySegment seg; + + public KEY_EVENT_RECORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public KEY_EVENT_RECORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public KEY_EVENT_RECORD(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public KEY_EVENT_RECORD(java.lang.foreign.MemorySegment seg, long offset) { + this.seg = Objects.requireNonNull(seg).asSlice(offset, LAYOUT.byteSize()); + } + + public boolean keyDown() { + return ((int) bKeyDown$VH.get(seg)) != 0; + } + + public int repeatCount() { + return (int) wRepeatCount$VH.get(seg); + } + + public short keyCode() { + return (short) wVirtualKeyCode$VH.get(seg); + } + + public short scanCode() { + return (short) wVirtualScanCode$VH.get(seg); + } + + public char uchar() { + return (char) UnicodeChar$VH.get(seg); + } + + public int controlKeyState() { + return (int) dwControlKeyState$VH.get(seg); + } + + public String toString() { + return "KEY_EVENT_RECORD{keyDown=" + this.keyDown() + ", repeatCount=" + this.repeatCount() + ", keyCode=" + + this.keyCode() + ", scanCode=" + this.scanCode() + ", uchar=" + this.uchar() + + ", controlKeyState=" + + this.controlKeyState() + '}'; + } + } + + public static final class CHAR_INFO { + + static final java.lang.foreign.GroupLayout LAYOUT = java.lang.foreign.MemoryLayout.structLayout( + java.lang.foreign.MemoryLayout.unionLayout( + C_WCHAR$LAYOUT.withName("UnicodeChar"), C_CHAR$LAYOUT.withName("AsciiChar")) + .withName("Char"), + C_WORD$LAYOUT.withName("Attributes")); + static final VarHandle UnicodeChar$VH = varHandle(LAYOUT, "Char", "UnicodeChar"); + static final VarHandle Attributes$VH = varHandle(LAYOUT, "Attributes"); + + final java.lang.foreign.MemorySegment seg; + + public CHAR_INFO() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public CHAR_INFO(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public CHAR_INFO(java.lang.foreign.Arena arena, char c, short a) { + this(arena); + UnicodeChar$VH.set(seg, c); + Attributes$VH.set(seg, a); + } + + public CHAR_INFO(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public char unicodeChar() { + return (char) UnicodeChar$VH.get(seg); + } + } + + public static final class CONSOLE_SCREEN_BUFFER_INFO { + static final java.lang.foreign.GroupLayout LAYOUT = java.lang.foreign.MemoryLayout.structLayout( + COORD.LAYOUT.withName("dwSize"), + COORD.LAYOUT.withName("dwCursorPosition"), + C_WORD$LAYOUT.withName("wAttributes"), + SMALL_RECT.LAYOUT.withName("srWindow"), + COORD.LAYOUT.withName("dwMaximumWindowSize")); + static final long dwSize$OFFSET = byteOffset(LAYOUT, "dwSize"); + static final long dwCursorPosition$OFFSET = byteOffset(LAYOUT, "dwCursorPosition"); + static final VarHandle wAttributes$VH = varHandle(LAYOUT, "wAttributes"); + static final long srWindow$OFFSET = byteOffset(LAYOUT, "srWindow"); + + private final java.lang.foreign.MemorySegment seg; + + public CONSOLE_SCREEN_BUFFER_INFO() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public CONSOLE_SCREEN_BUFFER_INFO(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public CONSOLE_SCREEN_BUFFER_INFO(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public COORD size() { + return new COORD(seg, dwSize$OFFSET); + } + + public COORD cursorPosition() { + return new COORD(seg, dwCursorPosition$OFFSET); + } + + public short attributes() { + return (short) wAttributes$VH.get(seg); + } + + public SMALL_RECT window() { + return new SMALL_RECT(seg, srWindow$OFFSET); + } + + public int windowWidth() { + return this.window().width() + 1; + } + + public int windowHeight() { + return this.window().height() + 1; + } + + public void attributes(short attr) { + wAttributes$VH.set(seg, attr); + } + } + + public static final class COORD { + + static final java.lang.foreign.GroupLayout LAYOUT = + java.lang.foreign.MemoryLayout.structLayout(C_SHORT$LAYOUT.withName("x"), C_SHORT$LAYOUT.withName("y")); + static final VarHandle x$VH = varHandle(LAYOUT, "x"); + static final VarHandle y$VH = varHandle(LAYOUT, "y"); + + private final java.lang.foreign.MemorySegment seg; + + public COORD() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public COORD(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public COORD(java.lang.foreign.Arena arena, short x, short y) { + this(arena.allocate(LAYOUT)); + x(x); + y(y); + } + + public COORD(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public COORD(java.lang.foreign.MemorySegment seg, long offset) { + this.seg = Objects.requireNonNull(seg).asSlice(offset, LAYOUT.byteSize()); + } + + public short x() { + return (short) COORD.x$VH.get(seg); + } + + public void x(short x) { + COORD.x$VH.set(seg, x); + } + + public short y() { + return (short) COORD.y$VH.get(seg); + } + + public void y(short y) { + COORD.y$VH.set(seg, y); + } + + public COORD copy(java.lang.foreign.Arena arena) { + return new COORD(arena.allocate(LAYOUT).copyFrom(seg)); + } + } + + public static final class SMALL_RECT { + + static final java.lang.foreign.GroupLayout LAYOUT = java.lang.foreign.MemoryLayout.structLayout( + C_SHORT$LAYOUT.withName("Left"), + C_SHORT$LAYOUT.withName("Top"), + C_SHORT$LAYOUT.withName("Right"), + C_SHORT$LAYOUT.withName("Bottom")); + static final VarHandle Left$VH = varHandle(LAYOUT, "Left"); + static final VarHandle Top$VH = varHandle(LAYOUT, "Top"); + static final VarHandle Right$VH = varHandle(LAYOUT, "Right"); + static final VarHandle Bottom$VH = varHandle(LAYOUT, "Bottom"); + + private final java.lang.foreign.MemorySegment seg; + + public SMALL_RECT() { + this(java.lang.foreign.Arena.ofAuto()); + } + + public SMALL_RECT(java.lang.foreign.Arena arena) { + this(arena.allocate(LAYOUT)); + } + + public SMALL_RECT(java.lang.foreign.Arena arena, SMALL_RECT rect) { + this(arena); + left(rect.left()); + right(rect.right()); + top(rect.top()); + bottom(rect.bottom()); + } + + public SMALL_RECT(java.lang.foreign.MemorySegment seg, long offset) { + this(seg.asSlice(offset, LAYOUT.byteSize())); + } + + public SMALL_RECT(java.lang.foreign.MemorySegment seg) { + this.seg = seg; + } + + public short left() { + return (short) Left$VH.get(seg); + } + + public short top() { + return (short) Top$VH.get(seg); + } + + public short right() { + return (short) Right$VH.get(seg); + } + + public short bottom() { + return (short) Bottom$VH.get(seg); + } + + public short width() { + return (short) (this.right() - this.left()); + } + + public short height() { + return (short) (this.bottom() - this.top()); + } + + public void left(short l) { + Left$VH.set(seg, l); + } + + public void top(short t) { + Top$VH.set(seg, t); + } + + public void right(short r) { + Right$VH.set(seg, r); + } + + public void bottom(short b) { + Bottom$VH.set(seg, b); + } + + public SMALL_RECT copy(java.lang.foreign.Arena arena) { + return new SMALL_RECT(arena.allocate(LAYOUT).copyFrom(seg)); + } + } + + static T requireNonNull(T obj, String symbolName) { + if (obj == null) { + throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName); + } + return obj; + } + + static VarHandle varHandle(java.lang.foreign.MemoryLayout layout, String name) { + return FfmTerminalProvider.lookupVarHandle( + layout, java.lang.foreign.MemoryLayout.PathElement.groupElement(name)); + } + + static VarHandle varHandle(java.lang.foreign.MemoryLayout layout, String e1, String name) { + return FfmTerminalProvider.lookupVarHandle( + layout, + java.lang.foreign.MemoryLayout.PathElement.groupElement(e1), + java.lang.foreign.MemoryLayout.PathElement.groupElement(name)); + } + + static long byteOffset(java.lang.foreign.MemoryLayout layout, String name) { + return layout.byteOffset(java.lang.foreign.MemoryLayout.PathElement.groupElement(name)); + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinConsoleWriter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinConsoleWriter.java new file mode 100644 index 00000000000..55a2ec65055 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinConsoleWriter.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.IOException; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +import jdk.internal.org.jline.terminal.impl.AbstractWindowsConsoleWriter; + +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.GetStdHandle; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.STD_OUTPUT_HANDLE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.WriteConsoleW; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.getLastErrorMessage; + +class NativeWinConsoleWriter extends AbstractWindowsConsoleWriter { + + private final java.lang.foreign.MemorySegment console = GetStdHandle(STD_OUTPUT_HANDLE); + + @Override + protected void writeConsole(char[] text, int len) throws IOException { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment txt = arena.allocateFrom(ValueLayout.JAVA_CHAR, text); + if (WriteConsoleW(console, txt, len, MemorySegment.NULL, MemorySegment.NULL) == 0) { + throw new IOException("Failed to write to console: " + getLastErrorMessage()); + } + } + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java new file mode 100644 index 00000000000..189fc2808d9 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2022-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.BufferedWriter; +import java.io.IOError; +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.function.Function; +import java.util.function.IntConsumer; + +import jdk.internal.org.jline.terminal.Cursor; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; +import jdk.internal.org.jline.terminal.spi.SystemStream; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.OSUtils; + +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.*; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.GetConsoleMode; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.GetConsoleScreenBufferInfo; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.GetStdHandle; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.INPUT_RECORD; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.INVALID_HANDLE_VALUE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.KEY_EVENT_RECORD; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.MOUSE_EVENT_RECORD; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.STD_ERROR_HANDLE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.STD_INPUT_HANDLE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.STD_OUTPUT_HANDLE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.SetConsoleMode; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.WaitForSingleObject; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.getLastErrorMessage; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.readConsoleInputHelper; + +public class NativeWinSysTerminal extends AbstractWindowsTerminal { + + public static NativeWinSysTerminal createTerminal( + TerminalProvider provider, + SystemStream systemStream, + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + SignalHandler signalHandler, + boolean paused, + Function inputStreamWrapper) + throws IOException { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + // Get input console mode + java.lang.foreign.MemorySegment consoleIn = GetStdHandle(STD_INPUT_HANDLE); + java.lang.foreign.MemorySegment inMode = allocateInt(arena); + if (GetConsoleMode(consoleIn, inMode) == 0) { + throw new IOException("Failed to get console mode: " + getLastErrorMessage()); + } + // Get output console and mode + java.lang.foreign.MemorySegment console; + switch (systemStream) { + case Output: + console = GetStdHandle(STD_OUTPUT_HANDLE); + break; + case Error: + console = GetStdHandle(STD_ERROR_HANDLE); + break; + default: + throw new IllegalArgumentException("Unsupported stream for console: " + systemStream); + } + java.lang.foreign.MemorySegment outMode = allocateInt(arena); + if (GetConsoleMode(console, outMode) == 0) { + throw new IOException("Failed to get console mode: " + getLastErrorMessage()); + } + // Create writer + Writer writer; + if (ansiPassThrough) { + type = type != null ? type : OSUtils.IS_CONEMU ? TYPE_WINDOWS_CONEMU : TYPE_WINDOWS; + writer = new NativeWinConsoleWriter(); + } else { + int m = inMode.get(java.lang.foreign.ValueLayout.JAVA_INT, 0); + if (enableVtp(console, m)) { + type = type != null ? type : TYPE_WINDOWS_VTP; + writer = new NativeWinConsoleWriter(); + } else if (OSUtils.IS_CONEMU) { + type = type != null ? type : TYPE_WINDOWS_CONEMU; + writer = new NativeWinConsoleWriter(); + } else { + type = type != null ? type : TYPE_WINDOWS; + writer = new WindowsAnsiWriter(new BufferedWriter(new NativeWinConsoleWriter())); + } + } + // Create terminal + NativeWinSysTerminal terminal = new NativeWinSysTerminal( + provider, + systemStream, + writer, + name, + type, + encoding, + nativeSignals, + signalHandler, + consoleIn, + inMode.get(java.lang.foreign.ValueLayout.JAVA_INT, 0), + console, + outMode.get(java.lang.foreign.ValueLayout.JAVA_INT, 0), + inputStreamWrapper); + // Start input pump thread + if (!paused) { + terminal.resume(); + } + return terminal; + } + } + + private static boolean enableVtp(java.lang.foreign.MemorySegment console, int m) { + return SetConsoleMode(console, m | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0; + } + + public static boolean isWindowsSystemStream(SystemStream stream) { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment console; + java.lang.foreign.MemorySegment mode = allocateInt(arena); + switch (stream) { + case Input: + console = GetStdHandle(STD_INPUT_HANDLE); + break; + case Output: + console = GetStdHandle(STD_OUTPUT_HANDLE); + break; + case Error: + console = GetStdHandle(STD_ERROR_HANDLE); + break; + default: + return false; + } + return GetConsoleMode(console, mode) != 0; + } + } + + private static java.lang.foreign.MemorySegment allocateInt(java.lang.foreign.Arena arena) { + return arena.allocate(java.lang.foreign.ValueLayout.JAVA_INT); + } + + NativeWinSysTerminal( + TerminalProvider provider, + SystemStream systemStream, + Writer writer, + String name, + String type, + Charset encoding, + boolean nativeSignals, + SignalHandler signalHandler, + java.lang.foreign.MemorySegment inConsole, + int inConsoleMode, + java.lang.foreign.MemorySegment outConsole, + int outConsoleMode, + Function inputStreamWrapper) + throws IOException { + super( + provider, + systemStream, + writer, + name, + type, + encoding, + nativeSignals, + signalHandler, + inConsole, + inConsoleMode, + outConsole, + outConsoleMode, + inputStreamWrapper); + } + + @Override + protected int getConsoleMode(java.lang.foreign.MemorySegment console) { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment mode = arena.allocate(java.lang.foreign.ValueLayout.JAVA_INT); + if (GetConsoleMode(console, mode) == 0) { + return -1; + } + return mode.get(java.lang.foreign.ValueLayout.JAVA_INT, 0); + } + } + + @Override + protected void setConsoleMode(java.lang.foreign.MemorySegment console, int mode) { + SetConsoleMode(console, mode); + } + + public Size getSize() { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(arena); + GetConsoleScreenBufferInfo(outConsole, info); + return new Size(info.windowWidth(), info.windowHeight()); + } + } + + @Override + public Size getBufferSize() { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(arena); + GetConsoleScreenBufferInfo(outConsole, info); + return new Size(info.size().x(), info.size().y()); + } + } + + protected boolean processConsoleInput() throws IOException { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + INPUT_RECORD[] events; + if (inConsole != null + && inConsole.address() != INVALID_HANDLE_VALUE + && WaitForSingleObject(inConsole, 100) == 0) { + events = readConsoleInputHelper(arena, inConsole, 1, false); + } else { + return false; + } + + boolean flush = false; + for (INPUT_RECORD event : events) { + int eventType = event.eventType(); + if (eventType == KEY_EVENT) { + KEY_EVENT_RECORD keyEvent = event.keyEvent(); + processKeyEvent( + keyEvent.keyDown(), keyEvent.keyCode(), keyEvent.uchar(), keyEvent.controlKeyState()); + flush = true; + } else if (eventType == WINDOW_BUFFER_SIZE_EVENT) { + raise(Signal.WINCH); + } else if (eventType == MOUSE_EVENT) { + processMouseEvent(event.mouseEvent()); + flush = true; + } else if (eventType == FOCUS_EVENT) { + processFocusEvent(event.focusEvent().setFocus()); + } + } + + return flush; + } + } + + private final char[] focus = new char[] {'\033', '[', ' '}; + + private void processFocusEvent(boolean hasFocus) throws IOException { + if (focusTracking) { + focus[2] = hasFocus ? 'I' : 'O'; + slaveInputPipe.write(focus); + } + } + + private final char[] mouse = new char[] {'\033', '[', 'M', ' ', ' ', ' '}; + + private void processMouseEvent(MOUSE_EVENT_RECORD mouseEvent) throws IOException { + int dwEventFlags = mouseEvent.eventFlags(); + int dwButtonState = mouseEvent.buttonState(); + if (tracking == MouseTracking.Off + || tracking == MouseTracking.Normal && dwEventFlags == MOUSE_MOVED + || tracking == MouseTracking.Button && dwEventFlags == MOUSE_MOVED && dwButtonState == 0) { + return; + } + int cb = 0; + dwEventFlags &= ~DOUBLE_CLICK; // Treat double-clicks as normal + if (dwEventFlags == MOUSE_WHEELED) { + cb |= 64; + if ((dwButtonState >> 16) < 0) { + cb |= 1; + } + } else if (dwEventFlags == MOUSE_HWHEELED) { + return; + } else if ((dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) != 0) { + cb |= 0x00; + } else if ((dwButtonState & RIGHTMOST_BUTTON_PRESSED) != 0) { + cb |= 0x01; + } else if ((dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) != 0) { + cb |= 0x02; + } else { + cb |= 0x03; + } + int cx = mouseEvent.mousePosition().x(); + int cy = mouseEvent.mousePosition().y(); + mouse[3] = (char) (' ' + cb); + mouse[4] = (char) (' ' + cx + 1); + mouse[5] = (char) (' ' + cy + 1); + slaveInputPipe.write(mouse); + } + + @Override + public Cursor getCursorPosition(IntConsumer discarded) { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(arena); + if (GetConsoleScreenBufferInfo(outConsole, info) == 0) { + throw new IOError(new IOException("Could not get the cursor position: " + getLastErrorMessage())); + } + return new Cursor(info.cursorPosition().x(), info.cursorPosition().y()); + } + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/WindowsAnsiWriter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/WindowsAnsiWriter.java new file mode 100644 index 00000000000..6330e975952 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/WindowsAnsiWriter.java @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2022-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.ffm; + +import java.io.IOException; +import java.io.Writer; + +import jdk.internal.org.jline.utils.AnsiWriter; +import jdk.internal.org.jline.utils.Colors; + +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.BACKGROUND_BLUE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.BACKGROUND_GREEN; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.BACKGROUND_INTENSITY; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.BACKGROUND_RED; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.CHAR_INFO; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.CONSOLE_SCREEN_BUFFER_INFO; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.COORD; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.FOREGROUND_BLUE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.FOREGROUND_GREEN; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.FOREGROUND_INTENSITY; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.FOREGROUND_RED; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.FillConsoleOutputAttribute; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.FillConsoleOutputCharacterW; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.GetConsoleScreenBufferInfo; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.GetStdHandle; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.SMALL_RECT; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.STD_OUTPUT_HANDLE; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.ScrollConsoleScreenBuffer; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.SetConsoleCursorPosition; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.SetConsoleTextAttribute; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.SetConsoleTitleW; +import static jdk.internal.org.jline.terminal.impl.ffm.Kernel32.getLastErrorMessage; + +class WindowsAnsiWriter extends AnsiWriter { + + private static final java.lang.foreign.MemorySegment console = GetStdHandle(STD_OUTPUT_HANDLE); + + private static final short FOREGROUND_BLACK = 0; + private static final short FOREGROUND_YELLOW = (short) (FOREGROUND_RED | FOREGROUND_GREEN); + private static final short FOREGROUND_MAGENTA = (short) (FOREGROUND_BLUE | FOREGROUND_RED); + private static final short FOREGROUND_CYAN = (short) (FOREGROUND_BLUE | FOREGROUND_GREEN); + private static final short FOREGROUND_WHITE = (short) (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + + private static final short BACKGROUND_BLACK = 0; + private static final short BACKGROUND_YELLOW = (short) (BACKGROUND_RED | BACKGROUND_GREEN); + private static final short BACKGROUND_MAGENTA = (short) (BACKGROUND_BLUE | BACKGROUND_RED); + private static final short BACKGROUND_CYAN = (short) (BACKGROUND_BLUE | BACKGROUND_GREEN); + private static final short BACKGROUND_WHITE = (short) (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); + + private static final short[] ANSI_FOREGROUND_COLOR_MAP = { + FOREGROUND_BLACK, + FOREGROUND_RED, + FOREGROUND_GREEN, + FOREGROUND_YELLOW, + FOREGROUND_BLUE, + FOREGROUND_MAGENTA, + FOREGROUND_CYAN, + FOREGROUND_WHITE, + }; + + private static final short[] ANSI_BACKGROUND_COLOR_MAP = { + BACKGROUND_BLACK, + BACKGROUND_RED, + BACKGROUND_GREEN, + BACKGROUND_YELLOW, + BACKGROUND_BLUE, + BACKGROUND_MAGENTA, + BACKGROUND_CYAN, + BACKGROUND_WHITE, + }; + + private final CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(java.lang.foreign.Arena.ofAuto()); + private final short originalColors; + + private boolean negative; + private boolean bold; + private boolean underline; + private short savedX = -1; + private short savedY = -1; + + public WindowsAnsiWriter(Writer out) throws IOException { + super(out); + getConsoleInfo(); + originalColors = info.attributes(); + } + + private void getConsoleInfo() throws IOException { + out.flush(); + if (GetConsoleScreenBufferInfo(console, info) == 0) { + throw new IOException("Could not get the screen info: " + getLastErrorMessage()); + } + if (negative) { + info.attributes(invertAttributeColors(info.attributes())); + } + } + + private void applyAttribute() throws IOException { + out.flush(); + short attributes = info.attributes(); + // bold is simulated by high foreground intensity + if (bold) { + attributes |= FOREGROUND_INTENSITY; + } + // underline is simulated by high foreground intensity + if (underline) { + attributes |= BACKGROUND_INTENSITY; + } + if (negative) { + attributes = invertAttributeColors(attributes); + } + if (SetConsoleTextAttribute(console, attributes) == 0) { + throw new IOException(getLastErrorMessage()); + } + } + + private short invertAttributeColors(short attributes) { + // Swap the the Foreground and Background bits. + int fg = 0x000F & attributes; + fg <<= 4; + int bg = 0X00F0 & attributes; + bg >>= 4; + attributes = (short) ((attributes & 0xFF00) | fg | bg); + return attributes; + } + + private void applyCursorPosition() throws IOException { + info.cursorPosition().x((short) + Math.max(0, Math.min(info.size().x() - 1, info.cursorPosition().x()))); + info.cursorPosition().y((short) + Math.max(0, Math.min(info.size().y() - 1, info.cursorPosition().y()))); + if (SetConsoleCursorPosition(console, info.cursorPosition()) == 0) { + throw new IOException(getLastErrorMessage()); + } + } + + @Override + protected void processEraseScreen(int eraseOption) throws IOException { + getConsoleInfo(); + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment written = arena.allocate(java.lang.foreign.ValueLayout.JAVA_INT); + switch (eraseOption) { + case ERASE_SCREEN -> { + COORD topLeft = new COORD(arena, (short) 0, info.window().top()); + int screenLength = info.window().height() * info.size().x(); + FillConsoleOutputAttribute(console, originalColors, screenLength, topLeft, written); + FillConsoleOutputCharacterW(console, ' ', screenLength, topLeft, written); + } + case ERASE_SCREEN_TO_BEGINING -> { + COORD topLeft2 = new COORD(arena, (short) 0, info.window().top()); + int lengthToCursor = + (info.cursorPosition().y() - info.window().top()) + * info.size().x() + + info.cursorPosition().x(); + FillConsoleOutputAttribute(console, originalColors, lengthToCursor, topLeft2, written); + FillConsoleOutputCharacterW(console, ' ', lengthToCursor, topLeft2, written); + } + case ERASE_SCREEN_TO_END -> { + int lengthToEnd = + (info.window().bottom() - info.cursorPosition().y()) + * info.size().x() + + (info.size().x() - info.cursorPosition().x()); + FillConsoleOutputAttribute(console, originalColors, lengthToEnd, info.cursorPosition(), written); + FillConsoleOutputCharacterW(console, ' ', lengthToEnd, info.cursorPosition(), written); + } + default -> {} + } + } + } + + @Override + protected void processEraseLine(int eraseOption) throws IOException { + getConsoleInfo(); + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment written = arena.allocate(java.lang.foreign.ValueLayout.JAVA_INT); + switch (eraseOption) { + case ERASE_LINE -> { + COORD leftColCurrRow = + new COORD(arena, (short) 0, info.cursorPosition().y()); + FillConsoleOutputAttribute( + console, originalColors, info.size().x(), leftColCurrRow, written); + FillConsoleOutputCharacterW(console, ' ', info.size().x(), leftColCurrRow, written); + } + case ERASE_LINE_TO_BEGINING -> { + COORD leftColCurrRow2 = + new COORD(arena, (short) 0, info.cursorPosition().y()); + FillConsoleOutputAttribute( + console, originalColors, info.cursorPosition().x(), leftColCurrRow2, written); + FillConsoleOutputCharacterW( + console, ' ', info.cursorPosition().x(), leftColCurrRow2, written); + } + case ERASE_LINE_TO_END -> { + int lengthToLastCol = + info.size().x() - info.cursorPosition().x(); + FillConsoleOutputAttribute( + console, originalColors, lengthToLastCol, info.cursorPosition(), written); + FillConsoleOutputCharacterW(console, ' ', lengthToLastCol, info.cursorPosition(), written); + } + default -> {} + } + } + } + + protected void processCursorUpLine(int count) throws IOException { + getConsoleInfo(); + info.cursorPosition().x((short) 0); + info.cursorPosition().y((short) (info.cursorPosition().y() - count)); + applyCursorPosition(); + } + + protected void processCursorDownLine(int count) throws IOException { + getConsoleInfo(); + info.cursorPosition().x((short) 0); + info.cursorPosition().y((short) (info.cursorPosition().y() + count)); + applyCursorPosition(); + } + + @Override + protected void processCursorLeft(int count) throws IOException { + getConsoleInfo(); + info.cursorPosition().x((short) (info.cursorPosition().x() - count)); + applyCursorPosition(); + } + + @Override + protected void processCursorRight(int count) throws IOException { + getConsoleInfo(); + info.cursorPosition().x((short) (info.cursorPosition().x() + count)); + applyCursorPosition(); + } + + @Override + protected void processCursorDown(int count) throws IOException { + getConsoleInfo(); + int nb = Math.max(0, info.cursorPosition().y() + count - info.size().y() + 1); + if (nb != count) { + info.cursorPosition().y((short) (info.cursorPosition().y() + count)); + applyCursorPosition(); + } + if (nb > 0) { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + SMALL_RECT scroll = new SMALL_RECT(arena, info.window()); + scroll.top((short) 0); + COORD org = new COORD(arena); + org.x((short) 0); + org.y((short) (-nb)); + CHAR_INFO info = new CHAR_INFO(arena, ' ', originalColors); + ScrollConsoleScreenBuffer(console, scroll, scroll, org, info); + } + } + } + + @Override + protected void processCursorUp(int count) throws IOException { + getConsoleInfo(); + info.cursorPosition().y((short) (info.cursorPosition().y() - count)); + applyCursorPosition(); + } + + @Override + protected void processCursorTo(int row, int col) throws IOException { + getConsoleInfo(); + info.cursorPosition().y((short) (info.window().top() + row - 1)); + info.cursorPosition().x((short) (col - 1)); + applyCursorPosition(); + } + + @Override + protected void processCursorToColumn(int x) throws IOException { + getConsoleInfo(); + info.cursorPosition().x((short) (x - 1)); + applyCursorPosition(); + } + + @Override + protected void processSetForegroundColorExt(int paletteIndex) throws IOException { + int color = Colors.roundColor(paletteIndex, 16); + info.attributes((short) ((info.attributes() & ~0x0007) | ANSI_FOREGROUND_COLOR_MAP[color & 0x07])); + info.attributes( + (short) ((info.attributes() & ~FOREGROUND_INTENSITY) | (color >= 8 ? FOREGROUND_INTENSITY : 0))); + applyAttribute(); + } + + @Override + protected void processSetBackgroundColorExt(int paletteIndex) throws IOException { + int color = Colors.roundColor(paletteIndex, 16); + info.attributes((short) ((info.attributes() & ~0x0070) | ANSI_BACKGROUND_COLOR_MAP[color & 0x07])); + info.attributes( + (short) ((info.attributes() & ~BACKGROUND_INTENSITY) | (color >= 8 ? BACKGROUND_INTENSITY : 0))); + applyAttribute(); + } + + @Override + protected void processDefaultTextColor() throws IOException { + info.attributes((short) ((info.attributes() & ~0x000F) | (originalColors & 0xF))); + info.attributes((short) (info.attributes() & ~FOREGROUND_INTENSITY)); + applyAttribute(); + } + + @Override + protected void processDefaultBackgroundColor() throws IOException { + info.attributes((short) ((info.attributes() & ~0x00F0) | (originalColors & 0xF0))); + info.attributes((short) (info.attributes() & ~BACKGROUND_INTENSITY)); + applyAttribute(); + } + + @Override + protected void processAttributeRest() throws IOException { + info.attributes((short) ((info.attributes() & ~0x00FF) | originalColors)); + this.negative = false; + this.bold = false; + this.underline = false; + applyAttribute(); + } + + @Override + protected void processSetAttribute(int attribute) throws IOException { + switch (attribute) { + case ATTRIBUTE_INTENSITY_BOLD -> { + bold = true; + applyAttribute(); + } + case ATTRIBUTE_INTENSITY_NORMAL -> { + bold = false; + applyAttribute(); + } + case ATTRIBUTE_UNDERLINE -> { + underline = true; + applyAttribute(); + } + case ATTRIBUTE_UNDERLINE_OFF -> { + underline = false; + applyAttribute(); + } + case ATTRIBUTE_NEGATIVE_ON -> { + negative = true; + applyAttribute(); + } + case ATTRIBUTE_NEGATIVE_OFF -> { + negative = false; + applyAttribute(); + } + default -> {} + } + } + + @Override + protected void processSaveCursorPosition() throws IOException { + getConsoleInfo(); + savedX = info.cursorPosition().x(); + savedY = info.cursorPosition().y(); + } + + @Override + protected void processRestoreCursorPosition() throws IOException { + // restore only if there was a save operation first + if (savedX != -1 && savedY != -1) { + out.flush(); + info.cursorPosition().x(savedX); + info.cursorPosition().y(savedY); + applyCursorPosition(); + } + } + + @Override + protected void processInsertLine(int optionInt) throws IOException { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + getConsoleInfo(); + SMALL_RECT scroll = info.window().copy(arena); + scroll.top(info.cursorPosition().y()); + COORD org = + new COORD(arena, (short) 0, (short) (info.cursorPosition().y() + optionInt)); + CHAR_INFO info = new CHAR_INFO(arena, ' ', originalColors); + if (ScrollConsoleScreenBuffer(console, scroll, scroll, org, info) == 0) { + throw new IOException(getLastErrorMessage()); + } + } + } + + @Override + protected void processDeleteLine(int optionInt) throws IOException { + try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) { + getConsoleInfo(); + SMALL_RECT scroll = info.window().copy(arena); + scroll.top(info.cursorPosition().y()); + COORD org = + new COORD(arena, (short) 0, (short) (info.cursorPosition().y() - optionInt)); + CHAR_INFO info = new CHAR_INFO(arena, ' ', originalColors); + if (ScrollConsoleScreenBuffer(console, scroll, scroll, org, info) == 0) { + throw new IOException(getLastErrorMessage()); + } + } + } + + @Override + protected void processChangeWindowTitle(String title) { + try (java.lang.foreign.Arena session = java.lang.foreign.Arena.ofConfined()) { + java.lang.foreign.MemorySegment str = session.allocateFrom(title); + SetConsoleTitleW(str); + } + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/jna/LastErrorException.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/jna/LastErrorException.java deleted file mode 100644 index 63795664dfc..00000000000 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/jna/LastErrorException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.org.jline.terminal.impl.jna; - -@SuppressWarnings("serial") -public class LastErrorException extends RuntimeException{ - - public final long lastError; - - public LastErrorException(long lastError) { - this.lastError = lastError; - } - -} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/Pty.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/Pty.java index b1e22056702..d72e0e669d1 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/Pty.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/Pty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -34,4 +34,7 @@ public interface Pty extends Closeable { void setSize(Size size) throws IOException; + SystemStream getSystemStream(); + + TerminalProvider getProvider(); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/SystemStream.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/SystemStream.java new file mode 100644 index 00000000000..5f950248295 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/SystemStream.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.spi; + +public enum SystemStream { + Input, + Output, + Error +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalExt.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalExt.java new file mode 100644 index 00000000000..00cfb2e9d47 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalExt.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.spi; + +import jdk.internal.org.jline.terminal.Terminal; + +/** + * The {@code TerminalExt} interface is implemented by {@code Terminal}s + * and provides access to the Terminal's internals. + */ +public interface TerminalExt extends Terminal { + + /** + * Returns the {@code TerminalProvider} that created this terminal + * or {@code null} if the terminal was created with no provider. + */ + TerminalProvider getProvider(); + + /** + * The underlying system stream, may be {@link SystemStream#Output}, + * {@link SystemStream#Error}, or {@code null} if this terminal is not bound + * to a system stream. + */ + SystemStream getSystemStream(); +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java index 69f353c5719..055bf224fc5 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, the original author or authors. + * Copyright (c) 2022, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -11,58 +11,60 @@ package jdk.internal.org.jline.terminal.spi; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.URL; import java.nio.charset.Charset; import java.util.Properties; -import java.util.ServiceLoader; import java.util.function.Function; import jdk.internal.org.jline.terminal.Attributes; import jdk.internal.org.jline.terminal.Size; import jdk.internal.org.jline.terminal.Terminal; import jdk.internal.org.jline.terminal.impl.exec.ExecTerminalProvider; +import jdk.internal.org.jline.terminal.impl.ffm.FfmTerminalProvider; -public interface TerminalProvider -{ - - enum Stream { - Input, - Output, - Error - } +public interface TerminalProvider { String name(); - Terminal sysTerminal(String name, String type, boolean ansiPassThrough, - Charset encoding, boolean nativeSignals, - Terminal.SignalHandler signalHandler, boolean paused, - Stream consoleStream, Function inputStreamWrapper) throws IOException; + Terminal sysTerminal( + String name, + String type, + boolean ansiPassThrough, + Charset encoding, + boolean nativeSignals, + Terminal.SignalHandler signalHandler, + boolean paused, + SystemStream systemStream, + Function inputStreamWrapper) + throws IOException; - Terminal newTerminal(String name, String type, - InputStream masterInput, OutputStream masterOutput, - Charset encoding, Terminal.SignalHandler signalHandler, - boolean paused, Attributes attributes, Size size) throws IOException; + Terminal newTerminal( + String name, + String type, + InputStream masterInput, + OutputStream masterOutput, + Charset encoding, + Terminal.SignalHandler signalHandler, + boolean paused, + Attributes attributes, + Size size) + throws IOException; - boolean isSystemStream(Stream stream); + boolean isSystemStream(SystemStream stream); - String systemStreamName(Stream stream); + String systemStreamName(SystemStream stream); + + int systemStreamWidth(SystemStream stream); static TerminalProvider load(String name) throws IOException { switch (name) { case "exec": return new ExecTerminalProvider(); - case "jna": { - try { - return (TerminalProvider) Class.forName("jdk.internal.org.jline.terminal.impl.jna.JnaTerminalProvider").getConstructor().newInstance(); - } catch (ReflectiveOperationException t) { - throw new IOException(t); - } - } + case "ffm": return new FfmTerminalProvider(); } ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) { cl = ClassLoader.getSystemClassLoader(); } - InputStream is = cl.getResourceAsStream( "META-INF/services/org/jline/terminal/provider/" + name); + InputStream is = cl.getResourceAsStream("META-INF/services/org/jline/terminal/provider/" + name); if (is != null) { Properties props = new Properties(); try { @@ -71,14 +73,13 @@ public interface TerminalProvider if (className == null) { throw new IOException("No class defined in terminal provider file " + name); } - Class clazz = cl.loadClass( className ); + Class clazz = cl.loadClass(className); return (TerminalProvider) clazz.getConstructor().newInstance(); - } catch ( Exception e ) { - throw new IOException("Unable to load terminal provider " + name, e); + } catch (Exception e) { + throw new IOException("Unable to load terminal provider " + name + ": " + e.getMessage(), e); } } else { throw new IOException("Unable to find terminal provider " + name); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AnsiWriter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AnsiWriter.java index 081665a2d46..32d8282d4c0 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AnsiWriter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AnsiWriter.java @@ -1,17 +1,10 @@ /* - * Copyright (C) 2009-2018 the original author(s). + * Copyright (c) 2009-2018, the original author(s). * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * https://opensource.org/licenses/BSD-3-Clause */ package jdk.internal.org.jline.utils; @@ -252,12 +245,10 @@ public class AnsiWriter extends FilterWriter { * @throws IOException if no more non-null values left */ private int getNextOptionInt(Iterator optionsIterator) throws IOException { - for (;;) { - if (!optionsIterator.hasNext()) - throw new IllegalArgumentException(); + for (; ; ) { + if (!optionsIterator.hasNext()) throw new IllegalArgumentException(); Object arg = optionsIterator.next(); - if (arg != null) - return (Integer) arg; + if (arg != null) return (Integer) arg; } } @@ -346,27 +337,21 @@ public class AnsiWriter extends FilterWriter { int g = getNextOptionInt(optionsIterator); int b = getNextOptionInt(optionsIterator); if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) { - if (value == 38) - processSetForegroundColorExt(r, g, b); - else - processSetBackgroundColorExt(r, g, b); + if (value == 38) processSetForegroundColorExt(r, g, b); + else processSetBackgroundColorExt(r, g, b); } else { throw new IllegalArgumentException(); } - } - else if (arg2or5 == 5) { + } else if (arg2or5 == 5) { // 256 color style like `esc[38;5;m` int paletteIndex = getNextOptionInt(optionsIterator); if (paletteIndex >= 0 && paletteIndex <= 255) { - if (value == 38) - processSetForegroundColorExt(paletteIndex); - else - processSetBackgroundColorExt(paletteIndex); + if (value == 38) processSetForegroundColorExt(paletteIndex); + else processSetBackgroundColorExt(paletteIndex); } else { throw new IllegalArgumentException(); } - } - else { + } else { throw new IllegalArgumentException(); } } else { @@ -449,47 +434,41 @@ public class AnsiWriter extends FilterWriter { * Process CSI u ANSI code, corresponding to RCP \u2013 Restore Cursor Position * @throws IOException if an error occurs */ - protected void processRestoreCursorPosition() throws IOException { - } + protected void processRestoreCursorPosition() throws IOException {} /** * Process CSI s ANSI code, corresponding to SCP \u2013 Save Cursor Position * @throws IOException if an error occurs */ - protected void processSaveCursorPosition() throws IOException { - } + protected void processSaveCursorPosition() throws IOException {} /** * Process CSI s ANSI code, corresponding to IL \u2013 Insert Line * @param optionInt the option * @throws IOException if an error occurs */ - protected void processInsertLine(int optionInt) throws IOException { - } + protected void processInsertLine(int optionInt) throws IOException {} /** * Process CSI s ANSI code, corresponding to DL \u2013 Delete Line * @param optionInt the option * @throws IOException if an error occurs */ - protected void processDeleteLine(int optionInt) throws IOException { - } + protected void processDeleteLine(int optionInt) throws IOException {} /** * Process CSI n T ANSI code, corresponding to SD \u2013 Scroll Down * @param optionInt the option * @throws IOException if an error occurs */ - protected void processScrollDown(int optionInt) throws IOException { - } + protected void processScrollDown(int optionInt) throws IOException {} /** * Process CSI n U ANSI code, corresponding to SU \u2013 Scroll Up * @param optionInt the option * @throws IOException if an error occurs */ - protected void processScrollUp(int optionInt) throws IOException { - } + protected void processScrollUp(int optionInt) throws IOException {} protected static final int ERASE_SCREEN_TO_END = 0; protected static final int ERASE_SCREEN_TO_BEGINING = 1; @@ -500,8 +479,7 @@ public class AnsiWriter extends FilterWriter { * @param eraseOption the erase option * @throws IOException if an error occurs */ - protected void processEraseScreen(int eraseOption) throws IOException { - } + protected void processEraseScreen(int eraseOption) throws IOException {} protected static final int ERASE_LINE_TO_END = 0; protected static final int ERASE_LINE_TO_BEGINING = 1; @@ -512,25 +490,27 @@ public class AnsiWriter extends FilterWriter { * @param eraseOption the erase option * @throws IOException if an error occurs */ - protected void processEraseLine(int eraseOption) throws IOException { - } + protected void processEraseLine(int eraseOption) throws IOException {} + + protected static final int ATTRIBUTE_INTENSITY_BOLD = 1; // Intensity: Bold + protected static final int ATTRIBUTE_INTENSITY_FAINT = 2; // Intensity; Faint not widely supported + protected static final int ATTRIBUTE_ITALIC = 3; // Italic; on not widely supported. Sometimes treated as inverse. + protected static final int ATTRIBUTE_UNDERLINE = 4; // Underline; Single + protected static final int ATTRIBUTE_BLINK_SLOW = 5; // Blink; Slow less than 150 per minute + protected static final int ATTRIBUTE_BLINK_FAST = 6; // Blink; Rapid MS-DOS ANSI.SYS; 150 per minute or more + protected static final int ATTRIBUTE_NEGATIVE_ON = + 7; // Image; Negative inverse or reverse; swap foreground and background + protected static final int ATTRIBUTE_CONCEAL_ON = 8; // Conceal on + protected static final int ATTRIBUTE_UNDERLINE_DOUBLE = 21; // Underline; Double not widely supported + protected static final int ATTRIBUTE_INTENSITY_NORMAL = 22; // Intensity; Normal not bold and not faint + protected static final int ATTRIBUTE_UNDERLINE_OFF = 24; // Underline; None + protected static final int ATTRIBUTE_BLINK_OFF = 25; // Blink; off - protected static final int ATTRIBUTE_INTENSITY_BOLD = 1; // Intensity: Bold - protected static final int ATTRIBUTE_INTENSITY_FAINT = 2; // Intensity; Faint not widely supported - protected static final int ATTRIBUTE_ITALIC = 3; // Italic; on not widely supported. Sometimes treated as inverse. - protected static final int ATTRIBUTE_UNDERLINE = 4; // Underline; Single - protected static final int ATTRIBUTE_BLINK_SLOW = 5; // Blink; Slow less than 150 per minute - protected static final int ATTRIBUTE_BLINK_FAST = 6; // Blink; Rapid MS-DOS ANSI.SYS; 150 per minute or more - protected static final int ATTRIBUTE_NEGATIVE_ON = 7; // Image; Negative inverse or reverse; swap foreground and background - protected static final int ATTRIBUTE_CONCEAL_ON = 8; // Conceal on - protected static final int ATTRIBUTE_UNDERLINE_DOUBLE = 21; // Underline; Double not widely supported - protected static final int ATTRIBUTE_INTENSITY_NORMAL = 22; // Intensity; Normal not bold and not faint - protected static final int ATTRIBUTE_UNDERLINE_OFF = 24; // Underline; None - protected static final int ATTRIBUTE_BLINK_OFF = 25; // Blink; off @Deprecated protected static final int ATTRIBUTE_NEGATIVE_Off = 27; // Image; Positive + protected static final int ATTRIBUTE_NEGATIVE_OFF = 27; // Image; Positive - protected static final int ATTRIBUTE_CONCEAL_OFF = 28; // Reveal conceal off + protected static final int ATTRIBUTE_CONCEAL_OFF = 28; // Reveal conceal off /** * process SGR other than 0 (reset), 30-39 (foreground), @@ -546,8 +526,7 @@ public class AnsiWriter extends FilterWriter { * @see #processDefaultTextColor() * @see #processDefaultBackgroundColor() */ - protected void processSetAttribute(int attribute) throws IOException { - } + protected void processSetAttribute(int attribute) throws IOException {} protected static final int BLACK = 0; protected static final int RED = 1; @@ -584,8 +563,7 @@ public class AnsiWriter extends FilterWriter { * @param paletteIndex the text color in the palette * @throws IOException if an error occurs */ - protected void processSetForegroundColorExt(int paletteIndex) throws IOException { - } + protected void processSetForegroundColorExt(int paletteIndex) throws IOException {} /** * process SGR 38 corresponding to extended set text color (foreground) @@ -625,8 +603,7 @@ public class AnsiWriter extends FilterWriter { * @param paletteIndex the background color in the palette * @throws IOException if an error occurs */ - protected void processSetBackgroundColorExt(int paletteIndex) throws IOException { - } + protected void processSetBackgroundColorExt(int paletteIndex) throws IOException {} /** * process SGR 48 corresponding to extended set background color @@ -644,22 +621,19 @@ public class AnsiWriter extends FilterWriter { * process SGR 39 corresponding to Default text color (foreground) * @throws IOException if an error occurs */ - protected void processDefaultTextColor() throws IOException { - } + protected void processDefaultTextColor() throws IOException {} /** * process SGR 49 corresponding to Default background color * @throws IOException if an error occurs */ - protected void processDefaultBackgroundColor() throws IOException { - } + protected void processDefaultBackgroundColor() throws IOException {} /** * process SGR 0 corresponding to Reset / Normal * @throws IOException if an error occurs */ - protected void processAttributeRest() throws IOException { - } + protected void processAttributeRest() throws IOException {} /** * process CSI n ; m H corresponding to CUP \u2013 Cursor Position or @@ -668,24 +642,21 @@ public class AnsiWriter extends FilterWriter { * @param col the column * @throws IOException if an error occurs */ - protected void processCursorTo(int row, int col) throws IOException { - } + protected void processCursorTo(int row, int col) throws IOException {} /** * process CSI n G corresponding to CHA \u2013 Cursor Horizontal Absolute * @param x the column * @throws IOException if an error occurs */ - protected void processCursorToColumn(int x) throws IOException { - } + protected void processCursorToColumn(int x) throws IOException {} /** * process CSI n F corresponding to CPL \u2013 Cursor Previous Line * @param count line count * @throws IOException if an error occurs */ - protected void processCursorUpLine(int count) throws IOException { - } + protected void processCursorUpLine(int count) throws IOException {} /** * process CSI n E corresponding to CNL \u2013 Cursor Next Line @@ -704,8 +675,7 @@ public class AnsiWriter extends FilterWriter { * @param count the count * @throws IOException if an error occurs */ - protected void processCursorLeft(int count) throws IOException { - } + protected void processCursorLeft(int count) throws IOException {} /** * process CSI n C corresponding to CUF \u2013 Cursor Forward @@ -724,19 +694,16 @@ public class AnsiWriter extends FilterWriter { * @param count the count * @throws IOException if an error occurs */ - protected void processCursorDown(int count) throws IOException { - } + protected void processCursorDown(int count) throws IOException {} /** * process CSI n A corresponding to CUU \u2013 Cursor Up * @param count the count * @throws IOException if an error occurs */ - protected void processCursorUp(int count) throws IOException { - } + protected void processCursorUp(int count) throws IOException {} - protected void processUnknownExtension(ArrayList options, int command) { - } + protected void processUnknownExtension(ArrayList options, int command) {} /** * process OSC 0;text BEL corresponding to Change Window and Icon label @@ -751,23 +718,20 @@ public class AnsiWriter extends FilterWriter { * process OSC 1;text BEL corresponding to Change Icon label * @param name the icon name */ - protected void processChangeIconName(String name) { - } + protected void processChangeIconName(String name) {} /** * process OSC 2;text BEL corresponding to Change Window title * @param title the title */ - protected void processChangeWindowTitle(String title) { - } + protected void processChangeWindowTitle(String title) {} /** * Process unknown OSC command. * @param command the command * @param param the param */ - protected void processUnknownOperatingSystemCommand(int command, String param) { - } + protected void processUnknownOperatingSystemCommand(int command, String param) {} /** * Process character set sequence. @@ -781,17 +745,13 @@ public class AnsiWriter extends FilterWriter { return true; } - protected void processCharsetSelect(int set, char seq) { - } + protected void processCharsetSelect(int set, char seq) {} private int optionInt(ArrayList options, int index) { - if (options.size() <= index) - throw new IllegalArgumentException(); + if (options.size() <= index) throw new IllegalArgumentException(); Object value = options.get(index); - if (value == null) - throw new IllegalArgumentException(); - if (!value.getClass().equals(Integer.class)) - throw new IllegalArgumentException(); + if (value == null) throw new IllegalArgumentException(); + if (!value.getClass().equals(Integer.class)) throw new IllegalArgumentException(); return (Integer) value; } @@ -828,5 +788,4 @@ public class AnsiWriter extends FilterWriter { flush(); super.close(); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedCharSequence.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedCharSequence.java index ccb0aaf689b..6386f5bba39 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedCharSequence.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedCharSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -15,6 +15,7 @@ import jdk.internal.org.jline.terminal.Terminal; import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; import jdk.internal.org.jline.utils.InfoCmp.Capability; +import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_DISABLE_ALTERNATE_CHARSET; import static jdk.internal.org.jline.utils.AttributedStyle.BG_COLOR; import static jdk.internal.org.jline.utils.AttributedStyle.BG_COLOR_EXP; import static jdk.internal.org.jline.utils.AttributedStyle.FG_COLOR; @@ -30,12 +31,11 @@ import static jdk.internal.org.jline.utils.AttributedStyle.F_FAINT; import static jdk.internal.org.jline.utils.AttributedStyle.F_FOREGROUND; import static jdk.internal.org.jline.utils.AttributedStyle.F_FOREGROUND_IND; import static jdk.internal.org.jline.utils.AttributedStyle.F_FOREGROUND_RGB; +import static jdk.internal.org.jline.utils.AttributedStyle.F_HIDDEN; import static jdk.internal.org.jline.utils.AttributedStyle.F_INVERSE; import static jdk.internal.org.jline.utils.AttributedStyle.F_ITALIC; import static jdk.internal.org.jline.utils.AttributedStyle.F_UNDERLINE; -import static jdk.internal.org.jline.utils.AttributedStyle.F_HIDDEN; import static jdk.internal.org.jline.utils.AttributedStyle.MASK; -import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_DISABLE_ALTERNATE_CHARSET; public abstract class AttributedCharSequence implements CharSequence { @@ -120,6 +120,7 @@ public abstract class AttributedCharSequence implements CharSequence { char c = charAt(i); if (altIn != null && altOut != null) { char pc = c; + // @spotless:off switch (c) { case '\u2518': c = 'j'; break; case '\u2510': c = 'k'; break; @@ -133,15 +134,16 @@ public abstract class AttributedCharSequence implements CharSequence { case '\u252C': c = 'w'; break; case '\u2502': c = 'x'; break; } + // @spotless:on boolean oldalt = alt; alt = c != pc; if (oldalt ^ alt) { sb.append(alt ? altIn : altOut); } } - long s = styleCodeAt(i) & ~F_HIDDEN; // The hidden flag does not change the ansi styles + long s = styleCodeAt(i) & ~F_HIDDEN; // The hidden flag does not change the ansi styles if (style != s) { - long d = (style ^ s) & MASK; + long d = (style ^ s) & MASK; long fg = (s & F_FOREGROUND) != 0 ? s & (FG_COLOR | F_FOREGROUND) : 0; long bg = (s & F_BACKGROUND) != 0 ? s & (BG_COLOR | F_BACKGROUND) : 0; if (s == 0) { @@ -172,16 +174,16 @@ public abstract class AttributedCharSequence implements CharSequence { if (fg > 0) { int rounded = -1; if ((fg & F_FOREGROUND_RGB) != 0) { - int r = (int)(fg >> (FG_COLOR_EXP + 16)) & 0xFF; - int g = (int)(fg >> (FG_COLOR_EXP + 8)) & 0xFF; - int b = (int)(fg >> FG_COLOR_EXP) & 0xFF; + int r = (int) (fg >> (FG_COLOR_EXP + 16)) & 0xFF; + int g = (int) (fg >> (FG_COLOR_EXP + 8)) & 0xFF; + int b = (int) (fg >> FG_COLOR_EXP) & 0xFF; if (colors >= HIGH_COLORS) { first = attr(sb, "38;2;" + r + ";" + g + ";" + b, first); } else { rounded = palette.round(r, g, b); } } else if ((fg & F_FOREGROUND_IND) != 0) { - rounded = palette.round((int)(fg >> FG_COLOR_EXP) & 0xFF); + rounded = palette.round((int) (fg >> FG_COLOR_EXP) & 0xFF); } if (rounded >= 0) { if (colors >= HIGH_COLORS && force == ForceMode.ForceTrueColors) { @@ -211,16 +213,16 @@ public abstract class AttributedCharSequence implements CharSequence { if (bg > 0) { int rounded = -1; if ((bg & F_BACKGROUND_RGB) != 0) { - int r = (int)(bg >> (BG_COLOR_EXP + 16)) & 0xFF; - int g = (int)(bg >> (BG_COLOR_EXP + 8)) & 0xFF; - int b = (int)(bg >> BG_COLOR_EXP) & 0xFF; + int r = (int) (bg >> (BG_COLOR_EXP + 16)) & 0xFF; + int g = (int) (bg >> (BG_COLOR_EXP + 8)) & 0xFF; + int b = (int) (bg >> BG_COLOR_EXP) & 0xFF; if (colors >= HIGH_COLORS) { first = attr(sb, "48;2;" + r + ";" + g + ";" + b, first); } else { rounded = palette.round(r, g, b); } } else if ((bg & F_BACKGROUND_IND) != 0) { - rounded = palette.round((int)(bg >> BG_COLOR_EXP) & 0xFF); + rounded = palette.round((int) (bg >> BG_COLOR_EXP) & 0xFF); } if (rounded >= 0) { if (colors >= HIGH_COLORS && force == ForceMode.ForceTrueColors) { @@ -243,8 +245,7 @@ public abstract class AttributedCharSequence implements CharSequence { background = bg; } if ((d & (F_BOLD | F_FAINT)) != 0) { - if ( (d & F_BOLD) != 0 && (s & F_BOLD) == 0 - || (d & F_FAINT) != 0 && (s & F_FAINT) == 0) { + if ((d & F_BOLD) != 0 && (s & F_BOLD) == 0 || (d & F_FAINT) != 0 && (s & F_FAINT) == 0) { first = attr(sb, "22", first); } if ((d & F_BOLD) != 0 && (s & F_BOLD) != 0) { @@ -360,8 +361,7 @@ public abstract class AttributedCharSequence implements CharSequence { int len = length(); for (int cur = 0; cur < len; ) { int cp = codePointAt(cur); - if (!isHidden(cur)) - cols += WCWidth.wcwidth(cp); + if (!isHidden(cur)) cols += WCWidth.wcwidth(cp); cur += Character.charCount(cp); } return cols; @@ -382,8 +382,7 @@ public abstract class AttributedCharSequence implements CharSequence { int end = begin; while (end < this.length()) { int cp = codePointAt(end); - if (cp == '\n') - break; + if (cp == '\n') break; int w = isHidden(end) ? 0 : WCWidth.wcwidth(cp); if (col + w > stop) { break; @@ -407,7 +406,7 @@ public abstract class AttributedCharSequence implements CharSequence { int cp = codePointAt(cur); int w = isHidden(cur) ? 0 : WCWidth.wcwidth(cp); if (cp == '\n') { - strings.add(subSequence(beg, includeNewlines ? cur+1 : cur)); + strings.add(subSequence(beg, includeNewlines ? cur + 1 : cur)); beg = cur + 1; col = 0; } else if ((col += w) > columns) { @@ -429,5 +428,4 @@ public abstract class AttributedCharSequence implements CharSequence { public AttributedString toAttributedString() { return substring(0, length()); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedString.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedString.java index 47492b72e76..3c70a6d0e7b 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedString.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -15,6 +15,8 @@ import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; +import jdk.internal.org.jline.terminal.Terminal; + /** * Attributed string. * Instances of this class are immutables. @@ -103,11 +105,28 @@ public class AttributedString extends AttributedCharSequence { } public static AttributedString fromAnsi(String ansi, List tabs) { + return fromAnsi(ansi, tabs, null, null); + } + + public static AttributedString fromAnsi(String ansi, Terminal terminal) { + String alternateIn, alternateOut; + if (!DISABLE_ALTERNATE_CHARSET) { + alternateIn = Curses.tputs(terminal.getStringCapability(InfoCmp.Capability.enter_alt_charset_mode)); + alternateOut = Curses.tputs(terminal.getStringCapability(InfoCmp.Capability.exit_alt_charset_mode)); + } else { + alternateIn = null; + alternateOut = null; + } + return fromAnsi(ansi, Arrays.asList(0), alternateIn, alternateOut); + } + + public static AttributedString fromAnsi(String ansi, List tabs, String altIn, String altOut) { if (ansi == null) { return null; } return new AttributedStringBuilder(ansi.length()) .tabs(tabs) + .altCharset(altIn, altOut) .ansiAppend(ansi) .toAttributedString(); } @@ -116,9 +135,7 @@ public class AttributedString extends AttributedCharSequence { if (ansi == null) { return null; } - return new AttributedStringBuilder(ansi.length()) - .ansiAppend(ansi) - .toString(); + return new AttributedStringBuilder(ansi.length()).ansiAppend(ansi).toString(); } @Override @@ -162,7 +179,7 @@ public class AttributedString extends AttributedCharSequence { } result = matcher.find(); } while (result); - return new AttributedString(buffer, newstyle, start , end); + return new AttributedString(buffer, newstyle, start, end); } return this; } @@ -179,15 +196,16 @@ public class AttributedString extends AttributedCharSequence { private boolean arrEq(char[] a1, char[] a2, int s1, int s2, int l) { for (int i = 0; i < l; i++) { - if (a1[s1+i] != a2[s2+i]) { + if (a1[s1 + i] != a2[s2 + i]) { return false; } } return true; } + private boolean arrEq(long[] a1, long[] a2, int s1, int s2, int l) { for (int i = 0; i < l; i++) { - if (a1[s1+i] != a2[s2+i]) { + if (a1[s1 + i] != a2[s2 + i]) { return false; } } @@ -221,5 +239,4 @@ public class AttributedString extends AttributedCharSequence { } return sb.toAttributedString(); } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStringBuilder.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStringBuilder.java index 779675348c9..554381d367d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStringBuilder.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStringBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -27,6 +27,9 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A private long[] style; private int length; private TabStops tabs = new TabStops(0); + private char[] altIn; + private char[] altOut; + private boolean inAltCharset; private int lastLineLength = 0; private AttributedStyle current = AttributedStyle.DEFAULT; @@ -81,10 +84,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A @Override public AttributedString subSequence(int start, int end) { return new AttributedString( - Arrays.copyOfRange(buffer, start, end), - Arrays.copyOfRange(style, start, end), - 0, - end - start); + Arrays.copyOfRange(buffer, start, end), Arrays.copyOfRange(style, start, end), 0, end - start); } @Override @@ -108,6 +108,14 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A return append(Character.toString(c)); } + public AttributedStringBuilder append(char c, int repeat) { + AttributedString s = new AttributedString(Character.toString(c), current); + while (repeat-- > 0) { + append(s); + } + return this; + } + public AttributedStringBuilder append(CharSequence csq, AttributedStyle style) { return append(new AttributedString(csq, style)); } @@ -117,12 +125,12 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A return this; } - public AttributedStringBuilder style(Function style) { + public AttributedStringBuilder style(Function style) { current = style.apply(current); return this; } - public AttributedStringBuilder styled(Function style, CharSequence cs) { + public AttributedStringBuilder styled(Function style, CharSequence cs) { return styled(style, sb -> sb.append(cs)); } @@ -130,7 +138,8 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A return styled(s -> style, sb -> sb.append(cs)); } - public AttributedStringBuilder styled(Function style, Consumer consumer) { + public AttributedStringBuilder styled( + Function style, Consumer consumer) { AttributedStyle prev = current; current = style.apply(prev); consumer.accept(this); @@ -338,23 +347,90 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A // This is not a SGR code, so ignore ansiState = 0; } - } else if (c == '\t' && tabs.defined()) { - insertTab(current); } else { - ensureCapacity(length + 1); - buffer[length] = c; - style[length] = this.current.getStyle(); - if (c == '\n') { - lastLineLength = 0; - } else { - lastLineLength++; + if (ansiState >= 1) { + ensureCapacity(length + 1); + buffer[length++] = 27; + if (ansiState >= 2) { + ensureCapacity(length + 1); + buffer[length++] = '['; + } + ansiState = 0; + } + if (c == '\t' && tabs.defined()) { + insertTab(current); + } else { + ensureCapacity(length + 1); + if (inAltCharset) { + switch (c) { + case 'j': + c = '\u2518'; + break; + case 'k': + c = '\u2510'; + break; + case 'l': + c = '\u250C'; + break; + case 'm': + c = '\u2514'; + break; + case 'n': + c = '\u253C'; + break; + case 'q': + c = '\u2500'; + break; + case 't': + c = '\u251C'; + break; + case 'u': + c = '\u2524'; + break; + case 'v': + c = '\u2534'; + break; + case 'w': + c = '\u252C'; + break; + case 'x': + c = '\u2502'; + break; + } + } + buffer[length] = c; + style[length] = this.current.getStyle(); + if (c == '\n') { + lastLineLength = 0; + } else { + lastLineLength++; + } + length++; + if (altIn != null && altOut != null) { + char[] alt = inAltCharset ? altOut : altIn; + if (equals(buffer, length - alt.length, alt, 0, alt.length)) { + inAltCharset = !inAltCharset; + length -= alt.length; + } + } } - length++; } } return this; } + private static boolean equals(char[] a, int aFromIndex, char[] b, int bFromIndex, int length) { + if (aFromIndex < 0 || bFromIndex < 0 || aFromIndex + length > a.length || bFromIndex + length > b.length) { + return false; + } + for (int i = 0; i < length; i++) { + if (a[aFromIndex + i] != b[bFromIndex + i]) { + return false; + } + } + return true; + } + protected void insertTab(AttributedStyle s) { int nb = tabs.spaces(lastLineLength); ensureCapacity(length + nb); @@ -393,6 +469,15 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A return this; } + public AttributedStringBuilder altCharset(String altIn, String altOut) { + if (length > 0) { + throw new IllegalStateException("Cannot change alternative charset after appending text"); + } + this.altIn = altIn != null ? altIn.toCharArray() : null; + this.altOut = altOut != null ? altOut.toCharArray() : null; + return this; + } + public AttributedStringBuilder styleMatches(Pattern pattern, AttributedStyle s) { Matcher matcher = pattern.matcher(this); while (matcher.find()) { @@ -416,7 +501,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A return this; } - private class TabStops { + private static class TabStops { private List tabs = new ArrayList<>(); private int lastStop = 0; private int lastSize = 0; @@ -428,7 +513,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A public TabStops(List tabs) { this.tabs = tabs; int p = 0; - for (int s: tabs) { + for (int s : tabs) { if (s <= p) { continue; } @@ -447,7 +532,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A if (lastLineLength >= lastStop) { out = lastSize - (lastLineLength - lastStop) % lastSize; } else { - for (int s: tabs) { + for (int s : tabs) { if (s > lastLineLength) { out = s - lastLineLength; break; @@ -456,7 +541,5 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A } return out; } - } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStyle.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStyle.java index 902e2e1f3b8..7845e99e0b0 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStyle.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/AttributedStyle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2021, the original author or authors. + * Copyright (c) 2002-2021, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -15,39 +15,39 @@ package jdk.internal.org.jline.utils; */ public class AttributedStyle { - public static final int BLACK = 0; - public static final int RED = 1; - public static final int GREEN = 2; - public static final int YELLOW = 3; - public static final int BLUE = 4; - public static final int MAGENTA = 5; - public static final int CYAN = 6; - public static final int WHITE = 7; + public static final int BLACK = 0; + public static final int RED = 1; + public static final int GREEN = 2; + public static final int YELLOW = 3; + public static final int BLUE = 4; + public static final int MAGENTA = 5; + public static final int CYAN = 6; + public static final int WHITE = 7; - public static final int BRIGHT = 8; + public static final int BRIGHT = 8; - static final long F_BOLD = 0x00000001; - static final long F_FAINT = 0x00000002; - static final long F_ITALIC = 0x00000004; - static final long F_UNDERLINE = 0x00000008; - static final long F_BLINK = 0x00000010; - static final long F_INVERSE = 0x00000020; - static final long F_CONCEAL = 0x00000040; - static final long F_CROSSED_OUT = 0x00000080; - static final long F_FOREGROUND_IND = 0x00000100; - static final long F_FOREGROUND_RGB = 0x00000200; - static final long F_FOREGROUND = F_FOREGROUND_IND | F_FOREGROUND_RGB; - static final long F_BACKGROUND_IND = 0x00000400; - static final long F_BACKGROUND_RGB = 0x00000800; - static final long F_BACKGROUND = F_BACKGROUND_IND | F_BACKGROUND_RGB; - static final long F_HIDDEN = 0x00001000; + static final long F_BOLD = 0x00000001; + static final long F_FAINT = 0x00000002; + static final long F_ITALIC = 0x00000004; + static final long F_UNDERLINE = 0x00000008; + static final long F_BLINK = 0x00000010; + static final long F_INVERSE = 0x00000020; + static final long F_CONCEAL = 0x00000040; + static final long F_CROSSED_OUT = 0x00000080; + static final long F_FOREGROUND_IND = 0x00000100; + static final long F_FOREGROUND_RGB = 0x00000200; + static final long F_FOREGROUND = F_FOREGROUND_IND | F_FOREGROUND_RGB; + static final long F_BACKGROUND_IND = 0x00000400; + static final long F_BACKGROUND_RGB = 0x00000800; + static final long F_BACKGROUND = F_BACKGROUND_IND | F_BACKGROUND_RGB; + static final long F_HIDDEN = 0x00001000; - static final long MASK = 0x00001FFF; + static final long MASK = 0x00001FFF; - static final int FG_COLOR_EXP = 15; - static final int BG_COLOR_EXP = 39; - static final long FG_COLOR = 0xFFFFFFL << FG_COLOR_EXP; - static final long BG_COLOR = 0xFFFFFFL << BG_COLOR_EXP; + static final int FG_COLOR_EXP = 15; + static final int BG_COLOR_EXP = 39; + static final long FG_COLOR = 0xFFFFFFL << FG_COLOR_EXP; + static final long BG_COLOR = 0xFFFFFFL << BG_COLOR_EXP; public static final AttributedStyle DEFAULT = new AttributedStyle(); public static final AttributedStyle BOLD = DEFAULT.bold(); @@ -70,8 +70,9 @@ public class AttributedStyle { public AttributedStyle(long style, long mask) { this.style = style; - this.mask = mask & MASK | ((style & F_FOREGROUND) != 0 ? FG_COLOR : 0) - | ((style & F_BACKGROUND) != 0 ? BG_COLOR : 0); + this.mask = mask & MASK + | ((style & F_FOREGROUND) != 0 ? FG_COLOR : 0) + | ((style & F_BACKGROUND) != 0 ? BG_COLOR : 0); } public AttributedStyle bold() { @@ -176,7 +177,9 @@ public class AttributedStyle { } public AttributedStyle foreground(int color) { - return new AttributedStyle(style & ~FG_COLOR | F_FOREGROUND_IND | (((long) color << FG_COLOR_EXP) & FG_COLOR), mask | F_FOREGROUND_IND); + return new AttributedStyle( + style & ~FG_COLOR | F_FOREGROUND_IND | (((long) color << FG_COLOR_EXP) & FG_COLOR), + mask | F_FOREGROUND_IND); } public AttributedStyle foreground(int r, int g, int b) { @@ -184,7 +187,9 @@ public class AttributedStyle { } public AttributedStyle foregroundRgb(int color) { - return new AttributedStyle(style & ~FG_COLOR | F_FOREGROUND_RGB | ((((long) color & 0xFFFFFF) << FG_COLOR_EXP) & FG_COLOR), mask | F_FOREGROUND_RGB); + return new AttributedStyle( + style & ~FG_COLOR | F_FOREGROUND_RGB | ((((long) color & 0xFFFFFF) << FG_COLOR_EXP) & FG_COLOR), + mask | F_FOREGROUND_RGB); } public AttributedStyle foregroundOff() { @@ -196,7 +201,9 @@ public class AttributedStyle { } public AttributedStyle background(int color) { - return new AttributedStyle(style & ~BG_COLOR | F_BACKGROUND_IND | (((long) color << BG_COLOR_EXP) & BG_COLOR), mask | F_BACKGROUND_IND); + return new AttributedStyle( + style & ~BG_COLOR | F_BACKGROUND_IND | (((long) color << BG_COLOR_EXP) & BG_COLOR), + mask | F_BACKGROUND_IND); } public AttributedStyle background(int r, int g, int b) { @@ -204,7 +211,9 @@ public class AttributedStyle { } public AttributedStyle backgroundRgb(int color) { - return new AttributedStyle(style & ~BG_COLOR | F_BACKGROUND_RGB | ((((long) color & 0xFFFFFF) << BG_COLOR_EXP) & BG_COLOR), mask | F_BACKGROUND_RGB); + return new AttributedStyle( + style & ~BG_COLOR | F_BACKGROUND_RGB | ((((long) color & 0xFFFFFF) << BG_COLOR_EXP) & BG_COLOR), + mask | F_BACKGROUND_RGB); } public AttributedStyle backgroundOff() { @@ -249,7 +258,6 @@ public class AttributedStyle { AttributedStyle that = (AttributedStyle) o; if (style != that.style) return false; return mask == that.mask; - } @Override @@ -266,10 +274,6 @@ public class AttributedStyle { @Override public String toString() { - return "AttributedStyle{" + - "style=" + style + - ", mask=" + mask + - ", ansi=" + toAnsi() + - '}'; + return "AttributedStyle{" + "style=" + style + ", mask=" + mask + ", ansi=" + toAnsi() + '}'; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ClosedException.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ClosedException.java index f2adb0878c7..a6f5bfb5b54 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ClosedException.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ClosedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,8 +14,7 @@ public class ClosedException extends IOException { private static final long serialVersionUID = 3085420657077696L; - public ClosedException() { - } + public ClosedException() {} public ClosedException(String message) { super(message); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ColorPalette.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ColorPalette.java index 6f55273a7b9..b4175fe13ce 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ColorPalette.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ColorPalette.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -21,7 +21,8 @@ import jdk.internal.org.jline.terminal.Terminal; */ public class ColorPalette { - public static final String XTERM_INITC = "\\E]4;%p1%d;rgb\\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\\E\\\\"; + public static final String XTERM_INITC = + "\\E]4;%p1%d;rgb\\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\\E\\\\"; public static final ColorPalette DEFAULT = new ColorPalette(); @@ -41,6 +42,7 @@ public class ColorPalette { this(terminal, null); } + @SuppressWarnings("this-escape") public ColorPalette(Terminal terminal, String distance) throws IOException { this.terminal = terminal; this.distanceName = distance; @@ -245,10 +247,13 @@ public class ColorPalette { if (rgb.size() != 3) { return null; } - double r = Integer.parseInt(rgb.get(0), 16) / ((1 << (4 * rgb.get(0).length())) - 1.0); - double g = Integer.parseInt(rgb.get(1), 16) / ((1 << (4 * rgb.get(1).length())) - 1.0); - double b = Integer.parseInt(rgb.get(2), 16) / ((1 << (4 * rgb.get(2).length())) - 1.0); - palette[idx] = (int)((Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255)); + double r = Integer.parseInt(rgb.get(0), 16) + / ((1 << (4 * rgb.get(0).length())) - 1.0); + double g = Integer.parseInt(rgb.get(1), 16) + / ((1 << (4 * rgb.get(1).length())) - 1.0); + double b = Integer.parseInt(rgb.get(2), 16) + / ((1 << (4 * rgb.get(2).length())) - 1.0); + palette[idx] = (int) ((Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255)); black &= palette[idx] == 0; } if (black) { @@ -256,7 +261,13 @@ public class ColorPalette { } } int max = 256; - while (max > 0 && palette[--max] == 0); + while (max > 0 && palette[--max] == 0) + ; return Arrays.copyOfRange(palette, 0, max + 1); } + + @Override + public String toString() { + return "ColorPalette[" + "length=" + getLength() + ", " + "distance='" + getDist() + "\']"; + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java index dc452e10364..d5e7644d3cb 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -21,6 +21,8 @@ import static jdk.internal.org.jline.terminal.TerminalBuilder.PROP_COLOR_DISTANC public class Colors { + // @spotless:off + /** * Default 256 colors palette */ @@ -111,24 +113,26 @@ public class Colors { 0x2e2e2e, 0x5c5c5c, 0x737373, 0x8b8b8b, 0xa2a2a2, 0xb9b9b9, 0xd0d0d0, 0xe7e7e7, }; + // @spotless:on + /** D50 illuminant for CAM color spaces */ - public static final double[] D50 = new double[] { 96.422f, 100.0f, 82.521f }; + public static final double[] D50 = new double[] {96.422f, 100.0f, 82.521f}; /** D65 illuminant for CAM color spaces */ - public static final double[] D65 = new double[] { 95.047, 100.0, 108.883 }; + public static final double[] D65 = new double[] {95.047, 100.0, 108.883}; /** Average surrounding for CAM color spaces */ - public static final double[] averageSurrounding = new double[] { 1.0, 0.690, 1.0 }; + public static final double[] averageSurrounding = new double[] {1.0, 0.690, 1.0}; /** Dim surrounding for CAM color spaces */ - public static final double[] dimSurrounding = new double[] { 0.9, 0.590, 0.9 }; + public static final double[] dimSurrounding = new double[] {0.9, 0.590, 0.9}; /** Dark surrounding for CAM color spaces */ - public static final double[] darkSurrounding = new double[] { 0.8, 0.525, 0.8 }; + public static final double[] darkSurrounding = new double[] {0.8, 0.525, 0.8}; /** sRGB encoding environment */ - public static final double[] sRGB_encoding_environment = vc(D50, 64.0, 64.0/5, dimSurrounding); + public static final double[] sRGB_encoding_environment = vc(D50, 64.0, 64.0 / 5, dimSurrounding); /** sRGB typical environment */ - public static final double[] sRGB_typical_environment = vc(D50, 200.0, 200.0/5, averageSurrounding); + public static final double[] sRGB_typical_environment = vc(D50, 200.0, 200.0 / 5, averageSurrounding); /** Adobe RGB environment */ - public static final double[] AdobeRGB_environment = vc(D65, 160.0, 160.0/5, averageSurrounding); + public static final double[] AdobeRGB_environment = vc(D65, 160.0, 160.0 / 5, averageSurrounding); private static int[] COLORS_256 = DEFAULT_COLORS_256; @@ -149,8 +153,9 @@ public class Colors { if (COLOR_NAMES == null) { Map colors = new LinkedHashMap<>(); try (InputStream is = InfoCmp.class.getResourceAsStream("colors.txt"); - BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - br.lines().map(String::trim) + BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + br.lines() + .map(String::trim) .filter(s -> !s.startsWith("#")) .filter(s -> !s.isEmpty()) .forEachOrdered(s -> { @@ -206,7 +211,7 @@ public class Colors { if (dist == null) { dist = System.getProperty(PROP_COLOR_DISTANCE, "cie76"); } - return doGetDistance(dist); + return new NamedDistance(dist, doGetDistance(dist)); } private static Distance doGetDistance(String dist) { @@ -216,7 +221,7 @@ public class Colors { double[] c1 = rgb(p1); double[] c2 = rgb(p2); double rmean = (c1[0] + c2[0]) / 2.0; - double[] w = { 2.0 + rmean, 4.0, 3.0 - rmean }; + double[] w = {2.0 + rmean, 4.0, 3.0 - rmean}; return scalar(c1, c2, w); }; } @@ -228,7 +233,7 @@ public class Colors { } if (dist.matches("lab\\(([0-9]+(\\.[0-9]+)?),([0-9]+(\\.[0-9]+)?)\\)")) { double[] w = getWeights(dist); - return (p1, p2) -> scalar(rgb2cielab(p1), rgb2cielab(p2), new double[] { w[0], w[1], w[1] }); + return (p1, p2) -> scalar(rgb2cielab(p1), rgb2cielab(p2), new double[] {w[0], w[1], w[1]}); } if (dist.equals("cie94")) { return (p1, p2) -> cie94(rgb2cielab(p1), rgb2cielab(p2)); @@ -251,7 +256,7 @@ public class Colors { double[] c1 = camlab(p1, sRGB_typical_environment); double[] c2 = camlab(p2, sRGB_typical_environment); double[] w = getWeights(dist); - return scalar(c1, c2, new double[] { w[0], w[1], w[1] }); + return scalar(c1, c2, new double[] {w[0], w[1], w[1]}); }; } if (dist.matches("camlch")) { @@ -273,20 +278,37 @@ public class Colors { } private static double[] getWeights(String dist) { - String[] weights = dist.substring(dist.indexOf('(') + 1, dist.length() - 1).split(","); + String[] weights = + dist.substring(dist.indexOf('(') + 1, dist.length() - 1).split(","); return Stream.of(weights).mapToDouble(Double::parseDouble).toArray(); } private static double scalar(double[] c1, double[] c2, double[] w) { - return sqr((c1[0] - c2[0]) * w[0]) - + sqr((c1[1] - c2[1]) * w[1]) - + sqr((c1[2] - c2[2]) * w[2]); + return sqr((c1[0] - c2[0]) * w[0]) + sqr((c1[1] - c2[1]) * w[1]) + sqr((c1[2] - c2[2]) * w[2]); } private static double scalar(double[] c1, double[] c2) { - return sqr(c1[0] - c2[0]) - + sqr(c1[1] - c2[1]) - + sqr(c1[2] - c2[2]); + return sqr(c1[0] - c2[0]) + sqr(c1[1] - c2[1]) + sqr(c1[2] - c2[2]); + } + + private static class NamedDistance implements Distance { + private final String name; + private final Distance delegate; + + public NamedDistance(String name, Distance delegate) { + this.name = name; + this.delegate = delegate; + } + + @Override + public double compute(int c1, int c2) { + return delegate.compute(c1, c2); + } + + @Override + public String toString() { + return name; + } } private static final int L = 0; @@ -325,7 +347,7 @@ public class Colors { double c_star_average_ab = (c_star_1_ab + c_star_2_ab) / 2.0; double c_star_average_ab_pot_3 = c_star_average_ab * c_star_average_ab * c_star_average_ab; double c_star_average_ab_pot_7 = c_star_average_ab_pot_3 * c_star_average_ab_pot_3 * c_star_average_ab; - double G = 0.5 * (1.0 - Math.sqrt(c_star_average_ab_pot_7 / (c_star_average_ab_pot_7 + 6103515625.0))); //25^7 + double G = 0.5 * (1.0 - Math.sqrt(c_star_average_ab_pot_7 / (c_star_average_ab_pot_7 + 6103515625.0))); // 25^7 double a1_prime = (1.0 + G) * lab1[A]; double a2_prime = (1.0 + G) * lab2[A]; double C_prime_1 = Math.sqrt(a1_prime * a1_prime + lab1[B] * lab1[B]); @@ -365,16 +387,18 @@ public class Colors { + 0.24 * Math.cos(Math.toRadians(h_prime_average * 2.0)) + 0.32 * Math.cos(Math.toRadians(h_prime_average * 3.0 + 6.0)) - 0.20 * Math.cos(Math.toRadians(h_prime_average * 4.0 - 63.0)); - double S_L = 1.0 + ((0.015 * L_prime_average_minus_50_square) / Math.sqrt(20.0 + L_prime_average_minus_50_square)); + double S_L = + 1.0 + ((0.015 * L_prime_average_minus_50_square) / Math.sqrt(20.0 + L_prime_average_minus_50_square)); double S_C = 1.0 + 0.045 * C_prime_average; double S_H = 1.0 + 0.015 * T * C_prime_average; double h_prime_average_minus_275_div_25 = (h_prime_average - 275.0) / (25.0); - double h_prime_average_minus_275_div_25_square = h_prime_average_minus_275_div_25 * h_prime_average_minus_275_div_25; + double h_prime_average_minus_275_div_25_square = + h_prime_average_minus_275_div_25 * h_prime_average_minus_275_div_25; double delta_theta = 30.0 * Math.exp(-h_prime_average_minus_275_div_25_square); double C_prime_average_pot_3 = C_prime_average * C_prime_average * C_prime_average; double C_prime_average_pot_7 = C_prime_average_pot_3 * C_prime_average_pot_3 * C_prime_average; - double R_C = 2.0 * Math.sqrt(C_prime_average_pot_7 / (C_prime_average_pot_7 + 6103515625.0)); //25^7 - double R_T = - Math.sin(Math.toRadians(2.0 * delta_theta)) * R_C; + double R_C = 2.0 * Math.sqrt(C_prime_average_pot_7 / (C_prime_average_pot_7 + 6103515625.0)); // 25^7 + double R_T = -Math.sin(Math.toRadians(2.0 * delta_theta)) * R_C; double dLKlsl = delta_L_prime / (kl * S_L); double dCkcsc = delta_C_prime / (kc * S_C); double dHkhsh = delta_H_prime / (kh * S_H); @@ -392,11 +416,11 @@ public class Colors { double sM = ((1.0 / 0.0228) * Math.log(1.0 + 0.0228 * lch[1])); double a = sM * Math.cos(Math.toRadians(lch[2])); double b = sM * Math.sin(Math.toRadians(lch[2])); - return new double[] {sJ, a, b }; + return new double[] {sJ, a, b}; } static double camlch(double[] c1, double[] c2) { - return camlch(c1, c2, new double[] { 1.0, 1.0, 1.0 }); + return camlch(c1, c2, new double[] {1.0, 1.0, 1.0}); } static double camlch(double[] c1, double[] c2, double[] w) { @@ -414,18 +438,16 @@ public class Colors { private static double hueDifference(double hue1, double hue2, double c) { double difference = (hue2 - hue1) % c; double ch = c / 2; - if (difference > ch) - difference -= c; - if (difference < -ch) - difference += c; + if (difference > ch) difference -= c; + if (difference < -ch) difference += c; return difference; } private static double[] rgb(int color) { int r = (color >> 16) & 0xFF; - int g = (color >> 8) & 0xFF; - int b = (color >> 0) & 0xFF; - return new double[] { r / 255.0, g / 255.0, b / 255.0 }; + int g = (color >> 8) & 0xFF; + int b = (color >> 0) & 0xFF; + return new double[] {r / 255.0, g / 255.0, b / 255.0}; } static double[] rgb2xyz(int color) { @@ -454,13 +476,13 @@ public class Colors { static double[] lch2lab(double[] lch) { double toRad = Math.PI / 180; - return new double[] { lch[0], lch[1] * Math.cos(lch[2] * toRad), lch[1] * Math.sin(lch[2] * toRad) }; + return new double[] {lch[0], lch[1] * Math.cos(lch[2] * toRad), lch[1] * Math.sin(lch[2] * toRad)}; } private static double[] xyz2camlch(double[] xyz, double[] vc) { double[] XYZ = new double[] {xyz[0] * 100.0, xyz[1] * 100.0, xyz[2] * 100.0}; double[] cam = forwardTransform(XYZ, vc); - return new double[] { cam[J], cam[M], cam[h] }; + return new double[] {cam[J], cam[M], cam[h]}; } /** Lightness */ @@ -478,12 +500,12 @@ public class Colors { /** Hue */ public static final int h = 6; - /** CIECAM02 appearance correlates */ private static double[] forwardTransform(double[] XYZ, double[] vc) { // calculate sharpened cone response double[] RGB = forwardPreAdaptationConeResponse(XYZ); - // calculate corresponding (sharpened) cone response considering various luminance level and surround conditions in D + // calculate corresponding (sharpened) cone response considering various luminance level and surround conditions + // in D double[] RGB_c = forwardPostAdaptationConeResponse(RGB, vc); // calculate HPE equal area cone fundamentals double[] RGBPrime = CAT02toHPE(RGB_c); @@ -501,37 +523,40 @@ public class Colors { // calculate eccentricity double e = ((12500.0 / 13.0) * vc[VC_N_C] * vc[VC_N_CB]) * (Math.cos(Math.toRadians(h) + 2.0) + 3.8); // get t - double t = e * Math.sqrt(Math.pow(a, 2.0) + Math.pow(b, 2.0)) / (RGBPrime_a[0] + RGBPrime_a[1] + 1.05 * RGBPrime_a[2]); + double t = e + * Math.sqrt(Math.pow(a, 2.0) + Math.pow(b, 2.0)) + / (RGBPrime_a[0] + RGBPrime_a[1] + 1.05 * RGBPrime_a[2]); // calculate brightness double Q = (4.0 / vc[VC_C]) * Math.sqrt(J / 100.0) * (vc[VC_A_W] + 4.0) * Math.pow(vc[VC_F_L], 0.25); // calculate the correlates of chroma, colorfulness, and saturation - double C = Math.signum(t) * Math.pow(Math.abs(t), 0.9) * Math.sqrt(J / 100.0) * Math.pow(1.64- Math.pow(0.29, vc[VC_N]), 0.73); + double C = Math.signum(t) + * Math.pow(Math.abs(t), 0.9) + * Math.sqrt(J / 100.0) + * Math.pow(1.64 - Math.pow(0.29, vc[VC_N]), 0.73); double M = C * Math.pow(vc[VC_F_L], 0.25); double s = 100.0 * Math.sqrt(M / Q); // calculate hue composition double H = calculateH(h); - return new double[] { J, Q, C, M, s, H, h }; + return new double[] {J, Q, C, M, s, H, h}; } private static double calculateH(double h) { - if (h < 20.14) - h = h + 360; + if (h < 20.14) h = h + 360; double i; - if (h >= 20.14 && h < 90.0) { // index i = 1 + if (h >= 20.14 && h < 90.0) { // index i = 1 i = (h - 20.14) / 0.8; return 100.0 * i / (i + (90 - h) / 0.7); } else if (h < 164.25) { // index i = 2 i = (h - 90) / 0.7; return 100.0 + 100.0 * i / (i + (164.25 - h) / 1); - } else if (h < 237.53) { // index i = 3 + } else if (h < 237.53) { // index i = 3 i = (h - 164.25) / 1.0; return 200.0 + 100.0 * i / (i + (237.53 - h) / 1.2); - } else if (h <= 380.14) { // index i = 4 + } else if (h <= 380.14) { // index i = 4 i = (h - 237.53) / 1.2; double H = 300.0 + 100.0 * i / (i + (380.14 - h) / 0.8); // don't use 400 if we can use 0 - if (H <= 400.0 && H >= 399.999) - H = 0; + if (H <= 400.0 && H >= 399.999) H = 0; return H; } else { throw new IllegalArgumentException("h outside assumed range 0..360: " + h); @@ -540,8 +565,8 @@ public class Colors { private static double[] forwardResponseCompression(double[] RGB, double[] vc) { double[] result = new double[3]; - for(int channel = 0; channel < RGB.length; channel++) { - if(RGB[channel] >= 0) { + for (int channel = 0; channel < RGB.length; channel++) { + if (RGB[channel] >= 0) { double n = Math.pow(vc[VC_F_L] * RGB[channel] / 100.0, 0.42); result[channel] = 400.0 * n / (n + 27.13) + 0.1; } else { @@ -553,22 +578,22 @@ public class Colors { } private static double[] forwardPostAdaptationConeResponse(double[] RGB, double[] vc) { - return new double[] { vc[VC_D_RGB_R] * RGB[0], vc[VC_D_RGB_G] * RGB[1], vc[VC_D_RGB_B] * RGB[2] }; + return new double[] {vc[VC_D_RGB_R] * RGB[0], vc[VC_D_RGB_G] * RGB[1], vc[VC_D_RGB_B] * RGB[2]}; } public static double[] CAT02toHPE(double[] RGB) { double[] RGBPrime = new double[3]; - RGBPrime[0] = 0.7409792 * RGB[0] + 0.2180250 * RGB[1] + 0.0410058 * RGB[2]; - RGBPrime[1] = 0.2853532 * RGB[0] + 0.6242014 * RGB[1] + 0.0904454 * RGB[2]; + RGBPrime[0] = 0.7409792 * RGB[0] + 0.2180250 * RGB[1] + 0.0410058 * RGB[2]; + RGBPrime[1] = 0.2853532 * RGB[0] + 0.6242014 * RGB[1] + 0.0904454 * RGB[2]; RGBPrime[2] = -0.0096280 * RGB[0] - 0.0056980 * RGB[1] + 1.0153260 * RGB[2]; return RGBPrime; } private static double[] forwardPreAdaptationConeResponse(double[] XYZ) { double[] RGB = new double[3]; - RGB[0] = 0.7328 * XYZ[0] + 0.4296 * XYZ[1] - 0.1624 * XYZ[2]; + RGB[0] = 0.7328 * XYZ[0] + 0.4296 * XYZ[1] - 0.1624 * XYZ[2]; RGB[1] = -0.7036 * XYZ[0] + 1.6975 * XYZ[1] + 0.0061 * XYZ[2]; - RGB[2] = 0.0030 * XYZ[0] + 0.0136 * XYZ[1] + 0.9834 * XYZ[2]; + RGB[2] = 0.0030 * XYZ[0] + 0.0136 * XYZ[1] + 0.9834 * XYZ[2]; return RGB; } @@ -581,8 +606,8 @@ public class Colors { static final int VC_Z_W = 2; static final int VC_L_A = 3; static final int VC_Y_B = 4; - static final int VC_F = 5; - static final int VC_C = 6; + static final int VC_F = 5; + static final int VC_C = 6; static final int VC_N_C = 7; static final int VC_Z = 8; @@ -607,33 +632,33 @@ public class Colors { vc[VC_N_C] = surrounding[SUR_N_C]; double[] RGB_w = forwardPreAdaptationConeResponse(xyz_w); - double D = Math.max(0.0, Math.min(1.0, vc[VC_F] * (1.0 - (1.0 / 3.6) * Math.pow(Math.E, (-L_A - 42.0) / 92.0)))); + double D = + Math.max(0.0, Math.min(1.0, vc[VC_F] * (1.0 - (1.0 / 3.6) * Math.pow(Math.E, (-L_A - 42.0) / 92.0)))); double Yw = xyz_w[1]; double[] RGB_c = new double[] { - (D * Yw / RGB_w[0]) + (1.0 - D), - (D * Yw / RGB_w[1]) + (1.0 - D), - (D * Yw / RGB_w[2]) + (1.0 - D), + (D * Yw / RGB_w[0]) + (1.0 - D), (D * Yw / RGB_w[1]) + (1.0 - D), (D * Yw / RGB_w[2]) + (1.0 - D), }; // calculate increase in brightness and colorfulness caused by brighter viewing environments double L_Ax5 = 5.0 * L_A; double k = 1.0 / (L_Ax5 + 1.0); double kpow4 = Math.pow(k, 4.0); - vc[VC_F_L] = 0.2 * kpow4 * (L_Ax5) + 0.1 * Math.pow(1.0 - kpow4, 2.0) * Math.pow(L_Ax5, 1.0/3.0); + vc[VC_F_L] = 0.2 * kpow4 * (L_Ax5) + 0.1 * Math.pow(1.0 - kpow4, 2.0) * Math.pow(L_Ax5, 1.0 / 3.0); // calculate response compression on J and C caused by background lightness. vc[VC_N] = Y_b / Yw; vc[VC_Z] = 1.48 + Math.sqrt(vc[VC_N]); vc[VC_N_BB] = 0.725 * Math.pow(1.0 / vc[VC_N], 0.2); - vc[VC_N_CB] = vc[VC_N_BB]; // chromatic contrast factors (calculate increase in J, Q, and C caused by dark backgrounds) + vc[VC_N_CB] = vc[ + VC_N_BB]; // chromatic contrast factors (calculate increase in J, Q, and C caused by dark backgrounds) // calculate achromatic response to white double[] RGB_wc = new double[] {RGB_c[0] * RGB_w[0], RGB_c[1] * RGB_w[1], RGB_c[2] * RGB_w[2]}; double[] RGBPrime_w = CAT02toHPE(RGB_wc); double[] RGBPrime_aw = new double[3]; - for(int channel = 0; channel < RGBPrime_w.length; channel++) { - if(RGBPrime_w[channel] >= 0) { + for (int channel = 0; channel < RGBPrime_w.length; channel++) { + if (RGBPrime_w[channel] >= 0) { double n = Math.pow(vc[VC_F_L] * RGBPrime_w[channel] / 100.0, 0.42); RGBPrime_aw[channel] = 400.0 * n / (n + 27.13) + 0.1; } else { @@ -660,7 +685,7 @@ public class Colors { double x = vr * 0.4124564 + vg * 0.3575761 + vb * 0.1804375; double y = vr * 0.2126729 + vg * 0.7151522 + vb * 0.0721750; double z = vr * 0.0193339 + vg * 0.1191920 + vb * 0.9503041; - return new double[] { x, y, z }; + return new double[] {x, y, z}; } private static double pivotRgb(double n) { @@ -674,11 +699,12 @@ public class Colors { double l = 116.0 * fy - 16.0; double a = 500.0 * (fx - fy); double b = 200.0 * (fy - fz); - return new double[] { l, a, b }; + return new double[] {l, a, b}; } private static final double epsilon = 216.0 / 24389.0; private static final double kappa = 24389.0 / 27.0; + private static double pivotXyz(double n) { return n > epsilon ? Math.cbrt(n) : (kappa * n + 16) / 116; } @@ -686,5 +712,4 @@ public class Colors { private static double sqr(double n) { return n * n; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java index bdfd4c37bc2..b9ada270705 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -29,8 +29,7 @@ public final class Curses { private static final int IFTE_THEN = 2; private static final int IFTE_ELSE = 3; - private Curses() { - } + private Curses() {} /** * Print the given terminal capabilities @@ -95,9 +94,9 @@ public final class Curses { case 'n': out.append('\n'); break; -// case 'l': -// rawPrint('\l'); -// break; + // case 'l': + // rawPrint('\l'); + // break; case 'r': if (exec) { out.append('\r'); @@ -138,7 +137,7 @@ public final class Curses { case '^': ch = str.charAt(index++); if (exec) { - out.append((char)(ch - '@')); + out.append((char) (ch - '@')); } break; case '%': @@ -195,7 +194,8 @@ public final class Curses { break; case '{': int start = index; - while (str.charAt(index++) != '}') ; + while (str.charAt(index++) != '}') + ; if (exec) { int v = Integer.parseInt(str.substring(start, index - 1)); stack.push(v); @@ -364,10 +364,18 @@ public final class Curses { int cnv; while ("-+# ".indexOf(ch) >= 0) { switch (ch) { - case '-': left = true; break; - case '+': plus = true; break; - case '#': alternate = true; break; - case ' ': space = true; break; + case '-': + left = true; + break; + case '+': + plus = true; + break; + case '#': + alternate = true; + break; + case ' ': + space = true; + break; } ch = str.charAt(index++); } @@ -473,5 +481,4 @@ public final class Curses { return Integer.parseInt(pop.toString()); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/DiffHelper.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/DiffHelper.java index 3852f572746..93b065395de 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/DiffHelper.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/DiffHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -25,7 +25,9 @@ public class DiffHelper { * which means: delete "Hello", add "Goodbye" and keep " world." */ public enum Operation { - DELETE, INSERT, EQUAL + DELETE, + INSERT, + EQUAL } /** @@ -86,16 +88,13 @@ public class DiffHelper { && text1.charAt(commonStart) == text2.charAt(commonStart) && text1.styleAt(commonStart).equals(text2.styleAt(commonStart))) { if (text1.isHidden(commonStart)) { - if (startHiddenRange < 0) - startHiddenRange = commonStart; - } else - startHiddenRange = -1; + if (startHiddenRange < 0) startHiddenRange = commonStart; + } else startHiddenRange = -1; commonStart++; } if (startHiddenRange >= 0 - && ((l1 > commonStart && text1.isHidden(commonStart)) - || (l2 > commonStart && text2.isHidden(commonStart)))) - commonStart = startHiddenRange; + && ((l1 > commonStart && text1.isHidden(commonStart)) + || (l2 > commonStart && text2.isHidden(commonStart)))) commonStart = startHiddenRange; startHiddenRange = -1; int commonEnd = 0; @@ -103,32 +102,24 @@ public class DiffHelper { && text1.charAt(l1 - commonEnd - 1) == text2.charAt(l2 - commonEnd - 1) && text1.styleAt(l1 - commonEnd - 1).equals(text2.styleAt(l2 - commonEnd - 1))) { if (text1.isHidden(l1 - commonEnd - 1)) { - if (startHiddenRange < 0) - startHiddenRange = commonEnd; - } else - startHiddenRange = -1; + if (startHiddenRange < 0) startHiddenRange = commonEnd; + } else startHiddenRange = -1; commonEnd++; } - if (startHiddenRange >= 0) - commonEnd = startHiddenRange; + if (startHiddenRange >= 0) commonEnd = startHiddenRange; LinkedList diffs = new LinkedList<>(); if (commonStart > 0) { - diffs.add(new Diff(DiffHelper.Operation.EQUAL, - text1.subSequence(0, commonStart))); + diffs.add(new Diff(DiffHelper.Operation.EQUAL, text1.subSequence(0, commonStart))); } if (l2 > commonStart + commonEnd) { - diffs.add(new Diff(DiffHelper.Operation.INSERT, - text2.subSequence(commonStart, l2 - commonEnd))); + diffs.add(new Diff(DiffHelper.Operation.INSERT, text2.subSequence(commonStart, l2 - commonEnd))); } if (l1 > commonStart + commonEnd) { - diffs.add(new Diff(DiffHelper.Operation.DELETE, - text1.subSequence(commonStart, l1 - commonEnd))); + diffs.add(new Diff(DiffHelper.Operation.DELETE, text1.subSequence(commonStart, l1 - commonEnd))); } if (commonEnd > 0) { - diffs.add(new Diff(DiffHelper.Operation.EQUAL, - text1.subSequence(l1 - commonEnd, l1))); + diffs.add(new Diff(DiffHelper.Operation.EQUAL, text1.subSequence(l1 - commonEnd, l1))); } return diffs; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java index aaeab9b71ff..557024a121e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -37,8 +37,8 @@ public class Display { protected final boolean fullScreen; protected List oldLines = Collections.emptyList(); protected int cursorPos; - private int columns; - private int columns1; // columns+1 + protected int columns; + protected int columns1; // columns+1 protected int rows; protected boolean reset; protected boolean delayLineWrap; @@ -49,15 +49,15 @@ public class Display { protected final boolean delayedWrapAtEol; protected final boolean cursorDownIsNewLine; + @SuppressWarnings("this-escape") public Display(Terminal terminal, boolean fullscreen) { this.terminal = terminal; this.fullScreen = fullscreen; this.canScroll = can(Capability.insert_line, Capability.parm_insert_line) - && can(Capability.delete_line, Capability.parm_delete_line); + && can(Capability.delete_line, Capability.parm_delete_line); this.wrapAtEol = terminal.getBooleanCapability(Capability.auto_right_margin); - this.delayedWrapAtEol = this.wrapAtEol - && terminal.getBooleanCapability(Capability.eat_newline_glitch); + this.delayedWrapAtEol = this.wrapAtEol && terminal.getBooleanCapability(Capability.eat_newline_glitch); this.cursorDownIsNewLine = "\n".equals(Curses.tputs(terminal.getStringCapability(Capability.cursor_down))); } @@ -69,18 +69,22 @@ public class Display { public boolean delayLineWrap() { return delayLineWrap; } - public void setDelayLineWrap(boolean v) { delayLineWrap = v; } + + public void setDelayLineWrap(boolean v) { + delayLineWrap = v; + } public void resize(int rows, int columns) { if (rows == 0 || columns == 0) { - columns = Integer.MAX_VALUE - 1; + columns = 1; rows = 1; } if (this.rows != rows || this.columns != columns) { this.rows = rows; this.columns = columns; this.columns1 = columns + 1; - oldLines = AttributedString.join(AttributedString.EMPTY, oldLines).columnSplitLength(columns, true, delayLineWrap()); + oldLines = AttributedString.join(AttributedString.EMPTY, oldLines) + .columnSplitLength(columns, true, delayLineWrap()); } } @@ -128,7 +132,8 @@ public class Display { // If dumb display, get rid of ansi sequences now Integer cols = terminal.getNumericCapability(Capability.max_colors); if (cols == null || cols < 8) { - newLines = newLines.stream().map(s -> new AttributedString(s.toString())) + newLines = newLines.stream() + .map(s -> new AttributedString(s.toString())) .collect(Collectors.toList()); } @@ -138,12 +143,13 @@ public class Display { int nbFooters = 0; // Find common headers and footers int l = newLines.size(); - while (nbHeaders < l - && Objects.equals(newLines.get(nbHeaders), oldLines.get(nbHeaders))) { + while (nbHeaders < l && Objects.equals(newLines.get(nbHeaders), oldLines.get(nbHeaders))) { nbHeaders++; } while (nbFooters < l - nbHeaders - 1 - && Objects.equals(newLines.get(newLines.size() - nbFooters - 1), oldLines.get(oldLines.size() - nbFooters - 1))) { + && Objects.equals( + newLines.get(newLines.size() - nbFooters - 1), + oldLines.get(oldLines.size() - nbFooters - 1))) { nbFooters++; } List o1 = newLines.subList(nbHeaders, newLines.size() - nbFooters); @@ -190,18 +196,14 @@ public class Display { int numLines = Math.min(rows, Math.max(oldLines.size(), newLines.size())); boolean wrapNeeded = false; while (lineIndex < numLines) { - AttributedString oldLine = - lineIndex < oldLines.size() ? oldLines.get(lineIndex) - : AttributedString.NEWLINE; - AttributedString newLine = - lineIndex < newLines.size() ? newLines.get(lineIndex) - : AttributedString.NEWLINE; + AttributedString oldLine = lineIndex < oldLines.size() ? oldLines.get(lineIndex) : AttributedString.NEWLINE; + AttributedString newLine = lineIndex < newLines.size() ? newLines.get(lineIndex) : AttributedString.NEWLINE; currentPos = lineIndex * columns1; int curCol = currentPos; int oldLength = oldLine.length(); int newLength = newLine.length(); - boolean oldNL = oldLength > 0 && oldLine.charAt(oldLength-1)=='\n'; - boolean newNL = newLength > 0 && newLine.charAt(newLength-1)=='\n'; + boolean oldNL = oldLength > 0 && oldLine.charAt(oldLength - 1) == '\n'; + boolean newNL = newLength > 0 && newLine.charAt(newLength - 1) == '\n'; if (oldNL) { oldLength--; oldLine = oldLine.substring(0, oldLength); @@ -210,9 +212,7 @@ public class Display { newLength--; newLine = newLine.substring(0, newLength); } - if (wrapNeeded - && lineIndex == (cursorPos + 1) / columns1 - && lineIndex < newLines.size()) { + if (wrapNeeded && lineIndex == (cursorPos + 1) / columns1 && lineIndex < newLines.size()) { // move from right margin to next line's left margin cursorPos++; if (newLength == 0 || newLine.isHidden(0)) { @@ -250,8 +250,7 @@ public class Display { } break; case INSERT: - if (i <= diffs.size() - 2 - && diffs.get(i + 1).operation == DiffHelper.Operation.EQUAL) { + if (i <= diffs.size() - 2 && diffs.get(i + 1).operation == DiffHelper.Operation.EQUAL) { cursorPos = moveVisualCursorTo(currentPos); if (insertChars(width)) { rawPrint(diff.text); @@ -282,8 +281,7 @@ public class Display { if (currentPos - curCol >= columns) { continue; } - if (i <= diffs.size() - 2 - && diffs.get(i + 1).operation == DiffHelper.Operation.EQUAL) { + if (i <= diffs.size() - 2 && diffs.get(i + 1).operation == DiffHelper.Operation.EQUAL) { if (currentPos + diffs.get(i + 1).text.columnLength() < columns) { moveVisualCursorTo(currentPos); if (deleteChars(width)) { @@ -305,25 +303,23 @@ public class Display { } } lineIndex++; - boolean newWrap = ! newNL && lineIndex < newLines.size(); - if (targetCursorPos + 1 == lineIndex * columns1 - && (newWrap || ! delayLineWrap)) - targetCursorPos++; + boolean newWrap = !newNL && lineIndex < newLines.size(); + if (targetCursorPos + 1 == lineIndex * columns1 && (newWrap || !delayLineWrap)) targetCursorPos++; boolean atRight = (cursorPos - curCol) % columns1 == columns; wrapNeeded = false; if (this.delayedWrapAtEol) { - boolean oldWrap = ! oldNL && lineIndex < oldLines.size(); - if (newWrap != oldWrap && ! (oldWrap && cleared)) { - moveVisualCursorTo(lineIndex*columns1-1, newLines); - if (newWrap) - wrapNeeded = true; - else - terminal.puts(Capability.clr_eol); + boolean oldWrap = !oldNL && lineIndex < oldLines.size(); + if (newWrap != oldWrap && !(oldWrap && cleared)) { + moveVisualCursorTo(lineIndex * columns1 - 1, newLines); + if (newWrap) wrapNeeded = true; + else terminal.puts(Capability.clr_eol); } } else if (atRight) { if (this.wrapAtEol) { - terminal.writer().write(" \b"); - cursorPos++; + if (!fullScreen || (fullScreen && lineIndex < numLines)) { + terminal.writer().write(" \b"); + cursorPos++; + } } else { terminal.puts(Capability.carriage_return); // CR / not newline. cursorPos = curCol; @@ -358,8 +354,7 @@ public class Display { } protected boolean can(Capability single, Capability multi) { - return terminal.getStringCapability(single) != null - || terminal.getStringCapability(multi) != null; + return terminal.getStringCapability(single) != null || terminal.getStringCapability(multi) != null; } protected boolean perform(Capability single, Capability multi, int nb) { @@ -405,7 +400,7 @@ public class Display { } } } - return max != 0 ? new int[] { start1, start2, max } : null; + return max != 0 ? new int[] {start1, start2, max} : null; } /* @@ -413,8 +408,7 @@ public class Display { * We're at the right margin if {@code (cursorPos % columns1) == columns}. * This method knows how to move both *from* and *to* the right margin. */ - protected void moveVisualCursorTo(int targetPos, - List newLines) { + protected void moveVisualCursorTo(int targetPos, List newLines) { if (cursorPos != targetPos) { boolean atRight = (targetPos % columns1) == columns; moveVisualCursorTo(targetPos - (atRight ? 1 : 0)); @@ -422,12 +416,11 @@ public class Display { // There is no portable way to move to the right margin // except by writing a character in the right-most column. int row = targetPos / columns1; - AttributedString lastChar = row >= newLines.size() ? AttributedString.EMPTY - : newLines.get(row).columnSubSequence(columns-1, columns); - if (lastChar.length() == 0) - rawPrint((int) ' '); - else - rawPrint(lastChar); + AttributedString lastChar = row >= newLines.size() + ? AttributedString.EMPTY + : newLines.get(row).columnSubSequence(columns - 1, columns); + if (lastChar.length() == 0) rawPrint((int) ' '); + else rawPrint(lastChar); cursorPos++; } } @@ -499,5 +492,4 @@ public class Display { public int wcwidth(String str) { return str != null ? AttributedString.fromAnsi(str).columnLength() : 0; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ExecHelper.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ExecHelper.java index 9fce26fcf35..5d3c235661b 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ExecHelper.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ExecHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -22,8 +22,7 @@ import java.util.Objects; */ public final class ExecHelper { - private ExecHelper() { - } + private ExecHelper() {} public static String exec(boolean redirectInput, final String... cmd) throws IOException { Objects.requireNonNull(cmd); @@ -31,7 +30,7 @@ public final class ExecHelper { Log.trace("Running: ", cmd); ProcessBuilder pb = new ProcessBuilder(cmd); if (OSUtils.IS_AIX) { - Map env = pb.environment(); + Map env = pb.environment(); env.put("PATH", "/opt/freeware/bin:" + env.get("PATH")); env.put("LANG", "C"); env.put("LC_ALL", "C"); @@ -90,4 +89,3 @@ public final class ExecHelper { } } } - diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/FastBufferedOutputStream.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/FastBufferedOutputStream.java new file mode 100644 index 00000000000..62c29c17f78 --- /dev/null +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/FastBufferedOutputStream.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009-2023, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.utils; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * A simple buffering output stream with no synchronization. + */ +public class FastBufferedOutputStream extends FilterOutputStream { + + protected final byte[] buf = new byte[8192]; + protected int count; + + public FastBufferedOutputStream(OutputStream out) { + super(out); + } + + @Override + public void write(int b) throws IOException { + if (count >= buf.length) { + flushBuffer(); + } + buf[count++] = (byte) b; + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if (len >= buf.length) { + flushBuffer(); + out.write(b, off, len); + return; + } + if (len > buf.length - count) { + flushBuffer(); + } + System.arraycopy(b, off, buf, count, len); + count += len; + } + + private void flushBuffer() throws IOException { + if (count > 0) { + out.write(buf, 0, count); + count = 0; + } + } + + @Override + public void flush() throws IOException { + flushBuffer(); + out.flush(); + } +} diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java index 23a76071486..32cf3f56318 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -28,476 +28,474 @@ public final class InfoCmp { private static final Map CAPS = new HashMap<>(); - private InfoCmp() { - } + private InfoCmp() {} @SuppressWarnings("unused") public enum Capability { - - auto_left_margin, // auto_left_margin, bw, bw - auto_right_margin, // auto_right_margin, am, am - back_color_erase, // back_color_erase, bce, ut - can_change, // can_change, ccc, cc - ceol_standout_glitch, // ceol_standout_glitch, xhp, xs - col_addr_glitch, // col_addr_glitch, xhpa, YA - cpi_changes_res, // cpi_changes_res, cpix, YF - cr_cancels_micro_mode, // cr_cancels_micro_mode, crxm, YB - dest_tabs_magic_smso, // dest_tabs_magic_smso, xt, xt - eat_newline_glitch, // eat_newline_glitch, xenl, xn - erase_overstrike, // erase_overstrike, eo, eo - generic_type, // generic_type, gn, gn - hard_copy, // hard_copy, hc, hc - hard_cursor, // hard_cursor, chts, HC - has_meta_key, // has_meta_key, km, km - has_print_wheel, // has_print_wheel, daisy, YC - has_status_line, // has_status_line, hs, hs - hue_lightness_saturation, // hue_lightness_saturation, hls, hl - insert_null_glitch, // insert_null_glitch, in, in - lpi_changes_res, // lpi_changes_res, lpix, YG - memory_above, // memory_above, da, da - memory_below, // memory_below, db, db - move_insert_mode, // move_insert_mode, mir, mi - move_standout_mode, // move_standout_mode, msgr, ms - needs_xon_xoff, // needs_xon_xoff, nxon, nx - no_esc_ctlc, // no_esc_ctlc, xsb, xb - no_pad_char, // no_pad_char, npc, NP - non_dest_scroll_region, // non_dest_scroll_region, ndscr, ND - non_rev_rmcup, // non_rev_rmcup, nrrmc, NR - over_strike, // over_strike, os, os - prtr_silent, // prtr_silent, mc5i, 5i - row_addr_glitch, // row_addr_glitch, xvpa, YD - semi_auto_right_margin, // semi_auto_right_margin, sam, YE - status_line_esc_ok, // status_line_esc_ok, eslok, es - tilde_glitch, // tilde_glitch, hz, hz - transparent_underline, // transparent_underline, ul, ul - xon_xoff, // xon_xoff, xon, xo - columns, // columns, cols, co - init_tabs, // init_tabs, it, it - label_height, // label_height, lh, lh - label_width, // label_width, lw, lw - lines, // lines, lines, li - lines_of_memory, // lines_of_memory, lm, lm - magic_cookie_glitch, // magic_cookie_glitch, xmc, sg - max_attributes, // max_attributes, ma, ma - max_colors, // max_colors, colors, Co - max_pairs, // max_pairs, pairs, pa - maximum_windows, // maximum_windows, wnum, MW - no_color_video, // no_color_video, ncv, NC - num_labels, // num_labels, nlab, Nl - padding_baud_rate, // padding_baud_rate, pb, pb - virtual_terminal, // virtual_terminal, vt, vt - width_status_line, // width_status_line, wsl, ws - bit_image_entwining, // bit_image_entwining, bitwin, Yo - bit_image_type, // bit_image_type, bitype, Yp - buffer_capacity, // buffer_capacity, bufsz, Ya - buttons, // buttons, btns, BT - dot_horz_spacing, // dot_horz_spacing, spinh, Yc - dot_vert_spacing, // dot_vert_spacing, spinv, Yb - max_micro_address, // max_micro_address, maddr, Yd - max_micro_jump, // max_micro_jump, mjump, Ye - micro_col_size, // micro_col_size, mcs, Yf - micro_line_size, // micro_line_size, mls, Yg - number_of_pins, // number_of_pins, npins, Yh - output_res_char, // output_res_char, orc, Yi - output_res_horz_inch, // output_res_horz_inch, orhi, Yk - output_res_line, // output_res_line, orl, Yj - output_res_vert_inch, // output_res_vert_inch, orvi, Yl - print_rate, // print_rate, cps, Ym - wide_char_size, // wide_char_size, widcs, Yn - acs_chars, // acs_chars, acsc, ac - back_tab, // back_tab, cbt, bt - bell, // bell, bel, bl - carriage_return, // carriage_return, cr, cr - change_char_pitch, // change_char_pitch, cpi, ZA - change_line_pitch, // change_line_pitch, lpi, ZB - change_res_horz, // change_res_horz, chr, ZC - change_res_vert, // change_res_vert, cvr, ZD - change_scroll_region, // change_scroll_region, csr, cs - char_padding, // char_padding, rmp, rP - clear_all_tabs, // clear_all_tabs, tbc, ct - clear_margins, // clear_margins, mgc, MC - clear_screen, // clear_screen, clear, cl - clr_bol, // clr_bol, el1, cb - clr_eol, // clr_eol, el, ce - clr_eos, // clr_eos, ed, cd - column_address, // column_address, hpa, ch - command_character, // command_character, cmdch, CC - create_window, // create_window, cwin, CW - cursor_address, // cursor_address, cup, cm - cursor_down, // cursor_down, cud1, do - cursor_home, // cursor_home, home, ho - cursor_invisible, // cursor_invisible, civis, vi - cursor_left, // cursor_left, cub1, le - cursor_mem_address, // cursor_mem_address, mrcup, CM - cursor_normal, // cursor_normal, cnorm, ve - cursor_right, // cursor_right, cuf1, nd - cursor_to_ll, // cursor_to_ll, ll, ll - cursor_up, // cursor_up, cuu1, up - cursor_visible, // cursor_visible, cvvis, vs - define_char, // define_char, defc, ZE - delete_character, // delete_character, dch1, dc - delete_line, // delete_line, dl1, dl - dial_phone, // dial_phone, dial, DI - dis_status_line, // dis_status_line, dsl, ds - display_clock, // display_clock, dclk, DK - down_half_line, // down_half_line, hd, hd - ena_acs, // ena_acs, enacs, eA - enter_alt_charset_mode, // enter_alt_charset_mode, smacs, as - enter_am_mode, // enter_am_mode, smam, SA - enter_blink_mode, // enter_blink_mode, blink, mb - enter_bold_mode, // enter_bold_mode, bold, md - enter_ca_mode, // enter_ca_mode, smcup, ti - enter_delete_mode, // enter_delete_mode, smdc, dm - enter_dim_mode, // enter_dim_mode, dim, mh - enter_doublewide_mode, // enter_doublewide_mode, swidm, ZF - enter_draft_quality, // enter_draft_quality, sdrfq, ZG - enter_insert_mode, // enter_insert_mode, smir, im - enter_italics_mode, // enter_italics_mode, sitm, ZH - enter_leftward_mode, // enter_leftward_mode, slm, ZI - enter_micro_mode, // enter_micro_mode, smicm, ZJ - enter_near_letter_quality, // enter_near_letter_quality, snlq, ZK - enter_normal_quality, // enter_normal_quality, snrmq, ZL - enter_protected_mode, // enter_protected_mode, prot, mp - enter_reverse_mode, // enter_reverse_mode, rev, mr - enter_secure_mode, // enter_secure_mode, invis, mk - enter_shadow_mode, // enter_shadow_mode, sshm, ZM - enter_standout_mode, // enter_standout_mode, smso, so - enter_subscript_mode, // enter_subscript_mode, ssubm, ZN - enter_superscript_mode, // enter_superscript_mode, ssupm, ZO - enter_underline_mode, // enter_underline_mode, smul, us - enter_upward_mode, // enter_upward_mode, sum, ZP - enter_xon_mode, // enter_xon_mode, smxon, SX - erase_chars, // erase_chars, ech, ec - exit_alt_charset_mode, // exit_alt_charset_mode, rmacs, ae - exit_am_mode, // exit_am_mode, rmam, RA - exit_attribute_mode, // exit_attribute_mode, sgr0, me - exit_ca_mode, // exit_ca_mode, rmcup, te - exit_delete_mode, // exit_delete_mode, rmdc, ed - exit_doublewide_mode, // exit_doublewide_mode, rwidm, ZQ - exit_insert_mode, // exit_insert_mode, rmir, ei - exit_italics_mode, // exit_italics_mode, ritm, ZR - exit_leftward_mode, // exit_leftward_mode, rlm, ZS - exit_micro_mode, // exit_micro_mode, rmicm, ZT - exit_shadow_mode, // exit_shadow_mode, rshm, ZU - exit_standout_mode, // exit_standout_mode, rmso, se - exit_subscript_mode, // exit_subscript_mode, rsubm, ZV - exit_superscript_mode, // exit_superscript_mode, rsupm, ZW - exit_underline_mode, // exit_underline_mode, rmul, ue - exit_upward_mode, // exit_upward_mode, rum, ZX - exit_xon_mode, // exit_xon_mode, rmxon, RX - fixed_pause, // fixed_pause, pause, PA - flash_hook, // flash_hook, hook, fh - flash_screen, // flash_screen, flash, vb - form_feed, // form_feed, ff, ff - from_status_line, // from_status_line, fsl, fs - goto_window, // goto_window, wingo, WG - hangup, // hangup, hup, HU - init_1string, // init_1string, is1, i1 - init_2string, // init_2string, is2, is - init_3string, // init_3string, is3, i3 - init_file, // init_file, if, if - init_prog, // init_prog, iprog, iP - initialize_color, // initialize_color, initc, Ic - initialize_pair, // initialize_pair, initp, Ip - insert_character, // insert_character, ich1, ic - insert_line, // insert_line, il1, al - insert_padding, // insert_padding, ip, ip - key_a1, // key_a1, ka1, K1 - key_a3, // key_a3, ka3, K3 - key_b2, // key_b2, kb2, K2 - key_backspace, // key_backspace, kbs, kb - key_beg, // key_beg, kbeg, @1 - key_btab, // key_btab, kcbt, kB - key_c1, // key_c1, kc1, K4 - key_c3, // key_c3, kc3, K5 - key_cancel, // key_cancel, kcan, @2 - key_catab, // key_catab, ktbc, ka - key_clear, // key_clear, kclr, kC - key_close, // key_close, kclo, @3 - key_command, // key_command, kcmd, @4 - key_copy, // key_copy, kcpy, @5 - key_create, // key_create, kcrt, @6 - key_ctab, // key_ctab, kctab, kt - key_dc, // key_dc, kdch1, kD - key_dl, // key_dl, kdl1, kL - key_down, // key_down, kcud1, kd - key_eic, // key_eic, krmir, kM - key_end, // key_end, kend, @7 - key_enter, // key_enter, kent, @8 - key_eol, // key_eol, kel, kE - key_eos, // key_eos, ked, kS - key_exit, // key_exit, kext, @9 - key_f0, // key_f0, kf0, k0 - key_f1, // key_f1, kf1, k1 - key_f10, // key_f10, kf10, k; - key_f11, // key_f11, kf11, F1 - key_f12, // key_f12, kf12, F2 - key_f13, // key_f13, kf13, F3 - key_f14, // key_f14, kf14, F4 - key_f15, // key_f15, kf15, F5 - key_f16, // key_f16, kf16, F6 - key_f17, // key_f17, kf17, F7 - key_f18, // key_f18, kf18, F8 - key_f19, // key_f19, kf19, F9 - key_f2, // key_f2, kf2, k2 - key_f20, // key_f20, kf20, FA - key_f21, // key_f21, kf21, FB - key_f22, // key_f22, kf22, FC - key_f23, // key_f23, kf23, FD - key_f24, // key_f24, kf24, FE - key_f25, // key_f25, kf25, FF - key_f26, // key_f26, kf26, FG - key_f27, // key_f27, kf27, FH - key_f28, // key_f28, kf28, FI - key_f29, // key_f29, kf29, FJ - key_f3, // key_f3, kf3, k3 - key_f30, // key_f30, kf30, FK - key_f31, // key_f31, kf31, FL - key_f32, // key_f32, kf32, FM - key_f33, // key_f33, kf33, FN - key_f34, // key_f34, kf34, FO - key_f35, // key_f35, kf35, FP - key_f36, // key_f36, kf36, FQ - key_f37, // key_f37, kf37, FR - key_f38, // key_f38, kf38, FS - key_f39, // key_f39, kf39, FT - key_f4, // key_f4, kf4, k4 - key_f40, // key_f40, kf40, FU - key_f41, // key_f41, kf41, FV - key_f42, // key_f42, kf42, FW - key_f43, // key_f43, kf43, FX - key_f44, // key_f44, kf44, FY - key_f45, // key_f45, kf45, FZ - key_f46, // key_f46, kf46, Fa - key_f47, // key_f47, kf47, Fb - key_f48, // key_f48, kf48, Fc - key_f49, // key_f49, kf49, Fd - key_f5, // key_f5, kf5, k5 - key_f50, // key_f50, kf50, Fe - key_f51, // key_f51, kf51, Ff - key_f52, // key_f52, kf52, Fg - key_f53, // key_f53, kf53, Fh - key_f54, // key_f54, kf54, Fi - key_f55, // key_f55, kf55, Fj - key_f56, // key_f56, kf56, Fk - key_f57, // key_f57, kf57, Fl - key_f58, // key_f58, kf58, Fm - key_f59, // key_f59, kf59, Fn - key_f6, // key_f6, kf6, k6 - key_f60, // key_f60, kf60, Fo - key_f61, // key_f61, kf61, Fp - key_f62, // key_f62, kf62, Fq - key_f63, // key_f63, kf63, Fr - key_f7, // key_f7, kf7, k7 - key_f8, // key_f8, kf8, k8 - key_f9, // key_f9, kf9, k9 - key_find, // key_find, kfnd, @0 - key_help, // key_help, khlp, %1 - key_home, // key_home, khome, kh - key_ic, // key_ic, kich1, kI - key_il, // key_il, kil1, kA - key_left, // key_left, kcub1, kl - key_ll, // key_ll, kll, kH - key_mark, // key_mark, kmrk, %2 - key_message, // key_message, kmsg, %3 - key_move, // key_move, kmov, %4 - key_next, // key_next, knxt, %5 - key_npage, // key_npage, knp, kN - key_open, // key_open, kopn, %6 - key_options, // key_options, kopt, %7 - key_ppage, // key_ppage, kpp, kP - key_previous, // key_previous, kprv, %8 - key_print, // key_print, kprt, %9 - key_redo, // key_redo, krdo, %0 - key_reference, // key_reference, kref, &1 - key_refresh, // key_refresh, krfr, &2 - key_replace, // key_replace, krpl, &3 - key_restart, // key_restart, krst, &4 - key_resume, // key_resume, kres, &5 - key_right, // key_right, kcuf1, kr - key_save, // key_save, ksav, &6 - key_sbeg, // key_sbeg, kBEG, &9 - key_scancel, // key_scancel, kCAN, &0 - key_scommand, // key_scommand, kCMD, *1 - key_scopy, // key_scopy, kCPY, *2 - key_screate, // key_screate, kCRT, *3 - key_sdc, // key_sdc, kDC, *4 - key_sdl, // key_sdl, kDL, *5 - key_select, // key_select, kslt, *6 - key_send, // key_send, kEND, *7 - key_seol, // key_seol, kEOL, *8 - key_sexit, // key_sexit, kEXT, *9 - key_sf, // key_sf, kind, kF - key_sfind, // key_sfind, kFND, *0 - key_shelp, // key_shelp, kHLP, #1 - key_shome, // key_shome, kHOM, #2 - key_sic, // key_sic, kIC, #3 - key_sleft, // key_sleft, kLFT, #4 - key_smessage, // key_smessage, kMSG, %a - key_smove, // key_smove, kMOV, %b - key_snext, // key_snext, kNXT, %c - key_soptions, // key_soptions, kOPT, %d - key_sprevious, // key_sprevious, kPRV, %e - key_sprint, // key_sprint, kPRT, %f - key_sr, // key_sr, kri, kR - key_sredo, // key_sredo, kRDO, %g - key_sreplace, // key_sreplace, kRPL, %h - key_sright, // key_sright, kRIT, %i - key_srsume, // key_srsume, kRES, %j - key_ssave, // key_ssave, kSAV, !1 - key_ssuspend, // key_ssuspend, kSPD, !2 - key_stab, // key_stab, khts, kT - key_sundo, // key_sundo, kUND, !3 - key_suspend, // key_suspend, kspd, &7 - key_undo, // key_undo, kund, &8 - key_up, // key_up, kcuu1, ku - keypad_local, // keypad_local, rmkx, ke - keypad_xmit, // keypad_xmit, smkx, ks - lab_f0, // lab_f0, lf0, l0 - lab_f1, // lab_f1, lf1, l1 - lab_f10, // lab_f10, lf10, la - lab_f2, // lab_f2, lf2, l2 - lab_f3, // lab_f3, lf3, l3 - lab_f4, // lab_f4, lf4, l4 - lab_f5, // lab_f5, lf5, l5 - lab_f6, // lab_f6, lf6, l6 - lab_f7, // lab_f7, lf7, l7 - lab_f8, // lab_f8, lf8, l8 - lab_f9, // lab_f9, lf9, l9 - label_format, // label_format, fln, Lf - label_off, // label_off, rmln, LF - label_on, // label_on, smln, LO - meta_off, // meta_off, rmm, mo - meta_on, // meta_on, smm, mm - micro_column_address, // micro_column_address, mhpa, ZY - micro_down, // micro_down, mcud1, ZZ - micro_left, // micro_left, mcub1, Za - micro_right, // micro_right, mcuf1, Zb - micro_row_address, // micro_row_address, mvpa, Zc - micro_up, // micro_up, mcuu1, Zd - newline, // newline, nel, nw - order_of_pins, // order_of_pins, porder, Ze - orig_colors, // orig_colors, oc, oc - orig_pair, // orig_pair, op, op - pad_char, // pad_char, pad, pc - parm_dch, // parm_dch, dch, DC - parm_delete_line, // parm_delete_line, dl, DL - parm_down_cursor, // parm_down_cursor, cud, DO - parm_down_micro, // parm_down_micro, mcud, Zf - parm_ich, // parm_ich, ich, IC - parm_index, // parm_index, indn, SF - parm_insert_line, // parm_insert_line, il, AL - parm_left_cursor, // parm_left_cursor, cub, LE - parm_left_micro, // parm_left_micro, mcub, Zg - parm_right_cursor, // parm_right_cursor, cuf, RI - parm_right_micro, // parm_right_micro, mcuf, Zh - parm_rindex, // parm_rindex, rin, SR - parm_up_cursor, // parm_up_cursor, cuu, UP - parm_up_micro, // parm_up_micro, mcuu, Zi - pkey_key, // pkey_key, pfkey, pk - pkey_local, // pkey_local, pfloc, pl - pkey_xmit, // pkey_xmit, pfx, px - plab_norm, // plab_norm, pln, pn - print_screen, // print_screen, mc0, ps - prtr_non, // prtr_non, mc5p, pO - prtr_off, // prtr_off, mc4, pf - prtr_on, // prtr_on, mc5, po - pulse, // pulse, pulse, PU - quick_dial, // quick_dial, qdial, QD - remove_clock, // remove_clock, rmclk, RC - repeat_char, // repeat_char, rep, rp - req_for_input, // req_for_input, rfi, RF - reset_1string, // reset_1string, rs1, r1 - reset_2string, // reset_2string, rs2, r2 - reset_3string, // reset_3string, rs3, r3 - reset_file, // reset_file, rf, rf - restore_cursor, // restore_cursor, rc, rc - row_address, // row_address, vpa, cv - save_cursor, // save_cursor, sc, sc - scroll_forward, // scroll_forward, ind, sf - scroll_reverse, // scroll_reverse, ri, sr - select_char_set, // select_char_set, scs, Zj - set_attributes, // set_attributes, sgr, sa - set_background, // set_background, setb, Sb - set_bottom_margin, // set_bottom_margin, smgb, Zk - set_bottom_margin_parm, // set_bottom_margin_parm, smgbp, Zl - set_clock, // set_clock, sclk, SC - set_color_pair, // set_color_pair, scp, sp - set_foreground, // set_foreground, setf, Sf - set_left_margin, // set_left_margin, smgl, ML - set_left_margin_parm, // set_left_margin_parm, smglp, Zm - set_right_margin, // set_right_margin, smgr, MR - set_right_margin_parm, // set_right_margin_parm, smgrp, Zn - set_tab, // set_tab, hts, st - set_top_margin, // set_top_margin, smgt, Zo - set_top_margin_parm, // set_top_margin_parm, smgtp, Zp - set_window, // set_window, wind, wi - start_bit_image, // start_bit_image, sbim, Zq - start_char_set_def, // start_char_set_def, scsd, Zr - stop_bit_image, // stop_bit_image, rbim, Zs - stop_char_set_def, // stop_char_set_def, rcsd, Zt - subscript_characters, // subscript_characters, subcs, Zu - superscript_characters, // superscript_characters, supcs, Zv - tab, // tab, ht, ta - these_cause_cr, // these_cause_cr, docr, Zw - to_status_line, // to_status_line, tsl, ts - tone, // tone, tone, TO - underline_char, // underline_char, uc, uc - up_half_line, // up_half_line, hu, hu - user0, // user0, u0, u0 - user1, // user1, u1, u1 - user2, // user2, u2, u2 - user3, // user3, u3, u3 - user4, // user4, u4, u4 - user5, // user5, u5, u5 - user6, // user6, u6, u6 - user7, // user7, u7, u7 - user8, // user8, u8, u8 - user9, // user9, u9, u9 - wait_tone, // wait_tone, wait, WA - xoff_character, // xoff_character, xoffc, XF - xon_character, // xon_character, xonc, XN - zero_motion, // zero_motion, zerom, Zx - alt_scancode_esc, // alt_scancode_esc, scesa, S8 - bit_image_carriage_return, // bit_image_carriage_return, bicr, Yv - bit_image_newline, // bit_image_newline, binel, Zz - bit_image_repeat, // bit_image_repeat, birep, Xy - char_set_names, // char_set_names, csnm, Zy - code_set_init, // code_set_init, csin, ci - color_names, // color_names, colornm, Yw - define_bit_image_region, // define_bit_image_region, defbi, Yx - device_type, // device_type, devt, dv - display_pc_char, // display_pc_char, dispc, S1 - end_bit_image_region, // end_bit_image_region, endbi, Yy - enter_pc_charset_mode, // enter_pc_charset_mode, smpch, S2 - enter_scancode_mode, // enter_scancode_mode, smsc, S4 - exit_pc_charset_mode, // exit_pc_charset_mode, rmpch, S3 - exit_scancode_mode, // exit_scancode_mode, rmsc, S5 - get_mouse, // get_mouse, getm, Gm - key_mouse, // key_mouse, kmous, Km - mouse_info, // mouse_info, minfo, Mi - pc_term_options, // pc_term_options, pctrm, S6 - pkey_plab, // pkey_plab, pfxl, xl - req_mouse_pos, // req_mouse_pos, reqmp, RQ - scancode_escape, // scancode_escape, scesc, S7 - set0_des_seq, // set0_des_seq, s0ds, s0 - set1_des_seq, // set1_des_seq, s1ds, s1 - set2_des_seq, // set2_des_seq, s2ds, s2 - set3_des_seq, // set3_des_seq, s3ds, s3 - set_a_background, // set_a_background, setab, AB - set_a_foreground, // set_a_foreground, setaf, AF - set_color_band, // set_color_band, setcolor, Yz - set_lr_margin, // set_lr_margin, smglr, ML - set_page_length, // set_page_length, slines, YZ - set_tb_margin, // set_tb_margin, smgtb, MT - enter_horizontal_hl_mode, // enter_horizontal_hl_mode, ehhlm, Xh - enter_left_hl_mode, // enter_left_hl_mode, elhlm, Xl - enter_low_hl_mode, // enter_low_hl_mode, elohlm, Xo - enter_right_hl_mode, // enter_right_hl_mode, erhlm, Xr - enter_top_hl_mode, // enter_top_hl_mode, ethlm, Xt - enter_vertical_hl_mode, // enter_vertical_hl_mode, evhlm, Xv - set_a_attributes, // set_a_attributes, sgr1, sA - set_pglen_inch, // set_pglen_inch, slength, sL) + auto_left_margin, // auto_left_margin, bw, bw + auto_right_margin, // auto_right_margin, am, am + back_color_erase, // back_color_erase, bce, ut + can_change, // can_change, ccc, cc + ceol_standout_glitch, // ceol_standout_glitch, xhp, xs + col_addr_glitch, // col_addr_glitch, xhpa, YA + cpi_changes_res, // cpi_changes_res, cpix, YF + cr_cancels_micro_mode, // cr_cancels_micro_mode, crxm, YB + dest_tabs_magic_smso, // dest_tabs_magic_smso, xt, xt + eat_newline_glitch, // eat_newline_glitch, xenl, xn + erase_overstrike, // erase_overstrike, eo, eo + generic_type, // generic_type, gn, gn + hard_copy, // hard_copy, hc, hc + hard_cursor, // hard_cursor, chts, HC + has_meta_key, // has_meta_key, km, km + has_print_wheel, // has_print_wheel, daisy, YC + has_status_line, // has_status_line, hs, hs + hue_lightness_saturation, // hue_lightness_saturation, hls, hl + insert_null_glitch, // insert_null_glitch, in, in + lpi_changes_res, // lpi_changes_res, lpix, YG + memory_above, // memory_above, da, da + memory_below, // memory_below, db, db + move_insert_mode, // move_insert_mode, mir, mi + move_standout_mode, // move_standout_mode, msgr, ms + needs_xon_xoff, // needs_xon_xoff, nxon, nx + no_esc_ctlc, // no_esc_ctlc, xsb, xb + no_pad_char, // no_pad_char, npc, NP + non_dest_scroll_region, // non_dest_scroll_region, ndscr, ND + non_rev_rmcup, // non_rev_rmcup, nrrmc, NR + over_strike, // over_strike, os, os + prtr_silent, // prtr_silent, mc5i, 5i + row_addr_glitch, // row_addr_glitch, xvpa, YD + semi_auto_right_margin, // semi_auto_right_margin, sam, YE + status_line_esc_ok, // status_line_esc_ok, eslok, es + tilde_glitch, // tilde_glitch, hz, hz + transparent_underline, // transparent_underline, ul, ul + xon_xoff, // xon_xoff, xon, xo + columns, // columns, cols, co + init_tabs, // init_tabs, it, it + label_height, // label_height, lh, lh + label_width, // label_width, lw, lw + lines, // lines, lines, li + lines_of_memory, // lines_of_memory, lm, lm + magic_cookie_glitch, // magic_cookie_glitch, xmc, sg + max_attributes, // max_attributes, ma, ma + max_colors, // max_colors, colors, Co + max_pairs, // max_pairs, pairs, pa + maximum_windows, // maximum_windows, wnum, MW + no_color_video, // no_color_video, ncv, NC + num_labels, // num_labels, nlab, Nl + padding_baud_rate, // padding_baud_rate, pb, pb + virtual_terminal, // virtual_terminal, vt, vt + width_status_line, // width_status_line, wsl, ws + bit_image_entwining, // bit_image_entwining, bitwin, Yo + bit_image_type, // bit_image_type, bitype, Yp + buffer_capacity, // buffer_capacity, bufsz, Ya + buttons, // buttons, btns, BT + dot_horz_spacing, // dot_horz_spacing, spinh, Yc + dot_vert_spacing, // dot_vert_spacing, spinv, Yb + max_micro_address, // max_micro_address, maddr, Yd + max_micro_jump, // max_micro_jump, mjump, Ye + micro_col_size, // micro_col_size, mcs, Yf + micro_line_size, // micro_line_size, mls, Yg + number_of_pins, // number_of_pins, npins, Yh + output_res_char, // output_res_char, orc, Yi + output_res_horz_inch, // output_res_horz_inch, orhi, Yk + output_res_line, // output_res_line, orl, Yj + output_res_vert_inch, // output_res_vert_inch, orvi, Yl + print_rate, // print_rate, cps, Ym + wide_char_size, // wide_char_size, widcs, Yn + acs_chars, // acs_chars, acsc, ac + back_tab, // back_tab, cbt, bt + bell, // bell, bel, bl + carriage_return, // carriage_return, cr, cr + change_char_pitch, // change_char_pitch, cpi, ZA + change_line_pitch, // change_line_pitch, lpi, ZB + change_res_horz, // change_res_horz, chr, ZC + change_res_vert, // change_res_vert, cvr, ZD + change_scroll_region, // change_scroll_region, csr, cs + char_padding, // char_padding, rmp, rP + clear_all_tabs, // clear_all_tabs, tbc, ct + clear_margins, // clear_margins, mgc, MC + clear_screen, // clear_screen, clear, cl + clr_bol, // clr_bol, el1, cb + clr_eol, // clr_eol, el, ce + clr_eos, // clr_eos, ed, cd + column_address, // column_address, hpa, ch + command_character, // command_character, cmdch, CC + create_window, // create_window, cwin, CW + cursor_address, // cursor_address, cup, cm + cursor_down, // cursor_down, cud1, do + cursor_home, // cursor_home, home, ho + cursor_invisible, // cursor_invisible, civis, vi + cursor_left, // cursor_left, cub1, le + cursor_mem_address, // cursor_mem_address, mrcup, CM + cursor_normal, // cursor_normal, cnorm, ve + cursor_right, // cursor_right, cuf1, nd + cursor_to_ll, // cursor_to_ll, ll, ll + cursor_up, // cursor_up, cuu1, up + cursor_visible, // cursor_visible, cvvis, vs + define_char, // define_char, defc, ZE + delete_character, // delete_character, dch1, dc + delete_line, // delete_line, dl1, dl + dial_phone, // dial_phone, dial, DI + dis_status_line, // dis_status_line, dsl, ds + display_clock, // display_clock, dclk, DK + down_half_line, // down_half_line, hd, hd + ena_acs, // ena_acs, enacs, eA + enter_alt_charset_mode, // enter_alt_charset_mode, smacs, as + enter_am_mode, // enter_am_mode, smam, SA + enter_blink_mode, // enter_blink_mode, blink, mb + enter_bold_mode, // enter_bold_mode, bold, md + enter_ca_mode, // enter_ca_mode, smcup, ti + enter_delete_mode, // enter_delete_mode, smdc, dm + enter_dim_mode, // enter_dim_mode, dim, mh + enter_doublewide_mode, // enter_doublewide_mode, swidm, ZF + enter_draft_quality, // enter_draft_quality, sdrfq, ZG + enter_insert_mode, // enter_insert_mode, smir, im + enter_italics_mode, // enter_italics_mode, sitm, ZH + enter_leftward_mode, // enter_leftward_mode, slm, ZI + enter_micro_mode, // enter_micro_mode, smicm, ZJ + enter_near_letter_quality, // enter_near_letter_quality, snlq, ZK + enter_normal_quality, // enter_normal_quality, snrmq, ZL + enter_protected_mode, // enter_protected_mode, prot, mp + enter_reverse_mode, // enter_reverse_mode, rev, mr + enter_secure_mode, // enter_secure_mode, invis, mk + enter_shadow_mode, // enter_shadow_mode, sshm, ZM + enter_standout_mode, // enter_standout_mode, smso, so + enter_subscript_mode, // enter_subscript_mode, ssubm, ZN + enter_superscript_mode, // enter_superscript_mode, ssupm, ZO + enter_underline_mode, // enter_underline_mode, smul, us + enter_upward_mode, // enter_upward_mode, sum, ZP + enter_xon_mode, // enter_xon_mode, smxon, SX + erase_chars, // erase_chars, ech, ec + exit_alt_charset_mode, // exit_alt_charset_mode, rmacs, ae + exit_am_mode, // exit_am_mode, rmam, RA + exit_attribute_mode, // exit_attribute_mode, sgr0, me + exit_ca_mode, // exit_ca_mode, rmcup, te + exit_delete_mode, // exit_delete_mode, rmdc, ed + exit_doublewide_mode, // exit_doublewide_mode, rwidm, ZQ + exit_insert_mode, // exit_insert_mode, rmir, ei + exit_italics_mode, // exit_italics_mode, ritm, ZR + exit_leftward_mode, // exit_leftward_mode, rlm, ZS + exit_micro_mode, // exit_micro_mode, rmicm, ZT + exit_shadow_mode, // exit_shadow_mode, rshm, ZU + exit_standout_mode, // exit_standout_mode, rmso, se + exit_subscript_mode, // exit_subscript_mode, rsubm, ZV + exit_superscript_mode, // exit_superscript_mode, rsupm, ZW + exit_underline_mode, // exit_underline_mode, rmul, ue + exit_upward_mode, // exit_upward_mode, rum, ZX + exit_xon_mode, // exit_xon_mode, rmxon, RX + fixed_pause, // fixed_pause, pause, PA + flash_hook, // flash_hook, hook, fh + flash_screen, // flash_screen, flash, vb + form_feed, // form_feed, ff, ff + from_status_line, // from_status_line, fsl, fs + goto_window, // goto_window, wingo, WG + hangup, // hangup, hup, HU + init_1string, // init_1string, is1, i1 + init_2string, // init_2string, is2, is + init_3string, // init_3string, is3, i3 + init_file, // init_file, if, if + init_prog, // init_prog, iprog, iP + initialize_color, // initialize_color, initc, Ic + initialize_pair, // initialize_pair, initp, Ip + insert_character, // insert_character, ich1, ic + insert_line, // insert_line, il1, al + insert_padding, // insert_padding, ip, ip + key_a1, // key_a1, ka1, K1 + key_a3, // key_a3, ka3, K3 + key_b2, // key_b2, kb2, K2 + key_backspace, // key_backspace, kbs, kb + key_beg, // key_beg, kbeg, @1 + key_btab, // key_btab, kcbt, kB + key_c1, // key_c1, kc1, K4 + key_c3, // key_c3, kc3, K5 + key_cancel, // key_cancel, kcan, @2 + key_catab, // key_catab, ktbc, ka + key_clear, // key_clear, kclr, kC + key_close, // key_close, kclo, @3 + key_command, // key_command, kcmd, @4 + key_copy, // key_copy, kcpy, @5 + key_create, // key_create, kcrt, @6 + key_ctab, // key_ctab, kctab, kt + key_dc, // key_dc, kdch1, kD + key_dl, // key_dl, kdl1, kL + key_down, // key_down, kcud1, kd + key_eic, // key_eic, krmir, kM + key_end, // key_end, kend, @7 + key_enter, // key_enter, kent, @8 + key_eol, // key_eol, kel, kE + key_eos, // key_eos, ked, kS + key_exit, // key_exit, kext, @9 + key_f0, // key_f0, kf0, k0 + key_f1, // key_f1, kf1, k1 + key_f10, // key_f10, kf10, k; + key_f11, // key_f11, kf11, F1 + key_f12, // key_f12, kf12, F2 + key_f13, // key_f13, kf13, F3 + key_f14, // key_f14, kf14, F4 + key_f15, // key_f15, kf15, F5 + key_f16, // key_f16, kf16, F6 + key_f17, // key_f17, kf17, F7 + key_f18, // key_f18, kf18, F8 + key_f19, // key_f19, kf19, F9 + key_f2, // key_f2, kf2, k2 + key_f20, // key_f20, kf20, FA + key_f21, // key_f21, kf21, FB + key_f22, // key_f22, kf22, FC + key_f23, // key_f23, kf23, FD + key_f24, // key_f24, kf24, FE + key_f25, // key_f25, kf25, FF + key_f26, // key_f26, kf26, FG + key_f27, // key_f27, kf27, FH + key_f28, // key_f28, kf28, FI + key_f29, // key_f29, kf29, FJ + key_f3, // key_f3, kf3, k3 + key_f30, // key_f30, kf30, FK + key_f31, // key_f31, kf31, FL + key_f32, // key_f32, kf32, FM + key_f33, // key_f33, kf33, FN + key_f34, // key_f34, kf34, FO + key_f35, // key_f35, kf35, FP + key_f36, // key_f36, kf36, FQ + key_f37, // key_f37, kf37, FR + key_f38, // key_f38, kf38, FS + key_f39, // key_f39, kf39, FT + key_f4, // key_f4, kf4, k4 + key_f40, // key_f40, kf40, FU + key_f41, // key_f41, kf41, FV + key_f42, // key_f42, kf42, FW + key_f43, // key_f43, kf43, FX + key_f44, // key_f44, kf44, FY + key_f45, // key_f45, kf45, FZ + key_f46, // key_f46, kf46, Fa + key_f47, // key_f47, kf47, Fb + key_f48, // key_f48, kf48, Fc + key_f49, // key_f49, kf49, Fd + key_f5, // key_f5, kf5, k5 + key_f50, // key_f50, kf50, Fe + key_f51, // key_f51, kf51, Ff + key_f52, // key_f52, kf52, Fg + key_f53, // key_f53, kf53, Fh + key_f54, // key_f54, kf54, Fi + key_f55, // key_f55, kf55, Fj + key_f56, // key_f56, kf56, Fk + key_f57, // key_f57, kf57, Fl + key_f58, // key_f58, kf58, Fm + key_f59, // key_f59, kf59, Fn + key_f6, // key_f6, kf6, k6 + key_f60, // key_f60, kf60, Fo + key_f61, // key_f61, kf61, Fp + key_f62, // key_f62, kf62, Fq + key_f63, // key_f63, kf63, Fr + key_f7, // key_f7, kf7, k7 + key_f8, // key_f8, kf8, k8 + key_f9, // key_f9, kf9, k9 + key_find, // key_find, kfnd, @0 + key_help, // key_help, khlp, %1 + key_home, // key_home, khome, kh + key_ic, // key_ic, kich1, kI + key_il, // key_il, kil1, kA + key_left, // key_left, kcub1, kl + key_ll, // key_ll, kll, kH + key_mark, // key_mark, kmrk, %2 + key_message, // key_message, kmsg, %3 + key_move, // key_move, kmov, %4 + key_next, // key_next, knxt, %5 + key_npage, // key_npage, knp, kN + key_open, // key_open, kopn, %6 + key_options, // key_options, kopt, %7 + key_ppage, // key_ppage, kpp, kP + key_previous, // key_previous, kprv, %8 + key_print, // key_print, kprt, %9 + key_redo, // key_redo, krdo, %0 + key_reference, // key_reference, kref, &1 + key_refresh, // key_refresh, krfr, &2 + key_replace, // key_replace, krpl, &3 + key_restart, // key_restart, krst, &4 + key_resume, // key_resume, kres, &5 + key_right, // key_right, kcuf1, kr + key_save, // key_save, ksav, &6 + key_sbeg, // key_sbeg, kBEG, &9 + key_scancel, // key_scancel, kCAN, &0 + key_scommand, // key_scommand, kCMD, *1 + key_scopy, // key_scopy, kCPY, *2 + key_screate, // key_screate, kCRT, *3 + key_sdc, // key_sdc, kDC, *4 + key_sdl, // key_sdl, kDL, *5 + key_select, // key_select, kslt, *6 + key_send, // key_send, kEND, *7 + key_seol, // key_seol, kEOL, *8 + key_sexit, // key_sexit, kEXT, *9 + key_sf, // key_sf, kind, kF + key_sfind, // key_sfind, kFND, *0 + key_shelp, // key_shelp, kHLP, #1 + key_shome, // key_shome, kHOM, #2 + key_sic, // key_sic, kIC, #3 + key_sleft, // key_sleft, kLFT, #4 + key_smessage, // key_smessage, kMSG, %a + key_smove, // key_smove, kMOV, %b + key_snext, // key_snext, kNXT, %c + key_soptions, // key_soptions, kOPT, %d + key_sprevious, // key_sprevious, kPRV, %e + key_sprint, // key_sprint, kPRT, %f + key_sr, // key_sr, kri, kR + key_sredo, // key_sredo, kRDO, %g + key_sreplace, // key_sreplace, kRPL, %h + key_sright, // key_sright, kRIT, %i + key_srsume, // key_srsume, kRES, %j + key_ssave, // key_ssave, kSAV, !1 + key_ssuspend, // key_ssuspend, kSPD, !2 + key_stab, // key_stab, khts, kT + key_sundo, // key_sundo, kUND, !3 + key_suspend, // key_suspend, kspd, &7 + key_undo, // key_undo, kund, &8 + key_up, // key_up, kcuu1, ku + keypad_local, // keypad_local, rmkx, ke + keypad_xmit, // keypad_xmit, smkx, ks + lab_f0, // lab_f0, lf0, l0 + lab_f1, // lab_f1, lf1, l1 + lab_f10, // lab_f10, lf10, la + lab_f2, // lab_f2, lf2, l2 + lab_f3, // lab_f3, lf3, l3 + lab_f4, // lab_f4, lf4, l4 + lab_f5, // lab_f5, lf5, l5 + lab_f6, // lab_f6, lf6, l6 + lab_f7, // lab_f7, lf7, l7 + lab_f8, // lab_f8, lf8, l8 + lab_f9, // lab_f9, lf9, l9 + label_format, // label_format, fln, Lf + label_off, // label_off, rmln, LF + label_on, // label_on, smln, LO + meta_off, // meta_off, rmm, mo + meta_on, // meta_on, smm, mm + micro_column_address, // micro_column_address, mhpa, ZY + micro_down, // micro_down, mcud1, ZZ + micro_left, // micro_left, mcub1, Za + micro_right, // micro_right, mcuf1, Zb + micro_row_address, // micro_row_address, mvpa, Zc + micro_up, // micro_up, mcuu1, Zd + newline, // newline, nel, nw + order_of_pins, // order_of_pins, porder, Ze + orig_colors, // orig_colors, oc, oc + orig_pair, // orig_pair, op, op + pad_char, // pad_char, pad, pc + parm_dch, // parm_dch, dch, DC + parm_delete_line, // parm_delete_line, dl, DL + parm_down_cursor, // parm_down_cursor, cud, DO + parm_down_micro, // parm_down_micro, mcud, Zf + parm_ich, // parm_ich, ich, IC + parm_index, // parm_index, indn, SF + parm_insert_line, // parm_insert_line, il, AL + parm_left_cursor, // parm_left_cursor, cub, LE + parm_left_micro, // parm_left_micro, mcub, Zg + parm_right_cursor, // parm_right_cursor, cuf, RI + parm_right_micro, // parm_right_micro, mcuf, Zh + parm_rindex, // parm_rindex, rin, SR + parm_up_cursor, // parm_up_cursor, cuu, UP + parm_up_micro, // parm_up_micro, mcuu, Zi + pkey_key, // pkey_key, pfkey, pk + pkey_local, // pkey_local, pfloc, pl + pkey_xmit, // pkey_xmit, pfx, px + plab_norm, // plab_norm, pln, pn + print_screen, // print_screen, mc0, ps + prtr_non, // prtr_non, mc5p, pO + prtr_off, // prtr_off, mc4, pf + prtr_on, // prtr_on, mc5, po + pulse, // pulse, pulse, PU + quick_dial, // quick_dial, qdial, QD + remove_clock, // remove_clock, rmclk, RC + repeat_char, // repeat_char, rep, rp + req_for_input, // req_for_input, rfi, RF + reset_1string, // reset_1string, rs1, r1 + reset_2string, // reset_2string, rs2, r2 + reset_3string, // reset_3string, rs3, r3 + reset_file, // reset_file, rf, rf + restore_cursor, // restore_cursor, rc, rc + row_address, // row_address, vpa, cv + save_cursor, // save_cursor, sc, sc + scroll_forward, // scroll_forward, ind, sf + scroll_reverse, // scroll_reverse, ri, sr + select_char_set, // select_char_set, scs, Zj + set_attributes, // set_attributes, sgr, sa + set_background, // set_background, setb, Sb + set_bottom_margin, // set_bottom_margin, smgb, Zk + set_bottom_margin_parm, // set_bottom_margin_parm, smgbp, Zl + set_clock, // set_clock, sclk, SC + set_color_pair, // set_color_pair, scp, sp + set_foreground, // set_foreground, setf, Sf + set_left_margin, // set_left_margin, smgl, ML + set_left_margin_parm, // set_left_margin_parm, smglp, Zm + set_right_margin, // set_right_margin, smgr, MR + set_right_margin_parm, // set_right_margin_parm, smgrp, Zn + set_tab, // set_tab, hts, st + set_top_margin, // set_top_margin, smgt, Zo + set_top_margin_parm, // set_top_margin_parm, smgtp, Zp + set_window, // set_window, wind, wi + start_bit_image, // start_bit_image, sbim, Zq + start_char_set_def, // start_char_set_def, scsd, Zr + stop_bit_image, // stop_bit_image, rbim, Zs + stop_char_set_def, // stop_char_set_def, rcsd, Zt + subscript_characters, // subscript_characters, subcs, Zu + superscript_characters, // superscript_characters, supcs, Zv + tab, // tab, ht, ta + these_cause_cr, // these_cause_cr, docr, Zw + to_status_line, // to_status_line, tsl, ts + tone, // tone, tone, TO + underline_char, // underline_char, uc, uc + up_half_line, // up_half_line, hu, hu + user0, // user0, u0, u0 + user1, // user1, u1, u1 + user2, // user2, u2, u2 + user3, // user3, u3, u3 + user4, // user4, u4, u4 + user5, // user5, u5, u5 + user6, // user6, u6, u6 + user7, // user7, u7, u7 + user8, // user8, u8, u8 + user9, // user9, u9, u9 + wait_tone, // wait_tone, wait, WA + xoff_character, // xoff_character, xoffc, XF + xon_character, // xon_character, xonc, XN + zero_motion, // zero_motion, zerom, Zx + alt_scancode_esc, // alt_scancode_esc, scesa, S8 + bit_image_carriage_return, // bit_image_carriage_return, bicr, Yv + bit_image_newline, // bit_image_newline, binel, Zz + bit_image_repeat, // bit_image_repeat, birep, Xy + char_set_names, // char_set_names, csnm, Zy + code_set_init, // code_set_init, csin, ci + color_names, // color_names, colornm, Yw + define_bit_image_region, // define_bit_image_region, defbi, Yx + device_type, // device_type, devt, dv + display_pc_char, // display_pc_char, dispc, S1 + end_bit_image_region, // end_bit_image_region, endbi, Yy + enter_pc_charset_mode, // enter_pc_charset_mode, smpch, S2 + enter_scancode_mode, // enter_scancode_mode, smsc, S4 + exit_pc_charset_mode, // exit_pc_charset_mode, rmpch, S3 + exit_scancode_mode, // exit_scancode_mode, rmsc, S5 + get_mouse, // get_mouse, getm, Gm + key_mouse, // key_mouse, kmous, Km + mouse_info, // mouse_info, minfo, Mi + pc_term_options, // pc_term_options, pctrm, S6 + pkey_plab, // pkey_plab, pfxl, xl + req_mouse_pos, // req_mouse_pos, reqmp, RQ + scancode_escape, // scancode_escape, scesc, S7 + set0_des_seq, // set0_des_seq, s0ds, s0 + set1_des_seq, // set1_des_seq, s1ds, s1 + set2_des_seq, // set2_des_seq, s2ds, s2 + set3_des_seq, // set3_des_seq, s3ds, s3 + set_a_background, // set_a_background, setab, AB + set_a_foreground, // set_a_foreground, setaf, AF + set_color_band, // set_color_band, setcolor, Yz + set_lr_margin, // set_lr_margin, smglr, ML + set_page_length, // set_page_length, slines, YZ + set_tb_margin, // set_tb_margin, smgtb, MT + enter_horizontal_hl_mode, // enter_horizontal_hl_mode, ehhlm, Xh + enter_left_hl_mode, // enter_left_hl_mode, elhlm, Xl + enter_low_hl_mode, // enter_low_hl_mode, elohlm, Xo + enter_right_hl_mode, // enter_right_hl_mode, erhlm, Xr + enter_top_hl_mode, // enter_top_hl_mode, ethlm, Xt + enter_vertical_hl_mode, // enter_vertical_hl_mode, evhlm, Xv + set_a_attributes, // set_a_attributes, sgr1, sA + set_pglen_inch, // set_pglen_inch, slength, sL) ; public String[] getNames() { @@ -515,8 +513,9 @@ public final class InfoCmp { public static Map getCapabilitiesByName() { Map capabilities = new LinkedHashMap<>(); try (InputStream is = InfoCmp.class.getResourceAsStream("capabilities.txt"); - BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - br.lines().map(String::trim) + BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + br.lines() + .map(String::trim) .filter(s -> !s.startsWith("#")) .filter(s -> !s.isEmpty()) .forEach(s -> { @@ -539,9 +538,7 @@ public final class InfoCmp { CAPS.putIfAbsent(terminal, caps); } - public static String getInfoCmp( - String terminal - ) throws IOException, InterruptedException { + public static String getInfoCmp(String terminal) throws IOException, InterruptedException { String caps = getLoadedInfoCmp(terminal); if (caps == null) { Process p = new ProcessBuilder(OSUtils.INFOCMP_COMMAND, terminal).start(); @@ -563,8 +560,7 @@ public final class InfoCmp { String capabilities, Set bools, Map ints, - Map strings - ) { + Map strings) { Map capsByName = getCapabilitiesByName(); String[] lines = capabilities.split("\n"); for (int i = 1; i < lines.length; i++) { @@ -609,7 +605,7 @@ public final class InfoCmp { static String loadDefaultInfoCmp(String name) { try (InputStream is = InfoCmp.class.getResourceAsStream(name + ".caps"); - BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { return br.lines().collect(Collectors.joining("\n", "", "\n")); } catch (IOException e) { throw new IOError(e); @@ -617,11 +613,23 @@ public final class InfoCmp { } static { - for (String s : Arrays.asList("dumb", "dumb-color", "ansi", "xterm", "xterm-256color", - "windows", "windows-256color", "windows-conemu", "windows-vtp", - "screen", "screen-256color", "rxvt-unicode", "rxvt-unicode-256color", "rxvt-basic", "rxvt")) { + for (String s : Arrays.asList( + "dumb", + "dumb-color", + "ansi", + "xterm", + "xterm-256color", + "windows", + "windows-256color", + "windows-conemu", + "windows-vtp", + "screen", + "screen-256color", + "rxvt-unicode", + "rxvt-unicode-256color", + "rxvt-basic", + "rxvt")) { setDefaultInfoCmp(s, () -> loadDefaultInfoCmp(s)); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InputStreamReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InputStreamReader.java index fda314fb9b4..449d6aa69c8 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InputStreamReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InputStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -22,7 +22,6 @@ import java.nio.charset.CodingErrorAction; import java.nio.charset.MalformedInputException; import java.nio.charset.UnmappableCharacterException; - /** * * NOTE for JLine: the default InputStreamReader that comes from the JRE @@ -66,9 +65,10 @@ public class InputStreamReader extends Reader { public InputStreamReader(InputStream in) { super(in); this.in = in; - decoder = Charset.defaultCharset().newDecoder().onMalformedInput( - CodingErrorAction.REPLACE).onUnmappableCharacter( - CodingErrorAction.REPLACE); + decoder = Charset.defaultCharset() + .newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); bytes.limit(0); } @@ -87,20 +87,19 @@ public class InputStreamReader extends Reader { * @throws UnsupportedEncodingException * if the encoding specified by {@code enc} cannot be found. */ - public InputStreamReader(InputStream in, final String enc) - throws UnsupportedEncodingException { + public InputStreamReader(InputStream in, final String enc) throws UnsupportedEncodingException { super(in); if (enc == null) { throw new NullPointerException(); } this.in = in; try { - decoder = Charset.forName(enc).newDecoder().onMalformedInput( - CodingErrorAction.REPLACE).onUnmappableCharacter( - CodingErrorAction.REPLACE); + decoder = Charset.forName(enc) + .newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); } catch (IllegalArgumentException e) { - throw (UnsupportedEncodingException) - new UnsupportedEncodingException(enc).initCause(e); + throw (UnsupportedEncodingException) new UnsupportedEncodingException(enc).initCause(e); } bytes.limit(0); } @@ -134,9 +133,9 @@ public class InputStreamReader extends Reader { public InputStreamReader(InputStream in, Charset charset) { super(in); this.in = in; - decoder = charset.newDecoder().onMalformedInput( - CodingErrorAction.REPLACE).onUnmappableCharacter( - CodingErrorAction.REPLACE); + decoder = charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); bytes.limit(0); } @@ -257,8 +256,7 @@ public class InputStreamReader extends Reader { // fill the buffer if needed if (needInput) { try { - if ((in.available() == 0) - && (out.position() > offset)) { + if ((in.available() == 0) && (out.position() > offset)) { // we could return the result without blocking read break; } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Levenshtein.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Levenshtein.java index cc95593ed80..015515f7d07 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Levenshtein.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Levenshtein.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -49,9 +49,8 @@ public class Levenshtein { return distance(lhs, rhs, 1, 1, 1, 1); } - public static int distance(CharSequence source, CharSequence target, - int deleteCost, int insertCost, - int replaceCost, int swapCost) { + public static int distance( + CharSequence source, CharSequence target, int deleteCost, int insertCost, int replaceCost, int swapCost) { /* * Required to facilitate the premise to the algorithm that two swaps of the * same character are never required for optimality. @@ -115,5 +114,4 @@ public class Levenshtein { } return table[source.length() - 1][target.length() - 1]; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Log.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Log.java index 91f18755e25..254173d5bd9 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Log.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -73,8 +73,7 @@ public final class Log { } } out.print("]"); - } - else { + } else { out.print(message); } } @@ -84,11 +83,10 @@ public final class Log { // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // PrintStream ps = new PrintStream(baos); // for (int i = 0; i < messages.length; i++) { -// // Special handling for the last message if its a throwable, render its stack on the next line +// // Special handling for the last message if it's a throwable, render its stack on the next line // if (i + 1 == messages.length && messages[i] instanceof Throwable) { // cause = (Throwable) messages[i]; -// } -// else { +// } else { // render(ps, messages[i]); // } // } @@ -122,5 +120,4 @@ public final class Log { // static boolean isEnabled(Level level) { // return logger.isLoggable(level); // } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java index f8cb53489f9..4130634ca4b 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -84,8 +84,7 @@ public class NonBlocking { @Override public int available() { - return (int) (reader.available() * this.encoder.averageBytesPerChar()) - + bytes.remaining(); + return (int) (reader.available() * this.encoder.averageBytesPerChar()) + bytes.remaining(); } @Override @@ -124,7 +123,6 @@ public class NonBlocking { return READ_EXPIRED; } } - } private static class NonBlockingInputStreamReader extends NonBlockingReader { @@ -135,10 +133,12 @@ public class NonBlocking { private final CharBuffer chars; public NonBlockingInputStreamReader(NonBlockingInputStream inputStream, Charset encoding) { - this(inputStream, - (encoding != null ? encoding : Charset.defaultCharset()).newDecoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE)); + this( + inputStream, + (encoding != null ? encoding : Charset.defaultCharset()) + .newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE)); } public NonBlockingInputStreamReader(NonBlockingInputStream input, CharsetDecoder decoder) { @@ -201,8 +201,8 @@ public class NonBlocking { bytes.position(0); bytes.limit(0); } - int nb = input.readBuffered(bytes.array(), bytes.limit(), - bytes.capacity() - bytes.limit(), t.timeout()); + int nb = input.readBuffered( + bytes.array(), bytes.limit(), bytes.capacity() - bytes.limit(), t.timeout()); if (nb < 0) { return nb; } @@ -227,5 +227,4 @@ public class NonBlocking { input.close(); } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java index a4283eb7006..10ab68cfd28 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -74,7 +74,7 @@ public abstract class NonBlockingInputStream extends InputStream { if (c == EOF) { return EOF; } - b[off] = (byte)c; + b[off] = (byte) c; return 1; } @@ -115,9 +115,7 @@ public abstract class NonBlockingInputStream extends InputStream { * thread is currently blocked waiting for I/O it may not actually * shut down until the I/O is received. */ - public void shutdown() { - } + public void shutdown() {} public abstract int read(long timeout, boolean isPeek) throws IOException; - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java index 680047fbe60..24cf13a0ee5 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -26,17 +26,15 @@ import java.io.InterruptedIOException; * the thread that handles blocking I/O. * */ -public class NonBlockingInputStreamImpl - extends NonBlockingInputStream -{ - private InputStream in; // The actual input stream - private int b = READ_EXPIRED; // Recently read byte +public class NonBlockingInputStreamImpl extends NonBlockingInputStream { + private InputStream in; // The actual input stream + private int b = READ_EXPIRED; // Recently read byte - private String name; - private boolean threadIsReading = false; - private IOException exception = null; - private long threadDelay = 60 * 1000; - private Thread thread; + private String name; + private boolean threadIsReading = false; + private IOException exception = null; + private long threadDelay = 60 * 1000; + private Thread thread; /** * Creates a NonBlockingReader out of a normal blocking @@ -97,8 +95,7 @@ public class NonBlockingInputStreamImpl if (exception != null) { assert b == READ_EXPIRED; IOException toBeThrown = exception; - if (!isPeek) - exception = null; + if (!isPeek) exception = null; throw toBeThrown; } @@ -109,11 +106,9 @@ public class NonBlockingInputStreamImpl */ if (b >= -1) { assert exception == null; - } - else if (!isPeek && timeout <= 0L && !threadIsReading) { + } else if (!isPeek && timeout <= 0L && !threadIsReading) { b = in.read(); - } - else { + } else { /* * If the thread isn't reading already, then ask it to do so. */ @@ -128,14 +123,13 @@ public class NonBlockingInputStreamImpl * now we play the waiting game. */ Timeout t = new Timeout(timeout); - while (!t.elapsed()) { + while (!t.elapsed()) { try { if (Thread.interrupted()) { throw new InterruptedException(); } wait(t.timeout()); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { exception = (IOException) new InterruptedIOException().initCause(e); } @@ -143,8 +137,7 @@ public class NonBlockingInputStreamImpl assert b == READ_EXPIRED; IOException toBeThrown = exception; - if (!isPeek) - exception = null; + if (!isPeek) exception = null; throw toBeThrown; } @@ -168,7 +161,7 @@ public class NonBlockingInputStreamImpl return ret; } - private void run () { + private void run() { Log.debug("NonBlockingInputStream start"); boolean needToRead; @@ -236,5 +229,4 @@ public class NonBlockingInputStreamImpl } } } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java index 5a361344350..aad6e3d0f5a 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -57,11 +57,7 @@ public class NonBlockingPumpInputStream extends NonBlockingInputStream { throw new InterruptedIOException(); } } - return buffer.hasRemaining() - ? 0 - : closed - ? EOF - : READ_EXPIRED; + return buffer.hasRemaining() ? 0 : closed ? EOF : READ_EXPIRED; } private static boolean rewind(ByteBuffer buffer, ByteBuffer other) { @@ -167,7 +163,7 @@ public class NonBlockingPumpInputStream extends NonBlockingInputStream { @Override public void write(int b) throws IOException { - NonBlockingPumpInputStream.this.write(new byte[] { (byte) b }, 0, 1); + NonBlockingPumpInputStream.this.write(new byte[] {(byte) b}, 0, 1); } @Override @@ -184,7 +180,5 @@ public class NonBlockingPumpInputStream extends NonBlockingInputStream { public void close() throws IOException { NonBlockingPumpInputStream.this.close(); } - } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java index f36423f03b8..63db6e5f5bf 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -121,7 +121,7 @@ public class NonBlockingPumpReader extends NonBlockingReader { try { if (timeout > 0) { if (!notEmpty.await(timeout, TimeUnit.MILLISECONDS)) { - throw new IOException( "Timeout reading" ); + throw new IOException("Timeout reading"); } } else { notEmpty.await(); @@ -207,14 +207,11 @@ public class NonBlockingPumpReader extends NonBlockingReader { } @Override - public void flush() throws IOException { - } + public void flush() throws IOException {} @Override public void close() throws IOException { NonBlockingPumpReader.this.close(); } - } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java index e2f664f2999..460f548b506 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -23,8 +23,7 @@ public abstract class NonBlockingReader extends Reader { * thread is currently blocked waiting for I/O it will not actually * shut down until the I/O is received. */ - public void shutdown() { - } + public void shutdown() {} @Override public int read() throws IOException { @@ -109,5 +108,4 @@ public abstract class NonBlockingReader extends Reader { * @throws IOException if anything wrong happens */ protected abstract int read(long timeout, boolean isPeek) throws IOException; - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java index d384cc9a0dc..5aaabd1d3c0 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -28,19 +28,17 @@ import java.io.Reader; * @since 2.7 * @author Scott C. Gray <scottgray1@gmail.com> */ -public class NonBlockingReaderImpl - extends NonBlockingReader -{ +public class NonBlockingReaderImpl extends NonBlockingReader { public static final int READ_EXPIRED = -2; - private Reader in; // The actual input stream - private int ch = READ_EXPIRED; // Recently read character + private Reader in; // The actual input stream + private int ch = READ_EXPIRED; // Recently read character - private String name; - private boolean threadIsReading = false; - private IOException exception = null; - private long threadDelay = 60 * 1000; - private Thread thread; + private String name; + private boolean threadIsReading = false; + private IOException exception = null; + private long threadDelay = 60 * 1000; + private Thread thread; /** * Creates a NonBlockingReader out of a normal blocking @@ -135,8 +133,7 @@ public class NonBlockingReaderImpl if (exception != null) { assert ch == READ_EXPIRED; IOException toBeThrown = exception; - if (!isPeek) - exception = null; + if (!isPeek) exception = null; throw toBeThrown; } @@ -147,11 +144,9 @@ public class NonBlockingReaderImpl */ if (ch >= -1) { assert exception == null; - } - else if (!isPeek && timeout <= 0L && !threadIsReading) { + } else if (!isPeek && timeout <= 0L && !threadIsReading) { ch = in.read(); - } - else { + } else { /* * If the thread isn't reading already, then ask it to do so. */ @@ -166,14 +161,13 @@ public class NonBlockingReaderImpl * now we play the waiting game. */ Timeout t = new Timeout(timeout); - while (!t.elapsed()) { + while (!t.elapsed()) { try { if (Thread.interrupted()) { throw new InterruptedException(); } wait(t.timeout()); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { exception = (IOException) new InterruptedIOException().initCause(e); } @@ -181,8 +175,7 @@ public class NonBlockingReaderImpl assert ch == READ_EXPIRED; IOException toBeThrown = exception; - if (!isPeek) - exception = null; + if (!isPeek) exception = null; throw toBeThrown; } @@ -206,7 +199,7 @@ public class NonBlockingReaderImpl return ret; } - private void run () { + private void run() { Log.debug("NonBlockingReader start"); boolean needToRead; @@ -245,12 +238,12 @@ public class NonBlockingReaderImpl IOException failure = null; try { charRead = in.read(); -// if (charRead < 0) { -// continue; -// } + // if (charRead < 0) { + // continue; + // } } catch (IOException e) { failure = e; -// charRead = -1; + // charRead = -1; } /* diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java index 97487731852..344d081c124 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -9,16 +9,23 @@ package jdk.internal.org.jline.utils; import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; public class OSUtils { - public static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("win"); + public static final boolean IS_LINUX = + System.getProperty("os.name").toLowerCase().contains("linux"); - public static final boolean IS_CYGWIN = IS_WINDOWS - && System.getenv("PWD") != null - && System.getenv("PWD").startsWith("/"); + public static final boolean IS_WINDOWS = + System.getProperty("os.name").toLowerCase().contains("win"); + + public static final boolean IS_OSX = + System.getProperty("os.name").toLowerCase().contains("mac"); + + public static final boolean IS_AIX = + System.getProperty("os.name").toLowerCase().contains("aix"); + + public static final boolean IS_CYGWIN = + IS_WINDOWS && System.getenv("PWD") != null && System.getenv("PWD").startsWith("/"); @Deprecated public static final boolean IS_MINGW = IS_WINDOWS @@ -28,7 +35,7 @@ public class OSUtils { public static final boolean IS_MSYSTEM = IS_WINDOWS && System.getenv("MSYSTEM") != null && (System.getenv("MSYSTEM").startsWith("MINGW") - || System.getenv("MSYSTEM").equals("MSYS")); + || System.getenv("MSYSTEM").equals("MSYS")); public static final boolean IS_WSL = System.getenv("WSL_DISTRO_NAME") != null; @@ -36,11 +43,7 @@ public class OSUtils { public static final boolean IS_WSL2 = IS_WSL && !IS_WSL1; - public static final boolean IS_CONEMU = IS_WINDOWS - && System.getenv("ConEmuPID") != null; - - public static final boolean IS_OSX = System.getProperty("os.name").toLowerCase().contains("mac"); - public static final boolean IS_AIX = System.getProperty("os.name").equals("AIX"); + public static final boolean IS_CONEMU = IS_WINDOWS && System.getenv("ConEmuPID") != null; public static String TTY_COMMAND; public static String STTY_COMMAND; @@ -48,64 +51,57 @@ public class OSUtils { public static String INFOCMP_COMMAND; public static String TEST_COMMAND; + private static boolean isExecutable(File f) { + return f.canExecute() && !f.isDirectory(); + } + static { - String tty; - String stty; - String sttyfopt; - String infocmp; - String test; - if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { - tty = null; - stty = null; - sttyfopt = null; - infocmp = null; - test = null; - String path = System.getenv("PATH"); - if (path != null) { - String[] paths = path.split(";"); - for (String p : paths) { - if (tty == null && new File(p, "tty.exe").exists()) { - tty = new File(p, "tty.exe").getAbsolutePath(); - } - if (stty == null && new File(p, "stty.exe").exists()) { - stty = new File(p, "stty.exe").getAbsolutePath(); - } - if (infocmp == null && new File(p, "infocmp.exe").exists()) { - infocmp = new File(p, "infocmp.exe").getAbsolutePath(); - } - if (test == null && new File(p, "test.exe").exists()) { - test = new File(p, "test.exe").getAbsolutePath(); - } + boolean cygwinOrMsys = OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM; + String suffix = cygwinOrMsys ? ".exe" : ""; + String tty = null; + String stty = null; + String sttyfopt = null; + String infocmp = null; + String test = null; + String path = System.getenv("PATH"); + if (path != null) { + String[] paths = path.split(File.pathSeparator); + for (String p : paths) { + File ttyFile = new File(p, "tty" + suffix); + if (tty == null && isExecutable(ttyFile)) { + tty = ttyFile.getAbsolutePath(); + } + File sttyFile = new File(p, "stty" + suffix); + if (stty == null && isExecutable(sttyFile)) { + stty = sttyFile.getAbsolutePath(); + } + File infocmpFile = new File(p, "infocmp" + suffix); + if (infocmp == null && isExecutable(infocmpFile)) { + infocmp = infocmpFile.getAbsolutePath(); + } + File testFile = new File(p, "test" + suffix); + if (test == null && isExecutable(testFile)) { + test = testFile.getAbsolutePath(); } } - if (tty == null) { - tty = "tty.exe"; - } - if (stty == null) { - stty = "stty.exe"; - } - if (infocmp == null) { - infocmp = "infocmp.exe"; - } - if (test == null) { - test = "test.exe"; - } - } else { - tty = "tty"; - stty = IS_OSX ? "/bin/stty" : "stty"; - sttyfopt = IS_OSX ? "-f" : "-F"; - infocmp = "infocmp"; - test = isTestCommandValid("/usr/bin/test") ? "/usr/bin/test" - : "/bin/test"; } + if (tty == null) { + tty = "tty" + suffix; + } + if (stty == null) { + stty = "stty" + suffix; + } + if (infocmp == null) { + infocmp = "infocmp" + suffix; + } + if (test == null) { + test = "test" + suffix; + } + sttyfopt = IS_OSX ? "-f" : "-F"; TTY_COMMAND = tty; STTY_COMMAND = stty; STTY_F_OPTION = sttyfopt; INFOCMP_COMMAND = infocmp; TEST_COMMAND = test; } - - private static boolean isTestCommandValid(String command) { - return Files.isExecutable(Paths.get(command)); - } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java index e80a18b6f3c..12e9795c6f5 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -378,7 +378,6 @@ public class PumpReader extends Reader { public void close() throws IOException { reader.close(); } - } private static class InputStream extends java.io.InputStream { @@ -464,7 +463,5 @@ public class PumpReader extends Reader { public void close() throws IOException { reader.close(); } - } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ShutdownHooks.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ShutdownHooks.java index 8089de321cc..d5456df03d3 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ShutdownHooks.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/ShutdownHooks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -18,8 +18,7 @@ import java.util.Objects; * @author Jason Dillon * @since 2.7 */ -public final class ShutdownHooks -{ +public final class ShutdownHooks { private static final List tasks = new ArrayList<>(); private static Thread hook; @@ -29,8 +28,7 @@ public final class ShutdownHooks // Install the hook thread if needed if (hook == null) { - hook = addHook(new Thread("JLine Shutdown Hook") - { + hook = addHook(new Thread("JLine Shutdown Hook") { @Override public void run() { runTasks(); @@ -53,8 +51,7 @@ public final class ShutdownHooks Log.debug("Running task: ", task); try { task.run(); - } - catch (Throwable e) { + } catch (Throwable e) { Log.warn("Task failed", e); } } @@ -91,8 +88,7 @@ public final class ShutdownHooks try { Runtime.getRuntime().removeShutdownHook(thread); - } - catch (IllegalStateException e) { + } catch (IllegalStateException e) { // The VM is shutting down, not a big deal; ignore } } @@ -100,8 +96,7 @@ public final class ShutdownHooks /** * Essentially a {@link Runnable} which allows running to throw an exception. */ - public interface Task - { + public interface Task { void run() throws Exception; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Signals.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Signals.java index b94f1fa318e..9b25a804735 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Signals.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Signals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2020, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -21,8 +21,7 @@ import java.util.Objects; */ public final class Signals { - private Signals() { - } + private Signals() {} /** * @@ -41,8 +40,8 @@ public final class Signals { try { Class signalHandlerClass = Class.forName("sun.misc.SignalHandler"); // Implement signal handler - Object signalHandler = Proxy.newProxyInstance(loader, - new Class[]{signalHandlerClass}, (proxy, method, args) -> { + Object signalHandler = + Proxy.newProxyInstance(loader, new Class[] {signalHandlerClass}, (proxy, method, args) -> { // only method we are proxying is handle() if (method.getDeclaringClass() == Object.class) { if ("toString".equals(method.getName())) { @@ -101,8 +100,7 @@ public final class Signals { return null; } Class signalHandlerClass = Class.forName("sun.misc.SignalHandler"); - return signalClass.getMethod("handle", signalClass, signalHandlerClass) - .invoke(null, signal, handler); + return signalClass.getMethod("handle", signalClass, signalHandlerClass).invoke(null, signal, handler); } @SuppressWarnings("") @@ -120,5 +118,4 @@ public final class Signals { } return handler != null ? handler.toString() : "null"; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Status.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Status.java index e8d9e49e8b3..7348b1ea1c5 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Status.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Status.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2019, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -8,187 +8,266 @@ */ package jdk.internal.org.jline.utils; -import java.util.Objects; -import java.util.Collections; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import jdk.internal.org.jline.terminal.Size; import jdk.internal.org.jline.terminal.Terminal; import jdk.internal.org.jline.terminal.impl.AbstractTerminal; import jdk.internal.org.jline.utils.InfoCmp.Capability; -import jdk.internal.org.jline.terminal.Size; public class Status { - protected final AbstractTerminal terminal; + protected final Terminal terminal; protected final boolean supported; - protected List oldLines = Collections.emptyList(); - protected List linesToRestore = Collections.emptyList(); - protected int rows; - protected int columns; - protected boolean force; protected boolean suspended = false; protected AttributedString borderString; protected int border = 0; + protected Display display; + protected List lines = Collections.emptyList(); + protected int scrollRegion; public static Status getStatus(Terminal terminal) { return getStatus(terminal, true); } - public static Status getStatus(Terminal terminal, boolean create) { - return terminal instanceof AbstractTerminal - ? ((AbstractTerminal) terminal).getStatus(create) - : null; + public static Optional getExistingStatus(Terminal terminal) { + return Optional.ofNullable(getStatus(terminal, false)); } + public static Status getStatus(Terminal terminal, boolean create) { + return terminal instanceof AbstractTerminal ? ((AbstractTerminal) terminal).getStatus(create) : null; + } - public Status(AbstractTerminal terminal) { + @SuppressWarnings("this-escape") + public Status(Terminal terminal) { this.terminal = Objects.requireNonNull(terminal, "terminal can not be null"); this.supported = terminal.getStringCapability(Capability.change_scroll_region) != null - && terminal.getStringCapability(Capability.save_cursor) != null - && terminal.getStringCapability(Capability.restore_cursor) != null - && terminal.getStringCapability(Capability.cursor_address) != null; + && terminal.getStringCapability(Capability.save_cursor) != null + && terminal.getStringCapability(Capability.restore_cursor) != null + && terminal.getStringCapability(Capability.cursor_address) != null; if (supported) { - char borderChar = '\u2700'; - AttributedStringBuilder bb = new AttributedStringBuilder(); - for (int i = 0; i < 200; i++) { - bb.append(borderChar); - } - borderString = bb.toAttributedString(); + display = new MovingCursorDisplay(terminal); resize(); + display.reset(); + scrollRegion = display.rows - 1; } } + public void close() { + terminal.puts(Capability.save_cursor); + terminal.puts(Capability.change_scroll_region, 0, display.rows - 1); + terminal.puts(Capability.restore_cursor); + terminal.flush(); + } + public void setBorder(boolean border) { this.border = border ? 1 : 0; } public void resize() { - Size size = terminal.getSize(); - this.rows = size.getRows(); - this.columns = size.getColumns(); - this.force = true; + resize(terminal.getSize()); + } + + public void resize(Size size) { + display.resize(size.getRows(), size.getColumns()); } public void reset() { - this.force = true; - } - - public void hardReset() { - if (suspended) { - return; + if (supported) { + display.reset(); + scrollRegion = display.rows; + terminal.puts(Capability.change_scroll_region, 0, scrollRegion); } - List lines = new ArrayList<>(oldLines); - int b = border; - update(null); - border = b; - update(lines); } public void redraw() { if (suspended) { return; } - update(oldLines); + update(lines); } - public void clear() { - privateClear(oldLines.size()); - } - - private void clearAll() { - int b = border; - border = 0; - privateClear(oldLines.size() + b); - } - - private void privateClear(int statusSize) { - List as = new ArrayList<>(); - for (int i = 0; i < statusSize; i++) { - as.add(new AttributedString("")); - } - if (!as.isEmpty()) { - update(as); - } + public void hide() { + update(Collections.emptyList()); } public void update(List lines) { + update(lines, true); + } + + private final AttributedString ellipsis = + new AttributedStringBuilder().append("\u2026", AttributedStyle.INVERSE).toAttributedString(); + + /** + * Returns true if the cursor may be misplaced and should + * be updated. + */ + public void update(List lines, boolean flush) { if (!supported) { return; } - if (lines == null) { - lines = Collections.emptyList(); - } + this.lines = new ArrayList<>(lines); if (suspended) { - linesToRestore = new ArrayList<>(lines); return; } - if (lines.isEmpty()) { - clearAll(); + + lines = new ArrayList<>(lines); + // add border + int rows = display.rows; + int columns = display.columns; + if (border == 1 && !lines.isEmpty() && rows > 1) { + lines.add(0, getBorderString(columns)); } - if (oldLines.equals(lines) && !force) { - return; + // trim or complete lines to the full width + for (int i = 0; i < lines.size(); i++) { + AttributedString str = lines.get(i); + if (str.columnLength() > columns) { + str = new AttributedStringBuilder(columns) + .append(lines.get(i).columnSubSequence(0, columns - ellipsis.columnLength())) + .append(ellipsis) + .toAttributedString(); + } else if (str.columnLength() < columns) { + str = new AttributedStringBuilder(columns) + .append(str) + .append(' ', columns - str.columnLength()) + .toAttributedString(); + } + lines.set(i, str); } - int statusSize = lines.size() + (lines.size() == 0 ? 0 : border); - int nb = statusSize - oldLines.size() - (oldLines.size() == 0 ? 0 : border); - if (nb > 0) { - for (int i = 0; i < nb; i++) { + + List oldLines = this.display.oldLines; + + int newScrollRegion = display.rows - 1 - lines.size(); + // Update the scroll region if needed. + // Note that settings the scroll region usually moves the cursor, so we need to get ready for that. + if (newScrollRegion < scrollRegion) { + // We need to scroll up to grow the status bar + terminal.puts(Capability.save_cursor); + for (int i = newScrollRegion; i < scrollRegion; i++) { terminal.puts(Capability.cursor_down); } - for (int i = 0; i < nb; i++) { + terminal.puts(Capability.change_scroll_region, 0, newScrollRegion); + terminal.puts(Capability.restore_cursor); + for (int i = newScrollRegion; i < scrollRegion; i++) { terminal.puts(Capability.cursor_up); } + scrollRegion = newScrollRegion; + } else if (newScrollRegion > scrollRegion) { + terminal.puts(Capability.save_cursor); + terminal.puts(Capability.change_scroll_region, 0, newScrollRegion); + terminal.puts(Capability.restore_cursor); + scrollRegion = newScrollRegion; } - terminal.puts(Capability.save_cursor); - terminal.puts(Capability.cursor_address, rows - statusSize, 0); - if (!terminal.puts(Capability.clr_eos)) { - for (int i = rows - statusSize; i < rows; i++) { - terminal.puts(Capability.cursor_address, i, 0); + + // if the display has more lines, we need to add empty ones to make sure they will be erased + List toDraw = new ArrayList<>(lines); + int nbToDraw = toDraw.size(); + int nbOldLines = oldLines.size(); + if (nbOldLines > nbToDraw) { + terminal.puts(Capability.save_cursor); + terminal.puts(Capability.cursor_address, display.rows - nbOldLines, 0); + for (int i = 0; i < nbOldLines - nbToDraw; i++) { terminal.puts(Capability.clr_eol); + if (i < nbOldLines - nbToDraw - 1) { + terminal.puts(Capability.cursor_down); + } + oldLines.remove(0); } + terminal.puts(Capability.restore_cursor); } - if (border == 1 && lines.size() > 0) { - terminal.puts(Capability.cursor_address, rows - statusSize, 0); - borderString.columnSubSequence(0, columns).print(terminal); - } - for (int i = 0; i < lines.size(); i++) { - terminal.puts(Capability.cursor_address, rows - lines.size() + i, 0); - if (lines.get(i).length() > columns) { - AttributedStringBuilder asb = new AttributedStringBuilder(); - asb.append(lines.get(i).substring(0, columns - 3)).append("...", new AttributedStyle(AttributedStyle.INVERSE)); - asb.toAttributedString().columnSubSequence(0, columns).print(terminal); - } else { - lines.get(i).columnSubSequence(0, columns).print(terminal); - } - } - terminal.puts(Capability.change_scroll_region, 0, rows - 1 - statusSize); - terminal.puts(Capability.restore_cursor); - terminal.flush(); - oldLines = new ArrayList<>(lines); - force = false; + // update display + display.update(lines, -1, flush); } + private AttributedString getBorderString(int columns) { + if (borderString == null || borderString.length() != columns) { + char borderChar = '\u2700'; + AttributedStringBuilder bb = new AttributedStringBuilder(); + for (int i = 0; i < columns; i++) { + bb.append(borderChar); + } + borderString = bb.toAttributedString(); + } + return borderString; + } + + /** + * The {@code suspend} method is used when a full-screen. + * If the status was not already suspended, the lines + * used by the status are cleared during this call. + */ public void suspend() { - if (suspended) { - return; + if (!suspended) { + suspended = true; } - linesToRestore = new ArrayList<>(oldLines); - int b = border; - update(null); - border = b; - suspended = true; } + /** + * The {@code restore()} call is the opposite of {@code suspend()} and + * will make the status bar be updated again. + * If the status was suspended, the lines + * used by the status will be drawn during this call. + */ public void restore() { - if (!suspended) { - return; + if (suspended) { + suspended = false; + update(this.lines); } - suspended = false; - update(linesToRestore); - linesToRestore = Collections.emptyList(); } public int size() { - return oldLines.size() + border; + return size(this.lines); } + private int size(List lines) { + int l = lines.size(); + return l > 0 ? l + border : 0; + } + + @Override + public String toString() { + return "Status[" + "supported=" + supported + ']'; + } + + static class MovingCursorDisplay extends Display { + protected int firstLine; + + public MovingCursorDisplay(Terminal terminal) { + super(terminal, false); + } + + @Override + public void update(List newLines, int targetCursorPos, boolean flush) { + cursorPos = -1; + firstLine = rows - newLines.size(); + super.update(newLines, targetCursorPos, flush); + if (cursorPos != -1) { + terminal.puts(Capability.restore_cursor); + } + } + + @Override + protected void moveVisualCursorTo(int targetPos, List newLines) { + initCursor(); + super.moveVisualCursorTo(targetPos, newLines); + } + + @Override + protected int moveVisualCursorTo(int i1) { + initCursor(); + return super.moveVisualCursorTo(i1); + } + + void initCursor() { + if (cursorPos == -1) { + terminal.puts(Capability.save_cursor); + terminal.puts(Capability.cursor_address, firstLine, 0); + cursorPos = 0; + } + } + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java index be1659957b4..29d87cbc3c8 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -55,12 +55,12 @@ public class StyleResolver { return null; } } else { - // load indexed color - Integer color = color(name); - if (color != null && color != -1) { - color = Colors.DEFAULT_COLORS_256[color]; - } - return color; + // load indexed color + Integer color = color(name); + if (color != null && color != -1) { + color = Colors.DEFAULT_COLORS_256[color]; + } + return color; } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java index edea89cf2d9..1e3091e19a1 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2018, the original author or authors. + * Copyright (c) 2002-2018, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -44,5 +44,4 @@ public class Timeout { public long timeout() { return timeout > 0 ? Math.max(1, end - cur) : timeout; } - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java index db3a8d3d990..7b0caf91c25 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2016, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -10,8 +10,7 @@ package jdk.internal.org.jline.utils; public final class WCWidth { - private WCWidth() { - } + private WCWidth() {} /* The following two functions define the column width of an ISO 10646 * character as follows: @@ -44,88 +43,86 @@ public final class WCWidth { * This implementation assumes that wchar_t characters are encoded * in ISO 10646. */ - public static int wcwidth(int ucs) - { + public static int wcwidth(int ucs) { /* test for 8-bit control characters */ - if (ucs == 0) - return 0; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return -1; + if (ucs == 0) return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return -1; /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, combining.length - 1)) - return 0; + if (bisearch(ucs, combining, combining.length - 1)) return 0; /* if we arrive here, ucs is not a combining or C0/C1 control character */ - return 1 + - ((ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && - ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x1f000 && ucs <= 0x1feee) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))) ? 1 : 0); + return 1 + + ((ucs >= 0x1100 + && (ucs <= 0x115f + || /* Hangul Jamo init. consonants */ ucs == 0x2329 + || ucs == 0x232a + || (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) + || /* CJK ... Yi */ (ucs >= 0xac00 && ucs <= 0xd7a3) + || /* Hangul Syllables */ (ucs >= 0xf900 && ucs <= 0xfaff) + || /* CJK Compatibility Ideographs */ (ucs >= 0xfe10 && ucs <= 0xfe19) + || /* Vertical forms */ (ucs >= 0xfe30 && ucs <= 0xfe6f) + || /* CJK Compatibility Forms */ (ucs >= 0xff00 && ucs <= 0xff60) + || /* Fullwidth Forms */ (ucs >= 0xffe0 && ucs <= 0xffe6) + || (ucs >= 0x1f000 && ucs <= 0x1feee) + || (ucs >= 0x20000 && ucs <= 0x2fffd) + || (ucs >= 0x30000 && ucs <= 0x3fffd))) + ? 1 + : 0); } /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ static Interval[] combining = { - new Interval( 0x0300, 0x036F ), new Interval( 0x0483, 0x0486 ), new Interval( 0x0488, 0x0489 ), - new Interval( 0x0591, 0x05BD ), new Interval( 0x05BF, 0x05BF ), new Interval( 0x05C1, 0x05C2 ), - new Interval( 0x05C4, 0x05C5 ), new Interval( 0x05C7, 0x05C7 ), new Interval( 0x0600, 0x0603 ), - new Interval( 0x0610, 0x0615 ), new Interval( 0x064B, 0x065E ), new Interval( 0x0670, 0x0670 ), - new Interval( 0x06D6, 0x06E4 ), new Interval( 0x06E7, 0x06E8 ), new Interval( 0x06EA, 0x06ED ), - new Interval( 0x070F, 0x070F ), new Interval( 0x0711, 0x0711 ), new Interval( 0x0730, 0x074A ), - new Interval( 0x07A6, 0x07B0 ), new Interval( 0x07EB, 0x07F3 ), new Interval( 0x0901, 0x0902 ), - new Interval( 0x093C, 0x093C ), new Interval( 0x0941, 0x0948 ), new Interval( 0x094D, 0x094D ), - new Interval( 0x0951, 0x0954 ), new Interval( 0x0962, 0x0963 ), new Interval( 0x0981, 0x0981 ), - new Interval( 0x09BC, 0x09BC ), new Interval( 0x09C1, 0x09C4 ), new Interval( 0x09CD, 0x09CD ), - new Interval( 0x09E2, 0x09E3 ), new Interval( 0x0A01, 0x0A02 ), new Interval( 0x0A3C, 0x0A3C ), - new Interval( 0x0A41, 0x0A42 ), new Interval( 0x0A47, 0x0A48 ), new Interval( 0x0A4B, 0x0A4D ), - new Interval( 0x0A70, 0x0A71 ), new Interval( 0x0A81, 0x0A82 ), new Interval( 0x0ABC, 0x0ABC ), - new Interval( 0x0AC1, 0x0AC5 ), new Interval( 0x0AC7, 0x0AC8 ), new Interval( 0x0ACD, 0x0ACD ), - new Interval( 0x0AE2, 0x0AE3 ), new Interval( 0x0B01, 0x0B01 ), new Interval( 0x0B3C, 0x0B3C ), - new Interval( 0x0B3F, 0x0B3F ), new Interval( 0x0B41, 0x0B43 ), new Interval( 0x0B4D, 0x0B4D ), - new Interval( 0x0B56, 0x0B56 ), new Interval( 0x0B82, 0x0B82 ), new Interval( 0x0BC0, 0x0BC0 ), - new Interval( 0x0BCD, 0x0BCD ), new Interval( 0x0C3E, 0x0C40 ), new Interval( 0x0C46, 0x0C48 ), - new Interval( 0x0C4A, 0x0C4D ), new Interval( 0x0C55, 0x0C56 ), new Interval( 0x0CBC, 0x0CBC ), - new Interval( 0x0CBF, 0x0CBF ), new Interval( 0x0CC6, 0x0CC6 ), new Interval( 0x0CCC, 0x0CCD ), - new Interval( 0x0CE2, 0x0CE3 ), new Interval( 0x0D41, 0x0D43 ), new Interval( 0x0D4D, 0x0D4D ), - new Interval( 0x0DCA, 0x0DCA ), new Interval( 0x0DD2, 0x0DD4 ), new Interval( 0x0DD6, 0x0DD6 ), - new Interval( 0x0E31, 0x0E31 ), new Interval( 0x0E34, 0x0E3A ), new Interval( 0x0E47, 0x0E4E ), - new Interval( 0x0EB1, 0x0EB1 ), new Interval( 0x0EB4, 0x0EB9 ), new Interval( 0x0EBB, 0x0EBC ), - new Interval( 0x0EC8, 0x0ECD ), new Interval( 0x0F18, 0x0F19 ), new Interval( 0x0F35, 0x0F35 ), - new Interval( 0x0F37, 0x0F37 ), new Interval( 0x0F39, 0x0F39 ), new Interval( 0x0F71, 0x0F7E ), - new Interval( 0x0F80, 0x0F84 ), new Interval( 0x0F86, 0x0F87 ), new Interval( 0x0F90, 0x0F97 ), - new Interval( 0x0F99, 0x0FBC ), new Interval( 0x0FC6, 0x0FC6 ), new Interval( 0x102D, 0x1030 ), - new Interval( 0x1032, 0x1032 ), new Interval( 0x1036, 0x1037 ), new Interval( 0x1039, 0x1039 ), - new Interval( 0x1058, 0x1059 ), new Interval( 0x1160, 0x11FF ), new Interval( 0x135F, 0x135F ), - new Interval( 0x1712, 0x1714 ), new Interval( 0x1732, 0x1734 ), new Interval( 0x1752, 0x1753 ), - new Interval( 0x1772, 0x1773 ), new Interval( 0x17B4, 0x17B5 ), new Interval( 0x17B7, 0x17BD ), - new Interval( 0x17C6, 0x17C6 ), new Interval( 0x17C9, 0x17D3 ), new Interval( 0x17DD, 0x17DD ), - new Interval( 0x180B, 0x180D ), new Interval( 0x18A9, 0x18A9 ), new Interval( 0x1920, 0x1922 ), - new Interval( 0x1927, 0x1928 ), new Interval( 0x1932, 0x1932 ), new Interval( 0x1939, 0x193B ), - new Interval( 0x1A17, 0x1A18 ), new Interval( 0x1B00, 0x1B03 ), new Interval( 0x1B34, 0x1B34 ), - new Interval( 0x1B36, 0x1B3A ), new Interval( 0x1B3C, 0x1B3C ), new Interval( 0x1B42, 0x1B42 ), - new Interval( 0x1B6B, 0x1B73 ), new Interval( 0x1DC0, 0x1DCA ), new Interval( 0x1DFE, 0x1DFF ), - new Interval( 0x200B, 0x200F ), new Interval( 0x202A, 0x202E ), new Interval( 0x2060, 0x2063 ), - new Interval( 0x206A, 0x206F ), new Interval( 0x20D0, 0x20EF ), new Interval( 0x302A, 0x302F ), - new Interval( 0x3099, 0x309A ), new Interval( 0xA806, 0xA806 ), new Interval( 0xA80B, 0xA80B ), - new Interval( 0xA825, 0xA826 ), new Interval( 0xFB1E, 0xFB1E ), new Interval( 0xFE00, 0xFE0F ), - new Interval( 0xFE20, 0xFE23 ), new Interval( 0xFEFF, 0xFEFF ), new Interval( 0xFFF9, 0xFFFB ), - new Interval( 0x10A01, 0x10A03 ), new Interval( 0x10A05, 0x10A06 ), new Interval( 0x10A0C, 0x10A0F ), - new Interval( 0x10A38, 0x10A3A ), new Interval( 0x10A3F, 0x10A3F ), new Interval( 0x1D167, 0x1D169 ), - new Interval( 0x1D173, 0x1D182 ), new Interval( 0x1D185, 0x1D18B ), new Interval( 0x1D1AA, 0x1D1AD ), - new Interval( 0x1D242, 0x1D244 ), new Interval( 0x1F3FB, 0x1F3FF ), new Interval( 0xE0001, 0xE0001 ), - new Interval( 0xE0020, 0xE007F ), new Interval( 0xE0100, 0xE01EF ) + new Interval(0x0300, 0x036F), new Interval(0x0483, 0x0486), new Interval(0x0488, 0x0489), + new Interval(0x0591, 0x05BD), new Interval(0x05BF, 0x05BF), new Interval(0x05C1, 0x05C2), + new Interval(0x05C4, 0x05C5), new Interval(0x05C7, 0x05C7), new Interval(0x0600, 0x0603), + new Interval(0x0610, 0x0615), new Interval(0x064B, 0x065E), new Interval(0x0670, 0x0670), + new Interval(0x06D6, 0x06E4), new Interval(0x06E7, 0x06E8), new Interval(0x06EA, 0x06ED), + new Interval(0x070F, 0x070F), new Interval(0x0711, 0x0711), new Interval(0x0730, 0x074A), + new Interval(0x07A6, 0x07B0), new Interval(0x07EB, 0x07F3), new Interval(0x0901, 0x0902), + new Interval(0x093C, 0x093C), new Interval(0x0941, 0x0948), new Interval(0x094D, 0x094D), + new Interval(0x0951, 0x0954), new Interval(0x0962, 0x0963), new Interval(0x0981, 0x0981), + new Interval(0x09BC, 0x09BC), new Interval(0x09C1, 0x09C4), new Interval(0x09CD, 0x09CD), + new Interval(0x09E2, 0x09E3), new Interval(0x0A01, 0x0A02), new Interval(0x0A3C, 0x0A3C), + new Interval(0x0A41, 0x0A42), new Interval(0x0A47, 0x0A48), new Interval(0x0A4B, 0x0A4D), + new Interval(0x0A70, 0x0A71), new Interval(0x0A81, 0x0A82), new Interval(0x0ABC, 0x0ABC), + new Interval(0x0AC1, 0x0AC5), new Interval(0x0AC7, 0x0AC8), new Interval(0x0ACD, 0x0ACD), + new Interval(0x0AE2, 0x0AE3), new Interval(0x0B01, 0x0B01), new Interval(0x0B3C, 0x0B3C), + new Interval(0x0B3F, 0x0B3F), new Interval(0x0B41, 0x0B43), new Interval(0x0B4D, 0x0B4D), + new Interval(0x0B56, 0x0B56), new Interval(0x0B82, 0x0B82), new Interval(0x0BC0, 0x0BC0), + new Interval(0x0BCD, 0x0BCD), new Interval(0x0C3E, 0x0C40), new Interval(0x0C46, 0x0C48), + new Interval(0x0C4A, 0x0C4D), new Interval(0x0C55, 0x0C56), new Interval(0x0CBC, 0x0CBC), + new Interval(0x0CBF, 0x0CBF), new Interval(0x0CC6, 0x0CC6), new Interval(0x0CCC, 0x0CCD), + new Interval(0x0CE2, 0x0CE3), new Interval(0x0D41, 0x0D43), new Interval(0x0D4D, 0x0D4D), + new Interval(0x0DCA, 0x0DCA), new Interval(0x0DD2, 0x0DD4), new Interval(0x0DD6, 0x0DD6), + new Interval(0x0E31, 0x0E31), new Interval(0x0E34, 0x0E3A), new Interval(0x0E47, 0x0E4E), + new Interval(0x0EB1, 0x0EB1), new Interval(0x0EB4, 0x0EB9), new Interval(0x0EBB, 0x0EBC), + new Interval(0x0EC8, 0x0ECD), new Interval(0x0F18, 0x0F19), new Interval(0x0F35, 0x0F35), + new Interval(0x0F37, 0x0F37), new Interval(0x0F39, 0x0F39), new Interval(0x0F71, 0x0F7E), + new Interval(0x0F80, 0x0F84), new Interval(0x0F86, 0x0F87), new Interval(0x0F90, 0x0F97), + new Interval(0x0F99, 0x0FBC), new Interval(0x0FC6, 0x0FC6), new Interval(0x102D, 0x1030), + new Interval(0x1032, 0x1032), new Interval(0x1036, 0x1037), new Interval(0x1039, 0x1039), + new Interval(0x1058, 0x1059), new Interval(0x1160, 0x11FF), new Interval(0x135F, 0x135F), + new Interval(0x1712, 0x1714), new Interval(0x1732, 0x1734), new Interval(0x1752, 0x1753), + new Interval(0x1772, 0x1773), new Interval(0x17B4, 0x17B5), new Interval(0x17B7, 0x17BD), + new Interval(0x17C6, 0x17C6), new Interval(0x17C9, 0x17D3), new Interval(0x17DD, 0x17DD), + new Interval(0x180B, 0x180D), new Interval(0x18A9, 0x18A9), new Interval(0x1920, 0x1922), + new Interval(0x1927, 0x1928), new Interval(0x1932, 0x1932), new Interval(0x1939, 0x193B), + new Interval(0x1A17, 0x1A18), new Interval(0x1B00, 0x1B03), new Interval(0x1B34, 0x1B34), + new Interval(0x1B36, 0x1B3A), new Interval(0x1B3C, 0x1B3C), new Interval(0x1B42, 0x1B42), + new Interval(0x1B6B, 0x1B73), new Interval(0x1DC0, 0x1DCA), new Interval(0x1DFE, 0x1DFF), + new Interval(0x200B, 0x200F), new Interval(0x202A, 0x202E), new Interval(0x2060, 0x2063), + new Interval(0x206A, 0x206F), new Interval(0x20D0, 0x20EF), new Interval(0x302A, 0x302F), + new Interval(0x3099, 0x309A), new Interval(0xA806, 0xA806), new Interval(0xA80B, 0xA80B), + new Interval(0xA825, 0xA826), new Interval(0xFB1E, 0xFB1E), new Interval(0xFE00, 0xFE0F), + new Interval(0xFE20, 0xFE23), new Interval(0xFEFF, 0xFEFF), new Interval(0xFFF9, 0xFFFB), + new Interval(0x10A01, 0x10A03), new Interval(0x10A05, 0x10A06), new Interval(0x10A0C, 0x10A0F), + new Interval(0x10A38, 0x10A3A), new Interval(0x10A3F, 0x10A3F), new Interval(0x1D167, 0x1D169), + new Interval(0x1D173, 0x1D182), new Interval(0x1D185, 0x1D18B), new Interval(0x1D1AA, 0x1D1AD), + new Interval(0x1D242, 0x1D244), new Interval(0x1F3FB, 0x1F3FF), new Interval(0xE0001, 0xE0001), + new Interval(0xE0020, 0xE007F), new Interval(0xE0100, 0xE01EF) }; private static class Interval { @@ -143,20 +140,14 @@ public final class WCWidth { int min = 0; int mid; - if (ucs < table[0].first || ucs > table[max].last) - return false; + if (ucs < table[0].first || ucs > table[max].last) return false; while (max >= min) { mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; - else - return true; + if (ucs > table[mid].last) min = mid + 1; + else if (ucs < table[mid].first) max = mid - 1; + else return true; } return false; } - - } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WriterOutputStream.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WriterOutputStream.java index 3ad63a8f381..b1285f9636e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WriterOutputStream.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WriterOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017, the original author or authors. + * Copyright (c) 2002-2017, the original author(s). * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -35,9 +35,11 @@ public class WriterOutputStream extends OutputStream { private final CharBuffer decoderOut = CharBuffer.allocate(128); public WriterOutputStream(Writer out, Charset charset) { - this(out, charset.newDecoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE)); + this( + out, + charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE)); } public WriterOutputStream(Writer out, CharsetDecoder decoder) { @@ -47,7 +49,7 @@ public class WriterOutputStream extends OutputStream { @Override public void write(int b) throws IOException { - write(new byte[] { (byte)b }, 0, 1); + write(new byte[] {(byte) b}, 0, 1); } @Override diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-conemu.caps b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-conemu.caps index 719bcf86202..f5caa4402bc 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-conemu.caps +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-conemu.caps @@ -5,6 +5,9 @@ windows-conemu|conemu windows terminal, cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\E[B, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, + civis=\E[?25l, cvvis=\E[?25h, + smcup=\E[?1049h, rmcup=\E[?1049l, + rc=\E8, sc=\E7, il=\E[%p1%dL, il1=\E[L, dl=\E[%p1%dM, dl1=\E[M, ech=\E[%p1%dX, diff --git a/src/jdk.internal.le/share/legal/jline.md b/src/jdk.internal.le/share/legal/jline.md index 6840c69cfc0..5b813c0af2f 100644 --- a/src/jdk.internal.le/share/legal/jline.md +++ b/src/jdk.internal.le/share/legal/jline.md @@ -1,9 +1,9 @@ -## JLine v3.22.0 +## JLine v3.26.1 ### JLine License
 
-Copyright (c) 2002-2018, the original author or authors.
+Copyright (c) 2002-2023, the original author or authors.
 All rights reserved.
 
 https://opensource.org/licenses/BSD-3-Clause
diff --git a/src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaNativePty.java b/src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaNativePty.java
deleted file mode 100644
index 2cf24e4ba85..00000000000
--- a/src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaNativePty.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2002-2020, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.Constructor;
-
-//import com.sun.jna.Platform;
-import jdk.internal.org.jline.terminal.Attributes;
-import jdk.internal.org.jline.terminal.Size;
-import jdk.internal.org.jline.terminal.impl.AbstractPty;
-import jdk.internal.org.jline.terminal.spi.TerminalProvider;
-import jdk.internal.org.jline.terminal.spi.Pty;
-//import jdk.internal.org.jline.terminal.impl.jna.freebsd.FreeBsdNativePty;
-//import jdk.internal.org.jline.terminal.impl.jna.linux.LinuxNativePty;
-//import jdk.internal.org.jline.terminal.impl.jna.osx.OsXNativePty;
-//import jdk.internal.org.jline.terminal.impl.jna.solaris.SolarisNativePty;
-
-public abstract class JnaNativePty extends AbstractPty implements Pty {
-
-    private final int master;
-    private final int slave;
-    private final int slaveOut;
-    private final String name;
-    private final FileDescriptor masterFD;
-    private final FileDescriptor slaveFD;
-    private final FileDescriptor slaveOutFD;
-
-    public static JnaNativePty current(TerminalProvider.Stream console) throws IOException {
-//        if (Platform.isMac()) {
-//            if (Platform.is64Bit() && Platform.isARM()) {
-//                throw new UnsupportedOperationException();
-//            }
-//            return OsXNativePty.current(console);
-//        } else if (Platform.isLinux()) {
-//            return LinuxNativePty.current(console);
-//        } else if (Platform.isSolaris()) {
-//            return SolarisNativePty.current(console);
-//        } else if (Platform.isFreeBSD()) {
-//            return FreeBsdNativePty.current(console);
-//        } else {
-//            throw new UnsupportedOperationException();
-//        }
-        return JDKNativePty.current(console);
-    }
-
-    public static JnaNativePty open(Attributes attr, Size size) throws IOException {
-//        if (Platform.isMac()) {
-//            return OsXNativePty.open(attr, size);
-//        } else if (Platform.isLinux()) {
-//            return LinuxNativePty.open(attr, size);
-//        } else if (Platform.isSolaris()) {
-//            return SolarisNativePty.open(attr, size);
-//        } else if (Platform.isFreeBSD()) {
-//            return FreeBsdNativePty.open(attr, size);
-//        } else {
-//            throw new UnsupportedOperationException();
-//        }
-        return JDKNativePty.open(attr, size);
-    }
-
-    protected JnaNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) {
-        this(master, masterFD, slave, slaveFD, slave, slaveFD, name);
-    }
-
-    protected JnaNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, int slaveOut, FileDescriptor slaveOutFD, String name) {
-        this.master = master;
-        this.slave = slave;
-        this.slaveOut = slaveOut;
-        this.name = name;
-        this.masterFD = masterFD;
-        this.slaveFD = slaveFD;
-        this.slaveOutFD = slaveOutFD;
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (master > 0) {
-            getMasterInput().close();
-        }
-        if (slave > 0) {
-            getSlaveInput().close();
-        }
-    }
-
-    public int getMaster() {
-        return master;
-    }
-
-    public int getSlave() {
-        return slave;
-    }
-
-    public int getSlaveOut() {
-        return slaveOut;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public FileDescriptor getMasterFD() {
-        return masterFD;
-    }
-
-    public FileDescriptor getSlaveFD() {
-        return slaveFD;
-    }
-
-    public FileDescriptor getSlaveOutFD() {
-        return slaveOutFD;
-    }
-
-    public InputStream getMasterInput() {
-        return new FileInputStream(getMasterFD());
-    }
-
-    public OutputStream getMasterOutput() {
-        return new FileOutputStream(getMasterFD());
-    }
-
-    protected InputStream doGetSlaveInput() {
-        return new FileInputStream(getSlaveFD());
-    }
-
-    public OutputStream getSlaveOutput() {
-        return new FileOutputStream(getSlaveOutFD());
-    }
-
-    protected static FileDescriptor newDescriptor(int fd) {
-        try {
-            Constructor cns = FileDescriptor.class.getDeclaredConstructor(int.class);
-            cns.setAccessible(true);
-            return cns.newInstance(fd);
-        } catch (Throwable e) {
-            throw new RuntimeException("Unable to create FileDescriptor", e);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "JnaNativePty[" + getName() + "]";
-    }
-
-    public static boolean isPosixSystemStream(TerminalProvider.Stream stream) {
-        switch (stream) {
-            case Input: return isatty(0);
-            case Output: return isatty(1);
-            case Error: return isatty(2);
-            default: return false;
-        }
-    }
-
-    public static String posixSystemStreamName(TerminalProvider.Stream stream) {
-        switch (stream) {
-            case Input: return ttyname(0);
-            case Output: return ttyname(1);
-            case Error: return ttyname(2);
-            default: return null;
-        }
-    }
-
-    private static boolean isatty(int fd) {
-//        if (Platform.isMac()) {
-//            return OsXNativePty.isatty(fd) == 1;
-//        } else if (Platform.isLinux()) {
-//            return LinuxNativePty.isatty(fd) == 1;
-//        } else if (Platform.isSolaris()) {
-//            return SolarisNativePty.isatty(fd) == 1;
-//        } else if (Platform.isFreeBSD()) {
-//            return FreeBsdNativePty.isatty(fd) == 1;
-//        } else {
-//            return false;
-//        }
-        return JDKNativePty.isatty(fd) == 1;
-    }
-
-    private static String ttyname(int fd) {
-//        if (Platform.isMac()) {
-//            return OsXNativePty.ttyname(fd);
-//        } else if (Platform.isLinux()) {
-//            return LinuxNativePty.ttyname(fd);
-//        } else if (Platform.isSolaris()) {
-//            return SolarisNativePty.ttyname(fd);
-//        } else if (Platform.isFreeBSD()) {
-//            return FreeBsdNativePty.ttyname(fd);
-//        } else {
-//            return null;
-//        }
-        return JDKNativePty.ttyname(fd);
-    }
-
-}
diff --git a/src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java b/src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java
deleted file mode 100644
index 04052202030..00000000000
--- a/src/jdk.internal.le/unix/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2002-2020, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna;
-
-import jdk.internal.org.jline.terminal.Attributes;
-import jdk.internal.org.jline.terminal.Size;
-import jdk.internal.org.jline.terminal.Terminal;
-import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal;
-import jdk.internal.org.jline.terminal.impl.PosixSysTerminal;
-//import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal;
-import jdk.internal.org.jline.terminal.spi.TerminalProvider;
-import jdk.internal.org.jline.terminal.spi.Pty;
-import jdk.internal.org.jline.utils.OSUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.Charset;
-import java.util.function.Function;
-
-public class JnaTerminalProvider implements TerminalProvider
-{
-    @Override
-    public String name() {
-        return "jna";
-    }
-
-    public Pty current(TerminalProvider.Stream console) throws IOException {
-        return JnaNativePty.current(console);
-    }
-
-    public Pty open(Attributes attributes, Size size) throws IOException {
-        return JnaNativePty.open(attributes, size);
-    }
-
-    @Override
-    public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
-                                boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
-                                Stream consoleStream, Function inputStreamWrapper) throws IOException {
-//        if (OSUtils.IS_WINDOWS) {
-//            return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream );
-//        } else {
-            return posixSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper );
-//        }
-    }
-
-//    public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
-//                                   boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
-//                                   Stream console, Function inputStreamWrapper) throws IOException {
-//        return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, console);
-//    }
-//
-    public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
-                                     boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
-                                     Stream consoleStream, Function inputStreamWrapper) throws IOException {
-//        Pty pty = jdk.internal.org.jline.terminal.impl.ExecPty.current(consoleStream);
-        Pty pty = current(consoleStream);
-        return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper);
-    }
-
-    @Override
-    public Terminal newTerminal(String name, String type, InputStream in, OutputStream out,
-                                Charset encoding, Terminal.SignalHandler signalHandler, boolean paused,
-                                Attributes attributes, Size size) throws IOException
-    {
-        Pty pty = open(attributes, size);
-        return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
-    }
-
-    @Override
-    public boolean isSystemStream(Stream stream) {
-        try {
-//            if (OSUtils.IS_WINDOWS) {
-//                return isWindowsSystemStream(stream);
-//            } else {
-                return isPosixSystemStream(stream);
-//            }
-        } catch (Throwable t) {
-            return false;
-        }
-    }
-
-//    public boolean isWindowsSystemStream(Stream stream) {
-//        return JnaWinSysTerminal.isWindowsSystemStream(stream);
-//    }
-
-    public boolean isPosixSystemStream(Stream stream) {
-        return JnaNativePty.isPosixSystemStream(stream);
-    }
-
-    @Override
-    public String systemStreamName(Stream stream) {
-        if (OSUtils.IS_WINDOWS) {
-            return null;
-        } else {
-            return JnaNativePty.posixSystemStreamName(stream);
-        }
-    }
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java
deleted file mode 100644
index b820ce2187e..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2002-2020, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna;
-
-import jdk.internal.org.jline.terminal.Attributes;
-import jdk.internal.org.jline.terminal.Size;
-import jdk.internal.org.jline.terminal.Terminal;
-import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal;
-import jdk.internal.org.jline.terminal.impl.PosixSysTerminal;
-import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal;
-import jdk.internal.org.jline.terminal.spi.TerminalProvider;
-import jdk.internal.org.jline.terminal.spi.Pty;
-import jdk.internal.org.jline.utils.OSUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.Charset;
-import java.util.function.Function;
-
-public class JnaTerminalProvider implements TerminalProvider
-{
-    @Override
-    public String name() {
-        return "jna";
-    }
-
-//    public Pty current(TerminalProvider.Stream console) throws IOException {
-//        return JnaNativePty.current(console);
-//    }
-//
-//    public Pty open(Attributes attributes, Size size) throws IOException {
-//        return JnaNativePty.open(attributes, size);
-//    }
-
-    @Override
-    public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
-                                boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
-                                Stream consoleStream, Function inputStreamWrapper) throws IOException {
-        if (OSUtils.IS_WINDOWS) {
-            return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper );
-        } else {
-            return null;
-        }
-    }
-
-    public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
-                                   boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
-                                   Stream console, Function inputStreamWrapper) throws IOException {
-        return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, console, inputStreamWrapper);
-    }
-
-//    public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
-//                                     boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
-//                                     Stream consoleStream) throws IOException {
-//        Pty pty = current(consoleStream);
-//        return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler);
-//    }
-
-    @Override
-    public Terminal newTerminal(String name, String type, InputStream in, OutputStream out,
-                                Charset encoding, Terminal.SignalHandler signalHandler, boolean paused,
-                                Attributes attributes, Size size) throws IOException
-    {
-//        Pty pty = open(attributes, size);
-//        return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
-        return null;
-    }
-
-    @Override
-    public boolean isSystemStream(Stream stream) {
-        try {
-            if (OSUtils.IS_WINDOWS) {
-                return isWindowsSystemStream(stream);
-            } else {
-//                return isPosixSystemStream(stream);
-                return false;
-            }
-        } catch (Throwable t) {
-            return false;
-        }
-    }
-
-    public boolean isWindowsSystemStream(Stream stream) {
-        return JnaWinSysTerminal.isWindowsSystemStream(stream);
-    }
-
-//    public boolean isPosixSystemStream(Stream stream) {
-//        return JnaNativePty.isPosixSystemStream(stream);
-//    }
-
-    @Override
-    public String systemStreamName(Stream stream) {
-//        if (OSUtils.IS_WINDOWS) {
-            return null;
-//        } else {
-//            return JnaNativePty.posixSystemStreamName(stream);
-//        }
-    }
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/IntByReference.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/IntByReference.java
deleted file mode 100644
index 7cfe401b582..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/IntByReference.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-class IntByReference {
-
-    public int value;
-
-    public int getValue() {
-        return value;
-    }
-
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java
deleted file mode 100644
index 7fcbb5416a6..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2002-2017, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-//import com.sun.jna.LastErrorException;
-//import com.sun.jna.Pointer;
-//import com.sun.jna.ptr.IntByReference;
-import jdk.internal.org.jline.terminal.impl.AbstractWindowsConsoleWriter;
-import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
-
-import java.io.IOException;
-
-class JnaWinConsoleWriter extends AbstractWindowsConsoleWriter {
-
-    private final Pointer console;
-    private final IntByReference writtenChars = new IntByReference();
-
-    JnaWinConsoleWriter(Pointer console) {
-        this.console = console;
-    }
-
-    @Override
-    protected void writeConsole(char[] text, int len) throws IOException {
-        try {
-            Kernel32.INSTANCE.WriteConsoleW(this.console, text, len, this.writtenChars, null);
-        } catch (LastErrorException e) {
-            throw new IOException("Failed to write to console", e);
-        }
-    }
-
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java
deleted file mode 100644
index 9baafb89bd9..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2002-2020, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.util.function.Function;
-import java.util.function.IntConsumer;
-
-//import com.sun.jna.LastErrorException;
-//import com.sun.jna.Pointer;
-//import com.sun.jna.ptr.IntByReference;
-import jdk.internal.org.jline.terminal.Cursor;
-import jdk.internal.org.jline.terminal.Size;
-import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal;
-import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
-import jdk.internal.org.jline.terminal.spi.TerminalProvider;
-import jdk.internal.org.jline.utils.InfoCmp;
-import jdk.internal.org.jline.utils.OSUtils;
-
-public class JnaWinSysTerminal extends AbstractWindowsTerminal {
-
-    private static final Pointer consoleIn = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_INPUT_HANDLE);
-    private static final Pointer consoleOut = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_OUTPUT_HANDLE);
-    private static final Pointer consoleErr = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_ERROR_HANDLE);
-
-    public static JnaWinSysTerminal createTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, boolean paused, TerminalProvider.Stream consoleStream, Function inputStreamWrapper) throws IOException {
-        Pointer console;
-        switch (consoleStream) {
-            case Output:
-                console = JnaWinSysTerminal.consoleOut;
-                break;
-            case Error:
-                console = JnaWinSysTerminal.consoleErr;
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream);
-        }
-        Writer writer;
-        if (ansiPassThrough) {
-            if (type == null) {
-                type = OSUtils.IS_CONEMU ? TYPE_WINDOWS_CONEMU : TYPE_WINDOWS;
-            }
-            writer = new JnaWinConsoleWriter(console);
-        } else {
-            IntByReference mode = new IntByReference();
-            Kernel32.INSTANCE.GetConsoleMode(console, mode);
-            try {
-                Kernel32.INSTANCE.SetConsoleMode(console, mode.getValue() | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING);
-                if (type == null) {
-                    type = TYPE_WINDOWS_VTP;
-                }
-                writer = new JnaWinConsoleWriter(console);
-            } catch (LastErrorException e) {
-                if (OSUtils.IS_CONEMU) {
-                    if (type == null) {
-                        type = TYPE_WINDOWS_CONEMU;
-                    }
-                    writer = new JnaWinConsoleWriter(console);
-                } else {
-                    if (type == null) {
-                        type = TYPE_WINDOWS;
-                    }
-                    writer = new WindowsAnsiWriter(new BufferedWriter(new JnaWinConsoleWriter(console)), console);
-                }
-            }
-        }
-        JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, nativeSignals, signalHandler, inputStreamWrapper);
-        // Start input pump thread
-        if (!paused) {
-            terminal.resume();
-        }
-        return terminal;
-    }
-
-    public static boolean isWindowsSystemStream(TerminalProvider.Stream stream) {
-        try {
-            IntByReference mode = new IntByReference();
-            Pointer console;
-            switch (stream) {
-                case Input: console = consoleIn; break;
-                case Output: console = consoleOut; break;
-                case Error: console = consoleErr; break;
-                default: return false;
-            }
-            Kernel32.INSTANCE.GetConsoleMode(console, mode);
-            return true;
-        } catch (LastErrorException e) {
-            return false;
-        }
-    }
-
-    JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler,
-            Function inputStreamWrapper) throws IOException {
-        super(writer, name, type, encoding, nativeSignals, signalHandler, inputStreamWrapper);
-        strings.put(InfoCmp.Capability.key_mouse, "\\E[M");
-    }
-
-    @Override
-    protected int getConsoleMode() {
-        IntByReference mode = new IntByReference();
-        Kernel32.INSTANCE.GetConsoleMode(consoleIn, mode);
-        return mode.getValue();
-    }
-
-    @Override
-    protected void setConsoleMode(int mode) {
-        Kernel32.INSTANCE.SetConsoleMode(consoleIn, mode);
-    }
-
-    public Size getSize() {
-        Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
-        Kernel32.INSTANCE.GetConsoleScreenBufferInfo(consoleOut, info);
-        return new Size(info.windowWidth(), info.windowHeight());
-    }
-
-    public Size getBufferSize() {
-        Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
-        Kernel32.INSTANCE.GetConsoleScreenBufferInfo(consoleOut, info);
-        return new Size(info.dwSize.X, info.dwSize.Y);
-    }
-
-    protected boolean processConsoleInput() throws IOException {
-        Kernel32.INPUT_RECORD event = readConsoleInput(100);
-        if (event == null) {
-            return false;
-        }
-
-        switch (event.EventType) {
-            case Kernel32.INPUT_RECORD.KEY_EVENT:
-                processKeyEvent(event.Event.KeyEvent);
-                return true;
-            case Kernel32.INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT:
-                raise(Signal.WINCH);
-                return false;
-            case Kernel32.INPUT_RECORD.MOUSE_EVENT:
-                processMouseEvent(event.Event.MouseEvent);
-                return true;
-            case Kernel32.INPUT_RECORD.FOCUS_EVENT:
-                processFocusEvent(event.Event.FocusEvent.bSetFocus);
-                return true;
-            default:
-                // Skip event
-                return false;
-        }
-    }
-
-    private void processKeyEvent(Kernel32.KEY_EVENT_RECORD keyEvent) throws IOException {
-        processKeyEvent(keyEvent.bKeyDown, keyEvent.wVirtualKeyCode, keyEvent.uChar.UnicodeChar, keyEvent.dwControlKeyState);
-    }
-
-    private char[] focus = new char[] { '\033', '[', ' ' };
-
-    private void processFocusEvent(boolean hasFocus) throws IOException {
-        if (focusTracking) {
-            focus[2] = hasFocus ? 'I' : 'O';
-            slaveInputPipe.write(focus);
-        }
-    }
-
-    private char[] mouse = new char[] { '\033', '[', 'M', ' ', ' ', ' ' };
-
-    private void processMouseEvent(Kernel32.MOUSE_EVENT_RECORD mouseEvent) throws IOException {
-        int dwEventFlags = mouseEvent.dwEventFlags;
-        int dwButtonState = mouseEvent.dwButtonState;
-        if (tracking == MouseTracking.Off
-                || tracking == MouseTracking.Normal && dwEventFlags == Kernel32.MOUSE_MOVED
-                || tracking == MouseTracking.Button && dwEventFlags == Kernel32.MOUSE_MOVED && dwButtonState == 0) {
-            return;
-        }
-        int cb = 0;
-        dwEventFlags &= ~ Kernel32.DOUBLE_CLICK; // Treat double-clicks as normal
-        if (dwEventFlags == Kernel32.MOUSE_WHEELED) {
-            cb |= 64;
-            if ((dwButtonState >> 16) < 0) {
-                cb |= 1;
-            }
-        } else if (dwEventFlags == Kernel32.MOUSE_HWHEELED) {
-            return;
-        } else if ((dwButtonState & Kernel32.FROM_LEFT_1ST_BUTTON_PRESSED) != 0) {
-            cb |= 0x00;
-        } else if ((dwButtonState & Kernel32.RIGHTMOST_BUTTON_PRESSED) != 0) {
-            cb |= 0x01;
-        } else if ((dwButtonState & Kernel32.FROM_LEFT_2ND_BUTTON_PRESSED) != 0) {
-            cb |= 0x02;
-        } else {
-            cb |= 0x03;
-        }
-        int cx = mouseEvent.dwMousePosition.X;
-        int cy = mouseEvent.dwMousePosition.Y;
-        mouse[3] = (char) (' ' + cb);
-        mouse[4] = (char) (' ' + cx + 1);
-        mouse[5] = (char) (' ' + cy + 1);
-        slaveInputPipe.write(mouse);
-    }
-
-    private final Kernel32.INPUT_RECORD[] inputEvents = new Kernel32.INPUT_RECORD[1];
-    private final IntByReference eventsRead = new IntByReference();
-
-    private Kernel32.INPUT_RECORD readConsoleInput(int dwMilliseconds) throws IOException {
-        if (Kernel32.INSTANCE.WaitForSingleObject(consoleIn, dwMilliseconds) != 0) {
-            return null;
-        }
-        Kernel32.INSTANCE.ReadConsoleInput(consoleIn, inputEvents, 1, eventsRead);
-        if (eventsRead.getValue() == 1) {
-            return inputEvents[0];
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public Cursor getCursorPosition(IntConsumer discarded) {
-        Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
-        Kernel32.INSTANCE.GetConsoleScreenBufferInfo(consoleOut, info);
-        return new Cursor(info.dwCursorPosition.X, info.dwCursorPosition.Y);
-    }
-
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32.java
deleted file mode 100644
index 20c6eefeece..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32.java
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (c) 2002-2018, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-//OpenJDK changes:
-//-references to JNA types commented out
-//-replacement types provided where needed (IntByReference, LastErrorException, Pointer)
-//-methods not used by JLine commented out
-//-provided an implementation of the interface (Kernel32Impl), backed by a native implementation (Kernel32.cpp)
-
-//import com.sun.jna.LastErrorException;
-//import com.sun.jna.Native;
-//import com.sun.jna.Pointer;
-//import com.sun.jna.Structure;
-//import com.sun.jna.Union;
-//import com.sun.jna.ptr.IntByReference;
-//import com.sun.jna.win32.StdCallLibrary;
-//import com.sun.jna.win32.W32APIOptions;
-import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
-
-interface Kernel32 {//extends StdCallLibrary {
-
-    Kernel32 INSTANCE = new Kernel32Impl();
-//    Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
-
-//    Pointer INVALID_HANDLE_VALUE = Pointer.createConstant(-1L);
-
-    int STD_INPUT_HANDLE =  -10;
-    int STD_OUTPUT_HANDLE = -11;
-    int STD_ERROR_HANDLE =  -12;
-
-    int ENABLE_PROCESSED_INPUT =    0x0001;
-    int ENABLE_LINE_INPUT =         0x0002;
-    int ENABLE_ECHO_INPUT =         0x0004;
-    int ENABLE_WINDOW_INPUT =       0x0008;
-    int ENABLE_MOUSE_INPUT =        0x0010;
-    int ENABLE_INSERT_MODE =        0x0020;
-    int ENABLE_QUICK_EDIT_MODE =    0x0040;
-    int ENABLE_EXTENDED_FLAGS =     0x0080;
-
-    int RIGHT_ALT_PRESSED =     0x0001;
-    int LEFT_ALT_PRESSED =      0x0002;
-    int RIGHT_CTRL_PRESSED =    0x0004;
-    int LEFT_CTRL_PRESSED =     0x0008;
-    int SHIFT_PRESSED =         0x0010;
-
-    int FOREGROUND_BLUE =       0x0001;
-    int FOREGROUND_GREEN =      0x0002;
-    int FOREGROUND_RED =        0x0004;
-    int FOREGROUND_INTENSITY =  0x0008;
-    int BACKGROUND_BLUE =       0x0010;
-    int BACKGROUND_GREEN =      0x0020;
-    int BACKGROUND_RED =        0x0040;
-    int BACKGROUND_INTENSITY =  0x0080;
-
-    // Button state
-    int FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001;
-    int RIGHTMOST_BUTTON_PRESSED     = 0x0002;
-    int FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004;
-    int FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008;
-    int FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010;
-
-    // Event flags
-    int MOUSE_MOVED                  = 0x0001;
-    int DOUBLE_CLICK                 = 0x0002;
-    int MOUSE_WHEELED                = 0x0004;
-    int MOUSE_HWHEELED               = 0x0008;
-
-    // DWORD WINAPI WaitForSingleObject(
-    //  _In_ HANDLE hHandle,
-    //  _In_ DWORD  dwMilliseconds
-    // );
-    int WaitForSingleObject(Pointer in_hHandle, int in_dwMilliseconds);
-
-    // HANDLE WINAPI GetStdHandle(
-    // __in DWORD nStdHandle
-    // );
-    Pointer GetStdHandle(int nStdHandle);
-
-//    // BOOL WINAPI AllocConsole(void);
-//    void AllocConsole() throws LastErrorException;
-//
-//    // BOOL WINAPI FreeConsole(void);
-//    void FreeConsole() throws LastErrorException;
-//
-//    // HWND WINAPI GetConsoleWindow(void);
-//    Pointer GetConsoleWindow();
-//
-//    // UINT WINAPI GetConsoleCP(void)
-//    int GetConsoleCP();
-//
-    // UINT WINAPI GetConsoleOutputCP(void)
-    int GetConsoleOutputCP();
-
-    // BOOL WINAPI FillConsoleOutputCharacter(
-    // _In_ HANDLE hConsoleOutput,
-    // _In_ TCHAR cCharacter,
-    // _In_ DWORD nLength,
-    // _In_ COORD dwWriteCoord,
-    // _Out_ LPDWORD lpNumberOfCharsWritten);
-    void FillConsoleOutputCharacter(Pointer in_hConsoleOutput,
-                                    char in_cCharacter, int in_nLength, COORD in_dwWriteCoord,
-                                    IntByReference out_lpNumberOfCharsWritten)
-            throws LastErrorException;
-
-    // BOOL WINAPI FillConsoleOutputAttribute(
-    // _In_ HANDLE hConsoleOutput,
-    // _In_ WORD wAttribute,
-    // _In_ DWORD nLength,
-    // _In_ COORD dwWriteCoord,
-    // _Out_ LPDWORD lpNumberOfAttrsWritten);
-    void FillConsoleOutputAttribute(Pointer in_hConsoleOutput,
-                                    short in_wAttribute, int in_nLength, COORD in_dwWriteCoord,
-                                    IntByReference out_lpNumberOfAttrsWritten)
-            throws LastErrorException;
-//
-////    // BOOL WINAPI GetConsoleCursorInfo(
-////    // _In_ HANDLE hConsoleOutput,
-////    // _Out_ PCONSOLE_CURSOR_INFO lpConsoleCursorInfo);
-////    void GetConsoleCursorInfo(Pointer in_hConsoleOutput,
-////                              CONSOLE_CURSOR_INFO.ByReference out_lpConsoleCursorInfo)
-////            throws LastErrorException;
-//
-    // BOOL WINAPI GetConsoleMode(
-    //   _In_   HANDLE hConsoleHandle,
-    //   _Out_  LPDWORD lpMode);
-    void GetConsoleMode(
-            Pointer in_hConsoleOutput,
-            IntByReference out_lpMode)
-            throws LastErrorException;
-
-    // BOOL WINAPI GetConsoleScreenBufferInfo(
-    // _In_   HANDLE hConsoleOutput,
-    // _Out_  PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
-    void GetConsoleScreenBufferInfo(
-            Pointer in_hConsoleOutput,
-            CONSOLE_SCREEN_BUFFER_INFO out_lpConsoleScreenBufferInfo)
-            throws LastErrorException;
-//
-//    // BOOL WINAPI GetNumberOfConsoleInputEvents(
-//    // _In_ HANDLE hConsoleInput,
-//    // _Out_ LPDWORD lpcNumberOfEvents);
-//    void GetNumberOfConsoleInputEvents(Pointer in_hConsoleOutput,
-//                                       IntByReference out_lpcNumberOfEvents) throws LastErrorException;
-//
-    // BOOL WINAPI ReadConsoleInput(
-    // _In_ HANDLE hConsoleInput,
-    // _Out_ PINPUT_RECORD lpBuffer,
-    // _In_ DWORD nLength,
-    // _Out_ LPDWORD lpNumberOfEventsRead);
-    void ReadConsoleInput(Pointer in_hConsoleOutput,
-                          INPUT_RECORD[] out_lpBuffer, int in_nLength,
-                          IntByReference out_lpNumberOfEventsRead) throws LastErrorException;
-
-//    // BOOL WINAPI SetConsoleCtrlHandler(
-//    // _In_opt_  PHANDLER_ROUTINE HandlerRoutine,
-//    // _In_      BOOL Add);
-//    void SetConsoleCtrlHandler(
-//            Pointer in_opt_HandlerRoutine,
-//            boolean in_Add)
-//            throws LastErrorException;
-//
-//    // BOOL WINAPI ReadConsoleOutput(
-//    // _In_     HANDLE hConsoleOutput,
-//    // _Out_    PCHAR_INFO lpBuffer,
-//    // _In_     COORD dwBufferSize,
-//    // _In_     COORD dwBufferCoord,
-//    // _Inout_  PSMALL_RECT lpReadRegion);
-////    void ReadConsoleOutput(Pointer in_hConsoleOutput, CHAR_INFO[] out_lpBuffer,
-////                           COORD in_dwBufferSize, COORD in_dwBufferCoord,
-////                           SMALL_RECT inout_lpReadRegion) throws LastErrorException;
-////    void ReadConsoleOutputA(Pointer in_hConsoleOutput, CHAR_INFO[] out_lpBuffer,
-////                            COORD in_dwBufferSize, COORD in_dwBufferCoord,
-////                            SMALL_RECT inout_lpReadRegion) throws LastErrorException;
-//
-//    // BOOL WINAPI ReadConsoleOutputCharacter(
-//    // _In_   HANDLE hConsoleOutput,
-//    // _Out_  LPTSTR lpCharacter,
-//    // _In_   DWORD nLength,
-//    // _In_   COORD dwReadCoord,
-//    // _Out_  LPDWORD lpNumberOfCharsRead);
-//    void ReadConsoleOutputCharacter(Pointer in_hConsoleOutput,
-//                                    char[] ouy_lpCharacter, int in_nLength, COORD in_dwReadCoord,
-//                                    IntByReference out_lpNumberOfCharsRead)
-//            throws LastErrorException;
-//    void ReadConsoleOutputCharacterA(Pointer in_hConsoleOutput,
-//                                     byte[] ouy_lpCharacter, int in_nLength, COORD in_dwReadCoord,
-//                                     IntByReference out_lpNumberOfCharsRead)
-//            throws LastErrorException;
-//
-//    // BOOL WINAPI SetConsoleCursorInfo(
-//    // _In_ HANDLE hConsoleOutput,
-//    // _In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo);
-//    void SetConsoleCursorInfo(Pointer in_hConsoleOutput,
-//                              CONSOLE_CURSOR_INFO in_lpConsoleCursorInfo)
-//            throws LastErrorException;
-//
-//    // BOOL WINAPI SetConsoleCP(
-//    // _In_ UINT wCodePageID);
-//    void SetConsoleCP(int in_wCodePageID) throws LastErrorException;
-//
-//    // BOOL WINAPI SetConsoleOutputCP(
-//    // _In_ UINT wCodePageID);
-//    void SetConsoleOutputCP(int in_wCodePageID) throws LastErrorException;
-//
-    // BOOL WINAPI SetConsoleCursorPosition(
-    // _In_ HANDLE hConsoleOutput,
-    // _In_ COORD dwCursorPosition);
-    void SetConsoleCursorPosition(Pointer in_hConsoleOutput,
-                                  COORD in_dwCursorPosition) throws LastErrorException;
-
-    // BOOL WINAPI SetConsoleMode(
-    //   _In_  HANDLE hConsoleHandle,
-    //   _In_  DWORD dwMode);
-    void SetConsoleMode(
-            Pointer in_hConsoleOutput,
-            int in_dwMode) throws LastErrorException;
-
-//    // BOOL WINAPI SetConsoleScreenBufferSize(
-//    // __in HANDLE hConsoleOutput,
-//    // __in COORD dwSize
-//    // );
-//    void SetConsoleScreenBufferSize(Pointer in_hConsoleOutput,
-//                                    COORD in_dwSize) throws LastErrorException;
-//
-    // BOOL WINAPI SetConsoleTextAttribute(
-    // _In_ HANDLE hConsoleOutput,
-    // _In_ WORD   wAttributes
-    // );
-    void SetConsoleTextAttribute(Pointer in_hConsoleOutput,
-                                 short in_wAttributes)
-            throws LastErrorException;
-
-    // BOOL WINAPI SetConsoleTitle(
-    // _In_ LPCTSTR lpConsoleTitle
-    // );
-    void SetConsoleTitle(String in_lpConsoleTitle)
-            throws LastErrorException;
-
-//    // BOOL WINAPI SetConsoleWindowInfo(
-//    // _In_ HANDLE hConsoleOutput,
-//    // _In_ BOOL bAbsolute,
-//    // _In_ const SMALL_RECT *lpConsoleWindow);
-//    void SetConsoleWindowInfo(Pointer in_hConsoleOutput,
-//                              boolean in_bAbsolute, SMALL_RECT in_lpConsoleWindow)
-//            throws LastErrorException;
-
-    // BOOL WINAPI WriteConsole(
-    //  _In_             HANDLE  hConsoleOutput,
-    //  _In_       const VOID    *lpBuffer,
-    //  _In_             DWORD   nNumberOfCharsToWrite,
-    //  _Out_            LPDWORD lpNumberOfCharsWritten,
-    //  _Reserved_       LPVOID  lpReserved
-    // );
-    void WriteConsoleW(Pointer in_hConsoleOutput, char[] in_lpBuffer, int in_nNumberOfCharsToWrite,
-                          IntByReference out_lpNumberOfCharsWritten, Pointer reserved_lpReserved) throws LastErrorException;
-
-//    // BOOL WINAPI WriteConsoleOutput(
-//    // _In_ HANDLE hConsoleOutput,
-//    // _In_ const CHAR_INFO *lpBuffer,
-//    // _In_ COORD dwBufferSize,
-//    // _In_ COORD dwBufferCoord,
-//    // _Inout_ PSMALL_RECT lpWriteRegion);
-////    void WriteConsoleOutput(Pointer in_hConsoleOutput, CHAR_INFO[] in_lpBuffer,
-////                            COORD in_dwBufferSize, COORD in_dwBufferCoord,
-////                            SMALL_RECT inout_lpWriteRegion) throws LastErrorException;
-////    void WriteConsoleOutputA(Pointer in_hConsoleOutput, CHAR_INFO[] in_lpBuffer,
-////                             COORD in_dwBufferSize, COORD in_dwBufferCoord,
-////                             SMALL_RECT inout_lpWriteRegion) throws LastErrorException;
-//
-//    // BOOL WINAPI WriteConsoleOutputCharacter(
-//    // _In_ HANDLE hConsoleOutput,
-//    // _In_ LPCTSTR lpCharacter,
-//    // _In_ DWORD nLength,
-//    // _In_ COORD dwWriteCoord,
-//    // _Out_ LPDWORD lpNumberOfCharsWritten);
-//    void WriteConsoleOutputCharacter(Pointer in_hConsoleOutput,
-//                                     char[] in_lpCharacter, int in_nLength, COORD in_dwWriteCoord,
-//                                     IntByReference out_lpNumberOfCharsWritten)
-//            throws LastErrorException;
-//    void WriteConsoleOutputCharacterA(Pointer in_hConsoleOutput,
-//                                      byte[] in_lpCharacter, int in_nLength, COORD in_dwWriteCoord,
-//                                      IntByReference out_lpNumberOfCharsWritten)
-//            throws LastErrorException;
-//
-    // BOOL WINAPI ScrollConsoleScreenBuffer(
-    //     _In_           HANDLE     hConsoleOutput,
-    //     _In_     const SMALL_RECT *lpScrollRectangle,
-    //     _In_opt_ const SMALL_RECT *lpClipRectangle,
-    //     _In_           COORD      dwDestinationOrigin,
-    //     _In_     const CHAR_INFO  *lpFill);
-    void ScrollConsoleScreenBuffer(Pointer in_hConsoleOutput,
-                                   SMALL_RECT in_lpScrollRectangle,
-                                   SMALL_RECT in_lpClipRectangle,
-                                   COORD in_dwDestinationOrigin,
-                                   CHAR_INFO in_lpFill)
-            throws LastErrorException;
-
-    // typedef struct _CHAR_INFO {
-    //   union {
-    //     WCHAR UnicodeChar;
-    //     CHAR  AsciiChar;
-    //   } Char;
-    //   WORD  Attributes;
-    // } CHAR_INFO, *PCHAR_INFO;
-    class CHAR_INFO {//extends Structure {
-        public CHAR_INFO() {
-        }
-
-        public CHAR_INFO(char c, short attr) {
-            uChar = new UnionChar(c);
-            Attributes = attr;
-        }
-
-//        public CHAR_INFO(byte c, short attr) {
-//            uChar = new UnionChar(c);
-//            Attributes = attr;
-//        }
-
-        public UnionChar uChar;
-        public short Attributes;
-
-//        public static CHAR_INFO[] createArray(int size) {
-//            return (CHAR_INFO[]) new CHAR_INFO().toArray(size);
-//        }
-//
-//        private static String[] fieldOrder = { "uChar", "Attributes" };
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _CONSOLE_CURSOR_INFO {
-    //   DWORD dwSize;
-    //   BOOL  bVisible;
-    // } CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
-    class CONSOLE_CURSOR_INFO {//extends Structure {
-        public int dwSize;
-        public boolean bVisible;
-
-//        public static class ByReference extends CONSOLE_CURSOR_INFO implements
-//                Structure.ByReference {
-//        }
-//
-//        private static String[] fieldOrder = { "dwSize", "bVisible" };
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
-    //   COORD      dwSize;
-    //   COORD      dwCursorPosition;
-    //   WORD       wAttributes;
-    //   SMALL_RECT srWindow;
-    //   COORD      dwMaximumWindowSize;
-    // } CONSOLE_SCREEN_BUFFER_INFO;
-    class CONSOLE_SCREEN_BUFFER_INFO {//extends Structure {
-        public COORD      dwSize;
-        public COORD      dwCursorPosition;
-        public short      wAttributes;
-        public SMALL_RECT srWindow;
-        public COORD      dwMaximumWindowSize;
-
-//        private static String[] fieldOrder = { "dwSize", "dwCursorPosition", "wAttributes", "srWindow", "dwMaximumWindowSize" };
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-
-        public int windowWidth() {
-            return this.srWindow.width() + 1;
-        }
-
-        public int windowHeight() {
-            return this.srWindow.height() + 1;
-        }
-    }
-
-    // typedef struct _COORD {
-    //    SHORT X;
-    //    SHORT Y;
-    //  } COORD, *PCOORD;
-    class COORD {//extends Structure implements Structure.ByValue {
-        public COORD() {
-        }
-
-        public COORD(short X, short Y) {
-            this.X = X;
-            this.Y = Y;
-        }
-
-        public short X;
-        public short Y;
-
-//        private static String[] fieldOrder = { "X", "Y" };
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _INPUT_RECORD {
-    //   WORD  EventType;
-    //   union {
-    //     KEY_EVENT_RECORD          KeyEvent;
-    //     MOUSE_EVENT_RECORD        MouseEvent;
-    //     WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
-    //     MENU_EVENT_RECORD         MenuEvent;
-    //     FOCUS_EVENT_RECORD        FocusEvent;
-    //   } Event;
-    // } INPUT_RECORD;
-    class INPUT_RECORD {//extends Structure {
-        public static final short KEY_EVENT = 0x0001;
-        public static final short MOUSE_EVENT = 0x0002;
-        public static final short WINDOW_BUFFER_SIZE_EVENT = 0x0004;
-        public static final short MENU_EVENT = 0x0008;
-        public static final short FOCUS_EVENT = 0x0010;
-
-        public short EventType;
-        public EventUnion Event;
-
-        public static class EventUnion {//extends Union {
-            public KEY_EVENT_RECORD KeyEvent;
-            public MOUSE_EVENT_RECORD MouseEvent;
-            public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
-            public MENU_EVENT_RECORD MenuEvent;
-            public FOCUS_EVENT_RECORD FocusEvent;
-        }
-
-//        @Override
-//        public void read() {
-//            readField("EventType");
-//            switch (EventType) {
-//                case KEY_EVENT:
-//                    Event.setType(KEY_EVENT_RECORD.class);
-//                    break;
-//                case MOUSE_EVENT:
-//                    Event.setType(MOUSE_EVENT_RECORD.class);
-//                    break;
-//                case WINDOW_BUFFER_SIZE_EVENT:
-//                    Event.setType(WINDOW_BUFFER_SIZE_RECORD.class);
-//                    break;
-//                case MENU_EVENT:
-//                    Event.setType(MENU_EVENT_RECORD.class);
-//                    break;
-//                case FOCUS_EVENT:
-//                    Event.setType(MENU_EVENT_RECORD.class);
-//                    break;
-//            }
-//            super.read();
-//        }
-
-//        private static String[] fieldOrder = {"EventType", "Event"};
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _KEY_EVENT_RECORD {
-    //   BOOL  bKeyDown;
-    //   WORD  wRepeatCount;
-    //   WORD  wVirtualKeyCode;
-    //   WORD  wVirtualScanCode;
-    //   union {
-    //     WCHAR UnicodeChar;
-    //     CHAR  AsciiChar;
-    //   } uChar;
-    //   DWORD dwControlKeyState;
-    // } KEY_EVENT_RECORD;
-    class KEY_EVENT_RECORD {//extends Structure {
-        public boolean bKeyDown;
-        public short wRepeatCount;
-        public short wVirtualKeyCode;
-        public short wVirtualScanCode;
-        public UnionChar uChar;
-        public int dwControlKeyState;
-
-//        private static String[] fieldOrder = {"bKeyDown", "wRepeatCount", "wVirtualKeyCode", "wVirtualScanCode", "uChar", "dwControlKeyState"};
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _MOUSE_EVENT_RECORD {
-    //   COORD dwMousePosition;
-    //   DWORD dwButtonState;
-    //   DWORD dwControlKeyState;
-    //   DWORD dwEventFlags;
-    // } MOUSE_EVENT_RECORD;
-    class MOUSE_EVENT_RECORD {//extends Structure {
-        public COORD dwMousePosition;
-        public int dwButtonState;
-        public int dwControlKeyState;
-        public int dwEventFlags;
-
-//        private static String[] fieldOrder = { "dwMousePosition", "dwButtonState", "dwControlKeyState", "dwEventFlags"};
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _WINDOW_BUFFER_SIZE_RECORD {
-    //   COORD dwSize;
-    // } WINDOW_BUFFER_SIZE_RECORD;
-    class WINDOW_BUFFER_SIZE_RECORD {//extends Structure {
-        public COORD dwSize;
-
-//        private static String[] fieldOrder = {"dwSize"};
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _MENU_EVENT_RECORD {
-    //   UINT dwCommandId;
-    // } MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;
-    class MENU_EVENT_RECORD {//extends Structure {
-
-        public int dwCommandId;
-
-//        private static String[] fieldOrder = {"dwCommandId"};
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _FOCUS_EVENT_RECORD {
-    //  BOOL bSetFocus;
-    //} FOCUS_EVENT_RECORD;
-    class FOCUS_EVENT_RECORD {//extends Structure {
-        public boolean bSetFocus;
-
-//        private static String[] fieldOrder = {"bSetFocus"};
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-    }
-
-    // typedef struct _SMALL_RECT {
-    //    SHORT Left;
-    //    SHORT Top;
-    //    SHORT Right;
-    //    SHORT Bottom;
-    //  } SMALL_RECT;
-    class SMALL_RECT {//extends Structure {
-        public SMALL_RECT() {
-        }
-
-        public SMALL_RECT(SMALL_RECT org) {
-            this(org.Top, org.Left, org.Bottom, org.Right);
-        }
-
-        public SMALL_RECT(short Top, short Left, short Bottom, short Right) {
-            this.Top = Top;
-            this.Left = Left;
-            this.Bottom = Bottom;
-            this.Right = Right;
-        }
-
-        public short Left;
-        public short Top;
-        public short Right;
-        public short Bottom;
-
-//        private static String[] fieldOrder = { "Left", "Top", "Right", "Bottom" };
-//
-//        @Override
-//        protected java.util.List getFieldOrder() {
-//            return java.util.Arrays.asList(fieldOrder);
-//        }
-
-        public short width() {
-            return (short)(this.Right - this.Left);
-        }
-
-        public short height() {
-            return (short)(this.Bottom - this.Top);
-        }
-
-    }
-
-    class UnionChar {//extends Union {
-        public UnionChar() {
-        }
-
-        public UnionChar(char c) {
-//            setType(char.class);
-            UnicodeChar = c;
-        }
-
-//        public UnionChar(byte c) {
-//            setType(byte.class);
-//            AsciiChar = c;
-//        }
-
-        public void set(char c) {
-//            setType(char.class);
-            UnicodeChar = c;
-        }
-
-//        public void set(byte c) {
-//            setType(byte.class);
-//            AsciiChar = c;
-//        }
-
-        public char UnicodeChar;
-//        public byte AsciiChar;
-    }
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32Impl.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32Impl.java
deleted file mode 100644
index 67f69a63511..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Kernel32Impl.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
-import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CHAR_INFO;
-import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CONSOLE_SCREEN_BUFFER_INFO;
-import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.COORD;
-import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.INPUT_RECORD;
-import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.SMALL_RECT;
-
-public class Kernel32Impl implements Kernel32 {
-
-    static {
-        System.loadLibrary("le");
-        initIDs();
-    }
-
-    private static native void initIDs();
-
-    @Override
-    public native int WaitForSingleObject(Pointer in_hHandle, int in_dwMilliseconds);
-
-    @Override
-    public native Pointer GetStdHandle(int nStdHandle);
-
-    @Override
-    public native int GetConsoleOutputCP();
-
-    @Override
-    public native void FillConsoleOutputCharacter(Pointer in_hConsoleOutput, char in_cCharacter, int in_nLength, COORD in_dwWriteCoord, IntByReference out_lpNumberOfCharsWritten) throws LastErrorException;
-
-    @Override
-    public native void FillConsoleOutputAttribute(Pointer in_hConsoleOutput, short in_wAttribute, int in_nLength, COORD in_dwWriteCoord, IntByReference out_lpNumberOfAttrsWritten) throws LastErrorException;
-
-    @Override
-    public native void GetConsoleMode(Pointer in_hConsoleOutput, IntByReference out_lpMode) throws LastErrorException;
-
-    @Override
-    public native void GetConsoleScreenBufferInfo(Pointer in_hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO out_lpConsoleScreenBufferInfo) throws LastErrorException;
-
-    @Override
-    public native void ReadConsoleInput(Pointer in_hConsoleOutput, INPUT_RECORD[] out_lpBuffer, int in_nLength, IntByReference out_lpNumberOfEventsRead) throws LastErrorException;
-
-    @Override
-    public native void SetConsoleCursorPosition(Pointer in_hConsoleOutput, COORD in_dwCursorPosition) throws LastErrorException;
-
-    @Override
-    public native void SetConsoleMode(Pointer in_hConsoleOutput, int in_dwMode) throws LastErrorException;
-
-    @Override
-    public native void SetConsoleTextAttribute(Pointer in_hConsoleOutput, short in_wAttributes) throws LastErrorException;
-
-    @Override
-    public native void SetConsoleTitle(String in_lpConsoleTitle) throws LastErrorException;
-
-    @Override
-    public native void WriteConsoleW(Pointer in_hConsoleOutput, char[] in_lpBuffer, int in_nNumberOfCharsToWrite, IntByReference out_lpNumberOfCharsWritten, Pointer reserved_lpReserved) throws LastErrorException;
-
-    @Override
-    public native void ScrollConsoleScreenBuffer(Pointer in_hConsoleOutput, SMALL_RECT in_lpScrollRectangle, SMALL_RECT in_lpClipRectangle, COORD in_dwDestinationOrigin, CHAR_INFO in_lpFill) throws LastErrorException;
-
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Pointer.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Pointer.java
deleted file mode 100644
index aeb7f758e7d..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/Pointer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-class Pointer {
-    public final long value;
-
-    public Pointer(long value) {
-        this.value = value;
-    }
-
-}
diff --git a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java b/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java
deleted file mode 100644
index 5ae0df1b201..00000000000
--- a/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/WindowsAnsiWriter.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2002-2016, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-package jdk.internal.org.jline.terminal.impl.jna.win;
-
-import java.io.IOException;
-import java.io.Writer;
-
-//import com.sun.jna.Pointer;
-//import com.sun.jna.ptr.IntByReference;
-import jdk.internal.org.jline.utils.AnsiWriter;
-import jdk.internal.org.jline.utils.Colors;
-
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.BACKGROUND_BLUE;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.BACKGROUND_GREEN;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.BACKGROUND_INTENSITY;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.BACKGROUND_RED;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.FOREGROUND_BLUE;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.FOREGROUND_GREEN;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.FOREGROUND_INTENSITY;
-import static jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.FOREGROUND_RED;
-
-
-/**
- * A Windows ANSI escape processor, uses JNA to access native platform
- * API's to change the console attributes.
- *
- * @since 1.0
- * @author Hiram Chirino
- * @author Joris Kuipers
- */
-public final class WindowsAnsiWriter extends AnsiWriter {
-
-    private static final short FOREGROUND_BLACK   = 0;
-    private static final short FOREGROUND_YELLOW  = (short) (FOREGROUND_RED|FOREGROUND_GREEN);
-    private static final short FOREGROUND_MAGENTA = (short) (FOREGROUND_BLUE|FOREGROUND_RED);
-    private static final short FOREGROUND_CYAN    = (short) (FOREGROUND_BLUE|FOREGROUND_GREEN);
-    private static final short FOREGROUND_WHITE   = (short) (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
-
-    private static final short BACKGROUND_BLACK   = 0;
-    private static final short BACKGROUND_YELLOW  = (short) (BACKGROUND_RED|BACKGROUND_GREEN);
-    private static final short BACKGROUND_MAGENTA = (short) (BACKGROUND_BLUE|BACKGROUND_RED);
-    private static final short BACKGROUND_CYAN    = (short) (BACKGROUND_BLUE|BACKGROUND_GREEN);
-    private static final short BACKGROUND_WHITE   = (short) (BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE);
-
-    private static final short ANSI_FOREGROUND_COLOR_MAP[] = {
-            FOREGROUND_BLACK,
-            FOREGROUND_RED,
-            FOREGROUND_GREEN,
-            FOREGROUND_YELLOW,
-            FOREGROUND_BLUE,
-            FOREGROUND_MAGENTA,
-            FOREGROUND_CYAN,
-            FOREGROUND_WHITE,
-    };
-
-    private static final short ANSI_BACKGROUND_COLOR_MAP[] = {
-            BACKGROUND_BLACK,
-            BACKGROUND_RED,
-            BACKGROUND_GREEN,
-            BACKGROUND_YELLOW,
-            BACKGROUND_BLUE,
-            BACKGROUND_MAGENTA,
-            BACKGROUND_CYAN,
-            BACKGROUND_WHITE,
-    };
-
-    private static final int MAX_ESCAPE_SEQUENCE_LENGTH = 100;
-
-    private final Pointer console;
-
-    private final Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
-    private final short originalColors;
-
-    private boolean negative;
-    private boolean bold;
-    private boolean underline;
-    private short savedX = -1;
-    private short savedY = -1;
-
-    public WindowsAnsiWriter(Writer out, Pointer console) throws IOException {
-        super(out);
-        this.console = console;
-        getConsoleInfo();
-        originalColors = info.wAttributes;
-    }
-
-    private void getConsoleInfo() throws IOException {
-        out.flush();
-        Kernel32.INSTANCE.GetConsoleScreenBufferInfo(console, info);
-        if (negative) {
-            info.wAttributes = invertAttributeColors(info.wAttributes);
-        }
-    }
-
-    private void applyAttribute() throws IOException {
-        out.flush();
-        short attributes = info.wAttributes;
-        // bold is simulated by high foreground intensity
-        if (bold) {
-            attributes |= FOREGROUND_INTENSITY;
-        }
-        // underline is simulated by high foreground intensity
-        if (underline) {
-            attributes |= BACKGROUND_INTENSITY;
-        }
-        if (negative) {
-            attributes = invertAttributeColors(attributes);
-        }
-        Kernel32.INSTANCE.SetConsoleTextAttribute(console, attributes);
-    }
-
-    private short invertAttributeColors(short attributes) {
-        // Swap the the Foreground and Background bits.
-        int fg = 0x000F & attributes;
-        fg <<= 4;
-        int bg = 0X00F0 & attributes;
-        bg >>= 4;
-        attributes = (short) ((attributes & 0xFF00) | fg | bg);
-        return attributes;
-    }
-
-    private void applyCursorPosition() throws IOException {
-        info.dwCursorPosition.X = (short) Math.max(0, Math.min(info.dwSize.X - 1, info.dwCursorPosition.X));
-        info.dwCursorPosition.Y = (short) Math.max(0, Math.min(info.dwSize.Y - 1, info.dwCursorPosition.Y));
-        Kernel32.INSTANCE.SetConsoleCursorPosition(console, info.dwCursorPosition);
-    }
-
-    protected void processEraseScreen(int eraseOption) throws IOException {
-        getConsoleInfo();
-        IntByReference written = new IntByReference();
-        switch(eraseOption) {
-            case ERASE_SCREEN:
-                Kernel32.COORD topLeft = new Kernel32.COORD();
-                topLeft.X = 0;
-                topLeft.Y = info.srWindow.Top;
-                int screenLength = info.srWindow.height() * info.dwSize.X;
-                Kernel32.INSTANCE.FillConsoleOutputCharacter(console, ' ', screenLength, topLeft, written);
-                Kernel32.INSTANCE.FillConsoleOutputAttribute(console, info.wAttributes, screenLength, topLeft, written);
-                break;
-            case ERASE_SCREEN_TO_BEGINING:
-                Kernel32.COORD topLeft2 = new Kernel32.COORD();
-                topLeft2.X = 0;
-                topLeft2.Y = info.srWindow.Top;
-                int lengthToCursor = (info.dwCursorPosition.Y - info.srWindow.Top) * info.dwSize.X + info.dwCursorPosition.X;
-                Kernel32.INSTANCE.FillConsoleOutputCharacter(console, ' ', lengthToCursor, topLeft2, written);
-                Kernel32.INSTANCE.FillConsoleOutputAttribute(console, info.wAttributes, lengthToCursor, topLeft2, written);
-                break;
-            case ERASE_SCREEN_TO_END:
-                int lengthToEnd = (info.srWindow.Bottom - info.dwCursorPosition.Y) * info.dwSize.X +
-                        (info.dwSize.X - info.dwCursorPosition.X);
-                Kernel32.INSTANCE.FillConsoleOutputCharacter(console, ' ', lengthToEnd, info.dwCursorPosition, written);
-                Kernel32.INSTANCE.FillConsoleOutputAttribute(console, info.wAttributes, lengthToEnd, info.dwCursorPosition, written);
-        }
-    }
-
-    protected void processEraseLine(int eraseOption) throws IOException {
-        getConsoleInfo();
-        IntByReference written = new IntByReference();
-        switch(eraseOption) {
-            case ERASE_LINE:
-                Kernel32.COORD leftColCurrRow = new Kernel32.COORD((short) 0, info.dwCursorPosition.Y);
-                Kernel32.INSTANCE.FillConsoleOutputCharacter(console, ' ', info.dwSize.X, leftColCurrRow, written);
-                Kernel32.INSTANCE.FillConsoleOutputAttribute(console, info.wAttributes, info.dwSize.X, leftColCurrRow, written);
-                break;
-            case ERASE_LINE_TO_BEGINING:
-                Kernel32.COORD leftColCurrRow2 = new Kernel32.COORD((short) 0, info.dwCursorPosition.Y);
-                Kernel32.INSTANCE.FillConsoleOutputCharacter(console, ' ', info.dwCursorPosition.X, leftColCurrRow2, written);
-                Kernel32.INSTANCE.FillConsoleOutputAttribute(console, info.wAttributes, info.dwCursorPosition.X, leftColCurrRow2, written);
-                break;
-            case ERASE_LINE_TO_END:
-                int lengthToLastCol = info.dwSize.X - info.dwCursorPosition.X;
-                Kernel32.INSTANCE.FillConsoleOutputCharacter(console, ' ', lengthToLastCol, info.dwCursorPosition, written);
-                Kernel32.INSTANCE.FillConsoleOutputAttribute(console, info.wAttributes, lengthToLastCol, info.dwCursorPosition, written);
-        }
-    }
-
-    protected void processCursorUpLine(int count) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.X = 0;
-        info.dwCursorPosition.Y -= (short) count;
-        applyCursorPosition();
-    }
-
-    protected void processCursorDownLine(int count) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.X = 0;
-        info.dwCursorPosition.Y += (short) count;
-        applyCursorPosition();
-    }
-
-    protected void processCursorLeft(int count) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.X -= (short) count;
-        applyCursorPosition();
-    }
-
-    protected void processCursorRight(int count) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.X += (short) count;
-        applyCursorPosition();
-    }
-
-    protected void processCursorDown(int count) throws IOException {
-        getConsoleInfo();
-        int nb = Math.max(0, info.dwCursorPosition.Y + count - info.dwSize.Y + 1);
-        if (nb != count) {
-            info.dwCursorPosition.Y += (short) count;
-            applyCursorPosition();
-        }
-        if (nb > 0) {
-            Kernel32.SMALL_RECT scroll = new Kernel32.SMALL_RECT(info.srWindow);
-            scroll.Top = 0;
-            Kernel32.COORD org = new Kernel32.COORD();
-            org.X = 0;
-            org.Y = (short)(- nb);
-            Kernel32.CHAR_INFO info = new Kernel32.CHAR_INFO(' ', originalColors);
-            Kernel32.INSTANCE.ScrollConsoleScreenBuffer(console, scroll, scroll, org, info);
-        }
-    }
-
-    protected void processCursorUp(int count) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.Y -= (short) count;
-        applyCursorPosition();
-    }
-
-    protected void processCursorTo(int row, int col) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.Y = (short) (info.srWindow.Top + row - 1);
-        info.dwCursorPosition.X = (short) (col - 1);
-        applyCursorPosition();
-    }
-
-    protected void processCursorToColumn(int x) throws IOException {
-        getConsoleInfo();
-        info.dwCursorPosition.X = (short) (x - 1);
-        applyCursorPosition();
-    }
-
-    @Override
-    protected void processSetForegroundColorExt(int paletteIndex) throws IOException {
-        int color = Colors.roundColor(paletteIndex, 16);
-        info.wAttributes = (short) ((info.wAttributes & ~0x0007) | ANSI_FOREGROUND_COLOR_MAP[color & 0x07]);
-        info.wAttributes = (short) ((info.wAttributes & ~FOREGROUND_INTENSITY) | (color >= 8 ? FOREGROUND_INTENSITY : 0));
-        applyAttribute();
-    }
-
-    protected void processSetBackgroundColorExt(int paletteIndex) throws IOException {
-        int color = Colors.roundColor(paletteIndex, 16);
-        info.wAttributes = (short)((info.wAttributes & ~0x0070 ) | ANSI_BACKGROUND_COLOR_MAP[color & 0x07]);
-        info.wAttributes = (short) ((info.wAttributes & ~BACKGROUND_INTENSITY) | (color >= 8 ? BACKGROUND_INTENSITY : 0));
-        applyAttribute();
-    }
-
-    protected void processDefaultTextColor() throws IOException {
-        info.wAttributes = (short)((info.wAttributes & ~0x000F ) | (originalColors & 0x000F));
-        applyAttribute();
-    }
-
-    protected void processDefaultBackgroundColor() throws IOException {
-        info.wAttributes = (short)((info.wAttributes & ~0x00F0 ) | (originalColors & 0x00F0));
-        applyAttribute();
-    }
-
-    protected void processAttributeRest() throws IOException {
-        info.wAttributes = (short)((info.wAttributes & ~0x00FF ) | originalColors);
-        this.negative = false;
-        this.bold = false;
-        this.underline = false;
-        applyAttribute();
-    }
-
-    protected void processSetAttribute(int attribute) throws IOException {
-        switch(attribute) {
-            case ATTRIBUTE_INTENSITY_BOLD:
-                bold = true;
-                applyAttribute();
-                break;
-            case ATTRIBUTE_INTENSITY_NORMAL:
-                bold = false;
-                applyAttribute();
-                break;
-
-            case ATTRIBUTE_UNDERLINE:
-                underline = true;
-                applyAttribute();
-                break;
-            case ATTRIBUTE_UNDERLINE_OFF:
-                underline = false;
-                applyAttribute();
-                break;
-
-            case ATTRIBUTE_NEGATIVE_ON:
-                negative = true;
-                applyAttribute();
-                break;
-            case ATTRIBUTE_NEGATIVE_OFF:
-                negative = false;
-                applyAttribute();
-                break;
-        }
-    }
-
-    protected void processSaveCursorPosition() throws IOException {
-        getConsoleInfo();
-        savedX = info.dwCursorPosition.X;
-        savedY = info.dwCursorPosition.Y;
-    }
-
-    protected void processRestoreCursorPosition() throws IOException {
-        // restore only if there was a save operation first
-        if (savedX != -1 && savedY != -1) {
-            out.flush();
-            info.dwCursorPosition.X = savedX;
-            info.dwCursorPosition.Y = savedY;
-            applyCursorPosition();
-        }
-    }
-
-    @Override
-    protected void processInsertLine(int optionInt) throws IOException {
-        getConsoleInfo();
-        Kernel32.SMALL_RECT scroll = new Kernel32.SMALL_RECT(info.srWindow);
-        scroll.Top = info.dwCursorPosition.Y;
-        Kernel32.COORD org = new Kernel32.COORD();
-        org.X = 0;
-        org.Y = (short)(info.dwCursorPosition.Y + optionInt);
-        Kernel32.CHAR_INFO info = new Kernel32.CHAR_INFO(' ', originalColors);
-        Kernel32.INSTANCE.ScrollConsoleScreenBuffer(console, scroll, scroll, org, info);
-    }
-
-    @Override
-    protected void processDeleteLine(int optionInt) throws IOException {
-        getConsoleInfo();
-        Kernel32.SMALL_RECT scroll = new Kernel32.SMALL_RECT(info.srWindow);
-        scroll.Top = info.dwCursorPosition.Y;
-        Kernel32.COORD org = new Kernel32.COORD();
-        org.X = 0;
-        org.Y = (short)(info.dwCursorPosition.Y - optionInt);
-        Kernel32.CHAR_INFO info = new Kernel32.CHAR_INFO(' ', originalColors);
-        Kernel32.INSTANCE.ScrollConsoleScreenBuffer(console, scroll, scroll, org, info);
-    }
-
-    protected void processChangeWindowTitle(String label) {
-        Kernel32.INSTANCE.SetConsoleTitle(label);
-    }
-}
diff --git a/src/jdk.internal.le/windows/native/lible/Kernel32.cpp b/src/jdk.internal.le/windows/native/lible/Kernel32.cpp
deleted file mode 100644
index 59f4df23fb3..00000000000
--- a/src/jdk.internal.le/windows/native/lible/Kernel32.cpp
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jvm.h"
-#include "jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl.h"
-
-#include 
-#include 
-#include 
-
-static jclass pointerClass;
-static jmethodID pointerConstructor;
-static jfieldID pointerValue;
-
-static jclass intByReferenceClass;
-static jfieldID intByReferenceValue;
-
-static jclass lastErrorExceptionClass;
-static jmethodID lastErrorExceptionConstructor;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CHAR_INFO
-static jclass CHAR_INFO_Class;
-static jmethodID CHAR_INFO_Constructor;
-static jfieldID CHAR_INFO_uChar;
-static jfieldID CHAR_INFO_Attributes;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CONSOLE_CURSOR_INFO
-static jclass CONSOLE_CURSOR_INFO_Class;
-static jmethodID CONSOLE_CURSOR_INFO_Constructor;
-static jfieldID CONSOLE_CURSOR_INFO_dwSize;
-static jfieldID CONSOLE_CURSOR_INFO_bVisible;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CONSOLE_SCREEN_BUFFER_INFO
-static jclass CONSOLE_SCREEN_BUFFER_INFO_Class;
-static jmethodID CONSOLE_SCREEN_BUFFER_INFO_Constructor;
-static jfieldID CONSOLE_SCREEN_BUFFER_INFO_dwSize;
-static jfieldID CONSOLE_SCREEN_BUFFER_INFO_dwCursorPosition;
-static jfieldID CONSOLE_SCREEN_BUFFER_INFO_wAttributes;
-static jfieldID CONSOLE_SCREEN_BUFFER_INFO_srWindow;
-static jfieldID CONSOLE_SCREEN_BUFFER_INFO_dwMaximumWindowSize;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.COORD
-static jclass COORD_Class;
-static jmethodID COORD_Constructor;
-static jfieldID COORD_X;
-static jfieldID COORD_Y;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.INPUT_RECORD
-static jclass INPUT_RECORD_Class;
-static jmethodID INPUT_RECORD_Constructor;
-static jfieldID INPUT_RECORD_EventType;
-static jfieldID INPUT_RECORD_Event;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.INPUT_RECORD.EventUnion
-static jclass EventUnion_Class;
-static jmethodID EventUnion_Constructor;
-static jfieldID EventUnion_KeyEvent;
-static jfieldID EventUnion_MouseEvent;
-static jfieldID EventUnion_WindowBufferSizeEvent;
-static jfieldID EventUnion_MenuEvent;
-static jfieldID EventUnion_FocusEvent;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.KEY_EVENT_RECORD
-static jclass KEY_EVENT_RECORD_Class;
-static jmethodID KEY_EVENT_RECORD_Constructor;
-static jfieldID KEY_EVENT_RECORD_bKeyDown;
-static jfieldID KEY_EVENT_RECORD_wRepeatCount;
-static jfieldID KEY_EVENT_RECORD_wVirtualKeyCode;
-static jfieldID KEY_EVENT_RECORD_wVirtualScanCode;
-static jfieldID KEY_EVENT_RECORD_uChar;
-static jfieldID KEY_EVENT_RECORD_dwControlKeyState;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.MOUSE_EVENT_RECORD
-static jclass MOUSE_EVENT_RECORD_Class;
-static jmethodID MOUSE_EVENT_RECORD_Constructor;
-static jfieldID MOUSE_EVENT_RECORD_dwMousePosition;
-static jfieldID MOUSE_EVENT_RECORD_dwButtonState;
-static jfieldID MOUSE_EVENT_RECORD_dwControlKeyState;
-static jfieldID MOUSE_EVENT_RECORD_dwEventFlags;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.WINDOW_BUFFER_SIZE_RECORD
-static jclass WINDOW_BUFFER_SIZE_RECORD_Class;
-static jmethodID WINDOW_BUFFER_SIZE_RECORD_Constructor;
-static jfieldID WINDOW_BUFFER_SIZE_RECORD_dwSize;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.MENU_EVENT_RECORD
-static jclass MENU_EVENT_RECORD_Class;
-static jmethodID MENU_EVENT_RECORD_Constructor;
-static jfieldID MENU_EVENT_RECORD_dwCommandId;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.FOCUS_EVENT_RECORD
-static jclass FOCUS_EVENT_RECORD_Class;
-static jmethodID FOCUS_EVENT_RECORD_Constructor;
-static jfieldID FOCUS_EVENT_RECORD_bSetFocus;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.SMALL_RECT
-static jclass SMALL_RECT_Class;
-static jmethodID SMALL_RECT_Constructor;
-static jfieldID SMALL_RECT_Left;
-static jfieldID SMALL_RECT_Top;
-static jfieldID SMALL_RECT_Right;
-static jfieldID SMALL_RECT_Bottom;
-
-//jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.UnionChar
-static jclass UnionChar_Class;
-static jmethodID UnionChar_Constructor;
-static jfieldID UnionChar_UnicodeChar;
-
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_initIDs
-  (JNIEnv *env, jclass) {
-    jclass cls;
-    cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Pointer");
-    CHECK_NULL(cls);
-    pointerClass = (jclass) env->NewGlobalRef(cls);
-    pointerConstructor = env->GetMethodID(cls, "", "(J)V");
-    CHECK_NULL(pointerConstructor);
-    pointerValue  = env->GetFieldID(cls, "value", "J");
-    CHECK_NULL(pointerValue);
-
-    cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/LastErrorException");
-    CHECK_NULL(cls);
-    lastErrorExceptionClass = (jclass) env->NewGlobalRef(cls);
-    lastErrorExceptionConstructor = env->GetMethodID(cls, "", "(J)V");
-    CHECK_NULL(lastErrorExceptionConstructor);
-
-    cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/IntByReference");
-    CHECK_NULL(cls);
-    intByReferenceClass = (jclass) env->NewGlobalRef(cls);
-    intByReferenceValue = env->GetFieldID(cls, "value", "I");
-    CHECK_NULL(intByReferenceValue);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CHAR_INFO
-    CHAR_INFO_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$CHAR_INFO"));
-    CHECK_NULL(CHAR_INFO_Class);
-    CHAR_INFO_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(CHAR_INFO_Constructor);
-    CHAR_INFO_uChar = env->GetFieldID(CHAR_INFO_Class, "uChar", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$UnionChar;");
-    CHECK_NULL(CHAR_INFO_uChar);
-    CHAR_INFO_Attributes = env->GetFieldID(CHAR_INFO_Class, "Attributes", "S");
-    CHECK_NULL(CHAR_INFO_Attributes);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CONSOLE_CURSOR_INFO
-    CONSOLE_CURSOR_INFO_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$CONSOLE_CURSOR_INFO"));
-    CHECK_NULL(CONSOLE_CURSOR_INFO_Class);
-    CONSOLE_CURSOR_INFO_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(CONSOLE_CURSOR_INFO_Constructor);
-    CONSOLE_CURSOR_INFO_dwSize = env->GetFieldID(CONSOLE_CURSOR_INFO_Class, "dwSize", "I");
-    CHECK_NULL(CONSOLE_CURSOR_INFO_dwSize);
-    CONSOLE_CURSOR_INFO_bVisible = env->GetFieldID(CONSOLE_CURSOR_INFO_Class, "bVisible", "Z");
-    CHECK_NULL(CONSOLE_CURSOR_INFO_bVisible);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CONSOLE_SCREEN_BUFFER_INFO
-    CONSOLE_SCREEN_BUFFER_INFO_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$CONSOLE_SCREEN_BUFFER_INFO"));
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_Class);
-    CONSOLE_SCREEN_BUFFER_INFO_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_Constructor);
-    CONSOLE_SCREEN_BUFFER_INFO_dwSize = env->GetFieldID(CONSOLE_SCREEN_BUFFER_INFO_Class, "dwSize", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$COORD;");
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_dwSize);
-    CONSOLE_SCREEN_BUFFER_INFO_dwCursorPosition = env->GetFieldID(CONSOLE_SCREEN_BUFFER_INFO_Class, "dwCursorPosition", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$COORD;");
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_dwCursorPosition);
-    CONSOLE_SCREEN_BUFFER_INFO_wAttributes = env->GetFieldID(CONSOLE_SCREEN_BUFFER_INFO_Class, "wAttributes", "S");
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_wAttributes);
-    CONSOLE_SCREEN_BUFFER_INFO_srWindow = env->GetFieldID(CONSOLE_SCREEN_BUFFER_INFO_Class, "srWindow", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$SMALL_RECT;");
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_srWindow);
-    CONSOLE_SCREEN_BUFFER_INFO_dwMaximumWindowSize = env->GetFieldID(CONSOLE_SCREEN_BUFFER_INFO_Class, "dwMaximumWindowSize", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$COORD;");
-    CHECK_NULL(CONSOLE_SCREEN_BUFFER_INFO_dwMaximumWindowSize);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.COORD
-    COORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$COORD"));
-    CHECK_NULL(COORD_Class);
-    COORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(COORD_Constructor);
-    COORD_X = env->GetFieldID(COORD_Class, "X", "S");
-    CHECK_NULL(COORD_X);
-    COORD_Y = env->GetFieldID(COORD_Class, "Y", "S");
-    CHECK_NULL(COORD_Y);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.INPUT_RECORD
-    INPUT_RECORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$INPUT_RECORD"));
-    CHECK_NULL(INPUT_RECORD_Class);
-    INPUT_RECORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(INPUT_RECORD_Constructor);
-    INPUT_RECORD_EventType = env->GetFieldID(INPUT_RECORD_Class, "EventType", "S");
-    CHECK_NULL(INPUT_RECORD_EventType);
-    INPUT_RECORD_Event = env->GetFieldID(INPUT_RECORD_Class, "Event", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$INPUT_RECORD$EventUnion;");
-    CHECK_NULL(INPUT_RECORD_Event);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.INPUT_RECORD.EventUnion
-    EventUnion_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$INPUT_RECORD$EventUnion"));
-    CHECK_NULL(EventUnion_Class);
-    EventUnion_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(EventUnion_Constructor);
-    EventUnion_KeyEvent = env->GetFieldID(EventUnion_Class, "KeyEvent", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$KEY_EVENT_RECORD;");
-    CHECK_NULL(EventUnion_KeyEvent);
-    EventUnion_MouseEvent = env->GetFieldID(EventUnion_Class, "MouseEvent", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$MOUSE_EVENT_RECORD;");
-    CHECK_NULL(EventUnion_MouseEvent);
-    EventUnion_WindowBufferSizeEvent = env->GetFieldID(EventUnion_Class, "WindowBufferSizeEvent", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$WINDOW_BUFFER_SIZE_RECORD;");
-    CHECK_NULL(EventUnion_WindowBufferSizeEvent);
-    EventUnion_MenuEvent = env->GetFieldID(EventUnion_Class, "MenuEvent", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$MENU_EVENT_RECORD;");
-    CHECK_NULL(EventUnion_MenuEvent);
-    EventUnion_FocusEvent = env->GetFieldID(EventUnion_Class, "FocusEvent", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$FOCUS_EVENT_RECORD;");
-    CHECK_NULL(EventUnion_FocusEvent);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.KEY_EVENT_RECORD
-    KEY_EVENT_RECORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$KEY_EVENT_RECORD"));
-    CHECK_NULL(KEY_EVENT_RECORD_Class);
-    KEY_EVENT_RECORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(KEY_EVENT_RECORD_Constructor);
-    KEY_EVENT_RECORD_bKeyDown = env->GetFieldID(KEY_EVENT_RECORD_Class, "bKeyDown", "Z");
-    CHECK_NULL(KEY_EVENT_RECORD_bKeyDown);
-    KEY_EVENT_RECORD_wRepeatCount = env->GetFieldID(KEY_EVENT_RECORD_Class, "wRepeatCount", "S");
-    CHECK_NULL(KEY_EVENT_RECORD_wRepeatCount);
-    KEY_EVENT_RECORD_wVirtualKeyCode = env->GetFieldID(KEY_EVENT_RECORD_Class, "wVirtualKeyCode", "S");
-    CHECK_NULL(KEY_EVENT_RECORD_wVirtualKeyCode);
-    KEY_EVENT_RECORD_wVirtualScanCode = env->GetFieldID(KEY_EVENT_RECORD_Class, "wVirtualScanCode", "S");
-    CHECK_NULL(KEY_EVENT_RECORD_wVirtualScanCode);
-    KEY_EVENT_RECORD_uChar = env->GetFieldID(KEY_EVENT_RECORD_Class, "uChar", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$UnionChar;");
-    CHECK_NULL(KEY_EVENT_RECORD_uChar);
-    KEY_EVENT_RECORD_dwControlKeyState = env->GetFieldID(KEY_EVENT_RECORD_Class, "dwControlKeyState", "I");
-    CHECK_NULL(KEY_EVENT_RECORD_dwControlKeyState);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.MOUSE_EVENT_RECORD
-    MOUSE_EVENT_RECORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$MOUSE_EVENT_RECORD"));
-    CHECK_NULL(MOUSE_EVENT_RECORD_Class);
-    MOUSE_EVENT_RECORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(MOUSE_EVENT_RECORD_Constructor);
-    MOUSE_EVENT_RECORD_dwMousePosition = env->GetFieldID(MOUSE_EVENT_RECORD_Class, "dwMousePosition", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$COORD;");
-    CHECK_NULL(MOUSE_EVENT_RECORD_dwMousePosition);
-    MOUSE_EVENT_RECORD_dwButtonState = env->GetFieldID(MOUSE_EVENT_RECORD_Class, "dwButtonState", "I");
-    CHECK_NULL(MOUSE_EVENT_RECORD_dwButtonState);
-    MOUSE_EVENT_RECORD_dwControlKeyState = env->GetFieldID(MOUSE_EVENT_RECORD_Class, "dwControlKeyState", "I");
-    CHECK_NULL(MOUSE_EVENT_RECORD_dwControlKeyState);
-    MOUSE_EVENT_RECORD_dwEventFlags = env->GetFieldID(MOUSE_EVENT_RECORD_Class, "dwEventFlags", "I");
-    CHECK_NULL(MOUSE_EVENT_RECORD_dwEventFlags);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.WINDOW_BUFFER_SIZE_RECORD
-    WINDOW_BUFFER_SIZE_RECORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$WINDOW_BUFFER_SIZE_RECORD"));
-    CHECK_NULL(WINDOW_BUFFER_SIZE_RECORD_Class);
-    WINDOW_BUFFER_SIZE_RECORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(WINDOW_BUFFER_SIZE_RECORD_Constructor);
-    WINDOW_BUFFER_SIZE_RECORD_dwSize = env->GetFieldID(WINDOW_BUFFER_SIZE_RECORD_Class, "dwSize", "Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32$COORD;");
-    CHECK_NULL(WINDOW_BUFFER_SIZE_RECORD_dwSize);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.MENU_EVENT_RECORD
-    MENU_EVENT_RECORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$MENU_EVENT_RECORD"));
-    CHECK_NULL(MENU_EVENT_RECORD_Class);
-    MENU_EVENT_RECORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(MENU_EVENT_RECORD_Constructor);
-    MENU_EVENT_RECORD_dwCommandId = env->GetFieldID(MENU_EVENT_RECORD_Class, "dwCommandId", "I");
-    CHECK_NULL(MENU_EVENT_RECORD_dwCommandId);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.FOCUS_EVENT_RECORD
-    FOCUS_EVENT_RECORD_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$FOCUS_EVENT_RECORD"));
-    CHECK_NULL(FOCUS_EVENT_RECORD_Class);
-    FOCUS_EVENT_RECORD_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(FOCUS_EVENT_RECORD_Constructor);
-    FOCUS_EVENT_RECORD_bSetFocus = env->GetFieldID(FOCUS_EVENT_RECORD_Class, "bSetFocus", "Z");
-    CHECK_NULL(FOCUS_EVENT_RECORD_bSetFocus);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.SMALL_RECT
-    SMALL_RECT_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$SMALL_RECT"));
-    CHECK_NULL(SMALL_RECT_Class);
-    SMALL_RECT_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(SMALL_RECT_Constructor);
-    SMALL_RECT_Left = env->GetFieldID(SMALL_RECT_Class, "Left", "S");
-    CHECK_NULL(SMALL_RECT_Left);
-    SMALL_RECT_Top = env->GetFieldID(SMALL_RECT_Class, "Top", "S");
-    CHECK_NULL(SMALL_RECT_Top);
-    SMALL_RECT_Right = env->GetFieldID(SMALL_RECT_Class, "Right", "S");
-    CHECK_NULL(SMALL_RECT_Right);
-    SMALL_RECT_Bottom = env->GetFieldID(SMALL_RECT_Class, "Bottom", "S");
-    CHECK_NULL(SMALL_RECT_Bottom);
-
-    //jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.UnionChar
-    UnionChar_Class = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/Kernel32$UnionChar"));
-    CHECK_NULL(UnionChar_Class);
-    UnionChar_Constructor = env->GetMethodID(cls, "", "()V");
-    CHECK_NULL(UnionChar_Constructor);
-    UnionChar_UnicodeChar = env->GetFieldID(UnionChar_Class, "UnicodeChar", "C");
-    CHECK_NULL(UnionChar_UnicodeChar);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    WaitForSingleObject
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;I)I
- */
-JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_WaitForSingleObject
-  (JNIEnv *env, jobject kernel, jobject in_hHandle, jint in_dwMilliseconds) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hHandle, pointerValue));
-    return WaitForSingleObject(h, in_dwMilliseconds);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    GetStdHandle
- * Signature: (I)Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;
- */
-JNIEXPORT jobject JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_GetStdHandle
-  (JNIEnv *env, jobject, jint nStdHandle) {
-    return env->NewObject(pointerClass,
-                          pointerConstructor,
-                          nStdHandle);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    GetConsoleOutputCP
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_GetConsoleOutputCP
-  (JNIEnv *, jobject) {
-    return GetConsoleOutputCP();
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    FillConsoleOutputCharacter
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;CILjdk/internal/org/jline/terminal/impl/jna/win/Kernel32/COORD;Ljdk/internal/org/jline/terminal/impl/jna/win/IntByReference;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_FillConsoleOutputCharacter
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jchar in_cCharacter, jint in_nLength, jobject in_dwWriteCoord, jobject out_lpNumberOfCharsWritten) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    DWORD written;
-    COORD coord;
-    coord.X = (SHORT) env->GetLongField(in_dwWriteCoord, COORD_X);
-    coord.Y = (SHORT) env->GetLongField(in_dwWriteCoord, COORD_Y);
-    if (!FillConsoleOutputCharacter(h, (CHAR) in_cCharacter, in_nLength, coord, &written)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-    env->SetIntField(out_lpNumberOfCharsWritten, intByReferenceValue, written);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    FillConsoleOutputAttribute
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;SILjdk/internal/org/jline/terminal/impl/jna/win/Kernel32/COORD;Ljdk/internal/org/jline/terminal/impl/jna/win/IntByReference;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_FillConsoleOutputAttribute
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jshort in_wAttribute, jint in_nLength, jobject in_dwWriteCoord, jobject out_lpNumberOfAttrsWritten) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    DWORD written;
-    COORD coord;
-    coord.X = (SHORT) env->GetLongField(in_dwWriteCoord, COORD_X);
-    coord.Y = (SHORT) env->GetLongField(in_dwWriteCoord, COORD_Y);
-    if (!FillConsoleOutputAttribute(h, in_wAttribute, in_nLength, coord, &written)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-    env->SetIntField(out_lpNumberOfAttrsWritten, intByReferenceValue, written);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    GetConsoleMode
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;Ljdk/internal/org/jline/terminal/impl/jna/win/IntByReference;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_GetConsoleMode
-  (JNIEnv *env, jobject, jobject in_hConsoleOutput, jobject out_lpMode) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    DWORD mode;
-    if (!GetConsoleMode(h, &mode)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-    env->SetIntField(out_lpMode, intByReferenceValue, mode);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    GetConsoleScreenBufferInfo
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/CONSOLE_SCREEN_BUFFER_INFO;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_GetConsoleScreenBufferInfo
-  (JNIEnv *env, jobject, jobject in_hConsoleOutput, jobject/*CONSOLE_SCREEN_BUFFER_INFO*/ out_lpConsoleScreenBufferInfo) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    CONSOLE_SCREEN_BUFFER_INFO buffer;
-    if (!GetConsoleScreenBufferInfo(h, &buffer)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-
-    jobject dwSize = env->NewObject(COORD_Class,
-                                    COORD_Constructor);
-    env->SetIntField(dwSize, COORD_X, buffer.dwSize.X);
-    env->SetIntField(dwSize, COORD_Y, buffer.dwSize.Y);
-    env->SetObjectField(out_lpConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO_dwSize, dwSize);
-
-    jobject dwCursorPosition = env->NewObject(COORD_Class,
-                                              COORD_Constructor);
-    env->SetIntField(dwCursorPosition, COORD_X, buffer.dwCursorPosition.X);
-    env->SetIntField(dwCursorPosition, COORD_Y, buffer.dwCursorPosition.Y);
-    env->SetObjectField(out_lpConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO_dwCursorPosition, dwCursorPosition);
-
-    env->SetIntField(out_lpConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO_wAttributes, buffer.wAttributes);
-
-    jobject srWindow = env->NewObject(SMALL_RECT_Class,
-                                      SMALL_RECT_Constructor);
-    env->SetIntField(srWindow, SMALL_RECT_Left, buffer.srWindow.Left);
-    env->SetIntField(srWindow, SMALL_RECT_Top, buffer.srWindow.Top);
-    env->SetIntField(srWindow, SMALL_RECT_Right, buffer.srWindow.Right);
-    env->SetIntField(srWindow, SMALL_RECT_Bottom, buffer.srWindow.Bottom);
-    env->SetObjectField(out_lpConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO_srWindow, srWindow);
-
-    jobject dwMaximumWindowSize = env->NewObject(COORD_Class,
-                                                 COORD_Constructor);
-    env->SetIntField(dwMaximumWindowSize, COORD_X, buffer.dwMaximumWindowSize.X);
-    env->SetIntField(dwMaximumWindowSize, COORD_Y, buffer.dwMaximumWindowSize.Y);
-    env->SetObjectField(out_lpConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO_dwMaximumWindowSize, dwMaximumWindowSize);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    ReadConsoleInput
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;[Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/INPUT_RECORD;ILjdk/internal/org/jline/terminal/impl/jna/win/IntByReference;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_ReadConsoleInput
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jobjectArray/*INPUT_RECORD[]*/ out_lpBuffer, jint in_nLength, jobject out_lpNumberOfEventsRead) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    INPUT_RECORD *buffer = new INPUT_RECORD[in_nLength];
-    DWORD numberOfEventsRead;
-    if (!ReadConsoleInputW(h, buffer, in_nLength, &numberOfEventsRead)) {
-        delete[] buffer;
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-    for (unsigned int i = 0; i < numberOfEventsRead; i++) {
-        jobject record = env->NewObject(INPUT_RECORD_Class,
-                                        INPUT_RECORD_Constructor);
-        env->SetShortField(record, INPUT_RECORD_EventType, buffer[i].EventType);
-        switch (buffer[i].EventType) {
-            case KEY_EVENT: {
-                jobject keyEvent = env->NewObject(KEY_EVENT_RECORD_Class,
-                                                  KEY_EVENT_RECORD_Constructor);
-                env->SetBooleanField(keyEvent, KEY_EVENT_RECORD_bKeyDown, buffer[i].Event.KeyEvent.bKeyDown);
-                env->SetShortField(keyEvent, KEY_EVENT_RECORD_wRepeatCount, buffer[i].Event.KeyEvent.wRepeatCount);
-                env->SetShortField(keyEvent, KEY_EVENT_RECORD_wVirtualKeyCode, buffer[i].Event.KeyEvent.wVirtualKeyCode);
-                env->SetShortField(keyEvent, KEY_EVENT_RECORD_wVirtualScanCode, buffer[i].Event.KeyEvent.wVirtualScanCode);
-
-                jobject unionChar = env->NewObject(UnionChar_Class,
-                                                   UnionChar_Constructor);
-
-                env->SetIntField(unionChar, UnionChar_UnicodeChar, buffer[i].Event.KeyEvent.uChar.UnicodeChar);
-
-                env->SetObjectField(keyEvent, KEY_EVENT_RECORD_uChar, unionChar);
-
-                env->SetIntField(keyEvent, KEY_EVENT_RECORD_dwControlKeyState, buffer[i].Event.KeyEvent.dwControlKeyState);
-
-                jobject event = env->NewObject(EventUnion_Class,
-                                               EventUnion_Constructor);
-
-                env->SetObjectField(event, EventUnion_KeyEvent, keyEvent);
-                env->SetObjectField(record, INPUT_RECORD_Event, event);
-                break;
-            }
-            case MOUSE_EVENT: {
-                jobject mouseEvent = env->NewObject(MOUSE_EVENT_RECORD_Class,
-                                                    MOUSE_EVENT_RECORD_Constructor);
-
-                jobject dwMousePosition = env->NewObject(COORD_Class,
-                                                         COORD_Constructor);
-                env->SetIntField(dwMousePosition, COORD_X, buffer[i].Event.MouseEvent.dwMousePosition.X);
-                env->SetIntField(dwMousePosition, COORD_Y, buffer[i].Event.MouseEvent.dwMousePosition.Y);
-                env->SetObjectField(mouseEvent, MOUSE_EVENT_RECORD_dwMousePosition, dwMousePosition);
-                env->SetIntField(mouseEvent, MOUSE_EVENT_RECORD_dwButtonState, buffer[i].Event.MouseEvent.dwButtonState);
-                env->SetIntField(mouseEvent, MOUSE_EVENT_RECORD_dwControlKeyState, buffer[i].Event.MouseEvent.dwControlKeyState);
-                env->SetIntField(mouseEvent, MOUSE_EVENT_RECORD_dwEventFlags, buffer[i].Event.MouseEvent.dwEventFlags);
-
-                jobject event = env->NewObject(EventUnion_Class,
-                                               EventUnion_Constructor);
-
-                env->SetObjectField(event, EventUnion_MouseEvent, mouseEvent);
-                env->SetObjectField(record, INPUT_RECORD_Event, event);
-                break;
-            }
-            case WINDOW_BUFFER_SIZE_EVENT: {
-                jobject windowBufferSize = env->NewObject(WINDOW_BUFFER_SIZE_RECORD_Class,
-                                                          WINDOW_BUFFER_SIZE_RECORD_Constructor);
-
-                jobject dwSize = env->NewObject(COORD_Class,
-                                                COORD_Constructor);
-                env->SetIntField(dwSize, COORD_X, buffer[i].Event.WindowBufferSizeEvent.dwSize.X);
-                env->SetIntField(dwSize, COORD_Y, buffer[i].Event.WindowBufferSizeEvent.dwSize.Y);
-                env->SetObjectField(windowBufferSize, WINDOW_BUFFER_SIZE_RECORD_dwSize, dwSize);
-
-                jobject event = env->NewObject(EventUnion_Class,
-                                               EventUnion_Constructor);
-
-                env->SetObjectField(event, EventUnion_WindowBufferSizeEvent, windowBufferSize);
-                env->SetObjectField(record, INPUT_RECORD_Event, event);
-                break;
-            }
-            case MENU_EVENT: {
-                jobject menuEvent = env->NewObject(MENU_EVENT_RECORD_Class,
-                                                          MENU_EVENT_RECORD_Constructor);
-
-                env->SetBooleanField(menuEvent, MENU_EVENT_RECORD_dwCommandId, buffer[i].Event.MenuEvent.dwCommandId);
-
-                jobject event = env->NewObject(EventUnion_Class,
-                                               EventUnion_Constructor);
-
-                env->SetObjectField(event, EventUnion_MenuEvent, menuEvent);
-                env->SetObjectField(record, INPUT_RECORD_Event, event);
-                break;
-            }
-            case FOCUS_EVENT: {
-                jobject focusEvent = env->NewObject(FOCUS_EVENT_RECORD_Class,
-                                                    FOCUS_EVENT_RECORD_Constructor);
-
-                env->SetIntField(focusEvent, FOCUS_EVENT_RECORD_bSetFocus, buffer[i].Event.FocusEvent.bSetFocus);
-
-                jobject event = env->NewObject(EventUnion_Class,
-                                               EventUnion_Constructor);
-
-                env->SetObjectField(event, EventUnion_FocusEvent, focusEvent);
-                env->SetObjectField(record, INPUT_RECORD_Event, event);
-                break;
-            }
-        }
-        env->SetObjectArrayElement(out_lpBuffer, i, record);
-    }
-    env->SetIntField(out_lpNumberOfEventsRead, intByReferenceValue, numberOfEventsRead);
-    delete[] buffer;
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    SetConsoleCursorPosition
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/COORD;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_SetConsoleCursorPosition
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jobject in_dwCursorPosition) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    COORD coord;
-    coord.X = (SHORT) env->GetLongField(in_dwCursorPosition, COORD_X);
-    coord.Y = (SHORT) env->GetLongField(in_dwCursorPosition, COORD_Y);
-    if (!SetConsoleCursorPosition(h, coord)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return;
-    }
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    SetConsoleMode
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;I)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_SetConsoleMode
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jint in_dwMode) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    if (!SetConsoleMode(h, in_dwMode)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    SetConsoleTextAttribute
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;S)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_SetConsoleTextAttribute
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jshort in_wAttributes) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    if (!SetConsoleTextAttribute(h, in_wAttributes)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    SetConsoleTitle
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_SetConsoleTitle
-  (JNIEnv *env, jobject, jstring in_lpConsoleTitle) {
-    const char *chars = env->GetStringUTFChars(in_lpConsoleTitle, NULL);
-    if (!SetConsoleTitle(chars)) {
-        env->ReleaseStringUTFChars(in_lpConsoleTitle, chars);
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-    env->ReleaseStringUTFChars(in_lpConsoleTitle, chars);
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    WriteConsoleW
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;[CILjdk/internal/org/jline/terminal/impl/jna/win/IntByReference;Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_WriteConsoleW
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jcharArray in_lpBuffer, jint in_nNumberOfCharsToWrite, jobject out_lpNumberOfCharsWritten, jobject) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-    jchar *chars = new jchar[in_nNumberOfCharsToWrite];
-    env->GetCharArrayRegion(in_lpBuffer, 0, in_nNumberOfCharsToWrite, chars);
-    DWORD written;
-    if (!WriteConsoleW(h, chars, in_nNumberOfCharsToWrite, &written, NULL)) {
-        delete[] chars;
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-
-    env->SetIntField(out_lpNumberOfCharsWritten, intByReferenceValue, written);
-    delete[] chars;
-}
-
-/*
- * Class:     jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl
- * Method:    ScrollConsoleScreenBuffer
- * Signature: (Ljdk/internal/org/jline/terminal/impl/jna/win/Pointer;Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/SMALL_RECT;Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/SMALL_RECT;Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/COORD;Ljdk/internal/org/jline/terminal/impl/jna/win/Kernel32/CHAR_INFO;)V
- */
-JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel32Impl_ScrollConsoleScreenBuffer
-  (JNIEnv *env, jobject kernel, jobject in_hConsoleOutput, jobject in_lpScrollRectangle, jobject in_lpClipRectangle, jobject in_dwDestinationOrigin, jobject in_lpFill) {
-    HANDLE h = GetStdHandle((jint) env->GetLongField(in_hConsoleOutput, pointerValue));
-
-    SMALL_RECT scrollRectangle;
-    scrollRectangle.Left = (SHORT) env->GetLongField(in_lpScrollRectangle, SMALL_RECT_Left);
-    scrollRectangle.Top = (SHORT) env->GetLongField(in_lpScrollRectangle, SMALL_RECT_Top);
-    scrollRectangle.Right = (SHORT) env->GetLongField(in_lpScrollRectangle, SMALL_RECT_Right);
-    scrollRectangle.Bottom = (SHORT) env->GetLongField(in_lpScrollRectangle, SMALL_RECT_Bottom);
-
-    SMALL_RECT clipRectangle;
-    clipRectangle.Left = (SHORT) env->GetLongField(in_lpClipRectangle, SMALL_RECT_Left);
-    clipRectangle.Top = (SHORT) env->GetLongField(in_lpClipRectangle, SMALL_RECT_Top);
-    clipRectangle.Right = (SHORT) env->GetLongField(in_lpClipRectangle, SMALL_RECT_Right);
-    clipRectangle.Bottom = (SHORT) env->GetLongField(in_lpClipRectangle, SMALL_RECT_Bottom);
-
-    COORD destinationOrigin;
-    destinationOrigin.X = (SHORT) env->GetLongField(in_dwDestinationOrigin, COORD_X);
-    destinationOrigin.Y = (SHORT) env->GetLongField(in_dwDestinationOrigin, COORD_Y);
-
-    CHAR_INFO charInfo;
-    charInfo.Char.UnicodeChar = env->GetCharField(env->GetObjectField(in_lpFill, CHAR_INFO_uChar), UnionChar_UnicodeChar);
-    charInfo.Attributes = env->GetShortField(in_lpFill, CHAR_INFO_Attributes);
-
-    if (!ScrollConsoleScreenBuffer(h, &scrollRectangle, &clipRectangle, destinationOrigin, &charInfo)) {
-        DWORD error = GetLastError();
-        jobject exc = env->NewObject(lastErrorExceptionClass,
-                                     lastErrorExceptionConstructor,
-                                     (jlong) error);
-        env->Throw((jthrowable) exc);
-        return ;
-    }
-}
diff --git a/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java b/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java
index d53c9b20309..1ca4c091d27 100644
--- a/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java
+++ b/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java
@@ -25,8 +25,10 @@
  * @test
  * @bug 8218287
  * @summary Verify the wrapper input stream is used when using Terminal.reader()
- * @modules jdk.internal.le/jdk.internal.org.jline.terminal
+ * @modules jdk.internal.le/jdk.internal.org.jline
+ *          jdk.internal.le/jdk.internal.org.jline.terminal
  *          jdk.internal.le/jdk.internal.org.jline.terminal.impl
+ *          jdk.internal.le/jdk.internal.org.jline.terminal.spi
  *          jdk.internal.le/jdk.internal.org.jline.utils
  */
 
@@ -39,6 +41,7 @@ import java.util.function.Function;
 import jdk.internal.org.jline.terminal.Size;
 import jdk.internal.org.jline.terminal.Terminal.SignalHandler;
 import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal;
+import jdk.internal.org.jline.terminal.spi.SystemStream;
 
 
 public class AbstractWindowsTerminalTest {
@@ -56,14 +59,17 @@ public class AbstractWindowsTerminalTest {
                 return is.read();
             }
         };
-        var t = new AbstractWindowsTerminal(out, "test", "vt100", null, false, SignalHandler.SIG_DFL, isWrapper) {
+        var t = new AbstractWindowsTerminal(null, SystemStream.Output, out,
+                                                    "test", "vt100", null, false,
+                                                    SignalHandler.SIG_DFL, "", 0,
+                                                    "", 0, isWrapper) {
             @Override
-            protected int getConsoleMode() {
+            protected int getConsoleMode(String console) {
                 return -1;
             }
 
             @Override
-            protected void setConsoleMode(int mode) {
+            protected void setConsoleMode(String console, int mode) {
                 throw new UnsupportedOperationException("unexpected.");
             }
 
diff --git a/test/jdk/jdk/internal/jline/KeyConversionTest.java b/test/jdk/jdk/internal/jline/KeyConversionTest.java
index aed9a726715..ffd116dbbc2 100644
--- a/test/jdk/jdk/internal/jline/KeyConversionTest.java
+++ b/test/jdk/jdk/internal/jline/KeyConversionTest.java
@@ -27,6 +27,7 @@
  * @summary Verify the conversion from key events to escape sequences works properly.
  * @modules jdk.internal.le/jdk.internal.org.jline.terminal
  *          jdk.internal.le/jdk.internal.org.jline.terminal.impl
+ *          jdk.internal.le/jdk.internal.org.jline.terminal.spi
  */
 
 import java.io.IOException;
@@ -36,6 +37,7 @@ import java.nio.charset.Charset;
 import jdk.internal.org.jline.terminal.Size;
 import jdk.internal.org.jline.terminal.Terminal.SignalHandler;
 import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal;
+import jdk.internal.org.jline.terminal.spi.SystemStream;
 
 public class KeyConversionTest {
     public static void main(String... args) throws Exception {
@@ -58,14 +60,17 @@ public class KeyConversionTest {
 
     void checkKeyConversion(KeyEvent event, String expected) throws IOException {
         StringBuilder result = new StringBuilder();
-        new AbstractWindowsTerminal(new StringWriter(), "", "windows", Charset.forName("UTF-8"),
-                                    true, SignalHandler.SIG_DFL, in -> in) {
+        new AbstractWindowsTerminal(null, SystemStream.Output,
+                                            new StringWriter(), "", "windows",
+                                            Charset.forName("UTF-8"), true,
+                                            SignalHandler.SIG_DFL, "", 0,
+                                            "", 0, in -> in) {
             @Override
-            protected int getConsoleMode() {
+            protected int getConsoleMode(String console) {
                 return 0;
             }
             @Override
-            protected void setConsoleMode(int mode) {
+            protected void setConsoleMode(String console, int mode) {
                 throw new UnsupportedOperationException("Not supported yet.");
             }
             @Override
diff --git a/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java b/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java
index 36f96644961..efd1cd010cd 100644
--- a/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java
+++ b/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java
@@ -26,7 +26,7 @@
  * @bug 8224184
  * @summary Control Char  check for pty
  * @modules jdk.internal.le/jdk.internal.org.jline.terminal
- *          jdk.internal.le/jdk.internal.org.jline.terminal.impl
+ *          jdk.internal.le/jdk.internal.org.jline.terminal.impl.exec
  *          jdk.internal.le/jdk.internal.org.jline.terminal.spi
  * @requires (os.family == "linux") | (os.family == "aix")
  */
@@ -35,12 +35,13 @@ import java.util.List;
 import jdk.internal.org.jline.terminal.Attributes;
 import jdk.internal.org.jline.terminal.Attributes.ControlChar;
 import jdk.internal.org.jline.terminal.Attributes.LocalFlag;
-import jdk.internal.org.jline.terminal.impl.ExecPty;
+import jdk.internal.org.jline.terminal.impl.exec.ExecPty;
+import jdk.internal.org.jline.terminal.spi.SystemStream;
 import jdk.internal.org.jline.terminal.spi.TerminalProvider;
 
 public class ExecPtyGetFlagsToSetTest extends ExecPty {
-    public ExecPtyGetFlagsToSetTest(String name, TerminalProvider.Stream stream) {
-        super(name, stream);
+    public ExecPtyGetFlagsToSetTest(TerminalProvider provider, SystemStream stream, String name) {
+        super(provider, stream, name);
     }
 
     @Override
@@ -50,7 +51,7 @@ public class ExecPtyGetFlagsToSetTest extends ExecPty {
 
     public static void main(String[] args) {
         ExecPtyGetFlagsToSetTest testPty =
-            new ExecPtyGetFlagsToSetTest("stty", TerminalProvider.Stream.Output);
+            new ExecPtyGetFlagsToSetTest(null, SystemStream.Output, "stty");
 
         Attributes attr = new Attributes();
         Attributes current = new Attributes();