more LSP work and some misc fixes
This commit is contained in:
parent
5457d83296
commit
d02f3859a1
21 changed files with 961 additions and 166 deletions
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains
|
||||||
|
|
||||||
|
import com.intellij.ide.BrowserUtil
|
||||||
|
import com.intellij.ide.plugins.PluginManager
|
||||||
|
import com.intellij.notification.Notification
|
||||||
|
import com.intellij.notification.NotificationAction
|
||||||
|
import com.intellij.notification.NotificationType
|
||||||
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
|
import com.intellij.openapi.extensions.PluginId
|
||||||
|
import com.intellij.openapi.options.Configurable
|
||||||
|
import com.intellij.openapi.options.ShowSettingsUtil
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.startup.ProjectActivity
|
||||||
|
import com.intellij.util.application
|
||||||
|
import java.lang.reflect.Constructor
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
|
class ZBStartup: ProjectActivity {
|
||||||
|
var firstInit = true
|
||||||
|
override suspend fun execute(project: Project) {
|
||||||
|
if (firstInit) {
|
||||||
|
firstInit = false
|
||||||
|
if (!PluginManager.isPluginInstalled(PluginId.getId("com.intellij.modules.cidr.debugger")) &&
|
||||||
|
PluginManager.isPluginInstalled(PluginId.getId("com.intellij.modules.nativeDebug-plugin-capable"))) {
|
||||||
|
val notif = Notification(
|
||||||
|
"zigbrains",
|
||||||
|
ZigBrainsBundle.message("notification.title.native-debug"),
|
||||||
|
ZigBrainsBundle.message("notification.content.native-debug"),
|
||||||
|
NotificationType.INFORMATION
|
||||||
|
)
|
||||||
|
if (JBInternalPluginManagerConfigurable.successful) {
|
||||||
|
notif.addAction(object: NotificationAction(ZigBrainsBundle.message("notification.content.native-debug.market")) {
|
||||||
|
override fun actionPerformed(e: AnActionEvent, notification: Notification) {
|
||||||
|
val configurable = JBInternalPluginManagerConfigurable()
|
||||||
|
ShowSettingsUtil.getInstance().editConfigurable(null as Project?, configurable.instance) {
|
||||||
|
configurable.openMarketplaceTab("/vendor:\"JetBrains s.r.o.\" /tag:Debugging \"Native Debugging Support\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
notif.addAction(object: NotificationAction(ZigBrainsBundle.message("notification.content.native-debug.browser")) {
|
||||||
|
override fun actionPerformed(e: AnActionEvent, notification: Notification) {
|
||||||
|
BrowserUtil.browse("https://plugins.jetbrains.com/plugin/12775-native-debugging-support")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
notif.notify(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//JetBrains Internal API, but we need to access it, so access it reflectively (hopefully safe enough to pass verifier)
|
||||||
|
private class JBInternalPluginManagerConfigurable {
|
||||||
|
init {
|
||||||
|
if (!successful) {
|
||||||
|
throw IllegalStateException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val instance = constructor.newInstance() as Configurable
|
||||||
|
|
||||||
|
fun openMarketplaceTab(option: String) {
|
||||||
|
openMarketplaceTab.invoke(instance, option)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private lateinit var constructor: Constructor<*>
|
||||||
|
private lateinit var openMarketplaceTab: Method
|
||||||
|
val successful: Boolean
|
||||||
|
|
||||||
|
init {
|
||||||
|
lateinit var constructor: Constructor<*>
|
||||||
|
lateinit var openMarketplaceTab: Method
|
||||||
|
val successful = try {
|
||||||
|
val theClass = Class.forName("com_intellij_ide_plugins_PluginManagerConfigurable".replace('_', '.'))
|
||||||
|
constructor = theClass.getDeclaredConstructor().apply { isAccessible = true }
|
||||||
|
openMarketplaceTab = theClass.getDeclaredMethod("openMarketplaceTab", String::class.java).apply { isAccessible = true }
|
||||||
|
true
|
||||||
|
} catch (_: Throwable) { false }
|
||||||
|
if (successful) {
|
||||||
|
this.constructor = constructor
|
||||||
|
this.openMarketplaceTab = openMarketplaceTab
|
||||||
|
}
|
||||||
|
this.successful = successful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,20 +29,24 @@ import com.intellij.notification.Notification
|
||||||
import com.intellij.notification.NotificationType
|
import com.intellij.notification.NotificationType
|
||||||
import com.intellij.notification.Notifications
|
import com.intellij.notification.Notifications
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
|
import com.intellij.openapi.progress.runBlockingCancellable
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.project.guessProjectDir
|
import com.intellij.openapi.project.guessProjectDir
|
||||||
import com.intellij.util.io.awaitExit
|
import com.intellij.util.io.awaitExit
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
class DirenvCmd(private val workingDirectory: Path) {
|
object DirenvCmd {
|
||||||
|
suspend fun importDirenv(project: Project): Env {
|
||||||
suspend fun importDirenv(): Env {
|
|
||||||
if (!direnvInstalled())
|
if (!direnvInstalled())
|
||||||
return emptyEnv
|
return emptyEnv
|
||||||
|
val workDir = project.guessProjectDir()?.toNioPath() ?: return emptyEnv
|
||||||
|
|
||||||
val runOutput = run("export", "json")
|
val runOutput = run(project, workDir, "export", "json")
|
||||||
if (runOutput.error) {
|
if (runOutput.error) {
|
||||||
if (runOutput.output.contains("is blocked")) {
|
if (runOutput.output.contains("is blocked")) {
|
||||||
Notifications.Bus.notify(Notification(
|
Notifications.Bus.notify(Notification(
|
||||||
|
@ -65,34 +69,34 @@ class DirenvCmd(private val workingDirectory: Path) {
|
||||||
return Env(Json.decodeFromString<Map<String, String>>(runOutput.output))
|
return Env(Json.decodeFromString<Map<String, String>>(runOutput.output))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun run(project: Project, workDir: Path, vararg args: String): DirenvOutput {
|
||||||
|
val cli = GeneralCommandLine("direnv", *args).withWorkingDirectory(workDir)
|
||||||
|
|
||||||
@NonNls
|
val process: Process
|
||||||
private suspend fun run(vararg args: String): DirenvOutput {
|
val exitCode: Int
|
||||||
@NonNls
|
|
||||||
val cli = GeneralCommandLine("direnv", *args)
|
|
||||||
.withWorkingDirectory(workingDirectory)
|
|
||||||
|
|
||||||
val process = cli.createProcess()
|
project.direnvService.mutex.withLock {
|
||||||
if (process.awaitExit() != 0) {
|
process = cli.createProcess()
|
||||||
|
exitCode = process.awaitExit()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exitCode != 0) {
|
||||||
val stdErr = process.errorStream.bufferedReader().use { it.readText() }
|
val stdErr = process.errorStream.bufferedReader().use { it.readText() }
|
||||||
return DirenvOutput(stdErr, true)
|
return DirenvOutput(stdErr, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val stdOut = process.errorStream.bufferedReader().use { it.readText() }
|
val stdOut = process.inputStream.bufferedReader().use { it.readText() }
|
||||||
return DirenvOutput(stdOut, false)
|
return DirenvOutput(stdOut, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
@NonNls
|
|
||||||
private const val GROUP_DISPLAY_ID = "zigbrains-direnv"
|
private const val GROUP_DISPLAY_ID = "zigbrains-direnv"
|
||||||
private val LOG = logger<DirenvCmd>()
|
|
||||||
fun direnvInstalled() =
|
fun direnvInstalled() =
|
||||||
// Using the builtin stuff here instead of Env because it should only scan for direnv on the process path
|
// Using the builtin stuff here instead of Env because it should only scan for direnv on the process path
|
||||||
PathEnvironmentVariableUtil.findExecutableInPathOnAnyOS("direnv") != null
|
PathEnvironmentVariableUtil.findExecutableInPathOnAnyOS("direnv") != null
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun Project?.getDirenv(): Env {
|
suspend fun Project?.getDirenv(): Env {
|
||||||
val dir = this?.guessProjectDir() ?: return emptyEnv
|
if (this == null)
|
||||||
return DirenvCmd(dir.toNioPath()).importDirenv()
|
return emptyEnv
|
||||||
|
return DirenvCmd.importDirenv(this)
|
||||||
}
|
}
|
|
@ -24,12 +24,12 @@ package com.falsepattern.zigbrains.direnv
|
||||||
|
|
||||||
import com.intellij.openapi.components.Service
|
import com.intellij.openapi.components.Service
|
||||||
import com.intellij.openapi.components.service
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.util.application
|
import com.intellij.openapi.project.Project
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
|
||||||
@Service
|
|
||||||
class DirenvService(val cs: CoroutineScope) {
|
|
||||||
|
|
||||||
|
@Service(Service.Level.PROJECT)
|
||||||
|
class DirenvProjectService {
|
||||||
|
val mutex = Mutex()
|
||||||
}
|
}
|
||||||
|
|
||||||
val direnvScope get() = application.service<DirenvService>().cs
|
val Project.direnvService get() = service<DirenvProjectService>()
|
|
@ -22,21 +22,17 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp
|
package com.falsepattern.zigbrains.lsp
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.redhat.devtools.lsp4ij.server.OSProcessStreamConnectionProvider
|
import com.intellij.util.messages.Topic
|
||||||
|
|
||||||
class ZigStreamConnectionProvider(private val project: Project): OSProcessStreamConnectionProvider() {
|
|
||||||
init {
|
|
||||||
|
|
||||||
|
interface LanguageServerStarter {
|
||||||
|
fun startLSP(project: Project, restart: Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
fun startLSP(project: Project, restart: Boolean) {
|
||||||
private val LOG = Logger.getInstance(ZigStreamConnectionProvider::class.java)
|
val publisher = project.messageBus.syncPublisher(LANGUAGE_SERVER_START_TOPIC)
|
||||||
|
publisher.startLSP(project, restart)
|
||||||
suspend fun getCommand(project: Project, full: Boolean) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Topic.ProjectLevel
|
||||||
|
val LANGUAGE_SERVER_START_TOPIC = Topic.create("LanguageServerStarter", LanguageServerStarter::class.java)
|
112
modules/core/src/main/resources/META-INF/zigbrains-core.xml
Normal file
112
modules/core/src/main/resources/META-INF/zigbrains-core.xml
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<idea-plugin>
|
||||||
|
<!-- region Zig -->
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<colorSettingsPage
|
||||||
|
implementation="com.falsepattern.zigbrains.zig.highlighter.ZigColorSettingsPage"/>
|
||||||
|
<fileType
|
||||||
|
name="Zig File"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.ZigFileType"
|
||||||
|
fieldName="INSTANCE"
|
||||||
|
language="Zig"
|
||||||
|
extensions="zig"/>
|
||||||
|
<lang.braceMatcher
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.pairing.ZigBraceMatcher"/>
|
||||||
|
<lang.commenter
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.comments.ZigCommenter"/>
|
||||||
|
<lang.formatter
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.formatter.ZigFormattingModelBuilder"/>
|
||||||
|
<lang.parserDefinition
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.parser.ZigParserDefinition"/>
|
||||||
|
<lang.syntaxHighlighterFactory
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighterFactory"/>
|
||||||
|
|
||||||
|
<!-- String manipulation -->
|
||||||
|
<enterHandlerDelegate
|
||||||
|
id="ZigEnterInTextBlockHandler"
|
||||||
|
implementation="com.falsepattern.zigbrains.zig.editing.ZigEnterInTextBlockHandler"/>
|
||||||
|
<enterHandlerDelegate
|
||||||
|
id="ZigEnterInQuotedStringHandler"
|
||||||
|
implementation="com.falsepattern.zigbrains.zig.editing.ZigEnterInQuotedStringHandler"/>
|
||||||
|
<intentionAction>
|
||||||
|
<language>Zig</language>
|
||||||
|
<className>com.falsepattern.zigbrains.zig.intentions.MakeStringMultiline</className>
|
||||||
|
<category>Zig</category>
|
||||||
|
</intentionAction>
|
||||||
|
<intentionAction>
|
||||||
|
<language>Zig</language>
|
||||||
|
<className>com.falsepattern.zigbrains.zig.intentions.MakeStringQuoted</className>
|
||||||
|
<category>Zig</category>
|
||||||
|
</intentionAction>
|
||||||
|
|
||||||
|
<!-- Language injection -->
|
||||||
|
<lang.elementManipulator
|
||||||
|
forClass="com.falsepattern.zigbrains.zig.psi.ZigStringLiteral"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.injection.ZigStringElementManipulator"/>
|
||||||
|
<languageInjectionPerformer
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zig.injection.ZigLanguageInjectionPerformer"/>
|
||||||
|
</extensions>
|
||||||
|
<!-- endregion Zig -->
|
||||||
|
|
||||||
|
<!-- region Zon -->
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<colorSettingsPage
|
||||||
|
implementation="com.falsepattern.zigbrains.zon.highlighting.ZonColorSettingsPage"/>
|
||||||
|
<completion.contributor
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.completion.ZonCompletionContributor"/>
|
||||||
|
<fileType
|
||||||
|
name="Zon File"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.ZonFileType"
|
||||||
|
fieldName="INSTANCE"
|
||||||
|
language="Zon"
|
||||||
|
extensions="zon"/>
|
||||||
|
<lang.braceMatcher
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.pairing.ZonBraceMatcher"/>
|
||||||
|
<lang.commenter
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.comments.ZonCommenter"/>
|
||||||
|
<lang.foldingBuilder
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.folding.ZonFoldingBuilder"/>
|
||||||
|
<lang.formatter
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.formatter.ZonFormattingModelBuilder"/>
|
||||||
|
<lang.parserDefinition
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.parser.ZonParserDefinition"/>
|
||||||
|
<lang.quoteHandler
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.pairing.ZonQuoteHandler"/>
|
||||||
|
<lang.syntaxHighlighterFactory
|
||||||
|
language="Zon"
|
||||||
|
implementationClass="com.falsepattern.zigbrains.zon.highlighting.ZonSyntaxHighlighterFactory"/>
|
||||||
|
</extensions>
|
||||||
|
<!-- endregion Zon -->
|
||||||
|
|
||||||
|
<!-- region direnv -->
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<notificationGroup displayType="BALLOON"
|
||||||
|
id="zigbrains-direnv"
|
||||||
|
bundle="zigbrains.Bundle"
|
||||||
|
key="notification.group.zigbrains-direnv"/>
|
||||||
|
<notificationGroup displayType="BALLOON"
|
||||||
|
id="zigbrains"
|
||||||
|
bundle="zigbrains.Bundle"
|
||||||
|
key="notification.group.zigbrains"/>
|
||||||
|
</extensions>
|
||||||
|
<!-- endregion direnv -->
|
||||||
|
|
||||||
|
<!-- region misc -->
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<postStartupActivity
|
||||||
|
implementation="com.falsepattern.zigbrains.ZBStartup"/>
|
||||||
|
</extensions>
|
||||||
|
<!-- endregion misc -->
|
||||||
|
</idea-plugin>
|
|
@ -63,3 +63,8 @@ zon.color-settings.comma=Comma
|
||||||
zon.color-settings.dot=Dot
|
zon.color-settings.dot=Dot
|
||||||
zon.color-settings.boolean=Boolean
|
zon.color-settings.boolean=Boolean
|
||||||
zon.color-settings.brace=Braces
|
zon.color-settings.brace=Braces
|
||||||
|
notification.group.zigbrains=ZigBrains
|
||||||
|
notification.title.native-debug=Zig native debugger
|
||||||
|
notification.content.native-debug=You need to install the "Native Debugging Support" plugin for Zig debugging in this IDE!
|
||||||
|
notification.content.native-debug.market=Install from Marketplace
|
||||||
|
notification.content.native-debug.browser=Open in Browser
|
||||||
|
|
|
@ -21,12 +21,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
|
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
val lsp4ijVersion: String by project
|
val lsp4ijVersion: String by project
|
||||||
val lsp4jVersion: String by project
|
val lsp4jVersion: String by project
|
||||||
val lsp4ijNightly = property("lsp4ijNightly").toString().toBoolean()
|
val lsp4ijNightly = property("lsp4ijNightly").toString().toBoolean()
|
||||||
val lsp4ijDepString = "${if (lsp4ijNightly) "nightly." else ""}com.jetbrains.plugins:com.redhat.devtools.lsp4ij:$lsp4ijVersion"
|
val lsp4ijDepString = "${if (lsp4ijNightly) "nightly." else ""}com.jetbrains.plugins:com.redhat.devtools.lsp4ij:$lsp4ijVersion"
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions {
|
||||||
|
freeCompilerArgs += "-Xcontext-receivers"
|
||||||
|
}
|
||||||
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
create(IntelliJPlatformType.IntellijIdeaCommunity, providers.gradleProperty("ideaCommunityVersion"))
|
create(IntelliJPlatformType.IntellijIdeaCommunity, providers.gradleProperty("ideaCommunityVersion"))
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.lsp
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.direnv.emptyEnv
|
||||||
|
import com.falsepattern.zigbrains.direnv.getDirenv
|
||||||
|
import com.falsepattern.zigbrains.lsp.config.ZLSConfigProviderBase
|
||||||
|
import com.falsepattern.zigbrains.lsp.settings.zlsSettings
|
||||||
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
|
import com.intellij.notification.Notification
|
||||||
|
import com.intellij.notification.NotificationType
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.project.guessProjectDir
|
||||||
|
import com.intellij.openapi.util.SystemInfo
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.openapi.vfs.toNioPathOrNull
|
||||||
|
import com.redhat.devtools.lsp4ij.server.OSProcessStreamConnectionProvider
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.encodeToStream
|
||||||
|
import org.eclipse.lsp4j.InlayHint
|
||||||
|
import org.eclipse.lsp4j.jsonrpc.messages.Message
|
||||||
|
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
|
||||||
|
import org.eclipse.lsp4j.services.LanguageServer
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.isExecutable
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.io.path.notExists
|
||||||
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
|
class ZLSStreamConnectionProvider private constructor(private val project: Project, commandLine: GeneralCommandLine?) : OSProcessStreamConnectionProvider(commandLine) {
|
||||||
|
override fun handleMessage(message: Message?, languageServer: LanguageServer?, rootUri: VirtualFile?) {
|
||||||
|
if (project.zlsSettings.state.inlayHintsCompact) {
|
||||||
|
if (message is ResponseMessage) {
|
||||||
|
val res = message.result
|
||||||
|
if (res is Collection<*>) {
|
||||||
|
res.forEach { e ->
|
||||||
|
if (e is InlayHint) {
|
||||||
|
tryMutateInlayHint(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (res is InlayHint) {
|
||||||
|
tryMutateInlayHint(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.handleMessage(message, languageServer, rootUri)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOG = Logger.getInstance(ZLSStreamConnectionProvider::class.java)
|
||||||
|
private val ERROR_BLOCK = Regex("error\\{.*?}", RegexOption.DOT_MATCHES_ALL)
|
||||||
|
|
||||||
|
suspend fun create(project: Project): ZLSStreamConnectionProvider {
|
||||||
|
val projectDir = project.guessProjectDir()?.toNioPathOrNull()
|
||||||
|
val commandLine = getCommand(project)?.let { GeneralCommandLine(it) }?.withWorkingDirectory(projectDir)
|
||||||
|
return ZLSStreamConnectionProvider(project, commandLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun validate(project: Project): Boolean {
|
||||||
|
val svc = project.zlsSettings
|
||||||
|
val state = svc.state
|
||||||
|
val zlsPath: Path = state.zlsPath.let { zlsPath ->
|
||||||
|
if (zlsPath.isEmpty()) {
|
||||||
|
val env = if (state.direnv) project.getDirenv() else emptyEnv
|
||||||
|
env.findExecutableOnPATH("zls") ?: run {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zlsPath.toNioPathOrNull() ?: run {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (zlsPath.notExists()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!zlsPath.isRegularFile() || !zlsPath.isExecutable()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
suspend fun getCommand(project: Project): List<String>? {
|
||||||
|
val svc = project.zlsSettings
|
||||||
|
val state = svc.state
|
||||||
|
val zlsPath: Path = state.zlsPath.let { zlsPath ->
|
||||||
|
if (zlsPath.isEmpty()) {
|
||||||
|
val env = if (state.direnv) project.getDirenv() else emptyEnv
|
||||||
|
env.findExecutableOnPATH("zls") ?: run {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.could-not-detect.content"),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zlsPath.toNioPathOrNull() ?: run {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-exe-path-invalid.content", zlsPath),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (zlsPath.notExists()) {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-exe-not-exists.content", zlsPath),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if (!zlsPath.isRegularFile() || !zlsPath.isExecutable()) {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-exe-not-executable.content", zlsPath),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val configPath: Path? = state.zlsConfigPath.let { configPath ->
|
||||||
|
if (configPath.isNotBlank()) {
|
||||||
|
configPath.toNioPathOrNull()?.let { nioPath ->
|
||||||
|
if (nioPath.notExists()) {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-config-not-exists.content", nioPath),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
null
|
||||||
|
} else if (!nioPath.isRegularFile()) {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-config-not-file.content", nioPath),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
nioPath
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-config-path-invalid.content", configPath),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
val config = ZLSConfigProviderBase.findEnvironment(project)
|
||||||
|
if (config.zigExePath.isNullOrEmpty() || config.zigLibPath.isNullOrEmpty()) {
|
||||||
|
Notification(
|
||||||
|
"zigbrains-lsp",
|
||||||
|
ZLSBundle.message("notification.message.zls-config-autogen-failed.content"),
|
||||||
|
NotificationType.ERROR
|
||||||
|
).notify(project)
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
val tmpFile = FileUtil.createTempFile("zigbrains-zls-autoconf", ".json", true)
|
||||||
|
tmpFile.outputStream().buffered().use { writer -> Json.encodeToStream(config, writer) }
|
||||||
|
tmpFile.toPath()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val cmd = ArrayList<String>()
|
||||||
|
cmd.add(zlsPath.pathString)
|
||||||
|
if (configPath != null) {
|
||||||
|
cmd.add("--config-path")
|
||||||
|
cmd.add(configPath.pathString)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.debug) {
|
||||||
|
cmd.add("--enable-debug-log")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.messageTrace) {
|
||||||
|
cmd.add("--enable-message-tracing")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SystemInfo.isWindows) {
|
||||||
|
val sb: StringBuilder by lazy { StringBuilder() }
|
||||||
|
for (i in 0..<cmd.size) {
|
||||||
|
val s = cmd[i]
|
||||||
|
if (s.contains(' ')) {
|
||||||
|
sb.setLength(0)
|
||||||
|
cmd[i] = sb.append('"').append(s).append('"').toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tryMutateInlayHint(inlayHint: InlayHint) {
|
||||||
|
val str = inlayHint.label?.left ?: return
|
||||||
|
val shortened = ERROR_BLOCK.replace(str, "error{...}")
|
||||||
|
inlayHint.setLabel(shortened)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.lsp
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.Service
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
|
@Service(Service.Level.PROJECT)
|
||||||
|
class ZigLSPProjectService(
|
||||||
|
val cs: CoroutineScope
|
||||||
|
)
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class ZigLSPApplicationService(
|
||||||
|
val cs: CoroutineScope
|
||||||
|
)
|
|
@ -22,5 +22,61 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp
|
package com.falsepattern.zigbrains.lsp
|
||||||
|
|
||||||
class ZigLanguageServerFactory {
|
import com.intellij.openapi.components.service
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||||
|
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
||||||
|
import com.intellij.util.application
|
||||||
|
import com.redhat.devtools.lsp4ij.LanguageServerEnablementSupport
|
||||||
|
import com.redhat.devtools.lsp4ij.LanguageServerFactory
|
||||||
|
import com.redhat.devtools.lsp4ij.LanguageServerManager
|
||||||
|
import com.redhat.devtools.lsp4ij.ServerStatus
|
||||||
|
import com.redhat.devtools.lsp4ij.server.StreamConnectionProvider
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
|
class ZigLanguageServerFactory: LanguageServerFactory, LanguageServerEnablementSupport {
|
||||||
|
override fun createConnectionProvider(project: Project): StreamConnectionProvider {
|
||||||
|
return if (application.isDispatchThread) {
|
||||||
|
runWithModalProgressBlocking(ModalTaskOwner.project(project), ZLSBundle.message("progress.title.create-connection-provider")) {
|
||||||
|
ZLSStreamConnectionProvider.create(project)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
runBlocking {
|
||||||
|
ZLSStreamConnectionProvider.create(project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEnabled(project: Project): Boolean {
|
||||||
|
return (project.getUserData(ENABLED_KEY) ?: true) && if (application.isDispatchThread) {
|
||||||
|
runWithModalProgressBlocking(ModalTaskOwner.project(project), ZLSBundle.message("progress.title.validate")) {
|
||||||
|
ZLSStreamConnectionProvider.validate(project)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runBlocking {
|
||||||
|
ZLSStreamConnectionProvider.validate(project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setEnabled(enabled: Boolean, project: Project) {
|
||||||
|
project.putUserData(ENABLED_KEY, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZLSStarter: LanguageServerStarter {
|
||||||
|
override fun startLSP(project: Project, restart: Boolean) {
|
||||||
|
project.service<ZigLSPProjectService>().cs.launch {
|
||||||
|
val manager = project.service<LanguageServerManager>()
|
||||||
|
val status = manager.getServerStatus("ZigBrains")
|
||||||
|
if ((status == ServerStatus.started || status == ServerStatus.starting) && !restart)
|
||||||
|
return@launch
|
||||||
|
manager.start("ZigBrains")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ENABLED_KEY = Key.create<Boolean>("ZLS_ENABLED")
|
|
@ -34,15 +34,4 @@ data class ZLSConfig(
|
||||||
@SerialName("build_on_save_step") val buildOnSaveStep: @NonNls String? = null,
|
@SerialName("build_on_save_step") val buildOnSaveStep: @NonNls String? = null,
|
||||||
@SerialName("dangerous_comptime_experiments_do_not_enable") val comptimeInterpreter: Boolean? = null,
|
@SerialName("dangerous_comptime_experiments_do_not_enable") val comptimeInterpreter: Boolean? = null,
|
||||||
@SerialName("highlight_global_var_declarations") val globalVarDeclarations: Boolean? = null
|
@SerialName("highlight_global_var_declarations") val globalVarDeclarations: Boolean? = null
|
||||||
) {
|
|
||||||
infix fun merge(other: ZLSConfig): ZLSConfig {
|
|
||||||
return ZLSConfig(
|
|
||||||
zigExePath ?: other.zigExePath,
|
|
||||||
zigLibPath ?: other.zigLibPath,
|
|
||||||
buildOnSave ?: other.buildOnSave,
|
|
||||||
buildOnSaveStep ?: other.buildOnSaveStep,
|
|
||||||
comptimeInterpreter ?: other.comptimeInterpreter,
|
|
||||||
globalVarDeclarations ?: other.globalVarDeclarations
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,18 +25,28 @@ package com.falsepattern.zigbrains.lsp.config
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName
|
import com.intellij.openapi.extensions.ExtensionPointName
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
|
||||||
interface ZLSConfigProvider {
|
sealed interface ZLSConfigProviderBase {
|
||||||
fun getEnvironment(project: Project): ZLSConfig
|
|
||||||
companion object {
|
companion object {
|
||||||
private val EXTENSION_POINT_NAME = ExtensionPointName.create<ZLSConfigProvider>("com.falsepattern.zigbrains.zlsConfigProvider")
|
private val EXTENSION_POINT_NAME = ExtensionPointName.create<ZLSConfigProviderBase>("com.falsepattern.zigbrains.zlsConfigProvider")
|
||||||
|
|
||||||
fun findEnvironment(project: Project): ZLSConfig {
|
suspend fun findEnvironment(project: Project): ZLSConfig {
|
||||||
val extensions = EXTENSION_POINT_NAME.extensionList
|
val extensions = EXTENSION_POINT_NAME.extensionList
|
||||||
var result = ZLSConfig()
|
var result = ZLSConfig()
|
||||||
for (extension in extensions) {
|
for (extension in extensions) {
|
||||||
result = result merge extension.getEnvironment(project)
|
result = when (extension) {
|
||||||
|
is ZLSConfigProvider -> extension.getEnvironment(project, result)
|
||||||
|
is SuspendingZLSConfigProvider -> extension.getEnvironment(project, result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ZLSConfigProvider: ZLSConfigProviderBase {
|
||||||
|
fun getEnvironment(project: Project, previous: ZLSConfig): ZLSConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SuspendingZLSConfigProvider: ZLSConfigProviderBase {
|
||||||
|
suspend fun getEnvironment(project: Project, previous: ZLSConfig): ZLSConfig
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.lsp.highlighting
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenModifiers.Declaration
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenModifiers.Definition
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenModifiers.Deprecated
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenModifiers.Generic
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Builtin
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Comment
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Enum
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.EnumMember
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.ErrorTag
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Function
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Keyword
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.KeywordLiteral
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Label
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Method
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Namespace
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Number
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Operator
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Parameter
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Property
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.String
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Struct
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Type
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.TypeParameter
|
||||||
|
import com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenTypes.Variable
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.BUILTIN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.ENUM_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.ENUM_MEMBER_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.ENUM_MEMBER_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.ENUM_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.ERROR_TAG_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.ERROR_TAG_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.FUNCTION_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.FUNCTION_DECL_GEN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.FUNCTION_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.FUNCTION_REF_GEN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.KEYWORD
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.LABEL_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.LABEL_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.METHOD_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.METHOD_DECL_GEN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.METHOD_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.METHOD_REF_GEN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.NAMESPACE_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.NAMESPACE_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.NUMBER
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.OPERATOR
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.PARAMETER
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.PROPERTY_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.PROPERTY_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.STRUCT_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.STRUCT_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.TYPE_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.TYPE_DECL_GEN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.TYPE_PARAM
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.TYPE_PARAM_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.TYPE_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.TYPE_REF_GEN
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.VARIABLE_DECL
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.VARIABLE_DECL_DEPR
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.VARIABLE_REF
|
||||||
|
import com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighter.Companion.VARIABLE_REF_DEPR
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.redhat.devtools.lsp4ij.features.semanticTokens.DefaultSemanticTokensColorsProvider
|
||||||
|
|
||||||
|
|
||||||
|
class ZLSSemanticTokenColorsProvider : DefaultSemanticTokensColorsProvider() {
|
||||||
|
override fun getTextAttributesKey(type: String, mod: List<String>, file: PsiFile) = with(mod) {
|
||||||
|
when (type) {
|
||||||
|
Builtin -> BUILTIN
|
||||||
|
Enum -> if (isDecl) ENUM_DECL else ENUM_REF
|
||||||
|
EnumMember -> if (isDecl) ENUM_MEMBER_DECL else ENUM_MEMBER_REF
|
||||||
|
ErrorTag -> if (isDecl) ERROR_TAG_DECL else ERROR_TAG_REF
|
||||||
|
Property -> if (isDecl) PROPERTY_DECL else PROPERTY_REF
|
||||||
|
Function -> if (isDecl)
|
||||||
|
if (has(Generic)) FUNCTION_DECL_GEN else FUNCTION_DECL
|
||||||
|
else
|
||||||
|
if (has(Generic)) FUNCTION_REF_GEN else FUNCTION_REF
|
||||||
|
|
||||||
|
Keyword, KeywordLiteral -> KEYWORD
|
||||||
|
Label -> if (isDecl) LABEL_DECL else LABEL_REF
|
||||||
|
Method -> if (isDecl)
|
||||||
|
if (has(Generic)) METHOD_DECL_GEN else METHOD_DECL
|
||||||
|
else
|
||||||
|
if (has(Generic)) METHOD_REF_GEN else METHOD_REF
|
||||||
|
|
||||||
|
Namespace -> if (isDecl) NAMESPACE_DECL else NAMESPACE_REF
|
||||||
|
Number -> NUMBER
|
||||||
|
Operator -> OPERATOR
|
||||||
|
Parameter -> PARAMETER
|
||||||
|
Struct -> if (isDecl) STRUCT_DECL else STRUCT_REF
|
||||||
|
Type -> if (isDecl)
|
||||||
|
if (has(Generic)) TYPE_DECL_GEN else TYPE_DECL
|
||||||
|
else
|
||||||
|
if (has(Generic)) TYPE_REF_GEN else TYPE_REF
|
||||||
|
|
||||||
|
TypeParameter -> if (isDecl) TYPE_PARAM_DECL else TYPE_PARAM
|
||||||
|
Variable -> if (isDecl)
|
||||||
|
if (has(Deprecated)) VARIABLE_DECL_DEPR else VARIABLE_DECL
|
||||||
|
else
|
||||||
|
if (has(Deprecated)) VARIABLE_REF_DEPR else VARIABLE_REF
|
||||||
|
|
||||||
|
Comment, String -> null
|
||||||
|
else -> super.getTextAttributesKey(type, mod, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun List<String>.has(key: String) = contains(key)
|
||||||
|
|
||||||
|
private val List<String>.isDecl get() = has(Declaration) || has(Definition)
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.falsepattern.zigbrains.lsp.highlighting
|
||||||
|
|
||||||
|
import org.eclipse.lsp4j.SemanticTokenModifiers
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
@NonNls
|
||||||
|
object ZLSSemanticTokenModifiers {
|
||||||
|
const val Declaration: String = SemanticTokenModifiers.Declaration
|
||||||
|
const val Definition: String = SemanticTokenModifiers.Definition
|
||||||
|
const val Readonly: String = SemanticTokenModifiers.Readonly
|
||||||
|
const val Static: String = SemanticTokenModifiers.Static
|
||||||
|
const val Deprecated: String = SemanticTokenModifiers.Deprecated
|
||||||
|
const val Abstract: String = SemanticTokenModifiers.Abstract
|
||||||
|
const val Async: String = SemanticTokenModifiers.Async
|
||||||
|
const val Modification: String = SemanticTokenModifiers.Modification
|
||||||
|
const val Documentation: String = SemanticTokenModifiers.Documentation
|
||||||
|
const val DefaultLibrary: String = SemanticTokenModifiers.DefaultLibrary
|
||||||
|
|
||||||
|
/** non standard token modifier */
|
||||||
|
const val Generic: String = "generic"
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.lsp.highlighting
|
||||||
|
|
||||||
|
import org.eclipse.lsp4j.SemanticTokenTypes
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
@NonNls
|
||||||
|
object ZLSSemanticTokenTypes {
|
||||||
|
const val Namespace: String = SemanticTokenTypes.Namespace
|
||||||
|
const val Type: String = SemanticTokenTypes.Type
|
||||||
|
const val Class: String = SemanticTokenTypes.Class
|
||||||
|
const val Enum: String = SemanticTokenTypes.Enum
|
||||||
|
const val Interface: String = SemanticTokenTypes.Interface
|
||||||
|
const val Struct: String = SemanticTokenTypes.Struct
|
||||||
|
const val TypeParameter: String = SemanticTokenTypes.TypeParameter
|
||||||
|
const val Parameter: String = SemanticTokenTypes.Parameter
|
||||||
|
const val Variable: String = SemanticTokenTypes.Variable
|
||||||
|
const val Property: String = SemanticTokenTypes.Property
|
||||||
|
const val EnumMember: String = SemanticTokenTypes.EnumMember
|
||||||
|
const val Event: String = SemanticTokenTypes.Event
|
||||||
|
const val Function: String = SemanticTokenTypes.Function
|
||||||
|
const val Method: String = SemanticTokenTypes.Method
|
||||||
|
const val Macro: String = SemanticTokenTypes.Macro
|
||||||
|
const val Keyword: String = SemanticTokenTypes.Keyword
|
||||||
|
const val Modifier: String = SemanticTokenTypes.Modifier
|
||||||
|
const val Comment: String = SemanticTokenTypes.Comment
|
||||||
|
const val String: String = SemanticTokenTypes.String
|
||||||
|
const val Number: String = SemanticTokenTypes.Number
|
||||||
|
const val Regexp: String = SemanticTokenTypes.Regexp
|
||||||
|
const val Operator: String = SemanticTokenTypes.Operator
|
||||||
|
const val Decorator: String = SemanticTokenTypes.Decorator
|
||||||
|
|
||||||
|
/** non standard token type */
|
||||||
|
const val ErrorTag: String = "errorTag"
|
||||||
|
|
||||||
|
/** non standard token type */
|
||||||
|
const val Builtin: String = "builtin"
|
||||||
|
|
||||||
|
/** non standard token type */
|
||||||
|
const val Label: String = "label"
|
||||||
|
|
||||||
|
/** non standard token type */
|
||||||
|
const val KeywordLiteral: String = "keywordLiteral"
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2024 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.lsp.settings
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.lsp.config.ZLSConfig
|
||||||
|
import com.falsepattern.zigbrains.lsp.config.ZLSConfigProvider
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
|
||||||
|
class ZLSSettingsConfigProvider: ZLSConfigProvider {
|
||||||
|
override fun getEnvironment(project: Project, previous: ZLSConfig): ZLSConfig {
|
||||||
|
val state = project.zlsSettings.state
|
||||||
|
return previous.copy(
|
||||||
|
buildOnSave = state.buildOnSave,
|
||||||
|
buildOnSaveStep = state.buildOnSaveStep,
|
||||||
|
globalVarDeclarations = state.globalVarDeclarations,
|
||||||
|
comptimeInterpreter = state.comptimeInterpreter
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@
|
||||||
package com.falsepattern.zigbrains.lsp.settings
|
package com.falsepattern.zigbrains.lsp.settings
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||||
|
import com.falsepattern.zigbrains.lsp.startLSP
|
||||||
import com.falsepattern.zigbrains.shared.NestedConfigurable
|
import com.falsepattern.zigbrains.shared.NestedConfigurable
|
||||||
import com.intellij.openapi.components.service
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
@ -47,7 +48,7 @@ class ZLSSettingsConfigurable(private val project: Project): NestedConfigurable
|
||||||
val reloadZLS = settings.isModified(data)
|
val reloadZLS = settings.isModified(data)
|
||||||
settings.state = data
|
settings.state = data
|
||||||
if (reloadZLS) {
|
if (reloadZLS) {
|
||||||
TODO("Not yet implemented")
|
startLSP(project, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,10 @@ package com.falsepattern.zigbrains.lsp.settings
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.direnv.*
|
import com.falsepattern.zigbrains.direnv.*
|
||||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
||||||
|
import com.falsepattern.zigbrains.lsp.ZigLSPApplicationService
|
||||||
|
import com.falsepattern.zigbrains.lsp.ZigLSPProjectService
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.ui.components.JBCheckBox
|
import com.intellij.ui.components.JBCheckBox
|
||||||
|
@ -32,6 +35,7 @@ import com.intellij.ui.components.fields.ExtendableTextField
|
||||||
import com.intellij.ui.components.textFieldWithBrowseButton
|
import com.intellij.ui.components.textFieldWithBrowseButton
|
||||||
import com.intellij.ui.dsl.builder.AlignX
|
import com.intellij.ui.dsl.builder.AlignX
|
||||||
import com.intellij.ui.dsl.builder.Panel
|
import com.intellij.ui.dsl.builder.Panel
|
||||||
|
import com.intellij.util.application
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
|
@ -110,7 +114,7 @@ class ZLSSettingsPanel(private val project: Project?) : Disposable {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun autodetect() {
|
fun autodetect() {
|
||||||
direnvScope.launch {
|
(project?.service<ZigLSPProjectService>()?.cs ?: application.service<ZigLSPApplicationService>().cs).launch {
|
||||||
getDirenv().findExecutableOnPATH("zls")?.let { zlsPath.text = it.pathString }
|
getDirenv().findExecutableOnPATH("zls")?.let { zlsPath.text = it.pathString }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
modules/lsp/src/main/resources/META-INF/zigbrains-lsp.xml
Normal file
59
modules/lsp/src/main/resources/META-INF/zigbrains-lsp.xml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<idea-plugin>
|
||||||
|
<resource-bundle>zigbrains.lsp.Bundle</resource-bundle>
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<!-- LSP textDocument/signatureHelp -->
|
||||||
|
<codeInsight.parameterInfo
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.redhat.devtools.lsp4ij.features.signatureHelp.LSPParameterInfoHandler"
|
||||||
|
/>
|
||||||
|
<!-- LSP textDocument/folding -->
|
||||||
|
<lang.foldingBuilder
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.redhat.devtools.lsp4ij.features.foldingRange.LSPFoldingRangeBuilder"
|
||||||
|
/>
|
||||||
|
<!-- LSP textDocument/documentSymbol -->
|
||||||
|
<lang.psiStructureViewFactory
|
||||||
|
language="Zig"
|
||||||
|
implementationClass="com.redhat.devtools.lsp4ij.features.documentSymbol.LSPDocumentSymbolStructureViewFactory"
|
||||||
|
/>
|
||||||
|
<notificationGroup
|
||||||
|
id="zigbrains-lsp"
|
||||||
|
displayType="BALLOON"
|
||||||
|
bundle="zigbrains.lsp.Bundle"
|
||||||
|
key="notification.group.zigbrains-lsp"
|
||||||
|
/>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="com.falsepattern.zigbrains">
|
||||||
|
<zlsConfigProvider
|
||||||
|
implementation="com.falsepattern.zigbrains.lsp.settings.ZLSSettingsConfigProvider"
|
||||||
|
/>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="com.redhat.devtools.lsp4ij">
|
||||||
|
<!--suppress PluginXmlCapitalization -->
|
||||||
|
<server
|
||||||
|
id="ZigBrains"
|
||||||
|
bundle="zigbrains.lsp.Bundle"
|
||||||
|
nameKey="lsp.zls.name"
|
||||||
|
descriptionKey="lsp.zls.description"
|
||||||
|
factoryClass="com.falsepattern.zigbrains.lsp.ZigLanguageServerFactory"
|
||||||
|
/>
|
||||||
|
<languageMapping
|
||||||
|
language="Zig"
|
||||||
|
serverId="ZigBrains"
|
||||||
|
languageId="zig"
|
||||||
|
/>
|
||||||
|
<semanticTokensColorsProvider
|
||||||
|
serverId="ZigBrains"
|
||||||
|
class="com.falsepattern.zigbrains.lsp.highlighting.ZLSSemanticTokenColorsProvider"
|
||||||
|
/>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
<applicationListeners>
|
||||||
|
<listener
|
||||||
|
class="com.falsepattern.zigbrains.lsp.ZLSStarter"
|
||||||
|
topic="com.falsepattern.zigbrains.lsp.LanguageServerStarter"
|
||||||
|
/>
|
||||||
|
</applicationListeners>
|
||||||
|
</idea-plugin>
|
|
@ -18,3 +18,18 @@ dev-settings.group.title=ZLS Developer Settings
|
||||||
dev-settings.debug.label=Debug log
|
dev-settings.debug.label=Debug log
|
||||||
dev-settings.message-trace.label=Message trace
|
dev-settings.message-trace.label=Message trace
|
||||||
configurable.name.zls.settings=ZLS Settings
|
configurable.name.zls.settings=ZLS Settings
|
||||||
|
notification.group.zigbrains-lsp=ZigBrains LSP Integration
|
||||||
|
notification.message.could-not-detect.content=Could not detect ZLS binary, please configure it
|
||||||
|
notification.message.zls-exe-path-invalid.content=ZLS executable path could not be parsed: {0}
|
||||||
|
notification.message.zls-exe-not-exists.content=ZLS executable does not exist: {0}
|
||||||
|
notification.message.zls-exe-not-executable.content=ZLS executable is not an executable file: {0}
|
||||||
|
notification.message.zls-config-not-exists.content=ZLS config file does not exist: {0}
|
||||||
|
notification.message.zls-config-not-file.content=ZLS config file is not a regular file: {0}
|
||||||
|
notification.message.zls-config-path-invalid.content=ZLS config path could not be parted: {0}
|
||||||
|
notification.message.zls-config-autogen-failed.content=Failed to autogenerate ZLS config from toolchain
|
||||||
|
progress.title.create-connection-provider=Creating ZLS connection provider
|
||||||
|
progress.title.validate=Validating ZLS
|
||||||
|
# suppress inspection "UnusedProperty"
|
||||||
|
lsp.zls.name=Zig Language Server
|
||||||
|
# suppress inspection "UnusedProperty"
|
||||||
|
lsp.zls.description=The <a href="https://github.com/Zigtools/ZLS">Zig Language Server</a>, via ZigBrains
|
|
@ -3,111 +3,14 @@
|
||||||
<name>ZigBrains</name>
|
<name>ZigBrains</name>
|
||||||
<vendor>FalsePattern</vendor>
|
<vendor>FalsePattern</vendor>
|
||||||
|
|
||||||
<depends>com.intellij.modules.platform</depends>
|
<depends config-file="zigbrains-core.xml">com.intellij.modules.platform</depends>
|
||||||
|
<depends config-file="zigbrains-lsp.xml">com.redhat.devtools.lsp4ij</depends>
|
||||||
|
|
||||||
<!-- region Zig -->
|
<resource-bundle>zigbrains.Bundle</resource-bundle>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
|
||||||
<colorSettingsPage
|
|
||||||
implementation="com.falsepattern.zigbrains.zig.highlighter.ZigColorSettingsPage"/>
|
|
||||||
<fileType
|
|
||||||
name="Zig File"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.ZigFileType"
|
|
||||||
fieldName="INSTANCE"
|
|
||||||
language="Zig"
|
|
||||||
extensions="zig"/>
|
|
||||||
<lang.braceMatcher
|
|
||||||
language="Zig"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.pairing.ZigBraceMatcher"/>
|
|
||||||
<lang.commenter
|
|
||||||
language="Zig"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.comments.ZigCommenter"/>
|
|
||||||
<lang.formatter
|
|
||||||
language="Zig"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.formatter.ZigFormattingModelBuilder"/>
|
|
||||||
<lang.parserDefinition
|
|
||||||
language="Zig"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.parser.ZigParserDefinition"/>
|
|
||||||
<lang.syntaxHighlighterFactory
|
|
||||||
language="Zig"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighterFactory"/>
|
|
||||||
|
|
||||||
<!-- String manipulation -->
|
|
||||||
<enterHandlerDelegate
|
|
||||||
id="ZigEnterInTextBlockHandler"
|
|
||||||
implementation="com.falsepattern.zigbrains.zig.editing.ZigEnterInTextBlockHandler"/>
|
|
||||||
<enterHandlerDelegate
|
|
||||||
id="ZigEnterInQuotedStringHandler"
|
|
||||||
implementation="com.falsepattern.zigbrains.zig.editing.ZigEnterInQuotedStringHandler"/>
|
|
||||||
<intentionAction>
|
|
||||||
<language>Zig</language>
|
|
||||||
<className>com.falsepattern.zigbrains.zig.intentions.MakeStringMultiline</className>
|
|
||||||
<category>Zig</category>
|
|
||||||
</intentionAction>
|
|
||||||
<intentionAction>
|
|
||||||
<language>Zig</language>
|
|
||||||
<className>com.falsepattern.zigbrains.zig.intentions.MakeStringQuoted</className>
|
|
||||||
<category>Zig</category>
|
|
||||||
</intentionAction>
|
|
||||||
|
|
||||||
<!-- Language injection -->
|
|
||||||
<lang.elementManipulator
|
|
||||||
forClass="com.falsepattern.zigbrains.zig.psi.ZigStringLiteral"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.injection.ZigStringElementManipulator"/>
|
|
||||||
<languageInjectionPerformer
|
|
||||||
language="Zig"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zig.injection.ZigLanguageInjectionPerformer"/>
|
|
||||||
</extensions>
|
|
||||||
<!-- endregion Zig -->
|
|
||||||
|
|
||||||
<!-- region Zon -->
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
|
||||||
<colorSettingsPage
|
|
||||||
implementation="com.falsepattern.zigbrains.zon.highlighting.ZonColorSettingsPage"/>
|
|
||||||
<completion.contributor
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.completion.ZonCompletionContributor"/>
|
|
||||||
<fileType
|
|
||||||
name="Zon File"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.ZonFileType"
|
|
||||||
fieldName="INSTANCE"
|
|
||||||
language="Zon"
|
|
||||||
extensions="zon"/>
|
|
||||||
<lang.braceMatcher
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.pairing.ZonBraceMatcher"/>
|
|
||||||
<lang.commenter
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.comments.ZonCommenter"/>
|
|
||||||
<lang.foldingBuilder
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.folding.ZonFoldingBuilder"/>
|
|
||||||
<lang.formatter
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.formatter.ZonFormattingModelBuilder"/>
|
|
||||||
<lang.parserDefinition
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.parser.ZonParserDefinition"/>
|
|
||||||
<lang.quoteHandler
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.pairing.ZonQuoteHandler"/>
|
|
||||||
<lang.syntaxHighlighterFactory
|
|
||||||
language="Zon"
|
|
||||||
implementationClass="com.falsepattern.zigbrains.zon.highlighting.ZonSyntaxHighlighterFactory"/>
|
|
||||||
</extensions>
|
|
||||||
<!-- endregion Zon -->
|
|
||||||
|
|
||||||
<!-- region direnv -->
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
|
||||||
<notificationGroup displayType="BALLOON"
|
|
||||||
id="zigbrains-direnv"
|
|
||||||
bundle="zigbrains.Bundle"
|
|
||||||
key="notification.group.zigbrains-direnv"/>
|
|
||||||
</extensions>
|
|
||||||
<!-- endregion direnv -->
|
|
||||||
|
|
||||||
<extensionPoints>
|
<extensionPoints>
|
||||||
<extensionPoint
|
<extensionPoint
|
||||||
interface="com.falsepattern.zigbrains.lsp.config.ZLSConfigProvider"
|
interface="com.falsepattern.zigbrains.lsp.config.ZLSConfigProviderBase"
|
||||||
dynamic="true"
|
dynamic="true"
|
||||||
name="zlsConfigProvider"/>
|
name="zlsConfigProvider"/>
|
||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
|
|
Loading…
Add table
Reference in a new issue