From 0676bd4afcdfa49f286370d3eba3936d9230fd40 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sat, 22 Aug 2020 13:48:02 +0430 Subject: [PATCH] Shell: Mark AST::Background as would_execute if its subnode does --- Shell/AST.cpp | 17 ++++++++++++++++- Shell/AST.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Shell/AST.cpp b/Shell/AST.cpp index 8fc57d9459..b7b1da69b2 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -336,7 +336,19 @@ void Background::dump(int level) const RefPtr Background::run(RefPtr shell) { - auto commands = m_command->run(shell)->resolve_as_commands(shell); + // FIXME: Currently this does not work correctly if `m_command.would_execute()', + // as it runs the node, which means nodes likes And and Or will evaluate + // all but their last subnode before yielding to this, causing a command + // like `foo && bar&` to effectively be `foo && (bar&)`. + auto value = m_command->run(shell)->resolve_without_cast(shell); + if (value->is_job()) { + auto job = static_cast(value.ptr())->job(); + job->set_running_in_background(true); + job->set_should_announce_exit(true); + return value; + } + + auto commands = value->resolve_as_commands(shell); auto& last = commands.last(); last.should_wait = false; @@ -1021,6 +1033,9 @@ void Execute::for_each_entry(RefPtr shell, Function Execute::run(RefPtr shell) { + if (m_command->would_execute()) + return m_command->run(shell); + NonnullRefPtrVector values; for_each_entry(shell, [&](auto value) { values.append(*value); diff --git a/Shell/AST.h b/Shell/AST.h index de0c139706..d7c793e7bd 100644 --- a/Shell/AST.h +++ b/Shell/AST.h @@ -458,6 +458,7 @@ private: virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override; virtual HitTestResult hit_test_position(size_t) override; virtual String class_name() const override { return "Background"; } + virtual bool would_execute() const override { return m_command->would_execute(); } RefPtr m_command; };