From 81a94ecf126a8b3a53f20fe139cb1c918b957edc Mon Sep 17 00:00:00 2001 From: Felix Ding Date: Tue, 3 Dec 2024 15:37:03 -0800 Subject: [PATCH 1/2] Adds rendering logic for non macos eclipse instances --- .../IQInlineSuggestionSegmentFactory.java | 4 +- .../QInlineSuggestionCloseBracketSegment.java | 45 ++++++++++++++----- .../util/QInlineSuggestionNormalSegment.java | 24 ++++++++-- .../amazonq/util/QInvocationSession.java | 6 +++ 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/IQInlineSuggestionSegmentFactory.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/IQInlineSuggestionSegmentFactory.java index e0dbaf54..7402c34a 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/IQInlineSuggestionSegmentFactory.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/IQInlineSuggestionSegmentFactory.java @@ -53,7 +53,7 @@ public static List getSegmentsFromSuggestion(final QI case CLOSE: if (!unresolvedBrackets.isEmpty()) { var closeBracket = new QInlineSuggestionCloseBracketSegment(startOffset + j, i, - currentLine.substring(0, j), c); + currentLine.substring(0, j), c, qSes.isMacOS()); var top = unresolvedBrackets.pop(); if (top.isAMatch(closeBracket)) { top.pairUp(closeBracket); @@ -70,7 +70,7 @@ public static List getSegmentsFromSuggestion(final QI } distanceTraversed += sb.length() + 1; // plus one because we got rid of a \\R when we split it endOffset = startOffset + sb.length() - 1; - res.add(new QInlineSuggestionNormalSegment(startOffset, endOffset, i, sb.toString())); + res.add(new QInlineSuggestionNormalSegment(startOffset, endOffset, i, sb.toString(), qSes.isMacOS())); } return res; } diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java index a7ebb9d0..e22362a8 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java @@ -7,6 +7,8 @@ import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; public final class QInlineSuggestionCloseBracketSegment implements IQInlineSuggestionSegment, IQInlineBracket { private QInlineSuggestionOpenBracketSegment openBracket; @@ -15,13 +17,17 @@ public final class QInlineSuggestionCloseBracketSegment implements IQInlineSugge private int lineInSuggestion; private String text; private Font adjustedTypedFont; + private TextLayout layout; + private boolean isMacOS; public QInlineSuggestionCloseBracketSegment(final int caretOffset, final int lineInSuggestion, final String text, - final char symbol) { + final char symbol, final boolean isMacOS) { this.caretOffset = caretOffset; this.symbol = symbol; this.lineInSuggestion = lineInSuggestion; this.text = text; + this.layout = isMacOS ? null : new TextLayout(Display.getCurrent()); + this.isMacOS = isMacOS; var qInvocationSessionInstance = QInvocationSession.getInstance(); adjustedTypedFont = qInvocationSessionInstance.getBoldInlineFont(); @@ -57,25 +63,39 @@ public void render(final GC gc, final int currentCaretOffset) { int invocationLine = widget.getLineAtOffset(invocationOffset); int lineHt = widget.getLineHeight(); int fontHt = gc.getFontMetrics().getHeight(); - // educated guess: - int endPadding = gc.getAdvanceWidth(symbol) / 4; y = (invocationLine + lineInSuggestion + 1) * lineHt - fontHt; x = gc.textExtent(text).x; if (lineInSuggestion == 0) { x += widget.getLocationAtOffset(invocationOffset).x; } - + int scrollOffsetY = widget.getTopPixel(); + y -= scrollOffsetY; + String textToRender = String.valueOf(symbol); if (currentCaretOffset > openBracket.getRelevantOffset()) { Color typedColor = widget.getForeground(); - gc.setForeground(typedColor); - gc.setFont(adjustedTypedFont); + if (isMacOS) { + gc.setForeground(typedColor); + gc.setFont(adjustedTypedFont); + gc.drawText(textToRender, x, y, false); + } else { + layout.setFont(adjustedTypedFont); + layout.setText(textToRender); + layout.setTabs(widget.getTabStops()); + layout.draw(gc, x, y, 0, textToRender.length(), typedColor, null); + } } else { - gc.setForeground(Q_INLINE_HINT_TEXT_COLOR); - gc.setFont(qInvocationSessionInstance.getInlineTextFont()); + if (isMacOS) { + gc.setForeground(Q_INLINE_HINT_TEXT_COLOR); + gc.setFont(qInvocationSessionInstance.getInlineTextFont()); + gc.drawText(textToRender, x, y, true); + } else { + layout.setFont(qInvocationSessionInstance.getInlineTextFont()); + layout.setText(textToRender); + layout.setTabs(widget.getTabStops()); + gc.setAlpha(127); + layout.draw(gc, x, y, 0, textToRender.length(), Q_INLINE_HINT_TEXT_COLOR, null); + } } - int scrollOffsetY = widget.getTopPixel(); - y -= scrollOffsetY; - gc.drawText(String.valueOf(symbol), x, y, true); } @Override @@ -112,5 +132,8 @@ public QInlineSuggestionOpenBracketSegment getOpenBracket() { @Override public void cleanUp() { + if (layout != null) { + layout.dispose(); + } } } diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java index de7481dc..cfaa1bbd 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java @@ -8,6 +8,8 @@ import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.GlyphMetrics; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; import software.aws.toolkits.eclipse.amazonq.plugin.Activator; @@ -17,13 +19,17 @@ public final class QInlineSuggestionNormalSegment implements IQInlineSuggestionS private int lineInSuggestion; private String text; private StyleRange styleRange = new StyleRange(); + private TextLayout layout; + private boolean isMacOS; public QInlineSuggestionNormalSegment(final int startCaretPosition, final int endCaretPosition, - final int lineInSuggestion, final String text) { + final int lineInSuggestion, final String text, final boolean isMacOS) { + this.isMacOS = isMacOS; this.text = text; this.startCaretOffset = startCaretPosition; this.endCaretOffset = endCaretPosition; this.lineInSuggestion = lineInSuggestion; + this.layout = isMacOS ? null : new TextLayout(Display.getCurrent()); } @Override @@ -73,13 +79,23 @@ public void render(final GC gc, final int currentCaretOffset) { int scrollOffsetY = widget.getTopPixel(); y -= scrollOffsetY; - gc.setForeground(Q_INLINE_HINT_TEXT_COLOR); - gc.setFont(qInvocationSessionInstance.getInlineTextFont()); - gc.drawText(textToRender, x, y, true); + if (!isMacOS) { + layout.setText(textToRender); + layout.setFont(qInvocationSessionInstance.getInlineTextFont()); + layout.setTabs(widget.getTabStops()); + layout.draw(gc, x, y); + } else { + gc.setForeground(Q_INLINE_HINT_TEXT_COLOR); + gc.setFont(qInvocationSessionInstance.getInlineTextFont()); + gc.drawText(textToRender, x, y, true); + } } @Override public void cleanUp() { + if (layout != null) { + layout.dispose(); + } QInvocationSession session = QInvocationSession.getInstance(); if (!session.isActive()) { return; diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInvocationSession.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInvocationSession.java index aa2563d8..5b759d69 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInvocationSession.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInvocationSession.java @@ -36,6 +36,7 @@ public final class QInvocationSession extends QResource { private volatile QInvocationSessionState state = QInvocationSessionState.INACTIVE; private CaretMovementReason caretMovementReason = CaretMovementReason.UNEXAMINED; private boolean suggestionAccepted = false; + private boolean isMacOS; private QSuggestionsContext suggestionsContext = null; @@ -60,6 +61,7 @@ public final class QInvocationSession extends QResource { // Private constructor to prevent instantiation private QInvocationSession() { // Initialization code here + isMacOS = System.getProperty("os.name").toLowerCase().contains("mac"); } // Method to get the single instance @@ -489,6 +491,10 @@ public Font getBoldInlineFont() { return inlineTextFontBold; } + public boolean isMacOS() { + return isMacOS; + } + // Additional methods for the session can be added here @Override public void dispose() { From 5b70bc5c07e1342e5fed90f4181946262b5ddcb6 Mon Sep 17 00:00:00 2001 From: Felix Ding Date: Wed, 4 Dec 2024 11:22:27 -0800 Subject: [PATCH 2/2] Refines rendering logic for bracket segments for non macos platform --- .../QInlineSuggestionCloseBracketSegment.java | 18 +++++++++++++++--- .../util/QInlineSuggestionNormalSegment.java | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java index e22362a8..8055f2cd 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionCloseBracketSegment.java @@ -18,6 +18,7 @@ public final class QInlineSuggestionCloseBracketSegment implements IQInlineSugge private String text; private Font adjustedTypedFont; private TextLayout layout; + private TextLayout measureLayout; private boolean isMacOS; public QInlineSuggestionCloseBracketSegment(final int caretOffset, final int lineInSuggestion, final String text, @@ -31,6 +32,13 @@ public QInlineSuggestionCloseBracketSegment(final int caretOffset, final int lin var qInvocationSessionInstance = QInvocationSession.getInstance(); adjustedTypedFont = qInvocationSessionInstance.getBoldInlineFont(); + if (!isMacOS) { + int[] tabStops = qInvocationSessionInstance.getViewer().getTextWidget().getTabStops(); + measureLayout = new TextLayout(Display.getCurrent()); + measureLayout.setText(text); + measureLayout.setFont(qInvocationSessionInstance.getInlineTextFont()); + measureLayout.setTabs(tabStops); + } } @Override @@ -64,7 +72,7 @@ public void render(final GC gc, final int currentCaretOffset) { int lineHt = widget.getLineHeight(); int fontHt = gc.getFontMetrics().getHeight(); y = (invocationLine + lineInSuggestion + 1) * lineHt - fontHt; - x = gc.textExtent(text).x; + x = isMacOS ? gc.textExtent(text).x : (int) measureLayout.getBounds().width; if (lineInSuggestion == 0) { x += widget.getLocationAtOffset(invocationOffset).x; } @@ -81,7 +89,8 @@ public void render(final GC gc, final int currentCaretOffset) { layout.setFont(adjustedTypedFont); layout.setText(textToRender); layout.setTabs(widget.getTabStops()); - layout.draw(gc, x, y, 0, textToRender.length(), typedColor, null); + gc.setAlpha(255); + layout.draw(gc, x, y); } } else { if (isMacOS) { @@ -93,7 +102,7 @@ public void render(final GC gc, final int currentCaretOffset) { layout.setText(textToRender); layout.setTabs(widget.getTabStops()); gc.setAlpha(127); - layout.draw(gc, x, y, 0, textToRender.length(), Q_INLINE_HINT_TEXT_COLOR, null); + layout.draw(gc, x, y); } } } @@ -135,5 +144,8 @@ public void cleanUp() { if (layout != null) { layout.dispose(); } + if (measureLayout != null) { + measureLayout.dispose(); + } } } diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java index cfaa1bbd..b5472fe0 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/QInlineSuggestionNormalSegment.java @@ -83,6 +83,7 @@ public void render(final GC gc, final int currentCaretOffset) { layout.setText(textToRender); layout.setFont(qInvocationSessionInstance.getInlineTextFont()); layout.setTabs(widget.getTabStops()); + gc.setAlpha(127); layout.draw(gc, x, y); } else { gc.setForeground(Q_INLINE_HINT_TEXT_COLOR);