1// âââââââ CHROME: tabline, winbar, tree, statusline, cmdline âââââââ 2 3function Tabline({ buffers, active, onSelect, modified, onSimpleView }) { 4 return ( 5 <div className="tabline"> 6 {buffers.map((b, i) => ( 7 <div 8 key={b.id} 9 className={'tab ' + (b.id === active ? 'active' : '')} 10 onClick={() => onSelect(b.id)} 11 > 12 <span className="tab-idx">{i + 1}</span> 13 <span>{b.file}</span> 14 {modified[b.id] && <span className="tab-dot">â</span>} 15 </div> 16 ))} 17 <div className="tab-spacer" /> 18 <div className="tab-meta"> 19 <span>~/portfolio</span> 20 <span style={{ color: 'var(--green)' }}>â main</span> 21 {onSimpleView && ( 22 <button 23 type="button" 24 className="view-switch tab-switch" 25 onClick={onSimpleView} 26 data-comment-anchor="8344181b30-button-335-7" 27 > 28 <span className="tab-switch-glyph">â³</span> 29 simple view 30 </button> 31 )} 32 </div> 33 </div> 34 ); 35} 36 37function Winbar({ buffer }) { 38 const crumbs = ['~', 'portfolio', buffer.file]; 39 return ( 40 <div className="winbar"> 41 {crumbs.map((c, i) => ( 42 <React.Fragment key={i}> 43 <span className={'crumb' + (i === crumbs.length - 1 ? ' accent' : '')}>{c}</span> 44 {i < crumbs.length - 1 && <span className="sep">âº</span>} 45 </React.Fragment> 46 ))} 47 </div> 48 ); 49} 50 51function FileTree({ buffers, active, onSelect, deps, theme, effTheme, onToggleTheme }) { 52 const data = deps.data; 53 const themeGlyph = theme === 'system' ? 'â' : (effTheme || theme) === 'light' ? 'â' : 'â¾'; 54 const themeLabel = theme === 'system' ? 'system' : theme === 'light' ? 'light' : 'dark'; 55 return ( 56 <div className="tree"> 57 <div className="tree-header">NETRW â ~/portfolio</div> 58 59 <div className="tree-group">ââ buffers ââ</div> 60 {buffers.map((b) => ( 61 <div 62 key={b.id} 63 className={'tree-item' + (b.id === active ? ' active' : '')} 64 onClick={() => onSelect(b.id)} 65 > 66 <span className="glyph">â¸</span> 67 <span>{b.file}</span> 68 <span className="key">{b.key}</span> 69 </div> 70 ))} 71 72 <div className="tree-group">ââ links ââ</div> 73 <a className="tree-item" href={`https://${data.github}`} target="_blank" rel="noreferrer"> 74 <span className="glyph">â</span> 75 <span>github</span> 76 </a> 77 <a className="tree-item" href={`https://${data.linkedin}`} target="_blank" rel="noreferrer"> 78 <span className="glyph">â</span> 79 <span>linkedin</span> 80 </a> 81 <a className="tree-item" href={`mailto:${data.email}`}> 82 <span className="glyph">â</span> 83 <span>email</span> 84 </a> 85 86 <div className="tree-group">ââ shortcuts ââ</div> 87 <div className="tree-item" style={{ cursor: 'default' }}> 88 <span className="glyph"></span> 89 <span>which-key</span> 90 <span className="key">?</span> 91 </div> 92 <div className="tree-item" style={{ cursor: 'default' }}> 93 <span className="glyph"></span> 94 <span>command</span> 95 <span className="key">:</span> 96 </div> 97 <div className="tree-item" style={{ cursor: 'default' }}> 98 <span className="glyph"></span> 99 <span>search</span> 100 <span className="key">/</span> 101 </div> 102 <div className="tree-item" style={{ cursor: 'default' }}> 103 <span className="glyph"></span> 104 <span>find files</span> 105 <span className="key">âp</span> 106 </div> 107 108 <div className="tree-group">ââ theme ââ</div> 109 <button type="button" className="tree-item tree-theme" onClick={onToggleTheme}> 110 <span className="glyph">{themeGlyph}</span> 111 <span>{themeLabel} theme</span> 112 <span className="key">t</span> 113 </button> 114 </div> 115 ); 116} 117 118function Statusline({ mode, buffer, line, total, search, match }) { 119 const modeLabel = 120 { 121 NORMAL: 'NORMAL', 122 INSERT: 'INSERT', 123 VISUAL: 'VISUAL', 124 COMMAND: 'COMMAND', 125 SEARCH: 'SEARCH', 126 }[mode] || 'NORMAL'; 127 const modeColor = { 128 NORMAL: 'var(--blue)', 129 INSERT: 'var(--green)', 130 VISUAL: 'var(--purple)', 131 COMMAND: 'var(--yellow)', 132 SEARCH: 'var(--orange)', 133 }[mode]; 134 const pct = total > 0 ? Math.round((line / total) * 100) : 0; 135 const hasMatches = match && match.count > 0; 136 return ( 137 <div className="statusline"> 138 <div className="sl-mode" style={{ background: modeColor }}> 139 {modeLabel} 140 </div> 141 <div className="sl-seg git"> main</div> 142 <div className="sl-seg">{buffer.file}</div> 143 {search && 144 <div className="sl-seg diag"> 145 /{search}{hasMatches ? ` [${match.idx}/${match.count}]` : ' [0/0]'} 146 </div> 147 } 148 <div className="sl-spacer" /> 149 <div className="sl-right">
150 <span className="sl-ft"> markdown</span> 151 <span className="sep">â</span> 152 <span>utf-8</span> 153 <span className="sep">â</span> 154 <span>LF</span> 155 <span className="sep">â</span> 156 <span>{line}:1</span> 157 <span className="sep">â</span> 158 <span>{pct}%</span> 159 </div> 160 </div> 161 ); 162} 163 164function Cmdline({ mode, cmd, setCmd, onSubmit, onCancel, hint, completions = [] }) { 165 const inputRef = React.useRef(null); 166 const [wildItems, setWildItems] = React.useState([]); 167 const compList = React.useRef([]); 168 const compIdx = React.useRef(-1); 169 170 function resetComp() { 171 compList.current = []; 172 compIdx.current = -1; 173 setWildItems([]); 174 } 175 176 React.useEffect(() => { 177 if ((mode === 'COMMAND' || mode === 'SEARCH') && inputRef.current) { 178 inputRef.current.focus(); 179 } 180 resetComp(); 181 }, [mode]); 182 183 if (mode === 'COMMAND' || mode === 'SEARCH') { 184 const prefix = mode === 'COMMAND' ? ':' : '/'; 185 return ( 186 <div className="cmdline active"> 187 {wildItems.length > 0 && ( 188 <div className="cmd-wildmenu"> 189 {wildItems.map((item, i) => ( 190 <span 191 key={item} 192 className={'cmd-wm-item' + (i === compIdx.current ? ' on' : '')} 193 > 194 {item} 195 </span> 196 ))} 197 </div> 198 )} 199 <span className="prefix">{prefix}</span> 200 <input 201 ref={inputRef} 202 value={cmd} 203 onChange={(e) => { 204 resetComp(); 205 setCmd(e.target.value); 206 }} 207 onKeyDown={(e) => { 208 if (e.key === 'Enter') { 209 e.preventDefault(); 210 resetComp(); 211 onSubmit(); 212 } else if (e.key === 'Escape') { 213 e.preventDefault(); 214 resetComp(); 215 onCancel(); 216 } else if (e.key === 'Tab' && mode === 'COMMAND') { 217 e.preventDefault(); 218 let list = compList.current; 219 if (!list.length) { 220 const base = cmd.trim().toLowerCase(); 221 list = completions.filter((c) => c.startsWith(base)); 222 if (!list.length) return; 223 compList.current = list; 224 } 225 const dir = e.shiftKey ? -1 : 1; 226 const len = list.length; 227 compIdx.current = ((compIdx.current + dir) % len + len) % len; 228 setCmd(list[compIdx.current]); 229 setWildItems([...list]); 230 } 231 }} 232 placeholder={mode === 'COMMAND' ? 'command â Tab to complete' : 'search bufferâ¦'} 233 /> 234 </div> 235 ); 236 } 237 238 return ( 239 <div className="cmdline"> 240 <span className="hint"> 241 {hint || 242 '-- ? which-key · : command · / search · âp find files · hjkl move · gg/G jump --'} 243 </span> 244 </div> 245 ); 246} 247 248function Splash() { 249 const ascii = ` âââ âââ· â⢠ââ 250 ââ â· ââ ââ ââªâââ 251 ââââ âââ âââââ âââââ 252 âââ¢ââââââªââ âªâââââââ 253 .â â·ââ· â â âââ 254 love.sahaj - portfolio v26.04`; 255 return ( 256 <div className="splash"> 257 <div className="splash-inner"> 258 <div className="logo">{ascii}</div> 259 <div className="ver">a portfolio by Love Sahajbir Singh</div> 260 <div className="tip"> 261 press <kbd>?</kbd> any time to learn the keys 262 </div> 263 </div> 264 </div> 265 ); 266} 267 268Object.assign(window, { Tabline, Winbar, FileTree, Statusline, Cmdline, Splash });
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.