[PATCH] Let clang-format move the cursor appropriately.
Daniel Jasper
djasper at google.com
Fri May 17 08:56:42 PDT 2013
Hi klimek,
If we format something in an editor integration, we basically want the cursor to be at the same spot relative to the changed source code.
http://llvm-reviews.chandlerc.com/D812
Files:
test/Format/cursor.cpp
tools/clang-format/ClangFormat.cpp
tools/clang-format/clang-format.py
Index: test/Format/cursor.cpp
===================================================================
--- /dev/null
+++ test/Format/cursor.cpp
@@ -0,0 +1,6 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t2.cpp
+// RUN: clang-format -style=LLVM %t2.cpp -cursor=6 > %t.cpp
+// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s
+// CHECK: {{^\{ "Cursor": 4 \}$}}
+// CHECK: {{^int\ \i;$}}
+ int i;
Index: tools/clang-format/ClangFormat.cpp
===================================================================
--- tools/clang-format/ClangFormat.cpp
+++ tools/clang-format/ClangFormat.cpp
@@ -71,6 +71,11 @@
cl::desc("Dump configuration options to stdout and exit.\n"
"Can be used with -style option."),
cl::cat(ClangFormatCategory));
+static cl::opt<unsigned>
+ Cursor("cursor",
+ cl::desc("The position of the cursor when invoking clang-format from"
+ " an editor integration"),
+ cl::init(0), cl::cat(ClangFormatCategory));
static cl::list<std::string> FileNames(cl::Positional, cl::desc("[<file> ...]"),
cl::cat(ClangFormatCategory));
@@ -123,6 +128,20 @@
return getLLVMStyle();
}
+static unsigned updatedOffset(const tooling::Replacements &Replaces,
+ unsigned Offset) {
+ int ShiftedBy = 0;
+ for (tooling::Replacements::iterator I = Replaces.begin(), E = Replaces.end();
+ I != E; ++I) {
+ if (I->getOffset() > Offset)
+ break;
+ if (I->getOffset() + I->getLength() > Offset)
+ ShiftedBy += I->getOffset() + I->getLength() - Offset;
+ ShiftedBy += I->getReplacementText().size() - I->getLength();
+ }
+ return Offset + ShiftedBy;
+}
+
// Returns true on error.
static bool format(std::string FileName) {
FileManager Files((FileSystemOptions()));
@@ -199,6 +218,8 @@
Rewrite.getEditBuffer(ID).write(FileStream);
FileStream.flush();
} else {
+ if (Cursor != 0)
+ outs() << "{ \"Cursor\": " << updatedOffset(Replaces, Cursor) << " }\n";
Rewrite.getEditBuffer(ID).write(outs());
}
}
Index: tools/clang-format/clang-format.py
===================================================================
--- tools/clang-format/clang-format.py
+++ tools/clang-format/clang-format.py
@@ -17,8 +17,9 @@
# It operates on the current, potentially unsaved buffer and does not create
# or save any files. To revert a formatting, just undo.
-import vim
+import json
import subprocess
+import vim
# Change this to the full path if clang-format is not on the path.
binary = 'clang-format'
@@ -29,17 +30,18 @@
# Get the current text.
buf = vim.current.buffer
-text = "\n".join(buf)
+text = '\n'.join(buf)
# Determine range to format.
+cursor = int(vim.eval('line2byte(line("."))+col(".")')) - 2
offset = int(vim.eval('line2byte(' +
str(vim.current.range.start + 1) + ')')) - 1
length = int(vim.eval('line2byte(' +
str(vim.current.range.end + 2) + ')')) - offset - 2
# Call formatter.
p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length),
- '-style', style],
+ '-style', style, '-cursor', str(cursor)],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
stdout, stderr = p.communicate(input=text)
@@ -56,10 +58,14 @@
if not stdout:
print ('No output from clang-format (crashed?).\n' +
'Please report to bugs.llvm.org.')
-elif stdout != text:
+else:
lines = stdout.split('\n')
- for i in range(min(len(buf), len(lines))):
- buf[i] = lines[i]
- for line in lines[len(buf):]:
- buf.append(line)
- del buf[len(lines):]
+ output = json.loads(lines[0])
+ lines = lines[1:]
+ if '\n'.join(lines) != text:
+ for i in range(min(len(buf), len(lines))):
+ buf[i] = lines[i]
+ for line in lines[len(buf):]:
+ buf.append(line)
+ del buf[len(lines):]
+ vim.command('goto %d' % (output['Cursor'] + 1))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D812.1.patch
Type: text/x-patch
Size: 4065 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130517/41687ff2/attachment.bin>
More information about the cfe-commits
mailing list