Skip to content

Instantly share code, notes, and snippets.

@Arnie97
Last active August 29, 2022 08:19
Show Gist options
  • Select an option

  • Save Arnie97/8d578ab793bb9b3f35394f416c85103c to your computer and use it in GitHub Desktop.

Select an option

Save Arnie97/8d578ab793bb9b3f35394f416c85103c to your computer and use it in GitHub Desktop.

Revisions

  1. Arnie97 created this gist Aug 26, 2022.
    76 changes: 76 additions & 0 deletions ufbump
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    #!/usr/bin/env python3

    """
    Neovim undo file version bumping script
    This python script backups and converts Vim undo files generated by
    vanilla Vim 7.2.444 - 9.0 or Neovim 0.1.0 - 0.4.4 (UF_VERSION=2) to
    reuse them on Neovim 0.5.0+ (UF_VERSION=3) without the error message
    "E824: Incompatible undo file".
    See https://github.com/neovim/neovim/pull/13973 for more information.
    Example usage w/ undodir:
    $ ./ufbump ~/.local/share/nvim/undo/*
    Alternative form if the shell complains about "too many arguments":
    $ find ~/.local/share/nvim/undo -type f -exec ./ufbump '{}' +
    Example usage w/o undodir:
    $ find /code/path -name '*.un~' -type f -exec ./ufbump '{}' +
    USE AT YOUR OWN RISK!
    The author disclaims copyright to this source code.
    In place of a legal notice, here is a blessing:
    * May you do good and not evil.
    * May you find forgiveness for yourself and forgive others.
    * May you share freely, never taking more than you give.
    """

    import os
    import shutil
    import struct
    import sys

    UF_START_MAGIC = b"Vim\237UnDo\345"
    UF_ENTRY_END_MAGIC = b"\x35\x81"

    UF_OLD_VERSION = 2
    UF_NEW_VERSION = 3


    def main(path):
    path_tmp = path + ".tmp"
    path_bak = path + ".bak"

    with open(path, "rb") as src:
    magic = src.read(len(UF_START_MAGIC))
    if magic != UF_START_MAGIC:
    print("%s: not a vim undo file, skipped" % path)
    return

    version, *_ = struct.unpack(">h", src.read(2))
    if version != UF_OLD_VERSION:
    print("%s: undo file version was %d, skipped" % (path, version))
    return

    with open(path_tmp, "wb") as dest:
    dest.write(UF_START_MAGIC)
    dest.write(struct.pack(">h", UF_NEW_VERSION))
    dest.write(src.read().replace(UF_ENTRY_END_MAGIC, UF_ENTRY_END_MAGIC * 2))

    os.rename(path, path_bak)
    os.rename(path_tmp, path)
    print("%s: added empty extmark section" % path)


    if __name__ == "__main__":
    script, *argv = sys.argv
    if not argv:
    print(__doc__.strip())
    for path in argv:
    main(path)