nvim-treesitter / nvim-treesitter/nvim-treesitter-textobjects
Swap Keymaps Not Being Used in TypeScript, Javascript, or Ruby Buffers
Nobody has claimed this yet.
- Dominant language
- Tree-sitter Query
- Stars
- 2.8k
- Forks
- 271
- Avg merge
- 8d 8h
- Merged PRs (30d)
- 1
Description
Describe the bug
I have updated my nvim/init.lua config such that I should be able to use the swapping functionality with nvim-treesitter-textobjects, however, when I try using these keybindings, <Leader>a or <Leader>A, the normal appends command are executed, instead of the swapping functionality:
nvim/lua/plugins/init.lua
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- must map leader key before "lazy" setup
vim.g.mapleader = " "
vim.g.maplocalleader = ","
return require("lazy").setup({
{
"nvim-telescope/telescope-media-files.nvim",
dependencies = { "nvim-lua/popup.nvim", "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" },
},
{
"nvim-neorg/neorg",
build = ":Neorg sync-parsers",
-- tag = "*",
dependencies = { "nvim-lua/plenary.nvim" },
},
{
"nvim-neotest/neotest",
lazy = true,
dependencies = {
"olimorris/neotest-rspec",
"nvim-neotest/neotest-jest",
},
},
{ "github/copilot.vim" },
{
"piersolenski/telescope-import.nvim",
requires = "nvim-telescope/telescope.nvim",
},
{
"nvim-telescope/telescope-fzf-native.nvim",
build = "cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build",
},
{
"nvim-telescope/telescope.nvim",
branch = "0.1.x",
dependencies = { "nvim-lua/plenary.nvim" },
},
{
"nvim-treesitter/nvim-treesitter",
dependencies = {
"JoosepAlviste/nvim-ts-context-commentstring",
},
build = ":TSUpdate",
},
{ "nvim-treesitter/nvim-treesitter-textobjects", dependencies = { "nvim-treesitter/nvim-treesitter" } },
{
"numToStr/Comment.nvim",
opts = {},
lazy = false,
},
{
"stevearc/overseer.nvim",
opts = {},
-- optional for nicer ui
dependencies = { "rcarriga/nvim-notify", "stevearc/dressing.nvim" },
},
{
"folke/zen-mode.nvim",
opts = {},
},
{
"pmizio/typescript-tools.nvim",
dependencies = { "nvim-lua/plenary.nvim", "neovim/nvim-lspconfig" },
opts = {},
},
{
"stevearc/oil.nvim",
opts = {},
-- Optional dependencies
dependencies = { "nvim-tree/nvim-web-devicons" },
},
{
"danymat/neogen",
dependencies = "nvim-treesitter/nvim-treesitter",
config = true,
},
{ "ThePrimeagen/harpoon", dependencies = { "nvim-lua/plenary.nvim" } },
"dfendr/clipboard-image.nvim",
"karb94/neoscroll.nvim",
"mxsdev/nvim-dap-vscode-js",
"barklan/capslock.nvim",
"stevearc/conform.nvim",
{ "rcarriga/nvim-dap-ui", dependencies = { "mfussenegger/nvim-dap" } },
{ "folke/neodev.nvim", opts = {} },
"ray-x/web-tools.nvim",
{ "rest-nvim/rest.nvim", dependencies = { "nvim-lua/plenary.nvim" } },
"ludovicchabant/vim-gutentags",
"RRethy/nvim-treesitter-endwise",
"williamboman/mason.nvim",
"tpope/vim-fugitive", -- Git operations, tools in neovim
"junegunn/gv.vim", -- Pretty Git log
"navarasu/onedark.nvim",
"xiyaowong/transparent.nvim",
-- recommended settings from 'nvim-lspconfig'
"neovim/nvim-lspconfig",
"hrsh7th/nvim-cmp", -- Autocompletion plugin
"hrsh7th/cmp-nvim-lsp", -- LSP source for nvim-cmp
"saadparwaiz1/cmp_luasnip", -- Snippets source for nvim-cmp
"L3MON4D3/LuaSnip", -- Snippets plugin
-- dap
"williamboman/mason.nvim",
"mfussenegger/nvim-dap",
--
{
"folke/which-key.nvim",
event = "VeryLazy",
init = function()
vim.o.timeout = true
vim.o.timeoutlen = 300
end,
opts = {},
},
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
opts = {
highlight = { enable = true },
},
config = function(_, opts)
require("nvim-treesitter.configs").setup(opts)
end,
},
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons", lazy = true },
},
{
"iamcco/markdown-preview.nvim",
build = function()
vim.fn["mkdp#util#install"]()
end,
},
{ "lukas-reineke/indent-blankline.nvim", main = "ibl", opts = {} },
})
nvim/init.lua
require("plugins")
--TODO: Figure out why typing 'g', waiting, then 'cA' works to insert comments, but typing them all quickly doesn't?
-- Is there some plugin that is causing combinations that start with g to wait/not wait?
-- MASON
-- https://github.com/williamboman/mason.nvim/issues/130
local present, mason = pcall(require, "mason")
if not present then
return
end
-- Not all dependencies installed by Mason here are specifically for nvim-lspconfig
-- some are installed here just for consistency across machines, and it's easier if
-- things are installed in one place.
local options = {
ensure_installed = {
"beautysh",
"bash-language-server",
"css-lsp",
"cssmodules-language-server",
"cucumber-language-server",
"docker-compose-language-service",
"dockerfile-language-server",
"emmet-language-server",
"eslint-lsp",
"html-lsp",
"json-lsp",
"jsonlint",
"lua-language-server",
"solargraph",
"stylua",
"sqlls",
"marksman",
"tailwindcss-language-server",
"vim-language-server",
"yaml-language-server",
"typescript-language-server",
"prettier",
},
max_concurrent_installers = 10,
}
mason.setup(options)
vim.api.nvim_create_user_command("MasonInstallAll", function()
vim.cmd("MasonInstall " .. table.concat(options.ensure_installed, " "))
end, {})
-- NVIM-DAP
-- https://github.com/mfussenegger/nvim-dap
require("dap").adapters["pwa-node"] = {
type = "server",
host = "localhost",
port = "9229",
executable = {
command = "node",
args = { vim.fn.stdpath("data") .. "/vscode-js-debug", "9229" },
},
}
-- DAP-VSCODE-JS
-- https://miguelcrespo.co/posts/debugging-javascript-applications-with-neovim/
---@diagnostic disable-next-line: missing-fields
require("dap-vscode-js").setup({
debugger_path = vim.fn.stdpath("data") .. "/vscode-js-debug",
adapters = {
"pwa-node",
"pwa-chrome",
},
})
local js_based_languages = { "typescript", "javascript", "typescriptreact" }
for _, language in ipairs(js_based_languages) do
require("dap").configurations[language] = {
{
type = "pwa-node",
request = "launch",
name = "Launch file",
program = "${file}",
cwd = "${workspaceFolder}",
},
{
type = "pwa-node",
request = "attach",
name = "Attach",
processId = require("dap.utils").pick_process,
cwd = "${workspaceFolder}",
},
{
type = "pwa-chrome",
request = "launch",
name = 'Start Chrome with "localhost"',
url = "http://localhost:3000",
webRoot = "${workspaceFolder}",
},
}
end
for _, language in ipairs({ "typescript", "javascript" }) do
require("dap").configurations[language] = {
{
type = "pwa-node",
request = "launch",
name = "Launch file",
program = "${file}",
cwd = "${workspaceFolder}",
},
{
type = "pwa-node",
request = "attach",
name = "Attach",
processId = require("dap.utils").pick_process,
cwd = "${workspaceFolder}",
},
}
end
-- NVIM-DAP-UI
-- https://github.com/rcarriga/nvim-dap-ui
require("dapui").setup()
local dap, dapui = require("dap"), require("dapui")
dap.listeners.after.event_initialized["dapui_config"] = function()
dapui.open()
end
dap.listeners.before.event_terminated["dapui_config"] = function()
dapui.close()
end
dap.listeners.before.event_exited["dapui_config"] = function()
dapui.close()
end
-- TRANSPARENT.NVIM
-- https://github.com/xiyaowong/transparent.nvim
require("transparent").setup()
-- NVIM-TREESITTER
-- https://github.com/nvim-treesitter/nvim-treesitter
---@diagnostic disable-next-line: missing-fields
require("nvim-treesitter.configs").setup({
ensure_installed = {
"c",
"lua",
"vim",
"vimdoc",
"query",
"bash",
"css",
"dockerfile",
"fish",
"html",
"http",
"javascript",
"jq",
"json",
"markdown",
"ruby",
"scss",
"sql",
"toml",
"tsx",
"typescript",
"yaml",
},
-- required by 'nvim-treesitter-endwise'
endwise = {
enable = true,
},
-- NVIM-TREESITTER-TEXTOBJECTS
-- https://github.com/nvim-treesitter/nvim-treesitter-textobjects
textobjects = {
lsp_interop = {
enable = true,
border = "none",
floating_preview_opts = {},
peek_definition_code = {
["<leader>vf"] = "@function.outer",
["<leader>vc"] = "@class.outer",
},
},
move = {
enable = true,
set_jumps = true, -- whether to set jumps in the jumplist
goto_next_start = {
["]m"] = "@function.outer",
["]]"] = "@class.outer",
},
goto_next_end = {
["]M"] = "@function.outer",
["]["] = "@class.outer",
},
goto_previous_start = {
["[m"] = "@function.outer",
["[["] = "@class.outer",
},
goto_previous_end = {
["[M"] = "@function.outer",
["[]"] = "@class.outer",
},
goto_next = {
["]d"] = "@conditional.outer",
},
goto_previous = {
["[d"] = "@conditional.outer",
},
},
context_commentstring = {
enable = true,
enable_autocmd = false,
},
select = {
enable = true,
lookahead = true,
keymaps = {
["af"] = { query = "@function.outer", desc = "Select outer function" },
["if"] = { query = "@function.inner", desc = "Select inner function" },
["ac"] = { query = "@class.outer", desc = "Select outer class" },
["ic"] = { query = "@class.inner", desc = "Select inner class" },
["as"] = { query = "@scope", query_group = "locals", desc = "Select language scope" },
["is"] = { query = "@scope.inner", query_group = "locals", desc = "Select inner language scope" },
["al"] = { query = "@loop.outer", desc = "Select outer loop" },
["il"] = { query = "@loop.inner", desc = "Select inner loop" },
["ab"] = { query = "@block.outer", desc = "Select outer block" },
["ib"] = { query = "@block.inner", desc = "Select inner block" },
["ap"] = { query = "@parameter.outer", desc = "Select outer parameter" },
["ip"] = { query = "@parameter.inner", desc = "Select inner parameter" },
["aP"] = { query = "@parameter.outer", mode = "a", desc = "Select outer parameter (inclusive)" },
["iP"] = { query = "@parameter.inner", mode = "a", desc = "Select inner parameter (inclusive)" },
["a,"] = { query = "@parameter.outer", mode = "i", desc = "Select outer parameter (exclusive)" },
["i,"] = { query = "@parameter.inner", mode = "i", desc = "Select inner parameter (exclusive)" },
["a;"] = {
query = "@parameter.outer",
mode = "a",
kind = "inclusive",
desc = "Select outer parameter (inclusive)",
},
["i;"] = {
query = "@parameter.inner",
mode = "a",
kind = "inclusive",
desc = "Select inner parameter (inclusive)",
},
["a:"] = {
query = "@parameter.outer",
mode = "i",
kind = "exclusive",
desc = "Select outer parameter (exclusive)",
},
["i:"] = {
query = "@parameter.inner",
mode = "i",
kind = "exclusive",
desc = "Select inner parameter (exclusive)",
},
["a/"] = { query = "@comment.outer", desc = "Select outer comment" },
["i/"] = { query = "@comment.inner", desc = "Select inner comment" },
["a#"] = {
query = "@comment.outer",
mode = "i",
kind = "inclusive",
desc = "Select outer comment (inclusive)",
},
["i#"] = {
query = "@comment.inner",
mode = "i",
kind = "inclusive",
desc = "Select inner comment (inclusive)",
},
},
selection_modes = {
["@parameter.outer"] = "v", -- charwise
["@function.outer"] = "V", -- linewise
["@class.outer"] = "V", -- blockwise
},
swap = {
enable = true,
swap_next = {
["<leader>a"] = "@parameter.inner",
},
swap_previous = {
["<leader>A"] = "@parameter.inner",
},
},
},
},
-- my config
highlight = {
enable = true,
},
incremental_selection = {
enable = true,
keymaps = {
--TODO: how to inform whichkey that <leader>s should be used for this?
init_selection = "<Leader>si", -- select start
node_incremental = "<Leader>sn", -- select node (incremental)
scope_incremental = "<Leader>ss", -- select scope
node_decremental = "<Leader>sd", -- select node (decremental)
},
},
indent = {
enable = true,
},
})
local ts_repeat_move = require("nvim-treesitter.textobjects.repeatable_move")
-- Repeat movement with ; and ,
-- ensure ; goes forward and , goes backward regardless of the last direction
vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move_next)
vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_previous)
-- vim way: ; goes to the direction you were moving.
-- vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move)
-- vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)
-- Optionally, make builtin f, F, t, T also repeatable with ; and ,
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f)
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F)
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t)
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T)
-- custom file associations
require("vim.treesitter.language").register("http", "hurl")
-- NEOSCROLL.NVIM
-- https://github.com/karb94/neoscroll.nvim
require("neoscroll").setup({
easing_function = "quadratic",
})
-- WEB-TOOLS.NVIM
-- https://github.com/ray-x/web-tools.nvim
require("web-tools").setup({
keymaps = {
rename = nil, -- by default use same setup of lspconfig
},
hurl = { -- hurl default
show_headers = false, -- do not show http headers
floating = false, -- use floating windows (need guihua.lua)
formatters = { -- format the result by filetype
json = { "jq" },
html = { "prettier", "--parser", "html" },
},
},
})
-- REST.NVIM
-- https://github.com/rest-nvim/rest.nvim
require("rest-nvim").setup({
result_split_horizontal = false,
result_split_in_place = true,
skip_ssl_verification = false,
encode_url = true,
highlight = {
enabled = true,
timeout = 150,
},
result = {
show_url = true,
show_curl_command = false,
show_http_info = true,
show_headers = true,
formatters = {
json = "jq",
html = function(body)
return vim.fn.system({ "tidy", "-i", "-q", "-" }, body)
end,
},
},
jump_to_request = false,
env_file = ".env",
custom_dynamic_variables = {},
yank_dry_run = true,
})
-- NEODEV.NVIM
-- https://github.com/folke/neodev.nvim
-- NOTE: must be done before any lspconfig
require("neodev").setup({})
--TODO: Figure out where this configuration was recommended?
-- Add additional capabilities supported by nvim-cmp
local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- NVIM-LSPCONFIG
-- https://github.com/neovim/nvim-lspconfig
local lspconfig = require("lspconfig")
local servers = {
"emmet_language_server",
"lua_ls",
"jsonls",
"html",
"bashls",
"cssls",
"cssmodules_ls",
"docker_compose_language_service",
"dockerls",
"emmet_language_server",
"yamlls",
"eslint",
"marksman",
"cucumber_language_server",
"tailwindcss",
"solargraph",
"sqlls",
"vimls",
}
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup({
capabilities = capabilities,
})
end
-- RECOMMENDED 'nvim-lspconfig' SETUP
-- LUASNIP
-- https://github.com/L3MON4D3/LuaSnip
local luasnip = require("luasnip")
-- NVIM-CMP
-- https://github.com/hrsh7th/nvim-cmp
local cmp = require("cmp")
---@diagnostic disable-next-line: missing-fields
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-u>"] = cmp.mapping.scroll_docs(-4), -- Up
["<C-d>"] = cmp.mapping.scroll_docs(4), -- Down
["<C-j>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
else
fallback()
end
end, { "i", "s" }),
["<C-k>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
else
fallback()
end
end, { "i", "s" }),
-- C-b (back) C-f (forward) for snippet placeholder navigation.
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Replace,
}),
}),
sources = {
{ name = "nvim_lsp" },
{ name = "luasnip" },
},
})
--TODO: Where was this bit of configuration recommended?
vim.o.updatetime = 250
vim.api.nvim_create_autocmd("CursorHold", {
buffer = bufnr,
callback = function()
local opts = {
focusable = false,
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
border = "rounded",
source = "always",
prefix = " ",
scope = "cursor",
}
vim.diagnostic.open_float(nil, opts)
end,
})
-- RECOMMENDED 'nvim-lspconfig' SETUP END
-- luasnip specific configuration
-- specify luasnippets directory to save a few ms of startup time
require("luasnip.loaders.from_lua").load({ paths = "./luasnippets/" })
local ls = require("luasnip")
ls.config.set_config({
-- Enable autotriggered snippets
enable_autosnippets = false,
-- Use Tab to trigger visual selection
store_selection_keys = "<Tab>",
-- show repeated node text as it's typed
update_events = "TextChanged,TextChangedI",
})
--TODO: Better way to map these potentially?
vim.keymap.set({ "i" }, "<C-K>", function()
ls.expand()
end, { silent = true })
vim.keymap.set({ "i", "s" }, "<C-L>", function()
ls.jump(1)
end, { silent = true })
vim.keymap.set({ "i", "s" }, "<C-J>", function()
ls.jump(-1)
end, { silent = true })
vim.keymap.set({ "i", "s" }, "<C-E>", function()
if ls.choice_active() then
ls.change_choice(1)
end
end, { silent = true })
ls.filetype_extend("javascriptreact", { "javascript" })
ls.filetype_extend("typescript", { "javascript" })
ls.filetype_extend("typescriptreact", { "javascriptreact" })
-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
callback = function(ev)
-- Enable completion triggered by <c-x><c-o>
vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc"
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
local opts = { buffer = ev.buf }
--TODO: Can I move these outside of this function?
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { unpack(opts), desc = "declaration" })
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { unpack(opts), desc = "definition" })
-- commenting this out since nvim-treesitter-textobject providers more consistent TypeScript support for peeking definitions
-- vim.keymap.set("n", "K", vim.lsp.buf.hover, { unpack(opts), desc = "hover" })
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, { unpack(opts), desc = "implementation" })
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, { unpack(opts), desc = "signature help" })
vim.keymap.set(
"n",
"<space>wa",
vim.lsp.buf.add_workspace_folder,
{ unpack(opts), desc = "add workspace folder" }
)
vim.keymap.set(
"n",
"<space>wr",
vim.lsp.buf.remove_workspace_folder,
{ unpack(opts), desc = "remove workspace folder" }
)
vim.keymap.set("n", "<space>wl", function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, { unpack(opts), desc = "list workspace folders" })
vim.keymap.set("n", "<space>D", vim.lsp.buf.type_definition, { unpack(opts), desc = "type definition" })
vim.keymap.set("n", "<space>rn", vim.lsp.buf.rename, { unpack(opts), desc = "rename" })
vim.keymap.set({ "n", "v" }, "<space>ca", vim.lsp.buf.code_action, { unpack(opts), desc = "code action" })
vim.keymap.set("n", "gr", vim.lsp.buf.references, { unpack(opts), desc = "references" })
-- conform.nvim should handle formatting
-- vim.keymap.set("n", "<space>f", function()
-- vim.lsp.buf.format({ async = true })
-- end, { unpack(opts), desc = "format" })
end,
})
-- Language Server Configuration END
-- LUALINE
-- https://github.com/nvim-lualine/lualine.nvim
require("lualine").setup({
sections = {
lualine_x = {
-- CAPSLOCK.NVIM
-- https://github.com/barklan/capslock.nvim
{ require("capslock").status_string },
},
},
})
-- CONFORM.NVIM
-- https://github.com/stevearc/conform.nvim
require("conform").setup({
formatters_by_ft = {
lua = { "stylua" },
html = { "htmlbeautifier" },
eruby = { "htmlbeaufifier" },
fish = { "fish_indent" },
json = { "jq" },
sql = { "sql_formatter" },
css = { "prettier" },
less = { "prettier" },
scss = { "prettier" },
},
})
vim.api.nvim_create_user_command("Format", function(args)
local range = nil
if args.count ~= -1 then
local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1]
range = {
start = { args.line1, 0 },
["end"] = { args.line2, end_line:len() },
}
end
require("conform").format({ async = true, lsp_fallback = true, range = range })
end, { range = true })
-- ONEDARK.NVIM
-- https://github.com/navarasu/onedark.nvim
---@diagnostic disable-next-line: missing-parameter
require("onedark").setup()
require("onedark").load()
-- CLIPBOARD-IMAGE.NVIM
-- https://github.com/ekickx/clipboard-image.nvim
--TODO: Figure out how to update the image path used in markdown links. Images are getting copied to /images/<image-name> correctly, but the markdown links reference /img/<image-name>.
require("clipboard-image").setup({
default = {
img_dir = "images",
},
})
-- NEOGEN
-- https://github.com/danymat/neogen
require("neogen").setup({ snippet_engine = "luasnip" })
-- OIL
-- https://github.com/stevearc/oil.nvim
require("oil").setup()
-- ZEN-MODE
-- https://github.com/folke/zen-mode.nvim
require("zen-mode").setup({
plugins = {
tmux = {
enabled = true,
},
},
})
-- NVIM-TS-COMMENTSTRING
-- https://github.com/JoosepAlviste/nvim-ts-context-commentstring
---@diagnostic disable-next-line: missing-parameter
require("ts_context_commentstring").setup()
-- COMMENT.NVIM
-- https://github.com/numToStr/Comment.nvim
require("Comment").setup()
-- NVIM-NOTIFY
-- https://github.com/rcarriga/nvim-notify
---@diagnostic disable-next-line: missing-fields
require("notify").setup({
background_colour = "#000000",
render = "compact",
})
-- TELESCOPE-IMPORT
-- https://github.com/piersolenski/telescope-import.nvim
require("telescope").load_extension("import")
-- TELESCOPE-MEDIA-FILES
-- https://github.com/nvim-telescope/telescope-media-files.nvim
require("telescope").load_extension("media_files")
require("telescope").setup({
extensions = { media_files = { file_types = { "png", "jpg", "jpeg", "mp4", "webm", "pdf" }, find_cmd = "rg" } },
})
-- OVERSEER.NVIM
-- https://github.com/stevearc/overseer.nvim
require("overseer").setup()
-- WHICH-KEY.NVIM
-- https://github.com/folke/which-key.nvim
local wk = require("which-key")
wk.register({
["<leader>"] = {
t = {
"<cmd>Telescope treesitter<cr>",
"Treesitter",
},
i = {
"<cmd>Telescope import<cr>",
"Import",
},
p = {
"<cmd>Format<cr>",
"Pretty",
},
},
})
local d = require("dap")
local duiw = require("dap.ui.widgets")
-- CAPSLOCK.NVIM
-- https://github.com/barklan/capslock.nvim
require("capslock").setup()
-- vim.keymap.set({ "i", "c", "n" }, "<C-g>c", "<Plug>CapsLockToggle")
-- vim.keymap.set("i", "<C-l>", "<Plug>CapsLockToggle", { desc = "toggle caps lock" })
wk.register({
["<leader>d"] = {
name = "Debug",
f = {
function()
duiw.centered_float(duiw.frames)
end,
"Frames",
},
h = {
duiw.hover,
"Hover",
},
p = {
duiw.preview,
"Preview",
},
s = {
function()
duiw.centered_float(duiw.scopes)
end,
"Scopes",
},
n = {
d.set_breakpoint,
"New Breakpoint",
},
t = {
d.toggle_breakpoint,
"Toggle Breakpoint",
},
c = {
d.continue,
"Continue",
},
v = {
d.step_over,
"Step Over",
},
u = {
d.step_out,
"Step Out",
},
r = {
function()
d.repl.open()
end,
"REPL",
},
l = {
d.run_last,
"Run Last",
},
},
})
wk.register({
["<leader>e"] = {
name = "Ex Commands",
c = {
"<cmd>Telescope commands<cr>",
"Ex Commands",
},
h = {
"<cmd>Telescope command_history<cr>",
"Ex Command History",
},
},
})
-- HARPOON
-- https://github.com/ThePrimeagen/harpoon
local hui = require("harpoon.ui")
local hm = require("harpoon.mark")
wk.register({
["<leader>f"] = {
name = "Files",
a = {
"<cmd>Telescope autocommands<cr>",
"Autocommands",
},
b = {
"<cmd>Telescope buffers<cr>",
"Buffer(s)",
},
d = {
"<cmd>:lua require('harpoon.mark').clear_all()<cr>",
"Delete All Harpoons",
},
f = {
"<cmd>Telescope find_files<cr>",
"File(s)",
},
g = {
"<cmd>Telescope git_files<cr>",
"Git-tracked File(s)",
},
i = {
"<cmd>Telescope media_files<cr>",
"Images & Media File(s)",
},
l = {
"<cmd>Telescope resume<cr>",
"Last Search Results",
},
o = {
"<cmd>Oil<cr>",
"Oil",
},
r = {
"<cmd>Telescope oldfiles<cr>",
"Recent File(s)",
},
t = {
"<cmd>Telescope tags<cr>",
"Tag",
},
c = { "<cmd>ene<cr>", "Create File" },
m = { "<cmd>Telescope marks<cr>", "Marks" },
q = { "<cmd>Telescope quickfix<cr>", "Quickfix" },
h = { "<cmd>Telescope quickfix_history<cr>", "Quickfix History" },
x = { hm.add_file, "Harpoon" },
s = { hui.toggle_quick_menu, "Switch Harpoon" },
p = { hui.nav_prev, "Previous Harpoon" },
n = { hui.nav_next, "Next Harpoon" },
},
})
wk.register({
["<leader>g"] = {
name = "Git",
b = {
"<cmd>Telescope git_branches<cr>",
"Branches",
},
--TODO: Come back to this one
-- b = {
-- "<cmd>Telescope git_bcommits<cr>",
-- "Buffer Commits",
-- },
c = {
"<cmd>Telescope git_commits<cr>",
"Commits",
},
r = {
"<cmd>Telescope git_bcommits_range<cr>",
"Range Buffer Commits",
},
s = {
"<cmd>Telescope git_status<cr>",
"Status",
},
w = {
"<cmd>Telescope git_stash<cr>",
"Work (Stashed)",
},
},
})
wk.register({
["<leader>h"] = {
name = "Help",
h = {
"<cmd>Telescope help_tags<cr>",
"Help Tags",
},
o = {
"<cmd>Telescope vim_options<cr>",
"Vim Options",
},
s = {
"<cmd>Telescope spell_suggest<cr>",
"Open Recent File",
},
m = {
"<cmd>Telescope man_pages<cr>",
"Man Pages",
},
},
})
wk.register({
["<leader>j"] = {
name = "Jump",
d = {
":cd %:p:h<cr>",
"Directory",
},
},
})
wk.register({
["<leader>l"] = {
name = "LSP",
a = {
-- code actions
},
b = {
"<cmd>LspRestart<cr>",
"Reboot LSP",
},
c = {
-- change name
},
d = {
"<cmd>Telescope diagnostics<cr>",
"Diagnostics",
},
D = {
-- definition
},
h = {
-- hover
},
i = {
"<cmd>Telescope lsp_implementations<cr>",
"Implementations",
},
o = {
vim.diagnostic.open_float,
"Open Float",
},
l = { vim.diagnostic.setloclist, "Set Location List" },
r = {
"<cmd>Telescope lsp_references<cr>",
"References",
},
R = {
-- references
},
t = {
"<cmd>Telescope lsp_type_definitions<cr>",
"Type Definitions",
},
p = {
vim.diagnostic.goto_prev,
"Go-To Prev Diagnostic",
},
n = {
vim.diagnostic.goto_next,
"Go-To Next Diagnostic",
},
s = {
-- signature_help
},
},
})
-- MARKDOWN-PREVIEW.NVIM
-- https://github.com/iamcco/markdown-preview.nvim
wk.register({
["<leader>m"] = {
name = "Markdown",
p = {
"<cmd>MarkdownPreview<cr>",
"Markdown Preview",
},
},
})
wk.register({
["<leader>r"] = {
name = "Request",
s = {
"<Plug>RestNvim",
"Send Request",
},
p = {
"<Plug>RestNvimPreview",
"Preview Request",
},
r = {
"<Plug>RestNvimLast",
"Repeat Last Request",
},
},
})
wk.register({
["<leader>q"] = {
name = "Query",
l = {
"<cmd>Telescope live_grep<cr>",
"Live Search",
},
h = {
"<cmd>Telescope search_history<cr>",
"Search History",
},
},
})
wk.register({
["<leader>t"] = {
name = "Test",
b = {
':lua require("neotest").run.run(vim.fn.expand("%"))<CR>',
"Buffer",
},
s = {
':lua require("neotest").run.run(vim.fn.getcwd())<CR>',
"Suite",
},
f = {
':lua require("neotest").run.run()<CR>',
"Function",
},
},
})
wk.register({
["<leader>S"] = {
name = "Snippets",
-- NEOGEN
-- https://github.com/danymat/neogen
--TODO: More plugin-agnostic name possible here?
n = {
":lua require('neogen').generate()<CR>",
"Neogen",
},
l = { '<Cmd>lua require("luasnip.loaders.from_lua").load({paths = "./luasnippets/"})<CR>', "Load" },
},
}, { silent = true })
wk.register({
["<leader>w"] = {
name = "Workspace",
a = {
-- workspace add
},
r = {
-- workspace remove
},
l = {
-- workspace list
},
},
})
-- NEOTEST-RSPEC
-- https://github.com/olimorris/neotest-rspec
--TODO: Figure out how to run ahoy rspec when running tests from work comp, but use default command when running tests from home comp.
-- require("neotest-rspec")({
-- rspec_cmd = function()
-- return vim.tbl_flatten({ "ahoy", "rspec" })
-- end
-- })
require("neotest").setup({
adapters = {
require("neotest-rspec"),
require("neotest-jest")({
jestCommand = "yarn test",
jestConfigFile = "jest.config.js",
cwd = function()
return vim.fn.getcwd()
end,
}),
},
})
-- TELESCOPE-FZF-NATIVE
-- https://github.com/nvim-telescope/telescope-fzf-native.nvim
---@diagnostic disable-next-line: missing-parameter
require("telescope").setup({
extensions = {
import = {
insert_at_top = true,
},
},
})
require("telescope").load_extension("fzf")
-- INDENT-BLANKLINE.NVIM
-- https://github.com/lukas-reineke/indent-blankline.nvim
require("ibl").setup()
-- NEORG
-- https://github.com/nvim-neorg/neorg
require("neorg").setup({
load = {
["core.defaults"] = {}, -- Loads default behaviour
["core.concealer"] = {}, -- Adds pretty icons to your documents
["core.dirman"] = { -- Manages Neorg workspaces
config = {
workspaces = {
work = "~/projects/work_notes",
home = "~/projects/home_notes",
},
},
},
},
})
-- GENERAL
local set = vim.opt
set.smartindent = true
set.autoindent = true
set.expandtab = true
set.tabstop = 2
set.shiftwidth = 2
set.softtabstop = 2
set.ignorecase = true
set.smartcase = true
set.number = true
set.hlsearch = false
set.wildignore = "node_modules/*"
set.number = true
vim.cmd([[autocmd FileType * set formatoptions-=ro]])
set.syntax = "on"
-- do not open folds when searching for text
vim.cmd([[set foldopen-=search]])
To Reproduce
Steps to reproduce the behavior:
- Install
neovimusingbrew(brew install neovim) - Edit a Typescript file with
neovim(nvim <a typescript file>) - Find a function call or a function declaration with multiple arguments/parameters
- Navigate to an argument or parameter
- Type
<space>aor<space>Ato see if the arguments/parameters get swapped - See that you are just placed into insert mode
Expected behavior
A clear and concise description of what you expected to happen.
Output of :checkhealth nvim-treesitter
==============================================================================
nvim-treesitter: require("nvim-treesitter.health").check()
Installation ~
- OK
tree-sitter found 0.20.8 (parser generator, only needed for :TSInstallFromGrammar)
- OK
node found v20.5.0 (only needed for :TSInstallFromGrammar)
- OK
git executable found.
- OK
cc executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
Version: Apple clang version 15.0.0 (clang-1500.1.0.2.5)
- OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.
OS Info:
{
machine = "arm64",
release = "23.2.0",
sysname = "Darwin",
version = "Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000"
} ~
Parser/Features H L F I J
- bash ✓ ✓ ✓ . ✓
- c ✓ ✓ ✓ ✓ ✓
- css ✓ . ✓ ✓ ✓
- dockerfile ✓ . . . ✓
- fish ✓ ✓ ✓ ✓ ✓
- html ✓ ✓ ✓ ✓ ✓
- http ✓ . . . ✓
- javascript ✓ ✓ ✓ ✓ ✓
- jq ✓ ✓ . . ✓
- json ✓ ✓ ✓ ✓ .
- lua ✓ ✓ ✓ ✓ ✓
- markdown ✓ . ✓ ✓ ✓
- markdown_inline ✓ . . . ✓
- norg ✓ . ✓ . ✓
- norg_meta ✓ . . ✓ .
- python ✓ ✓ ✓ ✓ ✓
- query ✓ ✓ ✓ ✓ ✓
- ruby ✓ ✓ ✓ ✓ ✓
- scss ✓ . ✓ ✓ .
- sql ✓ . . ✓ ✓
- toml ✓ ✓ ✓ ✓ ✓
- tsx ✓ ✓ ✓ ✓ ✓
- typescript ✓ ✓ ✓ ✓ ✓
- vim ✓ ✓ ✓ . ✓
- vimdoc ✓ . . . ✓
- yaml ✓ ✓ ✓ ✓ ✓
Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
+) multiple parsers found, only one will be used
x) errors found in the query, try to run :TSUpdate {lang} ~
Output of nvim --version
NVIM v0.9.5
Build type: Release
LuaJIT 2.1.1703358377
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/opt/homebrew/Cellar/neovim/0.9.5/share/nvim"
Run :checkhealth for more info
Additional context
Other keybinds, like ip work as expected, so I know that the @parameter.inner query is working as expected on these files, it just appears that the swapping functionality specifically doesn't run for these text objects for some reason.
- Navigating to a function parameter:
- After pressing
<space>ato swap the parameter with the next parameter (sent into insert mode):
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the keybinding behavior using the configuration in nvim/lua/plugins/init.lua and nvim/init.lua, especially in TypeScript, JavaScript, and Ruby buffers. Trace which mappings handle a and A, then verify that they invoke swapping rather than the normal append commands; no test file is mentioned, so completion requires a reliable reproduction check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, lua, ruby, typescript
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100