@@ -161,131 +161,134 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
161
161
mp_obj_t obj = MP_OBJ_FROM_PTR (& mp_module___main__ );
162
162
mp_obj_t dest [2 ];
163
163
164
+ const char * s_start ;
165
+ size_t s_len ;
166
+
164
167
for (;;) {
165
168
// get next word in string to complete
166
- const char * s_start = str ;
169
+ s_start = str ;
167
170
while (str < top && * str != '.' ) {
168
171
++ str ;
169
172
}
170
- size_t s_len = str - s_start ;
173
+ s_len = str - s_start ;
171
174
172
- if (str < top ) {
173
- // a complete word, lookup in current object
174
- qstr q = qstr_find_strn (s_start , s_len );
175
- if (q == MP_QSTR_NULL ) {
176
- // lookup will fail
177
- return 0 ;
178
- }
179
- mp_load_method_protected (obj , q , dest , true);
180
- obj = dest [0 ]; // attribute, method, or MP_OBJ_NULL if nothing found
175
+ if (str == top ) {
176
+ // end of string, do completion on this partial name
177
+ break ;
178
+ }
181
179
182
- if (obj == MP_OBJ_NULL ) {
183
- // lookup failed
184
- return 0 ;
185
- }
180
+ // a complete word, lookup in current object
181
+ qstr q = qstr_find_strn (s_start , s_len );
182
+ if (q == MP_QSTR_NULL ) {
183
+ // lookup will fail
184
+ return 0 ;
185
+ }
186
+ mp_load_method_protected (obj , q , dest , true);
187
+ obj = dest [0 ]; // attribute, method, or MP_OBJ_NULL if nothing found
186
188
187
- // skip '.' to move to next word
188
- ++ str ;
189
+ if (obj == MP_OBJ_NULL ) {
190
+ // lookup failed
191
+ return 0 ;
192
+ }
189
193
190
- } else {
191
- // end of string, do completion on this partial name
194
+ // skip '.' to move to next word
195
+ ++ str ;
196
+ }
192
197
193
- // look for matches
194
- const char * match_str = NULL ;
195
- size_t match_len = 0 ;
196
- qstr q_first = 0 , q_last = 0 ;
197
- for (qstr q = MP_QSTR_ + 1 ; q < nqstr ; ++ q ) {
198
- size_t d_len ;
199
- const char * d_str = (const char * )qstr_data (q , & d_len );
200
- if (s_len <= d_len && strncmp (s_start , d_str , s_len ) == 0 ) {
201
- mp_load_method_protected (obj , q , dest , true);
202
- if (dest [0 ] != MP_OBJ_NULL ) {
203
- // special case; filter out words that begin with underscore
204
- // unless there's already a partial match
205
- if (s_len == 0 && d_str [0 ] == '_' ) {
206
- continue ;
207
- }
208
- if (match_str == NULL ) {
209
- match_str = d_str ;
210
- match_len = d_len ;
211
- } else {
212
- // search for longest common prefix of match_str and d_str
213
- // (assumes these strings are null-terminated)
214
- for (size_t j = s_len ; j <= match_len && j <= d_len ; ++ j ) {
215
- if (match_str [j ] != d_str [j ]) {
216
- match_len = j ;
217
- break ;
218
- }
219
- }
220
- }
221
- if (q_first == 0 ) {
222
- q_first = q ;
198
+ // look for matches
199
+ const char * match_str = NULL ;
200
+ size_t match_len = 0 ;
201
+ qstr q_first = 0 , q_last = 0 ;
202
+ for (qstr q = MP_QSTR_ + 1 ; q < nqstr ; ++ q ) {
203
+ size_t d_len ;
204
+ const char * d_str = (const char * )qstr_data (q , & d_len );
205
+ if (s_len <= d_len && strncmp (s_start , d_str , s_len ) == 0 ) {
206
+ mp_load_method_protected (obj , q , dest , true);
207
+ if (dest [0 ] != MP_OBJ_NULL ) {
208
+ // special case; filter out words that begin with underscore
209
+ // unless there's already a partial match
210
+ if (s_len == 0 && d_str [0 ] == '_' ) {
211
+ continue ;
212
+ }
213
+ if (match_str == NULL ) {
214
+ match_str = d_str ;
215
+ match_len = d_len ;
216
+ } else {
217
+ // search for longest common prefix of match_str and d_str
218
+ // (assumes these strings are null-terminated)
219
+ for (size_t j = s_len ; j <= match_len && j <= d_len ; ++ j ) {
220
+ if (match_str [j ] != d_str [j ]) {
221
+ match_len = j ;
222
+ break ;
223
223
}
224
- q_last = q ;
225
224
}
226
225
}
227
- }
228
-
229
- // nothing found
230
- if (q_first == 0 ) {
231
- if (s_len == 0 ) {
232
- * compl_str = " " ;
233
- return 4 ;
226
+ if (q_first == 0 ) {
227
+ q_first = q ;
234
228
}
235
- // If there're no better alternatives, and if it's first word
236
- // in the line, try to complete "import".
237
- if (s_start == org_str ) {
238
- static const char import_str [] = "import " ;
239
- if (memcmp (s_start , import_str , s_len ) == 0 ) {
240
- * compl_str = import_str + s_len ;
241
- return sizeof (import_str ) - 1 - s_len ;
242
- }
243
- }
244
-
245
- return 0 ;
229
+ q_last = q ;
246
230
}
231
+ }
232
+ }
247
233
248
- // 1 match found, or multiple matches with a common prefix
249
- if (q_first == q_last || match_len > s_len ) {
250
- * compl_str = match_str + s_len ;
251
- return match_len - s_len ;
234
+ // nothing found
235
+ if (q_first == 0 ) {
236
+ if (s_len == 0 ) {
237
+ * compl_str = " " ;
238
+ return 4 ;
239
+ }
240
+ // If there're no better alternatives, and if it's first word
241
+ // in the line, try to complete "import".
242
+ if (s_start == org_str ) {
243
+ static const char import_str [] = "import " ;
244
+ if (memcmp (s_start , import_str , s_len ) == 0 ) {
245
+ * compl_str = import_str + s_len ;
246
+ return sizeof (import_str ) - 1 - s_len ;
252
247
}
248
+ }
253
249
254
- // multiple matches found, print them out
250
+ return 0 ;
251
+ }
255
252
256
- #define WORD_SLOT_LEN (16)
257
- #define MAX_LINE_LEN (4 * WORD_SLOT_LEN)
253
+ // 1 match found, or multiple matches with a common prefix
254
+ if (q_first == q_last || match_len > s_len ) {
255
+ * compl_str = match_str + s_len ;
256
+ return match_len - s_len ;
257
+ }
258
258
259
- int line_len = MAX_LINE_LEN ; // force a newline for first word
260
- for (qstr q = q_first ; q <= q_last ; ++ q ) {
261
- size_t d_len ;
262
- const char * d_str = (const char * )qstr_data (q , & d_len );
263
- if (s_len <= d_len && strncmp (s_start , d_str , s_len ) == 0 ) {
264
- mp_load_method_protected (obj , q , dest , true);
265
- if (dest [0 ] != MP_OBJ_NULL ) {
266
- int gap = (line_len + WORD_SLOT_LEN - 1 ) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len ;
267
- if (gap < 2 ) {
268
- gap += WORD_SLOT_LEN ;
269
- }
270
- if (line_len + gap + d_len <= MAX_LINE_LEN ) {
271
- // TODO optimise printing of gap?
272
- for (int j = 0 ; j < gap ; ++ j ) {
273
- mp_print_str (print , " " );
274
- }
275
- mp_print_str (print , d_str );
276
- line_len += gap + d_len ;
277
- } else {
278
- mp_printf (print , "\n%s" , d_str );
279
- line_len = d_len ;
280
- }
259
+ // multiple matches found, print them out
260
+
261
+ #define WORD_SLOT_LEN (16)
262
+ #define MAX_LINE_LEN (4 * WORD_SLOT_LEN)
263
+
264
+ int line_len = MAX_LINE_LEN ; // force a newline for first word
265
+ for (qstr q = q_first ; q <= q_last ; ++ q ) {
266
+ size_t d_len ;
267
+ const char * d_str = (const char * )qstr_data (q , & d_len );
268
+ if (s_len <= d_len && strncmp (s_start , d_str , s_len ) == 0 ) {
269
+ mp_load_method_protected (obj , q , dest , true);
270
+ if (dest [0 ] != MP_OBJ_NULL ) {
271
+ int gap = (line_len + WORD_SLOT_LEN - 1 ) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len ;
272
+ if (gap < 2 ) {
273
+ gap += WORD_SLOT_LEN ;
274
+ }
275
+ if (line_len + gap + d_len <= MAX_LINE_LEN ) {
276
+ // TODO optimise printing of gap?
277
+ for (int j = 0 ; j < gap ; ++ j ) {
278
+ mp_print_str (print , " " );
281
279
}
280
+ mp_print_str (print , d_str );
281
+ line_len += gap + d_len ;
282
+ } else {
283
+ mp_printf (print , "\n%s" , d_str );
284
+ line_len = d_len ;
282
285
}
283
286
}
284
- mp_print_str (print , "\n" );
285
-
286
- return (size_t )(-1 ); // indicate many matches
287
287
}
288
288
}
289
+ mp_print_str (print , "\n" );
290
+
291
+ return (size_t )(-1 ); // indicate many matches
289
292
}
290
293
291
294
#endif // MICROPY_HELPER_REPL
0 commit comments