diff options
Diffstat (limited to 'tools/clang-format/clang-format.py')
-rw-r--r-- | tools/clang-format/clang-format.py | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py index d90c62a..f5a5756 100644 --- a/tools/clang-format/clang-format.py +++ b/tools/clang-format/clang-format.py @@ -17,31 +17,43 @@ # It operates on the current, potentially unsaved buffer and does not create # or save any files. To revert a formatting, just undo. -import vim +import difflib +import json import subprocess +import sys +import vim # Change this to the full path if clang-format is not on the path. binary = 'clang-format' -# Change this to format according to other formatting styles (see -# clang-format -help) -style = 'LLVM' +# Change this to format according to other formatting styles. See the output of +# 'clang-format --help' for a list of supported styles. The default looks for +# a '.clang-format' or '_clang-format' file to indicate the style that should be +# used. +style = 'file' # Get the current text. buf = vim.current.buffer -text = "\n".join(buf) +text = '\n'.join(buf) # Determine range to format. -offset = int(vim.eval('line2byte(' + - str(vim.current.range.start + 1) + ')')) - 1 -length = int(vim.eval('line2byte(' + - str(vim.current.range.end + 2) + ')')) - offset - 2 +cursor = int(vim.eval('line2byte(line("."))+col(".")')) - 2 +lines = '%s:%s' % (vim.current.range.start + 1, vim.current.range.end + 1) + +# Avoid flashing an ugly, ugly cmd prompt on Windows when invoking clang-format. +startupinfo = None +if sys.platform.startswith('win32'): + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE # Call formatter. -p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length), - '-style', style], +command = [binary, '-lines', lines, '-style', style, '-cursor', str(cursor)] +if vim.current.buffer.name: + command.extend(['-assume-filename', vim.current.buffer.name]) +p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - stdin=subprocess.PIPE) + stdin=subprocess.PIPE, startupinfo=startupinfo) stdout, stderr = p.communicate(input=text) # If successful, replace buffer contents. @@ -56,10 +68,12 @@ if stderr: if not stdout: print ('No output from clang-format (crashed?).\n' + 'Please report to bugs.llvm.org.') -elif stdout != text: +else: lines = stdout.split('\n') - for i in range(min(len(buf), len(lines))): - buf[i] = lines[i] - for line in lines[len(buf):]: - buf.append(line) - del buf[len(lines):] + output = json.loads(lines[0]) + lines = lines[1:] + sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines) + for op in reversed(sequence.get_opcodes()): + if op[0] is not 'equal': + vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]] + vim.command('goto %d' % (output['Cursor'] + 1)) |