Transform Windows Terminal's paste behavior to match classic console (conhost) experience: eliminate annoying paste warnings, enable safe multi-line pasting, and get those beautiful > continuation prompts you remember from the good old days! π
Quick Links: Installation β’ Documentation β’ Contributing β’ Changelog
This PowerShell script configures Windows Terminal and PowerShell to provide a safe paste experience that matches classic console behavior:
β
No more paste warning dialogs - Paste multi-line content without interruption
β
Classic continuation prompts - Beautiful > markers instead of stacked full prompts
β
Safe multi-line pasting - Text lands in the buffer, doesn't auto-execute
β
Idempotent and reversible - Safe to run multiple times, full rollback support
β
Works everywhere - Windows PowerShell 5.1, PowerShell 7+, all Terminal variants
- Copy the entire
Set-TerminalPaste.ps1file - Paste it into your PowerShell console
- Run with preview first:
Set-TerminalPaste -WhatIf
- Apply the changes:
Set-TerminalPaste - Restart Windows Terminal (close all instances)
# Preview changes
.\Set-TerminalPaste.ps1 -WhatIf
# Apply changes
.\Set-TerminalPaste.ps1
# Restart Windows Terminal# Preview what will change (safe, no modifications)
Set-TerminalPaste -WhatIf
# Apply to most recent Terminal settings + current PowerShell profile
Set-TerminalPaste# Apply to ALL Terminal installations and BOTH PowerShell profiles
Set-TerminalPaste -AllTerminalSettings -AllPowerShellProfiles# Don't override existing keybindings (preserves custom configs)
Set-TerminalPaste -ConservativeWhat Conservative Mode Does:
- Windows Terminal: Won't override an existing
Ctrl+Shift+Vbinding if it's already set to something other than 'paste' - PowerShell Profile: Won't override an existing PSReadLine
Ctrl+Vbinding if one is already configured
When to Use:
- You have custom keybindings you want to preserve
- Other scripts or tools have already configured paste behavior
- You're unsure what's already configured and want to be safe
- You want to add Terminal configuration but keep existing PSReadLine bindings
Note: The conservative setting is embedded in your profile block. If you run the script again with or without -Conservative, it will update the profile block with the new setting.
# Restore from most recent backups
Set-TerminalPaste -Rollback
# Rollback everything (all settings + profiles)
Set-TerminalPaste -Rollback -AllTerminalSettings -AllPowerShellProfiles- Sets
multiLinePasteWarning: false - Sets
largePasteWarning: false - Unbinds
Ctrl+Vat terminal layer (passes to PowerShell) - Ensures
Ctrl+Shift+Vis bound to terminal paste
Note: Settings.json will be normalized (comments/formatting removed). Original is backed up automatically.
The script adds a code block to your PowerShell profile (typically Documents\PowerShell\Microsoft.PowerShell_profile.ps1 or Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1) that:
- Configures PSReadLine to handle
Ctrl+Vpaste with classic continuation prompts - Uses
Insert() + AddLine()approach to produce>markers instead of stacked full prompts - Checks for ConsoleHost - only runs in console environments (not ISE/VS Code)
- Respects conservative mode - won't override existing Ctrl+V bindings if you use
-Conservative
What the code block does:
When PowerShell starts, it loads PSReadLine and sets up a custom Ctrl+V handler that:
- Gets clipboard content
- Splits it into lines
- Inserts each line using
Insert() - Adds continuation prompts using
AddLine()between lines
This produces the classic console experience where multi-line pastes show > continuation prompts instead of stacked full prompts.
Idempotent: The block is marked with # >>> WT_SAFE_PASTE (managed) >>> markers. If you run the script again, it finds and updates that same block instead of adding duplicates.
Conservative Mode in Profile: If you look at the profile block, you'll see a condition like if ($canQuery -and $false) or if ($canQuery -and $true). The $false/$true value reflects whether you ran with -Conservative:
$false(default) = Always set the handler (not in conservative mode)$true= Check for existing binding first (conservative mode enabled)
- Timestamped backups - Every file gets a
.bak.yyyyMMdd-HHmmss-ffffbackup before modification - Pre-edit validation - Checks file structure before making changes
- Post-edit validation - Verifies JSON is valid and structure is intact (aborts on corruption)
- Change reports - Detailed audit trail saved to
WindowsTerminal_SafePaste_Changes_TIMESTAMP.txt - WhatIf support - Preview changes without applying them
- Full rollback - Restore from backups with
-Rollbackparameter
- Windows with Windows Terminal installed
- PowerShell 5.1 or 7+ (Windows PowerShell or PowerShell Core)
- PSReadLine module (usually pre-installed with PowerShell)
Change reports are saved next to the script file when run as a file, or in your current directory when pasted into console. Look for WindowsTerminal_SafePaste_Changes_TIMESTAMP.txt files.
If your PowerShell profile directory doesn't exist (e.g., Documents\PowerShell\), the script will create it automatically. This is normal and expected.
By default, the script patches only the most recently modified Windows Terminal settings file. If you have multiple Terminal installations (Stable + Preview), only one gets patched unless you use -AllTerminalSettings.
The code block added to your profile runs every time PowerShell starts. It's lightweight (just checks and configures PSReadLine), but it does execute on startup. If you remove the managed block markers, the script won't find it to update it.
If PSReadLine isn't available when PowerShell starts, the profile block silently does nothing (wrapped in try/catch). This is safe but means paste behavior won't be configured until PSReadLine is available.
Windows Terminal and classic console (conhost) render multi-line input differently:
| Feature | Windows Terminal | Classic Console |
|---|---|---|
| Multi-line display | Each line on separate row with stacked C:\ prompts |
Single wrapped line with inline >> markers |
| Escape key | Clears ONE line at a time | Clears entire input |
| Cancel all | Ctrl+C required |
Escape works |
This script solves the visual difference by using Insert() + AddLine() to produce classic > continuation prompts in Windows Terminal. Functionally, both work correctly (no warning, no auto-execute), but the editing experience is now consistent with classic console.
Windows Terminal settings files often contain comments (JSONC format). This script reads JSONC but writes normalized JSON (comments removed). This is expected behavior - your original file is backed up automatically.
If Windows Terminal Settings UI is open during script execution, it may rewrite settings.json after the script finishes. Close the Settings UI before running the script to avoid conflicts.
The script looks for settings in:
%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal*8wekyb3d8bbwe\LocalState\settings.json(Store apps)%LOCALAPPDATA%\Microsoft\Windows Terminal\settings.json(unpackaged)
If you have a custom installation location, you may need to manually patch that file.
Use -AllPowerShellProfiles to explicitly patch both profile locations, or manually specify profiles.
- Ensure Windows Terminal Settings UI is closed
- Restart Windows Terminal completely (close all windows)
- Verify settings.json was actually modified (check backup timestamp)
- Check that
multiLinePasteWarningandlargePasteWarningare set tofalse
- Ensure PowerShell profile was patched (check for managed block markers)
- Restart PowerShell session (or restart Windows Terminal)
- Verify PSReadLine is loaded:
Get-Module PSReadLine - Check key handler:
Get-PSReadLineKeyHandler -Chord 'Ctrl+V'
Windows Terminal intercepts Ctrl+V at the terminal layer, showing warning dialogs and executing multi-line pastes line-by-line instead of inserting them into the edit buffer.
- Disable warnings - Set
multiLinePasteWarningandlargePasteWarningtofalse - Unbind Ctrl+V - Remove
Ctrl+Vbinding from Terminal so it passes through to PowerShell - Configure PSReadLine - Use
Insert() + AddLine()to produce classic continuation prompts - Preserve Terminal paste - Keep
Ctrl+Shift+Vfor terminal-level paste operations
-
JSONC parsing - Custom parser handles comments and trailing commas (PowerShell's
ConvertFrom-Jsondoesn't support JSONC) -
Schema compatibility - Handles both modern "actions" schema and legacy "keybindings" schema
-
Idempotent operations - Safe to run multiple times. The script adds a marked code block to your PowerShell profile (between
# >>> WT_SAFE_PASTE (managed) >>>and# <<< WT_SAFE_PASTE (managed) <<<markers). If you run the script again, it finds and updates that same block instead of adding duplicates.Example scenario: You run the script today, then update to a new version of the script next month. Running the new version finds your existing managed block and updates it with any improvements, rather than leaving you with duplicate code blocks or conflicting configurations.
-
Defensive programming - Extensive validation, error handling, and rollback support
We welcome contributions! Please see our Contributing Guide for details on:
- π Bug Reports: Help us improve by reporting issues
- π‘ Feature Requests: Suggest new functionality
- π§ Pull Requests: Submit code improvements
- π Documentation: Help improve our docs
- π Issues: Report bugs or request features
- π Discussions: Ask questions and share ideas
- π Documentation: Technical details and guides
This project is licensed under the MIT License - see the LICENSE file for details.
- Created for PowerShell users who miss classic console paste behavior
- Inspired by the need for predictable, shell-friendly keybindings
- Tested extensively on Windows Terminal v1.24+ across multiple configurations
β Star this repo if it helped you! β’ π Found an issue? Report it β’ π‘ Have an idea? Share it
Enjoy your safe paste experience! π