mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-30 21:14:20 +01:00
added command completion
This commit is contained in:
parent
d76ccd7b1e
commit
97a9805336
@ -50,7 +50,7 @@ class mycli_t(cli_t):
|
|||||||
|
|
||||||
This callback is optional.
|
This callback is optional.
|
||||||
|
|
||||||
@param prefix: Line prefix at x (string)
|
@param prefix: Line prefix at prefix_start (string)
|
||||||
@param n: completion number (int)
|
@param n: completion number (int)
|
||||||
@param line: the current line (string)
|
@param line: the current line (string)
|
||||||
@param prefix_start: the index where PREFIX starts in LINE (int)
|
@param prefix_start: the index where PREFIX starts in LINE (int)
|
||||||
|
33
python.cpp
33
python.cpp
@ -1,7 +1,7 @@
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// IDAPython - Python plugin for Interactive Disassembler Pro
|
// IDAPython - Python plugin for Interactive Disassembler Pro
|
||||||
//
|
//
|
||||||
// Copyright (c) 2004-2010 Gergely Erdelyi <gergely.erdelyi@d-dome.net>
|
// Copyright (c) The IDAPython Team <idapython@googlegroups.com>
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@ -1021,6 +1021,35 @@ bool idaapi IDAPython_cli_execute_line(const char *line)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
bool idaapi IDAPYthon_cli_complete_line(
|
||||||
|
qstring *completion,
|
||||||
|
const char *prefix,
|
||||||
|
int n,
|
||||||
|
const char *line,
|
||||||
|
int x)
|
||||||
|
{
|
||||||
|
PyObject *py_complete = get_idaapi_attr(S_IDAAPI_COMPLETION);
|
||||||
|
if ( py_complete == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PyObject *py_ret = PyObject_CallFunction(py_complete, "sisi", prefix, n, line, x);
|
||||||
|
|
||||||
|
Py_DECREF(py_complete);
|
||||||
|
|
||||||
|
// Swallow the error
|
||||||
|
PyW_GetError(completion);
|
||||||
|
|
||||||
|
bool ok = py_ret != NULL && PyString_Check(py_ret) != 0;
|
||||||
|
|
||||||
|
if ( ok )
|
||||||
|
*completion = PyString_AS_STRING(py_ret);
|
||||||
|
|
||||||
|
Py_XDECREF(py_ret);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
static const cli_t cli_python =
|
static const cli_t cli_python =
|
||||||
{
|
{
|
||||||
@ -1030,7 +1059,7 @@ static const cli_t cli_python =
|
|||||||
"Python - IDAPython plugin",
|
"Python - IDAPython plugin",
|
||||||
"Enter any Python expression",
|
"Enter any Python expression",
|
||||||
IDAPython_cli_execute_line,
|
IDAPython_cli_execute_line,
|
||||||
NULL,
|
IDAPYthon_cli_complete_line,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define S_IDAAPI_MODNAME "idaapi"
|
#define S_IDAAPI_MODNAME "idaapi"
|
||||||
#define S_IDC_MODNAME "idc"
|
#define S_IDC_MODNAME "idc"
|
||||||
#define S_IDAAPI_EXECSCRIPT "IDAPython_ExecScript"
|
#define S_IDAAPI_EXECSCRIPT "IDAPython_ExecScript"
|
||||||
|
#define S_IDAAPI_COMPLETION "IDAPython_Completion"
|
||||||
|
|
||||||
// Vector of PyObject*
|
// Vector of PyObject*
|
||||||
typedef qvector<PyObject *> ppyobject_vec_t;
|
typedef qvector<PyObject *> ppyobject_vec_t;
|
||||||
|
@ -1635,10 +1635,13 @@ typedef int error_t;
|
|||||||
|
|
||||||
%pythoncode %{
|
%pythoncode %{
|
||||||
#<pycode(py_idaapi)>
|
#<pycode(py_idaapi)>
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
import traceback
|
import traceback
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import __builtin__
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
# Seek constants
|
# Seek constants
|
||||||
@ -1935,6 +1938,56 @@ def IDAPython_ExecScript(script, g):
|
|||||||
|
|
||||||
return PY_COMPILE_ERR
|
return PY_COMPILE_ERR
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
class __IDAPython_Completion_Util(object):
|
||||||
|
"""Internal utility class for auto-completion support"""
|
||||||
|
def __init__(self):
|
||||||
|
self.n = 0
|
||||||
|
self.completion = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_identifier(line, prefix, prefix_start):
|
||||||
|
"""Parse a line and extracts"""
|
||||||
|
id_start = prefix_start
|
||||||
|
while id_start > 0:
|
||||||
|
ch = line[id_start]
|
||||||
|
if not ch.isalpha() and ch != '.' and ch != '_':
|
||||||
|
id_start += 1
|
||||||
|
break
|
||||||
|
id_start -= 1
|
||||||
|
|
||||||
|
return line[id_start:prefix_start + len(prefix)]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_completion(id, prefix):
|
||||||
|
try:
|
||||||
|
parts = id.split('.')
|
||||||
|
m = sys.modules['__main__']
|
||||||
|
c = len(parts)
|
||||||
|
for i in xrange(0, c-1):
|
||||||
|
m = getattr(m, parts[i])
|
||||||
|
except Exception, e:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
# search in the module
|
||||||
|
completion = [x for x in dir(m) if x.startswith(prefix)]
|
||||||
|
|
||||||
|
# no completion found? looking from the global scope? then try the builtins
|
||||||
|
if not completion and c == 1:
|
||||||
|
completion = [x for x in dir(__builtin__) if x.startswith(prefix)]
|
||||||
|
|
||||||
|
return completion if len(completion) else None
|
||||||
|
|
||||||
|
def __call__(self, prefix, n, line, prefix_start):
|
||||||
|
if n == 0:
|
||||||
|
self.n = n
|
||||||
|
id = self.parse_identifier(line, prefix, prefix_start)
|
||||||
|
self.completion = self.get_completion(id, prefix)
|
||||||
|
return None if self.completion is None or n >= len(self.completion) else self.completion[n]
|
||||||
|
|
||||||
|
|
||||||
|
IDAPython_Completion = __IDAPython_Completion_Util()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The general callback format of notify_when() is:
|
# The general callback format of notify_when() is:
|
||||||
|
@ -2715,7 +2715,7 @@ class cli_t(pyidc_opaque_object_t):
|
|||||||
#
|
#
|
||||||
# This callback is optional.
|
# This callback is optional.
|
||||||
#
|
#
|
||||||
# @param prefix: Line prefix at x (string)
|
# @param prefix: Line prefix at prefix_start (string)
|
||||||
# @param n: completion number (int)
|
# @param n: completion number (int)
|
||||||
# @param line: the current line (string)
|
# @param line: the current line (string)
|
||||||
# @param prefix_start: the index where PREFIX starts in LINE (int)
|
# @param prefix_start: the index where PREFIX starts in LINE (int)
|
||||||
|
Loading…
Reference in New Issue
Block a user