Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

history.hxx 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #ifndef REPLXX_HISTORY_HXX_INCLUDED
  2. #define REPLXX_HISTORY_HXX_INCLUDED 1
  3. #include <list>
  4. #include <unordered_map>
  5. #include "unicodestring.hxx"
  6. #include "utf8string.hxx"
  7. #include "conversion.hxx"
  8. #include "util.hxx"
  9. namespace std {
  10. template<>
  11. struct hash<replxx::UnicodeString> {
  12. std::size_t operator()( replxx::UnicodeString const& us_ ) const {
  13. std::size_t h( 0 );
  14. char32_t const* p( us_.get() );
  15. char32_t const* e( p + us_.length() );
  16. while ( p != e ) {
  17. h *= 31;
  18. h += *p;
  19. ++ p;
  20. }
  21. return ( h );
  22. }
  23. };
  24. }
  25. namespace replxx {
  26. class History {
  27. public:
  28. class Entry {
  29. std::string _timestamp;
  30. UnicodeString _text;
  31. public:
  32. Entry( std::string const& timestamp_, UnicodeString const& text_ )
  33. : _timestamp( timestamp_ )
  34. , _text( text_ ) {
  35. }
  36. std::string const& timestamp( void ) const {
  37. return ( _timestamp );
  38. }
  39. UnicodeString const& text( void ) const {
  40. return ( _text );
  41. }
  42. bool operator < ( Entry const& other_ ) const {
  43. return ( _timestamp < other_._timestamp );
  44. }
  45. };
  46. typedef std::list<Entry> entries_t;
  47. typedef std::unordered_map<UnicodeString, entries_t::const_iterator> locations_t;
  48. private:
  49. entries_t _entries;
  50. locations_t _locations;
  51. int _maxSize;
  52. entries_t::const_iterator _current;
  53. entries_t::const_iterator _yankPos;
  54. /*
  55. * _previous and _recallMostRecent are used to allow
  56. * HISTORY_NEXT action (a down-arrow key) to have a special meaning
  57. * if invoked after a line from history was accepted without
  58. * any modification.
  59. * Special meaning is: a down arrow shall jump to the line one
  60. * after previously accepted from history.
  61. */
  62. entries_t::const_iterator _previous;
  63. bool _recallMostRecent;
  64. bool _unique;
  65. public:
  66. History( void );
  67. void add( UnicodeString const& line, std::string const& when = now_ms_str() );
  68. bool save( std::string const& filename, bool );
  69. bool load( std::string const& filename );
  70. void clear( void );
  71. void set_max_size( int len );
  72. void set_unique( bool unique_ ) {
  73. _unique = unique_;
  74. remove_duplicates();
  75. }
  76. void reset_yank_iterator();
  77. bool next_yank_position( void );
  78. void reset_recall_most_recent( void ) {
  79. _recallMostRecent = false;
  80. }
  81. void commit_index( void ) {
  82. _previous = _current;
  83. _recallMostRecent = true;
  84. }
  85. bool is_empty( void ) const {
  86. return ( _entries.empty() );
  87. }
  88. void update_last( UnicodeString const& );
  89. void drop_last( void );
  90. bool is_last( void ) const;
  91. bool move( bool );
  92. UnicodeString const& current( void ) const {
  93. return ( _current->text() );
  94. }
  95. UnicodeString const& yank_line( void ) const {
  96. return ( _yankPos->text() );
  97. }
  98. void jump( bool, bool = true );
  99. bool common_prefix_search( UnicodeString const&, int, bool );
  100. int size( void ) const {
  101. return ( static_cast<int>( _entries.size() ) );
  102. }
  103. Replxx::HistoryScan::impl_t scan( void ) const;
  104. void save_pos( void );
  105. void restore_pos( void );
  106. private:
  107. History( History const& ) = delete;
  108. History& operator = ( History const& ) = delete;
  109. bool move( entries_t::const_iterator&, int, bool = false ) const;
  110. entries_t::const_iterator moved( entries_t::const_iterator, int, bool = false ) const;
  111. void erase( entries_t::const_iterator );
  112. void trim_to_max_size( void );
  113. void remove_duplicate( UnicodeString const& );
  114. void remove_duplicates( void );
  115. bool do_load( std::string const& );
  116. entries_t::const_iterator last( void ) const;
  117. void sort( void );
  118. void reset_iters( void );
  119. };
  120. class Replxx::HistoryScanImpl {
  121. History::entries_t const& _entries;
  122. History::entries_t::const_iterator _it;
  123. mutable Utf8String _utf8Cache;
  124. mutable Replxx::HistoryEntry _entryCache;
  125. mutable bool _cacheValid;
  126. public:
  127. HistoryScanImpl( History::entries_t const& );
  128. bool next( void );
  129. Replxx::HistoryEntry const& get( void ) const;
  130. };
  131. }
  132. #endif