@@ -63,6 +63,25 @@ class CliMenu
6363 */
6464 protected $ parent ;
6565
66+ /**
67+ * @var array
68+ */
69+ protected $ defaultControlMappings = [
70+ '^P ' => InputCharacter::UP ,
71+ 'k ' => InputCharacter::UP ,
72+ '^K ' => InputCharacter::DOWN ,
73+ 'j ' => InputCharacter::DOWN ,
74+ "\r" => InputCharacter::ENTER ,
75+ ' ' => InputCharacter::ENTER ,
76+ 'l ' => InputCharacter::LEFT ,
77+ 'm ' => InputCharacter::RIGHT ,
78+ ];
79+
80+ /**
81+ * @var array
82+ */
83+ protected $ customControlMappings = [];
84+
6685 /**
6786 * @var Frame
6887 */
@@ -156,6 +175,30 @@ private function selectFirstItem() : void
156175 }
157176 }
158177
178+ /**
179+ * Adds a custom control mapping
180+ */
181+ public function addCustomControlMapping (string $ input , callable $ callable ) : void
182+ {
183+ if (isset ($ this ->defaultControlMappings [$ input ]) || isset ($ this ->customControlMappings [$ input ])) {
184+ throw new \InvalidArgumentException ('Cannot rebind this input. ' );
185+ }
186+
187+ $ this ->customControlMappings [$ input ] = $ callable ;
188+ }
189+
190+ /**
191+ * Removes a custom control mapping
192+ */
193+ public function removeCustomControlMapping (string $ input ) : void
194+ {
195+ if (!isset ($ this ->customControlMappings [$ input ])) {
196+ throw new \InvalidArgumentException ('This input is not registered. ' );
197+ }
198+
199+ unset($ this ->customControlMappings [$ input ]);
200+ }
201+
159202 /**
160203 * Display menu and capture input
161204 */
@@ -164,17 +207,14 @@ private function display() : void
164207 $ this ->draw ();
165208
166209 $ reader = new NonCanonicalReader ($ this ->terminal );
167- $ reader ->addControlMappings ([
168- '^P ' => InputCharacter::UP ,
169- 'k ' => InputCharacter::UP ,
170- '^K ' => InputCharacter::DOWN ,
171- 'j ' => InputCharacter::DOWN ,
172- "\r" => InputCharacter::ENTER ,
173- ' ' => InputCharacter::ENTER ,
174- ]);
210+ $ reader ->addControlMappings ($ this ->defaultControlMappings );
175211
176212 while ($ this ->isOpen () && $ char = $ reader ->readCharacter ()) {
177213 if (!$ char ->isHandledControl ()) {
214+ $ rawChar = $ char ->get ();
215+ if (isset ($ this ->customControlMappings [$ rawChar ])) {
216+ $ this ->customControlMappings [$ rawChar ]($ this );
217+ }
178218 continue ;
179219 }
180220
0 commit comments