ClangD support for Eclipse Che (#7516)

* ClangD ported to Che6

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>

* removed launch scripts

* added scripts for ubuntu and debian

* moved command to launch script. hide error messages

* fixing wrong positioning of code completion items

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>

* removed comments, updated script for other OS

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>

* updated language server script

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>

* added new line

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>

* updated version

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>

* fixed newline

Signed-off-by: Hanno Kolvenbach <kolvenbach@silexica.com>
6.19.x
Hanno Kolvenbach 2018-02-15 16:37:26 +01:00 committed by Vitalii Parfonov
parent 2b9c7413a3
commit 0a7cf2eb3a
13 changed files with 499 additions and 1 deletions

23
agents/ls-clang/pom.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2018 Red Hat, Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-agents-parent</artifactId>
<groupId>org.eclipse.che</groupId>
<version>6.1.0-SNAPSHOT</version>
</parent>
<artifactId>ls-clang-agent</artifactId>
<name>Language Server Clang Agent</name>
</project>

View File

@ -0,0 +1,8 @@
{
"id": "org.eclipse.che.ls.clangd",
"version": "1.0.0",
"name": "Clangd language server",
"description": "Clangd intellisense for C/C++ projects.",
"dependencies": [],
"properties": {}
}

View File

@ -0,0 +1,172 @@
#
# Copyright (c) 2012-2018 Red Hat, Inc.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
is_current_user_root() {
test "$(id -u)" = 0
}
is_current_user_sudoer() {
sudo -n true > /dev/null 2>&1
}
set_sudo_command() {
if is_current_user_sudoer && ! is_current_user_root; then SUDO="sudo -E"; else unset SUDO; fi
}
set_sudo_command
unset PACKAGES
command -v tar >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" tar"; }
command -v curl >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" curl"; }
command -v wget >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" wget"; }
CHE_DIR=$HOME/che
LS_DIR=${CHE_DIR}/ls-clangd
LS_LAUNCHER=${LS_DIR}/launch.sh
CLANGD_VERSION=6.0
CLANGD_BINARY=clangd-${CLANGD_VERSION}
if [ -f /etc/centos-release ]; then
FILE="/etc/centos-release"
LINUX_TYPE=$(cat $FILE | awk '{print $1}')
elif [ -f /etc/redhat-release ]; then
FILE="/etc/redhat-release"
LINUX_TYPE=$(cat $FILE | cut -c 1-8)
else
FILE="/etc/os-release"
LINUX_TYPE=$(cat $FILE | grep ^ID= | tr '[:upper:]' '[:lower:]')
LINUX_VERSION=$(cat $FILE | grep ^VERSION_ID=)
fi
MACHINE_TYPE=$(uname -m)
mkdir -p ${CHE_DIR}
mkdir -p ${LS_DIR}
#########################
#### Install packages ###
#########################
#
# Red Hat Enterprise Linux 7
############################
if echo ${LINUX_TYPE} | grep -qi "rhel"; then
test "${PACKAGES}" = "" || {
${SUDO} yum install ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
echo "LLVM / Clang ${CLANGD_VERSION} not supported on Red Hat Enterprise Linux 7.";
exit 1;
}
# Red Hat Enterprise Linux 6
############################
elif echo ${LINUX_TYPE} | grep -qi "Red Hat"; then
test "${PACKAGES}" = "" || {
${SUDO} yum install ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
echo "LLVM / Clang ${CLANGD_VERSION} not supported on Red Hat Enterprise Linux 6.";
exit 1;
}
# Ubuntu 14.04 16.04 / Linux Mint 17
####################################
elif echo ${LINUX_TYPE} | grep -qi "ubuntu"; then
test "${PACKAGES}" = "" || {
${SUDO} apt-get update;
${SUDO} apt-get -y install ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
{
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -;
# Fingerprint: 6084 F3CF 814B 57C1 CF12 EFD5 15CF 4D18 AF4F 7421
${SUDO} apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-${CLANGD_VERSION} main";
};
${SUDO} apt-get update;
${SUDO} apt-get install -y clang-tools-${CLANGD_VERSION};
${SUDO} ln -s /usr/bin/clangd-${CLANGD_VERSION} /usr/bin/clangd
}
# Debian 8
##########
elif echo ${LINUX_TYPE} | grep -qi "debian"; then
test "${PACKAGES}" = "" || {
${SUDO} apt-get update;
${SUDO} apt-get -y install ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
{
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -;
# Fingerprint: 6084 F3CF 814B 57C1 CF12 EFD5 15CF 4D18 AF4F 7421
${SUDO} apt-add-repository "deb http://apt.llvm.org/jessie/ llvm-toolchain-jessie-${CLANGD_VERSION} main";
};
${SUDO} apt-get update;
${SUDO} apt-get install -y clang-tools-${CLANGD_VERSION};
${SUDO} ln -s /usr/bin/clangd-${CLANGD_VERSION} /usr/bin/clangd
}
## Fedora 23
############
elif echo ${LINUX_TYPE} | grep -qi "fedora"; then
test "${PACKAGES}" = "" || {
${SUDO} dnf -y install ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
echo "LLVM / Clang ${CLANGD_VERSION} not supported on Fedora 23.";
exit 1;
}
## CentOS 7.1 & Oracle Linux 7.1
################################
elif echo ${LINUX_TYPE} | grep -qi "centos"; then
test "${PACKAGES}" = "" || {
${SUDO} yum -y install ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
echo "LLVM / Clang ${CLANGD_VERSION} not supported on CentOS.";
exit 1;
}
## openSUSE 13.2
################
elif echo ${LINUX_TYPE} | grep -qi "opensuse"; then
test "${PACKAGES}" = "" || {
${SUDO} zypper install -y ${PACKAGES};
}
command -v ${CLANGD_BINARY} >/dev/null 2>&1 || {
echo "LLVM / Clang ${CLANGD_VERSION} not supported on OpenSUSE 13.2.";
exit 1;
}
else
>&2 echo "Unrecognized Linux Type"
>&2 cat $FILE
exit 1
fi
#########################
### Install Clangd LS ###
#########################
touch ${LS_LAUNCHER}
chmod +x ${LS_LAUNCHER}
echo "tee -a /home/user/clangd-input.log | clangd -disable-symbolication -pretty -resource-dir=/usr/include/ -enable-snippets | tee -a /home/user/clangd-output.log" > ${LS_LAUNCHER}

View File

@ -39,5 +39,6 @@
<module>test-ls</module>
<module>ls-yaml</module>
<module>ls-camel</module>
<module>ls-clang</module>
</modules>
</project>

View File

@ -39,6 +39,10 @@
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-camel-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-clangd-lang-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-composer-server</artifactId>

View File

@ -88,6 +88,10 @@
<groupId>org.eclipse.che</groupId>
<artifactId>ls-camel-agent</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che</groupId>
<artifactId>ls-clang-agent</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che</groupId>
<artifactId>ls-csharp-agent</artifactId>

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2018 Red Hat, Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-plugin-clangd-parent</artifactId>
<groupId>org.eclipse.che.plugin</groupId>
<version>6.1.0-SNAPSHOT</version>
</parent>
<artifactId>che-plugin-clangd-lang-server</artifactId>
<name>Che Plugin :: ClangD C/C++ :: Extension Server</name>
<properties>
<findbugs.failonerror>false</findbugs.failonerror>
</properties>
<dependencies>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-languageserver</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-languageserver-shared</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-project</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-inject</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-cpp-lang-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.lsp4j</groupId>
<artifactId>org.eclipse.lsp4j</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.lsp4j</groupId>
<artifactId>org.eclipse.lsp4j.jsonrpc</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.plugin.clangd.inject;
import static java.util.Arrays.asList;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher;
import org.eclipse.che.api.languageserver.shared.model.LanguageDescription;
import org.eclipse.che.api.project.server.type.ProjectTypeDef;
import org.eclipse.che.inject.DynaModule;
import org.eclipse.che.plugin.cpp.projecttype.CProjectType;
import org.eclipse.che.plugin.cpp.projecttype.CppProjectType;
import org.eclipse.plugin.clangd.languageserver.ClangDLanguageServerLauncher;
/** @author Alexander Andrienko */
/** @author Hanno Kolvenbach */
@DynaModule
public class ClangModule extends AbstractModule {
public static final String LANGUAGE_ID = "clangd";
private static final String[] EXTENSIONS =
new String[] {
"c", "h", "cpp", "hpp", "cc", "hh", "hxx", "cxx", "C", "H", "CPP", "HPP", "CC", "HH", "CXX",
"HXX"
};
private static final String MIME_TYPE = "text/x-cpp";
@Override
protected void configure() {
Multibinder<ProjectTypeDef> projectTypeMultibinder =
Multibinder.newSetBinder(binder(), ProjectTypeDef.class);
projectTypeMultibinder.addBinding().to(CProjectType.class);
projectTypeMultibinder.addBinding().to(CppProjectType.class);
Multibinder.newSetBinder(binder(), LanguageServerLauncher.class)
.addBinding()
.to(ClangDLanguageServerLauncher.class);
LanguageDescription description = new LanguageDescription();
description.setFileExtensions(asList(EXTENSIONS));
description.setLanguageId(LANGUAGE_ID);
description.setMimeType(MIME_TYPE);
Multibinder.newSetBinder(binder(), LanguageDescription.class)
.addBinding()
.toInstance(description);
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.plugin.clangd.languageserver;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import org.eclipse.che.api.languageserver.exception.LanguageServerException;
import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher;
import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncherTemplate;
import org.eclipse.che.api.languageserver.registry.DocumentFilter;
import org.eclipse.che.api.languageserver.registry.LanguageServerDescription;
import org.eclipse.che.api.languageserver.registry.ServerInitializerObserver;
import org.eclipse.che.api.languageserver.service.LanguageServiceUtils;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageServer;
import org.eclipse.plugin.clangd.inject.ClangModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** @author Alexander Andrienko */
/** @author Hanno Kolvenbach */
@Singleton
public class ClangDLanguageServerLauncher extends LanguageServerLauncherTemplate
implements ServerInitializerObserver {
private static final LanguageServerDescription DESCRIPTION = createServerDescription();
private static final String REGEX = ".*\\.(c|h|cc|hh|cpp|hpp|cxx|hxx|C|H|CC|HH|CPP|HPP|CXX|HXX)";
private final Path launchScript;
private static final Logger LOG = LoggerFactory.getLogger(ClangDLanguageServerLauncher.class);
@Inject
public ClangDLanguageServerLauncher() {
launchScript = Paths.get(System.getenv("HOME"), "che/ls-clangd/launch.sh");
}
@Override
public boolean isAbleToLaunch() {
return Files.exists(launchScript);
}
@Override
protected LanguageServer connectToLanguageServer(
Process languageServerProcess, LanguageClient client) throws LanguageServerException {
Launcher<LanguageServer> launcher =
Launcher.createLauncher(
client,
LanguageServer.class,
languageServerProcess.getInputStream(),
languageServerProcess.getOutputStream());
launcher.startListening();
return launcher.getRemoteProxy();
}
protected Process startLanguageServerProcess(String projectPath) throws LanguageServerException {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(new File(LanguageServiceUtils.removeUriScheme(projectPath)));
processBuilder.command(launchScript.toString()).inheritIO();
processBuilder.redirectInput(ProcessBuilder.Redirect.PIPE);
processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
try {
return processBuilder.start();
} catch (IOException e) {
throw new LanguageServerException("Can't start ClangD language server", e);
}
}
@Override
public void onServerInitialized(
LanguageServerLauncher launcher,
LanguageServer server,
ServerCapabilities capabilities,
String projectPath) {
LOG.debug(projectPath);
LOG.debug("clangd language server initialized");
}
@Override
public LanguageServerDescription getDescription() {
return DESCRIPTION;
}
private static LanguageServerDescription createServerDescription() {
LanguageServerDescription description =
new LanguageServerDescription(
"org.eclipse.che.plugin.clangd.languageserver",
null,
Arrays.asList(new DocumentFilter(ClangModule.LANGUAGE_ID, REGEX, null)));
return description;
}
}

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2018 Red Hat, Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-plugin-parent</artifactId>
<groupId>org.eclipse.che.plugin</groupId>
<version>6.1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>che-plugin-clangd-parent</artifactId>
<packaging>pom</packaging>
<name>Che Plugin :: Clangd :: Parent</name>
<modules>
<module>che-plugin-clangd-lang-server</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto-maven-plugin</artifactId>
<version>${project.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -232,7 +232,7 @@ public class CompletionItemBasedCompletionProposal implements CompletionProposal
new TextEdit(
newRange(
cursorPosition.getLine(),
cursorPosition.getCharacter() - offset,
cursorPosition.getCharacter() - currentWord.length(),
cursorPosition.getLine(),
cursorPosition.getCharacter()),
completionItem.getInsertText()));

View File

@ -59,5 +59,6 @@
<module>plugin-pullrequest-parent</module>
<module>plugin-yaml</module>
<module>plugin-camel</module>
<module>plugin-clangd</module>
</modules>
</project>

10
pom.xml
View File

@ -187,6 +187,11 @@
<artifactId>ls-camel-agent</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che</groupId>
<artifactId>ls-clang-agent</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che</groupId>
<artifactId>ls-csharp-agent</artifactId>
@ -1028,6 +1033,11 @@
<artifactId>che-plugin-camel-server</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-clangd-lang-server</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.plugin</groupId>
<artifactId>che-plugin-composer-ide</artifactId>