Iron-E/nvim-highlite

github github
colorschemecolorscheme-creation
stars 240
issues 2
subscribers 2
forks 33
CREATED

2020-06-19

UPDATED

last month


nvim-highlite

Feature Overview

  • Use any of the built-in colorschemes using :colorscheme.
  • Easily write your own colorscheme by only specifying a few colors.
  • Import from formats other applications use to one that can be used with nvim-highlite.
  • Export any colorscheme (even from other repositories) to formats other applications use.

Built-in Colorschemes

Introduction

nvim-highlite is a colorscheme generator with great defaults.

The defaults focuses on:

  1. Compatibility with semantic highlighting.
    • I was using colorschemes that often did not provide enough colors to provide distinction between tokens.
  2. Visibility in any range of blue-light.
    • I use redshift often, and many colorschemes did not allow for me to see when I had lower color temperatures.

The generator focuses on:

  1. Rapid development.
    • Many times, all you need to do is pass in your colors and the highlight groups will be generated for you.
  2. Utilities for working with highlight groups.
    • Clone, extend, or merge groups in order to customize what the generator creates for you.

Installation

Requires the following:

  • Neovim 0.8+

Note

If you don't use termguicolors, see How Can I Get This Plugin To Work Without termguicolors?

lazy.nvim

I recommend using lazy.nvim:

require('lazy').setup {
  {'Iron-E/nvim-highlite',
    config = function(_, opts)
      -- OPTIONAL: setup the plugin. See "Configuration" for information
      require('highlite').setup {generator = {plugins = {vim = false}, syntax = false}}

      -- or one of the alternate colorschemes (see the "Built-in Colorschemes" section)
      vim.api.nvim_command 'colorscheme highlite'
    end,
    lazy = false,
    priority = math.huge,
    version = '^4.0.0',
  },
}

Others

  1. Install a plugin manager such as packer.nvim:
    -- packer.nvim example
    local install_path = vim.fn.stdpath('data')..'/site/pack/packer/opt/packer.nvim'
    
    if not vim.loop.fs_stat(vim.fn.glob(install_path)) then
      vim.fn.system {'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path}
    end
    
    vim.api.nvim_command 'packadd packer.nvim'
    
    return require('packer').startup {function(use)
      use {'wbthomason/packer.nvim', opt = true}
      use {'Iron-E/nvim-highlite', branch = 'master-v4'}
    end}
    
  2. Optional – setup the plugin (see Configuration for more info):
    require('highlite').setup {generator = {plugins = {vim = false}, syntax = false}}
    
  3. Specify this colorscheme as your default colorscheme:
    vim.api.nvim_command 'colorscheme highlite'
    

Configuration

You can configure what highlight groups get generated for both built-in and your custom colorschemes. Do this by calling setup before executing :colorscheme for any colorscheme created with nvim-highlite.

The available options are explained in the following sections. Note that the more you disable, the faster your startup time will be.

Generator

Controls what highlight groups get created by the plugin.

Note

All integrations are enabled by default, and the setup table accepts a deny list. If you instead want to use an allow list, you can do something like this instead:

local allow_list = {__index = function() return false end}
require('highlite').setup {
  generator = {
    plugins = {
      nvim = {packer = false}, -- use all but packer
      vim = setmetatable({coc = true}, allow_list), -- only use `coc`
    },
    syntax = setmetatable({man = true}, allow_list), -- only use `man` sytnax highlighting
  },
}

Plugins

Controls generating highlighting for plugins. You can disable all integrations:

require('highlite').setup {generator = {plugins = false}}

…or, to disable specific plugins, see Neovim and Vim.

Neovim

Controls generation for neovim plugins. You can disable all neovim plugin integrations:

require('highlite').setup {
  generator = {
    plugins = {nvim = false},
  },
}

…or, to disable generation for certain plugins:

require('highlite').setup {
  generator = {
    plugins = {nvim = {packer = false}},
  },
}
List of Neovim Plugins
Vim

Controls generation for vim plugins. You can disable all vim plugin integrations:

require('highlite').setup {
  generator = {
    plugins = {vim = false},
  },
}

…or, to disable generation for certain plugins:

require('highlite').setup {
  generator = {
    plugins = {vim = {ale = false}}
  },
}
List of Vim Plugins

Syntax

Controls generating legacy syntax highlighting. You can disable generation for all filetypes:

require('highlite').setup {
  generator = {syntax = false},
}

…or, to disable generation for certain filetypes:

require('highlite').setup {
  generator = {
    syntax = {dosini = false, git = false},
  },
}

Note

Treesitter highlighting is always enabled. You can safely disable :syntax highlighting if you only use treesitter.

List of Syntax Filetypes

Terminal Palette

Colors for Neovim's :terminal are automatically set for all built-in colorschemes (see :h terminal-config). To disable this, do the following:

require('highlite').setup {terminal_palette = false}

Usage

Built-in Colorschemes

To use one of the built-in colorschemes, simply do:

vim.api.nvim_command 'colorscheme <name>'

Warning

If you want to configure this plugin, make sure you do so before executing :colorscheme! See Configuration for more.

Exporting Colorschemes

Note

This specific feature requires Neovim 0.9+

This plugin has the ability to export any colorscheme (not just ours!) to various formats, including:

  • bat theme (tmTheme; also works for Sublime Text)
  • fish theme (set_color)
  • nvim theme (Lua)
  • vim theme (Vimscript)
  • wezterm theme (TOML)

To make use of this, just run this after installing the plugin:

require('highlite.export').<format>(
  '<colorscheme name>',
  -- all settings below are OPTIONAL
  {
    -- controls the directory where the exported colorscheme will be written.
    dir = '~/.config/nvim/colors/',

    -- controls the name of the file that is created, as well as the name of the
    -- output colorscheme.
    filename = 'foo',

    -- skip exporting certain groups. Currently only works for the `nvim` and `vim` targets
    filter = function(group, default_filter)
      return default_filter(group) or (group:find '^Nvim' or group:find '^Redraw') ~= nil
    end,

    -- if `false`, an existing target file will not be overwritten. Instead, a
    -- file with a similar name will be created.
    force = true,

    -- if `true`, the function will not notify you when it is finished.
    silent = false,
  }
)

If your plugin manager supports update hooks (e.g. lazy.nvim, packer.nvim, vim-plug) you can run this function whenever a given colorscheme plugin updates.

For example, to generate a Wezterm theme from tokyonight.nvim whenever it updates, you can do something like this (example for lazy.nvim):

{'folke/tokyonight.nvim',
  build = function() require('highlite.export').wezterm('tokyonight', {force = true}) end,
  config = function() vim.api.nvim_command 'colorscheme tokyonight' end,
  dependencies = 'Iron-E/nvim-highlite',
  priority = 1000,
}

Warning

If you use lazy.nvim's build option to export colorschemes, it is possible that the background color might not export correctly. See folke/lazy.nvim#753 for details and a workaround.

Importing/Writing Colorschemes

To create your own colorscheme, or import an existing one, see the advanced usage guide.

Contribution

See the contributing guide.

Limitations

cterm Colors

The generator, for simplicity and speed purposes, does not include cterm highlight groups. This was also partially motivated by a survey of configurations. However, you can make this plugin work with cterm colors! See How Can I Get This Plugin To Work Without termguicolors?

Generated Terminal Palettes

While nvim-highlite provides terminal palettes for all built-in colorschemes, nvim-highlite cannot generate new terminal palettes because of the difference in how terminal palettes and nvim-highlite's palletes are defined:

  • terminal palettes are created specifying the RGB color value of specific color names (e.g. "red" = "#FF0000"), and
  • nvim-highlite's palettes are defined by assigning an RGB color value to semantic categories (e.g. keyword = "#4422AA").

This is a problem because there is no association between token types (e.g. error, func) and the color value (e.g. "#A80000", "#CF55F0"). Thus, there's no performant way to assign a color to e.g. "red".

See Creating A Terminal Palette for a tutorial on how to write one yourself, or mini.colors for a supplementary plugin that can generate this palette for you.

FAQ

"How can I get this plugin to work without termguicolors?"

You can use mini.colors— it will infer a cterm palette based on the GUI colors from any colorscheme.

To use it, do this instead of :colorscheme <name>:

-- replace `<name>` with the name of any of the builtin colorschemes
require('mini.colors').get_colorscheme('<name>'):add_cterm_attributes():apply()

If your plugin manager has update hooks (e.g. vim-plug, packer.nvim, lazy.nvim) you can save performance by doing the above once every update. Here is an example for lazy.nvim:

{'Iron-E/nvim-highlite',
  build = function()
    require('mini.colors')
      -- replace `<name>` with the name of any of the builtin colorschemes
      .get_colorscheme('<name>', {new_name = 'my-custom-colorscheme'})
      :add_cterm_attributes()
      :write()
  end,
  config = function() vim.api.nvim_command 'colorscheme my-custom-colorscheme' end,
  dependencies = 'echasnovski/mini.colors',
  priority = 1000,
}

Warning

If you use lazy.nvim's build option to export colorschemes, it is possible that the background color might not export correctly. See folke/lazy.nvim#753 for details and a workaround.

"How can I override highlights in my init.lua?"

You can either write your own colorscheme, or add an autocmd to your config. Both have merits: a custom colorscheme has better performance, but an autocmd will work with multiple colorschemes (if you like to switch between them).

Note

For information about creating your own colorscheme, see the docs.

You can add an autocmd to your config like this:

vim.api.nvim_create_autocmd('ColorScheme', {
  callback = function()
    vim.api.nvim_set_hl(0, 'Error', {fg = '#000000', bg = '#FFFFFF'})
    -- other groups
  end,
  group = vim.api.nvim_create_augroup('config', {clear = true}),
  pattern = 'highlite', -- apply to just the highlite colorscheme
  -- pattern = {'highlite', 'tokyonight'}, -- apply to highlite and tokyonight
  -- pattern = '*', -- apply to all colorschemes
})

-- WARN: make sure the colorscheme gets loaded AFTER setting the autocommand!
vim.api.nvim_command 'colorscheme highlite'

Of course, substitute highlite with the name of your colorscheme.

"How does this compare to XYZ plugin?"

It doesn't seem right as a plugin author to weigh the benefits of others' work. Instead, here are some facts notable about nvim-highlite:

  • You only need 6 colors to create a colorscheme, but you can use as many as you want.
    • Want to use 1,000 colors? Go for it.
  • Great effort has been taken to reduce the startup cost of this plugin.
  • While our semantic color palette prevents generating a terminal palette, it makes creating a new colorscheme easier.
    • Remember: all built-in colorschemes come with a terminal palette.
  • This plugin can import any colorscheme written in a language Neovim supports, and give it support for the latest highlights.
    • VimScript colorschemes usually become faster when ported, and sometimes Lua colorschemes do too.
    • Contributors can use specially-made internal tools which automate certain development tasks.
  • This plugin provides a great starting point for a custom colorscheme:
    • all of the built-in highlight groups;
    • diagnostics, LSP, treesitter;
    • custom support for 20+ plugins (not counting ones that work out of the box); and
    • custom support for 30+ filetypes (not counting ones that work out of the box).
  • If something isn't to your liking, there are many tools for the purpose of customizing what is provided.
    • The syntax is familiar, simple, orthogonal, and completely stable.

If this plugin doesn't suit your needs, here is a list of excellent alternatives:

"What font is that in the screenshots?"

JetBrains Mono.

./doc/advanced-usage.md
./doc/contributing.md