Skip to content

Commit e36b2f1

Browse files
committed
Add dedicated TSX syntax highlighting
1 parent 245c589 commit e36b2f1

7 files changed

Lines changed: 91 additions & 6 deletions

File tree

anycode-base/src/code.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type { Lang } from './lang';
2525

2626
import javascript from './langs/javascript';
2727
import typescript from './langs/typescript';
28+
import tsx from './langs/tsx';
2829
import python from './langs/python';
2930
import rust from './langs/rust';
3031
import yaml from './langs/yaml';
@@ -642,6 +643,7 @@ export class Code {
642643
getLang(lang: string): Lang | null {
643644
if (lang === 'javascript') return javascript
644645
if (lang === 'typescript') return typescript
646+
if (lang === 'tsx') return tsx
645647
if (lang === 'rust') return rust
646648
if (lang === 'python') return python
647649
if (lang === 'yaml') return yaml

anycode-base/src/langs/tsx.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import type { Lang } from "../lang";
2+
import {
3+
cmd,
4+
cmdTest,
5+
executable,
6+
foldsQuery as typescriptFoldsQuery,
7+
query as typescriptQuery,
8+
} from "./typescript";
9+
10+
const jsxQuery = `
11+
; JSX elements
12+
13+
(jsx_opening_element
14+
(identifier) @tag)
15+
16+
(jsx_closing_element
17+
(identifier) @tag)
18+
19+
(jsx_self_closing_element
20+
(identifier) @tag)
21+
22+
[
23+
(jsx_opening_element (member_expression) @constructor)
24+
(jsx_closing_element (member_expression) @constructor)
25+
(jsx_self_closing_element (member_expression) @constructor)
26+
]
27+
28+
(jsx_attribute
29+
(property_identifier) @attribute)
30+
31+
[
32+
"<"
33+
">"
34+
"</"
35+
"/>"
36+
] @punctuation.bracket
37+
38+
(jsx_attribute
39+
"=" @operator)
40+
41+
(jsx_text) @string
42+
(html_character_reference) @string.special
43+
`;
44+
45+
const query = `${jsxQuery}\n${typescriptQuery}`;
46+
47+
const foldsQuery = `${typescriptFoldsQuery}
48+
[
49+
(jsx_element)
50+
(jsx_expression)
51+
] @fold
52+
`;
53+
54+
const indent = { width: 2, unit: " " };
55+
const comment = "//";
56+
57+
export default {
58+
query,
59+
foldsQuery,
60+
executable,
61+
cmd,
62+
cmdTest,
63+
indent,
64+
comment,
65+
} satisfies Lang;

anycode-base/src/langs/typescript.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Lang } from "../lang";
22

3-
const query = `
3+
export const query = `
44
; Special identifiers
55
;--------------------
66
@@ -464,7 +464,7 @@ let runnablesQuery = `
464464
)
465465
`
466466

467-
let foldsQuery = `
467+
export const foldsQuery = `
468468
[
469469
(statement_block)
470470
(class_body)
@@ -497,9 +497,9 @@ let foldsQuery = `
497497
] @fold
498498
`
499499

500-
let executable = true;
501-
let cmd = "node {file}"
502-
let cmdTest = "npx jest {file} -t \"{test-name}\""
500+
export const executable = true;
501+
export const cmd = "node {file}"
502+
export const cmdTest = "npx jest {file} -t \"{test-name}\""
503503

504504
export default {
505505
query, foldsQuery, runnablesQuery, executable, cmd, cmdTest, indent, comment

anycode-base/tests/code.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ function greet(name: string): void {
3737
expect(nodesLine2.some(n => n.name === 'type' && n.text === 'string')).toBe(true);
3838
expect(nodesLine2.some(n => n.name === 'type' && n.text === 'void')).toBe(true);
3939
});
40+
41+
it('should parse and highlight TSX elements separately from TypeScript', async () => {
42+
const tsxCode = `type Props = { title: string };
43+
export function Card({ title }: Props) {
44+
return <section className="card"><Header title={title} /></section>;
45+
}
46+
`;
47+
const code = new Code(tsxCode, 'Card.tsx', 'tsx');
48+
await code.init();
49+
50+
const jsxLine = code.getLineNodes(2);
51+
expect(code.language).toBe('tsx');
52+
expect(jsxLine.some(n => n.name === 'tag' && n.text === 'section')).toBe(true);
53+
expect(jsxLine.some(n => n.name === 'tag' && n.text === 'Header')).toBe(true);
54+
expect(jsxLine.some(n => n.name === 'attribute' && n.text === 'className')).toBe(true);
55+
expect(jsxLine.some(n => n.name === 'attribute' && n.text === 'title')).toBe(true);
56+
expect(jsxLine.some(n => n.name === 'string' && n.text === '"card"')).toBe(true);
57+
});
4058
});
4159

4260
describe('Python Parsing', () => {
1.38 MB
Binary file not shown.
1.38 MB
Binary file not shown.

anycode/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const LANGUAGE_EXTENSIONS: { [key: string]: string } = {
2727
'js': 'javascript',
2828
'ts': 'typescript',
2929
'jsx': 'javascript',
30-
'tsx': 'typescript',
30+
'tsx': 'tsx',
3131
'py': 'python',
3232
'cpp': 'cpp',
3333
'c': 'c',

0 commit comments

Comments
 (0)