Skip to content

Allow using shortcut such as "pwsh" as executable path #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 23, 2023
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
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ tasks.withType(JavaCompile).all {
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
apiVersion = '1.3'
languageVersion = '1.3'
apiVersion = '1.4'
languageVersion = '1.4'
jvmTarget = '1.8'
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.intellij.plugin.powershell.lang.lsp.ide.settings

import com.intellij.execution.configurations.PathEnvironmentVariableUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileChooser.FileChooserDescriptor
import com.intellij.openapi.fileChooser.FileChooserFactory
import com.intellij.openapi.options.ConfigurationException
import com.intellij.openapi.ui.TextComponentAccessor
import com.intellij.openapi.ui.TextFieldWithBrowseButton
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.plugin.powershell.ide.MessagesBundle
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils.getEditorServicesModuleVersion
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils.getEditorServicesStartupScript
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils.getPSExtensionModulesDir
import com.intellij.plugin.powershell.lang.lsp.languagehost.PowerShellExtensionError
import com.intellij.ui.components.JBTextField
import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.Contract

object FormUIUtil {

@JvmStatic
@Throws(ConfigurationException::class)
fun getEditorServicesVersion(editorServicesDir: String): String {
if (!FileUtil.exists(editorServicesDir)) throw ConfigurationException(
"Editor Services directory '$editorServicesDir' does not exist."
)
val editorServicesVersion: String
try {
editorServicesVersion = getEditorServicesModuleVersion(getPSExtensionModulesDir(editorServicesDir))
} catch (e: PowerShellExtensionError) {
PowerShellConfigurable.LOG.warn(
"Error detecting PowerShell Editor Services module version: " + e.message,
e
)
throw ConfigurationException("Can not detect Editor Services module version" + e.message)
}
if (StringUtil.isEmpty(editorServicesVersion)) throw ConfigurationException("Can not detect Editor Services module version")
val startupScript = getEditorServicesStartupScript(editorServicesDir)
if (StringUtil.isEmpty(startupScript)) throw ConfigurationException("Can not find Editor Services startup script")
return editorServicesVersion
}

@Contract("null -> fail")
@JvmStatic
fun validatePowerShellExecutablePath(powerShellExePath: String) {
val exists = if (FileUtil.isAbsolute(powerShellExePath)) {
FileUtil.exists(powerShellExePath)
} else {
PathEnvironmentVariableUtil.findExecutableInPathOnAnyOS(powerShellExePath) != null
}
if (!exists) {
throw ConfigurationException(
MessagesBundle.message("settings.errors.executable-not-found", powerShellExePath)
)
}
}

@JvmStatic
fun createTextFieldWithBrowseButton(
description: String,
field: JBTextField?,
fileChooserDescriptor: FileChooserDescriptor
): TextFieldWithBrowseButton {
val textFieldWithBrowseButton = TextFieldWithBrowseButton(field)
fileChooserDescriptor.withShowHiddenFiles(true)
val textField = textFieldWithBrowseButton.childComponent
textField.setDisabledTextColor(UIUtil.getLabelDisabledForeground())
textFieldWithBrowseButton.addBrowseFolderListener(
description,
null,
null,
fileChooserDescriptor,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT
)
FileChooserFactory.getInstance().installFileCompletion(textField, fileChooserDescriptor, true, null)
return textFieldWithBrowseButton
}

val globalSettingsExecutablePath: String?
get() = ApplicationManager.getApplication().getComponent(LSPInitMain::class.java).state.powerShellExePath
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ public void apply() throws ConfigurationException {
getPSJpanel().setEditorServicesVersionLabelValue(null);
throw e;
}
if (editorServicesVersion == null) {
getPSJpanel().setEditorServicesVersionLabelValue(null);
throw new ConfigurationException("Can not validate PowerShell extension");
}
} else {
editorServicesVersion = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.plugin.powershell.ide.MessagesBundle;
import com.intellij.plugin.powershell.lang.lsp.LSPInitMain;
import com.intellij.plugin.powershell.lang.lsp.languagehost.PSLanguageHostUtils;
Expand All @@ -15,6 +14,8 @@
import org.jetbrains.concurrency.CancellablePromise;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class PowerShellExecutableChooserPanel extends JComponent {
private final Logger LOG = Logger.getInstance(getClass());
Expand All @@ -29,34 +30,45 @@ public PowerShellExecutableChooserPanel(@Nullable String executablePath) {
}

private void createUIComponents() {
JBTextField textField = new JBTextField(0);
textField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
String powerShellExePath = textField.getText();
updatePowerShellVersionLabel(powerShellExePath);
}

@Override
public void removeUpdate(DocumentEvent e) {
String powerShellExePath = textField.getText();
updatePowerShellVersionLabel(powerShellExePath);
}

@Override
public void changedUpdate(DocumentEvent e) {
}
});
FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(true, false, false, false, false, false);
psExecutablePathTextFieldChooser = FormUIUtil.createTextFieldWithBrowseButton(
MessagesBundle.INSTANCE.message("powershell.executable.path.dialog.text"),
new JBTextField(0),
new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public void validateSelectedFiles(VirtualFile @NotNull [] files) throws Exception {
if (files.length <= 0) return;
String powerShellExePath = files[0].getCanonicalPath();
FormUIUtil.validatePowerShellExecutablePath(powerShellExePath);
CancellablePromise<String> versionPromise = PSLanguageHostUtils.INSTANCE.getPowerShellVersion(powerShellExePath);
versionPromise.onError(throwable -> {
LOG.warn("Exception when getting PowerShell version: ", throwable);
setPowerShellVersionLabelValue(null);
}).onSuccess(version -> setPowerShellVersionLabelValue(version)
);
}
});
textField, fileChooserDescriptor);
}

private void updatePowerShellVersionLabel(@NotNull String powerShellExePath) {
CancellablePromise<String> versionPromise = PSLanguageHostUtils.INSTANCE.getPowerShellVersion(powerShellExePath);
versionPromise.onError(throwable -> {
LOG.warn("Exception when getting PowerShell version: ", throwable);
setPowerShellVersionLabelValue(null);
}).onSuccess(this::setPowerShellVersionLabelValue);
LOG.debug("Exception when getting PowerShell version: ", throwable);
if (getExecutablePath().equals(powerShellExePath)) {
setPowerShellVersionLabelValue(null);
}
}).onSuccess(version -> {
if (getExecutablePath().equals(powerShellExePath)) {
setPowerShellVersionLabelValue(version);
}
});
}

public String getExecutablePath() {
public @NotNull String getExecutablePath() {
return psExecutablePathTextFieldChooser.getText().trim();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.intellij.plugin.powershell.lang.lsp.ide.settings.FormUIUtil
class MyRunConfigurationTemplateProvider : RunConfigurationTemplateProvider {
override fun getRunConfigurationTemplate(factory: ConfigurationFactory, runManager: RunManagerImpl): RunnerAndConfigurationSettingsImpl? {
val templateConfiguration = factory.createTemplateConfiguration(runManager.project, runManager) as? PowerShellRunConfiguration ?: return null
templateConfiguration.executablePath = FormUIUtil.getGlobalSettingsExecutablePath()
templateConfiguration.executablePath = FormUIUtil.globalSettingsExecutablePath
return RunnerAndConfigurationSettingsImpl(runManager, templateConfiguration, true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ class PowerShellRunConfiguration(project: Project, configurationFactory: Configu
var scriptParameters: String = ""
private var commandOptions: String? = null
var environmentVariables: EnvironmentVariablesData = EnvironmentVariablesData.DEFAULT
var executablePath: String? = FormUIUtil.getGlobalSettingsExecutablePath()
var executablePath: String? = FormUIUtil.globalSettingsExecutablePath

override fun getConfigurationEditor(): SettingsEditor<out RunConfiguration> = PowerShellRunSettingsEditor(project, this)

@Throws(ExecutionException::class)
override fun getState(executor: Executor, environment: ExecutionEnvironment): RunProfileState? =
override fun getState(executor: Executor, environment: ExecutionEnvironment): RunProfileState =
PowerShellScriptCommandLineState(this, environment)

@Throws(InvalidDataException::class)
Expand All @@ -60,7 +60,7 @@ class PowerShellRunConfiguration(project: Project, configurationFactory: Configu
this.workingDirectory = workingDirectory
}
environmentVariables = EnvironmentVariablesData.readExternal(element)
executablePath = if (StringUtil.isEmpty(exePath)) FormUIUtil.getGlobalSettingsExecutablePath() else exePath
executablePath = if (StringUtil.isEmpty(exePath)) FormUIUtil.globalSettingsExecutablePath else exePath
}

@Throws(WriteExternalException::class)
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
<dl>
<dt>Unreleased<br></dt>
<dd><a href="https://github.com/ant-druha/intellij-powershell/pull/45">&#45</a>: Upgrade PSScriptAnalyzer from 1.17.1 to 1.19.0;</dd>
<dd><a href="https://github.com/ant-druha/intellij-powershell/pull/75">&#75</a>: Add indents for array elements when formatting.</dd>
<dd><a href="https://github.com/ant-druha/intellij-powershell/pull/75">&#75</a>: Add indents for array elements when formatting;</dd>
<dd><a href="https://github.com/ant-druha/intellij-powershell/pull/89">&#89</a>: Allow entering the executables from <code>PATH</code> in the plugin settings.</dd>

<dt>2.0.10 update<br></dt>
<dd>&#183; Fixing <a href="https://github.com/ant-druha/intellij-powershell/issues/76">76 Exception thrown when plugin is enabled but no powershell is found in the path</a> ;</dd>
Expand Down
31 changes: 18 additions & 13 deletions src/main/resources/messages/MessagesBundle.properties
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
wrapping.catch,type.list=Catch type list
wrapping.attribute.argument=Attribute arguments
wrapping.pipeline=Pipeline
wrapping.block.parameters=Block parameters

code.style.align.multiline=Align when multiline

settings.powershell=PowerShell
editor.services.inspection=PSScriptAnalyzer

powershell.download.link=https://github.com/powershell/powershell#get-powershell
powershell.editor.services.download.link=https://github.com/PowerShell/PowerShellEditorServices/releases
powershell.editor.services.path.dialog.text=Select folder
powershell.executable.path.dialog.text=Select PowerShell executable
powershell.extension.path.form.label=PowerShell Editor Services:
powershell.extension.path.form.description=Here you can specify the path to <a href="{0}">PowerShellEditorServices</a> package.
ps.editor.services.detected.version.label=Version:
powershell.vs.code.extension.install.link=https://github.com/PowerShell/vscode-powershell#installing-the-extension
powershell.editor.services.download.link=https://github.com/PowerShell/PowerShellEditorServices/releases
powershell.download.link=https://github.com/powershell/powershell#get-powershell
powershell.extension.path.form.label=PowerShell Editor Services:
powershell.install.message=\nPowerShell executable not found in PATH. <a href="{0}">Install</a>
vs.code.powershell.extension.configure.message=\nWould you like to <a href="{0}">install</a> PowerShell VSCode extension to get more rich PowerShell Editor assistance? \nIf extension is installed, you can specify the path manually in <a href="{1}">Settings</a>.
powershell.vs.code.extension.install.link=https://github.com/PowerShell/vscode-powershell#installing-the-extension

ps.editor.services.detected.version.label=Version:

settings.errors.executable-not-found=PowerShell executable "{0}" could not be found.
settings.powershell.lsp.is.enabled.box.text=Integrate Editor with PowerShell EditorServices host
editor.services.inspection=PSScriptAnalyzer
settings.powershell=PowerShell

vs.code.powershell.extension.configure.message=\nWould you like to <a href="{0}">install</a> PowerShell VSCode extension to get more rich PowerShell Editor assistance? \nIf extension is installed, you can specify the path manually in <a href="{1}">Settings</a>.

wrapping.attribute.argument=Attribute arguments
wrapping.block.parameters=Block parameters
wrapping.catch,type.list=Catch type list
wrapping.pipeline=Pipeline