diff options
Diffstat (limited to 'contrib/replxx/src/killring.hxx')
-rw-r--r-- | contrib/replxx/src/killring.hxx | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/contrib/replxx/src/killring.hxx b/contrib/replxx/src/killring.hxx new file mode 100644 index 000000000..9eca23a8e --- /dev/null +++ b/contrib/replxx/src/killring.hxx @@ -0,0 +1,76 @@ +#ifndef REPLXX_KILLRING_HXX_INCLUDED +#define REPLXX_KILLRING_HXX_INCLUDED 1 + +#include <vector> + +#include "unicodestring.hxx" + +namespace replxx { + +class KillRing { + static const int capacity = 10; + int size; + int index; + char indexToSlot[10]; + std::vector<UnicodeString> theRing; + +public: + enum action { actionOther, actionKill, actionYank }; + action lastAction; + size_t lastYankSize; + + KillRing() : size(0), index(0), lastAction(actionOther) { + theRing.reserve(capacity); + } + + void kill(const char32_t* text, int textLen, bool forward) { + if (textLen == 0) { + return; + } + UnicodeString killedText(text, textLen); + if (lastAction == actionKill && size > 0) { + int slot = indexToSlot[0]; + int currentLen = static_cast<int>(theRing[slot].length()); + UnicodeString temp; + if ( forward ) { + temp.append( theRing[slot].get(), currentLen ).append( killedText.get(), textLen ); + } else { + temp.append( killedText.get(), textLen ).append( theRing[slot].get(), currentLen ); + } + theRing[slot] = temp; + } else { + if (size < capacity) { + if (size > 0) { + memmove(&indexToSlot[1], &indexToSlot[0], size); + } + indexToSlot[0] = size; + size++; + theRing.push_back(killedText); + } else { + int slot = indexToSlot[capacity - 1]; + theRing[slot] = killedText; + memmove(&indexToSlot[1], &indexToSlot[0], capacity - 1); + indexToSlot[0] = slot; + } + index = 0; + } + } + + UnicodeString* yank() { return (size > 0) ? &theRing[indexToSlot[index]] : 0; } + + UnicodeString* yankPop() { + if (size == 0) { + return 0; + } + ++index; + if (index == size) { + index = 0; + } + return &theRing[indexToSlot[index]]; + } +}; + +} + +#endif + |