| --- |
| layout: post |
| title: LSP Client demo - (ba)sh language server |
| date: '2019-08-17T15:25:14+00:00' |
| categories: netbeans |
| --- |
| <p>Below is a scenario by Jan Lahoda, the creator of LSP integration for Apache NetBeans, for how to integrate the bash language server with Apache NetBeans, including syntax highlighting.</p>
|
|
|
| <h3>Setting Up</h3>
|
|
|
| <ol>
|
|
|
| <li><p>Install npm (and node.js). On Ubuntu, e.g., do "apt install npm", though something different will be needed on Mac OS X.</p></li>
|
|
|
| <li><p>Create a directory in which we are going to work, have a terminal opened in that directory.</p></li>
|
|
|
| <li><p>Install the bash-language-server:</p>
|
|
|
| <pre>npm install bash-language-server</pre>
|
|
|
| <p>On Mac OSX:</p>
|
|
|
| <pre>npm install bash-language-server --unsafe-perm</pre>
|
|
|
| <p>This will install the server into the current directory.</p>
|
|
|
| </li>
|
|
|
| <li><p>Try the bash server:</p>
|
|
|
| <pre>./node_modules/bash-language-server/bin/main.js --help</pre>
|
|
|
| <p>You should see something like this:</p>
|
|
|
| <pre>Usage:
|
| bash-language-server start
|
| bash-language-server -h | --help
|
| bash-language-server -v | --version</pre>
|
|
|
| </li>
|
|
|
| <li>
|
|
|
| <p>Create a NetBeans module. Create a File Type (Module Development/File Type), mime type: text/sh, file extension: sh</p>
|
|
|
| </li>
|
|
|
| </ol>
|
|
|
| <h3>Syntax Coloring via TextMate</h3>
|
|
|
| <ol>
|
|
|
| <li>
|
|
|
| <p>Download the TextMate grammar file here, and put it alongside the newly created DataObject:</p>
|
|
|
| <p><a href="https://raw.githubusercontent.com/microsoft/vscode/master/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json">https://raw.githubusercontent.com/microsoft/vscode/master/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json</a></p>
|
|
|
| </li>
|
|
|
| <li>
|
|
|
| <p>
|
| Add "TextMate Lexer" as a dependency of the module.
|
| </p>
|
|
|
| </li>
|
|
|
| <li><p>Into the DataObject add this annotation:</p>
|
|
|
| <pre>@GrammarRegistration(grammar="shell-unix-bash.tmLanguage.json", mimeType="text/sh")</pre>
|
|
|
| <p>GrammarRegistration is:</p>
|
|
|
| <pre>import org.netbeans.modules.textmate.lexer.api.GrammarRegistration;</pre>
|
|
|
| </li>
|
|
|
| </ol>
|
|
|
| <p>This should lead to syntax highlighted source for .sh bash files taken from the TextMate grammar file.</p>
|
|
|
|
|
| <h3>Language Support via the Language Server</h3>
|
|
|
| <p>Next, we need to add language support using the language server.</p>
|
|
|
| <ol>
|
|
|
| <li>
|
|
|
| <p>Add "LSP Client" and "MIME Lookup API" as dependencies of the module.</p>
|
|
|
| </li>
|
|
|
| <li>
|
|
|
| <p>Create a new class, ShellClient, in the module, put this into it, (replacing "<path-to-bash-language-server>" with the absolute path to "node_modules/bash-language-server"):</p>
|
|
|
| <pre>import java.io.IOException;
|
| import org.netbeans.api.editor.mimelookup.MimeRegistration;
|
| import org.netbeans.modules.lsp.client.spi.LanguageServerProvider;
|
| import org.openide.util.Exceptions;
|
| import org.openide.util.Lookup;
|
|
|
| @MimeRegistration(mimeType="text/sh", service=LanguageServerProvider.class)
|
| public class ShellClient implements LanguageServerProvider {
|
|
|
| @Override
|
| public LanguageServerDescription startServer(Lookup lkp) {
|
| try {
|
| Process p = new ProcessBuilder("<path-to-bash-language-server>/bin/main.js", "start").start();
|
| return LanguageServerDescription.create(p.getInputStream(), p.getOutputStream(), p);
|
| } catch (IOException ex) {
|
| Exceptions.printStackTrace(ex);
|
| return null;
|
| }
|
| }
|
|
|
| }</pre>
|
|
|
| <p>You may need to explicitly call node in the above code, i.e., as follows:</p>
|
|
|
| <pre>Process p = new ProcessBuilder(
|
| "/usr/local/bin/node",
|
| "<path-to-bash-language-server>/bin/main.js",
|
| "start").start();</pre>
|
|
|
| </li>
|
|
|
| <li>
|
|
|
| <p>Build and start the module.</p>
|
|
|
| </li>
|
|
|
| </ol>
|
|
|
| <p>Caveat: the language server is started only for files that are inside a project, so create (any) new project, and inside the project, put a shell file. E.g. copy "bin/netbeans" as "test.sh" into the project. Open it in the editor - there should be syntax highlighting, Navigator, and code completion should show something, etc.</p> |