2b1f664aed
Whenever a command runs in the run dialog, it will be added to the history unless it is already the last entry. This does not apply for entries that are not consecutive, which can result in long chains of commands which alternate, e.g. lg, r, lg, r, lg, r. Not only is this wasteful in terms of space, but also inconsistent with how history works elsewhere, e.g. in the shell. Therefore, remove entries in the history that are equal to the one that will be added to the end of of the history when the entry already exists. https://gitlab.gnome.org/GNOME/gnome-shell/issues/524
113 lines
3.1 KiB
JavaScript
113 lines
3.1 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
const Lang = imports.lang;
|
|
const Signals = imports.signals;
|
|
const Clutter = imports.gi.Clutter;
|
|
const Params = imports.misc.params;
|
|
|
|
var DEFAULT_LIMIT = 512;
|
|
|
|
var HistoryManager = new Lang.Class({
|
|
Name: 'HistoryManager',
|
|
|
|
_init(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);
|