1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-02-14 17:08:45 +00:00

94 lines
2.6 KiB
Python
Raw Normal View History

2015-07-29 15:22:24 +03:00
# -*- encoding: utf-8 -*-
2015-07-28 22:04:27 +03:00
import sys
2015-09-06 21:47:12 +03:00
from .conf import settings
2015-09-08 15:24:49 +03:00
from .exceptions import NoRuleMatched
from .system import get_key
from . import logs, const
2015-07-29 15:22:24 +03:00
2015-07-28 22:04:27 +03:00
def read_actions():
"""Yields actions for pressed keys."""
while True:
key = get_key()
2015-07-28 22:04:27 +03:00
# Handle arrows, j/k (qwerty), and n/e (colemak)
if key in (const.KEY_UP, 'k', 'e'):
2016-02-22 18:40:28 +03:00
yield const.ACTION_PREVIOUS
elif key in (const.KEY_DOWN, 'j', 'n'):
2016-02-22 18:40:28 +03:00
yield const.ACTION_NEXT
elif key in (const.KEY_CTRL_C, 'q'):
2016-02-22 18:40:28 +03:00
yield const.ACTION_ABORT
elif key in ('\n', '\r'):
2016-02-22 18:40:28 +03:00
yield const.ACTION_SELECT
2015-07-28 22:04:27 +03:00
class CommandSelector(object):
"""Helper for selecting rule from rules list."""
2015-07-28 22:04:27 +03:00
def __init__(self, commands):
""":type commands: Iterable[thefuck.types.CorrectedCommand]"""
self._commands_gen = commands
2015-09-08 15:24:49 +03:00
try:
self._commands = [next(self._commands_gen)]
except StopIteration:
raise NoRuleMatched
self._realised = False
2015-07-28 22:04:27 +03:00
self._index = 0
def _realise(self):
if not self._realised:
self._commands += list(self._commands_gen)
self._realised = True
2015-07-28 22:04:27 +03:00
def next(self):
self._realise()
2015-07-28 22:04:27 +03:00
self._index = (self._index + 1) % len(self._commands)
def previous(self):
self._realise()
2015-07-28 22:04:27 +03:00
self._index = (self._index - 1) % len(self._commands)
@property
def value(self):
""":rtype hefuck.types.CorrectedCommand"""
2015-07-28 22:04:27 +03:00
return self._commands[self._index]
2015-09-06 21:47:12 +03:00
def select_command(corrected_commands):
2015-07-28 22:04:27 +03:00
"""Returns:
- the first command when confirmation disabled;
- None when ctrl+c pressed;
- selected command.
:type corrected_commands: Iterable[thefuck.types.CorrectedCommand]
:rtype: thefuck.types.CorrectedCommand | None
2015-07-28 22:04:27 +03:00
"""
try:
selector = CommandSelector(corrected_commands)
2015-09-08 15:24:49 +03:00
except NoRuleMatched:
2015-09-06 21:47:12 +03:00
logs.failed('No fucks given')
2015-07-28 22:04:27 +03:00
return
if not settings.require_confirmation:
2015-09-06 21:47:12 +03:00
logs.show_corrected_command(selector.value)
2015-07-28 22:04:27 +03:00
return selector.value
logs.confirm_text(selector.value)
2015-07-30 18:28:20 +03:00
for action in read_actions():
2016-02-22 18:40:28 +03:00
if action == const.ACTION_SELECT:
2015-07-28 22:04:27 +03:00
sys.stderr.write('\n')
return selector.value
2016-02-22 18:40:28 +03:00
elif action == const.ACTION_ABORT:
2015-09-06 21:47:12 +03:00
logs.failed('\nAborted')
2015-07-28 22:04:27 +03:00
return
2016-02-22 18:40:28 +03:00
elif action == const.ACTION_PREVIOUS:
2015-07-28 22:04:27 +03:00
selector.previous()
logs.confirm_text(selector.value)
2016-02-22 18:40:28 +03:00
elif action == const.ACTION_NEXT:
2015-07-28 22:04:27 +03:00
selector.next()
logs.confirm_text(selector.value)