27 @"@.":
@"cancelOperation:",
30 @"^a":
@"moveToBeginningOfParagraph:",
31 @"^$a":
@"moveToBeginningOfParagraphAndModifySelection:",
32 @"^b":
@"moveBackward:",
33 @"^$b":
@"moveBackwardAndModifySelection:",
34 @"^~b":
@"moveWordBackward:",
35 @"^~$b":
@"moveWordBackwardAndModifySelection:",
36 @"^d":
@"deleteForward:",
37 @"^e":
@"moveToEndOfParagraph:",
38 @"^$e":
@"moveToEndOfParagraphAndModifySelection:",
39 @"^f":
@"moveForward:",
40 @"^$f":
@"moveForwardAndModifySelection:",
41 @"^~f":
@"moveWordForward:",
42 @"^~$f":
@"moveWordForwardAndModifySelection:",
43 @"^h":
@"deleteBackward:",
44 @"^k":
@"deleteToEndOfParagraph:",
45 @"^l":
@"centerSelectionInVisibleArea:",
47 @"^$n":
@"moveDownAndModifySelection:",
48 @"^o": [
@"insertNewlineIgnoringFieldEditor:",
@"moveBackward:"],
50 @"^$p":
@"moveUpAndModifySelection:",
53 @"^$v":
@"pageDownAndModifySelection:",
71 CPStandardKeyBindings[@"~" + CPDeleteCharacter] = @"deleteWordBackward:";
72 CPStandardKeyBindings[@"^" + CPDeleteCharacter] = @"deleteBackwardByDecomposingPreviousCharacter:";
73 CPStandardKeyBindings[@"^~" + CPDeleteCharacter] = @"deleteWordBackward:";
75 CPStandardKeyBindings[CPDeleteFunctionKey] = @"deleteForward:";
76 CPStandardKeyBindings[@"~" + CPDeleteFunctionKey] = @"deleteWordForward:";
78 CPStandardKeyBindings[CPTabCharacter] = @"insertTab:";
79 CPStandardKeyBindings[@"~" + CPTabCharacter] = @"insertTabIgnoringFieldEditor:";
80 CPStandardKeyBindings[@"^" + CPTabCharacter] = @"selectNextKeyView:";
81 CPStandardKeyBindings[CPBackTabCharacter] = @"insertBacktab:";
82 CPStandardKeyBindings[@"^" + CPBackTabCharacter] = @"selectPreviousKeyView:";
84 CPStandardKeyBindings[CPEscapeFunctionKey] = @"cancelOperation:";
85 CPStandardKeyBindings[@"~" + CPEscapeFunctionKey] = @"complete:";
86 CPStandardKeyBindings[CPF5FunctionKey] = @"complete:";
88 CPStandardKeyBindings[CPLeftArrowFunctionKey] = @"moveLeft:";
89 CPStandardKeyBindings[@"~" + CPLeftArrowFunctionKey] = @"moveWordLeft:";
90 CPStandardKeyBindings[@"^" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLine:";
91 CPStandardKeyBindings[@"
@" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLine:";
92 CPStandardKeyBindings[@"$" + CPLeftArrowFunctionKey] = @"moveLeftAndModifySelection:";
93 CPStandardKeyBindings[@"$~" + CPLeftArrowFunctionKey] = @"moveWordLeftAndModifySelection:";
94 CPStandardKeyBindings[@"$^" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLineAndModifySelection:";
95 CPStandardKeyBindings[@"$@" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLineAndModifySelection:";
96 CPStandardKeyBindings[@"@^" + CPLeftArrowFunctionKey] = @"makeBaseWritingDirectionRightToLeft:";
97 CPStandardKeyBindings[@"@^~" + CPLeftArrowFunctionKey] = @"makeTextWritingDirectionRightToLeft:";
99 CPStandardKeyBindings[CPRightArrowFunctionKey] = @"moveRight:";
100 CPStandardKeyBindings[@"~" + CPRightArrowFunctionKey] = @"moveWordRight:";
101 CPStandardKeyBindings[@"^" + CPRightArrowFunctionKey] = @"moveToRightEndOfLine:";
102 CPStandardKeyBindings[@"
@" + CPRightArrowFunctionKey] = @"moveToRightEndOfLine:";
103 CPStandardKeyBindings[@"$" + CPRightArrowFunctionKey] = @"moveRightAndModifySelection:";
104 CPStandardKeyBindings[@"$~" + CPRightArrowFunctionKey] = @"moveWordRightAndModifySelection:";
105 CPStandardKeyBindings[@"$^" + CPRightArrowFunctionKey] = @"moveToRightEndOfLineAndModifySelection:";
106 CPStandardKeyBindings[@"$@" + CPRightArrowFunctionKey] = @"moveToRightEndOfLineAndModifySelection:";
107 CPStandardKeyBindings[@"@^" + CPRightArrowFunctionKey] = @"makeBaseWritingDirectionLeftToRight:";
108 CPStandardKeyBindings[@"@^~" + CPRightArrowFunctionKey] = @"makeTextWritingDirectionLeftToRight:";
110 CPStandardKeyBindings[CPUpArrowFunctionKey] = @"moveUp:";
111 CPStandardKeyBindings[@"~" + CPUpArrowFunctionKey] = [@"moveBackward:", @"moveToBeginningOfParagraph:"];
112 CPStandardKeyBindings[@"^" + CPUpArrowFunctionKey] = @"scrollPageUp:";
113 CPStandardKeyBindings[@"
@" + CPUpArrowFunctionKey] = @"moveToBeginningOfDocument:";
114 CPStandardKeyBindings[@"$" + CPUpArrowFunctionKey] = @"moveUpAndModifySelection:";
115 CPStandardKeyBindings[@"$~" + CPUpArrowFunctionKey] = @"moveParagraphBackwardAndModifySelection:";
116 CPStandardKeyBindings[@"$@" + CPUpArrowFunctionKey] = @"moveToBeginningOfDocumentAndModifySelection:";
118 CPStandardKeyBindings[CPDownArrowFunctionKey] = @"moveDown:";
119 CPStandardKeyBindings[@"~" + CPDownArrowFunctionKey] = [@"moveForward:", @"moveToEndOfParagraph:"];
120 CPStandardKeyBindings[@"^" + CPDownArrowFunctionKey] = @"scrollPageDown:";
121 CPStandardKeyBindings[@"
@" + CPDownArrowFunctionKey] = @"moveToEndOfDocument:";
122 CPStandardKeyBindings[@"$" + CPDownArrowFunctionKey] = @"moveDownAndModifySelection:";
123 CPStandardKeyBindings[@"$~" + CPDownArrowFunctionKey] = @"moveParagraphForwardAndModifySelection:";
124 CPStandardKeyBindings[@"$@" + CPDownArrowFunctionKey] = @"moveToEndOfDocumentAndModifySelection:";
125 CPStandardKeyBindings[@"@^" + CPDownArrowFunctionKey] = @"makeBaseWritingDirectionNatural:";
126 CPStandardKeyBindings[@"@^~" + CPDownArrowFunctionKey] = @"makeTextWritingDirectionNatural:";
128 CPStandardKeyBindings[CPHomeFunctionKey] = @"scrollToBeginningOfDocument:";
129 CPStandardKeyBindings[@"$" + CPHomeFunctionKey] = @"moveToBeginningOfDocumentAndModifySelection:";
130 CPStandardKeyBindings[CPEndFunctionKey] = @"scrollToEndOfDocument:";
131 CPStandardKeyBindings[@"$" + CPEndFunctionKey] = @"moveToEndOfDocumentAndModifySelection:";
133 CPStandardKeyBindings[CPPageUpFunctionKey] = @"scrollPageUp:";
134 CPStandardKeyBindings[@"~" + CPPageUpFunctionKey] = @"pageUp:";
135 CPStandardKeyBindings[@"$" + CPPageUpFunctionKey] = @"pageUpAndModifySelection:";
136 CPStandardKeyBindings[CPPageDownFunctionKey] = @"scrollPageDown:";
137 CPStandardKeyBindings[@"~" + CPPageDownFunctionKey] = @"pageDown:";
138 CPStandardKeyBindings[@"$" + CPPageDownFunctionKey] = @"pageDownAndModifySelection:";
140 var CPKeyBindingCache = {};
142 @implementation CPKeyBinding : CPObject
145 unsigned _modifierFlags;
154 if (self !== [CPKeyBinding class])
157 [self createKeyBindingsFromJSObject:CPStandardKeyBindings];
160 + (void)createKeyBindingsFromJSObject:(JSObject)anObject
163 for (binding in anObject)
164 [self cacheKeyBinding:[[CPKeyBinding alloc] initWithPhysicalKeyString:binding selectors:anObject[binding]]];
167 + (void)cacheKeyBinding:(CPKeyBinding)aBinding
172 CPKeyBindingCache[[aBinding _cacheName]] = aBinding;
175 + (CPKeyBinding)keyBindingForKey:(CPString)aKey modifierFlags:(unsigned)aFlag
177 var tempBinding = [[self alloc] initWithKey:aKey modifierFlags:aFlag selectors:nil];
178 return CPKeyBindingCache[[tempBinding _cacheName]];
181 + (CPArray)selectorsForKey:(CPString)aKey modifierFlags:(unsigned)aFlag
183 return [[self keyBindingForKey:aKey modifierFlags:aFlag] selectors];
186 - (id)initWithPhysicalKeyString:(CPString)binding selectors:(CPArray)selectors
188 var components = binding.split(@""),
189 modifierFlags = ([components containsObject:@"$"] ? CPShiftKeyMask : 0) |
190 ([components containsObject:@"^"] ? CPControlKeyMask : 0) |
191 ([components containsObject:@"~"] ? CPAlternateKeyMask : 0) |
192 ([components containsObject:@"
@"] ? CPCommandKeyMask : 0);
194 if (![selectors isKindOfClass:CPArray])
195 selectors = [selectors];
197 return [self initWithKey:[components lastObject] modifierFlags:modifierFlags selectors:selectors];
200 - (id)initWithKey:(CPString)aKey modifierFlags:(unsigned)aFlag selectors:(CPArray)selectors
207 _modifierFlags = aFlag;
209 _selectors = selectors;
211 // We normalize our key binding string in order to properly cache it.
212 // We want to ensure the modifiers are always in the same order.
215 if (_modifierFlags & CPCommandKeyMask)
216 cacheName.push(@"@");
217 if (_modifierFlags & CPControlKeyMask)
218 cacheName.push(@"^");
219 if (_modifierFlags & CPAlternateKeyMask)
220 cacheName.push(@"~");
221 if (_modifierFlags & CPShiftKeyMask)
222 cacheName.push(@"$");
224 cacheName.push(_key);
226 _cacheName = cacheName.join(@"");
237 - (unsigned)modifierFlags
239 return _modifierFlags;
247 - (CPString)_cacheName
252 - (BOOL)isEqual:(CPKeyBinding)rhs
254 return _key === [rhs key] && _modifierFlags === [rhs modifierFlags];
257 - (CPString)description
259 return [CPString stringWithFormat:@"<KeyBinding string: '%@' modifierFlags: 0x%lx selectors: %@>", _key, _modifierFlags, _selectors];