diff options
-rw-r--r-- | lib.c | 5 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | parser.c | 27 | ||||
-rw-r--r-- | struct.c | 38 | ||||
-rw-r--r-- | struct.h | 1 | ||||
-rw-r--r-- | txr.1 | 14 |
6 files changed, 74 insertions, 12 deletions
@@ -5053,7 +5053,10 @@ val unuse_package(val unuse_list, val package_in) return unuse_package_list; } -static val symbol_visible(val package, val sym) +/* symbol_visible assumes the perspective that package + * is the current package! + */ +val symbol_visible(val package, val sym) { val name = symbol_name(sym); type_check (package, PKG); @@ -800,6 +800,7 @@ val use_sym(val use_list, val package); val unuse_sym(val symbol, val package); val use_package(val use_list, val package); val unuse_package(val unuse_list, val package); +val symbol_visible(val package, val sym); val find_symbol(val str, val package); val intern(val str, val package); val unintern(val sym, val package); @@ -686,18 +686,20 @@ static val get_visible_syms(val package, int is_cur) static void find_matching_syms(lino_completions_t *cpl, val package, val prefix, - val line_prefix, char par, + val line_prefix, char kind, val force_qualify) { - int is_cur = package == cur_package; + val is_cur = tnil(package == cur_package); val qualify = tnil(force_qualify || !is_cur); val pkg_name = if2(qualify, if3(package == keyword_package && !force_qualify, lit(""), package_name(package))); - val syms; + val syms = ((kind == 'S' || kind == 'M') + ? hash_keys((get_slot_syms(package, is_cur, tnil(kind == 'M')))) + : get_visible_syms(package, is_cur != nil)); - for (syms = get_visible_syms(package, is_cur); syms; syms = cdr(syms)) { + for ( ; syms; syms = cdr(syms)) { val sym = car(syms); val name = symbol_name(sym); val found = if3(cpl->substring, @@ -707,7 +709,7 @@ static void find_matching_syms(lino_completions_t *cpl, if (found) { val comple; - switch (par) { + switch (kind) { case '(': if (!fboundp(sym) && !mboundp(sym) && !special_operator_p(sym)) continue; @@ -716,6 +718,9 @@ static void find_matching_syms(lino_completions_t *cpl, if (!boundp(sym) && !lookup_fun(nil, sym)) continue; break; + case 'M': + case 'S': + break; default: break; } @@ -812,13 +817,19 @@ static void provide_completions(const char *data, char prev = (end > data) ? end[-1] : 0; char pprev = (end > data + 1) ? end[-2] : 0; int quote = (pprev == '^' || pprev == '\'' || pprev == '#'); - int meth = (pprev == '.'); int ppar = (pprev == '('); int dwim = (prev == '['); - char par = (!pprev || (!quote && !meth && !ppar) || dwim) ? prev : 0; + int par = (prev == '('); + int slot = (prev == '.'); + int meth = (pprev == '.') && (dwim || par); + char kind = (slot + ? 'S' + : (meth + ? 'M' + : (!pprev || (!quote && !ppar) || dwim) ? prev : 0)); find_matching_syms(cpl, or2(package, cur_package), - sym_pfx, line_pfx, par, if2(package, null(keyword))); + sym_pfx, line_pfx, kind, if2(package, null(keyword))); } } } @@ -1507,6 +1507,44 @@ val method_name(val fun) return nil; } +val get_slot_syms(val package, val is_current, val method_only) +{ + val result_hash = make_hash(nil, nil, nil); + val sth_iter = hash_begin(struct_type_hash); + val sth_cell; + + while ((sth_cell = hash_next(sth_iter))) { + val stype = cdr(sth_cell); + val sl_iter; + struct struct_type *st = coerce(struct struct_type *, stype->co.handle); + + for (sl_iter = st->slots; sl_iter; sl_iter = cdr(sl_iter)) { + val slot = car(sl_iter); + + if (gethash(result_hash, slot)) + continue; + + if (!is_current && symbol_package(slot) != package) + continue; + + if (!symbol_visible(package, slot)) + continue; + + if (method_only) { + loc ptr = lookup_static_slot(st, slot); + if (nullocp(ptr)) + continue; + if (!functionp(deref(ptr))) + continue; + } + + sethash(result_hash, slot, t); + } + } + + return result_hash; +} + static_def(struct cobj_ops struct_type_ops = cobj_ops_init(eq, struct_type_print, struct_type_destroy, struct_type_mark, cobj_hash_op)) @@ -63,4 +63,5 @@ val super_method(val strct, val slotsym); val uslot(val slot); val umethod(val slot, struct args *); val method_name(val fun); +val get_slot_syms(val package, val is_current, val method_only); void struct_init(void); @@ -52097,11 +52097,19 @@ sequence Ctrl-X Tab. When completion is invoked with Tab or Ctrl-X Tab, the listener looks at a few of the trailing characters to the left of the cursor position to determine the applicable list of completions. Completions are determined from among the \*(TL symbols which have -global variable, function, macro and symbolic macro bindings. Symbols which -have operator binding are also taken into consideration. If a +global variable, function, macro and symbolic macro bindings, as well +as the static and instance slots of structures. Symbols which +have operator bindings are also taken into consideration. If a package-qualified symbol is completed, then completion is restricted to that package. Keyword symbol completion is restricted to the contents of the keyword -package. +package. The namespaces which are searched for symbols are restricted according +to preceding character syntax. For instance if the characters +.code ".(" +or +.code ".[" +immediately precede the prefix, then only those symbols are considered +which are methods: that is, each is the static slot of at least one structure, +in which that static slots holds a function. The difference between Tab and Ctrl-X Tab is that Tab completion looks only for prefix matches among the eligible identifiers. Thus it is a pure completion in |