Skip to content

Commit

Permalink
Assistant: Add provider to run a command in a terminal
Browse files Browse the repository at this point in the history
Prefix text with "$" in the Assistant text box to run a command in a
forked terminal. For example, "$ top" or "$ top -s pid".
  • Loading branch information
trflynn89 authored and gunnarbeutner committed Jul 3, 2021
1 parent d5dfc25 commit d69691a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
30 changes: 29 additions & 1 deletion Userland/Applications/Assistant/Providers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include <LibJS/Lexer.h>
#include <LibJS/Parser.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <errno.h>
#include <serenity.h>
#include <spawn.h>
#include <unistd.h>

namespace Assistant {
Expand All @@ -41,14 +44,27 @@ void FileResult::activate() const
Desktop::Launcher::open(URL::create_with_file_protocol(title()));
}

void TerminalResult::activate() const
{
pid_t pid;
char const* argv[] = { "Terminal", "-e", title().characters(), nullptr };

if ((errno = posix_spawn(&pid, "/bin/Terminal", nullptr, nullptr, const_cast<char**>(argv), environ))) {
perror("posix_spawn");
} else {
if (disown(pid) < 0)
perror("disown");
}
}

void URLResult::activate() const
{
Desktop::Launcher::open(URL::create_with_url_or_path(title()));
}

void AppProvider::query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete)
{
if (query.starts_with("="))
if (query.starts_with("=") || query.starts_with('$'))
return;

Vector<NonnullRefPtr<Result>> results;
Expand Down Expand Up @@ -156,6 +172,18 @@ void FileProvider::build_filesystem_cache()
return 0; }, [this](auto) { m_building_cache = false; });
}

void TerminalProvider::query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete)
{
if (!query.starts_with('$'))
return;

auto command = query.substring(1);

Vector<NonnullRefPtr<Result>> results;
results.append(adopt_ref(*new TerminalResult(move(command))));
on_complete(results);
}

void URLProvider::query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete)
{
URL url = URL(query);
Expand Down
25 changes: 20 additions & 5 deletions Userland/Applications/Assistant/Providers.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ class FileResult : public Result {
void activate() const override;
};

class TerminalResult : public Result {
public:
explicit TerminalResult(String command)
: Result(GUI::Icon::default_icon("app-terminal").bitmap_for_size(16), move(command), "Run command in Terminal"sv, 100)
{
}
~TerminalResult() override = default;
void activate() const override;
};

class URLResult : public Result {
public:
explicit URLResult(const URL& url)
Expand All @@ -99,31 +109,36 @@ class Provider {
public:
virtual ~Provider() = default;

virtual void query(const String&, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete) = 0;
virtual void query(const String&, Function<void(NonnullRefPtrVector<Result>)> on_complete) = 0;
};

class AppProvider : public Provider {
public:
void query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete) override;
void query(String const& query, Function<void(NonnullRefPtrVector<Result>)> on_complete) override;
};

class CalculatorProvider : public Provider {
public:
void query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete) override;
void query(String const& query, Function<void(NonnullRefPtrVector<Result>)> on_complete) override;
};

class FileProvider : public Provider {
public:
void query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete) override;
void query(String const& query, Function<void(NonnullRefPtrVector<Result>)> on_complete) override;
void build_filesystem_cache();

private:
RefPtr<Threading::BackgroundAction<Vector<NonnullRefPtr<Result>>>> m_fuzzy_match_work;
RefPtr<Threading::BackgroundAction<NonnullRefPtrVector<Result>>> m_fuzzy_match_work;
bool m_building_cache { false };
Vector<String> m_full_path_cache;
Queue<String> m_work_queue;
};

class TerminalProvider : public Provider {
public:
void query(String const& query, Function<void(NonnullRefPtrVector<Result>)> on_complete) override;
};

class URLProvider : public Provider {
public:
void query(String const& query, Function<void(Vector<NonnullRefPtr<Result>>)> on_complete) override;
Expand Down
5 changes: 5 additions & 0 deletions Userland/Applications/Assistant/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ class Database {
recv_results(query, results);
});

m_terminal_provider.query(query, [=, this](auto results) {
recv_results(query, results);
});

m_url_provider.query(query, [=, this](auto results) {
recv_results(query, results);
});
Expand Down Expand Up @@ -182,6 +186,7 @@ class Database {
AppProvider m_app_provider;
CalculatorProvider m_calculator_provider;
FileProvider m_file_provider;
TerminalProvider m_terminal_provider;
URLProvider m_url_provider;

Threading::Lock m_lock;
Expand Down

0 comments on commit d69691a

Please sign in to comment.