Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/tests/manual/input.lua

Raw
local M = {}
local BUF = nil
local WIN = nil

M.tests = {
  { name = 'Basic short prompt (Path A - border title)', prompt = 'What is your name, brave adventurer?' },
  { name = 'Short prompt with question mark (Path A)', prompt = 'Are you sure you want to rm -rf /?' },
  { name = 'Han vs Greedo (Path A)', prompt = 'Who shot first? (Han/Greedo)' },
  { name = 'Vim proficiency rating (Path A)', prompt = 'Rate your Vim proficiency from 0 to :wq' },
  { name = 'Semicolons in Lua (Path A)', prompt = 'Describe your feelings about semicolons in one word:' },
  { name = 'Richard Stallman wisdom (Path A)', prompt = 'What would Richard Stallman do?' },
  { name = 'The meaning of life (Path A)', prompt = 'The answer to life, the universe, and everything is:' },
  { name = 'Long warning prompt (Path B - virt_lines)', prompt = 'You are about to perform an irreversible operation on your carefully crafted dotfiles that you have spent months perfecting. Your Neovim config, your WezTerm theme, your niri layout — all of it could vanish in a puff of smoke. Are you absolutely, positively, cross-your-heart-and-hope-to-die sure you want to proceed?' },
  { name = 'Commandment prompt (Path B)', prompt = 'Thou shalt not use nano. Thou shalt not use emacs. Thou shalt use Neovim exclusively, for it is written: "In the beginning was the command line, and the command line was good."' },
  { name = 'Warranty scam prompt (Path B)', prompt = 'Congratulations! You have been selected as the lucky winner of a free compilation error! To claim your prize, simply enter your credit card number, social security number, mother maiden name, and the name of your first pet. Good luck!' },
  { name = 'Terms and conditions with newlines (Path B)', prompt = 'TERMS AND CONDITIONS:\n1. You will not use nano.\n2. You will not use emacs.\n3. See points 1 and 2.\n\nDo you accept?' },
  { name = 'Mission briefing with newlines (Path B)', prompt = 'Your mission, should you choose to accept it:\n\n- Infiltrate the VS Code headquarters\n- Replace all extensions with Neovim plugins\n- Escape undetected\n\nEnter your codename:' },
  { name = 'Lua love letter with newlines (Path B)', prompt = 'We have been trying to reach you about your cars extended warranty.\n\nJUST KIDDING.\n\nActually, we need you to type I love Lua to continue. The interpreter is watching.' },
  { name = 'Empty prompt (no title)', prompt = '' },
  { name = 'Emoji spirit picker', prompt = 'Pick your spirit emoji (choose wisely):' },
  { name = 'Unicode smorgasbord', prompt = 'Raksmorgas heisst nicht Scoop. Enter your favorite umlaut:' },
  { name = 'Exactly 85% width', prompt = nil },
  { name = 'One char over 85% width', prompt = nil },
  { name = 'Tab-separated columns', prompt = 'Column A\tColumn B\tColumn C' },
  { name = 'Input with default (VS Code trap)', prompt = 'Your favorite editor (hint: wrong answers only):', default = 'VS Code' },
  { name = 'Input with file completion', prompt = 'Pick a file to accidentally delete:', completion = 'file' },
  { name = 'Rapid fire: 3 sequential inputs', prompt = nil },
  { name = 'Input then immediately cancel', prompt = 'Type something then press Esc:' },
  { name = 'The ultimate question', prompt = 'You have reached the end of this manual test suite. As a reward, please type the answer to life, the universe, and everything:' },
}

local function get_buf()
  if BUF and vim.api.nvim_buf_is_valid(BUF) then
    return BUF
  end
  BUF = vim.api.nvim_create_buf(true, true)
  vim.bo[BUF].filetype = 'markdown'
  return BUF
end

local function ensure_window()
  local buf = get_buf()
  if WIN and vim.api.nvim_win_is_valid(WIN) then
    vim.api.nvim_win_set_buf(WIN, buf)
    return WIN
  end
  WIN = vim.api.nvim_open_win(buf, true, {
    relative = 'editor',
    width = math.floor(vim.o.columns * 0.7),
    height = math.floor(vim.o.lines * 0.65),
    row = math.floor(vim.o.lines * 0.33),
    col = math.floor(vim.o.columns * 0.15),
    style = 'minimal',
    border = 'rounded',
    title = ' cmdline input() manual test ',
    title_pos = 'center',
  })
  vim.wo[WIN].wrap = true
  vim.wo[WIN].cursorline = false
  vim.keymap.set('n', 'q', function()
    M.close()
  end, { buf = buf, nowait = true })
  return WIN
end

local function append_content(lines)
  local buf = get_buf()
  vim.api.nvim_buf_set_lines(buf, -1, -1, false, lines)
  if WIN and vim.api.nvim_win_is_valid(WIN) then
    local line_count = vim.api.nvim_buf_line_count(buf)
    vim.api.nvim_win_set_cursor(WIN, { line_count, 0 })
  end
end

function M.set_content(lines)
  local buf = get_buf()
  vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
  ensure_window()
end

function M.show_menu()
  local lines = {
    '',
    '=== CMDLINE INPUT() MANUAL TEST SUITE ===',
    '',
    'Path A = border title | Path B = in-popup virt_lines',
    '',
    'Short prompts (Path A):',
  }
  for i = 1, 7 do table.insert(lines, string.format('  [%2d] %s', i, M.tests[i].name)) end
  table.insert(lines, '')
  table.insert(lines, 'Long prompts (Path B):')
  for i = 8, 10 do table.insert(lines, string.format('  [%2d] %s', i, M.tests[i].name)) end
  table.insert(lines, '')
  table.insert(lines, 'Multi-line prompts (Path B):')
  for i = 11, 13 do table.insert(lines, string.format('  [%2d] %s', i, M.tests[i].name)) end
  table.insert(lines, '')
  table.insert(lines, 'Edge cases:')
  for i = 14, 19 do
    local name = M.tests[i].name
    if i == 17 or i == 18 then name = name .. ' (dynamic)' end
    table.insert(lines, string.format('  [%2d] %s', i, name))
  end
  table.insert(lines, '')
  table.insert(lines, 'Interactive:')
  for i = 20, 24 do table.insert(lines, string.format('  [%2d] %s', i, M.tests[i].name)) end
  M.set_content(lines)
end

function M.run_test(idx)
  local test = M.tests[idx]
  if not test then
    append_content({ 'Invalid test number: ' .. tostring(idx) })
    vim.defer_fn(M.input_loop, 10)
    return
  end

  local prompt = test.prompt
  if idx == 17 then
    local max_w = math.floor(vim.o.columns * 0.85) - 3
    prompt = 'Exactly 85%: ' .. string.rep('x', math.max(0, max_w))
  elseif idx == 18 then
    local max_w = math.floor(vim.o.columns * 0.85) - 3
    prompt = 'One over 85%: ' .. string.rep('x', math.max(0, max_w + 1))
  end

  append_content({
    '',
    '--------------------------------------------------------------------------------',
    'TEST: [' .. idx .. '] ' .. test.name,
    'Prompt: ' .. vim.inspect(prompt),
    'Display width: ' .. vim.fn.strdisplaywidth(prompt),
    '--------------------------------------------------------------------------------',
  })

  if idx == 22 then
    vim.ui.input({ prompt = 'First: ', default = 'one' }, function(a)
      append_content({ 'You entered: ' .. (a or 'nil') })
      vim.ui.input({ prompt = 'Second: ', default = 'two' }, function(b)
        append_content({ 'You entered: ' .. (b or 'nil') })
        vim.ui.input({ prompt = 'Third: ', default = 'three' }, function(c)
          append_content({ 'You entered: ' .. (c or 'nil') })
          append_content({ 'Rapid fire complete!' })
          vim.defer_fn(M.input_loop, 10)
        end)
      end)
    end)
    return
  end

  local opts = { prompt = prompt }
  if test.default then opts.default = test.default end
  if test.completion then opts.completion = test.completion end

  vim.ui.input(opts, function(answer)
    append_content({ 'You entered: ' .. (answer or 'nil') })
    vim.defer_fn(M.input_loop, 10)
  end)
end

function M.input_loop()
  if WIN and vim.api.nvim_win_is_valid(WIN) then
    vim.api.nvim_set_current_win(WIN)
  end
  vim.ui.input({ prompt = 'Enter test # (1-24) or q to quit: ' }, function(answer)
    if not answer or answer == 'q' or answer == 'Q' then
      append_content({ '', 'Done! Press q to close, or :TestAgain to run more tests.' })
      return
    end
    local num = tonumber(answer)
    if num and num >= 1 and num <= #M.tests then
      M.run_test(num)
    else
      if answer ~= '' then
        append_content({ 'Invalid selection: ' .. answer })
      end
      vim.defer_fn(M.input_loop, 10)
    end
  end)
end

function M.close()
  if WIN and vim.api.nvim_win_is_valid(WIN) then
    vim.api.nvim_win_close(WIN, true)
    WIN = nil
  end
end

vim.api.nvim_create_user_command('TestInputClose', function()
  M.close()
end, {})

vim.api.nvim_create_user_command('TestAgain', function()
  vim.defer_fn(M.input_loop, 10)
end, {})

vim.defer_fn(function()
  M.show_menu()
  vim.defer_fn(M.input_loop, 100)
end, 0)

return M