Git Product home page Git Product logo

tabout.nvim's Introduction

๐Ÿฆฟ tabout.nvim

Supercharge your workflow and start tabbing out from parentheses, quotes, and similar contexts today.

ย 

intro

ย 

๐Ÿ’ก examples

Before Key After Setting
{ | } <Tab> {} | -
{ |"string" } <Tab> { "string"| } ignore_beginning = true
{ |"string" } <Tab> { ....|"string"} ignore_beginning = false, act_as_tab = true,
{ "string"| } <S-Tab> { |"string" } -
|#[macro_use] <Tab> #[macro_use]| tabouts = {{open = '#', close = ']'}}

ย 

๐Ÿ“ฆ requirements

  • nvim >= 0.5
  • A tree-sitter parser for each language you would like to use this plugin with. You can install parsers with nvim-treesitter

ย 

๐Ÿ’พ installation

-- Lua
use {
  'abecodes/tabout.nvim',
  config = function()
    require('tabout').setup {
    tabkey = '<Tab>', -- key to trigger tabout, set to an empty string to disable
    backwards_tabkey = '<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disable
    act_as_tab = true, -- shift content if tab out is not possible
    act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
    default_tab = '<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)
    default_shift_tab = '<C-d>', -- reverse shift default action,
    enable_backwards = true, -- well ...
    completion = true, -- if the tabkey is used in a completion pum
    tabouts = {
      {open = "'", close = "'"},
      {open = '"', close = '"'},
      {open = '`', close = '`'},
      {open = '(', close = ')'},
      {open = '[', close = ']'},
      {open = '{', close = '}'}
    },
    ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
    exclude = {} -- tabout will ignore these filetypes
}
  end,
	wants = {'nvim-treesitter'}, -- (optional) or require if not used so far
	after = {'nvim-cmp'} -- if a completion plugin is using tabs load it before
}
-- Lua
return {
  {
    'abecodes/tabout.nvim',
    lazy = false,
    config = function()
      require('tabout').setup {
        tabkey = '<Tab>', -- key to trigger tabout, set to an empty string to disable
        backwards_tabkey = '<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disable
        act_as_tab = true, -- shift content if tab out is not possible
        act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
        default_tab = '<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)
        default_shift_tab = '<C-d>', -- reverse shift default action,
        enable_backwards = true, -- well ...
        completion = false, -- if the tabkey is used in a completion pum
        tabouts = {
          { open = "'", close = "'" },
          { open = '"', close = '"' },
          { open = '`', close = '`' },
          { open = '(', close = ')' },
          { open = '[', close = ']' },
          { open = '{', close = '}' }
        },
        ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
        exclude = {} -- tabout will ignore these filetypes
      }
    end,
    dependencies = { -- These are optional
      "nvim-treesitter/nvim-treesitter",
      "L3MON4D3/LuaSnip",
      "hrsh7th/nvim-cmp"
    },
    opt = true,  -- Set this to true if the plugin is optional
    event = 'InsertCharPre', -- Set the event to 'InsertCharPre' for better compatibility
    priority = 1000,
  },
  {
    "L3MON4D3/LuaSnip",
    keys = function()
      -- Disable default tab keybinding in LuaSnip
      return {}
    end,
  },
}

If you use another plugin manager just make sure you call tabout.nvim's setup after any completion that already uses your tabkey.

ย 

๐Ÿ› ๏ธ options

tabkey

Set the key you want to use to trigger tabout.

-- default
tabkey = '<Tab>'

backwards_tabkey

Set the key you want to use to trigger tabout backwards.

-- default
backwards_tabkey = '<S-Tab>'

act_as_tab

If a tab out is not possible shift the content.

-- default
act_as_tab = true

act_as_shift_tab

If a backwards tab out is not possible reverse shift the content. (Depends on keyboard/terminal if it will work)

-- default
act_as_shift_tab = false

default_tab

If act_as_tab is set to true, a tab out is not possible, and the cursor is at the beginnig of a line, this keysignals are sent in insert mode.

-- default
default_tab = '<C-t>'

default_shift_tab

If act_as_shift_tab is set to true and a tab out is not possible, this keysignals are sent in insert mode.

-- default
default_shift_tab = '<C-d>'

enable_backwards

Disable if you just want to move forward

-- default
enable_backwards = true

completion

Consider using the Plug API and setting this to false

If you use a completion pum that also uses the tab key for a smart scroll function. Setting this to true will disable tab out when the pum is open and execute the smart scroll function instead.

See here how to integrate tabout.vim into more complex completions with snippets.

-- default
completion = true

tabouts

Here you can add more symbols you want to tab out from.

open an close can only contain one character for now

-- default
tabouts = {
  {open = "'", close = "'"},
  {open = '"', close = '"'},
  {open = '`', close = '`'},
  {open = '(', close = ')'},
  {open = '[', close = ']'},
  {open = '{', close = '}'}
}

ignore_beginning

If set to true you can also tab out from the beginning of a string, object property, etc.

-- default
ignore_beginning = true

more complex keybindings

You can set tabkey and backwards_tabkey to empty strings and define more complex keybindings instead.

For example, to make <Tab> and <S-Tab> work with nvim-compe, vim-vsnip and this plugin:

require("tabout").setup({
  tabkey = "",
  backwards_tabkey = "",
})

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

function _G.tab_binding()
  if vim.fn.pumvisible() ~= 0 then
    return replace_keycodes("<C-n>")
  elseif vim.fn["vsnip#available"](1) ~= 0 then
    return replace_keycodes("<Plug>(vsnip-expand-or-jump)")
  else
    return replace_keycodes("<Plug>(Tabout)")
  end
end

function _G.s_tab_binding()
  if vim.fn.pumvisible() ~= 0 then
    return replace_keycodes("<C-p>")
  elseif vim.fn["vsnip#jumpable"](-1) ~= 0 then
    return replace_keycodes("<Plug>(vsnip-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})

Note that some other plugins that also use <Tab> and <S-Tab> might provide already handlers to avoid clashes with tabout.nvim.

For example nvim-cmp mappings can be created using a function that accepts a callback. When the fallback is called tabout.nvim is working out of the box and there is no need for special configurations.

The example below shows nvim-cmp with luasnip mappings using the fallback function:

['<Tab>'] = function(fallback)
    if cmp.visible() then
      cmp.select_next_item()
    elseif luasnip.expand_or_jumpable() then
      vim.fn.feedkeys(vim.api.nvim_replace_termcodes('<Plug>luasnip-expand-or-jump', true, true, false), '')
    else
      fallback()
    end
  end,
  ['<S-Tab>'] = function(fallback)
    if cmp.visible() then
      cmp.select_prev_item()
    elseif luasnip.jumpable(-1) then
      vim.fn.feedkeys(vim.api.nvim_replace_termcodes('<Plug>luasnip-jump-prev', true, true, false), '')
    else
      fallback()
    end
  end,

To make <Tab> and <S-Tab> work with vim-vsnip:

["<Tab>"] = function(fallback)
  if cmp.visible() then
    -- cmp.select_next_item()
    cmp.confirm(
      {
        behavior = cmp.ConfirmBehavior.Insert,
        select = true
      }
    )
  elseif vim.fn["vsnip#available"](1) ~= 0 then
    vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>(vsnip-expand-or-jump)", true, true, true), "")
  else
    fallback()
  end
end,
["<S-Tab>"] = function(fallback)
  if cmp.visible() then
    cmp.select_prev_item()
  elseif vim.fn["vsnip#available"](1) ~= 0 then
    vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>(vsnip-jump-prev)", true, true, true), "")
  else
    fallback()
  end
end,

See here for more nvim-cmp examples.

ย 

๐Ÿค– plug api

Mode plug action
i <Plug>(Tabout) tabout of current context (current line)
i <Plug>(TaboutMulti) tabout of current context (multiple lines)
i <Plug>(TaboutBack) tabout backwards of current context (current line)
i <Plug>(TaboutBackMulti) tabout backwards of current context (multiple lines)

multiline tabout

-- A multiline tabout setup could look like this
vim.api.nvim_set_keymap('i', '<A-x>', "<Plug>(TaboutMulti)", {silent = true})
vim.api.nvim_set_keymap('i', '<A-z>', "<Plug>(TaboutBackMulti)", {silent = true})

ย 

๐Ÿ“‹ commands

command triggers
Tabout ๐Ÿšจ DEPRECATED tries to tab out of current context
TaboutBack ๐Ÿšจ DEPRECATED tries to tab out backwards of current context
TaboutToggle (de)activates the plugin

ย 

โš ๏ธ exceptions

tabout.nvim only works with languages for which you have a tree-sitter parser installed. See for example nvim-treesitter's supported filetypes.

ย 

โœ… todo

  • tabout in blockcomment strings
  • allow multi line tabout
  • support multi character tabouts

tabout.nvim's People

Contributors

abecodes avatar aca avatar aindriu80 avatar amar1729 avatar annenpolka avatar az3r avatar b4shful avatar budswa avatar davidrambo avatar gregorias avatar lkhphuc avatar mrcjkb avatar silveste avatar yutkat avatar zeertzjq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tabout.nvim's Issues

Tabout stops working after save

Hi, I have some issue getting tabout to work.

It works fine before I save, but it stops working on code that was added after first saving.

Say I write the function hello, then save and then write world then save and the say()

    pub fn hello() {}
    pub fn world() {}
    pub fn say() {}

It would not tab-out of say (), but it still tabs out from hello and say ()

I use the lazy plugin manager and remapped the tabkey to C-t to rule out conflicts with other packages.

Here is my setup

return {
  'abecodes/tabout.nvim',
  dependencies = {
    "nvim-treesitter/nvim-treesitter",
    "hrsh7th/nvim-cmp",
  },
  opts = {
    -- options = {
    tabkey = '<C-t>',
    backwards_tabkey = '',
    act_as_tab = false,
    act_as_shift_tab = false,
    default_tab = '',
    default_shift_tab = '',
    enable_backwards = true,
    completion = false,
    tabouts = {
      { open = "'", close = "'" },
      { open = '"', close = '"' },
      { open = '`', close = '`' },
      { open = '(', close = ')' },
      { open = '[', close = ']' },
      { open = '{', close = '}' }
    },
    ignore_beginning = true,
    exclude = {}
  },
}

any idea what might be the problem?

What i tried so far without success

  • Disabling nvim-cmp
  • Different programming languages

<Tab> doesn't move out of parens ()

My Config

		use({
			"abecodes/tabout.nvim",
			wants = { "nvim-treesitter" },
			after = { "nvim-cmp" },
			config = function()
				require("tabout").setup({
					tabkey = "",
					backwards_tabkey = "",
				})
			end,
		})

-- and later in the config:
cmp.setup({
	snippet = {
		expand = function(args)
			luasnip.lsp_expand(args.body) -- For `luasnip` users.
		end,
	},
	window = {},
	mapping = {
		["<C-b>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "c" }),
		["<C-f>"] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "c" }),
		["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
		["<C-y>"] = cmp.config.disable, -- Specify `cmp.config.disable` if you want to remove the default `<C-y>` mapping.
		["<C-e>"] = cmp.mapping({
			i = cmp.mapping.abort(),
			c = cmp.mapping.close(),
		}),
		["<CR>"] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
		["<Tab>"] = function(fallback)
			if vim.fn.pumvisible() ~= 0 then
				cmp.select_next_item()
			elseif luasnip.expand_or_jumpable() then
				vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>luasnip-expand-or-jump", true, true, true), "")
			else
				fallback()
			end
		end,
		["<S-Tab>"] = function(fallback)
			if check_back_space() then
				vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<S-Tab>", true, true, true), "")
			elseif luasnip.jumpable(-1) then
				vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>luasnip-jump-prev", true, true, true), "")
			else
				fallback()
			end
		end,
	},
	sources = cmp.config.sources({
		{ name = "nvim_lsp" },
		{ name = "luasnip" }, -- For luasnip users.
	}, {
		{ name = "buffer" },
	}),
})

NVIM v0.8.3
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by [email protected]

Using latest tabout

How can I disable jumping from open bracket

Currently the behaviour with <tab> are

  1. |{hello} -> {hello}|
  2. |"hello" -> "hello"|
  3. {|hello} -> {hello}|
  4. "|hello" -> "hello"|

I want to disable jump in these scenarios. ignore_beginning = false, act_as_tab = true does not work for 3 and 4.

Multiline { or (

Hello, just trying out this wonderful plugin and I love it. I customized it with:

		use({
			"abecodes/tabout.nvim",
			config = function()
				require("tabout").setup({
					tabkey = "<C-l>", -- key to trigger tabout, set to an empty string to disable
					backwards_tabkey = "<C-h>", -- key to trigger backwards tabout, set to an empty string to disable
					act_as_tab = false,
				})
			end,
			wants = { "nvim-treesitter" }, -- or require if not used so far
			after = { "nvim-cmp" }, -- if a completion plugin is using tabs load it before
		})

I wonder if it would be feasible to tabout from a { or ( that is not on the same line, for example:

use({ -- cursor here
...
})

Not working on [ ]

Hi, the plugin seems to be working fine with the exception of the [ and ]. I assume this is conflicting with another plugin and not an issue with tabout, so I'm wondering if you have any idea what might be causing this?

Standalone setup file

Thanks for this plugin!

When I tried to move the setup config into a standalone lua file like I did for other plugins, an error occurs:

Error detected while processing /Users/ce/.config/nvim/init.lua:
E5113: Error while calling lua chunk: ./tabout.lua:1: loop or previous error loa
ding module 'tabout'
stack traceback:
        [C]: in function 'require'
        ./tabout.lua:1: in main chunk
        [C]: in function 'require'
        /Users/ce/.config/nvim/lua/plugins/tabout.lua:1: in main chunk
        [C]: in function 'require'
        /Users/ce/.config/nvim/lua/plugins/init.lua:9: in main chunk
        [C]: in function 'require'
        /Users/ce/.config/nvim/init.lua:1: in main chunk

Here is my config structure

.
โ”œโ”€โ”€ after
โ”‚ย ย  โ””โ”€โ”€ ftplugin
โ”œโ”€โ”€ init.lua
โ””โ”€โ”€ lua
 ย ย  โ”œโ”€โ”€ init.lua
 ย ย  โ””โ”€โ”€ plugins
        โ”œโ”€โ”€ init.lua
 ย ย      โ”œโ”€โ”€ cmp.lua
 ย ย      โ”œโ”€โ”€ ...
 ย ย      โ””โ”€โ”€ tabout.lua

I require every files in the plugins directory in the lua/plugins/init.lua file.

And here is my tabout config (the example config):

require'tabout'.setup({
    tabkey = '<Tab>', -- key to trigger tabout, set to an empty string to disable
    backwards_tabkey = '<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disable
    act_as_tab = true, -- shift content if tab out is not possible
    act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
    default_tab = '<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)
    default_shift_tab = '<C-d>', -- reverse shift default action,
    enable_backwards = true, -- well ...
    completion = true, -- if the tabkey is used in a completion pum
    tabouts = {
      {open = "'", close = "'"},
      {open = '"', close = '"'},
      {open = '`', close = '`'},
      {open = '(', close = ')'},
      {open = '[', close = ']'},
      {open = '{', close = '}'}
    },
    ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
    exclude = {} -- tabout will ignore these filetypes
})

Maybe this is a trivial issue, but since I haven't encountered it before, I have no clue. Thanks for any help!

Feature request: jump to next argument

I am using cmp for auto-completion. For method completion cmp may complete arguments together for placeholder.

For example, this is what it look like after completion. The first argument is selected and I can type any key to delete it.

image

After typing,
image

What I want is: in the second screenshot, if I presse <tab> then cursor jumps to second argument and select it.

  • If I type any non-<tab> key then I start to replace.
  • If I press <tab> again, then leave it and jump to next argument.

Actually this is what VSCode does for method completion right now.

Inserts tabs even if `expandtab` is `true`

I found out that pressing the Tab key inserts tabs even if expandtab is true. If I disable this plugin, this doesn't happen.

Relevant information:

nvim -v output:

NVIM v0.8.0
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by builduser

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

tabout config:

require('tabout').setup {
    tabkey = '<Tab>', -- key to trigger tabout
    act_as_tab = true, -- shift content if tab out is not possible
    completion = true, -- if the tabkey is used in a completion pum
    tabouts = {
        {open = "'", close = "'"},
        {open = '"', close = '"'},
        {open = '`', close = '`'},
        {open = '(', close = ')'},
        {open = '[', close = ']'},
        {open = '{', close = '}'}
    },
    ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
    exclude = {} -- tabout will ignore these filetypes
}

You can find the rest of my neovim config here

Is the example mappings wrong with "replace_termcodes"?

I'm trying to setup tabout with native nvim snippet on nvim 0.10 nightly and follow the examples on README.
However, it keeps inserting weird character when I press tab.
After tweaking around, I finally manage to get it running by setting the "special" opts of vim.api.nvim_replace_termcodes(str, true, true, false) , as compared all-true in the example.

I'm not very familiar to nvim internal so I just want to inform this so someone can check and correct the README if it's not correct. For my I got it working so feel free to close this.

Here is my full lazy.nvim config with native snippet:

  {
    "abecodes/tabout.nvim",
    event = "InsertCharPre",
    opts = { tabkey = "", backward_tabkey = "" },
    keys = {
      {
        "<Tab>",
        function()
          if vim.snippet.jumpable(1) then
            vim.schedule(function() vim.snippet.jump(1) end)
            return
          end
          return vim.api.nvim_replace_termcodes("<Plug>(Tabout)", true, true, false)
        end,
        expr = true,
        mode = "i",
      },
      {
        "<Tab>",
        function()
          vim.schedule(function() vim.snippet.jump(1) end)
        end,
        silent = true,
        mode = "s",
      },
      {
        "<S-Tab>",
        function()
          if vim.snippet.jumpable(-1) then
            vim.schedule(function() vim.snippet.jump(-1) end)
            return
          end
          return vim.api.nvim_replace_termcodes("<Plug>(TaboutBack)", true, true, false)
        end,
        expr = true,
        silent = true,
        mode = { "i", "s" },
      },
    },
  },

Thanks for the plugin.

A leading space is added to each tab in Makefile

Inserting a tab in Makefile with tabout.nvim installed cause a leading space is added before the tab. This caused make to fail with error: missing separator. Stop.

reproduce

  • open Makefile
  • disable nvim auto indent with :setl noai nocin nosi inde= (as tab inserted by auto indent does not have this problem)
  • enter and save:
main:
 	echo "passed"
  • Use cat -etv Makefile. It shows the presence of tabs with ^I and line endings with $.
main:$
 ^Iecho "hello"$
  • A space is before ^I

reproduced with minimal setup with only nvim treesiter and tabout.nvim installed.

system

  • nvim version: 0.8.0
  • tabout.nvim HEAD: be655cc

Why doesn't it tab out of square brackets?

In rust code:

#[derive(Error, Debug)]

Cursor before 'g', pressing tab moves cursor to after ')' and then further tabs don't progress to after the square brackets.
My configuration includes the square brackets characters.
It doesn't progress beyond square brackets also on other lines.

Is there a reason for that?

Recent change disables TAB key in shell files (bash, zsh, etc.) ... (and possibly others?)

Hi there,

I noticed that with the recent change (c442ae7), my TAB key is completely disabled in shell files I'm editing (in my case, it's mostly zsh files).

I see a lot of plugins use the "bleeding edge" APIs; is it possible that the recent change is using APIs that are not compatible with neovim version 0.9 (the version I have)?

Is there any config update I need to do because of the new commit?

Invalid Expression

I am getting this error when using Tabout

image

Config

require('tabout').setup {
    tabkey = '<c-o>', -- key to trigger tabout
    act_as_tab = true, -- shift content if tab out is not possible
    tabouts = {
      {open = "'", close = "'"},
      {open = '"', close = '"'},
      {open = '`', close = '`'},
      {open = '(', close = ')'},
      {open = '[', close = ']'},
      {open = '{', close = '}'}
    },
    ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
    exclude = {} -- tabout will ignore these filetypes
}

How to write the configure to susport coc.nvim?

Thank you for your awsome plug, but I need some help to make it works with coc.nvim.
I am a beginer and I know little about lua, I try to write configure in vimscript , but there is some thing wrong...

inoremap <silent><expr> <TAB>
    \ pumvisible() ? "\<C-n>" :
    \ coc#expandableOrJumpable() ? "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
    \ "\<Plug>(Tabout)"

when I push , it will send the words "<Plug>(Tabout)" to screen, then I try the lua , but I can't write it correctly

lua<<EOF
 vim.keymap.set({"i"},"<tab>",function()
             if vim.fn["pumvisible"]() == 1 then
                 return '<c-n>'
             elseif vim.fn["coc#expandableOrJumpable"]() == 1 then
                 return "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>"
             else
                 return '<Plug>(Tabout)'
             end
         end,{ expr=true })
EOF

it always shows E5107: Error loading lua [string ":lua"]:5: invalid escape sequence near ' " '

How can I use coc.nvim to select completion menu and jump snippets and don't tabout?

this is my configure:

lua<<EOF
require('tabout').setup {
    tabkey = "", -- key to trigger tabout, set to an empty string to disable
    backwards_tabkey = "", -- key to trigger backwards tabout, set to an empty string to disable
    -- act_as_tab = true, -- shift content if tab out is not possible
    -- act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
    -- enable_backwards = true, -- well ...
    -- completion = true, -- if the tabkey is used in a completion pum
    -- tabouts = {
    --   {open = "'", close = "'"},
    --   {open = '"', close = '"'},
    --   {open = '`', close = '`'},
    --   {open = '(', close = ')'},
    --   {open = '[', close = ']'},
    --   {open = '{', close = '}'},
    --   {open = '<', close = '>'}
    -- },
    -- ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
    -- exclude = {} -- tabout will ignore these filetypes
}
EOF

and I use vim-plug to manage my plug , maybe the problem is relative to the order of plug load


call plug#begin('$HOME/.config/nvim/plugged')
Plug 'abecodes/tabout.nvim'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
call plug#end()

source $HOME/.config/nvim/init/plugconf/tabout-nvim.vim
source $HOME/.config/nvim/init/plugconf/coc-nvim.vim

Tabout doesn't work at all

The tabout extension doesn't seem to be working at all...

2023-07-29.at.9.14.39.PM.mov

I included tabout in my plugins-setup.lua:

use({
  "abecodes/tabout.nvim",
  branch = "feature/tabout-md",
  wants = { "nvim-treesitter" },
  after = { "nvim-cmp" },
})

I also made a config file (copied from the docs):

local setup, tabout = pcall(require, "tabout")
if not setup then
  return
end

tabout.setup({
  tabkey = "<Tab>",
  backwards_tabkey = "<S-Tab>",
  act_as_tab = true,
  act_as_shift_tab = true,
  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, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
  exclude = {},
})

But it doesn't seem to work on any of the files. I did include it in my init.lua file as well (require("doyeon.plugins.tabout")) and I checked multiple issues and discussions by other and tried their solutions. None of them seemed to work. Am I doing something wrong?

Not working in lua files

Tabout works perfectly fine in .js files, but doesn't work for .lua. My config is copied word for word from the example, with one change,
after = {'completion-nvim'} -- if a completion plugin is using tabs load it before
instead of completion-nvim I use nvim-cmp.

packer-error: attempt to concatenate upvalue 'completion_binding' (a nil value)

This started happening earlier today, but somehow only, when I edit a Markdown-file. I don't have completion or Treesitter set up for Markdown, but I remapped the tab-key for Markdown-files in ftplugin/markdown.lua.

You can take a look at my config here.

It must have something to do with another plugins update, however I feel a bit lost in debugging this. Would love your insight on the error, maybe you know a solution off the top of your head.

`ignore_beginning` works differently between `(` and `"`

Hi, I have a question about the ignore_beginning option. The plugin does not seem to work consistently when this option is set to false.

For example, I have the following cpp code snippet.

#include <iostream>

int main() { std::cout << "It is a test " << (1 + 2) << std::endl; }

Now if the cursor is inside the double quotes, pressing TAB will tab out. However, if the curosr is inside the parentheses (for example, right before the + sign), pressing TAB will insert a tab instead of tabbing out.

I would expect tabout works when the cursor is inside a pair of parenthese as well.

My setup (I use lazy.nvim):

{
  "abecodes/tabout.nvim",
  event = { "InsertEnter" },
  opts = {
    ignore_beginning = false,
  },
},

E31: No such mapping

Hey! I'm getting the following error when trying to install with packer using the default config:

packer.nvim: Error running config for tabout.nvim: .../site/pack/packer/start/tabout.nvim/lua/tabout/utils.lua:53: E31: No such mapping

Luasnip?

Hey, So I see all the examples both in Luasnip and Tabout, but I'm not really familiar with Lua/neovim functions/configurations yet.

I'm trying to get <Tab> to be have properly in the following order:

  1. snippet expansion + jumping
  2. tabout

Here is what I have in Luasnip:

return {
  'L3MON4D3/LuaSnip',
  enabled = true,
  event = 'VeryLazy',
  version = '2.*',
  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',
    })

    local function interp(k) vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(k, true, false, true), 'n', false) end

    vim.keymap.set({'i', 's'}, '<Tab>', function()
      if ls.expand_or_jumpable() then ls.expand_or_jump()
      else interp('<Tab>') end
    end)

    vim.keymap.set({'i', 's'}, '<S-Tab>', function()
      if ls.jumpable(-1) then ls.jump(-1)
      else interp('<S-Tab>') end
    end)
  end
}

Now the problem is trying to get Tabout to work with this.

My tabout looks like this:

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

return {
  'abecodes/tabout.nvim',
  enabled = true,
  event = 'VeryLazy',
  dependencies = {
    'nvim-treesitter/nvim-treesitter',
    'hrsh7th/nvim-cmp',
    'L3MON4D3/LuaSnip',
  },
  config = function()
    -- https://github.com/abecodes/tabout.nvim#more-complex-keybindings

    require('tabout').setup({
      tabkey = '',
      backwards_tabkey = '',
      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 function replace_keycodes(c)
    --   return vim.api.nvim_replace_termcodes(c, true, true, true)
    -- end
    --
    -- function _G.tab_binding()
    --   if vim.fn.pumvisible() ~= 0 then
    --     return replace_keycodes("<C-n>")
    --   elseif vim.fn["vsnip#available"](1) ~= 0 then
    --     return replace_keycodes("<Plug>(vsnip-expand-or-jump)")
    --   else
    --     return replace_keycodes("<Plug>(Tabout)")
    --   end
    -- end
    --
    -- function _G.s_tab_binding()
    --   if vim.fn.pumvisible() ~= 0 then
    --     return replace_keycodes("<C-p>")
    --   elseif vim.fn["vsnip#jumpable"](-1) ~= 0 then
    --     return replace_keycodes("<Plug>(vsnip-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,
}

So far I have set this:

      tabkey = '',
      backwards_tabkey = '',

But I'm still trying to figure out what to actually put for the tab_binding.

Are you able to give any ideas?

How to install the plugin with vim-plug?

Hey, I've been trying to test this plugin out but I am having trouble getting it to work.

I am using https://github.com/junegunn/vim-plug instead of https://github.com/wbthomason/packer.nvim to manage my plugins.

I have added

	Plug 'abecodes/tabout.nvim'

to my init.vim and then below I have

lua << EOF
require'nvim-treesitter.configs'.setup {
	-- my config here
}
require('tabout').setup {
    tabkey = '<Tab>', -- key to trigger tabout
    act_as_tab = true, -- shift content if tab out is not possible
    completion = true, -- if the tabkey is used in a completion pum
    tabouts = {
		{open = "'", close = "'"},
		{open = '"', close = '"'},
		{open = '`', close = '`'},
		{open = '(', close = ')'},
		{open = '[', close = ']'},
		{open = '{', close = '}'}
	},
    ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
}
EOF

but when opening neovim I am getting this warning

log.warn("nvim-treesitter is missing")

I suppose the plugin assumes that packer is always used (I assume this is where package.loaded is coming from).

Is there a way to run the plugin with vim-plug?

Won't tab multiple times?

Make a new file, :setf ruby

and type:

hello['|']

And hit <Tab> twice... it just tabs over ' and then stops, it won't tab over ]

Tabout with nvim-cmp and LuaSnip

I tried to make a similiar function to the current 'nvim-compe vsnip tabout' function, but I'm not getting far and I don't know all the things yet have nvim-cmp.

Are there any tips to get nvim-cmp / LuaSnip and tabout working together?

`int a[10];` doesn't taboout in .cpp

int a | [10]
int a [ | 10]
int a [10 | ] 

these cases doesn't tabout, maybe it can add an option to always tabout when the next char is ] , } , )
test config:

require('tabout').setup {
    tabkey = "<tab>",
    backwards_tabkey = "<s-tab>",
    act_as_tab = true,
    act_as_shift_tab = false,
    enable_backwards = true,
    completion = true,
    tabouts = {
      {open = "'", close = "'"},
      {open = '"', close = '"'},
      {open = '`', close = '`'},
      {open = '(', close = ')'},
      {open = '[', close = ']'},
      {open = '{', close = '}'},
      {open = '<', close = '>'}
    },
    ignore_beginning = true,
    exclude = {}
}

Unable to get this working with nvim-cmp

Hi do you have any tips for getting this to work with nvim-cmp? I have tried following your suggested setup for working with nvim-compe which should be similar, but no matter what I do I cannot get this to work.

I'm using the default mapping for tab with nvim-cmp and then I have <tab> mapped to a function as suggested:

function _G.tab_complete()
   if cmp.visible()                                                                                                                                                                                                                                            
     return cmp.select_next_item()
   elseif luasnip.expand_or_jumpable() then
     return luasnip.expand_or_jump()
   elseif utils.check_back_space() then
     cmp.complete()
   else
     return utils.replace_keycodes("<Plug>(Tabout)")
   end
end

What I get though is pressing <tab> in insert mode just outputs <Plug>(Tabout) as text into the current position. The key map is using the expr = true syntax as well. Any thoughts?

Tubout inside Rust macro

I notice incorrect behavior of Tabout inside Rust macro. Let's take a simple oneline example:

format!("{:x}", hash_result);

Suppose I signifies cursor position before Tabout command is executed:

 format!("{:x}|", hash_result)

Now I click Tab and cursor gets to the end like this:

format!("{:x}", hash_result)|

rather than expect after ":

format!("{:x}"|, hash_result)

Is it possible to fix with some configuration?

Set 'fl' instead of TAB

I want to set 'fl' instead of TAB,how to set it
it tried

  use {
    'abecodes/tabout.nvim',
    config = function()
      require('tabout').setup {
      tabkey = "fl", -- key to trigger tabout, set to an empty string to disable
      backwards_tabkey = '<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disable
      act_as_tab = true, -- shift content if tab out is not possible
      act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
      enable_backwards = true, -- well ...
      completion = true, -- if the tabkey is used in a completion pum
      tabouts = {
        {open = "'", close = "'"},
        {open = '"', close = '"'},
        {open = '`', close = '`'},
        {open = '(', close = ')'},
        {open = '[', close = ']'},
        {open = '{', close = '}'}
      },
      ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
      exclude = {} -- tabout will ignore these filetypes
  }
    end,
    wants = {'nvim-treesitter'}, -- or require if not used so far
    after = {'nvim-cmp'} -- if a completion plugin is using tabs load it before
  }

It is giving me an error

How to prevent keybind from being overwritten?

Usually the plugin works just fine however when used in conjunction with some other plugins (e.g. vimwiki) it overwrites the tab key and the plugin won't work so long as I'm inside a vimwiki.

I'm using lazy and this is my plugin file

return{
	{
		'abecodes/tabout.nvim',
		lazy = false,
		config = function()
			require('tabout').setup {
				tabkey = '<Tab>', -- key to trigger tabout, set to an empty string to disable
				backwards_tabkey = '<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disable
				act_as_tab = true, -- shift content if tab out is not possible
				act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
				default_tab = '<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)
				default_shift_tab = '<C-d>', -- reverse shift default action,
				enable_backwards = true, -- well ...
				completion = true, -- if the tabkey is used in a completion pum
				tabouts = {
					{open = "'", close = "'"},
					{open = '"', close = '"'},
					{open = '`', close = '`'},
					{open = '(', close = ')'},
					{open = '[', close = ']'},
					{open = '{', close = '}'}
				},
				ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
				exclude = {} -- tabout will ignore these filetypes
			}
		end,
		dependencies = {'nvim-treesitter', 'L3MON4D3/LuaSnip'}, -- or require if not used so far
		priority = 1000,
	},
}

Can't get plugin to work

I'm using nvchad with this in my plugins.lua

  {
    'abecodes/tabout.nvim',
    lazy = false,
    config = function()
      require('tabout').setup {
      tabkey = '<Tab>', -- key to trigger tabout, set to an empty string to disable
      backwards_tabkey = '<S-Tab>', -- key to trigger backwards tabout, set to an empty string to disable
      act_as_tab = true, -- shift content if tab out is not possible
      act_as_shift_tab = false, -- reverse shift content if tab out is not possible (if your keyboard/terminal supports <S-Tab>)
      default_tab = '<C-t>', -- shift default action (only at the beginning of a line, otherwise <TAB> is used)
      default_shift_tab = '<C-d>', -- reverse shift default action,
      enable_backwards = true, -- well ...
      completion = true, -- if the tabkey is used in a completion pum
      tabouts = {
        {open = "'", close = "'"},
        {open = '"', close = '"'},
        {open = '`', close = '`'},
        {open = '(', close = ')'},
        {open = '[', close = ']'},
        {open = '{', close = '}'}
      },
      ignore_beginning = true, --[[ if the cursor is at the beginning of a filled element it will rather tab out than shift the content ]]
      exclude = {} -- tabout will ignore these filetypes
  }
    end,
    wants = {'nvim-treesitter'}, -- or require if not used so far
    after = {'nvim-cmp'} -- if a completion plugin is using tabs load it before
  },

Lazy installs the plugin after neovim is started and then afterwards I can press ctrl + t to indent the entire line one row but I can't seem to be able to use tab to get out of quotes as that just seems to add a tab spacing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.