From 8b3eb12947305ad3636227b7bfe6132f39b1028f Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 6 Sep 2015 07:26:35 -0700 Subject: Parenthesis sensitivity for completion. * eval.c (boundp): Static function becomes extern. * eval.h (boundp): Declared. * parser.c (find_matching_syms): New par parameter lets function determine whether previous character is a an open parenthesis or brace, based on which the set of possible completions is restricted. (provide_completions): Calculate the par parameter and pass to find_matching_syms. --- eval.c | 2 +- eval.h | 1 + parser.c | 27 +++++++++++++++++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/eval.c b/eval.c index 1e5919cf..2afc431c 100644 --- a/eval.c +++ b/eval.c @@ -3423,7 +3423,7 @@ static val symbol_function(val sym) gethash(op_table, sym)); } -static val boundp(val sym) +val boundp(val sym) { return if2(lookup_var(nil, sym) || lookup_symac(nil, sym), t); } diff --git a/eval.h b/eval.h index 301ac55c..61bfb5db 100644 --- a/eval.h +++ b/eval.h @@ -38,6 +38,7 @@ loc lookup_var_l(val env, val sym); loc lookup_global_var_l(val sym); val lookup_fun(val env, val sym); val interp_fun(val env, val fun, struct args *); +val boundp(val sym); val fboundp(val sym); val special_operator_p(val sym); val macro_form_p(val form, val menv); diff --git a/parser.c b/parser.c index 804822bf..d39d1fb6 100644 --- a/parser.c +++ b/parser.c @@ -345,7 +345,8 @@ val read_eval_stream(val stream, val error_stream, val hash_bang_support) static void find_matching_syms(lino_completions_t *cpl, val package, val prefix, - val line_prefix, val force_qualify) + val line_prefix, char par, + val force_qualify) { val qualify = tnil(force_qualify || package != user_package); val pkg_name = if2(qualify, @@ -361,6 +362,19 @@ static void find_matching_syms(lino_completions_t *cpl, if (match_str(name, prefix, zero)) { val compl; + switch (par) { + case '(': + if (!fboundp(sym)) + continue; + break; + case '[': + if (!boundp(sym) && !lookup_fun(nil, sym)) + continue; + break; + default: + break; + } + if (qualify) compl = format(nil, lit("~a~a:~a"), line_prefix, pkg_name, name, nao); else @@ -431,7 +445,7 @@ static void provide_completions(const char *data, } { - val sym_prefix = string_utf8(sym); + val sym_pfx = string_utf8(sym); size_t lsz = end - data + 1; char *line_pfxu8 = alloca(lsz); memcpy(line_pfxu8, data, lsz); @@ -439,15 +453,20 @@ static void provide_completions(const char *data, { val line_pfx = string_utf8(line_pfxu8); + char prev = (end > data) ? end[-1] : 0; + char pprev = (end > data + 1) ? end[-2] : 0; + int quote = (pprev == '^' || pprev == '\'' || pprev == '#'); + int dwim = (prev == '['); + char par = (!pprev || !quote || dwim) ? prev : 0; if (package) { - find_matching_syms(cpl, package, sym_prefix, line_pfx, null(keyword)); + find_matching_syms(cpl, package, sym_pfx, line_pfx, par, null(keyword)); } else { val pa; for (pa = package_alist(); pa; pa = cdr(pa)) { val pair = car(pa); - find_matching_syms(cpl, cdr(pair), sym_prefix, line_pfx, nil); + find_matching_syms(cpl, cdr(pair), sym_pfx, line_pfx, par, nil); } } } -- cgit v1.2.3