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

try to match at least 2 components of base scope with the map #2361

Merged
merged 10 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 16 additions & 79 deletions language-ids.sublime-settings
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
// -------------------------------------
//
// These are the "exceptional" base scopes. If a base scope is not in this
// map, then the rule is that we split the base scopes on the ".", and take
// the last element. The resuling string is assumed to be the language ID.
// map, nor the first two components or more match any of the entries here then
// the rule is that we split the base scope on the ".", and take
// the last element. The resulting string is assumed to be the language ID.
//
// Examples of this rule:
//
// source.julia -> julia
// source.rust -> rust
// text.tex.latex -> latex
// text.html.vue -> vue
//
// The official list is maintained at
// https://microsoft.github.io/language-server-protocol/specification#textDocumentItem
Expand All @@ -21,103 +21,40 @@
// request at github.com/sublimelsp/LSP if you believe an entry is missing.
{
"source.c++": "cpp",
"source.coffee.gulpfile": "coffeescript", // https://github.com/SublimeText/AFileIcon
"source.coffee": "coffeescript",
"source.cs": "csharp",
"source.css.tailwind": "css", // https://github.com/SublimeText/TailwindCSS
"source.css": "css",
"source.dosbatch": "bat",
"source.fixedform-fortran": "fortran", // https://packagecontrol.io/packages/Fortran
"source.groovy.gradle": "groovy", // https://github.com/SublimeText/AFileIcon
"source.groovy.jenkins": "groovy", // https://github.com/SublimeText/AFileIcon
"source.groovy": "groovy",
"source.js": "javascript",
"source.js.eslint": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.gruntfile": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.gulpfile": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.postcss": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.puglint": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.react": "javascriptreact", // https://github.com/Thom1729/Sublime-JS-Custom
predragnikolic marked this conversation as resolved.
Show resolved Hide resolved
"source.js.stylelint": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.unittest": "javascript", // https://github.com/SublimeText/AFileIcon
"source.js.webpack": "javascript", // https://github.com/SublimeText/AFileIcon
"source.json-tmlanguage": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.babel": "json", // https://github.com/SublimeText/AFileIcon
"source.json.bower": "json", // https://github.com/SublimeText/AFileIcon
"source.json.composer": "json", // https://github.com/SublimeText/AFileIcon
"source.json.eslint": "json", // https://github.com/SublimeText/AFileIcon
"source.json.npm": "json", // https://github.com/SublimeText/AFileIcon
"source.json.postcss": "json", // https://github.com/SublimeText/AFileIcon
"source.json.puglint": "json", // https://github.com/SublimeText/AFileIcon
"source.json.settings": "json", // https://github.com/SublimeText/AFileIcon
"source.json.stylelint": "json", // https://github.com/SublimeText/AFileIcon
"source.json": "json",
"source.json.sublime": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.build": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.color-scheme": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.commands": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.completions": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.keymap": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.macro": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.menu": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.mousemap": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.project": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.settings": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.sublime.theme": "jsonc", // https://github.com/SublimeText/PackageDev
"source.json.tern": "json", // https://github.com/SublimeText/AFileIcon
"source.jsx": "javascriptreact",
"source.jsx.unittest": "javascriptreact", // https://github.com/SublimeText/AFileIcon
"source.Kotlin": "kotlin", // https://github.com/vkostyukov/kotlin-sublime-package
"source.modern-fortran": "fortran", // https://packagecontrol.io/packages/Fortran
"source.objc": "objective-c",
"source.objc++": "objective-cpp",
"source.shader": "shaderlab", // https://github.com/waqiju/unity_shader_st3
"source.shell.bash": "shellscript",
"source.shell.docker": "shellscript", // https://github.com/SublimeText/AFileIcon
"source.shell.eslint": "shellscript", // https://github.com/SublimeText/AFileIcon
"source.shell.npm": "shellscript", // https://github.com/SublimeText/AFileIcon
"source.shell.ruby": "shellscript", // https://github.com/SublimeText/AFileIcon
"source.shell.stylelint": "shellscript", // https://github.com/SublimeText/AFileIcon
"source.shell": "shellscript",
"source.ts": "typescript",
"source.ts.react": "typescriptreact", // https://github.com/Thom1729/Sublime-JS-Custom
"source.ts.unittest": "typescript", // https://github.com/SublimeText/AFileIcon
"source.tsx": "typescriptreact",
"source.tsx.unittest": "typescriptreact", // https://github.com/SublimeText/AFileIcon
"source.unity.unity_shader": "shaderlab", // https://github.com/petereichinger/Unity3D-Shader
"source.viml.vimrc": "viml", // https://github.com/SublimeText/AFileIcon
"source.viml": "viml",
"source.yaml-tmlanguage": "yaml", // https://github.com/SublimeText/PackageDev
"source.yaml.circleci": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml.docker": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml.eslint": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml.lock": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml.procfile": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml.stylelint": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml.sublime.syntax": "yaml", // https://github.com/SublimeText/PackageDev
"source.yaml.yarn": "yaml", // https://github.com/SublimeText/AFileIcon
"source.yaml": "yaml",
"text.advanced_csv": "csv", // https://github.com/SublimeText/AFileIcon
"text.django": "html", // https://github.com/willstott101/django-sublime-syntax
"text.html.basic": "html",
"text.html.elixir": "html", // https://github.com/elixir-editors/elixir-tmbundle
"text.html.markdown.academicmarkdown": "markdown", // https://github.com/mangecoeur/AcademicMarkdown
"text.html.markdown.license": "markdown", // https://github.com/SublimeText/AFileIcon
"text.html": "html",
"text.html.handlebars": "handlebars",
"text.html.markdown": "markdown",
"text.html.markdown.rmarkdown": "r", // https://github.com/REditorSupport/sublime-ide-r
"text.html.ngx": "html", // https://github.com/princemaple/ngx-html-syntax
"text.html.vue": "vue",
jwortmann marked this conversation as resolved.
Show resolved Hide resolved
"text.jinja": "html", // https://github.com/Sublime-Instincts/BetterJinja
"text.plain": "plaintext",
"text.plain.buildpacks": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.eslint": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.fastq": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.license": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.lnk": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.log": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.nodejs": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.pcb": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.ps": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.python": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.readme": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.ruby": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.sketch": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plain.visualstudio": "plaintext", // https://github.com/SublimeText/AFileIcon
"text.plist": "xml", // https://bitbucket.org/fschwehn/sublime_plist
"text.xml.plist": "xml", // https://github.com/SublimeText/PackageDev
"text.xml.plist.textmate.preferences": "xml", // https://github.com/SublimeText/PackageDev
"text.xml.sublime.snippet": "xml", // https://github.com/SublimeText/PackageDev
"text.xml.svg": "xml", // https://github.com/SublimeText/AFileIcon
"text.xml.visualstudio": "xml", // https://github.com/SublimeText/AFileIcon
"text.xml": "xml",
"text.xml.xsl": "xsl",
}
12 changes: 11 additions & 1 deletion plugin/core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,17 @@
def basescope2languageid(base_scope: str) -> str:
# This the connection between Language IDs and ST selectors.
base_scope_map = sublime.load_settings("language-ids.sublime-settings")
result = base_scope_map.get(base_scope, base_scope.split(".")[-1])
result = ""
# Try to find exact match or less specific match consisting of at least 2 components.
scope_parts = base_scope.split('.')
while len(scope_parts) >= 2:
result = base_scope_map.get('.'.join(scope_parts))
if result:
break
scope_parts.pop()
if not result:
# If no match use last compoent of the scope as the language ID.
rchl marked this conversation as resolved.
Show resolved Hide resolved
result = base_scope.split(".")[-1]
return result if isinstance(result, str) else ""


Expand Down
104 changes: 104 additions & 0 deletions tests/test_types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from LSP.plugin.core.types import diff
from LSP.plugin.core.types import basescope2languageid
from LSP.plugin.core.types import DocumentSelector
from LSP.plugin.core.typing import List
from unittest.mock import MagicMock
Expand Down Expand Up @@ -145,3 +146,106 @@ def test_pattern_negated_character_range(self) -> None:
self.assertFalse(selector.matches(self._make_html_view("example.7")))
self.assertFalse(selector.matches(self._make_html_view("example.8")))
self.assertFalse(selector.matches(self._make_html_view("example.9")))

def test_basescope2languageid(self) -> None:
self.assertEqual(basescope2languageid("source.js.vite"), "javascript")
self.assertEqual(basescope2languageid("source.c++"), "cpp")
self.assertEqual(basescope2languageid("source.coffee.gulpfile"), "coffeescript")
self.assertEqual(basescope2languageid("source.cs"), "csharp")
self.assertEqual(basescope2languageid("source.css.tailwind"), "css")
self.assertEqual(basescope2languageid("source.dosbatch"), "bat")
self.assertEqual(basescope2languageid("source.fixedform-fortran"), "fortran")
self.assertEqual(basescope2languageid("source.groovy.gradle"), "groovy")
self.assertEqual(basescope2languageid("source.groovy.jenkins"), "groovy")
self.assertEqual(basescope2languageid("source.js"), "javascript")
self.assertEqual(basescope2languageid("source.js.eslint"), "javascript")
self.assertEqual(basescope2languageid("source.js.gruntfile"), "javascript")
self.assertEqual(basescope2languageid("source.js.gulpfile"), "javascript")
self.assertEqual(basescope2languageid("source.js.postcss"), "javascript")
self.assertEqual(basescope2languageid("source.js.puglint"), "javascript")
self.assertEqual(basescope2languageid("source.js.react"), "javascriptreact")
self.assertEqual(basescope2languageid("source.js.stylelint"), "javascript")
self.assertEqual(basescope2languageid("sourcet.js.unittest"), "javascript")
self.assertEqual(basescope2languageid("source.js.webpack"), "javascript")
self.assertEqual(basescope2languageid("source.json-tmlanguage"), "jsonc")
self.assertEqual(basescope2languageid("source.json.babel"), "json")
self.assertEqual(basescope2languageid("source.json.bower"), "json")
self.assertEqual(basescope2languageid("source.json.composer"), "json")
self.assertEqual(basescope2languageid("source.json.eslint"), "json")
self.assertEqual(basescope2languageid("source.json.npm"), "json")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having all those tests might be missing the point a bit. If we want to test that the function does proper matching then we should only need to test "unique" inputs from the point of the function. And should then likely mock the map so that it's clear from the test point of view what are all the inputs.

Unless we are testing the mappings and not the function itself which looks more like what we are doing here. But that doesn't do much for unittesting the code itself and it won't really help to catch the cases we don't account for now.

In any case, we can keep it but we can rewrite those with a lot less duplicated code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wrote the test to test the mapping to guarantee that we don't miss some things.

But a agree that we can remove it, before we merge.

self.assertEqual(basescope2languageid("source.json.postcss"), "json")
self.assertEqual(basescope2languageid("source.json.puglint"), "json")
self.assertEqual(basescope2languageid("source.json.settings"), "json")
self.assertEqual(basescope2languageid("source.json.stylelint"), "json")
self.assertEqual(basescope2languageid("source.json.sublime"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.build"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.color-scheme"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.commands"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.completions"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.keymap"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.macro"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.menu"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.mousemap"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.project"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.settings"), "jsonc")
self.assertEqual(basescope2languageid("source.json.sublime.theme"), "jsonc")
self.assertEqual(basescope2languageid("source.json.tern"), "json")
self.assertEqual(basescope2languageid("source.jsx"), "javascriptreact")
self.assertEqual(basescope2languageid("source.jsx.unittest"), "javascriptreact")
self.assertEqual(basescope2languageid("source.Kotlin"), "kotlin")
self.assertEqual(basescope2languageid("source.modern-fortran"), "fortran")
self.assertEqual(basescope2languageid("source.objc"), "objective-c")
self.assertEqual(basescope2languageid("source.objc++"), "objective-cpp")
self.assertEqual(basescope2languageid("source.shader"), "shaderlab")
self.assertEqual(basescope2languageid("source.shell.bash"), "shellscript")
self.assertEqual(basescope2languageid("source.shell.docker"), "shellscript")
self.assertEqual(basescope2languageid("source.shell.eslint"), "shellscript")
self.assertEqual(basescope2languageid("source.shell.npm"), "shellscript")
self.assertEqual(basescope2languageid("source.shell.ruby"), "shellscript")
self.assertEqual(basescope2languageid("source.shell.stylelint"), "shellscript")
self.assertEqual(basescope2languageid("source.ts"), "typescript")
self.assertEqual(basescope2languageid("source.ts.react"), "typescriptreact")
self.assertEqual(basescope2languageid("source.ts.unittest"), "typescript")
self.assertEqual(basescope2languageid("source.tsx"), "typescriptreact")
self.assertEqual(basescope2languageid("source.tsx.unittest"), "typescriptreact")
self.assertEqual(basescope2languageid("source.unity.unity_shader"), "shaderlab")
self.assertEqual(basescope2languageid("source.viml.vimrc"), "viml")
self.assertEqual(basescope2languageid("source.yaml-tmlanguage"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.circleci"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.docker"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.eslint"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.lock"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.procfile"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.stylelint"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.sublime.syntax"), "yaml")
self.assertEqual(basescope2languageid("source.yaml.yarn"), "yaml")
self.assertEqual(basescope2languageid("text.advanced_csv"), "csv")
self.assertEqual(basescope2languageid("text.django"), "html")
self.assertEqual(basescope2languageid("text.html.basic"), "html")
self.assertEqual(basescope2languageid("text.html.elixir"), "html")
self.assertEqual(basescope2languageid("text.html.markdown.academicmarkdown"), "markdown")
self.assertEqual(basescope2languageid("text.html.markdown.license"), "markdown")
self.assertEqual(basescope2languageid("text.html.markdown.rmarkdown"), "r")
self.assertEqual(basescope2languageid("text.html.ngx"), "html")
self.assertEqual(basescope2languageid("text.jinja"), "html")
self.assertEqual(basescope2languageid("text.plain"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.buildpacks"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.eslint"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.fastq"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.license"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.lnk"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.log"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.nodejs"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.pcb"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.ps"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.python"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.readme"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.ruby"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.sketch"), "plaintext")
self.assertEqual(basescope2languageid("text.plain.visualstudio"), "plaintext")
self.assertEqual(basescope2languageid("text.plist"), "xml")
self.assertEqual(basescope2languageid("text.xml.plist"), "xml")
self.assertEqual(basescope2languageid("text.xml.plist.textmate.preferences"), "xml")
self.assertEqual(basescope2languageid("text.xml.sublime.snippet"), "xml")
self.assertEqual(basescope2languageid("text.xml.svg"), "xml")
self.assertEqual(basescope2languageid("text.xml.visualstudio"), "xml")
Loading