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:
⌨️Shortcut
To use Peek:
- Select a file
- Press
Ctrl
+Space
. - Use the arrow keys (
Left
andRight
) or (Up
andDown
) 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.