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);