mirror of
https://github.com/nvbn/thefuck.git
synced 2025-02-21 12:28:41 +00:00
#N/A Add ability to get shell history
This commit is contained in:
parent
c7071763a3
commit
4b4e7acc0f
@ -12,6 +12,16 @@ def isfile(mocker):
|
|||||||
return mocker.patch('os.path.isfile', return_value=True)
|
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.__iter__.return_value = lines
|
||||||
|
return aux
|
||||||
|
|
||||||
|
|
||||||
class TestGeneric(object):
|
class TestGeneric(object):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def shell(self):
|
def shell(self):
|
||||||
@ -38,6 +48,12 @@ class TestGeneric(object):
|
|||||||
assert 'thefuck' in shell.app_alias()
|
assert 'thefuck' in shell.app_alias()
|
||||||
assert 'TF_ALIAS' in shell.app_alias()
|
assert 'TF_ALIAS' in shell.app_alias()
|
||||||
|
|
||||||
|
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()) == []
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('isfile')
|
@pytest.mark.usefixtures('isfile')
|
||||||
class TestBash(object):
|
class TestBash(object):
|
||||||
@ -85,6 +101,10 @@ class TestBash(object):
|
|||||||
assert 'thefuck' in shell.app_alias()
|
assert 'thefuck' in shell.app_alias()
|
||||||
assert 'TF_ALIAS' in shell.app_alias()
|
assert 'TF_ALIAS' in shell.app_alias()
|
||||||
|
|
||||||
|
def test_get_history(self, history_lines, shell):
|
||||||
|
history_lines(['ls', 'rm'])
|
||||||
|
assert list(shell.get_history()) == ['ls', 'rm']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('isfile')
|
@pytest.mark.usefixtures('isfile')
|
||||||
class TestFish(object):
|
class TestFish(object):
|
||||||
@ -187,3 +207,7 @@ class TestZsh(object):
|
|||||||
assert 'alias fuck' in shell.app_alias()
|
assert 'alias fuck' in shell.app_alias()
|
||||||
assert 'thefuck' in shell.app_alias()
|
assert 'thefuck' in shell.app_alias()
|
||||||
assert 'TF_ALIAS' in shell.app_alias()
|
assert 'TF_ALIAS' in shell.app_alias()
|
||||||
|
|
||||||
|
def test_get_history(self, history_lines, shell):
|
||||||
|
history_lines([': 1432613911:0;ls', ': 1432613916:0;rm'])
|
||||||
|
assert list(shell.get_history()) == ['ls', 'rm']
|
||||||
|
@ -7,7 +7,9 @@ from collections import defaultdict
|
|||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
from time import time
|
from time import time
|
||||||
import os
|
import os
|
||||||
|
import io
|
||||||
from psutil import Process
|
from psutil import Process
|
||||||
|
import six
|
||||||
from .utils import DEVNULL, memoize
|
from .utils import DEVNULL, memoize
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +50,26 @@ class Generic(object):
|
|||||||
with open(history_file_name, 'a') as history:
|
with open(history_file_name, 'a') as history:
|
||||||
history.write(self._get_history_line(command_script))
|
history.write(self._get_history_line(command_script))
|
||||||
|
|
||||||
|
def _script_from_history(self, line):
|
||||||
|
"""Returns prepared history line.
|
||||||
|
|
||||||
|
Should return a blank line if history line is corrupted or empty.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return ''
|
||||||
|
|
||||||
|
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:
|
||||||
|
for line in history:
|
||||||
|
prepared = self._script_from_history(line)\
|
||||||
|
.strip()
|
||||||
|
if prepared:
|
||||||
|
yield prepared
|
||||||
|
|
||||||
def and_(self, *commands):
|
def and_(self, *commands):
|
||||||
return u' && '.join(commands)
|
return u' && '.join(commands)
|
||||||
|
|
||||||
@ -63,7 +85,6 @@ class Bash(Generic):
|
|||||||
value = value[1:-1]
|
value = value[1:-1]
|
||||||
return name, value
|
return name, value
|
||||||
|
|
||||||
@memoize
|
|
||||||
def get_aliases(self):
|
def get_aliases(self):
|
||||||
proc = Popen('bash -ic alias', stdout=PIPE, stderr=DEVNULL,
|
proc = Popen('bash -ic alias', stdout=PIPE, stderr=DEVNULL,
|
||||||
shell=True)
|
shell=True)
|
||||||
@ -79,6 +100,10 @@ class Bash(Generic):
|
|||||||
def _get_history_line(self, command_script):
|
def _get_history_line(self, command_script):
|
||||||
return u'{}\n'.format(command_script)
|
return u'{}\n'.format(command_script)
|
||||||
|
|
||||||
|
def _script_from_history(self, line):
|
||||||
|
print(line)
|
||||||
|
return line
|
||||||
|
|
||||||
|
|
||||||
class Fish(Generic):
|
class Fish(Generic):
|
||||||
def app_alias(self):
|
def app_alias(self):
|
||||||
@ -96,7 +121,6 @@ class Fish(Generic):
|
|||||||
" end\n"
|
" end\n"
|
||||||
"end")
|
"end")
|
||||||
|
|
||||||
@memoize
|
|
||||||
def get_aliases(self):
|
def get_aliases(self):
|
||||||
proc = Popen('fish -ic functions', stdout=PIPE, stderr=DEVNULL,
|
proc = Popen('fish -ic functions', stdout=PIPE, stderr=DEVNULL,
|
||||||
shell=True)
|
shell=True)
|
||||||
@ -137,7 +161,6 @@ class Zsh(Generic):
|
|||||||
value = value[1:-1]
|
value = value[1:-1]
|
||||||
return name, value
|
return name, value
|
||||||
|
|
||||||
@memoize
|
|
||||||
def get_aliases(self):
|
def get_aliases(self):
|
||||||
proc = Popen('zsh -ic alias', stdout=PIPE, stderr=DEVNULL,
|
proc = Popen('zsh -ic alias', stdout=PIPE, stderr=DEVNULL,
|
||||||
shell=True)
|
shell=True)
|
||||||
@ -153,6 +176,12 @@ class Zsh(Generic):
|
|||||||
def _get_history_line(self, command_script):
|
def _get_history_line(self, command_script):
|
||||||
return u': {}:0;{}\n'.format(int(time()), 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 ''
|
||||||
|
|
||||||
|
|
||||||
class Tcsh(Generic):
|
class Tcsh(Generic):
|
||||||
def app_alias(self):
|
def app_alias(self):
|
||||||
@ -162,7 +191,6 @@ class Tcsh(Generic):
|
|||||||
name, value = alias.split("\t", 1)
|
name, value = alias.split("\t", 1)
|
||||||
return name, value
|
return name, value
|
||||||
|
|
||||||
@memoize
|
|
||||||
def get_aliases(self):
|
def get_aliases(self):
|
||||||
proc = Popen('tcsh -ic alias', stdout=PIPE, stderr=DEVNULL,
|
proc = Popen('tcsh -ic alias', stdout=PIPE, stderr=DEVNULL,
|
||||||
shell=True)
|
shell=True)
|
||||||
@ -219,5 +247,11 @@ def and_(*commands):
|
|||||||
return _get_shell().and_(*commands)
|
return _get_shell().and_(*commands)
|
||||||
|
|
||||||
|
|
||||||
|
@memoize
|
||||||
def get_aliases():
|
def get_aliases():
|
||||||
return list(_get_shell().get_aliases().keys())
|
return list(_get_shell().get_aliases().keys())
|
||||||
|
|
||||||
|
|
||||||
|
@memoize
|
||||||
|
def get_history():
|
||||||
|
return list(_get_shell().get_history())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user