Neovim + Telescope и разные раскладки клавиатуры
Опубликовано 02.12.2024 в OpenBSD
Анализировал тут в очередной раз свои незамысловатые потребности в области редактирования текстовых файлов (подобный анализ в этой и смежных областях я люблю, могу и практикую регулярно). Нашел следующие паттерны, причиняющие мне определенное неудобство:
-
открытие файла, расположение и/или название которого я помню достаточно смутно (положим, где-то там когда-то я настраивал автовключение проверки орфографии для различных типов файлов, но где? помню только, что там присутствовало слово 'after' в пути...)
-
аналогично применительно не к пути/названию файла, а к его содержимому - grep не всегда подчиняется мне в полной мере из-за нечеткости критериев поиска, ну и не так уж мне удобно грепать список файлов, в которых я упоминал что-то там такое...
-
то же самое с поиском по справочному руководству Neovim: часто я весьма смутно ощущаю как сформулировать, что именно я там хочу найти?
Ну а очертив таким образом текущие потребности и исходя из рационального, никогда не подводящего меня принципа "я не являюсь уникальной снежинкой и нитакусиком, всё, что я выдумал - уже приходило в голову сотням и тысячам людей до меня" - я, разумеется легко нагуглил этот ваш великий и ужасный telescope.nvim: плагин для Neovim, который из коробки умеет все перечисленное и еще многое, многое, МНОГОЕ-МНОГОЕ другое!
Про сам Telescope, его возможности, кастомизируемость и области потенциального применения - я тут распространяться не буду, ибо у меня нет лишнего года времени и трех-четырех клавиатур, которые можно стереть в процессе освещения этой бесконечной темы. Упомяну лишь, что нужные оному телескопу для работы утилиты ripgrep и fd присутствуют в пакетной базе OpenBSD и могут быть установлены, как обычно, через doas pkg_add ripgrep fd
. Ну а сам Telescope и его зависимости - см. по ссылке выше.
Я лучше о другом расскажу. Не так давно я писал, как добавил в Neovim функцию переключения раскладки на латиницу при выходе из режима вставки в командный режим, а при возвращении обратно в режим вставки, соответственно, функцию восстановления ранее использовавшейся раскладки. Штука эта до того удобная, что стала для меня уже чем-то самим собой разумеющимся - и именно поэтому мне поначалу показалось неудобным работать с Telescope.
Неудобство вот в чем: предположим, ввожу я текст на русском языке (да вот хоть бы этот) и выхожу из режима вставки в "нормальный" командный режим чтобы что-нибудь там поизучать через этот самый Telescope. При выходе у меня прикапывается специально мною разработанной методом копипейст-программирования функцией на lua русская раскладка - ведь я печатал по-русски?
И вот я топчу <leader>+ff
(в моем случае в качестве этой самой магической клавиши <leader>
я использую пробел:
-- use Space as <leader> key
vim.g.mapleader = " "
-- Telescope search hotkeys
local builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>ff', builtin.find_files, { desc = 'Telescope find files' })
vim.keymap.set('n', '<leader>fg', builtin.live_grep, { desc = 'Telescope live grep' })
vim.keymap.set('n', '<leader>fb', builtin.buffers, { desc = 'Telescope buffers' })
vim.keymap.set('n', '<leader>fh', builtin.help_tags, { desc = 'Telescope help tags' })
предо мной открывается всплывающее окно Telescope (ну, в терминологии neovim окно, конечно), где я по умолчанию нахожусь в строке ввода символов для поиска... в режиме ввода! А соответственно, упомянутая ранее lua-функция, обнаружив переход в режим ввода, восстановила последнюю использовавшуюся раскладку - русскую, которая мне в Telescope-то как раз нафиг и не сдалась.
Это нужно исправить, заодно доказав, что даже презренный гуманитарий способен писать пусть говнокод, но таки рабочий говнокод на языке lua. Итак, вот доработанный файл myxkbswitch.lua
: манипуляции с сохранением/восстановлением раскладки НЕ применяются теперь для окна Telescope, но остаются работоспособными для прочих окон:
local M = {}
-- nvim_create_autocmd shortcut
local autocmd = vim.api.nvim_create_autocmd
-- needs "xkb-switch" or "xkb-switch-i3" app to be installed
local xkb_switch_lib = '/usr/local/lib/libxkbswitch.so'
-- get current layout
local function get_current_layout()
return vim.fn.libcall(xkb_switch_lib, 'Xkb_Switch_getXkbLayout', '')
end
-- get the "filetype" option for active buffer
local function get_current_filetype()
return vim.api.nvim_buf_get_option(0, "filetype")
end
-- for first use after nvim has been started
local saved_layout = get_current_layout()
function M.setup()
-- When leaving Insert Mode:
-- 1. Save the current layout (but NOT for Telescope menu)
-- 2. Switch to the US layout
autocmd(
'InsertLeave',
{
pattern = "*",
callback = function()
vim.schedule(function()
current_filetype = get_current_filetype()
if current_filetype ~= 'TelescopePrompt' then
saved_layout = get_current_layout()
end
vim.fn.libcall(xkb_switch_lib, 'Xkb_Switch_setXkbLayout', 'us')
end)
end
}
)
-- When entering Insert Mode:
-- 1. Switch to the previously saved layout (if it is NOT Telescope window!)
autocmd(
'InsertEnter',
{
pattern = "*",
callback = function()
vim.schedule(function()
current_filetype = get_current_filetype()
if current_filetype ~= 'TelescopePrompt' then
vim.fn.libcall(xkb_switch_lib, 'Xkb_Switch_setXkbLayout', saved_layout)
end
end)
end
}
)
end
return M
И оно даже работает как нужно. Ну, если не забыть вписать require('myxkbswitch').setup()
куда-нибудь в init.lua.
P.S. А чтобы Telescope искал по скрытым файлам (по умолчанию не ищет) в тот же init.lua можно прописать вот это:
-- Telescope options
require('telescope').setup {
pickers = {
find_files = {
hidden = true -- show hidden files while file search
}
}
}
P.P.S. Чтоб два раза не вставать: заодно сделал еще одно микроулучшение своего юзер ыкспириенса: я время от времени пользуюсь терминалом прямо внутри текстового редактора (открываю командой :term
, хоткея не назначал в силу редкости использования) и давно хотел сделать так, чтобы а) терминал открывался сразу в режиме ввода (дефолтное поведение не такое - нужно сначала нажатием i войти в режим ввода), и б) чтобы в терминале не применялась проверка орфографии (а по умолчанию она там за каким-то фигом применяется если включено для всего редактора). Короче, это делается так:
vim.api.nvim_create_autocmd({ "BufWinEnter", "WinEnter", "TermOpen" }, {
pattern = "term://*",
callback = function()
vim.cmd.startinsert()
vim.cmd.setlocal "nospell"
end,
})