mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-06 09:20:57 +01:00
wip: work on history show
This commit is contained in:
parent
6bde45459e
commit
b0a292401d
6 changed files with 98 additions and 65 deletions
|
@ -1,4 +1,5 @@
|
|||
import threading
|
||||
import uuid
|
||||
|
||||
|
||||
class HistoryGC(threading.Thread):
|
||||
|
@ -6,16 +7,13 @@ class HistoryGC(threading.Thread):
|
|||
|
||||
|
||||
class HistoryBase:
|
||||
def __init__(self, gc=True, **kwargs):
|
||||
def __init__(self, sessionid=None, gc=True, **kwargs):
|
||||
self.sessionid = uuid.uuid4() if sessionid is None else sessionid
|
||||
self.gc = HistoryGC() if gc else None
|
||||
self.rtns = None
|
||||
self.last_cmd_rtn = None
|
||||
self.last_cmd_out = None
|
||||
|
||||
def __iter__(self):
|
||||
for cmd, ts, index in []:
|
||||
yield (cmd, ts, index)
|
||||
|
||||
def append(self, cmd):
|
||||
pass
|
||||
|
||||
|
@ -23,7 +21,13 @@ class HistoryBase:
|
|||
pass
|
||||
|
||||
def items(self):
|
||||
return []
|
||||
"""Display all history items."""
|
||||
raise NotImplementedError
|
||||
|
||||
def show_info(self):
|
||||
def session_items(self):
|
||||
"""Display history items of current session."""
|
||||
raise NotImplementedError
|
||||
|
||||
def show_info(self, ns, stdout=None, stderr=None):
|
||||
"""Display information about the shell history."""
|
||||
pass
|
||||
|
|
|
@ -1,15 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Implements the xonsh history backend."""
|
||||
import sys
|
||||
import collections
|
||||
import json
|
||||
|
||||
from xonsh.history.base import HistoryBase
|
||||
|
||||
|
||||
class DummyHistory(HistoryBase):
|
||||
def append(self, cmd):
|
||||
print('DummyHistory append: {}'.format(cmd), file=sys.stderr)
|
||||
pass
|
||||
|
||||
def flush(self, at_exit=False):
|
||||
print('DummyHistory flush ...', file=sys.stderr)
|
||||
pass
|
||||
|
||||
def items(self):
|
||||
yield {'inp': 'dummy in action\n'}
|
||||
"""Display all history items."""
|
||||
yield {'inp': 'dummy in action', 'ts': 1464652800, 'ind': 0}
|
||||
|
||||
def session_items(self):
|
||||
"""Display history items of current session."""
|
||||
return self.items()
|
||||
|
||||
def show_info(self, ns, stdout=None, stderr=None):
|
||||
"""Display information about the shell history."""
|
||||
data = collections.OrderedDict()
|
||||
data['backend'] = 'dummy'
|
||||
data['sessionid'] = str(self.sessionid)
|
||||
if ns.json:
|
||||
s = json.dumps(data)
|
||||
print(s, file=stdout)
|
||||
else:
|
||||
for k, v in data.items():
|
||||
print('{}: {}'.format(k, v))
|
||||
|
|
|
@ -402,16 +402,21 @@ class JsonHistory(HistoryBase):
|
|||
self.gc = JsonHistoryGC(wait_for_shell=False, size=size)
|
||||
return self.gc
|
||||
|
||||
def session_items(self, **kwargs):
|
||||
return iter(self)
|
||||
def session_items(self):
|
||||
"""Display history items of current session."""
|
||||
ind = 0
|
||||
for item, tss in zip(self.inps, self.tss):
|
||||
yield {'inp': item.rstrip(), 'ind': ind, 'ts': tss[0]}
|
||||
ind += 1
|
||||
|
||||
# TODO: merge methods all_items() and items() to one
|
||||
def all_items(self, **kwargs):
|
||||
def items(self, **kwargs):
|
||||
"""
|
||||
Returns all history as found in XONSH_DATA_DIR.
|
||||
|
||||
return format: (cmd, start_time, index)
|
||||
"""
|
||||
while self.gc.is_alive():
|
||||
time.sleep(0.011) # gc sleeps for 0.01 secs, sleep a beat longer
|
||||
ind = 0
|
||||
for f in _get_history_files():
|
||||
try:
|
||||
|
@ -421,23 +426,13 @@ class JsonHistory(HistoryBase):
|
|||
continue
|
||||
commands = json_file.load()['cmds']
|
||||
for c in commands:
|
||||
yield (c['inp'].rstrip(), c['ts'][0], ind)
|
||||
yield {'inp': c['inp'].rstrip(), 'ts': c['ts'][0], 'ind': ind}
|
||||
ind += 1
|
||||
|
||||
# TODO: merge methods all_items() and items() to one
|
||||
def items(self):
|
||||
while self.gc.is_alive():
|
||||
time.sleep(0.011) # gc sleeps for 0.01 secs, sleep a beat longer
|
||||
files = self.gc.files()
|
||||
for _, _, f in files:
|
||||
with open(self.filename, 'r', newline='\n') as f:
|
||||
hist = xlj.LazyJSON(f).load()
|
||||
for command in hist['cmds']:
|
||||
yield dict(command)
|
||||
|
||||
def show_info(self, ns, stdout=None, stderr=None):
|
||||
"""Display information about the shell history."""
|
||||
data = collections.OrderedDict()
|
||||
data['backend'] = 'json'
|
||||
data['sessionid'] = str(self.sessionid)
|
||||
data['filename'] = self.filename
|
||||
data['length'] = len(self)
|
||||
|
@ -450,19 +445,6 @@ class JsonHistory(HistoryBase):
|
|||
lines = ['{0}: {1}'.format(k, v) for k, v in data.items()]
|
||||
print('\n'.join(lines), file=stdout)
|
||||
|
||||
def __iter__(self):
|
||||
"""Get current session history.
|
||||
|
||||
Yields
|
||||
------
|
||||
tuple
|
||||
``tuple`` of the form (cmd, start_time, index).
|
||||
"""
|
||||
start_times = (start for start, end in self.tss)
|
||||
names = (name.rstrip() for name in self.inps)
|
||||
for ind, (c, t) in enumerate(zip(names, start_times)):
|
||||
yield (c, t, ind)
|
||||
|
||||
def __getitem__(self, item):
|
||||
"""Retrieve history parts based on filtering rules,
|
||||
see ``History`` docs for more info. Accepts one of
|
||||
|
|
|
@ -52,7 +52,7 @@ def _xh_all_parser(hist=None, **kwargs):
|
|||
"""Returns all history items."""
|
||||
if hist is None:
|
||||
hist = builtins.__xonsh_history__
|
||||
return hist.all_items()
|
||||
return hist.items()
|
||||
|
||||
|
||||
def _xh_find_histfile_var(file_list, default=None):
|
||||
|
@ -187,24 +187,24 @@ def _hist_show(ns, hist=None, stdout=None, stderr=None):
|
|||
if ns.reverse:
|
||||
commands = reversed(list(commands))
|
||||
if not ns.numerate and not ns.timestamp:
|
||||
for c, _, _ in commands:
|
||||
print(c, file=stdout)
|
||||
for c in commands:
|
||||
print(c['inp'], file=stdout)
|
||||
elif not ns.timestamp:
|
||||
for c, _, i in commands:
|
||||
print('{}: {}'.format(i, c), file=stdout)
|
||||
for c in commands:
|
||||
print('{}: {}'.format(c['ind'], c['inp']), file=stdout)
|
||||
elif not ns.numerate:
|
||||
for c, ts, _ in commands:
|
||||
dt = datetime.datetime.fromtimestamp(ts).ctime()
|
||||
print('({}) {}'.format(dt, c), file=stdout)
|
||||
for c in commands:
|
||||
dt = datetime.datetime.fromtimestamp(c['ts']).ctime()
|
||||
print('({}) {}'.format(dt, c['inp']), file=stdout)
|
||||
else:
|
||||
for c, ts, i in commands:
|
||||
dt = datetime.datetime.fromtimestamp(ts).ctime()
|
||||
print('{}:({}) {}'.format(i, dt, c), file=stdout)
|
||||
for c in commands:
|
||||
dt = datetime.datetime.fromtimestamp(c['ts']).ctime()
|
||||
print('{}:({}) {}'.format(c['ind'], dt, c['inp']), file=stdout)
|
||||
|
||||
|
||||
def _hist_info(ns, hist, stdout=None, stderr=None):
|
||||
def _xh_hist_info(ns, hist, stdout=None, stderr=None):
|
||||
"""Display information about the shell history."""
|
||||
hist.show_info(ns)
|
||||
hist.show_info(ns, stdout=stdout, stderr=stderr)
|
||||
|
||||
|
||||
@xla.lazyobject
|
||||
|
@ -222,7 +222,7 @@ def _HIST_MAIN_ACTIONS():
|
|||
'show': _hist_show,
|
||||
'id': lambda ns, hist, stdout, stderr: print(hist.sessionid, file=stdout),
|
||||
'file': lambda ns, hist, stdout, stderr: print(hist.filename, file=stdout),
|
||||
'info': _hist_info,
|
||||
'info': _xh_hist_info,
|
||||
'diff': xdh._dh_main_action,
|
||||
'gc': _hist_gc,
|
||||
}
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Implements the xonsh history backend via sqlite3."""
|
||||
import builtins
|
||||
import collections
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
import time
|
||||
|
||||
from xonsh.history.base import HistoryBase
|
||||
import xonsh.tools as xt
|
||||
|
||||
|
||||
def _xh_sqlite_get_file_name():
|
||||
envs = builtins.__xonsh_env__
|
||||
file_name = envs.get('XONSH_HISTORY_SQLITE_FILE')
|
||||
if not file_name:
|
||||
data_dir = envs.get('XONSH_DATA_DIR')
|
||||
file_name = os.path.join(data_dir, 'xonsh-history.sqlite')
|
||||
return xt.expanduser_abs_path(file_name)
|
||||
|
||||
|
||||
def _xh_sqlite_get_conn():
|
||||
data_dir = builtins.__xonsh_env__.get('XONSH_DATA_DIR')
|
||||
data_dir = xt.expanduser_abs_path(data_dir)
|
||||
db_file = os.path.join(data_dir, 'xonsh-history.sqlite')
|
||||
db_file = _xh_sqlite_get_file_name()
|
||||
return sqlite3.connect(db_file)
|
||||
|
||||
|
||||
|
@ -34,7 +42,7 @@ def _xh_sqlite_insert_command(cursor, cmd):
|
|||
|
||||
|
||||
def _xh_sqlite_get_records(cursor):
|
||||
cursor.execute('SELECT inp FROM xonsh_history ORDER BY tsb')
|
||||
cursor.execute('SELECT inp, tsb FROM xonsh_history ORDER BY tsb')
|
||||
return cursor.fetchall()
|
||||
|
||||
|
||||
|
@ -54,8 +62,11 @@ def xh_sqlite_items():
|
|||
|
||||
|
||||
class SqliteHistory(HistoryBase):
|
||||
def __init__(self, gc=True, **kwargs):
|
||||
super().__init__(gc=gc, **kwargs)
|
||||
def __init__(self, filename=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
if filename is None:
|
||||
filename = _xh_sqlite_get_file_name()
|
||||
self.filename = filename
|
||||
self.last_cmd_inp = None
|
||||
|
||||
def append(self, cmd):
|
||||
|
@ -67,13 +78,30 @@ class SqliteHistory(HistoryBase):
|
|||
# Skipping failed cmd
|
||||
return
|
||||
self.last_cmd_inp = cmd['inp'].rstrip()
|
||||
t = time.time()
|
||||
xh_sqlite_append_history(cmd)
|
||||
print('history cmd: {} took {:.4f}s'.format(cmd, time.time() - t))
|
||||
|
||||
def flush(self, at_exit=False):
|
||||
print('TODO: SqliteHistory flush() called')
|
||||
|
||||
def items(self):
|
||||
i = 0
|
||||
for item in xh_sqlite_items():
|
||||
yield {'inp': item[0]}
|
||||
yield {'inp': item[0], 'ts': item[1], 'ind': i}
|
||||
i += 1
|
||||
|
||||
def session_items(self):
|
||||
"""Display history items of current session."""
|
||||
return self.items()
|
||||
|
||||
def show_info(self, ns, stdout=None, stderr=None):
|
||||
"""Display information about the shell history."""
|
||||
data = collections.OrderedDict()
|
||||
data['backend'] = 'sqlite'
|
||||
data['sessionid'] = str(self.sessionid)
|
||||
data['filename'] = self.filename
|
||||
if ns.json:
|
||||
s = json.dumps(data)
|
||||
print(s, file=stdout)
|
||||
else:
|
||||
for k, v in data.items():
|
||||
print('{}: {}'.format(k, v))
|
||||
|
|
|
@ -105,7 +105,7 @@ def _rp_create_parser(p=None):
|
|||
return p
|
||||
|
||||
|
||||
def _rp_main_action(ns, h=None):
|
||||
def _rp_main_action(ns, h=None, stdout=None, stderr=None):
|
||||
replayer = Replayer(ns.path)
|
||||
hist = replayer.replay(merge_envs=ns.merge_envs, target=ns.target)
|
||||
print('----------------------------------------------------------------')
|
||||
|
|
Loading…
Add table
Reference in a new issue