A Neovim plugin for automatic keyboard layout switching on macOS when entering insert mode, while keeping an English layout (or really any layout the user wants) when in normal mode. The goal is to keep be able to keep using vim bindings in normal mode while typing in the users preferred language.
- 🔄 Automatic Layout Switching: Automatically switches to your alternate keyboard layout when entering insert mode or search mode
- 🎛️ Configurable Layouts: Support for any keyboard layout available on your macOS system
- ✅ Layout Validation: Automatically validates that configured layouts are available on your system
- 🚫 Smart Buffer Filtering: Ignores certain buffer types (Telescope, Oil, etc.)
- 📡 Status Integration: Provides global variables for statusline integration
- macOS (required)
- keyboardSwitcher - Install with:
brew install lutzifer/homebrew-tap/keyboardSwitcher
Using lazy.nvim:
{
dir = "Chiarandini/KeyboardMode",
config = function()
require("KeyboardMode").setup({
default_layout = "Canadian", -- Your default keyboard layout
alternate_layout = "Hiragana" -- Layout to switch to in insert mode
})
end
}
The plugin accepts the following options:
require("KeyboardMode").setup({
default_layout = "Canadian", -- Default layout (fallback to first available)
alternate_layout = "Hiragana" -- Alternate layout (fallback to second available)
})
toggle()
- Toggle between default and alternate keyboard modesenable()
- Enable alternate keyboard modedisable()
- Disable alternate keyboard mode (return to default)is_enabled()
- Check if alternate keyboard mode is currently enabled
get_available_layouts()
- Get list of all available keyboard layoutsget_config()
- Get current plugin configurationswitch_to_layout(layout_name)
- Temporarily switch to a specific layout
You can set up keyboard shortcuts to control the plugin:
-- Toggle keyboard mode
vim.keymap.set('n', '<leader>kt', function()
require('KeyboardMode').toggle()
end, { desc = 'Toggle keyboard mode' })
-- Enable alternate layout
vim.keymap.set('n', '<leader>ke', function()
require('KeyboardMode').enable()
end, { desc = 'Enable alternate keyboard' })
-- Disable alternate layout
vim.keymap.set('n', '<leader>kd', function()
require('KeyboardMode').disable()
end, { desc = 'Disable alternate keyboard' })
The plugin sets a global variable vim.g.KeyboardMode
that you can use in your statusline:
-- Example for lualine
{
function()
return vim.g.KeyboardMode and "🌸" or "🔤"
end
}
-- Example for heirline
{
condition = function()
return vim.g.KeyboardMode
end,
provider = "🌸",
}
The plugin triggers a KeyboardModeChanged
User event when the keyboard mode changes:
vim.api.nvim_create_autocmd('User', {
pattern = 'KeyboardModeChanged',
callback = function()
print('Keyboard mode changed!')
end,
})
The plugin automatically:
- Insert Mode: Switches to alternate layout when entering insert mode, back to default when leaving
- Search Mode: Switches to alternate layout when entering search (
/
), back to default when leaving - Buffer Filtering: Ignores switching in special buffer types:
- TelescopePrompt
- DressingSelect/DressingInput
- noice/notify/prompt
- Oil
To see what keyboard layouts are available on your system:
keyboardSwitcher list
Or from within the plugin:
local layouts = require('KeyboardMode').get_available_layouts()
vim.print(layouts)
Install keyboardSwitcher: brew install lutzifer/homebrew-tap/keyboardSwitcher
Check available layouts with keyboardSwitcher list
and update your configuration accordingly.
This plugin only was tested on macOS due to the keyboardSwitcher dependency.