1
0
mirror of https://github.com/nvbn/thefuck.git synced 2024-10-05 18:31:10 +01:00

#N/A: Use mmap for sharing output in instant mode

This commit is contained in:
Vladimir Iakovlev 2018-03-14 00:12:40 +01:00
parent 284d49da8d
commit 1508ecfeae
3 changed files with 26 additions and 20 deletions

View File

@ -76,8 +76,8 @@ CONFIGURATION_TIMEOUT = 60
USER_COMMAND_MARK = u'\u200B' * 10
LOG_SIZE = 1000
LOG_SIZE_IN_BYTES = 1024 * 1024
LOG_SIZE_TO_CLEAN = 10 * 1024
DIFF_WITH_ALIAS = 0.5

View File

@ -1,19 +1,24 @@
import array
import fcntl
from functools import partial
import mmap
import os
import pty
import signal
import sys
import termios
import tty
from ..logs import warn
from .. import logs, const
def _read(f, fd):
data = os.read(fd, 1024)
f.write(data)
f.flush()
try:
f.write(data)
except ValueError:
f.move(0, const.LOG_SIZE_TO_CLEAN,
const.LOG_SIZE_IN_BYTES - const.LOG_SIZE_TO_CLEAN)
f.seek(const.LOG_SIZE_IN_BYTES - const.LOG_SIZE_TO_CLEAN)
return data
@ -61,10 +66,12 @@ def shell_logger(output):
"""
if not os.environ.get('SHELL'):
warn("Shell logger doesn't support your platform.")
logs.warn("Shell logger doesn't support your platform.")
sys.exit(1)
with open(output, 'wb') as f:
return_code = _spawn(os.environ['SHELL'], partial(_read, f))
fd = os.open(output, os.O_CREAT | os.O_TRUNC | os.O_RDWR)
os.write(fd, b'\x00' * const.LOG_SIZE_IN_BYTES)
buffer = mmap.mmap(fd, const.LOG_SIZE_IN_BYTES, mmap.MAP_SHARED, mmap.PROT_WRITE)
return_code = _spawn(os.environ['SHELL'], partial(_read, buffer))
sys.exit(return_code)

View File

@ -1,5 +1,7 @@
import os
import shlex
import mmap
import re
try:
from shutil import get_terminal_size
except ImportError:
@ -18,11 +20,6 @@ def _group_by_calls(log):
script_line = None
lines = []
for line in log:
try:
line = line.decode()
except UnicodeDecodeError:
continue
if const.USER_COMMAND_MARK in line or ps1_counter > 0:
if script_line and ps1_counter == 0:
yield script_line, lines
@ -53,13 +50,14 @@ def _get_script_group_lines(grouped, script):
def _get_output_lines(script, log_file):
lines = log_file.readlines()[-const.LOG_SIZE:]
data = log_file.read().decode()
data = re.sub(r'\x00+$', '', data)
lines = data.split('\n')
grouped = list(_group_by_calls(lines))
script_lines = _get_script_group_lines(grouped, script)
screen = pyte.Screen(get_terminal_size().columns, len(script_lines))
stream = pyte.Stream(screen)
stream.feed(''.join(script_lines))
stream.feed('\n'.join(script_lines))
return screen.display
@ -91,10 +89,11 @@ def get_output(script):
return None
try:
with logs.debug_time(u'Read output from log'), \
open(os.environ['THEFUCK_OUTPUT_LOG'], 'rb') as log_file:
_skip_old_lines(log_file)
lines = _get_output_lines(script, log_file)
with logs.debug_time(u'Read output from log'):
fd = os.open(os.environ['THEFUCK_OUTPUT_LOG'], os.O_RDONLY)
buffer = mmap.mmap(fd, const.LOG_SIZE_IN_BYTES, mmap.MAP_SHARED, mmap.PROT_READ)
_skip_old_lines(buffer)
lines = _get_output_lines(script, buffer)
output = '\n'.join(lines).strip()
logs.debug(u'Received output: {}'.format(output))
return output