One of the many issues facing the development of a complex software product like Binary Ninja is discoverability. In UX design, a feature is “discoverable” if a user is able to locate that feature, understand what they can do with it, and use it to accomplish their goal.
There are many ways of solving this problem, but our favorite is the Command Palette. Unfortunately, the Command Palette itself has a bit of a discoverability problem. So, today, we’re going to show it off a bit and explain why you should consider spending more time using it.
The Command Palette is, essentially, a search function for available actions. Many users will immediately recognize this as a feature from other software, like Visual Studio Code. Ours works the same way.
Anything a user might want to do through the UI can be registered as an “action”. Actions can range from changing the type of a function (which we’ve bound to the y
hotkey while a function name is selected and an entry on the right-click menu on a function name) or opening the Plugin Manager (which is in the menu under Plugins -> Manage Plugins
or the hotkey Ctrl-Shift-M
/Cmd-Shift-M
). They’re a fundamental part of interacting with the UI.
There’s also an action for launching the command palette, which is Ctrl-P
(or Cmd-P
for us enlightened macOS users). It’s also available under the View -> Command Palette
menu.
In case it isn’t immediately obvious: Being able to search for any action within Binary Ninja is pretty powerful. You don’t need to remember where it is within menus or which button to click or which hotkey to use. You just need to have a vague idea of what word(s) are part of the action’s name. (Searching is fuzzy as well, so you don’t have to be exact.)
This makes it a great option for new users trying to figure out what features are available. If it’s something you can use, it’s probably in the Command Palette. It’s also a great option for experienced users since it’s often faster to reach a particular command via the keyboard, especially if it doesn’t have a hotkey. If it does have a hotkey, the Command Palette will show you what it is currently bound to.
One of the primary selling points of Binary Ninja is our API. Since our entire UI is, itself, a big plugin, we’ve exposed a lot of the things plugin authors might need to make more specialized tooling to fit their needs.
In the case of registering actions with the Command Palette, it’s very easy. Take a look at this example I’ve simplified from our Tanto plugin, written in Python:
# You'll need to add these imports to use the action system
from binaryninjaui import Menu, UIAction, UIActionHandler, UIActionContext
# This function will need to be called from your plugin to add your actions
def add_actions():
# Register an action with the name "My Action" in the namespace "My Plugin"
UIAction.registerAction(f"My Plugin\\My Action")
# Bind the action to the my_plugin_action handler
UIActionHandler.globalActions().bindAction(f"My Plugin\\My Action", UIAction(my_plugin_action()))
# Add the action to the "Plugins" section of the main menu
# This will be placed in the "MyPluginGroup" group at the first position
Menu.mainMenu("Plugins").addAction(f"My Plugin\\My Action", "MyPluginGroup", 0)
We also support this from C++, where you would do the following instead:
#include <action.h>
auto actionName = QString("My Plugin\\My Action");
auto windowMenu = Menu::mainMenu("Plugins");
UIAction::registerAction(actionName);
globalActions()->bindAction(actionName, UIAction([=]() { my_plugin_action();}));
windowMenu->addAction(actionName, "MyPluginGroup", 0);
If you want to see some other ways you can mess with actions in the UI, check out this earlier blog post.