Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.github.tempest.framework.console.run

import com.github.tempest.framework.TempestBundle
import com.github.tempest.framework.php.getConsoleCommandName
import com.intellij.execution.lineMarker.ExecutorAction
import com.intellij.execution.lineMarker.RunLineMarkerContributor
import com.intellij.icons.AllIcons
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.jetbrains.php.lang.psi.elements.Method

class ConsoleCommandLineMarkerProvider : RunLineMarkerContributor() {
override fun getInfo(element: PsiElement) = when {
element !is Method -> null
else -> {
val commandName = element.getConsoleCommandName() ?: return null
Info(
AllIcons.Actions.Execute,
ExecutorAction.getActions(1),
) {
TempestBundle.message(
"action.run.target.text",
StringUtil.wrapWithDoubleQuote(TempestBundle.message("action.run.target.command", commandName)),
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.github.tempest.framework.console.run

import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.configurations.RunConfigurationOptions
import com.intellij.openapi.project.Project
import com.jetbrains.php.config.commandLine.PhpCommandSettings
import com.jetbrains.php.run.PhpCommandLineRunConfiguration

class TempestConsoleCommandRunConfiguration(
project: Project,
factory: ConfigurationFactory,
name: String
) : PhpCommandLineRunConfiguration<TempestConsoleCommandRunConfigurationSettings>(project, factory, name) {
override fun fillCommandSettings(
envs: Map<String, String>,
command: PhpCommandSettings
) {
val commandName = settings.commandName ?: return
command.setScript("tempest", false)
command.addArgument(commandName)

command.importCommandLineSettings(settings.commandLineSettings, command.workingDirectory)
command.addEnvs(envs)
}

override fun getOptions() = super.getOptions() as TempestConsoleCommandRunConfigurationSettings
override fun getOptionsClass(): Class<out RunConfigurationOptions> {
return TempestConsoleCommandRunConfigurationSettings::class.java
}

override fun getConfigurationEditor() = TempestConsoleCommandSettingsEditor(project)

override fun createSettings() = TempestConsoleCommandRunConfigurationSettings().apply {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.github.tempest.framework.console.run

import com.intellij.execution.configurations.LocatableRunConfigurationOptions
import com.jetbrains.php.run.PhpCommandLineSettings
import com.jetbrains.php.run.PhpRunConfigurationSettings

class TempestConsoleCommandRunConfigurationSettings : PhpRunConfigurationSettings, LocatableRunConfigurationOptions() {
private val myCommandName = string("").provideDelegate(this, "commandName")
private val myBinary = string("./tempest").provideDelegate(this, "binary")
private val myWorkingDirectory = string("").provideDelegate(this, "binary")

var commandName: String?
get() = myCommandName.getValue(this)
set(scriptName) {
myCommandName.setValue(this, scriptName)
}

var binary: String?

Check warning on line 18 in src/main/kotlin/com/github/tempest/framework/console/run/TempestConsoleCommandRunConfigurationSettings.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "binary" is never used
get() = myBinary.getValue(this)
set(scriptName) {
myBinary.setValue(this, scriptName)
}

var documentRoot: String?

Check warning on line 24 in src/main/kotlin/com/github/tempest/framework/console/run/TempestConsoleCommandRunConfigurationSettings.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "documentRoot" is never used
get() = myBinary.getValue(this)
set(scriptName) {
myBinary.setValue(this, scriptName)
}

var commandLineSettings = PhpCommandLineSettings()

override fun getWorkingDirectory() = myWorkingDirectory.getValue(this)

override fun setWorkingDirectory(p0: String?) {
myWorkingDirectory.setValue(this, p0)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.github.tempest.framework.console.run

import com.github.tempest.framework.TempestIcons
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.configurations.ConfigurationTypeBase
import com.intellij.openapi.project.Project

class TempestConsoleCommandRunConfigurationType : ConfigurationTypeBase(
ID,
"Tempest Command",
"Runs console command",
TempestIcons.TEMPEST,
) {
init {
addFactory(object : ConfigurationFactory(this) {
override fun getId() = ID

override fun createTemplateConfiguration(project: Project) =
TempestConsoleCommandRunConfiguration(project, this, "Tempest")

override fun getOptionsClass() = TempestConsoleCommandRunConfigurationSettings::class.java
})
}

companion object {
const val ID = "TempestConsoleCommandRunConfiguration"

val INSTANCE = TempestConsoleCommandRunConfigurationType()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.github.tempest.framework.console.run

import com.intellij.openapi.options.SettingsEditor
import com.intellij.openapi.ui.DialogPanel
import com.intellij.ui.dsl.builder.Align
import com.intellij.ui.dsl.builder.LabelPosition
import com.intellij.ui.dsl.builder.TopGap
import com.intellij.ui.dsl.builder.panel
import com.jetbrains.php.run.PhpCommandLineConfigurationEditor
import javax.swing.JPanel
import javax.swing.JTextField

private fun PhpCommandLineConfigurationEditor.getMainPanel(): JPanel? {
val reflection = PhpCommandLineConfigurationEditor::class.java.getDeclaredField("myMainPanel")
reflection.isAccessible = true
return reflection.get(this) as JPanel?
}

class TempestConsoleCommandSettingsEditor private constructor(): SettingsEditor<TempestConsoleCommandRunConfiguration>() {
private val commandNameField = JTextField()
private val phpCommandLineConfigurationEditor = PhpCommandLineConfigurationEditor()

private lateinit var myPanel: DialogPanel

constructor(project: com.intellij.openapi.project.Project) : this() {
myPanel = panel {
row {
cell(commandNameField)
.label("Command:", LabelPosition.LEFT)
.align(Align.FILL)
}.topGap(TopGap.MEDIUM)

row {
phpCommandLineConfigurationEditor.init(project, true)
phpCommandLineConfigurationEditor.getMainPanel()?.apply {
scrollCell(this).align(Align.FILL)
}
}.topGap(TopGap.MEDIUM)
}
}

override fun resetEditorFrom(tempestConsoleCommandRunConfiguration: TempestConsoleCommandRunConfiguration) {
val settings = tempestConsoleCommandRunConfiguration.settings

myPanel.reset()
commandNameField.text = settings.commandName
phpCommandLineConfigurationEditor.resetEditorFrom(settings.commandLineSettings)
}

override fun applyEditorTo(tempestConsoleCommandRunConfiguration: TempestConsoleCommandRunConfiguration) {
val settings = tempestConsoleCommandRunConfiguration.settings

settings.commandName = commandNameField.text
phpCommandLineConfigurationEditor.applyEditorTo(settings.commandLineSettings)
}

override fun createEditor() = myPanel
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.github.tempest.framework.console.run

import com.github.tempest.framework.TempestBundle
import com.github.tempest.framework.TempestIcons
import com.github.tempest.framework.console.index.ConsoleCommandsIndex
import com.intellij.icons.AllIcons
import com.intellij.ide.actions.runAnything.activity.RunAnythingAnActionProvider
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.application.ReadAction
import com.intellij.util.indexing.FileBasedIndex

class TempestRunAnythingProvider : RunAnythingAnActionProvider<TempestRunCommandAction>() {
override fun getCommand(value: TempestRunCommandAction) =
TempestBundle.message("action.run.target.command", value.commandName)

override fun getHelpCommandPlaceholder() = "tempest <command>"

override fun getCompletionGroupTitle() = "Tempest"

override fun getHelpCommand() = "tempest"

override fun getHelpGroupTitle() = "PHP"

override fun getHelpIcon() = TempestIcons.TEMPEST

override fun getIcon(value: TempestRunCommandAction) = AllIcons.Actions.Execute

override fun getValues(dataContext: DataContext, pattern: String): Collection<TempestRunCommandAction> {
val project = CommonDataKeys.PROJECT.getData(dataContext) ?: return emptyList()

return ReadAction.compute<Collection<TempestRunCommandAction>, Throwable> {
FileBasedIndex.getInstance()
.getAllKeys(ConsoleCommandsIndex.key, project)
.map { TempestRunCommandAction(it) }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.github.tempest.framework.console.run

import com.github.tempest.framework.TempestBundle
import com.intellij.execution.Executor
import com.intellij.execution.RunManagerEx
import com.intellij.execution.runners.ExecutionUtil
import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent

class TempestRunCommandAction(val commandName: String) : AnAction() {
init {
templatePresentation.setText(TempestBundle.message("action.run.target.text", commandName), false)
templatePresentation.description = TempestBundle.message("action.run.target.description", commandName)
templatePresentation.icon = AllIcons.Actions.Execute
}

override fun actionPerformed(event: AnActionEvent) {
val project = event.project ?: return

val runManager = RunManagerEx.getInstanceEx(project)
val producer = TempestRunConfigurationProducer()
val configurationFactory = producer.configurationFactory

val runConfiguration = TempestConsoleCommandRunConfiguration(
project,
configurationFactory,
TempestBundle.message("action.run.target.command", commandName),
)
.apply { settings.commandName = commandName }

val configuration = runManager.createConfiguration(runConfiguration, configurationFactory)

runManager.setTemporaryConfiguration(configuration)
ExecutionUtil.runConfiguration(configuration, Executor.EXECUTOR_EXTENSION_NAME.extensionList.first())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.github.tempest.framework.console.run

import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.openapi.project.Project

class TempestRunConfigurationFactory(private val runConfigurationType: TempestConsoleCommandRunConfigurationType) :
ConfigurationFactory(runConfigurationType) {
override fun getId() = TempestConsoleCommandRunConfigurationType.ID
override fun getName() = runConfigurationType.displayName

override fun createTemplateConfiguration(project: Project) =
TempestConsoleCommandRunConfiguration(project, this, "name")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.github.tempest.framework.console.run

import com.github.tempest.framework.TempestBundle
import com.github.tempest.framework.php.getConsoleCommandName
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.LazyRunConfigurationProducer
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.jetbrains.php.lang.psi.elements.Method

class TempestRunConfigurationProducer : LazyRunConfigurationProducer<TempestConsoleCommandRunConfiguration>() {
override fun setupConfigurationFromContext(
configuration: TempestConsoleCommandRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val element = context.psiLocation as? Method ?: return false
val commandName = element.getConsoleCommandName() ?: return false

configuration.settings.commandName = commandName
configuration.name = TempestBundle.message("action.run.target.command", commandName)

return true
}

override fun isConfigurationFromContext(
configuration: TempestConsoleCommandRunConfiguration,
context: ConfigurationContext
): Boolean {
val method = context.psiLocation as? Method ?: return false

return configuration.settings.commandName == method.getConsoleCommandName()
}

override fun getConfigurationFactory() =
TempestRunConfigurationFactory(TempestConsoleCommandRunConfigurationType.INSTANCE)
}
14 changes: 14 additions & 0 deletions src/main/kotlin/com/github/tempest/framework/php/mixin.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.github.tempest.framework.php

import com.github.tempest.framework.TempestFrameworkClasses
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.util.PsiTreeUtil
import com.jetbrains.php.lang.psi.PhpFile
import com.jetbrains.php.lang.psi.elements.Method
import com.jetbrains.php.lang.psi.elements.Variable

fun PhpFile.getPhpViewVariables(): Set<Variable> {
Expand All @@ -11,3 +14,14 @@ fun PhpFile.getPhpViewVariables(): Set<Variable> {
.distinctBy { it.name }
.toSet()
}

fun Method.getConsoleCommandName(): String? {
return this
.getAttributes(TempestFrameworkClasses.ConsoleCommand)
.firstOrNull()
?.arguments
?.run { this.find { it.name == "name" } ?: firstOrNull() }
?.argument
?.value
?.run { StringUtil.unquoteString(this) }
}
10 changes: 9 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
<resource-bundle>messages.TempestBundle</resource-bundle>

<extensions defaultExtensionNs="com.intellij">
<configurationType
implementation="com.github.tempest.framework.console.run.TempestConsoleCommandRunConfigurationType"/>
<runLineMarkerContributor
language="PHP"
implementationClass="com.github.tempest.framework.console.run.ConsoleCommandLineMarkerProvider" />
<runConfigurationProducer
implementation="com.github.tempest.framework.console.run.TempestRunConfigurationProducer" />
<runAnything.executionProvider
implementation="com.github.tempest.framework.console.run.TempestRunAnythingProvider" />
<multiHostInjector
implementation="com.github.tempest.framework.views.injection.PHPLanguageInjector"/>
<webSymbols.webTypes
Expand All @@ -35,6 +44,5 @@
implementation="com.github.tempest.framework.router.index.RouterActionsIndex" />
</extensions>
<extensions defaultExtensionNs="com.jetbrains.php">

</extensions>
</idea-plugin>
3 changes: 3 additions & 0 deletions src/main/resources/messages/TempestBundle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
action.run.target.text=Run {0}
action.run.target.description=Tempest console command
action.run.target.command=tempest {0}
Loading