Neovim toggle moody words
Sérgio Araújo

Sérgio Araújo @voyeg3r

About: I am a Free Software enthusiast and a (neo)?vim addicted, I also like shell script, sed, awk, and as you can see I love Regular Expressions.

Location:
Brazil
Joined:
Sep 23, 2017

Neovim toggle moody words

Publish Date: Jun 14
2 0

Toggling values in programming is highlly frequent. What about a lua function and a mapping for that?


local M = {}

M.switch_moody_word = function()
  -- Grupos de estados relacionados (ordem importa)
  local state_groups = {
    { 'true', 'false' },
    { 'on', 'off' },
    { 'in', 'out' },
    { 'start', 'stop' },
    { 'show', 'hide' },
    { 'enable', 'disable' },
    { 'yes', 'no' },
    { 'up', 'down' },
    { 'always', 'never' },
    { 'error', 'warn', 'info', 'debug', 'trace' },
    { 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' },
  }

  -- Ajusta capitalização para combinar com a palavra original
  local function match_case(original, new)
    if original:match('^%u+$') then return new:upper() end -- TODO → DEBUG
    if original:match('^%l+$') then return new:lower() end -- todo → debug
    if original:match('^%u%l+$') then return new:sub(1, 1):upper() .. new:sub(2):lower() end -- Todo → Debug
    return new
  end

  -- Pega a próxima palavra dentro do mesmo grupo
  local function get_next_word(word)
    local lower = word:lower()
    for _, group in ipairs(state_groups) do
      for i, w in ipairs(group) do
        if w == lower then
          local next = group[(i % #group) + 1]
          return match_case(word, next)
        end
      end
    end
    return nil
  end

  -- Palavra sob o cursor
  local word = vim.fn.expand('<cword>')
  local replacement = get_next_word(word)
  if not replacement then return end

  -- Substitui palavra no buffer manualmente (evita bugs com `ciw`)
  local _, col = unpack(vim.api.nvim_win_get_cursor(0))
  local line = vim.api.nvim_get_current_line()

  local start_col = col
  while start_col > 0 and line:sub(start_col, start_col):match('[%w_]') do
    start_col = start_col - 1
  end
  start_col = start_col + 1

  local end_col = col + 1
  while line:sub(end_col, end_col):match('[%w_]') do
    end_col = end_col + 1
  end
  end_col = end_col - 1

  local new_line = line:sub(1, start_col - 1) .. replacement .. line:sub(end_col + 1)
  vim.api.nvim_set_current_line(new_line)
end

return M
Enter fullscreen mode Exit fullscreen mode

Now an intuitive mapping to toggle these words from our list above

local switch_moody_word = require('utils').swich_moody_word

-- NOTE: Adjust the require to fit your environment realitty

vim.keymap.set('n', '<Tab>', function() switch_moody_word() end, {
  desc = ' [T]oggle [b]oolean',
  silent = false,
})
Enter fullscreen mode Exit fullscreen mode

Comments 0 total

    Add comment