This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 2d5190437e Add colours to git diff, fixes #5282 (#6350)
2d5190437e is described below
commit 2d5190437e60e525e825f40bf43bbc1b2b2949ca
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Mon Jan 12 18:49:04 2026 +0100
Add colours to git diff, fixes #5282 (#6350)
---
.../apache/hop/git/info/DiffStyledTextComp.java | 121 +++++++++++++++++++++
.../git/info/GitInfoExplorerFileTypeHandler.java | 49 ++++++++-
2 files changed, 164 insertions(+), 6 deletions(-)
diff --git
a/plugins/misc/git/src/main/java/org/apache/hop/git/info/DiffStyledTextComp.java
b/plugins/misc/git/src/main/java/org/apache/hop/git/info/DiffStyledTextComp.java
new file mode 100644
index 0000000000..fdc444a7e0
--- /dev/null
+++
b/plugins/misc/git/src/main/java/org/apache/hop/git/info/DiffStyledTextComp.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.hop.git.info;
+
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.ui.core.widget.StyledTextVar;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Styled text component for displaying git diffs with syntax highlighting.
Green for additions (+),
+ * red for deletions (-), cyan for file headers (diff --git, +++, ---), and
yellow for hunk headers
+ * (@@).
+ *
+ * <p>This class should only be used in desktop mode, not in Hop Web.
+ */
+public class DiffStyledTextComp extends StyledTextVar {
+
+ private static final Color COLOR_ADDITION = new Color(Display.getDefault(),
0, 128, 0); // Green
+ private static final Color COLOR_DELETION = new Color(Display.getDefault(),
255, 0, 0); // Red
+ private static final Color COLOR_FILE_HEADER =
+ new Color(Display.getDefault(), 0, 128, 128); // Cyan
+ private static final Color COLOR_HUNK_HEADER =
+ new Color(Display.getDefault(), 153, 102, 0); // Brown/Orange
+
+ public DiffStyledTextComp(IVariables variables, Composite parent, int style)
{
+ super(variables, parent, style, false, false); // No variable support
needed
+ // Set read-only and disable editing
+ getTextWidget().setEditable(false);
+ }
+
+ /**
+ * Sets the diff text and applies syntax highlighting based on git diff
format.
+ *
+ * @param diffText The git diff text to display
+ */
+ public void setDiffText(String diffText) {
+ if (diffText == null || diffText.isEmpty()) {
+ setText("");
+ return;
+ }
+
+ setText(diffText);
+ applyDiffHighlighting();
+ }
+
+ /** Applies syntax highlighting to the diff text based on git diff format. */
+ private void applyDiffHighlighting() {
+ StyledText styledText = getTextWidget();
+ String text = styledText.getText();
+ if (text.isEmpty()) {
+ return;
+ }
+
+ String[] lines = text.split("\n", -1);
+ int offset = 0;
+
+ for (String line : lines) {
+ int lineLength = line.length();
+ StyleRange styleRange = null;
+
+ if (line.startsWith("+")) {
+ // Addition line (green)
+ styleRange = new StyleRange(offset, lineLength, COLOR_ADDITION, null);
+ } else if (line.startsWith("-")) {
+ // Deletion line (red)
+ styleRange = new StyleRange(offset, lineLength, COLOR_DELETION, null);
+ } else if (line.startsWith("diff --git")
+ || line.startsWith("+++")
+ || line.startsWith("---")
+ || line.startsWith("index ")
+ || line.startsWith("new file")
+ || line.startsWith("deleted file")
+ || line.startsWith("similarity index")
+ || line.startsWith("rename from")
+ || line.startsWith("rename to")) {
+ // File header (cyan)
+ styleRange = new StyleRange(offset, lineLength, COLOR_FILE_HEADER,
null);
+ if (line.startsWith("+++") || line.startsWith("---")) {
+ styleRange.fontStyle = SWT.BOLD;
+ }
+ } else if (line.startsWith("@@")) {
+ // Hunk header (brown/orange)
+ styleRange = new StyleRange(offset, lineLength, COLOR_HUNK_HEADER,
null);
+ styleRange.fontStyle = SWT.BOLD;
+ }
+
+ if (styleRange != null) {
+ styledText.setStyleRange(styleRange);
+ }
+
+ // Move offset to next line (including newline character)
+ offset += lineLength + 1;
+ }
+ }
+
+ @Override
+ public void dispose() {
+ // Colors are shared and managed by Display, no need to dispose them
explicitly
+ super.dispose();
+ }
+}
diff --git
a/plugins/misc/git/src/main/java/org/apache/hop/git/info/GitInfoExplorerFileTypeHandler.java
b/plugins/misc/git/src/main/java/org/apache/hop/git/info/GitInfoExplorerFileTypeHandler.java
index 8a25092da9..53a05619ca 100644
---
a/plugins/misc/git/src/main/java/org/apache/hop/git/info/GitInfoExplorerFileTypeHandler.java
+++
b/plugins/misc/git/src/main/java/org/apache/hop/git/info/GitInfoExplorerFileTypeHandler.java
@@ -30,6 +30,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.hop.core.Const;
+import org.apache.hop.core.Props;
import org.apache.hop.core.exception.HopException;
import org.apache.hop.core.exception.HopFileException;
import org.apache.hop.core.logging.LogChannel;
@@ -50,6 +51,7 @@ import org.apache.hop.ui.hopgui.HopGui;
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerFile;
import org.apache.hop.ui.hopgui.perspective.explorer.ExplorerPerspective;
import
org.apache.hop.ui.hopgui.perspective.explorer.file.types.base.BaseExplorerFileTypeHandler;
+import org.apache.hop.ui.util.EnvironmentUtils;
import org.apache.hop.workflow.WorkflowMeta;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.lib.Constants;
@@ -88,7 +90,9 @@ public class GitInfoExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler
private Text wBranch;
private TableView wFiles;
private TableView wRevisions;
- private Text wDiff;
+ private Control wDiff; // Can be Text (web) or DiffStyledTextComp (desktop)
+ private DiffStyledTextComp wDiffStyled; // Desktop only - for colored diff
+ private Text wDiffText; // Web only - for plain text diff
private Button wbDiff;
public GitInfoExplorerFileTypeHandler(
@@ -324,14 +328,33 @@ public class GitInfoExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler
fdlDiff.top = new FormAttachment(wbDiff, 0, SWT.CENTER);
wlDiff.setLayoutData(fdlDiff);
- wDiff = new Text(wDiffComposite, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL |
SWT.V_SCROLL);
- PropsUi.setLook(wDiff);
+ // Create appropriate diff widget based on desktop vs web mode
+ // Desktop: Use DiffStyledTextComp for colored syntax highlighting
+ // Web: Use plain Text widget (StyledText not supported in Hop Web)
FormData fdDiff = new FormData();
fdDiff.left = new FormAttachment(0, 0);
fdDiff.right = new FormAttachment(100, 0);
fdDiff.top = new FormAttachment(wbDiff, margin);
fdDiff.bottom = new FormAttachment(100, 0);
- wDiff.setLayoutData(fdDiff);
+
+ if (EnvironmentUtils.getInstance().isWeb()) {
+ // Hop Web: Use plain Text widget
+ wDiffText = new Text(wDiffComposite, SWT.MULTI | SWT.BORDER |
SWT.H_SCROLL | SWT.V_SCROLL);
+ wDiffText.setEditable(false);
+ PropsUi.setLook(wDiffText);
+ wDiffText.setLayoutData(fdDiff);
+ wDiff = wDiffText;
+ } else {
+ // Desktop: Use DiffStyledTextComp for colored diff
+ wDiffStyled =
+ new DiffStyledTextComp(
+ hopGui.getVariables(),
+ wDiffComposite,
+ SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+ PropsUi.setLook(wDiffStyled, Props.WIDGET_STYLE_FIXED);
+ wDiffStyled.setLayoutData(fdDiff);
+ wDiff = wDiffStyled;
+ }
sashForm.setWeights(40, 60);
@@ -724,10 +747,24 @@ public class GitInfoExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler
String parentCommitId = git.getParentCommitId(revisionId);
diff = git.diff(parentCommitId, revisionId, filename);
}
- wDiff.setText(Const.NVL(diff, ""));
+ setDiffText(Const.NVL(diff, ""));
return filename;
}
+ /**
+ * Sets the diff text in the appropriate widget (colored styled text for
desktop, plain text for
+ * web).
+ */
+ private void setDiffText(String text) {
+ if (wDiffStyled != null) {
+ // Desktop: Use colored diff
+ wDiffStyled.setDiffText(text);
+ } else if (wDiffText != null) {
+ // Web: Use plain text
+ wDiffText.setText(text);
+ }
+ }
+
private void refreshChangedFiles() {
GitGuiPlugin guiPlugin = GitGuiPlugin.getInstance();
@@ -739,7 +776,7 @@ public class GitInfoExplorerFileTypeHandler extends
BaseExplorerFileTypeHandler
boolean showStaged = true;
// Clear the diff text field and disable the visual diff button
- wDiff.setText("");
+ setDiffText("");
wbDiff.setEnabled(false);
// Pick up the revision ID...