28 binary =
'clang-include-fixer' 29 if vim.eval(
'exists("g:clang_include_fixer_path")') ==
"1":
30 binary = vim.eval(
'g:clang_include_fixer_path')
32 maximum_suggested_headers = 3
33 if vim.eval(
'exists("g:clang_include_fixer_maximum_suggested_headers")') ==
"1":
34 maximum_suggested_headers = max(
36 vim.eval(
'g:clang_include_fixer_maximum_suggested_headers'))
39 if vim.eval(
'exists("g:clang_include_fixer_increment_num")') ==
"1":
42 vim.eval(
'g:clang_include_fixer_increment_num'))
44 jump_to_include =
False 45 if vim.eval(
'exists("g:clang_include_fixer_jump_to_include")') ==
"1":
46 jump_to_include = vim.eval(
'g:clang_include_fixer_jump_to_include') !=
"0" 49 if vim.eval(
'exists("g:clang_include_fixer_query_mode")') ==
"1":
50 query_mode = vim.eval(
'g:clang_include_fixer_query_mode') !=
"0" 54 eval_message = message +
'\n' 55 for idx, header
in enumerate(headers[0:maximum_suggested_headers]):
56 eval_message +=
"({0}). {1}\n".format(idx + 1, header)
57 eval_message +=
"Enter (q) to quit;" 58 if maximum_suggested_headers < len(headers):
59 eval_message +=
" (m) to show {0} more candidates.".format(
60 min(increment_num, len(headers) - maximum_suggested_headers))
62 eval_message +=
"\nSelect (default 1): " 63 res = vim.eval(
"input('{0}')".format(eval_message))
68 raise Exception(
' Insertion cancelled...')
71 headers, maximum_suggested_headers + increment_num)
75 if idx <= 0
or idx > len(headers):
80 print >> sys.stderr,
"Invalid option:", res
82 return headers[idx - 1]
86 p = subprocess.Popen(command,
87 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
88 stdin=subprocess.PIPE)
89 return p.communicate(input=text)
93 command = [binary,
"-stdin",
"-insert-header=" + json.dumps(header),
94 vim.current.buffer.name]
95 stdout, stderr =
execute(command, text)
97 raise Exception(stderr)
99 lines = stdout.splitlines()
100 sequence = difflib.SequenceMatcher(
None, vim.current.buffer, lines)
102 for op
in reversed(sequence.get_opcodes()):
104 vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
105 if op[0] ==
'insert':
109 if jump_to_include
and line_num:
110 vim.current.window.cursor = (line_num, 0)
116 line = vim.eval(
"line(\".\")")
118 col = int(vim.eval(
"col(\".\")")) - 1
119 line_text = vim.eval(
"getline({0})".format(line))
120 if len(line_text) == 0:
return "" 121 symbol_pos_begin = col
122 p = re.compile(
'[a-zA-Z0-9:_]')
123 while symbol_pos_begin >= 0
and p.match(line_text[symbol_pos_begin]):
124 symbol_pos_begin -= 1
127 while symbol_pos_end < len(line_text)
and p.match(line_text[symbol_pos_end]):
129 return line_text[symbol_pos_begin+1:symbol_pos_end]
133 parser = argparse.ArgumentParser(
134 description=
'Vim integration for clang-include-fixer')
135 parser.add_argument(
'-db', default=
'yaml',
136 help=
'clang-include-fixer input format.')
137 parser.add_argument(
'-input', default=
'',
138 help=
'String to initialize the database.')
144 args, _ = parser.parse_known_args()
147 buf = vim.current.buffer
148 text =
'\n'.
join(buf)
153 print "Skip querying empty symbol." 156 "-db=" + args.db,
"-input=" + args.input,
157 vim.current.buffer.name]
160 command = [binary,
"-stdin",
"-output-headers",
"-db=" + args.db,
161 "-input=" + args.input, vim.current.buffer.name]
162 stdout, stderr =
execute(command, text)
164 print >> sys.stderr,
"Error while running clang-include-fixer: " + stderr
167 include_fixer_context = json.loads(stdout)
168 query_symbol_infos = include_fixer_context[
"QuerySymbolInfos"]
169 if not query_symbol_infos:
170 print "The file is fine, no need to add a header." 172 symbol = query_symbol_infos[0][
"RawIdentifier"]
174 header_infos = include_fixer_context[
"HeaderInfos"]
179 for header_info
in header_infos:
180 header = header_info[
"Header"]
181 if header
not in seen:
183 unique_headers.append(header)
185 if not unique_headers:
186 print "Couldn't find a header for {0}.".format(symbol)
190 selected = unique_headers[0]
191 inserted_header_infos = header_infos
192 if len(unique_headers) > 1:
194 "choose a header file for {0}.".format(symbol),
195 unique_headers, maximum_suggested_headers)
196 inserted_header_infos = [
197 header
for header
in header_infos
if header[
"Header"] == selected]
198 include_fixer_context[
"HeaderInfos"] = inserted_header_infos
201 print "Added #include {0} for {1}.".format(selected, symbol)
202 except Exception
as error:
203 print >> sys.stderr, error.message
207 if __name__ ==
'__main__':
def GetUserSelection(message, headers, maximum_suggested_headers)
def get_symbol_under_cursor()
def InsertHeaderToVimBuffer(header, text)
def execute(command, text)
static std::string join(ArrayRef< SpecialMemberFunctionsCheck::SpecialMemberFunctionKind > SMFS, llvm::StringRef AndOr)