feat(gui): on mouse hover highlight identifiers with enabled actions (like 'find usage' or 'rename')
This commit is contained in:
@@ -34,7 +34,7 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
this.contentPanel = contentPanel;
|
||||
this.node = contentPanel.getNode();
|
||||
|
||||
setMarkOccurrences(true);
|
||||
setMarkOccurrences(false);
|
||||
setEditable(false);
|
||||
setCodeFoldingEnabled(false);
|
||||
loadSettings();
|
||||
|
||||
@@ -36,7 +36,8 @@ public final class CodeArea extends AbstractCodeArea {
|
||||
super(contentPanel);
|
||||
setSyntaxEditingStyle(node.getSyntaxName());
|
||||
|
||||
if (node instanceof JClass) {
|
||||
boolean isJavaCode = node instanceof JClass;
|
||||
if (isJavaCode) {
|
||||
((RSyntaxDocument) getDocument()).setSyntaxStyle(new JadxTokenMaker(this));
|
||||
addMenuItems();
|
||||
}
|
||||
@@ -46,6 +47,7 @@ public final class CodeArea extends AbstractCodeArea {
|
||||
CodeLinkGenerator codeLinkGenerator = new CodeLinkGenerator(this);
|
||||
setLinkGenerator(codeLinkGenerator);
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.isControlDown()) {
|
||||
@@ -57,6 +59,9 @@ public final class CodeArea extends AbstractCodeArea {
|
||||
}
|
||||
}
|
||||
});
|
||||
if (isJavaCode) {
|
||||
addMouseMotionListener(new MouseHoverHighlighter(this, codeLinkGenerator));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,7 +26,7 @@ public final class JadxTokenMaker extends JavaTokenMaker {
|
||||
@Override
|
||||
public Token getTokenList(Segment text, int initialTokenType, int startOffset) {
|
||||
Token tokens = super.getTokenList(text, initialTokenType, startOffset);
|
||||
if (startOffset > 0 && tokens.getType() != TokenTypes.NULL) {
|
||||
if (tokens.getType() != TokenTypes.NULL) {
|
||||
try {
|
||||
processTokens(tokens);
|
||||
} catch (Exception e) {
|
||||
@@ -41,11 +41,14 @@ public final class JadxTokenMaker extends JavaTokenMaker {
|
||||
Token current = tokens;
|
||||
while (current != null) {
|
||||
if (prev != null) {
|
||||
int tokenType = current.getType();
|
||||
if (tokenType == TokenTypes.IDENTIFIER) {
|
||||
current = mergeLongClassNames(prev, current, false);
|
||||
} else if (tokenType == TokenTypes.ANNOTATION) {
|
||||
current = mergeLongClassNames(prev, current, true);
|
||||
switch (current.getType()) {
|
||||
case TokenTypes.IDENTIFIER:
|
||||
current = mergeLongClassNames(prev, current, false);
|
||||
break;
|
||||
|
||||
case TokenTypes.ANNOTATION:
|
||||
current = mergeLongClassNames(prev, current, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev = current;
|
||||
@@ -55,7 +58,7 @@ public final class JadxTokenMaker extends JavaTokenMaker {
|
||||
|
||||
@NotNull
|
||||
private Token mergeLongClassNames(Token prev, Token current, boolean annotation) {
|
||||
int offset = current.getOffset();
|
||||
int offset = current.getTextOffset();
|
||||
if (annotation) {
|
||||
offset++;
|
||||
}
|
||||
@@ -66,7 +69,7 @@ public final class JadxTokenMaker extends JavaTokenMaker {
|
||||
if (annotation && lexeme.length() > 1) {
|
||||
lexeme = lexeme.substring(1);
|
||||
}
|
||||
if (!lexeme.equals(name) && javaNode.getFullName().startsWith(lexeme)) {
|
||||
if (!lexeme.equals(name) && isClassNameStart(javaNode, lexeme)) {
|
||||
// try to replace long class name with one token
|
||||
Token replace = concatTokensUntil(current, name);
|
||||
if (replace != null && prev instanceof TokenImpl) {
|
||||
@@ -79,6 +82,18 @@ public final class JadxTokenMaker extends JavaTokenMaker {
|
||||
return current;
|
||||
}
|
||||
|
||||
private boolean isClassNameStart(JavaNode javaNode, String lexeme) {
|
||||
if (javaNode.getFullName().startsWith(lexeme)) {
|
||||
// full class name
|
||||
return true;
|
||||
}
|
||||
if (javaNode.getTopParentClass().getName().startsWith(lexeme)) {
|
||||
// inner class references from parent class
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Token concatTokensUntil(Token start, String endText) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package jadx.gui.ui.codearea;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
|
||||
import javax.swing.text.Highlighter;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.Token;
|
||||
import org.fife.ui.rsyntaxtextarea.TokenTypes;
|
||||
import org.fife.ui.rtextarea.SmartHighlightPainter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.gui.utils.JumpPosition;
|
||||
|
||||
class MouseHoverHighlighter extends MouseMotionAdapter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MouseHoverHighlighter.class);
|
||||
|
||||
private final CodeArea codeArea;
|
||||
private final CodeLinkGenerator codeLinkGenerator;
|
||||
private final Highlighter.HighlightPainter highlighter;
|
||||
|
||||
private boolean added;
|
||||
|
||||
public MouseHoverHighlighter(CodeArea codeArea, CodeLinkGenerator codeLinkGenerator) {
|
||||
this.codeArea = codeArea;
|
||||
this.codeLinkGenerator = codeLinkGenerator;
|
||||
this.highlighter = new SmartHighlightPainter(codeArea.getMarkOccurrencesColor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
Highlighter highlighter = codeArea.getHighlighter();
|
||||
if (added) {
|
||||
highlighter.removeAllHighlights();
|
||||
added = false;
|
||||
}
|
||||
if (e.getModifiersEx() != 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Token token = codeArea.viewToToken(e.getPoint());
|
||||
if (token == null || token.getType() != TokenTypes.IDENTIFIER) {
|
||||
return;
|
||||
}
|
||||
JumpPosition jump = codeLinkGenerator.getJumpLinkAtOffset(codeArea, token.getOffset());
|
||||
if (jump == null) {
|
||||
return;
|
||||
}
|
||||
highlighter.removeAllHighlights();
|
||||
highlighter.addHighlight(token.getOffset(), token.getEndOffset(), this.highlighter);
|
||||
added = true;
|
||||
} catch (Exception exc) {
|
||||
LOG.error("Mouse hover highlight error", exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user