This is a simple example of using pymacs to fix a flake8 warning. The warning is covering use of = or !
with None. The fixer is invoked with the point on the line containing the warning or error. This is part of a system I’m building to support auto-correction of flake8 and pylint warnings in emacs. As the system matures I plan to host it on github so that others may also contribute to it.
Here is the actual fixer function with a utility function to get the string of the current line. A key to understanding what’s going on with the code is that lisp.function(arg) is the equivalent of (function arg) in elisp.
def get_line_string ():
"""Get the start, end and string of the line the point is on."""
start = lisp.line_beginning_position()
end = lisp.line_end_position()
return start, end, lisp.buffer_substring(start, end)
def fixer_equals_none (unused_error, unused_errtext):
start, end, line = get_line_string()
newline = re.sub(r"==\s*None", r"is None", line)
newline = re.sub(r"!=\s*None", r"is not None", newline)
if newline != line:
lisp.delete_region(start, end)
lisp.insert(newline)
Obviously this function is invoked from somewhere else with the error number and text (e.g., E711 and E711: error text). The following is the code that does that.
fixers = {
# ...
"E711": fixer_equals_none,
}
def flymake_fix_current_line ():
lineno = lisp.flymake_current_line_no()
errinfo = lisp.flymake_err_info
errlist = lisp.nth(0, lisp.flymake_find_err_info(errinfo.value(), lineno))
menudata = lisp.flymake_make_err_menu_data(lineno, errlist)
did_something = False
# caadr (x ((e1 e2 ...))) -> (e1 e2 ...)
for errtxt in menudata[1][0]:
if not errtxt:
break
try:
m = re.match(r"([EFW]\d+) .*", errtxt)
except Exception as ex:
continue
if not m:
print("nomatch on {}".format(errtxt))
continue
key = m.group(1)
if key in fixers:
did_something = True
fixers[key](key, errtxt)
if did_something:
lisp.flymake_start_syntax_check()
interactions[flymake_fix_current_line] = ''
Finally we have the elisp code that binds a key to the dispatch function.
(pymacs-load "fixers" "fixers-")
(global-set-key "\C-c\C-\\" 'fixers-flymake-fix-current-line)