From 61b68fcfef70857afe38bda7d715f59b5c3864a8 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 27 Jun 2026 15:25:50 -0400 Subject: feat(theme-studio): rebuild the dirvish preview as a realistic two-pane The preview was a flat catalog dumping every face on labeled lines. It's now a believable two-pane dirvish: an active directory listing (the real nerd-icon glyph and color per file type, dir-entry counts, file sizes, the hl-line on the selected row, a dimmed backup) beside an ls-l preview of the selected dir. Faces that don't fit a calm listing (vc, git, subtree, media, proc, narrow, emerge) moved to a labeled extras strip below, so all 38 dirvish faces stay covered. Glyphs and colors mirror what nerd-icons actually emits per type. --- scripts/theme-studio/previews.js | 65 ++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) (limited to 'scripts/theme-studio/previews.js') diff --git a/scripts/theme-studio/previews.js b/scripts/theme-studio/previews.js index 9209d521a..72bf242e2 100644 --- a/scripts/theme-studio/previews.js +++ b/scripts/theme-studio/previews.js @@ -362,18 +362,59 @@ function renderDiredPreview(){const a='dired',L=[]; L.push(' '+os(a,'dired-special','prw-r--r--')+' craig 0 fifo.pipe'); L.push(os(a,'dired-warning','! disk space low on /home')); return previewLines(L);} -function renderDirvishPreview(){const a='dirvish',L=[]; - L.push(os(a,'dirvish-inactive','~/code')+' '+os(a,'dirvish-free-space','[free 24G]')); - L.push(os(a,'dirvish-hl-line',' '+os(a,'dirvish-file-modes','-rw-r--r--')+' '+os(a,'dirvish-file-link-number','1')+' '+os(a,'dirvish-file-user-id','craig')+' '+os(a,'dirvish-file-group-id','staff')+' '+os(a,'dirvish-file-size','4.0K')+' '+os(a,'dirvish-file-time','Jun 8 02:24')+' init.el ')); - L.push(' '+os(a,'dirvish-file-modes','drwxr-xr-x')+' '+os(a,'dirvish-file-link-number','5')+' '+os(a,'dirvish-file-user-id','craig')+' '+os(a,'dirvish-file-group-id','staff')+' '+os(a,'dirvish-file-size',' - ')+' '+os(a,'dirvish-file-time','Jun 7 18:00')+' '+os(a,'dirvish-collapse-dir-face','src')+os(a,'dirvish-subtree-state','+')+os(a,'dirvish-subtree-guide',' |')); - L.push(os(a,'dirvish-hl-line-inactive',' inactive-window current line ')); - L.push(' inode '+os(a,'dirvish-file-inode-number','1048576')+' dev '+os(a,'dirvish-file-device-number','8,1')+' '+os(a,'dirvish-collapse-empty-dir-face','empty/')+' '+os(a,'dirvish-collapse-file-face','file.txt')); - L.push(' VC '+os(a,'dirvish-vc-added-state','A')+os(a,'dirvish-vc-edited-state','M')+os(a,'dirvish-vc-removed-state','D')+os(a,'dirvish-vc-conflict-state','C')+os(a,'dirvish-vc-locked-state','L')+os(a,'dirvish-vc-missing-state','!')+os(a,'dirvish-vc-needs-merge-face','m')+os(a,'dirvish-vc-needs-update-state','u')+os(a,'dirvish-vc-unregistered-face','?')); - L.push(' git '+os(a,'dirvish-git-commit-message-face','feat: enlarge the picker')); - L.push(' '+os(a,'dirvish-media-info-heading','Media')+' '+os(a,'dirvish-media-info-property-key','Dimensions:')+' 1920x1080'); - L.push(' proc '+os(a,'dirvish-proc-running','running')+' / '+os(a,'dirvish-proc-finished','finished')+' / '+os(a,'dirvish-proc-failed','failed')); - L.push(' narrow '+os(a,'dirvish-narrow-match-face-0','m0')+' '+os(a,'dirvish-narrow-match-face-1','m1')+' '+os(a,'dirvish-narrow-match-face-2','m2')+' '+os(a,'dirvish-narrow-match-face-3','m3')+os(a,'dirvish-narrow-split',' | ')+os(a,'dirvish-emerge-group-title','Group: images')); - return previewLines(L);} +// A believable two-pane dirvish: an active directory listing on the left +// (nerd-icon per file type, dir-entry counts / file sizes, the hl-line on the +// selected row, a dimmed backup) and the selected dir's ls-l preview on the +// right. Faces that don't fit a calm listing (vc, git, subtree, media, proc, +// narrow, emerge) live in a labeled extras strip below so theme coverage stays +// complete. Glyphs/colors mirror what nerd-icons actually emits per type. +function renderDirvishPreview(){ + const D='dirvish', N='nerd-icons', DR='dired'; + // foreground-only span, so a row background (the hl-line) shows through it + const fg=(app,face,t)=>`${t}`; + const ic=(face,g)=>os(N,face,g); + const pad=(name,w)=>esc(name)+' '.repeat(Math.max(1,w-name.length)); + const HL=pkgEffBg(D,'dirvish-hl-line')||MAP['bg']; + + // ---- left pane: the active directory ---- + const left=[os(DR,'dired-header','~/code/emacs-wttrin:')]; + for(const [name,cnt,sel] of [['assets','4',true],['examples','1'],['githooks','1'], + ['inbox','3'],['scripts','1'],['tests','71']]){ + if(sel) left.push(``+fg(N,'nerd-icons-yellow','')+' ' + +fg(DR,'dired-directory',pad(name,21))+fg(D,'dirvish-file-size',cnt)+``); + else left.push(ic('nerd-icons-yellow','')+' '+os(DR,'dired-directory',pad(name,21)) + +os(D,'dirvish-file-size',cnt)); + } + for(const [face,g,name,size] of [['nerd-icons-lblue','','CLAUDE.md','4.9k'], + ['nerd-icons-blue','','Eask','518'],['nerd-icons-blue','','LICENSE','34k'], + ['nerd-icons-dorange','','Makefile','12k'],['nerd-icons-lcyan','','README.org','24k'], + ['nerd-icons-lgreen','','todo.org','23k'],['nerd-icons-purple','','wttrin.el','69k'], + ['nerd-icons-dsilver','','wttrin.elc','4.3k']]) + left.push(ic(face,g)+' '+pad(name,21)+os(D,'dirvish-file-size',size)); + left.push(ic('nerd-icons-lgreen','')+' '+os(DR,'dired-ignored',pad('todo.org~',21)) + +os(D,'dirvish-file-size','8.8k')); + + // ---- right pane: ls -l preview of the selected dir ---- + const ll=(size,time,name)=>os(D,'dirvish-file-modes','-rw-r--r--')+' ' + +os(D,'dirvish-file-link-number','1')+' '+os(D,'dirvish-file-user-id','cjennings')+' ' + +os(D,'dirvish-file-group-id','cjennings')+' '+os(D,'dirvish-file-size',size)+' ' + +os(D,'dirvish-file-time',time)+' '+ic('nerd-icons-orange','\u{F0E2D}')+' '+esc(name); + const right=[os(DR,'dired-header','assets:'), + ll('54K','Jun 26 10:53','geolocation.png'),ll('52K','Jun 26 10:53','location-menu.png'), + ll('3.1K','Apr 10 12:03','made-for-emacs.svg'),ll('346K','Jun 26 10:53','wttrin.png')]; + + // ---- extras: remaining dirvish faces, kept for theme coverage ---- + const ex=[ + os(D,'dirvish-inactive','inactive pane')+' '+os(D,'dirvish-hl-line-inactive',' inactive current line ')+' '+os(D,'dirvish-free-space','[free 24G]'), + 'vc '+os(D,'dirvish-vc-added-state','A')+os(D,'dirvish-vc-edited-state','M')+os(D,'dirvish-vc-removed-state','D')+os(D,'dirvish-vc-conflict-state','C')+os(D,'dirvish-vc-locked-state','L')+os(D,'dirvish-vc-missing-state','!')+os(D,'dirvish-vc-needs-merge-face','m')+os(D,'dirvish-vc-needs-update-state','u')+os(D,'dirvish-vc-unregistered-face','?')+' git '+os(D,'dirvish-git-commit-message-face','feat: enlarge the picker'), + 'subtree '+os(D,'dirvish-collapse-dir-face','src')+os(D,'dirvish-subtree-state','+')+os(D,'dirvish-subtree-guide',' | ')+os(D,'dirvish-collapse-empty-dir-face','empty/')+' '+os(D,'dirvish-collapse-file-face','file.txt')+' inode '+os(D,'dirvish-file-inode-number','1048576')+' dev '+os(D,'dirvish-file-device-number','8,1'), + 'media '+os(D,'dirvish-media-info-heading','Media')+' '+os(D,'dirvish-media-info-property-key','Dimensions:')+' 1920x1080 proc '+os(D,'dirvish-proc-running','running')+'/'+os(D,'dirvish-proc-finished','finished')+'/'+os(D,'dirvish-proc-failed','failed'), + 'narrow '+os(D,'dirvish-narrow-match-face-0','m0')+' '+os(D,'dirvish-narrow-match-face-1','m1')+' '+os(D,'dirvish-narrow-match-face-2','m2')+' '+os(D,'dirvish-narrow-match-face-3','m3')+os(D,'dirvish-narrow-split',' | ')+os(D,'dirvish-emerge-group-title','Group: images')]; + + const col=(lines)=>`
${lines.join('\n')}
`; + return `
` + +`
${col(left)}${col(right)}
` + +`
${col(ex)}
`;} function renderCalibredbPreview(){const a='calibredb',L=[]; L.push(os(a,'calibredb-search-header-library-name-face','Calibre')+' '+os(a,'calibredb-search-header-library-path-face','~/books')+' '+os(a,'calibredb-search-header-total-face','412 books')+' '+os(a,'calibredb-search-header-filter-face','tag:scifi')+' '+os(a,'calibredb-search-header-sort-face','sort:date')+' '+os(a,'calibredb-search-header-highlight-face','[*]')); L.push(''); -- cgit v1.2.3