Skip to content

Commit

Permalink
add automated usage mode to the repl
Browse files Browse the repository at this point in the history
This is definitely not a stable thing, but it does feel slightly crimes
to put it as an experimental feature. Shrug, up for bikeshedding.
  • Loading branch information
lf- committed Mar 6, 2024
1 parent 3e6c7d9 commit 47cce1e
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/libcmd/repl-interacter.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <cstdio>
#include <iostream>
#include <string>

#ifdef USE_READLINE
#include <readline/history.h>
Expand Down Expand Up @@ -183,4 +185,24 @@ ReadlineLikeInteracter::~ReadlineLikeInteracter()
write_history(historyFile.c_str());
}

AutomationInteracter::Guard AutomationInteracter::init(detail::ReplCompleterMixin *)
{
return Guard([] {});
}

// ASCII ENQ character
constexpr const char * automationPrompt = "\x05";

bool AutomationInteracter::getLine(std::string & input, ReplPromptType promptType)
{
std::cout << std::unitbuf;
std::cout << automationPrompt;
if (!std::getline(std::cin, input)) {
// reset failure bits on EOF
std::cin.clear();
return false;
}
return true;
}

};
9 changes: 9 additions & 0 deletions src/libcmd/repl-interacter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,13 @@ public:
virtual ~ReadlineLikeInteracter() override;
};

class AutomationInteracter : public virtual ReplInteracter
{
public:
AutomationInteracter() = default;
virtual Guard init(detail::ReplCompleterMixin * repl) override;
virtual bool getLine(std::string & input, ReplPromptType promptType) override;
virtual ~AutomationInteracter() override = default;
};

};
8 changes: 7 additions & 1 deletion src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,20 @@ std::string removeWhitespace(std::string s)
return s;
}

static box_ptr<ReplInteracter> makeInteractor() {
if (experimentalFeatureSettings.isEnabled(Xp::ReplAutomation))
return make_box_ptr<AutomationInteracter>();
else
return make_box_ptr<ReadlineLikeInteracter>(getDataDir() + "/nix/repl-history");
}

NixRepl::NixRepl(const SearchPath & searchPath, nix::ref<Store> store, ref<EvalState> state,
std::function<NixRepl::AnnotatedValues()> getValues)
: AbstractNixRepl(state)
, debugTraceIndex(0)
, getValues(getValues)
, staticEnv(new StaticEnv(nullptr, state->staticBaseEnv.get()))
, interacter(make_box_ptr<ReadlineLikeInteracter>(getDataDir() + "/nix/repl-history"))
, interacter(makeInteractor())
{
}

Expand Down
9 changes: 8 additions & 1 deletion src/libutil/experimental-features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct ExperimentalFeatureDetails
* feature, we either have no issue at all if few features are not added
* at the end of the list, or a proper merge conflict if they are.
*/
constexpr size_t numXpFeatures = 1 + static_cast<size_t>(Xp::VerifiedFetches);
constexpr size_t numXpFeatures = 1 + static_cast<size_t>(Xp::ReplAutomation);

constexpr std::array<ExperimentalFeatureDetails, numXpFeatures> xpFeatureDetails = {{
{
Expand Down Expand Up @@ -275,6 +275,13 @@ constexpr std::array<ExperimentalFeatureDetails, numXpFeatures> xpFeatureDetails
Enables verification of git commit signatures through the [`fetchGit`](@docroot@/language/builtins.md#builtins-fetchGit) built-in.
)",
},
{
.tag = Xp::ReplAutomation,
.name = "repl-automation",
.description = R"(
Makes the repl not use readline/editline, print ENQ (U+0005) when ready for a command, and take commands followed by newline.
)",
},
}};

static_assert(
Expand Down
1 change: 1 addition & 0 deletions src/libutil/experimental-features.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum struct ExperimentalFeature
ConfigurableImpureEnv,
MountedSSHStore,
VerifiedFetches,
ReplAutomation,
};

/**
Expand Down

0 comments on commit 47cce1e

Please sign in to comment.