Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

replxx_impl.hxx 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright (c) 2017-2018, Marcin Konarski (amok at codestation.org)
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Redis nor the names of its contributors may be used
  15. * to endorse or promote products derived from this software without
  16. * specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #ifndef HAVE_REPLXX_REPLXX_IMPL_HXX_INCLUDED
  31. #define HAVE_REPLXX_REPLXX_IMPL_HXX_INCLUDED 1
  32. #include <vector>
  33. #include <deque>
  34. #include <memory>
  35. #include <string>
  36. #include <unordered_map>
  37. #include <thread>
  38. #include <mutex>
  39. #include <chrono>
  40. #include "replxx.hxx"
  41. #include "history.hxx"
  42. #include "killring.hxx"
  43. #include "utf8string.hxx"
  44. #include "prompt.hxx"
  45. namespace replxx {
  46. class Replxx::ReplxxImpl {
  47. public:
  48. class Completion {
  49. UnicodeString _text;
  50. Replxx::Color _color;
  51. public:
  52. Completion( UnicodeString const& text_, Replxx::Color color_ )
  53. : _text( text_ )
  54. , _color( color_ ) {
  55. }
  56. Completion( Replxx::Completion const& completion_ )
  57. : _text( completion_.text() )
  58. , _color( completion_.color() ) {
  59. }
  60. Completion( Completion const& ) = default;
  61. Completion& operator = ( Completion const& ) = default;
  62. Completion( Completion&& ) = default;
  63. Completion& operator = ( Completion&& ) = default;
  64. UnicodeString const& text( void ) const {
  65. return ( _text );
  66. }
  67. Replxx::Color color( void ) const {
  68. return ( _color );
  69. }
  70. };
  71. typedef std::vector<Completion> completions_t;
  72. typedef std::vector<UnicodeString> data_t;
  73. typedef std::vector<UnicodeString> hints_t;
  74. typedef std::unique_ptr<char[]> utf8_buffer_t;
  75. typedef std::unique_ptr<char32_t[]> input_buffer_t;
  76. typedef std::vector<char32_t> display_t;
  77. typedef std::deque<char32_t> key_presses_t;
  78. typedef std::deque<std::string> messages_t;
  79. enum class HINT_ACTION {
  80. REGENERATE,
  81. REPAINT,
  82. TRIM,
  83. SKIP
  84. };
  85. typedef std::unordered_map<std::string, Replxx::key_press_handler_t> named_actions_t;
  86. typedef Replxx::ACTION_RESULT ( ReplxxImpl::* key_press_handler_raw_t )( char32_t );
  87. typedef std::unordered_map<int, Replxx::key_press_handler_t> key_press_handlers_t;
  88. private:
  89. typedef int long long unsigned action_trait_t;
  90. static action_trait_t const NOOP = 0;
  91. static action_trait_t const WANT_REFRESH = 1;
  92. static action_trait_t const RESET_KILL_ACTION = 2;
  93. static action_trait_t const SET_KILL_ACTION = 4;
  94. static action_trait_t const DONT_RESET_PREFIX = 8;
  95. static action_trait_t const DONT_RESET_COMPLETIONS = 16;
  96. static action_trait_t const HISTORY_RECALL_MOST_RECENT = 32;
  97. static action_trait_t const DONT_RESET_HIST_YANK_INDEX = 64;
  98. private:
  99. mutable Utf8String _utf8Buffer;
  100. UnicodeString _data;
  101. int _pos; // character position in buffer ( 0 <= _pos <= _data[_line].length() )
  102. display_t _display;
  103. int _displayInputLength;
  104. UnicodeString _hint;
  105. int _prefix; // prefix length used in common prefix search
  106. int _hintSelection; // Currently selected hint.
  107. History _history;
  108. KillRing _killRing;
  109. int long long _lastRefreshTime;
  110. bool _refreshSkipped;
  111. int _lastYankSize;
  112. int _maxHintRows;
  113. int _hintDelay;
  114. std::string _wordBreakChars;
  115. std::string _subwordBreakChars;
  116. int _completionCountCutoff;
  117. bool _overwrite;
  118. bool _doubleTabCompletion;
  119. bool _completeOnEmpty;
  120. bool _beepOnAmbiguousCompletion;
  121. bool _immediateCompletion;
  122. bool _bracketedPaste;
  123. bool _noColor;
  124. named_actions_t _namedActions;
  125. key_press_handlers_t _keyPressHandlers;
  126. Terminal _terminal;
  127. std::thread::id _currentThread;
  128. Prompt _prompt;
  129. Replxx::modify_callback_t _modifyCallback;
  130. Replxx::completion_callback_t _completionCallback;
  131. Replxx::highlighter_callback_t _highlighterCallback;
  132. Replxx::hint_callback_t _hintCallback;
  133. key_presses_t _keyPresses;
  134. messages_t _messages;
  135. completions_t _completions;
  136. int _completionContextLength;
  137. int _completionSelection;
  138. std::string _preloadedBuffer; // used with set_preload_buffer
  139. std::string _errorMessage;
  140. UnicodeString _previousSearchText; // remembered across invocations of replxx_input()
  141. bool _modifiedState;
  142. Replxx::Color _hintColor;
  143. hints_t _hintsCache;
  144. int _hintContextLenght;
  145. Utf8String _hintSeed;
  146. mutable std::mutex _mutex;
  147. public:
  148. ReplxxImpl( FILE*, FILE*, FILE* );
  149. virtual ~ReplxxImpl( void );
  150. void set_modify_callback( Replxx::modify_callback_t const& fn );
  151. void set_completion_callback( Replxx::completion_callback_t const& fn );
  152. void set_highlighter_callback( Replxx::highlighter_callback_t const& fn );
  153. void set_hint_callback( Replxx::hint_callback_t const& fn );
  154. char const* input( std::string const& prompt );
  155. void history_add( std::string const& line );
  156. bool history_sync( std::string const& filename );
  157. bool history_save( std::string const& filename );
  158. bool history_load( std::string const& filename );
  159. void history_clear( void );
  160. Replxx::HistoryScan::impl_t history_scan( void ) const;
  161. int history_size( void ) const;
  162. void set_preload_buffer(std::string const& preloadText);
  163. void set_word_break_characters( char const* wordBreakers );
  164. void set_subword_break_characters( char const* subwordBreakers );
  165. void set_max_hint_rows( int count );
  166. void set_hint_delay( int milliseconds );
  167. void set_double_tab_completion( bool val );
  168. void set_complete_on_empty( bool val );
  169. void set_beep_on_ambiguous_completion( bool val );
  170. void set_immediate_completion( bool val );
  171. void set_unique_history( bool );
  172. void set_no_color( bool val );
  173. void set_max_history_size( int len );
  174. void set_completion_count_cutoff( int len );
  175. int install_window_change_handler( void );
  176. void enable_bracketed_paste( void );
  177. void disable_bracketed_paste( void );
  178. void print( char const*, int );
  179. Replxx::ACTION_RESULT clear_screen( char32_t );
  180. void emulate_key_press( char32_t );
  181. Replxx::ACTION_RESULT invoke( Replxx::ACTION, char32_t );
  182. void bind_key( char32_t, Replxx::key_press_handler_t );
  183. void bind_key_internal( char32_t, char const* );
  184. Replxx::State get_state( void ) const;
  185. void set_state( Replxx::State const& );
  186. private:
  187. ReplxxImpl( ReplxxImpl const& ) = delete;
  188. ReplxxImpl& operator = ( ReplxxImpl const& ) = delete;
  189. private:
  190. void preload_puffer( char const* preloadText );
  191. int get_input_line( void );
  192. Replxx::ACTION_RESULT action( action_trait_t, key_press_handler_raw_t const&, char32_t );
  193. Replxx::ACTION_RESULT insert_character( char32_t );
  194. Replxx::ACTION_RESULT new_line( char32_t );
  195. Replxx::ACTION_RESULT go_to_begining_of_line( char32_t );
  196. Replxx::ACTION_RESULT go_to_end_of_line( char32_t );
  197. Replxx::ACTION_RESULT move_one_char_left( char32_t );
  198. Replxx::ACTION_RESULT move_one_char_right( char32_t );
  199. template <bool subword>
  200. Replxx::ACTION_RESULT move_one_word_left( char32_t );
  201. template <bool subword>
  202. Replxx::ACTION_RESULT move_one_word_right( char32_t );
  203. template <bool subword>
  204. Replxx::ACTION_RESULT kill_word_to_left( char32_t );
  205. template <bool subword>
  206. Replxx::ACTION_RESULT kill_word_to_right( char32_t );
  207. Replxx::ACTION_RESULT kill_to_whitespace_to_left( char32_t );
  208. Replxx::ACTION_RESULT kill_to_begining_of_line( char32_t );
  209. Replxx::ACTION_RESULT kill_to_end_of_line( char32_t );
  210. Replxx::ACTION_RESULT yank( char32_t );
  211. Replxx::ACTION_RESULT yank_cycle( char32_t );
  212. Replxx::ACTION_RESULT yank_last_arg( char32_t );
  213. template <bool subword>
  214. Replxx::ACTION_RESULT capitalize_word( char32_t );
  215. template <bool subword>
  216. Replxx::ACTION_RESULT lowercase_word( char32_t );
  217. template <bool subword>
  218. Replxx::ACTION_RESULT uppercase_word( char32_t );
  219. Replxx::ACTION_RESULT transpose_characters( char32_t );
  220. Replxx::ACTION_RESULT abort_line( char32_t );
  221. Replxx::ACTION_RESULT send_eof( char32_t );
  222. Replxx::ACTION_RESULT delete_character( char32_t );
  223. Replxx::ACTION_RESULT backspace_character( char32_t );
  224. Replxx::ACTION_RESULT commit_line( char32_t );
  225. Replxx::ACTION_RESULT history_next( char32_t );
  226. Replxx::ACTION_RESULT history_previous( char32_t );
  227. Replxx::ACTION_RESULT history_move( bool );
  228. Replxx::ACTION_RESULT history_first( char32_t );
  229. Replxx::ACTION_RESULT history_last( char32_t );
  230. Replxx::ACTION_RESULT history_jump( bool );
  231. Replxx::ACTION_RESULT hint_next( char32_t );
  232. Replxx::ACTION_RESULT hint_previous( char32_t );
  233. Replxx::ACTION_RESULT hint_move( bool );
  234. Replxx::ACTION_RESULT toggle_overwrite_mode( char32_t );
  235. #ifndef _WIN32
  236. Replxx::ACTION_RESULT verbatim_insert( char32_t );
  237. Replxx::ACTION_RESULT suspend( char32_t );
  238. #endif
  239. Replxx::ACTION_RESULT complete_line( char32_t );
  240. Replxx::ACTION_RESULT complete_next( char32_t );
  241. Replxx::ACTION_RESULT complete_previous( char32_t );
  242. Replxx::ACTION_RESULT complete( bool );
  243. Replxx::ACTION_RESULT incremental_history_search( char32_t startChar );
  244. Replxx::ACTION_RESULT common_prefix_search( char32_t startChar );
  245. Replxx::ACTION_RESULT bracketed_paste( char32_t startChar );
  246. char32_t read_char( HINT_ACTION = HINT_ACTION::SKIP );
  247. char const* read_from_stdin( void );
  248. char32_t do_complete_line( bool );
  249. void call_modify_callback( void );
  250. completions_t call_completer( std::string const& input, int& ) const;
  251. hints_t call_hinter( std::string const& input, int&, Replxx::Color& color ) const;
  252. void refresh_line( HINT_ACTION = HINT_ACTION::REGENERATE );
  253. void render( char32_t );
  254. void render( HINT_ACTION );
  255. int handle_hints( HINT_ACTION );
  256. void set_color( Replxx::Color );
  257. int context_length( void );
  258. void clear( void );
  259. void repaint( void );
  260. template <bool subword>
  261. bool is_word_break_character( char32_t ) const;
  262. void dynamicRefresh(Prompt& oldPrompt, Prompt& newPrompt, char32_t* buf32, int len, int pos);
  263. char const* finalize_input( char const* );
  264. void clear_self_to_end_of_screen( Prompt const* = nullptr );
  265. typedef struct {
  266. int index;
  267. bool error;
  268. } paren_info_t;
  269. paren_info_t matching_paren( void );
  270. };
  271. }
  272. #endif