Skip to content

Instantly share code, notes, and snippets.

@michaelsanford
Last active May 11, 2026 20:38
Show Gist options
  • Select an option

  • Save michaelsanford/a8c06cac51da47d03f9d6f0f6d05252f to your computer and use it in GitHub Desktop.

Select an option

Save michaelsanford/a8c06cac51da47d03f9d6f0f6d05252f to your computer and use it in GitHub Desktop.
Terminal Settings
{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"secondary_prompt": {
"template": "❯❯ ",
"foreground": "#16c60c"
},
"transient_prompt": {
"template": "",
"foreground": "#16c60c"
},
"console_title_template": "{{ .Shell }} in {{ .Folder }}",
"blocks": [
{
"alignment": "left",
"segments": [
{
"background": "#0077c2",
"foreground": "#ffffff",
"leading_diamond": "\u256d\u2500\ue0b6",
"style": "diamond",
"template": " {{ if or (eq .Name \"pwsh\") (eq .Name \"powershell\") }}\ue70f{{ else if eq .Env.WSL_DISTRO_NAME \"kali-linux\" }}\ue77f{{ else if eq .Name \"zsh\" }}\uf489{{ else }}\uf120{{ end }} ",
"type": "shell"
},
{
"background": "#16a085",
"foreground": "#ffffff",
"powerline_symbol": "\ue0b0",
"style": "powerline",
"template": " {{ .HostName }} ",
"type": "session"
},
{
"background": "#ef5350",
"foreground": "#FFFB38",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"template": " \uf292 ADMIN ",
"type": "root"
},
{
"background": "#91b4f7",
"foreground": "#2d3436",
"powerline_symbol": "\ue0b0",
"options": {
"folder_icon": " \uf07b ",
"home_icon": "\ue617",
"style": "full"
},
"style": "powerline",
"template": " \uf07b {{ .Path }} ",
"type": "path"
},
{
"background": "#ffeb95",
"background_templates": [
"{{ if or (.Working.Changed) (.Staging.Changed) }}#ffeb95{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#c5e478{{ end }}",
"{{ if gt .Ahead 0 }}#C792EA{{ end }}",
"{{ if gt .Behind 0 }}#C792EA{{ end }}"
],
"foreground": "#011627",
"powerline_symbol": "\ue0b0",
"options": {
"branch_icon": "\ue725 ",
"fetch_status": true,
"fetch_upstream_icon": true
},
"style": "powerline",
"template": " {{ .UpstreamIcon }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} \uf044 {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }}<#ef5350> \uf046 {{ .Staging.String }}</>{{ end }}{{ if gt .StashCount 0 }} \ueb4b {{ .StashCount }}{{ end }} ",
"type": "git"
},
{
"background": "#24292e",
"background_templates": [
"{{ if eq .Env.GH_ACTIONS_STATUS \"success\" }}#4caf50{{ end }}",
"{{ if or (eq .Env.GH_ACTIONS_STATUS \"failure\") (eq .Env.GH_ACTIONS_STATUS \"startup_failure\") (eq .Env.GH_ACTIONS_STATUS \"timed_out\") }}#ef5350{{ end }}",
"{{ if or (eq .Env.GH_ACTIONS_STATUS \"in_progress\") (eq .Env.GH_ACTIONS_STATUS \"queued\") (eq .Env.GH_ACTIONS_STATUS \"waiting\") (eq .Env.GH_ACTIONS_STATUS \"action_required\") (eq .Env.GH_ACTIONS_STATUS \"requested\") (eq .Env.GH_ACTIONS_STATUS \"pending\") }}#f5a623{{ end }}",
"{{ if or (eq .Env.GH_ACTIONS_STATUS \"cancelled\") (eq .Env.GH_ACTIONS_STATUS \"neutral\") (eq .Env.GH_ACTIONS_STATUS \"skipped\") (eq .Env.GH_ACTIONS_STATUS \"stale\") }}#78909c{{ end }}"
],
"foreground": "#ffffff",
"powerline_symbol": "",
"style": "powerline",
"template": "{{ if .Env.GH_ACTIONS_DISPLAY }}  {{ .Env.GH_ACTIONS_DISPLAY }} {{ end }}",
"type": "text"
},
{
"background": "#5f6a7a",
"foreground": "#faa029",
"powerline_symbol": "\ue0b0",
"style": "powerline",
"template": " \ue7ad {{.Profile}}{{if .Region}}@{{.Region}}{{end}} ",
"type": "aws"
}
],
"type": "prompt"
},
{
"alignment": "right",
"segments": [
{
"background": "#83769c",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"options": {
"style": "roundrock",
"threshold": 0
},
"style": "diamond",
"template": " \ueba2 {{ .FormattedMs }} ",
"type": "executiontime"
},
{
"background": "#303030",
"foreground": "#3C873A",
"leading_diamond": "\ue0b6",
"options": {
"fetch_package_manager": true,
"npm_icon": " <#cc3a3a>\ue5fa</> ",
"yarn_icon": " <#348cba>\ue6a7</>"
},
"style": "diamond",
"template": "\ue718 {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }}",
"trailing_diamond": "\ue0b4 ",
"type": "node"
},
{
"background": "#306998",
"foreground": "#FFE873",
"leading_diamond": "\ue0b6",
"style": "diamond",
"template": "\ue235 {{ if .Error }}{{ .Error }}{{ else }}{{ if .Venv }}{{ .Venv }} {{ end }}{{ .Full }}{{ end }}",
"trailing_diamond": "\ue0b4 ",
"type": "python"
},
{
"background": "#316ce4",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"style": "diamond",
"template": "\uf308 {{.Context}}{{if .Namespace}} :: {{.Namespace}}{{end}}",
"trailing_diamond": "\ue0b4 ",
"type": "kubectl"
},
{
"background": "#4ecdc4",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"options": {
"precision": 2
},
"style": "diamond",
"template": " \ue266 {{ (div ((sub .PhysicalTotalMemory .PhysicalAvailableMemory)|float64) 1073741824.0) }}/{{ (div .PhysicalTotalMemory 1073741824.0) }}GB",
"trailing_diamond": "\ue0b4 ",
"type": "sysinfo"
},
{
"background": "#f36943",
"background_templates": [
"{{if eq \"Charging\" .State.String}}#40c4ff{{end}}",
"{{if eq \"Discharging\" .State.String}}#ff5722{{end}}",
"{{if eq \"Full\" .State.String}}#4caf50{{end}}"
],
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"style": "diamond",
"template": " {{ if not .Error }}\uf240 {{ .Percentage }}{{ end }} ",
"trailing_diamond": "\ue0b4",
"type": "battery"
}
],
"type": "prompt"
},
{
"alignment": "left",
"newline": true,
"segments": [
{
"foreground": "#21c7c7",
"style": "plain",
"template": "\u2570\u2500",
"type": "text"
},
{
"foreground": "#16c60c",
"foreground_templates": ["{{ if gt .Code 0 }}#ef5350{{ end }}"],
"options": {
"always_enabled": true
},
"style": "plain",
"template": "",
"type": "status"
}
],
"type": "prompt"
}
],
"version": 3,
"final_space": true
}
# PSReadLine configuration
# - Visual styling
# - Bash/zsh-style editing chords
# - History-based prediction tuning
# Guard: do nothing if PSReadLine is unavailable (e.g., non-interactive hosts)
if (-not (Get-Module -ListAvailable -Name PSReadLine)) { return }
# Base options: prompt + colours
$PSROptions = @{
ContinuationPrompt = ' ' # Shown for wrapped / continued lines
Colors = @{
Operator = $PSStyle.Foreground.Magenta
Parameter = $PSStyle.Foreground.Magenta
Selection = $PSStyle.Background.BrightBlack
InLinePrediction = $PSStyle.Foreground.BrightYellow + $PSStyle.Background.BrightBlack
}
# Prediction and history behaviour
PredictionSource = 'History' # Use command history for suggestions
PredictionViewStyle = 'InlineView' # Show suggestions as a list [ InlineView | ListView ]
HistoryNoDuplicates = $true # Avoid duplicating identical commands
MaximumHistoryCount = 50000 # Retain up to 50 000 history entries
}
Set-PSReadLineOption @PSROptions
# Key bindings (bash/zsh-like)
# Ctrl+F: forward one word (note: default is usually "forward character")
Set-PSReadLineKeyHandler -Chord 'Ctrl+f' -Function ForwardWord
# Ctrl+W: delete the word to the left of the cursor
Set-PSReadLineKeyHandler -Chord 'Ctrl+w' -Function BackwardKillWord
# Alt+D: delete the word to the right of the cursor
Set-PSReadLineKeyHandler -Chord 'Alt+d' -Function KillWord
# Ctrl+U: delete from cursor to beginning of the line (bash/zsh kill-line-left)
Set-PSReadLineKeyHandler -Chord 'Ctrl+u' -Function BackwardDeleteLine
# Ctrl+D: if line is empty, run "exit"; otherwise delete character under cursor
Set-PSReadLineKeyHandler -Chord 'Ctrl+d' -ScriptBlock {
$line = $null
$cursor = 0
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
if ([string]::IsNullOrEmpty($line)) {
[Microsoft.PowerShell.PSConsoleReadLine]::Insert('exit')
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
} else {
[Microsoft.PowerShell.PSConsoleReadLine]::DeleteChar()
}
}
# Enter: validate syntax then accept the line (prevents executing incomplete input)
Set-PSReadLineKeyHandler -Chord 'Enter' -Function ValidateAndAcceptLine
function pip { py -m pip $args }
function k { wsl kiro-cli $args }
function ex { param($Path = '.') explorer $Path }
# Custom shell
# Update with
# winget upgrade JanDeDobbeleer.OhMyPosh --source winget
# oh-my-posh init pwsh --config 'https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/refs/heads/main/themes/rudolfs-light.omp.json' | Invoke-Expression
oh-my-posh init pwsh --config ~/.oh/flux-pills.json | Invoke-Expression
# GitHub Actions status for oh-my-posh (reads GH_ACTIONS_STATUS / GH_ACTIONS_DISPLAY env vars)
$script:_ghActionsCache = @{ RepoPath = $null; Status = ''; Display = ''; LastChecked = [DateTime]::MinValue }
function _Update-GHActionsStatus {
$repoPath = git rev-parse --show-toplevel 2>$null
if (-not $repoPath) {
$env:GH_ACTIONS_STATUS = ''; $env:GH_ACTIONS_DISPLAY = ''; return
}
$now = [DateTime]::UtcNow
$cache = $script:_ghActionsCache
if ($cache.RepoPath -eq $repoPath -and ($now - $cache.LastChecked).TotalSeconds -lt 60) {
$env:GH_ACTIONS_STATUS = $cache.Status; $env:GH_ACTIONS_DISPLAY = $cache.Display; return
}
if (-not (git remote -v 2>$null | Select-String 'github\.com')) {
$env:GH_ACTIONS_STATUS = ''; $env:GH_ACTIONS_DISPLAY = ''
$script:_ghActionsCache = @{ RepoPath = $repoPath; Status = ''; Display = ''; LastChecked = $now }
return
}
try {
$run = gh run list --limit 1 --json status,conclusion,workflowName 2>$null | ConvertFrom-Json | Select-Object -First 1
if ($run) {
$status = if ($run.conclusion) { $run.conclusion } else { $run.status }
$glyph = @{
success = [char]0xf00c
failure = [char]0xf00d
cancelled = [char]0xf05e
timed_out = [char]0xf017
action_required = [char]0xf071
startup_failure = [char]0xf0e7
neutral = [char]0xf068
skipped = [char]0xf051
stale = [char]0xf252
in_progress = [char]0xf013
queued = [char]0xf017
waiting = [char]0xf28b
requested = [char]0xf061
pending = [char]0xf10c
}[$status]
$display = "$($run.workflowName) · $(if ($glyph) { $glyph } else { $status })"
} else { $status = ''; $display = '' }
} catch { $status = ''; $display = '' }
$script:_ghActionsCache = @{ RepoPath = $repoPath; Status = $status; Display = $display; LastChecked = $now }
$env:GH_ACTIONS_STATUS = $status; $env:GH_ACTIONS_DISPLAY = $display
}
$_ompPrompt = $function:prompt
function prompt { _Update-GHActionsStatus; & $_ompPrompt }
# AWS Profile Switcher
if (-not (Get-Command sap -ErrorAction SilentlyContinue)) {
function sap { . "$env:LOCALAPPDATA\Scripts\Switch-AwsProfile.ps1" }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment