@@ -3,20 +3,30 @@ package com.github.biomejs.intellijbiome.lsp
3
3
import com.github.biomejs.intellijbiome.BiomeBundle
4
4
import com.github.biomejs.intellijbiome.BiomeIcons
5
5
import com.github.biomejs.intellijbiome.BiomePackage
6
- import com.github.biomejs.intellijbiome.extensions.runBiomeCLI
6
+ import com.github.biomejs.intellijbiome.extensions.isNodeScript
7
7
import com.github.biomejs.intellijbiome.listeners.BIOME_CONFIG_RESOLVED_TOPIC
8
8
import com.github.biomejs.intellijbiome.services.BiomeServerService
9
9
import com.github.biomejs.intellijbiome.settings.BiomeConfigurable
10
10
import com.github.biomejs.intellijbiome.settings.BiomeSettings
11
11
import com.intellij.execution.ExecutionException
12
12
import com.intellij.execution.configurations.GeneralCommandLine
13
+ import com.intellij.execution.process.OSProcessHandler
14
+ import com.intellij.javascript.nodejs.execution.NodeTargetRun
15
+ import com.intellij.javascript.nodejs.execution.NodeTargetRunOptions.Companion.of
16
+ import com.intellij.javascript.nodejs.execution.withInvisibleProgress
17
+ import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterManager
18
+ import com.intellij.javascript.nodejs.interpreter.local.NodeJsLocalInterpreter
19
+ import com.intellij.javascript.nodejs.interpreter.wsl.WslNodeInterpreter
20
+ import com.intellij.lang.javascript.JavaScriptBundle
13
21
import com.intellij.openapi.components.service
14
22
import com.intellij.openapi.project.Project
15
23
import com.intellij.openapi.vfs.VirtualFile
16
24
import com.intellij.platform.lsp.api.*
17
25
import com.intellij.platform.lsp.api.customization.LspFormattingSupport
18
26
import com.intellij.platform.lsp.api.lsWidget.LspServerWidgetItem
19
27
import com.intellij.util.SmartList
28
+ import java.io.File
29
+ import kotlin.io.path.Path
20
30
21
31
22
32
@Suppress(" UnstableApiUsage" )
@@ -38,29 +48,32 @@ class BiomeLspServerSupportProvider : LspServerSupportProvider {
38
48
serverStarter.ensureServerStarted(BiomeLspServerDescriptor (project, executable, configPath))
39
49
}
40
50
41
- override fun createLspServerWidgetItem (lspServer : LspServer , currentFile : VirtualFile ? ) = LspServerWidgetItem (
51
+ override fun createLspServerWidgetItem (lspServer : LspServer ,
52
+ currentFile : VirtualFile ? ) = LspServerWidgetItem (
42
53
lspServer, currentFile,
43
54
BiomeIcons .BiomeIcon , BiomeConfigurable ::class .java
44
55
)
45
56
}
46
57
47
58
@Suppress(" UnstableApiUsage" )
48
- class BiomeLspServerManagerListener (val project : Project ) : LspServerManagerListener {
49
- override fun serverStateChanged (lspServer : LspServer ) {
50
- if (lspServer.descriptor is BiomeLspServerDescriptor && lspServer.state == LspServerState .ShutdownUnexpectedly ) {
51
- // restart again if the server was shutdown unexpectedly.
52
- // This can be caused by race condition, when we restart LSP server because of config change,
53
- // but Intellij also tried to send a request to it at the same time.
54
- // Unfortunate There is no way prevent IDEA send requests after LSP started.
55
- project.service<BiomeServerService >().restartBiomeServer()
59
+ private class BiomeLspServerDescriptor (project : Project ,
60
+ val executable : String ,
61
+ val configPath : String? ) :
62
+ ProjectWideLspServerDescriptor (project, " Biome" ) {
63
+ private val biomePackage = BiomePackage (project)
64
+ private val executableFile = File (executable)
65
+ private val params: SmartList <String > by lazy {
66
+ val params = SmartList (" lsp-proxy" )
67
+ if (! configPath.isNullOrEmpty()) {
68
+ params.add(" --config-path" )
69
+ params.add(configPath)
56
70
}
71
+ return @lazy params
57
72
}
58
- }
59
73
60
- @Suppress(" UnstableApiUsage" )
61
- private class BiomeLspServerDescriptor (project : Project , val executable : String , val configPath : String? ) :
62
- ProjectWideLspServerDescriptor (project, " Biome" ) {
63
- private val biomePackage = BiomePackage (project)
74
+ init {
75
+ biomePackage.versionNumber()?.let { project.messageBus.syncPublisher(BIOME_CONFIG_RESOLVED_TOPIC ).resolved(it) }
76
+ }
64
77
65
78
override fun isSupportedFile (file : VirtualFile ): Boolean {
66
79
val settings = BiomeSettings .getInstance(project)
@@ -72,25 +85,44 @@ private class BiomeLspServerDescriptor(project: Project, val executable: String,
72
85
}
73
86
74
87
override fun createCommandLine (): GeneralCommandLine {
75
- val params = SmartList (" lsp-proxy" )
76
-
77
- if (! configPath.isNullOrEmpty()) {
78
- params.add(" --config-path" )
79
- params.add(configPath)
88
+ // we're here only if we specify an executable file
89
+ return GeneralCommandLine ().apply {
90
+ withExePath(executable)
91
+ withParentEnvironmentType(GeneralCommandLine .ParentEnvironmentType .CONSOLE )
92
+ project.basePath?.let {
93
+ withWorkingDirectory(Path (it))
94
+ }
95
+ addParameters(params)
80
96
}
81
97
98
+ }
99
+
100
+ override fun startServerProcess (): OSProcessHandler {
82
101
if (executable.isEmpty()) {
83
102
throw ExecutionException (BiomeBundle .message(" biome.language.server.not.found" ))
84
103
}
85
104
86
- val version = biomePackage.versionNumber()
105
+ if (! (executableFile.isFile && executableFile.isNodeScript())) {
106
+ return super .startServerProcess()
107
+ }
87
108
88
- version?.let { project.messageBus.syncPublisher(BIOME_CONFIG_RESOLVED_TOPIC ).resolved(it) }
109
+ val interpreter = NodeJsInterpreterManager .getInstance(project).interpreter
110
+ if (interpreter !is NodeJsLocalInterpreter && interpreter !is WslNodeInterpreter ) {
111
+ throw ExecutionException (JavaScriptBundle .message(" lsp.interpreter.error" ))
112
+ }
89
113
90
- return GeneralCommandLine ().runBiomeCLI(project, executable).apply {
114
+ val target = NodeTargetRun (interpreter, project, null , of(false ))
115
+ target.commandLineBuilder.apply {
116
+ project.basePath?.let { this .setWorkingDirectory(target.path(it)) }
117
+ addParameter(target.path(executable))
91
118
addParameters(params)
92
- withWorkDirectory(configPath)
119
+ addParameter(" --stdio" )
120
+ charset = Charsets .UTF_8
93
121
}
122
+
123
+ val process = withInvisibleProgress { target.startProcessEx() }
124
+
125
+ return process.processHandler
94
126
}
95
127
96
128
override val lspGoToDefinitionSupport = false
0 commit comments