Needing a bit of help with <Plug> command

I’m trying to get the following working with Luasnip + Tabout.nvim:

  1. key always prioritizes expanding a snippet first… ie… html will immediately expand my full doctype snippet

  2. If theres no snippet, then do Tabout.nvim which tabs over braces, ie (‘|’) it will tab over ’ and then )

Here’s my Tabout.nvim code, trying to follow along here: GitHub - abecodes/tabout.nvim: tabout plugin for neovim

-- https://github.com/abecodes/tabout.nvim

return {
  'abecodes/tabout.nvim',
  event = 'InsertEnter',
  dependencies = {
    'nvim-treesitter/nvim-treesitter',
    'hrsh7th/nvim-cmp',
    'L3MON4D3/LuaSnip',
  },
  config = function()
    require('tabout').setup({
      tabkey = '', --'<Tab>',
      backwards_tabkey = '', --'<S-Tab>',
      act_as_tab = true,
      act_as_shift_tab = false,
      default_tab = '<C-t>',
      default_shift_tab = '<C-d>',
      enable_backwards = true,
      completion = true,
      tabouts = {
        { open = "'", close = "'" },
        { open = '"', close = '"' },
        { open = '`', close = '`' },
        { open = '(', close = ')' },
        { open = '[', close = ']' },
        { open = '{', close = '}' }
      },
      ignore_beginning = true,
      exclude = {},
    })

    local ls = require('luasnip')

    local function replace_keycodes(c)
      return vim.api.nvim_replace_termcodes(c, true, true, true)
    end

    function _G.tab_binding()
      if ls.expand_or_jumpable() then
        return replace_keycodes('<Plug>(luasnip-expand-or-jump)')
      else
        return replace_keycodes('<Plug>(Tabout)')
      end
    end

    function _G.s_tab_binding()
      if ls.jumpable(-1) then
        return replace_keycodes('<Plug>(luasnip-jump-prev)')
      else
        return replace_keycodes('<Plug>(TaboutBack)')
      end
    end

    vim.api.nvim_set_keymap('i', '<Tab>', 'v:lua.tab_binding()', { expr = true })
    vim.api.nvim_set_keymap('i', '<S-Tab>', 'v:lua.s_tab_binding()', { expr = true })
  end,
}

But if I go to a document and type html<Tab> it writes the literal text:

html<Plug>(luasnip-expand-or-jump)

I’ve been staring at this for hours, what am I missing?

Here is my Luasnip config:

-- examples: https://github.com/honza/vim-snippets/tree/master/snippets
-- snippet format: https://github.com/garbas/vim-snipmate/blob/master/doc/SnipMate.txt#L228

return {
  'L3MON4D3/LuaSnip',
  event = 'InsertEnter',
  version = '*',
  build = 'make install_jsregexp',
  config = function()
    local ls = require('luasnip')

    -- https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#config-options
    ls.setup({
      update_events = 'TextChanged,TextChangedI',
    })

    require('luasnip.loaders.from_snipmate').lazy_load({
      paths = '~/.config/nvim/snippets',
    })
  end,
}

UGHHHHHHHH ITS BECAUSE

<Plug>(luasnip-jump-prev)

is defined WITHOUT parens but <Plug>(Tabout) IS defined with parens

I thought the parenthesis were for “executing” the name itself or something, not a part of the name.

You can see the names with:

:imap <Plug>