summaryrefslogtreecommitdiffstats
path: root/contrib/replxx/src/prompt.cxx
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-09-03 17:45:58 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-09-03 17:45:58 +0100
commit669cd52f685282289590200daed3fc89466e7206 (patch)
tree792c26273dd54dab61b5e94693e1895ff9c5440c /contrib/replxx/src/prompt.cxx
parent8a240656d8378ac20e4c4c3ae61d1a9c33488a20 (diff)
downloadrspamd-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.cxx150
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 );
+}
+
+}
+