snyvi 1.30.0

A fast, beautiful viewer for the documents your agents produce
# The folder dialog snyvi shows on Windows (src/platform.rs, `pick_folder`).
#
# The daemon runs this in `powershell -STA -EncodedCommand` and reads one
# line: the folder chosen, or nothing for a cancel. `@TITLE@` is replaced
# with the dialog's title before it runs, quoted for a single-quoted string.
#
# The dialog is Explorer's own (`IFileOpenDialog` asked for folders): an
# address bar, search, Quick access, the folders the reader pinned. .NET
# Framework's FolderBrowserDialog -- the one Windows PowerShell has -- is the
# "Browse For Folder" tree from XP, and is only the fallback here, for a
# machine where the C# below cannot be compiled.
#
# Either one is owned by a form of this script's own -- topmost, invisible,
# with a taskbar button -- so it opens above snyvi and can always be found
# again. Coming to the front is the window's to allow: it calls
# `AllowSetForegroundWindow` just before it asks (src/bin/app.rs).

$ErrorActionPreference = 'Stop'
# The path goes back on stdout as UTF-8, whatever the console's code page:
# a folder named in Hindi or with an accent comes back as it is spelled.
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$title = '@TITLE@'

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$owner = New-Object System.Windows.Forms.Form -Property @{
  Text = $title; TopMost = $true; ShowInTaskbar = $true
  StartPosition = 'CenterScreen'; FormBorderStyle = 'None'
  Size = [System.Drawing.Size]::new(1, 1); Opacity = 0
}
$owner.Show(); $owner.Activate()

$picked = $null
try {
  Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

public static class SnyviFolderDialog {
    [ComImport, Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")]
    class FileOpenDialog {}

    // IFileDialog's vtable up to GetResult, in order; nothing after it is called.
    [ComImport, Guid("42f85136-db7e-439c-85f1-e4075d135fc8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IFileDialog {
        [PreserveSig] int Show(IntPtr owner);
        void SetFileTypes(uint count, IntPtr specs);
        void SetFileTypeIndex(uint index);
        void GetFileTypeIndex(out uint index);
        void Advise(IntPtr events, out uint cookie);
        void Unadvise(uint cookie);
        void SetOptions(uint options);
        void GetOptions(out uint options);
        void SetDefaultFolder(IShellItem item);
        void SetFolder(IShellItem item);
        void GetFolder(out IShellItem item);
        void GetCurrentSelection(out IShellItem item);
        void SetFileName([MarshalAs(UnmanagedType.LPWStr)] string name);
        void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string name);
        void SetTitle([MarshalAs(UnmanagedType.LPWStr)] string title);
        void SetOkButtonLabel([MarshalAs(UnmanagedType.LPWStr)] string label);
        void SetFileNameLabel([MarshalAs(UnmanagedType.LPWStr)] string label);
        void GetResult(out IShellItem item);
    }

    [ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IShellItem {
        void BindToHandler(IntPtr bc, ref Guid handler, ref Guid iid, out IntPtr ppv);
        void GetParent(out IShellItem parent);
        void GetDisplayName(uint form, [MarshalAs(UnmanagedType.LPWStr)] out string name);
    }

    const uint FOS_PICKFOLDERS = 0x20, FOS_FORCEFILESYSTEM = 0x40, FOS_PATHMUSTEXIST = 0x800;
    const uint SIGDN_FILESYSPATH = 0x80058000;
    const int CANCELLED = unchecked((int)0x800704C7);

    // The folder chosen, or null for a cancel.
    public static string Pick(IntPtr owner, string title) {
        var d = (IFileDialog)new FileOpenDialog();
        try {
            uint o;
            d.GetOptions(out o);
            // Folders only, and only ones with a path: not Libraries, not
            // This PC, not a phone -- a desk needs somewhere to start.
            d.SetOptions(o | FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST);
            d.SetTitle(title);
            d.SetOkButtonLabel("Open");
            int hr = d.Show(owner);
            if (hr == CANCELLED) return null;
            Marshal.ThrowExceptionForHR(hr);
            IShellItem item;
            d.GetResult(out item);
            string path;
            item.GetDisplayName(SIGDN_FILESYSPATH, out path);
            return path;
        } finally {
            Marshal.ReleaseComObject(d);
        }
    }
}
'@
  $picked = [SnyviFolderDialog]::Pick($owner.Handle, $title)
} catch {
  # No compiler, a constrained language mode, a shell without the dialog:
  # the old dialog still answers the question.
  $d = New-Object System.Windows.Forms.FolderBrowserDialog
  $d.Description = $title; $d.ShowNewFolderButton = $false
  if ($d.ShowDialog($owner) -eq 'OK') { $picked = $d.SelectedPath }
}
$owner.Close()
if ($picked) { $picked }