diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 3272bf1..94a25f7 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -2,6 +2,5 @@
-
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0568aa3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+# C/C++ very basic support for IntelliJ IDEA CE
+
+... or how to make an IJ IDEA a little VSCode...
+
+## Includes
+- making new C or C++ file (e.g., in empty project)
+- syntax highlighting is actually provided by IJ itself;
+- refactoring, code analysis, advanced types of highlighting is provided with Language Server Protocol via lsp4ij plugin from Redhat.
+
+## Not (yet) implemented
+- CMake, make, ninja any project build support (just use Terminal...);
+- STM32 (or any other embedded C) projects
+- choosing various language standards for Clangd
+- any additional checks except the clangd provides by default;
+
+## Additional requirements
+- clangd visible through PATH
+- clang/clang++ for compiling projects manually
+
+## How to start
+
+Install plugin >> Restart IDE
+
+Empty project >> New file >> New C (or C++) file
+
+Enjoy!
diff --git a/build.gradle.kts b/build.gradle.kts
index e2d6415..8a7111f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,7 +5,7 @@ plugins {
}
group = "com.gregorybednov"
-version = "1.0.0"
+version = "1.0.1"
repositories {
mavenCentral()
diff --git a/src/main/kotlin/org/gregorybednov/NewCFileAction.kt b/src/main/kotlin/org/gregorybednov/NewCFileAction.kt
new file mode 100644
index 0000000..2abbe19
--- /dev/null
+++ b/src/main/kotlin/org/gregorybednov/NewCFileAction.kt
@@ -0,0 +1,25 @@
+package org.gregorybednov
+
+import com.intellij.ide.actions.CreateFileFromTemplateAction
+import com.intellij.ide.actions.CreateFileFromTemplateDialog
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiDirectory
+import org.gregorybednov.clsp.CIcon
+
+
+class NewCFileAction :
+ CreateFileFromTemplateAction("C File", "Creates new C file", CIcon.FILE ) {
+ override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
+ builder
+ .setTitle("New C File")
+ .addKind("My file", CIcon.FILE, "DefaultTemplate.c")
+ }
+
+ override fun getActionName(directory: PsiDirectory?, newName: String, templateName: String?): String {
+ return "C File"
+ }
+
+ override fun getDefaultTemplateProperty(): String {
+ return "DefaultTemplate.c";
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/org/gregorybednov/NewCppFileAction.kt b/src/main/kotlin/org/gregorybednov/NewCppFileAction.kt
new file mode 100644
index 0000000..18e8c03
--- /dev/null
+++ b/src/main/kotlin/org/gregorybednov/NewCppFileAction.kt
@@ -0,0 +1,26 @@
+package org.gregorybednov
+
+import com.intellij.ide.actions.CreateFileFromTemplateAction
+import com.intellij.ide.actions.CreateFileFromTemplateDialog
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiDirectory
+import org.gregorybednov.clsp.CIcon
+import org.gregorybednov.clsp.CppIcon
+
+
+class NewCppFileAction :
+ CreateFileFromTemplateAction("C++ File", "Creates new C++ file", CppIcon.FILE ) {
+ override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
+ builder
+ .setTitle("New C++ File")
+ .addKind("My file", CIcon.FILE, "DefaultTemplate.cpp")
+ }
+
+ override fun getActionName(directory: PsiDirectory?, newName: String, templateName: String?): String {
+ return "C++ File"
+ }
+
+ override fun getDefaultTemplateProperty(): String {
+ return "DefaultTemplate.cpp";
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/org/gregorybednov/clsp/CLanguage.kt b/src/main/kotlin/org/gregorybednov/clsp/CLanguage.kt
new file mode 100644
index 0000000..ea844fd
--- /dev/null
+++ b/src/main/kotlin/org/gregorybednov/clsp/CLanguage.kt
@@ -0,0 +1,65 @@
+package org.gregorybednov.clsp
+
+import com.intellij.execution.configurations.GeneralCommandLine
+import com.intellij.lang.Language
+import com.intellij.notification.NotificationGroupManager
+import com.intellij.notification.NotificationType
+import com.intellij.openapi.fileTypes.LanguageFileType
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.IconLoader.getIcon
+import com.intellij.util.EnvironmentUtil
+import com.redhat.devtools.lsp4ij.LanguageServerFactory
+import com.redhat.devtools.lsp4ij.LanguageServerManager
+import com.redhat.devtools.lsp4ij.server.OSProcessStreamConnectionProvider
+import com.redhat.devtools.lsp4ij.server.StreamConnectionProvider
+import javax.swing.Icon
+import org.jetbrains.annotations.NotNull
+import java.io.File
+import java.nio.file.Paths
+import kotlin.io.path.pathString
+
+object CLanguage : Language("C") {
+ private fun readResolve(): Any = CLanguage
+ val INSTANCE: CLanguage = CLanguage
+}
+
+object CIcon {
+ val FILE: Icon = getIcon("/icons/clogo.svg", CIcon::class.java)
+}
+
+class CFileType private constructor() : LanguageFileType(CLanguage.INSTANCE) {
+ override fun getName(): String { return "C File" }
+ override fun getDescription(): String { return "C language file" }
+ override fun getDefaultExtension(): String { return "c" }
+ override fun getIcon(): Icon { return CIcon.FILE }
+ companion object { val INSTANCE: CFileType = CFileType() }
+}
+
+class CLanguageServer(project: Project) : OSProcessStreamConnectionProvider() {
+ private fun findExecutableInPATH(executable: String) =
+ EnvironmentUtil.getEnvironmentMap().values.flatMap { it.split(File.pathSeparator) }
+ .map { File(Paths.get(it, executable).pathString) }.find { it.exists() && it.canExecute() }?.path
+
+ init {
+ val clangdPath = findExecutableInPATH("clangd")
+ if (clangdPath.isNullOrEmpty()) {
+ NotificationGroupManager.getInstance().getNotificationGroup("C/C++ notifications").createNotification(
+ "C LSP",
+ "LSP server clangd not found. Make sure it is installed properly (and is available in PATH)," +
+ "and restart the IDE.",
+ NotificationType.ERROR).notify(project)
+ LanguageServerManager.getInstance(project).stop("CLanguageServer")
+ } else {
+ val commandLine = GeneralCommandLine("clangd")
+ commandLine.setWorkDirectory(project.basePath)
+ super.setCommandLine(commandLine)
+ }
+ }
+}
+
+class CLanguageServerFactory : LanguageServerFactory {
+ @NotNull
+ override fun createConnectionProvider(project: Project): StreamConnectionProvider {
+ return CLanguageServer(project)
+ }
+}
diff --git a/src/main/kotlin/org/gregorybednov/clsp/CTextMateBundleProvider.kt b/src/main/kotlin/org/gregorybednov/clsp/CTextMateBundleProvider.kt
deleted file mode 100644
index ba511e5..0000000
--- a/src/main/kotlin/org/gregorybednov/clsp/CTextMateBundleProvider.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.gregorybednov.clsp
-
-import org.jetbrains.plugins.textmate.api.TextMateBundleProvider
-import org.jetbrains.plugins.textmate.api.TextMateBundleProvider.PluginBundle
-import kotlin.io.path.Path
-
-class CTextMateBundleProvider : TextMateBundleProvider {
- override fun getBundles(): List {
- return listOf(
- PluginBundle("c/c++", Path("/Users/gregorybednov/Downloads/better-cpp-syntax"))
- )
- }
-}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 1813763..d8f0010 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -10,7 +10,18 @@
com.redhat.devtools.lsp4ij
org.jetbrains.plugins.textmate
+
+
+
+
+
+
+
+
+
+
+
-
@@ -42,9 +52,6 @@
-
-
-
diff --git a/src/main/resources/fileTemplates/internal/DefaultTemplate.c.ft b/src/main/resources/fileTemplates/internal/DefaultTemplate.c.ft
new file mode 100644
index 0000000..c1a6458
--- /dev/null
+++ b/src/main/resources/fileTemplates/internal/DefaultTemplate.c.ft
@@ -0,0 +1,6 @@
+\#include
+
+int main() {
+ printf("Hello world");
+ return 0;
+}
\ No newline at end of file
diff --git a/src/main/resources/fileTemplates/internal/DefaultTemplate.cpp.ft b/src/main/resources/fileTemplates/internal/DefaultTemplate.cpp.ft
new file mode 100644
index 0000000..29bdc26
--- /dev/null
+++ b/src/main/resources/fileTemplates/internal/DefaultTemplate.cpp.ft
@@ -0,0 +1,6 @@
+\#include
+
+int main() {
+ std::cout << "Hello world";
+ return 0;
+}
\ No newline at end of file
diff --git a/src/main/resources/icons/clogo.svg b/src/main/resources/icons/clogo.svg
new file mode 100644
index 0000000..591e246
--- /dev/null
+++ b/src/main/resources/icons/clogo.svg
@@ -0,0 +1,38 @@
+
diff --git a/src/main/resources/icons/cpplogo.svg b/src/main/resources/icons/cpplogo.svg
index 71f3958..8a246c9 100644
--- a/src/main/resources/icons/cpplogo.svg
+++ b/src/main/resources/icons/cpplogo.svg
@@ -4,20 +4,20 @@
width="16" height="16" viewBox="0 0 306 344.35" enable-background="new 0 0 306 344.35" xml:space="preserve">
-
-
-
+
-
+
-
+