Implement command history

This commit is contained in:
Florian Bruhin 2014-04-15 18:02:07 +02:00
parent 1d5b0ca9a6
commit a410d56a78
4 changed files with 86 additions and 3 deletions

View File

@ -136,6 +136,7 @@ class QuteBrowser(QApplication):
self.config.changed.connect( self.config.changed.connect(
self.mainwindow.completion.on_config_changed) self.mainwindow.completion.on_config_changed)
self.config.changed.connect(self.mainwindow.on_config_changed) self.config.changed.connect(self.mainwindow.on_config_changed)
self.config.changed.connect(config.cmd_history.on_config_changed)
self.mainwindow.show() self.mainwindow.show()
self._python_hacks() self._python_hacks()
@ -379,6 +380,10 @@ class QuteBrowser(QApplication):
config.config.save() config.config.save()
except AttributeError: except AttributeError:
logging.exception("Could not save config.") logging.exception("Could not save config.")
try:
config.cmd_history.save()
except AttributeError:
logging.exception("Could not save command history.")
try: try:
self._save_geometry() self._save_geometry()
config.state.save() config.state.save()

View File

@ -30,7 +30,7 @@ import configparser
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
from collections.abc import MutableMapping from collections.abc import MutableMapping
from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
#from qutebrowser.utils.misc import read_file #from qutebrowser.utils.misc import read_file
import qutebrowser.config.configdata as configdata import qutebrowser.config.configdata as configdata
@ -40,6 +40,7 @@ from qutebrowser.config.conftypes import ValidationError
config = None config = None
state = None state = None
cmd_history = None
class NoSectionError(configparser.NoSectionError): class NoSectionError(configparser.NoSectionError):
@ -62,12 +63,14 @@ def init(configdir):
Args: Args:
configdir: The directory where the configs are stored in. configdir: The directory where the configs are stored in.
""" """
global config, state global config, state, cmd_history
logging.debug("Config init, configdir {}".format(configdir)) logging.debug("Config init, configdir {}".format(configdir))
#config = Config(configdir, 'qutebrowser.conf', #config = Config(configdir, 'qutebrowser.conf',
# read_file('qutebrowser.conf')) # read_file('qutebrowser.conf'))
config = Config(configdir, 'qutebrowser.conf') config = Config(configdir, 'qutebrowser.conf')
state = ReadWriteConfigParser(configdir, 'state') state = ReadWriteConfigParser(configdir, 'state')
cmd_history = LineConfigParser(configdir, 'cmd_history',
('general', 'cmd_histlen'))
class Config(QObject): class Config(QObject):
@ -400,6 +403,72 @@ class ReadWriteConfigParser(ReadConfigParser):
self.write(f) self.write(f)
class LineConfigParser:
"""Parser for configuration files which are simply line-based.
Attributes:
data: A list of lines.
_configdir: The directory to read the config from.
_configfile: The config file path.
"""
def __init__(self, configdir, fname, limit=None):
"""Config constructor.
Args:
configdir: Directory to read the config from.
fname: Filename of the config file.
limit: Config tuple (section, option) which contains a limit.
"""
self._configdir = configdir
self._configfile = os.path.join(self._configdir, fname)
self._limit = limit
self.data = None
if not os.path.isfile(self._configfile):
return
logging.debug("Reading config from {}".format(self._configfile))
self.read(self._configfile)
def read(self, filename):
"""Read the data from a file."""
with open(filename, 'r') as f:
self.data = [line.rstrip('\n') for line in f.readlines()]
def write(self, fp, limit=-1):
"""Write the data to a file.
Arguments:
fp: A file object to write the data to.
limit: How many lines to write, or -1 for no limit.
"""
if limit == -1:
data = self.data
else:
data = self.data[-limit:]
fp.write('\n'.join(data))
def save(self):
"""Save the config file."""
limit = -1 if self._limit is None else config.get(*self._limit)
if limit == 0:
return
if not os.path.exists(self._configdir):
os.makedirs(self._configdir, 0o755)
logging.debug("Saving config to {}".format(self._configfile))
with open(self._configfile, 'w') as f:
self.write(f, limit)
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Delete the file if the limit was changed to 0."""
if self._limit is None:
return
if (section, option) == self._limit and config.get(*self._limit) == 0:
if os.path.exists(self._configfile):
os.remove(self._configfile)
class SectionProxy(MutableMapping): class SectionProxy(MutableMapping):
"""A proxy for a single section from a config. """A proxy for a single section from a config.

View File

@ -138,6 +138,11 @@ def configdata():
('autosave', ('autosave',
SettingValue(types.Bool, "true"), SettingValue(types.Bool, "true"),
"Whether to save the config automatically on quit."), "Whether to save the config automatically on quit."),
('cmd_histlen',
SettingValue(types.Int, "100"),
"How many commands to save in the history. 0: no history / -1: "
"unlimited")
)), )),
('tabbar', sect.KeyValue( ('tabbar', sect.KeyValue(

View File

@ -25,6 +25,7 @@ from PyQt5.QtWidgets import (QWidget, QLineEdit, QProgressBar, QLabel,
QShortcut) QShortcut)
from PyQt5.QtGui import QPainter, QKeySequence, QValidator from PyQt5.QtGui import QPainter, QKeySequence, QValidator
import qutebrowser.config.config as config
from qutebrowser.config.style import set_register_stylesheet, get_stylesheet from qutebrowser.config.style import set_register_stylesheet, get_stylesheet
import qutebrowser.commands.keys as keys import qutebrowser.commands.keys as keys
from qutebrowser.utils.url import urlstring from qutebrowser.utils.url import urlstring
@ -267,7 +268,10 @@ class _Command(QLineEdit):
self.returnPressed.connect(self._on_return_pressed) self.returnPressed.connect(self._on_return_pressed)
self.textEdited.connect(self._histbrowse_stop) self.textEdited.connect(self._histbrowse_stop)
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
self.history = [] if config.cmd_history.data is None:
self.history = []
else:
self.history = config.cmd_history.data
self._shortcuts = [] self._shortcuts = []
for (key, handler) in [ for (key, handler) in [