Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline hints - test #27

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ caret-next-word=Insertion Point to Next Word
caret-previous-word=Insertion Point to Previous Word
selection-next-word=Extend Selection to Next Word
selection-previous-word=Extend Selection to Previous Word
toggle-inline-hints=Show Inline &Hints
toggle-lines-view=Show &Indent Guide Lines
clipboard-lines=Paste as Lines
remove-last-caret=Remove Last Caret
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.netbeans.modules.editor.actions;

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import org.netbeans.api.editor.EditorActionRegistration;

@EditorActionRegistration(name="toggle-inline-hints",
menuPath="View",
menuPosition=899,
preferencesKey=ShowInlineHintsAction.KEY_LINES,
preferencesDefault=ShowInlineHintsAction.DEF_LINES)
public class ShowInlineHintsAction extends AbstractAction {
public static final String KEY_LINES = "enable.inline.hints";
public static final boolean DEF_LINES = false;
@Override
public void actionPerformed(ActionEvent e) {
}

}
15 changes: 15 additions & 0 deletions ide/editor.lib2/apichanges.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ is the proper place.
<!-- ACTUAL CHANGES BEGIN HERE: -->

<changes>
<change id="PrependedTextOpt">
<summary>Prepended text for highlights</summary>
<version major="2" minor="24"/>
<date day="14" month="5" year="2019"/>
<author login="jlahoda"/>
<compatibility binary="compatible" source="compatible" semantic="compatible" addition="yes" deprecation="no" deletion="no" modification="no" />
<description>
<p>If AttributeSet returned from HighlightsSequence contains key "virtual-text-prepend"
with a value of type String, the UI may optionally render the value as a
virtual text before the text of the highlight. It is recommended to make the
span of length 1, to avoid problems when the AttributeSet with "virtual-test-prepend"
is merged with other AttributeSets, which could lead to duplication.</p>
</description>
<class name="HighlightsSequence" package="org.netbeans.spi.editor.highlighting"/>
</change>
<change id="EditorActionRegistration.category">
<summary>Added category to EditorActionRegistration</summary>
<version major="2" minor="15"/>
Expand Down
2 changes: 1 addition & 1 deletion ide/editor.lib2/nbproject/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
is.autoload=true
javac.source=1.7
javac.compilerargs=-Xlint:unchecked
spec.version.base=2.23.0
spec.version.base=2.24.0

javadoc.arch=${basedir}/arch.xml
javadoc.apichanges=${basedir}/apichanges.xml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.netbeans.modules.editor.lib2.highlighting;

import java.awt.Font;
import java.util.Objects;
import java.util.logging.Logger;
import javax.swing.text.AttributeSet;
import org.netbeans.lib.editor.util.ArrayUtilities;
Expand Down Expand Up @@ -117,9 +118,10 @@ public void add(HighlightItem item) {
* @param wsEndOffset whitespace end offset must be lower than or equal to maxEndOffset
* and when exceeded a first whitespace char in docText means that the cutting will end there.
* @param docText document text in order properly handle wsEndOffset parameter.
* @param usePrependText reflect the prepended text setting.
* @return either simple or compound attribute set.
*/
public AttributeSet cutSameFont(Font defaultFont, int maxEndOffset, int wsEndOffset, CharSequence docText) {
public AttributeSet cutSameFont(Font defaultFont, int maxEndOffset, int wsEndOffset, CharSequence docText, boolean usePrependText) {
assert (maxEndOffset <= endOffset()) :
"maxEndOffset=" + maxEndOffset + " > endOffset()=" + endOffset() + ", " + this; // NOI18N
HighlightItem item = get(0);
Expand Down Expand Up @@ -157,12 +159,14 @@ public AttributeSet cutSameFont(Font defaultFont, int maxEndOffset, int wsEndOff

// Extends beyond first highlight
Font firstFont = ViewUtils.getFont(firstAttrs, defaultFont);
Object firstPrependText = usePrependText && firstAttrs != null ? firstAttrs.getAttribute(ViewUtils.KEY_VIRTUAL_TEXT_PREPEND) : null;
int index = 1;
while (true) {
item = get(index);
AttributeSet attrs = item.getAttributes();
Font font = ViewUtils.getFont(attrs, defaultFont);
if (!font.equals(firstFont)) { // Stop at itemEndOffset
Object prependText = usePrependText && attrs != null ? attrs.getAttribute(ViewUtils.KEY_VIRTUAL_TEXT_PREPEND) : null;
if (!font.equals(firstFont) || !Objects.equals(firstPrependText, prependText)) { // Stop at itemEndOffset
if (index == 1) { // Just single attribute set
cutStartItems(1);
startOffset = itemEndOffset; // end offset of first item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ public final class DocumentViewOp
private Map<Font,FontInfo> fontInfos = new HashMap<Font, FontInfo>(4);

private Font defaultFont;
private Font defaultHintFont;

private boolean fontRenderContextFromPaint;

Expand All @@ -314,6 +315,7 @@ public final class DocumentViewOp
boolean asTextField;

private boolean guideLinesEnable;
private boolean inlineHintsEnable;

private int indentLevelSize;

Expand Down Expand Up @@ -921,10 +923,13 @@ public void run() {
// Line height correction
float lineHeightCorrectionOrig = rowHeightCorrection;
rowHeightCorrection = prefs.getFloat(SimpleValueNames.LINE_HEIGHT_CORRECTION, 1.0f);
boolean inlineHintsEnableOrig = inlineHintsEnable;
inlineHintsEnable = Boolean.TRUE.equals(prefs.getBoolean("enable.inline.hints", false)); // NOI18N
boolean updateMetrics = (rowHeightCorrection != lineHeightCorrectionOrig);
boolean releaseChildren = nonInitialUpdate &&
((nonPrintableCharactersVisible != nonPrintableCharactersVisibleOrig) ||
(rowHeightCorrection != lineHeightCorrectionOrig));
(rowHeightCorrection != lineHeightCorrectionOrig) ||
(inlineHintsEnable != inlineHintsEnableOrig));
indentLevelSize = getIndentSize();
tabSize = prefs.getInt(SimpleValueNames.TAB_SIZE, EditorPreferencesDefaults.defaultTabSize);
if (updateMetrics) {
Expand Down Expand Up @@ -1060,6 +1065,7 @@ private void updateCharMetrics() { // Update default row height and other params
fontInfos.put(null, defaultFontInfo); // Alternative way to find default font info
updateRowHeight(defaultFontInfo, true);
defaultFont = font;
defaultHintFont = font.deriveFont((float) (font.getSize2D() * 0.75));
defaultCharWidth = defaultFontInfo.charWidth;

tabTextLayout = null;
Expand Down Expand Up @@ -1165,6 +1171,10 @@ public boolean isGuideLinesEnable() {
return guideLinesEnable && !asTextField;
}

public boolean isInlineHintsEnable() {
return inlineHintsEnable;
}

public int getIndentLevelSize() {
return indentLevelSize;
}
Expand Down Expand Up @@ -1259,6 +1269,10 @@ public Font getDefaultFont() {
return defaultFont;
}

public Font getDefaultHintFont() {
return defaultHintFont;
}

public float getDefaultRowHeight() {
checkSettingsInfo();
return defaultRowHeightInt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.View;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.annotations.common.NullAllowed;
import org.netbeans.lib.editor.util.CharSequenceUtilities;
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
import org.netbeans.modules.editor.lib2.highlighting.DirectMergeContainer;
Expand Down Expand Up @@ -188,7 +190,7 @@ public EditorView createView(int startOffset, int limitOffset, boolean forcedLim
}
if (startOffset == lineEndOffset - 1) {
AttributeSet attrs = hList.cutSingleChar();
return new NewlineView(attrs);
return wrapWithPrependedText(new NewlineView(attrs), attrs);
} else { // Regular view with possible highlight(s) or tab view
updateTabsAndHighlightsAndRTL(startOffset);
if (charType == TAB_CHAR_TYPE) {
Expand All @@ -198,7 +200,7 @@ public EditorView createView(int startOffset, int limitOffset, boolean forcedLim
limitOffset = tabsEndOffset;
}
attrs = hList.cut(limitOffset);
return new TabView(limitOffset - startOffset, attrs);
return wrapWithPrependedText(new TabView(limitOffset - startOffset, attrs), attrs);

} else { // Create regular view with either LTR or RTL text
limitOffset = Math.min(limitOffset, nextTabOrRTLOffset); // nextTabOrRTLOffset < lineEndOffset
Expand All @@ -216,11 +218,13 @@ public EditorView createView(int startOffset, int limitOffset, boolean forcedLim
}

}
AttributeSet attrs = hList.cutSameFont(defaultFont, limitOffset, wsEndOffset, docText);
boolean inlineHints = documentView().op.isInlineHintsEnable();
AttributeSet attrs = hList.cutSameFont(defaultFont, limitOffset, wsEndOffset, docText, inlineHints);
int length = hList.startOffset() - startOffset;
HighlightsView view = new HighlightsView(length, attrs);
if (origView instanceof HighlightsView && origView.getLength() == length) { // Reuse
HighlightsView origHView = (HighlightsView) origView;
EditorView view = wrapWithPrependedText(new HighlightsView(length, attrs), attrs);
EditorView origViewUnwrapped = origView instanceof PrependedTextView ? ((PrependedTextView) origView).getDelegate() : origView;
if (origViewUnwrapped != null && origViewUnwrapped.getClass() == HighlightsView.class && origViewUnwrapped.getLength() == length) {
HighlightsView origHView = (HighlightsView) origViewUnwrapped;
TextLayout origTextLayout = origHView.getTextLayout();
if (origTextLayout != null) {
if (ViewHierarchyImpl.CHECK_LOG.isLoggable(Level.FINE)) {
Expand All @@ -235,11 +239,12 @@ public EditorView createView(int startOffset, int limitOffset, boolean forcedLim
}
}
Font font = ViewUtils.getFont(attrs, defaultFont);
Font origFont = ViewUtils.getFont(origView.getAttributes(), defaultFont);
Font origFont = ViewUtils.getFont(origViewUnwrapped.getAttributes(), defaultFont);
if (font != null && font.equals(origFont)) {
float origWidth = origHView.getWidth();
view.setTextLayout(origTextLayout, origWidth);
view.setBreakInfo(origHView.getBreakInfo());
HighlightsView hv = (HighlightsView) (view instanceof PrependedTextView ? ((PrependedTextView) view).getDelegate() : view);
hv.setTextLayout(origTextLayout, origWidth);
hv.setBreakInfo(origHView.getBreakInfo());
ViewStats.incrementTextLayoutReused(length);
}
}
Expand All @@ -249,6 +254,16 @@ public EditorView createView(int startOffset, int limitOffset, boolean forcedLim
}
}

private @NonNull EditorView wrapWithPrependedText(@NonNull EditorView origView, @NullAllowed AttributeSet attrs) {
boolean inlineHints = documentView().op.isInlineHintsEnable();

if (attrs != null && inlineHints && attrs.getAttribute(ViewUtils.KEY_VIRTUAL_TEXT_PREPEND) instanceof String) {
return new PrependedTextView(documentView().op, attrs, origView);
}

return origView;
}

private void updateTabsAndHighlightsAndRTL(int offset) {
if (offset >= nextTabOrRTLOffset) { // Update nextTabOrRTLOffset
// Determine situation right at offset
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ void replace(ParagraphView pView, int index, int removeCount, View[] addedViews)
view.setRawEndOffset(relEndOffset); // Below offset-gap
view.setParent(pView);
// Possibly assign text layout
if (view instanceof HighlightsView) {
HighlightsView hView = (HighlightsView) view;
if (view instanceof HighlightsView || (view instanceof PrependedTextView && ((PrependedTextView) view).getDelegate() instanceof HighlightsView)) {
HighlightsView hView = (HighlightsView) (view instanceof HighlightsView ? view : ((PrependedTextView) view).getDelegate());
// Fill in text layout if necessary
if (hView.getTextLayout() == null) { // Fill in text layout
if (docText == null) {
Expand Down
Loading