Skip to content
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

Don't show single non-boundary spaces in show-whitespace #5709

Merged
merged 12 commits into from
Jun 23, 2022
6 changes: 3 additions & 3 deletions source/helpers/show-whitespace-on-line.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,17 @@ test('showWhiteSpacesOnLine highlighted code', t => {
assertHighlighted(
t,
'[1, " "]',
'[1,"••"]',
'[1, "••"]',
);
assertHighlighted(
t,
' [1, " "] ',
'•[1,"••"]•',
'•[1, "••"]•',
);
assertHighlighted(
t,
' [1, " "] ',
'••[1,"••"]••',
'••[1, "••"]••',
);
assertHighlighted(
t,
Expand Down
28 changes: 19 additions & 9 deletions source/helpers/show-whitespace-on-line.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,36 @@ export default function showWhiteSpacesOnLine(line: Element, shouldAvoidSurround
continue;
}

const startingCharacter = shouldAvoidSurroundingSpaces && nodeIndex === 0 ? 1 : 0;
const skipLastCharacter = shouldAvoidSurroundingSpaces && nodeIndex === textNodesOnThisLine.length - 1;
const endingCharacter = text.length - 1 - Number(skipLastCharacter);
// This refers to the boundary text nodes, not actual whitespace nodes. Text nodes are generated by the syntax highlighter, so non-highlighted text will have one text node.
const isLeading = nodeIndex === 0;
const isTrailing = nodeIndex === textNodesOnThisLine.length - 1;

const startingCharacterIndex = shouldAvoidSurroundingSpaces && isLeading ? 1 : 0;
const skipLastCharacter = shouldAvoidSurroundingSpaces && isTrailing;
const endingCharacterIndex = text.length - 1 - Number(skipLastCharacter);

// Loop goes in reverse otherwise `splitText`'s `index` parameter needs to keep track of the previous split
for (let i = endingCharacter; i >= startingCharacter; i--) {
for (let i = endingCharacterIndex; i >= startingCharacterIndex; i--) {
const thisCharacter = text[i];
const endingIndex = i;

// Exclude irrelevant characters
if (thisCharacter !== ' ' && thisCharacter !== '\t') {
continue;
}

if (i < text.length - 1) {
textNode.splitText(i + 1);
// Find the same character so they can be wrapped together, but stop at `startingCharacterIndex`
while (text[i - 1] === thisCharacter && !(i === startingCharacterIndex)) {
i--;
}

// Find the same character so they can be wrapped together, but stop at `startingCharacter`
while (text[i - 1] === thisCharacter && !(i === startingCharacter)) {
i--;
// Skip non-boundary single spaces
if (!isLeading && !isTrailing && i === endingIndex && thisCharacter === ' ') {
continue;
}

if (endingIndex < text.length - 1) {
textNode.splitText(endingIndex + 1);
}

textNode.splitText(i);
Expand Down