Skip to content

Commit

Permalink
Merge pull request #437 from koxudaxi/support_LSP4IJ
Browse files Browse the repository at this point in the history
Support LSP4IJ, which is a third-party LSP server integration
  • Loading branch information
koxudaxi authored Sep 2, 2024
2 parents 36156cb + dec4e53 commit 8ca1fff
Show file tree
Hide file tree
Showing 23 changed files with 524 additions and 103 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# - Run 'test' and 'verifyPlugin' tasks.
# - Run Qodana inspections.
# - Run the 'buildPlugin' task and prepare artifact for further tests.
# - Run the 'runPluginVerifier' task.
# - Run the 'verifyPlugin' task.
# - Create a draft release.
#
# The workflow is triggered on push and pull_request events.
Expand Down Expand Up @@ -193,7 +193,7 @@ jobs:

# Run Qodana inspections
- name: Qodana - Code Inspection
uses: JetBrains/qodana-action@v2024.1.9
uses: JetBrains/qodana-action@v2024.1.2
with:
cache-default-branch-only: true

Expand Down
2 changes: 1 addition & 1 deletion .run/Run Verifications.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</option>
<option name="taskNames">
<list>
<option value="runPluginVerifier" />
<option value="verifyPlugin" />
</list>
</option>
<option name="vmOptions" value="" />
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## [Unreleased]
- Support LSP4IJ, which is a third-party LSP server integration [[#437](https://github.com/koxudaxi/pydantic-pycharm-plugin/pull/#437)]
- Use preview only for non-stable server versions (<0.5.3) [[#481](https://github.com/koxudaxi/pydantic-pycharm-plugin/pull/#481)]
- Use rule or --explain dependent on version. [[#479](https://github.com/koxudaxi/pydantic-pycharm-plugin/pull/#479)]

Expand Down
5 changes: 4 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import org.jetbrains.changelog.markdownToHTML
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
import org.jetbrains.intellij.platform.gradle.extensions.intellijPlatform


fun properties(key: String) = providers.gradleProperty(key)
fun environment(key: String) = providers.environmentVariable(key)

Expand All @@ -23,7 +24,6 @@ repositories {
mavenCentral()
intellijPlatform {
defaultRepositories()
snapshots()
}
}

Expand All @@ -39,6 +39,9 @@ dependencies {
val bundledPlugins = properties("platformBundledPlugins").map { it.split(',').map(String::trim).filter(String::isNotEmpty) }
create(type, version, useInstaller = false)
bundledPlugins(bundledPlugins)
val lsp4ij = libs.plugins.lsp4ij.get()
plugin("${lsp4ij.pluginId}:${lsp4ij.version.requiredVersion}")

instrumentationTools()
testFramework(TestFrameworkType.Bundled)
pluginVerifier()
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pluginUntilBuild = 242.*

# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
platformType = PY
platformVersion = 242-EAP-SNAPSHOT
platformVersion = 2024.2

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
Expand Down
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ kotlinxSerialization = "1.6.3"
# plugins
kotlin = "1.9.23"
changelog = "2.2.1"
gradleIntelliJPlugin = "2.0.0-rc1"
gradleIntelliJPlugin = "2.0.1"
qodana = "0.1.13"
kover = "0.7.6"
lsp4ij = "0.4.0"

[libraries]
annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" }
Expand All @@ -25,3 +26,4 @@ kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" }
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
lsp4ij = { id = "com.redhat.devtools.lsp4ij", version.ref = "lsp4ij"}
13 changes: 13 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<depends>com.intellij.modules.lang</depends>
<depends>com.intellij.modules.python</depends>
<depends>com.intellij.modules.platform</depends>
<depends>com.redhat.devtools.lsp4ij</depends>
<depends optional="true" config-file="only-ultimate.xml">com.intellij.modules.ultimate</depends>
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity implementation="com.koxudaxi.ruff.RuffProjectInitializer"/>
Expand All @@ -31,4 +32,16 @@
description="Run ruff with fix option">
</action>
</actions>
<extensions defaultExtensionNs="com.redhat.devtools.lsp4ij">
<server id="ruffLanguageServer"
name="Ruff Language Server"
factoryClass="com.koxudaxi.ruff.lsp.lsp4ij.RuffLanguageServerFactory">
<description><![CDATA[
Ruff Language Server for LSP4IJ.
]]>
</description>
</server>
<languageMapping language="Python"
serverId="ruffLanguageServer"/>
</extensions>
</idea-plugin>
37 changes: 29 additions & 8 deletions src/com/koxudaxi/ruff/Ruff.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.koxudaxi.ruff

import com.intellij.codeInspection.ex.InspectionToolRegistrar
import com.intellij.credentialStore.toByteArrayAndClear
import com.intellij.execution.ExecutionException
import com.intellij.execution.RunCanceledByUserException
Expand All @@ -16,7 +17,6 @@ import com.intellij.openapi.editor.Document
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.progress.progressStep
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.modules
import com.intellij.openapi.projectRoots.Sdk
Expand All @@ -25,6 +25,7 @@ import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.lsp.api.LspServerSupportProvider
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiFile
Expand All @@ -37,7 +38,6 @@ import com.jetbrains.python.sdk.flavors.conda.CondaEnvSdkFlavor
import com.jetbrains.python.target.PyTargetAwareAdditionalData
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import org.jetbrains.annotations.SystemDependent
import java.io.File
import java.io.IOError
import java.io.IOException
Expand Down Expand Up @@ -134,19 +134,19 @@ val Sdk.wslIsSupported: Boolean
}.also { wslSdkIsSupported = it }
}

private var lspIsSupportedValue: Boolean? = null
val lspIsSupported: Boolean
private var intellijLspClientSupportedValue: Boolean? = null
val intellijLspClientSupported: Boolean
get() {
if (lspIsSupportedValue is Boolean) {
return lspIsSupportedValue as Boolean
if (intellijLspClientSupportedValue is Boolean) {
return intellijLspClientSupportedValue as Boolean
}
return try {
@Suppress("UnstableApiUsage")
LspServerSupportProvider
lspIsSupportedValue = true
intellijLspClientSupportedValue = true
true
} catch (e: NoClassDefFoundError) {
lspIsSupportedValue = false
intellijLspClientSupportedValue = false
false
}
}
Expand Down Expand Up @@ -221,6 +221,27 @@ val PsiFile.isApplicableTo: Boolean
else -> language.isKindOf(PythonLanguage.getInstance())
}

fun getRuffExecutable(project: Project, ruffConfigService: RuffConfigService, lsp: Boolean): File? {
return when {
lsp -> ruffConfigService.ruffLspExecutablePath
else -> ruffConfigService.ruffExecutablePath
}?.let { File(it) }?.takeIf { it.exists() } ?: detectRuffExecutable(
project, ruffConfigService, lsp
)
}

fun getConfigArgs(ruffConfigService: RuffConfigService): List<String>? {
val config = ruffConfigService.ruffConfigPath?.let { File(it) }?.takeIf { it.exists() } ?: return null
return listOf(CONFIG_ARG, config.absolutePath)
}

fun isInspectionEnabled(project: Project): Boolean {
val inspectionProfileManager = ProjectInspectionProfileManager.getInstance(project)

val toolWrapper = InspectionToolRegistrar.getInstance().createTools()
.find { it.shortName == RuffInspection.INSPECTION_SHORT_NAME } ?: return false
return inspectionProfileManager.currentProfile.isToolEnabled(toolWrapper.displayKey)
}
fun runCommand(
commandArgs: CommandArgs
): String? = runCommand(
Expand Down
115 changes: 99 additions & 16 deletions src/com/koxudaxi/ruff/RuffConfigPanel.form
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</properties>
<border type="none"/>
<children>
<grid id="da542" layout-manager="GridLayoutManager" row-count="9" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="da542" layout-manager="GridLayoutManager" row-count="8" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
Expand Down Expand Up @@ -64,30 +64,103 @@
<text value="Exclude files outside of the project"/>
</properties>
</component>
<component id="1c73c" class="javax.swing.JCheckBox" binding="useRuffLspCheckBox">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Use ruff-lsp (Experimental) for PyCharm Pro/IDEA Ultimate"/>
</properties>
</component>
<component id="d521d" class="javax.swing.JCheckBox" binding="useRuffFormatCheckBox">
<constraints>
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Use ruff format (Experimental) for version 0.0.289 or later"/>
</properties>
</component>
<component id="36608" class="javax.swing.JCheckBox" binding="useRuffServerCheckBox">
<grid id="36978" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Use `ruff server` for LSP functionality (if ruff supports the server option, this is preferred over ruff-lsp)."/>
</properties>
</component>
<properties/>
<border type="none" title="Language Server Protocol (LSP)"/>
<children>
<grid id="1f570" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="1" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none" title="LSP Server"/>
<children>
<component id="93dcd" class="javax.swing.JRadioButton" binding="useRuffServerRadioButton">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<actionCommand value="`ruff server` command"/>
<label value="`ruff server` command"/>
<text value="`ruff server` command"/>
</properties>
</component>
<hspacer id="12e9e">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="89976" class="javax.swing.JRadioButton" binding="useRuffLspRadioButton">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<actionCommand value="`ruff-lsp` command"/>
<label value="`ruff-lsp` command"/>
<text value="`ruff-lsp` command"/>
</properties>
</component>
</children>
</grid>
<vspacer id="aaf9">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="7dbad" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="1" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none" title="LSP Client"/>
<children>
<component id="5d92e" class="javax.swing.JRadioButton" binding="useIntellijLspClientRadioButton">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Intellij's LSP Client (only pro versions)"/>
</properties>
</component>
<hspacer id="be0d7">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="59c8d" class="javax.swing.JRadioButton" binding="useLsp4ijRadioButton">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="LSP4IJ by RedHat"/>
</properties>
</component>
</children>
</grid>
<component id="df6ed" class="javax.swing.JCheckBox" binding="enableLspCheckBox">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Enable Ruff LSP feature"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<vspacer id="a33f9">
Expand Down Expand Up @@ -232,4 +305,14 @@
</hspacer>
</children>
</grid>
<buttonGroups>
<group name="lspClient">
<member id="59c8d"/>
<member id="5d92e"/>
</group>
<group name="lspServer">
<member id="93dcd"/>
<member id="89976"/>
</group>
</buttonGroups>
</form>
Loading

0 comments on commit 8ca1fff

Please sign in to comment.