mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 12:06:04 +00:00
#N/A: Split shells
module
This commit is contained in:
parent
60e19a054a
commit
abe287a52b
0
tests/shells/__init__.py
Normal file
0
tests/shells/__init__.py
Normal file
21
tests/shells/conftest.py
Normal file
21
tests/shells/conftest.py
Normal file
@ -0,0 +1,21 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def builtins_open(mocker):
|
||||
return mocker.patch('six.moves.builtins.open')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def isfile(mocker):
|
||||
return mocker.patch('os.path.isfile', return_value=True)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
def history_lines(mocker):
|
||||
def aux(lines):
|
||||
mock = mocker.patch('io.open')
|
||||
mock.return_value.__enter__ \
|
||||
.return_value.readlines.return_value = lines
|
||||
return aux
|
60
tests/shells/test_bash.py
Normal file
60
tests/shells/test_bash.py
Normal file
@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
from thefuck.shells import Bash
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
class TestBash(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return Bash()
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def Popen(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.bash.Popen')
|
||||
mock.return_value.stdout.read.return_value = (
|
||||
b'alias fuck=\'eval $(thefuck $(fc -ln -1))\'\n'
|
||||
b'alias l=\'ls -CF\'\n'
|
||||
b'alias la=\'ls -A\'\n'
|
||||
b'alias ll=\'ls -alF\'')
|
||||
return mock
|
||||
|
||||
@pytest.mark.parametrize('before, after', [
|
||||
('pwd', 'pwd'),
|
||||
('fuck', 'eval $(thefuck $(fc -ln -1))'),
|
||||
('awk', 'awk'),
|
||||
('ll', 'ls -alF')])
|
||||
def test_from_shell(self, before, after, shell):
|
||||
assert shell.from_shell(before) == after
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
@pytest.mark.parametrize('entry, entry_utf8', [
|
||||
('ls', 'ls\n'),
|
||||
(u'echo café', 'echo café\n')])
|
||||
def test_put_to_history(self, entry, entry_utf8, builtins_open, shell):
|
||||
shell.put_to_history(entry)
|
||||
builtins_open.return_value.__enter__.return_value. \
|
||||
write.assert_called_once_with(entry_utf8)
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('ls', 'cd') == 'ls && cd'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {'fuck': 'eval $(thefuck $(fc -ln -1))',
|
||||
'l': 'ls -CF',
|
||||
'la': 'ls -A',
|
||||
'll': 'ls -alF'}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'alias fuck' in shell.app_alias('fuck')
|
||||
assert 'alias FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines(['ls', 'rm'])
|
||||
assert list(shell.get_history()) == ['ls', 'rm']
|
86
tests/shells/test_fish.py
Normal file
86
tests/shells/test_fish.py
Normal file
@ -0,0 +1,86 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
from thefuck.shells import Fish
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
class TestFish(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return Fish()
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def Popen(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.fish.Popen')
|
||||
mock.return_value.stdout.read.return_value = (
|
||||
b'cd\nfish_config\nfuck\nfunced\nfuncsave\ngrep\nhistory\nll\nls\n'
|
||||
b'man\nmath\npopd\npushd\nruby')
|
||||
return mock
|
||||
|
||||
@pytest.fixture
|
||||
def environ(self, monkeypatch):
|
||||
data = {'TF_OVERRIDDEN_ALIASES': 'cd, ls, man, open'}
|
||||
monkeypatch.setattr('thefuck.shells.fish.os.environ', data)
|
||||
return data
|
||||
|
||||
@pytest.mark.usefixture('environ')
|
||||
def test_get_overridden_aliases(self, shell, environ):
|
||||
assert shell._get_overridden_aliases() == ['cd', 'ls', 'man', 'open']
|
||||
|
||||
@pytest.mark.parametrize('before, after', [
|
||||
('cd', 'cd'),
|
||||
('pwd', 'pwd'),
|
||||
('fuck', 'fish -ic "fuck"'),
|
||||
('find', 'find'),
|
||||
('funced', 'fish -ic "funced"'),
|
||||
('grep', 'grep'),
|
||||
('awk', 'awk'),
|
||||
('math "2 + 2"', r'fish -ic "math \"2 + 2\""'),
|
||||
('man', 'man'),
|
||||
('open', 'open'),
|
||||
('vim', 'vim'),
|
||||
('ll', 'fish -ic "ll"'),
|
||||
('ls', 'ls')]) # Fish has no aliases but functions
|
||||
def test_from_shell(self, before, after, shell):
|
||||
assert shell.from_shell(before) == after
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
@pytest.mark.parametrize('entry, entry_utf8', [
|
||||
('ls', '- cmd: ls\n when: 1430707243\n'),
|
||||
(u'echo café', '- cmd: echo café\n when: 1430707243\n')])
|
||||
def test_put_to_history(self, entry, entry_utf8, builtins_open, mocker, shell):
|
||||
mocker.patch('thefuck.shells.fish.time',
|
||||
return_value=1430707243.3517463)
|
||||
shell.put_to_history(entry)
|
||||
builtins_open.return_value.__enter__.return_value. \
|
||||
write.assert_called_once_with(entry_utf8)
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('foo', 'bar') == 'foo; and bar'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {'fish_config': 'fish_config',
|
||||
'fuck': 'fuck',
|
||||
'funced': 'funced',
|
||||
'funcsave': 'funcsave',
|
||||
'history': 'history',
|
||||
'll': 'll',
|
||||
'math': 'math',
|
||||
'popd': 'popd',
|
||||
'pushd': 'pushd',
|
||||
'ruby': 'ruby'}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'function fuck' in shell.app_alias('fuck')
|
||||
assert 'function FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines(['- cmd: ls', ' when: 1432613911',
|
||||
'- cmd: rm', ' when: 1432613916'])
|
||||
assert list(shell.get_history()) == ['ls', 'rm']
|
44
tests/shells/test_generic.py
Normal file
44
tests/shells/test_generic.py
Normal file
@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
from thefuck.shells import Generic
|
||||
|
||||
|
||||
class TestGeneric(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return Generic()
|
||||
|
||||
def test_from_shell(self, shell):
|
||||
assert shell.from_shell('pwd') == 'pwd'
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
def test_put_to_history(self, builtins_open, shell):
|
||||
assert shell.put_to_history('ls') is None
|
||||
assert shell.put_to_history(u'echo café') is None
|
||||
assert builtins_open.call_count == 0
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('ls', 'cd') == 'ls && cd'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'alias fuck' in shell.app_alias('fuck')
|
||||
assert 'alias FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines(['ls', 'rm'])
|
||||
# We don't know what to do in generic shell with history lines,
|
||||
# so just ignore them:
|
||||
assert list(shell.get_history()) == []
|
||||
|
||||
def test_split_command(self, shell):
|
||||
assert shell.split_command('ls') == ['ls']
|
||||
assert shell.split_command(u'echo café') == [u'echo', u'café']
|
62
tests/shells/test_zsh.py
Normal file
62
tests/shells/test_zsh.py
Normal file
@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
from thefuck.shells.zsh import Zsh
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
class TestZsh(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return Zsh()
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def Popen(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.zsh.Popen')
|
||||
mock.return_value.stdout.read.return_value = (
|
||||
b'fuck=\'eval $(thefuck $(fc -ln -1 | tail -n 1))\'\n'
|
||||
b'l=\'ls -CF\'\n'
|
||||
b'la=\'ls -A\'\n'
|
||||
b'll=\'ls -alF\'')
|
||||
return mock
|
||||
|
||||
@pytest.mark.parametrize('before, after', [
|
||||
('fuck', 'eval $(thefuck $(fc -ln -1 | tail -n 1))'),
|
||||
('pwd', 'pwd'),
|
||||
('ll', 'ls -alF')])
|
||||
def test_from_shell(self, before, after, shell):
|
||||
assert shell.from_shell(before) == after
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
@pytest.mark.parametrize('entry, entry_utf8', [
|
||||
('ls', ': 1430707243:0;ls\n'),
|
||||
(u'echo café', ': 1430707243:0;echo café\n')])
|
||||
def test_put_to_history(self, entry, entry_utf8, builtins_open, mocker, shell):
|
||||
mocker.patch('thefuck.shells.zsh.time',
|
||||
return_value=1430707243.3517463)
|
||||
shell.put_to_history(entry)
|
||||
builtins_open.return_value.__enter__.return_value. \
|
||||
write.assert_called_once_with(entry_utf8)
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('ls', 'cd') == 'ls && cd'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {
|
||||
'fuck': 'eval $(thefuck $(fc -ln -1 | tail -n 1))',
|
||||
'l': 'ls -CF',
|
||||
'la': 'ls -A',
|
||||
'll': 'ls -alF'}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'alias fuck' in shell.app_alias('fuck')
|
||||
assert 'alias FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines([': 1432613911:0;ls', ': 1432613916:0;rm'])
|
||||
assert list(shell.get_history()) == ['ls', 'rm']
|
@ -1,260 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
from thefuck import shells
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def builtins_open(mocker):
|
||||
return mocker.patch('six.moves.builtins.open')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def isfile(mocker):
|
||||
return mocker.patch('os.path.isfile', return_value=True)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
def history_lines(mocker):
|
||||
def aux(lines):
|
||||
mock = mocker.patch('io.open')
|
||||
mock.return_value.__enter__\
|
||||
.return_value.readlines.return_value = lines
|
||||
return aux
|
||||
|
||||
|
||||
class TestGeneric(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return shells.Generic()
|
||||
|
||||
def test_from_shell(self, shell):
|
||||
assert shell.from_shell('pwd') == 'pwd'
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
def test_put_to_history(self, builtins_open, shell):
|
||||
assert shell.put_to_history('ls') is None
|
||||
assert shell.put_to_history(u'echo café') is None
|
||||
assert builtins_open.call_count == 0
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('ls', 'cd') == 'ls && cd'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'alias fuck' in shell.app_alias('fuck')
|
||||
assert 'alias FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines(['ls', 'rm'])
|
||||
# We don't know what to do in generic shell with history lines,
|
||||
# so just ignore them:
|
||||
assert list(shell.get_history()) == []
|
||||
|
||||
def test_split_command(self, shell):
|
||||
assert shell.split_command('ls') == ['ls']
|
||||
assert shell.split_command(u'echo café') == [u'echo', u'café']
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
class TestBash(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return shells.Bash()
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def Popen(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.Popen')
|
||||
mock.return_value.stdout.read.return_value = (
|
||||
b'alias fuck=\'eval $(thefuck $(fc -ln -1))\'\n'
|
||||
b'alias l=\'ls -CF\'\n'
|
||||
b'alias la=\'ls -A\'\n'
|
||||
b'alias ll=\'ls -alF\'')
|
||||
return mock
|
||||
|
||||
@pytest.mark.parametrize('before, after', [
|
||||
('pwd', 'pwd'),
|
||||
('fuck', 'eval $(thefuck $(fc -ln -1))'),
|
||||
('awk', 'awk'),
|
||||
('ll', 'ls -alF')])
|
||||
def test_from_shell(self, before, after, shell):
|
||||
assert shell.from_shell(before) == after
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
@pytest.mark.parametrize('entry, entry_utf8', [
|
||||
('ls', 'ls\n'),
|
||||
(u'echo café', 'echo café\n')])
|
||||
def test_put_to_history(self, entry, entry_utf8, builtins_open, shell):
|
||||
shell.put_to_history(entry)
|
||||
builtins_open.return_value.__enter__.return_value. \
|
||||
write.assert_called_once_with(entry_utf8)
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('ls', 'cd') == 'ls && cd'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {'fuck': 'eval $(thefuck $(fc -ln -1))',
|
||||
'l': 'ls -CF',
|
||||
'la': 'ls -A',
|
||||
'll': 'ls -alF'}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'alias fuck' in shell.app_alias('fuck')
|
||||
assert 'alias FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines(['ls', 'rm'])
|
||||
assert list(shell.get_history()) == ['ls', 'rm']
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
class TestFish(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return shells.Fish()
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def Popen(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.Popen')
|
||||
mock.return_value.stdout.read.return_value = (
|
||||
b'cd\nfish_config\nfuck\nfunced\nfuncsave\ngrep\nhistory\nll\nls\n'
|
||||
b'man\nmath\npopd\npushd\nruby')
|
||||
return mock
|
||||
|
||||
@pytest.fixture
|
||||
def environ(self, monkeypatch):
|
||||
data = {'TF_OVERRIDDEN_ALIASES': 'cd, ls, man, open'}
|
||||
monkeypatch.setattr('thefuck.shells.os.environ', data)
|
||||
return data
|
||||
|
||||
@pytest.mark.usefixture('environ')
|
||||
def test_get_overridden_aliases(self, shell, environ):
|
||||
assert shell._get_overridden_aliases() == ['cd', 'ls', 'man', 'open']
|
||||
|
||||
@pytest.mark.parametrize('before, after', [
|
||||
('cd', 'cd'),
|
||||
('pwd', 'pwd'),
|
||||
('fuck', 'fish -ic "fuck"'),
|
||||
('find', 'find'),
|
||||
('funced', 'fish -ic "funced"'),
|
||||
('grep', 'grep'),
|
||||
('awk', 'awk'),
|
||||
('math "2 + 2"', r'fish -ic "math \"2 + 2\""'),
|
||||
('man', 'man'),
|
||||
('open', 'open'),
|
||||
('vim', 'vim'),
|
||||
('ll', 'fish -ic "ll"'),
|
||||
('ls', 'ls')]) # Fish has no aliases but functions
|
||||
def test_from_shell(self, before, after, shell):
|
||||
assert shell.from_shell(before) == after
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
@pytest.mark.parametrize('entry, entry_utf8', [
|
||||
('ls', '- cmd: ls\n when: 1430707243\n'),
|
||||
(u'echo café', '- cmd: echo café\n when: 1430707243\n')])
|
||||
def test_put_to_history(self, entry, entry_utf8, builtins_open, mocker, shell):
|
||||
mocker.patch('thefuck.shells.time',
|
||||
return_value=1430707243.3517463)
|
||||
shell.put_to_history(entry)
|
||||
builtins_open.return_value.__enter__.return_value. \
|
||||
write.assert_called_once_with(entry_utf8)
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('foo', 'bar') == 'foo; and bar'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {'fish_config': 'fish_config',
|
||||
'fuck': 'fuck',
|
||||
'funced': 'funced',
|
||||
'funcsave': 'funcsave',
|
||||
'history': 'history',
|
||||
'll': 'll',
|
||||
'math': 'math',
|
||||
'popd': 'popd',
|
||||
'pushd': 'pushd',
|
||||
'ruby': 'ruby'}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'function fuck' in shell.app_alias('fuck')
|
||||
assert 'function FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines(['- cmd: ls', ' when: 1432613911',
|
||||
'- cmd: rm', ' when: 1432613916'])
|
||||
assert list(shell.get_history()) == ['ls', 'rm']
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('isfile')
|
||||
class TestZsh(object):
|
||||
@pytest.fixture
|
||||
def shell(self):
|
||||
return shells.Zsh()
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def Popen(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.Popen')
|
||||
mock.return_value.stdout.read.return_value = (
|
||||
b'fuck=\'eval $(thefuck $(fc -ln -1 | tail -n 1))\'\n'
|
||||
b'l=\'ls -CF\'\n'
|
||||
b'la=\'ls -A\'\n'
|
||||
b'll=\'ls -alF\'')
|
||||
return mock
|
||||
|
||||
@pytest.mark.parametrize('before, after', [
|
||||
('fuck', 'eval $(thefuck $(fc -ln -1 | tail -n 1))'),
|
||||
('pwd', 'pwd'),
|
||||
('ll', 'ls -alF')])
|
||||
def test_from_shell(self, before, after, shell):
|
||||
assert shell.from_shell(before) == after
|
||||
|
||||
def test_to_shell(self, shell):
|
||||
assert shell.to_shell('pwd') == 'pwd'
|
||||
|
||||
@pytest.mark.parametrize('entry, entry_utf8', [
|
||||
('ls', ': 1430707243:0;ls\n'),
|
||||
(u'echo café', ': 1430707243:0;echo café\n')])
|
||||
def test_put_to_history(self, entry, entry_utf8, builtins_open, mocker, shell):
|
||||
mocker.patch('thefuck.shells.time',
|
||||
return_value=1430707243.3517463)
|
||||
shell.put_to_history(entry)
|
||||
builtins_open.return_value.__enter__.return_value. \
|
||||
write.assert_called_once_with(entry_utf8)
|
||||
|
||||
def test_and_(self, shell):
|
||||
assert shell.and_('ls', 'cd') == 'ls && cd'
|
||||
|
||||
def test_get_aliases(self, shell):
|
||||
assert shell.get_aliases() == {
|
||||
'fuck': 'eval $(thefuck $(fc -ln -1 | tail -n 1))',
|
||||
'l': 'ls -CF',
|
||||
'la': 'ls -A',
|
||||
'll': 'ls -alF'}
|
||||
|
||||
def test_app_alias(self, shell):
|
||||
assert 'alias fuck' in shell.app_alias('fuck')
|
||||
assert 'alias FUCK' in shell.app_alias('FUCK')
|
||||
assert 'thefuck' in shell.app_alias('fuck')
|
||||
assert 'TF_ALIAS=fuck PYTHONIOENCODING' in shell.app_alias('fuck')
|
||||
assert 'PYTHONIOENCODING=utf-8 thefuck' in shell.app_alias('fuck')
|
||||
|
||||
def test_get_history(self, history_lines, shell):
|
||||
history_lines([': 1432613911:0;ls', ': 1432613916:0;rm'])
|
||||
assert list(shell.get_history()) == ['ls', 'rm']
|
@ -1,334 +0,0 @@
|
||||
"""Module with shell specific actions, each shell class should
|
||||
implement `from_shell`, `to_shell`, `app_alias`, `put_to_history` and
|
||||
`get_aliases` methods.
|
||||
|
||||
"""
|
||||
from collections import defaultdict
|
||||
from psutil import Process
|
||||
from subprocess import Popen, PIPE
|
||||
from time import time
|
||||
import io
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
import six
|
||||
from .utils import DEVNULL, memoize, cache
|
||||
from .conf import settings
|
||||
from . import logs
|
||||
|
||||
|
||||
class Generic(object):
|
||||
def get_aliases(self):
|
||||
return {}
|
||||
|
||||
def _expand_aliases(self, command_script):
|
||||
aliases = self.get_aliases()
|
||||
binary = command_script.split(' ')[0]
|
||||
if binary in aliases:
|
||||
return command_script.replace(binary, aliases[binary], 1)
|
||||
else:
|
||||
return command_script
|
||||
|
||||
def from_shell(self, command_script):
|
||||
"""Prepares command before running in app."""
|
||||
return self._expand_aliases(command_script)
|
||||
|
||||
def to_shell(self, command_script):
|
||||
"""Prepares command for running in shell."""
|
||||
return command_script
|
||||
|
||||
def app_alias(self, fuck):
|
||||
return "alias {0}='eval $(TF_ALIAS={0} PYTHONIOENCODING=utf-8 " \
|
||||
"thefuck $(fc -ln -1))'".format(fuck)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return ''
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return ''
|
||||
|
||||
def put_to_history(self, command_script):
|
||||
"""Puts command script to shell history."""
|
||||
history_file_name = self._get_history_file_name()
|
||||
if os.path.isfile(history_file_name):
|
||||
with open(history_file_name, 'a') as history:
|
||||
entry = self._get_history_line(command_script)
|
||||
if six.PY2:
|
||||
history.write(entry.encode('utf-8'))
|
||||
else:
|
||||
history.write(entry)
|
||||
|
||||
def get_history(self):
|
||||
"""Returns list of history entries."""
|
||||
history_file_name = self._get_history_file_name()
|
||||
if os.path.isfile(history_file_name):
|
||||
with io.open(history_file_name, 'r',
|
||||
encoding='utf-8', errors='ignore') as history_file:
|
||||
|
||||
lines = history_file.readlines()
|
||||
if settings.history_limit:
|
||||
lines = lines[-settings.history_limit:]
|
||||
|
||||
for line in lines:
|
||||
prepared = self._script_from_history(line) \
|
||||
.strip()
|
||||
if prepared:
|
||||
yield prepared
|
||||
|
||||
def and_(self, *commands):
|
||||
return u' && '.join(commands)
|
||||
|
||||
def how_to_configure(self):
|
||||
return
|
||||
|
||||
def split_command(self, command):
|
||||
"""Split the command using shell-like syntax."""
|
||||
if six.PY2:
|
||||
return [s.decode('utf8') for s in shlex.split(command.encode('utf8'))]
|
||||
return shlex.split(command)
|
||||
|
||||
def quote(self, s):
|
||||
"""Return a shell-escaped version of the string s."""
|
||||
|
||||
if six.PY2:
|
||||
from pipes import quote
|
||||
else:
|
||||
from shlex import quote
|
||||
|
||||
return quote(s)
|
||||
|
||||
def _script_from_history(self, line):
|
||||
return line
|
||||
|
||||
|
||||
class Bash(Generic):
|
||||
def app_alias(self, fuck):
|
||||
return "alias {0}='eval " \
|
||||
"$(TF_ALIAS={0} PYTHONIOENCODING=utf-8 thefuck $(fc -ln -1));" \
|
||||
" history -r'".format(fuck)
|
||||
|
||||
def _parse_alias(self, alias):
|
||||
name, value = alias.replace('alias ', '', 1).split('=', 1)
|
||||
if value[0] == value[-1] == '"' or value[0] == value[-1] == "'":
|
||||
value = value[1:-1]
|
||||
return name, value
|
||||
|
||||
@memoize
|
||||
@cache('.bashrc', '.bash_profile')
|
||||
def get_aliases(self):
|
||||
proc = Popen(['bash', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
|
||||
return dict(
|
||||
self._parse_alias(alias)
|
||||
for alias in proc.stdout.read().decode('utf-8').split('\n')
|
||||
if alias and '=' in alias)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.environ.get("HISTFILE",
|
||||
os.path.expanduser('~/.bash_history'))
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u'{}\n'.format(command_script)
|
||||
|
||||
def how_to_configure(self):
|
||||
if os.path.join(os.path.expanduser('~'), '.bashrc'):
|
||||
config = '~/.bashrc'
|
||||
elif os.path.join(os.path.expanduser('~'), '.bash_profile'):
|
||||
config = '~/.bashrc'
|
||||
else:
|
||||
config = 'bash config'
|
||||
return 'eval $(thefuck --alias)', config
|
||||
|
||||
|
||||
class Fish(Generic):
|
||||
def _get_overridden_aliases(self):
|
||||
overridden_aliases = os.environ.get('TF_OVERRIDDEN_ALIASES', '').strip()
|
||||
if overridden_aliases:
|
||||
return [alias.strip() for alias in overridden_aliases.split(',')]
|
||||
else:
|
||||
return ['cd', 'grep', 'ls', 'man', 'open']
|
||||
|
||||
def app_alias(self, fuck):
|
||||
return ('function {0} -d "Correct your previous console command"\n'
|
||||
' set -l exit_code $status\n'
|
||||
' set -l fucked_up_command $history[1]\n'
|
||||
' env TF_ALIAS={0} PYTHONIOENCODING=utf-8'
|
||||
' thefuck $fucked_up_command | read -l unfucked_command\n'
|
||||
' if [ "$unfucked_command" != "" ]\n'
|
||||
' eval $unfucked_command\n'
|
||||
' if test $exit_code -ne 0\n'
|
||||
' history --delete $fucked_up_command\n'
|
||||
' history --merge ^ /dev/null\n'
|
||||
' return 0\n'
|
||||
' end\n'
|
||||
' end\n'
|
||||
'end').format(fuck)
|
||||
|
||||
@memoize
|
||||
@cache('.config/fish/config.fish', '.config/fish/functions')
|
||||
def get_aliases(self):
|
||||
overridden = self._get_overridden_aliases()
|
||||
proc = Popen(['fish', '-ic', 'functions'], stdout=PIPE, stderr=DEVNULL)
|
||||
functions = proc.stdout.read().decode('utf-8').strip().split('\n')
|
||||
return {func: func for func in functions if func not in overridden}
|
||||
|
||||
def _expand_aliases(self, command_script):
|
||||
aliases = self.get_aliases()
|
||||
binary = command_script.split(' ')[0]
|
||||
if binary in aliases:
|
||||
return u'fish -ic "{}"'.format(command_script.replace('"', r'\"'))
|
||||
else:
|
||||
return command_script
|
||||
|
||||
def from_shell(self, command_script):
|
||||
"""Prepares command before running in app."""
|
||||
return self._expand_aliases(command_script)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.path.expanduser('~/.config/fish/fish_history')
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u'- cmd: {}\n when: {}\n'.format(command_script, int(time()))
|
||||
|
||||
def _script_from_history(self, line):
|
||||
if '- cmd: ' in line:
|
||||
return line.split('- cmd: ', 1)[1]
|
||||
else:
|
||||
return ''
|
||||
|
||||
def and_(self, *commands):
|
||||
return u'; and '.join(commands)
|
||||
|
||||
def how_to_configure(self):
|
||||
return 'eval thefuck --alias', '~/.config/fish/config.fish'
|
||||
|
||||
|
||||
class Zsh(Generic):
|
||||
def app_alias(self, fuck):
|
||||
return "alias {0}='eval $(TF_ALIAS={0} PYTHONIOENCODING=utf-8" \
|
||||
" thefuck $(fc -ln -1 | tail -n 1));" \
|
||||
" fc -R'".format(fuck)
|
||||
|
||||
def _parse_alias(self, alias):
|
||||
name, value = alias.split('=', 1)
|
||||
if value[0] == value[-1] == '"' or value[0] == value[-1] == "'":
|
||||
value = value[1:-1]
|
||||
return name, value
|
||||
|
||||
@memoize
|
||||
@cache('.zshrc')
|
||||
def get_aliases(self):
|
||||
proc = Popen(['zsh', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
|
||||
return dict(
|
||||
self._parse_alias(alias)
|
||||
for alias in proc.stdout.read().decode('utf-8').split('\n')
|
||||
if alias and '=' in alias)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.environ.get("HISTFILE",
|
||||
os.path.expanduser('~/.zsh_history'))
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u': {}:0;{}\n'.format(int(time()), command_script)
|
||||
|
||||
def _script_from_history(self, line):
|
||||
if ';' in line:
|
||||
return line.split(';', 1)[1]
|
||||
else:
|
||||
return ''
|
||||
|
||||
def how_to_configure(self):
|
||||
return 'eval $(thefuck --alias)', '~/.zshrc'
|
||||
|
||||
|
||||
class Tcsh(Generic):
|
||||
def app_alias(self, fuck):
|
||||
return ("alias {0} 'setenv TF_ALIAS {0} && "
|
||||
"set fucked_cmd=`history -h 2 | head -n 1` && "
|
||||
"eval `thefuck ${{fucked_cmd}}`'").format(fuck)
|
||||
|
||||
def _parse_alias(self, alias):
|
||||
name, value = alias.split("\t", 1)
|
||||
return name, value
|
||||
|
||||
@memoize
|
||||
def get_aliases(self):
|
||||
proc = Popen(['tcsh', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
|
||||
return dict(
|
||||
self._parse_alias(alias)
|
||||
for alias in proc.stdout.read().decode('utf-8').split('\n')
|
||||
if alias and '\t' in alias)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.environ.get("HISTFILE",
|
||||
os.path.expanduser('~/.history'))
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u'#+{}\n{}\n'.format(int(time()), command_script)
|
||||
|
||||
def how_to_configure(self):
|
||||
return 'eval `thefuck --alias`', '~/.tcshrc'
|
||||
|
||||
|
||||
shells = defaultdict(Generic, {
|
||||
'bash': Bash(),
|
||||
'fish': Fish(),
|
||||
'zsh': Zsh(),
|
||||
'csh': Tcsh(),
|
||||
'tcsh': Tcsh()})
|
||||
|
||||
|
||||
@memoize
|
||||
def _get_shell():
|
||||
try:
|
||||
shell = Process(os.getpid()).parent().name()
|
||||
except TypeError:
|
||||
shell = Process(os.getpid()).parent.name
|
||||
return shells[shell]
|
||||
|
||||
|
||||
def from_shell(command):
|
||||
return _get_shell().from_shell(command)
|
||||
|
||||
|
||||
def to_shell(command):
|
||||
return _get_shell().to_shell(command)
|
||||
|
||||
|
||||
def app_alias(alias):
|
||||
return _get_shell().app_alias(alias)
|
||||
|
||||
|
||||
def thefuck_alias():
|
||||
return os.environ.get('TF_ALIAS', 'fuck')
|
||||
|
||||
|
||||
def put_to_history(command):
|
||||
try:
|
||||
return _get_shell().put_to_history(command)
|
||||
except IOError:
|
||||
logs.exception("Can't update history", sys.exc_info())
|
||||
|
||||
|
||||
def and_(*commands):
|
||||
return _get_shell().and_(*commands)
|
||||
|
||||
|
||||
def get_aliases():
|
||||
return list(_get_shell().get_aliases().keys())
|
||||
|
||||
|
||||
def split_command(command):
|
||||
return _get_shell().split_command(command)
|
||||
|
||||
|
||||
def quote(s):
|
||||
return _get_shell().quote(s)
|
||||
|
||||
|
||||
@memoize
|
||||
def get_history():
|
||||
return list(_get_shell().get_history())
|
||||
|
||||
|
||||
def how_to_configure():
|
||||
return _get_shell().how_to_configure()
|
75
thefuck/shells/__init__.py
Normal file
75
thefuck/shells/__init__.py
Normal file
@ -0,0 +1,75 @@
|
||||
from collections import defaultdict
|
||||
from psutil import Process
|
||||
import os
|
||||
import sys
|
||||
from ..utils import memoize
|
||||
from .. import logs
|
||||
from .bash import Bash
|
||||
from .fish import Fish
|
||||
from .generic import Generic
|
||||
from .tcsh import Tcsh
|
||||
from .zsh import Zsh
|
||||
|
||||
shells = defaultdict(Generic,
|
||||
bash=Bash(),
|
||||
fish=Fish(),
|
||||
zsh=Zsh(),
|
||||
csh=Tcsh(),
|
||||
tcsh=Tcsh())
|
||||
|
||||
|
||||
@memoize
|
||||
def _get_shell():
|
||||
try:
|
||||
shell = Process(os.getpid()).parent().name()
|
||||
except TypeError:
|
||||
shell = Process(os.getpid()).parent.name
|
||||
return shells[shell]
|
||||
|
||||
|
||||
def from_shell(command):
|
||||
return _get_shell().from_shell(command)
|
||||
|
||||
|
||||
def to_shell(command):
|
||||
return _get_shell().to_shell(command)
|
||||
|
||||
|
||||
def app_alias(alias):
|
||||
return _get_shell().app_alias(alias)
|
||||
|
||||
|
||||
def thefuck_alias():
|
||||
return os.environ.get('TF_ALIAS', 'fuck')
|
||||
|
||||
|
||||
def put_to_history(command):
|
||||
try:
|
||||
return _get_shell().put_to_history(command)
|
||||
except IOError:
|
||||
logs.exception("Can't update history", sys.exc_info())
|
||||
|
||||
|
||||
def and_(*commands):
|
||||
return _get_shell().and_(*commands)
|
||||
|
||||
|
||||
def get_aliases():
|
||||
return list(_get_shell().get_aliases().keys())
|
||||
|
||||
|
||||
def split_command(command):
|
||||
return _get_shell().split_command(command)
|
||||
|
||||
|
||||
def quote(s):
|
||||
return _get_shell().quote(s)
|
||||
|
||||
|
||||
@memoize
|
||||
def get_history():
|
||||
return list(_get_shell().get_history())
|
||||
|
||||
|
||||
def how_to_configure():
|
||||
return _get_shell().how_to_configure()
|
42
thefuck/shells/bash.py
Normal file
42
thefuck/shells/bash.py
Normal file
@ -0,0 +1,42 @@
|
||||
from subprocess import Popen, PIPE
|
||||
import os
|
||||
from ..utils import DEVNULL, memoize, cache
|
||||
from .generic import Generic
|
||||
|
||||
|
||||
class Bash(Generic):
|
||||
def app_alias(self, fuck):
|
||||
return "alias {0}='eval " \
|
||||
"$(TF_ALIAS={0} PYTHONIOENCODING=utf-8 thefuck $(fc -ln -1));" \
|
||||
" history -r'".format(fuck)
|
||||
|
||||
def _parse_alias(self, alias):
|
||||
name, value = alias.replace('alias ', '', 1).split('=', 1)
|
||||
if value[0] == value[-1] == '"' or value[0] == value[-1] == "'":
|
||||
value = value[1:-1]
|
||||
return name, value
|
||||
|
||||
@memoize
|
||||
@cache('.bashrc', '.bash_profile')
|
||||
def get_aliases(self):
|
||||
proc = Popen(['bash', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
|
||||
return dict(
|
||||
self._parse_alias(alias)
|
||||
for alias in proc.stdout.read().decode('utf-8').split('\n')
|
||||
if alias and '=' in alias)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.environ.get("HISTFILE",
|
||||
os.path.expanduser('~/.bash_history'))
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u'{}\n'.format(command_script)
|
||||
|
||||
def how_to_configure(self):
|
||||
if os.path.join(os.path.expanduser('~'), '.bashrc'):
|
||||
config = '~/.bashrc'
|
||||
elif os.path.join(os.path.expanduser('~'), '.bash_profile'):
|
||||
config = '~/.bashrc'
|
||||
else:
|
||||
config = 'bash config'
|
||||
return 'eval $(thefuck --alias)', config
|
68
thefuck/shells/fish.py
Normal file
68
thefuck/shells/fish.py
Normal file
@ -0,0 +1,68 @@
|
||||
from subprocess import Popen, PIPE
|
||||
from time import time
|
||||
import os
|
||||
from ..utils import DEVNULL, memoize, cache
|
||||
from .generic import Generic
|
||||
|
||||
|
||||
class Fish(Generic):
|
||||
def _get_overridden_aliases(self):
|
||||
overridden_aliases = os.environ.get('TF_OVERRIDDEN_ALIASES', '').strip()
|
||||
if overridden_aliases:
|
||||
return [alias.strip() for alias in overridden_aliases.split(',')]
|
||||
else:
|
||||
return ['cd', 'grep', 'ls', 'man', 'open']
|
||||
|
||||
def app_alias(self, fuck):
|
||||
return ('function {0} -d "Correct your previous console command"\n'
|
||||
' set -l exit_code $status\n'
|
||||
' set -l fucked_up_command $history[1]\n'
|
||||
' env TF_ALIAS={0} PYTHONIOENCODING=utf-8'
|
||||
' thefuck $fucked_up_command | read -l unfucked_command\n'
|
||||
' if [ "$unfucked_command" != "" ]\n'
|
||||
' eval $unfucked_command\n'
|
||||
' if test $exit_code -ne 0\n'
|
||||
' history --delete $fucked_up_command\n'
|
||||
' history --merge ^ /dev/null\n'
|
||||
' return 0\n'
|
||||
' end\n'
|
||||
' end\n'
|
||||
'end').format(fuck)
|
||||
|
||||
@memoize
|
||||
@cache('.config/fish/config.fish', '.config/fish/functions')
|
||||
def get_aliases(self):
|
||||
overridden = self._get_overridden_aliases()
|
||||
proc = Popen(['fish', '-ic', 'functions'], stdout=PIPE, stderr=DEVNULL)
|
||||
functions = proc.stdout.read().decode('utf-8').strip().split('\n')
|
||||
return {func: func for func in functions if func not in overridden}
|
||||
|
||||
def _expand_aliases(self, command_script):
|
||||
aliases = self.get_aliases()
|
||||
binary = command_script.split(' ')[0]
|
||||
if binary in aliases:
|
||||
return u'fish -ic "{}"'.format(command_script.replace('"', r'\"'))
|
||||
else:
|
||||
return command_script
|
||||
|
||||
def from_shell(self, command_script):
|
||||
"""Prepares command before running in app."""
|
||||
return self._expand_aliases(command_script)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.path.expanduser('~/.config/fish/fish_history')
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u'- cmd: {}\n when: {}\n'.format(command_script, int(time()))
|
||||
|
||||
def _script_from_history(self, line):
|
||||
if '- cmd: ' in line:
|
||||
return line.split('- cmd: ', 1)[1]
|
||||
else:
|
||||
return ''
|
||||
|
||||
def and_(self, *commands):
|
||||
return u'; and '.join(commands)
|
||||
|
||||
def how_to_configure(self):
|
||||
return 'eval thefuck --alias', '~/.config/fish/config.fish'
|
89
thefuck/shells/generic.py
Normal file
89
thefuck/shells/generic.py
Normal file
@ -0,0 +1,89 @@
|
||||
import io
|
||||
import os
|
||||
import shlex
|
||||
import six
|
||||
from ..conf import settings
|
||||
|
||||
|
||||
class Generic(object):
|
||||
def get_aliases(self):
|
||||
return {}
|
||||
|
||||
def _expand_aliases(self, command_script):
|
||||
aliases = self.get_aliases()
|
||||
binary = command_script.split(' ')[0]
|
||||
if binary in aliases:
|
||||
return command_script.replace(binary, aliases[binary], 1)
|
||||
else:
|
||||
return command_script
|
||||
|
||||
def from_shell(self, command_script):
|
||||
"""Prepares command before running in app."""
|
||||
return self._expand_aliases(command_script)
|
||||
|
||||
def to_shell(self, command_script):
|
||||
"""Prepares command for running in shell."""
|
||||
return command_script
|
||||
|
||||
def app_alias(self, fuck):
|
||||
return "alias {0}='eval $(TF_ALIAS={0} PYTHONIOENCODING=utf-8 " \
|
||||
"thefuck $(fc -ln -1))'".format(fuck)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return ''
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return ''
|
||||
|
||||
def put_to_history(self, command_script):
|
||||
"""Puts command script to shell history."""
|
||||
history_file_name = self._get_history_file_name()
|
||||
if os.path.isfile(history_file_name):
|
||||
with open(history_file_name, 'a') as history:
|
||||
entry = self._get_history_line(command_script)
|
||||
if six.PY2:
|
||||
history.write(entry.encode('utf-8'))
|
||||
else:
|
||||
history.write(entry)
|
||||
|
||||
def get_history(self):
|
||||
"""Returns list of history entries."""
|
||||
history_file_name = self._get_history_file_name()
|
||||
if os.path.isfile(history_file_name):
|
||||
with io.open(history_file_name, 'r',
|
||||
encoding='utf-8', errors='ignore') as history_file:
|
||||
|
||||
lines = history_file.readlines()
|
||||
if settings.history_limit:
|
||||
lines = lines[-settings.history_limit:]
|
||||
|
||||
for line in lines:
|
||||
prepared = self._script_from_history(line) \
|
||||
.strip()
|
||||
if prepared:
|
||||
yield prepared
|
||||
|
||||
def and_(self, *commands):
|
||||
return u' && '.join(commands)
|
||||
|
||||
def how_to_configure(self):
|
||||
return
|
||||
|
||||
def split_command(self, command):
|
||||
"""Split the command using shell-like syntax."""
|
||||
if six.PY2:
|
||||
return [s.decode('utf8') for s in shlex.split(command.encode('utf8'))]
|
||||
return shlex.split(command)
|
||||
|
||||
def quote(self, s):
|
||||
"""Return a shell-escaped version of the string s."""
|
||||
|
||||
if six.PY2:
|
||||
from pipes import quote
|
||||
else:
|
||||
from shlex import quote
|
||||
|
||||
return quote(s)
|
||||
|
||||
def _script_from_history(self, line):
|
||||
return line
|
34
thefuck/shells/tcsh.py
Normal file
34
thefuck/shells/tcsh.py
Normal file
@ -0,0 +1,34 @@
|
||||
from subprocess import Popen, PIPE
|
||||
from time import time
|
||||
import os
|
||||
from ..utils import DEVNULL, memoize
|
||||
from .generic import Generic
|
||||
|
||||
|
||||
class Tcsh(Generic):
|
||||
def app_alias(self, fuck):
|
||||
return ("alias {0} 'setenv TF_ALIAS {0} && "
|
||||
"set fucked_cmd=`history -h 2 | head -n 1` && "
|
||||
"eval `thefuck ${{fucked_cmd}}`'").format(fuck)
|
||||
|
||||
def _parse_alias(self, alias):
|
||||
name, value = alias.split("\t", 1)
|
||||
return name, value
|
||||
|
||||
@memoize
|
||||
def get_aliases(self):
|
||||
proc = Popen(['tcsh', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
|
||||
return dict(
|
||||
self._parse_alias(alias)
|
||||
for alias in proc.stdout.read().decode('utf-8').split('\n')
|
||||
if alias and '\t' in alias)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.environ.get("HISTFILE",
|
||||
os.path.expanduser('~/.history'))
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u'#+{}\n{}\n'.format(int(time()), command_script)
|
||||
|
||||
def how_to_configure(self):
|
||||
return 'eval `thefuck --alias`', '~/.tcshrc'
|
43
thefuck/shells/zsh.py
Normal file
43
thefuck/shells/zsh.py
Normal file
@ -0,0 +1,43 @@
|
||||
from subprocess import Popen, PIPE
|
||||
from time import time
|
||||
import os
|
||||
from ..utils import DEVNULL, memoize, cache
|
||||
from .generic import Generic
|
||||
|
||||
|
||||
class Zsh(Generic):
|
||||
def app_alias(self, fuck):
|
||||
return "alias {0}='eval $(TF_ALIAS={0} PYTHONIOENCODING=utf-8" \
|
||||
" thefuck $(fc -ln -1 | tail -n 1));" \
|
||||
" fc -R'".format(fuck)
|
||||
|
||||
def _parse_alias(self, alias):
|
||||
name, value = alias.split('=', 1)
|
||||
if value[0] == value[-1] == '"' or value[0] == value[-1] == "'":
|
||||
value = value[1:-1]
|
||||
return name, value
|
||||
|
||||
@memoize
|
||||
@cache('.zshrc')
|
||||
def get_aliases(self):
|
||||
proc = Popen(['zsh', '-ic', 'alias'], stdout=PIPE, stderr=DEVNULL)
|
||||
return dict(
|
||||
self._parse_alias(alias)
|
||||
for alias in proc.stdout.read().decode('utf-8').split('\n')
|
||||
if alias and '=' in alias)
|
||||
|
||||
def _get_history_file_name(self):
|
||||
return os.environ.get("HISTFILE",
|
||||
os.path.expanduser('~/.zsh_history'))
|
||||
|
||||
def _get_history_line(self, command_script):
|
||||
return u': {}:0;{}\n'.format(int(time()), command_script)
|
||||
|
||||
def _script_from_history(self, line):
|
||||
if ';' in line:
|
||||
return line.split(';', 1)[1]
|
||||
else:
|
||||
return ''
|
||||
|
||||
def how_to_configure(self):
|
||||
return 'eval $(thefuck --alias)', '~/.zshrc'
|
Loading…
x
Reference in New Issue
Block a user