Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CommonUtilsTest.java29
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageAreaTest.java30
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java57
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java41
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java17
5 files changed, 157 insertions, 17 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CommonUtilsTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CommonUtilsTest.java
index 5ab6c18250..e7805cf720 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CommonUtilsTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/CommonUtilsTest.java
@@ -1,6 +1,7 @@
/*******************************************************************************
* Copyright (C) 2011, Robin Stocker <robin@nibor.org>
* Copyright (C) 2013, Michael Keppler <michael.keppler@gmx.de>
+ * Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -140,4 +141,32 @@ public class CommonUtilsTest {
p.getProject().getFolder("test").delete(false, monitor);
p.getProject().delete(false, monitor);
}
+
+ @Test
+ public void testFooterOffsetNoFooter() {
+ assertEquals(-1, CommonUtils.getFooterOffset(""));
+ assertEquals(-1, CommonUtils.getFooterOffset("line 1"));
+ assertEquals(-1, CommonUtils.getFooterOffset("line 1\nFoobar"));
+ assertEquals(-1, CommonUtils.getFooterOffset("line 1\n\nFoobar"));
+ assertEquals(-1, CommonUtils.getFooterOffset("line 1\nFoo:bar"));
+ assertEquals(-1, CommonUtils.getFooterOffset("line 1\n_\nFoo:bar"));
+ }
+
+ @Test
+ public void testFooterOffset() {
+ assertEquals(8, CommonUtils.getFooterOffset("line 1\n\nFoo:bar"));
+ assertEquals(8, CommonUtils.getFooterOffset("line 1\n\nFoo:bar "));
+ assertEquals(8, CommonUtils.getFooterOffset("line 1\n\nFoo:bar\n "));
+ assertEquals(8, CommonUtils.getFooterOffset("line 1\n\nFoo:bar\n \n"));
+ assertEquals(8, CommonUtils
+ .getFooterOffset("line 1\n\nFoo:bar\nFoobar: barbar"));
+ assertEquals(8, CommonUtils
+ .getFooterOffset("line 1\n\nFoo:bar\nFoobar: barbar "));
+ assertEquals(8, CommonUtils
+ .getFooterOffset("line 1\n\nFoo:bar\nFoobar: barbar\n "));
+ assertEquals(10,
+ CommonUtils.getFooterOffset("line 1\n \nFoo:bar\n \n"));
+ assertEquals(17, CommonUtils
+ .getFooterOffset("line 1\n\nFoo:bar\n\nFoobar: barbar\n "));
+ }
}
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageAreaTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageAreaTest.java
index f52091994d..d9d2dd3e36 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageAreaTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageAreaTest.java
@@ -2,6 +2,7 @@
* Copyright (C) 2010, Robin Stocker
* Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com>
* Copyright (C) 2012, IBM Corporation (Markus Keller <markus_keller@ch.ibm.com>)
+ * Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -188,4 +189,33 @@ public class SpellcheckableMessageAreaTest {
String wrapped = SpellcheckableMessageArea.hardWrap(Utils.normalizeLineEndings(text));
return wrapped.replaceAll("\n", lineDelimiter);
}
+
+ @Test
+ public void dontWrapShortMessage() {
+ String input = "short";
+ assertEquals(input, SpellcheckableMessageArea.wrapCommitMessage(input));
+ }
+
+ @Test
+ public void dontWrapLongCommitMessageFooter() {
+ String input = "short\n\nfoo\n\n"
+ + "Change-Id: I0000000000000000000000000000000000000000\n"
+ + "Signed-off-by: Some-Arguablylong Name <jsomearguablylong.name@somecompany.com>";
+ assertEquals(input, SpellcheckableMessageArea.wrapCommitMessage(input));
+ }
+
+ @Test
+ public void wrapOnlyCommitMessageBody() {
+ String input = "short\n\n"
+ + "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789\n\n"
+ + "Change-Id: I0000000000000000000000000000000000000000\n"
+ + "Signed-off-by: Some-Arguablylong Name <somearguablylong.name@somecompany.com>";
+ String expected = "short\n\n"
+ + "123456789 123456789 123456789 123456789 123456789 123456789 123456789\n"
+ + "123456789\n\n"
+ + "Change-Id: I0000000000000000000000000000000000000000\n"
+ + "Signed-off-by: Some-Arguablylong Name <somearguablylong.name@somecompany.com>";
+ assertEquals(expected,
+ SpellcheckableMessageArea.wrapCommitMessage(input));
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
index 17b83722b1..755257da7b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
@@ -5,6 +5,7 @@
* Copyright (C) 2013, Michael Keppler <michael.keppler@gmx.de>
* Copyright (C) 2014, IBM Corporation (Markus Keller <markus_keller@ch.ibm.com>)
* Copyright (C) 2015, IBM Corporation (Dani Megert <daniel_megert@ch.ibm.com>)
+ * Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -16,6 +17,8 @@ package org.eclipse.egit.ui.internal;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ParameterizedCommand;
@@ -38,6 +41,14 @@ import org.eclipse.ui.services.IServiceLocator;
*/
public class CommonUtils {
+ /**
+ * Pattern to figure out where the footer lines in a commit are.
+ *
+ * @see org.eclipse.jgit.revwalk.RevCommit#getFooterLines()
+ */
+ private static final Pattern FOOTER_PATTERN = Pattern
+ .compile("(?:\n(?:[A-Za-z0-9-]+:[^\n]*))+\\s*$"); //$NON-NLS-1$
+
private CommonUtils() {
// non-instantiable utility class
}
@@ -197,7 +208,7 @@ public class CommonUtils {
}
return null;
}
-
+
/**
* Returns the adapter corresponding to the given adapter class.
* <p>
@@ -217,7 +228,7 @@ public class CommonUtils {
Object adapter = adaptable.getAdapter(adapterClass);
return (T) adapter;
}
-
+
private static LinkedList<String> splitIntoDigitAndNonDigitParts(
String input) {
@@ -242,4 +253,46 @@ public class CommonUtils {
return input.substring(i);
return ""; //$NON-NLS-1$
}
+
+ /**
+ * Assuming that the string {@code commitMessage} is a commit message,
+ * returns the offset in the string of the footer of the commit message, if
+ * one can found, or -1 otherwise.
+ * <p>
+ * A footer of a commit message is defined to be the non-empty lines
+ * following the last empty line in the commit message if they have the
+ * format "key: value" as defined by
+ * {@link org.eclipse.jgit.revwalk.RevCommit#getFooterLines()}, like
+ * Change-Id: I000... or Signed-off-by: ... Empty lines at the end of the
+ * commit message are ignored.
+ * </p>
+ *
+ * @param commitMessage
+ * text of the commit message, assumed to use '\n' as line
+ * delimiter
+ * @return the index of the beginning of the footer, if any, or -1
+ * otherwise.
+ */
+ public static int getFooterOffset(String commitMessage) {
+ if (commitMessage == null) {
+ return -1;
+ }
+ Matcher matcher = FOOTER_PATTERN.matcher(commitMessage);
+ if (matcher.find()) {
+ int start = matcher.start();
+ // Check that the line that ends at start is empty.
+ int i = start - 1;
+ while (i >= 0) {
+ char ch = commitMessage.charAt(i--);
+ if (ch == '\n') {
+ return start + 1;
+ } else if (!Character.isWhitespace(ch)) {
+ return -1;
+ }
+ }
+ // No \n but only whitespace: first line is empty
+ return start + 1;
+ }
+ return -1;
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java
index 12b6494be8..dfd6e47bdb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java
@@ -425,6 +425,14 @@ public class SpellcheckableMessageArea extends Composite {
hardWrapSegmentListener = new BidiSegmentListener() {
@Override
public void lineGetSegments(BidiSegmentEvent e) {
+ if (e.widget == textWidget) {
+ int footerOffset = CommonUtils
+ .getFooterOffset(textWidget.getText());
+ if (footerOffset >= 0
+ && e.lineOffset >= footerOffset) {
+ return;
+ }
+ }
int[] segments = calculateWrapOffsets(e.lineText, MAX_LINE_WIDTH);
if (segments != null) {
char[] segmentsChars = new char[segments.length];
@@ -921,18 +929,43 @@ public class SpellcheckableMessageArea extends Composite {
public String getCommitMessage() {
String text = getText();
text = Utils.normalizeLineEndings(text);
- if (shouldHardWrap())
- text = hardWrap(text);
+ if (shouldHardWrap()) {
+ text = wrapCommitMessage(text);
+ }
return text;
}
/**
+ * Wraps a commit message, leaving the footer as defined by
+ * {@link CommonUtils#getFooterOffset(String)} unwrapped.
+ *
+ * @param text
+ * of the whole commit message, including footer, using '\n' as
+ * line delimiter
+ * @return the wrapped text
+ */
+ protected static String wrapCommitMessage(String text) {
+ // protected in order to be easily testable
+ int footerStart = CommonUtils.getFooterOffset(text);
+ if (footerStart < 0) {
+ return hardWrap(text);
+ } else {
+ // Do not wrap footer lines.
+ String footer = text.substring(footerStart);
+ text = hardWrap(text.substring(0, footerStart));
+ return text + footer;
+ }
+ }
+
+ /**
* Hard-wraps the given text.
*
- * @param text the text to wrap, must use '\n' as line delimiter
+ * @param text
+ * the text to wrap, must use '\n' as line delimiter
* @return the wrapped text
*/
- public static String hardWrap(String text) {
+ protected static String hardWrap(String text) {
+ // protected for testing
int[] wrapOffsets = calculateWrapOffsets(text, MAX_LINE_WIDTH);
if (wrapOffsets != null) {
StringBuilder builder = new StringBuilder(text.length() + wrapOffsets.length);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
index 0dbe2ebfb1..b6bb40eb88 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
@@ -21,13 +21,12 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.CommonUtils;
import org.eclipse.egit.ui.internal.PreferenceBasedDateFormatter;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.history.FormatJob.FormatResult;
@@ -56,9 +55,6 @@ public class CommitInfoBuilder {
private static final int MAXBRANCHES = 20;
- private static final Pattern FOOTER_PATTERN = Pattern
- .compile("(?:\n(?:[A-Z](?:[A-Za-z]+-)*[A-Za-z]+:[^\n]*))+$"); //$NON-NLS-1$
-
private PlotCommit<?> commit;
private final Repository db;
@@ -180,17 +176,16 @@ public class CommitInfoBuilder {
int headerEnd = d.length();
String msg = commit.getFullMessage().trim();
// Find start of footer:
- Matcher spm = FOOTER_PATTERN.matcher(msg);
- int footerStart = -1;
- if (spm.find()) {
+ int footerStart = CommonUtils.getFooterOffset(msg);
+ if (footerStart >= 0) {
if (fill) {
- String footer = msg.substring(spm.start());
- msg = msg.substring(0, spm.start());
+ String footer = msg.substring(footerStart);
+ msg = msg.substring(0, footerStart);
msg = msg.replaceAll("([\\w.,; \t])\n(\\w)", "$1 $2") //$NON-NLS-1$ //$NON-NLS-2$
+ footer;
footerStart = headerEnd + msg.length() - footer.length();
} else {
- footerStart = headerEnd + spm.start();
+ footerStart = headerEnd + footerStart;
}
} else if (fill) {
msg = msg.replaceAll("([\\w.,; \t])\n(\\w)", "$1 $2"); //$NON-NLS-1$ //$NON-NLS-2$

Back to the top