| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <meta name="description" content=""> |
| <meta name="keywords" content="extensionsassemblydev-docs, framework, language servers, code assistant, language support, code completion, error marking"> |
| <title>Language Support | Eclipse Che Documentation</title> |
| <link rel="stylesheet" href="css/syntax.css"> |
| |
| <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous"> |
| <!--<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">--> |
| <link rel="stylesheet" href="css/modern-business.css"> |
| <!-- Latest compiled and minified CSS --> |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> |
| <link rel="stylesheet" href="css/customstyles.css"> |
| <link rel="stylesheet" href="css/boxshadowproperties.css"> |
| <!-- most color styles are extracted out to here --> |
| <link rel="stylesheet" href="css/theme-che.css"> |
| |
| |
| <link rel="stylesheet" href="/css/coderay.css" media="screen" type="text/css"> |
| |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script> |
| |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js" crossorigin="anonymous"></script> |
| <script src="js/jquery.navgoco.min.js"></script> |
| |
| |
| <!-- Latest compiled and minified JavaScript --> |
| <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> |
| <!-- Anchor.js --> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script> |
| <script src="js/toc.js"></script> |
| <script src="js/customscripts.js"></script> |
| |
| <link rel="shortcut icon" href="che/docs/images/favicon.ico"> |
| |
| <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> |
| <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> |
| <!--[if lt IE 9]> |
| <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> |
| <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> |
| <![endif]--> |
| |
| <link rel="alternate" type="application/rss+xml" title="che" href="http://0.0.0.0:4000/feed.xml"> |
| |
| <script> |
| $(document).ready(function() { |
| // Initialize navgoco with default options |
| $("#mysidebar").navgoco({ |
| caretHtml: '', |
| accordion: true, |
| openClass: 'active', // open |
| save: false, // leave false or nav highlighting doesn't work right |
| cookie: { |
| name: 'navgoco', |
| expires: false, |
| path: '/' |
| }, |
| slide: { |
| duration: 400, |
| easing: 'swing' |
| } |
| }); |
| |
| $("#collapseAll").click(function(e) { |
| e.preventDefault(); |
| $("#mysidebar").navgoco('toggle', false); |
| }); |
| |
| $("#expandAll").click(function(e) { |
| e.preventDefault(); |
| $("#mysidebar").navgoco('toggle', true); |
| }); |
| |
| }); |
| |
| </script> |
| <script> |
| $(function () { |
| $('[data-toggle="tooltip"]').tooltip() |
| }) |
| </script> |
| <script> |
| $(document).ready(function() { |
| $("#tg-sb-link").click(function() { |
| $("#tg-sb-sidebar").toggle(); |
| $("#tg-sb-content").toggleClass('col-md-9'); |
| $("#tg-sb-content").toggleClass('col-md-12'); |
| $("#tg-sb-icon").toggleClass('fa-toggle-on'); |
| $("#tg-sb-icon").toggleClass('fa-toggle-off'); |
| }); |
| }); |
| </script> |
| |
| |
| </head> |
| <body> |
| <!-- Navigation --> |
| <nav class="navbar navbar-inverse navbar-static-top"> |
| <div class="container topnavlinks"> |
| <div class="navbar-header"> |
| <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| <a class="fa fa-home fa-lg navbar-brand" href="index.html"> <span class="projectTitle"> Eclipse Che Documentation</span></a> |
| </div> |
| <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> |
| <ul class="nav navbar-nav navbar-right"> |
| <!-- toggle sidebar button --> |
| <li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li> |
| <!-- entries without drop-downs appear here --> |
| |
| |
| |
| |
| |
| |
| |
| <li><a href="https://medium.com/eclipse-che-blog/" target="_blank">Blog</a></li> |
| |
| |
| |
| <li><a href="https://github.com/eclipse/che" target="_blank">Source Code</a></li> |
| |
| |
| |
| <!-- entries with drop-downs appear here --> |
| <!-- conditional logic to control which topnav appears for the audience defined in the configuration file.--> |
| |
| |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Support<b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| |
| |
| <li><a href="https://github.com/eclipse/che/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Akind%2Fbug" target="_blank">Known Bugs</a></li> |
| |
| |
| |
| <li><a href="https://github.com/eclipse/che/issues/new" target="_blank">File an Issue</a></li> |
| |
| |
| |
| <li><a href="https://stackoverflow.com/questions/tagged/eclipse-che" target="_blank">Che on StackOverflow</a></li> |
| |
| |
| </ul> |
| </li> |
| |
| |
| <!-- |
| <li> |
| |
| |
| |
| <a class="email" title="Submit feedback" href="#" onclick="javascript:window.location='mailto:?subject= feedback&body=I have some feedback about the Language Support page: ' + window.location.href;"><i class="fa fa-envelope-o"></i> Feedback</a> |
| |
| </li> |
| --> |
| |
| <!--comment out this block if you want to hide search--> |
| <li> |
| <!--start search--> |
| <div id="search-demo-container"> |
| <input type="text" id="search-input" placeholder="search..."> |
| <ul id="results-container"></ul> |
| </div> |
| <script src="js/jekyll-search.js" type="text/javascript"></script> |
| <script type="text/javascript"> |
| SimpleJekyllSearch.init({ |
| searchInput: document.getElementById('search-input'), |
| resultsContainer: document.getElementById('results-container'), |
| dataSource: 'search.json', |
| searchResultTemplate: '<li><a href="{url}" title="Language Support">{title}</a></li>', |
| noResultsText: 'No results found.', |
| limit: 10, |
| fuzzy: true, |
| }) |
| </script> |
| <!--end search--> |
| </li> |
| </ul> |
| </div> |
| </div> |
| <!-- /.container --> |
| </nav> |
| |
| <!-- Page Content --> |
| <div class="container"> |
| <div id="main"> |
| <!-- Content Row --> |
| <div class="row"> |
| |
| |
| <!-- Sidebar Column --> |
| <div class="col-md-3" id="tg-sb-sidebar"> |
| |
| |
| <ul id="mysidebar" class="nav"> |
| <li class="sidebarTitle"> </li> |
| |
| |
| |
| |
| |
| <li> |
| <a href="#">Overview</a> |
| <ul> |
| |
| |
| |
| <li><a href="index.html">Introduction</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="quick-start.html">Getting Started</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="single-multi-user.html">Single and Multi-User Flavors</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="infra-support.html">Supported Infrastructures</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Che on Docker</a> |
| <ul> |
| |
| |
| |
| <li><a href="docker-single-user.html">Docker - Single User</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="docker-multi-user.html">Docker - Multi User</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="docker-config.html">Docker - Configuration</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="docker-cli.html">Docker - CLI Reference</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Che on Kubernetes</a> |
| <ul> |
| |
| |
| |
| <li><a href="kubernetes-single-user.html">Kubernetes - Single User</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="kubernetes-multi-user.html">Kubernetes - Multi User</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="kubernetes-config.html">Kubernetes - Configuration</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="kubernetes-admin-guide.html">Kubernetes - Admin Guide</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Che on OpenShift</a> |
| <ul> |
| |
| |
| |
| <li><a href="openshift-single-user.html">OpenShift - Single User</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="openshift-multi-user.html">OpenShift - Multi User</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="openshift-config.html">OpenShift - Configuration</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="openshift-admin-guide.html">OpenShift - Admin Guide</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">User Management</a> |
| <ul> |
| |
| |
| |
| <li><a href="user-management.html">Authentication and Authorization</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="authentication.html">Security Model</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="permissions.html">Permissions</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="organizations.html">Organizations in UD</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="resource-management.html">Resource Management</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">User Guides</a> |
| <ul> |
| |
| |
| |
| <li><a href="creating-starting-workspaces.html">Creating and starting Workspaces</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="ide-projects.html">Projects</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="editor-code-assistance.html">Editor and Code-Assistance</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="dependency-management.html">Dependency Management</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="commands-ide-macro.html">Commands and IDE Macros</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="version-control.html">Version Control</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="debug.html">Debug</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Workspace Administration</a> |
| <ul> |
| |
| |
| |
| <li><a href="what-are-workspaces.html">Workspace Overview</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="stacks.html">Workspace - Stacks</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="recipes.html">Workspace - Recipes</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="servers.html">Workspace - Servers</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="installers.html">Workspace - Installers</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="volumes.html">Workspace - Volumes Mount</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="env-variables.html">Workspace - Environment Variables</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="projects.html">Workspace - Projects</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="workspaces-troubleshooting.html">Workspace - Troubleshooting</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="workspace-data-model.html">Workspace Data Model</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Portable Workspaces</a> |
| <ul> |
| |
| |
| |
| <li><a href="chedir-getting-started.html">Chedir - Getting Started</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="why-chedir.html">Chedir - Why Chedir?</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="chedir-installation.html">Chedir - Installation</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="chedir-project-setup.html">Chedir - Project Setup</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="chedir-up-and-down.html">Chedir - Up and Down</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="chefile.html">Chedir - Chefile</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="chedir-ssh.html">Chedir - SSH</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="factories-getting-started.html">Factory - Getting Started</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="creating-factories.html">Factory - Creating</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="factories_json_reference.html">Factory - JSON Reference</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Developer Guides</a> |
| <ul> |
| |
| |
| |
| <li><a href="framework-overview.html">Overview</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="rest-api.html">SDK - REST API</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="che-in-che-quickstart.html">SDK - Your First Plugin</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="build-reqs.html">SDK - Building Che</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="assemblies.html">SDK - Assemblies</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="logging.html">SDK - Logging</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="ide-extensions-gwt.html">SDK - GWT IDE Extensions</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="server-side-extensions.html">SDK - Server Side Extensions</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="custom-installers.html">SDK - Installers</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="project-types.html">SDK - Project Types</a></li> |
| |
| |
| |
| |
| |
| |
| <li class="active"><a href="language-servers.html">SDK - Language Support</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="parts.html">IDE UI: Parts</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="actions.html">IDE UI: Actions</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Dev Essentials</a> |
| <ul> |
| |
| |
| |
| <li><a href="guice.html">Dependency Injection</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="dto.html">Transport: DTO</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="json-rpc.html">Communication: JSON-RPC</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="handling-projects-in-plugins.html">Handling Projects in Plugins</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="dao.html">Persistence, DAO</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="properties.html">Properties</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <li> |
| <a href="#">Infrastructure and SPI</a> |
| <ul> |
| |
| |
| |
| <li><a href="spi_overview.html">Overview</a></li> |
| |
| |
| |
| |
| |
| |
| <li><a href="spi-implementation.html">Implementation Notes</a></li> |
| |
| |
| |
| |
| </ul> |
| </li> |
| |
| |
| |
| <!-- if you aren't using the accordion, uncomment this block: |
| <p class="external"> |
| <a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a> |
| </p> |
| --> |
| </ul> |
| |
| <!-- this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.--> |
| <script>$("li.active").parents('li').toggleClass("active");</script> |
| |
| </div> |
| |
| |
| |
| |
| <!-- Content Column --> |
| <div class="col-md-9" id="tg-sb-content"> |
| <div class="post-header"> |
| <h1 class="post-title-main">Language Support</h1> |
| </div> |
| |
| |
| |
| <div class="post-content"> |
| |
| |
| |
| |
| |
| <!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. --> |
| <script> |
| $( document ).ready(function() { |
| // Handler for .ready() called. |
| $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2' }); |
| /* this offset helps account for the space taken up by the floating toolbar. */ |
| $('#toc').on('click', 'a', function() { |
| var target = $(this.getAttribute('href')) |
| , scroll_target = target.offset().top |
| $(window).scrollTop(scroll_target - 10); |
| return false |
| }) |
| |
| }); |
| </script> |
| |
| <div id="toc"></div> |
| |
| |
| |
| |
| <!-- |
| |
| |
| --> |
| |
| <div class="sect1"> |
| <h2 id="overview">Overview</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>The Language Server Protocol is used between a tool (the client) and a language intelligence provider (the server) to integrate features like auto complete, goto definition, find references, etc.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You can learn more about the language server specification on the <a href="https://github.com/Microsoft/language-server-protocol">LSP GitHub page</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Currently Eclipse Che implements the <a href="https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md">3.x protocol version</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Note that, Eclipse Che also implements the snippet syntax used in VSCode. It is not versioned in the LSP specification, but the supported syntax is described <a href="https://github.com/Microsoft/vscode/blob/0ebd01213a65231f0af8187acaf264243629e4dc/src/vs/editor/contrib/snippet/browser/snippet.md">here</a>.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="adding-support-for-new-languages">Adding Support for New Languages</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>There are two approaches to add a new language server:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>via installer and launcher: this way a language server runs in the machine where the respective installer has been enabled</p> |
| </li> |
| <li> |
| <p>adding <a href="#ls-sidecars">language server as a sidecar</a> in workspace configuration - multi-machine recipe + server with required attributes</p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="general-concept">General Concept</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Language server integration is divided into 2 steps: an install followed by a separately triggered start. Language servers aren’t started when the agent starts. Instead they are started in a second step which can be triggered at any time. This is done to reduce resource consumption and reduce workspace startup time.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>The language server agent is launched when the workspace starts - its job is to install all dependencies and prepare the <code>bash</code> launcher file that will be used to start the language server.</p> |
| </li> |
| <li> |
| <p>The <a href="https://github.com/eclipse/che/blob/master/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/launcher/LanguageServerLauncher.java">launcher</a> is triggered and starts the language server. We suggest triggering the launcher when the user begins interacting with file types related to the language server. Once launched, the language server is registered with specific file types (covered in more detail below).</p> |
| </li> |
| </ol> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="adding-a-language-server-installer">Adding a Language Server Installer</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Follow the documentation on how to <a href="custom-installers.html">add new installer</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Examples of existed language server agents you can learn from:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="https://github.com/eclipse/che/tree/master/agents/ls-json">JSON</a></p> |
| </li> |
| <li> |
| <p><a href="https://github.com/eclipse/che/tree/master/agents/ls-php">PHP</a></p> |
| </li> |
| <li> |
| <p><a href="https://github.com/eclipse/che/tree/master/agents/ls-python">Python</a></p> |
| </li> |
| <li> |
| <p><a href="https://github.com/eclipse/che/tree/master/agents/ls-csharp">C#</a></p> |
| </li> |
| <li> |
| <p><a href="https://github.com/eclipse/che/tree/master/agents/ls-typescript">TypeScript</a></p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="adding-a-language-server-config">Adding a Language Server Config</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>In order to start/initialize a language server for the desired language, you need to implement <a href="https://github.com/eclipse/che/blob/master/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/LanguageServerConfig.java">LanguageServerConfig interface</a> which pretty much defines what needs to be accomplished to start a 'local' language server.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Here is how a typical LanguageServerConfig looks like: <a href="https://github.com/eclipse/che/blob/master/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/languageserver/ClangDLanguageServerConfig.java">Clangd</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Things to pay attention to:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><strong>REGEX</strong> defines regexp for desired files. It can be a path, all fines with certain extension or particular file names etc.</p> |
| </li> |
| <li> |
| <p><strong>launchScript</strong> is usually created by an installer script and contains command(s) to launch a language server in a stdio mode</p> |
| </li> |
| <li> |
| <p><strong>LANGUAGE_ID</strong> is defined in a guice module. See: <a href="https://github.com/eclipse/che/blob/master/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/inject/ClangModule.java">ClangdModule</a></p> |
| </li> |
| <li> |
| <p>add binding in <a href="https://github.com/eclipse/che/blob/master/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/inject/ClangModule.java#L37">guice module</a></p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>Installers are packaged into wsmaster, so you will need to add required dependencies there. LanguageServerConfigs are usually part of plugins packages with a workspace agent.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="ls-sidecars">LS-Sidecars</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>While the above approach works well for custom assemblies, i.e. you actually need to rebuild Che with a custom plugin that registers a new installer and a language server launcher, there is a mechanism to launch Language Servers in parallel containers/sidecars. This is what you need to do to add a new language server to your workspace as a sidecar.</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Build a Docker image in which language server is started in <code>ENTRYPOINT</code> or <code>CMD</code>. Note that some language servers support <code>tcp</code> arguments in their start syntax. Make sure that the language server acts like a server, rather than attempts to bind to a socket. The best way to check it is to run the image: <code>docker run -ti ${image}</code>. If the container starts, everything is fine, and if it exits immediately, you need to fix it.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>We recommend running language servers in <code>stdio</code> mode and use sockat as a proxy. Here’s an example of a Dockerfile that builds an image with TyperScript language server:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre># inherit an image with node.js and npm - runtime requirements for TypeScript LS |
| FROM eclipse/node |
| |
| # install socat |
| RUN sudo apt-get install socat -y && \ |
| sudo npm install -g typescript@2.5.3 typescript-language-server@0.1.4 |
| |
| # run socat that listens on port 4417 with exec command that starts LS |
| CMD socat TCP4-LISTEN:4417,reuseaddr,fork EXEC:"typescript-language-server --stdio"</pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Create a stack with a <a href="creating-starting-workspaces.html">custom recipe</a>: Create Workspace > Add Stack:</p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="yaml"><span class="key">services</span>: |
| <span class="key">typescript-ls-machine</span>: |
| <span class="key">image</span>: <span class="string"><span class="content">ls/image</span></span> |
| <span class="key">mem_limit</span>: <span class="string"><span class="content">1073741824</span></span> |
| <span class="key">dev-machine</span>: |
| <span class="key">image</span>: <span class="string"><span class="content">eclipse/ubuntu_jdk8</span></span> |
| <span class="key">mem_limit</span>: <span class="string"><span class="content">2147483648</span></span> |
| <span class="key">depends_on</span>: |
| - <span class="string"><span class="content">typescript-ls-machine</span></span></code></pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>In User Dashboard, go to <strong>Workspaces > Your Workspace > Config</strong>, and add a server for typescript-ls-machine in <code>servers:[]</code></p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="json"><span class="key"><span class="delimiter">"</span><span class="content">servers</span><span class="delimiter">"</span></span>: { |
| <span class="key"><span class="delimiter">"</span><span class="content">ls</span><span class="delimiter">"</span></span>: { |
| <span class="key"><span class="delimiter">"</span><span class="content">attributes</span><span class="delimiter">"</span></span>: { |
| <span class="key"><span class="delimiter">"</span><span class="content">id</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">go-ls</span><span class="delimiter">"</span></span>, |
| <span class="key"><span class="delimiter">"</span><span class="content">internal</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>, |
| <span class="key"><span class="delimiter">"</span><span class="content">type</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">ls</span><span class="delimiter">"</span></span>, |
| <span class="key"><span class="delimiter">"</span><span class="content">languageRegexes</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">[ {</span><span class="char">\"</span><span class="content">languageId</span><span class="char">\"</span><span class="content">:</span><span class="char">\"</span><span class="content">golang</span><span class="char">\"</span><span class="content">, </span><span class="char">\"</span><span class="content">regex</span><span class="char">\"</span><span class="content">:</span><span class="char">\"</span><span class="content">.*</span><span class="char">\\</span><span class="char">\\</span><span class="content">.go$</span><span class="char">\"</span><span class="content">}]</span><span class="delimiter">"</span></span>, |
| }, |
| <span class="key"><span class="delimiter">"</span><span class="content">protocol</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">tcp</span><span class="delimiter">"</span></span>, |
| <span class="key"><span class="delimiter">"</span><span class="content">port</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">4417</span><span class="delimiter">"</span></span> |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><strong>ls</strong> - server name - can be any string</p> |
| </li> |
| <li> |
| <p><strong>attributes.id</strong> - can be any unique identifier</p> |
| </li> |
| <li> |
| <p><strong>attributes.internal</strong> - <code>true</code>. Mandatory! Used to get an internal link to server</p> |
| </li> |
| <li> |
| <p><strong>attributes.type</strong> - <code>ls</code>. Mandatory. Used by the IDE client to identify a server as a language server</p> |
| </li> |
| <li> |
| <p><strong>languageRegexes.languageId</strong> - language identifier, either one of those supported in [LSP specification] (<a href="https://microsoft.github.io/language-server-protocol/specification#textdocumentitem" class="bare">https://microsoft.github.io/language-server-protocol/specification#textdocumentitem</a>) or own.</p> |
| </li> |
| <li> |
| <p><strong>languageRegexes.regex</strong> - regexp expression to match either extension or file name + extension, or whatever match you need (for example, path, say, initialize language server only for config/config.xml files). Pay attention to regexp syntax since errors are not validated by server, and bad regexp will result in the client ignoring your files.</p> |
| </li> |
| <li> |
| <p>In User Dashboard, go to Workspaces > Your Workspace > Volumes, add a volume for <strong>each machine</strong>. The two volumes have to share the same name (for example, <code>projects</code>) and path <code>/projects</code> so that they actually share one volume. This way a language server container has access to workspace project types.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="/che/docs/images/extensibility/lang_servers/volumes_ls.png" alt="volumes ls"> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Start a workspace. Open a file with one of the extensions bound to a language ID. Che client will attempt to connect to language server over tcp socket. This data is retrieved from workspace runtime. Language server process should be available at the port declared in the server. You can either use Socat or launch a language server in tcp mode if it supports it. It is your Docker image’s responsibility to launch the language server. Adding <code>ENTRYPOINT</code> or <code>CMD</code> instruction should work well.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>See: <a href="https://gist.githubusercontent.com/eivantsov/4e86b4d51cf23fbd8fd68410170f06e3/raw/e9c1edc600d0ff82e15d2d68d2ac5c6304a981b9/go-workspace.json">Sample configuration</a> of a workspace featuring 2 machines, one of which is a language server machine.</p> |
| </div> |
| </div> |
| </div> |
| |
| <div class="tags"> |
| |
| <b>Tags: </b> |
| |
| |
| |
| <a href="tag_extensions.html" class="btn btn-default navbar-btn cursorNorm" role="button">extensions</a> |
| |
| |
| |
| <a href="tag_assembly.html" class="btn btn-default navbar-btn cursorNorm" role="button">assembly</a> |
| |
| |
| |
| <a href="tag_dev-docs.html" class="btn btn-default navbar-btn cursorNorm" role="button">dev-docs</a> |
| |
| |
| |
| </div> |
| |
| <!-- |
| --> |
| |
| </div> |
| |
| <hr class="shaded"/> |
| |
| <footer> |
| <div class="row"> |
| <div class="col-lg-12 footer"> |
| Eclipse Che - Documentation <br/> |
| Site last generated: Sep 13, 2018 <br/> |
| <hr> |
| <a href="http://www.eclipse.org" target="_blank">Eclipse Foundation</a><br/> |
| <a href="http://www.eclipse.org/legal/privacy.php" target="_blank">Privacy Policy</a><br/> |
| <a href="http://www.eclipse.org/legal/termsofuse.php" target="_blank">Terms of Use</a><br/> |
| <a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">Eclipse Public License</a><br/> |
| <a href="http://www.eclipse.org/legal" target="_blank">Legal Resources</a><br/> |
| </div> |
| </div> |
| </footer> |
| |
| |
| |
| |
| <!-- /.row --> |
| </div> |
| <!-- /.container --> |
| </div> |
| <!-- /#main --> |
| </div> |
| |
| </body> |
| |
| </html> |