# This file is a minimal clang-format vim-integration. To install:
# - Change 'binary' if clang-format is not on the path (see below).
# - Add to your .vimrc:
#
#   if has('python')
#     map <C-I> :pyf <path-to-this-file>/clang-format.py<cr>
#     imap <C-I> <c-o>:pyf <path-to-this-file>/clang-format.py<cr>
#   elseif has('python3')
#     map <C-I> :py3f <path-to-this-file>/clang-format.py<cr>
#     imap <C-I> <c-o>:py3f <path-to-this-file>/clang-format.py<cr>
#   endif
#
# The if-elseif-endif conditional should pick either the python3 or python2
# integration depending on your vim setup.
#
# The first mapping enables clang-format for NORMAL and VISUAL mode, the second
# mapping adds support for INSERT mode. Change "C-I" to another binding if you
# need clang-format on a different key (C-I stands for Ctrl+i).
#
# With this integration you can press the bound key and clang-format will
# format the current line in NORMAL and INSERT mode or the selected region in
# VISUAL mode. The line or region is extended to the next bigger syntactic
# entity.
#
# You can also pass in the variable "l:lines" to choose the range for
# formatting. This variable can either contain "<start line>:<end line>" or
# "all" to format the full file. So, to format the full file, write a function
# like:
# :function FormatFile()
# :  let l:lines="all"
# :  if has('python')
# :    pyf <path-to-this-file>/clang-format.py
# :  elseif has('python3')
# :    py3f <path-to-this-file>/clang-format.py
# :  endif
# :endfunction
#
# It operates on the current, potentially unsaved buffer and does not create
# or save any files. To revert a formatting, just undo.
from __future__ import absolute_import, division, print_function

import difflib
import json
import platform
import subprocess
import sys
import vim

# set g:clang_format_path to the path to clang-format if it is not on the path
# Change this to the full path if clang-format is not on the path.
binary = 'clang-format'
if vim.eval('exists("g:clang_format_path")') == "1":
  binary = vim.eval('g:clang_format_path')

# 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 = None
fallback_style = None
if vim.eval('exists("g:clang_format_fallback_style")') == "1":
  fallback_style = vim.eval('g:clang_format_fallback_style')

def get_buffer(encoding):
  if platform.python_version_tuple()[0] == '3':
    return vim.current.buffer
  return [ line.decode(encoding) for line in vim.current.buffer ]

def main():
  # Get the current text.
  encoding = vim.eval("&encoding")
  buf = get_buffer(encoding)
  # Join the buffer into a single string with a terminating newline
  text = ('\n'.join(buf) + '\n').encode(encoding)

  # Determine range to format.
  if vim.eval('exists("l:lines")') == '1':
    lines = ['-lines', vim.eval('l:lines')]
  elif vim.eval('exists("l:formatdiff")') == '1':
    with open(vim.current.buffer.name, 'r') as f:
      ondisk = f.read().splitlines();
    sequence = difflib.SequenceMatcher(None, ondisk, vim.current.buffer)
    lines = []
    for op in reversed(sequence.get_opcodes()):
      if op[0] not in ['equal', 'delete']:
        lines += ['-lines', '%s:%s' % (op[3] + 1, op[4])]
    if lines == []:
      return
  else:
    lines = ['-lines', '%s:%s' % (vim.current.range.start + 1,
                                  vim.current.range.end + 1)]

  # Convert cursor (line, col) to bytes.
  # Don't use line2byte: https://github.com/vim/vim/issues/5930
  _, cursor_line, cursor_col, _ = vim.eval('getpos(".")') # 1-based
  cursor_byte = 0
  for line in text.split(b'\n')[:int(cursor_line) - 1]:
    cursor_byte += len(line) + 1
  cursor_byte += int(cursor_col) - 1
  if cursor_byte < 0:
    print('Couldn\'t determine cursor position. Is your file empty?')
    return

  # 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.
  command = [binary, '-cursor', str(cursor_byte)]
  if lines != ['-lines', 'all']:
    command += lines
  if style:
    command.extend(['-style', style])
  if fallback_style:
    command.extend(['-fallback-style', fallback_style])
  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, startupinfo=startupinfo)
  stdout, stderr = p.communicate(input=text)

  # If successful, replace buffer contents.
  if stderr:
    print(stderr)

  if not stdout:
    print(
        'No output from clang-format (crashed?).\n'
        'Please report to bugs.llvm.org.'
    )
  else:
    header, content = stdout.split(b'\n', 1)
    header = json.loads(header.decode('utf-8'))
    # Strip off the trailing newline (added above).
    # This maintains trailing empty lines present in the buffer if
    # the -lines specification requests them to remain unchanged.
    lines = content.decode(encoding).split('\n')[:-1]
    sequence = difflib.SequenceMatcher(None, buf, lines)
    for op in reversed(sequence.get_opcodes()):
      if op[0] != 'equal':
        vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
    if header.get('IncompleteFormat'):
      print('clang-format: incomplete (syntax errors)')
    # Convert cursor bytes to (line, col)
    # Don't use goto: https://github.com/vim/vim/issues/5930
    cursor_byte = int(header['Cursor'])
    prefix = content[0:cursor_byte]
    cursor_line = 1 + prefix.count(b'\n')
    cursor_column = 1 + len(prefix.rsplit(b'\n', 1)[-1])
    vim.command('call cursor(%d, %d)' % (cursor_line, cursor_column))

main()
