Skip to content

change markdown preview to inherit base colors from the active Neovim theme#1150

Open
oddish3 wants to merge 1 commit intoqvacua:masterfrom
oddish3:master
Open

change markdown preview to inherit base colors from the active Neovim theme#1150
oddish3 wants to merge 1 commit intoqvacua:masterfrom
oddish3:master

Conversation

@oddish3
Copy link

@oddish3 oddish3 commented Feb 15, 2026

Hey,

Thanks for this project, it's great.
I just wanted to share/add this PR to fix the markdown preview being white by default. Maybe this could be added as an option, but I'm not sure how to do that and wanted to start this as a PR

Related to #732

Thank you

Changes:
Implements theme inheritance for the Markdown preview window, including syntax highlighting for code blocks.

  • The preview background, text, and other elements are now styled using the main colors from the active Neovim theme.
  • Code blocks are syntax-highlighted using Prism.js. The highlight colors are sourced from the corresponding Neovim highlight groups (Comment, String, Number, etc.).
  • The theme-loading mechanism has been refactored to be more resilient, ensuring the theme applies even if some highlight groups are not defined by the colorscheme.

…d, links, etc.) from the active Neovim theme
Copilot AI review requested due to automatic review settings February 15, 2026 12:27
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances the markdown preview feature by implementing theme inheritance from the active Neovim colorscheme and adding syntax highlighting for code blocks. This addresses issue #732 by ensuring the preview adapts to both light and dark themes.

Changes:

  • Integrated Prism.js for syntax highlighting in markdown code blocks
  • Extended theme color extraction to include syntax highlighting groups (Comment, String, Number, Boolean, Statement, Type, Constant, Special)
  • Refactored theme loading to be more resilient by using fallback colors when highlight groups are undefined

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
VimR/VimR/markdown/template.html Added Prism.js CSS and JavaScript libraries from CDN for syntax highlighting
VimR/VimR/markdown/color-overrides.css Renamed CSS variables for clarity and added Prism token color rules mapped to Neovim highlight groups
VimR/VimR/Theme.swift Added syntax highlighting color properties with system color defaults and refactored color extraction to use optional unwrapping
VimR/VimR/MainWindow+Delegates.swift Extended highlight group fetching to include syntax groups and changed error handling to always return a color map
VimR/VimR/CssUtils.swift Updated template variable replacements to match renamed CSS variables and added new syntax color replacements

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="github-markdown.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading Prism's default light theme CSS may cause visual conflicts with dark Neovim themes. The custom CSS overrides target specific token types, but Prism's base theme still applies background colors and other styles that may not align with the user's theme. Consider either:

  1. Not loading the Prism CSS at all and relying only on the custom token colors defined in color-overrides.css
  2. Loading a minimal Prism theme that doesn't include background/foreground colors
    This will ensure a more consistent appearance across different Neovim color schemes.
Suggested change
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +76
var cssStatementColor = NSColor.systemTeal
var cssTypeColor = NSColor.systemGreen
var cssConstantColor = NSColor.systemRed
var cssSpecialColor = NSColor.systemOrange
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default values for syntax highlighting colors use system colors (NSColor.systemTeal, NSColor.systemGreen, etc.) which are macOS 10.14+ APIs. Ensure these system colors provide appropriate contrast with both light and dark backgrounds, as they may not be optimized for the markdown preview context. Consider using colors that are explicitly designed to work with the base cssColor and cssBackgroundColor, or testing these defaults with various Neovim themes to ensure readability.

Suggested change
var cssStatementColor = NSColor.systemTeal
var cssTypeColor = NSColor.systemGreen
var cssConstantColor = NSColor.systemRed
var cssSpecialColor = NSColor.systemOrange
var cssStatementColor = NSColor(hex: "005cc5")!
var cssTypeColor = NSColor(hex: "6f42c1")!
var cssConstantColor = NSColor(hex: "d73a49")!
var cssSpecialColor = NSColor(hex: "e36209")!

Copilot uses AI. Check for mistakes.
return map
} else {
self.logger.warning("Could not get all theme colors, will use defaults for some.")
return map
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change modifies the return type behavior from optional (returning nil when not all colors found) to always returning a dictionary. While this makes the code more resilient, it's a breaking change that affects the caller in colorschemeChanged() method (line 84), which still expects nil returns for error cases. The else branch at line 89 of that method will never execute now. Consider updating the method signature to return a non-optional dictionary, or ensuring the calling code is also updated to handle the new behavior correctly.

Suggested change
return map
return nil

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +12
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
<style>
{{ css-overrides }}
</style>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prism.js version 1.29.0 is being used from a CDN. While this is a valid version, consider verifying if there are any known security vulnerabilities in this version and whether a newer version is available. Using a CDN without SRI (Subresource Integrity) attributes also means the content could potentially be modified. Consider adding integrity and crossorigin attributes to the script and link tags for better security, or bundle Prism.js locally to have full control over the version and content.

Suggested change
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
<style>
{{ css-overrides }}
</style>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" integrity="sha512-gCwi39u9W+dhOY6pscdI9cH8zlZd8Qv5Jp5yloN5uGxmimm7umPIHh7W8gVjaoHXP+STsp8lpql3h7rXx2sQ7w==" crossorigin="anonymous">
<style>
{{ css-overrides }}
</style>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js" integrity="sha512-uA3F/Wq+zoQ7aYIzl2nK0zUvwneQBOBedVgOxb6xviJn/NQqV5bugLax9Lw1Xb6RMxRRVwYFB9C1rRgL3y0R9Q==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-d6XBxoFepZqRFB5VX3M3+gOVDwSbz5pFKJSa2tZUTWH0SzV+AFUxwT5reMWKUhcT9wBxW2uX8OHSjMyxukYQjw==" crossorigin="anonymous"></script>

Copilot uses AI. Check for mistakes.
background-color: var(--nvim-code-background-color);
}

/* New styles for additional highlight groups */
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment "New styles for additional highlight groups" could be more descriptive. Consider updating it to explain that these styles apply Neovim syntax highlighting colors to Prism.js code tokens, which helps users understand the purpose and relationship between the two systems.

Suggested change
/* New styles for additional highlight groups */
/* Apply Neovim syntax highlighting colors (from the CSS variables above)
to Prism.js code tokens so markdown code blocks mirror Neovim's
highlight groups. */

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +12
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Prism.js scripts are loaded synchronously, which will block HTML parsing and page rendering until they're downloaded and executed. Consider adding the 'defer' attribute to these script tags (lines 11-12) to allow the HTML to parse completely before executing the scripts. Since Prism.highlightAll() is called at the end of the body anyway, deferring won't affect functionality but will improve page load performance, especially on slower connections.

Suggested change
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>

Copilot uses AI. Check for mistakes.
@oddish3
Copy link
Author

oddish3 commented Feb 15, 2026

Sorry for including copilot, i didn't actually use this to help, but it was enabled in my settings to review the PR, I'll leave it to the maintainers to decide whether they want this feature / whether what its saying is even accurate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants