diff --git a/.gitignore b/.gitignore
index 83c26b836..db4325627 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,9 @@
.classpath
.project
+.factorypath
.settings/
+.apt_generated/
target/
diff --git a/core/pom.xml b/core/pom.xml
index e4d8fa251..e3e5a299a 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -147,6 +147,51 @@
+
+ maven-resources-plugin
+ 3.0.1
+
+
+ copy-resources
+ package
+
+ copy-resources
+
+
+ ../eclipse_plugin/lib
+
+
+ target
+ ${project.artifactId}-${project.version}.jar
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.10
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ../eclipse_plugin/lib
+ true
+ true
+ true
+ org.eclipse.jdt.core
+ compile
+ provided
+
+
+
+
diff --git a/eclipse_plugin/.classpath b/eclipse_plugin/.classpath
new file mode 100644
index 000000000..edb3814bd
--- /dev/null
+++ b/eclipse_plugin/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/eclipse_plugin/.project b/eclipse_plugin/.project
new file mode 100644
index 000000000..038992d3c
--- /dev/null
+++ b/eclipse_plugin/.project
@@ -0,0 +1,34 @@
+
+
+ google-java-format-eclipse
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/eclipse_plugin/.settings/org.eclipse.jdt.core.prefs b/eclipse_plugin/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..295926d96
--- /dev/null
+++ b/eclipse_plugin/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/eclipse_plugin/META-INF/MANIFEST.MF b/eclipse_plugin/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..ffdf09894
--- /dev/null
+++ b/eclipse_plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Google Java Formatter
+Bundle-SymbolicName: google-java-format-eclipse-plugin;singleton:=true
+Bundle-Version: 0.0.1
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0",
+ org.eclipse.jface,
+ org.eclipse.text,
+ org.eclipse.ui,
+ org.eclipse.equinox.common
+Bundle-ClassPath: .,
+ lib/guava-19.0.jar,
+ lib/javac-9-dev-r3297-1-shaded.jar,
+ lib/google-java-format-1.3-SNAPSHOT.jar
diff --git a/eclipse_plugin/build.properties b/eclipse_plugin/build.properties
new file mode 100644
index 000000000..4b0465531
--- /dev/null
+++ b/eclipse_plugin/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = target/classes
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ lib/google-java-format-1.3-SNAPSHOT.jar,\
+ lib/javac-9-dev-r3297-1-shaded.jar,\
+ lib/guava-19.0.jar
diff --git a/eclipse_plugin/lib/.gitignore b/eclipse_plugin/lib/.gitignore
new file mode 100644
index 000000000..d6b7ef32c
--- /dev/null
+++ b/eclipse_plugin/lib/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/eclipse_plugin/plugin.xml b/eclipse_plugin/plugin.xml
new file mode 100644
index 000000000..062ef668b
--- /dev/null
+++ b/eclipse_plugin/plugin.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml
new file mode 100644
index 000000000..e55f43558
--- /dev/null
+++ b/eclipse_plugin/pom.xml
@@ -0,0 +1,103 @@
+
+
+
+ 4.0.0
+
+ com.google.googlejavaformat
+ google-java-format-parent
+ 1.3-SNAPSHOT
+
+
+ google-java-format-eclipse-plugin
+ 0.0.1
+ eclipse-plugin
+ Google Java Format Plugin for Eclipse 4.5+
+
+
+ A Java source code formatter that follows Google Java Style.
+
+
+
+ 0.26.0
+
+
+
+
+ mars
+ p2
+ http://download.eclipse.org/releases/mars
+
+
+
+
+
+ com.google.googlejavaformat
+ google-java-format
+ 1.3-SNAPSHOT
+
+
+
+
+
+
+
+ org.eclipse.tycho
+ tycho-maven-plugin
+ ${tycho-version}
+ true
+
+
+
+ org.eclipse.tycho
+ target-platform-configuration
+ ${tycho-version}
+
+
+
+ linux
+ gtk
+ x86
+
+
+ linux
+ gtk
+ x86_64
+
+
+ win32
+ win32
+ x86
+
+
+ win32
+ win32
+ x86_64
+
+
+ macosx
+ cocoa
+ x86_64
+
+
+
+
+
+
+
+
+
diff --git a/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java b/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java
new file mode 100644
index 000000000..945c068bd
--- /dev/null
+++ b/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.googlejavaformat.java;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Range;
+import com.google.googlejavaformat.java.SnippetFormatter.SnippetKind;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/** Runs the Google Java formatter on the given code. */
+public class GoogleJavaFormatter extends CodeFormatter {
+
+ private static final int INDENTATION_SIZE = 2;
+
+ @Override
+ public TextEdit format(
+ int kind, String source, int offset, int length, int indentationLevel, String lineSeparator) {
+ IRegion[] regions = new IRegion[] {new Region(offset, length)};
+ return formatInternal(kind, source, regions, indentationLevel);
+ }
+
+ @Override
+ public TextEdit format(
+ int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) {
+ return formatInternal(kind, source, regions, indentationLevel);
+ }
+
+ @Override
+ public String createIndentationString(int indentationLevel) {
+ Preconditions.checkArgument(
+ indentationLevel >= 0,
+ "Indentation level cannot be less than zero. Given: %s",
+ indentationLevel);
+ int spaces = indentationLevel * INDENTATION_SIZE;
+ StringBuilder buf = new StringBuilder(spaces);
+ for (int i = 0; i < spaces; i++) {
+ buf.append(' ');
+ }
+ return buf.toString();
+ }
+
+ /** Runs the Google Java formatter on the given source, with only the given ranges specified. */
+ private TextEdit formatInternal(int kind, String source, IRegion[] regions, int initialIndent) {
+ try {
+ boolean includeComments =
+ (kind & CodeFormatter.F_INCLUDE_COMMENTS) == CodeFormatter.F_INCLUDE_COMMENTS;
+ kind &= ~CodeFormatter.F_INCLUDE_COMMENTS;
+ SnippetKind snippetKind;
+ switch (kind) {
+ case ASTParser.K_EXPRESSION:
+ snippetKind = SnippetKind.EXPRESSION;
+ break;
+ case ASTParser.K_STATEMENTS:
+ snippetKind = SnippetKind.STATEMENTS;
+ break;
+ case ASTParser.K_CLASS_BODY_DECLARATIONS:
+ snippetKind = SnippetKind.CLASS_BODY_DECLARATIONS;
+ break;
+ case ASTParser.K_COMPILATION_UNIT:
+ snippetKind = SnippetKind.COMPILATION_UNIT;
+ break;
+ default:
+ throw new IllegalArgumentException(String.format("Unknown snippet kind: %d", kind));
+ }
+ return editFromReplacements(
+ new SnippetFormatter()
+ .format(
+ snippetKind, source, rangesFromRegions(regions), initialIndent, includeComments));
+ } catch (IllegalArgumentException | FormatterException exception) {
+ // Do not format on errors.
+ return null;
+ }
+ }
+
+ private List> rangesFromRegions(IRegion[] regions) {
+ List> ranges = new ArrayList<>();
+ for (IRegion region : regions) {
+ ranges.add(Range.closedOpen(region.getOffset(), region.getOffset() + region.getLength()));
+ }
+ return ranges;
+ }
+
+ private TextEdit editFromReplacements(List replacements) {
+ // Split the replacements that cross line boundaries.
+ TextEdit edit = new MultiTextEdit();
+ for (Replacement replacement : replacements) {
+ Range replaceRange = replacement.getReplaceRange();
+ edit.addChild(
+ new ReplaceEdit(
+ replaceRange.lowerEndpoint(),
+ replaceRange.upperEndpoint() - replaceRange.lowerEndpoint(),
+ replacement.getReplacementString()));
+ }
+ return edit;
+ }
+}
diff --git a/pom.xml b/pom.xml
index 52fb2d742..1ffecf857 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,7 @@
core
+ eclipse_plugin