summaryrefslogtreecommitdiff
path: root/config/nvim/lua/plugins/editing.lua
blob: af7a867d2d7713ac46172a566eb79403a03b5b84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
local plugins = {
    { "godlygeek/tabular" }, -- text filtering and alignment
    {
        "Wansmer/treesj",    -- splitting/joining blocks of code
        dependencies = { "nvim-treesitter/nvim-treesitter" },
        config = function()
            require("treesj").setup({
                -- use_default_keymaps = false,
            })
            vim.keymap.set("n", "<leader>jj", require("treesj").join)
            vim.keymap.set("n", "<leader>js", require("treesj").split)
            vim.keymap.set("n", "<leader>jm", require("treesj").toggle)
            vim.keymap.set("n", "<leader>jM", function()
                require("treesj").toggle({ split = { recursive = true } })
            end)
        end,
    },
    { "tpope/vim-repeat" }, -- enable plugins to repeat actions
    { "tpope/vim-sleuth" }, -- heuristically set buffer options
    -- Add/delete/replace surrounding pairs: sa (add), sd (delete), sr (replace).
    -- Replaces tpope/vim-surround; consolidates onto mini.* with built-in
    -- dot-repeat. NOTE: the `s` prefix shadows native `s` (substitute) — use `cl`.
    {
        "nvim-mini/mini.surround",
        event = "VeryLazy",
        opts = {},
    },
    -- Auto close/rename HTML/JSX/TSX/Astro tags
    {
        "windwp/nvim-ts-autotag",
        ft = {
            "html", "xml", "markdown", "svelte", "vue",
            "javascript", "javascriptreact", "typescript", "typescriptreact", "astro",
        },
        opts = {},
    },
    -- Context-aware commentstring (e.g. {/* */} inside JSX, not //)
    {
        "folke/ts-comments.nvim",
        event = "VeryLazy",
        opts = {},
    },
    -- Extended text objects: af/if (function), ac/ic (class),
    -- ao/io (block/conditional/loop), plus args/quotes/brackets.
    -- Takes over the old fold if/af mappings.
    {
        "nvim-mini/mini.ai",
        event = "VeryLazy",
        dependencies = {
            "nvim-treesitter/nvim-treesitter-textobjects",
        },
        opts = function()
            local ai = require("mini.ai")
            return {
                n_lines = 500,
                custom_textobjects = {
                    f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }),
                    c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }),
                    o = ai.gen_spec.treesitter({
                        a = { "@block.outer", "@conditional.outer", "@loop.outer" },
                        i = { "@block.inner", "@conditional.inner", "@loop.inner" },
                    }),
                },
            }
        end,
    },
    -- Treesitter textobjects (main): move between and swap functions/classes/args,
    -- and make ; , (and f F t T) repeat the last move.
    {
        "nvim-treesitter/nvim-treesitter-textobjects",
        branch = "main",
        event = "VeryLazy",
        config = function()
            require("nvim-treesitter-textobjects").setup({
                move = { set_jumps = true }, -- record moves in the jumplist
            })

            local move = require("nvim-treesitter-textobjects.move")
            local swap = require("nvim-treesitter-textobjects.swap")
            local rep = require("nvim-treesitter-textobjects.repeatable_move")

            -- Repeat the last textobject move with ; and , ...
            vim.keymap.set({ "n", "x", "o" }, ";", rep.repeat_last_move)
            vim.keymap.set({ "n", "x", "o" }, ",", rep.repeat_last_move_opposite)
            -- ... and upgrade f/F/t/T to repeat with the same ; ,
            vim.keymap.set({ "n", "x", "o" }, "f", rep.builtin_f_expr, { expr = true })
            vim.keymap.set({ "n", "x", "o" }, "F", rep.builtin_F_expr, { expr = true })
            vim.keymap.set({ "n", "x", "o" }, "t", rep.builtin_t_expr, { expr = true })
            vim.keymap.set({ "n", "x", "o" }, "T", rep.builtin_T_expr, { expr = true })

            -- Jump between functions / classes ( ]] [[ are taken by quickfix ).
            -- Note: ]c / [c shadow diff-mode change navigation; swap to ]C/[C if
            -- you'd rather keep that.
            local jumps = {
                ["]f"] = { move.goto_next_start, "@function.outer", "Next function start" },
                ["[f"] = { move.goto_previous_start, "@function.outer", "Prev function start" },
                ["]F"] = { move.goto_next_end, "@function.outer", "Next function end" },
                ["[F"] = { move.goto_previous_end, "@function.outer", "Prev function end" },
                ["]c"] = { move.goto_next_start, "@class.outer", "Next class start" },
                ["[c"] = { move.goto_previous_start, "@class.outer", "Prev class start" },
            }
            for lhs, m in pairs(jumps) do
                vim.keymap.set({ "n", "x", "o" }, lhs, function()
                    m[1](m[2], "textobjects")
                end, { desc = m[3] })
            end

            -- Swap the argument under the cursor with the next / previous one
            vim.keymap.set("n", "<leader>sa", function()
                swap.swap_next("@parameter.inner")
            end, { desc = "Swap argument with next" })
            vim.keymap.set("n", "<leader>sA", function()
                swap.swap_previous("@parameter.inner")
            end, { desc = "Swap argument with previous" })
        end,
    },
    -- Comment.nvim and nvim-ts-context-commentstring removed
    -- Neovim 0.10+ has built-in gc/gcc commenting with native treesitter commentstring support
}

for _, plugin in ipairs(plugins) do
    if not plugin.priority then
        plugin.priority = 2000
    end
end

return plugins