diff --git a/Package/PackageDev.sublime-settings b/Package/PackageDev.sublime-settings index 1081dbab..82af9b5e 100644 --- a/Package/PackageDev.sublime-settings +++ b/Package/PackageDev.sublime-settings @@ -30,6 +30,13 @@ // settings file for this to take effect. "settings.show_quick_edit_icon": true, + // List of patterns for syntax not to be displayed in completions. + // Each theme containing one of the list's strings is hidden. + "settings.exclude_syntax_patterns": [ + "*.tmLanguage", + "Packages/zzz A File Icon zzz/**" + ], + // Whether or not to keep the scope suffix in the suggested test scopes // i.e. if the base scope is text.html.markdown // then suggest meta.example.markdown (true) vs meta.example (false). diff --git a/Package/Sublime Text Syntax Definition/Sublime Text Syntax Definition.sublime-syntax b/Package/Sublime Text Syntax Definition/Sublime Text Syntax Definition.sublime-syntax index c3d2f54e..8e168458 100644 --- a/Package/Sublime Text Syntax Definition/Sublime Text Syntax Definition.sublime-syntax +++ b/Package/Sublime Text Syntax Definition/Sublime Text Syntax Definition.sublime-syntax @@ -133,6 +133,7 @@ contexts: captures: 1: string.unquoted.plain.out.yaml storage.type.extends.sublime-syntax 2: punctuation.separator.key-value.yaml + push: expect_extends_list - match: ((?:hidden_)?file_extensions)\s*(:)(?=\s|$) captures: @@ -162,6 +163,52 @@ contexts: - include: scope:source.yaml + expect_extends_list: + - meta_content_scope: meta.extends.sublime-syntax + - include: comment + - include: yaml-tags-anchors + # array-like context list + - match: \[ + scope: punctuation.definition.array.begin.sublime-syntax + set: + - meta_scope: meta.extends.sublime-syntax meta.flow-sequence.yaml + - match: \] + scope: punctuation.definition.array.end.sublime-syntax + pop: true + - match: ',' + scope: punctuation.separator.array-element.sublime-syntax + - match: '{{plain_scalar_but_not_block_key}}' + push: extended_syntax_file + - include: comment + - include: yaml-tags-anchors + # multi-line context list + - match: ^([ ]+)(?=-\s*{{plain_scalar_but_not_block_key}}) + set: + - meta_scope: meta.extends.sublime-syntax meta.block-sequence.yaml + # pop off at none-empty line with different indention than first item + - match: ^(?!(\s*$|\1-)) + pop: true + - match: '{{plain_scalar_but_not_block_key}}' + push: extended_syntax_file + - include: comment + - include: yaml-block-sequence + - match: \S.*$ + scope: invalid.illegal.extends.sublime-syntax + # maybe single include + - match: '{{plain_scalar_but_not_block_key}}' + set: + - meta_scope: meta.extends.sublime-syntax meta.path.sublime-syntax string.unquoted.plain.out.yaml + - include: extended_syntax_file + - match: ^(?=\s*$) + pop: 1 + + extended_syntax_file: + - meta_scope: meta.path.sublime-syntax string.unquoted.plain.out.yaml + - match: '{{_flow_scalar_end_plain_in}}' + pop: true + - match: / + scope: punctuation.separator.path.sublime-syntax + variables_block: - meta_scope: meta.block.variables.sublime-syntax - include: comment diff --git a/Package/Sublime Text Syntax Definition/syntax_test_sublime-syntax.yaml b/Package/Sublime Text Syntax Definition/syntax_test_sublime-syntax.yaml index bb8e2e11..1e6a2d04 100644 --- a/Package/Sublime Text Syntax Definition/syntax_test_sublime-syntax.yaml +++ b/Package/Sublime Text Syntax Definition/syntax_test_sublime-syntax.yaml @@ -13,7 +13,26 @@ version: 2 extends: Packages/Default/Text.sublime-syntax #^^^^^^ string.unquoted.plain.out.yaml storage.type.extends.sublime-syntax # ^ punctuation.separator.key-value.yaml -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.unquoted.plain.out.yaml +# ^ meta.extends - meta.path +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.extends.sublime-syntax meta.path.sublime-syntax string.unquoted.plain.out.yaml +# ^ punctuation.separator.path.sublime-syntax +# ^ punctuation.separator.path.sublime-syntax +# ^ - meta.extends - meta.path +extends: [ Text.sublime-syntax , Source.sublime-syntax ] +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.extends.sublime-syntax meta.flow-sequence.yaml +# ^ - meta.path +# ^^^^^^^^^^^^^^^^^^^ meta.path.sublime-syntax string.unquoted.plain.out.yaml +# ^^^ - meta.path +# ^^^^^^^^^^^^^^^^^^^^^ meta.path.sublime-syntax string.unquoted.plain.out.yaml +# ^^ - meta.path +extends: + - Packages/Default/Text.sublime-syntax +# <- meta.extends.sublime-syntax meta.block-sequence.yaml +#^^^ meta.extends.sublime-syntax meta.block-sequence.yaml +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.extends.sublime-syntax meta.block-sequence.yaml meta.path.sublime-syntax string.unquoted.plain.out.yaml +# ^ punctuation.separator.path.sublime-syntax +# ^ punctuation.separator.path.sublime-syntax +# ^ meta.extends.sublime-syntax meta.block-sequence.yaml - meta.path file_extensions: [a, b] #^^^^^^^^^^^^^^ string.unquoted.plain.out.yaml entity.name.tag.yaml # ^^^^^^ meta.flow-sequence.yaml, meta.sequence.flow.yaml diff --git a/plugins/syntax_dev/completions.py b/plugins/syntax_dev/completions.py index cd79d53b..3a928b5b 100644 --- a/plugins/syntax_dev/completions.py +++ b/plugins/syntax_dev/completions.py @@ -1,6 +1,8 @@ import logging import re from collections import namedtuple +from fnmatch import fnmatch +from sublime_lib.resource_path import ResourcePath import sublime import sublime_plugin @@ -266,6 +268,12 @@ def match_selector(selector, offset=0): ): result = self._complete_branch_point() + elif match_selector( + "meta.extends", + -1, + ): + result = self._complete_syntax_file() + # Auto-completion for variables in match patterns using 'variables' keys elif match_selector("keyword.other.variable"): result = self._complete_variable() @@ -299,6 +307,45 @@ def _complete_context(self, prefix, locations): kind=TPL_CONTEXT.kind, ) + def _complete_syntax_file(self): + completions = [] + kind = (sublime.KIND_ID_VARIABLE, 's', 'Syntax') + + settings = sublime.load_settings("PackageDev.sublime-settings") + excludes = settings.get("settings.exclude_syntax_patterns", []) + if not isinstance(excludes, list): + excludes = [] + + try: + my_folder = str(ResourcePath.from_file_path(self.view.file_name()).parent) + except (TypeError, ValueError): + my_folder = "" + + for syntax in sublime.list_syntaxes(): + if any(fnmatch(syntax.path, pattern) for pattern in excludes): + continue + # add relative resource path completion (file name of siblings) + if my_folder: + folder, file = syntax.path.rsplit("/", 1) + if folder == my_folder: + completions.append( + sublime.CompletionItem( + trigger=file, + kind=kind, + annotation="hidden" if syntax.hidden else "" + ) + ) + # add full resource path + completions.append( + sublime.CompletionItem( + trigger=syntax.path, + kind=kind, + annotation="hidden" if syntax.hidden else "" + ) + ) + + return completions + def _complete_keyword(self, prefix, locations): def match_selector(selector, offset=0):