L3MON4D3 / LuaSnip

Snippet Engine for Neovim written in Lua.
Apache License 2.0
3.31k stars 234 forks source link

Wrap selected text using TM_SELECTED_TEXT #825

Closed JxJxxJxJ closed 1 year ago

JxJxxJxJ commented 1 year ago

I'm trying something like this but does not seem to work.

return {

  s({trig = 'bk', wordTrig = true, snippetType = "autosnippet" },
      {
        require('luasnip').function_node(function(snip)
          local selected_text = snip.env.TM_SELECTED_TEXT or ""
          return "\\textbf{" .. selected_text .. "}"
        end, {})
      },
      { condition = in_text }
  ),

}

After I press <Tab> as in store_selection_keys = "<Tab>", in my require("luasnip").config.set_configand then bk to trigger the snippet the following error appears

E5108: Error executing lua ...k/packer/start/LuaSnip/lua/luasnip/nodes/dynamicNode.lua:134: attempt to cal
l field 'fn' (a nil value)
stack traceback:
        ...k/packer/start/LuaSnip/lua/luasnip/nodes/dynamicNode.lua:134: in function 'update'
        .../pack/packer/start/LuaSnip/lua/luasnip/nodes/snippet.lua:813: in function 'update'
        .../pack/packer/start/LuaSnip/lua/luasnip/nodes/snippet.lua:504: in function 'trigger_expand'
        ...rvim/site/pack/packer/start/LuaSnip/lua/luasnip/init.lua:227: in function 'snip_expand'
        ...rvim/site/pack/packer/start/LuaSnip/lua/luasnip/init.lua:310: in function 'expand_auto'
        [string ":lua"]:1: in main chunk
leiserfg commented 1 year ago

You need to drop the first argument of the function (the list of inputs).

require('luasnip').function_node(function( _ ,  snip)
JxJxxJxJ commented 1 year ago

You need to drop the first argument of the function (the list of inputs).

require('luasnip').function_node(function( _ ,  snip)

Sorry I did not understand, what should I do with that?

leiserfg commented 1 year ago

The first argument is the list of inputs the function will use, not the parent snippet.

JxJxxJxJ commented 1 year ago

@leiserfg I'm trying again to solve this. Currently I made the modifications you indicated.

I have:

return {
  s({ trig = 'bk', wordTrig = true, snippetType = "autosnippet" },
    {
      require('luasnip').function_node(function(_, snip)
        local selected_text = snip.env.TM_SELECTED_TEXT or ""
        return "\\textbf{" .. selected_text .. "}"
      end, {})
    },
    { condition = in_text }
  ),
}

But when I select text + press TAB + bk the following error appear

E5108: Error executing lua [string "require("luasnip").setup_snip_env() ---@diagn..."]:7: attempt to conca
tenate local 'selected_text' (a table value)
stack traceback:
        [string "require("luasnip").setup_snip_env() ---@diagn..."]:7: in function 'fn'
        .../packer/start/LuaSnip/lua/luasnip/nodes/functionNode.lua:47: in function 'update'
        .../pack/packer/start/LuaSnip/lua/luasnip/nodes/snippet.lua:813: in function 'update'
        .../pack/packer/start/LuaSnip/lua/luasnip/nodes/snippet.lua:504: in function 'trigger_expand'
        ...rvim/site/pack/packer/start/LuaSnip/lua/luasnip/init.lua:227: in function 'snip_expand'
        ...rvim/site/pack/packer/start/LuaSnip/lua/luasnip/init.lua:310: in function 'expand_auto'
        [string ":lua"]:1: in main chunk
JxJxxJxJ commented 1 year ago

The problem I encountered is that selected_text is a table value, but I am trying to concatenate it as a string. This could be because TM_SELECTED_TEXT returns a table instead of a string in some cases.

To fix this issue, I can convert the selected_text table into a string before concatenating it in the function node. Here's a way to do that using table.concat:

return {
  s({ trig = 'bk', wordTrig = true, snippetType = "autosnippet" },
    {
      require('luasnip').function_node(function(_, snip)
        local selected_text = snip.env.TM_SELECTED_TEXT or ""
        if type(selected_text) == 'table' then
          selected_text = table.concat(selected_text, '\n')
        end
        return "\\textbf{" .. selected_text .. "}"
      end, {})
    },
    { condition = in_text }
  ),
}

This solution checks if selected_text is a table and, if so, converts it into a string by concatenating its elements with newline characters as separators.

Is there any more elegant solution?

leiserfg commented 1 year ago

TM_SELECTED_TEXT is always a table.

JxJxxJxJ commented 1 year ago

Thanks!

  s({ trig = 'vbf', wordTrig = true, snippetType = "autosnippet" },
    {
      require('luasnip').function_node(function(_, snip)
        local selected_text = snip.env.TM_SELECTED_TEXT or {}
        local text = table.concat(selected_text, '\n')
        return "\\textbf{" .. text .. "}"
      end, {})
    },
    { condition = in_text }
  ),

Works perfectly :) Thank you very much