mirror of
https://github.com/akiyosi/goneovim.git
synced 2025-08-04 10:05:28 +02:00
The current list of modifiers keys inside editor/input.go doesn't handle the keys Hyper_L or Hyper_R, typically mapped to Linux window manager actions. As now, at least on a Debian 12 with DWM setup, it insert a `�` character. This commit add the `Hyper_L` and `Hyper_R` keys to the list to avoid this behaviour. This is only made possible by the fact that the akiyosi's version of Qt bindings add these modifiers.
400 lines
10 KiB
Go
400 lines
10 KiB
Go
package editor
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/akiyosi/qt/core"
|
|
"github.com/akiyosi/qt/gui"
|
|
)
|
|
|
|
func (e *Editor) keyRelease(event *gui.QKeyEvent) {
|
|
if !e.isKeyAutoRepeating {
|
|
return
|
|
}
|
|
|
|
// if editor.config.Editor.SmoothScroll {
|
|
// ws := e.workspaces[e.active]
|
|
// win, ok := ws.screen.getWindow(ws.cursor.gridid)
|
|
// if !ok {
|
|
// return
|
|
// }
|
|
// if win.scrollPixels2 != 0 {
|
|
// return
|
|
// }
|
|
// win.grabScreenSnapshot()
|
|
// }
|
|
|
|
e.isKeyAutoRepeating = false
|
|
}
|
|
|
|
func (e *Editor) keyPress(event *gui.QKeyEvent) {
|
|
if len(e.workspaces) <= e.active {
|
|
return
|
|
}
|
|
ws := e.workspaces[e.active]
|
|
if ws.nvim == nil {
|
|
return
|
|
}
|
|
if event.IsAutoRepeat() {
|
|
e.isKeyAutoRepeating = true
|
|
}
|
|
// if !e.isKeyAutoRepeating {
|
|
// ws.getSnapshot()
|
|
// }
|
|
if !e.isHideMouse && e.config.Editor.HideMouseWhenTyping {
|
|
bc := gui.NewQCursor2(core.Qt__BlankCursor)
|
|
gui.QGuiApplication_SetOverrideCursor(bc)
|
|
gui.QGuiApplication_ChangeOverrideCursor(bc)
|
|
e.isHideMouse = true
|
|
}
|
|
|
|
input := e.convertKey(event)
|
|
|
|
e.putLog("key input for nvim::", "input:", input)
|
|
if input != "" {
|
|
ws.nvim.Input(input)
|
|
}
|
|
}
|
|
|
|
func keyToText(key int, mod core.Qt__KeyboardModifier) string {
|
|
text := string(rune(key))
|
|
if !(mod&core.Qt__ShiftModifier > 0) {
|
|
text = strings.ToLower(text)
|
|
}
|
|
|
|
return text
|
|
}
|
|
|
|
// controlModifier is
|
|
func controlModifier() (controlModifier core.Qt__KeyboardModifier) {
|
|
if runtime.GOOS == "windows" {
|
|
controlModifier = core.Qt__ControlModifier
|
|
}
|
|
if runtime.GOOS == "linux" {
|
|
controlModifier = core.Qt__ControlModifier
|
|
}
|
|
if runtime.GOOS == "darwin" {
|
|
controlModifier = core.Qt__MetaModifier
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// cmdModifier is
|
|
func cmdModifier() (cmdModifier core.Qt__KeyboardModifier) {
|
|
if runtime.GOOS == "windows" {
|
|
cmdModifier = core.Qt__NoModifier
|
|
}
|
|
if runtime.GOOS == "linux" {
|
|
cmdModifier = core.Qt__MetaModifier
|
|
}
|
|
if runtime.GOOS == "darwin" {
|
|
cmdModifier = core.Qt__ControlModifier
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func isAsciiCharRequiringAlt(key int, mod core.Qt__KeyboardModifier, c rune) bool {
|
|
// Ignore all key events where Alt is not pressed
|
|
if !(mod&core.Qt__AltModifier > 0) {
|
|
return false
|
|
}
|
|
|
|
// These low-ascii characters may require AltModifier on MacOS
|
|
if (c == '[' /* && key != int(core.Qt__Key_BracketLeft) */) ||
|
|
(c == ']' && key != int(core.Qt__Key_BracketRight)) ||
|
|
(c == '{' /* && key != int(core.Qt__Key_BraceLeft) */) ||
|
|
(c == '}' && key != int(core.Qt__Key_BraceRight)) ||
|
|
(c == '|' && key != int(core.Qt__Key_Bar)) ||
|
|
(c == '~' && key != int(core.Qt__Key_AsciiTilde)) ||
|
|
(c == '@' && key != int(core.Qt__Key_At)) ||
|
|
(c == '#' && key != int(core.Qt__Key_NumberSign)) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func isControlCaretKeyEvent(key int, mod core.Qt__KeyboardModifier, text string) bool {
|
|
if key != int(core.Qt__Key_6) && key != int(core.Qt__Key_AsciiCircum) {
|
|
return false
|
|
}
|
|
|
|
if !(mod&controlModifier() > 0) {
|
|
return false
|
|
}
|
|
|
|
if text != "\u001E" && text != "^" && text != "6" && text != "" {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (e *Editor) convertKey(event *gui.QKeyEvent) string {
|
|
text := event.Text()
|
|
key := event.Key()
|
|
mod := event.Modifiers()
|
|
|
|
if e.opts.Debug != "" {
|
|
e.putLog("key input(raw)::", fmt.Sprintf("text: %s, key: %d, mod: %v", text, key, mod))
|
|
}
|
|
|
|
// this is macmeta alternatively
|
|
if e.config.Editor.Macmeta {
|
|
if mod&core.Qt__AltModifier > 0 && mod&core.Qt__ShiftModifier > 0 {
|
|
text = string(rune(key))
|
|
} else if mod&core.Qt__AltModifier > 0 && !(mod&core.Qt__ShiftModifier > 0) {
|
|
text = strings.ToLower(string(rune(key)))
|
|
}
|
|
}
|
|
|
|
keypadKeys := map[core.Qt__Key]string{
|
|
core.Qt__Key_Home: "kHome",
|
|
core.Qt__Key_End: "kEnd",
|
|
core.Qt__Key_PageUp: "kPageUp",
|
|
core.Qt__Key_PageDown: "kPageDown",
|
|
core.Qt__Key_Plus: "kPlus",
|
|
core.Qt__Key_Minus: "kMinus",
|
|
core.Qt__Key_multiply: "kMultiply",
|
|
core.Qt__Key_division: "kDivide",
|
|
core.Qt__Key_Enter: "kEnter",
|
|
core.Qt__Key_Period: "kPoint",
|
|
core.Qt__Key_0: "k0",
|
|
core.Qt__Key_1: "k1",
|
|
core.Qt__Key_2: "k2",
|
|
core.Qt__Key_3: "k3",
|
|
core.Qt__Key_4: "k4",
|
|
core.Qt__Key_5: "k5",
|
|
core.Qt__Key_6: "k6",
|
|
core.Qt__Key_7: "k7",
|
|
core.Qt__Key_8: "k8",
|
|
core.Qt__Key_9: "k9",
|
|
}
|
|
|
|
if mod&core.Qt__KeypadModifier > 0 {
|
|
if value, ok := keypadKeys[core.Qt__Key(key)]; ok {
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), value)
|
|
}
|
|
}
|
|
|
|
if key == int(core.Qt__Key_Space) && len([]rune(text)) > 0 && !unicode.IsPrint([]rune(text)[0]) {
|
|
text = " "
|
|
}
|
|
|
|
if key == int(core.Qt__Key_Space) && len([]rune(text)) > 0 && text != " " {
|
|
if mod != core.Qt__NoModifier {
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), text)
|
|
}
|
|
}
|
|
|
|
specialKey, ok := e.specialKeys[core.Qt__Key(key)]
|
|
if ok {
|
|
if key == int(core.Qt__Key_Space) && text != " " {
|
|
return text
|
|
}
|
|
if key == int(core.Qt__Key_Space) || key == int(core.Qt__Key_Backspace) {
|
|
mod &= ^core.Qt__ShiftModifier
|
|
}
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), specialKey)
|
|
}
|
|
|
|
if text == "<" {
|
|
modNoShift := mod & ^core.Qt__ShiftModifier
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(modNoShift), "lt")
|
|
}
|
|
|
|
// neovim-qt issue#720
|
|
if key == int(core.Qt__Key_AsciiCircum) && text == "[" {
|
|
modNoAlt := mod & ^core.Qt__AltModifier
|
|
if modNoAlt == core.Qt__NoModifier {
|
|
return "["
|
|
}
|
|
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(modNoAlt), "[")
|
|
}
|
|
|
|
// Normalize modifiers, CTRL+^ always sends as <C-^>
|
|
if isControlCaretKeyEvent(key, mod, text) {
|
|
modNoShiftMeta := mod & ^core.Qt__ShiftModifier & ^cmdModifier()
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(modNoShiftMeta), "^")
|
|
}
|
|
|
|
if text == "\\" {
|
|
// If key code is yen and text is backslash, return backslash. #534
|
|
if key == 165 {
|
|
return "<Bslash>"
|
|
}
|
|
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), "Bslash")
|
|
}
|
|
|
|
rtext := []rune(text)
|
|
isGraphic := false
|
|
if len(rtext) > 0 {
|
|
isGraphic = unicode.IsGraphic(rtext[0])
|
|
}
|
|
if text == "" || !isGraphic {
|
|
if key == int(core.Qt__Key_Alt) ||
|
|
key == int(core.Qt__Key_AltGr) ||
|
|
key == int(core.Qt__Key_CapsLock) ||
|
|
key == int(core.Qt__Key_Control) ||
|
|
key == int(core.Qt__Key_Meta) ||
|
|
key == int(core.Qt__Key_Shift) ||
|
|
key == int(core.Qt__Key_Hyper_L) ||
|
|
key == int(core.Qt__Key_Hyper_R) ||
|
|
key == int(core.Qt__Key_Super_L) ||
|
|
key == int(core.Qt__Key_Super_R) {
|
|
return ""
|
|
}
|
|
|
|
// Ignore special keys
|
|
if key == int(core.Qt__Key_VolumeDown) ||
|
|
key == int(core.Qt__Key_VolumeMute) ||
|
|
key == int(core.Qt__Key_VolumeUp) {
|
|
return ""
|
|
}
|
|
|
|
text = keyToText(key, mod)
|
|
}
|
|
c := text
|
|
if c == "" {
|
|
return ""
|
|
}
|
|
|
|
char := []rune(c)[0]
|
|
// char := core.NewQChar11(c)
|
|
|
|
// Remove SHIFT
|
|
if (int(char) >= 0x80 || unicode.IsPrint(char)) && !(mod&controlModifier() > 0) && !(mod&cmdModifier() > 0) {
|
|
mod &= ^core.Qt__ShiftModifier
|
|
}
|
|
// if (char.Unicode() >= 0x80 || char.IsPrint()) && !(mod&controlModifier() > 0) && !(mod&cmdModifier() > 0) {
|
|
// mod &= ^core.Qt__ShiftModifier
|
|
// }
|
|
|
|
// Remove CTRL
|
|
if int(char) < 0x20 {
|
|
text = keyToText(key, mod)
|
|
}
|
|
// if char.Unicode() < 0x20 {
|
|
// text = keyToText(key, mod)
|
|
// }
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
// Remove ALT/OPTION
|
|
if int(char) >= 0x80 && unicode.IsPrint(char) {
|
|
mod &= ^core.Qt__AltModifier
|
|
}
|
|
// if char.Unicode() >= 0x80 && char.IsPrint() {
|
|
// mod &= ^core.Qt__AltModifier
|
|
// }
|
|
|
|
// Some locales require Alt for basic low-ascii characters,
|
|
// remove AltModifer. Ex) German layouts use Alt for "{".
|
|
if isAsciiCharRequiringAlt(key, mod, []rune(c)[0]) {
|
|
mod &= ^core.Qt__AltModifier
|
|
}
|
|
|
|
}
|
|
|
|
prefix := e.modPrefix(mod)
|
|
if prefix != "" {
|
|
return fmt.Sprintf("<%s%s>", prefix, c)
|
|
}
|
|
|
|
return c
|
|
}
|
|
|
|
func (e *Editor) modPrefix(mod core.Qt__KeyboardModifier) string {
|
|
prefix := ""
|
|
if runtime.GOOS == "windows" {
|
|
if mod&controlModifier() > 0 && !(mod&core.Qt__AltModifier > 0) {
|
|
prefix += "C-"
|
|
}
|
|
if mod&core.Qt__ShiftModifier > 0 {
|
|
prefix += "S-"
|
|
}
|
|
if mod&core.Qt__AltModifier > 0 && !(mod&controlModifier() > 0) {
|
|
prefix += e.prefixToMapMetaKey
|
|
}
|
|
} else {
|
|
if mod&cmdModifier() > 0 {
|
|
prefix += "D-"
|
|
}
|
|
if mod&controlModifier() > 0 {
|
|
prefix += "C-"
|
|
}
|
|
if mod&core.Qt__ShiftModifier > 0 {
|
|
prefix += "S-"
|
|
}
|
|
if mod&core.Qt__AltModifier > 0 {
|
|
prefix += e.prefixToMapMetaKey
|
|
}
|
|
}
|
|
|
|
return prefix
|
|
}
|
|
|
|
func (e *Editor) initSpecialKeys() {
|
|
e.specialKeys = map[core.Qt__Key]string{}
|
|
e.specialKeys[core.Qt__Key_Up] = "Up"
|
|
e.specialKeys[core.Qt__Key_Down] = "Down"
|
|
e.specialKeys[core.Qt__Key_Left] = "Left"
|
|
e.specialKeys[core.Qt__Key_Right] = "Right"
|
|
|
|
e.specialKeys[core.Qt__Key_F1] = "F1"
|
|
e.specialKeys[core.Qt__Key_F2] = "F2"
|
|
e.specialKeys[core.Qt__Key_F3] = "F3"
|
|
e.specialKeys[core.Qt__Key_F4] = "F4"
|
|
e.specialKeys[core.Qt__Key_F5] = "F5"
|
|
e.specialKeys[core.Qt__Key_F6] = "F6"
|
|
e.specialKeys[core.Qt__Key_F7] = "F7"
|
|
e.specialKeys[core.Qt__Key_F8] = "F8"
|
|
e.specialKeys[core.Qt__Key_F9] = "F9"
|
|
e.specialKeys[core.Qt__Key_F10] = "F10"
|
|
e.specialKeys[core.Qt__Key_F11] = "F11"
|
|
e.specialKeys[core.Qt__Key_F12] = "F12"
|
|
e.specialKeys[core.Qt__Key_F13] = "F13"
|
|
e.specialKeys[core.Qt__Key_F14] = "F14"
|
|
e.specialKeys[core.Qt__Key_F15] = "F15"
|
|
e.specialKeys[core.Qt__Key_F16] = "F16"
|
|
e.specialKeys[core.Qt__Key_F17] = "F17"
|
|
e.specialKeys[core.Qt__Key_F18] = "F18"
|
|
e.specialKeys[core.Qt__Key_F19] = "F19"
|
|
e.specialKeys[core.Qt__Key_F20] = "F20"
|
|
e.specialKeys[core.Qt__Key_F21] = "F21"
|
|
e.specialKeys[core.Qt__Key_F22] = "F22"
|
|
e.specialKeys[core.Qt__Key_F23] = "F23"
|
|
e.specialKeys[core.Qt__Key_F24] = "F24"
|
|
e.specialKeys[core.Qt__Key_Backspace] = "BS"
|
|
e.specialKeys[core.Qt__Key_Delete] = "Del"
|
|
e.specialKeys[core.Qt__Key_Insert] = "Insert"
|
|
e.specialKeys[core.Qt__Key_Home] = "Home"
|
|
e.specialKeys[core.Qt__Key_End] = "End"
|
|
e.specialKeys[core.Qt__Key_PageUp] = "PageUp"
|
|
e.specialKeys[core.Qt__Key_PageDown] = "PageDown"
|
|
e.specialKeys[core.Qt__Key_Return] = "Enter"
|
|
e.specialKeys[core.Qt__Key_Enter] = "Enter"
|
|
e.specialKeys[core.Qt__Key_Tab] = "Tab"
|
|
e.specialKeys[core.Qt__Key_Backtab] = "Tab"
|
|
e.specialKeys[core.Qt__Key_Escape] = "Esc"
|
|
e.specialKeys[core.Qt__Key_Backslash] = "Bslash"
|
|
e.specialKeys[core.Qt__Key_Space] = "Space"
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
e.keyControl = core.Qt__Key_Meta
|
|
e.keyCmd = core.Qt__Key_Control
|
|
} else if runtime.GOOS == "windows" {
|
|
e.keyControl = core.Qt__Key_Control
|
|
e.keyCmd = (core.Qt__Key)(0)
|
|
} else {
|
|
e.keyControl = core.Qt__Key_Control
|
|
e.keyCmd = core.Qt__Key_Meta
|
|
}
|
|
|
|
e.prefixToMapMetaKey = "A-"
|
|
}
|