Skip to content

Commit cd1cd28

Browse files
committed
initialize php lsp support
1 parent 6e6b7df commit cd1cd28

12 files changed

Lines changed: 230 additions & 91 deletions

File tree

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ dependencies {
4343
// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace.
4444
plugins(providers.gradleProperty("platformPlugins").map { it.split(',') })
4545

46-
instrumentationTools()
4746
pluginVerifier()
4847
zipSigner()
4948
testFramework(TestFrameworkType.Platform)
49+
// intellijIdeaUltimate("2024.3.1.1")
5050
}
5151
}
5252

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ pluginVersion = 0.0.1
88

99
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1010
pluginSinceBuild = 233
11-
pluginUntilBuild = 242.*
11+
pluginUntilBuild = 243.*
1212

1313
# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
14-
platformType = IC
15-
platformVersion = 2023.3.8
14+
platformType = IU
15+
platformVersion = 2024.3.1.1
1616

1717
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
1818
# Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP

gradle/libs.versions.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ junit = "4.13.2"
44

55
# plugins
66
changelog = "2.2.1"
7-
intelliJPlatform = "2.1.0"
8-
kotlin = "1.9.25"
9-
kover = "0.8.3"
10-
qodana = "2024.2.3"
7+
intelliJPlatform = "2.2.1"
8+
kotlin = "2.1.0"
9+
kover = "0.9.1"
10+
qodana = "2024.3.4"
1111

1212
[libraries]
1313
junit = { group = "junit", name = "junit", version.ref = "junit" }
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
2+
package com.github.xepozz.phplsp
3+
4+
import com.intellij.openapi.application.ApplicationManager
5+
import com.intellij.openapi.components.*
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.platform.lsp.api.LspServerManager
8+
9+
@Service(Service.Level.PROJECT)
10+
@State(name = "PrismaServiceSettings", storages = [Storage(StoragePathMacros.WORKSPACE_FILE)])
11+
class LspServiceSettings(val project: Project) :
12+
SimplePersistentStateComponent<LspServiceState>(LspServiceState()) {
13+
var serviceMode
14+
get() = state.serviceMode
15+
set(value) {
16+
val changed = state.serviceMode != value
17+
state.serviceMode = value
18+
if (changed) {
19+
restartPhpLspServerAsync(project)
20+
}
21+
}
22+
23+
var port
24+
get() = state.port
25+
set(value) {
26+
val changed = state.port != value
27+
state.port = value
28+
if (changed) {
29+
restartPhpLspServerAsync(project)
30+
}
31+
}
32+
33+
var command
34+
get() = state.command ?: ""
35+
set(value) {
36+
val changed = state.command != value
37+
state.command = value
38+
if (changed) {
39+
restartPhpLspServerAsync(project)
40+
}
41+
}
42+
43+
var binary
44+
get() = state.binary ?: ""
45+
set(value) {
46+
val changed = state.binary != value
47+
state.binary = value
48+
if (changed) {
49+
restartPhpLspServerAsync(project)
50+
}
51+
}
52+
53+
companion object {
54+
fun getInstance(project: Project) = project.service<LspServiceSettings>()
55+
}
56+
}
57+
58+
class LspServiceState : BaseState() {
59+
var serviceMode by enum(LspServiceMode.ENABLED)
60+
var binary by string("/bin/lsp")
61+
var command by string("serve App\\\\Application --port=%d")
62+
var port by property(5007)
63+
}
64+
65+
enum class LspServiceMode {
66+
ENABLED,
67+
DISABLED
68+
}
69+
70+
fun restartPhpLspServerAsync(project: Project) {
71+
ApplicationManager.getApplication().invokeLater({
72+
val lspServerManager = LspServerManager.getInstance(project)
73+
74+
lspServerManager.stopAndRestartIfNeeded(PhpLspServerSupportProvider::class.java)
75+
}, project.disposed)
76+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.github.xepozz.phplsp
2+
3+
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.execution.process.OSProcessHandler
5+
import com.intellij.openapi.project.Project
6+
import com.intellij.openapi.vfs.VirtualFile
7+
import com.intellij.platform.lsp.api.LspCommunicationChannel
8+
import com.intellij.platform.lsp.api.ProjectWideLspServerDescriptor
9+
import com.intellij.util.io.BaseDataReader
10+
import com.intellij.util.io.BaseOutputReader
11+
import com.intellij.util.io.BaseOutputReader.Options.forMostlySilentProcess
12+
13+
class PhpLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "PHP Language") {
14+
val settings = LspServiceSettings.getInstance(project)
15+
16+
override fun isSupportedFile(file: VirtualFile) =
17+
settings.serviceMode == LspServiceMode.ENABLED && file.extension == "php"
18+
19+
override val lspDocumentColorSupport = super.lspDocumentColorSupport
20+
override val lspCodeActionsSupport = super.lspCodeActionsSupport
21+
override val lspCommandsSupport = super.lspCommandsSupport
22+
override val lspDiagnosticsSupport = super.lspDiagnosticsSupport
23+
override val lspFindReferencesSupport = super.lspFindReferencesSupport
24+
override val lspFormattingSupport = super.lspFormattingSupport
25+
26+
override val lspSemanticTokensSupport = super.lspSemanticTokensSupport
27+
override val lspGoToDefinitionSupport = true
28+
override val lspGoToTypeDefinitionSupport = true
29+
override val lspCompletionSupport = super.lspCompletionSupport
30+
override val lspHoverSupport = true
31+
32+
override val lspCommunicationChannel = LspCommunicationChannel.Socket(settings.port, false)
33+
34+
override fun startServerProcess(): OSProcessHandler {
35+
// Thread.sleep(1)
36+
val startingCommandLine = createCommandLine().withCharset(Charsets.UTF_8)
37+
// LOG.info("$this: starting LSP server: $startingCommandLine")
38+
return object : OSProcessHandler(startingCommandLine) {
39+
override fun readerOptions(): BaseOutputReader.Options = object : BaseOutputReader.Options() {
40+
override fun policy(): BaseDataReader.SleepingPolicy = BaseDataReader.SleepingPolicy.BLOCKING
41+
42+
// Must not loose '\r' in "\r\n" line endings. They affect char count, which must match `Content-Length`
43+
override fun splitToLines(): Boolean = true
44+
}
45+
}
46+
}
47+
override fun createCommandLine() = GeneralCommandLine(
48+
settings.binary,
49+
"serve",
50+
"App\\Application",
51+
"--port=%d".format(settings.port),
52+
)
53+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.github.xepozz.phplsp
2+
3+
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.intellij.execution.process.OSProcessHandler
5+
import com.intellij.icons.AllIcons
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.vfs.VirtualFile
8+
import com.intellij.platform.lsp.api.LspCommunicationChannel
9+
import com.intellij.platform.lsp.api.LspServer
10+
import com.intellij.platform.lsp.api.LspServerSupportProvider
11+
import com.intellij.platform.lsp.api.LspServerSupportProvider.LspServerStarter
12+
import com.intellij.platform.lsp.api.ProjectWideLspServerDescriptor
13+
import com.intellij.platform.lsp.api.lsWidget.LspServerWidgetItem
14+
15+
internal class PhpLspServerSupportProvider : LspServerSupportProvider {
16+
override fun fileOpened(project: Project, file: VirtualFile, serverStarter: LspServerStarter) {
17+
if (file.extension == "php") {
18+
serverStarter.ensureServerStarted(PhpLspServerDescriptor(project))
19+
}
20+
}
21+
22+
override fun createLspServerWidgetItem(
23+
lspServer: LspServer,
24+
currentFile: VirtualFile?
25+
) = LspServerWidgetItem(
26+
lspServer,
27+
currentFile,
28+
AllIcons.Language.Php,
29+
PhpLspSettingsConfigurable::class.java,
30+
)
31+
}
32+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
2+
package com.github.xepozz.phplsp
3+
4+
import com.intellij.openapi.options.Configurable
5+
import com.intellij.openapi.options.UiDslUnnamedConfigurable
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.ui.dsl.builder.Panel
8+
import com.intellij.ui.dsl.builder.bind
9+
import com.intellij.ui.dsl.builder.bindIntText
10+
import com.intellij.ui.dsl.builder.bindText
11+
12+
class PhpLspSettingsConfigurable(project: Project) : UiDslUnnamedConfigurable.Simple(), Configurable {
13+
private val settings = LspServiceSettings.getInstance(project)
14+
15+
override fun Panel.createContent() {
16+
group("Language Server Configuration") {
17+
buttonsGroup {
18+
row {
19+
radioButton("Enabled", LspServiceMode.ENABLED)
20+
}
21+
row {
22+
radioButton("Disabled", LspServiceMode.DISABLED)
23+
}
24+
}.apply {
25+
bind(settings::serviceMode)
26+
}
27+
28+
separator()
29+
30+
row {
31+
textFieldWithBrowseButton()
32+
.label("Binary")
33+
.bindText(settings::binary)
34+
}
35+
// row {
36+
// textField()
37+
// .label("Command")
38+
// .bindText(settings::command)
39+
// }
40+
row {
41+
textField()
42+
.label("Port")
43+
.bindIntText(settings::port)
44+
}
45+
46+
}
47+
}
48+
49+
override fun getDisplayName() = MyBundle.message("settings.configurable.title")
50+
}

src/main/kotlin/com/github/xepozz/phplsp/listeners/MyApplicationActivationListener.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/main/kotlin/com/github/xepozz/phplsp/services/MyProjectService.kt

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/kotlin/com/github/xepozz/phplsp/toolWindow/MyToolWindowFactory.kt

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)