diff --git a/agents/ls-clang/pom.xml b/agents/ls-clang/pom.xml
new file mode 100644
index 0000000000..d22dd2291d
--- /dev/null
+++ b/agents/ls-clang/pom.xml
@@ -0,0 +1,23 @@
+
+
+
+ 4.0.0
+
+ che-agents-parent
+ org.eclipse.che
+ 6.1.0-SNAPSHOT
+
+ ls-clang-agent
+ Language Server Clang Agent
+
diff --git a/agents/ls-clang/src/main/resources/installers/1.0.0/org.eclipse.che.ls.clang.json b/agents/ls-clang/src/main/resources/installers/1.0.0/org.eclipse.che.ls.clang.json
new file mode 100644
index 0000000000..0cbe6283df
--- /dev/null
+++ b/agents/ls-clang/src/main/resources/installers/1.0.0/org.eclipse.che.ls.clang.json
@@ -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": {}
+ }
diff --git a/agents/ls-clang/src/main/resources/installers/1.0.0/org.eclipse.che.ls.clang.script.sh b/agents/ls-clang/src/main/resources/installers/1.0.0/org.eclipse.che.ls.clang.script.sh
new file mode 100644
index 0000000000..0a5e517b57
--- /dev/null
+++ b/agents/ls-clang/src/main/resources/installers/1.0.0/org.eclipse.che.ls.clang.script.sh
@@ -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}
diff --git a/agents/pom.xml b/agents/pom.xml
index 1fb3e32f11..5f9b6beafb 100644
--- a/agents/pom.xml
+++ b/agents/pom.xml
@@ -39,5 +39,6 @@
test-ls
ls-yaml
ls-camel
+ ls-clang
diff --git a/assembly/assembly-wsagent-war/pom.xml b/assembly/assembly-wsagent-war/pom.xml
index 9fad61aed3..303275d2c9 100644
--- a/assembly/assembly-wsagent-war/pom.xml
+++ b/assembly/assembly-wsagent-war/pom.xml
@@ -39,6 +39,10 @@
org.eclipse.che.plugin
che-plugin-camel-server
+
+ org.eclipse.che.plugin
+ che-plugin-clangd-lang-server
+
org.eclipse.che.plugin
che-plugin-composer-server
diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml
index f7bcbcb9ac..c908477d46 100644
--- a/assembly/assembly-wsmaster-war/pom.xml
+++ b/assembly/assembly-wsmaster-war/pom.xml
@@ -88,6 +88,10 @@
org.eclipse.che
ls-camel-agent
+
+ org.eclipse.che
+ ls-clang-agent
+
org.eclipse.che
ls-csharp-agent
diff --git a/plugins/plugin-clangd/che-plugin-clangd-lang-server/pom.xml b/plugins/plugin-clangd/che-plugin-clangd-lang-server/pom.xml
new file mode 100644
index 0000000000..a3547bc83a
--- /dev/null
+++ b/plugins/plugin-clangd/che-plugin-clangd-lang-server/pom.xml
@@ -0,0 +1,68 @@
+
+
+
+ 4.0.0
+
+ che-plugin-clangd-parent
+ org.eclipse.che.plugin
+ 6.1.0-SNAPSHOT
+
+ che-plugin-clangd-lang-server
+ Che Plugin :: ClangD C/C++ :: Extension Server
+
+ false
+
+
+
+ com.google.inject
+ guice
+
+
+ com.google.inject.extensions
+ guice-multibindings
+
+
+ org.eclipse.che.core
+ che-core-api-languageserver
+
+
+ org.eclipse.che.core
+ che-core-api-languageserver-shared
+
+
+ org.eclipse.che.core
+ che-core-api-project
+
+
+ org.eclipse.che.core
+ che-core-commons-inject
+
+
+ org.eclipse.che.plugin
+ che-plugin-cpp-lang-server
+
+
+ org.eclipse.lsp4j
+ org.eclipse.lsp4j
+
+
+ org.eclipse.lsp4j
+ org.eclipse.lsp4j.jsonrpc
+
+
+ org.slf4j
+ slf4j-api
+
+
+
diff --git a/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/inject/ClangModule.java b/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/inject/ClangModule.java
new file mode 100644
index 0000000000..0698a35143
--- /dev/null
+++ b/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/inject/ClangModule.java
@@ -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 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);
+ }
+}
diff --git a/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/languageserver/ClangDLanguageServerLauncher.java b/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/languageserver/ClangDLanguageServerLauncher.java
new file mode 100644
index 0000000000..c6a4219f27
--- /dev/null
+++ b/plugins/plugin-clangd/che-plugin-clangd-lang-server/src/main/java/org/eclipse/plugin/clangd/languageserver/ClangDLanguageServerLauncher.java
@@ -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 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;
+ }
+}
diff --git a/plugins/plugin-clangd/pom.xml b/plugins/plugin-clangd/pom.xml
new file mode 100644
index 0000000000..22dec1a81d
--- /dev/null
+++ b/plugins/plugin-clangd/pom.xml
@@ -0,0 +1,39 @@
+
+
+
+ 4.0.0
+
+ che-plugin-parent
+ org.eclipse.che.plugin
+ 6.1.0-SNAPSHOT
+ ../pom.xml
+
+ che-plugin-clangd-parent
+ pom
+ Che Plugin :: Clangd :: Parent
+
+ che-plugin-clangd-lang-server
+
+
+
+
+
+ org.eclipse.che.core
+ che-core-api-dto-maven-plugin
+ ${project.version}
+
+
+
+
+
diff --git a/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/codeassist/CompletionItemBasedCompletionProposal.java b/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/codeassist/CompletionItemBasedCompletionProposal.java
index ff2a70ed37..cc1ec293be 100644
--- a/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/codeassist/CompletionItemBasedCompletionProposal.java
+++ b/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/editor/codeassist/CompletionItemBasedCompletionProposal.java
@@ -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()));
diff --git a/plugins/pom.xml b/plugins/pom.xml
index dc802733fd..d5601c2d0b 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -59,5 +59,6 @@
plugin-pullrequest-parent
plugin-yaml
plugin-camel
+ plugin-clangd
diff --git a/pom.xml b/pom.xml
index 727bf5dd2d..ca2f61b6b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -187,6 +187,11 @@
ls-camel-agent
${che.version}
+
+ org.eclipse.che
+ ls-clang-agent
+ ${che.version}
+
org.eclipse.che
ls-csharp-agent
@@ -1028,6 +1033,11 @@
che-plugin-camel-server
${che.version}
+
+ org.eclipse.che.plugin
+ che-plugin-clangd-lang-server
+ ${che.version}
+
org.eclipse.che.plugin
che-plugin-composer-ide