Skip to content

ImmanuelHaffner/pigmentor.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


pigmentor.nvim

Your mentor for dealing with pigments (colors) in Neovim

Neovim minimum version MIT License

Pigmentor is a Neovim plugin that intelligently highlights color values in your code with their actual colors. Whether you're working with CSS, LaTeX, or any code containing color values, Pigmentor visualizes them directly in your editor.

✨ Features

  • 🎯 Smart Color Detection: Automatically finds and highlights various color formats
  • 🎨 Multiple Display Styles: Choose between inline, highlight, or hybrid visualization modes
  • 🔄 Real-time Updates: Colors update as you type and move your cursor
  • 🎛️ Mode-aware: Different behavior for normal, insert, visual, and operator-pending modes
  • 🖥️ Window Management: Smart handling of active/inactive windows
  • Performance Optimized: Only processes visible content for smooth editing

Supported Color Formats

  • Hexadecimal: #FF0000, #F00, #FF0000AA
  • CSS RGB/RGBA: rgb(255, 0, 0), rgba(255, 0, 0, 0.5)
  • CSS HSL/HSLA: hsl(200, 1, .6), hsla(200deg, 100%, 60.0%)
  • LaTeX Colors: \definecolor{red}{RGB}{255,0,0}, \definecolor{blue}{HTML}{0000FF}

Examples

📦 Installation

Install using your favorite plugin manager:

{
  'ImmanuelHaffner/pigmentor.nvim',
  config = function()
    require'pigmentor'.setup{
      -- your configuration here
    }
  end,
}
use {
  'ImmanuelHaffner/pigmentor.nvim',
  config = function()
    require'pigmentor'.setup{
      -- your configuration here
    }
  end
}
Plug 'ImmanuelHaffner/pigmentor.nvim'

vim.pack

The plugin supports auto-loading with default configuration via plugin/pigmentor.lua, requiring no additional setup for basic functionality.

Try before using

Pigmentor provides a minimalistic Nvim configuration for demonstrational and testing purposes. Simply clone the repository and run nvim --clean -u path/to/pigmentor/demo/lazy/init.lua.

⚙️ Configuration

Pigmentor comes with sensible defaults, but you can customize it to your needs.

Default Configuration

require'pigmentor'.setup{
  enabled = true,                   -- whether the plugin is active
  buftypes = {                      -- which buftypes to support
    '',                             -- normal files
    'help',
    'nofile',
    'nowrite',
    'quickfix',
  },
  display = {
    inactive = true,                -- show in inactive windows
    style = 'inline',               -- one of 'inline', 'highlight', 'hybrid'
    priority = 150,                 -- highlight priority, slightly above treesitter
    inline = {
      text_pre = nil,               -- text before color
      text_post = '',              -- text after color (dot indicator)
    },
    highlight = {
      padding = {
        left = 1,                   -- padding spaces on the left
        right = 1,                  -- padding spaces on the right
      },
    },
  },
  modes = {
    n = {                           -- normal mode
      cursor = true,                -- show for item under cursor
      line = true,                  -- show for current line
      visible = true,               -- show for all visible lines
    },
    no = {                          -- operator-pending mode
      cursor = false,
      line = false,
      visible = false,
    },
    i = {                           -- insert mode
      cursor = false,
      line = false,
      visible = true,
    },
    [{ 'v', 'V', '\x16' }] = {      -- visual modes
      cursor = false,
      line = false,
      visible = false,
    },
  },
}

Display Styles

Inline

Shows color indicators next to color values without replacing the text.

{
  display = {
    style = 'inline',
    inline = {
      text_post = '',
    }
  }
}

You can use multiple characters.

{
  display = {
    style = 'inline',
    inline = {
      text_post = '',
    }
  }
}

You can place characters before the text.

{
  display = {
    style = 'inline',
    inline = {
      text_pre = '',
      text_post = nil,
    }
  }
}

You can provide a table of strings to text_pre and text_post. The texts will be rendered consecutively with alternating inverting colors. With inverted you configure whether to start with inverted colors.

{
  display = {
    style = 'inline',
    inline = {
      inverted = true,
      text_post = { '', '', },
    }
  }
}

Highlight

Replaces the foreground text color with the actual color.

{
  display = {
    style = 'highlight',
    highlight = {
      inverted = false,
      padding = {
        left = 0,
        right = 0,
      }
    }
  }
}

You can swap foreground and background colors.

{
  display = {
    style = 'highlight',
    highlight = {
      inverted = true,
      padding = {
        left = 1,
        right = 1,
      }
    }
  }
}

Hybrid

Combines both inline and highlight modes:

{
  display = {
    style = 'hybrid',
    inline = {
      text_pre = '',
      text_post = nil,
    },
    highlight = {
      inverted = false,
      padding = {
        left = 0,
        right = 0
      }
    }
  }
}

{
  display = {
    style = 'hybrid',
    inline = {
      text_pre = '',
      text_post = '',
    },
    highlight = {
      inverted = true,
      padding = {
        left = 1,
        right = 1
      }
    }
  }
}

🚀 Usage

Once installed and configured, Pigmentor works automatically. You can also control it manually:

local pigmentor = require'pigmentor'

-- Toggle the plugin on/off
pigmentor.toggle()

-- Enable/disable explicitly
pigmentor.enable()
pigmentor.disable()

-- Cycle through display styles
pigmentor.cycle_display_style()

-- Refresh current buffer
pigmentor.refresh_buffer(vim.api.nvim_get_current_buf())

-- Refresh all visible buffers
pigmentor.refresh_visible_buffers()

Keymaps

Add these to your configuration for convenient access:

local pm = require'pigmentor'
vim.keymap.set('n', '<leader>pt', pm.toggle,
  { desc = 'Toggle color highlighting' })
vim.keymap.set('n', '<leader>pc', pm.cycle_display_style,
  { desc = 'Cycle color display style' })

Different Styles

You can easily implement your own collection of styles and your own style cycler. Here's what I have in my setup of Pigmentor:

local display_styles = {
    {
        -- '#00AAFF'
        style = 'inline',
        inline = {
            text_pre = '',
            text_post = '',
        },
    },
    {
        -- '♦#00AAFF'
        style = 'inline',
        inline = {
            text_pre = '',
            text_post = '',
        },
    },
    {
        -- '#00AAFF' with fg text color
        style = 'highlight',
        highlight = {
            padding = { left = 0, right = 0 },
            inverted = false,
        },
    },
    {
        -- '#00AAFF' with bg color
        style = 'highlight',
        highlight = {
            padding = { left = 1, right = 1 },
            inverted = true,
        },
    },
    {
        -- '#00AAFF' with bg color
        style = 'hybrid',
        inline = {
            text_pre = '',
            text_post = '',
        },
        highlight = {
            inverted = true,
            padding = { left = 0, right = 0 },
        },
    },
}
local current_display_style = 1

local pm = require'pigmentor'
pm.setup{
    display = display_styles[current_display_style],
}

local wk = require'which-key'
wk.add({
    { '<leader>p', group = 'Pigmentor…' },
    { '<leader>pt', pm.toggle, desc = 'Toggle globally' },
    { '<leader>pc', function()
        if current_display_style >= #display_styles then
            current_display_style = 1
        else
            current_display_style = current_display_style + 1
        end
        pm.load_config{display = display_styles[current_display_style]}
        pm.refresh_visible_buffers()
    end, desc = 'Cycle display style' },
})

🎯 Mode Configuration

Pigmentor can behave differently in various Vim modes:

  • cursor: Show colors for the item under the cursor
  • line: Show colors for the entire current line
  • visible: Show colors for all visible lines in the buffer

For example, you might want to see all colors while in normal mode, but only show colors for visible lines in insert mode to reduce distractions.

🔧 Advanced Configuration

Custom Color Formats

While Pigmentor comes with built-in support for common color formats, you can examine lua/pigmentor/colormatchers.lua to understand how to extend it with custom patterns.

Performance Tuning

For large files or when performance is a concern:

require'pigmentor'.setup{
  display = {
    inactive = false,   -- Don't highlight inactive windows
    priority = 100,     -- Tune extmark priority to not interfere with other extmarks
  },
  modes = {
    i = {
      visible = false,  -- Disable in insert mode for performance
    },
  },
}

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

Thanks to the Neovim team for the excellent extmarks API.

Inspiration and Alternatives

  • color-picker.nvim - A powerful plugin that lets Neovim Users choose & modify colors. This plugin supports RGB, HSL and HEX colors.

  • ccc.nvim - Create Color Code in neovim. Use the colorful sliders to easily generate any desired color!

  • mini.hipatterns – Highlight patterns in text

  • catgoose/nvim-colorizer.lua – A high-performance color highlighter for Neovim which has no external dependencies! Written in performant Luajit.

🚧 Planned Features

The following features are planned for future releases:

  • 📚 Vim Help Documentation: Comprehensive help documentation accessible via :help pigmentor
  • 🎨 Extended Color Format Support:
    • HSV/HSB: hsv(0, 100%, 100%), hsva(0, 100%, 100%, 0.5)
  • Per-Channel Color Manipulation: Increment/decrement individual color channels using <Ctrl-a> and <Ctrl-x> respectively

Built with ❤️ for the Neovim community

About

Your mentor to dealing with pigments (colors) in Neovim

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages