From 244dbe3a77bf548f73d8781da7327f30e818b08a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 25 Apr 2015 18:47:31 +0300 Subject: viminfo: First version of ShaDa file dumping What works: 1. ShaDa file dumping: header, registers, jump list, history, search patterns, substitute strings, variables. 2. ShaDa file reading: registers, global marks, variables. Most was not tested. TODO: 1. Merging. 2. Reading history, local marks, jump and buffer lists. 3. Documentation update. 4. Converting some data from &encoding. 5. Safer variant of dumping viminfo (dump to temporary file then rename). 6. Removing old viminfo code (currently masked with `#if 0` in a ShaDa file for reference). --- scripts/shadacat.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100755 scripts/shadacat.py (limited to 'scripts/shadacat.py') diff --git a/scripts/shadacat.py b/scripts/shadacat.py new file mode 100755 index 0000000000..8f5ed276f8 --- /dev/null +++ b/scripts/shadacat.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3.4 + +import sys +import codecs + +from enum import Enum +from datetime import datetime +from functools import reduce + +import msgpack + + +class EntryTypes(Enum): + Unknown = -1 + Missing = 0 + Header = 1 + SearchPattern = 2 + SubString = 3 + HistoryEntry = 4 + Register = 5 + Variable = 6 + GlobalMark = 7 + Jump = 8 + BufferList = 9 + LocalMark = 10 + + +def strtrans_errors(e): + if not isinstance(e, UnicodeDecodeError): + raise NotImplementedError('don’t know how to handle {0} error'.format( + e.__class__.__name__)) + return '<{0:x}>'.format(reduce((lambda a, b: a*0x100+b), + list(e.object[e.start:e.end]))), e.end + + +codecs.register_error('strtrans', strtrans_errors) + + +def idfunc(o): + return o + + +class CharInt(int): + def __repr__(self): + return super(CharInt, self).__repr__() + ' (\'%s\')' % chr(self) + + +ctable = { + bytes: lambda s: s.decode('utf-8', 'strtrans'), + dict: lambda d: dict((mnormalize(k), mnormalize(v)) for k, v in d.items()), + list: lambda l: list(mnormalize(i) for i in l), + int: lambda n: CharInt(n) if 0x20 <= n <= 0x7E else n, +} + + +def mnormalize(o): + return ctable.get(type(o), idfunc)(o) + + +with open(sys.argv[1], 'rb') as fp: + unpacker = msgpack.Unpacker(file_like=fp) + while True: + try: + typ = EntryTypes(unpacker.unpack()) + except msgpack.OutOfData: + break + else: + timestamp = unpacker.unpack() + time = datetime.fromtimestamp(timestamp) + length = unpacker.unpack() + entry = unpacker.unpack() + print('{0:13} {1} {2:5} {3!r}'.format( + typ.name, time.isoformat(), length, mnormalize(entry))) -- cgit From 200e62efebe8e87fc612218b675b74def57519f1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 28 Jun 2015 08:06:16 +0300 Subject: shada: Add support for dumping/restoring bufs changes and win jumps --- scripts/shadacat.py | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts/shadacat.py') diff --git a/scripts/shadacat.py b/scripts/shadacat.py index 8f5ed276f8..c710d0ca95 100755 --- a/scripts/shadacat.py +++ b/scripts/shadacat.py @@ -23,6 +23,7 @@ class EntryTypes(Enum): Jump = 8 BufferList = 9 LocalMark = 10 + Change = 11 def strtrans_errors(e): -- cgit From 38b8eb35610f154ef6d90b0e9be693f832dda0a9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 26 Jul 2015 19:29:49 +0300 Subject: scripts: Also print entry offset in shadacat.py --- scripts/shadacat.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts/shadacat.py') diff --git a/scripts/shadacat.py b/scripts/shadacat.py index c710d0ca95..d29000a5d9 100755 --- a/scripts/shadacat.py +++ b/scripts/shadacat.py @@ -59,9 +59,10 @@ def mnormalize(o): with open(sys.argv[1], 'rb') as fp: - unpacker = msgpack.Unpacker(file_like=fp) + unpacker = msgpack.Unpacker(file_like=fp, read_size=1) while True: try: + pos = fp.tell() typ = EntryTypes(unpacker.unpack()) except msgpack.OutOfData: break @@ -70,5 +71,5 @@ with open(sys.argv[1], 'rb') as fp: time = datetime.fromtimestamp(timestamp) length = unpacker.unpack() entry = unpacker.unpack() - print('{0:13} {1} {2:5} {3!r}'.format( - typ.name, time.isoformat(), length, mnormalize(entry))) + print('{0:4} {1:13} {2} {3:5} {4!r}'.format( + pos, typ.name, time.isoformat(), length, mnormalize(entry))) -- cgit From 1e067920994a5dd02df8f71f21afa29f0d4bcd21 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Aug 2015 05:10:19 +0300 Subject: scripts: Improve shadacat to work with unknown items --- scripts/shadacat.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'scripts/shadacat.py') diff --git a/scripts/shadacat.py b/scripts/shadacat.py index d29000a5d9..4ff493bfbc 100755 --- a/scripts/shadacat.py +++ b/scripts/shadacat.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3.4 +import os import sys import codecs @@ -58,18 +59,28 @@ def mnormalize(o): return ctable.get(type(o), idfunc)(o) -with open(sys.argv[1], 'rb') as fp: +fname = sys.argv[1] +poswidth = len(str(os.stat(fname).st_size or 1000)) + + +with open(fname, 'rb') as fp: unpacker = msgpack.Unpacker(file_like=fp, read_size=1) + max_type = max(typ.value for typ in EntryTypes) while True: try: pos = fp.tell() - typ = EntryTypes(unpacker.unpack()) + typ = unpacker.unpack() except msgpack.OutOfData: break else: timestamp = unpacker.unpack() time = datetime.fromtimestamp(timestamp) length = unpacker.unpack() - entry = unpacker.unpack() - print('{0:4} {1:13} {2} {3:5} {4!r}'.format( - pos, typ.name, time.isoformat(), length, mnormalize(entry))) + if typ > max_type: + entry = fp.read(length) + typ = EntryTypes.Unknown + else: + entry = unpacker.unpack() + typ = EntryTypes(typ) + print('%*u %13s %s %5u %r' % ( + poswidth, pos, typ.name, time.isoformat(), length, mnormalize(entry))) -- cgit