commit 4893fc8: [Minor] Update replxx library
Vsevolod Stakhov
vsevolod at highsecure.ru
Tue Aug 24 14:56:04 UTC 2021
Author: Vsevolod Stakhov
Date: 2021-08-24 15:47:07 +0100
URL: https://github.com/rspamd/rspamd/commit/4893fc8dc5b54968be8949fe3b45fc7326cbb90f
[Minor] Update replxx library
---
contrib/replxx/include/replxx.h | 142 +++++-
contrib/replxx/include/replxx.hxx | 174 ++++++-
contrib/replxx/src/conversion.cxx | 88 ++--
contrib/replxx/src/conversion.hxx | 21 +-
contrib/replxx/src/escape.cxx | 36 +-
contrib/replxx/src/history.cxx | 390 ++++++++++++---
contrib/replxx/src/history.hxx | 134 ++++--
contrib/replxx/src/killring.hxx | 6 +-
contrib/replxx/src/prompt.cxx | 64 ++-
contrib/replxx/src/prompt.hxx | 12 +-
contrib/replxx/src/replxx.cxx | 159 ++++++-
contrib/replxx/src/replxx_impl.cxx | 896 +++++++++++++++++++++++------------
contrib/replxx/src/replxx_impl.hxx | 73 ++-
contrib/replxx/src/unicodestring.hxx | 28 +-
contrib/replxx/src/utf8string.hxx | 33 +-
contrib/replxx/src/util.cxx | 30 +-
contrib/replxx/src/util.hxx | 6 +-
contrib/replxx/src/windows.cxx | 38 +-
contrib/replxx/src/windows.hxx | 2 +-
19 files changed, 1692 insertions(+), 640 deletions(-)
diff --git a/contrib/replxx/include/replxx.h b/contrib/replxx/include/replxx.h
index 4bdad5127..5127ac2ae 100644
--- a/contrib/replxx/include/replxx.h
+++ b/contrib/replxx/include/replxx.h
@@ -126,6 +126,8 @@ enum { REPLXX_KEY_F22 = REPLXX_KEY_F21 + 1 };
enum { REPLXX_KEY_F23 = REPLXX_KEY_F22 + 1 };
enum { REPLXX_KEY_F24 = REPLXX_KEY_F23 + 1 };
enum { REPLXX_KEY_MOUSE = REPLXX_KEY_F24 + 1 };
+enum { REPLXX_KEY_PASTE_START = REPLXX_KEY_MOUSE + 1 };
+enum { REPLXX_KEY_PASTE_FINISH = REPLXX_KEY_PASTE_START + 1 };
#define REPLXX_KEY_SHIFT( key ) ( ( key ) | REPLXX_KEY_BASE_SHIFT )
#define REPLXX_KEY_CONTROL( key ) ( ( key ) | REPLXX_KEY_BASE_CONTROL )
@@ -139,19 +141,25 @@ enum { REPLXX_KEY_ENTER = REPLXX_KEY_CONTROL( 'M' ) };
*/
typedef enum {
REPLXX_ACTION_INSERT_CHARACTER,
+ REPLXX_ACTION_NEW_LINE,
REPLXX_ACTION_DELETE_CHARACTER_UNDER_CURSOR,
REPLXX_ACTION_DELETE_CHARACTER_LEFT_OF_CURSOR,
REPLXX_ACTION_KILL_TO_END_OF_LINE,
REPLXX_ACTION_KILL_TO_BEGINING_OF_LINE,
REPLXX_ACTION_KILL_TO_END_OF_WORD,
REPLXX_ACTION_KILL_TO_BEGINING_OF_WORD,
+ REPLXX_ACTION_KILL_TO_END_OF_SUBWORD,
+ REPLXX_ACTION_KILL_TO_BEGINING_OF_SUBWORD,
REPLXX_ACTION_KILL_TO_WHITESPACE_ON_LEFT,
REPLXX_ACTION_YANK,
REPLXX_ACTION_YANK_CYCLE,
+ REPLXX_ACTION_YANK_LAST_ARG,
REPLXX_ACTION_MOVE_CURSOR_TO_BEGINING_OF_LINE,
REPLXX_ACTION_MOVE_CURSOR_TO_END_OF_LINE,
REPLXX_ACTION_MOVE_CURSOR_ONE_WORD_LEFT,
REPLXX_ACTION_MOVE_CURSOR_ONE_WORD_RIGHT,
+ REPLXX_ACTION_MOVE_CURSOR_ONE_SUBWORD_LEFT,
+ REPLXX_ACTION_MOVE_CURSOR_ONE_SUBWORD_RIGHT,
REPLXX_ACTION_MOVE_CURSOR_LEFT,
REPLXX_ACTION_MOVE_CURSOR_RIGHT,
REPLXX_ACTION_HISTORY_NEXT,
@@ -165,12 +173,16 @@ typedef enum {
REPLXX_ACTION_CAPITALIZE_WORD,
REPLXX_ACTION_LOWERCASE_WORD,
REPLXX_ACTION_UPPERCASE_WORD,
+ REPLXX_ACTION_CAPITALIZE_SUBWORD,
+ REPLXX_ACTION_LOWERCASE_SUBWORD,
+ REPLXX_ACTION_UPPERCASE_SUBWORD,
REPLXX_ACTION_TRANSPOSE_CHARACTERS,
REPLXX_ACTION_TOGGLE_OVERWRITE_MODE,
#ifndef _WIN32
REPLXX_ACTION_VERBATIM_INSERT,
REPLXX_ACTION_SUSPEND,
#endif
+ REPLXX_ACTION_BRACKETED_PASTE,
REPLXX_ACTION_CLEAR_SCREEN,
REPLXX_ACTION_CLEAR_SELF,
REPLXX_ACTION_REPAINT,
@@ -196,12 +208,17 @@ typedef struct ReplxxStateTag {
} ReplxxState;
typedef struct Replxx Replxx;
+typedef struct ReplxxHistoryScan ReplxxHistoryScan;
+typedef struct ReplxxHistoryEntryTag {
+ char const* timestamp;
+ char const* text;
+} ReplxxHistoryEntry;
-/*! \brief Create Replxx library resouce holder.
+/*! \brief Create Replxx library resource holder.
*
- * Use replxx_end() to free resoiurce acquired with this function.
+ * Use replxx_end() to free resources acquired with this function.
*
- * \return Replxx library resouce holder.
+ * \return Replxx library resource holder.
*/
REPLXX_IMPEXP Replxx* replxx_init( void );
@@ -211,6 +228,28 @@ REPLXX_IMPEXP Replxx* replxx_init( void );
*/
REPLXX_IMPEXP void replxx_end( Replxx* replxx );
+/*! \brief Line modification callback type definition.
+ *
+ * User can observe and modify line contents (and cursor position)
+ * in response to changes to both introduced by the user through
+ * normal interactions.
+ *
+ * When callback returns Replxx updates current line content
+ * and current cursor position to the ones updated by the callback.
+ *
+ * \param line[in,out] - a R/W reference to an UTF-8 encoded input entered by the user so far.
+ * \param cursorPosition[in,out] - a R/W reference to current cursor position.
+ * \param userData - pointer to opaque user data block.
+ */
+typedef void (replxx_modify_callback_t)(char** input, int* contextLen, void* userData);
+
+/*! \brief Register modify callback.
+ *
+ * \param fn - user defined callback function.
+ * \param userData - pointer to opaque user data block to be passed into each invocation of the callback.
+ */
+REPLXX_IMPEXP void replxx_set_modify_callback( Replxx*, replxx_modify_callback_t* fn, void* userData );
+
/*! \brief Highlighter callback type definition.
*
* If user want to have colorful input she must simply install highlighter callback.
@@ -247,8 +286,8 @@ typedef struct replxx_completions replxx_completions;
* input == "if ( obj.me"
* contextLen == 2 (depending on \e replxx_set_word_break_characters())
*
- * Client application is free to update \e contextLen to be 6 (or any orther non-negative
- * number not greated than the number of code points in input) if it makes better sense
+ * Client application is free to update \e contextLen to be 6 (or any other non-negative
+ * number not greater than the number of code points in input) if it makes better sense
* for given client application semantics.
*
* \param input - UTF-8 encoded input entered by the user until current cursor position.
@@ -292,8 +331,8 @@ typedef struct replxx_hints replxx_hints;
* input == "if ( obj.me"
* contextLen == 2 (depending on \e replxx_set_word_break_characters())
*
- * Client application is free to update \e contextLen to be 6 (or any orther non-negative
- * number not greated than the number of code points in input) if it makes better sense
+ * Client application is free to update \e contextLen to be 6 (or any other non-negative
+ * number not greater than the number of code points in input) if it makes better sense
* for given client application semantics.
*
* \param input - UTF-8 encoded input entered by the user until current cursor position.
@@ -314,7 +353,7 @@ REPLXX_IMPEXP void replxx_set_hint_callback( Replxx*, replxx_hint_callback_t* fn
/*! \brief Key press handler type definition.
*
* \param code - the key code replxx got from terminal.
- * \return Decition on how should input() behave after this key handler returns.
+ * \return Decision on how should input() behave after this key handler returns.
*/
typedef ReplxxActionResult (key_press_handler_t)( int code, void* userData );
@@ -326,6 +365,8 @@ typedef ReplxxActionResult (key_press_handler_t)( int code, void* userData );
REPLXX_IMPEXP void replxx_add_hint( replxx_hints* hints, const char* str );
/*! \brief Read line of user input.
+ *
+ * Returned pointer is managed by the library and is not to be freed in the client.
*
* \param prompt - prompt to be displayed before getting user input.
* \return An UTF-8 encoded input given by the user (or nullptr on EOF).
@@ -356,11 +397,17 @@ REPLXX_IMPEXP void replxx_set_state( Replxx*, ReplxxState* state );
*
* \param fmt - printf style format.
*/
-#ifdef __GNUC__
-__attribute__((format(printf, 2, 3)))
-#endif
REPLXX_IMPEXP int replxx_print( Replxx*, char const* fmt, ... );
+/*! \brief Prints a char array with the given length to standard output.
+ *
+ * \copydetails print
+ *
+ * \param str - The char array to print.
+ * \param length - The length of the array.
+ */
+REPLXX_IMPEXP int replxx_write( Replxx*, char const* str, int length );
+
/*! \brief Schedule an emulated key press event.
*
* \param code - key press code to be emulated.
@@ -385,6 +432,19 @@ REPLXX_IMPEXP ReplxxActionResult replxx_invoke( Replxx*, ReplxxAction action, in
*/
REPLXX_IMPEXP void replxx_bind_key( Replxx*, int code, key_press_handler_t handler, void* userData );
+/*! \brief Bind internal `replxx` action (by name) to handle given key-press event.
+ *
+ * Action names are the same as unique part of names of ReplxxAction enumerations
+ * but in lower case, e.g.: an action for recalling previous history line
+ * is \e REPLXX_ACTION_HISTORY_PREVIOUS so action name to be used in this
+ * interface for the same effect is "history_previous".
+ *
+ * \param code - handle this key-press event with following handler.
+ * \param actionName - name of internal action to be invoked on key press.
+ * \return -1 if invalid action name was used, 0 otherwise.
+ */
+int replxx_bind_key_internal( Replxx*, int code, char const* actionName );
+
REPLXX_IMPEXP void replxx_set_preload_buffer( Replxx*, const char* preloadText );
REPLXX_IMPEXP void replxx_history_add( Replxx*, const char* line );
@@ -430,6 +490,23 @@ REPLXX_IMPEXP void replxx_set_complete_on_empty( Replxx*, int val );
*/
REPLXX_IMPEXP void replxx_set_beep_on_ambiguous_completion( Replxx*, int val );
+/*! \brief Set complete next/complete previous behavior.
+ *
+ * COMPLETE_NEXT/COMPLETE_PREVIOUS actions have two modes of operations,
+ * in case when a partial completion is possible complete only partial part (`false` setting)
+ * or complete first proposed completion fully (`true` setting).
+ * The default is to complete fully (a `true` setting - complete immediately).
+ *
+ * \param val - complete immediately.
+ */
+REPLXX_IMPEXP void replxx_set_immediate_completion( Replxx*, int val );
+
+/*! \brief Set history duplicate entries behaviour.
+ *
+ * \param val - should history contain only unique entries?
+ */
+REPLXX_IMPEXP void replxx_set_unique_history( Replxx*, int val );
+
/*! \brief Disable output coloring.
*
* \param val - if set to non-zero disable output colors.
@@ -439,15 +516,56 @@ REPLXX_IMPEXP void replxx_set_no_color( Replxx*, int val );
/*! \brief Set maximum number of entries in history list.
*/
REPLXX_IMPEXP void replxx_set_max_history_size( Replxx*, int len );
-REPLXX_IMPEXP char const* replxx_history_line( Replxx*, int index );
+REPLXX_IMPEXP ReplxxHistoryScan* replxx_history_scan_start( Replxx* );
+REPLXX_IMPEXP void replxx_history_scan_stop( Replxx*, ReplxxHistoryScan* );
+REPLXX_IMPEXP int replxx_history_scan_next( Replxx*, ReplxxHistoryScan*, ReplxxHistoryEntry* );
+
+/*! \brief Synchronize REPL's history with given file.
+ *
+ * Synchronizing means loading existing history from given file,
+ * merging it with current history sorted by timestamps,
+ * saving merged version to given file,
+ * keeping merged version as current REPL's history.
+ *
+ * This call is an equivalent of calling:
+ * replxx_history_save( rx, "some-file" );
+ * replxx_history_load( rx, "some-file" );
+ *
+ * \param filename - a path to the file with which REPL's current history should be synchronized.
+ * \return 0 iff history file was successfully created, -1 otherwise.
+ */
+REPLXX_IMPEXP int replxx_history_sync( Replxx*, const char* filename );
+
+/*! \brief Save REPL's history into given file.
+ *
+ * Saving means loading existing history from given file,
+ * merging it with current history sorted by timestamps,
+ * saving merged version to given file,
+ * keeping original (NOT merged) version as current REPL's history.
+ *
+ * \param filename - a path to the file where REPL's history should be saved.
+ * \return 0 iff history file was successfully created, -1 otherwise.
+ */
REPLXX_IMPEXP int replxx_history_save( Replxx*, const char* filename );
+
+/*! \brief Load REPL's history from given file.
+ *
+ * \param filename - a path to the file which contains REPL's history that should be loaded.
+ * \return 0 iff history file was successfully opened, -1 otherwise.
+ */
REPLXX_IMPEXP int replxx_history_load( Replxx*, const char* filename );
+
+/*! \brief Clear REPL's in-memory history.
+ */
+REPLXX_IMPEXP void replxx_history_clear( Replxx* );
REPLXX_IMPEXP void replxx_clear_screen( Replxx* );
#ifdef __REPLXX_DEBUG__
void replxx_debug_dump_print_codes(void);
#endif
/* the following is extension to the original linenoise API */
REPLXX_IMPEXP int replxx_install_window_change_handler( Replxx* );
+REPLXX_IMPEXP void replxx_enable_bracketed_paste( Replxx* );
+REPLXX_IMPEXP void replxx_disable_bracketed_paste( Replxx* );
#ifdef __cplusplus
}
diff --git a/contrib/replxx/include/replxx.hxx b/contrib/replxx/include/replxx.hxx
index 1401ea27c..5362312e5 100644
--- a/contrib/replxx/include/replxx.hxx
+++ b/contrib/replxx/include/replxx.hxx
@@ -131,6 +131,8 @@ public:
static char32_t const F23 = F22 + 1;
static char32_t const F24 = F23 + 1;
static char32_t const MOUSE = F24 + 1;
+ static char32_t const PASTE_START = MOUSE + 1;
+ static char32_t const PASTE_FINISH = PASTE_START + 1;
static constexpr char32_t shift( char32_t key_ ) {
return ( key_ | BASE_SHIFT );
}
@@ -148,19 +150,25 @@ public:
*/
enum class ACTION {
INSERT_CHARACTER,
+ NEW_LINE,
DELETE_CHARACTER_UNDER_CURSOR,
DELETE_CHARACTER_LEFT_OF_CURSOR,
KILL_TO_END_OF_LINE,
KILL_TO_BEGINING_OF_LINE,
KILL_TO_END_OF_WORD,
KILL_TO_BEGINING_OF_WORD,
+ KILL_TO_END_OF_SUBWORD,
+ KILL_TO_BEGINING_OF_SUBWORD,
KILL_TO_WHITESPACE_ON_LEFT,
YANK,
YANK_CYCLE,
+ YANK_LAST_ARG,
MOVE_CURSOR_TO_BEGINING_OF_LINE,
MOVE_CURSOR_TO_END_OF_LINE,
MOVE_CURSOR_ONE_WORD_LEFT,
MOVE_CURSOR_ONE_WORD_RIGHT,
+ MOVE_CURSOR_ONE_SUBWORD_LEFT,
+ MOVE_CURSOR_ONE_SUBWORD_RIGHT,
MOVE_CURSOR_LEFT,
MOVE_CURSOR_RIGHT,
HISTORY_NEXT,
@@ -174,12 +182,16 @@ public:
CAPITALIZE_WORD,
LOWERCASE_WORD,
UPPERCASE_WORD,
+ CAPITALIZE_SUBWORD,
+ LOWERCASE_SUBWORD,
+ UPPERCASE_SUBWORD,
TRANSPOSE_CHARACTERS,
TOGGLE_OVERWRITE_MODE,
#ifndef _WIN32
VERBATIM_INSERT,
SUSPEND,
#endif
+ BRACKETED_PASTE,
CLEAR_SCREEN,
CLEAR_SELF,
REPAINT,
@@ -222,8 +234,60 @@ public:
}
};
typedef std::vector<Completion> completions_t;
+ class HistoryEntry {
+ std::string _timestamp;
+ std::string _text;
+ public:
+ HistoryEntry( std::string const& timestamp_, std::string const& text_ )
+ : _timestamp( timestamp_ )
+ , _text( text_ ) {
+ }
+ std::string const& timestamp( void ) const {
+ return ( _timestamp );
+ }
+ std::string const& text( void ) const {
+ return ( _text );
+ }
+ };
+ class HistoryScanImpl;
+ class HistoryScan {
+ public:
+ typedef std::unique_ptr<HistoryScanImpl, void (*)( HistoryScanImpl* )> impl_t;
+ private:
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+ impl_t _impl;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+ public:
+ HistoryScan( impl_t );
+ HistoryScan( HistoryScan&& ) = default;
+ HistoryScan& operator = ( HistoryScan&& ) = default;
+ bool next( void );
+ HistoryEntry const& get( void ) const;
+ private:
+ HistoryScan( HistoryScan const& ) = delete;
+ HistoryScan& operator = ( HistoryScan const& ) = delete;
+ };
typedef std::vector<std::string> hints_t;
+ /*! \brief Line modification callback type definition.
+ *
+ * User can observe and modify line contents (and cursor position)
+ * in response to changes to both introduced by the user through
+ * normal interactions.
+ *
+ * When callback returns Replxx updates current line content
+ * and current cursor position to the ones updated by the callback.
+ *
+ * \param line[in,out] - a R/W reference to an UTF-8 encoded input entered by the user so far.
+ * \param cursorPosition[in,out] - a R/W reference to current cursor position.
+ */
+ typedef std::function<void ( std::string& line, int& cursorPosition )> modify_callback_t;
+
/*! \brief Completions callback type definition.
*
* \e contextLen is counted in Unicode code points (not in bytes!).
@@ -234,8 +298,8 @@ public:
* input == "if ( obj.me"
* contextLen == 2 (depending on \e set_word_break_characters())
*
- * Client application is free to update \e contextLen to be 6 (or any orther non-negative
- * number not greated than the number of code points in input) if it makes better sense
+ * Client application is free to update \e contextLen to be 6 (or any other non-negative
+ * number not greater than the number of code points in input) if it makes better sense
* for given client application semantics.
*
* \param input - UTF-8 encoded input entered by the user until current cursor position.
@@ -252,7 +316,7 @@ public:
* displayed user input.
*
* Size of \e colors buffer is equal to number of code points in user \e input
- * which will be different from simple `input.lenght()`!
+ * which will be different from simple `input.length()`!
*
* \param input - an UTF-8 encoded input entered by the user so far.
* \param colors - output buffer for color information.
@@ -269,8 +333,8 @@ public:
* input == "if ( obj.me"
* contextLen == 2 (depending on \e set_word_break_characters())
*
- * Client application is free to update \e contextLen to be 6 (or any orther non-negative
- * number not greated than the number of code points in input) if it makes better sense
+ * Client application is free to update \e contextLen to be 6 (or any other non-negative
+ * number not greater than the number of code points in input) if it makes better sense
* for given client application semantics.
*
* \param input - UTF-8 encoded input entered by the user until current cursor position.
@@ -283,7 +347,7 @@ public:
/*! \brief Key press handler type definition.
*
* \param code - the key code replxx got from terminal.
- * \return Decition on how should input() behave after this key handler returns.
+ * \return Decision on how should input() behave after this key handler returns.
*/
typedef std::function<ACTION_RESULT ( char32_t code )> key_press_handler_t;
@@ -307,12 +371,12 @@ public:
class ReplxxImpl;
private:
typedef std::unique_ptr<ReplxxImpl, void (*)( ReplxxImpl* )> impl_t;
-#ifdef _WIN32
+#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4251)
#endif
impl_t _impl;
-#ifdef _WIN32
+#ifdef _MSC_VER
#pragma warning(pop)
#endif
@@ -321,6 +385,12 @@ public:
Replxx( Replxx&& ) = default;
Replxx& operator = ( Replxx&& ) = default;
+ /*! \brief Register modify callback.
+ *
+ * \param fn - user defined callback function.
+ */
+ void set_modify_callback( modify_callback_t const& fn );
+
/*! \brief Register completion callback.
*
* \param fn - user defined callback function.
@@ -340,6 +410,8 @@ public:
void set_hint_callback( hint_callback_t const& fn );
/*! \brief Read line of user input.
+ *
+ * Returned pointer is managed by the library and is not to be freed in the client.
*
* \param prompt - prompt to be displayed before getting user input.
* \return An UTF-8 encoded input given by the user (or nullptr on EOF).
@@ -370,11 +442,17 @@ public:
*
* \param fmt - printf style format.
*/
-#ifdef __GNUC__
- __attribute__((format(printf, 2, 3)))
-#endif
void print( char const* fmt, ... );
+ /*! \brief Prints a char array with the given length to standard output.
+ *
+ * \copydetails print
+ *
+ * \param str - The char array to print.
+ * \param length - The length of the array.
+ */
+ void write( char const* str, int length );
+
/*! \brief Schedule an emulated key press event.
*
* \param code - key press code to be emulated.
@@ -398,11 +476,60 @@ public:
*/
void bind_key( char32_t code, key_press_handler_t handler );
+ /*! \brief Bind internal `replxx` action (by name) to handle given key-press event.
+ *
+ * Action names are the same as names of Replxx::ACTION enumerations
+ * but in lower case, e.g.: an action for recalling previous history line
+ * is \e Replxx::ACTION::HISTORY_PREVIOUS so action name to be used in this
+ * interface for the same effect is "history_previous".
+ *
+ * \param code - handle this key-press event with following handler.
+ * \param actionName - name of internal action to be invoked on key press.
+ */
+ void bind_key_internal( char32_t code, char const* actionName );
+
void history_add( std::string const& line );
- int history_save( std::string const& filename );
- int history_load( std::string const& filename );
+
+ /*! \brief Synchronize REPL's history with given file.
+ *
+ * Synchronizing means loading existing history from given file,
+ * merging it with current history sorted by timestamps,
+ * saving merged version to given file,
+ * keeping merged version as current REPL's history.
+ *
+ * This call is an equivalent of calling:
+ * history_save( "some-file" );
+ * history_load( "some-file" );
+ *
+ * \param filename - a path to the file with which REPL's current history should be synchronized.
+ * \return True iff history file was successfully created.
+ */
+ bool history_sync( std::string const& filename );
+
+ /*! \brief Save REPL's history into given file.
+ *
+ * Saving means loading existing history from given file,
+ * merging it with current history sorted by timestamps,
+ * saving merged version to given file,
+ * keeping original (NOT merged) version as current REPL's history.
+ *
+ * \param filename - a path to the file where REPL's history should be saved.
+ * \return True iff history file was successfully created.
+ */
+ bool history_save( std::string const& filename );
+
+ /*! \brief Load REPL's history from given file.
+ *
+ * \param filename - a path to the file which contains REPL's history that should be loaded.
+ * \return True iff history file was successfully opened.
+ */
+ bool history_load( std::string const& filename );
+
+ /*! \brief Clear REPL's in-memory history.
+ */
+ void history_clear( void );
int history_size( void ) const;
- std::string history_line( int index );
+ HistoryScan history_scan( void ) const;
void set_preload_buffer( std::string const& preloadText );
@@ -446,6 +573,23 @@ public:
*/
void set_beep_on_ambiguous_completion( bool val );
+ /*! \brief Set complete next/complete previous behavior.
+ *
+ * COMPLETE_NEXT/COMPLETE_PREVIOUS actions have two modes of operations,
+ * in case when a partial completion is possible complete only partial part (`false` setting)
+ * or complete first proposed completion fully (`true` setting).
+ * The default is to complete fully (a `true` setting - complete immediately).
+ *
+ * \param val - complete immediately.
+ */
+ void set_immediate_completion( bool val );
+
+ /*! \brief Set history duplicate entries behaviour.
+ *
+ * \param val - should history contain only unique entries?
+ */
+ void set_unique_history( bool val );
+
/*! \brief Disable output coloring.
*
* \param val - if set to non-zero disable output colors.
@@ -457,6 +601,8 @@ public:
void set_max_history_size( int len );
void clear_screen( void );
int install_window_change_handler( void );
+ void enable_bracketed_paste( void );
+ void disable_bracketed_paste( void );
private:
Replxx( Replxx const& ) = delete;
diff --git a/contrib/replxx/src/conversion.cxx b/contrib/replxx/src/conversion.cxx
index ce9bd932b..bcdbe048e 100644
--- a/contrib/replxx/src/conversion.cxx
+++ b/contrib/replxx/src/conversion.cxx
@@ -2,10 +2,7 @@
#include <string>
#include <cstring>
#include <cctype>
-#include <clocale>
-
-#include "unicode/utf8.h"
-
+#include <locale.h>
#include "conversion.hxx"
@@ -47,38 +44,20 @@ bool is8BitEncoding( is_8bit_encoding() );
ConversionResult copyString8to32(char32_t* dst, int dstSize, int& dstCount, const char* src) {
ConversionResult res = ConversionResult::conversionOK;
if ( ! locale::is8BitEncoding ) {
- auto sourceStart = reinterpret_cast<const unsigned char*>(src);
- auto slen = strlen(src);
- auto targetStart = reinterpret_cast<UChar32*>(dst);
- int i = 0, j = 0;
-
- while (i < slen && j < dstSize) {
- UChar32 uc;
- auto prev_i = i;
- U8_NEXT (sourceStart, i, slen, uc);
-
- if (uc <= 0) {
- if (U8_IS_LEAD (sourceStart[prev_i])) {
- auto lead_byte = sourceStart[prev_i];
- auto trailing_bytes = (((uint8_t)(lead_byte)>=0xc2)+
- ((uint8_t)(lead_byte)>=0xe0)+
- ((uint8_t)(lead_byte)>=0xf0));
-
- if (trailing_bytes + i > slen) {
- return ConversionResult::sourceExhausted;
- }
- }
-
- /* Replace with 0xFFFD */
- uc = 0x0000FFFD;
- }
- targetStart[j++] = uc;
- }
+ const UTF8* sourceStart = reinterpret_cast<const UTF8*>(src);
+ const UTF8* sourceEnd = sourceStart + strlen(src);
+ UTF32* targetStart = reinterpret_cast<UTF32*>(dst);
+ UTF32* targetEnd = targetStart + dstSize;
- dstCount = j;
+ res = ConvertUTF8toUTF32(
+ &sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion);
- if (j < dstSize) {
- targetStart[j] = 0;
+ if (res == conversionOK) {
+ dstCount = static_cast<int>( targetStart - reinterpret_cast<UTF32*>( dst ) );
+
+ if (dstCount < dstSize) {
+ *targetStart = 0;
+ }
}
} else {
for ( dstCount = 0; ( dstCount < dstSize ) && src[dstCount]; ++ dstCount ) {
@@ -94,28 +73,22 @@ ConversionResult copyString8to32(char32_t* dst, int dstSize, int& dstCount, cons
);
}
-void copyString32to8(
- char* dst, int dstSize, const char32_t* src, int srcSize, int* dstCount
-) {
+int copyString32to8( char* dst, int dstSize, const char32_t* src, int srcSize ) {
+ int resCount( 0 );
if ( ! locale::is8BitEncoding ) {
- int j = 0;
- UBool is_error = 0;
-
- for (auto i = 0; i < srcSize; i ++) {
- U8_APPEND ((uint8_t *)dst, j, dstSize, src[i], is_error);
-
- if (is_error) {
- break;
- }
- }
-
- if (!is_error) {
- if (dstCount) {
- *dstCount = j;
*** OUTPUT TRUNCATED, 3484 LINES SKIPPED ***
More information about the Commits
mailing list