Run parameterized shell commands from Atom.
Highlights:
- Parameterize commands with values from the workspace, e.g, file path, project path, selected text, etc.
- Add entries to the command palette with optionally shortcut keys for each command.
- Define parameterized environment variables.
- Run multiple instances of commands in parallel.
- Provides a convenient graphical editor. No need to edit configuration files directly unless you want to.
- Integrates with the project tree. Select a file in the project tree and choose which command to run it with.
- Detects paths and line numbers in the output that links back to the editor.
- Add hooks for custom JavaScript to run before and after a process.
See the changelog for the latest improvements.
Install Process Palette and then either generate or download a configuration file.
- Open the Process Palette panel by choosing
Packages|Process Palette|Toggle
from the menu orProcess Palette: Toggle
from the command palette. The following panel will appear: - Create a global configuration or a project specific configuration with the respective
Do it!
buttons. If a project specific configuration is created and more than one project is open then one can be chosen from the dialog box that will appear. - Either of the
Do it!
buttons will create an example configuration file and open it in the graphical editor. - Configuration files can be edited graphically by choosing
Packages|Process Palette|Edit Configuration
from the menu orProcess Palette: Edit Configuration
from the command palette. Closing the editor will automatically reload the configuration. Theprocess-palette.json
file can also be edited directly, but then it needs to be reloaded by runningProcess Palette: Reload Configuration
.
- Download the example process-palette.json configuration file and place it in the root of your project folder.
- Load the new configuration file by choosing
Packages|Process Palette|Reload Configuration
from the menu orProcess Palette: Reload Configuration
from the command palette.
These example configurations define a command that will echo a message to standard output. It can be run by choosing Process Palette: Echo Example
from the command palette. This will open the Process Palette panel and show the output. The panel can also be opened directly by pressing Ctrl-Alt-P
or running Process Palette: Toggle
from the command palette.
It also contains an example called Stream Example
to show the direct stream ability. When streaming is enabled the output is written directly to the target without being formatted.
- Play with the graphical editor or poke around in the configuration file a bit. Just remember to run the
Process Palette: Reload Configuration
command when making changes directly to theprocess-palette.json
file. - Read the rest of this document. Especially the Properties and Variables sections for extra flexibility.
The graphical editor makes it easier to edit the configuration files. It can be opened by choosing Process Palette: Edit Configuration
from the command palette. A dialog will pop up from where you can choose to edit either the global configuration or a project specific configuration. The following is a screenshot of the graphical editor.
The commands are listed on the left. Selecting one will show its details on the right. Pressing the Edit Patterns
button allows you to define custom patterns for recognizing file paths and line numbers when writing output to the panel, although the default built-in pattern ought to be sufficient in most cases.
The configuration file will be saved and automatically reloaded when closed.
The palette panel shows the configured command and output targets for each command. The visibility of these can be toggled in the settings.
Commands will be executed by the system's default shell, which is sh
on OSX and Linux and cmd.exe
on Windows.
If you would like to use a particular shell then you can specify it under Process Palette's settings. This shell will then be used when running any of the commands. Leave the value blank for the system default to be used.
Process Palette has a small panel that lists all the commands that are configured. It can be toggled by pressing Ctrl-Alt-P
or from the menu Packages|Process Palette|Toggle
.
From here one can see all the commands and also run them.
Pressing the down arrow in the top right corner will hide the panel.
Multiple instances of a process can run at a time. The process ID of each instance is shown on the right in the form of a button. Pressing the button will show that process' output. The process can be manually terminated by pressing the square stop button next to the process ID.
If the command is configured to output to the Process Palette panel then clicking on the process ID button will cause the panel to switch to showing the output of that process.
The other process instances will still be shown, but the selected one will be highlighted.
Scroll lock can be toggled with the lock button. Scroll lock will also enable when one starts to scroll or clicks on the output. It will automatically disable when one scrolls to the bottom.
The output can be cleared by pressing the trash can button.
From here one can return to the list by pressing the button in the top left corner.
Each time a process is executed a message will be shown in the top right hand corner. A successful execution with an exit status code of 0 will show a success message. Anything other than 0 will show a warning. What these messages display can be configured or even disabled completely as will be seen in the Advanced Configuration section.
Commands can be run from the tree view with the selected file as input to the command. Any command that references any of the {file*}
variables will be available.
To choose the command to run a file with, open the context menu on a file in the tree view and choose the command from the Run With
sub menu.
See the example at the top.
Command | Description |
---|---|
Hide | Hides the output panel. |
Show | Shows the output panel. |
Toggle | Toggles the output panel's visibility. |
Edit Configuration | Opens graphical configuration editor. |
Reload Configuration | Reloads all configuration files. This is only necessary if a process-palette.json file was directly modified with a text editor. |
Rerun Last | Runs the last command that was executed again. |
Kill Focused Process | Kills the process that is currently shown. |
Kill And Remove Focused Process | Kill the process that is currently shown and removes its output. |
Remove Focused Output | Removes the output that is currently shown, unless the process is still running. |
The configuration files can also be edited by hand. The remainder of the document will describe how to do this.
Commands are specified with a configuration file in JSON format. The name of the file must be process-palette.json
and should be in the root of your project folder. If you have multiple project folders, each with its own configuration file, then their configurations will be merged.
A process-palette.json
file can also be placed in your ~/.atom
folder. If that is the case then it will be loaded first and any project specific files will be loaded afterwards.
A process-palette.json
configuration file contains an array called commands
. The following is an example of an empty array:
{
"commands" : [
]
}
Each entry in the array is an object that describes one command. The most basic configuration simply specifies the command to run and associates it with an action. The following command will run Ant without any arguments:
{
"commands" : [
{
"command" : "ant",
"action" : "Ant default"
}
]
}
Tip! :
All process-palette.json
configuration files can be reloaded by running the Process Palette: Reload Configuration
command. It can be found in the Command Palette
or in the Packages|Process Palette
menu. There is also a reload button in the top right of the Process Palette panel.
The new command will cause an entry to be added to the command palette called Process Palette: Ant default
.
The working directory used when running a command is by default the project path, but it can also be configured. More on this in the Advanced Configuration section.
Command line arguments can also be specified in the form of an array of strings. The following example adds another command that causes the clean
target to be executed by means of an argument:
{
"commands" : [
{
"action" : "ant-default",
"command" : "ant"
},
{
"action" : "ant-clean-artifacts",
"command" : "ant clean"
}
]
}
Reloading the configuration will cause the command palette to now have two new entries:
- Process Palette: Ant default
- Process Palette: Ant clean artifacts
The namespace used for all commands is by default Process Palette
. This is also configurable. One must just be careful to not override commands in existing packages.
Let's modify the previous two commands to use a namespace call Ant
:
{
"commands" : [
{
"namespace" : "ant",
"action" : "default",
"command" : "ant"
},
{
"namespace" : "ant",
"action" : "clean-artifacts",
"command" : "ant clean",
}
]
}
After reloading the configuration file the entries will be:
- Ant: Default
- Ant: Clean artifacts
Custom shortcut keys can also be associated with commands by adding a keystroke
entry. Let's add the keystroke Ctrl-Alt-A
to the Ant: Default
command:
{
"namespace" : "ant",
"action" : "default",
"command" : "ant",
"keystroke" : "ctrl-alt-a"
}
After reloading the configuration the Ant: Default
command can be run by pressing Ctrl-Alt-A
.
The namespace
, action
, command
and keystroke
aren't the only properties that can be configured. Of these only the action
and command
are required. The rest are optional and have default values.
Many of the properties can be parameterized with variables from the environment. The following two sections describe the configurable properties and also the variables that can be used to parameterize them.
Property | Description | Default |
---|---|---|
namespace | The namespace under which the command is categorized. This forms part of its identity in the Command Palette. It should be lowercase and words separated by hyphens. | "process-palette" |
action (required) | The name of the action. This, together with the namespace, gives the command a unique identifier in the Command Palette. It should be lowercase and words separated by hyphens. | null |
command (required) | A string with the name and arguments of the command to execute. | null |
arguments | An array of strings to pass as arguments to the command. Since v0.4.10 arguments can be added directly to the command property's value, however this approach can still be used. |
[ ] |
cwd | The working directory from which to execute the command. It doesn't have a default value, but one is automatically determined when the command is executed. If projects are open then the first project's folder is used. If there aren't any projects open then the folder of the process-palette.json file is used. |
null |
keystroke | A string describing the shortcut to associate with this command. It can be any combination of ctrl , alt , shift and cmd followed by another key separated with - characters. |
null |
promptToSave | Indicates whether the user should be prompted before any files are saved. | true |
saveOption | Specify what should be saved. Either nothing, everything or only the files referenced by the command. Indicate with none , all and referenced respectively. |
"none" |
env | A map of environment variables. These will be made available in addition to the ones that are already defined in process.env |
{ } |
patterns | Array of pattern names to match. | ["default"] |
inputDialogs | Input dialogs to open in order to get input from the user which can then be used with variables. | [] |
The following properties relate to the output produced by the process. The output can be redirected to a particular target. It can also be formatted depending on whether the process executed successfully or not. Giving any of the xxxOutput
properties a value of null
will prevent that output from being shown.
Property | Description | Default |
---|---|---|
outputTarget | Where the output produced by the process should be directed to. It can have one of the following values: "panel", "editor", "clipboard", "console" or "void". If the value is overridden with null then it will default to "void". More on this below. |
"panel" |
successOutput | The format of the output when the process returned with an exit status of 0. | "{stdout}" |
errorOutput | The format of the output when the process returned with a non-0 exit status. | "{stdout}\n{stderr}" |
fatalOutput | The format of the output when the command could not be executed at all. | "Failed to execute : {fullCommand}\n{stdout}\n{stderr}" |
stream | Indicate whether the output should be streamed. If this is false then the output will be formatted and sent to the target only after the process completes. If it is true then the output, both standard and error, will be streamed to the target without any formatting applied. | false |
autoShowOutput | If the panel should automatically be made visible when the process produces output. At the moment this only applies when outputTarget is set to panel . |
true |
autoHideOutput | If the panel should automatically be hidden when the process terminates. It will only be hidden if the process completes successfully and also only if the output is being viewed at the time of completion. This only applies when outputTarget is set to panel . |
false |
scrollLockEnabled | If scroll lock should automatically be enabled. This only applies when outputTarget is set to panel . |
false |
maxCompleted | The maximum number of completed processes whose output to keep at a time. It is used to automatically discard the oldest completed process in order to prevent them from piling up. This property only applies when the outputTarget is set to panel . It can be disabled by setting the value to null in which case all panels will have to be discarded manually. |
3 |
outputBufferSize | The maximum number of characters to accumulate from standard output and error. When the buffer size is reached the oldest output is discarded. This is not applied to the output target, but only to the output accumulated in the stdout and stderr variables. This limit can be disabled by setting it to null , but should be done with caution for long running processes. |
80000 |
singular | Set to true to terminate the running process before running a new instance. |
false |
The following properties relate to the messages shown before and after a command is executed. Giving any of the xxxMessage
properties a value of null
will prevent that message from being shown.
Property | Description | Default |
---|---|---|
startMessage | The format of the message before the process starts. | null |
successMessage | The format of the message when the process returned with an exit status of 0. | "Executed : {fullCommand}" |
errorMessage | The format of the message when the process returned with a non-0 exit status. | "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}" |
notifyOnStart | true if the start message should be shown. | false |
notifyOnSuccess | true if the success message should be shown. | true |
notifyOnError | true if the error message should be shown. | true |
The following properties relate to custom JavaScript that can be executed before and after the process.
Property | Description | Default |
---|---|---|
startScript | Base-64 encoded JavaScript to run before the process starts. | null |
successScript | Base-64 encoded JavaScript to run when the process returned with exit status of 0. | null |
errorScript | Base-64 encoded JavaScript to run when the process returned with a non-0 exit status. | null |
scriptOnStart | true if the start script should be run. | false |
scriptOnSuccess | true if the success script should be run. | false |
scriptOnError | true if the error script should be run. | false |
The outputTarget
property specifies where the output produced by the process should be directed to. The following are valid targets:
Target | Description |
---|---|
void | The output will not be captured at all. |
panel | The output will be shown in Process Palette's panel. Running a command that outputs to the panel will automatically open it if autoShowOutput is true . |
clipboard | The output will be stored on the clipboard. Streaming to the clipboard is not supported. If stream is true when the output target is clipboard then streaming will be disabled. |
editor | The output will be inserted into the open editor at the current cursor position. If an editor is not open the output is lost. |
console | The output will be appended to the developer console. |
file | The output will be written to a new file that will be opened in the Atom workspace. |
The default value of outputTarget
is "panel". If it is overridden with null
then it will default to "void".
Some of the properties can be parameterized with variables. Variables are added by enclosing the name of the variable in braces : {
and }
. The default values of some of the properties are already parameterized as can be seen in the tables above.
There are two types of variables : input and output. Input variables are available before the process executes and output variables are available after it has executed.
The following tables list the input and output variables:
Input
Variable | Description |
---|---|
clipboard | Text currently on clipboard. |
fullCommand | The full command along with its arguments. Both the command and arguments will have their variables resolved. |
configDirAbsPath | Absolute path of folder where the process-palette.json configuration file is that defines this command. |
projectPath | If projects are open then the first project's folder will be used. If there aren't any projects open then the path of the folder containing the process-palette.json file is used. |
selectProjectPath | Prompts to choose the path of one of the projects in the workspace. |
Input from editor
The following input variables are only available if an editor is open. Their values default to an empty string otherwise.
Variable | Description |
---|---|
fileExt | Extension of file. |
fileName | Name of file without extension. |
fileNameExt | Name of file with extension. |
filePath | Path of file relative to project. |
fileDirPath | Path of file's directory relative to project. |
fileAbsPath | Absolute path of file. |
fileDirAbsPath | Absolute path of file's directory. |
fileProjectPath | Absolute path of file's project folder. |
selection | Currently selected text. |
word | Word under cursor. |
line | Line at cursor. |
lineNo | Line number at cursor. |
token | Token under the cursor according to the file's grammar. |
Input from user
The inputDialogs
property is an array of objects, each defining an input dialog that will be opened in order to take input from the user. Every dialog must specify the variableName
that can then be used just like any other variable. Dialogs can be customized with a different message
and initialInput
.
Property | Description |
---|---|
name (required) | Name of the variable that can then be used in other properties. |
message | Message to display with the input dialog. |
initialInput | Initial text in the input dialog. |
Here is an example of one such dialog:
"inputDialogs" : [
{
"variableName": "userInput",
"message": "Foo?",
"initialInput": "Bar!"
}
]
Output
These variables are only available after the process has executed. They can therefore typically be used in the output and message related properties.
Variable | Description |
---|---|
stdout | Standard output produced by the process. |
stderr | Standard error output produced by the process. |
exitStatus | Exit status code returned by the process. |
The table below shows which properties support input variables and/or output variables:
Property | Input | Output |
---|---|---|
cwd | yes | no |
env | yes | no |
command | yes | no |
arguments | yes | no |
successOutput | yes | yes |
errorOutput | yes | yes |
fatalOutput | yes | yes |
startMessage | yes | no |
successMessage | yes | yes |
errorMessage | yes | yes |
startScript | yes | no |
successScript | yes | yes |
errorMessage | yes | yes |
The namespace
, action
and keystroke
properties do not support variables. The env
property supports variables only in its values, for example :
"env" : {
"MYVAR" : "{fileName}"
}
A useful way of seeing the values of the variables is to add them to one of the output properties and then executing the command. For instance :
"successOutput" : "File path : {filePath}\nProject path : {projectPath}"
will show the values of filePath
and projectPath
respectively.
Another way is to simply echo
them as shown in the example.
Keep in mind that the arguments
property is an array of strings. Adding variables to arguments should therefore be done as such:
"arguments" : ["{fileNameExt}", "{selection}"]
The value of a variable can be modified by piping it through a transform. The syntax is {variable | transform}
The following transforms are available:
Transform | Description |
---|---|
unix | Converts a Windows path to a unix path. |
posix | The same as unix . |
win | Converts a posix path to a Windows path. |
trim | Trims whitespace. |
It may sometimes be necessary to convert a file path to use separators for a different platform. Any of the variables can be converted by piping it through a transform.
If, for instance, you are running on Linux and need to convert the filePath
variable to a Windows style path, then you can specify it as {filePath | win}
. The opposite can also be done with {filePath | unix}
or {filePath | posix}
when running on Windows.
Commands that write to the output panel can be configured to detect file paths and optionally line numbers.
Detected paths will be underlined. Clicking it will open the file and if a line number is detected jump to it.
All commands will detect file paths by default. If line numbers are required then additional configuration is necessary.
Patterns are used to detect paths and line numbers. Process Palette has one built in pattern for detecting paths and all commands use this pattern by default.
Custom patterns can be added to the configuration file. Commands can then be configured to detect any of these patterns. The following example shows two custom patterns. The one pattern (P1) detects a path followed by a :
and then the line number, whereas the other (P2) has whitespace between the path and line number.
"patterns" : {
"P1" : {
"expression" : "(path):(line)"
},
"P2" : {
"expression" : "(path)\\s+(line)"
}
},
"commands" : [
{
"patterns" : ["P1", "P2"]
}
]
Notice the following:
patterns
is an object and is defined on the same level ascommands
.- Each pattern has a name.
P1
andP2
in this case. - Each pattern has a JS regular expression called
expression
. (path)
and(line)
are special placeholders. These are substituted with regular expressions for matching each respectively.- Everything around
(path)
and(line)
should be valid regular expressions.
With this configuration the command will be able to match P1
and P2
patterns. This overrides the default configuration that matches only paths. The built-in pattern for matching paths is called default
. To match the default pattern as well, simply add it to the list:
"patterns" : ["P1", "P2", "default"]
Order matters!
Patterns are evaluated in the order they are given. This means that if default
was first in the list then it will be matched, but never any of the line numbers.
To disable pattern matching simply set the value of patterns
to null
.
In the previous example the (path)
and (line)
placeholders were used to quickly create an expression. In the background these are replaced with appropriate regular expressions. The (path)
placeholder, in particular, will be replaced with an expression that is appropriate for the platform.
It may be that the built in expression is not sufficient for detecting paths in your command's output. If that is the case then you can overwrite it with your own. The following example shows how.
"patterns" : {
"P1" : {
"expression" : "(path):(line)",
"path" : "(?:\\/[\\w\\.\\-]+)+"
}
}
In this case the given expression for path
will be used instead.
Important note about groups
Groups are enclosed in round brackets. path
and line
each forms a group and in this order they are at index 1 and 2 respectively. In this example the path
expression is being overwritten, but this expression defines a group of its own. What's important to notice is the ?:
at the start of the group, which ensures that the group is not counted. The only groups that are allowed to be counted are for path
and line
, but neglecting to exclude other groups will interfere with their indexes.
You can specify your own JavaScript to run at certain stages of a process. Code can be specified to run before the process starts and after it has completed. Separate scripts can be specified based on whether the process completed successfully or failed.
Any of the input and output variables are available from within the scripts. Variables can be accessed simply by using its name, without the need to enclose it in braces. You also have access to Atom's API. For example:
atom.workspace.open(fileProjectPath + '/my.file')
Environment variables can be accessed via a variable called env
. For example:
console.log(env['MY_ENV_VAR'])
These scripts are base-64 encoded. It is therefore advised to rather edit the scripts from the graphical editor instead of directly in the process-palette.json
file, because then the script will be encoded automatically.
Process Palette considers its process to be completed only when all commands have finished executing. For instance, if a command is executed with an &
appended then Process Palette will continue to handle the output produced by it until the child process spawned by that command exits.
This in itself is not a major problem. The issue is that Process Palette currently cannot kill child processes that are executed in this way. If the command executed with &
opens a window then closing the window will allow the parent process to complete, but if it doesn't then one will have to kill the process by whatever means your OS allows.