Start using KeyParser for command mode
This commit is contained in:
parent
30a6b5610e
commit
55a8da7f1b
@ -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):
|
||||
|
@ -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(),
|
||||
)),
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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('')
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user