Start using KeyParser for command mode

This commit is contained in:
Florian Bruhin 2014-04-25 07:50:21 +02:00
parent 30a6b5610e
commit 55a8da7f1b
5 changed files with 88 additions and 74 deletions

View File

@ -129,6 +129,7 @@ class QuteBrowser(QApplication):
'hint': HintKeyParser(self),
'insert': PassthroughKeyParser('keybind.insert', self),
'passthrough': PassthroughKeyParser('keybind.passthrough', self),
'command': PassthroughKeyParser('keybind.command', self),
}
self._init_cmds()
self.mainwindow = MainWindow()
@ -140,7 +141,8 @@ class QuteBrowser(QApplication):
modes.manager.register('passthrough',
self._keyparsers['passthrough'].handle,
passthrough=True)
modes.manager.register('command', None, passthrough=True)
modes.manager.register('command', self._keyparsers['command'].handle,
passthrough=True)
self.modeman = modes.manager # for commands
self.installEventFilter(modes.manager)
self.setQuitOnLastWindowClosed(False)
@ -302,12 +304,11 @@ class QuteBrowser(QApplication):
tabs.cur_link_hovered.connect(status.url.set_hover_url)
# command input / completion
cmd.esc_pressed.connect(tabs.setFocus)
modes.manager.left.connect(tabs.on_mode_left)
cmd.clear_completion_selection.connect(
completion.on_clear_completion_selection)
cmd.hide_completion.connect(completion.hide)
cmd.textChanged.connect(completion.on_cmd_text_changed)
cmd.tab_pressed.connect(completion.on_tab_pressed)
completion.change_completed_part.connect(cmd.on_change_completed_part)
def _recover_pages(self):

View File

@ -89,7 +89,12 @@ SECTION_DESC = {
"supported in this mode.\n"
"An useful command to map here is the hidden command leave_mode."),
'keybind.passthrough': (
"Keybindings for hint passthrough.\n"
"Keybindings for hint mode.\n"
"Since normal keypresses are passed through, only special keys are "
"supported in this mode.\n"
"An useful command to map here is the hidden command leave_mode."),
'keybind.command': (
"Keybindings for command mode.\n"
"Since normal keypresses are passed through, only special keys are "
"supported in this mode.\n"
"An useful command to map here is the hidden command leave_mode."),
@ -448,6 +453,15 @@ DATA = OrderedDict([
('<Escape>', 'leave_mode'),
)),
('keybind.command', sect.ValueList(
types.KeyBindingName(), types.KeyBinding(),
('<Escape>', 'leave_mode'),
('<Up>', 'command_history_prev'),
('<Down>', 'command_history_next'),
('<Shift-Tab>', 'command_item_prev'),
('<Tab>', 'command_item_next'),
)),
('aliases', sect.ValueList(
types.Command(), types.Command(),
)),

View File

@ -199,6 +199,30 @@ class CompletionView(QTreeView):
logging.debug("No completion model for {}.".format(compl))
return None
def _next_prev_item(self, prev):
"""Handle a tab press for the CompletionView.
Select the previous/next item and write the new text to the
statusbar.
Args:
prev: True for prev item, False for next one.
Emit:
change_completed_part: When a completion took place.
"""
if not self._completing:
# No completion running at the moment, ignore keypress
return
idx = self._next_idx(prev)
self.selectionModel().setCurrentIndex(
idx, QItemSelectionModel.ClearAndSelect |
QItemSelectionModel.Rows)
data = self._model.data(idx)
if data is not None:
self._ignore_next = True
self.change_completed_part.emit(data)
def set_model(self, model):
"""Switch completion to a new model.
@ -265,31 +289,6 @@ class CompletionView(QTreeView):
if self._enabled:
self.show()
@pyqtSlot(bool)
def on_tab_pressed(self, shift):
"""Handle a tab press for the CompletionView.
Select the previous/next item and write the new text to the
statusbar. Called by key_(s)tab_handler in statusbar.command.
Args:
shift: Whether shift is pressed or not.
Emit:
change_completed_part: When a completion took place.
"""
if not self._completing:
# No completion running at the moment, ignore keypress
return
idx = self._next_idx(shift)
self.selectionModel().setCurrentIndex(
idx, QItemSelectionModel.ClearAndSelect |
QItemSelectionModel.Rows)
data = self._model.data(idx)
if data is not None:
self._ignore_next = True
self.change_completed_part.emit(data)
@pyqtSlot()
def on_clear_completion_selection(self):
"""Clear the selection model when an item is activated."""
@ -298,6 +297,16 @@ class CompletionView(QTreeView):
selmod.clearSelection()
selmod.clearCurrentIndex()
@cmdutils.register(instance='mainwindow.completion')
def command_item_prev(self):
"""Select the previous completion item."""
self._next_prev_item(prev=True)
@cmdutils.register(instance='mainwindow.completion')
def command_item_next(self):
"""Select the next completion item."""
self._next_prev_item(prev=False)
class _CompletionItemDelegate(QStyledItemDelegate):

View File

@ -24,6 +24,7 @@ from PyQt5.QtWidgets import (QWidget, QLineEdit, QProgressBar, QLabel,
from PyQt5.QtGui import QPainter, QKeySequence, QValidator
import qutebrowser.keyinput.modes as modes
import qutebrowser.commands.utils as cmdutils
from qutebrowser.keyinput.normalmode import STARTCHARS
from qutebrowser.config.style import set_register_stylesheet, get_stylesheet
from qutebrowser.utils.url import urlstring
@ -214,7 +215,6 @@ class _Command(QLineEdit):
Attributes:
history: The command history object.
_statusbar: The statusbar (parent) QWidget.
_shortcuts: Defined QShortcuts to prevent GCing.
_validator: The current command validator.
Signals:
@ -224,9 +224,6 @@ class _Command(QLineEdit):
arg: The search term.
got_rev_search: Emitted when the user started a new reverse search.
arg: The search term.
esc_pressed: Emitted when the escape key was pressed.
tab_pressed: Emitted when the tab key was pressed.
arg: Whether shift has been pressed.
clear_completion_selection: Emitted before the completion widget is
hidden.
hide_completion: Emitted when the completion widget should be hidden.
@ -237,8 +234,6 @@ class _Command(QLineEdit):
got_cmd = pyqtSignal(str)
got_search = pyqtSignal(str)
got_search_rev = pyqtSignal(str)
esc_pressed = pyqtSignal()
tab_pressed = pyqtSignal(bool)
clear_completion_selection = pyqtSignal()
hide_completion = pyqtSignal()
show_cmd = pyqtSignal()
@ -264,44 +259,6 @@ class _Command(QLineEdit):
self.returnPressed.connect(self._on_return_pressed)
self.textEdited.connect(self.history.stop)
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
self._shortcuts = []
for (key, handler) in [
(Qt.Key_Escape, self.esc_pressed),
(Qt.Key_Up, self._on_key_up_pressed),
(Qt.Key_Down, self._on_key_down_pressed),
(Qt.Key_Tab | Qt.SHIFT, lambda: self.tab_pressed.emit(True)),
(Qt.Key_Tab, lambda: self.tab_pressed.emit(False))
]:
sc = QShortcut(self)
sc.setKey(QKeySequence(key))
sc.setContext(Qt.WidgetWithChildrenShortcut)
sc.activated.connect(handler)
self._shortcuts.append(sc)
@pyqtSlot()
def _on_key_up_pressed(self):
"""Handle Up presses (go back in history)."""
try:
if not self.history.browsing:
item = self.history.start(self.text().strip())
else:
item = self.history.previtem()
except (HistoryEmptyError, HistoryEndReachedError):
return
if item:
self.set_cmd_text(item)
@pyqtSlot()
def _on_key_down_pressed(self):
"""Handle Down presses (go forward in history)."""
if not self.history.browsing:
return
try:
item = self.history.nextitem()
except HistoryEndReachedError:
return
if item:
self.set_cmd_text(item)
@pyqtSlot()
def _on_return_pressed(self):
@ -355,6 +312,31 @@ class _Command(QLineEdit):
self.setFocus()
self.show_cmd.emit()
@cmdutils.register(instance='mainwindow.status.cmd', hide=True)
def command_history_prev(self):
"""Handle Up presses (go back in history)."""
try:
if not self.history.browsing:
item = self.history.start(self.text().strip())
else:
item = self.history.previtem()
except (HistoryEmptyError, HistoryEndReachedError):
return
if item:
self.set_cmd_text(item)
@cmdutils.register(instance='mainwindow.status.cmd', hide=True)
def command_history_next(self):
"""Handle Down presses (go forward in history)."""
if not self.history.browsing:
return
try:
item = self.history.nextitem()
except HistoryEndReachedError:
return
if item:
self.set_cmd_text(item)
def focusInEvent(self, e):
"""Extend focusInEvent to enter command mode."""
modes.enter("command")
@ -368,6 +350,8 @@ class _Command(QLineEdit):
- Clear completion selection
- Hide completion
FIXME we should rather do this on on_mode_left...
Args:
e: The QFocusEvent.
@ -375,7 +359,7 @@ class _Command(QLineEdit):
clear_completion_selection: Always emitted.
hide_completion: Always emitted so the completion is hidden.
"""
modes.leave("command")
modes.maybe_leave("command")
if e.reason() in [Qt.MouseFocusReason, Qt.TabFocusReason,
Qt.BacktabFocusReason, Qt.OtherFocusReason]:
self.setText('')

View File

@ -343,6 +343,12 @@ class TabbedBrowser(TabWidget):
else:
logging.debug('ignoring title change')
@pyqtSlot(str)
def on_mode_left(self, mode):
"""Focus tabs if command mode was left."""
if mode == "command":
self.setFocus()
def resizeEvent(self, e):
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.