After pressing Ctrl + P in the editor, write the file name and the line number so that it takes you straight to that line?

๐Ÿ“ฆ Key shortcuts
โœจ The Prompt Phrase
After pressing Ctrl + P in the editor, how do you write the file name and the line number so that it takes you straight to that line?

~filename:linenumber~

๐Ÿ’ป Code Preview

๐Ÿ“ฆ All-in-One Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Support Prompt - Interactive Tutorial</title>
<style>
:root{
  --bg:#0b0b1a;--bg2:#14142b;--glass:rgba(255,255,255,.06);--border:rgba(255,255,255,.14);
  --text:#e8e8f5;--muted:#a3a3c2;--purple:#8b5cf6;--blue:#3b82f6;--green:#10b981;--red:#f43f5e;--amber:#f59e0b;
  --grad:linear-gradient(135deg,var(--purple),var(--blue) 55%,var(--green));
}
body.light{--bg:#f4f4ff;--bg2:#e6e6fa;--glass:rgba(255,255,255,.75);--border:rgba(80,80,140,.2);--text:#1b1b3a;--muted:#55557a}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font-family:'Segoe UI',system-ui,sans-serif;background:radial-gradient(circle at 20% 0%,var(--bg2),var(--bg) 60%);color:var(--text);line-height:1.7;min-height:100vh}
#progress{position:fixed;top:0;left:0;height:5px;width:0;background:var(--grad);z-index:100}
nav{position:sticky;top:5px;z-index:50;margin:12px auto;max-width:980px;display:flex;gap:6px;flex-wrap:wrap;justify-content:center;align-items:center;padding:8px 12px;background:var(--glass);border:1px solid var(--border);border-radius:999px;backdrop-filter:blur(14px)}
nav a{color:var(--muted);text-decoration:none;font-size:.85rem;padding:4px 10px;border-radius:999px;transition:.2s}
nav a:hover{color:var(--text);background:var(--glass)}
#theme{background:none;border:1px solid var(--border);border-radius:999px;cursor:pointer;padding:4px 10px;color:var(--text)}
main{max-width:900px;margin:0 auto;padding:0 18px 60px}
section{margin:36px 0;padding:28px;background:var(--glass);border:1px solid var(--border);border-radius:24px;backdrop-filter:blur(12px);box-shadow:0 20px 40px rgba(0,0,0,.25);opacity:0;transform:translateY(24px);transition:.7s ease}
section.show{opacity:1;transform:none}
h1{font-size:clamp(1.6rem,5vw,2.6rem);line-height:1.2}
h2{font-size:1.6rem;margin-bottom:12px}
p{margin-bottom:12px}
.grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;background-size:200%;animation:shift 6s linear infinite}
@keyframes shift{to{background-position:200% 0}}
.hero{text-align:center;padding:50px 20px}
.float{font-size:3rem;display:inline-block;animation:float 3s ease-in-out infinite}
@keyframes float{50%{transform:translateY(-12px)}}
code{font-family:Consolas,'Courier New',monospace}
.cmd{display:flex;align-items:center;justify-content:space-between;gap:10px;background:#0a0a14;color:#d6d6ff;border:1px solid var(--border);border-radius:14px;padding:12px 16px;margin:14px auto;overflow-x:auto;text-align:left}
.cmd code{white-space:nowrap}
.k-a{color:#34d399}.k-b{color:#60a5fa}.k-sym{color:#f472b6;font-weight:700}.k-c{color:#fbbf24}
kbd{display:inline-block;min-width:2.2em;text-align:center;font-family:Consolas,monospace;font-weight:700;padding:3px 10px;border-radius:8px;border:1px solid var(--border);border-bottom-width:4px;background:var(--glass);color:var(--text)}
button.btn{background:var(--grad);color:#fff;border:none;border-radius:12px;padding:8px 16px;font-weight:600;cursor:pointer;font-family:inherit;transition:transform .15s,box-shadow .15s}
button.btn:hover{transform:translateY(-2px);box-shadow:0 8px 20px rgba(139,92,246,.4)}
button.small{padding:5px 12px;font-size:.8rem;white-space:nowrap}
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin-top:14px}
.card{background:var(--glass);border:1px solid var(--border);border-radius:16px;padding:16px;transition:.25s}
.card:hover{transform:translateY(-5px) rotate(-.5deg);border-color:var(--purple)}
.card h3{margin-bottom:6px;font-size:1.05rem}
.acc{border:1px solid var(--border);border-radius:14px;margin-bottom:10px;overflow:hidden}
.acc button{width:100%;text-align:left;background:var(--glass);color:var(--text);border:none;padding:14px 16px;font-size:1rem;font-family:inherit;cursor:pointer;display:flex;justify-content:space-between}
.acc .body{max-height:0;overflow:hidden;transition:max-height .35s ease;padding:0 16px}
.acc.open .body{max-height:300px;padding:12px 16px}
.chev{transition:.3s}.acc.open .chev{transform:rotate(180deg)}
figure.shot{margin:18px 0 6px;padding:14px;background:var(--glass);border:1px solid var(--border);border-radius:18px;text-align:center}
figure.shot .imgwrap{overflow:auto;border-radius:12px;background:#0a0a14;border:1px solid var(--border);padding:6px}
figure.shot img{display:block;max-width:100%;height:auto;margin:0 auto;border-radius:8px;cursor:zoom-in;transition:transform .3s}
figure.shot img.zoom{max-width:none;width:150%;cursor:zoom-out}
figure.shot figcaption{margin:10px 0 0;color:var(--muted);font-size:.88rem}
.imgfail{display:none;padding:18px;color:var(--muted);font-size:.9rem}
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.tab{background:var(--glass);color:var(--text);border:1px solid var(--border);border-radius:999px;padding:6px 14px;cursor:pointer;font-family:inherit}
.tab[aria-selected=true]{background:var(--grad);color:#fff;border-color:transparent}
.panel{display:none}.panel.active{display:block;animation:fade .4s}
@keyframes fade{from{opacity:0;transform:translateY(8px)}}
.ide{border-radius:16px;border:1px solid var(--border);background:#1e1e2e;margin-top:12px;outline:none;min-height:300px;position:relative;overflow:hidden;color:#e8e8f5}
.ide:focus{border-color:var(--amber)}
.ide .bar{background:#14142b;padding:8px 14px;font-size:.82rem;color:#a3a3c2}
.editor{padding:10px 0;font-family:Consolas,monospace;font-size:.88rem}
.ln{display:flex;padding:1px 14px;transition:background .3s}
.ln b{width:2.5em;color:#6b6b8f;font-weight:400;user-select:none}
.ln.hit{background:rgba(245,158,11,.3);box-shadow:inset 3px 0 var(--amber)}
.qo{position:absolute;top:44px;left:50%;transform:translateX(-50%);width:min(440px,92%);background:#252540;border:1px solid var(--purple);border-radius:12px;box-shadow:0 16px 40px rgba(0,0,0,.5);display:none;z-index:5}
.qo.on{display:block;animation:fade .25s}
.qo input{width:100%;background:#14142b;border:none;border-bottom:1px solid var(--border);color:#fff;padding:10px 12px;font-size:.95rem;font-family:Consolas,monospace;border-radius:12px 12px 0 0;outline:none}
.qo ul{list-style:none;max-height:150px;overflow:auto}
.qo li{padding:7px 12px;font-family:Consolas,monospace;font-size:.88rem;cursor:pointer}
.qo li.sel,.qo li:hover{background:rgba(139,92,246,.35)}
.qo li small{color:#a3a3c2;margin-left:8px}
.bad,.good,.warn{border-radius:14px;padding:14px;margin-bottom:10px}
.bad{background:rgba(244,63,94,.12);border:1px solid rgba(244,63,94,.4)}
.good{background:rgba(16,185,129,.12);border:1px solid rgba(16,185,129,.4)}
.warn{background:rgba(245,158,11,.14);border:1px solid rgba(245,158,11,.5)}
.opt{display:block;width:100%;text-align:left;background:var(--glass);color:var(--text);border:1px solid var(--border);border-radius:12px;padding:10px 14px;margin:8px 0;cursor:pointer;font-family:inherit;font-size:.95rem;transition:.2s}
.opt:hover:not(:disabled){border-color:var(--purple);transform:translateX(4px)}
.opt.right{background:rgba(16,185,129,.25);border-color:var(--green)}
.opt.wrong{background:rgba(244,63,94,.25);border-color:var(--red);animation:shake .4s}
@keyframes shake{25%{transform:translateX(-6px)}75%{transform:translateX(6px)}}
.badges{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:10px}
.badge{padding:6px 12px;border-radius:999px;border:1px dashed var(--border);color:var(--muted);font-size:.85rem;filter:grayscale(1);opacity:.6;transition:.4s}
.badge.on{filter:none;opacity:1;color:var(--text);border:1px solid var(--amber);background:rgba(245,158,11,.15);animation:pop .5s}
@keyframes pop{50%{transform:scale(1.2)}}
table{width:100%;border-collapse:collapse;font-size:.92rem}
th,td{padding:9px 10px;border-bottom:1px solid var(--border);text-align:left;vertical-align:top}
th{color:var(--muted)}
.tip{position:relative;border-bottom:2px dotted var(--purple);cursor:help}
.tip::after{content:attr(data-tip);position:absolute;left:50%;bottom:130%;transform:translateX(-50%) scale(.9);width:max-content;max-width:240px;background:#1e1b4b;color:#fff;font-size:.78rem;padding:8px 10px;border-radius:10px;opacity:0;pointer-events:none;transition:.2s;z-index:10;font-family:'Segoe UI',sans-serif;white-space:normal}
.tip:hover::after,.tip:focus::after{opacity:1;transform:translateX(-50%) scale(1)}
footer{text-align:center;color:var(--muted);padding:30px 18px;font-size:.9rem}
canvas#confetti{position:fixed;inset:0;pointer-events:none;z-index:200}
.toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%) translateY(80px);background:var(--grad);color:#fff;padding:10px 20px;border-radius:999px;font-weight:600;z-index:150;transition:.4s}
.toast.show{transform:translateX(-50%)}
:focus-visible{outline:3px solid var(--amber);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}section{opacity:1;transform:none}}
</style>
</head>
<body>
<div id="progress" role="progressbar" aria-label="Reading progress"></div>
<canvas id="confetti" aria-hidden="true"></canvas>
<div class="toast" id="toast" role="status" aria-live="polite"></div>

<nav aria-label="Tutorial sections">
  <a href="#what">What</a><a href="#why">Why</a><a href="#how">How</a><a href="#demo">Demo</a><a href="#breakdown">Breakdown</a>
  <a href="#mistakes">Mistakes</a><a href="#tips">Tips</a><a href="#quiz">Quiz</a><a href="#summary">Cheat Sheet</a>
  <button id="theme" aria-label="Toggle light and dark theme">๐ŸŒ—</button>
</nav>

<main>
<header class="hero section show">
  <div class="float" aria-hidden="true">๐ŸŽฏ</div>
  <h1 class="grad">filename:linenumber โ€” Jump Straight to a Line</h1>
  <p style="color:var(--muted);margin-top:10px">"After Ctrl + P, type the file name, a colon, and the line number, and it takes you to that line."</p>
  <div class="cmd" style="max-width:420px">
    <code><span class="k-a">app.js</span><span class="k-sym">:</span><span class="k-c">42</span></code>
    <button class="btn small copy" data-copy="app.js:42" aria-label="Copy example">๐Ÿ“‹ Copy</button>
  </div>
  <div class="warn" style="text-align:left">โš ๏ธ <strong>Heads up:</strong> This is a <strong>VS Code</strong> Quick Open feature. In full <strong>Visual Studio</strong>, Ctrl + P prints. Use Ctrl + G or Ctrl + T there. This tutorial explains both.</div>
  <p>๐ŸŽฏ 5-10 minutes ยท ๐Ÿ† 4 badges to earn</p>
  <div class="badges" aria-label="Achievement badges">
    <span class="badge" id="b-read">๐Ÿ“– Explorer</span>
    <span class="badge" id="b-copy">๐Ÿ“‹ Copy Master</span>
    <span class="badge" id="b-demo">๐ŸŽฏ Line Jumper</span>
    <span class="badge" id="b-quiz">๐Ÿ† Quiz Champ</span>
  </div>
</header>

<section id="what">
  <h2>๐Ÿค” 1. What Is It?</h2>
  <p>Imagine telling a taxi driver both the <strong>building</strong> and the <strong>floor</strong> ๐Ÿข. In your editor, the file name is the building and the <span class="tip" tabindex="0" data-tip="Line number: the position of a line in a file, counting from 1 at the top.">line number</span> is the floor.</p>
  <p>You write it as <code>filename<span class="k-sym">:</span>linenumber</code>: the name, a <strong>colon</strong>, then the number, with no spaces. Example: <code>index.html:15</code>.</p>
  <div class="warn">โœ… <strong>The answer to your question:</strong> write <code>app.js:42</code>. That is the file name, then <code>:</code>, then the line number.</div>
</section>

<section id="why">
  <h2>๐ŸŽ 2. Why Use It?</h2>
  <div class="cards">
    <div class="card"><h3>๐Ÿž Fix errors</h3>Error messages often name a file and a line. Jump right there.</div>
    <div class="card"><h3>โšก One step</h3>Open the file and go to the line in a single box.</div>
    <div class="card"><h3>๐Ÿ“‹ Paste friendly</h3>Copy <code>file:line</code> from a log and paste it in.</div>
    <div class="card"><h3>๐Ÿค Code reviews</h3>Share exact locations with teammates.</div>
  </div>
</section>

<section id="how">
  <h2>โš™๏ธ 3. How Does It Work?</h2>
  <p>Click each step ๐Ÿ‘‡</p>
  <div class="acc open"><button aria-expanded="true">1๏ธโƒฃ Open Quick Open <span class="chev">โ–ผ</span></button><div class="body">In VS Code, press <kbd>Ctrl</kbd>+<kbd>P</kbd> (Mac: <kbd>Cmd</kbd>+<kbd>P</kbd>).</div></div>
  <div class="acc"><button aria-expanded="false">2๏ธโƒฃ Type the file name <span class="chev">โ–ผ</span></button><div class="body">A few letters are enough, for example <code>app</code>. Fuzzy matching helps.</div></div>
  <div class="acc"><button aria-expanded="false">3๏ธโƒฃ Add a colon and a number <span class="chev">โ–ผ</span></button><div class="body">Type <code>:</code> then the line, so you have <code>app.js:42</code>. Optionally add a column: <code>app.js:42:10</code>.</div></div>
  <div class="acc"><button aria-expanded="false">4๏ธโƒฃ Press Enter <span class="chev">โ–ผ</span></button><div class="body">The file opens and the cursor lands on that line. If the line is past the end, you usually land on the last line.</div></div>

  <figure class="shot" id="shot">
    <div class="imgwrap">
      <img src="DB_IMAGE" alt="Prompt Image: visual walkthrough of how to type a file name, a colon and a line number after pressing Ctrl + P" style="max-width:100%;" id="howImg" title="Click to zoom in or out">
      <div class="imgfail" id="imgFail" role="note">๐Ÿ–ผ๏ธ The walkthrough image could not be loaded. The steps above explain the same process.</div>
    </div>
    <figcaption>๐Ÿ–ผ๏ธ Visual walkthrough: compare it with the four steps above. Click the image to zoom.</figcaption>
  </figure>
</section>

<section id="demo">
  <h2>๐ŸŽฎ 4. Live Demo</h2>
  <p>This is a <strong>simulation</strong> with fake files. It doesn't touch your real editor.</p>
  <div class="tabs" role="tablist" aria-label="Demo modes">
    <button class="tab" role="tab" aria-selected="true" data-panel="p1">VS Code</button>
    <button class="tab" role="tab" aria-selected="false" data-panel="p2">Visual Studio</button>
    <button class="tab" role="tab" aria-selected="false" data-panel="p3">Not working?</button>
  </div>
  <div class="panel active" id="p1"><p>Click the mock editor, press <kbd>Ctrl</kbd>+<kbd>P</kbd> (or use the button), then type <code>app.js:3</code> and press <kbd>Enter</kbd>.</p><button class="btn" id="openQO">๐Ÿ”Ž Open Quick Open</button></div>
  <div class="panel" id="p2"><table>
    <tr><th>Goal</th><th>Default shortcut</th></tr>
    <tr><td>Go to a line in the current file</td><td><kbd>Ctrl</kbd>+<kbd>G</kbd></td></tr>
    <tr><td>Go To All (type <code>:42</code> for a line)</td><td><kbd>Ctrl</kbd>+<kbd>T</kbd> or <kbd>Ctrl</kbd>+<kbd>,</kbd></td></tr>
    <tr><td>Ctrl + P</td><td>Print</td></tr></table>
    <p style="margin-top:8px;color:var(--muted)">I couldn't confirm that <code>filename:line</code> in one go works in Visual Studio. Test it on your version. Check Tools &gt; Options &gt; Environment &gt; Keyboard.</p></div>
  <div class="panel" id="p3"><p>๐Ÿ” Checklist: Is there a space around the colon? Is the file in the open folder? Did the browser print dialog open instead? Is the editor focused? Is the number higher than the file's line count?</p></div>
  <div class="ide" id="ide" tabindex="0" aria-label="Simulated editor. Press Control P to open Quick Open.">
    <div class="bar" id="tabbar">๐Ÿ“„ No file open</div>
    <div class="editor" id="editor" aria-live="polite"><div class="ln"><b></b>Click here, then press Ctrl + P.</div></div>
    <div class="qo" id="qo" role="dialog" aria-label="Quick Open (simulated)">
      <input id="qi" type="text" placeholder="e.g. app.js:3" aria-label="Search files" autocomplete="off">
      <ul id="ql"></ul>
    </div>
  </div>
  <p id="demoMsg" aria-live="polite" style="margin-top:10px;color:var(--muted)"></p>
</section>

<section id="breakdown">
  <h2>๐Ÿ”ฌ 5. Code Breakdown</h2>
  <p>Hover or focus the colored parts:</p>
  <div class="cmd" style="font-size:1.1rem"><code>
    <span class="k-a tip" tabindex="0" data-tip="The file name. Partial names work, like 'app'.">app.js</span><span class="k-sym tip" tabindex="0" data-tip="The colon separates the name from the line number. No spaces.">:</span><span class="k-c tip" tabindex="0" data-tip="The line number, counting from 1.">42</span><span class="k-sym">:</span><span class="k-b tip" tabindex="0" data-tip="Optional column number (VS Code).">10</span></code>
    <button class="btn small copy" data-copy="app.js:42:10" aria-label="Copy">๐Ÿ“‹</button></div>
  <table>
    <tr><th>Part</th><th>Meaning</th></tr>
    <tr><td><code class="k-a">app.js</code></td><td>File to open</td></tr>
    <tr><td><code class="k-sym">:</code></td><td>Separator (type it, no spaces)</td></tr>
    <tr><td><code class="k-c">42</code></td><td>Line to jump to</td></tr>
    <tr><td><code class="k-b">10</code></td><td>Optional column</td></tr>
  </table>
</section>

<section id="mistakes">
  <h2>๐Ÿšซ 6. Common Mistakes</h2>
  <div class="bad">โŒ <strong>Using a space:</strong> <code>app.js : 42</code> may not work. Write <code>app.js:42</code>.</div>
  <div class="bad">โŒ <strong>Wrong separator:</strong> a semicolon or comma isn't a colon.</div>
  <div class="bad">โŒ <strong>Ctrl + P in Visual Studio.</strong> That prints. Use Ctrl + G or Ctrl + T.</div>
  <div class="bad">โŒ <strong>Wrong line count.</strong> Lines start at 1, not 0.</div>
  <div class="good">โœ… <strong>Do:</strong> name, colon, number, Enter.</div>
</section>

<section id="tips">
  <h2>๐Ÿง  7. Pro Tips</h2>
  <div class="cards">
    <div class="card"><h3>๐Ÿ“‹ Paste from logs</h3>Paste <code>file:line</code> from an error straight into Quick Open.</div>
    <div class="card"><h3>๐Ÿ“ Same file</h3>Type just <code>:42</code> after Ctrl + P to jump in the current file. Ctrl + G also works.</div>
    <div class="card"><h3>๐Ÿงญ Column too</h3>Add a second colon and a column number.</div>
    <div class="card"><h3>๐Ÿ› ๏ธ Remap</h3>Change shortcuts in Keyboard Shortcuts if they clash.</div>
  </div>
</section>

<section id="quiz">
  <h2>๐ŸŽฎ 8. Practice Quiz</h2>
  <p id="qcount" style="color:var(--muted)"></p>
  <div id="qbox"></div>
</section>

<section id="summary">
  <h2>๐Ÿ“Œ 9. Summary Cheat Sheet</h2>
  <div class="cmd"><code>Ctrl + P โ†’ app.js:42 โ†’ Enter</code><button class="btn small copy" data-copy="app.js:42">๐Ÿ“‹</button></div>
  <table>
    <tr><td>Format</td><td><code>filename:linenumber</code></td></tr>
    <tr><td>VS Code</td><td><kbd>Ctrl</kbd>+<kbd>P</kbd>, type it, <kbd>Enter</kbd></td></tr>
    <tr><td>Visual Studio</td><td><kbd>Ctrl</kbd>+<kbd>G</kbd> or <kbd>Ctrl</kbd>+<kbd>T</kbd> then <code>:42</code></td></tr>
    <tr><td>Close</td><td><kbd>Esc</kbd></td></tr>
  </table>
  <p style="margin-top:12px">๐ŸŽ‰ Great job! Now go land on any line in seconds.</p>
</section>
</main>

<footer>โœจ Generated by AI Prompt Dictionary ยท Made for curious beginners ๐Ÿ’œ</footer>

<script>
(function(){
  var $=function(s,r){return (r||document).querySelector(s)},$$=function(s,r){return Array.prototype.slice.call((r||document).querySelectorAll(s))};
  function toast(m){var t=$('#toast');t.textContent=m;t.classList.add('show');setTimeout(function(){t.classList.remove('show')},2200)}
  function badge(id,msg){var b=$('#'+id);if(!b.classList.contains('on')){b.classList.add('on');toast('๐Ÿ… Badge unlocked: '+msg)}}
  $('#theme').onclick=function(){document.body.classList.toggle('light')};
  window.addEventListener('scroll',function(){
    var h=document.documentElement.scrollHeight-innerHeight,p=h>0?scrollY/h*100:0;
    $('#progress').style.width=p+'%';$('#progress').setAttribute('aria-valuenow',Math.round(p));
    if(p>95)badge('b-read','Explorer')});
  var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('show');io.unobserve(e.target)}})},{threshold:.1});
  $$('section').forEach(function(s){io.observe(s)});
  $$('.copy').forEach(function(b){b.onclick=function(){
    var t=b.getAttribute('data-copy');
    function done(){toast('โœ… Copied!');badge('b-copy','Copy Master')}
    function fb(){var a=document.createElement('textarea');a.value=t;document.body.appendChild(a);a.select();try{document.execCommand('copy')}catch(e){}document.body.removeChild(a);done()}
    if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t).then(done,fb)}else fb()}});
  $$('.acc button').forEach(function(b){b.onclick=function(){var o=b.parentNode.classList.toggle('open');b.setAttribute('aria-expanded',o)}});
  $$('.tab').forEach(function(t){t.onclick=function(){
    $$('.tab').forEach(function(x){x.setAttribute('aria-selected','false')});t.setAttribute('aria-selected','true');
    $$('.panel').forEach(function(p){p.classList.remove('active')});$('#'+t.getAttribute('data-panel')).classList.add('active')}});

  // image: zoom toggle + fallback
  var img=$('#howImg');
  img.addEventListener('click',function(){img.classList.toggle('zoom')});
  img.addEventListener('error',function(){img.style.display='none';$('#imgFail').style.display='block'});

  // demo (simulation only)
  var FILES={
    'app.js':['const express = require("express");','const app = express();','app.get("/", handler);','function handler(req, res) {','  res.send("Hello");','}','app.listen(3000);','// end of file'],
    'utils.js':['export function add(a, b) {','  return a + b;','}','export const PI = 3.14;'],
    'index.html':['<!DOCTYPE html>','<html>','<body>','  <h1>Hello</h1>','</body>','</html>']
  };
  var names=Object.keys(FILES);
  var ide=$('#ide'),qo=$('#qo'),qi=$('#qi'),ql=$('#ql'),cur=[],sel=0;
  function fuzzy(q,n){q=q.toLowerCase();n=n.toLowerCase();var i=0;for(var c=0;c<n.length&&i<q.length;c++){if(n[c]===q[i])i++}return i===q.length}
  function parse(v){
    var m=v.trim().match(/^([^:]*)(?::(\d+))?(?::(\d+))?$/);
    return m?{name:m[1].trim(),line:m[2]?parseInt(m[2],10):null,col:m[3]?parseInt(m[3],10):null}:{name:v.trim(),line:null,col:null};
  }
  function list(){
    var p=parse(qi.value);
    cur=p.name?names.filter(function(f){return fuzzy(p.name,f)}):names.slice();
    sel=0;ql.textContent='';
    if(!cur.length){var li=document.createElement('li');li.textContent='No matching files';ql.appendChild(li);return}
    cur.forEach(function(f,i){
      var li=document.createElement('li');li.textContent=f;
      if(p.line){var s=document.createElement('small');s.textContent='โ†’ line '+p.line;li.appendChild(s)}
      if(i===0)li.className='sel';
      li.onclick=function(){pick(i)};ql.appendChild(li)});
  }
  function mark(){$$('li',ql).forEach(function(l,i){l.classList.toggle('sel',i===sel)})}
  function openQO(){qo.classList.add('on');qi.value='';list();qi.focus()}
  function closeQO(){qo.classList.remove('on');ide.focus()}
  function pick(i){
    var f=cur[i];if(!f)return;
    var p=parse(qi.value),lines=FILES[f],ed=$('#editor');
    ed.textContent='';
    lines.forEach(function(t,n){
      var d=document.createElement('div');d.className='ln';
      var b=document.createElement('b');b.textContent=n+1;d.appendChild(b);d.appendChild(document.createTextNode(t));ed.appendChild(d)});
    $('#tabbar').textContent='๐Ÿ“„ '+f;
    var msg='Opened '+f+'.';
    if(p.line){
      var target=Math.min(Math.max(p.line,1),lines.length);
      $$('.ln',ed)[target-1].classList.add('hit');
      msg='Opened '+f+' and jumped to line '+target+(p.line>lines.length?' (the last line, since '+p.line+' is past the end)':'')+'.';
      badge('b-demo','Line Jumper');boom();
    }
    $('#demoMsg').textContent='โœ… '+msg;
    closeQO();
  }
  ide.addEventListener('click',function(e){if(!qo.contains(e.target))ide.focus()});
  ide.addEventListener('keydown',function(e){
    if(e.ctrlKey&&!e.shiftKey&&(e.key==='p'||e.key==='P')){e.preventDefault();openQO()}
    else if(e.key==='Escape'&&qo.classList.contains('on')){closeQO()}});
  qi.addEventListener('input',list);
  qi.addEventListener('keydown',function(e){
    if(e.key==='ArrowDown'){e.preventDefault();sel=Math.min(sel+1,cur.length-1);mark()}
    else if(e.key==='ArrowUp'){e.preventDefault();sel=Math.max(sel-1,0);mark()}
    else if(e.key==='Enter'){e.preventDefault();pick(sel)}
    else if(e.key==='Escape'){closeQO()}});
  $('#openQO').onclick=openQO;

  // quiz
  var Q=[
    {q:'How do you write "go to line 42 of app.js" in Quick Open?',o:['app.js:42','app.js 42','app.js;42'],a:0,e:'File name, colon, line number, no spaces.'},
    {q:'What does Ctrl + P do by default in full Visual Studio?',o:['Prints','Opens Quick Open','Jumps to a line'],a:0,e:'Use Ctrl + G or Ctrl + T there instead.'},
    {q:'What does the optional second colon, as in app.js:42:10, add?',o:['A column number','A second file','A search word'],a:0,e:'It places the cursor at column 10 in VS Code.'}
  ],qn=0,score=0;
  function render(){
    var box=$('#qbox');
    if(qn>=Q.length){
      box.innerHTML='<h3>๐ŸŽ‰ Score: '+score+' / '+Q.length+'</h3><p>'+(score===Q.length?'Perfect! Line-jump master! ๐ŸŽฏ':'Nice try! Retry to get them all.')+'</p><button class="btn" id="retry">๐Ÿ”„ Try again</button>';
      $('#qcount').textContent='Finished!';
      if(score===Q.length){badge('b-quiz','Quiz Champ');boom()}
      $('#retry').onclick=function(){qn=0;score=0;render()};return}
    var q=Q[qn];$('#qcount').textContent='Question '+(qn+1)+' of '+Q.length;
    box.innerHTML='<h3></h3>'+q.o.map(function(t,i){return '<button class="opt" data-i="'+i+'"></button>'}).join('')+'<p id="fb" aria-live="polite"></p>';
    $('h3',box).textContent=q.q;
    $$('.opt',box).forEach(function(b,i){b.textContent=q.o[i];b.onclick=function(){
      $$('.opt',box).forEach(function(x){x.disabled=true});
      if(i===q.a){b.classList.add('right');score++;$('#fb').textContent='๐ŸŽ‰ '+q.e;boom()}
      else{b.classList.add('wrong');$$('.opt',box)[q.a].classList.add('right');$('#fb').textContent='๐Ÿ’ช Not quite. '+q.e}
      setTimeout(function(){qn++;render()},1700)}});
  }
  render();

  // confetti
  var cv=$('#confetti'),cx=cv.getContext('2d'),parts=[],raf;
  function size(){cv.width=innerWidth;cv.height=innerHeight}size();addEventListener('resize',size);
  function boom(){
    if(matchMedia('(prefers-reduced-motion:reduce)').matches)return;
    var c=['#8b5cf6','#3b82f6','#10b981','#f59e0b','#f43f5e'];
    for(var i=0;i<110;i++)parts.push({x:innerWidth/2,y:innerHeight/3,vx:(Math.random()-.5)*14,vy:Math.random()*-12-2,s:Math.random()*7+3,c:c[i%5],l:100});
    cancelAnimationFrame(raf);loop()}
  function loop(){
    cx.clearRect(0,0,cv.width,cv.height);
    parts=parts.filter(function(p){return p.l>0});
    parts.forEach(function(p){p.x+=p.vx;p.y+=p.vy;p.vy+=.35;p.l--;cx.globalAlpha=Math.max(p.l/100,0);cx.fillStyle=p.c;cx.fillRect(p.x,p.y,p.s,p.s)});
    if(parts.length)raf=requestAnimationFrame(loop);else cx.clearRect(0,0,cv.width,cv.height)}
})();
</script>
</body>
</html>
Live Preview