-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Fix search addons: Fix problem of skipping some results and incorrect text selection after resize window #1866
Conversation
- Changed to use `this._terminal.cols` for buffer line length instead. - Let `_findInLine` check on wrapped line - Added conditions in `_findInLine` - For reverse search, if there is no selection at given row, then start scan at the end of the string
src/addons/search/SearchHelper.ts
Outdated
@@ -187,9 +187,6 @@ export class SearchHelper implements ISearchHelper { | |||
* @return The search result if it was found. | |||
*/ | |||
protected _findInLine(term: string, row: number, col: number, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult { | |||
if (this._terminal._core.buffer.lines.get(row).isWrapped) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing ti locally on master and your branch it doesn't seem to work on either? 😕
The idea behind this isWrapped
check is to ignore all rows flagged as wrapped and only take the first row (which always has isWrapped = false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, I misunderstand the idea. I will put back the return block and try to fix else where. The problem is that if the wrapped line has multiple matches, the search result will highlight only one result and skipped others then go to next line.
by managing column range that is needed to be scanned.
I fixed the problem by controlling index of |
- Convert buffer index to string index before searching - Convert string index to buffer index after searching - Fix bug when search selection skipped some result
For the latest commit, I try to modify searching function to support wide characters and combined characters by mapping between buffer index and string index. I'm not sure if term.core.write('Hello World\r\ntest\n123....hello');
const hello2 = term.searchHelper.findInLine('Hello', 2); return the result as {col: 11, row: 2, term: 'Hello'}. I'm not sure why |
It might be better to revert the latest commit and do that in another one as this was so close. I'm happy to merge if we revert that, provided that "- Fix bug when search selection skipped some result" in the latest commit message is not something we need to worry about? Also on the actual solution, that's way too much code to copy over to the addon as it will quickly get out of sync.
That's happening because you did |
This reverts commit f961f90.
to be able to scan unwrapped line at the last row
OK, I reverted the latest commit to the previous commit. However, at the latest commit, there is a fix that relates to the previous commit, so I make an additional commit to complete the fix. |
src/addons/search/SearchHelper.ts
Outdated
for (let y = 0; y <= startRow; y++) { | ||
result = this._findInLine(term, y, 0, searchOptions); | ||
result = this._findInLine(term, findingRow, cumulativeCols, searchOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this change is grabbing the cumulativeCols
and calling _findInLine multiple times for a single wrapped row. This kind of goes against the design and _findInLines is meant to get the full unwrapped line and search it fully. I think the actual root cause is somewhere inside _findInLine
and calling it multiple times on the same row is getting around it.
After this section searchStringLine
is meant to contain the full wrapped line so we can search it in full:
xterm.js/src/addons/search/SearchHelper.ts
Lines 190 to 203 in 509ce5f
if (this._terminal._core.buffer.lines.get(row).isWrapped) { | |
return; | |
} | |
let stringLine = this._linesCache ? this._linesCache[row] : void 0; | |
if (stringLine === void 0) { | |
stringLine = this.translateBufferLineToStringWithWrap(row, true); | |
if (this._linesCache) { | |
this._linesCache[row] = stringLine; | |
} | |
} | |
const searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase(); | |
const searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you were right. _findInLine
should return the result at the first time, otherwise, go to the next unwrapped line.
I reverted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update branch
…en start scan at the last row
If you mean that, after typed a bunch of the string and ran |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, seems to work great now! I fixed a minor issue which started findPrevious at the top of the buffer rather than where the viewport was.
When function
_findInLine
is run in reverse mode (find previous), it skipped the results that is wrapped, and also skipped the line that hasisWrapped === true
although there are other results in the line. When resizing the window and search again, it highlights incorrect position.So, for skipping wrapped result problem, I added a condition to check whether start column index is in the range or not. If not, then
lastIndexOf
function should begin matching at the end of the string.For skipping wrapped line, I think the part of code inside
_findInLine
that did a return when found propertiesisWrapped === true
can be removed because we should also scan other results in wrapped line.For resizing window, I saw that the value at
this._terminal._core.buffer.lines.get(y).length
didn't change when the window was resized, but forthis._terminal.cols
, the value is changed, so I decided to usethis._terminal.cols
to match with searching range.