mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-25 03:00:49 +00:00
96 lines
2.0 KiB
C++
96 lines
2.0 KiB
C++
|
#include <common/LineReader.h>
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
|
||
|
/// Trim ending whitespace inplace
|
||
|
void trim(String & s)
|
||
|
{
|
||
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }).base(), s.end());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
LineReader::LineReader(const String & history_file_path_, char extender_, char delimiter_)
|
||
|
: history_file_path(history_file_path_), extender(extender_), delimiter(delimiter_)
|
||
|
{
|
||
|
#ifdef USE_REPLXX
|
||
|
if (!history_file_path.empty())
|
||
|
rx.history_load(history_file_path);
|
||
|
#endif
|
||
|
/// FIXME: check extender != delimiter
|
||
|
}
|
||
|
|
||
|
LineReader::~LineReader()
|
||
|
{
|
||
|
#ifdef USE_REPLXX
|
||
|
if (!history_file_path.empty())
|
||
|
rx.history_save(history_file_path);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
String LineReader::readLine(const String & first_prompt, const String & second_prompt)
|
||
|
{
|
||
|
String line;
|
||
|
bool is_multiline = false;
|
||
|
|
||
|
while (readOneLine(is_multiline ? second_prompt : first_prompt))
|
||
|
{
|
||
|
if (input.empty())
|
||
|
continue;
|
||
|
|
||
|
is_multiline = (input.back() == extender) || (delimiter && input.back() != delimiter);
|
||
|
|
||
|
if (input.back() == extender)
|
||
|
{
|
||
|
input = input.substr(0, input.size() - 1);
|
||
|
trim(input);
|
||
|
if (input.empty())
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
line += (line.empty() ? "" : " ") + input;
|
||
|
|
||
|
if (!is_multiline)
|
||
|
{
|
||
|
if (line != prev_line)
|
||
|
{
|
||
|
addToHistory(line);
|
||
|
prev_line = line;
|
||
|
}
|
||
|
|
||
|
return line;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
bool LineReader::readOneLine(const String & prompt)
|
||
|
{
|
||
|
#ifdef USE_REPLXX
|
||
|
const char* cinput = rx.input(prompt);
|
||
|
if (cinput == nullptr && errno != EAGAIN)
|
||
|
return false;
|
||
|
input = cinput;
|
||
|
#else
|
||
|
std::cout << prompt;
|
||
|
std::getline(std::cin, input);
|
||
|
if (!std::cin.good())
|
||
|
return false;
|
||
|
#endif
|
||
|
trim(input);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void LineReader::addToHistory(const String & line)
|
||
|
{
|
||
|
#ifdef USE_REPLXX
|
||
|
rx.history_add(line);
|
||
|
/// TODO: implement this.
|
||
|
#endif
|
||
|
}
|