diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java index b16d87fda4ee..0a3ca9670323 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java @@ -14,6 +14,7 @@ import com.intellij.execution.runners.ExecutionUtil; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.icons.AllIcons; +import com.intellij.ide.macro.MacroManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -322,7 +323,7 @@ public class ExecutorRegistryImpl extends ExecutorRegistry implements Disposable if (project == null || project.isDisposed()) { return; } - + MacroManager.getInstance().cacheMacrosPreview(e.getDataContext()); run(project, getSelectedConfiguration(project), e.getDataContext()); } } diff --git a/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java index 91559712e24b..3ed9d6b25f86 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java @@ -23,6 +23,7 @@ import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.configurations.LocatableConfiguration; import com.intellij.execution.configurations.LocatableConfigurationBase; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.ide.macro.MacroManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -125,6 +126,7 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { @Override public void actionPerformed(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); + MacroManager.getInstance().cacheMacrosPreview(e.getDataContext()); final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); final RunnerAndConfigurationSettings existing = context.findExisting(); if (existing == null) { diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java index d33f9324b1c3..f714fdc8aa07 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java @@ -25,6 +25,7 @@ import com.intellij.execution.runners.ExecutionUtil; import com.intellij.execution.runners.ProgramRunner; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; +import com.intellij.ide.macro.MacroManager; import com.intellij.ide.util.PropertiesComponent; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.CommonDataKeys; @@ -328,6 +329,7 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider { public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) { RunnerAndConfigurationSettings config = getValue(); RunManager.getInstance(project).setSelectedConfiguration(config); + MacroManager.getInstance().cacheMacrosPreview(context); ExecutionUtil.runConfiguration(config, executor); } diff --git a/platform/lang-impl/src/com/intellij/execution/runners/FakeRerunAction.java b/platform/lang-impl/src/com/intellij/execution/runners/FakeRerunAction.java index 49f1d6c0d8f4..7de34fe3f655 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/FakeRerunAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/FakeRerunAction.java @@ -24,6 +24,7 @@ import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; +import com.intellij.ide.macro.MacroManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.LangDataKeys; @@ -56,6 +57,7 @@ public class FakeRerunAction extends AnAction { public void actionPerformed(@NotNull AnActionEvent event) { ExecutionEnvironment environment = getEnvironment(event); if (environment != null) { + MacroManager.getInstance().cacheMacrosPreview(event.getDataContext()); ExecutionUtil.restart(environment); } } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java b/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java index 21b055186bfd..3bed6e731870 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java @@ -19,6 +19,9 @@ import com.intellij.execution.CommonProgramRunConfigurationParameters; import com.intellij.execution.ExecutionBundle; import com.intellij.execution.configuration.EnvironmentVariablesComponent; import com.intellij.icons.AllIcons; +import com.intellij.ide.macro.EditorMacro; +import com.intellij.ide.macro.MacrosDialog; +import com.intellij.ide.macro.PromptingMacro; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.module.Module; @@ -28,9 +31,12 @@ import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.PanelWithAnchor; import com.intellij.ui.RawCommandLineEditor; import com.intellij.ui.TextAccessor; +import com.intellij.ui.components.fields.ExpandableTextField; +import com.intellij.ui.components.fields.ExtendableTextComponent; import com.intellij.util.PathUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -87,6 +93,26 @@ public class CommonProgramParametersPanel extends JPanel implements PanelWithAnc protected void initComponents() { myProgramParametersComponent = LabeledComponent.create(new RawCommandLineEditor(), ExecutionBundle.message("run.configuration.program.parameters")); + ExpandableTextField expandableTextField = (ExpandableTextField)myProgramParametersComponent.getComponent().getTextField(); + if (Registry.is("allow.macros.for.run.configurations")) { + expandableTextField.addExtension(new ExtendableTextComponent.Extension() { + @Override + public Icon getIcon(boolean hovered) { + return AllIcons.General.Add; + } + + @Override + public String getTooltip() { + return "Insert Macros"; + } + + @Override + public Runnable getActionOnClick() { + return () -> MacrosDialog.show(expandableTextField, + macro -> !(macro instanceof PromptingMacro) && !(macro instanceof EditorMacro)); + } + }); + } FileChooserDescriptor fileChooserDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); //noinspection DialogTitleCapitalization diff --git a/platform/lang-impl/src/com/intellij/execution/util/ProgramParametersConfigurator.java b/platform/lang-impl/src/com/intellij/execution/util/ProgramParametersConfigurator.java index 2c1da0024dad..84be60c39126 100644 --- a/platform/lang-impl/src/com/intellij/execution/util/ProgramParametersConfigurator.java +++ b/platform/lang-impl/src/com/intellij/execution/util/ProgramParametersConfigurator.java @@ -5,6 +5,10 @@ import com.intellij.execution.CommonProgramRunConfigurationParameters; import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.configurations.RuntimeConfigurationWarning; import com.intellij.execution.configurations.SimpleProgramParameters; +import com.intellij.ide.macro.EditorMacro; +import com.intellij.ide.macro.Macro; +import com.intellij.ide.macro.MacroManager; +import com.intellij.ide.macro.PromptingMacro; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.module.Module; @@ -13,6 +17,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ExternalProjectSystemRegistry; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.EnvironmentUtil; @@ -23,6 +28,7 @@ import org.jetbrains.annotations.SystemIndependent; import org.jetbrains.jps.model.serialization.PathMacroUtil; import java.io.File; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -37,7 +43,7 @@ public class ProgramParametersConfigurator { Project project = configuration.getProject(); Module module = getModule(configuration); - parameters.getProgramParametersList().addParametersString(expandPath(configuration.getProgramParameters(), module, project)); + parameters.getProgramParametersList().addParametersString(expandMacros(expandPath(configuration.getProgramParameters(), module, project))); parameters.setWorkingDirectory(getWorkingDir(configuration, project, module)); @@ -51,6 +57,23 @@ public class ProgramParametersConfigurator { parameters.setPassParentEnvs(configuration.isPassParentEnvs()); } + private static String expandMacros(String path) { + if (Registry.is("allow.macros.for.run.configurations")) { + Collection macros = MacroManager.getInstance().getMacros(); + for (Macro macro: macros) { + String value = StringUtil.notNullize( + macro instanceof PromptingMacro || macro instanceof EditorMacro + ? null : + macro.preview(), ""); + if (StringUtil.containsWhitespaces(value)) { + value = "\"" + value + "\""; + } + path = path.replace("$" + macro.getName() + "$", value); + } + } + return path; + } + @Nullable public String getWorkingDir(CommonProgramRunConfigurationParameters configuration, Project project, Module module) { String workingDirectory = configuration.getWorkingDirectory(); diff --git a/platform/lang-impl/src/com/intellij/ide/macro/MacrosDialog.java b/platform/lang-impl/src/com/intellij/ide/macro/MacrosDialog.java index 9e02cac3b70c..a2ebec48a2f0 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/MacrosDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/MacrosDialog.java @@ -22,59 +22,89 @@ import com.intellij.openapi.actionSystem.impl.SimpleDataContext; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.SeparatorFactory; import com.intellij.ui.components.JBList; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.List; public final class MacrosDialog extends DialogWrapper { - private final DefaultListModel myMacrosModel; - private final JList myMacrosList; - private final JTextArea myPreviewTextarea; + private final DefaultListModel myMacrosModel = new DefaultListModel<>(); + private final JBList myMacrosList = new JBList<>(myMacrosModel); + private final JTextArea myPreviewTextarea = new JTextArea(); public MacrosDialog(Project project) { super(project, true); MacroManager.getInstance().cacheMacrosPreview(SimpleDataContext.getProjectContext(project)); - setTitle(IdeBundle.message("title.macros")); - setOKButtonText(IdeBundle.message("button.insert")); - - myMacrosModel = new DefaultListModel(); - myMacrosList = new JBList(myMacrosModel); - myPreviewTextarea = new JTextArea(); - init(); } public MacrosDialog(Component parent) { super(parent, true); MacroManager.getInstance().cacheMacrosPreview(DataManager.getInstance().getDataContext(parent)); - setTitle(IdeBundle.message("title.macros")); - setOKButtonText(IdeBundle.message("button.insert")); - - myMacrosModel = new DefaultListModel(); - myMacrosList = new JBList(myMacrosModel); - myPreviewTextarea = new JTextArea(); - init(); } + public static void show(@NotNull JTextComponent textComponent, @Nullable Condition filter) { + MacrosDialog dialog = new MacrosDialog(textComponent); + if (filter != null) { + for (int i = 0; i < dialog.myMacrosModel.size(); i++) { + if (!filter.value(dialog.myMacrosModel.get(i).myMacro)) { + dialog.myMacrosModel.remove(i); + i--; + } + } + if (dialog.myMacrosModel.size() > 0){ + dialog.myMacrosList.setSelectedIndex(0); + } + else{ + dialog.setOKActionEnabled(false); + } + + } + if (dialog.showAndGet() && dialog.getSelectedMacro() != null) { + String macro = dialog.getSelectedMacro().getName(); + int position = textComponent.getCaretPosition(); + int selectionStart = textComponent.getSelectionStart(); + int selectionEnd = textComponent.getSelectionEnd(); + try { + if (selectionStart < selectionEnd) { + textComponent.getDocument().remove(selectionStart, selectionEnd - selectionStart); + position = selectionStart; + } + textComponent.getDocument().insertString(position, "$" + macro + "$", null); + textComponent.setCaretPosition(position + macro.length() + 2); + } catch (BadLocationException ignored) { + } + } + IdeFocusManager.findInstance().requestFocus(textComponent, true); + } + @Override protected void init() { super.init(); - java.util.List macros = new ArrayList<>(MacroManager.getInstance().getMacros()); + setTitle(IdeBundle.message("title.macros")); + setOKButtonText(IdeBundle.message("button.insert")); + + List macros = new ArrayList<>(MacroManager.getInstance().getMacros()); Collections.sort(macros, new Comparator() { @Override public int compare(Macro macro1, Macro macro2) { diff --git a/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java b/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java index 261d646bfbea..e1de8d0893e7 100644 --- a/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java +++ b/platform/platform-api/src/com/intellij/ui/RawCommandLineEditor.java @@ -15,13 +15,7 @@ */ package com.intellij.ui; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooserDescriptor; -import com.intellij.openapi.ui.LabeledComponent; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.TextFieldWithBrowseButton; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.components.fields.ExpandableTextField; import com.intellij.util.Function; @@ -31,15 +25,10 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.text.Document; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.List; public class RawCommandLineEditor extends JPanel implements TextAccessor { - private static final Logger LOG = Logger.getInstance("#com.intellij.ui.RawCommandLineEditor"); - - private final JTextField myEditor; - private final TextFieldWithBrowseButton myTextField; + private final ExpandableTextField myEditor; private String myDialogCaption = ""; public RawCommandLineEditor() { @@ -48,30 +37,8 @@ public class RawCommandLineEditor extends JPanel implements TextAccessor { public RawCommandLineEditor(final Function> lineParser, final Function, String> lineJoiner) { super(new BorderLayout()); - if (Registry.is("raw.command.line.editor.dialog")) { - myTextField = new TextFieldWithBrowseButton(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (myDialogCaption == null) { - Container parent = getParent(); - if (parent instanceof LabeledComponent) { - parent = parent.getParent(); - } - LOG.error("Did not call RawCommandLineEditor.setDialogCaption() in " + parent); - myDialogCaption = "Parameters"; - } - Messages.showTextAreaDialog(myTextField.getTextField(), myDialogCaption, "EditParametersPopupWindow", lineParser, lineJoiner); - } - }); - myEditor = myTextField.getTextField(); - myTextField.setButtonIcon(AllIcons.Actions.ShowViewer); - add(myTextField, BorderLayout.CENTER); - } - else { - myTextField = null; - myEditor = new ExpandableTextField(lineParser, lineJoiner); - add(myEditor, BorderLayout.CENTER); - } + myEditor = new ExpandableTextField(lineParser, lineJoiner); + add(myEditor, BorderLayout.CENTER); setDescriptor(null); } @@ -83,10 +50,12 @@ public class RawCommandLineEditor extends JPanel implements TextAccessor { InsertPathAction.addTo(myEditor, descriptor, insertSystemDependentPaths); } + @Deprecated public String getDialogCaption() { return myDialogCaption; } + @Deprecated public void setDialogCaption(String dialogCaption) { myDialogCaption = dialogCaption != null ? dialogCaption : ""; } @@ -116,6 +85,6 @@ public class RawCommandLineEditor extends JPanel implements TextAccessor { @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); - (myTextField != null ? myTextField : myEditor).setEnabled(enabled); + myEditor.setEnabled(enabled); } } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index c489685dd934..e5e3b4f65e0a 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -913,9 +913,6 @@ emmet.segments.limit=50 emmet.template.length.limit.kilobytes=15 command.line.execution.timeout=30 -raw.command.line.editor.dialog=false -raw.command.line.editor.dialog.description=Use dialog to edit command line - ide.settings.keymap.input.method.enabled=false ide.settings.keymap.input.method.enabled.description=Use input method instead of simple key event to enter shortcuts. @@ -1354,6 +1351,8 @@ run.configuration.max.name.length.description=When name of run configuration exc suggest.all.run.configurations.from.context=false suggest.all.run.configurations.from.context.description=With the option enabled, all run configuration from context will be suggested to\ run or create in spite of existing run configuration in the context +allow.macros.for.run.configurations=true +allow.macros.for.run.configurations.description=Enables context-dependent macros like $FileName$ or $SelectedText$ in Run Configurations pause.indexing.in.power.save.mode=false