Kernel: Shell now somewhat functions again
I will not be fixing the shell implementation until I get to userspace
This commit is contained in:
parent
5db4e5b4d5
commit
e84f613c4d
|
@ -59,6 +59,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
MUST(set_prompt(s_default_prompt));
|
MUST(set_prompt(s_default_prompt));
|
||||||
MUST(m_buffer.push_back(""sv));
|
MUST(m_buffer.push_back(""sv));
|
||||||
|
MUST(Process::current()->set_termios(termios { .canonical = false, .echo = false }));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Shell::set_prompt(BAN::StringView prompt)
|
BAN::ErrorOr<void> Shell::set_prompt(BAN::StringView prompt)
|
||||||
|
@ -111,21 +112,83 @@ namespace Kernel
|
||||||
|
|
||||||
void Shell::run()
|
void Shell::run()
|
||||||
{
|
{
|
||||||
|
auto getch = [this] { uint8_t ch; MUST(Process::current()->read(STDIN_FILENO, &ch, 1)); return ch; };
|
||||||
|
|
||||||
|
MUST(m_buffer.push_back(""sv));
|
||||||
|
|
||||||
TTY_PRINT("{}", m_prompt);
|
TTY_PRINT("{}", m_prompt);
|
||||||
BAN::String input;
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
char buffer[128];
|
BAN::String& current = m_buffer[m_cursor_pos.line];
|
||||||
size_t n_read = MUST(Process::current()->read(STDIN_FILENO, buffer, sizeof(buffer)));
|
|
||||||
|
|
||||||
MUST(input.append(BAN::StringView(buffer, n_read)));
|
uint8_t ch = getch();
|
||||||
if (input.back() == '\n')
|
|
||||||
|
if (ch == '\b')
|
||||||
{
|
{
|
||||||
input.pop_back();
|
if (!current.empty())
|
||||||
if (auto res = process_command(parse_arguments(input)); res.is_error())
|
{
|
||||||
TTY_PRINTLN("{}", res.error());
|
while ((current.back() & 0xC0) == 0x80)
|
||||||
TTY_PRINT("{}", m_prompt);
|
current.pop_back();
|
||||||
input.clear();
|
current.pop_back();
|
||||||
|
MUST(Process::current()->write(STDOUT_FILENO, "\b \b", 3));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == '\e')
|
||||||
|
{
|
||||||
|
bool handled = false;
|
||||||
|
if (getch() == '[')
|
||||||
|
{
|
||||||
|
handled = true;
|
||||||
|
switch (getch())
|
||||||
|
{
|
||||||
|
case 'A': // Up
|
||||||
|
if (m_cursor_pos.line > 0)
|
||||||
|
{
|
||||||
|
m_cursor_pos.line--;
|
||||||
|
TTY_PRINT("\e[G{}{}\e[K", m_prompt, m_buffer[m_cursor_pos.line]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'B': // Down
|
||||||
|
if (m_cursor_pos.line < m_buffer.size() - 1)
|
||||||
|
{
|
||||||
|
m_cursor_pos.line++;
|
||||||
|
TTY_PRINT("\e[G{}{}\e[K", m_prompt, m_buffer[m_cursor_pos.line]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C': // Right
|
||||||
|
break;
|
||||||
|
case 'D': // Left
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled)
|
||||||
|
while (!isalpha(ch))
|
||||||
|
ch = getch();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MUST(Process::current()->write(STDOUT_FILENO, &ch, 1));
|
||||||
|
|
||||||
|
if (ch != '\n')
|
||||||
|
{
|
||||||
|
MUST(current.push_back(ch));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto res = process_command(parse_arguments(current)); res.is_error())
|
||||||
|
TTY_PRINTLN("{}", res.error());
|
||||||
|
TTY_PRINT("{}", m_prompt);
|
||||||
|
|
||||||
|
if (!current.empty())
|
||||||
|
{
|
||||||
|
MUST(m_old_buffer.push_back(current));
|
||||||
|
m_buffer = m_old_buffer;
|
||||||
|
MUST(m_buffer.push_back(""sv));
|
||||||
|
m_cursor_pos.line = m_buffer.size() - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
#include <kernel/Terminal/TTY.h>
|
#include <kernel/Terminal/TTY.h>
|
||||||
#include <kernel/Terminal/VesaTerminalDriver.h>
|
#include <kernel/Terminal/VesaTerminalDriver.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
extern "C" const char g_kernel_cmdline[];
|
extern "C" const char g_kernel_cmdline[];
|
||||||
|
|
||||||
struct ParsedCommandLine
|
struct ParsedCommandLine
|
||||||
|
|
Loading…
Reference in New Issue