mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-31 02:01:13 +00:00
#N/A: Use mmap for sharing output in instant mode
This commit is contained in:
parent
284d49da8d
commit
1508ecfeae
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user