summaryrefslogtreecommitdiff
path: root/py/repl.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/repl.c')
-rw-r--r--py/repl.c78
1 files changed, 32 insertions, 46 deletions
diff --git a/py/repl.c b/py/repl.c
index 7e8922e19..61ae2c1fe 100644
--- a/py/repl.c
+++ b/py/repl.c
@@ -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;