[{"data":1,"prerenderedAt":2778},["ShallowReactive",2],{"blog-cutting-powershell-startup-time-in-half":3,"blog-surround-cutting-powershell-startup-time-in-half":1597},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"body":11,"_type":1591,"_id":1592,"_source":1593,"_file":1594,"_stem":1595,"_extension":1596},"/blog/cutting-powershell-startup-time-in-half","blog",false,"","Cutting PowerShell startup time in half","How I brought pwsh startup from ~900ms down to ~440ms by caching init scripts and lazy-loading modules.","2026-04-05T16:30:00+07:00",{"type":12,"children":13,"toc":1582},"root",[14,22,29,43,101,106,157,162,177,182,188,200,497,502,569,574,580,591,881,886,892,919,1158,1170,1190,1196,1208,1447,1460,1466,1514,1519,1525,1571,1576],{"type":15,"tag":16,"props":17,"children":18},"element","p",{},[19],{"type":20,"value":21},"text","Every time I opened a new PowerShell tab in Windows Terminal, it felt sluggish. Not unbearable, but enough that I noticed the lag before my prompt appeared. I finally sat down to figure out what was eating all that time, and the fix turned out to be small changes that added up to roughly half a second saved on every single shell launch.",{"type":15,"tag":23,"props":24,"children":26},"h3",{"id":25},"measure-first-guess-later",[27],{"type":20,"value":28},"Measure first, guess later",{"type":15,"tag":16,"props":30,"children":31},{},[32,34,41],{"type":20,"value":33},"PowerShell has a built in ",{"type":15,"tag":35,"props":36,"children":38},"code",{"className":37},[],[39],{"type":20,"value":40},"Measure-Command",{"type":20,"value":42}," cmdlet that returns how long a script block takes to run. To benchmark a cold startup (profile loading included) from a running shell:",{"type":15,"tag":44,"props":45,"children":49},"pre",{"className":46,"code":47,"language":48,"meta":7,"style":7},"language-powershell shiki shiki-themes one-dark-pro","Measure-Command { pwsh -Command 'exit' } | Select-Object TotalMilliseconds\n","powershell",[50],{"type":15,"tag":35,"props":51,"children":52},{"__ignoreMap":7},[53],{"type":15,"tag":54,"props":55,"children":58},"span",{"class":56,"line":57},"line",1,[59,64,70,75,80,86,91,96],{"type":15,"tag":54,"props":60,"children":62},{"style":61},"--shiki-default:#56B6C2",[63],{"type":20,"value":40},{"type":15,"tag":54,"props":65,"children":67},{"style":66},"--shiki-default:#ABB2BF",[68],{"type":20,"value":69}," { pwsh ",{"type":15,"tag":54,"props":71,"children":72},{"style":61},[73],{"type":20,"value":74},"-",{"type":15,"tag":54,"props":76,"children":77},{"style":66},[78],{"type":20,"value":79},"Command ",{"type":15,"tag":54,"props":81,"children":83},{"style":82},"--shiki-default:#98C379",[84],{"type":20,"value":85},"'exit'",{"type":15,"tag":54,"props":87,"children":88},{"style":66},[89],{"type":20,"value":90}," } | ",{"type":15,"tag":54,"props":92,"children":93},{"style":61},[94],{"type":20,"value":95},"Select-Object",{"type":15,"tag":54,"props":97,"children":98},{"style":66},[99],{"type":20,"value":100}," TotalMilliseconds\n",{"type":15,"tag":16,"props":102,"children":103},{},[104],{"type":20,"value":105},"And to compare against a clean startup without your profile:",{"type":15,"tag":44,"props":107,"children":109},{"className":46,"code":108,"language":48,"meta":7,"style":7},"Measure-Command { pwsh -NoProfile -Command 'exit' } | Select-Object TotalMilliseconds\n",[110],{"type":15,"tag":35,"props":111,"children":112},{"__ignoreMap":7},[113],{"type":15,"tag":54,"props":114,"children":115},{"class":56,"line":57},[116,120,124,128,133,137,141,145,149,153],{"type":15,"tag":54,"props":117,"children":118},{"style":61},[119],{"type":20,"value":40},{"type":15,"tag":54,"props":121,"children":122},{"style":66},[123],{"type":20,"value":69},{"type":15,"tag":54,"props":125,"children":126},{"style":61},[127],{"type":20,"value":74},{"type":15,"tag":54,"props":129,"children":130},{"style":66},[131],{"type":20,"value":132},"NoProfile ",{"type":15,"tag":54,"props":134,"children":135},{"style":61},[136],{"type":20,"value":74},{"type":15,"tag":54,"props":138,"children":139},{"style":66},[140],{"type":20,"value":79},{"type":15,"tag":54,"props":142,"children":143},{"style":82},[144],{"type":20,"value":85},{"type":15,"tag":54,"props":146,"children":147},{"style":66},[148],{"type":20,"value":90},{"type":15,"tag":54,"props":150,"children":151},{"style":61},[152],{"type":20,"value":95},{"type":15,"tag":54,"props":154,"children":155},{"style":66},[156],{"type":20,"value":100},{"type":15,"tag":16,"props":158,"children":159},{},[160],{"type":20,"value":161},"The difference is all profile overhead. Mine was:",{"type":15,"tag":163,"props":164,"children":165},"ul",{},[166,172],{"type":15,"tag":167,"props":168,"children":169},"li",{},[170],{"type":20,"value":171},"With profile: ~905ms",{"type":15,"tag":167,"props":173,"children":174},{},[175],{"type":20,"value":176},"Without profile: ~225ms",{"type":15,"tag":16,"props":178,"children":179},{},[180],{"type":20,"value":181},"So my profile was adding nearly 700ms. Time to find out where.",{"type":15,"tag":23,"props":183,"children":185},{"id":184},"finding-the-slow-parts",[186],{"type":20,"value":187},"Finding the slow parts",{"type":15,"tag":16,"props":189,"children":190},{},[191,193,198],{"type":20,"value":192},"I wrapped each suspicious line in the profile with ",{"type":15,"tag":35,"props":194,"children":196},{"className":195},[],[197],{"type":20,"value":40},{"type":20,"value":199}," and ran them one at a time in a fresh no-profile pwsh:",{"type":15,"tag":44,"props":201,"children":203},{"className":46,"code":202,"language":48,"meta":7,"style":7},"Write-Host 'oh-my-posh init: ' -NoNewline\n(Measure-Command {\n    (@(& 'C:\\path\\to\\oh-my-posh.exe' init pwsh --config='C:\\path\\to\\config.json' --print) -join \"`n\") | Invoke-Expression\n}).TotalMilliseconds\n\nWrite-Host 'Terminal-Icons import: ' -NoNewline\n(Measure-Command { Import-Module -Name Terminal-Icons }).TotalMilliseconds\n\nWrite-Host 'fnm env: ' -NoNewline\n(Measure-Command { fnm env --use-on-cd --shell powershell | Out-String | Invoke-Expression }).TotalMilliseconds\n",[204],{"type":15,"tag":35,"props":205,"children":206},{"__ignoreMap":7},[207,230,248,332,341,351,372,412,420,441],{"type":15,"tag":54,"props":208,"children":209},{"class":56,"line":57},[210,215,220,225],{"type":15,"tag":54,"props":211,"children":212},{"style":61},[213],{"type":20,"value":214},"Write-Host",{"type":15,"tag":54,"props":216,"children":217},{"style":82},[218],{"type":20,"value":219}," 'oh-my-posh init: '",{"type":15,"tag":54,"props":221,"children":222},{"style":61},[223],{"type":20,"value":224}," -",{"type":15,"tag":54,"props":226,"children":227},{"style":66},[228],{"type":20,"value":229},"NoNewline\n",{"type":15,"tag":54,"props":231,"children":233},{"class":56,"line":232},2,[234,239,243],{"type":15,"tag":54,"props":235,"children":236},{"style":66},[237],{"type":20,"value":238},"(",{"type":15,"tag":54,"props":240,"children":241},{"style":61},[242],{"type":20,"value":40},{"type":15,"tag":54,"props":244,"children":245},{"style":66},[246],{"type":20,"value":247}," {\n",{"type":15,"tag":54,"props":249,"children":251},{"class":56,"line":250},3,[252,257,263,268,273,278,283,288,293,298,303,308,313,318,322,327],{"type":15,"tag":54,"props":253,"children":254},{"style":66},[255],{"type":20,"value":256},"    (",{"type":15,"tag":54,"props":258,"children":260},{"style":259},"--shiki-default:#C678DD",[261],{"type":20,"value":262},"@",{"type":15,"tag":54,"props":264,"children":265},{"style":66},[266],{"type":20,"value":267},"(& ",{"type":15,"tag":54,"props":269,"children":270},{"style":82},[271],{"type":20,"value":272},"'C:\\path\\to\\oh-my-posh.exe'",{"type":15,"tag":54,"props":274,"children":275},{"style":66},[276],{"type":20,"value":277}," init pwsh ",{"type":15,"tag":54,"props":279,"children":280},{"style":61},[281],{"type":20,"value":282},"--",{"type":15,"tag":54,"props":284,"children":285},{"style":66},[286],{"type":20,"value":287},"config",{"type":15,"tag":54,"props":289,"children":290},{"style":61},[291],{"type":20,"value":292},"=",{"type":15,"tag":54,"props":294,"children":295},{"style":82},[296],{"type":20,"value":297},"'C:\\path\\to\\config.json'",{"type":15,"tag":54,"props":299,"children":300},{"style":61},[301],{"type":20,"value":302}," --",{"type":15,"tag":54,"props":304,"children":305},{"style":66},[306],{"type":20,"value":307},"print) -join ",{"type":15,"tag":54,"props":309,"children":310},{"style":82},[311],{"type":20,"value":312},"\"",{"type":15,"tag":54,"props":314,"children":315},{"style":61},[316],{"type":20,"value":317},"`n",{"type":15,"tag":54,"props":319,"children":320},{"style":82},[321],{"type":20,"value":312},{"type":15,"tag":54,"props":323,"children":324},{"style":66},[325],{"type":20,"value":326},") | ",{"type":15,"tag":54,"props":328,"children":329},{"style":61},[330],{"type":20,"value":331},"Invoke-Expression\n",{"type":15,"tag":54,"props":333,"children":335},{"class":56,"line":334},4,[336],{"type":15,"tag":54,"props":337,"children":338},{"style":66},[339],{"type":20,"value":340},"}).TotalMilliseconds\n",{"type":15,"tag":54,"props":342,"children":344},{"class":56,"line":343},5,[345],{"type":15,"tag":54,"props":346,"children":348},{"emptyLinePlaceholder":347},true,[349],{"type":20,"value":350},"\n",{"type":15,"tag":54,"props":352,"children":354},{"class":56,"line":353},6,[355,359,364,368],{"type":15,"tag":54,"props":356,"children":357},{"style":61},[358],{"type":20,"value":214},{"type":15,"tag":54,"props":360,"children":361},{"style":82},[362],{"type":20,"value":363}," 'Terminal-Icons import: '",{"type":15,"tag":54,"props":365,"children":366},{"style":61},[367],{"type":20,"value":224},{"type":15,"tag":54,"props":369,"children":370},{"style":66},[371],{"type":20,"value":229},{"type":15,"tag":54,"props":373,"children":375},{"class":56,"line":374},7,[376,380,384,389,394,398,403,407],{"type":15,"tag":54,"props":377,"children":378},{"style":66},[379],{"type":20,"value":238},{"type":15,"tag":54,"props":381,"children":382},{"style":61},[383],{"type":20,"value":40},{"type":15,"tag":54,"props":385,"children":386},{"style":66},[387],{"type":20,"value":388}," { ",{"type":15,"tag":54,"props":390,"children":391},{"style":61},[392],{"type":20,"value":393},"Import-Module",{"type":15,"tag":54,"props":395,"children":396},{"style":61},[397],{"type":20,"value":224},{"type":15,"tag":54,"props":399,"children":400},{"style":66},[401],{"type":20,"value":402},"Name Terminal",{"type":15,"tag":54,"props":404,"children":405},{"style":61},[406],{"type":20,"value":74},{"type":15,"tag":54,"props":408,"children":409},{"style":66},[410],{"type":20,"value":411},"Icons }).TotalMilliseconds\n",{"type":15,"tag":54,"props":413,"children":415},{"class":56,"line":414},8,[416],{"type":15,"tag":54,"props":417,"children":418},{"emptyLinePlaceholder":347},[419],{"type":20,"value":350},{"type":15,"tag":54,"props":421,"children":423},{"class":56,"line":422},9,[424,428,433,437],{"type":15,"tag":54,"props":425,"children":426},{"style":61},[427],{"type":20,"value":214},{"type":15,"tag":54,"props":429,"children":430},{"style":82},[431],{"type":20,"value":432}," 'fnm env: '",{"type":15,"tag":54,"props":434,"children":435},{"style":61},[436],{"type":20,"value":224},{"type":15,"tag":54,"props":438,"children":439},{"style":66},[440],{"type":20,"value":229},{"type":15,"tag":54,"props":442,"children":444},{"class":56,"line":443},10,[445,449,453,458,463,468,472,477,482,487,492],{"type":15,"tag":54,"props":446,"children":447},{"style":66},[448],{"type":20,"value":238},{"type":15,"tag":54,"props":450,"children":451},{"style":61},[452],{"type":20,"value":40},{"type":15,"tag":54,"props":454,"children":455},{"style":66},[456],{"type":20,"value":457}," { fnm env ",{"type":15,"tag":54,"props":459,"children":460},{"style":61},[461],{"type":20,"value":462},"--use-on-",{"type":15,"tag":54,"props":464,"children":465},{"style":66},[466],{"type":20,"value":467},"cd ",{"type":15,"tag":54,"props":469,"children":470},{"style":61},[471],{"type":20,"value":282},{"type":15,"tag":54,"props":473,"children":474},{"style":66},[475],{"type":20,"value":476},"shell powershell | ",{"type":15,"tag":54,"props":478,"children":479},{"style":61},[480],{"type":20,"value":481},"Out-String",{"type":15,"tag":54,"props":483,"children":484},{"style":66},[485],{"type":20,"value":486}," | ",{"type":15,"tag":54,"props":488,"children":489},{"style":61},[490],{"type":20,"value":491},"Invoke-Expression",{"type":15,"tag":54,"props":493,"children":494},{"style":66},[495],{"type":20,"value":496}," }).TotalMilliseconds\n",{"type":15,"tag":16,"props":498,"children":499},{},[500],{"type":20,"value":501},"Results:",{"type":15,"tag":503,"props":504,"children":505},"table",{},[506,525],{"type":15,"tag":507,"props":508,"children":509},"thead",{},[510],{"type":15,"tag":511,"props":512,"children":513},"tr",{},[514,520],{"type":15,"tag":515,"props":516,"children":517},"th",{},[518],{"type":20,"value":519},"Thing",{"type":15,"tag":515,"props":521,"children":522},{},[523],{"type":20,"value":524},"Cost",{"type":15,"tag":526,"props":527,"children":528},"tbody",{},[529,543,556],{"type":15,"tag":511,"props":530,"children":531},{},[532,538],{"type":15,"tag":533,"props":534,"children":535},"td",{},[536],{"type":20,"value":537},"oh-my-posh init",{"type":15,"tag":533,"props":539,"children":540},{},[541],{"type":20,"value":542},"~377ms",{"type":15,"tag":511,"props":544,"children":545},{},[546,551],{"type":15,"tag":533,"props":547,"children":548},{},[549],{"type":20,"value":550},"Terminal-Icons import",{"type":15,"tag":533,"props":552,"children":553},{},[554],{"type":20,"value":555},"~284ms",{"type":15,"tag":511,"props":557,"children":558},{},[559,564],{"type":15,"tag":533,"props":560,"children":561},{},[562],{"type":20,"value":563},"fnm env",{"type":15,"tag":533,"props":565,"children":566},{},[567],{"type":20,"value":568},"~60ms",{"type":15,"tag":16,"props":570,"children":571},{},[572],{"type":20,"value":573},"Three culprits. None of them are doing anything wrong, they just have to run every single time a shell opens.",{"type":15,"tag":23,"props":575,"children":577},{"id":576},"fix-1-cache-oh-my-posh-init",[578],{"type":20,"value":579},"Fix 1: cache oh-my-posh init",{"type":15,"tag":16,"props":581,"children":582},{},[583,589],{"type":15,"tag":35,"props":584,"children":586},{"className":585},[],[587],{"type":20,"value":588},"oh-my-posh init pwsh",{"type":20,"value":590}," spawns the executable, parses your config JSON, and prints a PowerShell script that sets up the prompt. That generated script barely changes unless you edit your config or update oh-my-posh. So I cache it:",{"type":15,"tag":44,"props":592,"children":594},{"className":46,"code":593,"language":48,"meta":7,"style":7},"$ompExe = 'C:\\Users\\ibnuh\\AppData\\Local\\Microsoft\\WindowsApps\\oh-my-posh.exe'\n$ompConfig = 'C:\\Users\\ibnuh\\Documents\\PowerShell\\wopian.omp.json'\n$ompCache = Join-Path $env:TEMP 'omp-init-wopian.ps1'\nif (-not (Test-Path $ompCache) -or\n    (Get-Item $ompConfig).LastWriteTime -gt (Get-Item $ompCache).LastWriteTime -or\n    (Get-Item $ompExe).LastWriteTime   -gt (Get-Item $ompCache).LastWriteTime) {\n    & $ompExe init pwsh --config=$ompConfig --print | Out-File -FilePath $ompCache -Encoding utf8\n}\n. $ompCache\n",[595],{"type":15,"tag":35,"props":596,"children":597},{"__ignoreMap":7},[598,617,634,661,703,750,792,860,868],{"type":15,"tag":54,"props":599,"children":600},{"class":56,"line":57},[601,607,612],{"type":15,"tag":54,"props":602,"children":604},{"style":603},"--shiki-default:#E06C75",[605],{"type":20,"value":606},"$ompExe",{"type":15,"tag":54,"props":608,"children":609},{"style":61},[610],{"type":20,"value":611}," =",{"type":15,"tag":54,"props":613,"children":614},{"style":82},[615],{"type":20,"value":616}," 'C:\\Users\\ibnuh\\AppData\\Local\\Microsoft\\WindowsApps\\oh-my-posh.exe'\n",{"type":15,"tag":54,"props":618,"children":619},{"class":56,"line":232},[620,625,629],{"type":15,"tag":54,"props":621,"children":622},{"style":603},[623],{"type":20,"value":624},"$ompConfig",{"type":15,"tag":54,"props":626,"children":627},{"style":61},[628],{"type":20,"value":611},{"type":15,"tag":54,"props":630,"children":631},{"style":82},[632],{"type":20,"value":633}," 'C:\\Users\\ibnuh\\Documents\\PowerShell\\wopian.omp.json'\n",{"type":15,"tag":54,"props":635,"children":636},{"class":56,"line":250},[637,642,646,651,656],{"type":15,"tag":54,"props":638,"children":639},{"style":603},[640],{"type":20,"value":641},"$ompCache",{"type":15,"tag":54,"props":643,"children":644},{"style":61},[645],{"type":20,"value":611},{"type":15,"tag":54,"props":647,"children":648},{"style":61},[649],{"type":20,"value":650}," Join-Path",{"type":15,"tag":54,"props":652,"children":653},{"style":603},[654],{"type":20,"value":655}," $env:TEMP",{"type":15,"tag":54,"props":657,"children":658},{"style":82},[659],{"type":20,"value":660}," 'omp-init-wopian.ps1'\n",{"type":15,"tag":54,"props":662,"children":663},{"class":56,"line":334},[664,669,674,679,683,688,693,698],{"type":15,"tag":54,"props":665,"children":666},{"style":259},[667],{"type":20,"value":668},"if",{"type":15,"tag":54,"props":670,"children":671},{"style":66},[672],{"type":20,"value":673}," (",{"type":15,"tag":54,"props":675,"children":676},{"style":61},[677],{"type":20,"value":678},"-not",{"type":15,"tag":54,"props":680,"children":681},{"style":66},[682],{"type":20,"value":673},{"type":15,"tag":54,"props":684,"children":685},{"style":61},[686],{"type":20,"value":687},"Test-Path",{"type":15,"tag":54,"props":689,"children":690},{"style":603},[691],{"type":20,"value":692}," $ompCache",{"type":15,"tag":54,"props":694,"children":695},{"style":66},[696],{"type":20,"value":697},") ",{"type":15,"tag":54,"props":699,"children":700},{"style":61},[701],{"type":20,"value":702},"-or\n",{"type":15,"tag":54,"props":704,"children":705},{"class":56,"line":343},[706,710,715,720,725,730,734,738,742,746],{"type":15,"tag":54,"props":707,"children":708},{"style":66},[709],{"type":20,"value":256},{"type":15,"tag":54,"props":711,"children":712},{"style":61},[713],{"type":20,"value":714},"Get-Item",{"type":15,"tag":54,"props":716,"children":717},{"style":603},[718],{"type":20,"value":719}," $ompConfig",{"type":15,"tag":54,"props":721,"children":722},{"style":66},[723],{"type":20,"value":724},").LastWriteTime ",{"type":15,"tag":54,"props":726,"children":727},{"style":61},[728],{"type":20,"value":729},"-gt",{"type":15,"tag":54,"props":731,"children":732},{"style":66},[733],{"type":20,"value":673},{"type":15,"tag":54,"props":735,"children":736},{"style":61},[737],{"type":20,"value":714},{"type":15,"tag":54,"props":739,"children":740},{"style":603},[741],{"type":20,"value":692},{"type":15,"tag":54,"props":743,"children":744},{"style":66},[745],{"type":20,"value":724},{"type":15,"tag":54,"props":747,"children":748},{"style":61},[749],{"type":20,"value":702},{"type":15,"tag":54,"props":751,"children":752},{"class":56,"line":353},[753,757,761,766,771,775,779,783,787],{"type":15,"tag":54,"props":754,"children":755},{"style":66},[756],{"type":20,"value":256},{"type":15,"tag":54,"props":758,"children":759},{"style":61},[760],{"type":20,"value":714},{"type":15,"tag":54,"props":762,"children":763},{"style":603},[764],{"type":20,"value":765}," $ompExe",{"type":15,"tag":54,"props":767,"children":768},{"style":66},[769],{"type":20,"value":770},").LastWriteTime   ",{"type":15,"tag":54,"props":772,"children":773},{"style":61},[774],{"type":20,"value":729},{"type":15,"tag":54,"props":776,"children":777},{"style":66},[778],{"type":20,"value":673},{"type":15,"tag":54,"props":780,"children":781},{"style":61},[782],{"type":20,"value":714},{"type":15,"tag":54,"props":784,"children":785},{"style":603},[786],{"type":20,"value":692},{"type":15,"tag":54,"props":788,"children":789},{"style":66},[790],{"type":20,"value":791},").LastWriteTime) {\n",{"type":15,"tag":54,"props":793,"children":794},{"class":56,"line":374},[795,800,804,808,812,816,820,824,828,833,838,842,847,851,855],{"type":15,"tag":54,"props":796,"children":797},{"style":66},[798],{"type":20,"value":799},"    & ",{"type":15,"tag":54,"props":801,"children":802},{"style":603},[803],{"type":20,"value":606},{"type":15,"tag":54,"props":805,"children":806},{"style":66},[807],{"type":20,"value":277},{"type":15,"tag":54,"props":809,"children":810},{"style":61},[811],{"type":20,"value":282},{"type":15,"tag":54,"props":813,"children":814},{"style":66},[815],{"type":20,"value":287},{"type":15,"tag":54,"props":817,"children":818},{"style":61},[819],{"type":20,"value":292},{"type":15,"tag":54,"props":821,"children":822},{"style":603},[823],{"type":20,"value":624},{"type":15,"tag":54,"props":825,"children":826},{"style":61},[827],{"type":20,"value":302},{"type":15,"tag":54,"props":829,"children":830},{"style":66},[831],{"type":20,"value":832},"print | ",{"type":15,"tag":54,"props":834,"children":835},{"style":61},[836],{"type":20,"value":837},"Out-File",{"type":15,"tag":54,"props":839,"children":840},{"style":61},[841],{"type":20,"value":224},{"type":15,"tag":54,"props":843,"children":844},{"style":66},[845],{"type":20,"value":846},"FilePath ",{"type":15,"tag":54,"props":848,"children":849},{"style":603},[850],{"type":20,"value":641},{"type":15,"tag":54,"props":852,"children":853},{"style":61},[854],{"type":20,"value":224},{"type":15,"tag":54,"props":856,"children":857},{"style":66},[858],{"type":20,"value":859},"Encoding utf8\n",{"type":15,"tag":54,"props":861,"children":862},{"class":56,"line":414},[863],{"type":15,"tag":54,"props":864,"children":865},{"style":66},[866],{"type":20,"value":867},"}\n",{"type":15,"tag":54,"props":869,"children":870},{"class":56,"line":422},[871,876],{"type":15,"tag":54,"props":872,"children":873},{"style":66},[874],{"type":20,"value":875},". ",{"type":15,"tag":54,"props":877,"children":878},{"style":603},[879],{"type":20,"value":880},"$ompCache\n",{"type":15,"tag":16,"props":882,"children":883},{},[884],{"type":20,"value":885},"The cache auto-regenerates if either the config or the oh-my-posh binary is newer than the cache file. Dot-sourcing the cached script is much faster than spawning the process again.",{"type":15,"tag":23,"props":887,"children":889},{"id":888},"fix-2-lazy-load-terminal-icons",[890],{"type":20,"value":891},"Fix 2: lazy load Terminal-Icons",{"type":15,"tag":16,"props":893,"children":894},{},[895,897,903,905,910,912,917],{"type":20,"value":896},"Terminal-Icons is a formatter that renders pretty icons next to files in ",{"type":15,"tag":35,"props":898,"children":900},{"className":899},[],[901],{"type":20,"value":902},"ls",{"type":20,"value":904}," output. You only need it when you actually run ",{"type":15,"tag":35,"props":906,"children":908},{"className":907},[],[909],{"type":20,"value":902},{"type":20,"value":911},". So instead of eagerly importing it at shell startup, I defer it to the first time ",{"type":15,"tag":35,"props":913,"children":915},{"className":914},[],[916],{"type":20,"value":902},{"type":20,"value":918}," is called:",{"type":15,"tag":44,"props":920,"children":922},{"className":46,"code":921,"language":48,"meta":7,"style":7},"# Remove the built-in `ls` alias first, since aliases win over functions\nif (Get-Alias -Name ls -ErrorAction SilentlyContinue) {\n    Remove-Item Alias:ls -Force\n}\n$script:__TerminalIconsLoaded = $false\nfunction ls {\n    if (-not $script:__TerminalIconsLoaded) {\n        Import-Module -Name Terminal-Icons\n        $script:__TerminalIconsLoaded = $true\n    }\n    Get-ChildItem @args\n}\n",[923],{"type":15,"tag":35,"props":924,"children":925},{"__ignoreMap":7},[926,935,969,991,998,1026,1044,1078,1103,1128,1136,1150],{"type":15,"tag":54,"props":927,"children":928},{"class":56,"line":57},[929],{"type":15,"tag":54,"props":930,"children":932},{"style":931},"--shiki-default:#7F848E;--shiki-default-font-style:italic",[933],{"type":20,"value":934},"# Remove the built-in `ls` alias first, since aliases win over functions\n",{"type":15,"tag":54,"props":936,"children":937},{"class":56,"line":232},[938,942,946,951,955,960,964],{"type":15,"tag":54,"props":939,"children":940},{"style":259},[941],{"type":20,"value":668},{"type":15,"tag":54,"props":943,"children":944},{"style":66},[945],{"type":20,"value":673},{"type":15,"tag":54,"props":947,"children":948},{"style":61},[949],{"type":20,"value":950},"Get-Alias",{"type":15,"tag":54,"props":952,"children":953},{"style":61},[954],{"type":20,"value":224},{"type":15,"tag":54,"props":956,"children":957},{"style":66},[958],{"type":20,"value":959},"Name ls ",{"type":15,"tag":54,"props":961,"children":962},{"style":61},[963],{"type":20,"value":74},{"type":15,"tag":54,"props":965,"children":966},{"style":66},[967],{"type":20,"value":968},"ErrorAction SilentlyContinue) {\n",{"type":15,"tag":54,"props":970,"children":971},{"class":56,"line":250},[972,977,982,986],{"type":15,"tag":54,"props":973,"children":974},{"style":61},[975],{"type":20,"value":976},"    Remove-Item",{"type":15,"tag":54,"props":978,"children":979},{"style":66},[980],{"type":20,"value":981}," Alias:ls ",{"type":15,"tag":54,"props":983,"children":984},{"style":61},[985],{"type":20,"value":74},{"type":15,"tag":54,"props":987,"children":988},{"style":66},[989],{"type":20,"value":990},"Force\n",{"type":15,"tag":54,"props":992,"children":993},{"class":56,"line":334},[994],{"type":15,"tag":54,"props":995,"children":996},{"style":66},[997],{"type":20,"value":867},{"type":15,"tag":54,"props":999,"children":1000},{"class":56,"line":343},[1001,1006,1011,1016,1020],{"type":15,"tag":54,"props":1002,"children":1003},{"style":603},[1004],{"type":20,"value":1005},"$",{"type":15,"tag":54,"props":1007,"children":1008},{"style":259},[1009],{"type":20,"value":1010},"script",{"type":15,"tag":54,"props":1012,"children":1013},{"style":603},[1014],{"type":20,"value":1015},":__TerminalIconsLoaded",{"type":15,"tag":54,"props":1017,"children":1018},{"style":61},[1019],{"type":20,"value":611},{"type":15,"tag":54,"props":1021,"children":1023},{"style":1022},"--shiki-default:#D19A66",[1024],{"type":20,"value":1025}," $false\n",{"type":15,"tag":54,"props":1027,"children":1028},{"class":56,"line":353},[1029,1034,1040],{"type":15,"tag":54,"props":1030,"children":1031},{"style":259},[1032],{"type":20,"value":1033},"function",{"type":15,"tag":54,"props":1035,"children":1037},{"style":1036},"--shiki-default:#61AFEF",[1038],{"type":20,"value":1039}," ls",{"type":15,"tag":54,"props":1041,"children":1042},{"style":66},[1043],{"type":20,"value":247},{"type":15,"tag":54,"props":1045,"children":1046},{"class":56,"line":374},[1047,1052,1056,1060,1065,1069,1073],{"type":15,"tag":54,"props":1048,"children":1049},{"style":259},[1050],{"type":20,"value":1051},"    if",{"type":15,"tag":54,"props":1053,"children":1054},{"style":66},[1055],{"type":20,"value":673},{"type":15,"tag":54,"props":1057,"children":1058},{"style":61},[1059],{"type":20,"value":678},{"type":15,"tag":54,"props":1061,"children":1062},{"style":603},[1063],{"type":20,"value":1064}," $",{"type":15,"tag":54,"props":1066,"children":1067},{"style":259},[1068],{"type":20,"value":1010},{"type":15,"tag":54,"props":1070,"children":1071},{"style":603},[1072],{"type":20,"value":1015},{"type":15,"tag":54,"props":1074,"children":1075},{"style":66},[1076],{"type":20,"value":1077},") {\n",{"type":15,"tag":54,"props":1079,"children":1080},{"class":56,"line":414},[1081,1086,1090,1094,1098],{"type":15,"tag":54,"props":1082,"children":1083},{"style":61},[1084],{"type":20,"value":1085},"        Import-Module",{"type":15,"tag":54,"props":1087,"children":1088},{"style":61},[1089],{"type":20,"value":224},{"type":15,"tag":54,"props":1091,"children":1092},{"style":66},[1093],{"type":20,"value":402},{"type":15,"tag":54,"props":1095,"children":1096},{"style":61},[1097],{"type":20,"value":74},{"type":15,"tag":54,"props":1099,"children":1100},{"style":66},[1101],{"type":20,"value":1102},"Icons\n",{"type":15,"tag":54,"props":1104,"children":1105},{"class":56,"line":422},[1106,1111,1115,1119,1123],{"type":15,"tag":54,"props":1107,"children":1108},{"style":603},[1109],{"type":20,"value":1110},"        $",{"type":15,"tag":54,"props":1112,"children":1113},{"style":259},[1114],{"type":20,"value":1010},{"type":15,"tag":54,"props":1116,"children":1117},{"style":603},[1118],{"type":20,"value":1015},{"type":15,"tag":54,"props":1120,"children":1121},{"style":61},[1122],{"type":20,"value":611},{"type":15,"tag":54,"props":1124,"children":1125},{"style":1022},[1126],{"type":20,"value":1127}," $true\n",{"type":15,"tag":54,"props":1129,"children":1130},{"class":56,"line":443},[1131],{"type":15,"tag":54,"props":1132,"children":1133},{"style":66},[1134],{"type":20,"value":1135},"    }\n",{"type":15,"tag":54,"props":1137,"children":1139},{"class":56,"line":1138},11,[1140,1145],{"type":15,"tag":54,"props":1141,"children":1142},{"style":61},[1143],{"type":20,"value":1144},"    Get-ChildItem",{"type":15,"tag":54,"props":1146,"children":1147},{"style":603},[1148],{"type":20,"value":1149}," @args\n",{"type":15,"tag":54,"props":1151,"children":1153},{"class":56,"line":1152},12,[1154],{"type":15,"tag":54,"props":1155,"children":1156},{"style":66},[1157],{"type":20,"value":867},{"type":15,"tag":16,"props":1159,"children":1160},{},[1161,1163,1168],{"type":20,"value":1162},"The first ",{"type":15,"tag":35,"props":1164,"children":1166},{"className":1165},[],[1167],{"type":20,"value":902},{"type":20,"value":1169}," of the session pays the ~280ms import cost. Every subsequent call is instant, and shell startup doesn't pay it at all.",{"type":15,"tag":16,"props":1171,"children":1172},{},[1173,1175,1180,1182,1188],{"type":20,"value":1174},"One thing that bit me: in PowerShell, aliases take precedence over functions during command resolution. ",{"type":15,"tag":35,"props":1176,"children":1178},{"className":1177},[],[1179],{"type":20,"value":902},{"type":20,"value":1181}," is a built in alias pointing to ",{"type":15,"tag":35,"props":1183,"children":1185},{"className":1184},[],[1186],{"type":20,"value":1187},"Get-ChildItem",{"type":20,"value":1189},", so my function was never called until I removed the alias.",{"type":15,"tag":23,"props":1191,"children":1193},{"id":1192},"fix-3-cache-fnm-env",[1194],{"type":20,"value":1195},"Fix 3: cache fnm env",{"type":15,"tag":16,"props":1197,"children":1198},{},[1199,1201,1206],{"type":20,"value":1200},"Same trick as oh-my-posh. ",{"type":15,"tag":35,"props":1202,"children":1204},{"className":1203},[],[1205],{"type":20,"value":563},{"type":20,"value":1207}," prints shell code that sets up node version management hooks. Cache it, regenerate only when fnm is updated:",{"type":15,"tag":44,"props":1209,"children":1211},{"className":46,"code":1210,"language":48,"meta":7,"style":7},"$fnmExe = (Get-Command fnm -ErrorAction SilentlyContinue).Source\nif ($fnmExe) {\n    $fnmCache = Join-Path $env:TEMP 'fnm-env.ps1'\n    if (-not (Test-Path $fnmCache) -or\n        (Get-Item $fnmExe).LastWriteTime -gt (Get-Item $fnmCache).LastWriteTime) {\n        fnm env --use-on-cd --shell powershell | Out-File -FilePath $fnmCache -Encoding utf8\n    }\n    . $fnmCache\n}\n",[1212],{"type":15,"tag":35,"props":1213,"children":1214},{"__ignoreMap":7},[1215,1250,1269,1294,1330,1371,1420,1427,1440],{"type":15,"tag":54,"props":1216,"children":1217},{"class":56,"line":57},[1218,1223,1227,1231,1236,1241,1245],{"type":15,"tag":54,"props":1219,"children":1220},{"style":603},[1221],{"type":20,"value":1222},"$fnmExe",{"type":15,"tag":54,"props":1224,"children":1225},{"style":61},[1226],{"type":20,"value":611},{"type":15,"tag":54,"props":1228,"children":1229},{"style":66},[1230],{"type":20,"value":673},{"type":15,"tag":54,"props":1232,"children":1233},{"style":61},[1234],{"type":20,"value":1235},"Get-Command",{"type":15,"tag":54,"props":1237,"children":1238},{"style":66},[1239],{"type":20,"value":1240}," fnm ",{"type":15,"tag":54,"props":1242,"children":1243},{"style":61},[1244],{"type":20,"value":74},{"type":15,"tag":54,"props":1246,"children":1247},{"style":66},[1248],{"type":20,"value":1249},"ErrorAction SilentlyContinue).Source\n",{"type":15,"tag":54,"props":1251,"children":1252},{"class":56,"line":232},[1253,1257,1261,1265],{"type":15,"tag":54,"props":1254,"children":1255},{"style":259},[1256],{"type":20,"value":668},{"type":15,"tag":54,"props":1258,"children":1259},{"style":66},[1260],{"type":20,"value":673},{"type":15,"tag":54,"props":1262,"children":1263},{"style":603},[1264],{"type":20,"value":1222},{"type":15,"tag":54,"props":1266,"children":1267},{"style":66},[1268],{"type":20,"value":1077},{"type":15,"tag":54,"props":1270,"children":1271},{"class":56,"line":250},[1272,1277,1281,1285,1289],{"type":15,"tag":54,"props":1273,"children":1274},{"style":603},[1275],{"type":20,"value":1276},"    $fnmCache",{"type":15,"tag":54,"props":1278,"children":1279},{"style":61},[1280],{"type":20,"value":611},{"type":15,"tag":54,"props":1282,"children":1283},{"style":61},[1284],{"type":20,"value":650},{"type":15,"tag":54,"props":1286,"children":1287},{"style":603},[1288],{"type":20,"value":655},{"type":15,"tag":54,"props":1290,"children":1291},{"style":82},[1292],{"type":20,"value":1293}," 'fnm-env.ps1'\n",{"type":15,"tag":54,"props":1295,"children":1296},{"class":56,"line":334},[1297,1301,1305,1309,1313,1317,1322,1326],{"type":15,"tag":54,"props":1298,"children":1299},{"style":259},[1300],{"type":20,"value":1051},{"type":15,"tag":54,"props":1302,"children":1303},{"style":66},[1304],{"type":20,"value":673},{"type":15,"tag":54,"props":1306,"children":1307},{"style":61},[1308],{"type":20,"value":678},{"type":15,"tag":54,"props":1310,"children":1311},{"style":66},[1312],{"type":20,"value":673},{"type":15,"tag":54,"props":1314,"children":1315},{"style":61},[1316],{"type":20,"value":687},{"type":15,"tag":54,"props":1318,"children":1319},{"style":603},[1320],{"type":20,"value":1321}," $fnmCache",{"type":15,"tag":54,"props":1323,"children":1324},{"style":66},[1325],{"type":20,"value":697},{"type":15,"tag":54,"props":1327,"children":1328},{"style":61},[1329],{"type":20,"value":702},{"type":15,"tag":54,"props":1331,"children":1332},{"class":56,"line":343},[1333,1338,1342,1347,1351,1355,1359,1363,1367],{"type":15,"tag":54,"props":1334,"children":1335},{"style":66},[1336],{"type":20,"value":1337},"        (",{"type":15,"tag":54,"props":1339,"children":1340},{"style":61},[1341],{"type":20,"value":714},{"type":15,"tag":54,"props":1343,"children":1344},{"style":603},[1345],{"type":20,"value":1346}," $fnmExe",{"type":15,"tag":54,"props":1348,"children":1349},{"style":66},[1350],{"type":20,"value":724},{"type":15,"tag":54,"props":1352,"children":1353},{"style":61},[1354],{"type":20,"value":729},{"type":15,"tag":54,"props":1356,"children":1357},{"style":66},[1358],{"type":20,"value":673},{"type":15,"tag":54,"props":1360,"children":1361},{"style":61},[1362],{"type":20,"value":714},{"type":15,"tag":54,"props":1364,"children":1365},{"style":603},[1366],{"type":20,"value":1321},{"type":15,"tag":54,"props":1368,"children":1369},{"style":66},[1370],{"type":20,"value":791},{"type":15,"tag":54,"props":1372,"children":1373},{"class":56,"line":353},[1374,1379,1383,1387,1391,1395,1399,1403,1407,1412,1416],{"type":15,"tag":54,"props":1375,"children":1376},{"style":66},[1377],{"type":20,"value":1378},"        fnm env ",{"type":15,"tag":54,"props":1380,"children":1381},{"style":61},[1382],{"type":20,"value":462},{"type":15,"tag":54,"props":1384,"children":1385},{"style":66},[1386],{"type":20,"value":467},{"type":15,"tag":54,"props":1388,"children":1389},{"style":61},[1390],{"type":20,"value":282},{"type":15,"tag":54,"props":1392,"children":1393},{"style":66},[1394],{"type":20,"value":476},{"type":15,"tag":54,"props":1396,"children":1397},{"style":61},[1398],{"type":20,"value":837},{"type":15,"tag":54,"props":1400,"children":1401},{"style":61},[1402],{"type":20,"value":224},{"type":15,"tag":54,"props":1404,"children":1405},{"style":66},[1406],{"type":20,"value":846},{"type":15,"tag":54,"props":1408,"children":1409},{"style":603},[1410],{"type":20,"value":1411},"$fnmCache",{"type":15,"tag":54,"props":1413,"children":1414},{"style":61},[1415],{"type":20,"value":224},{"type":15,"tag":54,"props":1417,"children":1418},{"style":66},[1419],{"type":20,"value":859},{"type":15,"tag":54,"props":1421,"children":1422},{"class":56,"line":374},[1423],{"type":15,"tag":54,"props":1424,"children":1425},{"style":66},[1426],{"type":20,"value":1135},{"type":15,"tag":54,"props":1428,"children":1429},{"class":56,"line":414},[1430,1435],{"type":15,"tag":54,"props":1431,"children":1432},{"style":66},[1433],{"type":20,"value":1434},"    . ",{"type":15,"tag":54,"props":1436,"children":1437},{"style":603},[1438],{"type":20,"value":1439},"$fnmCache\n",{"type":15,"tag":54,"props":1441,"children":1442},{"class":56,"line":422},[1443],{"type":15,"tag":54,"props":1444,"children":1445},{"style":66},[1446],{"type":20,"value":867},{"type":15,"tag":16,"props":1448,"children":1449},{},[1450,1452,1458],{"type":20,"value":1451},"This pattern works for any tool that prints shell init code on every launch. Later I added the same thing for ",{"type":15,"tag":35,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":20,"value":1457},"zoxide init powershell",{"type":20,"value":1459},".",{"type":15,"tag":23,"props":1461,"children":1463},{"id":1462},"the-results",[1464],{"type":20,"value":1465},"The results",{"type":15,"tag":503,"props":1467,"children":1468},{},[1469,1485],{"type":15,"tag":507,"props":1470,"children":1471},{},[1472],{"type":15,"tag":511,"props":1473,"children":1474},{},[1475,1480],{"type":15,"tag":515,"props":1476,"children":1477},{},[1478],{"type":20,"value":1479},"State",{"type":15,"tag":515,"props":1481,"children":1482},{},[1483],{"type":20,"value":1484},"Startup",{"type":15,"tag":526,"props":1486,"children":1487},{},[1488,1501],{"type":15,"tag":511,"props":1489,"children":1490},{},[1491,1496],{"type":15,"tag":533,"props":1492,"children":1493},{},[1494],{"type":20,"value":1495},"Original profile",{"type":15,"tag":533,"props":1497,"children":1498},{},[1499],{"type":20,"value":1500},"~905ms",{"type":15,"tag":511,"props":1502,"children":1503},{},[1504,1509],{"type":15,"tag":533,"props":1505,"children":1506},{},[1507],{"type":20,"value":1508},"After all three caches",{"type":15,"tag":533,"props":1510,"children":1511},{},[1512],{"type":20,"value":1513},"~440ms",{"type":15,"tag":16,"props":1515,"children":1516},{},[1517],{"type":20,"value":1518},"Roughly 51% faster. The remaining ~440ms is the unavoidable cost of pwsh itself loading the CLR and PSReadLine, plus parsing the cached oh-my-posh init script (which is still ~250ms even cached, since that generated script is large and sets up the prompt hooks).",{"type":15,"tag":23,"props":1520,"children":1522},{"id":1521},"things-to-know",[1523],{"type":20,"value":1524},"Things to know",{"type":15,"tag":163,"props":1526,"children":1527},{},[1528,1533,1545,1558],{"type":15,"tag":167,"props":1529,"children":1530},{},[1531],{"type":20,"value":1532},"If you edit your oh-my-posh config, the cache regenerates automatically on the next shell launch. Same for fnm and zoxide when their binaries update.",{"type":15,"tag":167,"props":1534,"children":1535},{},[1536,1538,1544],{"type":20,"value":1537},"If you want to force a regeneration, just delete the cache file from ",{"type":15,"tag":35,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":20,"value":1543},"%TEMP%",{"type":20,"value":1459},{"type":15,"tag":167,"props":1546,"children":1547},{},[1548,1550,1556],{"type":20,"value":1549},"Adding ",{"type":15,"tag":35,"props":1551,"children":1553},{"className":1552},[],[1554],{"type":20,"value":1555},"-NoLogo",{"type":20,"value":1557}," to your pwsh command in Windows Terminal shaves off another ~40ms.",{"type":15,"tag":167,"props":1559,"children":1560},{},[1561,1563,1569],{"type":20,"value":1562},"Check your PowerShell version with ",{"type":15,"tag":35,"props":1564,"children":1566},{"className":1565},[],[1567],{"type":20,"value":1568},"$PSVersionTable.PSVersion",{"type":20,"value":1570},". Newer releases tend to have startup improvements, so staying current helps.",{"type":15,"tag":16,"props":1572,"children":1573},{},[1574],{"type":20,"value":1575},"If you want to go even further, you can defer oh-my-posh itself until the first prompt renders, which would get you down to around 240ms. I didn't bother because the tradeoff is that your very first prompt shows plain text for a split second before oh-my-posh swaps in, which felt worse than waiting 200ms.",{"type":15,"tag":1577,"props":1578,"children":1579},"style",{},[1580],{"type":20,"value":1581},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":232,"depth":232,"links":1583},[1584,1585,1586,1587,1588,1589,1590],{"id":25,"depth":250,"text":28},{"id":184,"depth":250,"text":187},{"id":576,"depth":250,"text":579},{"id":888,"depth":250,"text":891},{"id":1192,"depth":250,"text":1195},{"id":1462,"depth":250,"text":1465},{"id":1521,"depth":250,"text":1524},"markdown","content:blog:cutting-powershell-startup-time-in-half.md","content","blog/cutting-powershell-startup-time-in-half.md","blog/cutting-powershell-startup-time-in-half","md",[1598,2229],{"_path":1599,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1600,"description":1601,"date":1602,"body":1603,"_type":1591,"_id":2226,"_source":1593,"_file":2227,"_stem":2228,"_extension":1596},"/blog/tildewin-macos-style-window-switching-on-windows","TildeWin: macOS-style window switching on Windows","A small AutoHotkey v2 script that brings Cmd+` style same-app window switching to Windows.","2026-04-23T20:45:00+07:00",{"type":12,"children":1604,"toc":2218},[1605,1618,1641,1648,1653,1678,1690,1696,1701,1706,1745,1750,1756,1761,1771,1776,1846,1857,1862,1895,1900,1906,1928,1963,1994,2006,2012,2032,2055,2067,2153,2182,2186,2209,2214],{"type":15,"tag":16,"props":1606,"children":1607},{},[1608,1610,1616],{"type":20,"value":1609},"One shortcut I keep missing on Windows is ",{"type":15,"tag":35,"props":1611,"children":1613},{"className":1612},[],[1614],{"type":20,"value":1615},"Cmd + grave",{"type":20,"value":1617}," from macOS. If you have multiple windows open from the same app, it cycles through only those windows. It is especially useful with browsers, terminals, editors, and File Explorer.",{"type":15,"tag":16,"props":1619,"children":1620},{},[1621,1623,1629,1631,1640],{"type":20,"value":1622},"Windows has ",{"type":15,"tag":35,"props":1624,"children":1626},{"className":1625},[],[1627],{"type":20,"value":1628},"Alt + Tab",{"type":20,"value":1630},", but that cycles through every window. It also has taskbar grouping, but cycling through a grouped app usually means reaching for the mouse. I wanted the same direct keyboard behavior, so I made a tiny AutoHotkey script called ",{"type":15,"tag":1632,"props":1633,"children":1637},"a",{"href":1634,"rel":1635},"https://github.com/ibnuh/tildewin",[1636],"nofollow",[1638],{"type":20,"value":1639},"TildeWin",{"type":20,"value":1459},{"type":15,"tag":1642,"props":1643,"children":1645},"h2",{"id":1644},"what-it-does",[1646],{"type":20,"value":1647},"What it does",{"type":15,"tag":16,"props":1649,"children":1650},{},[1651],{"type":20,"value":1652},"TildeWin adds these shortcuts:",{"type":15,"tag":163,"props":1654,"children":1655},{},[1656,1667],{"type":15,"tag":167,"props":1657,"children":1658},{},[1659,1665],{"type":15,"tag":35,"props":1660,"children":1662},{"className":1661},[],[1663],{"type":20,"value":1664},"Win + grave",{"type":20,"value":1666},": switch to the next window in the current app.",{"type":15,"tag":167,"props":1668,"children":1669},{},[1670,1676],{"type":15,"tag":35,"props":1671,"children":1673},{"className":1672},[],[1674],{"type":20,"value":1675},"Win + Shift + grave",{"type":20,"value":1677},": switch to the previous window in the current app.",{"type":15,"tag":16,"props":1679,"children":1680},{},[1681,1683,1688],{"type":20,"value":1682},"So if I am focused on a Chrome window, ",{"type":15,"tag":35,"props":1684,"children":1686},{"className":1685},[],[1687],{"type":20,"value":1664},{"type":20,"value":1689}," moves to another Chrome window. If I am focused on VS Code, it cycles through VS Code windows. Other apps stay out of the way.",{"type":15,"tag":1642,"props":1691,"children":1693},{"id":1692},"why-autohotkey",[1694],{"type":20,"value":1695},"Why AutoHotkey",{"type":15,"tag":16,"props":1697,"children":1698},{},[1699],{"type":20,"value":1700},"AutoHotkey is still the simplest tool for this kind of Windows automation. The script can ask Windows which window is active, find other windows from the same process, filter out windows that should not be switch targets, then activate the next one.",{"type":15,"tag":16,"props":1702,"children":1703},{},[1704],{"type":20,"value":1705},"For this first version, grouping is based on executable name:",{"type":15,"tag":163,"props":1707,"children":1708},{},[1709,1718,1727,1736],{"type":15,"tag":167,"props":1710,"children":1711},{},[1712],{"type":15,"tag":35,"props":1713,"children":1715},{"className":1714},[],[1716],{"type":20,"value":1717},"chrome.exe",{"type":15,"tag":167,"props":1719,"children":1720},{},[1721],{"type":15,"tag":35,"props":1722,"children":1724},{"className":1723},[],[1725],{"type":20,"value":1726},"Code.exe",{"type":15,"tag":167,"props":1728,"children":1729},{},[1730],{"type":15,"tag":35,"props":1731,"children":1733},{"className":1732},[],[1734],{"type":20,"value":1735},"explorer.exe",{"type":15,"tag":167,"props":1737,"children":1738},{},[1739],{"type":15,"tag":35,"props":1740,"children":1742},{"className":1741},[],[1743],{"type":20,"value":1744},"notepad.exe",{"type":15,"tag":16,"props":1746,"children":1747},{},[1748],{"type":20,"value":1749},"That covers the apps I use most. It is not a perfect clone of Windows taskbar grouping, but it is small, predictable, and easy to change.",{"type":15,"tag":1642,"props":1751,"children":1753},{"id":1752},"the-script",[1754],{"type":20,"value":1755},"The script",{"type":15,"tag":16,"props":1757,"children":1758},{},[1759],{"type":20,"value":1760},"The full script is in the repo:",{"type":15,"tag":44,"props":1762,"children":1766},{"className":1763,"code":1765,"language":20,"meta":7},[1764],"language-text","https://github.com/ibnuh/tildewin\n",[1767],{"type":15,"tag":35,"props":1768,"children":1769},{"__ignoreMap":7},[1770],{"type":20,"value":1765},{"type":15,"tag":16,"props":1772,"children":1773},{},[1774],{"type":20,"value":1775},"The important part is this:",{"type":15,"tag":44,"props":1777,"children":1781},{"className":1778,"code":1779,"language":1780,"meta":7,"style":7},"language-autohotkey shiki shiki-themes one-dark-pro","#vkC0::SwitchSameAppWindow(1)\n#+vkC0::SwitchSameAppWindow(-1)\n","autohotkey",[1782],{"type":15,"tag":35,"props":1783,"children":1784},{"__ignoreMap":7},[1785,1817],{"type":15,"tag":54,"props":1786,"children":1787},{"class":56,"line":57},[1788,1793,1798,1803,1807,1812],{"type":15,"tag":54,"props":1789,"children":1790},{"style":259},[1791],{"type":20,"value":1792},"#vkC0",{"type":15,"tag":54,"props":1794,"children":1795},{"style":66},[1796],{"type":20,"value":1797},"::",{"type":15,"tag":54,"props":1799,"children":1800},{"style":1036},[1801],{"type":20,"value":1802},"SwitchSameAppWindow",{"type":15,"tag":54,"props":1804,"children":1805},{"style":66},[1806],{"type":20,"value":238},{"type":15,"tag":54,"props":1808,"children":1809},{"style":1022},[1810],{"type":20,"value":1811},"1",{"type":15,"tag":54,"props":1813,"children":1814},{"style":66},[1815],{"type":20,"value":1816},")\n",{"type":15,"tag":54,"props":1818,"children":1819},{"class":56,"line":232},[1820,1825,1829,1833,1838,1842],{"type":15,"tag":54,"props":1821,"children":1822},{"style":259},[1823],{"type":20,"value":1824},"#+vkC0",{"type":15,"tag":54,"props":1826,"children":1827},{"style":66},[1828],{"type":20,"value":1797},{"type":15,"tag":54,"props":1830,"children":1831},{"style":1036},[1832],{"type":20,"value":1802},{"type":15,"tag":54,"props":1834,"children":1835},{"style":66},[1836],{"type":20,"value":1837},"(-",{"type":15,"tag":54,"props":1839,"children":1840},{"style":1022},[1841],{"type":20,"value":1811},{"type":15,"tag":54,"props":1843,"children":1844},{"style":66},[1845],{"type":20,"value":1816},{"type":15,"tag":16,"props":1847,"children":1848},{},[1849,1855],{"type":15,"tag":35,"props":1850,"children":1852},{"className":1851},[],[1853],{"type":20,"value":1854},"vkC0",{"type":20,"value":1856}," is the grave/backtick key on a US-style keyboard. I used the virtual key name because the backtick character has special meaning in AutoHotkey strings and comments can get confusing quickly.",{"type":15,"tag":16,"props":1858,"children":1859},{},[1860],{"type":20,"value":1861},"The script skips windows that should not behave like normal app windows:",{"type":15,"tag":163,"props":1863,"children":1864},{},[1865,1870,1875,1880,1885,1890],{"type":15,"tag":167,"props":1866,"children":1867},{},[1868],{"type":20,"value":1869},"minimized windows",{"type":15,"tag":167,"props":1871,"children":1872},{},[1873],{"type":20,"value":1874},"hidden or cloaked windows",{"type":15,"tag":167,"props":1876,"children":1877},{},[1878],{"type":20,"value":1879},"tool windows",{"type":15,"tag":167,"props":1881,"children":1882},{},[1883],{"type":20,"value":1884},"no-activate windows",{"type":15,"tag":167,"props":1886,"children":1887},{},[1888],{"type":20,"value":1889},"disabled windows",{"type":15,"tag":167,"props":1891,"children":1892},{},[1893],{"type":20,"value":1894},"desktop and taskbar shell windows",{"type":15,"tag":16,"props":1896,"children":1897},{},[1898],{"type":20,"value":1899},"This makes the shortcut feel closer to how I expect app window switching to work.",{"type":15,"tag":1642,"props":1901,"children":1903},{"id":1902},"setup",[1904],{"type":20,"value":1905},"Setup",{"type":15,"tag":1907,"props":1908,"children":1909},"ol",{},[1910,1923],{"type":15,"tag":167,"props":1911,"children":1912},{},[1913,1915,1922],{"type":20,"value":1914},"Install ",{"type":15,"tag":1632,"props":1916,"children":1919},{"href":1917,"rel":1918},"https://www.autohotkey.com/",[1636],[1920],{"type":20,"value":1921},"AutoHotkey v2",{"type":20,"value":1459},{"type":15,"tag":167,"props":1924,"children":1925},{},[1926],{"type":20,"value":1927},"Download or clone TildeWin:",{"type":15,"tag":44,"props":1929,"children":1931},{"className":46,"code":1930,"language":48,"meta":7,"style":7},"git clone https://github.com/ibnuh/tildewin.git\n",[1932],{"type":15,"tag":35,"props":1933,"children":1934},{"__ignoreMap":7},[1935],{"type":15,"tag":54,"props":1936,"children":1937},{"class":56,"line":57},[1938,1943,1948,1953,1958],{"type":15,"tag":54,"props":1939,"children":1940},{"style":66},[1941],{"type":20,"value":1942},"git clone https:",{"type":15,"tag":54,"props":1944,"children":1945},{"style":61},[1946],{"type":20,"value":1947},"//github.com/",{"type":15,"tag":54,"props":1949,"children":1950},{"style":66},[1951],{"type":20,"value":1952},"ibnuh",{"type":15,"tag":54,"props":1954,"children":1955},{"style":61},[1956],{"type":20,"value":1957},"/",{"type":15,"tag":54,"props":1959,"children":1960},{"style":66},[1961],{"type":20,"value":1962},"tildewin.git\n",{"type":15,"tag":1907,"props":1964,"children":1965},{"start":250},[1966,1978,1983],{"type":15,"tag":167,"props":1967,"children":1968},{},[1969,1971,1977],{"type":20,"value":1970},"Run ",{"type":15,"tag":35,"props":1972,"children":1974},{"className":1973},[],[1975],{"type":20,"value":1976},"tildewin.ahk",{"type":20,"value":1459},{"type":15,"tag":167,"props":1979,"children":1980},{},[1981],{"type":20,"value":1982},"Open multiple windows from the same app.",{"type":15,"tag":167,"props":1984,"children":1985},{},[1986,1988,1993],{"type":20,"value":1987},"Press ",{"type":15,"tag":35,"props":1989,"children":1991},{"className":1990},[],[1992],{"type":20,"value":1664},{"type":20,"value":1459},{"type":15,"tag":16,"props":1995,"children":1996},{},[1997,1999,2004],{"type":20,"value":1998},"To run it automatically on startup, put a shortcut to ",{"type":15,"tag":35,"props":2000,"children":2002},{"className":2001},[],[2003],{"type":20,"value":1976},{"type":20,"value":2005}," in the Windows Startup folder.",{"type":15,"tag":1642,"props":2007,"children":2009},{"id":2008},"changing-the-hotkey",[2010],{"type":20,"value":2011},"Changing the hotkey",{"type":15,"tag":16,"props":2013,"children":2014},{},[2015,2017,2022,2024,2030],{"type":20,"value":2016},"If ",{"type":15,"tag":35,"props":2018,"children":2020},{"className":2019},[],[2021],{"type":20,"value":1664},{"type":20,"value":2023}," does not feel right, the script includes ",{"type":15,"tag":35,"props":2025,"children":2027},{"className":2026},[],[2028],{"type":20,"value":2029},"Alt + grave",{"type":20,"value":2031}," bindings as comments:",{"type":15,"tag":44,"props":2033,"children":2035},{"className":1778,"code":2034,"language":1780,"meta":7,"style":7},"; !vkC0::SwitchSameAppWindow(1)\n; !+vkC0::SwitchSameAppWindow(-1)\n",[2036],{"type":15,"tag":35,"props":2037,"children":2038},{"__ignoreMap":7},[2039,2047],{"type":15,"tag":54,"props":2040,"children":2041},{"class":56,"line":57},[2042],{"type":15,"tag":54,"props":2043,"children":2044},{"style":931},[2045],{"type":20,"value":2046},"; !vkC0::SwitchSameAppWindow(1)\n",{"type":15,"tag":54,"props":2048,"children":2049},{"class":56,"line":232},[2050],{"type":15,"tag":54,"props":2051,"children":2052},{"style":931},[2053],{"type":20,"value":2054},"; !+vkC0::SwitchSameAppWindow(-1)\n",{"type":15,"tag":16,"props":2056,"children":2057},{},[2058,2060,2065],{"type":20,"value":2059},"Uncomment those lines and comment out the ",{"type":15,"tag":35,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":20,"value":1792},{"type":20,"value":2066}," lines:",{"type":15,"tag":44,"props":2068,"children":2070},{"className":1778,"code":2069,"language":1780,"meta":7,"style":7},"; #vkC0::SwitchSameAppWindow(1)\n; #+vkC0::SwitchSameAppWindow(-1)\n\n!vkC0::SwitchSameAppWindow(1)\n!+vkC0::SwitchSameAppWindow(-1)\n",[2071],{"type":15,"tag":35,"props":2072,"children":2073},{"__ignoreMap":7},[2074,2082,2090,2097,2125],{"type":15,"tag":54,"props":2075,"children":2076},{"class":56,"line":57},[2077],{"type":15,"tag":54,"props":2078,"children":2079},{"style":931},[2080],{"type":20,"value":2081},"; #vkC0::SwitchSameAppWindow(1)\n",{"type":15,"tag":54,"props":2083,"children":2084},{"class":56,"line":232},[2085],{"type":15,"tag":54,"props":2086,"children":2087},{"style":931},[2088],{"type":20,"value":2089},"; #+vkC0::SwitchSameAppWindow(-1)\n",{"type":15,"tag":54,"props":2091,"children":2092},{"class":56,"line":250},[2093],{"type":15,"tag":54,"props":2094,"children":2095},{"emptyLinePlaceholder":347},[2096],{"type":20,"value":350},{"type":15,"tag":54,"props":2098,"children":2099},{"class":56,"line":334},[2100,2105,2109,2113,2117,2121],{"type":15,"tag":54,"props":2101,"children":2102},{"style":259},[2103],{"type":20,"value":2104},"!vkC0",{"type":15,"tag":54,"props":2106,"children":2107},{"style":66},[2108],{"type":20,"value":1797},{"type":15,"tag":54,"props":2110,"children":2111},{"style":1036},[2112],{"type":20,"value":1802},{"type":15,"tag":54,"props":2114,"children":2115},{"style":66},[2116],{"type":20,"value":238},{"type":15,"tag":54,"props":2118,"children":2119},{"style":1022},[2120],{"type":20,"value":1811},{"type":15,"tag":54,"props":2122,"children":2123},{"style":66},[2124],{"type":20,"value":1816},{"type":15,"tag":54,"props":2126,"children":2127},{"class":56,"line":343},[2128,2133,2137,2141,2145,2149],{"type":15,"tag":54,"props":2129,"children":2130},{"style":259},[2131],{"type":20,"value":2132},"!+vkC0",{"type":15,"tag":54,"props":2134,"children":2135},{"style":66},[2136],{"type":20,"value":1797},{"type":15,"tag":54,"props":2138,"children":2139},{"style":1036},[2140],{"type":20,"value":1802},{"type":15,"tag":54,"props":2142,"children":2143},{"style":66},[2144],{"type":20,"value":1837},{"type":15,"tag":54,"props":2146,"children":2147},{"style":1022},[2148],{"type":20,"value":1811},{"type":15,"tag":54,"props":2150,"children":2151},{"style":66},[2152],{"type":20,"value":1816},{"type":15,"tag":16,"props":2154,"children":2155},{},[2156,2158,2164,2166,2172,2174,2180],{"type":20,"value":2157},"In AutoHotkey syntax, ",{"type":15,"tag":35,"props":2159,"children":2161},{"className":2160},[],[2162],{"type":20,"value":2163},"#",{"type":20,"value":2165}," means Win, ",{"type":15,"tag":35,"props":2167,"children":2169},{"className":2168},[],[2170],{"type":20,"value":2171},"!",{"type":20,"value":2173}," means Alt, and ",{"type":15,"tag":35,"props":2175,"children":2177},{"className":2176},[],[2178],{"type":20,"value":2179},"+",{"type":20,"value":2181}," means Shift.",{"type":15,"tag":1642,"props":2183,"children":2184},{"id":1521},[2185],{"type":20,"value":1524},{"type":15,"tag":163,"props":2187,"children":2188},{},[2189,2194,2199,2204],{"type":15,"tag":167,"props":2190,"children":2191},{},[2192],{"type":20,"value":2193},"Admin windows may need the script to run as administrator.",{"type":15,"tag":167,"props":2195,"children":2196},{},[2197],{"type":20,"value":2198},"Browser tabs are not separate windows. This switches browser windows, not tabs.",{"type":15,"tag":167,"props":2200,"children":2201},{},[2202],{"type":20,"value":2203},"Apps with unusual window models may not behave perfectly.",{"type":15,"tag":167,"props":2205,"children":2206},{},[2207],{"type":20,"value":2208},"The current version does not use Windows AppUserModelID yet, so process-name grouping is the main rule.",{"type":15,"tag":16,"props":2210,"children":2211},{},[2212],{"type":20,"value":2213},"That is enough for my daily use right now. It is one of those tiny utilities that removes a little friction every time I switch contexts.",{"type":15,"tag":1577,"props":2215,"children":2216},{},[2217],{"type":20,"value":1581},{"title":7,"searchDepth":232,"depth":232,"links":2219},[2220,2221,2222,2223,2224,2225],{"id":1644,"depth":232,"text":1647},{"id":1692,"depth":232,"text":1695},{"id":1752,"depth":232,"text":1755},{"id":1902,"depth":232,"text":1905},{"id":2008,"depth":232,"text":2011},{"id":1521,"depth":232,"text":1524},"content:blog:tildewin-macos-style-window-switching-on-windows.md","blog/tildewin-macos-style-window-switching-on-windows.md","blog/tildewin-macos-style-window-switching-on-windows",{"_path":2230,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":2231,"description":2232,"date":2233,"body":2234,"_type":1591,"_id":2775,"_source":1593,"_file":2776,"_stem":2777,"_extension":1596},"/blog/global-hotkey-to-toggle-cmux-with-hammerspoon","Global hotkey to toggle cmux with Hammerspoon","How to set up a global Ctrl+Space hotkey to summon and hide cmux, since cmux does not have a built-in global hotkey feature.","2026-03-14T10:00:00+07:00",{"type":12,"children":2235,"toc":2770},[2236,2250,2256,2261,2266,2284,2298,2304,2326,2594,2599,2633,2638,2644,2656,2761,2766],{"type":15,"tag":16,"props":2237,"children":2238},{},[2239,2241,2248],{"type":20,"value":2240},"I recently switched to ",{"type":15,"tag":1632,"props":2242,"children":2245},{"href":2243,"rel":2244},"https://www.cmux.dev/",[1636],[2246],{"type":20,"value":2247},"cmux",{"type":20,"value":2249}," as my main terminal. It's a Ghostty-based macOS terminal built for AI coding agents, with vertical tabs, split panes, and notifications. It's great, but it's missing one feature I consider essential: a global hotkey to summon the terminal from anywhere.",{"type":15,"tag":1642,"props":2251,"children":2253},{"id":2252},"why-ctrlspace",[2254],{"type":20,"value":2255},"Why Ctrl+Space",{"type":15,"tag":16,"props":2257,"children":2258},{},[2259],{"type":20,"value":2260},"Most terminal apps I've used (Ghostty, Windows Terminal, iTerm2) have a built-in option to set a system-wide hotkey that toggles the terminal window. You press the key combo, the terminal appears. Press it again, it hides. This eliminates Cmd+Tab or Alt+Tab cycling.",{"type":15,"tag":16,"props":2262,"children":2263},{},[2264],{"type":20,"value":2265},"I picked Ctrl+Space specifically because:",{"type":15,"tag":163,"props":2267,"children":2268},{},[2269,2274,2279],{"type":15,"tag":167,"props":2270,"children":2271},{},[2272],{"type":20,"value":2273},"It's easy to hit with one hand, right on the home row area.",{"type":15,"tag":167,"props":2275,"children":2276},{},[2277],{"type":20,"value":2278},"It doesn't conflict with common app shortcuts. macOS used to use it for input source switching, but I have that disabled.",{"type":15,"tag":167,"props":2280,"children":2281},{},[2282],{"type":20,"value":2283},"It's what I used with Ghostty, Windows Terminal, and iTerm before, so the muscle memory is already there.",{"type":15,"tag":16,"props":2285,"children":2286},{},[2287,2289,2296],{"type":20,"value":2288},"cmux doesn't offer this setting anywhere in its preferences. There's an ",{"type":15,"tag":1632,"props":2290,"children":2293},{"href":2291,"rel":2292},"https://github.com/manaflow-ai/cmux/issues/135",[1636],[2294],{"type":20,"value":2295},"open issue",{"type":20,"value":2297}," requesting customizable keybindings, but as of now it's not available. Terminal keybindings in cmux are read from your Ghostty config, and cmux-specific shortcuts are in its Settings, but neither of those covers a global summon hotkey.",{"type":15,"tag":1642,"props":2299,"children":2301},{"id":2300},"the-hammerspoon-solution",[2302],{"type":20,"value":2303},"The Hammerspoon solution",{"type":15,"tag":16,"props":2305,"children":2306},{},[2307,2309,2316,2318,2324],{"type":20,"value":2308},"Since I already use ",{"type":15,"tag":1632,"props":2310,"children":2313},{"href":2311,"rel":2312},"https://www.hammerspoon.org/",[1636],[2314],{"type":20,"value":2315},"Hammerspoon",{"type":20,"value":2317}," for other macOS automation, adding a global hotkey for cmux is just a few lines in ",{"type":15,"tag":35,"props":2319,"children":2321},{"className":2320},[],[2322],{"type":20,"value":2323},"~/.hammerspoon/init.lua",{"type":20,"value":2325},":",{"type":15,"tag":44,"props":2327,"children":2331},{"className":2328,"code":2329,"language":2330,"meta":7,"style":7},"language-lua shiki shiki-themes one-dark-pro","hs.hotkey.bind({\"ctrl\"}, \"space\", function()\n    local app = hs.application.find(\"cmux\")\n    if app then\n        if app:isFrontmost() then\n            app:hide()\n        else\n            app:activate()\n        end\n    else\n        hs.application.launchOrFocus(\"cmux\")\n    end\nend)\n","lua",[2332],{"type":15,"tag":35,"props":2333,"children":2334},{"__ignoreMap":7},[2335,2387,2432,2448,2480,2501,2509,2529,2537,2545,2574,2582],{"type":15,"tag":54,"props":2336,"children":2337},{"class":56,"line":57},[2338,2343,2348,2353,2358,2363,2368,2373,2378,2382],{"type":15,"tag":54,"props":2339,"children":2340},{"style":603},[2341],{"type":20,"value":2342},"hs",{"type":15,"tag":54,"props":2344,"children":2345},{"style":66},[2346],{"type":20,"value":2347},".hotkey.",{"type":15,"tag":54,"props":2349,"children":2350},{"style":1036},[2351],{"type":20,"value":2352},"bind",{"type":15,"tag":54,"props":2354,"children":2355},{"style":66},[2356],{"type":20,"value":2357},"({",{"type":15,"tag":54,"props":2359,"children":2360},{"style":82},[2361],{"type":20,"value":2362},"\"ctrl\"",{"type":15,"tag":54,"props":2364,"children":2365},{"style":66},[2366],{"type":20,"value":2367},"}, ",{"type":15,"tag":54,"props":2369,"children":2370},{"style":82},[2371],{"type":20,"value":2372},"\"space\"",{"type":15,"tag":54,"props":2374,"children":2375},{"style":66},[2376],{"type":20,"value":2377},", ",{"type":15,"tag":54,"props":2379,"children":2380},{"style":259},[2381],{"type":20,"value":1033},{"type":15,"tag":54,"props":2383,"children":2384},{"style":66},[2385],{"type":20,"value":2386},"()\n",{"type":15,"tag":54,"props":2388,"children":2389},{"class":56,"line":232},[2390,2395,2400,2405,2409,2414,2419,2423,2428],{"type":15,"tag":54,"props":2391,"children":2392},{"style":259},[2393],{"type":20,"value":2394},"    local",{"type":15,"tag":54,"props":2396,"children":2397},{"style":603},[2398],{"type":20,"value":2399}," app",{"type":15,"tag":54,"props":2401,"children":2402},{"style":66},[2403],{"type":20,"value":2404}," = ",{"type":15,"tag":54,"props":2406,"children":2407},{"style":603},[2408],{"type":20,"value":2342},{"type":15,"tag":54,"props":2410,"children":2411},{"style":66},[2412],{"type":20,"value":2413},".application.",{"type":15,"tag":54,"props":2415,"children":2416},{"style":1036},[2417],{"type":20,"value":2418},"find",{"type":15,"tag":54,"props":2420,"children":2421},{"style":66},[2422],{"type":20,"value":238},{"type":15,"tag":54,"props":2424,"children":2425},{"style":82},[2426],{"type":20,"value":2427},"\"cmux\"",{"type":15,"tag":54,"props":2429,"children":2430},{"style":66},[2431],{"type":20,"value":1816},{"type":15,"tag":54,"props":2433,"children":2434},{"class":56,"line":250},[2435,2439,2443],{"type":15,"tag":54,"props":2436,"children":2437},{"style":259},[2438],{"type":20,"value":1051},{"type":15,"tag":54,"props":2440,"children":2441},{"style":603},[2442],{"type":20,"value":2399},{"type":15,"tag":54,"props":2444,"children":2445},{"style":259},[2446],{"type":20,"value":2447}," then\n",{"type":15,"tag":54,"props":2449,"children":2450},{"class":56,"line":334},[2451,2456,2461,2465,2470,2475],{"type":15,"tag":54,"props":2452,"children":2453},{"style":259},[2454],{"type":20,"value":2455},"        if",{"type":15,"tag":54,"props":2457,"children":2459},{"style":2458},"--shiki-default:#E5C07B",[2460],{"type":20,"value":2399},{"type":15,"tag":54,"props":2462,"children":2463},{"style":66},[2464],{"type":20,"value":2325},{"type":15,"tag":54,"props":2466,"children":2467},{"style":1036},[2468],{"type":20,"value":2469},"isFrontmost",{"type":15,"tag":54,"props":2471,"children":2472},{"style":66},[2473],{"type":20,"value":2474},"() ",{"type":15,"tag":54,"props":2476,"children":2477},{"style":259},[2478],{"type":20,"value":2479},"then\n",{"type":15,"tag":54,"props":2481,"children":2482},{"class":56,"line":343},[2483,2488,2492,2497],{"type":15,"tag":54,"props":2484,"children":2485},{"style":2458},[2486],{"type":20,"value":2487},"            app",{"type":15,"tag":54,"props":2489,"children":2490},{"style":66},[2491],{"type":20,"value":2325},{"type":15,"tag":54,"props":2493,"children":2494},{"style":1036},[2495],{"type":20,"value":2496},"hide",{"type":15,"tag":54,"props":2498,"children":2499},{"style":66},[2500],{"type":20,"value":2386},{"type":15,"tag":54,"props":2502,"children":2503},{"class":56,"line":353},[2504],{"type":15,"tag":54,"props":2505,"children":2506},{"style":259},[2507],{"type":20,"value":2508},"        else\n",{"type":15,"tag":54,"props":2510,"children":2511},{"class":56,"line":374},[2512,2516,2520,2525],{"type":15,"tag":54,"props":2513,"children":2514},{"style":2458},[2515],{"type":20,"value":2487},{"type":15,"tag":54,"props":2517,"children":2518},{"style":66},[2519],{"type":20,"value":2325},{"type":15,"tag":54,"props":2521,"children":2522},{"style":1036},[2523],{"type":20,"value":2524},"activate",{"type":15,"tag":54,"props":2526,"children":2527},{"style":66},[2528],{"type":20,"value":2386},{"type":15,"tag":54,"props":2530,"children":2531},{"class":56,"line":414},[2532],{"type":15,"tag":54,"props":2533,"children":2534},{"style":259},[2535],{"type":20,"value":2536},"        end\n",{"type":15,"tag":54,"props":2538,"children":2539},{"class":56,"line":422},[2540],{"type":15,"tag":54,"props":2541,"children":2542},{"style":259},[2543],{"type":20,"value":2544},"    else\n",{"type":15,"tag":54,"props":2546,"children":2547},{"class":56,"line":443},[2548,2553,2557,2562,2566,2570],{"type":15,"tag":54,"props":2549,"children":2550},{"style":603},[2551],{"type":20,"value":2552},"        hs",{"type":15,"tag":54,"props":2554,"children":2555},{"style":66},[2556],{"type":20,"value":2413},{"type":15,"tag":54,"props":2558,"children":2559},{"style":1036},[2560],{"type":20,"value":2561},"launchOrFocus",{"type":15,"tag":54,"props":2563,"children":2564},{"style":66},[2565],{"type":20,"value":238},{"type":15,"tag":54,"props":2567,"children":2568},{"style":82},[2569],{"type":20,"value":2427},{"type":15,"tag":54,"props":2571,"children":2572},{"style":66},[2573],{"type":20,"value":1816},{"type":15,"tag":54,"props":2575,"children":2576},{"class":56,"line":1138},[2577],{"type":15,"tag":54,"props":2578,"children":2579},{"style":259},[2580],{"type":20,"value":2581},"    end\n",{"type":15,"tag":54,"props":2583,"children":2584},{"class":56,"line":1152},[2585,2590],{"type":15,"tag":54,"props":2586,"children":2587},{"style":259},[2588],{"type":20,"value":2589},"end",{"type":15,"tag":54,"props":2591,"children":2592},{"style":66},[2593],{"type":20,"value":1816},{"type":15,"tag":16,"props":2595,"children":2596},{},[2597],{"type":20,"value":2598},"This does three things depending on the current state:",{"type":15,"tag":1907,"props":2600,"children":2601},{},[2602,2613,2623],{"type":15,"tag":167,"props":2603,"children":2604},{},[2605,2611],{"type":15,"tag":2606,"props":2607,"children":2608},"strong",{},[2609],{"type":20,"value":2610},"cmux is focused",{"type":20,"value":2612}," - hides it, sending you back to whatever app you were using.",{"type":15,"tag":167,"props":2614,"children":2615},{},[2616,2621],{"type":15,"tag":2606,"props":2617,"children":2618},{},[2619],{"type":20,"value":2620},"cmux is running but not focused",{"type":20,"value":2622}," - brings it to the front.",{"type":15,"tag":167,"props":2624,"children":2625},{},[2626,2631],{"type":15,"tag":2606,"props":2627,"children":2628},{},[2629],{"type":20,"value":2630},"cmux is not running",{"type":20,"value":2632}," - launches it.",{"type":15,"tag":16,"props":2634,"children":2635},{},[2636],{"type":20,"value":2637},"After adding the snippet, reload Hammerspoon (click the menu bar icon and select \"Reload Config\", or set up a reload hotkey).",{"type":15,"tag":1642,"props":2639,"children":2641},{"id":2640},"works-with-any-app",[2642],{"type":20,"value":2643},"Works with any app",{"type":15,"tag":16,"props":2645,"children":2646},{},[2647,2649,2654],{"type":20,"value":2648},"There's nothing cmux-specific about this pattern. You can use the same snippet for any app by replacing ",{"type":15,"tag":35,"props":2650,"children":2652},{"className":2651},[],[2653],{"type":20,"value":2427},{"type":20,"value":2655}," with the app's process name. To find the exact process name, run this in the Hammerspoon console:",{"type":15,"tag":44,"props":2657,"children":2659},{"className":2328,"code":2658,"language":2330,"meta":7,"style":7},"hs.fnutils.each(hs.application.runningApplications(), function(app)\n    print(app:name())\nend)\n",[2660],{"type":15,"tag":35,"props":2661,"children":2662},{"__ignoreMap":7},[2663,2720,2750],{"type":15,"tag":54,"props":2664,"children":2665},{"class":56,"line":57},[2666,2670,2675,2680,2684,2688,2692,2697,2702,2706,2710,2716],{"type":15,"tag":54,"props":2667,"children":2668},{"style":603},[2669],{"type":20,"value":2342},{"type":15,"tag":54,"props":2671,"children":2672},{"style":66},[2673],{"type":20,"value":2674},".fnutils.",{"type":15,"tag":54,"props":2676,"children":2677},{"style":1036},[2678],{"type":20,"value":2679},"each",{"type":15,"tag":54,"props":2681,"children":2682},{"style":66},[2683],{"type":20,"value":238},{"type":15,"tag":54,"props":2685,"children":2686},{"style":603},[2687],{"type":20,"value":2342},{"type":15,"tag":54,"props":2689,"children":2690},{"style":66},[2691],{"type":20,"value":2413},{"type":15,"tag":54,"props":2693,"children":2694},{"style":1036},[2695],{"type":20,"value":2696},"runningApplications",{"type":15,"tag":54,"props":2698,"children":2699},{"style":66},[2700],{"type":20,"value":2701},"(), ",{"type":15,"tag":54,"props":2703,"children":2704},{"style":259},[2705],{"type":20,"value":1033},{"type":15,"tag":54,"props":2707,"children":2708},{"style":66},[2709],{"type":20,"value":238},{"type":15,"tag":54,"props":2711,"children":2713},{"style":2712},"--shiki-default:#ABB2BF;--shiki-default-font-style:italic",[2714],{"type":20,"value":2715},"app",{"type":15,"tag":54,"props":2717,"children":2718},{"style":66},[2719],{"type":20,"value":1816},{"type":15,"tag":54,"props":2721,"children":2722},{"class":56,"line":232},[2723,2728,2732,2736,2740,2745],{"type":15,"tag":54,"props":2724,"children":2725},{"style":61},[2726],{"type":20,"value":2727},"    print",{"type":15,"tag":54,"props":2729,"children":2730},{"style":66},[2731],{"type":20,"value":238},{"type":15,"tag":54,"props":2733,"children":2734},{"style":2458},[2735],{"type":20,"value":2715},{"type":15,"tag":54,"props":2737,"children":2738},{"style":66},[2739],{"type":20,"value":2325},{"type":15,"tag":54,"props":2741,"children":2742},{"style":1036},[2743],{"type":20,"value":2744},"name",{"type":15,"tag":54,"props":2746,"children":2747},{"style":66},[2748],{"type":20,"value":2749},"())\n",{"type":15,"tag":54,"props":2751,"children":2752},{"class":56,"line":250},[2753,2757],{"type":15,"tag":54,"props":2754,"children":2755},{"style":259},[2756],{"type":20,"value":2589},{"type":15,"tag":54,"props":2758,"children":2759},{"style":66},[2760],{"type":20,"value":1816},{"type":15,"tag":16,"props":2762,"children":2763},{},[2764],{"type":20,"value":2765},"Or check Activity Monitor.",{"type":15,"tag":1577,"props":2767,"children":2768},{},[2769],{"type":20,"value":1581},{"title":7,"searchDepth":232,"depth":232,"links":2771},[2772,2773,2774],{"id":2252,"depth":232,"text":2255},{"id":2300,"depth":232,"text":2303},{"id":2640,"depth":232,"text":2643},"content:blog:global-hotkey-to-toggle-cmux-with-hammerspoon.md","blog/global-hotkey-to-toggle-cmux-with-hammerspoon.md","blog/global-hotkey-to-toggle-cmux-with-hammerspoon",1777867099819]