Skip to content

Commit 76ab07a

Browse files
authored
Don't merge consecutive equal tokens if the line contains RTL (#257)
1 parent 5a7d9e3 commit 76ab07a

4 files changed

Lines changed: 26 additions & 5 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vscode-textmate",
3-
"version": "9.2.0",
3+
"version": "9.2.1",
44
"description": "VSCode TextMate grammar helpers",
55
"author": {
66
"name": "Microsoft Corporation"

src/grammar/grammar.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { disposeOnigString, IOnigLib, OnigScanner, OnigString } from '../onigLib
1010
import { IRawGrammar, IRawRepository, IRawRule } from '../rawGrammar';
1111
import { ruleIdFromNumber, IRuleFactoryHelper, IRuleRegistry, Rule, RuleFactory, RuleId, ruleIdToNumber } from '../rule';
1212
import { FontStyle, ScopeName, ScopePath, ScopeStack, StyleAttributes } from '../theme';
13-
import { clone } from '../utils';
13+
import { clone, containsRTL } from '../utils';
1414
import { BasicScopeAttributes, BasicScopeAttributesProvider } from './basicScopesAttributeProvider';
1515
import { _tokenizeString } from './tokenizeString';
1616

@@ -960,6 +960,7 @@ export class LineTokens {
960960
private _lastTokenEndIndex: number;
961961

962962
private readonly _tokenTypeOverrides: TokenTypeMatcher[];
963+
private readonly _mergeConsecutiveTokensWithEqualMetadata: boolean;
963964

964965
constructor(
965966
emitBinaryTokens: boolean,
@@ -974,6 +975,8 @@ export class LineTokens {
974975
} else {
975976
this._lineText = null;
976977
}
978+
// Don't merge tokens if the line contains RTL characters
979+
this._mergeConsecutiveTokensWithEqualMetadata = !containsRTL(lineText);
977980
this._tokens = [];
978981
this._binaryTokens = [];
979982
this._lastTokenEndIndex = 0;
@@ -1031,7 +1034,7 @@ export class LineTokens {
10311034
);
10321035
}
10331036

1034-
if (this._binaryTokens.length > 0 && this._binaryTokens[this._binaryTokens.length - 1] === metadata) {
1037+
if (this._mergeConsecutiveTokensWithEqualMetadata && this._binaryTokens.length > 0 && this._binaryTokens[this._binaryTokens.length - 1] === metadata) {
10351038
// no need to push a token with the same metadata
10361039
this._lastTokenEndIndex = endIndex;
10371040
return;

src/utils.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,22 @@ export const performanceNow =
184184
}
185185
: function () {
186186
return performance!.now();
187-
};
187+
};
188+
189+
let CONTAINS_RTL: RegExp | undefined = undefined;
190+
191+
function makeContainsRtl() {
192+
// Generated using https://github.com/alexdima/unicode-utils/blob/main/rtl-test.js
193+
return /(?:[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05F4\u0608\u060B\u060D\u061B-\u064A\u066D-\u066F\u0671-\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u0710\u0712-\u072F\u074D-\u07A5\u07B1-\u07EA\u07F4\u07F5\u07FA\u07FE-\u0815\u081A\u0824\u0828\u0830-\u0858\u085E-\u088E\u08A0-\u08C9\u200F\uFB1D\uFB1F-\uFB28\uFB2A-\uFD3D\uFD50-\uFDC7\uFDF0-\uFDFC\uFE70-\uFEFC]|\uD802[\uDC00-\uDD1B\uDD20-\uDE00\uDE10-\uDE35\uDE40-\uDEE4\uDEEB-\uDF35\uDF40-\uDFFF]|\uD803[\uDC00-\uDD23\uDE80-\uDEA9\uDEAD-\uDF45\uDF51-\uDF81\uDF86-\uDFF6]|\uD83A[\uDC00-\uDCCF\uDD00-\uDD43\uDD4B-\uDFFF]|\uD83B[\uDC00-\uDEBB])/;
194+
}
195+
196+
/**
197+
* Returns true if `str` contains any Unicode character that is classified as "R" or "AL".
198+
*/
199+
export function containsRTL(str: string): boolean {
200+
if (!CONTAINS_RTL) {
201+
CONTAINS_RTL = makeContainsRtl();
202+
}
203+
204+
return CONTAINS_RTL.test(str);
205+
}

0 commit comments

Comments
 (0)