[include-fixer] Create a mode in vim integration to show multiple potential headers.
Summary:
Some changes in the patch:
* Add two commandline flags in clang-include-fixer.
* Introduce a IncludeFixerContext for the queried symbol.
* Pull out CreateReplacementsForHeader.
Reviewers: bkramer
Subscribers: klimek, cfe-commits, ioeric
Differential Revision: http://reviews.llvm.org/D20621
llvm-svn: 271258
diff --git a/clang-tools-extra/include-fixer/tool/clang-include-fixer.py b/clang-tools-extra/include-fixer/tool/clang-include-fixer.py
index 23154aa..dfb5fcc 100644
--- a/clang-tools-extra/include-fixer/tool/clang-include-fixer.py
+++ b/clang-tools-extra/include-fixer/tool/clang-include-fixer.py
@@ -18,7 +18,6 @@
import argparse
import difflib
import subprocess
-import sys
import vim
# set g:clang_include_fixer_path to the path to clang-include-fixer if it is not
@@ -28,6 +27,39 @@
if vim.eval('exists("g:clang_include_fixer_path")') == "1":
binary = vim.eval('g:clang_include_fixer_path')
+maximum_suggested_headers=3
+if vim.eval('exists("g:clang_include_fixer_maximum_suggested_headers")') == "1":
+ maximum_suggested_headers = max(
+ 1,
+ vim.eval('g:clang_include_fixer_maximum_suggested_headers'))
+
+
+def ShowDialog(message, choices, default_choice_index=0):
+ to_eval = "confirm('{0}', '{1}', '{2}')".format(message,
+ choices,
+ default_choice_index)
+ return int(vim.eval(to_eval));
+
+
+def execute(command, text):
+ p = subprocess.Popen(command,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE)
+ return p.communicate(input=text)
+
+
+def InsertHeaderToVimBuffer(header, text):
+ command = [binary, "-stdin", "-insert-header="+header,
+ vim.current.buffer.name]
+ stdout, stderr = execute(command, text)
+ if stdout:
+ lines = stdout.splitlines()
+ sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines)
+ for op in reversed(sequence.get_opcodes()):
+ if op[0] is not 'equal':
+ vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
+
+
def main():
parser = argparse.ArgumentParser(
description='Vim integration for clang-include-fixer')
@@ -41,24 +73,36 @@
buf = vim.current.buffer
text = '\n'.join(buf)
- # Call clang-include-fixer.
- command = [binary, "-stdin", "-db="+args.db, "-input="+args.input,
+ # Run command to get all headers.
+ command = [binary, "-stdin", "-output-headers", "-db="+args.db, "-input="+args.input, "-debug",
vim.current.buffer.name]
- p = subprocess.Popen(command,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- stdin=subprocess.PIPE)
- stdout, stderr = p.communicate(input=text)
+ stdout, stderr = execute(command, text)
+ lines = stdout.splitlines()
+ if len(lines) < 2:
+ print "No header is included.\n"
+ return
- # If successful, replace buffer contents.
- if stderr:
- print stderr
+ # The first line is the symbol name.
+ symbol = lines[0]
+ # If there is only one suggested header, insert it directly.
+ if len(lines) == 2 or maximum_suggested_headers == 1:
+ InsertHeaderToVimBuffer(lines[1], text)
+ print "Added #include {0} for {1}.\n".format(lines[1], symbol)
+ return
- if stdout:
- lines = stdout.splitlines()
- sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines)
- for op in reversed(sequence.get_opcodes()):
- if op[0] is not 'equal':
- vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
+ choices_message = ""
+ index = 1;
+ for header in lines[1:1+maximum_suggested_headers]:
+ choices_message += "&" + str(index) + header + "\n"
+ index += 1
+
+ select = ShowDialog("choose a header file for {0}.".format(symbol),
+ choices_message)
+ # Insert a selected header.
+ InsertHeaderToVimBuffer(lines[select], text)
+ print "Added #include {0} for {1}.\n".format(lines[select], symbol)
+ return;
+
if __name__ == '__main__':
main()