Merge remote-tracking branch 'origin/GP-6443-dragonmacher-decomp-find-text-infinity--SQUASHED'

This commit is contained in:
Ryan Kurtz
2026-02-17 17:06:59 -05:00
8 changed files with 42 additions and 27 deletions
@@ -175,8 +175,7 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
FieldElement[] elements = createFieldElementsForLine(tokens);
int indent = line.getIndent() * indentWidth;
int updatedMaxWidth = maxWidth;
return new ClangTextField(tokens, elements, indent, line.getLineNumber(), updatedMaxWidth,
return new ClangTextField(tokens, elements, indent, line.getLineNumber(), maxWidth,
hlFactory);
}
@@ -4,9 +4,9 @@
* Licensed 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.
@@ -33,7 +33,7 @@ public class ClangTextField extends WrappingVerticalLayoutTextField {
public ClangTextField(List<ClangToken> tokenList, FieldElement[] fieldElements, int x,
int lineNumber, int width, FieldHighlightFactory hlFactory) {
super(createSingleLineElement(fieldElements), x, width - x, 30, hlFactory, false);
super(createSingleLineElement(fieldElements), x, width - x, 30, hlFactory, false, "");
this.tokenList = tokenList;
this.lineNumber = lineNumber;
}
@@ -113,7 +113,7 @@ public class DecompilerSearchResults extends SearchResults {
// getNextLocation() will find the next matching location, starting at the given field
// location. The next location may or may not actually contain the given field location.
DecompilerSearchLocation nextLocation = getNextLocation(fieldLocation, searchForward);
if (nextLocation.contains(fieldLocation)) {
if (nextLocation != null && nextLocation.contains(fieldLocation)) {
return nextLocation;
}
return null;
@@ -119,7 +119,7 @@ public class DecompilerSearcher implements FindDialogSearcher {
FieldLocation last = searchLocation.getFieldLocation();
int line = last.getIndex().intValue();
int field = 0; // there is only 1 field
int row = 0; // there is only 1 row
int row = last.getRow(); // more than 1 row when the line wraps
int col = last.getCol() + 1; // move over one char to handle sub-matches
start = new FieldLocation(line, field, row, col);
searchLocation = findNext(forwardMatcher, searchText, start);
@@ -215,7 +215,6 @@ public class DecompilerSearcher implements FindDialogSearcher {
private DecompilerSearchLocation findNext(Function<String, SearchMatch> matcher,
String searchString, FieldLocation currentLocation) {
List<Field> fields = decompilerPanel.getFields();
int line = currentLocation.getIndex().intValue();
for (int i = line; i < fields.size(); i++) {
@@ -234,6 +233,8 @@ public class DecompilerSearcher implements FindDialogSearcher {
// the match start is relative to the cursor position. Update the start to
// compensate for the difference between the start of the line and the cursor.
//
// The match start/end for a partial line will be relative to that line's text. We
// want the start/end to be based on a full line.
int cursorOffset = fullLine.length() - partialLine.length();
match.start += cursorOffset;
match.end += cursorOffset;
@@ -241,7 +242,7 @@ public class DecompilerSearcher implements FindDialogSearcher {
FieldLineLocation lineInfo = getFieldIndexFromOffset(match.start, field);
FieldLocation fieldLocation =
new FieldLocation(i, lineInfo.fieldNumber(), 0, lineInfo.column());
new FieldLocation(i, lineInfo.fieldNumber(), lineInfo.row(), lineInfo.column());
int lineNumber = lineInfo.lineNumber();
SearchLocationContext context = createContext(fullLine, match);
return new DecompilerSearchLocation(fieldLocation, match.start, match.end - 1,
@@ -266,31 +267,35 @@ public class DecompilerSearcher implements FindDialogSearcher {
private String substring(ClangTextField textField, FieldLocation location,
boolean forwardSearch) {
// Note: full text may include multiple wrapped UI lines that are then put back into one
// line here for searching.
String fullText = textField.getText();
if (location == null) { // the cursor location is not on this line; use all of the text
return textField.getText();
return fullText;
}
if (textField.getText().isEmpty()) { // the cursor is on blank line
if (fullText.isEmpty()) { // the cursor is on blank line
return "";
}
String partialText = textField.getText();
if (forwardSearch) {
int row = location.getRow();
int nextCol = location.getCol();
int screenCol = textField.screenLocationToTextOffset(row, nextCol);
int nextCol = location.getCol();
if (forwardSearch) {
// protects against the location column being out of range (this can happen if we're
// searching forward and the cursor is past the last token)
if (nextCol >= partialText.length()) {
if (screenCol >= fullText.length()) {
return "";
}
// skip a character to start the next search; this prevents matching the previous match
return partialText.substring(nextCol);
return fullText.substring(screenCol);
}
// backwards search
return partialText.substring(0, location.getCol());
return fullText.substring(0, screenCol);
}
private FieldLineLocation getFieldIndexFromOffset(int screenOffset, ClangTextField textField) {
@@ -298,8 +303,10 @@ public class DecompilerSearcher implements FindDialogSearcher {
RowColLocation rowColLocation = textField.textOffsetToScreenLocation(screenOffset);
int lineNumber = textField.getLineNumber();
// we use 0 here because currently there is only one field, which is the entire line
return new FieldLineLocation(0, lineNumber, rowColLocation.col());
int fieldNumber = 0; // We use 0 here because there is only one field, which is the entire line
int row = rowColLocation.row();
int col = rowColLocation.col();
return new FieldLineLocation(fieldNumber, lineNumber, row, col);
}
private static class SearchMatch {
@@ -323,5 +330,5 @@ public class DecompilerSearcher implements FindDialogSearcher {
}
}
private record FieldLineLocation(int fieldNumber, int lineNumber, int column) {}
private record FieldLineLocation(int fieldNumber, int lineNumber, int row, int column) {}
}
@@ -48,7 +48,12 @@ public class FindReferencesToAddressAction extends AbstractFindReferencesToAddre
if (!(context instanceof DecompilerActionContext dac)) {
return false;
}
updateMenuName(dac.getAddress());
Address address = dac.getAddress();
if (address == null) {
return false;
}
updateMenuName(address);
return super.isEnabledForContext(context);
}
@@ -136,7 +136,7 @@ public class VerticalLayoutTextField implements TextField {
for (int i = 0; i < n; i++) {
String text = elements.get(i).getText();
buf.append(text);
if (!text.endsWith(delimiter)) { // prevent 2 spaces between merged lines
if (!text.endsWith(delimiter)) { // prevent 2 delimiters between merged lines
buf.append(delimiter);
}
}
@@ -4,9 +4,9 @@
* Licensed 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.
@@ -47,11 +47,14 @@ public class WrappingVerticalLayoutTextField extends VerticalLayoutTextField {
* @param maxLines is the max number of lines to display
* @param hlFactory is the highlight factory
* @param breakOnWhiteSpace is true if wrapping should break on word boundaries
* @param rowSeparator The string used to space lines of text when concatenated by the
* getText() method.
*/
public WrappingVerticalLayoutTextField(FieldElement textElement, int startX, int width,
int maxLines, FieldHighlightFactory hlFactory, boolean breakOnWhiteSpace) {
int maxLines, FieldHighlightFactory hlFactory, boolean breakOnWhiteSpace,
String rowSeparator) {
super(FieldUtils.wrap(textElement, width, breakOnWhiteSpace), startX, width, maxLines,
hlFactory, " ");
hlFactory, rowSeparator);
}
@Override
@@ -21,6 +21,7 @@ import org.jdom2.Element;
import docking.widgets.fieldpanel.Layout;
import docking.widgets.fieldpanel.field.Field;
import generic.json.Json;
/**
* Class to represent {@link Field} locations within the field viewer.
@@ -207,7 +208,7 @@ public class FieldLocation implements Comparable<FieldLocation> {
@Override
public String toString() {
return index.toString() + ", " + fieldNum + ", " + row + ", " + col;
return Json.toString(this, "index", "fieldNum", "row", "col");
}