mirror of
https://git.checksum.fail/alec/erythros
synced 2025-12-10 13:09:55 +02:00
System/Libraries/Stdio: Initial support for @dir_entry autocomplete
This commit is contained in:
@@ -147,7 +147,7 @@ U0 @stdio_read_line_autocomplete_cmd(@shell* sh, U8* str, U8* line, I64* pos)
|
||||
}
|
||||
}
|
||||
|
||||
I64 @stdio_read_line_autocomplete_sort_cmds(U8** e1, U8** e2)
|
||||
I64 @stdio_read_line_autocomplete_sort(U8** e1, U8** e2)
|
||||
{
|
||||
return StrCmp(*e1, *e2);
|
||||
}
|
||||
@@ -179,7 +179,7 @@ U0 @stdio_read_line_autocomplete_list_cmds(@shell* sh, U8* prompt, U8* str, U8*
|
||||
tbl = tbl->next;
|
||||
}
|
||||
if (cnt) {
|
||||
QSort(cmds, cnt, sizeof(U8*), &@stdio_read_line_autocomplete_sort_cmds);
|
||||
QSort(cmds, cnt, sizeof(U8*), &@stdio_read_line_autocomplete_sort);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
@stdio_write_line(sh, "%s\n", cmds[i]);
|
||||
}
|
||||
@@ -188,24 +188,136 @@ U0 @stdio_read_line_autocomplete_list_cmds(@shell* sh, U8* prompt, U8* str, U8*
|
||||
Free(cmds);
|
||||
}
|
||||
|
||||
U0 @stdio_read_line_autocomplete(@shell* sh, U8* prompt, U8* str, I64* pos)
|
||||
I64 @stdio_read_line_autocomplete_dir_entry_count(@shell* sh, U8* str, @dir_entry* de)
|
||||
{
|
||||
U8 ac_buf[4096];
|
||||
I64 space_count = StrOcc(str, ' ');
|
||||
I64 cmd_count = 0;
|
||||
switch (space_count) {
|
||||
I64 cnt = 0;
|
||||
I64 len = StrLen(str);
|
||||
@dir_entry* tmpf = de;
|
||||
|
||||
while (tmpf) {
|
||||
if (StrCmp(tmpf->name, ".") && StrCmp(tmpf->name, "..")) {
|
||||
switch (len) {
|
||||
case 0:
|
||||
++cnt;
|
||||
break;
|
||||
default:
|
||||
if (!MemCmp(tmpf->name, str, len)) {
|
||||
++cnt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
tmpf = tmpf->next;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
U0 @stdio_read_line_autocomplete_dir_entry(@shell* sh, U8* str, @dir_entry* de, U8* line, I64* pos)
|
||||
{
|
||||
U8* ac_ch_ptr = NULL;
|
||||
I64 len = StrLen(str);
|
||||
@dir_entry* tmpf = de;
|
||||
Bool matched = FALSE;
|
||||
|
||||
while (tmpf) {
|
||||
if (!MemCmp(tmpf->name, str, len) && !matched) {
|
||||
ac_ch_ptr = tmpf->name + len;
|
||||
while (*ac_ch_ptr) {
|
||||
String.Append(line, "%c", *ac_ch_ptr);
|
||||
FifoU8Ins(sh->output, *ac_ch_ptr);
|
||||
++pos[0];
|
||||
++ac_ch_ptr;
|
||||
}
|
||||
if (tmpf->type == DE_TYPE_DIR) {
|
||||
String.Append(line, "/");
|
||||
FifoU8Ins(sh->output, '/');
|
||||
} else {
|
||||
String.Append(line, " ");
|
||||
FifoU8Ins(sh->output, ' ');
|
||||
}
|
||||
++pos[0];
|
||||
matched = TRUE;
|
||||
}
|
||||
tmpf = tmpf->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @stdio_read_line_autocomplete_list_dir_entries(@shell* sh, U8* prompt, U8* str, @dir_entry* de, U8* line, I64* pos, I64 entry_count)
|
||||
{
|
||||
I64 cnt = 0;
|
||||
|
||||
I64 i;
|
||||
U8** entries = CAlloc(sizeof(U8*) * entry_count);
|
||||
I64 len = StrLen(str);
|
||||
@dir_entry* tmpf = de;
|
||||
|
||||
while (tmpf) {
|
||||
if (!MemCmp(tmpf->name, str, len)) {
|
||||
if (!cnt) {
|
||||
@stdio_write_line(sh, "\n");
|
||||
}
|
||||
entries[cnt] = tmpf->name;
|
||||
++cnt;
|
||||
}
|
||||
tmpf = tmpf->next;
|
||||
}
|
||||
if (cnt) {
|
||||
QSort(entries, cnt, sizeof(U8*), &@stdio_read_line_autocomplete_sort);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
@stdio_write_line(sh, "%s\n", entries[i]);
|
||||
}
|
||||
@stdio_write_line(sh, "%s%s", prompt, line);
|
||||
}
|
||||
Free(entries);
|
||||
}
|
||||
|
||||
U0 @stdio_read_line_autocompletion_from_cmd(@shell* sh, U8* prompt, U8* ac_buf, U8* str, I64* pos)
|
||||
{
|
||||
StrPrint(ac_buf, "@shell_cmd_%s", str);
|
||||
cmd_count = @stdio_read_line_autocomplete_cmd_count(ac_buf);
|
||||
switch (cmd_count) {
|
||||
I64 word_count = @stdio_read_line_autocomplete_cmd_count(ac_buf);
|
||||
switch (word_count) {
|
||||
case 1:
|
||||
@stdio_read_line_autocomplete_cmd(sh, ac_buf, str, pos);
|
||||
break;
|
||||
default:
|
||||
@stdio_read_line_autocomplete_list_cmds(sh, prompt, ac_buf, str, pos, cmd_count);
|
||||
@stdio_read_line_autocomplete_list_cmds(sh, prompt, ac_buf, str, pos, word_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @stdio_read_line_autocompletion_from_dir_entry(@shell* sh, U8* prompt, U8* ac_buf, U8* str, I64* pos)
|
||||
{
|
||||
StrPrint(ac_buf, StrLastOcc(str, " ") + 1);
|
||||
@dir_entry* de = FileSystem.GetFiles(sh->cwd);
|
||||
@dir_entry* de2 = NULL;
|
||||
I64 word_count = @stdio_read_line_autocomplete_dir_entry_count(sh, ac_buf, de);
|
||||
switch (word_count) {
|
||||
case 1:
|
||||
@stdio_read_line_autocomplete_dir_entry(sh, ac_buf, de, str, pos);
|
||||
break;
|
||||
default:
|
||||
@stdio_read_line_autocomplete_list_dir_entries(sh, prompt, ac_buf, de, str, pos, word_count);
|
||||
break;
|
||||
}
|
||||
// Free @dir_entries
|
||||
while (de) {
|
||||
de2 = de;
|
||||
de = de->next;
|
||||
Free(de2);
|
||||
}
|
||||
}
|
||||
|
||||
U0 @stdio_read_line_autocomplete(@shell* sh, U8* prompt, U8* str, I64* pos)
|
||||
{
|
||||
U8 ac_buf[4096];
|
||||
I64 space_count = StrOcc(str, ' ');
|
||||
switch (space_count) {
|
||||
case 0:
|
||||
@stdio_read_line_autocompletion_from_cmd(sh, prompt, ac_buf, str, pos);
|
||||
break;
|
||||
default:
|
||||
// TODO: Handle completion for specific commands
|
||||
@stdio_read_line_autocompletion_from_dir_entry(sh, prompt, ac_buf, str, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user