diff --git a/src/Gui/CommandPy.xml b/src/Gui/CommandPy.xml
index a67df25b8f..0556da17f3 100644
--- a/src/Gui/CommandPy.xml
+++ b/src/Gui/CommandPy.xml
@@ -117,5 +117,15 @@ Returns True if something was removed, or False if not.
+
+
+ Find the name of a custom command, given a macro name
+findCustomCommand(name) -> Optional[str]
+--
+Given the name of a macro, return the name of the custom command for that macro, or
+None if there is no command matching that macro script name.
+
+
+
diff --git a/src/Gui/CommandPyImp.cpp b/src/Gui/CommandPyImp.cpp
index b223a5c8d2..f40a292bea 100644
--- a/src/Gui/CommandPyImp.cpp
+++ b/src/Gui/CommandPyImp.cpp
@@ -384,6 +384,31 @@ PyObject* CommandPy::removeCustomCommand(PyObject* args)
}
}
+PyObject* CommandPy::findCustomCommand(PyObject* args)
+{
+ const char* macroScriptName = nullptr;
+ if (!PyArg_ParseTuple(args, "s", ¯oScriptName))
+ return nullptr;
+
+ CommandManager& commandManager = Application::Instance->commandManager();
+ std::vector macros = commandManager.getGroupCommands("Macros");
+
+ auto action = std::find_if(macros.begin(), macros.end(), [macroScriptName](const Command* c) {
+ if (auto mc = dynamic_cast(c))
+ if (std::string(mc->getScriptName()) == std::string(macroScriptName))
+ return true;
+ return false;
+ });
+
+ if (action != macros.end()) {
+ return PyUnicode_FromString((*action)->getName());
+ }
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
PyObject *CommandPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;