Status: accepted (P2.2), checked against IntelliJ Platform 2025.1.3.
FR-11 asks for a setting that picks the viewer IntelliJ’s diff window shows first for a .md file: rendered side by
side, rendered merged, or the built-in text viewer. Whatever the mechanism, the user must still be able to switch
viewers in the diff window, and the setting must keep control.
How DiffRequestProcessor (the diff window’s controller) picks a viewer in 2025.1:
DiffSettingsHolder.DiffSettings.getSettings(place).diffToolsOrder,
a list of tool class names stored per place (DiffPlaces: CommitDialog, ChangesView, VcsLogView,
VcsFileHistoryView, Default and others). Tools missing from the list are appended in the order of
DiffManagerEx.getDiffTools(), which lists diff.DiffTool extensions before the built-in SimpleDiffTool,
UnifiedDiffTool, BinaryDiffTool and DirDiffTool.canShow() is true.DiffUserDataKeysEx.FORCE_DIFF_TOOL is read from the window’s context, not from the request, and disables the
switcher entirely.Defaults: most places start with an empty order, so a plugin viewer already wins there; VcsLogView starts with
SimpleDiffTool, UnifiedDiffTool and VcsFileHistoryView with UnifiedDiffTool, so the text viewer wins there.
DiffToolSubstitutor: replaces the first fitted tool with another one. It is @ApiStatus.Internal, and the
substitute also replaces the text viewer when the user picks it in the switcher, so there is no way back.FORCE_DIFF_TOOL: fixes one tool for the whole window and hides the switcher. Phase 1 set it on the request in
Compare Markdown Files…, where it had no effect.DiffSettings (chosen): public, not marked internal, and it is the mechanism IntelliJ itself uses
to remember the user’s choice.DefaultViewerOrder rewrites the tool order of every known place (DiffPlaces constants used for file diffs) and of
every place already stored in DiffSettingsHolder’s state:
SimpleDiffTool is listed first when no text tool is listed yet (otherwise the
unlisted plugin tools would still come first).Our tools accept only Markdown requests, so the order changes nothing for other files.
The order is written when the setting changes (Settings | Tools | Markdown Review, Apply) and once after the plugin
is installed or updated (a startup activity compares the setting with appliedDefaultViewer in the plugin’s state).
Between those moments IntelliJ’s own behavior applies: a viewer picked in a diff window stays first for that kind of
window. Compare Markdown Files… no longer forces a tool; it opens in the Default place, so it follows the
setting as well.
DiffSettingsHolder lives in an impl package. verifyPlugin reports no internal API use for it, and the
integration tests (DefaultViewerOrderTest) compute the effective order with DiffRequestProcessor’s own public
method, so a change in the platform shows up in CI.