diff options
Diffstat (limited to 'py/repl.c')
-rw-r--r-- | py/repl.c | 78 |
1 files changed, 32 insertions, 46 deletions
@@ -27,6 +27,7 @@ #include <string.h> #include "py/obj.h" #include "py/runtime.h" +#include "py/builtin.h" #include "py/repl.h" #if MICROPY_HELPER_REPL @@ -136,8 +137,11 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print } } - // begin search in locals dict - mp_obj_dict_t *dict = mp_locals_get(); + size_t nqstr = QSTR_TOTAL(); + + // begin search in outer global dict which is accessed from __main__ + mp_obj_t obj = MP_OBJ_FROM_PTR(&mp_module___main__); + mp_obj_t dest[2]; for (;;) { // get next word in string to complete @@ -148,43 +152,20 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print size_t s_len = str - s_start; if (str < top) { - // a complete word, lookup in current dict - - mp_obj_t obj = MP_OBJ_NULL; - for (size_t i = 0; i < dict->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { - size_t d_len; - const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len); - if (s_len == d_len && strncmp(s_start, d_str, d_len) == 0) { - obj = dict->map.table[i].value; - break; - } - } + // a complete word, lookup in current object + qstr q = qstr_find_strn(s_start, s_len); + if (q == MP_QSTR_NULL) { + // lookup will fail + return 0; } + mp_load_method_maybe(obj, q, dest); + obj = dest[0]; // attribute, method, or MP_OBJ_NULL if nothing found if (obj == MP_OBJ_NULL) { // lookup failed return 0; } - // found an object of this name; try to get its dict - if (MP_OBJ_IS_TYPE(obj, &mp_type_module)) { - dict = mp_obj_module_get_globals(obj); - } else { - mp_obj_type_t *type; - if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) { - type = MP_OBJ_TO_PTR(obj); - } else { - type = mp_obj_get_type(obj); - } - if (type->locals_dict != NULL && type->locals_dict->base.type == &mp_type_dict) { - dict = type->locals_dict; - } else { - // obj has no dict - return 0; - } - } - // skip '.' to move to next word ++str; @@ -192,14 +173,15 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print // end of string, do completion on this partial name // look for matches - int n_found = 0; const char *match_str = NULL; size_t match_len = 0; - for (size_t i = 0; i < dict->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { - size_t d_len; - const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len); - if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + qstr q_first = 0, q_last; + for (qstr q = 1; q < nqstr; ++q) { + size_t d_len; + const char *d_str = (const char*)qstr_data(q, &d_len); + if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + mp_load_method_maybe(obj, q, dest); + if (dest[0] != MP_OBJ_NULL) { if (match_str == NULL) { match_str = d_str; match_len = d_len; @@ -213,13 +195,16 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print } } } - ++n_found; + if (q_first == 0) { + q_first = q; + } + q_last = q; } } } // nothing found - if (n_found == 0) { + if (q_first == 0) { // If there're no better alternatives, and if it's first word // in the line, try to complete "import". if (s_start == org_str) { @@ -234,7 +219,7 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print } // 1 match found, or multiple matches with a common prefix - if (n_found == 1 || match_len > s_len) { + if (q_first == q_last || match_len > s_len) { *compl_str = match_str + s_len; return match_len - s_len; } @@ -245,11 +230,12 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print #define MAX_LINE_LEN (4 * WORD_SLOT_LEN) int line_len = MAX_LINE_LEN; // force a newline for first word - for (size_t i = 0; i < dict->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { - size_t d_len; - const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len); - if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + for (qstr q = q_first; q <= q_last; ++q) { + size_t d_len; + const char *d_str = (const char*)qstr_data(q, &d_len); + if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + mp_load_method_maybe(obj, q, dest); + if (dest[0] != MP_OBJ_NULL) { int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; if (gap < 2) { gap += WORD_SLOT_LEN; |