nui-components.nvim icon indicating copy to clipboard operation
nui-components.nvim copied to clipboard

[Bug] Text input made readonly

Open Ajaymamtora opened this issue 1 year ago • 4 comments

Description

When setting the buffer to start in visual mode, the text input is readonly. Seems similar to https://github.com/grapp-dev/nui-components.nvim/issues/17

Repro

local M = {}

vim.api.nvim_create_user_command("NuiGoToLine", function()
  M.go_to_line_nui()
end, {})

local function go_to_line(input)
  -- Print the input
  print(input)

  -- Check if the input matches the format LINE or LINE:COLUMN using a Lua pattern
  local line, column = input:match("^(%d+):?(%d*)$")

  -- Return early if the input is not in the correct format
  if not line then
    print("Input must be in the format LINE or LINE:COLUMN")
    return
  end

  -- Convert line and column to numbers
  line = tonumber(line)
  column = tonumber(column)

  -- Default to column 1 if no column is provided
  if column == 0 then
    column = 1
  end

  -- Go to the specified line and column
  vim.api.nvim_win_set_cursor(0, { line, column })
end

function M.go_to_line_nui()
  local n = require("nui-components")
  local event = require("nui.utils.autocmd").event

  local r, c = unpack(vim.api.nvim_win_get_cursor(0))

  local signal = n.create_signal({
    value = r .. ":" .. c,
  })

  local subscription = signal:observe(function(previous_state, current_state)
    -- call side effects
  end)

  local renderer = n.create_renderer({
    width = 80,
    height = 1,
  })

  renderer:add_mappings({
    {
      mode = { "n", "i", "v" },
      key = "<CR>",
      handler = function()
        go_to_line(signal.value:get_value())
        renderer:close()
      end,
    },
    {
      mode = { "n", "i" },
      key = "<C-q>",
      handler = function()
        renderer:close()
      end,
    },
  })
  local content
  content = n.text_input({
    autofocus = true,
    autoresize = true,
    size = 1,
    value = signal.value,
    border_label = "Go to line",
    placeholder = "L:C",
    max_lines = 1,
    on_change = function(value, component)
      signal.value = value

      component:modify_buffer_content(function()
        -- component:set_border_text("bottom", "Length: " .. #value, "right")
      end)
    end,
    on_mount = function(component)
      local initial_value = signal.value:get_value()

      component:set_border_text("bottom", "Current: " .. r .. ":" .. c, "right")

      local _close = function()
        renderer:close()
      end
      vim.api.nvim_create_autocmd({ "BufLeave" }, { callback = _close, once = true })

      -- Start visual mode
      vim.cmd("normal! v")
    end,
  })

  local body = function()
    return content
  end
  renderer:on_unmount(function()
    subscription:unsubscribe()
  end)

  renderer:render(body)
end

return M

Current Behavior

Input set to readonly

Expected Behavior

Dont set to readonly

NuiComponents version

Main caecfe2

Neovim version

0.10 stable

Ajaymamtora avatar Jul 18 '24 17:07 Ajaymamtora

Another issue: If I remove vim.cmd("normal! v") I can edit the input, but then entering cc in normal mode empties the text and makes the buffer readonly.

It looks like just exiting insert mode makes the input readonly.

Ajaymamtora avatar Jul 19 '24 09:07 Ajaymamtora

Removing autoresize seems to be a workaround

Ajaymamtora avatar Jul 19 '24 09:07 Ajaymamtora

It looks like component:modify_buffer_content sets the buffer option 'modifiable' to false

henrique-smr avatar Dec 18 '24 06:12 henrique-smr

I found a workaround, that basically do what component:modify_buffer_content does, but it restores the original value for the 'modifiable' option, instead of setting to false:

n.text_input({
    autofocus = true,
    autoresize = true,
    size = 1,
    value = signal.value,
    border_label = "Go to line",
    placeholder = "L:C",
    max_lines = 1,
    on_change = function(value, component)
      signal.value = value
      vim.schedule(function()
	    local modifiable = vim.api.nvim_get_option_value("modifiable", { buf = component.bufnr })
	    component:set_buffer_option("modifiable", true)
	    component:set_border_text("bottom", "Length: " .. #value, "right")
	    component:set_buffer_option("modifiable", modifiable)
       end)
    end,
    on_mount = function(component)
      local initial_value = signal.value:get_value()

      component:set_border_text("bottom", "Current: " .. r .. ":" .. c, "right")

      local _close = function()
        renderer:close()
      end
      vim.api.nvim_create_autocmd({ "BufLeave" }, { callback = _close, once = true })

      -- Start visual mode
      vim.cmd("normal! v")
    end,
  })


henrique-smr avatar Dec 18 '24 06:12 henrique-smr