Streamline Your Workflow: Open Files and Folders in VS Code from Finder
Developers often work with files and project folders scattered across their macOS file system. While the terminal command code . is a staple for opening the current directory in Visual Studio Code, it requires an extra step: opening Terminal, navigating to the correct directory, and then executing the command. For those who spend significant time in Finder, this can feel like an unnecessary interruption to a fluid workflow. Fortunately, macOS offers a way to integrate this functionality directly into Finder’s contextual menu, creating an “Open in VS Code” Quick Action.
This integration allows you to right-click on any file or folder within Finder and instantly open it in VS Code. This eliminates the need to switch applications or type commands, saving valuable seconds that add up over a day of coding. The setup can be achieved through two primary methods: a manual approach using the built-in Automator app, or a more automated shell script that configures the same Quick Action for you. Both methods yield the same user-facing result, providing a more efficient way to manage your development environment.
Method 1: Manual Setup with Automator
The manual method involves using macOS’s powerful Automator application to create a custom workflow that can be triggered from Finder. This gives you a clear understanding of how the Quick Action is constructed.
Step-by-Step Guide:
- Open Automator: Launch Automator from your Applications folder or via Spotlight Search (Cmd + Space, then type “Automator”).
- Create a New Document: Select “File” > “New” (or Cmd + N). Choose “Quick Action” as the document type and click “Choose”.
- Configure Workflow Input: At the top of the workflow window, set “Workflow receives current” to “files or folders” and “in” to “Finder.app”. This ensures the Quick Action will appear when you right-click on files or folders in Finder.
- Add “Run Shell Script” Action: In the Actions library on the left, search for “Run Shell Script”. Drag and drop this action into the workflow area on the right.
- Configure Shell Script: In the “Run Shell Script” action, set “Shell” to
/bin/bashor/bin/zsh(depending on your default shell). Set “Pass input” to “as arguments”. - Enter the Script: Paste the following script into the text area of the “Run Shell Script” action. This script iterates through the selected files or folders and opens them with the
codecommand. If thecodecommand is not in your PATH, you might need to provide the full path to the VS Code executable.
for f in "$@"
do
open -a "Visual Studio Code" "$f"
done
Explanation of the script:
for f in "$@": This loop iterates over all the arguments passed to the script, which in this case are the files and folders selected in Finder. The"$@"ensures that filenames with spaces are handled correctly.open -a "Visual Studio Code" "$f": Theopencommand is a macOS utility that can open files, directories, and URLs. The-aflag specifies the application to use for opening. Here, we explicitly target “Visual Studio Code”."$f"represents the current file or folder being processed in the loop.
If you encounter issues, ensure “Visual Studio Code” is spelled correctly and that VS Code is installed in your Applications folder. You may also need to ensure the code command is available in your PATH by running the “Install ‘code’ command in PATH” command from within VS Code itself (accessible via the Command Palette: Cmd + Shift + P, then search for “Shell Command: Install ‘code’ command in PATH”). If you use the latter, you can simplify the script to code "$@".
Note on PATH: If your code command is properly installed in your PATH, you can use a simpler script: code "$@". This relies on the command-line tool installed by VS Code to find and open the files. The open -a method is more explicit about the application and works even if the command-line tool isn't configured.
- Save the Quick Action: Go to “File” > “Save” (or Cmd + S). Give your Quick Action a descriptive name, such as “Open in VS Code”.
After saving, navigate to any folder or file in Finder, right-click, and you should see “Open in VS Code” under the “Quick Actions” or “Services” submenu (depending on your macOS version and configuration). Selecting it will open the chosen item(s) in VS Code.
Method 2: Automated Setup with a Shell Script
For users who prefer a quicker, script-driven approach, a shell script can automate the creation of this Finder Quick Action. This method is particularly useful if you want to deploy this functionality across multiple machines or for users less familiar with Automator.
Using the Script:
- Create a Script File: Open a text editor (like VS Code itself) and paste the following script. Save it with a
.shextension, for example,create_vscode_quick_action.sh.
#!/bin/bash
# Define the name of the Quick Action
ACTION_NAME="Open in VS Code"
# Define the script content for the Quick Action
# This script opens selected files/folders in VS Code
# It assumes 'code' command is in PATH
SCRIPT_CONTENT="for f in \"$@\"; do
code \"$f\"
done"
# Create the Quick Action directory if it doesn't exist
QUICK_ACTION_DIR="$HOME/Library/Services"
mkdir -p "$QUICK_ACTION_DIR"
# Create the workflow file (.workflow)
WORKFLOW_FILE="$QUICK_ACTION_DIR/$ACTION_NAME.workflow"
# Basic structure of a .workflow file (plist format)
# This is a simplified representation. A full plist is more complex.
# We will create a temporary directory and then zip it into a .workflow bundle.
# Create a temporary directory for the workflow bundle
TEMP_DIR="/tmp/$ACTION_NAME.workflow.tmp"
rm -rf "$TEMP_DIR"
mkdir -p "$TEMP_DIR/Contents/Resources"
mkdir -p "$TEMP_DIR/Contents/MacOS"
# Create the Info.plist file
cat > "$TEMP_DIR/Contents/Info.plist" <<EOF
{
CFBundleDocumentTypes = (
{
CFBundleTypeName = "Public";
LSItemContentTypes = (
"public.item"
);
}
);
CFBundleName = "$ACTION_NAME";
CFBundleShortVersionString = "1.0";
CFBundleVersion = "1";
NSServicesDescription = {
"$ACTION_NAME" = {
NSMenuItem = {
default = "Open in VS Code";
};
NS hjælpe
NSRequiredContext = {
NSServiceDelegate = "ServiceDelegate";
NSServiceRunner = "ServiceRunner";
};
NSServicesDelegateClassName = "ServiceDelegate";
NSUserData = "$SCRIPT_CONTENT";
NSArguments = (
"$f"
);
NSPrincipalClass = "NSObject";
NSMessage = "runWorkflowWithArguments:";
NSArguments = (
"$f"
);
};
};
NSPrincipalClass = "NSObject";
NSMessage = "runWorkflowWithArguments:";
NSArguments = (
"$f"
);
NSUserData = "$SCRIPT_CONTENT";
NSMenuItem = {
default = "Open in VS Code";
};
NSServicesDescription = {
"$ACTION_NAME" = {
NSMenuItem = {
default = "Open in VS Code";
};
NSRequiredContext = {
NSServiceDelegate = "ServiceDelegate";
NSServiceRunner = "ServiceRunner";
};
NSServicesDelegateClassName = "ServiceDelegate";
NSUserData = "$SCRIPT_CONTENT";
NSArguments = (
"$f"
);
NSPrincipalClass = "NSObject";
NSMessage = "runWorkflowWithArguments:";
NSArguments = (
"$f"
);
};
};
}
EOF
# Create the ServiceDelegate.swift file (needed for newer macOS versions)
# This is a placeholder; actual Swift implementation might be required for complex services.
# For simple shell scripts, the plist often suffices, but a Swift delegate adds robustness.
cat > "$TEMP_DIR/Contents/ServiceDelegate.swift" <<EOF
import Foundation
class ServiceDelegate: NSObject {
@objc func runWorkflowWithArguments(_ invocation: NSXPCConnection) {
// This is a placeholder. For complex workflows, this would parse arguments and execute.
// For simple shell scripts, the main script is executed via the plist.
print("Running workflow: $ACTION_NAME")
}
}
EOF
# Create the main script executable
cat > "$TEMP_DIR/Contents/MacOS/$ACTION_NAME" <<EOF
#!/bin/bash
# This script is executed by Automator/Services
# The actual commands are defined in the Info.plist's NSUserData for simplicity here.
# The following is a more direct way to run the shell command
# if the 'code' command is in your PATH.
for f in "$@"
do
code "$f"
done
exit 0
EOF
# Make the script executable
chmod +x "$TEMP_DIR/Contents/MacOS/$ACTION_NAME"
# Convert the temporary directory into a .workflow bundle
# This requires 'osacompile' for older macOS, or manual bundle creation.
# For simplicity, we'll create the bundle structure manually.
# Move the created files into the final .workflow bundle structure
# The actual .workflow file is a directory with a .workflow extension.
# Remove the temporary directory and rename it to .workflow extension
rm -rf "$WORKFLOW_FILE"
mv "$TEMP_DIR" "$WORKFLOW_FILE"
# Ensure the .workflow directory is owned by the user
chown -R $(id -u):$(id -g) "$WORKFLOW_FILE"
echo "Quick Action '$ACTION_NAME' created successfully at $WORKFLOW_FILE"
echo "You may need to enable it in System Settings > Privacy & Security > Extensions > Finder."
exit 0
