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

Improvements to the base pygls.Client #340

Merged
merged 7 commits into from
Jun 12, 2023

Conversation

alcarney
Copy link
Collaborator

@alcarney alcarney commented Jun 10, 2023

Description (e.g. "Related to ...", etc.)

This makes some improvements to... port pytest-lsp to use the new autogenerated LanguageClient

TODO:

  • Fix issue with parsing large responses (see comment)
  • Add tests!

pygls.Client

This copies the feature decorator from pygls.LanguageServer,
allowing clients to implement handlers for messages coming from a server
e.g.

client = LanguageClient(...)

@client.feature('window/logMessage')
def handler(ls, params: LogMessageParams):
    logger.info("%s", params.message)

The client now also watches to see if the server process exits and shuts
itself down accordingly. Subclasses of pygls.Client can implement a
server_exit method if they want to take action when that happens.

On a similar note, the _report_server_error method has also been
ported so a client can implement report_server_error if they want to
do something when a server sends malformed JSON for example.

pygls.LanguageClient

To help prevent against hangs due to the server process exiting.
This updates the autogenerated client to make sure the self.stopped
is False before sending anything.

Code review checklist (for code reviewer to complete)

  • Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR)
  • Title summarizes what is changing
  • Commit messages are meaningful (see this for details)
  • Tests have been included and/or updated, as appropriate
  • Docstrings have been included and/or updated, as appropriate
  • [/] Standalone docs have been updated accordingly
  • [/] CONTRIBUTORS.md was updated, as appropriate
  • Changelog has been updated, as needed (see CHANGELOG.md)

@alcarney
Copy link
Collaborator Author

alcarney commented Jun 10, 2023

Edit: Turns out the issue was a lot simpler than I initially thought. stdout.read(n) does not guarantee that you will get n bytes back, instead you will get at most n bytes back. stdout.readexactly(n) on the other does give you exactly n (unless EOF is reached of course).


This makes some improvements to... almost port pytest-lsp to use the new autogenerated LanguageClient

I say "almost port" since despite the fact I have the testsuite for pytest-lsp itself passing, I have an issue where the testsuite for esbonio now hangs while trying to parse a particularly large response (Content-Length: 194758) from the server...

DEBUG    pygls.protocol:protocol.py:518 Received b'Content-Length: 194758\r\nContent-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n{"id": "e84c0bec-1546-48cf-be9f-04d2f65ee1fb", "jsonrpc": "2.0", "result": {"isIncomplete": false, "items": [{"label": "abap", "kind": 21, "documentation": {"kind": "markdown", "value": "### ABAP\\n\\nFilenames:  *.abap, *.ABAP\\n\\nMIME Types: text/x-abap\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "amdgpu", "kind": 21, "documentation": {"kind": "markdown", "value": "### AMDGPU\\n\\nFilenames:  *.isa\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "apl", "kind": 21, "documentation": {"kind": "markdown", "value": "### APL\\n\\nFilenames:  *.apl, *.aplf, *.aplo, *.apln, *.aplc, *.apli, *.dyalog\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "abnf", "kind": 21, "documentation": {"kind": "markdown", "value": "### ABNF\\n\\nFilenames:  *.abnf\\n\\nMIME Types: text/x-abnf\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "actionscript3", "kind": 21, "documentation": {"kind": "markdown", "value": "### ActionScript 3\\n\\nFilenames:  *.as\\n\\nMIME Types: application/x-actionscript3, text/x-actionscript3, text/actionscript3\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "as3", "kind": 21, "documentation": {"kind": "markdown", "value": "### ActionScript 3\\n\\nFilenames:  *.as\\n\\nMIME Types: application/x-actionscript3, text/x-actionscript3, text/actionscript3\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "actionscript", "kind": 21, "documentation": {"kind": "markdown", "value": "### ActionScript\\n\\nFilenames:  *.as\\n\\nMIME Types: application/x-actionscript, text/x-actionscript, text/actionscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "as", "kind": 21, "documentation": {"kind": "markdown", "value": "### ActionScript\\n\\nFilenames:  *.as\\n\\nMIME Types: application/x-actionscript, text/x-actionscript, text/actionscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ada", "kind": 21, "documentation": {"kind": "markdown", "value": "### Ada\\n\\nFilenames:  *.adb, *.ads, *.ada\\n\\nMIME Types: text/x-ada\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ada95", "kind": 21, "documentation": {"kind": "markdown", "value": "### Ada\\n\\nFilenames:  *.adb, *.ads, *.ada\\n\\nMIME Types: text/x-ada\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ada2005", "kind": 21, "documentation": {"kind": "markdown", "value": "### Ada\\n\\nFilenames:  *.adb, *.ads, *.ada\\n\\nMIME Types: text/x-ada\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "adl", "kind": 21, "documentation": {"kind": "markdown", "value": "### ADL\\n\\nFilenames:  *.adl, *.adls, *.adlf, *.adlx\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "agda", "kind": 21, "documentation": {"kind": "markdown", "value": "### Agda\\n\\nFilenames:  *.agda\\n\\nMIME Types: text/x-agda\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "aheui", "kind": 21, "documentation": {"kind": "markdown", "value": "### Aheui\\n\\nFilenames:  *.aheui\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "alloy", "kind": 21, "documentation": {"kind": "markdown", "value": "### Alloy\\n\\nFilenames:  *.als\\n\\nMIME Types: text/x-alloy\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ambienttalk", "kind": 21, "documentation": {"kind": "markdown", "value": "### AmbientTalk\\n\\nFilenames:  *.at\\n\\nMIME Types: text/x-ambienttalk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ambienttalk/2", "kind": 21, "documentation": {"kind": "markdown", "value": "### AmbientTalk\\n\\nFilenames:  *.at\\n\\nMIME Types: text/x-ambienttalk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "at", "kind": 21, "documentation": {"kind": "markdown", "value": "### AmbientTalk\\n\\nFilenames:  *.at\\n\\nMIME Types: text/x-ambienttalk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ampl", "kind": 21, "documentation": {"kind": "markdown", "value": "### Ampl\\n\\nFilenames:  *.run\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "html+ng2", "kind": 21, "documentation": {"kind": "markdown", "value": "### HTML + Angular2\\n\\nFilenames:  *.ng2\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ng2", "kind": 21, "documentation": {"kind": "markdown", "value": "### Angular2\\n\\nFilenames:  \\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-actionscript", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With ActionScript Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-as", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With ActionScript Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-csharp", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With C# Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-c#", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With C# Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-cpp", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With CPP Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-java", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With Java Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR\\n\\nFilenames:  \\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-objc", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With ObjectiveC Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-perl", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With Perl Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-python", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With Python Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-ruby", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With Ruby Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "antlr-rb", "kind": 21, "documentation": {"kind": "markdown", "value": "### ANTLR With Ruby Target\\n\\nFilenames:  *.G, *.g\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "apacheconf", "kind": 21, "documentation": {"kind": "markdown", "value": "### ApacheConf\\n\\nFilenames:  .htaccess, apache.conf, apache2.conf\\n\\nMIME Types: text/x-apacheconf\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "aconf", "kind": 21, "documentation": {"kind": "markdown", "value": "### ApacheConf\\n\\nFilenames:  .htaccess, apache.conf, apache2.conf\\n\\nMIME Types: text/x-apacheconf\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "apache", "kind": 21, "documentation": {"kind": "markdown", "value": "### ApacheConf\\n\\nFilenames:  .htaccess, apache.conf, apache2.conf\\n\\nMIME Types: text/x-apacheconf\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "applescript", "kind": 21, "documentation": {"kind": "markdown", "value": "### AppleScript\\n\\nFilenames:  *.applescript\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "arduino", "kind": 21, "documentation": {"kind": "markdown", "value": "### Arduino\\n\\nFilenames:  *.ino\\n\\nMIME Types: text/x-arduino\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "arrow", "kind": 21, "documentation": {"kind": "markdown", "value": "### Arrow\\n\\nFilenames:  *.arw\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "arturo", "kind": 21, "documentation": {"kind": "markdown", "value": "### Arturo\\n\\nFilenames:  *.art\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "art", "kind": 21, "documentation": {"kind": "markdown", "value": "### Arturo\\n\\nFilenames:  *.art\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "asc", "kind": 21, "documentation": {"kind": "markdown", "value": "### ASCII armored\\n\\nFilenames:  *.asc, *.pem, id_dsa, id_ecdsa, id_ecdsa_sk, id_ed25519, id_ed25519_sk, id_rsa\\n\\nMIME Types: application/pgp-keys, application/pgp-encrypted, application/pgp-signature\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "pem", "kind": 21, "documentation": {"kind": "markdown", "value": "### ASCII armored\\n\\nFilenames:  *.asc, *.pem, id_dsa, id_ecdsa, id_ecdsa_sk, id_ed25519, id_ed25519_sk, id_rsa\\n\\nMIME Types: application/pgp-keys, application/pgp-encrypted, application/pgp-signature\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "aspectj", "kind": 21, "documentation": {"kind": "markdown", "value": "### AspectJ\\n\\nFilenames:  *.aj\\n\\nMIME Types: text/x-aspectj\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "asymptote", "kind": 21, "documentation": {"kind": "markdown", "value": "### Asymptote\\n\\nFilenames:  *.asy\\n\\nMIME Types: text/x-asymptote\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "asy", "kind": 21, "documentation": {"kind": "markdown", "value": "### Asymptote\\n\\nFilenames:  *.asy\\n\\nMIME Types: text/x-asymptote\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "augeas", "kind": 21, "documentation": {"kind": "markdown", "value": "### Augeas\\n\\nFilenames:  *.aug\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "autoit", "kind": 21, "documentation": {"kind": "markdown", "value": "### AutoIt\\n\\nFilenames:  *.au3\\n\\nMIME Types: text/x-autoit\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "autohotkey", "kind": 21, "documentation": {"kind": "markdown", "value": "### autohotkey\\n\\nFilenames:  *.ahk, *.ahkl\\n\\nMIME Types: text/x-autohotkey\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ahk", "kind": 21, "documentation": {"kind": "markdown", "value": "### autohotkey\\n\\nFilenames:  *.ahk, *.ahkl\\n\\nMIME Types: text/x-autohotkey\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "awk", "kind": 21, "documentation": {"kind": "markdown", "value": "### Awk\\n\\nFilenames:  *.awk\\n\\nMIME Types: application/x-awk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gawk", "kind": 21, "documentation": {"kind": "markdown", "value": "### Awk\\n\\nFilenames:  *.awk\\n\\nMIME Types: application/x-awk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "mawk", "kind": 21, "documentation": {"kind": "markdown", "value": "### Awk\\n\\nFilenames:  *.awk\\n\\nMIME Types: application/x-awk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "nawk", "kind": 21, "documentation": {"kind": "markdown", "value": "### Awk\\n\\nFilenames:  *.awk\\n\\nMIME Types: application/x-awk\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bbcbasic", "kind": 21, "documentation": {"kind": "markdown", "value": "### BBC Basic\\n\\nFilenames:  *.bbc\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bbcode", "kind": 21, "documentation": {"kind": "markdown", "value": "### BBCode\\n\\nFilenames:  \\n\\nMIME Types: text/x-bbcode\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bc", "kind": 21, "documentation": {"kind": "markdown", "value": "### BC\\n\\nFilenames:  *.bc\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bst", "kind": 21, "documentation": {"kind": "markdown", "value": "### BST\\n\\nFilenames:  *.bst\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bst-pybtex", "kind": 21, "documentation": {"kind": "markdown", "value": "### BST\\n\\nFilenames:  *.bst\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bare", "kind": 21, "documentation": {"kind": "markdown", "value": "### BARE\\n\\nFilenames:  *.bare\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "basemake", "kind": 21, "documentation": {"kind": "markdown", "value": "### Base Makefile\\n\\nFilenames:  \\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bash", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash\\n\\nFilenames:  *.sh, *.ksh, *.bash, *.ebuild, *.eclass, *.exheres-0, *.exlib, *.zsh, .bashrc, bashrc, .bash_*, bash_*, zshrc, .zshrc, .kshrc, kshrc, PKGBUILD\\n\\nMIME Types: application/x-sh, application/x-shellscript, text/x-shellscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "sh", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash\\n\\nFilenames:  *.sh, *.ksh, *.bash, *.ebuild, *.eclass, *.exheres-0, *.exlib, *.zsh, .bashrc, bashrc, .bash_*, bash_*, zshrc, .zshrc, .kshrc, kshrc, PKGBUILD\\n\\nMIME Types: application/x-sh, application/x-shellscript, text/x-shellscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ksh", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash\\n\\nFilenames:  *.sh, *.ksh, *.bash, *.ebuild, *.eclass, *.exheres-0, *.exlib, *.zsh, .bashrc, bashrc, .bash_*, bash_*, zshrc, .zshrc, .kshrc, kshrc, PKGBUILD\\n\\nMIME Types: application/x-sh, application/x-shellscript, text/x-shellscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "zsh", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash\\n\\nFilenames:  *.sh, *.ksh, *.bash, *.ebuild, *.eclass, *.exheres-0, *.exlib, *.zsh, .bashrc, bashrc, .bash_*, bash_*, zshrc, .zshrc, .kshrc, kshrc, PKGBUILD\\n\\nMIME Types: application/x-sh, application/x-shellscript, text/x-shellscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "shell", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash\\n\\nFilenames:  *.sh, *.ksh, *.bash, *.ebuild, *.eclass, *.exheres-0, *.exlib, *.zsh, .bashrc, bashrc, .bash_*, bash_*, zshrc, .zshrc, .kshrc, kshrc, PKGBUILD\\n\\nMIME Types: application/x-sh, application/x-shellscript, text/x-shellscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "console", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash Session\\n\\nFilenames:  *.sh-session, *.shell-session\\n\\nMIME Types: application/x-shell-session, application/x-sh-session\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "shell-session", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bash Session\\n\\nFilenames:  *.sh-session, *.shell-session\\n\\nMIME Types: application/x-shell-session, application/x-sh-session\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "batch", "kind": 21, "documentation": {"kind": "markdown", "value": "### Batchfile\\n\\nFilenames:  *.bat, *.cmd\\n\\nMIME Types: application/x-dos-batch\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bat", "kind": 21, "documentation": {"kind": "markdown", "value": "### Batchfile\\n\\nFilenames:  *.bat, *.cmd\\n\\nMIME Types: application/x-dos-batch\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dosbatch", "kind": 21, "documentation": {"kind": "markdown", "value": "### Batchfile\\n\\nFilenames:  *.bat, *.cmd\\n\\nMIME Types: application/x-dos-batch\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "winbatch", "kind": 21, "documentation": {"kind": "markdown", "value": "### Batchfile\\n\\nFilenames:  *.bat, *.cmd\\n\\nMIME Types: application/x-dos-batch\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bdd", "kind": 21, "documentation": {"kind": "markdown", "value": "### Bdd\\n\\nFilenames:  *.feature\\n\\nMIME Types: text/x-bdd\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "befunge", "kind": 21, "documentation": {"kind": "markdown", "value": "### Befunge\\n\\nFilenames:  *.befunge\\n\\nMIME Types: application/x-befunge\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "berry", "kind": 21, "documentation": {"kind": "markdown", "value": "### Berry\\n\\nFilenames:  *.be\\n\\nMIME Types: text/x-berry, application/x-berry\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "be", "kind": 21, "documentation": {"kind": "markdown", "value": "### Berry\\n\\nFilenames:  *.be\\n\\nMIME Types: text/x-berry, application/x-berry\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bibtex", "kind": 21, "documentation": {"kind": "markdown", "value": "### BibTeX\\n\\nFilenames:  *.bib\\n\\nMIME Types: text/x-bibtex\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bib", "kind": 21, "documentation": {"kind": "markdown", "value": "### BibTeX\\n\\nFilenames:  *.bib\\n\\nMIME Types: text/x-bibtex\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "blitzbasic", "kind": 21, "documentation": {"kind": "markdown", "value": "### BlitzBasic\\n\\nFilenames:  *.bb, *.decls\\n\\nMIME Types: text/x-bb\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "b3d", "kind": 21, "documentation": {"kind": "markdown", "value": "### BlitzBasic\\n\\nFilenames:  *.bb, *.decls\\n\\nMIME Types: text/x-bb\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bplus", "kind": 21, "documentation": {"kind": "markdown", "value": "### BlitzBasic\\n\\nFilenames:  *.bb, *.decls\\n\\nMIME Types: text/x-bb\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "blitzmax", "kind": 21, "documentation": {"kind": "markdown", "value": "### BlitzMax\\n\\nFilenames:  *.bmx\\n\\nMIME Types: text/x-bmx\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bmax", "kind": 21, "documentation": {"kind": "markdown", "value": "### BlitzMax\\n\\nFilenames:  *.bmx\\n\\nMIME Types: text/x-bmx\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bnf", "kind": 21, "documentation": {"kind": "markdown", "value": "### BNF\\n\\nFilenames:  *.bnf\\n\\nMIME Types: text/x-bnf\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "boa", "kind": 21, "documentation": {"kind": "markdown", "value": "### Boa\\n\\nFilenames:  *.boa\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "boo", "kind": 21, "documentation": {"kind": "markdown", "value": "### Boo\\n\\nFilenames:  *.boo\\n\\nMIME Types: text/x-boo\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "boogie", "kind": 21, "documentation": {"kind": "markdown", "value": "### Boogie\\n\\nFilenames:  *.bpl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "brainfuck", "kind": 21, "documentation": {"kind": "markdown", "value": "### Brainfuck\\n\\nFilenames:  *.bf, *.b\\n\\nMIME Types: application/x-brainfuck\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bf", "kind": 21, "documentation": {"kind": "markdown", "value": "### Brainfuck\\n\\nFilenames:  *.bf, *.b\\n\\nMIME Types: application/x-brainfuck\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "bugs", "kind": 21, "documentation": {"kind": "markdown", "value": "### BUGS\\n\\nFilenames:  *.bug\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "winbugs", "kind": 21, "documentation": {"kind": "markdown", "value": "### BUGS\\n\\nFilenames:  *.bug\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "openbugs", "kind": 21, "documentation": {"kind": "markdown", "value": "### BUGS\\n\\nFilenames:  *.bug\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "camkes", "kind": 21, "documentation": {"kind": "markdown", "value": "### CAmkES\\n\\nFilenames:  *.camkes, *.idl4\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "idl4", "kind": 21, "documentation": {"kind": "markdown", "value": "### CAmkES\\n\\nFilenames:  *.camkes, *.idl4\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "c", "kind": 21, "documentation": {"kind": "markdown", "value": "### C\\n\\nFilenames:  *.c, *.h, *.idc, *.x[bp]m\\n\\nMIME Types: text/x-chdr, text/x-csrc, image/x-xbitmap, image/x-xpixmap\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cmake", "kind": 21, "documentation": {"kind": "markdown", "value": "### CMake\\n\\nFilenames:  *.cmake, CMakeLists.txt\\n\\nMIME Types: text/x-cmake\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "c-objdump", "kind": 21, "documentation": {"kind": "markdown", "value": "### c-objdump\\n\\nFilenames:  *.c-objdump\\n\\nMIME Types: text/x-c-objdump\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cpsa", "kind": 21, "documentation": {"kind": "markdown", "value": "### CPSA\\n\\nFilenames:  *.cpsa\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+ul4", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+UL4\\n\\nFilenames:  *.cssul4\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "aspx-cs", "kind": 21, "documentation": {"kind": "markdown", "value": "### aspx-cs\\n\\nFilenames:  *.aspx, *.asax, *.ascx, *.ashx, *.asmx, *.axd\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csharp", "kind": 21, "documentation": {"kind": "markdown", "value": "### C#\\n\\nFilenames:  *.cs\\n\\nMIME Types: text/x-csharp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "c#", "kind": 21, "documentation": {"kind": "markdown", "value": "### C#\\n\\nFilenames:  *.cs\\n\\nMIME Types: text/x-csharp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cs", "kind": 21, "documentation": {"kind": "markdown", "value": "### C#\\n\\nFilenames:  *.cs\\n\\nMIME Types: text/x-csharp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ca65", "kind": 21, "documentation": {"kind": "markdown", "value": "### ca65 assembler\\n\\nFilenames:  *.s\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cadl", "kind": 21, "documentation": {"kind": "markdown", "value": "### cADL\\n\\nFilenames:  *.cadl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "capdl", "kind": 21, "documentation": {"kind": "markdown", "value": "### CapDL\\n\\nFilenames:  *.cdl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "capnp", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cap\'n Proto\\n\\nFilenames:  *.capnp\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "carbon", "kind": 21, "documentation": {"kind": "markdown", "value": "### Carbon\\n\\nFilenames:  *.carbon\\n\\nMIME Types: text/x-carbon\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cbmbas", "kind": 21, "documentation": {"kind": "markdown", "value": "### CBM BASIC V2\\n\\nFilenames:  *.bas\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cddl", "kind": 21, "documentation": {"kind": "markdown", "value": "### CDDL\\n\\nFilenames:  *.cddl\\n\\nMIME Types: text/x-cddl\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ceylon", "kind": 21, "documentation": {"kind": "markdown", "value": "### Ceylon\\n\\nFilenames:  *.ceylon\\n\\nMIME Types: text/x-ceylon\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cfengine3", "kind": 21, "documentation": {"kind": "markdown", "value": "### CFEngine3\\n\\nFilenames:  *.cf\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cf3", "kind": 21, "documentation": {"kind": "markdown", "value": "### CFEngine3\\n\\nFilenames:  *.cf\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "chaiscript", "kind": 21, "documentation": {"kind": "markdown", "value": "### ChaiScript\\n\\nFilenames:  *.chai\\n\\nMIME Types: text/x-chaiscript, application/x-chaiscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "chai", "kind": 21, "documentation": {"kind": "markdown", "value": "### ChaiScript\\n\\nFilenames:  *.chai\\n\\nMIME Types: text/x-chaiscript, application/x-chaiscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "chapel", "kind": 21, "documentation": {"kind": "markdown", "value": "### Chapel\\n\\nFilenames:  *.chpl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "chpl", "kind": 21, "documentation": {"kind": "markdown", "value": "### Chapel\\n\\nFilenames:  *.chpl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "charmci", "kind": 21, "documentation": {"kind": "markdown", "value": "### Charmci\\n\\nFilenames:  *.ci\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "html+cheetah", "kind": 21, "documentation": {"kind": "markdown", "value": "### HTML+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: text/html+cheetah, text/html+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "html+spitfire", "kind": 21, "documentation": {"kind": "markdown", "value": "### HTML+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: text/html+cheetah, text/html+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "htmlcheetah", "kind": 21, "documentation": {"kind": "markdown", "value": "### HTML+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: text/html+cheetah, text/html+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "javascript+cheetah", "kind": 21, "documentation": {"kind": "markdown", "value": "### JavaScript+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: application/x-javascript+cheetah, text/x-javascript+cheetah, text/javascript+cheetah, application/x-javascript+spitfire, text/x-javascript+spitfire, text/javascript+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "js+cheetah", "kind": 21, "documentation": {"kind": "markdown", "value": "### JavaScript+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: application/x-javascript+cheetah, text/x-javascript+cheetah, text/javascript+cheetah, application/x-javascript+spitfire, text/x-javascript+spitfire, text/javascript+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "javascript+spitfire", "kind": 21, "documentation": {"kind": "markdown", "value": "### JavaScript+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: application/x-javascript+cheetah, text/x-javascript+cheetah, text/javascript+cheetah, application/x-javascript+spitfire, text/x-javascript+spitfire, text/javascript+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "js+spitfire", "kind": 21, "documentation": {"kind": "markdown", "value": "### JavaScript+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: application/x-javascript+cheetah, text/x-javascript+cheetah, text/javascript+cheetah, application/x-javascript+spitfire, text/x-javascript+spitfire, text/javascript+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cheetah", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cheetah\\n\\nFilenames:  *.tmpl, *.spt\\n\\nMIME Types: application/x-cheetah, application/x-spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "spitfire", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cheetah\\n\\nFilenames:  *.tmpl, *.spt\\n\\nMIME Types: application/x-cheetah, application/x-spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "xml+cheetah", "kind": 21, "documentation": {"kind": "markdown", "value": "### XML+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: application/xml+cheetah, application/xml+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "xml+spitfire", "kind": 21, "documentation": {"kind": "markdown", "value": "### XML+Cheetah\\n\\nFilenames:  \\n\\nMIME Types: application/xml+cheetah, application/xml+spitfire\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cirru", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cirru\\n\\nFilenames:  *.cirru\\n\\nMIME Types: text/x-cirru\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "clay", "kind": 21, "documentation": {"kind": "markdown", "value": "### Clay\\n\\nFilenames:  *.clay\\n\\nMIME Types: text/x-clay\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "clean", "kind": 21, "documentation": {"kind": "markdown", "value": "### Clean\\n\\nFilenames:  *.icl, *.dcl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "clojure", "kind": 21, "documentation": {"kind": "markdown", "value": "### Clojure\\n\\nFilenames:  *.clj, *.cljc\\n\\nMIME Types: text/x-clojure, application/x-clojure\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "clj", "kind": 21, "documentation": {"kind": "markdown", "value": "### Clojure\\n\\nFilenames:  *.clj, *.cljc\\n\\nMIME Types: text/x-clojure, application/x-clojure\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "clojurescript", "kind": 21, "documentation": {"kind": "markdown", "value": "### ClojureScript\\n\\nFilenames:  *.cljs\\n\\nMIME Types: text/x-clojurescript, application/x-clojurescript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cljs", "kind": 21, "documentation": {"kind": "markdown", "value": "### ClojureScript\\n\\nFilenames:  *.cljs\\n\\nMIME Types: text/x-clojurescript, application/x-clojurescript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cobolfree", "kind": 21, "documentation": {"kind": "markdown", "value": "### COBOLFree\\n\\nFilenames:  *.cbl, *.CBL\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cobol", "kind": 21, "documentation": {"kind": "markdown", "value": "### COBOL\\n\\nFilenames:  *.cob, *.COB, *.cpy, *.CPY\\n\\nMIME Types: text/x-cobol\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "coffeescript", "kind": 21, "documentation": {"kind": "markdown", "value": "### CoffeeScript\\n\\nFilenames:  *.coffee\\n\\nMIME Types: text/coffeescript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "coffee-script", "kind": 21, "documentation": {"kind": "markdown", "value": "### CoffeeScript\\n\\nFilenames:  *.coffee\\n\\nMIME Types: text/coffeescript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "coffee", "kind": 21, "documentation": {"kind": "markdown", "value": "### CoffeeScript\\n\\nFilenames:  *.coffee\\n\\nMIME Types: text/coffeescript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cfc", "kind": 21, "documentation": {"kind": "markdown", "value": "### Coldfusion CFC\\n\\nFilenames:  *.cfc\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cfm", "kind": 21, "documentation": {"kind": "markdown", "value": "### Coldfusion HTML\\n\\nFilenames:  *.cfm, *.cfml\\n\\nMIME Types: application/x-coldfusion\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cfs", "kind": 21, "documentation": {"kind": "markdown", "value": "### cfstatement\\n\\nFilenames:  \\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "comal", "kind": 21, "documentation": {"kind": "markdown", "value": "### COMAL-80\\n\\nFilenames:  *.cml, *.comal\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "comal80", "kind": 21, "documentation": {"kind": "markdown", "value": "### COMAL-80\\n\\nFilenames:  *.cml, *.comal\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "common-lisp", "kind": 21, "documentation": {"kind": "markdown", "value": "### Common Lisp\\n\\nFilenames:  *.cl, *.lisp\\n\\nMIME Types: text/x-common-lisp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cl", "kind": 21, "documentation": {"kind": "markdown", "value": "### Common Lisp\\n\\nFilenames:  *.cl, *.lisp\\n\\nMIME Types: text/x-common-lisp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "lisp", "kind": 21, "documentation": {"kind": "markdown", "value": "### Common Lisp\\n\\nFilenames:  *.cl, *.lisp\\n\\nMIME Types: text/x-common-lisp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "componentpascal", "kind": 21, "documentation": {"kind": "markdown", "value": "### Component Pascal\\n\\nFilenames:  *.cp, *.cps\\n\\nMIME Types: text/x-component-pascal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cp", "kind": 21, "documentation": {"kind": "markdown", "value": "### Component Pascal\\n\\nFilenames:  *.cp, *.cps\\n\\nMIME Types: text/x-component-pascal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "coq", "kind": 21, "documentation": {"kind": "markdown", "value": "### Coq\\n\\nFilenames:  *.v\\n\\nMIME Types: text/x-coq\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cplint", "kind": 21, "documentation": {"kind": "markdown", "value": "### cplint\\n\\nFilenames:  *.ecl, *.prolog, *.pro, *.pl, *.P, *.lpad, *.cpl\\n\\nMIME Types: text/x-cplint\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cpp", "kind": 21, "documentation": {"kind": "markdown", "value": "### C++\\n\\nFilenames:  *.cpp, *.hpp, *.c++, *.h++, *.cc, *.hh, *.cxx, *.hxx, *.C, *.H, *.cp, *.CPP, *.tpp\\n\\nMIME Types: text/x-c++hdr, text/x-c++src\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "c++", "kind": 21, "documentation": {"kind": "markdown", "value": "### C++\\n\\nFilenames:  *.cpp, *.hpp, *.c++, *.h++, *.cc, *.hh, *.cxx, *.hxx, *.C, *.H, *.cp, *.CPP, *.tpp\\n\\nMIME Types: text/x-c++hdr, text/x-c++src\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cpp-objdump", "kind": 21, "documentation": {"kind": "markdown", "value": "### cpp-objdump\\n\\nFilenames:  *.cpp-objdump, *.c++-objdump, *.cxx-objdump\\n\\nMIME Types: text/x-cpp-objdump\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "c++-objdumb", "kind": 21, "documentation": {"kind": "markdown", "value": "### cpp-objdump\\n\\nFilenames:  *.cpp-objdump, *.c++-objdump, *.cxx-objdump\\n\\nMIME Types: text/x-cpp-objdump\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cxx-objdump", "kind": 21, "documentation": {"kind": "markdown", "value": "### cpp-objdump\\n\\nFilenames:  *.cpp-objdump, *.c++-objdump, *.cxx-objdump\\n\\nMIME Types: text/x-cpp-objdump\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "crmsh", "kind": 21, "documentation": {"kind": "markdown", "value": "### Crmsh\\n\\nFilenames:  *.crmsh, *.pcmk\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "pcmk", "kind": 21, "documentation": {"kind": "markdown", "value": "### Crmsh\\n\\nFilenames:  *.crmsh, *.pcmk\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "croc", "kind": 21, "documentation": {"kind": "markdown", "value": "### Croc\\n\\nFilenames:  *.croc\\n\\nMIME Types: text/x-crocsrc\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cryptol", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cryptol\\n\\nFilenames:  *.cry\\n\\nMIME Types: text/x-cryptol\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cry", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cryptol\\n\\nFilenames:  *.cry\\n\\nMIME Types: text/x-cryptol\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cr", "kind": 21, "documentation": {"kind": "markdown", "value": "### Crystal\\n\\nFilenames:  *.cr\\n\\nMIME Types: text/x-crystal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "crystal", "kind": 21, "documentation": {"kind": "markdown", "value": "### Crystal\\n\\nFilenames:  *.cr\\n\\nMIME Types: text/x-crystal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csound-document", "kind": 21, "documentation": {"kind": "markdown", "value": "### Csound Document\\n\\nFilenames:  *.csd\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csound-csd", "kind": 21, "documentation": {"kind": "markdown", "value": "### Csound Document\\n\\nFilenames:  *.csd\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csound", "kind": 21, "documentation": {"kind": "markdown", "value": "### Csound Orchestra\\n\\nFilenames:  *.orc, *.udo\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csound-orc", "kind": 21, "documentation": {"kind": "markdown", "value": "### Csound Orchestra\\n\\nFilenames:  *.orc, *.udo\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csound-score", "kind": 21, "documentation": {"kind": "markdown", "value": "### Csound Score\\n\\nFilenames:  *.sco\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "csound-sco", "kind": 21, "documentation": {"kind": "markdown", "value": "### Csound Score\\n\\nFilenames:  *.sco\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+django", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Django/Jinja\\n\\nFilenames:  *.css.j2, *.css.jinja2\\n\\nMIME Types: text/css+django, text/css+jinja\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+jinja", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Django/Jinja\\n\\nFilenames:  *.css.j2, *.css.jinja2\\n\\nMIME Types: text/css+django, text/css+jinja\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+ruby", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Ruby\\n\\nFilenames:  \\n\\nMIME Types: text/css+ruby\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+erb", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Ruby\\n\\nFilenames:  \\n\\nMIME Types: text/css+ruby\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+genshitext", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Genshi Text\\n\\nFilenames:  \\n\\nMIME Types: text/css+genshi\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+genshi", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Genshi Text\\n\\nFilenames:  \\n\\nMIME Types: text/css+genshi\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS\\n\\nFilenames:  *.css\\n\\nMIME Types: text/css\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+php", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+PHP\\n\\nFilenames:  \\n\\nMIME Types: text/css+php\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "css+smarty", "kind": 21, "documentation": {"kind": "markdown", "value": "### CSS+Smarty\\n\\nFilenames:  \\n\\nMIME Types: text/css+smarty\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cuda", "kind": 21, "documentation": {"kind": "markdown", "value": "### CUDA\\n\\nFilenames:  *.cu, *.cuh\\n\\nMIME Types: text/x-cuda\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cu", "kind": 21, "documentation": {"kind": "markdown", "value": "### CUDA\\n\\nFilenames:  *.cu, *.cuh\\n\\nMIME Types: text/x-cuda\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cypher", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cypher\\n\\nFilenames:  *.cyp, *.cypher\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "cython", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cython\\n\\nFilenames:  *.pyx, *.pxd, *.pxi\\n\\nMIME Types: text/x-cython, application/x-cython\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "pyx", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cython\\n\\nFilenames:  *.pyx, *.pxd, *.pxi\\n\\nMIME Types: text/x-cython, application/x-cython\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "pyrex", "kind": 21, "documentation": {"kind": "markdown", "value": "### Cython\\n\\nFilenames:  *.pyx, *.pxd, *.pxi\\n\\nMIME Types: text/x-cython, application/x-cython\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "d", "kind": 21, "documentation": {"kind": "markdown", "value": "### D\\n\\nFilenames:  *.d, *.di\\n\\nMIME Types: text/x-dsrc\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "d-objdump", "kind": 21, "documentation": {"kind": "markdown", "value": "### d-objdump\\n\\nFilenames:  *.d-objdump\\n\\nMIME Types: text/x-d-objdump\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dpatch", "kind": 21, "documentation": {"kind": "markdown", "value": "### Darcs Patch\\n\\nFilenames:  *.dpatch, *.darcspatch\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dart", "kind": 21, "documentation": {"kind": "markdown", "value": "### Dart\\n\\nFilenames:  *.dart\\n\\nMIME Types: text/x-dart\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dasm16", "kind": 21, "documentation": {"kind": "markdown", "value": "### DASM16\\n\\nFilenames:  *.dasm16, *.dasm\\n\\nMIME Types: text/x-dasm16\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dax", "kind": 21, "documentation": {"kind": "markdown", "value": "### Dax\\n\\nFilenames:  *.dax\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "debcontrol", "kind": 21, "documentation": {"kind": "markdown", "value": "### Debian Control file\\n\\nFilenames:  control\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "control", "kind": 21, "documentation": {"kind": "markdown", "value": "### Debian Control file\\n\\nFilenames:  control\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "delphi", "kind": 21, "documentation": {"kind": "markdown", "value": "### Delphi\\n\\nFilenames:  *.pas, *.dpr\\n\\nMIME Types: text/x-pascal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "pas", "kind": 21, "documentation": {"kind": "markdown", "value": "### Delphi\\n\\nFilenames:  *.pas, *.dpr\\n\\nMIME Types: text/x-pascal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "pascal", "kind": 21, "documentation": {"kind": "markdown", "value": "### Delphi\\n\\nFilenames:  *.pas, *.dpr\\n\\nMIME Types: text/x-pascal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "objectpascal", "kind": 21, "documentation": {"kind": "markdown", "value": "### Delphi\\n\\nFilenames:  *.pas, *.dpr\\n\\nMIME Types: text/x-pascal\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "devicetree", "kind": 21, "documentation": {"kind": "markdown", "value": "### Devicetree\\n\\nFilenames:  *.dts, *.dtsi\\n\\nMIME Types: text/x-c\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dts", "kind": 21, "documentation": {"kind": "markdown", "value": "### Devicetree\\n\\nFilenames:  *.dts, *.dtsi\\n\\nMIME Types: text/x-c\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dg", "kind": 21, "documentation": {"kind": "markdown", "value": "### dg\\n\\nFilenames:  *.dg\\n\\nMIME Types: text/x-dg\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "diff", "kind": 21, "documentation": {"kind": "markdown", "value": "### Diff\\n\\nFilenames:  *.diff, *.patch\\n\\nMIME Types: text/x-diff, text/x-patch\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "udiff", "kind": 21, "documentation": {"kind": "markdown", "value": "### Diff\\n\\nFilenames:  *.diff, *.patch\\n\\nMIME Types: text/x-diff, text/x-patch\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "django", "kind": 21, "documentation": {"kind": "markdown", "value": "### Django/Jinja\\n\\nFilenames:  \\n\\nMIME Types: application/x-django-templating, application/x-jinja\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "jinja", "kind": 21, "documentation": {"kind": "markdown", "value": "### Django/Jinja\\n\\nFilenames:  \\n\\nMIME Types: application/x-django-templating, application/x-jinja\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "docker", "kind": 21, "documentation": {"kind": "markdown", "value": "### Docker\\n\\nFilenames:  Dockerfile, *.docker\\n\\nMIME Types: text/x-dockerfile-config\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dockerfile", "kind": 21, "documentation": {"kind": "markdown", "value": "### Docker\\n\\nFilenames:  Dockerfile, *.docker\\n\\nMIME Types: text/x-dockerfile-config\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dtd", "kind": 21, "documentation": {"kind": "markdown", "value": "### DTD\\n\\nFilenames:  *.dtd\\n\\nMIME Types: application/xml-dtd\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "duel", "kind": 21, "documentation": {"kind": "markdown", "value": "### Duel\\n\\nFilenames:  *.duel, *.jbst\\n\\nMIME Types: text/x-duel, text/x-jbst\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "jbst", "kind": 21, "documentation": {"kind": "markdown", "value": "### Duel\\n\\nFilenames:  *.duel, *.jbst\\n\\nMIME Types: text/x-duel, text/x-jbst\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "jsonml+bst", "kind": 21, "documentation": {"kind": "markdown", "value": "### Duel\\n\\nFilenames:  *.duel, *.jbst\\n\\nMIME Types: text/x-duel, text/x-jbst\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dylan-console", "kind": 21, "documentation": {"kind": "markdown", "value": "### Dylan session\\n\\nFilenames:  *.dylan-console\\n\\nMIME Types: text/x-dylan-console\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dylan-repl", "kind": 21, "documentation": {"kind": "markdown", "value": "### Dylan session\\n\\nFilenames:  *.dylan-console\\n\\nMIME Types: text/x-dylan-console\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dylan", "kind": 21, "documentation": {"kind": "markdown", "value": "### Dylan\\n\\nFilenames:  *.dylan, *.dyl, *.intr\\n\\nMIME Types: text/x-dylan\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "dylan-lid", "kind": 21, "documentation": {"kind": "markdown", "value": "### DylanLID\\n\\nFilenames:  *.lid, *.hdp\\n\\nMIME Types: text/x-dylan-lid\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "lid", "kind": 21, "documentation": {"kind": "markdown", "value": "### DylanLID\\n\\nFilenames:  *.lid, *.hdp\\n\\nMIME Types: text/x-dylan-lid\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ecl", "kind": 21, "documentation": {"kind": "markdown", "value": "### ECL\\n\\nFilenames:  *.ecl\\n\\nMIME Types: application/x-ecl\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ec", "kind": 21, "documentation": {"kind": "markdown", "value": "### eC\\n\\nFilenames:  *.ec, *.eh\\n\\nMIME Types: text/x-echdr, text/x-ecsrc\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "earl-grey", "kind": 21, "documentation": {"kind": "markdown", "value": "### Earl Grey\\n\\nFilenames:  *.eg\\n\\nMIME Types: text/x-earl-grey\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "earlgrey", "kind": 21, "documentation": {"kind": "markdown", "value": "### Earl Grey\\n\\nFilenames:  *.eg\\n\\nMIME Types: text/x-earl-grey\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "eg", "kind": 21, "documentation": {"kind": "markdown", "value": "### Earl Grey\\n\\nFilenames:  *.eg\\n\\nMIME Types: text/x-earl-grey\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "easytrieve", "kind": 21, "documentation": {"kind": "markdown", "value": "### Easytrieve\\n\\nFilenames:  *.ezt, *.mac\\n\\nMIME Types: text/x-easytrieve\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ebnf", "kind": 21, "documentation": {"kind": "markdown", "value": "### EBNF\\n\\nFilenames:  *.ebnf\\n\\nMIME Types: text/x-ebnf\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "eiffel", "kind": 21, "documentation": {"kind": "markdown", "value": "### Eiffel\\n\\nFilenames:  *.e\\n\\nMIME Types: text/x-eiffel\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "iex", "kind": 21, "documentation": {"kind": "markdown", "value": "### Elixir iex session\\n\\nFilenames:  \\n\\nMIME Types: text/x-elixir-shellsession\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "elixir", "kind": 21, "documentation": {"kind": "markdown", "value": "### Elixir\\n\\nFilenames:  *.ex, *.eex, *.exs, *.leex\\n\\nMIME Types: text/x-elixir\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ex", "kind": 21, "documentation": {"kind": "markdown", "value": "### Elixir\\n\\nFilenames:  *.ex, *.eex, *.exs, *.leex\\n\\nMIME Types: text/x-elixir\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "exs", "kind": 21, "documentation": {"kind": "markdown", "value": "### Elixir\\n\\nFilenames:  *.ex, *.eex, *.exs, *.leex\\n\\nMIME Types: text/x-elixir\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "elm", "kind": 21, "documentation": {"kind": "markdown", "value": "### Elm\\n\\nFilenames:  *.elm\\n\\nMIME Types: text/x-elm\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "elpi", "kind": 21, "documentation": {"kind": "markdown", "value": "### Elpi\\n\\nFilenames:  *.elpi\\n\\nMIME Types: text/x-elpi\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "emacs-lisp", "kind": 21, "documentation": {"kind": "markdown", "value": "### EmacsLisp\\n\\nFilenames:  *.el\\n\\nMIME Types: text/x-elisp, application/x-elisp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "elisp", "kind": 21, "documentation": {"kind": "markdown", "value": "### EmacsLisp\\n\\nFilenames:  *.el\\n\\nMIME Types: text/x-elisp, application/x-elisp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "emacs", "kind": 21, "documentation": {"kind": "markdown", "value": "### EmacsLisp\\n\\nFilenames:  *.el\\n\\nMIME Types: text/x-elisp, application/x-elisp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "email", "kind": 21, "documentation": {"kind": "markdown", "value": "### E-mail\\n\\nFilenames:  *.eml\\n\\nMIME Types: message/rfc822\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "eml", "kind": 21, "documentation": {"kind": "markdown", "value": "### E-mail\\n\\nFilenames:  *.eml\\n\\nMIME Types: message/rfc822\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "erb", "kind": 21, "documentation": {"kind": "markdown", "value": "### ERB\\n\\nFilenames:  \\n\\nMIME Types: application/x-ruby-templating\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "erlang", "kind": 21, "documentation": {"kind": "markdown", "value": "### Erlang\\n\\nFilenames:  *.erl, *.hrl, *.es, *.escript\\n\\nMIME Types: text/x-erlang\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "erl", "kind": 21, "documentation": {"kind": "markdown", "value": "### Erlang erl session\\n\\nFilenames:  *.erl-sh\\n\\nMIME Types: text/x-erl-shellsession\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "html+evoque", "kind": 21, "documentation": {"kind": "markdown", "value": "### HTML+Evoque\\n\\nFilenames:  *.html\\n\\nMIME Types: text/html+evoque\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "evoque", "kind": 21, "documentation": {"kind": "markdown", "value": "### Evoque\\n\\nFilenames:  *.evoque\\n\\nMIME Types: application/x-evoque\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "xml+evoque", "kind": 21, "documentation": {"kind": "markdown", "value": "### XML+Evoque\\n\\nFilenames:  *.xml\\n\\nMIME Types: application/xml+evoque\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "execline", "kind": 21, "documentation": {"kind": "markdown", "value": "### execline\\n\\nFilenames:  *.exec\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "ezhil", "kind": 21, "documentation": {"kind": "markdown", "value": "### Ezhil\\n\\nFilenames:  *.n\\n\\nMIME Types: text/x-ezhil\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fsharp", "kind": 21, "documentation": {"kind": "markdown", "value": "### F#\\n\\nFilenames:  *.fs, *.fsi, *.fsx\\n\\nMIME Types: text/x-fsharp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "f#", "kind": 21, "documentation": {"kind": "markdown", "value": "### F#\\n\\nFilenames:  *.fs, *.fsi, *.fsx\\n\\nMIME Types: text/x-fsharp\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fstar", "kind": 21, "documentation": {"kind": "markdown", "value": "### FStar\\n\\nFilenames:  *.fst, *.fsti\\n\\nMIME Types: text/x-fstar\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "factor", "kind": 21, "documentation": {"kind": "markdown", "value": "### Factor\\n\\nFilenames:  *.factor\\n\\nMIME Types: text/x-factor\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fancy", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fancy\\n\\nFilenames:  *.fy, *.fancypack\\n\\nMIME Types: text/x-fancysrc\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fy", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fancy\\n\\nFilenames:  *.fy, *.fancypack\\n\\nMIME Types: text/x-fancysrc\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fan", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fantom\\n\\nFilenames:  *.fan\\n\\nMIME Types: application/x-fantom\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "felix", "kind": 21, "documentation": {"kind": "markdown", "value": "### Felix\\n\\nFilenames:  *.flx, *.flxh\\n\\nMIME Types: text/x-felix\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "flx", "kind": 21, "documentation": {"kind": "markdown", "value": "### Felix\\n\\nFilenames:  *.flx, *.flxh\\n\\nMIME Types: text/x-felix\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fennel", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fennel\\n\\nFilenames:  *.fnl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fnl", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fennel\\n\\nFilenames:  *.fnl\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fift", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fift\\n\\nFilenames:  *.fif\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fif", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fift\\n\\nFilenames:  *.fif\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fish", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fish\\n\\nFilenames:  *.fish, *.load\\n\\nMIME Types: application/x-fish\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fishshell", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fish\\n\\nFilenames:  *.fish, *.load\\n\\nMIME Types: application/x-fish\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "flatline", "kind": 21, "documentation": {"kind": "markdown", "value": "### Flatline\\n\\nFilenames:  \\n\\nMIME Types: text/x-flatline\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "floscript", "kind": 21, "documentation": {"kind": "markdown", "value": "### FloScript\\n\\nFilenames:  *.flo\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "flo", "kind": 21, "documentation": {"kind": "markdown", "value": "### FloScript\\n\\nFilenames:  *.flo\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "forth", "kind": 21, "documentation": {"kind": "markdown", "value": "### Forth\\n\\nFilenames:  *.frt, *.fs\\n\\nMIME Types: application/x-forth\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fortranfixed", "kind": 21, "documentation": {"kind": "markdown", "value": "### FortranFixed\\n\\nFilenames:  *.f, *.F\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fortran", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fortran\\n\\nFilenames:  *.f03, *.f90, *.F03, *.F90\\n\\nMIME Types: text/x-fortran\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "f90", "kind": 21, "documentation": {"kind": "markdown", "value": "### Fortran\\n\\nFilenames:  *.f03, *.f90, *.F03, *.F90\\n\\nMIME Types: text/x-fortran\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "foxpro", "kind": 21, "documentation": {"kind": "markdown", "value": "### FoxPro\\n\\nFilenames:  *.PRG, *.prg\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "vfp", "kind": 21, "documentation": {"kind": "markdown", "value": "### FoxPro\\n\\nFilenames:  *.PRG, *.prg\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "clipper", "kind": 21, "documentation": {"kind": "markdown", "value": "### FoxPro\\n\\nFilenames:  *.PRG, *.prg\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "xbase", "kind": 21, "documentation": {"kind": "markdown", "value": "### FoxPro\\n\\nFilenames:  *.PRG, *.prg\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "freefem", "kind": 21, "documentation": {"kind": "markdown", "value": "### Freefem\\n\\nFilenames:  *.edp\\n\\nMIME Types: text/x-freefem\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "func", "kind": 21, "documentation": {"kind": "markdown", "value": "### FunC\\n\\nFilenames:  *.fc, *.func\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "fc", "kind": 21, "documentation": {"kind": "markdown", "value": "### FunC\\n\\nFilenames:  *.fc, *.func\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "futhark", "kind": 21, "documentation": {"kind": "markdown", "value": "### Futhark\\n\\nFilenames:  *.fut\\n\\nMIME Types: text/x-futhark\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gap-console", "kind": 21, "documentation": {"kind": "markdown", "value": "### GAP session\\n\\nFilenames:  *.tst\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gap-repl", "kind": 21, "documentation": {"kind": "markdown", "value": "### GAP session\\n\\nFilenames:  *.tst\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gap", "kind": 21, "documentation": {"kind": "markdown", "value": "### GAP\\n\\nFilenames:  *.g, *.gd, *.gi, *.gap\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gdscript", "kind": 21, "documentation": {"kind": "markdown", "value": "### GDScript\\n\\nFilenames:  *.gd\\n\\nMIME Types: text/x-gdscript, application/x-gdscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gd", "kind": 21, "documentation": {"kind": "markdown", "value": "### GDScript\\n\\nFilenames:  *.gd\\n\\nMIME Types: text/x-gdscript, application/x-gdscript\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "glsl", "kind": 21, "documentation": {"kind": "markdown", "value": "### GLSL\\n\\nFilenames:  *.vert, *.frag, *.geo\\n\\nMIME Types: text/x-glslsrc\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gsql", "kind": 21, "documentation": {"kind": "markdown", "value": "### GSQL\\n\\nFilenames:  *.gsql\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gas", "kind": 21, "documentation": {"kind": "markdown", "value": "### GAS\\n\\nFilenames:  *.s, *.S\\n\\nMIME Types: text/x-gas\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "asm", "kind": 21, "documentation": {"kind": "markdown", "value": "### GAS\\n\\nFilenames:  *.s, *.S\\n\\nMIME Types: text/x-gas\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "gcode", "kind": 21, "documentation": {"kind": "markdown", "value": "### g-code\\n\\nFilenames:  *.gcode\\n\\nMIME Types: \\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "genshi", "kind": 21, "documentation": {"kind": "markdown", "value": "### Genshi\\n\\nFilenames:  *.kid\\n\\nMIME Types: application/x-genshi, application/x-kid\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "kid", "kind": 21, "documentation": {"kind": "markdown", "value": "### Genshi\\n\\nFilenames:  *.kid\\n\\nMIME Types: application/x-genshi, application/x-kid\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "xml+genshi", "kind": 21, "documentation": {"kind": "markdown", "value": "### Genshi\\n\\nFilenames:  *.kid\\n\\nMIME Types: application/x-genshi, application/x-kid\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "xml+kid", "kind": 21, "documentation": {"kind": "markdown", "value": "### Genshi\\n\\nFilenames:  *.kid\\n\\nMIME Types: application/x-genshi, application/x-kid\\n"}, "data": {"source_feature": "esbonio.lsp.directives.Directives"}}, {"label": "genshitext", "kind": 21, "documentation": {"kind": "markdown", "'

Notice how the request just... stops mid JSON object? The docs do warn against using server.stdout directly

Warning
Use the communicate() method rather than process.stdin.write(), await process.stdout.read() or await process.stderr.read(). This avoids deadlocks due to streams pausing reading or writing and blocking the child process.

Which is what I guess is happening here? The problem is that we can't use communicate() as it will not return until the server exits! Definitely not what we want when we want to send messages back and forth. So a little bit of thought might be needed... 🤔

alcarney added 3 commits June 11, 2023 18:42
This copies the `feature` decorator from `pygls.LanguageServer`,
allowing clients to implement handlers for messages coming from a server
e.g.

```python
client = LanguageClient(...)

@client.feature('window/logMessage')
def handler(ls, params: LogMessageParams):
    logger.info("%s", params.message)

```

The client now also watches to see if the server process exits and shuts
itself down accordingly. Subclasses of `pygls.Client` can implement a
`server_exit` method if they want to take action when that happens.

On a similar note, the `_report_server_error` method has also been
ported so a client can implement `report_server_error` if they want to
do something when a server sends malformed JSON for example.
To help prevent against hangs due to the server process exiting.
This updates the autogenerated client to make sure the `self.stopped`
is `False` before sending anything.
@alcarney alcarney force-pushed the client-improvements branch from 99a42b9 to 03b8b6c Compare June 11, 2023 18:00
alcarney added 4 commits June 12, 2023 20:25
It turns out that `StreamReader.read(n)` only guarantees that you will
read **at most** `n` bytes, but it's very possible to read `m < n` bytes
- especially when `n` is large.

By switching to `StreamReader.readexactly(n)`, the only time we will not
read `n` bytes is when the stream encounters `EOF`.

Also, `client.stop()` will now terminate the server process if it still
happens to be running.
Not sure why, but this seems to be necessary to ensure the messages
are formatted correctly on Windows
I don't know why, but there is a particularly annoying edge case when
running the entire test suite, on Python 3.7, on Linux.

As far as I can tell, the server process for the code actions test
case never terminates. The test case works perfectly on all other
Python versions and platforms. It even works fine if you run the test
case on its own! But run the test case along with everything else, on
Linux using Python 3.7 - the server process hangs, hanging the rest of
the test suite with it.

Luckily, the fix appears to be simply not re-using the event loop
across test cases, thankfully we don't have any test cases that
require this yet.
@alcarney alcarney force-pushed the client-improvements branch from 03b8b6c to d71baba Compare June 12, 2023 19:25
@alcarney alcarney marked this pull request as ready for review June 12, 2023 19:28
@alcarney alcarney requested a review from tombh June 12, 2023 19:28
@tombh
Copy link
Collaborator

tombh commented Jun 12, 2023

A lot of great stuff in here. Especially seeing how simply we're now properly end-to-end testing client/server interaction. Really awesome. Looking at how powerful this new client/server testing is now, I'm wondering where your lib/pytest-lsp is fitting in at the moment?

Are there any other uses for the client apart from testing? I feel like there very much could be, an LSP-capable "editor" purely through STDIN pipes?? But it's very much a testing feature at the moment, so could it equally live under tests?

@tombh tombh merged commit eb71c85 into openlawlibrary:master Jun 12, 2023
@alcarney alcarney deleted the client-improvements branch June 12, 2023 22:39
@alcarney
Copy link
Collaborator Author

I'm wondering where your lib/pytest-lsp is fitting in at the moment?

My current thinking is that with pygls taking on fundamental details of talking to the server, pytest-lsp can focus on "nice to haves" like hooking into pytest to automatically include captured log messages in failure reports etc. As well as higher level checks around client capabilities (though that's very much under construction atm)

Are there any other uses for the client apart from testing?

Loads!

I'm sure there would be plenty of improvements to make, but fundamentally, I don't see why anyone couldn't start using this to build their own LSP-powered editor. Also, if you can keep a secret 😉 I've started work on what (hopefully!) will become the next-generation architecture for esbonio - it's going to make heavy use of the new pygls.Client!

@tombh
Copy link
Collaborator

tombh commented Jun 14, 2023

My current thinking is that with pygls taking on fundamental details of talking to the server, pytest-lsp can focus on "nice to haves" like hooking into pytest to automatically include captured log messages in failure reports etc. As well as higher level checks around client capabilities (though that's very much under construction atm)

Right, makes sense.

I've started work on what (hopefully!) will become the next-generation architecture for esbonio

Sai'n mynd y siarad gyda neb 😉 So you're embedding Sphinx basically natively into the LSP server, that's pretty cool. Though I don't see yet how it would use the client. Anyway, I'm sure it'll be awesome 😏

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

Successfully merging this pull request may close these issues.

2 participants