2019-12-26 15:30:25 +00:00
|
|
|
#pragma once
|
|
|
|
|
2024-06-25 14:23:37 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <unistd.h>
|
2022-01-18 18:03:51 +00:00
|
|
|
#include <mutex>
|
2020-01-10 13:26:23 +00:00
|
|
|
#include <atomic>
|
2020-01-01 19:22:57 +00:00
|
|
|
#include <vector>
|
2020-09-28 09:58:42 +00:00
|
|
|
#include <optional>
|
2022-01-24 20:04:48 +00:00
|
|
|
#include <replxx.hxx>
|
2020-01-01 19:22:57 +00:00
|
|
|
|
2022-01-18 18:03:51 +00:00
|
|
|
#include <base/types.h>
|
2022-06-14 22:35:55 +00:00
|
|
|
#include <base/defines.h>
|
2022-01-18 18:03:51 +00:00
|
|
|
|
2022-12-10 10:16:31 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-12-26 15:30:25 +00:00
|
|
|
class LineReader
|
|
|
|
{
|
|
|
|
public:
|
2020-02-25 08:30:11 +00:00
|
|
|
struct Suggest
|
2020-01-01 19:22:57 +00:00
|
|
|
{
|
|
|
|
using Words = std::vector<std::string>;
|
2023-04-27 00:11:45 +00:00
|
|
|
using Callback = std::function<Words(const String & prefix, size_t prefix_length)>;
|
2020-01-01 19:22:57 +00:00
|
|
|
|
2022-01-18 18:03:51 +00:00
|
|
|
/// Get vector for the matched range of words if any.
|
2023-08-04 07:20:01 +00:00
|
|
|
replxx::Replxx::completions_t getCompletions(const String & prefix, size_t prefix_length, const char * word_break_characters);
|
2022-01-18 18:03:51 +00:00
|
|
|
void addWords(Words && new_words);
|
|
|
|
|
2023-04-27 00:11:45 +00:00
|
|
|
void setCompletionsCallback(Callback && callback) { custom_completions_callback = callback; }
|
|
|
|
|
2022-01-18 18:03:51 +00:00
|
|
|
private:
|
2022-06-14 22:35:55 +00:00
|
|
|
Words words TSA_GUARDED_BY(mutex);
|
|
|
|
Words words_no_case TSA_GUARDED_BY(mutex);
|
2020-01-01 19:22:57 +00:00
|
|
|
|
2023-04-27 00:11:45 +00:00
|
|
|
Callback custom_completions_callback = nullptr;
|
|
|
|
|
2022-01-18 18:03:51 +00:00
|
|
|
std::mutex mutex;
|
2020-01-01 19:22:57 +00:00
|
|
|
};
|
|
|
|
|
2020-06-02 03:25:19 +00:00
|
|
|
using Patterns = std::vector<const char *>;
|
|
|
|
|
2024-06-25 14:23:37 +00:00
|
|
|
LineReader(
|
|
|
|
const String & history_file_path,
|
|
|
|
bool multiline,
|
|
|
|
Patterns extenders,
|
|
|
|
Patterns delimiters,
|
|
|
|
std::istream & input_stream_ = std::cin,
|
|
|
|
std::ostream & output_stream_ = std::cout,
|
2024-07-15 03:13:38 +00:00
|
|
|
int in_fd_ = STDIN_FILENO);
|
2024-06-25 14:23:37 +00:00
|
|
|
|
2022-06-14 22:35:55 +00:00
|
|
|
virtual ~LineReader() = default;
|
2019-12-26 15:30:25 +00:00
|
|
|
|
|
|
|
/// Reads the whole line until delimiter (in multiline mode) or until the last line without extender.
|
|
|
|
/// If resulting line is empty, it means the user interrupted the input.
|
|
|
|
/// Non-empty line is appended to history - without duplication.
|
|
|
|
/// Typical delimiter is ';' (semicolon) and typical extender is '\' (backslash).
|
|
|
|
String readLine(const String & first_prompt, const String & second_prompt);
|
|
|
|
|
2020-02-25 08:30:11 +00:00
|
|
|
/// When bracketed paste mode is set, pasted text is bracketed with control sequences so
|
|
|
|
/// that the program can differentiate pasted text from typed-in text. This helps
|
|
|
|
/// clickhouse-client so that without -m flag, one can still paste multiline queries, and
|
|
|
|
/// possibly get better pasting performance. See https://cirw.in/blog/bracketed-paste for
|
|
|
|
/// more details.
|
2023-04-06 23:04:51 +00:00
|
|
|
/// These methods (if implemented) emit the control characters immediately, without waiting
|
|
|
|
/// for the next readLine() call.
|
2020-02-25 08:30:11 +00:00
|
|
|
virtual void enableBracketedPaste() {}
|
2023-04-06 23:04:51 +00:00
|
|
|
virtual void disableBracketedPaste() {}
|
2020-02-25 08:30:11 +00:00
|
|
|
|
2024-06-25 14:23:37 +00:00
|
|
|
bool hasInputData() const;
|
|
|
|
|
2020-01-23 08:18:19 +00:00
|
|
|
protected:
|
2019-12-27 13:11:29 +00:00
|
|
|
enum InputStatus
|
|
|
|
{
|
|
|
|
ABORT = 0,
|
|
|
|
RESET_LINE,
|
|
|
|
INPUT_LINE,
|
|
|
|
};
|
|
|
|
|
2019-12-26 15:30:25 +00:00
|
|
|
const String history_file_path;
|
2020-01-23 08:18:19 +00:00
|
|
|
|
|
|
|
String input;
|
|
|
|
|
2020-06-02 03:25:19 +00:00
|
|
|
bool multiline;
|
|
|
|
|
|
|
|
Patterns extenders;
|
|
|
|
Patterns delimiters;
|
2019-12-26 15:30:25 +00:00
|
|
|
|
2020-01-23 08:18:19 +00:00
|
|
|
String prev_line;
|
2019-12-26 15:30:25 +00:00
|
|
|
|
2020-01-23 08:18:19 +00:00
|
|
|
virtual InputStatus readOneLine(const String & prompt);
|
|
|
|
virtual void addToHistory(const String &) {}
|
2024-06-25 14:23:37 +00:00
|
|
|
|
|
|
|
std::istream & input_stream;
|
|
|
|
std::ostream & output_stream;
|
|
|
|
int in_fd;
|
2019-12-26 15:30:25 +00:00
|
|
|
};
|
2022-12-10 10:16:31 +00:00
|
|
|
|
|
|
|
}
|