From d69691a26b8833a56aeccd23e6e4b75b0b8a0798 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 1 Jul 2021 10:15:53 -0400 Subject: [PATCH] Assistant: Add provider to run a command in a terminal Prefix text with "$" in the Assistant text box to run a command in a forked terminal. For example, "$ top" or "$ top -s pid". --- Userland/Applications/Assistant/Providers.cpp | 30 ++++++++++++++++++- Userland/Applications/Assistant/Providers.h | 25 ++++++++++++---- Userland/Applications/Assistant/main.cpp | 5 ++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Userland/Applications/Assistant/Providers.cpp b/Userland/Applications/Assistant/Providers.cpp index a133f2a3de..0873bf91c6 100644 --- a/Userland/Applications/Assistant/Providers.cpp +++ b/Userland/Applications/Assistant/Providers.cpp @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include #include namespace Assistant { @@ -41,6 +44,19 @@ 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(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())); @@ -48,7 +64,7 @@ void URLResult::activate() const void AppProvider::query(String const& query, Function>)> on_complete) { - if (query.starts_with("=")) + if (query.starts_with("=") || query.starts_with('$')) return; Vector> results; @@ -156,6 +172,18 @@ void FileProvider::build_filesystem_cache() return 0; }, [this](auto) { m_building_cache = false; }); } +void TerminalProvider::query(String const& query, Function>)> on_complete) +{ + if (!query.starts_with('$')) + return; + + auto command = query.substring(1); + + Vector> results; + results.append(adopt_ref(*new TerminalResult(move(command)))); + on_complete(results); +} + void URLProvider::query(String const& query, Function>)> on_complete) { URL url = URL(query); diff --git a/Userland/Applications/Assistant/Providers.h b/Userland/Applications/Assistant/Providers.h index edc1af19f6..e8be8deb1b 100644 --- a/Userland/Applications/Assistant/Providers.h +++ b/Userland/Applications/Assistant/Providers.h @@ -85,6 +85,16 @@ public: 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) @@ -99,31 +109,36 @@ class Provider { public: virtual ~Provider() = default; - virtual void query(const String&, Function>)> on_complete) = 0; + virtual void query(const String&, Function)> on_complete) = 0; }; class AppProvider : public Provider { public: - void query(String const& query, Function>)> on_complete) override; + void query(String const& query, Function)> on_complete) override; }; class CalculatorProvider : public Provider { public: - void query(String const& query, Function>)> on_complete) override; + void query(String const& query, Function)> on_complete) override; }; class FileProvider : public Provider { public: - void query(String const& query, Function>)> on_complete) override; + void query(String const& query, Function)> on_complete) override; void build_filesystem_cache(); private: - RefPtr>>> m_fuzzy_match_work; + RefPtr>> m_fuzzy_match_work; bool m_building_cache { false }; Vector m_full_path_cache; Queue m_work_queue; }; +class TerminalProvider : public Provider { +public: + void query(String const& query, Function)> on_complete) override; +}; + class URLProvider : public Provider { public: void query(String const& query, Function>)> on_complete) override; diff --git a/Userland/Applications/Assistant/main.cpp b/Userland/Applications/Assistant/main.cpp index 6427fe1c3e..8140c23caf 100644 --- a/Userland/Applications/Assistant/main.cpp +++ b/Userland/Applications/Assistant/main.cpp @@ -139,6 +139,10 @@ public: 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); }); @@ -182,6 +186,7 @@ private: AppProvider m_app_provider; CalculatorProvider m_calculator_provider; FileProvider m_file_provider; + TerminalProvider m_terminal_provider; URLProvider m_url_provider; Threading::Lock m_lock;