Skip to content
This repository has been archived by the owner on Apr 20, 2024. It is now read-only.

Commit

Permalink
Lsh: Autocomplete function names
Browse files Browse the repository at this point in the history
  • Loading branch information
minexew committed Mar 23, 2017
1 parent d9cb137 commit 6730173
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 25 deletions.
171 changes: 148 additions & 23 deletions Lsh/Lsh.HC
Original file line number Diff line number Diff line change
Expand Up @@ -164,30 +164,140 @@ U0 TransformCommand(U8* command, U8* exec_buf) {
}

// -------------------------------------
// Shell
// Autocomplete

Bool skip_intro = FALSE;
class CHashTableIter {
CHashTable* ht;
I64 i;
CHash* curr;
I64 recursive;
};

// No matches -> return 0
// 1 match -> return 1, set *p_match to alloced
// multiple matches -> print matches, return count
I64 Autocomplete(U8* buffer) {
U8* mask = MStrPrint("%s*", buffer);
U0 HashTableIterBegin(CHashTableIter* it, CHashTable* ht, I64 recursive) {
it->ht = ht;
it->i = 0;
it->curr = NULL;
it->recursive = recursive;
}

CHash* HashTableIterNext(CHashTableIter* it) {
// End of current bucket?
while (!it->curr) {
// End of hash table?
while (it->i >= it->ht->mask) {
// If recursive search is enabled,
// jump to the next table in chain
if (it->recursive) {
if (!it->ht->next)
return NULL;

it->ht = it->ht->next;
it->i = 0;
}
else
return NULL;
}

it->curr = it->ht->body[it->i];
it->i++;
}

CHash* ret = it->curr;
it->curr = it->curr->next;
return ret;
}

class CAutocompleteIter {
U8* query;
I64 length;
CDirEntry* entries;
CDirEntry* de;
CHashTableIter hti;
};

class CAutocompleteResult {
// Exactly one of these will be set
CDirEntry* de;
CHashFun* fun;
};

U0 AutocompleteIterRewind(CAutocompleteIter* it) {
it->de = it->entries;
HashTableIterBegin(&it->hti, Fs->hash_table, TRUE);
}

U0 AutocompleteIterBegin(CAutocompleteIter* it, U8* query) {
it->query = query;
it->length = StrLen(query);

U8* mask = MStrPrint("%s*", query);
try {
de = FilesFind(mask);
it->entries = FilesFind(mask);
}
catch {
de = NULL;
it->entries = NULL;
}
Free(mask);

if (!de)
AutocompleteIterRewind(it);
}

I64 AutocompleteIterNext(CAutocompleteIter* it, CAutocompleteResult* out) {
// Go through all file matches first
while (it->de) {
if (it->de->name[0] != '.') {
// Return the DE, iteration will resume at the next one
out->de = it->de;
out->fun = NULL;
it->de = it->de->next;
return TRUE;
}

it->de = it->de->next;
}

// Go through all hashtable matches
CHash* next;
while ((next = HashTableIterNext(&it->hti))) {
// Function?
if ((next->type & HTT_FUN) != 0
&& !MemCmp(next->str, it->query, it->length)) {
out->de = NULL;
out->fun = next(CHashFun*);
return TRUE;
}
}

return FALSE;
}

U0 AutocompleteIterEnd(CAutocompleteIter* it) {
DirTreeDel(it->entries);
}


// No matches -> return 0
// 1 match -> return 1, set *p_match to alloced
// multiple matches -> print matches, return count
I64 Autocomplete(U8* buffer) {
// This is somewhat complicated, because we want
// to avoid any unnecessary allocations.

CAutocompleteIter it;
CAutocompleteResult first, next;

AutocompleteIterBegin(&it, buffer);

if (!AutocompleteIterNext(&it, &first)) {
// No results.
return 0;
}

I64 count = LinkedLstCnt(de);
I64 count;

if (!AutocompleteIterNext(&it, &next)) {
// Single result.

if (count == 1) {
// Completing path or last argument?
U8* start = StrLastOcc(buffer, "/");

Expand All @@ -196,26 +306,41 @@ I64 Autocomplete(U8* buffer) {
else
start = buffer;

StrCpy(start, de->name);
if (first.de)
StrCpy(start, first.de->name);
else if (first.fun)
StrCpy(start, first.fun->str);

count = 1;
}
else {
CDirEntry* de2 = de;
I64 shown = 0;
AutocompleteIterRewind(&it);

count = 0;
"\n";
while (shown < AUTOCOMPLETE_MAX_RESULTS && de2) {
if (de2->name[0] != '.') {
"%s\n", de2->name;
shown++;
}
de2 = de2->next;

while (count < AUTOCOMPLETE_MAX_RESULTS
&& AutocompleteIterNext(&it, &next)) {
if (next.de)
"$FG,4$%s\n", next.de->name;
else if (next.fun)
"$FG,3$%s\n", next.fun->str;
count++;
}
if (de2)

if (AutocompleteIterNext(&it, &next))
"$FG,6$Too many results, display truncated\n$FG$";
}
DirTreeDel(de);

AutocompleteIterEnd(&it);
return count;
}

// -------------------------------------
// Shell

Bool skip_intro = FALSE;

U8* DirCurShort() {
U8* dir = DirCur();
// FIXME!!
Expand Down
4 changes: 2 additions & 2 deletions Lsh/manifest
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ website https://github.com/minexew/Shrine
pkgmin 10
iso.c ::/Tmp/Lsh.ISO.C
osmin 503
version 5.03.0
release 5030
version 5.03.1
release 5031
installdir ::/Apps

0 comments on commit 6730173

Please sign in to comment.