Last active
August 29, 2022 08:19
-
-
Save Arnie97/8d578ab793bb9b3f35394f416c85103c to your computer and use it in GitHub Desktop.
Neovim 0.5+ undo file version bumping script. Fixes "E824: Incompatible undo file"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment