From 036fef33832ae672f13c394f39a0ed1b5040d4ec Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 21 Sep 2020 11:17:11 -0700 Subject: [PATCH] Fix end, delete and insert keys on windows The ansi.caps file doesn't contain any bindings for delete, end or insert keys. To work around that, we specifiy the defaults in the WindowsInputStream and override the terminal's getStringCapability method in the wrapped jline 3 terminal that we pass to the jline 3 line reader. --- .../src/main/scala/sbt/internal/util/JLine3.scala | 7 ++++++- .../sbt/internal/util/WindowsInputStream.scala | 13 +++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala b/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala index 7a64526d6..ef091496b 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/JLine3.scala @@ -172,7 +172,12 @@ private[sbt] object JLine3 { * are the same. */ override def getStringCapability(cap: Capability): String = { - term.getStringCapability(cap.toString) + term.getStringCapability(cap.toString) match { + case null if cap == Capability.key_dc && Util.isWindows => "\\E[3~" + case null if cap == Capability.key_end && Util.isWindows => "\\E[4~" + case null if cap == Capability.key_ic && Util.isWindows => "\\E[2~" + case c => c + } } override def getNumericCapability(cap: Capability): Integer = term.getNumericCapability(cap.toString) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala b/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala index 6f6a169f7..a9604f092 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/WindowsInputStream.scala @@ -77,14 +77,11 @@ private[util] class WindowsInputStream(term: org.jline.terminal.Terminal, in: In val escapeSequence = keyEvent.keyCode match { case 0x21 /* VK_PRIOR PageUp*/ => getCapability(Capability.key_ppage); case 0x22 /* VK_NEXT PageDown*/ => getCapability(Capability.key_npage); - case 0x23 /* VK_END */ => getCapability(Capability.key_end) case 0x24 /* VK_HOME */ => getCapability(Capability.key_home) case 0x25 /* VK_LEFT */ => getCapability(Capability.key_left) case 0x26 /* VK_UP */ => getCapability(Capability.key_up) case 0x27 /* VK_RIGHT */ => getCapability(Capability.key_right) case 0x28 /* VK_DOWN */ => getCapability(Capability.key_down) - case 0x2D /* VK_INSERT */ => getCapability(Capability.key_ic) - case 0x2E /* VK_DELETE */ => getCapability(Capability.key_dc) case 0x70 /* VK_F1 */ => getCapability(Capability.key_f1) case 0x71 /* VK_F2 */ => getCapability(Capability.key_f2) case 0x72 /* VK_F3 */ => getCapability(Capability.key_f3) @@ -97,7 +94,15 @@ private[util] class WindowsInputStream(term: org.jline.terminal.Terminal, in: In case 0x79 /* VK_F10 */ => getCapability(Capability.key_f10) case 0x7A /* VK_F11 */ => getCapability(Capability.key_f11) case 0x7B /* VK_F12 */ => getCapability(Capability.key_f12) - case _ => null + // VK_END, VK_INSERT and VK_DELETE are not in the ansi key bindings so we + // have to manually apply the the sequences here and in JLine3.wrap + case 0x23 /* VK_END */ => + Option(getCapability(Capability.key_end)).getOrElse("\u001B[4!") + case 0x2D /* VK_INSERT */ => + Option(getCapability(Capability.key_ic)).getOrElse("\u001B[2~") + case 0x2E /* VK_DELETE */ => + Option(getCapability(Capability.key_dc)).getOrElse("\u001B[3~") + case _ => null } escapeSequence match { case null =>