[{"data":1,"prerenderedAt":2146},["ShallowReactive",2],{"blog-tildewin-macos-style-window-switching-on-windows":3,"blog-surround-tildewin-macos-style-window-switching-on-windows":582},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"body":11,"_type":576,"_id":577,"_source":578,"_file":579,"_stem":580,"_extension":581},"/blog/tildewin-macos-style-window-switching-on-windows","blog",false,"","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":13,"toc":568},"root",[14,31,55,62,67,94,106,112,117,122,161,166,172,177,188,193,222,233,238,271,276,282,304,343,375,387,393,413,436,449,499,528,534,557,562],{"type":15,"tag":16,"props":17,"children":18},"element","p",{},[19,22,29],{"type":20,"value":21},"text","One shortcut I keep missing on Windows is ",{"type":15,"tag":23,"props":24,"children":26},"code",{"className":25},[],[27],{"type":20,"value":28},"Cmd + grave",{"type":20,"value":30}," 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":32,"children":33},{},[34,36,42,44,53],{"type":20,"value":35},"Windows has ",{"type":15,"tag":23,"props":37,"children":39},{"className":38},[],[40],{"type":20,"value":41},"Alt + Tab",{"type":20,"value":43},", 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":45,"props":46,"children":50},"a",{"href":47,"rel":48},"https://github.com/ibnuh/tildewin",[49],"nofollow",[51],{"type":20,"value":52},"TildeWin",{"type":20,"value":54},".",{"type":15,"tag":56,"props":57,"children":59},"h2",{"id":58},"what-it-does",[60],{"type":20,"value":61},"What it does",{"type":15,"tag":16,"props":63,"children":64},{},[65],{"type":20,"value":66},"TildeWin adds these shortcuts:",{"type":15,"tag":68,"props":69,"children":70},"ul",{},[71,83],{"type":15,"tag":72,"props":73,"children":74},"li",{},[75,81],{"type":15,"tag":23,"props":76,"children":78},{"className":77},[],[79],{"type":20,"value":80},"Win + grave",{"type":20,"value":82},": switch to the next window in the current app.",{"type":15,"tag":72,"props":84,"children":85},{},[86,92],{"type":15,"tag":23,"props":87,"children":89},{"className":88},[],[90],{"type":20,"value":91},"Win + Shift + grave",{"type":20,"value":93},": switch to the previous window in the current app.",{"type":15,"tag":16,"props":95,"children":96},{},[97,99,104],{"type":20,"value":98},"So if I am focused on a Chrome window, ",{"type":15,"tag":23,"props":100,"children":102},{"className":101},[],[103],{"type":20,"value":80},{"type":20,"value":105}," 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":56,"props":107,"children":109},{"id":108},"why-autohotkey",[110],{"type":20,"value":111},"Why AutoHotkey",{"type":15,"tag":16,"props":113,"children":114},{},[115],{"type":20,"value":116},"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":118,"children":119},{},[120],{"type":20,"value":121},"For this first version, grouping is based on executable name:",{"type":15,"tag":68,"props":123,"children":124},{},[125,134,143,152],{"type":15,"tag":72,"props":126,"children":127},{},[128],{"type":15,"tag":23,"props":129,"children":131},{"className":130},[],[132],{"type":20,"value":133},"chrome.exe",{"type":15,"tag":72,"props":135,"children":136},{},[137],{"type":15,"tag":23,"props":138,"children":140},{"className":139},[],[141],{"type":20,"value":142},"Code.exe",{"type":15,"tag":72,"props":144,"children":145},{},[146],{"type":15,"tag":23,"props":147,"children":149},{"className":148},[],[150],{"type":20,"value":151},"explorer.exe",{"type":15,"tag":72,"props":153,"children":154},{},[155],{"type":15,"tag":23,"props":156,"children":158},{"className":157},[],[159],{"type":20,"value":160},"notepad.exe",{"type":15,"tag":16,"props":162,"children":163},{},[164],{"type":20,"value":165},"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":56,"props":167,"children":169},{"id":168},"the-script",[170],{"type":20,"value":171},"The script",{"type":15,"tag":16,"props":173,"children":174},{},[175],{"type":20,"value":176},"The full script is in the repo:",{"type":15,"tag":178,"props":179,"children":183},"pre",{"className":180,"code":182,"language":20,"meta":7},[181],"language-text","https://github.com/ibnuh/tildewin\n",[184],{"type":15,"tag":23,"props":185,"children":186},{"__ignoreMap":7},[187],{"type":20,"value":182},{"type":15,"tag":16,"props":189,"children":190},{},[191],{"type":20,"value":192},"The important part is this:",{"type":15,"tag":178,"props":194,"children":198},{"className":195,"code":196,"language":197,"meta":7,"style":7},"language-autohotkey shiki shiki-themes one-dark-pro","#vkC0::SwitchSameAppWindow(1)\n#+vkC0::SwitchSameAppWindow(-1)\n","autohotkey",[199],{"type":15,"tag":23,"props":200,"children":201},{"__ignoreMap":7},[202,213],{"type":15,"tag":203,"props":204,"children":207},"span",{"class":205,"line":206},"line",1,[208],{"type":15,"tag":203,"props":209,"children":210},{},[211],{"type":20,"value":212},"#vkC0::SwitchSameAppWindow(1)\n",{"type":15,"tag":203,"props":214,"children":216},{"class":205,"line":215},2,[217],{"type":15,"tag":203,"props":218,"children":219},{},[220],{"type":20,"value":221},"#+vkC0::SwitchSameAppWindow(-1)\n",{"type":15,"tag":16,"props":223,"children":224},{},[225,231],{"type":15,"tag":23,"props":226,"children":228},{"className":227},[],[229],{"type":20,"value":230},"vkC0",{"type":20,"value":232}," 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":234,"children":235},{},[236],{"type":20,"value":237},"The script skips windows that should not behave like normal app windows:",{"type":15,"tag":68,"props":239,"children":240},{},[241,246,251,256,261,266],{"type":15,"tag":72,"props":242,"children":243},{},[244],{"type":20,"value":245},"minimized windows",{"type":15,"tag":72,"props":247,"children":248},{},[249],{"type":20,"value":250},"hidden or cloaked windows",{"type":15,"tag":72,"props":252,"children":253},{},[254],{"type":20,"value":255},"tool windows",{"type":15,"tag":72,"props":257,"children":258},{},[259],{"type":20,"value":260},"no-activate windows",{"type":15,"tag":72,"props":262,"children":263},{},[264],{"type":20,"value":265},"disabled windows",{"type":15,"tag":72,"props":267,"children":268},{},[269],{"type":20,"value":270},"desktop and taskbar shell windows",{"type":15,"tag":16,"props":272,"children":273},{},[274],{"type":20,"value":275},"This makes the shortcut feel closer to how I expect app window switching to work.",{"type":15,"tag":56,"props":277,"children":279},{"id":278},"setup",[280],{"type":20,"value":281},"Setup",{"type":15,"tag":283,"props":284,"children":285},"ol",{},[286,299],{"type":15,"tag":72,"props":287,"children":288},{},[289,291,298],{"type":20,"value":290},"Install ",{"type":15,"tag":45,"props":292,"children":295},{"href":293,"rel":294},"https://www.autohotkey.com/",[49],[296],{"type":20,"value":297},"AutoHotkey v2",{"type":20,"value":54},{"type":15,"tag":72,"props":300,"children":301},{},[302],{"type":20,"value":303},"Download or clone TildeWin:",{"type":15,"tag":178,"props":305,"children":309},{"className":306,"code":307,"language":308,"meta":7,"style":7},"language-powershell shiki shiki-themes one-dark-pro","git clone https://github.com/ibnuh/tildewin.git\n","powershell",[310],{"type":15,"tag":23,"props":311,"children":312},{"__ignoreMap":7},[313],{"type":15,"tag":203,"props":314,"children":315},{"class":205,"line":206},[316,322,328,333,338],{"type":15,"tag":203,"props":317,"children":319},{"style":318},"--shiki-default:#ABB2BF",[320],{"type":20,"value":321},"git clone https:",{"type":15,"tag":203,"props":323,"children":325},{"style":324},"--shiki-default:#56B6C2",[326],{"type":20,"value":327},"//github.com/",{"type":15,"tag":203,"props":329,"children":330},{"style":318},[331],{"type":20,"value":332},"ibnuh",{"type":15,"tag":203,"props":334,"children":335},{"style":324},[336],{"type":20,"value":337},"/",{"type":15,"tag":203,"props":339,"children":340},{"style":318},[341],{"type":20,"value":342},"tildewin.git\n",{"type":15,"tag":283,"props":344,"children":346},{"start":345},3,[347,359,364],{"type":15,"tag":72,"props":348,"children":349},{},[350,352,358],{"type":20,"value":351},"Run ",{"type":15,"tag":23,"props":353,"children":355},{"className":354},[],[356],{"type":20,"value":357},"tildewin.ahk",{"type":20,"value":54},{"type":15,"tag":72,"props":360,"children":361},{},[362],{"type":20,"value":363},"Open multiple windows from the same app.",{"type":15,"tag":72,"props":365,"children":366},{},[367,369,374],{"type":20,"value":368},"Press ",{"type":15,"tag":23,"props":370,"children":372},{"className":371},[],[373],{"type":20,"value":80},{"type":20,"value":54},{"type":15,"tag":16,"props":376,"children":377},{},[378,380,385],{"type":20,"value":379},"To run it automatically on startup, put a shortcut to ",{"type":15,"tag":23,"props":381,"children":383},{"className":382},[],[384],{"type":20,"value":357},{"type":20,"value":386}," in the Windows Startup folder.",{"type":15,"tag":56,"props":388,"children":390},{"id":389},"changing-the-hotkey",[391],{"type":20,"value":392},"Changing the hotkey",{"type":15,"tag":16,"props":394,"children":395},{},[396,398,403,405,411],{"type":20,"value":397},"If ",{"type":15,"tag":23,"props":399,"children":401},{"className":400},[],[402],{"type":20,"value":80},{"type":20,"value":404}," does not feel right, the script includes ",{"type":15,"tag":23,"props":406,"children":408},{"className":407},[],[409],{"type":20,"value":410},"Alt + grave",{"type":20,"value":412}," bindings as comments:",{"type":15,"tag":178,"props":414,"children":416},{"className":195,"code":415,"language":197,"meta":7,"style":7},"; !vkC0::SwitchSameAppWindow(1)\n; !+vkC0::SwitchSameAppWindow(-1)\n",[417],{"type":15,"tag":23,"props":418,"children":419},{"__ignoreMap":7},[420,428],{"type":15,"tag":203,"props":421,"children":422},{"class":205,"line":206},[423],{"type":15,"tag":203,"props":424,"children":425},{},[426],{"type":20,"value":427},"; !vkC0::SwitchSameAppWindow(1)\n",{"type":15,"tag":203,"props":429,"children":430},{"class":205,"line":215},[431],{"type":15,"tag":203,"props":432,"children":433},{},[434],{"type":20,"value":435},"; !+vkC0::SwitchSameAppWindow(-1)\n",{"type":15,"tag":16,"props":437,"children":438},{},[439,441,447],{"type":20,"value":440},"Uncomment those lines and comment out the ",{"type":15,"tag":23,"props":442,"children":444},{"className":443},[],[445],{"type":20,"value":446},"#vkC0",{"type":20,"value":448}," lines:",{"type":15,"tag":178,"props":450,"children":452},{"className":195,"code":451,"language":197,"meta":7,"style":7},"; #vkC0::SwitchSameAppWindow(1)\n; #+vkC0::SwitchSameAppWindow(-1)\n\n!vkC0::SwitchSameAppWindow(1)\n!+vkC0::SwitchSameAppWindow(-1)\n",[453],{"type":15,"tag":23,"props":454,"children":455},{"__ignoreMap":7},[456,464,472,481,490],{"type":15,"tag":203,"props":457,"children":458},{"class":205,"line":206},[459],{"type":15,"tag":203,"props":460,"children":461},{},[462],{"type":20,"value":463},"; #vkC0::SwitchSameAppWindow(1)\n",{"type":15,"tag":203,"props":465,"children":466},{"class":205,"line":215},[467],{"type":15,"tag":203,"props":468,"children":469},{},[470],{"type":20,"value":471},"; #+vkC0::SwitchSameAppWindow(-1)\n",{"type":15,"tag":203,"props":473,"children":474},{"class":205,"line":345},[475],{"type":15,"tag":203,"props":476,"children":478},{"emptyLinePlaceholder":477},true,[479],{"type":20,"value":480},"\n",{"type":15,"tag":203,"props":482,"children":484},{"class":205,"line":483},4,[485],{"type":15,"tag":203,"props":486,"children":487},{},[488],{"type":20,"value":489},"!vkC0::SwitchSameAppWindow(1)\n",{"type":15,"tag":203,"props":491,"children":493},{"class":205,"line":492},5,[494],{"type":15,"tag":203,"props":495,"children":496},{},[497],{"type":20,"value":498},"!+vkC0::SwitchSameAppWindow(-1)\n",{"type":15,"tag":16,"props":500,"children":501},{},[502,504,510,512,518,520,526],{"type":20,"value":503},"In AutoHotkey syntax, ",{"type":15,"tag":23,"props":505,"children":507},{"className":506},[],[508],{"type":20,"value":509},"#",{"type":20,"value":511}," means Win, ",{"type":15,"tag":23,"props":513,"children":515},{"className":514},[],[516],{"type":20,"value":517},"!",{"type":20,"value":519}," means Alt, and ",{"type":15,"tag":23,"props":521,"children":523},{"className":522},[],[524],{"type":20,"value":525},"+",{"type":20,"value":527}," means Shift.",{"type":15,"tag":56,"props":529,"children":531},{"id":530},"things-to-know",[532],{"type":20,"value":533},"Things to know",{"type":15,"tag":68,"props":535,"children":536},{},[537,542,547,552],{"type":15,"tag":72,"props":538,"children":539},{},[540],{"type":20,"value":541},"Admin windows may need the script to run as administrator.",{"type":15,"tag":72,"props":543,"children":544},{},[545],{"type":20,"value":546},"Browser tabs are not separate windows. This switches browser windows, not tabs.",{"type":15,"tag":72,"props":548,"children":549},{},[550],{"type":20,"value":551},"Apps with unusual window models may not behave perfectly.",{"type":15,"tag":72,"props":553,"children":554},{},[555],{"type":20,"value":556},"The current version does not use Windows AppUserModelID yet, so process-name grouping is the main rule.",{"type":15,"tag":16,"props":558,"children":559},{},[560],{"type":20,"value":561},"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":563,"props":564,"children":565},"style",{},[566],{"type":20,"value":567},"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":215,"depth":215,"links":569},[570,571,572,573,574,575],{"id":58,"depth":215,"text":61},{"id":108,"depth":215,"text":111},{"id":168,"depth":215,"text":171},{"id":278,"depth":215,"text":281},{"id":389,"depth":215,"text":392},{"id":530,"depth":215,"text":533},"markdown","content:blog:tildewin-macos-style-window-switching-on-windows.md","content","blog/tildewin-macos-style-window-switching-on-windows.md","blog/tildewin-macos-style-window-switching-on-windows","md",[583,584],null,{"_path":585,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":586,"description":587,"date":588,"body":589,"_type":576,"_id":2143,"_source":578,"_file":2144,"_stem":2145,"_extension":581},"/blog/cutting-powershell-startup-time-in-half","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":590,"toc":2134},[591,596,603,616,666,671,722,727,740,745,751,763,1054,1059,1126,1131,1137,1148,1438,1443,1449,1476,1715,1727,1747,1753,1765,2004,2016,2022,2070,2075,2079,2125,2130],{"type":15,"tag":16,"props":592,"children":593},{},[594],{"type":20,"value":595},"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":597,"props":598,"children":600},"h3",{"id":599},"measure-first-guess-later",[601],{"type":20,"value":602},"Measure first, guess later",{"type":15,"tag":16,"props":604,"children":605},{},[606,608,614],{"type":20,"value":607},"PowerShell has a built in ",{"type":15,"tag":23,"props":609,"children":611},{"className":610},[],[612],{"type":20,"value":613},"Measure-Command",{"type":20,"value":615}," 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":178,"props":617,"children":619},{"className":306,"code":618,"language":308,"meta":7,"style":7},"Measure-Command { pwsh -Command 'exit' } | Select-Object TotalMilliseconds\n",[620],{"type":15,"tag":23,"props":621,"children":622},{"__ignoreMap":7},[623],{"type":15,"tag":203,"props":624,"children":625},{"class":205,"line":206},[626,630,635,640,645,651,656,661],{"type":15,"tag":203,"props":627,"children":628},{"style":324},[629],{"type":20,"value":613},{"type":15,"tag":203,"props":631,"children":632},{"style":318},[633],{"type":20,"value":634}," { pwsh ",{"type":15,"tag":203,"props":636,"children":637},{"style":324},[638],{"type":20,"value":639},"-",{"type":15,"tag":203,"props":641,"children":642},{"style":318},[643],{"type":20,"value":644},"Command ",{"type":15,"tag":203,"props":646,"children":648},{"style":647},"--shiki-default:#98C379",[649],{"type":20,"value":650},"'exit'",{"type":15,"tag":203,"props":652,"children":653},{"style":318},[654],{"type":20,"value":655}," } | ",{"type":15,"tag":203,"props":657,"children":658},{"style":324},[659],{"type":20,"value":660},"Select-Object",{"type":15,"tag":203,"props":662,"children":663},{"style":318},[664],{"type":20,"value":665}," TotalMilliseconds\n",{"type":15,"tag":16,"props":667,"children":668},{},[669],{"type":20,"value":670},"And to compare against a clean startup without your profile:",{"type":15,"tag":178,"props":672,"children":674},{"className":306,"code":673,"language":308,"meta":7,"style":7},"Measure-Command { pwsh -NoProfile -Command 'exit' } | Select-Object TotalMilliseconds\n",[675],{"type":15,"tag":23,"props":676,"children":677},{"__ignoreMap":7},[678],{"type":15,"tag":203,"props":679,"children":680},{"class":205,"line":206},[681,685,689,693,698,702,706,710,714,718],{"type":15,"tag":203,"props":682,"children":683},{"style":324},[684],{"type":20,"value":613},{"type":15,"tag":203,"props":686,"children":687},{"style":318},[688],{"type":20,"value":634},{"type":15,"tag":203,"props":690,"children":691},{"style":324},[692],{"type":20,"value":639},{"type":15,"tag":203,"props":694,"children":695},{"style":318},[696],{"type":20,"value":697},"NoProfile ",{"type":15,"tag":203,"props":699,"children":700},{"style":324},[701],{"type":20,"value":639},{"type":15,"tag":203,"props":703,"children":704},{"style":318},[705],{"type":20,"value":644},{"type":15,"tag":203,"props":707,"children":708},{"style":647},[709],{"type":20,"value":650},{"type":15,"tag":203,"props":711,"children":712},{"style":318},[713],{"type":20,"value":655},{"type":15,"tag":203,"props":715,"children":716},{"style":324},[717],{"type":20,"value":660},{"type":15,"tag":203,"props":719,"children":720},{"style":318},[721],{"type":20,"value":665},{"type":15,"tag":16,"props":723,"children":724},{},[725],{"type":20,"value":726},"The difference is all profile overhead. Mine was:",{"type":15,"tag":68,"props":728,"children":729},{},[730,735],{"type":15,"tag":72,"props":731,"children":732},{},[733],{"type":20,"value":734},"With profile: ~905ms",{"type":15,"tag":72,"props":736,"children":737},{},[738],{"type":20,"value":739},"Without profile: ~225ms",{"type":15,"tag":16,"props":741,"children":742},{},[743],{"type":20,"value":744},"So my profile was adding nearly 700ms. Time to find out where.",{"type":15,"tag":597,"props":746,"children":748},{"id":747},"finding-the-slow-parts",[749],{"type":20,"value":750},"Finding the slow parts",{"type":15,"tag":16,"props":752,"children":753},{},[754,756,761],{"type":20,"value":755},"I wrapped each suspicious line in the profile with ",{"type":15,"tag":23,"props":757,"children":759},{"className":758},[],[760],{"type":20,"value":613},{"type":20,"value":762}," and ran them one at a time in a fresh no-profile pwsh:",{"type":15,"tag":178,"props":764,"children":766},{"className":306,"code":765,"language":308,"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",[767],{"type":15,"tag":23,"props":768,"children":769},{"__ignoreMap":7},[770,793,810,893,901,908,929,969,977,998],{"type":15,"tag":203,"props":771,"children":772},{"class":205,"line":206},[773,778,783,788],{"type":15,"tag":203,"props":774,"children":775},{"style":324},[776],{"type":20,"value":777},"Write-Host",{"type":15,"tag":203,"props":779,"children":780},{"style":647},[781],{"type":20,"value":782}," 'oh-my-posh init: '",{"type":15,"tag":203,"props":784,"children":785},{"style":324},[786],{"type":20,"value":787}," -",{"type":15,"tag":203,"props":789,"children":790},{"style":318},[791],{"type":20,"value":792},"NoNewline\n",{"type":15,"tag":203,"props":794,"children":795},{"class":205,"line":215},[796,801,805],{"type":15,"tag":203,"props":797,"children":798},{"style":318},[799],{"type":20,"value":800},"(",{"type":15,"tag":203,"props":802,"children":803},{"style":324},[804],{"type":20,"value":613},{"type":15,"tag":203,"props":806,"children":807},{"style":318},[808],{"type":20,"value":809}," {\n",{"type":15,"tag":203,"props":811,"children":812},{"class":205,"line":345},[813,818,824,829,834,839,844,849,854,859,864,869,874,879,883,888],{"type":15,"tag":203,"props":814,"children":815},{"style":318},[816],{"type":20,"value":817},"    (",{"type":15,"tag":203,"props":819,"children":821},{"style":820},"--shiki-default:#C678DD",[822],{"type":20,"value":823},"@",{"type":15,"tag":203,"props":825,"children":826},{"style":318},[827],{"type":20,"value":828},"(& ",{"type":15,"tag":203,"props":830,"children":831},{"style":647},[832],{"type":20,"value":833},"'C:\\path\\to\\oh-my-posh.exe'",{"type":15,"tag":203,"props":835,"children":836},{"style":318},[837],{"type":20,"value":838}," init pwsh ",{"type":15,"tag":203,"props":840,"children":841},{"style":324},[842],{"type":20,"value":843},"--",{"type":15,"tag":203,"props":845,"children":846},{"style":318},[847],{"type":20,"value":848},"config",{"type":15,"tag":203,"props":850,"children":851},{"style":324},[852],{"type":20,"value":853},"=",{"type":15,"tag":203,"props":855,"children":856},{"style":647},[857],{"type":20,"value":858},"'C:\\path\\to\\config.json'",{"type":15,"tag":203,"props":860,"children":861},{"style":324},[862],{"type":20,"value":863}," --",{"type":15,"tag":203,"props":865,"children":866},{"style":318},[867],{"type":20,"value":868},"print) -join ",{"type":15,"tag":203,"props":870,"children":871},{"style":647},[872],{"type":20,"value":873},"\"",{"type":15,"tag":203,"props":875,"children":876},{"style":324},[877],{"type":20,"value":878},"`n",{"type":15,"tag":203,"props":880,"children":881},{"style":647},[882],{"type":20,"value":873},{"type":15,"tag":203,"props":884,"children":885},{"style":318},[886],{"type":20,"value":887},") | ",{"type":15,"tag":203,"props":889,"children":890},{"style":324},[891],{"type":20,"value":892},"Invoke-Expression\n",{"type":15,"tag":203,"props":894,"children":895},{"class":205,"line":483},[896],{"type":15,"tag":203,"props":897,"children":898},{"style":318},[899],{"type":20,"value":900},"}).TotalMilliseconds\n",{"type":15,"tag":203,"props":902,"children":903},{"class":205,"line":492},[904],{"type":15,"tag":203,"props":905,"children":906},{"emptyLinePlaceholder":477},[907],{"type":20,"value":480},{"type":15,"tag":203,"props":909,"children":911},{"class":205,"line":910},6,[912,916,921,925],{"type":15,"tag":203,"props":913,"children":914},{"style":324},[915],{"type":20,"value":777},{"type":15,"tag":203,"props":917,"children":918},{"style":647},[919],{"type":20,"value":920}," 'Terminal-Icons import: '",{"type":15,"tag":203,"props":922,"children":923},{"style":324},[924],{"type":20,"value":787},{"type":15,"tag":203,"props":926,"children":927},{"style":318},[928],{"type":20,"value":792},{"type":15,"tag":203,"props":930,"children":932},{"class":205,"line":931},7,[933,937,941,946,951,955,960,964],{"type":15,"tag":203,"props":934,"children":935},{"style":318},[936],{"type":20,"value":800},{"type":15,"tag":203,"props":938,"children":939},{"style":324},[940],{"type":20,"value":613},{"type":15,"tag":203,"props":942,"children":943},{"style":318},[944],{"type":20,"value":945}," { ",{"type":15,"tag":203,"props":947,"children":948},{"style":324},[949],{"type":20,"value":950},"Import-Module",{"type":15,"tag":203,"props":952,"children":953},{"style":324},[954],{"type":20,"value":787},{"type":15,"tag":203,"props":956,"children":957},{"style":318},[958],{"type":20,"value":959},"Name Terminal",{"type":15,"tag":203,"props":961,"children":962},{"style":324},[963],{"type":20,"value":639},{"type":15,"tag":203,"props":965,"children":966},{"style":318},[967],{"type":20,"value":968},"Icons }).TotalMilliseconds\n",{"type":15,"tag":203,"props":970,"children":972},{"class":205,"line":971},8,[973],{"type":15,"tag":203,"props":974,"children":975},{"emptyLinePlaceholder":477},[976],{"type":20,"value":480},{"type":15,"tag":203,"props":978,"children":980},{"class":205,"line":979},9,[981,985,990,994],{"type":15,"tag":203,"props":982,"children":983},{"style":324},[984],{"type":20,"value":777},{"type":15,"tag":203,"props":986,"children":987},{"style":647},[988],{"type":20,"value":989}," 'fnm env: '",{"type":15,"tag":203,"props":991,"children":992},{"style":324},[993],{"type":20,"value":787},{"type":15,"tag":203,"props":995,"children":996},{"style":318},[997],{"type":20,"value":792},{"type":15,"tag":203,"props":999,"children":1001},{"class":205,"line":1000},10,[1002,1006,1010,1015,1020,1025,1029,1034,1039,1044,1049],{"type":15,"tag":203,"props":1003,"children":1004},{"style":318},[1005],{"type":20,"value":800},{"type":15,"tag":203,"props":1007,"children":1008},{"style":324},[1009],{"type":20,"value":613},{"type":15,"tag":203,"props":1011,"children":1012},{"style":318},[1013],{"type":20,"value":1014}," { fnm env ",{"type":15,"tag":203,"props":1016,"children":1017},{"style":324},[1018],{"type":20,"value":1019},"--use-on-",{"type":15,"tag":203,"props":1021,"children":1022},{"style":318},[1023],{"type":20,"value":1024},"cd ",{"type":15,"tag":203,"props":1026,"children":1027},{"style":324},[1028],{"type":20,"value":843},{"type":15,"tag":203,"props":1030,"children":1031},{"style":318},[1032],{"type":20,"value":1033},"shell powershell | ",{"type":15,"tag":203,"props":1035,"children":1036},{"style":324},[1037],{"type":20,"value":1038},"Out-String",{"type":15,"tag":203,"props":1040,"children":1041},{"style":318},[1042],{"type":20,"value":1043}," | ",{"type":15,"tag":203,"props":1045,"children":1046},{"style":324},[1047],{"type":20,"value":1048},"Invoke-Expression",{"type":15,"tag":203,"props":1050,"children":1051},{"style":318},[1052],{"type":20,"value":1053}," }).TotalMilliseconds\n",{"type":15,"tag":16,"props":1055,"children":1056},{},[1057],{"type":20,"value":1058},"Results:",{"type":15,"tag":1060,"props":1061,"children":1062},"table",{},[1063,1082],{"type":15,"tag":1064,"props":1065,"children":1066},"thead",{},[1067],{"type":15,"tag":1068,"props":1069,"children":1070},"tr",{},[1071,1077],{"type":15,"tag":1072,"props":1073,"children":1074},"th",{},[1075],{"type":20,"value":1076},"Thing",{"type":15,"tag":1072,"props":1078,"children":1079},{},[1080],{"type":20,"value":1081},"Cost",{"type":15,"tag":1083,"props":1084,"children":1085},"tbody",{},[1086,1100,1113],{"type":15,"tag":1068,"props":1087,"children":1088},{},[1089,1095],{"type":15,"tag":1090,"props":1091,"children":1092},"td",{},[1093],{"type":20,"value":1094},"oh-my-posh init",{"type":15,"tag":1090,"props":1096,"children":1097},{},[1098],{"type":20,"value":1099},"~377ms",{"type":15,"tag":1068,"props":1101,"children":1102},{},[1103,1108],{"type":15,"tag":1090,"props":1104,"children":1105},{},[1106],{"type":20,"value":1107},"Terminal-Icons import",{"type":15,"tag":1090,"props":1109,"children":1110},{},[1111],{"type":20,"value":1112},"~284ms",{"type":15,"tag":1068,"props":1114,"children":1115},{},[1116,1121],{"type":15,"tag":1090,"props":1117,"children":1118},{},[1119],{"type":20,"value":1120},"fnm env",{"type":15,"tag":1090,"props":1122,"children":1123},{},[1124],{"type":20,"value":1125},"~60ms",{"type":15,"tag":16,"props":1127,"children":1128},{},[1129],{"type":20,"value":1130},"Three culprits. None of them are doing anything wrong, they just have to run every single time a shell opens.",{"type":15,"tag":597,"props":1132,"children":1134},{"id":1133},"fix-1-cache-oh-my-posh-init",[1135],{"type":20,"value":1136},"Fix 1: cache oh-my-posh init",{"type":15,"tag":16,"props":1138,"children":1139},{},[1140,1146],{"type":15,"tag":23,"props":1141,"children":1143},{"className":1142},[],[1144],{"type":20,"value":1145},"oh-my-posh init pwsh",{"type":20,"value":1147}," 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":178,"props":1149,"children":1151},{"className":306,"code":1150,"language":308,"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",[1152],{"type":15,"tag":23,"props":1153,"children":1154},{"__ignoreMap":7},[1155,1174,1191,1218,1260,1307,1349,1417,1425],{"type":15,"tag":203,"props":1156,"children":1157},{"class":205,"line":206},[1158,1164,1169],{"type":15,"tag":203,"props":1159,"children":1161},{"style":1160},"--shiki-default:#E06C75",[1162],{"type":20,"value":1163},"$ompExe",{"type":15,"tag":203,"props":1165,"children":1166},{"style":324},[1167],{"type":20,"value":1168}," =",{"type":15,"tag":203,"props":1170,"children":1171},{"style":647},[1172],{"type":20,"value":1173}," 'C:\\Users\\ibnuh\\AppData\\Local\\Microsoft\\WindowsApps\\oh-my-posh.exe'\n",{"type":15,"tag":203,"props":1175,"children":1176},{"class":205,"line":215},[1177,1182,1186],{"type":15,"tag":203,"props":1178,"children":1179},{"style":1160},[1180],{"type":20,"value":1181},"$ompConfig",{"type":15,"tag":203,"props":1183,"children":1184},{"style":324},[1185],{"type":20,"value":1168},{"type":15,"tag":203,"props":1187,"children":1188},{"style":647},[1189],{"type":20,"value":1190}," 'C:\\Users\\ibnuh\\Documents\\PowerShell\\wopian.omp.json'\n",{"type":15,"tag":203,"props":1192,"children":1193},{"class":205,"line":345},[1194,1199,1203,1208,1213],{"type":15,"tag":203,"props":1195,"children":1196},{"style":1160},[1197],{"type":20,"value":1198},"$ompCache",{"type":15,"tag":203,"props":1200,"children":1201},{"style":324},[1202],{"type":20,"value":1168},{"type":15,"tag":203,"props":1204,"children":1205},{"style":324},[1206],{"type":20,"value":1207}," Join-Path",{"type":15,"tag":203,"props":1209,"children":1210},{"style":1160},[1211],{"type":20,"value":1212}," $env:TEMP",{"type":15,"tag":203,"props":1214,"children":1215},{"style":647},[1216],{"type":20,"value":1217}," 'omp-init-wopian.ps1'\n",{"type":15,"tag":203,"props":1219,"children":1220},{"class":205,"line":483},[1221,1226,1231,1236,1240,1245,1250,1255],{"type":15,"tag":203,"props":1222,"children":1223},{"style":820},[1224],{"type":20,"value":1225},"if",{"type":15,"tag":203,"props":1227,"children":1228},{"style":318},[1229],{"type":20,"value":1230}," (",{"type":15,"tag":203,"props":1232,"children":1233},{"style":324},[1234],{"type":20,"value":1235},"-not",{"type":15,"tag":203,"props":1237,"children":1238},{"style":318},[1239],{"type":20,"value":1230},{"type":15,"tag":203,"props":1241,"children":1242},{"style":324},[1243],{"type":20,"value":1244},"Test-Path",{"type":15,"tag":203,"props":1246,"children":1247},{"style":1160},[1248],{"type":20,"value":1249}," $ompCache",{"type":15,"tag":203,"props":1251,"children":1252},{"style":318},[1253],{"type":20,"value":1254},") ",{"type":15,"tag":203,"props":1256,"children":1257},{"style":324},[1258],{"type":20,"value":1259},"-or\n",{"type":15,"tag":203,"props":1261,"children":1262},{"class":205,"line":492},[1263,1267,1272,1277,1282,1287,1291,1295,1299,1303],{"type":15,"tag":203,"props":1264,"children":1265},{"style":318},[1266],{"type":20,"value":817},{"type":15,"tag":203,"props":1268,"children":1269},{"style":324},[1270],{"type":20,"value":1271},"Get-Item",{"type":15,"tag":203,"props":1273,"children":1274},{"style":1160},[1275],{"type":20,"value":1276}," $ompConfig",{"type":15,"tag":203,"props":1278,"children":1279},{"style":318},[1280],{"type":20,"value":1281},").LastWriteTime ",{"type":15,"tag":203,"props":1283,"children":1284},{"style":324},[1285],{"type":20,"value":1286},"-gt",{"type":15,"tag":203,"props":1288,"children":1289},{"style":318},[1290],{"type":20,"value":1230},{"type":15,"tag":203,"props":1292,"children":1293},{"style":324},[1294],{"type":20,"value":1271},{"type":15,"tag":203,"props":1296,"children":1297},{"style":1160},[1298],{"type":20,"value":1249},{"type":15,"tag":203,"props":1300,"children":1301},{"style":318},[1302],{"type":20,"value":1281},{"type":15,"tag":203,"props":1304,"children":1305},{"style":324},[1306],{"type":20,"value":1259},{"type":15,"tag":203,"props":1308,"children":1309},{"class":205,"line":910},[1310,1314,1318,1323,1328,1332,1336,1340,1344],{"type":15,"tag":203,"props":1311,"children":1312},{"style":318},[1313],{"type":20,"value":817},{"type":15,"tag":203,"props":1315,"children":1316},{"style":324},[1317],{"type":20,"value":1271},{"type":15,"tag":203,"props":1319,"children":1320},{"style":1160},[1321],{"type":20,"value":1322}," $ompExe",{"type":15,"tag":203,"props":1324,"children":1325},{"style":318},[1326],{"type":20,"value":1327},").LastWriteTime   ",{"type":15,"tag":203,"props":1329,"children":1330},{"style":324},[1331],{"type":20,"value":1286},{"type":15,"tag":203,"props":1333,"children":1334},{"style":318},[1335],{"type":20,"value":1230},{"type":15,"tag":203,"props":1337,"children":1338},{"style":324},[1339],{"type":20,"value":1271},{"type":15,"tag":203,"props":1341,"children":1342},{"style":1160},[1343],{"type":20,"value":1249},{"type":15,"tag":203,"props":1345,"children":1346},{"style":318},[1347],{"type":20,"value":1348},").LastWriteTime) {\n",{"type":15,"tag":203,"props":1350,"children":1351},{"class":205,"line":931},[1352,1357,1361,1365,1369,1373,1377,1381,1385,1390,1395,1399,1404,1408,1412],{"type":15,"tag":203,"props":1353,"children":1354},{"style":318},[1355],{"type":20,"value":1356},"    & ",{"type":15,"tag":203,"props":1358,"children":1359},{"style":1160},[1360],{"type":20,"value":1163},{"type":15,"tag":203,"props":1362,"children":1363},{"style":318},[1364],{"type":20,"value":838},{"type":15,"tag":203,"props":1366,"children":1367},{"style":324},[1368],{"type":20,"value":843},{"type":15,"tag":203,"props":1370,"children":1371},{"style":318},[1372],{"type":20,"value":848},{"type":15,"tag":203,"props":1374,"children":1375},{"style":324},[1376],{"type":20,"value":853},{"type":15,"tag":203,"props":1378,"children":1379},{"style":1160},[1380],{"type":20,"value":1181},{"type":15,"tag":203,"props":1382,"children":1383},{"style":324},[1384],{"type":20,"value":863},{"type":15,"tag":203,"props":1386,"children":1387},{"style":318},[1388],{"type":20,"value":1389},"print | ",{"type":15,"tag":203,"props":1391,"children":1392},{"style":324},[1393],{"type":20,"value":1394},"Out-File",{"type":15,"tag":203,"props":1396,"children":1397},{"style":324},[1398],{"type":20,"value":787},{"type":15,"tag":203,"props":1400,"children":1401},{"style":318},[1402],{"type":20,"value":1403},"FilePath ",{"type":15,"tag":203,"props":1405,"children":1406},{"style":1160},[1407],{"type":20,"value":1198},{"type":15,"tag":203,"props":1409,"children":1410},{"style":324},[1411],{"type":20,"value":787},{"type":15,"tag":203,"props":1413,"children":1414},{"style":318},[1415],{"type":20,"value":1416},"Encoding utf8\n",{"type":15,"tag":203,"props":1418,"children":1419},{"class":205,"line":971},[1420],{"type":15,"tag":203,"props":1421,"children":1422},{"style":318},[1423],{"type":20,"value":1424},"}\n",{"type":15,"tag":203,"props":1426,"children":1427},{"class":205,"line":979},[1428,1433],{"type":15,"tag":203,"props":1429,"children":1430},{"style":318},[1431],{"type":20,"value":1432},". ",{"type":15,"tag":203,"props":1434,"children":1435},{"style":1160},[1436],{"type":20,"value":1437},"$ompCache\n",{"type":15,"tag":16,"props":1439,"children":1440},{},[1441],{"type":20,"value":1442},"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":597,"props":1444,"children":1446},{"id":1445},"fix-2-lazy-load-terminal-icons",[1447],{"type":20,"value":1448},"Fix 2: lazy load Terminal-Icons",{"type":15,"tag":16,"props":1450,"children":1451},{},[1452,1454,1460,1462,1467,1469,1474],{"type":20,"value":1453},"Terminal-Icons is a formatter that renders pretty icons next to files in ",{"type":15,"tag":23,"props":1455,"children":1457},{"className":1456},[],[1458],{"type":20,"value":1459},"ls",{"type":20,"value":1461}," output. You only need it when you actually run ",{"type":15,"tag":23,"props":1463,"children":1465},{"className":1464},[],[1466],{"type":20,"value":1459},{"type":20,"value":1468},". So instead of eagerly importing it at shell startup, I defer it to the first time ",{"type":15,"tag":23,"props":1470,"children":1472},{"className":1471},[],[1473],{"type":20,"value":1459},{"type":20,"value":1475}," is called:",{"type":15,"tag":178,"props":1477,"children":1479},{"className":306,"code":1478,"language":308,"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",[1480],{"type":15,"tag":23,"props":1481,"children":1482},{"__ignoreMap":7},[1483,1492,1526,1548,1555,1583,1601,1635,1660,1685,1693,1707],{"type":15,"tag":203,"props":1484,"children":1485},{"class":205,"line":206},[1486],{"type":15,"tag":203,"props":1487,"children":1489},{"style":1488},"--shiki-default:#7F848E;--shiki-default-font-style:italic",[1490],{"type":20,"value":1491},"# Remove the built-in `ls` alias first, since aliases win over functions\n",{"type":15,"tag":203,"props":1493,"children":1494},{"class":205,"line":215},[1495,1499,1503,1508,1512,1517,1521],{"type":15,"tag":203,"props":1496,"children":1497},{"style":820},[1498],{"type":20,"value":1225},{"type":15,"tag":203,"props":1500,"children":1501},{"style":318},[1502],{"type":20,"value":1230},{"type":15,"tag":203,"props":1504,"children":1505},{"style":324},[1506],{"type":20,"value":1507},"Get-Alias",{"type":15,"tag":203,"props":1509,"children":1510},{"style":324},[1511],{"type":20,"value":787},{"type":15,"tag":203,"props":1513,"children":1514},{"style":318},[1515],{"type":20,"value":1516},"Name ls ",{"type":15,"tag":203,"props":1518,"children":1519},{"style":324},[1520],{"type":20,"value":639},{"type":15,"tag":203,"props":1522,"children":1523},{"style":318},[1524],{"type":20,"value":1525},"ErrorAction SilentlyContinue) {\n",{"type":15,"tag":203,"props":1527,"children":1528},{"class":205,"line":345},[1529,1534,1539,1543],{"type":15,"tag":203,"props":1530,"children":1531},{"style":324},[1532],{"type":20,"value":1533},"    Remove-Item",{"type":15,"tag":203,"props":1535,"children":1536},{"style":318},[1537],{"type":20,"value":1538}," Alias:ls ",{"type":15,"tag":203,"props":1540,"children":1541},{"style":324},[1542],{"type":20,"value":639},{"type":15,"tag":203,"props":1544,"children":1545},{"style":318},[1546],{"type":20,"value":1547},"Force\n",{"type":15,"tag":203,"props":1549,"children":1550},{"class":205,"line":483},[1551],{"type":15,"tag":203,"props":1552,"children":1553},{"style":318},[1554],{"type":20,"value":1424},{"type":15,"tag":203,"props":1556,"children":1557},{"class":205,"line":492},[1558,1563,1568,1573,1577],{"type":15,"tag":203,"props":1559,"children":1560},{"style":1160},[1561],{"type":20,"value":1562},"$",{"type":15,"tag":203,"props":1564,"children":1565},{"style":820},[1566],{"type":20,"value":1567},"script",{"type":15,"tag":203,"props":1569,"children":1570},{"style":1160},[1571],{"type":20,"value":1572},":__TerminalIconsLoaded",{"type":15,"tag":203,"props":1574,"children":1575},{"style":324},[1576],{"type":20,"value":1168},{"type":15,"tag":203,"props":1578,"children":1580},{"style":1579},"--shiki-default:#D19A66",[1581],{"type":20,"value":1582}," $false\n",{"type":15,"tag":203,"props":1584,"children":1585},{"class":205,"line":910},[1586,1591,1597],{"type":15,"tag":203,"props":1587,"children":1588},{"style":820},[1589],{"type":20,"value":1590},"function",{"type":15,"tag":203,"props":1592,"children":1594},{"style":1593},"--shiki-default:#61AFEF",[1595],{"type":20,"value":1596}," ls",{"type":15,"tag":203,"props":1598,"children":1599},{"style":318},[1600],{"type":20,"value":809},{"type":15,"tag":203,"props":1602,"children":1603},{"class":205,"line":931},[1604,1609,1613,1617,1622,1626,1630],{"type":15,"tag":203,"props":1605,"children":1606},{"style":820},[1607],{"type":20,"value":1608},"    if",{"type":15,"tag":203,"props":1610,"children":1611},{"style":318},[1612],{"type":20,"value":1230},{"type":15,"tag":203,"props":1614,"children":1615},{"style":324},[1616],{"type":20,"value":1235},{"type":15,"tag":203,"props":1618,"children":1619},{"style":1160},[1620],{"type":20,"value":1621}," $",{"type":15,"tag":203,"props":1623,"children":1624},{"style":820},[1625],{"type":20,"value":1567},{"type":15,"tag":203,"props":1627,"children":1628},{"style":1160},[1629],{"type":20,"value":1572},{"type":15,"tag":203,"props":1631,"children":1632},{"style":318},[1633],{"type":20,"value":1634},") {\n",{"type":15,"tag":203,"props":1636,"children":1637},{"class":205,"line":971},[1638,1643,1647,1651,1655],{"type":15,"tag":203,"props":1639,"children":1640},{"style":324},[1641],{"type":20,"value":1642},"        Import-Module",{"type":15,"tag":203,"props":1644,"children":1645},{"style":324},[1646],{"type":20,"value":787},{"type":15,"tag":203,"props":1648,"children":1649},{"style":318},[1650],{"type":20,"value":959},{"type":15,"tag":203,"props":1652,"children":1653},{"style":324},[1654],{"type":20,"value":639},{"type":15,"tag":203,"props":1656,"children":1657},{"style":318},[1658],{"type":20,"value":1659},"Icons\n",{"type":15,"tag":203,"props":1661,"children":1662},{"class":205,"line":979},[1663,1668,1672,1676,1680],{"type":15,"tag":203,"props":1664,"children":1665},{"style":1160},[1666],{"type":20,"value":1667},"        $",{"type":15,"tag":203,"props":1669,"children":1670},{"style":820},[1671],{"type":20,"value":1567},{"type":15,"tag":203,"props":1673,"children":1674},{"style":1160},[1675],{"type":20,"value":1572},{"type":15,"tag":203,"props":1677,"children":1678},{"style":324},[1679],{"type":20,"value":1168},{"type":15,"tag":203,"props":1681,"children":1682},{"style":1579},[1683],{"type":20,"value":1684}," $true\n",{"type":15,"tag":203,"props":1686,"children":1687},{"class":205,"line":1000},[1688],{"type":15,"tag":203,"props":1689,"children":1690},{"style":318},[1691],{"type":20,"value":1692},"    }\n",{"type":15,"tag":203,"props":1694,"children":1696},{"class":205,"line":1695},11,[1697,1702],{"type":15,"tag":203,"props":1698,"children":1699},{"style":324},[1700],{"type":20,"value":1701},"    Get-ChildItem",{"type":15,"tag":203,"props":1703,"children":1704},{"style":1160},[1705],{"type":20,"value":1706}," @args\n",{"type":15,"tag":203,"props":1708,"children":1710},{"class":205,"line":1709},12,[1711],{"type":15,"tag":203,"props":1712,"children":1713},{"style":318},[1714],{"type":20,"value":1424},{"type":15,"tag":16,"props":1716,"children":1717},{},[1718,1720,1725],{"type":20,"value":1719},"The first ",{"type":15,"tag":23,"props":1721,"children":1723},{"className":1722},[],[1724],{"type":20,"value":1459},{"type":20,"value":1726}," 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":1728,"children":1729},{},[1730,1732,1737,1739,1745],{"type":20,"value":1731},"One thing that bit me: in PowerShell, aliases take precedence over functions during command resolution. ",{"type":15,"tag":23,"props":1733,"children":1735},{"className":1734},[],[1736],{"type":20,"value":1459},{"type":20,"value":1738}," is a built in alias pointing to ",{"type":15,"tag":23,"props":1740,"children":1742},{"className":1741},[],[1743],{"type":20,"value":1744},"Get-ChildItem",{"type":20,"value":1746},", so my function was never called until I removed the alias.",{"type":15,"tag":597,"props":1748,"children":1750},{"id":1749},"fix-3-cache-fnm-env",[1751],{"type":20,"value":1752},"Fix 3: cache fnm env",{"type":15,"tag":16,"props":1754,"children":1755},{},[1756,1758,1763],{"type":20,"value":1757},"Same trick as oh-my-posh. ",{"type":15,"tag":23,"props":1759,"children":1761},{"className":1760},[],[1762],{"type":20,"value":1120},{"type":20,"value":1764}," prints shell code that sets up node version management hooks. Cache it, regenerate only when fnm is updated:",{"type":15,"tag":178,"props":1766,"children":1768},{"className":306,"code":1767,"language":308,"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",[1769],{"type":15,"tag":23,"props":1770,"children":1771},{"__ignoreMap":7},[1772,1807,1826,1851,1887,1928,1977,1984,1997],{"type":15,"tag":203,"props":1773,"children":1774},{"class":205,"line":206},[1775,1780,1784,1788,1793,1798,1802],{"type":15,"tag":203,"props":1776,"children":1777},{"style":1160},[1778],{"type":20,"value":1779},"$fnmExe",{"type":15,"tag":203,"props":1781,"children":1782},{"style":324},[1783],{"type":20,"value":1168},{"type":15,"tag":203,"props":1785,"children":1786},{"style":318},[1787],{"type":20,"value":1230},{"type":15,"tag":203,"props":1789,"children":1790},{"style":324},[1791],{"type":20,"value":1792},"Get-Command",{"type":15,"tag":203,"props":1794,"children":1795},{"style":318},[1796],{"type":20,"value":1797}," fnm ",{"type":15,"tag":203,"props":1799,"children":1800},{"style":324},[1801],{"type":20,"value":639},{"type":15,"tag":203,"props":1803,"children":1804},{"style":318},[1805],{"type":20,"value":1806},"ErrorAction SilentlyContinue).Source\n",{"type":15,"tag":203,"props":1808,"children":1809},{"class":205,"line":215},[1810,1814,1818,1822],{"type":15,"tag":203,"props":1811,"children":1812},{"style":820},[1813],{"type":20,"value":1225},{"type":15,"tag":203,"props":1815,"children":1816},{"style":318},[1817],{"type":20,"value":1230},{"type":15,"tag":203,"props":1819,"children":1820},{"style":1160},[1821],{"type":20,"value":1779},{"type":15,"tag":203,"props":1823,"children":1824},{"style":318},[1825],{"type":20,"value":1634},{"type":15,"tag":203,"props":1827,"children":1828},{"class":205,"line":345},[1829,1834,1838,1842,1846],{"type":15,"tag":203,"props":1830,"children":1831},{"style":1160},[1832],{"type":20,"value":1833},"    $fnmCache",{"type":15,"tag":203,"props":1835,"children":1836},{"style":324},[1837],{"type":20,"value":1168},{"type":15,"tag":203,"props":1839,"children":1840},{"style":324},[1841],{"type":20,"value":1207},{"type":15,"tag":203,"props":1843,"children":1844},{"style":1160},[1845],{"type":20,"value":1212},{"type":15,"tag":203,"props":1847,"children":1848},{"style":647},[1849],{"type":20,"value":1850}," 'fnm-env.ps1'\n",{"type":15,"tag":203,"props":1852,"children":1853},{"class":205,"line":483},[1854,1858,1862,1866,1870,1874,1879,1883],{"type":15,"tag":203,"props":1855,"children":1856},{"style":820},[1857],{"type":20,"value":1608},{"type":15,"tag":203,"props":1859,"children":1860},{"style":318},[1861],{"type":20,"value":1230},{"type":15,"tag":203,"props":1863,"children":1864},{"style":324},[1865],{"type":20,"value":1235},{"type":15,"tag":203,"props":1867,"children":1868},{"style":318},[1869],{"type":20,"value":1230},{"type":15,"tag":203,"props":1871,"children":1872},{"style":324},[1873],{"type":20,"value":1244},{"type":15,"tag":203,"props":1875,"children":1876},{"style":1160},[1877],{"type":20,"value":1878}," $fnmCache",{"type":15,"tag":203,"props":1880,"children":1881},{"style":318},[1882],{"type":20,"value":1254},{"type":15,"tag":203,"props":1884,"children":1885},{"style":324},[1886],{"type":20,"value":1259},{"type":15,"tag":203,"props":1888,"children":1889},{"class":205,"line":492},[1890,1895,1899,1904,1908,1912,1916,1920,1924],{"type":15,"tag":203,"props":1891,"children":1892},{"style":318},[1893],{"type":20,"value":1894},"        (",{"type":15,"tag":203,"props":1896,"children":1897},{"style":324},[1898],{"type":20,"value":1271},{"type":15,"tag":203,"props":1900,"children":1901},{"style":1160},[1902],{"type":20,"value":1903}," $fnmExe",{"type":15,"tag":203,"props":1905,"children":1906},{"style":318},[1907],{"type":20,"value":1281},{"type":15,"tag":203,"props":1909,"children":1910},{"style":324},[1911],{"type":20,"value":1286},{"type":15,"tag":203,"props":1913,"children":1914},{"style":318},[1915],{"type":20,"value":1230},{"type":15,"tag":203,"props":1917,"children":1918},{"style":324},[1919],{"type":20,"value":1271},{"type":15,"tag":203,"props":1921,"children":1922},{"style":1160},[1923],{"type":20,"value":1878},{"type":15,"tag":203,"props":1925,"children":1926},{"style":318},[1927],{"type":20,"value":1348},{"type":15,"tag":203,"props":1929,"children":1930},{"class":205,"line":910},[1931,1936,1940,1944,1948,1952,1956,1960,1964,1969,1973],{"type":15,"tag":203,"props":1932,"children":1933},{"style":318},[1934],{"type":20,"value":1935},"        fnm env ",{"type":15,"tag":203,"props":1937,"children":1938},{"style":324},[1939],{"type":20,"value":1019},{"type":15,"tag":203,"props":1941,"children":1942},{"style":318},[1943],{"type":20,"value":1024},{"type":15,"tag":203,"props":1945,"children":1946},{"style":324},[1947],{"type":20,"value":843},{"type":15,"tag":203,"props":1949,"children":1950},{"style":318},[1951],{"type":20,"value":1033},{"type":15,"tag":203,"props":1953,"children":1954},{"style":324},[1955],{"type":20,"value":1394},{"type":15,"tag":203,"props":1957,"children":1958},{"style":324},[1959],{"type":20,"value":787},{"type":15,"tag":203,"props":1961,"children":1962},{"style":318},[1963],{"type":20,"value":1403},{"type":15,"tag":203,"props":1965,"children":1966},{"style":1160},[1967],{"type":20,"value":1968},"$fnmCache",{"type":15,"tag":203,"props":1970,"children":1971},{"style":324},[1972],{"type":20,"value":787},{"type":15,"tag":203,"props":1974,"children":1975},{"style":318},[1976],{"type":20,"value":1416},{"type":15,"tag":203,"props":1978,"children":1979},{"class":205,"line":931},[1980],{"type":15,"tag":203,"props":1981,"children":1982},{"style":318},[1983],{"type":20,"value":1692},{"type":15,"tag":203,"props":1985,"children":1986},{"class":205,"line":971},[1987,1992],{"type":15,"tag":203,"props":1988,"children":1989},{"style":318},[1990],{"type":20,"value":1991},"    . ",{"type":15,"tag":203,"props":1993,"children":1994},{"style":1160},[1995],{"type":20,"value":1996},"$fnmCache\n",{"type":15,"tag":203,"props":1998,"children":1999},{"class":205,"line":979},[2000],{"type":15,"tag":203,"props":2001,"children":2002},{"style":318},[2003],{"type":20,"value":1424},{"type":15,"tag":16,"props":2005,"children":2006},{},[2007,2009,2015],{"type":20,"value":2008},"This pattern works for any tool that prints shell init code on every launch. Later I added the same thing for ",{"type":15,"tag":23,"props":2010,"children":2012},{"className":2011},[],[2013],{"type":20,"value":2014},"zoxide init powershell",{"type":20,"value":54},{"type":15,"tag":597,"props":2017,"children":2019},{"id":2018},"the-results",[2020],{"type":20,"value":2021},"The results",{"type":15,"tag":1060,"props":2023,"children":2024},{},[2025,2041],{"type":15,"tag":1064,"props":2026,"children":2027},{},[2028],{"type":15,"tag":1068,"props":2029,"children":2030},{},[2031,2036],{"type":15,"tag":1072,"props":2032,"children":2033},{},[2034],{"type":20,"value":2035},"State",{"type":15,"tag":1072,"props":2037,"children":2038},{},[2039],{"type":20,"value":2040},"Startup",{"type":15,"tag":1083,"props":2042,"children":2043},{},[2044,2057],{"type":15,"tag":1068,"props":2045,"children":2046},{},[2047,2052],{"type":15,"tag":1090,"props":2048,"children":2049},{},[2050],{"type":20,"value":2051},"Original profile",{"type":15,"tag":1090,"props":2053,"children":2054},{},[2055],{"type":20,"value":2056},"~905ms",{"type":15,"tag":1068,"props":2058,"children":2059},{},[2060,2065],{"type":15,"tag":1090,"props":2061,"children":2062},{},[2063],{"type":20,"value":2064},"After all three caches",{"type":15,"tag":1090,"props":2066,"children":2067},{},[2068],{"type":20,"value":2069},"~440ms",{"type":15,"tag":16,"props":2071,"children":2072},{},[2073],{"type":20,"value":2074},"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":597,"props":2076,"children":2077},{"id":530},[2078],{"type":20,"value":533},{"type":15,"tag":68,"props":2080,"children":2081},{},[2082,2087,2099,2112],{"type":15,"tag":72,"props":2083,"children":2084},{},[2085],{"type":20,"value":2086},"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":72,"props":2088,"children":2089},{},[2090,2092,2098],{"type":20,"value":2091},"If you want to force a regeneration, just delete the cache file from ",{"type":15,"tag":23,"props":2093,"children":2095},{"className":2094},[],[2096],{"type":20,"value":2097},"%TEMP%",{"type":20,"value":54},{"type":15,"tag":72,"props":2100,"children":2101},{},[2102,2104,2110],{"type":20,"value":2103},"Adding ",{"type":15,"tag":23,"props":2105,"children":2107},{"className":2106},[],[2108],{"type":20,"value":2109},"-NoLogo",{"type":20,"value":2111}," to your pwsh command in Windows Terminal shaves off another ~40ms.",{"type":15,"tag":72,"props":2113,"children":2114},{},[2115,2117,2123],{"type":20,"value":2116},"Check your PowerShell version with ",{"type":15,"tag":23,"props":2118,"children":2120},{"className":2119},[],[2121],{"type":20,"value":2122},"$PSVersionTable.PSVersion",{"type":20,"value":2124},". Newer releases tend to have startup improvements, so staying current helps.",{"type":15,"tag":16,"props":2126,"children":2127},{},[2128],{"type":20,"value":2129},"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":563,"props":2131,"children":2132},{},[2133],{"type":20,"value":567},{"title":7,"searchDepth":215,"depth":215,"links":2135},[2136,2137,2138,2139,2140,2141,2142],{"id":599,"depth":345,"text":602},{"id":747,"depth":345,"text":750},{"id":1133,"depth":345,"text":1136},{"id":1445,"depth":345,"text":1448},{"id":1749,"depth":345,"text":1752},{"id":2018,"depth":345,"text":2021},{"id":530,"depth":345,"text":533},"content:blog:cutting-powershell-startup-time-in-half.md","blog/cutting-powershell-startup-time-in-half.md","blog/cutting-powershell-startup-time-in-half",1776948255025]