Logo Xingxin on Bug

Boost Productivity Using PowerToys Day 4 - Peek

January 8, 2025
4 min read

This is the day 4 of my journey using PowerToys following the post. ⏮️ Day 3: Registry Preview ⏸️ Day 5: FancyZones ⏭️

📝Description

Peek is a feature similar to the “Preview Pane” in Windows Explorer.

However, it offers a richer display for developer files like Markdown, yml, .gitignore, and more. For example, it can render YAML files with syntax highlighting: boost-my-productivity-using-powertoys-day-4-peek-yml.webp

⌨️Shortcut

To use Peek:

  1. Select a file
  2. Press Ctrl + Space.
  3. Use the arrow keys (Left and Right) or (Up and Down) to navigate through the preview.

Remark

I think this is the real power using Peek as you only need keyboard to navigate without touching your mouse.

🖱Code

File Preview Handler

One of the first things I wondered was how how Peek renders files of different formats. For instance, an image is displayed differently from plain text. After digging into the code, I discovered that the class PreviewerFactory uses the Factory Method🧩 design pattern to handle various file types.

Here’s a simplified version of the code:

public class PreviewerFactory
{
    //🏭 factory method
    public IPreviewer Create(IFileSystemItem item)
    {
        if (ImagePreviewer.IsItemSupported(item))
        {
            return new ImagePreviewer(item);
        }
        else if (VideoPreviewer.IsItemSupported(item))
        {
            return new VideoPreviewer(item);
        }
        //... many more
    }
}

In this design, if a file IsItemSupported() by a specific previewer, that previewer handles the display and processing. Peek supports a wide range of file types, including:

  • 1️⃣ image
  • 2️⃣ video
  • 3️⃣ audio
  • 4️⃣ archive(.zip, .7z,.tar…)
  • 5️⃣ webbrowser (.html, .md, .pdf)
  • 6️⃣ …and more

Wait, why is Markdown categorized under “WebBrowser” content?🫢

Let’s explore that next.

Markdown

As an avid markdown user, I was particularly curious about how Peek renders .md files. What tool do Microsoft developers use to process .md🤔? It turns out they use markdig, a popular Markdown processing library.

Here’s a snippet of how it works:

using Markdig;
 
public static string MarkdownHtml(string fileContent, string theme, string filePath, ImagesBlockedCallBack imagesBlockedCallBack)
{
    //...(details hidden for brevity)
    MarkdownPipelineBuilder pipelineBuilder;
    pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley().UseYamlFrontMatter().UseMathematics();
 
    MarkdownPipeline pipeline = pipelineBuilder.Build();
    string parsedMarkdown = Markdown.ToHtml(fileContent, pipeline);
 
    string markdownHTML = $"{htmlHeader}{parsedMarkdown}{HtmlFooter}";
    return markdownHTML;  //👈 This is what we see in the Peek dialog
}

Dispose

One thing I truly appreciate about Microsoft developers’ code is how they follow the best practices they advocate. Here’s a comparison on dispose pattern of good vs. bad design:

// ❌bad design
public class DisposableResourceHolder : IDisposable {
    public virtual void Dispose() { ... }
    protected virtual void Dispose(bool disposing) { ... }
}
 
// ✅good design
public class DisposableResourceHolder : IDisposable {
    public void Dispose() { ... }
    protected virtual void Dispose(bool disposing) { ... }
}

We can be clearly seen Microsoft developers follow the best practice in the WebBrowserPreviewer:

~WebBrowserPreviewer()
{
    Dispose(false);
}
 
public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}
 
protected virtual async void Dispose(bool disposing)
{
    if (!this.disposed)
    {
        await Microsoft.PowerToys.FilePreviewCommon.Helper.CleanupTempDirAsync(TempFolderPath.Path);
        disposed = true;
    }
}

In the meantime, we can also notice that this design avoid lots of unnecessary clean up every time this class destroyed.