[NFC][RISCV] Remove CFIIndex argument from allocateStack (#117871)
[llvm-project.git] / clang / tools / clang-format / clang-format.py
blob07eebd27f49d112e852791160428153480520821
1 # This file is a minimal clang-format vim-integration. To install:
2 # - Change 'binary' if clang-format is not on the path (see below).
3 # - Add to your .vimrc:
5 # if has('python')
6 # map <C-I> :pyf <path-to-this-file>/clang-format.py<cr>
7 # imap <C-I> <c-o>:pyf <path-to-this-file>/clang-format.py<cr>
8 # elseif has('python3')
9 # map <C-I> :py3f <path-to-this-file>/clang-format.py<cr>
10 # imap <C-I> <c-o>:py3f <path-to-this-file>/clang-format.py<cr>
11 # endif
13 # The if-elseif-endif conditional should pick either the python3 or python2
14 # integration depending on your vim setup.
16 # The first mapping enables clang-format for NORMAL and VISUAL mode, the second
17 # mapping adds support for INSERT mode. Change "C-I" to another binding if you
18 # need clang-format on a different key (C-I stands for Ctrl+i).
20 # With this integration you can press the bound key and clang-format will
21 # format the current line in NORMAL and INSERT mode or the selected region in
22 # VISUAL mode. The line or region is extended to the next bigger syntactic
23 # entity.
25 # You can also pass in the variable "l:lines" to choose the range for
26 # formatting. This variable can either contain "<start line>:<end line>" or
27 # "all" to format the full file. So, to format the full file, write a function
28 # like:
29 # :function FormatFile()
30 # : let l:lines="all"
31 # : if has('python')
32 # : pyf <path-to-this-file>/clang-format.py
33 # : elseif has('python3')
34 # : py3f <path-to-this-file>/clang-format.py
35 # : endif
36 # :endfunction
38 # It operates on the current, potentially unsaved buffer and does not create
39 # or save any files. To revert a formatting, just undo.
40 from __future__ import absolute_import, division, print_function
42 import difflib
43 import json
44 import os.path
45 import platform
46 import subprocess
47 import sys
48 import vim
50 # set g:clang_format_path to the path to clang-format if it is not on the path
51 # Change this to the full path if clang-format is not on the path.
52 binary = "clang-format"
53 if vim.eval('exists("g:clang_format_path")') == "1":
54 binary = vim.eval("g:clang_format_path")
56 # Change this to format according to other formatting styles. See the output of
57 # 'clang-format --help' for a list of supported styles. The default looks for
58 # a '.clang-format' or '_clang-format' file to indicate the style that should be
59 # used.
60 style = None
61 fallback_style = None
62 if vim.eval('exists("g:clang_format_fallback_style")') == "1":
63 fallback_style = vim.eval("g:clang_format_fallback_style")
66 def get_buffer(encoding):
67 if platform.python_version_tuple()[0] == "3":
68 return vim.current.buffer
69 return [line.decode(encoding) for line in vim.current.buffer]
72 def main():
73 # Get the current text.
74 encoding = vim.eval("&encoding")
75 buf = get_buffer(encoding)
76 # Join the buffer into a single string with a terminating newline
77 text = ("\n".join(buf) + "\n").encode(encoding)
79 # Determine range to format.
80 if vim.eval('exists("l:lines")') == "1":
81 lines = ["--lines", vim.eval("l:lines")]
82 elif vim.eval('exists("l:formatdiff")') == "1" and os.path.exists(
83 vim.current.buffer.name
85 with open(vim.current.buffer.name, "r") as f:
86 ondisk = f.read().splitlines()
87 sequence = difflib.SequenceMatcher(None, ondisk, vim.current.buffer)
88 lines = []
89 for op in reversed(sequence.get_opcodes()):
90 if op[0] not in ["equal", "delete"]:
91 lines += ["--lines", "%s:%s" % (op[3] + 1, op[4])]
92 if lines == []:
93 return
94 else:
95 lines = [
96 "--lines",
97 "%s:%s" % (vim.current.range.start + 1, vim.current.range.end + 1),
100 # Convert cursor (line, col) to bytes.
101 # Don't use line2byte: https://github.com/vim/vim/issues/5930
102 _, cursor_line, cursor_col, _ = vim.eval('getpos(".")') # 1-based
103 cursor_byte = 0
104 for line in text.split(b"\n")[: int(cursor_line) - 1]:
105 cursor_byte += len(line) + 1
106 cursor_byte += int(cursor_col) - 1
107 if cursor_byte < 0:
108 print("Couldn't determine cursor position. Is your file empty?")
109 return
111 # Avoid flashing an ugly, ugly cmd prompt on Windows when invoking clang-format.
112 startupinfo = None
113 if sys.platform.startswith("win32"):
114 startupinfo = subprocess.STARTUPINFO()
115 startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
116 startupinfo.wShowWindow = subprocess.SW_HIDE
118 # Call formatter.
119 command = [binary, "--cursor", str(cursor_byte)]
120 if lines != ["--lines", "all"]:
121 command += lines
122 if style:
123 command.extend(["--style", style])
124 if fallback_style:
125 command.extend(["--fallback-style", fallback_style])
126 if vim.current.buffer.name:
127 command.extend(["--assume-filename", vim.current.buffer.name])
128 p = subprocess.Popen(
129 command,
130 stdout=subprocess.PIPE,
131 stderr=subprocess.PIPE,
132 stdin=subprocess.PIPE,
133 startupinfo=startupinfo,
135 stdout, stderr = p.communicate(input=text)
137 # If successful, replace buffer contents.
138 if stderr:
139 print(stderr)
141 if not stdout:
142 print(
143 "No output from clang-format (crashed?).\n"
144 "Please report to bugs.llvm.org."
146 else:
147 header, content = stdout.split(b"\n", 1)
148 header = json.loads(header.decode("utf-8"))
149 # Strip off the trailing newline (added above).
150 # This maintains trailing empty lines present in the buffer if
151 # the -lines specification requests them to remain unchanged.
152 lines = content.decode(encoding).split("\n")[:-1]
153 sequence = difflib.SequenceMatcher(None, buf, lines)
154 for op in reversed(sequence.get_opcodes()):
155 if op[0] != "equal":
156 vim.current.buffer[op[1] : op[2]] = lines[op[3] : op[4]]
157 if header.get("IncompleteFormat"):
158 print("clang-format: incomplete (syntax errors)")
159 # Convert cursor bytes to (line, col)
160 # Don't use goto: https://github.com/vim/vim/issues/5930
161 cursor_byte = int(header["Cursor"])
162 prefix = content[0:cursor_byte]
163 cursor_line = 1 + prefix.count(b"\n")
164 cursor_column = 1 + len(prefix.rsplit(b"\n", 1)[-1])
165 vim.command("call cursor(%d, %d)" % (cursor_line, cursor_column))
168 main()