Skip to content

How to Add a Shortcut / PyMOL Command

This guide explains how to register a new function as a PyMOL cmd.extend command, wrap it with a dialog popup, and add it to the REvoDesign Tools menu.

1. Write the function

Place your core logic in an existing or new file under REvoDesign.shortcuts.wrappers/ or REvoDesign.tools/. Keep it as a plain Python function that accepts keyword arguments:

# src/REvoDesign/shortcuts/wrappers/my_tool.py
def my_function(threshold: float = 0.5, pdb_path: str = "") -> None:
    """Do something useful."""
    # implementation...

2. Wrap with a dialog (optional)

If the function needs user input, create a YAML config in src/REvoDesign/shortcuts/registry/ that describes the input fields:

# src/REvoDesign/shortcuts/registry/my_tool.yaml
my_function:
  title: "My Tool"
  banner: "Describe what this tool does"
  options:
    - name: "threshold"
      type: float
      default: 0.5
      reason: "Score threshold for filtering"
    - name: "pdb_path"
      type: str
      default: ""
      reason: "Path to the PDB file"
      required: true
      source: File

Then create a wrapper module that registers the function with the dialog:

# src/REvoDesign/shortcuts/wrappers/my_tool.py
from REvoDesign.shortcuts.utils import DialogWrapperRegistry

registry = DialogWrapperRegistry("my_tool")  # matches registry/my_tool.yaml
wrapped_my_function = registry.register("my_function", my_function, use_thread=True)

The YAML name entries map to AskedValue fields:

YAML key AskedValue attr Description
name key Keyword argument name
type typing str, int, float, bool
default val Default value
reason reason Tooltip / help text
required required Whether the field is mandatory
choices choices Static list of options
choices_from (dynamic) See below
source source "None", "File", "Directory"
multiple_choices multiple_choices Allow multiple selections

Dynamic choices

For dropdowns populated at runtime, use choices_from:

- name: "model"
  type: str
  required: true
  choices_from: "REvoDesign.my.module:function_name"

This resolves the dotted string "REvoDesign.my.module:function_name" to a callable, invokes it, and uses the returned iterable as choices. Other supported prefixes:

Prefix Example Effect
range: range:1,10 or range:0,20,2 Integer range
FloatRange: FloatRange:0.1,1.0,0.1 Float range
CFG: CFG:ui.mutate.max_score Look up a config value
LAMBDA: LAMBDA:[1,2,3] Evaluate a Python expression

Options for registry.register()

Argument Default Description
use_thread False Run in background thread
has_dynamic_values False Accept dynamic input at call time
use_progressbar True Show progress bar in threaded mode

Manual dialog (without YAML)

For simple cases you can build the dialog directly with AskedValue and dialog_wrapper:

from REvoDesign.tools.customized_widgets import AskedValue, dialog_wrapper

@dialog_wrapper(
    title="My Tool",
    banner="Describe what this tool does",
    allow_real_time_update=False,
    options=(
        AskedValue("threshold", val=0.5, typing=float, reason="Score threshold"),
        AskedValue("pdb_path", val="", typing=str, reason="PDB file", required=True),
    ),
)
def my_function(threshold: float = 0.5, pdb_path: str = "") -> None:
    """Do something useful."""

3. Register as a PyMOL command

Open src/REvoDesign/shortcuts/__init__.py and add a cmd.extend call:

from pymol import cmd
from .wrappers.my_tool import wrapped_my_function

cmd.extend("my_command", wrapped_my_function)

Optionally add autocompletion hints:

cmd.auto_arg[0]["my_command"] = [
    cmd.auto_arg[0]["enable"][0],  # reuse existing shortcut
    "Target object",
    "",
]

4. Add to the Tools menu

Open src/REvoDesign/application/menu.py and add a MenuItem to TOOLS_MENU_LINKS:

from REvoDesign.basic.menu_item import MenuItem

TOOLS_MENU_LINKS = (
    # ... existing items ...
    MenuItem(
        "actionMyFunction",
        "REvoDesign.shortcuts.wrappers.my_tool:wrapped_my_function",
    ),
)

The first argument is a unique action name. The second is a dotted path to the wrapped function, using the module:attr format.

5. Test

Run cmd.extend registered commands from PyMOL's command line:

my_command threshold=0.8

For dialog-wrapped functions, the menu item or calling the wrapper directly opens the popup window. Verify with:

conda run -n REvoDesignTestFlight make kw-test PYTEST_KW="shortcut or dialog"