Skip to content
Zachary Churchill edited this page Sep 26, 2021 · 4 revisions

User contributed tips and tricks

keys

Utility function to specify many key combinations

It can sometimes be tedious to specify all key combinations which should trigger the loading of a plugin. To simplify that you can put the following utility function in your setup.

local M = {}

local function string_product(keys)
    if #keys == 1 then
        return keys[1]
    end
    local keys_copy = {}
    for _, key in ipairs(keys) do
        table.insert(keys_copy, key)
    end
    local product = {}
    local first = table.remove(keys_copy, 1)
    for _, a in ipairs(first) do
        if type(a) ~= 'string' then
            vim.cmd('echoerr "Not a valid keys table"')
        end
        for _, b in ipairs(string_product(keys_copy)) do
            table.insert(product, a .. b)
        end
    end
    return product
end

local function expand_keys(keys)
    if type(keys) == 'string' then
        return {keys}
    elseif type(keys[1]) == 'string' then
        return keys
    else
        return string_product(keys)
    end
end

M.get_keys = function(modes, keys)
    if type(modes) == 'string' then
        modes = {modes}
    end
    local combinations = {}
    for _, mode in ipairs(modes) do
        for _, v in ipairs(expand_keys(keys)) do
            table.insert(combinations, {mode, v})
        end
    end
    return combinations
end

return M

Previously you might have for example written:

use {
    'michaeljsmith/vim-indent-object',
    keys = {
        {'o', 'ii'},
        {'o', 'ai'},
        {'o', 'iI'},
        {'o', 'aI'},
        {'v', 'ii'},
        {'v', 'ai'},
        {'v', 'iI'},
        {'v', 'aI'},
    },
    wants = 'vim-textobj-user',
}

but with the above function you can write:

use {
    'michaeljsmith/vim-indent-object',
    keys = get_keys({'o', 'v'}, {{'a', 'i'}, {'i', 'I'}}),
    wants = 'vim-textobj-user',
}

which expands to the product of the individual keys in the specified modes.

Some examples:

local get_keys = require('packer').get_keys
print(vim.inspect(get_keys('n', 'a')))
print(vim.inspect(get_keys('n', {'a', 'b'})))
print(vim.inspect(get_keys('n', {{'a', 'b'}, {'c', 'd'}})))
print(vim.inspect(get_keys({'n', 'o'}, {{'a', 'b'}, {'c', 'd'}})))

which gives

{ { "n", "a" } }
{ { "n", "a" }, { "n", "b" } }
{ { "n", "ac" }, { "n", "ad" }, { "n", "bc" }, { "n", "bd" } }
{ { "n", "ac" }, { "n", "ad" }, { "n", "bc" }, { "n", "bd" }, { "o", "ac" }, { "o", "ad" }, { "o", "bc" }, { "o", "bd" } }

Running nvim without loading packer plugins

Since packer installs plugins to a folder which is in your runtime path by default, installed plugins will run even when loading another configuration. One way to remedy this is by invoking nvim with the --clean flag:

--clean

  • Skips initializations from files and environment variables.
  • No 'shada' file is read or written.
  • Excludes user directories from 'runtimepath'

So if you wanted to run nvim with a minimal vimrc to debug a plugin for example, you would invoke nvim --clean -u min.vim