30 binary =
'clang-include-fixer' 31 if vim.eval(
'exists("g:clang_include_fixer_path")') ==
"1":
32 binary = vim.eval(
'g:clang_include_fixer_path')
34 maximum_suggested_headers = 3
35 if vim.eval(
'exists("g:clang_include_fixer_maximum_suggested_headers")') ==
"1":
36 maximum_suggested_headers = max(
38 vim.eval(
'g:clang_include_fixer_maximum_suggested_headers'))
41 if vim.eval(
'exists("g:clang_include_fixer_increment_num")') ==
"1":
44 vim.eval(
'g:clang_include_fixer_increment_num'))
46 jump_to_include =
False 47 if vim.eval(
'exists("g:clang_include_fixer_jump_to_include")') ==
"1":
48 jump_to_include = vim.eval(
'g:clang_include_fixer_jump_to_include') !=
"0" 51 if vim.eval(
'exists("g:clang_include_fixer_query_mode")') ==
"1":
52 query_mode = vim.eval(
'g:clang_include_fixer_query_mode') !=
"0" 56 eval_message = message +
'\n' 57 for idx, header
in enumerate(headers[0:maximum_suggested_headers]):
58 eval_message +=
"({0}). {1}\n".format(idx + 1, header)
59 eval_message +=
"Enter (q) to quit;" 60 if maximum_suggested_headers < len(headers):
61 eval_message +=
" (m) to show {0} more candidates.".format(
62 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 headers, maximum_suggested_headers + increment_num)
77 if idx <= 0
or idx > len(headers):
82 print >> sys.stderr,
"Invalid option:", res
84 return headers[idx - 1]
88 p = subprocess.Popen(command,
89 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
90 stdin=subprocess.PIPE)
91 return p.communicate(input=text)
95 command = [binary,
"-stdin",
"-insert-header=" + json.dumps(header),
96 vim.current.buffer.name]
97 stdout, stderr =
execute(command, text)
99 raise Exception(stderr)
101 lines = stdout.splitlines()
102 sequence = difflib.SequenceMatcher(
None, vim.current.buffer, lines)
104 for op
in reversed(sequence.get_opcodes()):
106 vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
107 if op[0] ==
'insert':
111 if jump_to_include
and line_num:
112 vim.current.window.cursor = (line_num, 0)
118 line = vim.eval(
"line(\".\")")
120 col = int(vim.eval(
"col(\".\")")) - 1
121 line_text = vim.eval(
"getline({0})".format(line))
122 if len(line_text) == 0:
return "" 123 symbol_pos_begin = col
124 p = re.compile(
'[a-zA-Z0-9:_]')
125 while symbol_pos_begin >= 0
and p.match(line_text[symbol_pos_begin]):
126 symbol_pos_begin -= 1
129 while symbol_pos_end < len(line_text)
and p.match(line_text[symbol_pos_end]):
131 return line_text[symbol_pos_begin+1:symbol_pos_end]
135 parser = argparse.ArgumentParser(
136 description=
'Vim integration for clang-include-fixer')
137 parser.add_argument(
'-db', default=
'yaml',
138 help=
'clang-include-fixer input format.')
139 parser.add_argument(
'-input', default=
'',
140 help=
'String to initialize the database.')
146 args, _ = parser.parse_known_args()
149 buf = vim.current.buffer
150 text =
'\n'.
join(buf)
155 print "Skip querying empty symbol." 158 "-db=" + args.db,
"-input=" + args.input,
159 vim.current.buffer.name]
162 command = [binary,
"-stdin",
"-output-headers",
"-db=" + args.db,
163 "-input=" + args.input, vim.current.buffer.name]
164 stdout, stderr =
execute(command, text)
166 print >> sys.stderr,
"Error while running clang-include-fixer: " + stderr
169 include_fixer_context = json.loads(stdout)
170 query_symbol_infos = include_fixer_context[
"QuerySymbolInfos"]
171 if not query_symbol_infos:
172 print "The file is fine, no need to add a header." 174 symbol = query_symbol_infos[0][
"RawIdentifier"]
176 header_infos = include_fixer_context[
"HeaderInfos"]
181 for header_info
in header_infos:
182 header = header_info[
"Header"]
183 if header
not in seen:
185 unique_headers.append(header)
187 if not unique_headers:
188 print "Couldn't find a header for {0}.".format(symbol)
192 selected = unique_headers[0]
193 inserted_header_infos = header_infos
194 if len(unique_headers) > 1:
196 "choose a header file for {0}.".format(symbol),
197 unique_headers, maximum_suggested_headers)
198 inserted_header_infos = [
199 header
for header
in header_infos
if header[
"Header"] == selected]
200 include_fixer_context[
"HeaderInfos"] = inserted_header_infos
203 print "Added #include {0} for {1}.".format(selected, symbol)
204 except Exception
as error:
205 print >> sys.stderr, error.message
209 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)