summaryrefslogtreecommitdiffstats
path: root/js/misc/history.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/misc/history.js109
1 files changed, 109 insertions, 0 deletions
diff --git a/js/misc/history.js b/js/misc/history.js
new file mode 100644
index 0000000..c82722c
--- /dev/null
+++ b/js/misc/history.js
@@ -0,0 +1,109 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Signals = imports.signals;
+const Clutter = imports.gi.Clutter;
+const Params = imports.misc.params;
+
+var DEFAULT_LIMIT = 512;
+
+var HistoryManager = class {
+ constructor(params) {
+ params = Params.parse(params, { gsettingsKey: null,
+ limit: DEFAULT_LIMIT,
+ entry: null });
+
+ this._key = params.gsettingsKey;
+ this._limit = params.limit;
+
+ this._historyIndex = 0;
+ if (this._key) {
+ this._history = global.settings.get_strv(this._key);
+ global.settings.connect(`changed::${this._key}`,
+ this._historyChanged.bind(this));
+
+ } else {
+ this._history = [];
+ }
+
+ this._entry = params.entry;
+
+ if (this._entry) {
+ this._entry.connect('key-press-event',
+ this._onEntryKeyPress.bind(this));
+ }
+ }
+
+ _historyChanged() {
+ this._history = global.settings.get_strv(this._key);
+ this._historyIndex = this._history.length;
+ }
+
+ _setPrevItem(text) {
+ if (this._historyIndex <= 0)
+ return false;
+
+ if (text)
+ this._history[this._historyIndex] = text;
+ this._historyIndex--;
+ this._indexChanged();
+ return true;
+ }
+
+ _setNextItem(text) {
+ if (this._historyIndex >= this._history.length)
+ return false;
+
+ if (text)
+ this._history[this._historyIndex] = text;
+ this._historyIndex++;
+ this._indexChanged();
+ return true;
+ }
+
+ lastItem() {
+ if (this._historyIndex != this._history.length) {
+ this._historyIndex = this._history.length;
+ this._indexChanged();
+ }
+
+ return this._historyIndex ? this._history[this._historyIndex - 1] : null;
+ }
+
+ addItem(input) {
+ if (this._history.length == 0 ||
+ this._history[this._history.length - 1] != input) {
+
+ this._history = this._history.filter(entry => entry != input);
+ this._history.push(input);
+ this._save();
+ }
+ this._historyIndex = this._history.length;
+ }
+
+ _onEntryKeyPress(entry, event) {
+ let symbol = event.get_key_symbol();
+ if (symbol == Clutter.KEY_Up)
+ return this._setPrevItem(entry.get_text());
+ else if (symbol == Clutter.KEY_Down)
+ return this._setNextItem(entry.get_text());
+
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ _indexChanged() {
+ let current = this._history[this._historyIndex] || '';
+ this.emit('changed', current);
+
+ if (this._entry)
+ this._entry.set_text(current);
+ }
+
+ _save() {
+ if (this._history.length > this._limit)
+ this._history.splice(0, this._history.length - this._limit);
+
+ if (this._key)
+ global.settings.set_strv(this._key, this._history);
+ }
+};
+Signals.addSignalMethods(HistoryManager.prototype);