TextMate for Visual Studio Code

April 14, 2026 · View on GitHub

This extension aims at recreating the TextMate experience in Visual Studio Code.

Features

TextMate Commands

Execute arbitrary scripts with configurable input/output handling via keyboard shortcuts. Define commands directly in your keybindings.json with full control over execution context.

Usage

Add keybindings to your keybindings.json:

{
  "key": "ctrl+alt+cmd+t",
  "command": "vscode-textmate.command",
  "when": "editorTextFocus",
  "args": {
    "script": "#!/usr/bin/env bash\n\nopen \"$TM_PROJECT_DIRECTORY\" -a Terminal.app",
    "save": "currentDocument",
    "input": "none",
    "output": "discard"
  }
}

Arguments

  • script (string): Shell script to execute (supports shebang)
  • save: Document saving - "none" | "currentDocument" | "allDocuments"
  • input: Input source - "selection" | "document" | "line" | "word" | "character" | "scope" | "none"
  • output: Output handling - "replaceInput" | "replaceSelection" | "replaceDocument" | "insertText" | "insertAsSnippet" | "newDocument" | "showAsHTML" | "showAsTooltip" | "discard"
  • outputFormat: Output format - "text" | "snippet" | "HTML"
  • caretPlacement: Caret positioning - "afterOutput" | "selectOutput" | "characterInterpolation" | "lineInterpolation" | "Heuristic"

Environment Variables

Scripts receive TextMate-style environment variables:

  • TM_SELECTED_TEXT - Currently selected text
  • TM_CURRENT_LINE - Current line content
  • TM_CURRENT_WORD - Current word at cursor
  • TM_FILENAME - Current file name
  • TM_FILEPATH - Current file path
  • TM_DIRECTORY - Current file directory
  • TM_PROJECT_DIRECTORY - Workspace root directory
  • TM_LINE_INDEX - Current line (0-based)
  • TM_LINE_NUMBER - Current line (1-based)
  • TM_COLUMN_NUMBER - Current column (1-based)

Examples

Text transformation:

{
  "key": "ctrl+u",
  "command": "vscode-textmate.command",
  "when": "editorTextFocus",
  "args": {
    "script": "tr '[:lower:]' '[:upper:]'",
    "input": "selection",
    "output": "replaceInput"
  }
}

Insert timestamp:

{
  "key": "ctrl+alt+d",
  "command": "vscode-textmate.command",
  "when": "editorTextFocus",
  "args": {
    "script": "date +%Y-%m-%d",
    "input": "none",
    "output": "insertText"
  }
}

Sort lines:

{
  "key": "ctrl+alt+s",
  "command": "vscode-textmate.command",
  "when": "editorTextFocus",
  "args": {
    "script": "sort",
    "input": "selection",
    "output": "replaceInput"
  }
}

Keybindings

A good amount of keybindings have been ported from TextMate.

closeOtherEditors, closeEditorInAllGroups

Fix the default VSCode behavior of asking to save unsaved files when closing editors. These commands will close specified editors except any "dirty" or "pinned" editor.

NameCommandKeybinding
Close Other EditorscloseOtherEditors⌃⌘W
Close Editor in All GroupscloseEditorInAllGroups⌃⌥⌘W

openProject

Open a project in a new window, selecting from subfolders of the folders listed in the projectFolders setting.

openQuickly

Quick file opener that replaces VS Code's default "Open Quickly…" command with TextMate's behavior. Press ⌘T to open a searchable list of all files in the workspace, filtered intelligently to exclude common build artifacts and dependencies. Uses the same selection interface as other TextMate commands for a consistent experience.

selectFromList (internal)

Provides a flexible UI for selecting items from a list. Shows a webview-based selection interface that allows for multi-selection from a provided array of items. Can be used by other extensions as a nearly drop-in replacement for showQuickPick.

Command Usage

picks = await vscode.commands.executeCommand(
  "vscode-textmate.showSelectFromList",
  items,
  options
)

Parameters

  • items (array, required): Array of items to select from. Items can be:

    • Strings: "Item 1"
    • Numbers/Booleans: 42, true
    • Objects: { label: "Custom Item", description: "Optional description" }
  • options (object, optional): Configuration options

    • title (string): Title displayed in the selection interface (default: "Select From List")
    • renderAs (string): Where to show the interface:
      • "sidebar": Shows in dedicated sidebar view
      • "panel": Opens in webview panel
      • Defaults to user's vscode-textmate.selectFromList.renderAs setting

Examples

// Simple string selection
const picks = await vscode.commands.executeCommand(
  "vscode-textmate.showSelectFromList",
  ["Option 1", "Option 2", "Option 3"],
  { title: "Choose Options" }
)

// Mixed item types with custom rendering
const picks = await vscode.commands.executeCommand(
  "vscode-textmate.showSelectFromList",
  [
    "Simple string",
    { label: "Complex Item", description: "With description" },
    42,
    true
  ],
  {
    title: "Mixed Selection",
    renderAs: "panel"
  }
)

File Operations

NameCommandKeybinding
Open QuicklyopenQuickly⌘T

Find

Replaces VS Code's find keybindings with TextMate-style behavior.

NameKeybinding
Find in Files⇧⌘F
In-editor Find⌘F
Next Search Result⌘G
Previous Search Result⇧⌘G

You can navigate between brackets and blocks using ctrl with up and down, adding shift to also update the selection. Word movement (alt+left/right) follows TextMate semantics.

NameCommandKeybinding
Jump to SelectionjumpToSelection⌘J
Move Word LeftmoveWordLeft⌥←
Move Word RightmoveWordRight⌥→
Select Word LeftmoveWordLeftAndModifySelection⌥⇧←
Select Word RightmoveWordRightAndModifySelection⌥⇧→
Move to beginning of BlockmoveToBeginningOfBlock⌃⭡
Move to end of BlockmoveToEndOfBlock⌃⭣
Select to beginning of BlockmoveToBeginningOfBlockAndModifySelection⌃⇧⭡
Select to end of BlockmoveToEndOfBlockAndModifySelection⌃⇧⭣
Move to beginning of ColumnmoveToBeginningOfColumn⌥⭡
Move to end of ColumnmoveToEndOfColumn⌥⭣
Select to beginning of ColumnmoveToBeginningOfColumnAndModifySelection⌥⇧⭡
Select to end of ColumnmoveToEndOfColumnAndModifySelection⌥⇧⭣

Editing

NameCommandKeybinding
Join LinesjoinLines⌃⇧J
Toggle CasetoggleCase⌃⇧-
TransposetransposeWords⌃T
Copy to Find PasteboardcopyToFindPasteboard⌘E

Folding

Toggle folding at a specific depth with ⌥⌘0⌥⌘7.

NameCommandKeybinding
Toggle Fold at Depth 0foldAtDepth⌥⌘0
Toggle Fold at Depth 1foldAtDepth⌥⌘1
Toggle Fold at Depth 2foldAtDepth⌥⌘2
Toggle Fold at Depth 3foldAtDepth⌥⌘3
Toggle Fold at Depth 4foldAtDepth⌥⌘4
Toggle Fold at Depth 5foldAtDepth⌥⌘5
Toggle Fold at Depth 6foldAtDepth⌥⌘6
Toggle Fold at Depth 7foldAtDepth⌥⌘7

All commands are under the vscode-textmate namespace, e.g. vscode-textmate.moveToEndOfColumn.

Migration Notes

Window title (up to v0.27.1)

Prior to v0.28.0, this extension managed the window title by directly writing to the window.title workspace setting, injecting the current SCM branch via a custom ${scmBranch} variable and polling for changes every few seconds.

This approach is no longer needed — VS Code 1.35+ includes ${activeRepositoryBranchName} as a native window.title variable. If you were using the old vscode-textmate.windowTitle setting, you can remove it and configure window.title directly in your settings.

Before (in .vscode/settings.json):

{
  "vscode-textmate.windowTitle": "${scmBranch} — ${rootName}"
}

After (in settings.json):

{
  "window.title": "${activeRepositoryBranchName} — ${rootName}"
}

Troubleshooting

VS Code plays a sound with some keybindings: https://superuser.com/a/1530872

License

MIT

Icon by Marc Oliver Orth