I have a utils file where I have this:
M.bipolar = function()
-- source: https://github.com/sagarrakshe/toggle-bool/blob/master/plugin/toggle_bool.py
values = {
["true"] = "false",
["on"] = "off",
["yes"] = "no",
["1"] = "0",
["enable"] = "disable",
["enabled"] = "disabled",
["before"] = "after",
["first"] = "last"
}
function format_value(word, toggleWord)
if word:upper() == word then
toggleWord = toggleWord:upper()
elseif word:sub(1, 1):upper() .. word:sub(2) == word then
toggleWord = toggleWord:sub(1, 1):upper() .. toggleWord:sub(2)
end
return toggleWord
end
function toggle_bool_value(word)
local toggleWord = word
for key, value in pairs(values) do
if string.lower(key) == word:lower() then
toggleWord = value
toggleWord = format_value(word, toggleWord)
break
elseif string.lower(value) == word:lower() then
toggleWord = key
toggleWord = format_value(word, toggleWord)
break
end
end
return toggleWord
end
end
I would like to map a key to toggle the word under cursor
– the solution
-- https://github.com/sagarrakshe/toggle-bool/blob/master/plugin/toggle_bool.py
M.toggle_boolean_value_on_line = function()
local values = {
["true"] = "false",
["on"] = "off",
["yes"] = "no",
["1"] = "0",
["enable"] = "disable",
["enabled"] = "disabled",
["before"] = "after",
["first"] = "last",
["up"] = "down",
}
local function format_value(word, toggleWord)
if word:upper() == word then
toggleWord = toggleWord:upper()
elseif word:sub(1, 1):upper() .. word:sub(2) == word then
toggleWord = toggleWord:sub(1, 1):upper() .. toggleWord:sub(2)
end
return toggleWord
end
local function toggle_bool_value(word)
local toggleWord = word
for key, value in pairs(values) do
if string.lower(key) == word:lower() then
toggleWord = value
toggleWord = format_value(word, toggleWord)
break
elseif string.lower(value) == word:lower() then
toggleWord = key
toggleWord = format_value(word, toggleWord)
break
end
end
return toggleWord
end
local current_line = vim.api.nvim_get_current_line()
local line_words = {}
for word in current_line:gmatch("%S+") do
table.insert(line_words, word)
end
for i, word in ipairs(line_words) do
line_words[i] = toggle_bool_value(word)
end
local new_line = table.concat(line_words, " ")
vim.api.nvim_set_current_line(new_line)
end
-- put this keymap on your keymaps.lua
vim.keymap.set('n', '<leader>t', '<cmd>lua require("core.utils").toggle_boolean_value_on_line()<cr>',
{ desc = "toggle boolean on line"})
– the code bellow handles some exceptions, booleans followed by comma, preserves indentation etc.
M.toggle_boolean_value_on_line = function()
-- https://github.com/sagarrakshe/toggle-bool/blob/master/plugin/toggle_bool.py
local values = {
["true"] = "false",
["false"] = "true",
["on"] = "off",
["off"] = "on",
["yes"] = "no",
["no"] = "yes",
["1"] = "0",
["0"] = "1",
["enable"] = "disable",
["disable"] = "enable",
["enabled"] = "disabled",
["disabled"] = "enabled",
["before"] = "after",
["after"] = "before",
["first"] = "last",
["last"] = "first",
["up"] = "down",
["down"] = "up",
}
local function toggle_bool_value(word)
local toggleWord = values[word]
if toggleWord == nil then
return word
end
return toggleWord
end
local current_line = vim.api.nvim_get_current_line()
local indent = current_line:match("^%s*") -- Get the leading whitespace
local line_words = {}
local bool_count = 0
for word in current_line:gmatch("%S+") do
if values[word] ~= nil then
bool_count = bool_count + 1
end
table.insert(line_words, word)
end
local cursor_word = vim.fn.expand("<cword>")
if bool_count == 1 then
for i, word in ipairs(line_words) do
if values[word] ~= nil then
line_words[i] = toggle_bool_value(word)
end
end
else
for i, word in ipairs(line_words) do
if word == cursor_word then
line_words[i] = toggle_bool_value(word)
break
end
end
end
local new_line = indent .. table.concat(line_words, " ")
vim.api.nvim_set_current_line(new_line)
end
I’m not sure if this solves all of your use cases, but it’s worth a look