mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-15 18:02:58 +08:00
fix: emacs alt x
This commit is contained in:
@@ -11,6 +11,7 @@ import app.termora.terminal.panel.TerminalPanel
|
||||
import app.termora.terminal.panel.TerminalWriter
|
||||
import kotlinx.coroutines.*
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.awt.event.ComponentEvent
|
||||
import java.awt.event.ComponentListener
|
||||
import java.nio.charset.Charset
|
||||
@@ -105,6 +106,10 @@ class TerminalPanelFactory : Disposable {
|
||||
}
|
||||
|
||||
private class MyTerminalWriter(private val ptyConnector: PtyConnector) : TerminalWriter {
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(MyTerminalWriter::class.java)
|
||||
}
|
||||
|
||||
private lateinit var evt: AnActionEvent
|
||||
|
||||
override fun onMounted(c: JComponent) {
|
||||
@@ -112,6 +117,11 @@ class TerminalPanelFactory : Disposable {
|
||||
}
|
||||
|
||||
override fun write(request: TerminalWriter.WriteRequest) {
|
||||
|
||||
if (log.isDebugEnabled) {
|
||||
log.debug("write: ${String(request.buffer, getCharset())}")
|
||||
}
|
||||
|
||||
val windowScope = evt.getData(DataProviders.WindowScope)
|
||||
if (windowScope == null) {
|
||||
ptyConnector.write(request.buffer)
|
||||
|
||||
@@ -58,11 +58,10 @@ open class ColorPaletteImpl(private val terminal: Terminal) : ColorPalette {
|
||||
for (g in 0 until 6) {
|
||||
for (b in 0 until 6) {
|
||||
val idx = 36 * r + 6 * g + b
|
||||
xterm256Colors[idx] = Color(
|
||||
getCubeColorValue(r),
|
||||
getCubeColorValue(g),
|
||||
getCubeColorValue(b),
|
||||
).rgb
|
||||
val x = getCubeColorValue(r)
|
||||
val y = getCubeColorValue(g)
|
||||
val z = getCubeColorValue(b)
|
||||
xterm256Colors[idx] = 65536 * x + 256 * y + z
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +69,7 @@ open class ColorPaletteImpl(private val terminal: Terminal) : ColorPalette {
|
||||
for (gray in 0..23) {
|
||||
val a = 10 * gray + 8
|
||||
val idx = 216 + gray
|
||||
xterm256Colors[idx] = Color(a, a, a).rgb
|
||||
xterm256Colors[idx] = 65536 * a + 256 * a + a
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,26 +15,39 @@ class TerminalPanelKeyAdapter(
|
||||
private val writer: TerminalWriter
|
||||
) : KeyAdapter() {
|
||||
|
||||
companion object {
|
||||
private const val ASCII_ESC = 27.toChar()
|
||||
}
|
||||
|
||||
private val activeKeymap get() = KeymapManager.getInstance().getActiveKeymap()
|
||||
private var isIgnoreKeyTyped = false
|
||||
|
||||
override fun keyTyped(e: KeyEvent) {
|
||||
if (Character.isISOControl(e.keyChar)) {
|
||||
// 如果忽略并且不是正常字符
|
||||
if (isIgnoreKeyTyped || Character.isISOControl(e.keyChar)) {
|
||||
return
|
||||
}
|
||||
|
||||
terminal.getSelectionModel().clearSelection()
|
||||
|
||||
writer.write(
|
||||
TerminalWriter.WriteRequest.fromBytes(
|
||||
"${e.keyChar}".toByteArray(writer.getCharset())
|
||||
)
|
||||
)
|
||||
|
||||
writer.write(TerminalWriter.WriteRequest.fromBytes("${e.keyChar}".toByteArray(writer.getCharset())))
|
||||
terminal.getScrollingModel().scrollTo(Int.MAX_VALUE)
|
||||
|
||||
}
|
||||
|
||||
override fun keyPressed(e: KeyEvent) {
|
||||
// 重置
|
||||
isIgnoreKeyTyped = false
|
||||
|
||||
// 处理
|
||||
doKeyPressed(e)
|
||||
|
||||
// 如果已经处理,那么忽略 keyTyped 事件
|
||||
if (e.isConsumed) {
|
||||
isIgnoreKeyTyped = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun doKeyPressed(e: KeyEvent) {
|
||||
if (e.isConsumed) return
|
||||
|
||||
// remove all toast
|
||||
@@ -53,6 +66,7 @@ class TerminalPanelKeyAdapter(
|
||||
val encode = terminal.getKeyEncoder().encode(AWTTerminalKeyEvent(e))
|
||||
if (encode.isNotEmpty()) {
|
||||
writer.write(TerminalWriter.WriteRequest.fromBytes(encode.toByteArray(writer.getCharset())))
|
||||
e.consume()
|
||||
}
|
||||
|
||||
// https://github.com/TermoraDev/termora/issues/52
|
||||
@@ -60,6 +74,14 @@ class TerminalPanelKeyAdapter(
|
||||
return
|
||||
}
|
||||
|
||||
// https://github.com/TermoraDev/termora/issues/331
|
||||
if (isAltPressedOnly(e) && Character.isDefined(e.keyChar)) {
|
||||
val c = String(charArrayOf(ASCII_ESC, simpleMapKeyCodeToChar(e)))
|
||||
writer.write(TerminalWriter.WriteRequest.fromBytes(c.toByteArray(writer.getCharset())))
|
||||
e.consume()
|
||||
return
|
||||
}
|
||||
|
||||
// 如果命中了全局快捷键,那么不处理
|
||||
if (keyStroke.modifiers != 0 && activeKeymap.getActionIds(KeyShortcut(keyStroke)).isNotEmpty()) {
|
||||
return
|
||||
@@ -70,6 +92,7 @@ class TerminalPanelKeyAdapter(
|
||||
// 如果不为空表示已经发送过了,所以这里为空的时候再发送
|
||||
if (encode.isEmpty()) {
|
||||
writer.write(TerminalWriter.WriteRequest.fromBytes("${e.keyChar}".toByteArray(writer.getCharset())))
|
||||
e.consume()
|
||||
}
|
||||
terminal.getScrollingModel().scrollTo(Int.MAX_VALUE)
|
||||
}
|
||||
@@ -83,4 +106,20 @@ class TerminalPanelKeyAdapter(
|
||||
&& (modifiersEx and InputEvent.CTRL_DOWN_MASK) != 0
|
||||
&& (modifiersEx and InputEvent.SHIFT_DOWN_MASK) == 0
|
||||
}
|
||||
|
||||
private fun isAltPressedOnly(e: KeyEvent): Boolean {
|
||||
val modifiersEx = e.modifiersEx
|
||||
return (modifiersEx and InputEvent.ALT_DOWN_MASK) != 0
|
||||
&& (modifiersEx and InputEvent.ALT_GRAPH_DOWN_MASK) == 0
|
||||
&& (modifiersEx and InputEvent.CTRL_DOWN_MASK) == 0
|
||||
&& (modifiersEx and InputEvent.SHIFT_DOWN_MASK) == 0
|
||||
}
|
||||
|
||||
|
||||
private fun simpleMapKeyCodeToChar(e: KeyEvent): Char {
|
||||
// zsh requires proper case of letter
|
||||
if (e.isShiftDown) return Character.toUpperCase(e.keyCode.toChar())
|
||||
return Character.toLowerCase(e.keyCode.toChar());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user