diff --git a/CHANGES.md b/CHANGES.md index f724dac486..7bebecb027 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ Core Grammars: - fix(rust) recognize `\\` and `\"` char-literal escapes so highlighting doesn't leak, issue #4351 [Sarath Francis][] - fix(cmake) only highlight standalone numbers, not digits that begin an identifier (e.g. `3rdparty`), issue #4170 [MarkXian][] - fix(cpp) require a word boundary before numeric literals so digits inside identifiers aren't highlighted as numbers, issue #4231 [Mark Xian][] +- fix(csharp) support digit separators in binary literals and numeric type suffixes, and stop highlighting the leading `_` of an identifier, issue #4258 [Sarath Francis][] Documentation: diff --git a/src/languages/csharp.js b/src/languages/csharp.js index 5201903356..2af7ede983 100644 --- a/src/languages/csharp.js +++ b/src/languages/csharp.js @@ -161,12 +161,18 @@ export default function(hljs) { literal: LITERAL_KEYWORDS }; const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { begin: '[a-zA-Z](\\.?\\w)*' }); + // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types + // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types + // `_` separators sit between digits, and may also follow the `0x`/`0b` prefix + const DIGITS = '\\d(_*\\d)*'; + const INTEGER_SUFFIX = '([uU][lL]?|[lL][uU]?)?'; + const REAL_SUFFIX = '([fFdDmM]|[uU][lL]?|[lL][uU]?)?'; const NUMBERS = { className: 'number', variants: [ - { begin: '\\b(0b[01\']+)' }, - { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B)' }, - { begin: '(-?)(\\b0[xX][a-fA-F0-9\'_]+|(\\b[\\d\'_]+(\\.[\\d\'_]*)?|\\.[\\d\'_]+)([eE][-+]?[\\d\'_]+)?)' } + { begin: '\\b0[bB]_*[01](_*[01])*' + INTEGER_SUFFIX }, + { begin: '(-?)\\b0[xX]_*[a-fA-F0-9](_*[a-fA-F0-9])*' + INTEGER_SUFFIX }, + { begin: '(-?)(\\b' + DIGITS + '(\\.(' + DIGITS + ')?)?|\\.' + DIGITS + ')([eE][-+]?' + DIGITS + ')?' + REAL_SUFFIX } ], relevance: 0 }; diff --git a/test/markup/csharp/numbers.expect.txt b/test/markup/csharp/numbers.expect.txt new file mode 100644 index 0000000000..c9f5a67a0c --- /dev/null +++ b/test/markup/csharp/numbers.expect.txt @@ -0,0 +1,10 @@ +int bin = 0b1010_1010; +int binSeparatorFirst = 0b_1010_1010; +ulong hex = 0xFF_FFUL; +uint hexSuffix = 0xFFu; +ulong decSuffix = 1_000_000UL; +decimal price = 19.99m; +double ratio = 3.14d; +decimal big = 1.5e10M; +int _count = 0; +int index = point._1; diff --git a/test/markup/csharp/numbers.txt b/test/markup/csharp/numbers.txt new file mode 100644 index 0000000000..c1da6780a6 --- /dev/null +++ b/test/markup/csharp/numbers.txt @@ -0,0 +1,10 @@ +int bin = 0b1010_1010; +int binSeparatorFirst = 0b_1010_1010; +ulong hex = 0xFF_FFUL; +uint hexSuffix = 0xFFu; +ulong decSuffix = 1_000_000UL; +decimal price = 19.99m; +double ratio = 3.14d; +decimal big = 1.5e10M; +int _count = 0; +int index = point._1;