-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Progress toward #1686: some desirable selection behaviour #2526
Conversation
|
||
import { fill } from './TypedArrayUtils'; | ||
|
||
export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number { |
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.
If we're going to need internal code in an addon we can actually reference it directly using the same trick as the webgl addon:
xterm.js/addons/xterm-addon-webgl/src/tsconfig.json
Lines 14 to 27 in 16409da
"paths": { | |
"common/*": [ "../../../src/common/*" ], | |
"browser/*": [ "../../../src/browser/*" ] | |
}, | |
"strict": true | |
}, | |
"include": [ | |
"./**/*", | |
"../../../typings/xterm.d.ts" | |
], | |
"references": [ | |
{ "path": "../../../src/common" }, | |
{ "path": "../../../src/browser" } | |
] |
xterm.js/addons/xterm-addon-webgl/webpack.config.js
Lines 27 to 30 in 16409da
alias: { | |
common: path.resolve('../../out/common'), | |
browser: path.resolve('../../out/browser') | |
} |
xterm.js/addons/xterm-addon-webgl/src/WebglAddon.ts
Lines 8 to 9 in 16409da
import { IRenderService } from 'browser/services/Services'; | |
import { IColorSet } from 'browser/Types'; |
Care needs to be used here as when webpack does its thing it will pull in all code from the file (and linked from that file), but CharWidth is a pretty standalone thing so it should be good.
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.
❤️ Many thx! There are still some bugs in the code, esp. the mixing of string indices with cell indices will not work this way, see my remarks below. Lemme know if you need some help fixing it (the cell vs string offset separation can get confusing)
@@ -52,7 +53,7 @@ export class SearchAddon implements ITerminalAddon { | |||
throw new Error('Cannot use addon until it has been loaded'); | |||
} | |||
|
|||
if (!term || term.length === 0) { | |||
if (!term || getStringCellWidth(term) === 0) { |
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.
I think this will make searching for diacritical characters impossible? (like find all "`" in terminal)
I would remove the second condition completely, not sure why it was placed there in the first place (!term
already catches term.length === 0
anyway).
@@ -116,7 +117,7 @@ export class SearchAddon implements ITerminalAddon { | |||
throw new Error('Cannot use addon until it has been loaded'); | |||
} | |||
|
|||
if (!term || term.length === 0) { | |||
if (!term || getStringCellWidth(term) === 0) { |
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.
Same as above.
@@ -211,7 +212,7 @@ export class SearchAddon implements ITerminalAddon { | |||
*/ | |||
private _isWholeWord(searchIndex: number, line: string, term: string): boolean { | |||
return (((searchIndex === 0) || (NON_WORD_CHARACTERS.indexOf(line[searchIndex - 1]) !== -1)) && | |||
(((searchIndex + term.length) === line.length) || (NON_WORD_CHARACTERS.indexOf(line[searchIndex + term.length]) !== -1))); | |||
(((searchIndex + getStringCellWidth(term)) === line.length) || (NON_WORD_CHARACTERS.indexOf(line[searchIndex + getStringCellWidth(term)]) !== -1))); |
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.
I think term.length
was right here since it evals data in the line
string (thus the string index should be used). The wcwidth correction is only needed for buffer offset/index calculation.
term = foundTerm[0]; | ||
searchRegex.lastIndex -= (term.length - 1); | ||
searchRegex.lastIndex -= (getStringCellWidth(term) - 1); |
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.
Same problem here - the regex operates on string data, thus go with the string index/length.
if (foundTerm && foundTerm[0].length > 0) { | ||
resultIndex = col + (searchRegex.lastIndex - foundTerm[0].length); | ||
if (foundTerm && getStringCellWidth(foundTerm[0]) > 0) { | ||
resultIndex = col + (searchRegex.lastIndex - getStringCellWidth(foundTerm[0])); |
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.
Imho this does not work at all this way - it mixes cell offsets (col
) with string offsets into resultIndex
. Note that cell offsets must contain the wcwidth correction, while string offsets should never.
Possible fix:
- do the regexp index handling/matching beforehand
- if a match was found, take the match index and do a
getStringCellWidth(stringLine.slice(0, matchIndex))
- this gives the correct cell offset of the start character - add
getStringCellWidth(term)
to that - cell offset of the end character + 1 - do a divmod correction for both values to translate them into actual col/row values (
col = startOffset % terminal.cols
,row += startOffset / terminal.cols
)
term = foundTerm[0]; | ||
} | ||
} | ||
} else { | ||
if (isReverseSearch) { | ||
if (col - searchTerm.length >= 0) { | ||
resultIndex = searchStringLine.lastIndexOf(searchTerm, col - searchTerm.length); | ||
if (col - getStringCellWidth(searchTerm) >= 0) { |
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.
Same here but in opposite direction.
if (char.length == 2 && getStringCellWidth(char) == 2) { | ||
resultIndex -= char.length - 1; |
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.
This code does not make any sense to me. It definitely does not (only) do what the comment says. Again resultIndex
is involved in this, I think the whole block from line 288 on needs a rewrite introduced by the needed rewrites above.
@@ -349,7 +350,7 @@ export class SearchAddon implements ITerminalAddon { | |||
terminal.clearSelection(); | |||
return false; | |||
} | |||
terminal.select(result.col, result.row, result.term.length); | |||
terminal.select(result.col, result.row, getStringCellWidth(result.term)); |
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.
Yepp here getStringCellWidth
is needed. Still result.col
and result.row
may contain wrong value due to the cell and string offset mixing above.
Also note, that you might have to do the divmod correction on the end position here (if the term happens to wrap at the rightmost column).
@Silvyre Any progress on your side? Plz drop me a note if you need some help. |
Really appreciately the offer for help, and will definitely will take you up on it. I am a bit apprehensive of making further changes, as I am still not very confident in my understanding of cell and string offsetting. |
Thanks for the PR but closing off since it's a bit stale 🙂 |
@Silvyre Thx for dealing with this issue. Sorry from my side, it went somewhat under my radar. |
@jerch No problem, thanks for all of your help! |
Some progress was made towards #1686:
String.length
were replaced with calls towcwidth
.common/CharWidth.ts
withinaddons/xterm-addon-search/
, as helper functions insrc/common
, e.g.wcwidth
, cannot currently be imported into addons; I will open an issue to address this.)ééé
or¥¥¥
after insertingecho -en 'combining: ééé\nfullwidth: ¥¥¥\n'
into the demo now works well.