Show current RPC input more clearly

Change-Id: Ibc1c8802b814bbe860b4af433c13c712a08fe3d5
diff --git a/src/cli.cpp b/src/cli.cpp
index a2c9cdc..5a9de67 100644
--- a/src/cli.cpp
+++ b/src/cli.cpp
@@ -6,6 +6,7 @@
  *
 */
 #include <atomic>
+#include <boost/algorithm/string.hpp>
 #include <docopt.h>
 #include <iostream>
 #include <optional>
@@ -227,7 +228,18 @@
     }
 
     while (backendReturnCode == 0) {
-        auto line = lineEditor.input(parser.currentNode() + "> ");
+        auto fullContextPath = parser.currentNode();
+        std::string prompt;
+        if (auto activeRpcPath = proxyDatastore.inputDatastorePath()) {
+            auto rpcPrefixLength = activeRpcPath->size();
+            prompt = "(prepare: " + *activeRpcPath + ") " + fullContextPath.substr(rpcPrefixLength);
+        } else {
+            prompt = fullContextPath;
+        }
+
+        prompt += "> ";
+
+        auto line = lineEditor.input(prompt);
         if (!line) {
             // If user pressed CTRL-C to abort the line, errno gets set to EAGAIN.
             // If user pressed CTRL-D (for EOF), errno doesn't get set to EAGAIN, so we exit the program.
diff --git a/src/proxy_datastore.cpp b/src/proxy_datastore.cpp
index ef3c5db..f212d45 100644
--- a/src/proxy_datastore.cpp
+++ b/src/proxy_datastore.cpp
@@ -62,7 +62,7 @@
 void ProxyDatastore::initiate(const std::string& path)
 {
     if (m_inputDatastore) {
-        throw std::runtime_error("RPC/action input already in progress (" + m_inputPath + ")");
+        throw std::runtime_error("RPC/action input already in progress (" + *m_inputPath + ")");
     }
     m_inputDatastore = m_createTemporaryDatastore(m_datastore);
     m_inputPath = path;
@@ -75,13 +75,17 @@
         throw std::runtime_error("No RPC/action input in progress");
     }
     auto inputData = m_inputDatastore->getItems("/");
-    m_inputDatastore = nullptr;
-    return m_datastore->execute(m_inputPath, inputData);
+
+    auto out = m_datastore->execute(*m_inputPath, inputData);
+    cancel();
+
+    return out;
 }
 
 void ProxyDatastore::cancel()
 {
     m_inputDatastore = nullptr;
+    m_inputPath = std::nullopt;
 }
 
 std::shared_ptr<Schema> ProxyDatastore::schema() const
@@ -89,9 +93,14 @@
     return m_datastore->schema();
 }
 
+std::optional<std::string> ProxyDatastore::inputDatastorePath()
+{
+    return m_inputPath;
+}
+
 std::shared_ptr<DatastoreAccess> ProxyDatastore::pickDatastore(const std::string& path) const
 {
-    if (!m_inputDatastore || !boost::starts_with(path, m_inputPath)) {
+    if (!m_inputDatastore || !boost::starts_with(path, *m_inputPath)) {
         return m_datastore;
     } else {
         return m_inputDatastore;
diff --git a/src/proxy_datastore.hpp b/src/proxy_datastore.hpp
index ab7e3a2..f084a2d 100644
--- a/src/proxy_datastore.hpp
+++ b/src/proxy_datastore.hpp
@@ -33,6 +33,8 @@
     [[nodiscard]] DatastoreAccess::Tree execute();
     void cancel();
 
+    std::optional<std::string> inputDatastorePath();
+
     [[nodiscard]] std::shared_ptr<Schema> schema() const;
 
 private:
@@ -47,5 +49,5 @@
     std::function<std::shared_ptr<DatastoreAccess>(const std::shared_ptr<DatastoreAccess>&)> m_createTemporaryDatastore;
     std::shared_ptr<DatastoreAccess> m_inputDatastore;
 
-    std::string m_inputPath;
+    std::optional<std::string> m_inputPath;
 };