mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Shell: Move everything to the Shell namespace
Also provide a basic default-constructor.
This commit is contained in:
parent
34039d6639
commit
f164b808b5
Notes:
sideshowbarker
2024-07-19 02:03:08 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/f164b808b5a Pull-request: https://github.com/SerenityOS/serenity/pull/3675 Reviewed-by: https://github.com/awesomekling
17 changed files with 115 additions and 17 deletions
|
@ -33,6 +33,8 @@
|
|||
|
||||
namespace GUI {
|
||||
|
||||
using namespace Shell;
|
||||
|
||||
enum class AugmentedTokenKind : u32 {
|
||||
__TokenTypeCount = (u32)AST::Node::Kind::__Count,
|
||||
OpenParen,
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
//#define EXECUTE_DEBUG
|
||||
|
||||
namespace AST {
|
||||
namespace Shell::AST {
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static inline NonnullRefPtr<T> create(Args... args)
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <LibLine/Editor.h>
|
||||
|
||||
namespace AST {
|
||||
namespace Shell::AST {
|
||||
|
||||
struct HighlightMetadata {
|
||||
bool is_first_in_list { true };
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
extern char** environ;
|
||||
|
||||
namespace Shell {
|
||||
|
||||
int Shell::builtin_alias(int argc, const char** argv)
|
||||
{
|
||||
Vector<const char*> arguments;
|
||||
|
@ -806,3 +808,5 @@ bool Shell::has_builtin(const StringView& name) const
|
|||
#undef __ENUMERATE_SHELL_BUILTIN
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <LibCore/ElapsedTimer.h>
|
||||
|
||||
namespace Shell {
|
||||
|
||||
class FileDescriptionCollector {
|
||||
public:
|
||||
FileDescriptionCollector() { }
|
||||
|
@ -59,3 +61,5 @@ private:
|
|||
Vector<SavedFileDescriptor> m_saves;
|
||||
FileDescriptionCollector m_collector;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "Parser.h"
|
||||
#include <AK/TemporaryChange.h>
|
||||
|
||||
namespace Shell {
|
||||
|
||||
String Formatter::format()
|
||||
{
|
||||
auto node = Parser(m_source).parse();
|
||||
|
@ -595,3 +597,5 @@ void Formatter::visit(const AST::WriteRedirection* node)
|
|||
current_builder().append(" >");
|
||||
NodeVisitor::visit(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <ctype.h>
|
||||
|
||||
namespace Shell {
|
||||
|
||||
class Formatter final : public AST::NodeVisitor {
|
||||
public:
|
||||
Formatter(const StringView& source, ssize_t cursor = -1)
|
||||
|
@ -119,3 +121,5 @@ private:
|
|||
|
||||
StringView m_trivia;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
class Shell;
|
||||
namespace AST {
|
||||
namespace Shell::AST {
|
||||
|
||||
struct Command;
|
||||
class Node;
|
||||
|
@ -75,3 +74,9 @@ class WriteAppendRedirection;
|
|||
class WriteRedirection;
|
||||
|
||||
}
|
||||
|
||||
namespace Shell {
|
||||
|
||||
class Shell;
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
namespace Shell {
|
||||
|
||||
bool Job::print_status(PrintStatusMode mode)
|
||||
{
|
||||
int wstatus;
|
||||
|
@ -110,3 +112,5 @@ void Job::unblock() const
|
|||
if (!m_exited && on_exit)
|
||||
on_exit(*this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
# undef JOB_TIME_INFO
|
||||
#endif
|
||||
|
||||
namespace Shell {
|
||||
|
||||
struct LocalFrame;
|
||||
|
||||
class Job : public RefCounted<Job> {
|
||||
|
@ -127,3 +129,5 @@ private:
|
|||
bool m_should_be_disowned { false };
|
||||
OwnPtr<AST::Command> m_command;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "NodeVisitor.h"
|
||||
#include "AST.h"
|
||||
|
||||
namespace AST {
|
||||
namespace Shell::AST {
|
||||
|
||||
void NodeVisitor::visit(const AST::PathRedirectionNode* node)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "Forward.h"
|
||||
|
||||
namespace AST {
|
||||
namespace Shell::AST {
|
||||
|
||||
class NodeVisitor {
|
||||
public:
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace Shell {
|
||||
|
||||
Parser::SavedOffset Parser::save_offset() const
|
||||
{
|
||||
return { m_offset, m_line };
|
||||
|
@ -1350,3 +1352,5 @@ StringView Parser::consume_while(Function<bool(char)> condition)
|
|||
|
||||
return m_input.substring_view(start_offset, m_offset - start_offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
namespace Shell {
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
Parser(StringView input)
|
||||
|
@ -232,3 +234,5 @@ glob :: [*?] bareword?
|
|||
| bareword [*?]
|
||||
)";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ extern char** environ;
|
|||
|
||||
//#define SH_DEBUG
|
||||
|
||||
namespace Shell {
|
||||
|
||||
// FIXME: This should eventually be removed once we've established that
|
||||
// waitpid() is not passed the same job twice.
|
||||
#ifdef __serenity__
|
||||
|
@ -523,6 +525,10 @@ bool Shell::is_runnable(const StringView& name)
|
|||
|
||||
int Shell::run_command(const StringView& cmd)
|
||||
{
|
||||
// The default-constructed mode of the shell
|
||||
// should not be used for execution!
|
||||
ASSERT(!m_default_constructed);
|
||||
|
||||
if (cmd.is_empty())
|
||||
return 0;
|
||||
|
||||
|
@ -1158,6 +1164,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base, cons
|
|||
// since we are not suggesting anything starting with
|
||||
// `/foo/', but rather just `bar...'
|
||||
auto token_length = escape_token(token).length();
|
||||
if (m_editor)
|
||||
m_editor->suggest(token_length, original_token.length() - token_length);
|
||||
|
||||
// only suggest dot-files if path starts with a dot
|
||||
|
@ -1195,6 +1202,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_program_name(const String& na
|
|||
return complete_path("", name, offset);
|
||||
|
||||
String completion = *match;
|
||||
if (m_editor)
|
||||
m_editor->suggest(escape_token(name).length(), 0);
|
||||
|
||||
// Now that we have a program name starting with our token, we look at
|
||||
|
@ -1220,6 +1228,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_variable(const String& name,
|
|||
Vector<Line::CompletionSuggestion> suggestions;
|
||||
auto pattern = offset ? name.substring_view(0, offset) : "";
|
||||
|
||||
if (m_editor)
|
||||
m_editor->suggest(offset);
|
||||
|
||||
// Look at local variables.
|
||||
|
@ -1252,6 +1261,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_user(const String& name, size
|
|||
Vector<Line::CompletionSuggestion> suggestions;
|
||||
auto pattern = offset ? name.substring_view(0, offset) : "";
|
||||
|
||||
if (m_editor)
|
||||
m_editor->suggest(offset);
|
||||
|
||||
Core::DirIterator di("/home", Core::DirIterator::SkipParentAndBaseDir);
|
||||
|
@ -1274,6 +1284,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_
|
|||
while (start < option.length() && option[start] == '-' && start < 2)
|
||||
++start;
|
||||
auto option_pattern = offset > start ? option.substring_view(start, offset - start) : "";
|
||||
if (m_editor)
|
||||
m_editor->suggest(offset);
|
||||
|
||||
Vector<Line::CompletionSuggestion> suggestions;
|
||||
|
@ -1459,6 +1470,42 @@ void Shell::notify_child_event()
|
|||
} while (!found_child);
|
||||
}
|
||||
|
||||
Shell::Shell()
|
||||
: m_default_constructed(true)
|
||||
{
|
||||
push_frame().leak_frame();
|
||||
|
||||
int rc = gethostname(hostname, Shell::HostNameSize);
|
||||
if (rc < 0)
|
||||
perror("gethostname");
|
||||
|
||||
{
|
||||
auto* pw = getpwuid(getuid());
|
||||
if (pw) {
|
||||
username = pw->pw_name;
|
||||
home = pw->pw_dir;
|
||||
setenv("HOME", pw->pw_dir, 1);
|
||||
}
|
||||
endpwent();
|
||||
}
|
||||
|
||||
// For simplicity, start at the user's home directory.
|
||||
this->cwd = home;
|
||||
setenv("PWD", home.characters(), 1);
|
||||
|
||||
// Add the default PATH vars.
|
||||
{
|
||||
StringBuilder path;
|
||||
path.append(getenv("PATH"));
|
||||
if (path.length())
|
||||
path.append(":");
|
||||
path.append("/bin:/usr/bin:/usr/local/bin");
|
||||
setenv("PATH", path.to_string().characters(), true);
|
||||
}
|
||||
|
||||
cache_path();
|
||||
}
|
||||
|
||||
Shell::Shell(Line::Editor& editor)
|
||||
: m_editor(editor)
|
||||
{
|
||||
|
@ -1507,6 +1554,9 @@ Shell::Shell(Line::Editor& editor)
|
|||
|
||||
Shell::~Shell()
|
||||
{
|
||||
if (m_default_constructed)
|
||||
return;
|
||||
|
||||
stop_all_jobs();
|
||||
save_history();
|
||||
}
|
||||
|
@ -1641,3 +1691,5 @@ SavedFileDescriptors::~SavedFileDescriptors()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
__ENUMERATE_SHELL_OPTION(inline_exec_keep_empty_segments, false, "Keep empty segments in inline execute $(...)") \
|
||||
__ENUMERATE_SHELL_OPTION(verbose, false, "Announce every command that is about to be executed")
|
||||
|
||||
namespace Shell {
|
||||
|
||||
class Shell;
|
||||
|
||||
class Shell : public Core::Object {
|
||||
|
@ -199,6 +201,7 @@ public:
|
|||
|
||||
private:
|
||||
Shell(Line::Editor&);
|
||||
Shell();
|
||||
virtual ~Shell() override;
|
||||
|
||||
// FIXME: Port to Core::Property
|
||||
|
@ -252,9 +255,13 @@ private:
|
|||
bool m_should_format_live { false };
|
||||
|
||||
RefPtr<Line::Editor> m_editor;
|
||||
|
||||
bool m_default_constructed { false };
|
||||
};
|
||||
|
||||
static constexpr bool is_word_character(char c)
|
||||
{
|
||||
return c == '_' || (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <string.h>
|
||||
|
||||
RefPtr<Line::Editor> editor;
|
||||
Shell* s_shell;
|
||||
Shell::Shell* s_shell;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ int main(int argc, char** argv)
|
|||
|
||||
editor = Line::Editor::construct();
|
||||
|
||||
auto shell = Shell::construct(*editor);
|
||||
auto shell = Shell::Shell::construct(*editor);
|
||||
s_shell = shell.ptr();
|
||||
|
||||
s_shell->setup_signals();
|
||||
|
@ -163,15 +163,15 @@ int main(int argc, char** argv)
|
|||
shell->run_file(file_path, false);
|
||||
}
|
||||
};
|
||||
run_rc_file(Shell::global_init_file_path);
|
||||
run_rc_file(Shell::local_init_file_path);
|
||||
run_rc_file(Shell::Shell::global_init_file_path);
|
||||
run_rc_file(Shell::Shell::local_init_file_path);
|
||||
}
|
||||
|
||||
{
|
||||
Vector<String> args;
|
||||
for (auto* arg : script_args)
|
||||
args.empend(arg);
|
||||
shell->set_local_variable("ARGV", adopt(*new AST::ListValue(move(args))));
|
||||
shell->set_local_variable("ARGV", adopt(*new Shell::AST::ListValue(move(args))));
|
||||
}
|
||||
|
||||
if (command_to_run) {
|
||||
|
@ -188,7 +188,7 @@ int main(int argc, char** argv)
|
|||
|
||||
shell->add_child(*editor);
|
||||
|
||||
Core::EventLoop::current().post_event(*shell, make<Core::CustomEvent>(Shell::ShellEventType::ReadLine));
|
||||
Core::EventLoop::current().post_event(*shell, make<Core::CustomEvent>(Shell::Shell::ShellEventType::ReadLine));
|
||||
|
||||
return loop.exec();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue