From 983452b40972263b083bcbdbf27b3ab191e44285 Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 19 Oct 2022 22:55:56 +0300 Subject: [PATCH] system value completion --- src/builtins/fns.c | 5 +- src/builtins/sysfn.c | 16 ++++++ src/main.c | 114 ++++++++++++++++++++++++++++++------------- 3 files changed, 100 insertions(+), 35 deletions(-) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 0acd2e0c..2098484b 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -223,7 +223,7 @@ void clearImportCacheMap() { } static H_b2i* globalNames; -static B globalNameList; +B globalNameList; i32 str2gid(B s) { if (globalNames==NULL) { globalNames = m_b2i(32); @@ -250,6 +250,9 @@ B gid2str(i32 n) { // print_fmt("gid2str %i → %R\n", n, r); return r; } +B allNsFields() { + return globalNames==NULL? bi_N : incG(globalNameList); +} void* profiler_makeMap() { return m_b2i(64); diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index c143dfb7..7fdf27a8 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1541,6 +1541,22 @@ static char* dsv_strs[] = { #undef F }; + +u32* dsv_text[] = { + #define F(L,N,B) N, + FOR_DEFAULT_SYSVALS(F) + #undef F + U"•file.Accessed",U"•file.At",U"•file.Bytes",U"•file.Chars",U"•file.Created",U"•file.CreateDir",U"•file.Exists",U"•file.Lines",U"•file.List", + U"•file.MapBytes",U"•file.Modified",U"•file.Name",U"•file.Parent",U"•file.Remove",U"•file.Rename",U"•file.Size",U"•file.Type", + + U"•internal.ClearRefs",U"•internal.DeepSqueeze",U"•internal.EEqual",U"•internal.ElType",U"•internal.HeapDump",U"•internal.Info",U"•internal.IsPure",U"•internal.ListVariations",U"•internal.Refc",U"•internal.Squeeze",U"•internal.Temp",U"•internal.Type",U"•internal.Unshare",U"•internal.Variation", + + U"•math.Acos",U"•math.Asin",U"•math.Atan",U"•math.Cos",U"•math.Sin",U"•math.Tan", + + U"•term.CharB",U"•term.CharN",U"•term.ErrRaw",U"•term.Flush",U"•term.OutRaw",U"•term.RawMode", + NULL +}; + B dsv_ns, dsv_vs; void sysfn_init() { usz dsv_num = sizeof(dsv_strs)/sizeof(char*); diff --git a/src/main.c b/src/main.c index ef278743..ef28e3fb 100644 --- a/src/main.c +++ b/src/main.c @@ -58,9 +58,8 @@ static NOINLINE void repl_init() { res[i] = v0>=0? replxx_color_rgb666(v0,v1,v2) : v2>=0? replxx_color_grayscale(v2) : REPLXX_COLOR_DEFAULT; } } - static void cbqn_init_replxx() { - build_theme(theme0_built, theme0); - } + extern u32* dsv_text[]; + static B sysvalNames, sysvalNamesNorm; NOINLINE void fill_color(ReplxxColor* cols, int s, int e, ReplxxColor col) { for (int i = s; i < e; i++) cols[i] = col; @@ -126,51 +125,83 @@ static NOINLINE void repl_init() { end: dec(charObj); } - + B allNsFields(void); + B str_norm(u32* chars, usz len, bool* upper) { + B norm = emptyCVec(); + bool hadLetter = false; + bool hasLower = false; + bool hasUpper = false; + for (usz i = 0; i < len; i++) { + u32 c = chars[i]; if (c=='_') continue; + bool low = chr_low(c); + bool upp = chr_upp(c); + if (low) hasLower = true; + if (hadLetter) hasUpper|= upp; + if (upp) c = chr_to_low(c); + hadLetter = upp | low; + norm = vec_addN(norm, m_c32(c)); + } + *upper = !hasLower && hasUpper; + return norm; + } + NOINLINE B vec_slice(B x, usz s, usz e) { + return taga(arr_shVec(TI(x,slice)(incG(x), s, e))); + } + NOINLINE u32* rskip_name(u32* start, u32* c) { + while (c>start && chr_nameM(*(c-1))) c--; + return c; + } NOINLINE void completion_impl(const char* inp, void* res, bool hint, int* dist) { - B vars = listVars(gsc); - if (q_N(vars)) return; - B inpB = toC32Any(utf8Decode0(inp)); u32* chars = c32any_ptr(inpB); u32* we = chars+IA(inpB); - u32* ws = we; - while (ws>chars && chr_nameM(*(ws-1))) ws--; + u32* ws = rskip_name(chars, we); + bool sysval = ws>chars && U'•' == *(ws-1); + bool nsField = ws>chars && '.' == *(ws-1); + if (nsField) { + u32* ws2 = rskip_name(chars, ws-1); + if (ws2>chars && U'•' == *(ws2-1)) { ws=ws2; sysval=true; nsField=false; } + } + if (sysval) ws--; usz wl = *dist = we-ws; if (wl>0) { usz wo = ws-chars; - B norm = emptyCVec(); - bool hasLower = false; - bool hasUpper = false; - for (usz i = 0; i < wl; i++) { - u32 c = ws[i]; if (c=='_') continue; - if (chr_low(c)) hasLower = true; - bool upp = chr_upp(c); - if (IA(norm)) hasUpper|= upp; - if (upp) c = chr_to_low(c); - norm = vec_addN(norm, m_c32(c)); - } + bool doUpper; + B norm = str_norm(ws, wl, &doUpper); + B reg = sysval? vec_slice(inpB, wo, wl) : bi_N; usz normLen = IA(norm); if (normLen>0) { + B vars = sysval? incG(sysvalNames) : nsField? allNsFields() : listVars(gsc); + if (q_N(vars)) goto noVars; usz via=IA(vars); SGetU(vars) for (usz i = 0; i < via; i++) { - B var = GetU(vars,i); - usz vlen = IA(var); - if (vlen<=normLen) continue; - B cSlc = taga(arr_shVec(TI(var,slice)(incG(var), 0, normLen))); - if (equal(norm, cSlc)) { - usz ext = vlen-normLen; + i32 matchState=0; B match=bi_N; usz matchLen=0, skip=0; + for (usz j = 0; j < (sysval? 2 : 1); j++) { + match = j? harr_ptr(sysvalNamesNorm)[i] : GetU(vars,i); + bool doNorm = sysval? j : true; + matchLen = IA(match); + usz wlen = doNorm? normLen : wl; + if (wlen>=matchLen) continue; + B slc = vec_slice(match, 0, wlen); + bool matched = equal(slc, doNorm? norm : reg); + decG(slc); + if (matched) { matchState=doNorm?1:2; skip=wlen; break; } + } + + if (matchState) { + usz ext = matchLen-skip; + assert(ext<100); u32* rp; B r = m_c32arrv(&rp, wl + ext); COPY_TO(rp, el_c32, 0, inpB, wo, wl); - if (hasLower || !hasUpper) { - COPY_TO(rp, el_c32, wl, var, normLen, ext); - } else { - SGetU(var) + if (doUpper && matchState!=2) { + SGetU(match) for (usz i = 0; i < ext; i++) { - u32 cc=o2cG(GetU(var,i+normLen)); + u32 cc=o2cG(GetU(match,i+skip)); rp[wl+i] = chr_low(cc)? chr_to_upp(cc) : cc; } + } else { + COPY_TO(rp, el_c32, wl, match, skip, ext); } char* str = toCStr(r); if (hint) replxx_add_hint(res, str); @@ -178,14 +209,15 @@ static NOINLINE void repl_init() { freeCStr(str); decG(r); } - decG(cSlc); } + decG(vars); + noVars:; } decG(norm); + if (sysval) decG(reg); } dec(inpB); - dec(vars); } void complete_replxx(const char* inp, replxx_completions* res, int* dist, void* data) { completion_impl(inp, res, false, dist); @@ -193,6 +225,20 @@ static NOINLINE void repl_init() { void hint_replxx(const char* inp, replxx_hints* res, int* dist, ReplxxColor* c, void* data) { completion_impl(inp, res, true, dist); } + + static void cbqn_init_replxx() { + build_theme(theme0_built, theme0); + sysvalNames = emptyHVec(); + sysvalNamesNorm = emptyHVec(); + u32** c = dsv_text; + while (*c) { bool unused; + B str = m_c32vec_0(*(c++)); + sysvalNames = vec_addN(sysvalNames, str); + sysvalNamesNorm = vec_addN(sysvalNamesNorm, str_norm(c32any_ptr(str), IA(str), &unused)); + } + gc_add(sysvalNames); + gc_add(sysvalNamesNorm); + } #endif @@ -651,4 +697,4 @@ int main(int argc, char* argv[]) { bqn_exit(0); #undef INIT } -#endif \ No newline at end of file +#endif