Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement idea: use sublime.find_resources to pick up recommended AutoSetSyntax rules from other packages #21

Open
keith-hall opened this issue Oct 30, 2024 · 8 comments

Comments

@keith-hall
Copy link
Contributor

Hi,

Thanks for this really useful plugin. Sometimes I am developing syntax definition packages, and update my local User AutoSetSyntax.sublime-settings user_syntax_rules (and I plan to contribute those here as default_syntax_rules when time permits). But I had the idea, how cool it would be if AutoSetSyntax would automatically pick up "recommended" syntax rules from other packages (i.e. by using sublime.find_resources for specifically named files), and inject them between the default_syntax_rules and user_syntax_rules. So users can still override the behavior even on a project basis. The advantage would be:

It would be easier to manage my packages because I would be able to see what rules it ships with, rather than having to go to the AutoSetSyntax package's settings and manually look for what rules apply for my packages...

Hopefully with all the debugging tools AutoSetSyntax supplies, it wouldn't make maintenance harder for you if a package ships rules which confuse users...

@jfcherng
Copy link
Member

jfcherng commented Oct 30, 2024

It would be easier to manage my packages because I would be able to see what rules it ships with, rather than having to go to the AutoSetSyntax package's settings and manually look for what rules apply for my packages...

Would the output panel of this plugin help?
image

✔ Change View(48, "C:/Users/jfcherng/Desktop/Jenkinsfile_aaa") syntax from "Plain Text" to "Jenkinsfile" because {'event': "<ListenerEvent.LOAD('load')>", 'reason': 'plugin rule', 'rule': SyntaxRule(comment='', syntax=Syntax('Packages/User/my_language/Jenkinsfile.sublime-syntax', 'Jenkinsfile', False, 'source.groovy.jenkinsfile'), syntaxes_name=('Jenkinsfile', 'scope:source.groovy'), selector='text.plain', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.name_contains_regex.NameContainsRegexConstraint object>", constraint_name='name_contains_regex', args=('^Jenkinsfile(?=\\b|_)',), kwargs={}, inverted=False),))), 'syntax': Syntax('Packages/User/my_language/Jenkinsfile.sublime-syntax', 'Jenkinsfile', False, 'source.groovy.jenkinsfile')}

Not too readable though.

@jfcherng
Copy link
Member

how cool it would be if AutoSetSyntax would automatically pick up "recommended" syntax rules from other packages

That sounds like a standard has to be made for this. And I wonder how many syntax maintainers will join the party...

@keith-hall
Copy link
Contributor Author

Would the output panel of this plugin help?

A little. Still not the same as having all the rules that relate to a package inside that package. That's one thing I don't like about Package Control for example, is that the "ST build range to package tag mapping" is done inside package control channel repository, instead of it being self contained.

That sounds like a standard has to be made for this.

Definitely :)

And I wonder how many syntax maintainers will join the party...

Good question. I have the idea that somehow advertising could help - for example I've seen a few plugins implemented as part of syntax packages just to set the syntax when a file is opened if the file path contains a certain folder name etc. That would be a perfect use case for delegating to AutoSetSyntax instead of maintaining plugin code. Some maintainers may be reluctant to delegate to another package, but IMHO AutoSetSyntax is as essential as PackageDev... Especially as core ST is too limiting. I plan to update some of my packages which are guilty of this to recommend installing AutoSetSyntax instead.

@jfcherng
Copy link
Member

jfcherng commented Nov 2, 2024

I have added a Syntax Rules Summary command, which shows

# === [AutoSetSyntax] Syntax Rules Summary === #
# You may use the following website to beautify this debug information.
# @link https://play.ruff.rs/?secondary=Format

########################
# Syntax Rules Summary #
########################

# Syntax: Apache Conf
SyntaxRule(comment='Apache config', syntax=Syntax('Packages/User/my_language/ApacheConf/ApacheConf.sublime-syntax', 'Apache Conf', False, 'source.apacheconf'), syntaxes_name=('scope:source.apacheconf',), selector='text.plain | source.nginx', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.path_contains_regex.PathContainsRegexConstraint object>", constraint_name='path_contains_regex', args=('\\b(?i:apache|httpd)(?:\\b|_).*/conf/.*\\.conf$',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('<(?:VirtualHost|Directory|Macro)(?:$|\\s)',), kwargs={}, inverted=False))))

# Syntax: Bash
SyntaxRule(comment='', syntax=Syntax('Packages/ShellScript/Bash.sublime-syntax', 'Bash', False, 'source.shell.bash'), syntaxes_name=('scope:source.shell.bash',), selector='text.plain', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.is_name.IsNameConstraint object>", constraint_name='is_name', args=('profile', '.bash_history'), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.name_contains_regex.NameContainsRegexConstraint object>", constraint_name='name_contains_regex', args=('\\.(?:bash|z(?:shrc|shenv|profile|login|logout))(?:\\.[^/]*)?$',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.first_line_contains_regex.FirstLineContainsRegexConstraint object>", constraint_name='first_line_contains_regex', args=('^\\s*#\\s+shellcheck\\s+shell=(?:bash|sh|zsh)',), kwargs={}, inverted=False))))
SyntaxRule(comment='Linux .env files', syntax=Syntax('Packages/ShellScript/Bash.sublime-syntax', 'Bash', False, 'source.shell.bash'), syntaxes_name=('/DotENV.', 'scope:source.shell.bash'), selector='', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.all.AllMatch object>", match_name='all', args=(), kwargs={}, rules=(MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.selector_matches.SelectorMatchesConstraint object>", constraint_name='selector_matches', args=('text.plain',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.is_hidden_syntax.IsHiddenSyntaxConstraint object>", constraint_name='is_hidden_syntax', args=(), kwargs={}, inverted=False))), MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.is_name.IsNameConstraint object>", constraint_name='is_name', args=('.envrc',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.name_contains_regex.NameContainsRegexConstraint object>", constraint_name='name_contains_regex', args=('\\.(?:env)(?:\\.[^/]*)?$',), kwargs={}, inverted=False))))))

# Syntax: C#
SyntaxRule(comment='', syntax=Syntax('Packages/C#/C#.sublime-syntax', 'C#', False, 'source.cs'), syntaxes_name=('scope:source.cs',), selector='text.plain', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.all.AllMatch object>", match_name='all', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^using\\s',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^namespace\\s',), kwargs={}, inverted=False))))

# Syntax: C++
SyntaxRule(comment='', syntax=Syntax('Packages/C++/C++.sublime-syntax', 'C++', False, 'source.c++'), syntaxes_name=('scope:source.c++',), selector='text.plain', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('(?:^|\\s)#include\\s*[<"]', '(?:^|\\s)#pragma\\s+(?:once|pack|(?:pop|push)_macro|warning)(?=$|\\s)', '(?:^|\\s)template\\s*<\\s*(?:class|typename)(?=$|\\s)', '\\b(?:const(?:eval|expr|init)|decltype|nullptr|(?:const|dynamic|reinterpret|static)_cast)(?=$|\\s)'), kwargs={}, inverted=False),)))

# Syntax: Diff
SyntaxRule(comment='', syntax=Syntax('Packages/Diff/Diff.sublime-syntax', 'Diff', False, 'source.diff'), syntaxes_name=('scope:source.diff',), selector='text.plain', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(MatchRule(match="<AutoSetSyntax.plugin.rules.matches.all.AllMatch object>", match_name='all', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^\\+{3} ',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^-{3} ',), kwargs={}, inverted=False))), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^@@ -\\d+,\\d+ \\+\\d+,\\d+ @@',), kwargs={}, inverted=False))))

# Syntax: Git Config
SyntaxRule(comment='', syntax=Syntax('Packages/Git Formats/Git Config.sublime-syntax', 'Git Config', False, 'text.git.config'), syntaxes_name=('scope:text.git.config',), selector='- text.git.config', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.any.AnyMatch object>", match_name='any', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.path_contains_regex.PathContainsRegexConstraint object>", constraint_name='path_contains_regex', args=('/\\.?git/config$',), kwargs={}, inverted=False),)))

# Syntax: Go
SyntaxRule(comment='', syntax=Syntax('Packages/Go/Go.sublime-syntax', 'Go', False, 'source.go'), syntaxes_name=('scope:source.go',), selector='text.plain', on_events=None, root_rule=MatchRule(match="<AutoSetSyntax.plugin.rules.matches.all.AllMatch object>", match_name='all', args=(), kwargs={}, rules=(ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^(?:package)\\s',), kwargs={}, inverted=False), ConstraintRule(constraint="<AutoSetSyntax.plugin.rules.constraints.contains_regex.ContainsRegexConstraint object>", constraint_name='contains_regex', args=('^(?:import|func|type)\\s',), kwargs={}, inverted=False))))

...

@keith-hall
Copy link
Contributor Author

Thanks, looks useful! Have you considered using pprint.pp instead of repr in utils.stringify to avoid the need for manual reformatting for readibility?

@jfcherng
Copy link
Member

jfcherng commented Nov 3, 2024

Thanks, looks useful! Have you considered using pprint.pp instead of repr in utils.stringify to avoid the need for manual reformatting for readibility?

Not much helpful. You will still have something like ConstraintRule(constraint=<AutoSetSyntax.plugin.rules.constraints.is_name.IsNameConstraint object at 0x000001FC567AE1C0>, .... And I don't get any indented output somehow.

I would rather define .to_dict() method for objects and dump their JSON format. Or, probably just introduce pydantic, which also provides data validation.

@jfcherng
Copy link
Member

jfcherng commented Nov 3, 2024

Or, probably just introduce pydantic, which also provides data validation.

I have a working example in the refactor/pydantic branch. Merged into master.

@jfcherng
Copy link
Member

jfcherng commented Nov 4, 2024

Or, probably just introduce pydantic, which also provides data validation.

I have a working example in the refactor/pydantic branch.

One small issue. I don't want LSP-json to work on that generated view :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants