summaryrefslogtreecommitdiff
path: root/python/scriptingprovider.py
diff options
context:
space:
mode:
author0cyn <kat@vector35.com>2026-04-14 05:03:15 -0400
committerAlexander Taylor <alex@vector35.com>2026-05-18 14:55:52 -0400
commit297a98bff289ecde90d808f6538c2c5edf804af6 (patch)
tree4ca5f9868354cb26f7c6ef70140e4ed0f0395944 /python/scriptingprovider.py
parentf1a688a1e7fb6d962d8c9addaaefdfd59e5dd28b (diff)
Argument Assist Popup
Diffstat (limited to 'python/scriptingprovider.py')
-rw-r--r--python/scriptingprovider.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py
index 8a541422..b1f83ec4 100644
--- a/python/scriptingprovider.py
+++ b/python/scriptingprovider.py
@@ -152,6 +152,8 @@ class ScriptingInstance:
self._cb.setCurrentAddress = self._cb.setCurrentAddress.__class__(self._set_current_address)
self._cb.setCurrentSelection = self._cb.setCurrentSelection.__class__(self._set_current_selection)
self._cb.completeInput = self._cb.completeInput.__class__(self._complete_input)
+ self._cb.canCompleteArguments = self._cb.canCompleteArguments.__class__(self._can_complete_arguments)
+ self._cb.completeArguments = self._cb.completeArguments.__class__(self._complete_arguments)
self._cb.stop = self._cb.stop.__class__(self._stop)
self._completed_input = None
self.handle = core.BNInitScriptingInstance(provider.handle, self._cb)
@@ -264,6 +266,29 @@ class ScriptingInstance:
logger.log_error_for_exception("Unhandled Python exception in ScriptingInstance._complete_input")
return core.BNAllocString("")
+ def _can_complete_arguments(self, ctx, text):
+ try:
+ if not isinstance(text, str):
+ text = text.decode("utf-8")
+ return self.perform_can_complete_arguments(text)
+ except Exception:
+ logger.log_error_for_exception("Unhandled Python exception in ScriptingInstance._can_complete_arguments")
+ return False
+
+ def _complete_arguments(self, ctx, text, argument_start):
+ try:
+ if not isinstance(text, str):
+ text = text.decode("utf-8")
+ result, start = self.perform_complete_arguments(text)
+ argument_start[0] = start
+ if result is None:
+ return None
+ return core.BNAllocString(result)
+ except Exception:
+ logger.log_error_for_exception("Unhandled Python exception in ScriptingInstance._complete_arguments")
+ argument_start[0] = 0
+ return None
+
def _stop(self, ctxt):
try:
self.perform_stop()
@@ -307,6 +332,14 @@ class ScriptingInstance:
return NotImplemented
@abc.abstractmethod
+ def perform_can_complete_arguments(self, text: str) -> bool:
+ return NotImplemented
+
+ @abc.abstractmethod
+ def perform_complete_arguments(self, text: str) -> Tuple[Optional[str], int]:
+ return NotImplemented
+
+ @abc.abstractmethod
def perform_stop(self):
return NotImplemented
@@ -360,6 +393,14 @@ class ScriptingInstance:
def complete_input(self, text, state):
return core.BNScriptingInstanceCompleteInput(self.handle, text, state)
+ def can_complete_arguments(self, text):
+ return core.BNScriptingInstanceCanCompleteArguments(self.handle, text)
+
+ def complete_arguments(self, text):
+ argument_start = ctypes.c_ulonglong()
+ result = core.BNScriptingInstanceCompleteArguments(self.handle, text, argument_start)
+ return result, argument_start.value
+
def stop(self):
core.BNStopScriptingInstance(self.handle)
@@ -1039,6 +1080,24 @@ from binaryninja import *
return ""
return result
+ @abc.abstractmethod
+ def perform_can_complete_arguments(self, text: str) -> bool:
+ try:
+ self.interpreter.update_locals()
+ except Exception:
+ traceback.print_exc()
+ return self.interpreter.completer.can_complete_arguments(text)
+
+ @abc.abstractmethod
+ def perform_complete_arguments(self, text: str) -> Tuple[Optional[str], int]:
+ try:
+ self.interpreter.update_locals()
+ except Exception:
+ traceback.print_exc()
+ result = self.interpreter.completer.complete_arguments(text)
+ if result[0] is None:
+ return None, 0
+ return result
class PythonScriptingProvider(ScriptingProvider):
name = "Python"