prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Use case-insensitive Regexps for matching syntaxes
  ### Suggestion:
  
  When using `settings.get('syntax')` to filter configurations, it's needed such configurations to match exactly. Many times there are more than one single package for any given syntax (and oftentimes there are packages that haven't been updated in some time and for which syntax files have moved or extension definition changed from `tmLanguage` to `sublime-syntax`). This can lead in the need to configure server languages "guessing" what syntax files are configured for it.
  
  Real-world examples of such:
  
  **Markdown**:
  1. `Packages/Markdown/Markdown.sublime-syntax`
  2. `Packages/Markdown Extended/Syntaxes/Markdown Extended.sublime-syntax`
  3. `Packages/Markdown Extended/Syntaxes/Markdown Extended.tmLanguage`
  
  **SCSS**:
  1. `Packages/Sass/Syntaxes/SCSS.sublime-syntax`
  2. `Packages/SCSS/SCSS.tmLanguage`
  
  **JSON**:
  1. `Packages/JavaScript/JSON.sublime-syntax`
  2. `Packages/Babel/JSON (Babel).sublime-syntax`
  3. `Packages/PackageDev/Package/Sublime Text Settings/Sublime Text Settings.sublime-syntax`
  
  It could very well be better to have a set of case insensitive regexps to match the language from the syntax (after all scopes are later used to confirm). That way we could have, accordingly, the following syntaxes that would do a `re.search()`.
  
  ```json
    "syntaxes": [
      "Markdown"
    ]
  ```
  
  ```json
    "syntaxes": [
      "SCSS"
    ]
  ```
  
  ```json
    "syntaxes": [
      "JSON",
      "Sublime Text Settings"
    ]
  ```
  
  _Alternatively_, we could add `languages` as the list of regexps that match, keeping `syntaxes` for exact matches and using `languages` as fallbacks to figure out the language configuration.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `plugin/core/configurations.py`
  Content:
  ```
  1 import sublime
  2 
  3 from .settings import ClientConfig, client_configs
  4 from .logging import debug
  5 from .workspace import get_project_config
  6 
  7 assert ClientConfig
  8 
  9 try:
  10     from typing import Any, List, Dict, Tuple, Callable, Optional
  11     assert Any and List and Dict and Tuple and Callable and Optional
  12 except ImportError:
  13     pass
  14 
  15 
  16 window_client_configs = dict()  # type: Dict[int, List[ClientConfig]]
  17 
  18 
  19 def get_scope_client_config(view: 'sublime.View', configs: 'List[ClientConfig]') -> 'Optional[ClientConfig]':
  20     for config in configs:
  21         for scope in config.scopes:
  22             if len(view.sel()) > 0:
  23                 if view.match_selector(view.sel()[0].begin(), scope):
  24                     return config
  25 
  26     return None
  27 
  28 
  29 def register_client_config(config: ClientConfig) -> None:
  30     window_client_configs.clear()
  31     client_configs.add_external_config(config)
  32 
  33 
  34 def get_global_client_config(view: sublime.View) -> 'Optional[ClientConfig]':
  35     return get_scope_client_config(view, client_configs.all)
  36 
  37 
  38 def get_default_client_config(view: sublime.View) -> 'Optional[ClientConfig]':
  39     return get_scope_client_config(view, client_configs.defaults)
  40 
  41 
  42 def get_window_client_config(view: sublime.View) -> 'Optional[ClientConfig]':
  43     window = view.window()
  44     if window:
  45         configs_for_window = window_client_configs.get(window.id(), [])
  46         return get_scope_client_config(view, configs_for_window)
  47     else:
  48         return None
  49 
  50 
  51 def config_for_scope(view: sublime.View) -> 'Optional[ClientConfig]':
  52     # check window_client_config first
  53     window_client_config = get_window_client_config(view)
  54     if not window_client_config:
  55         global_client_config = get_global_client_config(view)
  56 
  57         if global_client_config:
  58             window = view.window()
  59             if window:
  60                 window_client_config = apply_window_settings(global_client_config, view)
  61                 add_window_client_config(window, window_client_config)
  62                 return window_client_config
  63             else:
  64                 # always return a client config even if the view has no window anymore
  65                 return global_client_config
  66 
  67     return window_client_config
  68 
  69 
  70 def add_window_client_config(window: 'sublime.Window', config: 'ClientConfig'):
  71     global window_client_configs
  72     window_client_configs.setdefault(window.id(), []).append(config)
  73 
  74 
  75 def clear_window_client_configs(window: 'sublime.Window'):
  76     global window_client_configs
  77     if window.id() in window_client_configs:
  78         del window_client_configs[window.id()]
  79 
  80 
  81 def apply_window_settings(client_config: 'ClientConfig', view: 'sublime.View') -> 'ClientConfig':
  82     window = view.window()
  83     if window:
  84         window_config = get_project_config(window)
  85 
  86         if client_config.name in window_config:
  87             overrides = window_config[client_config.name]
  88             debug('window has override for', client_config.name, overrides)
  89             return ClientConfig(
  90                 client_config.name,
  91                 overrides.get("command", client_config.binary_args),
  92                 overrides.get("tcp_port", client_config.tcp_port),
  93                 overrides.get("scopes", client_config.scopes),
  94                 overrides.get("syntaxes", client_config.syntaxes),
  95                 overrides.get("languageId", client_config.languageId),
  96                 overrides.get("enabled", client_config.enabled),
  97                 overrides.get("initializationOptions", client_config.init_options),
  98                 overrides.get("settings", client_config.settings),
  99                 overrides.get("env", client_config.env)
  100             )
  101 
  102     return client_config
  103 
  104 
  105 def is_supportable_syntax(syntax: str) -> bool:
  106     # TODO: filter out configs disabled by the user.
  107     for config in client_configs.defaults:
  108         if syntax in config.syntaxes:
  109             return True
  110     return False
  111 
  112 
  113 def is_supported_syntax(syntax: str) -> bool:
  114     for config in client_configs.all:
  115         if syntax in config.syntaxes:
  116             return True
  117     return False
  118 
  119 
  120 def is_supported_view(view: sublime.View) -> bool:
  121     # TODO: perhaps make this check for a client instead of a config
  122     if config_for_scope(view):
  123         return True
  124     else:
  125         return False
  126
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/plugin/core/configurations.py b/plugin/core/configurations.py
  --- a/plugin/core/configurations.py
  +++ b/plugin/core/configurations.py
  @@ -1,3 +1,4 @@
  +import re
   import sublime
   
   from .settings import ClientConfig, client_configs
  @@ -105,14 +106,14 @@
   def is_supportable_syntax(syntax: str) -> bool:
       # TODO: filter out configs disabled by the user.
       for config in client_configs.defaults:
  -        if syntax in config.syntaxes:
  +        if re.search(r'|'.join(r'\b%s\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):
               return True
       return False
   
   
   def is_supported_syntax(syntax: str) -> bool:
       for config in client_configs.all:
  -        if syntax in config.syntaxes:
  +        if re.search(r'|'.join(r'\b%s\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):
               return True
       return False
  
verification_info: {"golden_diff": "diff --git a/plugin/core/configurations.py b/plugin/core/configurations.py\n--- a/plugin/core/configurations.py\n+++ b/plugin/core/configurations.py\n@@ -1,3 +1,4 @@\n+import re\n import sublime\n \n from .settings import ClientConfig, client_configs\n@@ -105,14 +106,14 @@\n def is_supportable_syntax(syntax: str) -> bool:\n     # TODO: filter out configs disabled by the user.\n     for config in client_configs.defaults:\n-        if syntax in config.syntaxes:\n+        if re.search(r'|'.join(r'\\b%s\\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):\n             return True\n     return False\n \n \n def is_supported_syntax(syntax: str) -> bool:\n     for config in client_configs.all:\n-        if syntax in config.syntaxes:\n+        if re.search(r'|'.join(r'\\b%s\\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):\n             return True\n     return False\n", "issue": "Use case-insensitive Regexps for matching syntaxes\n### Suggestion:\r\n\r\nWhen using `settings.get('syntax')` to filter configurations, it's needed such configurations to match exactly. Many times there are more than one single package for any given syntax (and oftentimes there are packages that haven't been updated in some time and for which syntax files have moved or extension definition changed from `tmLanguage` to `sublime-syntax`). This can lead in the need to configure server languages \"guessing\" what syntax files are configured for it.\r\n\r\nReal-world examples of such:\r\n\r\n**Markdown**:\r\n1. `Packages/Markdown/Markdown.sublime-syntax`\r\n2. `Packages/Markdown Extended/Syntaxes/Markdown Extended.sublime-syntax`\r\n3. `Packages/Markdown Extended/Syntaxes/Markdown Extended.tmLanguage`\r\n\r\n**SCSS**:\r\n1. `Packages/Sass/Syntaxes/SCSS.sublime-syntax`\r\n2. `Packages/SCSS/SCSS.tmLanguage`\r\n\r\n**JSON**:\r\n1. `Packages/JavaScript/JSON.sublime-syntax`\r\n2. `Packages/Babel/JSON (Babel).sublime-syntax`\r\n3. `Packages/PackageDev/Package/Sublime Text Settings/Sublime Text Settings.sublime-syntax`\r\n\r\nIt could very well be better to have a set of case insensitive regexps to match the language from the syntax (after all scopes are later used to confirm). That way we could have, accordingly, the following syntaxes that would do a `re.search()`.\r\n\r\n```json\r\n  \"syntaxes\": [\r\n    \"Markdown\"\r\n  ]\r\n```\r\n\r\n```json\r\n  \"syntaxes\": [\r\n    \"SCSS\"\r\n  ]\r\n```\r\n\r\n```json\r\n  \"syntaxes\": [\r\n    \"JSON\",\r\n    \"Sublime Text Settings\"\r\n  ]\r\n```\r\n\r\n_Alternatively_, we could add `languages` as the list of regexps that match, keeping `syntaxes` for exact matches and using `languages` as fallbacks to figure out the language configuration.\n", "before_files": [{"content": "import sublime\n\nfrom .settings import ClientConfig, client_configs\nfrom .logging import debug\nfrom .workspace import get_project_config\n\nassert ClientConfig\n\ntry:\n    from typing import Any, List, Dict, Tuple, Callable, Optional\n    assert Any and List and Dict and Tuple and Callable and Optional\nexcept ImportError:\n    pass\n\n\nwindow_client_configs = dict()  # type: Dict[int, List[ClientConfig]]\n\n\ndef get_scope_client_config(view: 'sublime.View', configs: 'List[ClientConfig]') -> 'Optional[ClientConfig]':\n    for config in configs:\n        for scope in config.scopes:\n            if len(view.sel()) > 0:\n                if view.match_selector(view.sel()[0].begin(), scope):\n                    return config\n\n    return None\n\n\ndef register_client_config(config: ClientConfig) -> None:\n    window_client_configs.clear()\n    client_configs.add_external_config(config)\n\n\ndef get_global_client_config(view: sublime.View) -> 'Optional[ClientConfig]':\n    return get_scope_client_config(view, client_configs.all)\n\n\ndef get_default_client_config(view: sublime.View) -> 'Optional[ClientConfig]':\n    return get_scope_client_config(view, client_configs.defaults)\n\n\ndef get_window_client_config(view: sublime.View) -> 'Optional[ClientConfig]':\n    window = view.window()\n    if window:\n        configs_for_window = window_client_configs.get(window.id(), [])\n        return get_scope_client_config(view, configs_for_window)\n    else:\n        return None\n\n\ndef config_for_scope(view: sublime.View) -> 'Optional[ClientConfig]':\n    # check window_client_config first\n    window_client_config = get_window_client_config(view)\n    if not window_client_config:\n        global_client_config = get_global_client_config(view)\n\n        if global_client_config:\n            window = view.window()\n            if window:\n                window_client_config = apply_window_settings(global_client_config, view)\n                add_window_client_config(window, window_client_config)\n                return window_client_config\n            else:\n                # always return a client config even if the view has no window anymore\n                return global_client_config\n\n    return window_client_config\n\n\ndef add_window_client_config(window: 'sublime.Window', config: 'ClientConfig'):\n    global window_client_configs\n    window_client_configs.setdefault(window.id(), []).append(config)\n\n\ndef clear_window_client_configs(window: 'sublime.Window'):\n    global window_client_configs\n    if window.id() in window_client_configs:\n        del window_client_configs[window.id()]\n\n\ndef apply_window_settings(client_config: 'ClientConfig', view: 'sublime.View') -> 'ClientConfig':\n    window = view.window()\n    if window:\n        window_config = get_project_config(window)\n\n        if client_config.name in window_config:\n            overrides = window_config[client_config.name]\n            debug('window has override for', client_config.name, overrides)\n            return ClientConfig(\n                client_config.name,\n                overrides.get(\"command\", client_config.binary_args),\n                overrides.get(\"tcp_port\", client_config.tcp_port),\n                overrides.get(\"scopes\", client_config.scopes),\n                overrides.get(\"syntaxes\", client_config.syntaxes),\n                overrides.get(\"languageId\", client_config.languageId),\n                overrides.get(\"enabled\", client_config.enabled),\n                overrides.get(\"initializationOptions\", client_config.init_options),\n                overrides.get(\"settings\", client_config.settings),\n                overrides.get(\"env\", client_config.env)\n            )\n\n    return client_config\n\n\ndef is_supportable_syntax(syntax: str) -> bool:\n    # TODO: filter out configs disabled by the user.\n    for config in client_configs.defaults:\n        if syntax in config.syntaxes:\n            return True\n    return False\n\n\ndef is_supported_syntax(syntax: str) -> bool:\n    for config in client_configs.all:\n        if syntax in config.syntaxes:\n            return True\n    return False\n\n\ndef is_supported_view(view: sublime.View) -> bool:\n    # TODO: perhaps make this check for a client instead of a config\n    if config_for_scope(view):\n        return True\n    else:\n        return False\n", "path": "plugin/core/configurations.py"}], "after_files": [{"content": "import re\nimport sublime\n\nfrom .settings import ClientConfig, client_configs\nfrom .logging import debug\nfrom .workspace import get_project_config\n\nassert ClientConfig\n\ntry:\n    from typing import Any, List, Dict, Tuple, Callable, Optional\n    assert Any and List and Dict and Tuple and Callable and Optional\nexcept ImportError:\n    pass\n\n\nwindow_client_configs = dict()  # type: Dict[int, List[ClientConfig]]\n\n\ndef get_scope_client_config(view: 'sublime.View', configs: 'List[ClientConfig]') -> 'Optional[ClientConfig]':\n    for config in configs:\n        for scope in config.scopes:\n            if len(view.sel()) > 0:\n                if view.match_selector(view.sel()[0].begin(), scope):\n                    return config\n\n    return None\n\n\ndef register_client_config(config: ClientConfig) -> None:\n    window_client_configs.clear()\n    client_configs.add_external_config(config)\n\n\ndef get_global_client_config(view: sublime.View) -> 'Optional[ClientConfig]':\n    return get_scope_client_config(view, client_configs.all)\n\n\ndef get_default_client_config(view: sublime.View) -> 'Optional[ClientConfig]':\n    return get_scope_client_config(view, client_configs.defaults)\n\n\ndef get_window_client_config(view: sublime.View) -> 'Optional[ClientConfig]':\n    window = view.window()\n    if window:\n        configs_for_window = window_client_configs.get(window.id(), [])\n        return get_scope_client_config(view, configs_for_window)\n    else:\n        return None\n\n\ndef config_for_scope(view: sublime.View) -> 'Optional[ClientConfig]':\n    # check window_client_config first\n    window_client_config = get_window_client_config(view)\n    if not window_client_config:\n        global_client_config = get_global_client_config(view)\n\n        if global_client_config:\n            window = view.window()\n            if window:\n                window_client_config = apply_window_settings(global_client_config, view)\n                add_window_client_config(window, window_client_config)\n                return window_client_config\n            else:\n                # always return a client config even if the view has no window anymore\n                return global_client_config\n\n    return window_client_config\n\n\ndef add_window_client_config(window: 'sublime.Window', config: 'ClientConfig'):\n    global window_client_configs\n    window_client_configs.setdefault(window.id(), []).append(config)\n\n\ndef clear_window_client_configs(window: 'sublime.Window'):\n    global window_client_configs\n    if window.id() in window_client_configs:\n        del window_client_configs[window.id()]\n\n\ndef apply_window_settings(client_config: 'ClientConfig', view: 'sublime.View') -> 'ClientConfig':\n    window = view.window()\n    if window:\n        window_config = get_project_config(window)\n\n        if client_config.name in window_config:\n            overrides = window_config[client_config.name]\n            debug('window has override for', client_config.name, overrides)\n            return ClientConfig(\n                client_config.name,\n                overrides.get(\"command\", client_config.binary_args),\n                overrides.get(\"tcp_port\", client_config.tcp_port),\n                overrides.get(\"scopes\", client_config.scopes),\n                overrides.get(\"syntaxes\", client_config.syntaxes),\n                overrides.get(\"languageId\", client_config.languageId),\n                overrides.get(\"enabled\", client_config.enabled),\n                overrides.get(\"initializationOptions\", client_config.init_options),\n                overrides.get(\"settings\", client_config.settings),\n                overrides.get(\"env\", client_config.env)\n            )\n\n    return client_config\n\n\ndef is_supportable_syntax(syntax: str) -> bool:\n    # TODO: filter out configs disabled by the user.\n    for config in client_configs.defaults:\n        if re.search(r'|'.join(r'\\b%s\\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):\n            return True\n    return False\n\n\ndef is_supported_syntax(syntax: str) -> bool:\n    for config in client_configs.all:\n        if re.search(r'|'.join(r'\\b%s\\b' % re.escape(s) for s in config.syntaxes), syntax, re.IGNORECASE):\n            return True\n    return False\n\n\ndef is_supported_view(view: sublime.View) -> bool:\n    # TODO: perhaps make this check for a client instead of a config\n    if config_for_scope(view):\n        return True\n    else:\n        return False\n", "path": "plugin/core/configurations.py"}]}