native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: satisfy key token swiftlint rules

onevpaw 04cdf259 a8f402ce

+198 -150
+74 -68
supacode/CLIService/Shared/KeyCommandPayload.swift
··· 172 172 /// Shared token definitions for the `key` command. 173 173 /// Used by CLI for validation and by app for response building. 174 174 public enum KeyTokens { 175 + private static let namedBaseDescriptors: [String: KeyBaseDescriptor] = [ 176 + "enter": KeyBaseDescriptor(canonical: "enter", category: .editing), 177 + "return": KeyBaseDescriptor(canonical: "enter", category: .editing), 178 + "esc": KeyBaseDescriptor(canonical: "esc", category: .control), 179 + "escape": KeyBaseDescriptor(canonical: "esc", category: .control), 180 + "tab": KeyBaseDescriptor(canonical: "tab", category: .navigation), 181 + "backspace": KeyBaseDescriptor(canonical: "backspace", category: .editing), 182 + "delete": KeyBaseDescriptor(canonical: "backspace", category: .editing), 183 + "del": KeyBaseDescriptor(canonical: "backspace", category: .editing), 184 + "delete-forward": KeyBaseDescriptor(canonical: "delete-forward", category: .editing), 185 + "forward-delete": KeyBaseDescriptor(canonical: "delete-forward", category: .editing), 186 + "deleteforward": KeyBaseDescriptor(canonical: "delete-forward", category: .editing), 187 + "forwarddelete": KeyBaseDescriptor(canonical: "delete-forward", category: .editing), 188 + "insert": KeyBaseDescriptor(canonical: "insert", category: .editing), 189 + "ins": KeyBaseDescriptor(canonical: "insert", category: .editing), 190 + "up": KeyBaseDescriptor(canonical: "up", category: .navigation), 191 + "arrow-up": KeyBaseDescriptor(canonical: "up", category: .navigation), 192 + "down": KeyBaseDescriptor(canonical: "down", category: .navigation), 193 + "arrow-down": KeyBaseDescriptor(canonical: "down", category: .navigation), 194 + "left": KeyBaseDescriptor(canonical: "left", category: .navigation), 195 + "arrow-left": KeyBaseDescriptor(canonical: "left", category: .navigation), 196 + "right": KeyBaseDescriptor(canonical: "right", category: .navigation), 197 + "arrow-right": KeyBaseDescriptor(canonical: "right", category: .navigation), 198 + "pageup": KeyBaseDescriptor(canonical: "pageup", category: .navigation), 199 + "page-up": KeyBaseDescriptor(canonical: "pageup", category: .navigation), 200 + "pgup": KeyBaseDescriptor(canonical: "pageup", category: .navigation), 201 + "pagedown": KeyBaseDescriptor(canonical: "pagedown", category: .navigation), 202 + "page-down": KeyBaseDescriptor(canonical: "pagedown", category: .navigation), 203 + "pgdn": KeyBaseDescriptor(canonical: "pagedown", category: .navigation), 204 + "home": KeyBaseDescriptor(canonical: "home", category: .navigation), 205 + "end": KeyBaseDescriptor(canonical: "end", category: .navigation), 206 + "space": KeyBaseDescriptor(canonical: "space", category: .editing), 207 + "minus": KeyBaseDescriptor(canonical: "minus", category: .editing), 208 + "hyphen": KeyBaseDescriptor(canonical: "minus", category: .editing), 209 + "dash": KeyBaseDescriptor(canonical: "minus", category: .editing), 210 + "equal": KeyBaseDescriptor(canonical: "equal", category: .editing), 211 + "equals": KeyBaseDescriptor(canonical: "equal", category: .editing), 212 + "comma": KeyBaseDescriptor(canonical: "comma", category: .editing), 213 + "period": KeyBaseDescriptor(canonical: "period", category: .editing), 214 + "dot": KeyBaseDescriptor(canonical: "period", category: .editing), 215 + "slash": KeyBaseDescriptor(canonical: "slash", category: .editing), 216 + "backslash": KeyBaseDescriptor(canonical: "backslash", category: .editing), 217 + "semicolon": KeyBaseDescriptor(canonical: "semicolon", category: .editing), 218 + "quote": KeyBaseDescriptor(canonical: "quote", category: .editing), 219 + "apostrophe": KeyBaseDescriptor(canonical: "quote", category: .editing), 220 + "grave": KeyBaseDescriptor(canonical: "grave", category: .editing), 221 + "backtick": KeyBaseDescriptor(canonical: "grave", category: .editing), 222 + "left-bracket": KeyBaseDescriptor(canonical: "[", category: .editing), 223 + "leftbracket": KeyBaseDescriptor(canonical: "[", category: .editing), 224 + "lbracket": KeyBaseDescriptor(canonical: "[", category: .editing), 225 + "right-bracket": KeyBaseDescriptor(canonical: "]", category: .editing), 226 + "rightbracket": KeyBaseDescriptor(canonical: "]", category: .editing), 227 + "rbracket": KeyBaseDescriptor(canonical: "]", category: .editing), 228 + ] 229 + 175 230 public static func normalize(_ raw: String) -> String? { 176 231 descriptor(for: raw)?.normalized 177 232 } ··· 193 248 .map(String.init) 194 249 guard !parts.isEmpty, !parts.contains(where: \.isEmpty) else { return nil } 195 250 196 - for baseLength in [2, 1] where parts.count >= baseLength { 251 + return descriptor(for: parts, baseLengths: [2, 1]) 252 + } 253 + 254 + private static func descriptor(for parts: [String], baseLengths: [Int]) -> KeyTokenDescriptor? { 255 + for baseLength in baseLengths where parts.count >= baseLength { 197 256 let baseRaw = parts.suffix(baseLength).joined(separator: "-") 198 257 guard let base = baseDescriptor(for: baseRaw) else { continue } 199 - 200 - let modifierParts = parts.dropLast(baseLength) 201 - var modifierSet = Set<KeyModifier>() 202 - for modifierRaw in modifierParts { 203 - guard let modifier = KeyModifier.resolve(modifierRaw), modifierSet.insert(modifier).inserted else { 204 - return nil 205 - } 206 - } 258 + guard let modifiers = modifiers(from: parts.dropLast(baseLength)) else { return nil } 207 259 208 - let modifiers = KeyModifier.canonicalOrder.filter { modifierSet.contains($0) } 209 260 let normalized = (modifiers.map(\.rawValue) + [base.canonical]).joined(separator: "-") 210 - let category = category(for: base, modifiers: modifiers) 211 261 return KeyTokenDescriptor( 212 262 normalized: normalized, 213 263 baseToken: base.canonical, 214 264 modifiers: modifiers, 215 - category: category 265 + category: category(for: base, modifiers: modifiers) 216 266 ) 217 267 } 218 268 219 269 return nil 220 270 } 221 271 272 + private static func modifiers(from parts: ArraySlice<String>) -> [KeyModifier]? { 273 + var modifierSet = Set<KeyModifier>() 274 + for modifierRaw in parts { 275 + guard let modifier = KeyModifier.resolve(modifierRaw), modifierSet.insert(modifier).inserted else { 276 + return nil 277 + } 278 + } 279 + 280 + return KeyModifier.canonicalOrder.filter { modifierSet.contains($0) } 281 + } 282 + 222 283 private static func category(for base: KeyBaseDescriptor, modifiers: [KeyModifier]) -> KeyCategory { 223 284 guard !modifiers.isEmpty else { return base.category } 224 285 if modifiers == [.ctrl] { ··· 228 289 } 229 290 230 291 private static func baseDescriptor(for raw: String) -> KeyBaseDescriptor? { 231 - switch raw { 232 - case "enter", "return": 233 - return KeyBaseDescriptor(canonical: "enter", category: .editing) 234 - case "esc", "escape": 235 - return KeyBaseDescriptor(canonical: "esc", category: .control) 236 - case "tab": 237 - return KeyBaseDescriptor(canonical: "tab", category: .navigation) 238 - case "backspace", "delete", "del": 239 - return KeyBaseDescriptor(canonical: "backspace", category: .editing) 240 - case "delete-forward", "forward-delete", "deleteforward", "forwarddelete": 241 - return KeyBaseDescriptor(canonical: "delete-forward", category: .editing) 242 - case "insert", "ins": 243 - return KeyBaseDescriptor(canonical: "insert", category: .editing) 244 - case "up", "arrow-up": 245 - return KeyBaseDescriptor(canonical: "up", category: .navigation) 246 - case "down", "arrow-down": 247 - return KeyBaseDescriptor(canonical: "down", category: .navigation) 248 - case "left", "arrow-left": 249 - return KeyBaseDescriptor(canonical: "left", category: .navigation) 250 - case "right", "arrow-right": 251 - return KeyBaseDescriptor(canonical: "right", category: .navigation) 252 - case "pageup", "page-up", "pgup": 253 - return KeyBaseDescriptor(canonical: "pageup", category: .navigation) 254 - case "pagedown", "page-down", "pgdn": 255 - return KeyBaseDescriptor(canonical: "pagedown", category: .navigation) 256 - case "home": 257 - return KeyBaseDescriptor(canonical: "home", category: .navigation) 258 - case "end": 259 - return KeyBaseDescriptor(canonical: "end", category: .navigation) 260 - case "space": 261 - return KeyBaseDescriptor(canonical: "space", category: .editing) 262 - case "minus", "hyphen", "dash": 263 - return KeyBaseDescriptor(canonical: "minus", category: .editing) 264 - case "equal", "equals": 265 - return KeyBaseDescriptor(canonical: "equal", category: .editing) 266 - case "comma": 267 - return KeyBaseDescriptor(canonical: "comma", category: .editing) 268 - case "period", "dot": 269 - return KeyBaseDescriptor(canonical: "period", category: .editing) 270 - case "slash": 271 - return KeyBaseDescriptor(canonical: "slash", category: .editing) 272 - case "backslash": 273 - return KeyBaseDescriptor(canonical: "backslash", category: .editing) 274 - case "semicolon": 275 - return KeyBaseDescriptor(canonical: "semicolon", category: .editing) 276 - case "quote", "apostrophe": 277 - return KeyBaseDescriptor(canonical: "quote", category: .editing) 278 - case "grave", "backtick": 279 - return KeyBaseDescriptor(canonical: "grave", category: .editing) 280 - case "left-bracket", "leftbracket", "lbracket": 281 - return KeyBaseDescriptor(canonical: "[", category: .editing) 282 - case "right-bracket", "rightbracket", "rbracket": 283 - return KeyBaseDescriptor(canonical: "]", category: .editing) 284 - default: 285 - break 286 - } 292 + if let base = namedBaseDescriptors[raw] { return base } 287 293 288 294 if raw.count == 1, let scalar = raw.unicodeScalars.first, scalar.isASCII, !scalar.properties.isWhitespace { 289 295 return KeyBaseDescriptor(canonical: raw, category: .editing)
+124 -82
supacode/Infrastructure/Ghostty/GhosttySurfaceView.swift
··· 1915 1915 } 1916 1916 1917 1917 private static let namedBaseSpecs: [String: BaseSpec] = [ 1918 - "enter": BaseSpec(keyCode: UInt16(kVK_Return), charactersIgnoringModifiers: "\r", usesFunctionModifier: false), 1919 - "esc": BaseSpec(keyCode: UInt16(kVK_Escape), charactersIgnoringModifiers: "\u{1B}", usesFunctionModifier: false), 1920 - "tab": BaseSpec(keyCode: UInt16(kVK_Tab), charactersIgnoringModifiers: "\t", usesFunctionModifier: false), 1921 - "backspace": BaseSpec(keyCode: UInt16(kVK_Delete), charactersIgnoringModifiers: "\u{7F}", usesFunctionModifier: false), 1918 + "enter": BaseSpec( 1919 + keyCode: UInt16(kVK_Return), 1920 + charactersIgnoringModifiers: "\r", 1921 + usesFunctionModifier: false 1922 + ), 1923 + "esc": BaseSpec( 1924 + keyCode: UInt16(kVK_Escape), 1925 + charactersIgnoringModifiers: "\u{1B}", 1926 + usesFunctionModifier: false 1927 + ), 1928 + "tab": BaseSpec( 1929 + keyCode: UInt16(kVK_Tab), 1930 + charactersIgnoringModifiers: "\t", 1931 + usesFunctionModifier: false 1932 + ), 1933 + "backspace": BaseSpec( 1934 + keyCode: UInt16(kVK_Delete), 1935 + charactersIgnoringModifiers: "\u{7F}", 1936 + usesFunctionModifier: false 1937 + ), 1922 1938 "delete-forward": BaseSpec( 1923 1939 keyCode: UInt16(kVK_ForwardDelete), 1924 1940 charactersIgnoringModifiers: String(UnicodeScalar(NSDeleteFunctionKey)!), ··· 1986 2002 "f12": (UInt16(kVK_F12), NSF12FunctionKey), 1987 2003 ] 1988 2004 2005 + private static let printableKeyCodes: [String: UInt16] = [ 2006 + "a": UInt16(kVK_ANSI_A), 2007 + "b": UInt16(kVK_ANSI_B), 2008 + "c": UInt16(kVK_ANSI_C), 2009 + "d": UInt16(kVK_ANSI_D), 2010 + "e": UInt16(kVK_ANSI_E), 2011 + "f": UInt16(kVK_ANSI_F), 2012 + "g": UInt16(kVK_ANSI_G), 2013 + "h": UInt16(kVK_ANSI_H), 2014 + "i": UInt16(kVK_ANSI_I), 2015 + "j": UInt16(kVK_ANSI_J), 2016 + "k": UInt16(kVK_ANSI_K), 2017 + "l": UInt16(kVK_ANSI_L), 2018 + "m": UInt16(kVK_ANSI_M), 2019 + "n": UInt16(kVK_ANSI_N), 2020 + "o": UInt16(kVK_ANSI_O), 2021 + "p": UInt16(kVK_ANSI_P), 2022 + "q": UInt16(kVK_ANSI_Q), 2023 + "r": UInt16(kVK_ANSI_R), 2024 + "s": UInt16(kVK_ANSI_S), 2025 + "t": UInt16(kVK_ANSI_T), 2026 + "u": UInt16(kVK_ANSI_U), 2027 + "v": UInt16(kVK_ANSI_V), 2028 + "w": UInt16(kVK_ANSI_W), 2029 + "x": UInt16(kVK_ANSI_X), 2030 + "y": UInt16(kVK_ANSI_Y), 2031 + "z": UInt16(kVK_ANSI_Z), 2032 + "0": UInt16(kVK_ANSI_0), 2033 + "1": UInt16(kVK_ANSI_1), 2034 + "2": UInt16(kVK_ANSI_2), 2035 + "3": UInt16(kVK_ANSI_3), 2036 + "4": UInt16(kVK_ANSI_4), 2037 + "5": UInt16(kVK_ANSI_5), 2038 + "6": UInt16(kVK_ANSI_6), 2039 + "7": UInt16(kVK_ANSI_7), 2040 + "8": UInt16(kVK_ANSI_8), 2041 + "9": UInt16(kVK_ANSI_9), 2042 + "space": UInt16(kVK_Space), 2043 + "minus": UInt16(kVK_ANSI_Minus), 2044 + "equal": UInt16(kVK_ANSI_Equal), 2045 + ",": UInt16(kVK_ANSI_Comma), 2046 + "comma": UInt16(kVK_ANSI_Comma), 2047 + ".": UInt16(kVK_ANSI_Period), 2048 + "period": UInt16(kVK_ANSI_Period), 2049 + "/": UInt16(kVK_ANSI_Slash), 2050 + "slash": UInt16(kVK_ANSI_Slash), 2051 + "\\": UInt16(kVK_ANSI_Backslash), 2052 + "backslash": UInt16(kVK_ANSI_Backslash), 2053 + ";": UInt16(kVK_ANSI_Semicolon), 2054 + "semicolon": UInt16(kVK_ANSI_Semicolon), 2055 + "'": UInt16(kVK_ANSI_Quote), 2056 + "quote": UInt16(kVK_ANSI_Quote), 2057 + "`": UInt16(kVK_ANSI_Grave), 2058 + "grave": UInt16(kVK_ANSI_Grave), 2059 + "[": UInt16(kVK_ANSI_LeftBracket), 2060 + "]": UInt16(kVK_ANSI_RightBracket), 2061 + ] 2062 + 2063 + private static let shiftedCharacterMap: [String: String] = [ 2064 + "1": "!", 2065 + "2": "@", 2066 + "3": "#", 2067 + "4": "$", 2068 + "5": "%", 2069 + "6": "^", 2070 + "7": "&", 2071 + "8": "*", 2072 + "9": "(", 2073 + "0": ")", 2074 + "minus": "_", 2075 + "equal": "+", 2076 + ",": "<", 2077 + "comma": "<", 2078 + ".": ">", 2079 + "period": ">", 2080 + "/": "?", 2081 + "slash": "?", 2082 + "\\": "|", 2083 + "backslash": "|", 2084 + ";": ":", 2085 + "semicolon": ":", 2086 + "'": "\"", 2087 + "quote": "\"", 2088 + "`": "~", 2089 + "[": "{", 2090 + "]": "}", 2091 + ] 2092 + 1989 2093 private static func eventModifiers(from modifiers: [KeyModifier]) -> NSEvent.ModifierFlags { 1990 2094 modifiers.reduce(into: NSEvent.ModifierFlags()) { result, modifier in 1991 2095 switch modifier { ··· 2000 2104 private static func baseSpec(for token: String) -> BaseSpec? { 2001 2105 if let base = namedBaseSpecs[token] { return base } 2002 2106 if let (keyCode, scalar) = functionKeyMap[token] { 2003 - return BaseSpec(keyCode: keyCode, charactersIgnoringModifiers: String(UnicodeScalar(scalar)!), usesFunctionModifier: true) 2107 + return BaseSpec( 2108 + keyCode: keyCode, 2109 + charactersIgnoringModifiers: String(UnicodeScalar(scalar)!), 2110 + usesFunctionModifier: true 2111 + ) 2004 2112 } 2005 2113 return printableBaseSpec(for: token) 2006 2114 } 2007 2115 2008 2116 private static func printableBaseSpec(for token: String) -> BaseSpec? { 2009 - guard let character = printableCharacter(for: token), let keyCode = printableKeyCode(for: token) else { return nil } 2010 - return BaseSpec(keyCode: keyCode, charactersIgnoringModifiers: String(character), usesFunctionModifier: false) 2117 + guard let character = printableCharacter(for: token), 2118 + let keyCode = printableKeyCode(for: token) 2119 + else { return nil } 2120 + 2121 + return BaseSpec( 2122 + keyCode: keyCode, 2123 + charactersIgnoringModifiers: String(character), 2124 + usesFunctionModifier: false 2125 + ) 2011 2126 } 2012 2127 2013 2128 private static func printableCharacter(for token: String) -> Character? { ··· 2029 2144 } 2030 2145 2031 2146 private static func printableKeyCode(for token: String) -> UInt16? { 2032 - switch token { 2033 - case "a": return UInt16(kVK_ANSI_A) 2034 - case "b": return UInt16(kVK_ANSI_B) 2035 - case "c": return UInt16(kVK_ANSI_C) 2036 - case "d": return UInt16(kVK_ANSI_D) 2037 - case "e": return UInt16(kVK_ANSI_E) 2038 - case "f": return UInt16(kVK_ANSI_F) 2039 - case "g": return UInt16(kVK_ANSI_G) 2040 - case "h": return UInt16(kVK_ANSI_H) 2041 - case "i": return UInt16(kVK_ANSI_I) 2042 - case "j": return UInt16(kVK_ANSI_J) 2043 - case "k": return UInt16(kVK_ANSI_K) 2044 - case "l": return UInt16(kVK_ANSI_L) 2045 - case "m": return UInt16(kVK_ANSI_M) 2046 - case "n": return UInt16(kVK_ANSI_N) 2047 - case "o": return UInt16(kVK_ANSI_O) 2048 - case "p": return UInt16(kVK_ANSI_P) 2049 - case "q": return UInt16(kVK_ANSI_Q) 2050 - case "r": return UInt16(kVK_ANSI_R) 2051 - case "s": return UInt16(kVK_ANSI_S) 2052 - case "t": return UInt16(kVK_ANSI_T) 2053 - case "u": return UInt16(kVK_ANSI_U) 2054 - case "v": return UInt16(kVK_ANSI_V) 2055 - case "w": return UInt16(kVK_ANSI_W) 2056 - case "x": return UInt16(kVK_ANSI_X) 2057 - case "y": return UInt16(kVK_ANSI_Y) 2058 - case "z": return UInt16(kVK_ANSI_Z) 2059 - case "0": return UInt16(kVK_ANSI_0) 2060 - case "1": return UInt16(kVK_ANSI_1) 2061 - case "2": return UInt16(kVK_ANSI_2) 2062 - case "3": return UInt16(kVK_ANSI_3) 2063 - case "4": return UInt16(kVK_ANSI_4) 2064 - case "5": return UInt16(kVK_ANSI_5) 2065 - case "6": return UInt16(kVK_ANSI_6) 2066 - case "7": return UInt16(kVK_ANSI_7) 2067 - case "8": return UInt16(kVK_ANSI_8) 2068 - case "9": return UInt16(kVK_ANSI_9) 2069 - case "space": return UInt16(kVK_Space) 2070 - case "minus": return UInt16(kVK_ANSI_Minus) 2071 - case "equal": return UInt16(kVK_ANSI_Equal) 2072 - case ",", "comma": return UInt16(kVK_ANSI_Comma) 2073 - case ".", "period": return UInt16(kVK_ANSI_Period) 2074 - case "/", "slash": return UInt16(kVK_ANSI_Slash) 2075 - case "\\", "backslash": return UInt16(kVK_ANSI_Backslash) 2076 - case ";", "semicolon": return UInt16(kVK_ANSI_Semicolon) 2077 - case "'", "quote": return UInt16(kVK_ANSI_Quote) 2078 - case "`", "grave": return UInt16(kVK_ANSI_Grave) 2079 - case "[": return UInt16(kVK_ANSI_LeftBracket) 2080 - case "]": return UInt16(kVK_ANSI_RightBracket) 2081 - default: return nil 2082 - } 2147 + printableKeyCodes[token] 2083 2148 } 2084 2149 2085 2150 private static func shiftedCharacters(for token: String) -> String? { ··· 2087 2152 return String(character).uppercased() 2088 2153 } 2089 2154 2090 - switch token { 2091 - case "1": return "!" 2092 - case "2": return "@" 2093 - case "3": return "#" 2094 - case "4": return "$" 2095 - case "5": return "%" 2096 - case "6": return "^" 2097 - case "7": return "&" 2098 - case "8": return "*" 2099 - case "9": return "(" 2100 - case "0": return ")" 2101 - case "minus": return "_" 2102 - case "equal": return "+" 2103 - case ",", "comma": return "<" 2104 - case ".", "period": return ">" 2105 - case "/", "slash": return "?" 2106 - case "\\", "backslash": return "|" 2107 - case ";", "semicolon": return ":" 2108 - case "'", "quote": return "\"" 2109 - case "`", "grave": return "~" 2110 - case "[": return "{" 2111 - case "]": return "}" 2112 - default: return nil 2113 - } 2155 + return shiftedCharacterMap[token] 2114 2156 } 2115 2157 2116 2158 private static func controlCharacter(for token: String) -> String? {