20from __future__
import print_function
31binary =
"clang-include-fixer"
32if vim.eval(
'exists("g:clang_include_fixer_path")') ==
"1":
33 binary = vim.eval(
"g:clang_include_fixer_path")
35maximum_suggested_headers = 3
36if vim.eval(
'exists("g:clang_include_fixer_maximum_suggested_headers")') ==
"1":
37 maximum_suggested_headers = max(
38 1, vim.eval(
"g:clang_include_fixer_maximum_suggested_headers")
42if vim.eval(
'exists("g:clang_include_fixer_increment_num")') ==
"1":
43 increment_num = max(1, vim.eval(
"g:clang_include_fixer_increment_num"))
45jump_to_include =
False
46if vim.eval(
'exists("g:clang_include_fixer_jump_to_include")') ==
"1":
47 jump_to_include = vim.eval(
"g:clang_include_fixer_jump_to_include") !=
"0"
50if vim.eval(
'exists("g:clang_include_fixer_query_mode")') ==
"1":
51 query_mode = vim.eval(
"g:clang_include_fixer_query_mode") !=
"0"
55 eval_message = message +
"\n"
56 for idx, header
in enumerate(headers[0:maximum_suggested_headers]):
57 eval_message +=
"({0}). {1}\n".format(idx + 1, header)
58 eval_message +=
"Enter (q) to quit;"
59 if maximum_suggested_headers < len(headers):
60 eval_message +=
" (m) to show {0} more candidates.".format(
61 min(increment_num, len(headers) - maximum_suggested_headers)
64 eval_message +=
"\nSelect (default 1): "
65 res = vim.eval(
"input('{0}')".format(eval_message))
70 raise Exception(
" Insertion cancelled...")
73 message, headers, maximum_suggested_headers + increment_num
78 if idx <= 0
or idx > len(headers):
83 print(
"Invalid option: {}".format(res), file=sys.stderr)
85 return headers[idx - 1]
91 if sys.platform.startswith(
"win32"):
92 startupinfo = subprocess.STARTUPINFO()
93 startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
94 startupinfo.wShowWindow = subprocess.SW_HIDE
98 stdout=subprocess.PIPE,
99 stderr=subprocess.PIPE,
100 stdin=subprocess.PIPE,
101 startupinfo=startupinfo,
103 return p.communicate(input=text.encode(
"utf-8"))
110 "-insert-header=" + json.dumps(header),
111 vim.current.buffer.name,
113 stdout, stderr =
execute(command, text)
115 raise Exception(stderr)
117 lines = stdout.splitlines()
118 sequence = difflib.SequenceMatcher(
None, vim.current.buffer, lines)
120 for op
in reversed(sequence.get_opcodes()):
122 vim.current.buffer[op[1] : op[2]] = lines[op[3] : op[4]]
123 if op[0] ==
"insert":
127 if jump_to_include
and line_num:
128 vim.current.window.cursor = (line_num, 0)
134 line = vim.eval(
'line(".")')
136 col = int(vim.eval(
'col(".")')) - 1
137 line_text = vim.eval(
"getline({0})".format(line))
138 if len(line_text) == 0:
140 symbol_pos_begin = col
141 p = re.compile(
"[a-zA-Z0-9:_]")
142 while symbol_pos_begin >= 0
and p.match(line_text[symbol_pos_begin]):
143 symbol_pos_begin -= 1
146 while symbol_pos_end < len(line_text)
and p.match(line_text[symbol_pos_end]):
148 return line_text[symbol_pos_begin + 1 : symbol_pos_end]
152 parser = argparse.ArgumentParser(
153 description=
"Vim integration for clang-include-fixer"
155 parser.add_argument(
"-db", default=
"yaml", help=
"clang-include-fixer input format.")
156 parser.add_argument(
"-input", default=
"", help=
"String to initialize the database.")
162 args, _ = parser.parse_known_args()
165 buf = vim.current.buffer
166 text =
"\n".join(buf)
171 print(
"Skip querying empty symbol.")
178 "-input=" + args.input,
179 vim.current.buffer.name,
188 "-input=" + args.input,
189 vim.current.buffer.name,
191 stdout, stderr =
execute(command, text)
194 "Error while running clang-include-fixer: {}".format(stderr),
199 include_fixer_context = json.loads(stdout)
200 query_symbol_infos = include_fixer_context[
"QuerySymbolInfos"]
201 if not query_symbol_infos:
202 print(
"The file is fine, no need to add a header.")
204 symbol = query_symbol_infos[0][
"RawIdentifier"]
206 header_infos = include_fixer_context[
"HeaderInfos"]
211 for header_info
in header_infos:
212 header = header_info[
"Header"]
213 if header
not in seen:
215 unique_headers.append(header)
217 if not unique_headers:
218 print(
"Couldn't find a header for {0}.".format(symbol))
222 selected = unique_headers[0]
223 inserted_header_infos = header_infos
224 if len(unique_headers) > 1:
226 "choose a header file for {0}.".format(symbol),
228 maximum_suggested_headers,
230 inserted_header_infos = [
231 header
for header
in header_infos
if header[
"Header"] == selected
233 include_fixer_context[
"HeaderInfos"] = inserted_header_infos
236 print(
"Added #include {0} for {1}.".format(selected, symbol))
237 except Exception
as error:
238 print(error, file=sys.stderr)
242if __name__ ==
"__main__":
def get_symbol_under_cursor()
def execute(command, text)
def InsertHeaderToVimBuffer(header, text)
def GetUserSelection(message, headers, maximum_suggested_headers)