Vimade
Vimade let's you dim, fade, tint, animate, and customize colors in your windows and buffers for (Neo)vim
Install / Use
/learn @TaDaa/VimadeREADME
Dim, Fade, Tint, and Customize (Neo)vim
</td> </tr> <tr> <td> <img src="https://raw.githubusercontent.com/TaDaa/tadaa.github.io/refs/heads/master/images/minimalist_full.gif"></img> </td> </tr> </tbody> </table>Vimade helps you maintain focus on what matters. It dims, fades, and tints inactive windows and buffers. It can also provide "limelight" or "twilight" style highlighting around your cursor, but with a key difference: Vimade preserves syntax highlighting, allowing you to stay in context while focusing on the code that matters most.
Vimade offers a powerful and flexible way to customize your coding environment with:
- 🎨 Pre-built Recipes: Get started quickly with a variety of visual styles.
- 🔋 Batteries Included: Works out-of-the-box with no configuration necessary.
- ✨ Smooth Animations: Enjoy a fluid and visually appealing experience.
- 🌈 Extensive Customization: Tailor every aspect of the fading and tinting to your liking.
- 🧩 Unmatched Compatibility: Works with all colorschemes and even other plugin namespaces.
- ⏰ Sub-millisecond Performance: Keep your editor snappy and responsive.
Create a truly unique and focused coding environment with Vimade.
🚀 Getting Started
<details open> <summary><a><ins>lazy.nvim</ins></a></summary> <br>[!IMPORTANT] Neovim 0.8+ uses a pure Lua implementation. Some features, like focus mode, require Neovim 0.10+. For Vim and older versions of Neovim, Python is required.
<sub>::lua::lazy.nvim::</sub>
{
"tadaa/vimade",
opts = {
recipe = {"default", {animate = true}},
fadelevel = 0.4,
}
}
</details>
<details open>
<summary><a><ins>vim-plug</ins></a></summary>
<br>
<sub>::vimscript::vim-plug::</sub>
Plug 'TaDaa/vimade'
</details>
<details>
<summary><a><ins>Configure with lua (Neovim only)</ins></a></summary>
require('vimade').setup({
recipe = {'default', {animate = true}},
fadelevel = 0.4,
})
</details>
<details>
<summary><a><ins>Configure with vimscript</ins></a></summary>
<br>
let g:vimade = {}
let g:vimade.recipe = ['default', {'animate': v:false}]
let g:vimade.fadelevel = 0.4
</details>
<details>
<summary><a><ins>Configure with python</ins></a></summary>
<br>
For Vim & Neovim < 0.8
<sub>::python::</sub>
function! SetupMyVimadeConfig()
python << EOF
from vimade import vimade
vimade.setup(
recipe = ['default', {'animate':False}],
fadelevel = 0.4,
)
EOF
endfunction
# SetupMyVimadeConfig will be called lazily after python becomes available.
# You can call vimade.setup(...) whenever you want.
au! User Vimade#PythonReady call SetupMyVimadeConfig()
</details>
📖 Guides
<details> <summary><a><ins>Important note on configuration</ins></a></summary> <br>Vimade treats the setup() command as an overlay. Each time you call it, it will override any previous settings. Therefore, if you want to combine multiple settings, you must include them all in the same setup() call. If you want to reset the overlay to defaults, just call setup({}) with no options.
Correct:
require('vimade').setup({
recipe = {'minimalist', {animate = true}},
fadelevel = 0.3,
})
Incorrect:
require('vimade').setup({recipe = {'minimalist', {animate = true}}})
require('vimade').setup({fadelevel = 0.3}) -- This will override the recipe setting!
</details>
<details>
<summary><a><ins>Choosing an ncmode</ins></a></summary>
<br>
Vimade can fade inactive windows in a few different ways. You can control this behavior with the ncmode option.
'buffers': (Default) Fades all windows that do not share the same buffer as the active window. This is useful if you have the same buffer open in multiple splits and you want them all to remain highlighted.'windows': Fades all inactive windows. This is a good choice if you want a clear distinction between the window you are currently working in and all other windows.'focus': (Neovim 0.10+) Only fades when the:VimadeFocuscommand is active. This is useful for on-demand highlighting.
Most users should try each option to see what they like best.
<sub>::lua::</sub>
require('vimade').setup{ncmode = 'buffers'} -- or 'windows' or 'focus'
<sub>::vimscript::</sub>
let g:vimade.ncmode = 'buffers' " or 'windows' or 'focus'
<sub>::python::</sub>
from vimade import vimade
vimade.setup(ncmode='buffers') # or 'windows' or 'focus'
</details>
<details>
<summary><a><ins>Preparing a transparent terminal</ins></a></summary>
<br>
When using a transparent terminal, your Normal highlight group has a background of NONE. Vimade needs to know the actual background color to properly calculate faded colors. For the best results, you should set the basebg option.
- Place your transparent terminal over a pure white background (
#FFFFFF). - Use a color picker to determine the hex code of the background color of your terminal.
- Set
basebgto this value in your configuration. You may need to darken it slightly to get the best results.
<sub>::lua::</sub>
require('vimade').setup{basebg = '#2d2d2d'} -- or {45, 45, 45}
<sub>::vimscript::</sub>
let g:vimade.basebg = '#2d2d2d' " or [45, 45, 45]
<sub>::python::</sub>
from vimade import vimade
vimade.setup(basebg='#2d2d2d') # or [45, 45, 45]
</details>
<details>
<summary><a><ins>Fixing Issues with tmux</ins></a></summary>
<br>
If you are having issues with Vimade in tmux, here are a few things to try:
- 256 Colors: Vimade requires a 256 color terminal. By default, tmux may set
t_Coto 8. It is recommended that you setexport TERM=xterm-256colorbefore starting Vim. You can also setset termguicolorsinside Vim if your terminal supports it for an even more accurate level of fading. - Focus Events: If you want windows to fade when switching between tmux panes, you need to enable focus events.
- Enable focus fading in Vimade:
let g:vimade.enablefocusfading = 1 - Add
set -g focus-events onto yourtmux.conf. - For Vim users, you may also need to install the
tmux-plugins/vim-tmux-focus-eventsplugin.
- Enable focus fading in Vimade:
You can configure Vimade to only fade windows when a floating window is open. This is useful if you only want to dim the background when you are focused on a floating window, like a popup or a dialog.
This can be achieved with a blocklist function that checks if the current window is a floating window.
<ins>Lua:</ins>
require('vimade').setup({
blocklist = {
demo_tutorial = function (win, current)
-- current can be nil
if (win.win_config.relative == '') and (current and current.win_config.relative ~= '') then
return false
end
return true
end
}
})
<ins>Python:</ins>
Similar behaviors can be managed for python as well. Vim doesn't support Focusable floating windows, so the logic required is a bit more complex, but still achievable
from vimade import vimade
from vimade.state import globals
g_tick_id = -1
g_popup_visible = False
g_popup_winids = []
def refresh_popup_visible():
global g_popup_visible
global g_popup_winids
g_popup_winids = vim.eval('popup_list()')
any_visible = False
for winid in g_popup_winids:
if vim.eval(f'popup_getpos({winid})["visible"]') == '1':
any_visible = True
break
if any_visible != g_popup_visible:
g_popup_visible = any_visible
if g_popup_visible:
# A popup is visible, so fade the background including active win
vim.command('VimadeFadeActive')
else:
# No popups are visible, so clear the fade including active win
vim.command('VimadeUnfadeActive')
def only_behind_float_windows (win, current):
global g_tick_id
# This is a performance optimization. We only run the expensive
# refresh_popup_state() function once per "tick" (screen refresh),
# not for every single window being checked.
if g_tick_id != globals.tick_id:
g_tick_id = globals.tick_id
refresh_popup_visible()
return not g_popup_visible or win.winid in g_popup_winids
vimade.setup(blocklist = {
'demo_tutorial': only_behind_float_windows,
})
Now, Vimade will only fade windows when a floating window is active.

🎨 Recipes
Vimade comes with several pre-built recipes to get you started. You can enable them with the recipe option.
The standard Vimade experience.
<table> <tbody> <tr> <td> <p align="center"> <img height="236" src="https://raw.githubusercontent.com/TaDaa/tadaa.github.io/refs/heads/master/images/default_recipe_animate.gif" alt="Default Recipe"> </p> </td> </tr> <tr> <td>require("vimade").setup({recipe = {"default", {animate = true}}})
</td>
</tr>
</tbody>
</table>
</details>
<details open>
<summary><a><ins>Minimalist</ins></a></summary>
<br>
Hides low-value inactive highlights like line numbers and the end-of-buffer marker.
<table> <tbody> <tr> <td> <p align="center"> <img height="236" src="https://raw.githubusercontent.com/TaDaa/tadaa.github.io/refs/heads/master/images/minimalist_recipe_animate2.gif" alt="Mi