diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-09-03 17:45:58 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-09-03 17:45:58 +0100 |
commit | 669cd52f685282289590200daed3fc89466e7206 (patch) | |
tree | 792c26273dd54dab61b5e94693e1895ff9c5440c /contrib/replxx/src/prompt.cxx | |
parent | 8a240656d8378ac20e4c4c3ae61d1a9c33488a20 (diff) | |
download | rspamd-669cd52f685282289590200daed3fc89466e7206.tar.gz rspamd-669cd52f685282289590200daed3fc89466e7206.zip |
[Rework] Replace linenoise with replxx
Source: https://github.com/AmokHuginnsson/replxx
Diffstat (limited to 'contrib/replxx/src/prompt.cxx')
-rw-r--r-- | contrib/replxx/src/prompt.cxx | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/contrib/replxx/src/prompt.cxx b/contrib/replxx/src/prompt.cxx new file mode 100644 index 000000000..391d3745b --- /dev/null +++ b/contrib/replxx/src/prompt.cxx @@ -0,0 +1,150 @@ +#ifdef _WIN32 + +#include <conio.h> +#include <windows.h> +#include <io.h> +#if _MSC_VER < 1900 && defined (_MSC_VER) +#define snprintf _snprintf // Microsoft headers use underscores in some names +#endif +#define strcasecmp _stricmp +#define strdup _strdup +#define write _write +#define STDIN_FILENO 0 + +#else /* _WIN32 */ + +#include <unistd.h> + +#endif /* _WIN32 */ + +#include "prompt.hxx" +#include "util.hxx" + +namespace replxx { + +Prompt::Prompt( Terminal& terminal_ ) + : _extraLines( 0 ) + , _lastLinePosition( 0 ) + , _previousInputLen( 0 ) + , _previousLen( 0 ) + , _screenColumns( 0 ) + , _terminal( terminal_ ) { +} + +void Prompt::write() { + _terminal.write32( _text.get(), _byteCount ); +} + +void Prompt::update_screen_columns( void ) { + _screenColumns = _terminal.get_screen_columns(); +} + +void Prompt::set_text( UnicodeString const& text_ ) { + update_screen_columns(); + // strip control characters from the prompt -- we do allow newline + _text = text_; + UnicodeString::const_iterator in( text_.begin() ); + UnicodeString::iterator out( _text.begin() ); + + int len = 0; + int x = 0; + + bool const strip = !tty::out; + + while (in != text_.end()) { + char32_t c = *in; + if ('\n' == c || !is_control_code(c)) { + *out = c; + ++out; + ++in; + ++len; + if ('\n' == c || ++x >= _screenColumns) { + x = 0; + ++_extraLines; + _lastLinePosition = len; + } + } else if (c == '\x1b') { + if ( strip ) { + // jump over control chars + ++in; + if (*in == '[') { + ++in; + while ( ( in != text_.end() ) && ( ( *in == ';' ) || ( ( ( *in >= '0' ) && ( *in <= '9' ) ) ) ) ) { + ++in; + } + if (*in == 'm') { + ++in; + } + } + } else { + // copy control chars + *out = *in; + ++out; + ++in; + if (*in == '[') { + *out = *in; + ++out; + ++in; + while ( ( in != text_.end() ) && ( ( *in == ';' ) || ( ( ( *in >= '0' ) && ( *in <= '9' ) ) ) ) ) { + *out = *in; + ++out; + ++in; + } + if (*in == 'm') { + *out = *in; + ++out; + ++in; + } + } + } + } else { + ++in; + } + } + _characterCount = len; + _byteCount = static_cast<int>(out - _text.begin()); + + _indentation = len - _lastLinePosition; + _cursorRowOffset = _extraLines; +} + +// Used with DynamicPrompt (history search) +// +const UnicodeString forwardSearchBasePrompt("(i-search)`"); +const UnicodeString reverseSearchBasePrompt("(reverse-i-search)`"); +const UnicodeString endSearchBasePrompt("': "); +UnicodeString previousSearchText; // remembered across invocations of replxx_input() + +DynamicPrompt::DynamicPrompt( Terminal& terminal_, int initialDirection ) + : Prompt( terminal_ ) + , _searchText() + , _direction( initialDirection ) { + update_screen_columns(); + _cursorRowOffset = 0; + const UnicodeString* basePrompt = + (_direction > 0) ? &forwardSearchBasePrompt : &reverseSearchBasePrompt; + size_t promptStartLength = basePrompt->length(); + _characterCount = static_cast<int>(promptStartLength + endSearchBasePrompt.length()); + _byteCount = _characterCount; + _lastLinePosition = _characterCount; // TODO fix this, we are asssuming + // that the history prompt won't wrap (!) + _previousLen = _characterCount; + _text.assign( *basePrompt ).append( endSearchBasePrompt ); + calculate_screen_position( + 0, 0, screen_columns(), _characterCount, + _indentation, _extraLines + ); +} + +void DynamicPrompt::updateSearchPrompt(void) { + const UnicodeString* basePrompt = + (_direction > 0) ? &forwardSearchBasePrompt : &reverseSearchBasePrompt; + size_t promptStartLength = basePrompt->length(); + _characterCount = static_cast<int>(promptStartLength + _searchText.length() + + endSearchBasePrompt.length()); + _byteCount = _characterCount; + _text.assign( *basePrompt ).append( _searchText ).append( endSearchBasePrompt ); +} + +} + |