Skip to content
Will Hopkins edited this page Jul 16, 2023 · 15 revisions

Welcome to the nvim-cokeline wiki!

Configuration recipes

Harpoon-based sorting:

This sorter pins harpoon-marked buffers to the left hand side of the tabline, while still allowing you to rearrange any others that are open.

local harpoon = require("harpoon.mark")
local function marknum(bufnr)
  local stat = harpoon.status(bufnr)
  -- harpoon.mark.status() returns "M%d" where %d is the index
  return tonumber(string.match(stat, "%d+"))
end

---@type a Buffer
---@type b Buffer
-- Use this in `config.buffers.new_buffers_position`
local function sorter(a, b)
  -- switch the a and b._valid_index to place non-harpoon buffers on the left
  -- side of the tabline - this puts them on the right.
  local ma = marknum(a)
  local mb = marknum(b)
  if ma == nil or mb == nil then
    ma = a._valid_index
    mb = b._valid_index
  end
  return ma < mb
end

Focus mappings by @psmolak:

From #59

Instead of setting up new keybinding for each buffer number separately in a loop, we could use count variable like so:

vim.keymap.set('n', '<tab>', function()
  return ('<Plug>(cokeline-focus-%s)'):format(vim.v.count > 0 and vim.v.count or 'next')
end, { silent = true, expr = true })

Now whenever we precede Tab with a count, we will go directly to that buffer. Otherwise the Tab will just move to the next buffer in a list.

Rounded corners

userconfig-noib3

This config shows how you configure buffers w/ rounded corners.
local get_hex = require('cokeline/utils').get_hex

require('cokeline').setup({
  default_hl = {
    fg = function(buffer)
      return
        buffer.is_focused
        and get_hex('Normal', 'fg')
         or get_hex('Comment', 'fg')
    end,
    bg = get_hex('ColorColumn', 'bg'),
  },

  components = {
    {
      text = ' ',
      bg = get_hex('Normal', 'bg'),
    },
    {
      text = '',
      fg = get_hex('ColorColumn', 'bg'),
      bg = get_hex('Normal', 'bg'),
    },
    {
      text = function(buffer)
        return buffer.devicon.icon
      end,
      fg = function(buffer)
        return buffer.devicon.color
      end,
    },
    {
      text = ' ',
    },
    {
      text = function(buffer) return buffer.filename .. '  ' end,
      style = function(buffer)
        return buffer.is_focused and 'bold' or nil
      end,
    },
    {
      text = '',
      delete_buffer_on_left_click = true,
    },
    {
      text = '',
      fg = get_hex('ColorColumn', 'bg'),
      bg = get_hex('Normal', 'bg'),
    },
  },
})

Equally sized buffers

This config shows how to get equally sized buffers. All the buffers are 23 characters wide, adding padding spaces left and right if a buffer is too short and cutting it off if it's too long.
local get_hex = require('cokeline/utils').get_hex
local mappings = require('cokeline/mappings')

local str_rep = string.rep

local green = vim.g.terminal_color_2
local yellow = vim.g.terminal_color_3

local comments_fg = get_hex('Comment', 'fg')
local errors_fg = get_hex('DiagnosticError', 'fg')
local warnings_fg = get_hex('DiagnosticWarn', 'fg')

local min_buffer_width = 23

local components = {
  separator = {
    text = ' ',
    bg = get_hex('Normal', 'bg'),
    truncation = { priority = 1 },
  },

  space = {
    text = ' ',
    truncation = { priority = 1 },
  },

  left_half_circle = {
    text = '',
    fg = get_hex('ColorColumn', 'bg'),
    bg = get_hex('Normal', 'bg'),
    truncation = { priority = 1 },
  },

  right_half_circle = {
    text = '',
    fg = get_hex('ColorColumn', 'bg'),
    bg = get_hex('Normal', 'bg'),
    truncation = { priority = 1 },
  },

  devicon = {
    text = function(buffer)
      return buffer.devicon.icon
    end,
    fg = function(buffer)
      return buffer.devicon.color
    end,
    truncation = { priority = 1 },
  },

  index = {
    text = function(buffer)
      return buffer.index .. ': '
    end,
    fg = function(buffer)
      return
        (buffer.diagnostics.errors ~= 0 and errors_fg)
        or (buffer.diagnostics.warnings ~= 0 and warnings_fg)
        or nil
    end,
    truncation = { priority = 1 },
  },

  unique_prefix = {
    text = function(buffer)
      return buffer.unique_prefix
    end,
    fg = comments_fg,
    style = 'italic',
    truncation = {
      priority = 3,
      direction = 'left',
    },
  },

  filename = {
    text = function(buffer)
      return buffer.filename
    end,
    fg = function(buffer)
      return
        (buffer.diagnostics.errors ~= 0 and errors_fg)
        or (buffer.diagnostics.warnings ~= 0 and warnings_fg)
        or nil
    end,
    style = function(buffer)
      return
        ((buffer.is_focused and buffer.diagnostics.errors ~= 0)
          and 'bold,underline')
        or (buffer.is_focused and 'bold')
        or (buffer.diagnostics.errors ~= 0 and 'underline')
        or nil
    end
    truncation = {
      priority = 2,
      direction = 'left',
    },
  },

  close_or_unsaved = {
    text = function(buffer)
      return buffer.is_modified and '' or ''
    end,
    fg = function(buffer)
      return buffer.is_modified and green or nil
    end
    delete_buffer_on_left_click = true,
    truncation = { priority = 1 },
  },
}

local get_remaining_space = function(buffer)
  local used_space = 0
  for _, component in pairs(components) do
    used_space = used_space + vim.fn.strwidth(
      (type(component.text) == 'string' and component.text)
      or (type(component.text) == 'function' and component.text(buffer))
    )
  end
  return math.max(0, min_buffer_width - used_space)
end

local left_padding = {
  text = function(buffer)
    local remaining_space = get_remaining_space(buffer)
    return str_rep(' ', remaining_space / 2 + remaining_space % 2)
  end,
}

local right_padding = {
  text = function(buffer)
    local remaining_space = get_remaining_space(buffer)
    return str_rep(' ', remaining_space / 2)
  end,
}

require('cokeline').setup({
  show_if_buffers_are_at_least = 2,

  buffers = {
    -- filter_valid = function(buffer) return buffer.type ~= 'terminal' end,
    -- filter_visible = function(buffer) return buffer.type ~= 'terminal' end,
    focus_on_delete = 'next',
    new_buffers_position = 'next',
  },

  rendering = {
    max_buffer_width = 23,
  },

  default_hl = {
    fg = function(buffer)
      return
        buffer.is_focused
        and get_hex('Normal', 'fg')
         or get_hex('Comment', 'fg')
    end,
    bg = get_hex('ColorColumn', 'bg'),
  },

  sidebar = {
    filetype = 'NvimTree',
    components = {
      {
        text = '  NvimTree',
        fg = yellow,
        bg = get_hex('NvimTreeNormal', 'bg'),
        style = 'bold',
      },
    }
  },

  components = {
    components.separator,
    components.left_half_circle,
    left_padding,
    components.devicon,
    components.index,
    components.unique_prefix,
    components.filename,
    components.space,
    right_padding,
    components.close_or_unsaved,
    components.right_half_circle,
  },
})

API Reference

Objects

Functions

cokeline.mappings

cokeline.utils

cokeline.hlgroups

cokeline.buffers

cokeline.tabs

cokeline.history

  • push(bufnr) Push an item into the history.
  • pop() Pop the last item off of the history.
  • list() Returns the history items as a (copied) list.
  • iter() Returns an iterator over the history items.
  • get(idx) Get the item at history index idx, if any.
  • last() Peek the last item in the history, without removing it.
  • contains(bufnr) Check if the history contains the given bufnr.
  • capacity() Returns the configured capacity.
  • len() Returns the number of items in the history.
Clone this wiki locally