fix(gui): fix caret positions of search/usage/goto decl, add search to popup menu (#1093) (PR #1094)
* fix caret positions of search/usage/goto decl to matched place & add menu items for search * Remove static field for main window Co-authored-by: tobias <tobias.hotmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ public final class CodePosition {
|
||||
private final JavaNode node;
|
||||
private final int line;
|
||||
private final int offset;
|
||||
private int usagePosition = -1;
|
||||
|
||||
public CodePosition(JavaNode node, int line, int offset) {
|
||||
this.node = node;
|
||||
@@ -18,6 +19,15 @@ public final class CodePosition {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getUsagePosition() {
|
||||
return usagePosition;
|
||||
}
|
||||
|
||||
public CodePosition setUsagePosition(int usagePosition) {
|
||||
this.usagePosition = usagePosition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -120,8 +120,16 @@ public class CodeWriter {
|
||||
CodeWriter add(CodeWriter code) {
|
||||
line--;
|
||||
for (Map.Entry<CodePosition, Object> entry : code.annotations.entrySet()) {
|
||||
Object val = entry.getValue();
|
||||
if (val instanceof DefinitionWrapper) {
|
||||
LineAttrNode node = ((DefinitionWrapper) val).getNode();
|
||||
node.setDefPosition(node.getDefPosition() + this.buf.length());
|
||||
}
|
||||
CodePosition pos = entry.getKey();
|
||||
attachAnnotation(entry.getValue(), new CodePosition(line + pos.getLine(), pos.getOffset()));
|
||||
int usagePos = pos.getUsagePosition() + bufLength();
|
||||
attachAnnotation(val,
|
||||
new CodePosition(line + pos.getLine(), pos.getOffset())
|
||||
.setUsagePosition(usagePos));
|
||||
}
|
||||
for (Map.Entry<Integer, Integer> entry : code.lineMap.entrySet()) {
|
||||
attachSourceLine(line + entry.getKey(), entry.getValue());
|
||||
@@ -211,12 +219,14 @@ public class CodeWriter {
|
||||
}
|
||||
|
||||
public void attachDefinition(LineAttrNode obj) {
|
||||
obj.setDefPosition(buf.length());
|
||||
attachAnnotation(obj);
|
||||
attachAnnotation(new DefinitionWrapper(obj), new CodePosition(line, offset));
|
||||
}
|
||||
|
||||
public void attachAnnotation(Object obj) {
|
||||
attachAnnotation(obj, new CodePosition(line, offset + 1));
|
||||
attachAnnotation(obj,
|
||||
new CodePosition(line, offset + 1).setUsagePosition(bufLength()));
|
||||
}
|
||||
|
||||
public void attachLineAnnotation(Object obj) {
|
||||
|
||||
@@ -8,6 +8,17 @@ public abstract class LineAttrNode extends AttrNode {
|
||||
|
||||
private int decompiledLine;
|
||||
|
||||
// the position exactly where a node declared at in decompiled java code.
|
||||
private int defPosition;
|
||||
|
||||
public int getDefPosition() {
|
||||
return this.defPosition;
|
||||
}
|
||||
|
||||
public void setDefPosition(int defPosition) {
|
||||
this.defPosition = defPosition;
|
||||
}
|
||||
|
||||
public int getSourceLine() {
|
||||
return sourceLine;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public class CodeNode extends JNode {
|
||||
private final transient JClass jParent;
|
||||
private final transient StringRef line;
|
||||
private final transient int lineNum;
|
||||
private transient int pos = -1;
|
||||
private transient boolean precise;
|
||||
|
||||
public CodeNode(JNode jNode, int lineNum, StringRef lineStr) {
|
||||
this.jNode = jNode;
|
||||
@@ -93,4 +95,25 @@ public class CodeNode extends JNode {
|
||||
public int hashCode() {
|
||||
return jNode.hashCode();
|
||||
}
|
||||
|
||||
public int getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public CodeNode setPos(int pos) {
|
||||
this.pos = pos;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeNode setPrecisePos(int pos) {
|
||||
this.pos = pos;
|
||||
if (pos > -1) {
|
||||
this.precise = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isPrecisePos() {
|
||||
return precise;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@ public class JField extends JNode {
|
||||
this.jParent = jClass;
|
||||
}
|
||||
|
||||
public JavaField getJavaField() {
|
||||
return (JavaField) getJavaNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaNode getJavaNode() {
|
||||
return field;
|
||||
|
||||
@@ -11,7 +11,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -20,7 +19,6 @@ import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.DocumentRange;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.fife.ui.rtextarea.SearchContext;
|
||||
@@ -33,7 +31,7 @@ import org.slf4j.LoggerFactory;
|
||||
import jadx.gui.jobs.BackgroundJob;
|
||||
import jadx.gui.jobs.BackgroundWorker;
|
||||
import jadx.gui.jobs.DecompileJob;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.treemodel.*;
|
||||
import jadx.gui.ui.codearea.AbstractCodeArea;
|
||||
import jadx.gui.utils.CacheObject;
|
||||
import jadx.gui.utils.JumpPosition;
|
||||
@@ -111,9 +109,18 @@ public abstract class CommonSearchDialog extends JDialog {
|
||||
if (selectedId == -1) {
|
||||
return;
|
||||
}
|
||||
int pos = Math.max(0, resultsModel.renderer.getFirstMarkOfCode(selectedId));
|
||||
JumpPosition jmpPos;
|
||||
JNode node = (JNode) resultsModel.getValueAt(selectedId, 0);
|
||||
tabbedPane.codeJump(new JumpPosition(node.getRootClass(), node.getLine(), pos));
|
||||
if (node instanceof CodeNode) {
|
||||
CodeNode codeNode = (CodeNode) node;
|
||||
jmpPos = new JumpPosition(node.getRootClass(), node.getLine(), codeNode.getPos());
|
||||
if (codeNode.isPrecisePos()) {
|
||||
jmpPos.setPrecise(codeNode.getPos());
|
||||
}
|
||||
} else {
|
||||
jmpPos = new JumpPosition(node.getRootClass(), node.getLine());
|
||||
}
|
||||
tabbedPane.codeJump(jmpPos);
|
||||
|
||||
dispose();
|
||||
}
|
||||
@@ -413,19 +420,6 @@ public abstract class CommonSearchDialog extends JDialog {
|
||||
this.codeBackground = area.getBackground();
|
||||
}
|
||||
|
||||
public int getFirstMarkOfCode(int row) {
|
||||
Component comp = componentCache.get(makeID(row, 1));
|
||||
if (comp instanceof RSyntaxTextArea) {
|
||||
List<DocumentRange> ranges = ((RSyntaxTextArea) comp).getMarkAllHighlightRanges();
|
||||
if (ranges.size() > 0) {
|
||||
// minus 2 cuz the start of textArea of the column is added 2
|
||||
// spaces in makeCell method.
|
||||
return ranges.get(0).getStartOffset() - 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected,
|
||||
boolean hasFocus, int row, int column) {
|
||||
|
||||
@@ -81,6 +81,7 @@ import jadx.api.JadxArgs;
|
||||
import jadx.api.JavaClass;
|
||||
import jadx.api.JavaNode;
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.core.utils.StringUtils;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
import jadx.gui.JadxWrapper;
|
||||
@@ -100,6 +101,7 @@ import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.treemodel.JPackage;
|
||||
import jadx.gui.treemodel.JResource;
|
||||
import jadx.gui.treemodel.JRoot;
|
||||
import jadx.gui.ui.codearea.AbstractCodeContentPanel;
|
||||
import jadx.gui.update.JadxUpdate;
|
||||
import jadx.gui.update.JadxUpdate.IUpdateCallback;
|
||||
import jadx.gui.update.data.Release;
|
||||
@@ -228,7 +230,8 @@ public class MainWindow extends JFrame {
|
||||
return;
|
||||
}
|
||||
JNode node = cacheObject.getNodeCache().makeFrom(javaNode);
|
||||
tabbedPane.codeJump(new JumpPosition(node.getRootClass(), node.getLine()));
|
||||
tabbedPane.codeJump(new JumpPosition(node.getRootClass(), node.getLine())
|
||||
.setPrecise(JumpPosition.getDefPos(node)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,7 +516,8 @@ public class MainWindow extends JFrame {
|
||||
continue;
|
||||
}
|
||||
JNode newNode = cacheObject.getNodeCache().makeFrom(newClass);
|
||||
tabbedPane.codeJump(new JumpPosition(newNode, position));
|
||||
tabbedPane.codeJump(new JumpPosition(newNode, position)
|
||||
.setPrecise(JumpPosition.getDefPos(newNode)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,7 +650,8 @@ public class MainWindow extends JFrame {
|
||||
JNode node = (JNode) obj;
|
||||
JClass cls = node.getRootClass();
|
||||
if (cls != null) {
|
||||
tabbedPane.codeJump(new JumpPosition(cls, node.getLine()));
|
||||
tabbedPane.codeJump(new JumpPosition(cls, node.getLine())
|
||||
.setPrecise(JumpPosition.getDefPos(node)));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -812,6 +817,14 @@ public class MainWindow extends JFrame {
|
||||
Action textSearchAction = new AbstractAction(NLS.str("menu.text_search"), ICON_SEARCH) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ContentPanel panel = tabbedPane.getSelectedCodePanel();
|
||||
if (panel instanceof AbstractCodeContentPanel) {
|
||||
String preferText = ((AbstractCodeContentPanel) panel).getCodeArea().getSelectedText();
|
||||
if (!StringUtils.isEmpty(preferText)) {
|
||||
SearchDialog.searchText(MainWindow.this, preferText);
|
||||
return;
|
||||
}
|
||||
}
|
||||
new SearchDialog(MainWindow.this, true).setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.reactivex.Flowable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import jadx.core.utils.StringUtils;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.TextStandardActions;
|
||||
@@ -47,6 +48,7 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
|
||||
private transient Disposable searchDisposable;
|
||||
private transient SearchEventEmitter searchEmitter;
|
||||
private transient String text = null;
|
||||
|
||||
public SearchDialog(MainWindow mainWindow, boolean textSearch) {
|
||||
super(mainWindow);
|
||||
@@ -286,13 +288,23 @@ public class SearchDialog extends CommonSearchDialog {
|
||||
|
||||
@Override
|
||||
protected void loadFinished() {
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
searchField.setText(text);
|
||||
}
|
||||
resultsTable.setEnabled(true);
|
||||
searchField.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadStart() {
|
||||
text = cache.getLastSearch(); // SearchDialog is opened by menu item, let loadFinished to set text
|
||||
cache.setLastSearch("");
|
||||
resultsTable.setEnabled(false);
|
||||
searchField.setEnabled(false);
|
||||
}
|
||||
|
||||
public static void searchText(MainWindow window, String text) {
|
||||
window.getCacheObject().setLastSearch(text);
|
||||
new SearchDialog(window, true).setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ public class TabbedPane extends JTabbedPane {
|
||||
line = pos.getNode().getLine();
|
||||
}
|
||||
}
|
||||
if (pos.getPos() <= 0) {
|
||||
if (pos.getPos() < 0) {
|
||||
codeArea.scrollToLine(line);
|
||||
} else {
|
||||
int lineNum = Math.max(0, line - 1);
|
||||
@@ -225,6 +225,9 @@ public class TabbedPane extends JTabbedPane {
|
||||
}
|
||||
|
||||
public void navBack() {
|
||||
if (jumps.size() > 1) {
|
||||
jumps.updateCurPosition(getCurrentPosition());
|
||||
}
|
||||
JumpPosition pos = jumps.getPrev();
|
||||
if (pos != null) {
|
||||
showCode(pos);
|
||||
@@ -232,6 +235,9 @@ public class TabbedPane extends JTabbedPane {
|
||||
}
|
||||
|
||||
public void navForward() {
|
||||
if (jumps.size() > 1) {
|
||||
jumps.updateCurPosition(getCurrentPosition());
|
||||
}
|
||||
JumpPosition pos = jumps.getNext();
|
||||
if (pos != null) {
|
||||
showCode(pos);
|
||||
|
||||
@@ -32,11 +32,6 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
|
||||
public static final Color MARK_ALL_HIGHLIGHT_COLOR = Color.decode("#FFED89");
|
||||
|
||||
@Override
|
||||
public boolean getHighlightCurrentLine() {
|
||||
return super.getHighlightCurrentLine();
|
||||
}
|
||||
|
||||
protected final ContentPanel contentPanel;
|
||||
protected final JNode node;
|
||||
|
||||
@@ -115,13 +110,7 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
int pos = e.getDot();
|
||||
if (pos == 0) {
|
||||
// not accepting 0, cuz sometimes the underlying RSyntaxTextArea
|
||||
// will fire a fake event to force repaint caret, and its dot is
|
||||
// usually 0, so we just ignore 0 anyway as a workaround.
|
||||
return;
|
||||
}
|
||||
int pos = getCaretPosition();
|
||||
if (lastPos != pos) {
|
||||
lastPos = pos;
|
||||
lastText = highlightCaretWord(lastText, pos);
|
||||
|
||||
@@ -145,7 +145,8 @@ public final class CodeArea extends AbstractCodeArea {
|
||||
return null;
|
||||
}
|
||||
JNode jNode = convertJavaNode(foundNode);
|
||||
return new JumpPosition(jNode.getRootClass(), pos.getLine());
|
||||
return new JumpPosition(jNode.getRootClass(), pos.getLine())
|
||||
.setPrecise(JumpPosition.getDefPos(jNode));
|
||||
}
|
||||
|
||||
private JNode convertJavaNode(JavaNode javaNode) {
|
||||
|
||||
@@ -8,9 +8,16 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.JPopupMenu.Separator;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
import jadx.api.ICodeInfo;
|
||||
import jadx.core.utils.StringUtils;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.SearchDialog;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
/**
|
||||
@@ -42,6 +49,56 @@ public class CodePanel extends JPanel {
|
||||
searchBar.toggle();
|
||||
}
|
||||
});
|
||||
JMenuItem searchItem = new JMenuItem();
|
||||
JMenuItem globalSearchItem = new JMenuItem();
|
||||
AbstractAction searchAction = new AbstractAction(NLS.str("popup.search", "")) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
searchBar.toggle();
|
||||
}
|
||||
};
|
||||
AbstractAction globalSearchAction = new AbstractAction(NLS.str("popup.search_global", "")) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
MainWindow mainWindow = codeArea.getContentPanel().getTabbedPane().getMainWindow();
|
||||
SearchDialog.searchText(mainWindow, codeArea.getSelectedText());
|
||||
}
|
||||
};
|
||||
searchItem.setAction(searchAction);
|
||||
globalSearchItem.setAction(globalSearchAction);
|
||||
Separator separator = new Separator();
|
||||
JPopupMenu popupMenu = codeArea.getPopupMenu();
|
||||
popupMenu.addPopupMenuListener(new PopupMenuListener() {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
String preferText = codeArea.getSelectedText();
|
||||
if (!StringUtils.isEmpty(preferText)) {
|
||||
if (preferText.length() >= 23) {
|
||||
preferText = preferText.substring(0, 20) + " ...";
|
||||
}
|
||||
searchAction.putValue(Action.NAME, NLS.str("popup.search", preferText));
|
||||
globalSearchAction.putValue(Action.NAME, NLS.str("popup.search_global", preferText));
|
||||
popupMenu.add(separator);
|
||||
popupMenu.add(globalSearchItem);
|
||||
popupMenu.add(searchItem);
|
||||
} else {
|
||||
popupMenu.remove(separator);
|
||||
popupMenu.remove(globalSearchItem);
|
||||
popupMenu.remove(searchItem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void loadSettings() {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.fife.ui.rtextarea.SearchResult;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.utils.StringUtils;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.TextStandardActions;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
@@ -113,6 +114,10 @@ class SearchBar extends JToolBar {
|
||||
setVisible(visible);
|
||||
|
||||
if (visible) {
|
||||
String preferText = rTextArea.getSelectedText();
|
||||
if (!StringUtils.isEmpty(preferText)) {
|
||||
searchField.setText(preferText);
|
||||
}
|
||||
searchField.requestFocus();
|
||||
searchField.selectAll();
|
||||
} else {
|
||||
|
||||
@@ -64,7 +64,7 @@ public class CodeUsageInfo {
|
||||
JavaNode javaNodeByLine = linesInfo.getJavaNodeByLine(line);
|
||||
StringRef codeLine = lines.get(line - 1);
|
||||
JNode node = nodeCache.makeFrom(javaNodeByLine == null ? javaClass : javaNodeByLine);
|
||||
CodeNode codeNode = new CodeNode(node, line, codeLine);
|
||||
CodeNode codeNode = new CodeNode(node, line, codeLine).setPrecisePos(codePosition.getUsagePosition());
|
||||
usageInfo.addUsage(codeNode);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,14 @@ public class JumpManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCurPosition(JumpPosition pos) {
|
||||
list.set(currentPos, pos);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
private boolean ignoreJump(JumpPosition pos) {
|
||||
JumpPosition current = getCurrent();
|
||||
if (current == null) {
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package jadx.gui.utils;
|
||||
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.api.JavaClass;
|
||||
import jadx.api.JavaField;
|
||||
import jadx.api.JavaMethod;
|
||||
import jadx.api.JavaNode;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.gui.treemodel.*;
|
||||
|
||||
public class JumpPosition {
|
||||
private final JNode node;
|
||||
private final int line;
|
||||
// the position of the node in java code,
|
||||
// call codeArea.scrollToPos(pos) to set caret
|
||||
private int pos;
|
||||
// Precise means caret can be set right at the node in codeArea,
|
||||
// not just the start of the line.
|
||||
private boolean precise;
|
||||
|
||||
public JumpPosition(JNode node, int line) {
|
||||
this(node, line, 0);
|
||||
this(node, line, -1);
|
||||
}
|
||||
|
||||
public JumpPosition(JNode node, int line, int pos) {
|
||||
@@ -44,6 +45,32 @@ public class JumpPosition {
|
||||
return line;
|
||||
}
|
||||
|
||||
public static int getDefPos(JNode node) {
|
||||
if (node instanceof JClass) {
|
||||
return ((JClass) node).getCls().getClassNode().getDefPosition();
|
||||
}
|
||||
if (node instanceof JMethod) {
|
||||
return ((JMethod) node).getJavaMethod().getMethodNode().getDefPosition();
|
||||
}
|
||||
if (node instanceof JField) {
|
||||
return ((JField) node).getJavaField().getFieldNode().getDefPosition();
|
||||
}
|
||||
throw new JadxRuntimeException("Unexpected node " + node);
|
||||
}
|
||||
|
||||
public static int getDefPos(JavaNode node) {
|
||||
if (node instanceof JavaClass) {
|
||||
return ((JavaClass) node).getClassNode().getDefPosition();
|
||||
}
|
||||
if (node instanceof JavaMethod) {
|
||||
return ((JavaMethod) node).getMethodNode().getDefPosition();
|
||||
}
|
||||
if (node instanceof JavaField) {
|
||||
return ((JavaField) node).getFieldNode().getDefPosition();
|
||||
}
|
||||
throw new JadxRuntimeException("Unexpected node " + node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
|
||||
@@ -35,7 +35,9 @@ public class CodeIndex {
|
||||
return Flowable.create(emitter -> {
|
||||
LOG.debug("Code search started: {} ...", searchSettings.getSearchString());
|
||||
for (CodeNode node : values) {
|
||||
if (isMatched(node.getLineStr(), searchSettings)) {
|
||||
int pos = searchSettings.find(node.getLineStr());
|
||||
node.setPos(pos);
|
||||
if (pos > -1) {
|
||||
emitter.onNext(node);
|
||||
}
|
||||
if (emitter.isCancelled()) {
|
||||
|
||||
@@ -158,7 +158,7 @@ public class TextSearchIndex {
|
||||
int lineStart = 1 + code.lastIndexOf(CodeWriter.NL, pos);
|
||||
int lineEnd = code.indexOf(CodeWriter.NL, pos + searchSettings.getSearchString().length());
|
||||
StringRef line = StringRef.subString(code, lineStart, lineEnd == -1 ? code.length() : lineEnd);
|
||||
emitter.onNext(new CodeNode(nodeCache.makeFrom(javaClass), -pos, line.trim()));
|
||||
emitter.onNext(new CodeNode(nodeCache.makeFrom(javaClass), -pos, line.trim()).setPos(pos));
|
||||
return lineEnd;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +160,8 @@ popup.find_usage=Verwendung suchen
|
||||
popup.go_to_declaration=Zur Erklärung gehen
|
||||
popup.exclude=Ausschließen
|
||||
popup.rename=Umbennen
|
||||
#popup.search=
|
||||
#popup.search_global=
|
||||
|
||||
confirm.save_as_title=Speichern unter bestätigen
|
||||
confirm.save_as_message=%s existiert bereits.\nErsetzen?
|
||||
|
||||
@@ -160,6 +160,8 @@ popup.find_usage=Find Usage
|
||||
popup.go_to_declaration=Go to declaration
|
||||
popup.exclude=Exclude
|
||||
popup.rename=Rename
|
||||
popup.search=Search "%s"
|
||||
popup.search_global=Global Search "%s"
|
||||
|
||||
confirm.save_as_title=Confirm Save as
|
||||
confirm.save_as_message=%s already exists.\nDo you want to replace it?
|
||||
|
||||
@@ -160,6 +160,8 @@ popup.select_all=Seleccionar todo
|
||||
#popup.go_to_declaration=
|
||||
#popup.exclude=
|
||||
popup.rename=Nimeta ümber
|
||||
#popup.search=
|
||||
#popup.search_global=
|
||||
|
||||
#confirm.save_as_title=
|
||||
#confirm.save_as_message=
|
||||
|
||||
@@ -160,6 +160,8 @@ popup.find_usage=사용 찾기
|
||||
popup.go_to_declaration=선언문으로 이동
|
||||
popup.exclude=제외
|
||||
popup.rename=이름 바꾸기
|
||||
#popup.search=
|
||||
#popup.search_global=
|
||||
|
||||
confirm.save_as_title=다른 이름으로 저장 확인
|
||||
confirm.save_as_message=%s이(가) 이미 있습니다.\n바꾸시겠습니까?
|
||||
|
||||
@@ -160,6 +160,8 @@ popup.find_usage=查找用例
|
||||
popup.go_to_declaration=跳到声明
|
||||
popup.exclude=排除
|
||||
popup.rename=改名
|
||||
#popup.search=
|
||||
#popup.search_global=
|
||||
|
||||
confirm.save_as_title=确认另存为
|
||||
confirm.save_as_message=%s 已存在。\n你想替换它吗?
|
||||
|
||||
Reference in New Issue
Block a user