Implementing commands turns out to involve some thinking about fundamentals.
First there are keystrokes. If you're going crossplatform, there's actually a lot of craziness under the hood in getting keystrokes. Getting a consistent return value when the user presses a key, across variables of locale, operating system, keyboard mapping, function keys, characters, curses implementations, (especially wide or unicode curses), network connections (telnet/ssh remap some keys) etc, turns out to be surprisingly hard. And it creates alias groups. For example, the KEY_ENTER function key code, the newline character, the carriage return character, and the carriage return/linefeed combo are all possible returns when someone presses the "enter" key depending on various craziness. You want your Input_GetKeystroke function to return exactly one of these things and you want to prevent commands from ever getting bound to any of the others. So there needs to be an abstraction layer over keystrokes.
While you're abstracting over keystrokes, you want to give each key a human-readable name which you can use in your help system. For ordinary graphical characters, you can use the character as the name. But beyond that it gets harder. Curses provides names for function keys, but they're not suitable for interfaces intended to be used by the public, nor do they localize with language settings. Then you have nongraphical characters, such as tab, backspace, space, and return. Some of these are part of alias groups, but some (such as tab) are not. So you have to be able to give each key or alias group a name that tells the user how to enter it.
Okay, now you have to make a decision. Is a command just a code path, or can it be stored in data? I recommend going with the data option. That gives you the ability to create a set of menus, and switch menus with a single command. It also means the help subsystem can just "read" the keystrokes and commands out of the current menu, so it'll never ever get out of synch. So, you find a way to represent the command (maybe an integer, maybe a code pointer plus parameters) then you build menus, which are sets of keystroke-to-command bindings, then you implement context-sensitive menu switching.
Then you decide your key-to-command mappings. There are four interesting cases to cater for right out of the box. Numpad movement, wasd movement, vikey movement, and arrow-only movement are all popular, and their partisans are fiercely opposed to switching. If you abstracted menus (that is, commands-as-data and sets of command bindings) you can support all four. Let the game come up in your preferred mode, and then have a command for the user to just switch to the other modes.
Maybe you want to include a way for the user to make his own mappings, or maybe you put that off for the next version. If you do include a way to remap it, you have to make sure that commands can't get "lost" or become impossible for the user to refer to.
Or maybe you're making a 7drl, in which case you just let yourself be satisfied with a switch statement. :-)