forked from toolshed/abra
We were running behind and there were quite some deprecations to update. This was mostly in the upstream copy/pasta package but seems quite minimal.
173 lines
4.3 KiB
Go
173 lines
4.3 KiB
Go
package ansi
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// MouseButton represents the button that was pressed during a mouse message.
|
|
type MouseButton byte
|
|
|
|
// Mouse event buttons
|
|
//
|
|
// This is based on X11 mouse button codes.
|
|
//
|
|
// 1 = left button
|
|
// 2 = middle button (pressing the scroll wheel)
|
|
// 3 = right button
|
|
// 4 = turn scroll wheel up
|
|
// 5 = turn scroll wheel down
|
|
// 6 = push scroll wheel left
|
|
// 7 = push scroll wheel right
|
|
// 8 = 4th button (aka browser backward button)
|
|
// 9 = 5th button (aka browser forward button)
|
|
// 10
|
|
// 11
|
|
//
|
|
// Other buttons are not supported.
|
|
const (
|
|
MouseNone MouseButton = iota
|
|
MouseButton1
|
|
MouseButton2
|
|
MouseButton3
|
|
MouseButton4
|
|
MouseButton5
|
|
MouseButton6
|
|
MouseButton7
|
|
MouseButton8
|
|
MouseButton9
|
|
MouseButton10
|
|
MouseButton11
|
|
|
|
MouseLeft = MouseButton1
|
|
MouseMiddle = MouseButton2
|
|
MouseRight = MouseButton3
|
|
MouseWheelUp = MouseButton4
|
|
MouseWheelDown = MouseButton5
|
|
MouseWheelLeft = MouseButton6
|
|
MouseWheelRight = MouseButton7
|
|
MouseBackward = MouseButton8
|
|
MouseForward = MouseButton9
|
|
MouseRelease = MouseNone
|
|
)
|
|
|
|
var mouseButtons = map[MouseButton]string{
|
|
MouseNone: "none",
|
|
MouseLeft: "left",
|
|
MouseMiddle: "middle",
|
|
MouseRight: "right",
|
|
MouseWheelUp: "wheelup",
|
|
MouseWheelDown: "wheeldown",
|
|
MouseWheelLeft: "wheelleft",
|
|
MouseWheelRight: "wheelright",
|
|
MouseBackward: "backward",
|
|
MouseForward: "forward",
|
|
MouseButton10: "button10",
|
|
MouseButton11: "button11",
|
|
}
|
|
|
|
// String returns a string representation of the mouse button.
|
|
func (b MouseButton) String() string {
|
|
return mouseButtons[b]
|
|
}
|
|
|
|
// EncodeMouseButton returns a byte representing a mouse button.
|
|
// The button is a bitmask of the following leftmost values:
|
|
//
|
|
// - The first two bits are the button number:
|
|
// 0 = left button, wheel up, or button no. 8 aka (backwards)
|
|
// 1 = middle button, wheel down, or button no. 9 aka (forwards)
|
|
// 2 = right button, wheel left, or button no. 10
|
|
// 3 = release event, wheel right, or button no. 11
|
|
//
|
|
// - The third bit indicates whether the shift key was pressed.
|
|
//
|
|
// - The fourth bit indicates the alt key was pressed.
|
|
//
|
|
// - The fifth bit indicates the control key was pressed.
|
|
//
|
|
// - The sixth bit indicates motion events. Combined with button number 3, i.e.
|
|
// release event, it represents a drag event.
|
|
//
|
|
// - The seventh bit indicates a wheel event.
|
|
//
|
|
// - The eighth bit indicates additional buttons.
|
|
//
|
|
// If button is [MouseNone], and motion is false, this returns a release event.
|
|
// If button is undefined, this function returns 0xff.
|
|
func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) {
|
|
// mouse bit shifts
|
|
const (
|
|
bitShift = 0b0000_0100
|
|
bitAlt = 0b0000_1000
|
|
bitCtrl = 0b0001_0000
|
|
bitMotion = 0b0010_0000
|
|
bitWheel = 0b0100_0000
|
|
bitAdd = 0b1000_0000 // additional buttons 8-11
|
|
|
|
bitsMask = 0b0000_0011
|
|
)
|
|
|
|
if b == MouseNone {
|
|
m = bitsMask
|
|
} else if b >= MouseLeft && b <= MouseRight {
|
|
m = byte(b - MouseLeft)
|
|
} else if b >= MouseWheelUp && b <= MouseWheelRight {
|
|
m = byte(b - MouseWheelUp)
|
|
m |= bitWheel
|
|
} else if b >= MouseBackward && b <= MouseButton11 {
|
|
m = byte(b - MouseBackward)
|
|
m |= bitAdd
|
|
} else {
|
|
m = 0xff // invalid button
|
|
}
|
|
|
|
if shift {
|
|
m |= bitShift
|
|
}
|
|
if alt {
|
|
m |= bitAlt
|
|
}
|
|
if ctrl {
|
|
m |= bitCtrl
|
|
}
|
|
if motion {
|
|
m |= bitMotion
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// x10Offset is the offset for X10 mouse events.
|
|
// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
|
const x10Offset = 32
|
|
|
|
// MouseX10 returns an escape sequence representing a mouse event in X10 mode.
|
|
// Note that this requires the terminal support X10 mouse modes.
|
|
//
|
|
// CSI M Cb Cx Cy
|
|
//
|
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
|
func MouseX10(b byte, x, y int) string {
|
|
return "\x1b[M" + string(b+x10Offset) + string(byte(x)+x10Offset+1) + string(byte(y)+x10Offset+1)
|
|
}
|
|
|
|
// MouseSgr returns an escape sequence representing a mouse event in SGR mode.
|
|
//
|
|
// CSI < Cb ; Cx ; Cy M
|
|
// CSI < Cb ; Cx ; Cy m (release)
|
|
//
|
|
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
|
func MouseSgr(b byte, x, y int, release bool) string {
|
|
s := 'M'
|
|
if release {
|
|
s = 'm'
|
|
}
|
|
if x < 0 {
|
|
x = -x
|
|
}
|
|
if y < 0 {
|
|
y = -y
|
|
}
|
|
return fmt.Sprintf("\x1b[<%d;%d;%d%c", b, x+1, y+1, s)
|
|
}
|