Skip to content

Commit

Permalink
Improve syntax file parsing
Browse files Browse the repository at this point in the history
Fixes #1028

For a lot of files `yaml.safe_load` fails if the lib does not support
the used yaml format.  It is also very slow to parse all syntax files.

Since we only use relatively simple information here, t.i. a single
key, we just run a regex and extract the useful information.
  • Loading branch information
kaste committed Jun 20, 2020
1 parent f269334 commit ff19f30
Showing 1 changed file with 39 additions and 16 deletions.
55 changes: 39 additions & 16 deletions common/util/file.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,74 @@
import sublime
from collections import defaultdict
from contextlib import contextmanager
import os
import re
import threading
import yaml
import os
from contextlib import contextmanager

import sublime


MYPY = False
if MYPY:
from typing import Dict, List
from typing import DefaultDict, List, Optional


if 'syntax_file_map' not in globals():
syntax_file_map = {} # type: Dict[str, List[str]]
syntax_file_map = defaultdict(list) # type: DefaultDict[str, List[str]]

if 'determine_syntax_thread' not in globals():
determine_syntax_thread = None


def determine_syntax_files():
# type: () -> None
global determine_syntax_thread
if not syntax_file_map:
determine_syntax_thread = threading.Thread(
target=_determine_syntax_files)
determine_syntax_thread.start()


def try_parse_for_file_extensions(text):
# type: (str) -> Optional[List[str]]
match = re.search(r"^file_extensions:\n((.*\n)+?)^(?=\w)", text, re.M)
if match:
return _try_yaml_parse(match.group(0))
return _try_yaml_parse(text)


def _try_yaml_parse(text):
# type: (str) -> Optional[List[str]]
try:
return yaml.safe_load(text)["file_extensions"]
except Exception:
return None


def _determine_syntax_files():
# type: () -> None
syntax_files = sublime.find_resources("*.sublime-syntax")
for syntax_file in syntax_files:
try:
# Use `sublime.load_resource`, in case Package is `*.sublime-package`.
resource = sublime.load_resource(syntax_file)
for extension in yaml.safe_load(resource)["file_extensions"]:
if extension not in syntax_file_map:
syntax_file_map[extension] = []
extension_list = syntax_file_map[extension]
extension_list.append(syntax_file)
except Exception:
print("GitSavvy: could not load {}".format(syntax_file))
continue

for extension in try_parse_for_file_extensions(resource) or []:
syntax_file_map[extension].append(syntax_file)


def get_syntax_for_file(filename):
def get_syntax_for_file(filename, default="Packages/Text/Plain text.tmLanguage"):
# type: (str, str) -> str
if not determine_syntax_thread or determine_syntax_thread.is_alive():
return "Packages/Text/Plain text.tmLanguage"
extension = get_file_extension(filename)
syntaxes = syntax_file_map.get(filename, None) or syntax_file_map.get(extension, None)
return syntaxes[-1] if syntaxes else "Packages/Text/Plain text.tmLanguage"
return default
syntaxes = (
syntax_file_map.get(filename, [])
or syntax_file_map.get(get_file_extension(filename), [])
or [default]
)
return syntaxes[-1]


def get_file_extension(filename):
Expand Down

0 comments on commit ff19f30

Please sign in to comment.