mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-24 01:59:18 +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.
|
||||
|
||||
@param prefix: Line prefix at x (string)
|
||||
@param prefix: Line prefix at prefix_start (string)
|
||||
@param n: completion number (int)
|
||||
@param line: the current line (string)
|
||||
@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
|
||||
//
|
||||
// Copyright (c) 2004-2010 Gergely Erdelyi <gergely.erdelyi@d-dome.net>
|
||||
// Copyright (c) The IDAPython Team <idapython@googlegroups.com>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@ -1021,6 +1021,35 @@ bool idaapi IDAPython_cli_execute_line(const char *line)
|
||||
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 =
|
||||
{
|
||||
@ -1030,7 +1059,7 @@ static const cli_t cli_python =
|
||||
"Python - IDAPython plugin",
|
||||
"Enter any Python expression",
|
||||
IDAPython_cli_execute_line,
|
||||
NULL,
|
||||
IDAPYthon_cli_complete_line,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define S_IDAAPI_MODNAME "idaapi"
|
||||
#define S_IDC_MODNAME "idc"
|
||||
#define S_IDAAPI_EXECSCRIPT "IDAPython_ExecScript"
|
||||
#define S_IDAAPI_COMPLETION "IDAPython_Completion"
|
||||
|
||||
// Vector of PyObject*
|
||||
typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
|
@ -1635,10 +1635,13 @@ typedef int error_t;
|
||||
|
||||
%pythoncode %{
|
||||
#<pycode(py_idaapi)>
|
||||
|
||||
import struct
|
||||
import traceback
|
||||
import os
|
||||
import sys
|
||||
import __builtin__
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# Seek constants
|
||||
@ -1935,6 +1938,56 @@ def IDAPython_ExecScript(script, g):
|
||||
|
||||
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:
|
||||
|
@ -2715,7 +2715,7 @@ class cli_t(pyidc_opaque_object_t):
|
||||
#
|
||||
# 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 line: the current line (string)
|
||||
# @param prefix_start: the index where PREFIX starts in LINE (int)
|
||||
|
Loading…
Reference in New Issue
Block a user