From e480135055eaf6807afe2fef6aa78411385a3fb0 Mon Sep 17 00:00:00 2001 From: Gregory Bednov Date: Fri, 10 Jan 2025 16:22:24 +0300 Subject: [PATCH 1/5] C/C++ plugin - notifications improvement --- .idea/vcs.xml | 1 - .../gregorybednov/clsp/CTextMateBundleProvider.kt | 13 ------------- src/main/resources/META-INF/plugin.xml | 3 --- 3 files changed, 17 deletions(-) delete mode 100644 src/main/kotlin/org/gregorybednov/clsp/CTextMateBundleProvider.kt 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/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..177e38d 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -42,9 +42,6 @@ - - - From 91b7a63db5baf3ec6405fbe8b0f25da614e05589 Mon Sep 17 00:00:00 2001 From: Gregory Bednov Date: Fri, 10 Jan 2025 16:34:12 +0300 Subject: [PATCH 2/5] Added C language via CLanguage.kt, removed not needed CTextMateBundleProvider.kt Unfortunately still doesn't implement options in New project... menu --- .idea/vcs.xml | 1 - .../org/gregorybednov/clsp/CLanguage.kt | 65 +++++++++++++++++++ .../clsp/CTextMateBundleProvider.kt | 13 ---- src/main/resources/META-INF/plugin.xml | 3 - src/main/resources/icons/clogo.svg | 38 +++++++++++ src/main/resources/icons/cpplogo.svg | 10 +-- 6 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 src/main/kotlin/org/gregorybednov/clsp/CLanguage.kt delete mode 100644 src/main/kotlin/org/gregorybednov/clsp/CTextMateBundleProvider.kt create mode 100644 src/main/resources/icons/clogo.svg 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/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..177e38d 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -42,9 +42,6 @@ - - - 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"> - - - + - + - + From 262d26869c2b0d06deaccfedf2b5927a7b1370de Mon Sep 17 00:00:00 2001 From: Gregory Bednov Date: Fri, 10 Jan 2025 19:56:51 +0300 Subject: [PATCH 3/5] C/C++ plugin - added file support --- build.gradle.kts | 2 +- .../org/gregorybednov/NewCFileAction.kt | 25 ++++++++++++++++++ .../org/gregorybednov/NewCppFileAction.kt | 26 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 12 ++++++++- .../internal/DefaultTemplate.c.ft | 6 +++++ .../internal/DefaultTemplate.cpp.ft | 6 +++++ 6 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/org/gregorybednov/NewCFileAction.kt create mode 100644 src/main/kotlin/org/gregorybednov/NewCppFileAction.kt create mode 100644 src/main/resources/fileTemplates/internal/DefaultTemplate.c.ft create mode 100644 src/main/resources/fileTemplates/internal/DefaultTemplate.cpp.ft 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/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 177e38d..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 + + + + + + + + + + + - 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 From ff8f68ec038b7b85f9ccaa0bf19f459ec7532903 Mon Sep 17 00:00:00 2001 From: Gregory Bednov Date: Fri, 10 Jan 2025 19:57:22 +0300 Subject: [PATCH 4/5] C/C++ plugin - added C support --- .../org/gregorybednov/clsp/CLanguage.kt | 65 +++++++++++++++++++ src/main/resources/icons/clogo.svg | 38 +++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/main/kotlin/org/gregorybednov/clsp/CLanguage.kt create mode 100644 src/main/resources/icons/clogo.svg 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/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 @@ + + + + + + + From 7883e43e05a49f4ffd2a140f6e1af214df9126f1 Mon Sep 17 00:00:00 2001 From: Gregory Bednov Date: Fri, 10 Jan 2025 20:08:07 +0300 Subject: [PATCH 5/5] Create README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 README.md 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!