Skip to content

Repository files navigation

Catalyst – Run on Save

Execute commands automatically on file save in Visual Studio Code.

Catalyst enables you to automate development workflows by executing shell commands instantly whenever specific files are saved. Whether you need to apply formatters, linters, code generators, tests, or build tasks, this extension handles it seamlessly in the background.

Examples

1. Code Formatting with Prettier

Automatically format TypeScript, JavaScript, and JSON files on save:

{
  "catalyst-run-on-save.actions": [
    {
      "name": "Prettier Format",
      "command": "npx prettier --write \"${file}\"",
      "include": ["**/*.ts", "**/*.js", "**/*.json"],
      "exclude": ["**/node_modules/**"]
    }
  ]
}

2. Code Linting with ESLint

Automatically fix linting issues in TypeScript and JavaScript files on save:

{
  "catalyst-run-on-save.actions": [
    {
      "name": "ESLint Fix",
      "command": "npx eslint --fix \"${file}\"",
      "include": ["**/*.ts", "**/*.js"],
      "exclude": ["**/node_modules/**"]
    }
  ]
}

3. Java & Kotlin Formatting with Spotless (Gradle)

Run different Gradle scripts based on the active operating system to format Java and Kotlin files:

{
  "catalyst-run-on-save.actions": [
    {
      "name": "Spotless Format (Gradle)",
      "command": {
        "windows": "${workspaceFolder}\\gradlew.bat spotlessApply -PspotlessFiles=\"${file}\"",
        "default": "${workspaceFolder}/gradlew spotlessApply -PspotlessFiles=\"${file}\""
      },
      "include": ["**/*.java", "**/*.kt"],
      "exclude": ["**/build/**"]
    }
  ]
}

4. Go Build & Test on Save

Automatically compile and run tests in a Go project when code changes:

{
  "catalyst-run-on-save.actions": [
    {
      "name": "Build & Test Go Project",
      "command": "go build ./... && go test ./...",
      "include": ["**/*.go"],
      "exclude": ["**/vendor/**"]
    }
  ]
}

Configuration

Configure the extension inside your VS Code settings.json file.

Settings

Setting Type Default Description
catalyst-run-on-save.actions array [] List of actions to execute on file save.
catalyst-run-on-save.showErrorPopups boolean true Show notification popups if an action command exits with an error.
catalyst-run-on-save.showOutput string "onError" Auto-reveal output channel behavior ("never", "onError", "always").

Action Properties

Each action object in catalyst-run-on-save.actions supports the following properties:

Property Type Required Description
name string No A descriptive label for the action (used in logs and error notifications).
command string or object Yes The shell command to run. To use platform-specific commands, pass an object with keys: windows, macos, linux, or default.
include string[] No Glob patterns indicating which files trigger the action. Matches all files if omitted.
exclude string[] No Glob patterns to prevent matching files from triggering the action.
shell string No Absolute path to a custom shell executable (e.g., /bin/zsh, powershell.exe).
timeout number No Execution timeout limit in milliseconds. The process is terminated if it exceeds this threshold. Omitted or 0 disables timeout.
cwd string No Custom working directory for executing the command. Supports variable placeholders (defaults to ${workspaceFolder}).
env object No Key-value map of environment variables passed to the spawned process (e.g. { "NODE_ENV": "development" }).

Note: Globs are evaluated relative to your workspace root directory. They support both standard file extension patterns (e.g., **/*.ts) and directory-specific exclusions.

Variable Substitution

You can embed the following placeholders in your command strings:

Variable Description Example Output
${workspaceFolder} Absolute path of the active workspace folder /Users/alice/Code/my-app
${workspaceFolderBasename} The folder name of the workspace root my-app
${file} Absolute path of the saved file /Users/alice/Code/my-app/src/config.json
${relativeFile} Workspace-relative path of the saved file src/config.json
${relativeFileDirname} Workspace-relative directory of saved file src
${fileBasename} Filename including extension config.json
${fileBasenameNoExtension} Filename excluding extension config
${fileExtname} Only the file extension .json
${fileDirname} Absolute path of the saved file's directory /Users/alice/Code/my-app/src
${pathSeparator} System path separator (/ or \) /
${env:VAR_NAME} Value of environment variable VAR_NAME alice

Commands & Status Bar

Catalyst contributes interactive commands via the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and a status bar indicator:

Command Title Description
catalyst.toggle Catalyst: Toggle Execution on Save Globally enable or disable automatic execution on file save. Also toggled by clicking the status bar item.
catalyst.run Catalyst: Run Actions for Active File Manually trigger matching run-on-save actions for the active text editor document.
catalyst.showOutput Catalyst: Show Output Channel Open the Catalyst log output channel.

Troubleshooting

Silent Failures

Problem: Commands are not running or are failing silently, making it difficult to debug the issue.

Solution: Check the extension logs in VS Code:

  1. Open the Output panel in VS Code (View > Output or Cmd+Shift+U/Ctrl+Shift+U).
  2. Select Catalyst from the dropdown menu in the top-right corner.
  3. Review the execution logs to inspect target file matches, resolved command strings, and shell exit codes.

Spaces in File Paths

Problem: If your file paths contain spaces or special characters, commands might fail or parse incorrectly.

Solution: Always wrap ${file} and other path variables in double quotes within your command template, for example: npx prettier --write "${file}".

Command Not Found or Missing PATH Variables

Problem: VS Code commands run in a non-interactive shell environment that might not load all of your user profile configurations (like custom alias settings or dynamic PATH expansions from .bashrc or .zshrc), causing commands to fail because they cannot be found.

Solution:

  • Use absolute paths for commands (e.g., /usr/local/bin/node instead of just node) if they cannot be found.
  • Specify a custom shell executable using the shell option (e.g., /bin/zsh or powershell.exe) if you need a specific shell context.

Re-trigger Task Cancellation

Behavior: If a file is saved again while an action for that file is still executing, Catalyst sends a SIGTERM signal to cancel the previous child process before launching the new run, preventing overlapping process contention.

Performance & High CPU Usage

Problem: Running heavy build or compile commands on every save can slow down your workspace and consume high CPU resources.

Solution: Use the exclude property to ignore files in temporary directories (e.g., **/tmp/**), build folders (e.g., **/dist/**, **/build/**), or dependency folders (e.g., **/node_modules/**).


deep.rent Logo
deep.rent

About

Visual Studio Code extension to run commands on file save

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages