Skip to content

Commit

Permalink
volar: add an option to specify package WEB-61476
Browse files Browse the repository at this point in the history
GitOrigin-RevId: f33eb0237df6493c4639a8e4b7f375676f239f2a
  • Loading branch information
anstarovoyt authored and intellij-monorepo-bot committed Jun 13, 2023
1 parent 46945d1 commit a65cb40
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 12 deletions.
2 changes: 0 additions & 2 deletions vuejs/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@
nonDefaultProject="true"
/>

<projectService serviceImplementation="org.jetbrains.vuejs.options.VueSettings" />

<postStartupActivity implementation="org.jetbrains.vuejs.lang.html.psi.arrangement.VueArrangementSettingsMigration"/>

<directoryIndexExcludePolicy implementation="org.jetbrains.vuejs.libraries.nuxt.index.NuxtIndexExcludePolicy"/>
Expand Down
3 changes: 2 additions & 1 deletion vuejs/resources/messages/VueBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ vue.configurable.service.auto.help=Select this option to enable service integrat
vue.configurable.service.ts=TypeScript
vue.configurable.service.ts.help=Select this option to enable direct integration with TypeScript service for vue files. \
Because this integration doesn't work for TypeScript version 5.0.0 and later, in such cases internal IDE inspections will be used instead.
vue.configurable.service.volar=Volar
vue.configurable.service.volar=&Volar
vue.configurable.service.volar.package=Volar package:
vue.configurable.service.volar.help=Select this option to use Volar integration for all vue files. \
Please note that the integration is experimental, so it can be unstable in some cases.
vue.configurable.service.disabled=Disabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.text.SemVer
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.vuejs.lang.typescript.service.isVolarEnabledAndAvailable
import com.intellij.lang.typescript.lsp.defaultPackageKey
import com.intellij.lang.typescript.lsp.extractRefText
import org.jetbrains.vuejs.options.getVueSettings

internal val volarVersion = SemVer.parseFromText("1.6.5")
private const val volarPackage = "@volar/vue-language-server"
val defaultVolarVersion: SemVer = SemVer.parseFromText("1.6.5")!!
const val volarPackage = "@volar/vue-language-server"
private const val packageRelativePath = "/bin/vue-language-server.js"
val serverPackageName = TypeScriptPackageName(volarPackage, volarVersion)
val serverPackageName = TypeScriptPackageName(volarPackage, defaultVolarVersion)

class VolarSupportProvider : LspServerSupportProvider {
override fun fileOpened(project: Project, file: VirtualFile, serverStarter: LspServerStarter) {
Expand All @@ -44,12 +47,18 @@ class VolarServerDescriptor(project: Project, vararg roots: VirtualFile)

@ApiStatus.Experimental
object VolarExecutableDownloader {
fun getExecutable(): String? {
return getLspServerExecutablePath(serverPackageName, packageRelativePath)
fun getExecutable(project: Project): String? {
val packageRef = getVueSettings(project).packageRef
val ref = extractRefText(packageRef)
if (ref == defaultPackageKey) {
return getLspServerExecutablePath(serverPackageName, packageRelativePath)
}

return ref
}

fun getExecutableOrRefresh(project: Project): String? {
val executable = getExecutable()
val executable = getExecutable(project)
if (executable != null) return executable
scheduleLspServerDownloading(project, serverPackageName)
return null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.vuejs.lang.typescript.service.volar

import com.intellij.javascript.nodejs.PackageJsonData
import com.intellij.lang.javascript.buildTools.npm.PackageJsonUtil
import com.intellij.lang.javascript.ecmascript6.TypeScriptAnnotatorCheckerProvider
import com.intellij.lang.javascript.modules.NodeModuleUtil
import com.intellij.lang.typescript.compiler.TypeScriptLanguageServiceAnnotatorCheckerProvider
import com.intellij.lang.typescript.compiler.languageService.protocol.commands.response.TypeScriptQuickInfoResponse
import com.intellij.lang.typescript.lsp.JSFrameworkLspTypeScriptService
Expand All @@ -10,9 +13,11 @@ import com.intellij.platform.lsp.api.LspServerSupportProvider
import com.intellij.platform.lsp.impl.LspServerImpl
import com.intellij.platform.lsp.impl.requests.LspHoverRequest
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.util.text.SemVer
import org.jetbrains.vuejs.lang.typescript.service.isVolarEnabledAndAvailable
import org.jetbrains.vuejs.lang.typescript.service.isVolarFileTypeAcceptable
import org.jetbrains.vuejs.options.VueServiceSettings
Expand All @@ -24,7 +29,15 @@ class VolarTypeScriptService(project: Project) : JSFrameworkLspTypeScriptService
override fun getProviderClass(): Class<out LspServerSupportProvider> = VolarSupportProvider::class.java

override val name = "Volar"
override val serverVersion = volarVersion
override val serverVersion: SemVer
get() = calculateVersion()

private fun calculateVersion(): SemVer {
return VolarExecutableDownloader.getExecutable(project)
?.let { LocalFileSystem.getInstance().findFileByPath(it) }
?.let { PackageJsonUtil.findUpPackageJson(it) }
?.let { PackageJsonData.getOrCreate(it).version } ?: defaultVolarVersion
}

private fun quickInfo(element: PsiElement): TypeScriptQuickInfoResponse? {
val server = getServer() ?: return null
Expand Down
23 changes: 22 additions & 1 deletion vuejs/src/org/jetbrains/vuejs/options/VueConfigurable.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.vuejs.options

import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterManager
import com.intellij.javascript.nodejs.util.NodePackageField
import com.intellij.lang.typescript.lsp.JSExternalDefinitionsNodeDescriptor
import com.intellij.lang.typescript.lsp.JSExternalDefinitionsPackageResolver
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.options.UiDslUnnamedConfigurable
import com.intellij.openapi.project.Project
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.Panel
import com.intellij.ui.dsl.builder.bind
import com.intellij.ui.dsl.builder.toMutableProperty
import org.jetbrains.vuejs.VueBundle
import org.jetbrains.vuejs.lang.typescript.service.volar.serverPackageName

class VueConfigurable(project: Project) : UiDslUnnamedConfigurable.Simple(), Configurable {
class VueConfigurable(private val project: Project) : UiDslUnnamedConfigurable.Simple(), Configurable {
private val settings = getVueSettings(project)

override fun Panel.createContent() {
group(VueBundle.message("vue.configurable.service.group")) {
row(VueBundle.message("vue.configurable.service.volar.package")) {
val volarNodeDescriptor = JSExternalDefinitionsNodeDescriptor(serverPackageName)
val packageField = NodePackageField(project, volarNodeDescriptor, { NodeJsInterpreterManager.getInstance(project).interpreter },
JSExternalDefinitionsPackageResolver(project, volarNodeDescriptor))

cell(packageField)
.align(AlignX.FILL)
.bind({ it.selectedRef },
{ nodePackageField, nodePackageRef -> nodePackageField.selectedRef = nodePackageRef },
settings::packageRef.toMutableProperty())
}

buttonsGroup {
row {
radioButton(VueBundle.message("vue.configurable.service.disabled"), VueServiceSettings.DISABLED)
Expand All @@ -34,5 +53,7 @@ class VueConfigurable(project: Project) : UiDslUnnamedConfigurable.Simple(), Con
}
}



override fun getDisplayName() = VueBundle.message("vue.configurable.title")
}
17 changes: 17 additions & 0 deletions vuejs/src/org/jetbrains/vuejs/options/VueSettings.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.vuejs.options

import com.intellij.lang.typescript.lsp.createPackageRef
import com.intellij.lang.typescript.lsp.defaultPackageKey
import com.intellij.lang.typescript.lsp.extractRefText
import com.intellij.lang.typescript.lsp.restartTypeScriptServicesAsync
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project
import org.jetbrains.vuejs.lang.typescript.service.volar.serverPackageName

fun getVueSettings(project: Project): VueSettings = project.service<VueSettings>() //

@Service(Service.Level.PROJECT)
@State(name = "VueSettings", storages = [Storage(StoragePathMacros.WORKSPACE_FILE)])
class VueSettings(val project: Project) : SimplePersistentStateComponent<VueSettingsState>(VueSettingsState()) {

var serviceType
get() = state.innerServiceType
set(value) {
val changed = state.innerServiceType != value
state.innerServiceType = value
if (changed) restartTypeScriptServicesAsync(project)
}

var packageRef
get() = createPackageRef(state.packageName ?: defaultPackageKey, serverPackageName)
set(value) {
val refText = extractRefText(value)
val changed = state.packageName != refText
state.packageName = refText
if (changed) restartTypeScriptServicesAsync(project)
}

}

class VueSettingsState : BaseState() {
var innerServiceType by enum(VueServiceSettings.AUTO)
var packageName by string(defaultPackageKey)
}

enum class VueServiceSettings {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class VolarServiceTest : JSTempDirWithNodeInterpreterTest() {
(myFixture as CodeInsightTestFixtureImpl).canChangeDocumentDuringHighlighting(true)

VolarExecutableDownloader.getExecutableOrRefresh(project) // could run blocking download
TestCase.assertNotNull(VolarExecutableDownloader.getExecutable())
TestCase.assertNotNull(VolarExecutableDownloader.getExecutable(project))
}

@Test
Expand Down

0 comments on commit a65cb40

Please sign in to comment.