From a3069229b8801d0e7f6be78244c855785e91f87d Mon Sep 17 00:00:00 2001 From: hstyi Date: Wed, 20 Aug 2025 17:02:44 +0800 Subject: [PATCH] chore: ssh supports modifying the backspace behaviour --- .../plugin/internal/ssh/SSHHostOptionsPane.kt | 6 ++++++ .../plugin/internal/ssh/SSHTerminalTab.kt | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/app/termora/plugin/internal/ssh/SSHHostOptionsPane.kt b/src/main/kotlin/app/termora/plugin/internal/ssh/SSHHostOptionsPane.kt index 92e0b85..507f6cf 100644 --- a/src/main/kotlin/app/termora/plugin/internal/ssh/SSHHostOptionsPane.kt +++ b/src/main/kotlin/app/termora/plugin/internal/ssh/SSHHostOptionsPane.kt @@ -8,6 +8,7 @@ import app.termora.keymgr.KeyManagerDialog import app.termora.plugin.internal.AltKeyModifier import app.termora.plugin.internal.BasicProxyOption import app.termora.plugin.internal.BasicTerminalOption +import app.termora.plugin.internal.telnet.TelnetHostOptionsPane.Backspace import app.termora.tree.Filter import app.termora.tree.HostTreeNode import app.termora.tree.NewHostTreeDialog @@ -36,6 +37,7 @@ internal class SSHHostOptionsPane(private val accountOwner: AccountOwner) : Opti private val terminalOption = BasicTerminalOption().apply { showCharsetComboBox = true showLoginScripts = true + showBackspaceComboBox = true showEnvironmentTextArea = true showStartupCommandTextField = true showHeartbeatIntervalTextField = true @@ -112,6 +114,7 @@ internal class SSHHostOptionsPane(private val accountOwner: AccountOwner) : Opti x11Forwarding = tunnelingOption.x11ServerTextField.text, loginScripts = terminalOption.loginScripts, extras = mutableMapOf( + "backspace" to (terminalOption.backspaceComboBox.selectedItem as Backspace).name, "altModifier" to (terminalOption.altModifierComboBox.selectedItem?.toString() ?: AltKeyModifier.EightBit.name), "keywordHighlightSetId" to ((terminalOption.highlightSetComboBox.selectedItem as? KeywordHighlight)?.id @@ -169,6 +172,9 @@ internal class SSHHostOptionsPane(private val accountOwner: AccountOwner) : Opti .getOrNull() ?: AltKeyModifier.EightBit + terminalOption.backspaceComboBox.selectedItem = + Backspace.valueOf(host.options.extras["backspace"] ?: Backspace.Delete.name) + val timeout = host.options.extras["timeout"] ?: "60" terminalOption.timeoutTextField.value = timeout.toIntOrNull() ?: 60 diff --git a/src/main/kotlin/app/termora/plugin/internal/ssh/SSHTerminalTab.kt b/src/main/kotlin/app/termora/plugin/internal/ssh/SSHTerminalTab.kt index 83778cc..f80c041 100644 --- a/src/main/kotlin/app/termora/plugin/internal/ssh/SSHTerminalTab.kt +++ b/src/main/kotlin/app/termora/plugin/internal/ssh/SSHTerminalTab.kt @@ -7,9 +7,8 @@ import app.termora.addons.zmodem.ZModemPtyConnectorAdaptor import app.termora.database.DatabaseManager import app.termora.keymap.KeyShortcut import app.termora.keymap.KeymapManager -import app.termora.terminal.ControlCharacters -import app.termora.terminal.DataKey -import app.termora.terminal.PtyConnector +import app.termora.plugin.internal.telnet.TelnetHostOptionsPane +import app.termora.terminal.* import kotlinx.coroutines.* import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.sync.Mutex @@ -20,6 +19,7 @@ import org.apache.sshd.client.session.ClientSession import org.apache.sshd.common.future.CloseFuture import org.apache.sshd.common.future.SshFutureListener import org.slf4j.LoggerFactory +import java.awt.event.KeyEvent import java.nio.charset.StandardCharsets import javax.swing.Icon import javax.swing.JComponent @@ -110,7 +110,18 @@ class SSHTerminalTab( // clear screen terminal.clearScreen() // show cursor - terminalModel.setData(DataKey.Companion.ShowCursor, true) + terminalModel.setData(DataKey.ShowCursor, true) + + val encoder = terminal.getKeyEncoder() + if (encoder is KeyEncoderImpl) { + val backspace = host.options.extras["backspace"] + if (backspace == TelnetHostOptionsPane.Backspace.Backspace.name) { + encoder.putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_BACK_SPACE), String(byteArrayOf(0x08))) + } else if (backspace == TelnetHostOptionsPane.Backspace.VT220.name) { + encoder.putCode(TerminalKeyEvent(keyCode = KeyEvent.VK_BACK_SPACE), "${ControlCharacters.ESC}[3~") + } + } + } return ptyConnectorFactory.decorate(