Use linenoise for user input

Change-Id: I7647cc2ec1eec9689cd1d2670d07731179554659
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23fff35..9864ce4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -113,6 +113,8 @@
     target_link_libraries(netconf-cli stdc++fs)
 endif()
 
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/linenoise)
+
 add_dependencies(netconf-cli target-NETCONF_CLI_VERSION)
 target_include_directories(netconf-cli PRIVATE ${PROJECT_BINARY_DIR})
 
diff --git a/src/main.cpp b/src/main.cpp
index f263b42..eaba76a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -9,6 +9,7 @@
 #include <docopt.h>
 #include <experimental/filesystem>
 #include <iostream>
+#include <linenoise.hpp>
 #include "NETCONF_CLI_VERSION.h"
 #include "interpreter.hpp"
 #include "sysrepo_access.hpp"
@@ -38,24 +39,28 @@
     Parser parser(datastore.schema());
 
     while (true) {
-        std::cout << parser.currentNode() << "> ";
-        std::string input;
-        std::getline(std::cin, input);
-        if (std::cin.eof())
+        linenoise::SetHistoryMaxLen(4);
+        linenoise::SetMultiLine(true);
+        std::string line;
+        auto quit = linenoise::Readline((parser.currentNode() + "> ").c_str(), line);
+        if (quit) {
             break;
+        }
 
         std::locale C_locale("C");
-        if (std::all_of(input.begin(), input.end(),
+        if (std::all_of(line.begin(), line.end(),
                         [C_locale](const auto c) { return std::isspace(c, C_locale);})) {
             continue;
         }
 
         try {
-            command_ cmd = parser.parseCommand(input, std::cout);
+            command_ cmd = parser.parseCommand(line, std::cout);
             boost::apply_visitor(Interpreter(parser, datastore), cmd);
         } catch (InvalidCommandException& ex) {
             std::cerr << ex.what() << std::endl;
         }
+
+        linenoise::AddHistory(line.c_str());
     }
 
     return 0;