VSCode extension that automatically makes script files executable on save. https://marketplace.visualstudio.com/items?itemName=jimeh.executable-on-save
Find a file
Jim Myhrberg 9b19f84278
chore(deps): update dev dependencies (#47)
Reduce drift and pick up latest fixes/improvements in the dev toolchain:

- @types/node: pin to 20.19.33 (was 20.x range)
- @types/sinon: ^17.0.4 → ^21.0.0
- @vscode/test-cli: ^0.0.11 → ^0.0.12
- esbuild: ^0.25.9 → ^0.27.3

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 04:32:08 +00:00
.cursor build: migrate from npm to pnpm (#38) 2026-02-13 18:34:13 +00:00
.github fix: prefix glob patterns with ./ in workflow shells to prevent option parsing (#45) 2026-02-14 03:47:27 +00:00
.vscode build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00
img fix(icon): improve extension icon (#37) 2025-10-25 13:13:28 +01:00
scripts build: improve VSIX packaging with explicit file list and artifact-based publishing (#39) 2026-02-13 19:02:46 +00:00
src build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00
.gitignore ci(build): resolve issues with auto-mated building and publishing (#13) 2025-10-13 03:46:34 +01:00
.oxfmtrc.json build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00
.oxlintrc.json build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00
.vscode-test.mjs build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00
AGENTS.md docs: slim AGENTS.md and replace CLAUDE.md symlink with @-reference (#41) 2026-02-13 19:30:35 +00:00
CHANGELOG.md chore(main): release 0.2.5 (#35) 2025-10-25 18:47:04 +01:00
CLAUDE.md docs: slim AGENTS.md and replace CLAUDE.md symlink with @-reference (#41) 2026-02-13 19:30:35 +00:00
esbuild.js build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00
LICENSE chore(license): add MIT license 2025-10-12 20:25:21 +01:00
mise.lock build: migrate from npm to pnpm (#38) 2026-02-13 18:34:13 +00:00
mise.toml build: migrate from npm to pnpm (#38) 2026-02-13 18:34:13 +00:00
package.json chore(deps): update dev dependencies (#47) 2026-02-14 04:32:08 +00:00
pnpm-lock.yaml chore(deps): update dev dependencies (#47) 2026-02-14 04:32:08 +00:00
README.md fix(command): allow manual "Make Executable If Script" when on-save is disabled (#32) 2025-10-17 09:14:59 +01:00
tsconfig.json build: migrate from ESLint + Prettier to OXC toolchain (#44) 2026-02-13 21:01:37 +00:00

Logo

Executable on Save

VSCode extension that automatically makes script files executable on save.

VSCode OpenVSX Latest Release GitHub Issues GitHub Pull Requests License

What It Does

When you save a file that starts with #! (a shebang), this extension automatically makes it executable (similar to chmod +x). No more manually making your shell scripts, Python scripts, or other executable files runnable.

It is similar in behavior to Emacs' executable-make-buffer-file-executable-if-script-p when set up as an after-save hook.

Installation

Install from the VSCode Marketplace, OpenVSX, or via the command line:

code --install-extension jimeh.executable-on-save

How It Works

The extension watches for file saves. When a file is saved:

  1. Checks if the first two characters are #!
  2. Checks if the file is already executable
  3. If not executable and has a shebang, applies the appropriate permissions

Behavior Notes

  • Only processes files with file:// URIs (ignores untitled documents)
  • Ignores non-file URI schemes (e.g., git:)
  • Skips files that are already executable
  • Requires the shebang at the very beginning of the file (no leading whitespace)
  • Only reads the first two characters out of documents for shebang detection
  • Shows a small notice when file permissions are modified, which can be silenced
  • Runs after every save with very minimal performance impact

Configuration

Enable/Disable

Control whether the extension runs when saving a file:

{
  "executableOnSave.enabled": true
}

Default: true

Permission Strategy

Choose how the execute permissions are added:

{
  "executableOnSave.permissionStrategy": "umask"
}

Options:

  • "umask" (default): Respects system umask when adding execute
  • "read-based": Adds execute only where read permission exists
  • "all": Adds execute for user, group, and other unconditionally

Respects your system's umask setting, following Unix conventions. Only adds execute permissions that would be allowed on newly created files.

With umask 0o022 (typical):

Before After Description
rw-r--r-- rwxr-xr-x All get execute
rw------- rwx--x--x All get execute
rw-rw-r-- rwxrwxr-x All get execute

With umask 0o077 (restrictive):

Before After Description
rw-r--r-- rwxr--r-- Only user gets execute
rw------- rwx------ Only user gets execute
rw-rw-r-- rwxrw-r-- Only user gets execute

Technical: Calculates default file permissions (0o777 & ~umask), extracts execute bits, and applies them via bitwise OR.

Read-based Strategy

Maintains permission symmetry by only adding execute where read exists:

Before After Description
rw-r--r-- rwxr-xr-x Standard file permissions
rw------- rwx------ Private file stays private
rw-r----- rwxr-x--- Group-readable becomes group-executable

Technical: shifts read bits right by 2 positions to derive execute bits.

All Strategy

Always adds execute for all three permission groups:

Before After Description
rw-r--r-- rwxr-xr-x Standard file permissions
rw------- rwx--x--x Adds execute for user, group, and other
rw-r----- rwxr-x--x Adds execute for user, group, and other

Technical: performs bitwise OR with 0o111.

Silent Mode

Disable information popups when permissions change:

{
  "executableOnSave.silent": false
}

Set to true to suppress notifications altogether.

Manual Execution

Run "Make Executable If Script" from the command palette to manually run checks and mark the current file as executable if needed.

Platform Support

  • macOS: Full support
  • Linux: Full support
  • BSD: Full support
  • Windows: Disabled (Windows uses different permission model)

License

MIT