跪拜 Guibai
← Back to the summary

Windows 11 Terminal Beautification: A Complete From-Scratch Guide

Windows 11 Terminal Beautification Complete Guide

Applicable environment: Windows 11 22H2 and above, Windows Terminal 1.20+, PowerShell 7.2+ Tab bar UI theme: requires Windows Terminal 1.24 and above (see section 3.5) Goal: from "white background black text, full of square boxes" to a modern terminal with "frosted glass, Nerd icons, Git status, smart completion" How to read: in a hurry → see Chapter 2 "10 Minute Quick Start"; want to understand everything → read sequentially from Chapter 0


github: https://github.com/sumigmomo/Windows11-Terminal-Setup-Offline Provides a one-click installation script, recommended to download and use directly, double-click Setup-NewPc.cmd

Font link: https://github.com/subframe7536/maple-font/releases/download/v7.9/MapleMono-NF-CN.zip Font size about 150M, if the script download is too slow you can download manually, put it in the root directory \fonts directory, the script will automatically find and install the font

image.png

Effect preview

image.png

Preface

This is a from-scratch Windows 11 terminal beautification tutorial, covering Windows Terminal appearance, Nerd Font, Oh My Posh prompt, PSReadLine completion, common command-line tools, and a ready-to-use profile.

The text uses Catppuccin Mocha and Tokyo Night Storm as two color scheme examples, but all steps are not bound to a specific theme: you can replace them with any color scheme and OMP theme you like.

The text uses relatively recent versions of Windows Terminal and Oh My Posh as examples; when version differences occur, compatibility ranges are noted in the text.


Table of Contents


0. First figure out: what exactly are you beautifying

Many people copy a bunch of configs at the start and don't know which layer went wrong. Terminal beautification actually only has four layers:

┌─────────────────────────────────────────────────────┐
│  Windows Terminal (terminal host)                   │
│  Responsible for: window, tabs, font rendering, color scheme, transparency, background image │
│  ┌───────────────────────────────────────────────┐  │
│  │  PowerShell 7 (Shell)                         │  │
│  │  Responsible for: executing commands, history, completion, syntax highlighting │  │
│  │  ┌─────────────────────────────────────────┐  │  │
│  │  │  Oh My Posh (prompt framework)          │  │  │
│  │  │  Responsible for: path, Git branch, execution time, version numbers… │  │
│  │  └─────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────┘  │
│  Font (Nerd Font): provides arrows, file/language icons and monospaced alignment │
└─────────────────────────────────────────────────────┘
Layer Component When something goes wrong you'll see
Terminal host Windows Terminal Wrong color scheme, not transparent, font not selectable
Shell PowerShell 7 Commands not working, profile errors
Prompt Oh My Posh Prompt is still the old PS C:\>
Font Nerd Font Full of □, ?, icons misaligned

Correct order: terminal → font → prompt → completion → toolchain. If the font is not right, all icons later will become boxes — this is the most common pitfall for beginners.


1. Environment self-check

First spend 1 minute confirming the current state. Execute in PowerShell 7 (not Windows PowerShell 5.1):

# 1. PowerShell version, should be 7.x
$PSVersionTable.PSVersion

# 2. Whether Windows Terminal exists
(Get-Command wt.exe).Source

# 3. PowerShell 7 profile path (not existing is normal)
$PROFILE
Test-Path $PROFILE

# 4. Execution policy, RemoteSigned is fine
Get-ExecutionPolicy -List

# 5. Whether Nerd Font is installed (output means installed)
@(
    (Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts').PSObject.Properties.Name
    (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts').PSObject.Properties.Name
) | Where-Object { $_ -match 'Nerd|NF|Maple|Cascadia|Sarasa|Meslo' } | Sort-Object -Unique

How to judge your environment:

Check item Normal situation
PowerShell 7.x; if only 5.1, need to install PowerShell 7 first
Windows Terminal Get-Command wt.exe has a result
PowerShell 7 profile Path not existing is also normal, Chapter 8 will create it
Nerd Font Not installed is fine, Chapter 4 will install it
Execution policy RemoteSigned or Unrestricted both work

As long as PowerShell 7 and Windows Terminal are in place, other components can be installed as you go. This text does not require cleaning up old configs first; profile and settings.json are plain text, and can be restored if messed up.

⚠️ Don't confuse the two PowerShells

  • Windows PowerShell 5.1: built-in, profile in Documents\WindowsPowerShell
  • PowerShell 7: installed by you, profile in Documents\PowerShell

All configs in this text are written in the profile of 7; it's normal that they don't take effect in 5.1.


2. 10 Minute Quick Start (lazy version)

If you just want to quickly look better, follow these 5 steps, details in later chapters:

# ① Install Oh My Posh (skip if already installed)
winget install --id JanDeDobbeleer.OhMyPosh -e --source winget --accept-package-agreements --accept-source-agreements

# ② Install font (interactive list, use arrow keys to select CascadiaCode and press Enter; Chinese users see Chapter 4)
oh-my-posh font install

# ③ Copy all themes, write the current theme, then create profile
$ompThemes = if ($env:POSH_THEMES_PATH) { $env:POSH_THEMES_PATH } else { (Get-AppxPackage ohmyposh.cli).InstallLocation + '\themes' }
New-Item -ItemType Directory "$HOME\.config\oh-my-posh" -Force | Out-Null
Copy-Item "$ompThemes\*.omp.json" -Destination "$HOME\.config\oh-my-posh" -Force
Set-Content "$HOME\.config\oh-my-posh\active-theme.txt" 'catppuccin_mocha' -Encoding utf8
New-Item -ItemType File -Path $PROFILE -Force
notepad $PROFILE   # paste the template from Chapter 8, save

If Get-AppxPackage reports "access denied", use the Get-OmpThemesDir function from section 5.3 instead.

④ Open Windows Terminal → Ctrl + , → Appearance → set font to Cascadia Code NF (based on the name shown in the font dropdown, Chinese users select Maple Mono NF CN), font size 11. If you want to use Catppuccin color scheme, first add the JSON from section 3.5 to schemes; if you're too lazy to change, first select the built-in One Half Dark.

⑤ Close all terminal tabs and reopen. You should see a prompt with icons and Git info.

If you want more refinement (frosted glass, Catppuccin color scheme, smart completion, ll/z/fzf), continue reading.


3. Step 1: Windows Terminal configuration

3.1 Set Windows Terminal as the default terminal

If not set, double-clicking .ps1, launching cmd from Run, etc. will still pop up the old conhost window.

Method one (recommended): Windows Settings → System → Developer options → find Terminal → set Default terminal application to Windows Terminal.

Method two: Windows Terminal → Ctrl + , → Startup → Default terminal application → Windows Terminal.

3.2 Open PowerShell 7 by default

Ctrl + , → Startup → Default profile → select PowerShell (the one with black >_ icon, not Windows PowerShell).

Conveniently set Startup to "Maximized" or "Default", depending on your habit.

3.3 Find and back up settings.json

All appearance of Windows Terminal ultimately falls on settings.json. The GUI can only change a subset; transparent frosted glass, background image, scrollbar hidden, antialiasing must be changed in JSON.

Ctrl + , → click Open JSON file at bottom left. The file is usually at:

# Store version (most people)
%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json

# Non-Store version (winget / scoop / portable)
%LOCALAPPDATA%\Microsoft\Windows Terminal\settings.json

Backup (strongly recommended, so you can roll back instantly if you mess up):

$wt = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
if (Test-Path $wt) {
    Copy-Item $wt "$wt.bak" -Force
    "Backed up to $wt.bak"
} else {
    "Store version config not found, check %LOCALAPPDATA%\Microsoft\Windows Terminal\settings.json"
}

💡 You can also directly edit: code $wt (requires VS Code), or notepad $wt.

3.4 Appearance: core JSON

In settings.json, find "profiles" → "defaults". If there is no defaults, manually add one, then merge the following keys into it (if the same key already exists, change the value; don't repeat-listen):

"profiles":
{
    "defaults":
    {
        "font":
        {
            "face": "Maple Mono NF CN",
            "size": 11,
            "weight": "normal"
        },
        "colorScheme": "Catppuccin Mocha",
        "opacity": 88,
        "useAcrylic": true,
        "padding": "10, 10, 8, 10",
        "cursorShape": "bar",
        "antialiasingMode": "grayscale",
        "scrollbarState": "hidden",
        "intenseTextStyle": "bright",
        "copyOnSelect": true,
        "multiLinePasteWarning": false
    }
}

The above is just a schematic structure. When actually editing: if profiles already has defaults, only merge the keys inside; leave the list array unchanged.

Explanation item by item:

Key Function Suggestion
font.face Font name, must exactly match the system one Maple Mono NF CN / Cascadia Code NF
font.size Font size 1080p use 11, 2K use 12, 4K use 13–14
font.weight Font weight normal; high-DPI screens can try light
colorScheme Color scheme name see 3.5
opacity Opacity 0–100 85–92 is comfortable, too low strains eyes
useAcrylic Acrylic frosted glass true; if old GPU feels laggy, change to false
padding Inner padding, left, top, right, bottom "10, 10, 8, 10" whitespace is just right
cursorShape Cursor shape bar (vertical line) / filledBox (block) / doubleUnderline
antialiasingMode Antialiasing grayscale is clearer for thin fonts; cleartype is sharper
scrollbarState Scrollbar hidden is cleanest; change to visible if needed (older WT may not support)
intenseTextStyle Bold color enhancement bright makes the 16 colors more vibrant
copyOnSelect Copy on selection true, once you use it you know
multiLinePasteWarning Multi-line paste warning false saves one Enter press

defaults applies to all profiles (including cmd, WSL). If you only want to change PowerShell 7, write the same keys into the corresponding item in profiles.list.

3.5 Color scheme: Catppuccin Mocha

Windows Terminal comes with several color schemes (Campbell, One Half Dark, Solarized…), but none are as pleasing as community color schemes. Here is a complete usable Catppuccin Mocha.

Find or add "schemes": [ ... ] at the root level of settings.json, and add the following entire block to the array:

{
    "name": "Catppuccin Mocha",
    "background": "#1E1E2E",
    "foreground": "#CDD6F4",
    "cursorColor": "#F5E0DC",
    "selectionBackground": "#585B70",
    "black": "#45475A",
    "red": "#F38BA8",
    "green": "#A6E3A1",
    "yellow": "#F9E2AF",
    "blue": "#89B4FA",
    "purple": "#F5C2E7",
    "cyan": "#94E2D5",
    "white": "#BAC2DE",
    "brightBlack": "#585B70",
    "brightRed": "#F38BA8",
    "brightGreen": "#A6E3A1",
    "brightYellow": "#F9E2AF",
    "brightBlue": "#89B4FA",
    "brightPurple": "#F5C2E7",
    "brightCyan": "#94E2D5",
    "brightWhite": "#A6ADC8"
}

Then confirm that the value of profiles.defaults.colorScheme and "name" are exactly the same (including spaces).

Windows Terminal 1.24 and above also has an independent "themes" array, controlling the tab bar/title bar colors, which is not the same as "schemes". When both are configured, the visual is unified.

If the color scheme name conflict is reported after saving: it means your WT version has a built-in scheme with the same name, just delete the block you pasted and select it in the UI; or change both Catppuccin Mocha occurrences to Catppuccin Mocha Custom.

Alternative: Tokyo Night Storm (more blue-purple, higher contrast)

{
    "name": "Tokyo Night Storm",
    "background": "#24283B",
    "foreground": "#C0CAF5",
    "cursorColor": "#C0CAF5",
    "selectionBackground": "#364A82",
    "black": "#1D202F",
    "red": "#F7768E",
    "green": "#9ECE6A",
    "yellow": "#E0AF68",
    "blue": "#7AA2F7",
    "purple": "#BB9AF7",
    "cyan": "#7DCFFF",
    "white": "#A9B1D6",
    "brightBlack": "#414868",
    "brightRed": "#F7768E",
    "brightGreen": "#9ECE6A",
    "brightYellow": "#E0AF68",
    "brightBlue": "#7AA2F7",
    "brightPurple": "#BB9AF7",
    "brightCyan": "#7DCFFF",
    "brightWhite": "#C0CAF5"
}

3.6 Background image and frosted glass (optional)

If you like anime wallpapers/dark textures, add to profiles.defaults:

"backgroundImage": "C:\\Users\\<your username>\\Pictures\\terminal-bg.jpg",
"backgroundImageOpacity": 0.22,
"backgroundImageStretchMode": "uniformToFill",
"backgroundImageAlignment": "center"

Note:

3.7 Startup and window

At the root level (sibling of "profiles"):

"launchMode": "maximized",
"startOnUserLogin": false,
"confirmCloseAllTabs": true

3.8 Shortcut cheat sheet

Shortcut Function
Ctrl + Shift + T New tab
Ctrl + Shift + W Close tab
Alt + Shift + D Duplicate current profile and split (default vertical)
Alt + Shift + + / - Split left-right / top-bottom
Ctrl + Shift + P Command palette (search all actions)
Ctrl + Shift + F Find
Win + backtick Quake dropdown terminal (global summon)
Ctrl + + / Ctrl + - Font size zoom

Split screen + Quake mode are the two features with the biggest efficiency boost, worth practicing.


4. Step 2: Nerd Font font

4.1 Why you must change the font

PowerShell itself doesn't need a special font, but Oh My Posh / Terminal-Icons / eza / Starship output these characters:

Normal fonts (Microsoft YaHei, Consolas, original Cascadia Code) don't have these glyphs, so they display as □ or ?. Nerd Font = patched 3000+ icons onto monospaced programming fonts, solving it once and for all.

4.2 How to choose a font

Font Chinese Icons Ligatures Style Suitable for
Maple Mono NF CN ✅ ✅ ✅ Rounded, slightly handwritten, gentle italic First choice for Chinese users, default in this text
Sarasa Term SC Nerd Font (更纱黑体) ✅✅ ✅ ❌ Rigorous, widest glyph coverage Chinese-first, hate fancy
Cascadia Code NF ❌ ✅ ✅ Microsoft official, modern English-only environments
JetBrainsMono Nerd Font ❌ ✅ ✅ Hard, highly recognizable Code writing
MesloLGS NF ❌ ✅ ❌ p10k standard Copying macOS config

⚠️ Key pitfall for Chinese users: Cascadia Code / JetBrains Mono do not contain Chinese. Windows Terminal will fall back character by character to Microsoft YaHei, causing Chinese to become proportional-width — width misalignment, line height jumping, table misalignment. So in Chinese environments, prioritize Maple Mono NF CN or Sarasa Term SC Nerd Font with CJK.

4.3 Install Maple Mono NF CN (recommended, manual is most stable)

  1. Open the Release page: https://github.com/subframe7536/maple-font/releases
  2. Download MapleMono-NF-CN.zip from the latest version's Assets
    • NF = Nerd Font (with icons)
    • CN = includes Chinese
    • Don't select the Variable version; static version has better compatibility
  3. Unzip, enter the directory, select all .ttf files
  4. Right-click → Install (or "Install for all users", requires administrator)
    • Windows 11's right-click menu requires clicking "Show more options" first to see "Install"
  5. Completely close and reopen Windows Terminal (font cache needs refreshing)

4.4 Install with scoop (one command, suitable for those with scoop already)

If you don't have scoop, install it first:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned -Force
Invoke-RestMethod get.scoop.sh | Invoke-Expression

Then:

scoop bucket add nerd-fonts
scoop install nerd-fonts/Maple-Mono-NF-CN

Sarasa (package name based on scoop search results):

scoop search sarasa          # first look at the package name
scoop install nerd-fonts/Sarasa-Term-SC-Nerd

The benefit of scoop: upgrade and uninstall are one command, no need to manually delete fonts.

4.5 Verify the font is installed

# The registry should show the full font name
@(
    (Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts').PSObject.Properties.Name
    (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts').PSObject.Properties.Name
) | Where-Object { $_ -match 'Maple|Nerd|Sarasa|Cascadia' } | Sort-Object -Unique

Or directly print a test string of icons in the terminal:

"`u{e0b0}  `u{e0b2}  `u{f07b}  `u{e725}  `u{f1d3}  `u{e70f}"

Finally confirm in Windows Terminal → Settings → Appearance → Font → Font face dropdown that you can search for Maple Mono NF CN.

4.6 Font size and clarity

Resolution Suggested font size
1920×1080 11
2560×1440 12
3840×2160 13–14 (or 12 + system scaling 150%)

With "antialiasingMode": "grayscale", thin font weights look cleaner.

4.7 Font-related pitfalls

Phenomenon Reason Solution
Can't find font in WT Didn't restart terminal after install Completely exit WT and reopen
Selected correct font but icons still boxes Installed the non-NF version Reinstall *NF* package
Font name written wrong Actually called Maple Mono NF CN, not Maple Mono Copy the exact name from the dropdown
Chinese width misaligned Font doesn't contain CJK, fell back to YaHei Switch to Maple Mono NF CN / Sarasa
Icons squeezed together Used a non-monospaced Nerd Font Switch to monospaced version

5. Step 3: Oh My Posh prompt

5.1 What it is

Oh My Posh does only one thing: renders a beautiful prompt line based on the current directory, Git status, last command execution time, language versions, and other information. It doesn't take over your Shell, nor change command behavior — so you can delete it anytime with zero risk.

Competing product: Starship (written in Rust, faster and simpler, config is TOML). Chapter 10 later will cover how to choose.

5.2 Install

# Recommended: winget
winget install --id JanDeDobbeleer.OhMyPosh -e --source winget --accept-package-agreements --accept-source-agreements

# Or scoop
scoop install oh-my-posh

After installation open a new terminal to verify:

oh-my-posh --version

5.3 MSIX installation has a pitfall: themes are not in POSH_THEMES_PATH

Most online tutorials will tell you to use $env:POSH_THEMES_PATH to build the theme path. Under some MSIX installation methods, this variable may be empty, and copying that will get CONFIG NOT FOUND.

Theme directories for different installation methods:

Installation method Theme directory
MSIX (newer winget install) C:\Program Files\WindowsApps\ohmyposh.cli_<version>_x64__<hash>\themes
Portable / old winget %LOCALAPPDATA%\Programs\oh-my-posh\themes (= $env:POSH_THEMES_PATH)
winget portable package %LOCALAPPDATA%\Microsoft\WinGet\Packages\JanDeDobbeleer.OhMyPosh_*\themes
scoop %USERPROFILE%\scoop\apps\oh-my-posh\current\themes

Use the following to automatically locate (paste into terminal and run once):

function Get-OmpThemesDir {
    # Old version / portable
    if ($env:POSH_THEMES_PATH -and (Test-Path $env:POSH_THEMES_PATH)) {
        return $env:POSH_THEMES_PATH
    }

    # MSIX version
    $pkg = $null
    try { $pkg = Get-AppxPackage -Name ohmyposh.cli -ErrorAction Stop } catch { $pkg = $null }

    if ($pkg) {
        $p = Join-Path $pkg.InstallLocation 'themes'
        if (Test-Path $p) { return $p }
    }

    # If Get-AppxPackage is blocked by policy, find the install directory directly
    $pkgDir = $null
    try {
        $pkgDir = Get-ChildItem 'C:\Program Files\WindowsApps' -Directory -Filter 'ohmyposh.cli_*' -ErrorAction Stop |
            Sort-Object LastWriteTime -Descending |
            Select-Object -First 1
    }
    catch {
        $pkgDir = $null
    }
    if ($pkgDir) {
        $p = Join-Path $pkgDir.FullName 'themes'
        if (Test-Path $p) { return $p }
    }

    # winget portable package
    $wingetPkg = Get-ChildItem (Join-Path $env:LOCALAPPDATA 'Microsoft\WinGet\Packages') -Directory -Filter 'JanDeDobbeleer.OhMyPosh*' -ErrorAction SilentlyContinue |
        Select-Object -First 1
    if ($wingetPkg) {
        $p = Join-Path $wingetPkg.FullName 'themes'
        if (Test-Path $p) { return $p }
    }

    # scoop
    $scoop = Join-Path $HOME 'scoop\apps\oh-my-posh\current\themes'
    if (Test-Path $scoop) { return $scoop }

    return $null
}

$ompThemes = Get-OmpThemesDir
$ompThemes
Get-ChildItem $ompThemes -Filter *.omp.json |
    ForEach-Object { $_.Name -replace '\.omp\.json$', '' }

The last line will list more than a hundred theme names (catppuccin_mocha, tokyonight_storm, atomic…).

If Get-OmpThemesDir returns empty: run Get-AppxPackage ohmyposh.cli | Select-Object InstallLocation in a normal (non-admin is fine) PowerShell, and manually append \themes to the output path.

5.4 First step: copy all themes to your own directory

Do not directly reference the installation directory — MSIX upgrades change the version number in the path, and the next startup won't find the theme. Copy all themes out, keeping the original file names:

$configDir = "$HOME\.config\oh-my-posh"
New-Item -ItemType Directory -Path $configDir -Force | Out-Null

Copy-Item "$ompThemes\*.omp.json" -Destination $configDir -Force
(Get-ChildItem $configDir -Filter *.omp.json).Count

This way each theme keeps its original name, and you can switch by name later without overwriting one file repeatedly. Upgrading Oh My Posh also won't affect this copy.

Re-running this step will overwrite same-named themes with the version from the installation directory; if you've modified a theme, back it up first, or only copy the needed files.

You can also keep only a few themes; just copy the needed .omp.json files into it; the following is described assuming you copy all.

5.5 Initialize

First write the current theme name:

Set-Content "$HOME\.config\oh-my-posh\active-theme.txt" 'catppuccin_mocha' -Encoding utf8

Then write in $PROFILE:

$ompThemeDir = "$HOME\.config\oh-my-posh"
$ompThemeState = Join-Path $ompThemeDir 'active-theme.txt'

$ompThemeName = if (Test-Path $ompThemeState) {
    (Get-Content $ompThemeState -Raw).Trim()
}
else {
    'catppuccin_mocha'
}

$ompTheme = Join-Path $ompThemeDir "$ompThemeName.omp.json"

if (-not (Test-Path $ompTheme)) {
    $ompTheme = Join-Path $ompThemeDir 'catppuccin_mocha.omp.json'
}

if ((Get-Command oh-my-posh -ErrorAction SilentlyContinue) -and (Test-Path $ompTheme)) {
    oh-my-posh init pwsh --config $ompTheme | Invoke-Expression
}

After saving, execute . $PROFILE, the prompt immediately changes. From then on, every time you open a new tab, the profile reads active-theme.txt and automatically loads the current theme.

If you haven't copied themes yet and just want to see the default effect:

oh-my-posh init pwsh | Invoke-Expression

If you get oh-my-posh is not recognized as an internal or external command: PATH hasn't refreshed. Close all terminals and reopen; if still not working, manually add:

$env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')

5.6 Pick a theme

Newer versions of the init script may no longer provide Get-PoshThemes; if your version still has this command, you can also use it directly. First list all themes:

Get-ChildItem "$HOME\.config\oh-my-posh" -Filter *.omp.json |
    ForEach-Object { $_.Name -replace '\.omp\.json$', '' }

To preview a single theme (without switching):

function Show-OmpTheme {
    param([Parameter(Mandatory)][string]$Name)

    $dir = Get-OmpThemesDir
    if (-not $dir) {
        "First execute Get-OmpThemesDir from section 5.3, confirm you can find the theme directory"
        return
    }

    $file = Join-Path $dir "$Name.omp.json"
    if (Test-Path $file) {
        oh-my-posh print primary --config $file
    }
    else {
        "No such theme: $Name"
    }
}

Show-OmpTheme catppuccin_mocha
Show-OmpTheme tokyonight_storm

A few well-reviewed ones (theme name is filename without .omp.json):

Theme Style
jandedobbeleer Default, complete info, balanced
catppuccin_mocha Perfect match with this text's color scheme, soft
tokyonight_storm Blue-purple neon, tech feel
atomic Simple two-segment, fast
clean-detailed Minimalist, only path and Git
powerlevel10k_rainbow p10k-like, flashy
montys Colorful blocks, highly recognizable

Switch themes with poshtheme. Put the following two functions into $PROFILE (the Chapter 8 template already includes them):

function poshthemes {
    $dir = "$HOME\.config\oh-my-posh"
    $state = Join-Path $dir 'active-theme.txt'
    $active = if (Test-Path $state) { (Get-Content $state -Raw).Trim() } else { '' }

    Get-ChildItem $dir -Filter *.omp.json |
        ForEach-Object {
            $name = $_.Name -replace '\.omp\.json$', ''
            [pscustomobject]@{
                Active = if ($name -eq $active) { '*' } else { '' }
                Name   = $name
            }
        } |
        Sort-Object Name
}

function poshtheme {
    param([Parameter(Position = 0)][string]$Name)

    $dir = "$HOME\.config\oh-my-posh"
    $state = Join-Path $dir 'active-theme.txt'

    if (-not $Name) {
        $current = if (Test-Path $state) { (Get-Content $state -Raw).Trim() } else { '(not set)' }
        "Current theme: $current"
        "Usage: poshtheme <theme name>"
        "View all: poshthemes"
        return
    }

    $file = Join-Path $dir "$Name.omp.json"
    if (-not (Test-Path $file)) {
        Write-Warning "No such theme: $Name"
        return
    }

    Set-Content -Path $state -Value $Name -Encoding utf8
    Remove-Module oh-my-posh-core -Force -ErrorAction SilentlyContinue
    $global:_ompInitialized = $false
    oh-my-posh init pwsh --config $file | Invoke-Expression
    Write-Host "Switched theme: $Name" -ForegroundColor Green
}

Usage:

poshthemes                  # list all, * is current
poshtheme tokyonight_storm  # switch
poshtheme catppuccin_mocha  # switch back
poshtheme                   # current theme

poshtheme writes the name into active-theme.txt and reinitializes the current session; new tabs also read this file.

If the prompt doesn't change after switching: . $PROFILE or reopen the tab. Some OMP versions have different module names, auto-reload may fail, but the theme name is already written; reopening will definitely take effect.

5.7 Custom theme

Themes are placed under $HOME\.config\oh-my-posh with original names. To modify the current theme:

$name = (Get-Content "$HOME\.config\oh-my-posh\active-theme.txt" -Raw).Trim()
code "$HOME\.config\oh-my-posh\$name.omp.json"   # if no VS Code, use notepad

Or directly modify any file, for example:

code "$HOME\.config\oh-my-posh\catppuccin_mocha.omp.json"

A minimal usable theme looks like this (newer v4 syntax):

{
  "version": 4,
  "final_space": true,
  "blocks": [
    {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "path",
          "style": "powerline",
          "powerline_symbol": "\ue0b0",
          "foreground": "#1e1e2e",
          "background": "#89b4fa",
          "options": { "style": "folder", "max_depth": 3 }
        },
        {
          "type": "git",
          "style": "powerline",
          "powerline_symbol": "\ue0b0",
          "foreground": "#1e1e2e",
          "background": "#a6e3a1",
          "options": { "branch_icon": "\ue725 " }
        },
        {
          "type": "executiontime",
          "style": "plain",
          "foreground": "#6c7086",
          "template": " {{ .FormattedMs }}"
        },
        {
          "type": "text",
          "style": "plain",
          "foreground": "#89b4fa",
          "template": "\u276f"
        }
      ]
    }
  ]
}

Version differences: old themes are "version": 3 + "properties"; newer versions default export "version": 4 + "options". Both load fine, new configs are advised to use v4.

Common options:

{
  "style": "folder",
  "max_depth": 3,
  "fetch_status": false,
  "branch_max_length": 25,
  "display_mode": "directory"
}

To make colors maintainable, add palette at the top of the theme, then write colors as p:blue:

"palette": {
  "blue": "#89B4FA",
  "green": "#A6E3A1",
  "text": "#CDD6F4"
}

After saving, poshtheme <theme name> or reopen a tab to see the effect.

5.8 Upgrade and uninstall

winget upgrade --id JanDeDobbeleer.OhMyPosh -e
winget uninstall --id JanDeDobbeleer.OhMyPosh -e

5.9 Performance

Oh My Posh executes once per prompt, and on large Git repositories may lag (100ms+ can be felt).

oh-my-posh debug

It prints the execution time of each segment. Optimization methods:

  1. Turn off fetch_status (most effective)
  2. Fewer language version segments
  3. In large repositories use lightweight themes like clean-detailed
  4. Still slow → switch to Starship

6. Step 4: PSReadLine completion and prediction

PSReadLine is PowerShell's "line editor", responsible for syntax highlighting, history, completion, prediction. PowerShell 7 has it built-in, generally no need to install separately.

6.1 Must-enable configuration

Write into profile:

Set-PSReadLineOption -EditMode Windows
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineOption -PredictionViewStyle ListView
Set-PSReadLineOption -HistorySearchCursorMovesToEnd
Set-PSReadLineOption -HistoryNoDuplicates
Set-PSReadLineOption -MaximumHistoryCount 20000

Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward

If the PredictionViewStyle ListView line reports an error, it means PSReadLine version is old; delete that line, the rest is unaffected.

Effects:

6.2 Optional: syntax highlight colors

Default colors are fine on dark backgrounds, but to unify with Catppuccin you can add this (if it doesn't work, delete it, other functions unaffected):

Set-PSReadLineOption -Colors @{
    Command          = "`e[38;2;137;180;250m"
    Parameter        = "`e[38;2;249;226;175m"
    Operator         = "`e[38;2;148;226;213m"
    Variable         = "`e[38;2;245;194;231m"
    String           = "`e[38;2;166;227;161m"
    Number           = "`e[38;2;250;179;135m"
    Type             = "`e[38;2;249;226;175m"
    Comment          = "`e[38;2;108;112;134m"
    Keyword          = "`e[38;2;203;166;247m"
    Error            = "`e[38;2;243;139;168m"
    InlinePrediction = "`e[38;2;108;112;134m"
}

6.3 Plugin prediction (more accurate)

By default it predicts only history. After installing CompletionPredictor, it can predict parameters from module completion results:

Install-Module CompletionPredictor -Scope CurrentUser -Force

In profile:

Import-Module CompletionPredictor -ErrorAction SilentlyContinue

The Plugin in PredictionSource will then be enabled automatically.

6.4 Key table

Key Function
→ / End Accept inline prediction
Tab Open completion menu / next in menu
Shift + Tab Previous in completion menu
↑ / ↓ Prefix history search
Ctrl + R Reverse search history (fuzzy after PSFzf)
Ctrl + L Clear screen (keep current input)
Ctrl + C Cancel current line
F2 Switch prediction view (needs manual binding)

To bind F2 to view switching:

Set-PSReadLineKeyHandler -Key F2 -Function SwitchPredictionView

7. Step 5: Efficiency tools family bucket

These are not "looks good", but after installing them your terminal is truly usable. All optional, install as needed.

Tool Replaces/enhances Function winget ID
Terminal-Icons ls Files and folders show icons PSGallery module
zoxide cd Smart jump, z proj goes straight to usual directory ajeetdsouza.zoxide
fzf Ctrl+R Fuzzy search history/files junegunn.fzf
PSFzf — fzf and PSReadLine integration PSGallery module
posh-git — Git branch/command Tab completion PSGallery module
ConsoleGuiTools — Out-ConsoleGridView interactive table selection PSGallery module
PSScriptAnalyzer — PowerShell script static check PSGallery module
bat cat Syntax highlighting + line numbers sharkdp.bat
eza ls Color, icons, Git status, tree eza-community.eza
ripgrep grep Much faster recursive search BurntSushi.ripgrep.MSVC
fd find Friendlier file search sharkdp.fd
delta git diff Side-by-side diff, syntax highlighting dandavison.delta
fastfetch systeminfo Show system info at startup Fastfetch-cli.Fastfetch
gsudo — Linux-like sudo gerardog.gsudo

7.1 One-time installation

$apps = @(
    'ajeetdsouza.zoxide',
    'junegunn.fzf',
    'sharkdp.bat',
    'eza-community.eza',
    'BurntSushi.ripgrep.MSVC',
    'sharkdp.fd',
    'dandavison.delta',
    'Fastfetch-cli.Fastfetch',
    'gerardog.gsudo'
)

foreach ($id in $apps) {
    winget install --id $id -e --source winget --accept-package-agreements --accept-source-agreements
}

PowerShell modules:

Install-Module Terminal-Icons, PSFzf, CompletionPredictor, posh-git, Microsoft.PowerShell.ConsoleGuiTools, PSScriptAnalyzer -Scope CurrentUser -Force -AllowClobber

The first Install-Module may prompt to install the NuGet provider, press Y. If it reports "untrusted repository", first execute Set-PSRepository PSGallery -InstallationPolicy Trusted, or press Y at the prompt.

7.2 How to use each tool

Terminal-Icons: after install, import it, ls automatically gets icons:

Import-Module Terminal-Icons

zoxide: remembers directories you've visited, jumps by frequency:

zoxide init powershell | Out-String | Invoke-Expression   # write into profile
z proj          # jump to any common directory whose name contains proj
z -             # go back to last directory
zi              # interactive selection

Advanced: zoxide init powershell --cmd cd makes cd itself support fuzzy jumping.

fzf + PSFzf:

Ctrl + R   # fuzzy search command history
Ctrl + T   # fuzzy select a file under current directory, insert into command line

posh-git: adds Tab completion for commands like git checkout, git branch (branch names, remote names), doesn't take over the prompt.

git checkout feat<Tab>   # complete branch name

ConsoleGuiTools: Get-Process | Out-ConsoleGridView, filter, sort, multi-select objects in a table.

PSScriptAnalyzer: Invoke-ScriptAnalyzer -Path .\script.ps1, checks scripts for common issues.

bat:

bat README.md
bat --list-themes        # see available themes

To use bat instead of cat by default: Set-Alias -Name cat -Value bat -Force (bat automatically falls back to plain text when piping, so it won't pollute scripts).

eza:

eza -la --group-directories-first --icons
eza --tree --level=2 --icons

ripgrep / fd:

rg "TODO" -n
fd "\.ps1$"

delta: configure to ~/.gitconfig:

[core]
    pager = delta

[interactive]
    diffFilter = delta --color-only

[delta]
    navigate = true
    line-numbers = true
    side-by-side = false
    syntax-theme = Catppuccin Mocha

[merge]
    conflictstyle = zdiff3

If syntax-theme errors, execute bat --list-themes to change to an existing name, e.g., Monokai Extended.

If git diff doesn't seem to use delta: run git var GIT_PAGER, should be delta. If it outputs cat, the environment variable GIT_PAGER overrides core.pager, execute Remove-Item Env:GIT_PAGER or clear it in profile. Git only enables pager in interactive terminals; redirected output won't go through delta.

fastfetch:

fastfetch
fastfetch --gen-config     # generate config file, path is in output

Config file at ~\.config\fastfetch\config.jsonc (fastfetch --gen-config prints actual path).

This color scheme is based on Tokyo Night's blue/purple/cyan; to change colors, modify display.color and logo.color.

gsudo:

gsudo Get-Service   # elevate a single command, pops UAC
sudo ...            # Windows 11 24H2+ has built-in sudo, can be enabled in Settings → System → Developer options

8. Step 6: Complete profile template

Copy the entire block below into $PROFILE (first New-Item -ItemType File -Path $PROFILE -Force, then code $PROFILE or notepad $PROFILE).

It already has existence checks: uninstalled tools are automatically skipped, no errors.

This is the minimal usable version. If you need Git shortcut commands, system utility functions, theme switching, etc., you can extend based on this template.

# ============================================================
#  PowerShell 7 terminal beautification configuration
#  Location: %USERPROFILE%\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
#  After editing, run: . $PROFILE   or reopen a tab
# ============================================================

# ---------- 0. UTF-8 (fix Chinese garbled text) ----------
$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)

# ---------- 1. PSReadLine: prediction, history, completion ----------
if (Get-Module -ListAvailable -Name PSReadLine) {
    try {
        Set-PSReadLineOption -EditMode Windows
        Set-PSReadLineOption -PredictionSource HistoryAndPlugin
        Set-PSReadLineOption -PredictionViewStyle ListView
        Set-PSReadLineOption -HistorySearchCursorMovesToEnd
        Set-PSReadLineOption -HistoryNoDuplicates
        Set-PSReadLineOption -MaximumHistoryCount 20000

        Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
        Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
        Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
    }
    catch {
        # A few hosts that don't support virtual terminals error here, skip
    }
}

# ---------- 2. Modules ----------
Import-Module Terminal-Icons -ErrorAction SilentlyContinue
Import-Module CompletionPredictor -ErrorAction SilentlyContinue

# posh-git: Git branch/command Tab completion (doesn't take over prompt)
Import-Module posh-git -ErrorAction SilentlyContinue

if ((Get-Module -ListAvailable -Name PSFzf) -and (Get-Command fzf -ErrorAction SilentlyContinue)) {
    Import-Module PSFzf
    Set-PsFzfOption -PSReadlineChordProvider 'Ctrl+t' -PSReadlineChordReverseHistory 'Ctrl+r'
}

# ---------- 3. zoxide ----------
if (Get-Command zoxide -ErrorAction SilentlyContinue) {
    zoxide init powershell | Out-String | Invoke-Expression
}

# ---------- 4. Aliases and small functions ----------
function ll {
    Get-ChildItem -Force @args
}

function la {
    Get-ChildItem -Force @args
}

function .. {
    Set-Location ..
}

function ... {
    Set-Location ../..
}

function mkcd {
    param(
        [Parameter(Mandatory)]
        [string]$Path
    )
    New-Item -ItemType Directory -Force -Path $Path | Out-Null
    Set-Location $Path
}

function reload {
    . $PROFILE
}

function myprofile {
    if (Get-Command code -ErrorAction SilentlyContinue) {
        code $PROFILE
    }
    else {
        notepad $PROFILE
    }
}

# eza exists, use eza to rewrite ll / lt
if (Get-Command eza -ErrorAction SilentlyContinue) {
    function ll {
        eza --long --all --group-directories-first --icons @args
    }
    function lt {
        eza --tree --level=2 --icons @args
    }
}

# bat exists, cat goes through bat
if (Get-Command bat -ErrorAction SilentlyContinue) {
    $env:BAT_THEME = 'Catppuccin Mocha'
    Set-Alias -Name cat -Value bat -Force
}

# ---------- 5. Theme switching ----------
function poshthemes {
    $dir = "$HOME\.config\oh-my-posh"
    $state = Join-Path $dir 'active-theme.txt'
    $active = if (Test-Path $state) { (Get-Content $state -Raw).Trim() } else { '' }

    Get-ChildItem $dir -Filter *.omp.json |
        ForEach-Object {
            $name = $_.Name -replace '\.omp\.json$', ''
            [pscustomobject]@{
                Active = if ($name -eq $active) { '*' } else { '' }
                Name   = $name
            }
        } |
        Sort-Object Name
}

function poshtheme {
    param([Parameter(Position = 0)][string]$Name)

    $dir = "$HOME\.config\oh-my-posh"
    $state = Join-Path $dir 'active-theme.txt'

    if (-not $Name) {
        $current = if (Test-Path $state) { (Get-Content $state -Raw).Trim() } else { '(not set)' }
        "Current theme: $current"
        "Usage: poshtheme <theme name>"
        "View all: poshthemes"
        return
    }

    $file = Join-Path $dir "$Name.omp.json"
    if (-not (Test-Path $file)) {
        Write-Warning "No such theme: $Name"
        return
    }

    Set-Content -Path $state -Value $Name -Encoding utf8
    Remove-Module oh-my-posh-core -Force -ErrorAction SilentlyContinue
    $global:_ompInitialized = $false
    oh-my-posh init pwsh --config $file | Invoke-Expression
    Write-Host "Switched theme: $Name" -ForegroundColor Green
}

# ---------- 6. Oh My Posh (placed last, overrides prompt) ----------
if (Get-Command oh-my-posh -ErrorAction SilentlyContinue) {
    $ompThemeDir = "$HOME\.config\oh-my-posh"
    $ompThemeState = Join-Path $ompThemeDir 'active-theme.txt'
    $ompThemeName = if (Test-Path $ompThemeState) { (Get-Content $ompThemeState -Raw).Trim() } else { 'catppuccin_mocha' }
    $ompTheme = Join-Path $ompThemeDir "$ompThemeName.omp.json"

    if (-not (Test-Path $ompTheme)) {
        $ompTheme = Join-Path $ompThemeDir 'catppuccin_mocha.omp.json'
    }

    try {
        if (Test-Path $ompTheme) {
            oh-my-posh init pwsh --config $ompTheme | Invoke-Expression
        }
        else {
            # haven't copied themes yet, fall back to Oh My Posh default config
            oh-my-posh init pwsh | Invoke-Expression
        }
    }
    catch {
        # prompt load failure should not affect Shell startup
    }
}

8.1 Save and apply

. $PROFILE

Or use the quick function from the template (after new session takes effect): reload.

If there are errors, first look at the error message to locate the line; temporarily bypass profile startup with:

pwsh -NoProfile

8.2 If you use VS Code

VS Code's integrated terminal defaults to Windows PowerShell 5.1, and the font is set independently. In settings.json add:

"terminal.integrated.defaultProfile.windows": "PowerShell",
"terminal.integrated.fontFamily": "Maple Mono NF CN",
"terminal.integrated.fontSize": 13

9. Step 7: Unified color scheme

The key to visual unity: terminal background color, Oh My Posh theme, bat theme, delta theme, PSReadLine highlighting use the same palette.

Catppuccin Mocha family bucket:

Component Setting
Windows Terminal colorScheme: "Catppuccin Mocha" or "Tokyo Night Storm" (section 3.5)
Windows Terminal UI root-level "theme" select same-named UI theme, controls tab bar/title bar
Oh My Posh poshtheme catppuccin_mocha / poshtheme tokyonight_storm
bat $env:BAT_THEME = 'Catppuccin Mocha'
delta syntax-theme = Catppuccin Mocha
PSReadLine RGB colors from section 6.2

Tokyo Night users: WT select Tokyo Night Storm, OMP use poshtheme tokyonight_storm; if bat/delta don't have a matching theme, keep Catppuccin or OneHalfDark.

bat / delta theme names must actually exist, check with bat --list-themes. If Catppuccin isn't found, bat version is old, winget upgrade sharkdp.bat will fix it.


10. Advanced play

10.1 Oh My Posh vs Starship, how to choose

Oh My Posh Starship
Config format JSON TOML
Theme count 100+ ready-made few but refined, you assemble
Speed medium faster
Getting started install and use need to write config
Cross-shell all platforms all platforms

Suggestion: if you want "install and look good" use Oh My Posh; if you pursue minimalism and speed use Starship.

Starship install:

winget install --id Starship.Starship -e

Profile:

Invoke-Expression (&starship init powershell)

Config: $HOME\.config\starship.toml, official presets at https://starship.rs/presets/.

Don't initialize both at the same time, or the prompts will conflict.

10.2 Add color and icons to Git

Oh My Posh's git segment automatically reads repository status, no extra config needed. For more detail you can add:

{
  "type": "git",
  "style": "powerline",
  "powerline_symbol": "\ue0b0",
  "foreground": "#1e1e2e",
  "background": "#a6e3a1",
  "options": {
    "branch_icon": "\ue725 ",
    "fetch_status": true,
    "fetch_upstream_icon": true
  }
}

fetch_status: true shows +3 ~2 -1 (added/modified/deleted), but large repositories become slower.

10.3 SSH to Linux, want the same style

Oh My Posh supports remote; a simpler approach is install Starship on the remote, local terminal only handles rendering. Font icons are rendered locally, so having Nerd Font locally is enough.

10.4 Chinese alignment: don't rely on font fallback

Windows Terminal's font fallback is automatic: when the current font lacks a glyph, the system temporarily finds another font to fill it. There is no reliable configuration option, and width can't be controlled.

The result: using Cascadia Code with Chinese, characters fall back to Microsoft YaHei — proportional font, misaligned with English monospaced grid, tables, eza columns, progress bars all skew.

The only reliable solution is to choose a monospaced font that includes Chinese (Maple Mono NF CN, Sarasa Term SC Nerd Font), rather than configuring fallback.

10.5 Use Windows Terminal Preview

To experience new features first (command palette enhancements, new renderer):

winget install --id Microsoft.WindowsTerminal.Preview -e

Preview and stable can coexist, configs are independent.


11. Troubleshooting manual

11.1 Full of boxes / question marks

Cause: font not installed, not selected correctly, or name wrong. Check:

"`u{e0b0} `u{e725} `u{f07b}"

Still boxes → install Nerd Font; icons fine but some OMP icons are boxes → the theme uses private-use area characters not in the font, switch theme.

11.2 Chinese garbled / width misaligned

11.3 Prompt didn't change

Check in order:

  1. Is it PowerShell 7? $PSVersionTable.PSVersion
  2. Is the profile path correct? $PROFILE, does the file exist?
  3. Are there errors in the profile? pwsh -NoProfile starts fine, means it's a profile issue.
  4. Is the OMP initialization line at the end of the profile? Overwritten by later code?
  5. Did you run . $PROFILE after editing?

11.4 "Cannot load file because running scripts is disabled on this system"

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

11.5 oh-my-posh command not found

PATH hasn't refreshed. Close all terminals and reopen; or temporarily add PATH:

$env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')

11.6 Startup noticeably slower

oh-my-posh debug

See which segment takes time. Most common is Git's fetch_status. To compare, start a session without profile using pwsh -NoProfile.

11.7 winget errors

winget source reset --force
winget source update

Still not working, update "App Installer" from Microsoft Store.

11.8 Settings saved but terminal won't open / crashes

settings.json JSON syntax error. Restore backup:

$wt = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
Copy-Item "$wt.bak" $wt -Force

Common syntax errors: extra comma, missing quote, path not escaped (backslash must be doubled).

11.9 VS Code terminal shows boxes for icons

VS Code's terminal font must be set separately in terminal.integrated.fontFamily, doesn't follow Windows Terminal.

11.10 Installed Oh My Posh but Git icon doesn't show


12. Rollback and uninstall

12.1 Rollback config only

# back up/clear entire profile
Copy-Item $PROFILE "$PROFILE.bak" -Force
Set-Content $PROFILE -Value '' -Encoding utf8

# Windows Terminal
$wt = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
Copy-Item "$wt.bak" $wt -Force

12.2 Uninstall software

$ids = @(
  'JanDeDobbeleer.OhMyPosh','ajeetdsouza.zoxide','junegunn.fzf','sharkdp.bat',
  'eza-community.eza','BurntSushi.ripgrep.MSVC','sharkdp.fd','dandavison.delta',
  'Fastfetch-cli.Fastfetch','gerardog.gsudo'
)
foreach ($id in $ids) { winget uninstall --id $id -e }

Modules:

Uninstall-Module Terminal-Icons, PSFzf, CompletionPredictor, posh-git, Microsoft.PowerShell.ConsoleGuiTools, PSScriptAnalyzer -AllVersions -Force

12.3 Delete fonts

Settings → Personalization → Fonts → search font name → uninstall (only works for fonts installed for current user).

Or manually delete registry key + file:

# first confirm what to delete!
Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts' |
    Select-Object -Property *Maple* | Format-List

Deleting fonts is risky, recommend using the settings interface.


Appendix A: Solidify configuration into a script (optional)

If you often configure new machines, you can write the steps into a PowerShell script. Suggested order:

  1. Check winget, PowerShell 7, Windows Terminal
  2. Use winget to install Oh My Posh, Git, common tools
  3. Install PowerShell modules
  4. Install Nerd Font: download font package, or call oh-my-posh font install
  5. Copy OMP themes to ~\.config\oh-my-posh
  6. Write profile (use marker blocks for later replacement)
  7. Merge Windows Terminal's settings.json (backup first)
  8. Write ~\.gitconfig

Several key points:

This way even if a step fails, you can roll back and re-run.


Appendix B: Command cheat sheet

# reload config
. $PROFILE

# list themes / switch theme
poshthemes
poshtheme tokyonight_storm

# preview current theme
$name = (Get-Content "$HOME\.config\oh-my-posh\active-theme.txt" -Raw).Trim()
oh-my-posh print primary --config "$HOME\.config\oh-my-posh\$name.omp.json"

# current profile path
$PROFILE

# verify font
"`u{e0b0} `u{e725} `u{f07b}"

# test OMP performance
oh-my-posh debug

# update all software
winget upgrade --all --include-unknown

# open WT settings JSON
code "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"

Last sentence

The end goal of terminal beautification is not "how many plugins installed", but you feel good when opening the terminal, and your hands aren't tired when typing commands. If one day it feels too fancy, clear the profile, run poshtheme clean-detailed, you can always start over — all configs are plain text, delete them and it's gone, nothing breaks.

Hope this tutorial helps you build a comfortable terminal.