DEV Community

Cover image for VS Code Remote SSH: Automatically Invoke VS Code as Your Editor from External Terminals
upa_rupa
upa_rupa

Posted on

VS Code Remote SSH: Automatically Invoke VS Code as Your Editor from External Terminals

The Problem to Solve

VS Code Remote (SSH) is powerful, but there are situations where you want to handle terminal operations in your favorite external terminal like iTerm2 instead of the integrated terminal.

However, when working from an external terminal, you can't seamlessly use VS Code as your editor out of the box.

  • Open files with code <filename> from external terminals like iTerm2, Alacritty, or WezTerm
  • Use VS Code as the editor for git commit or crontab -e, but automatically fall back to another editor when VS Code isn't running

This article introduces a wrapper script that solves both.

Background: Why code Doesn't Work from Terminals Outside VS Code

Inside VS Code's integrated terminal, environment variables for communicating with the VS Code server (VSCODE_IPC_HOOK_CLI) and paths to dedicated executables are set automatically.

These aren't inherited by external terminals, though. So simply running the code command won't actually "open the file in a VS Code window."

This issue is well known, and there are existing articles offering solutions:

A common approach is to write the socket lookup in .zshrc or .bashrc — both references above take this route. The downside is that it's evaluated once at shell startup, so it can't keep up when VS Code is started or restarted afterward. The Vinnie article works around this by wrapping the lookup in a shell function you can re-run manually, but neither reference handles the case where VS Code isn't running at all.

In this article, we'll put the lookup in a standalone script that re-evaluates on every invocation and gracefully falls back to another editor when VS Code isn't running.

The Solution: A Wrapper Script Called editor

First, create a directory to hold the script (e.g., ~/bin) and save the following as editor.

Creating the Script

#!/bin/bash
# Find the most recent IPC socket
export VSCODE_IPC_HOOK_CLI=$(ls -t /run/user/$(id -u)/vscode-ipc-*.sock 2>/dev/null | head -1)
# Get the path to the VS Code CLI executable
vscode_code=$(ls -td ~/.vscode-server/cli/servers/*/server/bin/remote-cli/code 2>/dev/null | head -1)

# When VS Code is available
if [ -S "$VSCODE_IPC_HOOK_CLI" ] && [ -n "$vscode_code" ]; then
  if [ $# -eq 0 ]; then
    # Running `code` with no arguments often just exits silently,
    # so prompt the user to specify a file when invoked as an editor
    echo "When using VS Code, please specify a file: editor <filename>"
    exit 1
  fi
  # VS Code may be hidden behind other windows or take a moment to surface
  echo "Opening in VS Code..."
  # --wait blocks until the file is closed in VS Code
  "$vscode_code" --wait "$@" >/dev/null 2>&1
  exit $?
else
  # If VS Code isn't available, fall back to another editor (nano, vim, etc.)
  nano "$@"
fi
Enter fullscreen mode Exit fullscreen mode

Granting Execute Permission

chmod +x ~/bin/editor
Enter fullscreen mode Exit fullscreen mode

Shell Configuration

Make the script callable from anywhere and register it as the system's default editor. Add the following to your .zshrc or .bashrc:

# Add ~/bin to PATH (if not already)
export PATH="$HOME/bin:$PATH"

# Register as the default editor
export EDITOR="$HOME/bin/editor"
export VISUAL="$HOME/bin/editor"
Enter fullscreen mode Exit fullscreen mode

How It Works

Auto-discovering the Latest Socket

You could hardcode the socket path in .zshrc, but it changes every time VS Code restarts and breaks. This script looks under /run/user/ on every invocation, so it adapts to whatever the current connection state is.

Use from External Terminals

With this script in place, you don't have to think about whether you're inside VS Code's integrated terminal. Just type editor in your favorite external terminal and VS Code opens the file.

Handling No-Argument Invocation

Running code with no arguments simply exits. That's confusing when invoked as an editor — nothing happens — so the script prints a hint instead.

Programs differ in whether they read EDITOR or VISUAL. Many tools, including git and crontab, prefer VISUAL, but some only check EDITOR. Setting both is the most reliable approach.

Where This Helps

Once EDITOR/VISUAL point at this script, VS Code is automatically used in situations like:

  • git commit — Editing commit messages
  • git rebase -i — Interactive rebase operations
  • crontab -e — Editing crontabs
  • Ctrl+x, Ctrl+e — Bash/Zsh command-line editing
  • Claude Code's Ctrl+X, Ctrl+E — Launching an external editor for prompt input

If VS Code isn't running when you invoke any of these, nano (or whatever you configured) takes over, so your workflow doesn't stall.

Behavior Summary

State editor file.txt editor (no arguments)
VS Code running Opens in VS Code Shows a guidance message
VS Code not running Opens in nano Opens in nano

Closing Thoughts

I love VS Code, but iTerm2's tmux integration (tmux -CC) is so handy that I often skip the integrated terminal entirely. Even then, I still want VS Code for actual file editing, and this wrapper made that workflow much smoother. Getting Copilot completions while editing crontabs is a quietly nice bonus.

It's a small piece of configuration, but if you're a fellow VS Code user in the same situation, hopefully this is useful.


This article was originally published in Japanese at archelon-inc.jp.

Top comments (0)