Skip to content

Commit ca496b4

Browse files
authored
tree-sitter upgrade (#5320)
* Using separate language packages and update lockfile * Fixing some but not all languages * Theme updates * More theme fixes * Improving the VS Code theme * Fixes * Fixing CSS rendering * Fixing SQL and JavaScript highlight queries * Update GitHub Actions to run syntax highlighting tests on 3.13, and avoid those tests on 3.8. * Update CHANGELOG and remove `SyntaxAwareDocument.language_name` property. * Remove unused Kotlin language syntax highlighting snapshot * Update CHANGELOG to note that Kotlin syntax highlighting was removed * Bail out of TextArea.language watcher early if tree-sitter is not installed * Skip a test on 3.8 as it relates to syntax highlighting (tree-sitter) being available
1 parent a1c34c1 commit ca496b4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3654
-3652
lines changed

.github/workflows/pythonpackage.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,18 @@ jobs:
3535
cache: "poetry"
3636
- name: Install dependencies
3737
run: poetry install --no-interaction --extras syntax
38-
if: ${{ matrix.python-version != '3.13' }}
39-
- name: Install dependencies for 3.13
38+
if: ${{ matrix.python-version != '3.8' }}
39+
- name: Install dependencies for 3.8
4040
run: poetry install --no-interaction
41-
if: ${{ matrix.python-version == '3.13' }}
42-
- name: Test with pytest
41+
if: ${{ matrix.python-version == '3.8' }}
42+
- name: Test with pytest (Py39+ - with syntax highlighting)
4343
run: |
4444
poetry run pytest tests -v --cov=./src/textual --cov-report=xml:./coverage.xml --cov-report term-missing
45-
if: ${{ matrix.python-version != '3.13' }}
46-
- name: Test with pytest for 3.13
45+
if: ${{ matrix.python-version != '3.8' }}
46+
- name: Test with pytest (Py38 - without syntax highlighting)
4747
run: |
4848
poetry run pytest tests -v --cov=./src/textual --cov-report=xml:./coverage.xml --cov-report term-missing -m 'not syntax'
49-
if: ${{ matrix.python-version == '3.13' }}
49+
if: ${{ matrix.python-version == '3.8' }}
5050
- name: Upload snapshot report
5151
if: always()
5252
uses: actions/upload-artifact@v3

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
## Added
1111

1212
- Added "tab" border style https://github.com/Textualize/textual/pull/5335
13+
- Added support for XML syntax highlighting https://github.com/Textualize/textual/pull/5320
14+
- Added `TextArea.update_highlight_query` https://github.com/Textualize/textual/pull/5320
15+
1316

1417
## Fixed
1518

1619
- Fixed Select not scrolling highlight in to view when clicked https://github.com/Textualize/textual/issues/5255
20+
- Upgraded tree-sitter to 0.23+ (`syntax` extras) https://github.com/Textualize/textual/pull/5320
21+
- Some syntax highlighting changes due to tree-sitter updates https://github.com/Textualize/textual/pull/5320
22+
- Breaking change: `Document.query_syntax_tree` signature changed https://github.com/Textualize/textual/pull/5320
23+
- Breaking change: `TextArea.register_language` signature changed https://github.com/Textualize/textual/pull/5320
24+
- Breaking change: `SyntaxAwareDocument.language_name` property removed https://github.com/Textualize/textual/pull/5320
25+
- Breaking change: Kotlin syntax highlighting removed from `TextArea` https://github.com/Textualize/textual/pull/5320
1726
- Fixed selection list wrapping https://github.com/Textualize/textual/pull/5331
1827
- Fixed CSS encoding issue on Windows https://github.com/Textualize/textual/pull/5324
1928

poetry.lock

Lines changed: 351 additions & 201 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,48 @@ markdown-it-py = { extras = ["plugins", "linkify"], version = ">=2.1.0" }
4646
rich = ">=13.3.3"
4747
#rich = {path="../rich", develop=true}
4848
typing-extensions = "^4.4.0"
49-
tree-sitter = { version = "^0.20.1", optional = true }
50-
tree-sitter-languages = { version = "1.10.2", optional = true }
5149
platformdirs = ">=3.6.0,<5"
5250

51+
# start of [syntax] extras
52+
# Require tree-sitter >= 0.23.0 and python >= 3.9
53+
# Windows, MacOS and Linux binary wheels are available for all of the languages below.
54+
tree-sitter = { version = ">=0.23.0", optional = true, python = ">=3.9" }
55+
tree-sitter-python = { version = ">=0.23.0", optional = true, python = ">=3.9" }
56+
tree-sitter-markdown = { version = ">=0.3.0", optional = true, python = ">=3.9"}
57+
tree-sitter-json = { version = ">=0.24.0", optional = true, python = ">=3.9" }
58+
tree-sitter-toml = { version = ">=0.6.0", optional = true, python = ">=3.9" }
59+
tree-sitter-yaml = { version = ">=0.6.0", optional = true, python = ">=3.9" }
60+
tree-sitter-html = { version = ">=0.23.0", optional = true, python = ">=3.9" }
61+
tree-sitter-css = { version = ">=0.23.0", optional = true, python = ">=3.9" }
62+
tree-sitter-javascript = { version = ">=0.23.0", optional = true, python = ">=3.9" }
63+
tree-sitter-rust = { version = ">=0.23.0", optional = true, python = ">=3.9" }
64+
tree-sitter-go = { version = ">=0.23.0", optional = true, python = ">=3.9" }
65+
tree-sitter-regex = { version = ">=0.24.0", optional = true, python = ">=3.9" }
66+
tree-sitter-xml = { version = ">=0.7.0", optional = true, python = ">=3.9" }
67+
tree-sitter-sql = { version = ">=0.3.0", optional = true, python = ">=3.9" }
68+
tree-sitter-java = { version = ">=0.23.0", optional = true, python = ">=3.9" }
69+
tree-sitter-bash = { version = ">=0.23.0", optional = true, python = ">=3.9" }
70+
# end of [syntax] extras
71+
5372
[tool.poetry.extras]
54-
syntax = ["tree-sitter", "tree_sitter_languages"]
73+
syntax = [
74+
"tree-sitter",
75+
"tree-sitter-python",
76+
"tree-sitter-markdown",
77+
"tree-sitter-json",
78+
"tree-sitter-toml",
79+
"tree-sitter-yaml",
80+
"tree-sitter-html",
81+
"tree-sitter-css",
82+
"tree-sitter-javascript",
83+
"tree-sitter-rust",
84+
"tree-sitter-go",
85+
"tree-sitter-regex",
86+
"tree-sitter-xml",
87+
"tree-sitter-sql",
88+
"tree-sitter-java",
89+
"tree-sitter-bash",
90+
]
5591

5692
[tool.poetry.group.dev.dependencies]
5793
black = "24.4.2"
@@ -72,8 +108,6 @@ pytest-asyncio = "*"
72108
pytest-cov = "^5.0.0"
73109
textual-dev = "^1.7.0"
74110
types-setuptools = "^67.2.0.1"
75-
types-tree-sitter = "^0.20.1.4"
76-
types-tree-sitter-languages = "^1.7.0.1"
77111
isort = "^5.13.2"
78112
pytest-textual-snapshot = "^1.0.0"
79113

src/textual/_text_area_theme.py

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def apply_css(self, text_area: TextArea) -> None:
148148
self.selection_style = selection_style
149149
else:
150150
selection_background_color = background_color.blend(
151-
app_theme.primary, factor=0.75
151+
app_theme.primary, factor=0.5
152152
)
153153
self.selection_style = Style.from_color(
154154
bgcolor=selection_background_color.rich_color
@@ -204,8 +204,9 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
204204
"string": Style(color="#E6DB74"),
205205
"string.documentation": Style(color="#E6DB74"),
206206
"comment": Style(color="#75715E"),
207+
"heading.marker": Style(color="#90908a"),
207208
"keyword": Style(color="#F92672"),
208-
"operator": Style(color="#F92672"),
209+
"operator": Style(color="#f8f8f2"),
209210
"repeat": Style(color="#F92672"),
210211
"exception": Style(color="#F92672"),
211212
"include": Style(color="#F92672"),
@@ -216,7 +217,10 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
216217
"number": Style(color="#AE81FF"),
217218
"float": Style(color="#AE81FF"),
218219
"class": Style(color="#A6E22E"),
220+
"type": Style(color="#A6E22E"),
219221
"type.class": Style(color="#A6E22E"),
222+
"type.builtin": Style(color="#F92672"),
223+
"variable.builtin": Style(color="#f8f8f2"),
220224
"function": Style(color="#A6E22E"),
221225
"function.call": Style(color="#A6E22E"),
222226
"method": Style(color="#A6E22E"),
@@ -232,12 +236,18 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
232236
"json.label": Style(color="#F92672", bold=True),
233237
"toml.type": Style(color="#F92672"),
234238
"toml.datetime": Style(color="#AE81FF"),
239+
"css.property": Style(color="#AE81FF"),
235240
"heading": Style(color="#F92672", bold=True),
236241
"bold": Style(bold=True),
237242
"italic": Style(italic=True),
238243
"strikethrough": Style(strike=True),
239-
"link": Style(color="#66D9EF", underline=True),
244+
"link.label": Style(color="#F92672"),
245+
"link.uri": Style(color="#66D9EF", underline=True),
246+
"list.marker": Style(color="#90908a"),
240247
"inline_code": Style(color="#E6DB74"),
248+
"punctuation.bracket": Style(color="#f8f8f2"),
249+
"punctuation.delimiter": Style(color="#f8f8f2"),
250+
"punctuation.special": Style(color="#f8f8f2"),
241251
},
242252
)
243253

@@ -254,8 +264,9 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
254264
"string": Style(color="#f1fa8c"),
255265
"string.documentation": Style(color="#f1fa8c"),
256266
"comment": Style(color="#6272a4"),
267+
"heading.marker": Style(color="#6272a4"),
257268
"keyword": Style(color="#ff79c6"),
258-
"operator": Style(color="#ff79c6"),
269+
"operator": Style(color="#f8f8f2"),
259270
"repeat": Style(color="#ff79c6"),
260271
"exception": Style(color="#ff79c6"),
261272
"include": Style(color="#ff79c6"),
@@ -266,12 +277,15 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
266277
"number": Style(color="#bd93f9"),
267278
"float": Style(color="#bd93f9"),
268279
"class": Style(color="#50fa7b"),
280+
"type": Style(color="#ff79c6"),
269281
"type.class": Style(color="#50fa7b"),
282+
"type.builtin": Style(color="#bd93f9"),
283+
"variable.builtin": Style(color="#f8f8f2"),
270284
"function": Style(color="#50fa7b"),
271285
"function.call": Style(color="#50fa7b"),
272286
"method": Style(color="#50fa7b"),
273287
"method.call": Style(color="#50fa7b"),
274-
"boolean": Style(color="#bd93f9"),
288+
"boolean": Style(color="#50fa7b"),
275289
"constant.builtin": Style(color="#bd93f9"),
276290
"json.null": Style(color="#bd93f9"),
277291
"regex.punctuation.bracket": Style(color="#ff79c6"),
@@ -282,12 +296,18 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
282296
"json.label": Style(color="#ff79c6", bold=True),
283297
"toml.type": Style(color="#ff79c6"),
284298
"toml.datetime": Style(color="#bd93f9"),
299+
"css.property": Style(color="#bd93f9"),
285300
"heading": Style(color="#ff79c6", bold=True),
286301
"bold": Style(bold=True),
287302
"italic": Style(italic=True),
288303
"strikethrough": Style(strike=True),
289-
"link": Style(color="#bd93f9", underline=True),
304+
"link.label": Style(color="#ff79c6"),
305+
"link.uri": Style(color="#bd93f9", underline=True),
306+
"list.marker": Style(color="#6272a4"),
290307
"inline_code": Style(color="#f1fa8c"),
308+
"punctuation.bracket": Style(color="#f8f8f2"),
309+
"punctuation.delimiter": Style(color="#f8f8f2"),
310+
"punctuation.special": Style(color="#f8f8f2"),
291311
},
292312
)
293313

@@ -304,8 +324,9 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
304324
"string": Style(color="#ce9178"),
305325
"string.documentation": Style(color="#ce9178"),
306326
"comment": Style(color="#6A9955"),
307-
"keyword": Style(color="#569cd6"),
308-
"operator": Style(color="#569cd6"),
327+
"heading.marker": Style(color="#6E7681"),
328+
"keyword": Style(color="#C586C0"),
329+
"operator": Style(color="#CCCCCC"),
309330
"conditional": Style(color="#569cd6"),
310331
"keyword.function": Style(color="#569cd6"),
311332
"keyword.return": Style(color="#569cd6"),
@@ -316,25 +337,35 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
316337
"number": Style(color="#b5cea8"),
317338
"float": Style(color="#b5cea8"),
318339
"class": Style(color="#4EC9B0"),
340+
"type": Style(color="#EFCB43"),
319341
"type.class": Style(color="#4EC9B0"),
320-
"function": Style(color="#4EC9B0"),
321-
"function.call": Style(color="#4EC9B0"),
342+
"type.builtin": Style(color="#9CDCFE"),
343+
"function": Style(color="#DCDCAA"),
344+
"function.call": Style(color="#DCDCAA"),
322345
"method": Style(color="#4EC9B0"),
323346
"method.call": Style(color="#4EC9B0"),
347+
"constructor": Style(color="#4EC9B0"),
324348
"boolean": Style(color="#7DAF9C"),
325349
"constant.builtin": Style(color="#7DAF9C"),
326350
"json.null": Style(color="#7DAF9C"),
327351
"tag": Style(color="#EFCB43"),
328352
"yaml.field": Style(color="#569cd6", bold=True),
329353
"json.label": Style(color="#569cd6", bold=True),
330354
"toml.type": Style(color="#569cd6"),
355+
"toml.datetime": Style(color="#C586C0", italic=True),
356+
"css.property": Style(color="#569cd6"),
331357
"heading": Style(color="#569cd6", bold=True),
332358
"bold": Style(bold=True),
333359
"italic": Style(italic=True),
334360
"strikethrough": Style(strike=True),
335-
"link": Style(color="#40A6FF", underline=True),
361+
"link.uri": Style(color="#40A6FF", underline=True),
362+
"link.label": Style(color="#569cd6"),
363+
"list.marker": Style(color="#6E7681"),
336364
"inline_code": Style(color="#ce9178"),
337365
"info_string": Style(color="#ce9178", bold=True, italic=True),
366+
"punctuation.bracket": Style(color="#CCCCCC"),
367+
"punctuation.delimiter": Style(color="#CCCCCC"),
368+
"punctuation.special": Style(color="#CCCCCC"),
338369
},
339370
)
340371

@@ -351,6 +382,10 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
351382
"string": Style(color="#093069"),
352383
"string.documentation": Style(color="#093069"),
353384
"comment": Style(color="#6a737d"),
385+
"heading.marker": Style(color="#A4A4A4"),
386+
"type": Style(color="#A4A4A4"),
387+
"type.class": Style(color="#A4A4A4"),
388+
"type.builtin": Style(color="#7DAF9C"),
354389
"keyword": Style(color="#d73a49"),
355390
"operator": Style(color="#0450AE"),
356391
"conditional": Style(color="#CF222E"),
@@ -373,12 +408,18 @@ def builtin_themes(cls) -> list[TextAreaTheme]:
373408
"yaml.field": Style(color="#6639BB"),
374409
"json.label": Style(color="#6639BB"),
375410
"toml.type": Style(color="#6639BB"),
411+
"css.property": Style(color="#6639BB"),
376412
"heading": Style(color="#24292e", bold=True),
377413
"bold": Style(bold=True),
378414
"italic": Style(italic=True),
379415
"strikethrough": Style(strike=True),
380-
"link": Style(color="#40A6FF", underline=True),
416+
"link.uri": Style(color="#40A6FF", underline=True),
417+
"link.label": Style(color="#6639BB"),
418+
"list.marker": Style(color="#A4A4A4"),
381419
"inline_code": Style(color="#093069"),
420+
"punctuation.bracket": Style(color="#24292e"),
421+
"punctuation.delimiter": Style(color="#24292e"),
422+
"punctuation.special": Style(color="#24292e"),
382423
},
383424
)
384425

src/textual/_tree_sitter.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,49 @@
11
from __future__ import annotations
22

33
try:
4-
from tree_sitter import Language, Parser, Tree
5-
from tree_sitter.binding import Query
6-
from tree_sitter_languages import get_language, get_parser
4+
import tree_sitter_bash
5+
import tree_sitter_css
6+
import tree_sitter_go
7+
import tree_sitter_html
8+
import tree_sitter_java
9+
import tree_sitter_javascript
10+
import tree_sitter_json
11+
import tree_sitter_markdown
12+
import tree_sitter_python
13+
import tree_sitter_regex
14+
import tree_sitter_rust
15+
import tree_sitter_sql
16+
import tree_sitter_toml
17+
import tree_sitter_xml
18+
import tree_sitter_yaml
19+
from tree_sitter import Language
20+
21+
_tree_sitter = True
22+
23+
_languages = {
24+
"python": Language(tree_sitter_python.language()),
25+
"json": Language(tree_sitter_json.language()),
26+
"markdown": Language(tree_sitter_markdown.language()),
27+
"yaml": Language(tree_sitter_yaml.language()),
28+
"toml": Language(tree_sitter_toml.language()),
29+
"rust": Language(tree_sitter_rust.language()),
30+
"html": Language(tree_sitter_html.language()),
31+
"css": Language(tree_sitter_css.language()),
32+
"xml": Language(tree_sitter_xml.language_xml()),
33+
"regex": Language(tree_sitter_regex.language()),
34+
"sql": Language(tree_sitter_sql.language()),
35+
"javascript": Language(tree_sitter_javascript.language()),
36+
"java": Language(tree_sitter_java.language()),
37+
"bash": Language(tree_sitter_bash.language()),
38+
"go": Language(tree_sitter_go.language()),
39+
}
40+
41+
def get_language(language_name: str) -> Language | None:
42+
return _languages.get(language_name)
743

8-
TREE_SITTER = True
944
except ImportError:
10-
TREE_SITTER = False
45+
_tree_sitter = False
46+
_languages = {}
47+
48+
TREE_SITTER = _tree_sitter
49+
BUILTIN_LANGUAGES: dict[str, "Language"] = _languages

src/textual/demo/widgets.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,6 @@ def compose(self) -> ComposeResult:
731731
"Java",
732732
"Javascript",
733733
"JSON",
734-
"Kotlin",
735734
"Markdown",
736735
"Python",
737736
"Rust",

0 commit comments

Comments
 (0)