diff --git a/cmake/Modules/FindReadline.cmake b/cmake/Modules/FindReadline.cmake
new file mode 100644
index 0000000..745cfe5
--- /dev/null
+++ b/cmake/Modules/FindReadline.cmake
@@ -0,0 +1,47 @@
+# - Try to find readline include dirs and libraries
+#
+# Usage of this module as follows:
+#
+# find_package(Readline)
+#
+# Variables used by this module, they can change the default behaviour and need
+# to be set before calling find_package:
+#
+# Readline_ROOT_DIR Set this variable to the root installation of
+# readline if the module has problems finding the
+# proper installation path.
+#
+# Variables defined by this module:
+#
+# READLINE_FOUND System has readline, include and lib dirs found
+# Readline_INCLUDE_DIR The readline include directories.
+# Readline_LIBRARY The readline library.
+
+find_path(Readline_ROOT_DIR
+ NAMES include/readline/readline.h
+)
+
+find_path(Readline_INCLUDE_DIR
+ NAMES readline/readline.h
+ HINTS ${Readline_ROOT_DIR}/include
+)
+
+find_library(Readline_LIBRARY
+ NAMES readline
+ HINTS ${Readline_ROOT_DIR}/lib
+)
+
+if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
+ set(READLINE_FOUND TRUE)
+else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
+ FIND_LIBRARY(Readline_LIBRARY NAMES readline)
+ include(FindPackageHandleStandardArgs)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY )
+ MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY)
+endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
+
+mark_as_advanced(
+ Readline_ROOT_DIR
+ Readline_INCLUDE_DIR
+ Readline_LIBRARY
+)
diff --git a/src/navigate/CMakeLists.txt b/src/navigate/CMakeLists.txt
index 8bb77d5..c8ebf9c 100644
--- a/src/navigate/CMakeLists.txt
+++ b/src/navigate/CMakeLists.txt
@@ -1,20 +1,27 @@
project(${bare_name}-navigate CXX)
+find_package(Readline 6.3 REQUIRED)
+
add_executable(${PROJECT_NAME}
main.cpp
commandline.cpp
commandprocessor.cpp
genericpath.cpp
dbsource.cpp
+ linereader.cpp
)
target_include_directories(${PROJECT_NAME}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
)
+target_include_directories(${PROJECT_NAME} SYSTEM
+ PRIVATE ${Readline_INCLUDE_DIR}
+)
target_link_libraries(${PROJECT_NAME}
PRIVATE ${bare_name}-if
PRIVATE ${bare_name}-common
+ PRIVATE ${Readline_LIBRARY}
)
string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}")
diff --git a/src/navigate/linereader.cpp b/src/navigate/linereader.cpp
new file mode 100644
index 0000000..807845b
--- /dev/null
+++ b/src/navigate/linereader.cpp
@@ -0,0 +1,44 @@
+/* Copyright 2015, 2016, Michele Santullo
+ * This file is part of "dindexer".
+ *
+ * "dindexer" is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * "dindexer" is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with "dindexer". If not, see .
+ */
+
+#include "linereader.hpp"
+#include
+#include
+#include
+#include
+#include
+
+namespace din {
+ LineReader::LineReader() {
+ }
+
+ std::string LineReader::read (const std::string& parMessage) {
+ typedef std::unique_ptr RawCharMemory;
+
+ RawCharMemory line(readline(parMessage.c_str()), &std::free);
+
+ if (line) {
+ if (*line) {
+ add_history(line.get());
+ }
+ return std::string(line.get());
+ }
+ else {
+ return std::string();
+ }
+ }
+} //namespace din
diff --git a/src/navigate/linereader.hpp b/src/navigate/linereader.hpp
new file mode 100644
index 0000000..2a7b8cf
--- /dev/null
+++ b/src/navigate/linereader.hpp
@@ -0,0 +1,33 @@
+/* Copyright 2015, 2016, Michele Santullo
+ * This file is part of "dindexer".
+ *
+ * "dindexer" is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * "dindexer" is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with "dindexer". If not, see .
+ */
+
+#ifndef idBB92A7743E75400CBA486A241F13D35C
+#define idBB92A7743E75400CBA486A241F13D35C
+
+#include
+
+namespace din {
+ class LineReader {
+ public:
+ LineReader ( void );
+ ~LineReader ( void ) noexcept = default;
+
+ std::string read ( const std::string& parMessage );
+ };
+} //namespace din
+
+#endif
diff --git a/src/navigate/main.cpp b/src/navigate/main.cpp
index bccd822..f4e9754 100644
--- a/src/navigate/main.cpp
+++ b/src/navigate/main.cpp
@@ -22,6 +22,7 @@
#include "dbsource.hpp"
#include "dindexerConfig.h"
#include "helpers/infix_iterator.hpp"
+#include "linereader.hpp"
#include
#include
#include
@@ -104,7 +105,8 @@ namespace {
}
void do_navigation (din::DBSource& parDB) {
- auto& inp = std::cin;
+ const std::string prompt;
+ din::LineReader lines;
bool running = true;
std::string curr_line;
@@ -117,7 +119,7 @@ namespace {
proc.add_command("ls", std::function(std::bind(&on_ls, std::ref(dir_man), std::ref(parDB))), 0);
do {
do {
- std::getline(inp, curr_line);
+ curr_line = lines.read(prompt);
} while (curr_line.empty());
running = proc.exec_command(curr_line);
} while (running);