diff --git a/README.md b/README.md index 395253f4..29d73ff1 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`; * `no_command` – fixes wrong console commands, for example `vom/vim`; * `no_such_file` – creates missing directories with `mv` and `cp` commands; -* `open` – prepends `http` to address passed to `open`; +* `open` – either prepends `http://` to address passed to `open` or create a new file or directory and passes it to `open`; * `pip_unknown_command` – fixes wrong `pip` commands, for example `pip instatl/pip install`; * `python_command` – prepends `python` when you trying to run not executable/without `./` python script; * `python_execute` – appends missing `.py` when executing Python files; diff --git a/tests/rules/test_open.py b/tests/rules/test_open.py index c80eeca8..9186adf4 100644 --- a/tests/rules/test_open.py +++ b/tests/rules/test_open.py @@ -1,31 +1,49 @@ import pytest -from thefuck.rules.open import match, get_new_command +from thefuck.rules.open import is_arg_url, match, get_new_command from tests.utils import Command -@pytest.mark.parametrize('command', [ - Command(script='open foo.com'), - Command(script='open foo.ly'), - Command(script='open foo.org'), - Command(script='open foo.net'), - Command(script='open foo.se'), - Command(script='open foo.io'), - Command(script='xdg-open foo.com'), - Command(script='gnome-open foo.com'), - Command(script='kde-open foo.com')]) -def test_match(command): - assert match(command) +@pytest.fixture +def stderr(script): + return 'The file {} does not exist.\n'.format(script.split(' ', 1)[1]) -@pytest.mark.parametrize('command, new_command', [ - (Command('open foo.com'), 'open http://foo.com'), - (Command('open foo.ly'), 'open http://foo.ly'), - (Command('open foo.org'), 'open http://foo.org'), - (Command('open foo.net'), 'open http://foo.net'), - (Command('open foo.se'), 'open http://foo.se'), - (Command('open foo.io'), 'open http://foo.io'), - (Command('xdg-open foo.io'), 'xdg-open http://foo.io'), - (Command('gnome-open foo.io'), 'gnome-open http://foo.io'), - (Command('kde-open foo.io'), 'kde-open http://foo.io')]) -def test_get_new_command(command, new_command): - assert get_new_command(command) == new_command +@pytest.mark.parametrize('script', [ + 'open foo.com', + 'open foo.edu', + 'open foo.info', + 'open foo.io', + 'open foo.ly', + 'open foo.me', + 'open foo.net', + 'open foo.org', + 'open foo.se', + 'open www.foo.ru']) +def test_is_arg_url(script): + assert is_arg_url(Command(script)) + + +@pytest.mark.parametrize('script', ['open foo', 'open bar.txt', 'open egg.doc']) +def test_not_is_arg_url(script): + assert not is_arg_url(Command(script)) + + +@pytest.mark.parametrize('script', [ + 'open foo.com', + 'xdg-open foo.com', + 'gnome-open foo.com', + 'kde-open foo.com', + 'open nonest']) +def test_match(script, stderr): + assert match(Command(script, stderr=stderr)) + + +@pytest.mark.parametrize('script, new_command', [ + ('open foo.io', ['open http://foo.io']), + ('xdg-open foo.io', ['xdg-open http://foo.io']), + ('gnome-open foo.io', ['gnome-open http://foo.io']), + ('kde-open foo.io', ['kde-open http://foo.io']), + ('open nonest', ['touch nonest && open nonest', + 'mkdir nonest && open nonest'])]) +def test_get_new_command(script, new_command, stderr): + assert get_new_command(Command(script, stderr=stderr)) == new_command diff --git a/thefuck/rules/open.py b/thefuck/rules/open.py index b46f497d..86f20087 100644 --- a/thefuck/rules/open.py +++ b/thefuck/rules/open.py @@ -5,22 +5,36 @@ # The file ~/github.com does not exist. # Perhaps you meant 'http://github.com'? # -from thefuck.utils import for_app +from thefuck.shells import shell +from thefuck.utils import eager, for_app + + +def is_arg_url(command): + return ('.com' in command.script or + '.edu' in command.script or + '.info' in command.script or + '.io' in command.script or + '.ly' in command.script or + '.me' in command.script or + '.net' in command.script or + '.org' in command.script or + '.se' in command.script or + 'www.' in command.script) @for_app('open', 'xdg-open', 'gnome-open', 'kde-open') def match(command): - return ('.com' in command.script - or '.net' in command.script - or '.org' in command.script - or '.ly' in command.script - or '.io' in command.script - or '.se' in command.script - or '.edu' in command.script - or '.info' in command.script - or '.me' in command.script - or 'www.' in command.script) + return (is_arg_url(command) or + command.stderr.strip().startswith('The file ') and + command.stderr.strip().endswith(' does not exist.')) +@eager def get_new_command(command): - return command.script.replace('open ', 'open http://') + stderr = command.stderr.strip() + if is_arg_url(command): + yield command.script.replace('open ', 'open http://') + elif stderr.startswith('The file ') and stderr.endswith(' does not exist.'): + arg = command.script.split(' ', 1)[1] + for option in ['touch', 'mkdir']: + yield shell.and_(u'{} {}'.format(option, arg), command.script)