nvim-ts-autotag icon indicating copy to clipboard operation
nvim-ts-autotag copied to clipboard

Feature Request - automatically close unpaired tag on '/'

Open speelbarrow opened this issue 1 year ago • 7 comments

Would it possible/particularly difficult to implement behaviour that would automatically transform <component / to <component />?

(I'd try to just implement it myself but I have absolutely no experience with Treesitter :/)

Let me know if anything about this request is unclear, I'm happy to clarify!

speelbarrow avatar May 27 '24 13:05 speelbarrow

This should be doable depending on the language and the associated treesitter parser.

I'll look into this when I get some time and other issues I've prioritized are knocked out.

PriceHiller avatar May 27 '24 18:05 PriceHiller

Awesome! Thanks so much (:

speelbarrow avatar May 29 '24 15:05 speelbarrow

I'd also love to see this! Since in at least react you don't want a paired tag just <Tag />

jasper-clarke avatar Jun 04 '24 09:06 jasper-clarke

I built this feature in my own config and it works pretty well.

Here are the react-specific instructions:

  1. Create a after/ftplugin directory at the top level of your config.
  2. Create javascriptreact.lua, typescriptreact.lua, and javascript.lua files inside that directory.
  3. Paste the snippet below into each one of those files
-- Automatically end a self-closing tag when pressing /
vim.keymap.set('i', '/', function()
  local node = vim.treesitter.get_node()
  if not node then
    return '/'
  end

  if node:type() == 'jsx_opening_element' then
    local char_after_cursor = vim.fn.strcharpart(vim.fn.strpart(vim.fn.getline('.'), vim.fn.col('.') - 1), 0, 1) ---@type string

    if char_after_cursor == '>' then
      return '/'
    end

    local char_at_cursor = vim.fn.strcharpart(vim.fn.strpart(vim.fn.getline('.'), vim.fn.col('.') - 2), 0, 1) ---@type string
    local already_have_space = char_at_cursor == ' '

    return already_have_space and '/>' or ' />'
  end

  return '/'
end, { expr = true, buffer = true })

@PriceHiller this should be straightforward to implement if you want a PR. This strategy can be used in other file-types as long as the correct node type is known. The code is identical in svelte files, except you match for the 'element' node.

roycrippen4 avatar Jul 14 '24 18:07 roycrippen4

@roycrippen4 if you open a PR to me, I'll gladly merge it (preferably with tests, but it's ok if none are written 🙂 ).

Should be gated beind the enable_close_on_slash configuration option.

PriceHiller avatar Jul 14 '24 18:07 PriceHiller

Thanks all for the great work on this!

jasper-clarke avatar Jul 14 '24 23:07 jasper-clarke

I'm digging into the solution now, but I need to ensure it's more robust than the snippets I provided above. It's one thing to add stuff that's close enough in your own config; it's a completely different ball game integrating it into a plugin and not breaking it for everyone else.

roycrippen4 avatar Jul 14 '24 23:07 roycrippen4

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 13 '24 02:09 stale[bot]

Sorry, I know this issue is closed but I wasn't able to find the corresponding setting in the documentation, I tried enable_close_on_slash but it doesn't work, I don't know if it's a problem with my settings or if this feature doesn't take effect, please help me, sorry again!

jellli avatar Feb 22 '25 08:02 jellli