mellow.nvim icon indicating copy to clipboard operation
mellow.nvim copied to clipboard

Thank you! (and show-n-tell)

Open pkazmier opened this issue 7 months ago • 4 comments

I just wanted to say thank you for creating such a nice theme. I've spent the past two days tuning it for various plug-ins, lazygit, pure prompt, fzf (and zoxide). Love the theme! Here are some screenshots and configurations if you are interested in seeing how I'm using it:

Pure Prompt

Image

Minor tweaks to replace the few hardcoded colors in the pure prompt with the mellow palette.

zstyle ':prompt:pure:git:branch' color '#757581'
zstyle ':prompt:pure:git:dirty' color 'magenta'
zstyle ':prompt:pure:git:stash' show yes
zstyle ':prompt:pure:host' color '#757581'
zstyle ':prompt:pure:user' color '#757581'
zstyle ':prompt:pure:virtualenv' color '#757581'

Fzf

Image

My fzf configuration. You'll see a theme (pun intended) with later configurations (blink, mini.pick) where I diverge from mellow's convention of using c.blue for matched parts of fuzzy searches. I find that the light blue does not provide enough contrast with the rest of the non-matching text. The bat previews use base16 so they get mellow for free so to speak.

export FZF_DEFAULT_OPTS="
  --multi
  --border=top
  --color=bg+:#1B1B1D
  --color=bg:-1
  --color=border:#2A2A2D
  --color=gutter:-1
  --color=header:#90B99F
  --color=hl+:#EA83A5
  --color=hl:#EA83A5:bold
  --color=info:#F5A191
  --color=marker:#F0C5A9
  --color=pointer:#ACA1CF
  --color=preview-scrollbar:#57575F
  --color=prompt:#E29ECA
  --color=query:#ACA1CF:bold
  --color=scrollbar:#57575F
  --color=spinner:#F0C5A9:bold
  --highlight-line
  --info=inline-right
  --layout=reverse
  --pointer='█'
  --scrollbar='▌'
  "

# Preview file content using bat (https://github.com/sharkdp/bat)
export FZF_CTRL_T_OPTS="
  --walker-skip .git,node_modules,target
  --preview 'bat -n --color=always {}'
  --bind 'ctrl-b:preview-up,ctrl-f:preview-down'
  --bind 'ctrl-/:change-preview-window(down|hidden|)'"

# CTRL-Y to copy the command into clipboard using pbcopy
export FZF_CTRL_R_OPTS="
  --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'
  --header 'Press CTRL-Y to copy command into clipboard'"

# Print tree structure in the preview window
export FZF_ALT_C_OPTS="
  --height=50%
  --walker-skip .git,node_modules,target
  --preview-window=down,border-top
  --preview 'eza --color=always {}'
  --bind 'ctrl-b:preview-up,ctrl-f:preview-down'
  --bind 'ctrl-/:change-preview-window(right|hidden|)'"

Zoxide (fzf)

Image

See fzf section above for the definition of FZF_DEFAULT_OPTS:

# zoxide fzf window
export _ZO_FZF_OPTS="
  $FZF_DEFAULT_OPTS
  --height=50%
  --preview 'eza --color=always {2..}'
  --preview-window=down,border-top
  --bind 'ctrl-b:preview-up,ctrl-f:preview-down'
  --bind 'ctrl-/:change-preview-window(right|hidden|)'"

Lazygit

Image

My lazygit configuration:

git:
  paging:
    colorArg: always
    pager: delta --dark --paging=never
gui:
  # Mellow theme
  authorColors:
    "*": "#E6B99D"
  nerdFontsVersion: "3"
  theme:
    activeBorderColor:
      - "#ACA1CF"
      - "bold"
    inactiveBorderColor:
      - "#57575F"
    optionsTextColor:
      - "#90B99F"
    selectedLineBgColor:
      - "#1B1B1D"
    cherryPickedCommitFgColor:
      - "#ACA1CF"
    cherryPickedCommitBgColor:
      - "bg"
    markedBaseCommitFgColor:
      - "#ACA1CF"
    markedBaseCommitBgColor:
      - "bg"
    unstagedChangesColor:
      - "#EA83A5"
    defaultFgColor:
      - "#C9C7CD"

mini.starter

Image

Highlight group settings:

    MiniStarterInactive   = { fg = c.gray04 },
    MiniStarterItemBullet = { fg = c.gray04, bold = true },
    MiniStarterItemPrefix = { fg = c.magenta, bold = true },
    MiniStarterQuery      = { fg = c.cyan, bold = true },
    MiniStarterSection    = { fg = c.blue, bold = true },
    MiniStarterHeader     = { fg = c.cyan, bold = true },

mini.statusline, mini.tabline, mini.map, mini.diff, treesitter-context

Image

Highlight group settings below. You'll notice I also enable bold (not shown but via vim.g.mellow_bold_functions) for function calls as I find the difference in color between the default foreground and white is very minor, so rather than use color, I use font weight to provide that distinction.

    MiniMapNormal                  = { fg = c.gray04, bg = c.gray01 },

    MiniStatuslineModeNormal       = { fg = c.bg, bg = c.cyan, bold = true },
    MiniStatuslineModeInsert       = { fg = c.bg, bg = c.blue, bold = true },
    MiniStatuslineModeVisual       = { fg = c.bg, bg = c.magenta, bold = true },
    MiniStatuslineModeCommand      = { fg = c.bg, bg = c.yellow, bold = true },
    MiniStatuslineModeReplace      = { fg = c.bg, bg = c.red, bold = true },
    MiniStatuslineModeTerminal     = { fg = c.bg, bg = c.green, bold = true },
    MiniStatuslineModeOther        = { fg = c.bg, bg = c.green, bold = true },

    StatusLine                     = { fg = c.white, bg = c.gray02 },
    StatusLineNC                   = { fg = c.gray05, bg = c.gray02 },
    MiniStatuslineFileinfo         = { fg = c.gray06, bg = c.gray03 },
    MiniStatuslineDevinfo          = { fg = c.gray06, bg = c.gray03 },
    MiniStatuslineDirectory        = { fg = c.gray05 },
    MiniStatuslineFilename         = { fg = c.white, bold = true },
    MiniStatuslineFilenameModified = { fg = c.red, bold = true },

    MiniTablineCurrent             = { fg = c.blue, bg = c.black, bold = true },
    MiniTablineVisible             = { fg = c.gray07, bg = c.black },
    MiniTablineModifiedCurrent     = { fg = c.black, bg = c.blue, bold = true },
    MiniTablineModifiedHidden      = { fg = c.black, bg = c.gray05, bold = true },
    MiniTablineModifiedVisible     = { fg = c.black, bg = c.gray07, bold = true },
    MiniTablineTabpagesection      = { fg = c.black, bg = c.green, bold = true },

    TreesitterContext              = { bg = c.gray01 },
    TreesitterContextBottom        = { sp = c.gray03, underdotted = true },
    TreesitterContextLineNumber    = { fg = c.gray04, bg = c.gray01 },

mini.pick

Image

Highlight group settings for Blink and MiniPick. Again, like my fzf configurations, I prefer matches when fuzzy searching to have more contrast than the non-matching text. I find the default c.blue used by mellow does not provide enough separation. In addition, I also found the cursor line in mini.pick and mini.files to be too faint, so I make that a bit brighter. But for my regular cursor line a normal buffer, I love the faint one provided by mellow.

    -- The default blue for matches in blink/cmp/pick is too faint,
    -- so we use c.cyan (which is really a bright magenta) instead.
    BlinkCmpLabelMatch   = { fg = c.cyan, bold = true },
    MiniPickMatchRanges  = { fg = c.cyan, bold = true },
    MiniPickMatchCurrent = { bg = c.gray02, bold = true },
    MiniPickPrompt       = { fg = c.blue, bold = true },
    MiniPickPromptPrefix = { fg = c.magenta },

Incremental search

Image

I found the default search settings in mellow did not distinguish the other matches sufficiently—they blend in with the rest of the syntax highlighting in the buffer. So I added the double underline to make them pop better. I also use the double underline as I use mini.cursorword which uses a single underline for the word under the cursor.

    Search = { sp = c.bright_yellow, underdouble = true },

mini.jump

Image

This is a better f/t where it allows you to keep pressing to move to subsequent instances on other lines. To help highlight those other spots, I like to use the undercurl as it really pops out.

    MiniJump = { sp = c.yellow, undercurl = true },

leap

Image

For leap I prefer to dim the rest of the text and use bold bright labels (versus using reverse text labels which are hard to read imo). I stick with the yellow as it's used by search and f/t above:

    LeapLabel    = { fg = c.bright_yellow, bold = true },
    LeapBackdrop = { fg = c.gray05 },

mini.clue

Image

Mini.clue uses DiagnosticHint as the default label for keys, which by default in mellow is c.cyan (the bright red). Before talking about mini.clue, I find that using red for a hint is very confusing as I associate red with error, but mellow uses c.red (orange) for error. So, I've changed hint to c.blue as it avoids the confusion with the least amount of change to mellow. And, now that I've done this, the mini.clue labels look good. For hydra-like keys, I then use the c.cyan (bright red) to signify that those can be pressed repeatedly.

    DiagnosticHint = { fg = c.blue },
    DiagnosticUnderlineHint = { fg = c.blue, underline = true },
    MiniClueNextKeyWithPostkeys = { fg = c.cyan },

render-markdown

Image

Highlight group settings for markdown:

    RenderMarkdownBullet     = { fg = c.cyan },
    RenderMarkdownCodeBorder = { bg = c.black },
    RenderMarkdownTableHead  = { fg = c.gray03 },
    RenderMarkdownTableRow   = { fg = c.gray03 },


    ["@markup.heading"]      = { fg = c.bright_cyan, bold = true },
    ["@markup.heading.1"]    = { italic = false },
    ["@markup.heading.2"]    = { italic = false },
    ["@markup.heading.3"]    = { italic = false },
    ["@markup.heading.4"]    = { italic = false },
    ["@markup.heading.5"]    = { italic = false },
    ["@markup.heading.6"]    = { italic = false },
    ["@markup.strong"]       = { fg = c.cyan, bold = true },
    ["@markup.italic"]       = { fg = c.cyan, italic = true },

Render Markdown configuration:

  require("render-markdown").setup({
    file_types = { "markdown", "md", "codecompanion" },
    render_modes = { "n", "no", "c", "t", "i", "ic" },
    checkbox = {
      enable = true,
      position = "inline",
    },
    code = {
      sign = false,
      border = "thin",
      position = "right",
      width = "block",
      above = "▁",
      below = "▔",
      language_left = "█",
      language_right = "█",
      language_border = "▁",
      left_pad = 1,
      right_pad = 1,
    },
    heading = {
      width = "block",
      backgrounds = {
        "MiniStatusLineModeNormal",
        "MiniStatusLineModeInsert",
        "MiniStatusLineModeOther",
        "MiniStatusLineModeReplace",
        "MiniStatusLineModeCommand",
        "MiniStatusLineModeVisual",
      },
      sign = false,
      left_pad = 1,
      right_pad = 0,
      position = "right",
      icons = {
        "",
        "",
        "",
        "",
        "",
        "",
      },
    },
  })

pkazmier avatar Jul 09 '25 15:07 pkazmier

Wow, this is super cool to see the theme getting some love. Thank you so much for sharing. You are welcome to contribute your tweaks to the theme, IMO, it looks better with these changes.

kvrohit avatar Jul 11 '25 07:07 kvrohit

Thanks. I'd be happy to contribute back, but I'm not sure all of my changes make sense. For example, the changes I made for search and f/t (mini.jump) look great IMO, but only if your terminal allows you to configure the position and weight of the underline. Let me make a list of the things I changed and you let me know which you think would be good for a PR:

Additions with no impact

  • [x] Extra for lazygit
  • [x] Extra for fzf
  • [x] Support for mini.clue
  • [x] Support for mini.map
  • [x] Support for mini.pick
  • [x] Support for mini.starter
  • [x] Support for mini.statusline
  • [x] Support for mini.tabline
  • [x] Support for leap
  • [x] Support for treesitter-context

Changes for your consideration

  • [x] StatusLine and StatusLineNC: use gray02 instead of gray01 for three reasons. It provides better contrast between windows. It matches the color used by WinSeparator, so frames around windows use the same color. It provides better contrast with the cursor line.
  • [x] CmpItemAbbrMatch and CmpItemAbbrMatchFuzzy: use cyan instead of blue for better contrast with matched portions and non-matched text. As part of this, I'd set BlinkCmpLabelMatch to use cyan as well for the same reasons. I also use this color in mini.pick as well.
  • [x] DiagnosticHint and DiagnosticUnderlineHint: use blue for hints instead of cyan, which is a bright red and could be mistaken for error messages.
  • [x] @lsp.type.variable and @variable.member: disable use of semantic token for variable in favor of treesitter. I grabbed this from Tokyonight. It allows for different highlight groups for things such as this Python code object.attr. I set the variable.member to white, so it is slightly different from the fg used on the object variable.

Changes not suitable

  • [ ] Search and MiniJump: While I really like my customization of these two highlight groups, it really only looks good if adjusts the position and thickness of the underline in their terminal emulator. So while I think these look great in my screenshots, it would require a user to tune in their own to get the full effect.
  • [ ] My markdown tweaks as they are tightly coupled with the use of render-markdown. While I think these look amazing and make for a very pleasant markdown experience (I have over 2,000 markdown notes in my note taking system), they probably would be better served as an example in a Wiki or Show-n-Tell discussion thread.

pkazmier avatar Jul 11 '25 19:07 pkazmier

Thanks for the detailed breakdown. I checked the ones that make sense.

kvrohit avatar Jul 13 '25 15:07 kvrohit

Great. I'll submit a PR later today. Thanks for the feedback.

pkazmier avatar Jul 13 '25 17:07 pkazmier