Repository: charmbracelet/bubbletea
Pull request #1119 (2024-08-28 15:43:47)

(v2) Export different input mode commands and messages
This exports the following modes:
- Kitty keyboard commands and options
- Xterm modifyOtherKeys commands and options
- Win32Input commands and options


Patch:
diff --git a/key.go b/key.go
index a2d1a10..31546c3 100644
--- a/key.go
+++ b/key.go
@@ -354,10 +354,15 @@ func (k Key) String() string {
 			code = k.BaseCode
 		}
 
-		if code == ' ' {
+		switch code {
+		case KeySpace:
 			// Space is the only invisible printable character.
 			sb.WriteString("space")
-		} else {
+		case KeyExtended:
+			// Write the actual text of the key when the key contains multiple
+			// runes.
+			sb.WriteString(k.Text)
+		default:
 			sb.WriteRune(code)
 		}
 	}
diff --git a/kitty.go b/kitty.go
index 834ad6d..c6820b6 100644
--- a/kitty.go
+++ b/kitty.go
@@ -11,7 +11,7 @@ import (
 // enhancement protocol flags.
 type setKittyKeyboardFlagsMsg int
 
-// enableKittyKeyboard is a command to enable Kitty keyboard progressive
+// EnableKittyKeyboard is a command to enable Kitty keyboard progressive
 // enhancements.
 //
 // The flags parameter is a bitmask of the following
@@ -23,15 +23,15 @@ type setKittyKeyboardFlagsMsg int
 //	16: Report associated text
 //
 // See https://sw.kovidgoyal.net/kitty/keyboard-protocol/ for more information.
-func enableKittyKeyboard(flags int) Cmd { //nolint:unused
+func EnableKittyKeyboard(flags int) Cmd { //nolint:unused
 	return func() Msg {
 		return setKittyKeyboardFlagsMsg(flags)
 	}
 }
 
-// disableKittyKeyboard is a command to disable Kitty keyboard progressive
+// DisableKittyKeyboard is a command to disable Kitty keyboard progressive
 // enhancements.
-func disableKittyKeyboard() Msg { //nolint:unused
+func DisableKittyKeyboard() Msg { //nolint:unused
 	return setKittyKeyboardFlagsMsg(0)
 }
 
@@ -39,14 +39,26 @@ func disableKittyKeyboard() Msg { //nolint:unused
 // progressive enhancement flags.
 type kittyKeyboardMsg struct{}
 
-// kittyKeyboard is a command that queries the current Kitty keyboard
+// KittyKeyboard is a command that queries the current Kitty keyboard
 // progressive enhancement flags from the terminal.
-func kittyKeyboard() Msg { //nolint:unused
+func KittyKeyboard() Msg { //nolint:unused
 	return kittyKeyboardMsg{}
 }
 
-// _KittyKeyboardMsg represents Kitty keyboard progressive enhancement flags message.
-type _KittyKeyboardMsg int
+// KittyKeyboardMsg is a bitmask message representing Kitty keyboard
+// progressive enhancement flags.
+//
+// The bitmaps represents the following:
+//
+//	0:  Disable all features
+//	1:  Disambiguate escape codes
+//	2:  Report event types
+//	4:  Report alternate keys
+//	8:  Report all keys as escape codes
+//	16: Report associated text
+//
+// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/ for more information.
+type KittyKeyboardMsg int
 
 // Kitty Clipboard Control Sequences
 var kittyKeyMap = map[int]rune{
diff --git a/options.go b/options.go
index b270a9d..19653c7 100644
--- a/options.go
+++ b/options.go
@@ -265,16 +265,18 @@ func WithReportFocus() ProgramOption {
 // keyboard sequences. This might also enable reporting of release key events
 // depending on the terminal emulator supporting it.
 //
-// This is a syntactic sugar for WithKittyKeyboard(3) and WithXtermModifyOtherKeys(1).
+// This is a syntactic sugar for WithKittyKeyboard(7) and WithXtermModifyOtherKeys(1).
 func WithEnhancedKeyboard() ProgramOption {
 	return func(p *Program) {
-		_WithKittyKeyboard(ansi.KittyDisambiguateEscapeCodes |
-			ansi.KittyReportEventTypes)(p)
-		_WithModifyOtherKeys(1)(p)
+		WithKittyKeyboard(ansi.KittyDisambiguateEscapeCodes |
+			ansi.KittyReportEventTypes |
+			ansi.KittyReportAlternateKeys,
+		)(p)
+		WithModifyOtherKeys(1)(p)
 	}
 }
 
-// _WithKittyKeyboard enables support for the Kitty keyboard protocol. This
+// WithKittyKeyboard enables support for the Kitty keyboard protocol. This
 // protocol enables more key combinations and events than the traditional
 // ambiguous terminal keyboard sequences.
 //
@@ -288,14 +290,14 @@ func WithEnhancedKeyboard() ProgramOption {
 //	16: Report associated text
 //
 // See https://sw.kovidgoyal.net/kitty/keyboard-protocol/ for more information.
-func _WithKittyKeyboard(flags int) ProgramOption {
+func WithKittyKeyboard(flags int) ProgramOption {
 	return func(p *Program) {
 		p.kittyFlags = flags
 		p.startupOptions |= withKittyKeyboard
 	}
 }
 
-// _WithModifyOtherKeys enables support for the XTerm modifyOtherKeys feature.
+// WithModifyOtherKeys enables support for the XTerm modifyOtherKeys feature.
 // This feature allows the terminal to report ambiguous keys as escape codes.
 // This is useful for terminals that don't support the Kitty keyboard protocol.
 //
@@ -307,21 +309,21 @@ func _WithKittyKeyboard(flags int) ProgramOption {
 //	   and Meta-<key>
 //
 // See https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
-func _WithModifyOtherKeys(mode int) ProgramOption {
+func WithModifyOtherKeys(mode int) ProgramOption {
 	return func(p *Program) {
 		p.modifyOtherKeys = mode
 		p.startupOptions |= withModifyOtherKeys
 	}
 }
 
-// _WithWindowsInputMode enables Windows Input Mode (win32-input-mode) which
+// WithWindowsInputMode enables Windows Input Mode (win32-input-mode) which
 // allows for more advanced input handling and reporting. This is experimental
 // and may not work on all terminals.
 //
 // See
 // https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
 // for more information.
-func _WithWindowsInputMode() ProgramOption { //nolint:unused
+func WithWindowsInputMode() ProgramOption { //nolint:unused
 	return func(p *Program) {
 		p.startupOptions |= withWindowsInputMode
 		p.win32Input = true
diff --git a/parse.go b/parse.go
index 4427c38..5cdd864 100644
--- a/parse.go
+++ b/parse.go
@@ -250,7 +250,7 @@ func parseCsi(b []byte) (int, Msg) {
 	case 'u' | '?'<<parser.MarkerShift:
 		// Kitty keyboard flags
 		if param := csi.Param(0); param != -1 {
-			return i, _KittyKeyboardMsg(param)
+			return i, KittyKeyboardMsg(param)
 		}
 	case 'R' | '?'<<parser.MarkerShift:
 		// This report may return a third parameter representing the page
@@ -266,7 +266,7 @@ func parseCsi(b []byte) (int, Msg) {
 	case 'm' | '>'<<parser.MarkerShift:
 		// XTerm modifyOtherKeys
 		if paramsLen == 2 && csi.Param(0) == 4 && csi.Param(1) != -1 {
-			return i, modifyOtherKeysMsg(csi.Param(1))
+			return i, ModifyOtherKeysMsg(csi.Param(1))
 		}
 	case 'I':
 		return i, FocusMsg{}
diff --git a/tea.go b/tea.go
index 22c150a..b02e1a2 100644
--- a/tea.go
+++ b/tea.go
@@ -498,7 +498,7 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
 			case cursorColorMsg:
 				p.execute(ansi.RequestCursorColor)
 
-			case _KittyKeyboardMsg:
+			case KittyKeyboardMsg:
 				// Store the kitty flags whenever they are queried.
 				p.kittyFlags = int(msg)
 
diff --git a/win32input.go b/win32input.go
index 220a740..47e7c1e 100644
--- a/win32input.go
+++ b/win32input.go
@@ -7,26 +7,26 @@ import (
 // enableWin32InputMsg is a message that enables Windows input mode.
 type enableWin32InputMsg struct{}
 
-// enableWindowsInputMode is a command that enables Windows input mode
+// EnableWindowsInputMode is a command that enables Windows input mode
 // (win32-input-mode).
 //
 // See
 // https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
 // for more information.
-func enableWindowsInputMode() Msg { //nolint:unused
+func EnableWindowsInputMode() Msg { //nolint:unused
 	return enableWin32InputMsg{}
 }
 
 // disableWin32InputMsg is a message that disables Windows input mode.
 type disableWin32InputMsg struct{}
 
-// disableWindowsInputMode is a command that disables Windows input mode
+// DisableWindowsInputMode is a command that disables Windows input mode
 // (win32-input-mode).
 //
 // See
 // https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md
 // for more information.
-func disableWindowsInputMode() Msg { //nolint:unused
+func DisableWindowsInputMode() Msg { //nolint:unused
 	return disableWin32InputMsg{}
 }
 
diff --git a/xterm.go b/xterm.go
index 298f494..ffedca1 100644
--- a/xterm.go
+++ b/xterm.go
@@ -16,14 +16,14 @@ type setModifyOtherKeysMsg int
 //	   and Meta-<key>
 //
 // See https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
-func enableModifyOtherKeys(mode int) Cmd { //nolint:unused
+func EnableModifyOtherKeys(mode int) Cmd { //nolint:unused
 	return func() Msg {
 		return setModifyOtherKeysMsg(mode)
 	}
 }
 
-// disableModifyOtherKeys is a command to disable XTerm modifyOtherKeys mode.
-func disableModifyOtherKeys() Msg { //nolint:unused
+// DisableModifyOtherKeys is a command to disable XTerm modifyOtherKeys mode.
+func DisableModifyOtherKeys() Msg { //nolint:unused
 	return setModifyOtherKeysMsg(0)
 }
 
@@ -58,15 +58,15 @@ func parseXTermModifyOtherKeys(csi *ansi.CsiSequence) Msg {
 // modifyOtherKeys mode.
 type modifyOtherKeys struct{}
 
-// _ModifyOtherKeys is a command that queries the terminal for its
+// ModifyOtherKeys is a command that queries the terminal for its
 // modifyOtherKeys mode.
-func _ModifyOtherKeys() Msg { //nolint:unused
+func ModifyOtherKeys() Msg { //nolint:unused
 	return modifyOtherKeys{}
 }
 
-// modifyOtherKeysMsg is a message that represents XTerm modifyOtherKeys
+// ModifyOtherKeysMsg is a message that represents XTerm modifyOtherKeys
 // report. Querying the terminal for the modifyOtherKeys mode will return a
-// modifyOtherKeysMsg message with the current mode set.
+// ModifyOtherKeysMsg message with the current mode set.
 //
 //	0: disable
 //	1: enable mode 1
@@ -74,7 +74,7 @@ func _ModifyOtherKeys() Msg { //nolint:unused
 //
 // See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
 // See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys
-type modifyOtherKeysMsg uint8
+type ModifyOtherKeysMsg uint8
 
 // TerminalVersionMsg is a message that represents the terminal version.
 type TerminalVersionMsg string


Test patch:
diff --git a/screen_test.go b/screen_test.go
index 2e52e97..b719ba8 100644
--- a/screen_test.go
+++ b/screen_test.go
@@ -74,7 +74,7 @@ func TestClearMsg(t *testing.T) {
 		},
 		{
 			name:     "kitty_start",
-			cmds:     []Cmd{disableKittyKeyboard, enableKittyKeyboard(3)},
+			cmds:     []Cmd{DisableKittyKeyboard, EnableKittyKeyboard(3)},
 			expected: "\x1b[?25l\x1b[?2004h\x1b[?2027h\x1b[?2027$p\x1b[>u\x1b[>3u\rsuccess\r\n\x1b[D\x1b[2K\r\x1b[?2004l\x1b[?25h\x1b[>0u",
 		},
 	}