Skip to content

Instantly share code, notes, and snippets.

@ernix
Last active March 12, 2022 06:02
Show Gist options
  • Save ernix/f190b2c1a8b7a933abf44eff80a0648a to your computer and use it in GitHub Desktop.
Save ernix/f190b2c1a8b7a933abf44eff80a0648a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# See: https://github.com/textlint/textlint/issues/852
import json
import subprocess
import sys
from functools import cache
from os import getenv
from unicodedata import east_asian_width
r"""
USAGE:
Set makeprg/errorformat in your ~/.vimrc like:
> " text
> autocmd BufNewFile,BufRead *.txt setlocal filetype=text
> autocmd FileType text
> \ setlocal
> \ makeprg=nkf\ -w\ %\ \\\\|textlint_fix_col.py\ --stdin
> \\ \\\\|awk\ 'BEGIN{FS=\":\";OFS=\":\"}/:/{$1=\"%\";print}'
> \ errorformat=%f:%l:%v:\ %m\ [%t%*[a-zA-Z0-9/]],
> \%-G,
> \%-G%.%#\ problem,
> \%-G%.%#\ problems
>
> " markdown
> autocmd BufNewFile,BufRead *.md,*.mkd setlocal filetype=markdown
> autocmd FileType markdown
> \ setlocal
> \ colorcolumn=0
> \ spell
> \ previewheight=3
> \ makeprg=textlint_fix_col.py\ --plugin\ markdown
> \ errorformat=%f:%l:%v:\ %m\ [%t%*[a-zA-Z0-9/]],
> \%-G,
> \%-G%.%#\ problem,
> \%-G%.%#\ problems
"""
@cache
def read_file(path):
with open(path, "r") as f:
return f.readlines()
def main():
args = sys.argv[1:]
if "--" in args:
index = args.index("--")
else:
index = len(args)
opt_stdin = "--stdin" in args[:index]
args = ["npx", "textlint", *args[:index], "--format", "json", *args[index:]]
lines = None
if opt_stdin:
lines = sys.stdin.readlines()
result = subprocess.run(args,
capture_output=True,
input=bytes("".join(lines), "utf-8"))
else:
result = subprocess.run(args,
capture_output=True)
obj = json.loads(result.stdout)
for row in obj:
file_path = row["filePath"]
if not opt_stdin:
lines = read_file(file_path)
for err in row.get("messages", []):
line = lines[err["line"] - 1]
col = err["column"] - 1
binary = bytearray(line, encoding="utf-16le")[0:col * 2]
display_col = 0
for char in binary.decode("utf-16le"):
if char == "\t":
display_col += int(getenv("TEXTLINT_TAB_WIDTH", 4))
elif east_asian_width(char) in ("F", "W"):
display_col += 2
else:
display_col += 1
print("%s:%d:%d: %s [Error/%s]" % (file_path,
err["line"],
display_col + 1,
err["message"],
err["ruleId"],))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment