|
1 | 1 | from __future__ import annotations |
| 2 | +from importlib import import_module |
| 3 | + |
| 4 | +from textual import log |
| 5 | + |
2 | 6 |
|
3 | 7 | try: |
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 | 8 | from tree_sitter import Language |
20 | 9 |
|
21 | | - _tree_sitter = True |
| 10 | + _LANGUAGE_CACHE: dict[str, Language] = {} |
22 | 11 |
|
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 | | - } |
| 12 | + _tree_sitter = True |
40 | 13 |
|
41 | 14 | def get_language(language_name: str) -> Language | None: |
42 | | - return _languages.get(language_name) |
| 15 | + if language_name in _LANGUAGE_CACHE: |
| 16 | + return _LANGUAGE_CACHE[language_name] |
| 17 | + |
| 18 | + try: |
| 19 | + module = import_module(f"tree_sitter_{language_name}") |
| 20 | + except ImportError: |
| 21 | + return None |
| 22 | + else: |
| 23 | + try: |
| 24 | + if language_name == "xml": |
| 25 | + # xml uses language_xml() instead of language() |
| 26 | + # it's the only outlier amongst the languages in the `textual[syntax]` extra |
| 27 | + language = Language(module.language_xml(), name=language_name) |
| 28 | + else: |
| 29 | + language = Language(module.language(), name=language_name) |
| 30 | + except (OSError, AttributeError): |
| 31 | + log.warning(f"Could not load language {language_name!r}.") |
| 32 | + return None |
| 33 | + else: |
| 34 | + _LANGUAGE_CACHE[language_name] = language |
| 35 | + return language |
43 | 36 |
|
44 | 37 | except ImportError: |
45 | 38 | _tree_sitter = False |
46 | | - _languages = {} |
| 39 | + |
| 40 | + def get_language(language_name: str) -> Language | None: |
| 41 | + return None |
| 42 | + |
47 | 43 |
|
48 | 44 | TREE_SITTER = _tree_sitter |
49 | | -BUILTIN_LANGUAGES: dict[str, "Language"] = _languages |
0 commit comments