Tools/glow.ps1
|
# Companion for glow — wraps the executable so style and config reach it as CLI # flags instead of environment variables. # # glow honors no XDG environment variable (verified against glow 2.1.2): # * GLOW_CONFIG_DIR / GLOW_CONFIG_HOME / GLOW_CONFIG / GLOW_CONFIG_FILE are all # ignored — the config path comes from a Win32 known-folder lookup, so it does # not move even when APPDATA/LOCALAPPDATA are redirected. # * GLAMOUR_STYLE is never read at all. # * GLOW_STYLE is parsed, but loses to glow's non-TTY downgrade, so it silently # fails to apply. # Only the --config and -s flags work reliably, hence this wrapper. # adapter for glow/honors-env:GLOW_CONFIG_DIR # See docs/external-dependencies.md. # # Reads: $DFConfig.GlowTheme, then $DFConfig.Theme, then settings.theme in glow.json; # settings.configFile (default ${XDG_CONFIG_HOME}/glow/glow.yml). # Defines: glow (wrapper), Resolve-DFGlowStyle, $global:DFGlowStyle. # Writes: creates the config file's directory only; glow.yml itself is yours. # 1. Settings from tool JSON. Theme: per-tool GlowTheme -> shared Theme -> JSON default. $_settings = $DFCurrentTool.settings $_default = $_settings.PSObject.Properties['theme']?.Value ?? 'catppuccin-mocha' $_theme = Get-DFConfiguredTheme -ToolKey 'GlowTheme' -Default $_default $_theme = Resolve-DFThemeName -Name $_theme -ThemeMap $DFCurrentTool.themeMap $_cfgRaw = $_settings.PSObject.Properties['configFile']?.Value ?? '${XDG_CONFIG_HOME}/glow/glow.yml' $_cfg = Expand-DFXdgPath $_cfgRaw New-DFDirectory (Split-Path $_cfg) | Out-Null # 2. Register Resolve-DFGlowStyle (captures $_bundledDir via closure) $_bundledDir = Join-Path $PSScriptRoot 'glow' # Private helpers can't be called by name from a function:global: closure, but a # captured scriptblock keeps its module binding, so capture them here. $_resolveThemeFile = ${function:Resolve-DFThemeFile} Set-Item -Path 'function:global:Resolve-DFGlowStyle' -Value ({ <# .SYNOPSIS Resolves a glow style name to the value handed to glow's -s flag. .DESCRIPTION Tries, in order: -Name as a full path to an existing file; then $XDG_CONFIG_HOME\glow\themes\<Name>.json; then DotForge's bundled Tools\glow\<Name>.json (catppuccin-mocha ships there); then glow's own built-in styles (auto, dark, light, dracula, pink, notty, ascii, tokyo-night), returned as the bare name. Anything else warns and returns 'auto', because glow exits with an error on an unknown style. Defined by DotForge's glow companion. To switch the style for the rest of the session, assign the result to $global:DFGlowStyle. .PARAMETER Name A style name or the full path to a glamour style JSON file. .EXAMPLE $global:DFGlowStyle = Resolve-DFGlowStyle -Name dracula Switches every later glow call in this session to the dracula style. .OUTPUTS System.String. A style file path or a glow built-in style name. .LINK https://github.com/simsrw73/DotForge/blob/main/docs/guide/tools.md #> [CmdletBinding()] [OutputType([string])] param([Parameter(Mandatory)][string]$Name) # glow's own style names — passed through verbatim when no file matches. $builtin = @('auto', 'dark', 'light', 'dracula', 'pink', 'notty', 'ascii', 'tokyo-night') $file = & $_resolveThemeFile -Tool 'glow' -Name $Name -BundledDir $_bundledDir if ($file) { return $file } if ($Name -in $builtin) { return $Name } # Never return an unresolved path: glow exits 1 with "specified style does not # exist" rather than degrading, which would break the command outright. Write-Warning "DotForge: glow style '$Name' not found — falling back to 'auto'" 'auto' }.GetNewClosure()) # 3. Resolve the initial style. The wrapper reads $DFGlowStyle at call time rather # than capturing it, so `$global:DFGlowStyle = 'dracula'` switches theme live. $global:DFGlowStyle = Resolve-DFGlowStyle -Name $_theme # 4. Wrap the executable. A simple (non-advanced) function keeps @args available so # glow's own flags pass through unbound; & glow.exe resolves to the Application, # not back into this function. The ExpectingInput branch is required: without it # a piped `'# Hi' | glow` hangs, because a function with no process block swallows # the pipeline and glow.exe then blocks on the inherited console stdin. Set-Item -Path 'function:global:glow' -Value ({ <# .SYNOPSIS Runs glow with DotForge's config file and the current session style. .DESCRIPTION Wraps glow.exe and always passes --config <glow.yml> and -s <style>, because glow ignores its environment variables on Windows. The style is read from $global:DFGlowStyle on every call, so assigning to it switches the theme immediately; when it is empty, 'auto' is used. Other arguments, glow's subcommands and piped input pass through unchanged. Defined by DotForge's glow companion. .EXAMPLE glow README.md Renders a Markdown file with the configured style. .EXAMPLE Get-Content notes.md | glow Renders piped Markdown. .OUTPUTS System.String. The rendered Markdown. .LINK https://github.com/simsrw73/DotForge/blob/main/docs/guide/tools.md #> $_s = if ($global:DFGlowStyle) { $global:DFGlowStyle } else { 'auto' } if ($MyInvocation.ExpectingInput) { $input | & glow.exe --config $_cfg -s $_s @args } else { & glow.exe --config $_cfg -s $_s @args } }.GetNewClosure()) |