fast word completion for functions names in the shell

This commit is contained in:
Krasimir Angelov
2023-03-02 10:28:00 +01:00
parent adc8a2fa29
commit f7ca8afa81
8 changed files with 87 additions and 2 deletions

View File

@@ -627,6 +627,32 @@ void namespace_iter(Namespace<V> map, PgfItor* itor, PgfExn *err)
return;
}
template <class V>
void namespace_iter_prefix(Namespace<V> map, PgfText *prefix, PgfItor* itor, PgfExn *err)
{
if (map == 0)
return;
int cmp = textcmp_prefix(prefix,&map->value->name);
if (cmp < 0)
namespace_iter_prefix(map->left, prefix, itor, err);
else if (cmp > 0)
namespace_iter_prefix(map->right, prefix, itor, err);
else {
namespace_iter_prefix(map->left, prefix, itor, err);
if (err->type != PGF_EXN_NONE)
return;
itor->fn(itor, &map->value->name, map->value.as_object(), err);
if (err->type != PGF_EXN_NONE)
return;
namespace_iter_prefix(map->right, prefix, itor, err);
if (err->type != PGF_EXN_NONE)
return;
}
}
template <class V>
Namespace<V> namespace_map(Namespace<V> map, std::function<ref<V>(ref<V>)> f)
{

View File

@@ -487,6 +487,19 @@ void pgf_iter_functions(PgfDB *db, PgfRevision revision,
} PGF_API_END
}
PGF_API
void pgf_iter_functions_by_prefix(PgfDB *db, PgfRevision revision,
PgfText *prefix, PgfItor *itor, PgfExn *err)
{
PGF_API_BEGIN {
DB_scope scope(db, READER_SCOPE);
ref<PgfPGF> pgf = db->revision2pgf(revision);
pgf_exn_clear(err);
namespace_iter_prefix(pgf->abstract.funs, prefix, itor, err);
} PGF_API_END
}
PGF_API
void pgf_iter_functions_by_cat(PgfDB *db, PgfRevision revision,
PgfText *cat, PgfItor *itor, PgfExn *err)

View File

@@ -336,6 +336,10 @@ PGF_API_DECL
void pgf_iter_functions(PgfDB *db, PgfRevision revision,
PgfItor *itor, PgfExn *err);
PGF_API_DECL
void pgf_iter_functions_by_prefix(PgfDB *db, PgfRevision revision,
PgfText *prefix, PgfItor *itor, PgfExn *err);
PGF_API_DECL
void pgf_iter_functions_by_cat(PgfDB *db, PgfRevision revision,
PgfText *cat, PgfItor *itor, PgfExn *err);

View File

@@ -16,6 +16,22 @@ int textcmp(PgfText *t1, PgfText *t2)
}
}
PGF_INTERNAL
int textcmp_prefix(PgfText *t1, PgfText *t2)
{
for (size_t i = 0; ; i++) {
if (i >= t1->size)
return 0;
if (i >= t2->size)
return 1;
if (t1->text[i] > t2->text[i])
return 1;
else if (t1->text[i] < t2->text[i])
return -1;
}
}
PGF_INTERNAL
void texticmp(PgfText *t1, PgfText *t2, int res[2])
{

View File

@@ -5,6 +5,10 @@
PGF_INTERNAL_DECL
int textcmp(PgfText *t1, PgfText *t2);
/* The same as textcmp but returns 0 if t1 is a prefix of t2. */
PGF_INTERNAL_DECL
int textcmp_prefix(PgfText *t1, PgfText *t2);
/* Performs both case-insensitive and case-sensitive comparison.
* The first element in res contains the result from
* the case-insensitive comparison. The second the result