From 307fceea38b7352a79b0bdb87025a34b76973867 Mon Sep 17 00:00:00 2001 From: TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:34:13 +0900 Subject: updates --- ar/.config/TheSiahxyz/ftplugin/markdown.lua | 10 +- ar/.config/TheSiahxyz/init.lua | 2 +- .../TheSiahxyz/lua/TheSiahxyz/core/autocmds.lua | 391 +++++++ .../TheSiahxyz/lua/TheSiahxyz/core/keymaps.lua | 809 ++++++++++++++ ar/.config/TheSiahxyz/lua/TheSiahxyz/core/lazy.lua | 39 + .../TheSiahxyz/lua/TheSiahxyz/core/options.lua | 47 + ar/.config/TheSiahxyz/lua/TheSiahxyz/health.lua | 45 + ar/.config/TheSiahxyz/lua/TheSiahxyz/init.lua | 15 + .../TheSiahxyz/lua/TheSiahxyz/plugins/ai.lua | 286 +++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/cloak.lua | 42 + .../TheSiahxyz/lua/TheSiahxyz/plugins/cmp.lua | 331 ++++++ .../lua/TheSiahxyz/plugins/colorizer.lua | 76 ++ .../lua/TheSiahxyz/plugins/colorschemes.lua | 350 ++++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/comment.lua | 8 + .../TheSiahxyz/lua/TheSiahxyz/plugins/compiler.lua | 53 + .../TheSiahxyz/lua/TheSiahxyz/plugins/context.lua | 25 + .../TheSiahxyz/lua/TheSiahxyz/plugins/csv.lua | 55 + .../TheSiahxyz/lua/TheSiahxyz/plugins/dadbod.lua | 53 + .../TheSiahxyz/lua/TheSiahxyz/plugins/dap.lua | 310 ++++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/docker.lua | 222 ++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/git.lua | 215 ++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/goyo.lua | 39 + .../TheSiahxyz/lua/TheSiahxyz/plugins/grug-far.lua | 31 + .../TheSiahxyz/lua/TheSiahxyz/plugins/harpoon2.lua | 110 ++ .../TheSiahxyz/lua/TheSiahxyz/plugins/image.lua | 210 ++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/init.lua | 83 ++ .../TheSiahxyz/lua/TheSiahxyz/plugins/keys.lua | 114 ++ .../TheSiahxyz/lua/TheSiahxyz/plugins/lf.lua | 121 ++ .../TheSiahxyz/lua/TheSiahxyz/plugins/lsp.lua | 674 ++++++++++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/lualine.lua | 273 +++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/macro.lua | 172 +++ .../TheSiahxyz/lua/TheSiahxyz/plugins/markdown.lua | 551 ++++++++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/marks.lua | 16 + .../TheSiahxyz/lua/TheSiahxyz/plugins/mini.lua | 1162 ++++++++++++++++++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/navic.lua | 52 + .../TheSiahxyz/lua/TheSiahxyz/plugins/neo-tree.lua | 141 +++ .../TheSiahxyz/lua/TheSiahxyz/plugins/obsidian.lua | 616 +++++++++++ .../TheSiahxyz/lua/TheSiahxyz/plugins/outline.lua | 11 + .../TheSiahxyz/lua/TheSiahxyz/plugins/project.lua | 12 + .../TheSiahxyz/lua/TheSiahxyz/plugins/python.lua | 55 + .../TheSiahxyz/lua/TheSiahxyz/plugins/quickfix.lua | 76 ++ .../lua/TheSiahxyz/plugins/refactoring.lua | 78 ++ .../TheSiahxyz/lua/TheSiahxyz/plugins/sessions.lua | 60 + .../TheSiahxyz/lua/TheSiahxyz/plugins/silicon.lua | 145 +++ .../TheSiahxyz/lua/TheSiahxyz/plugins/snippets.lua | 72 ++ .../lua/TheSiahxyz/plugins/stay-centered.lua | 28 + .../TheSiahxyz/lua/TheSiahxyz/plugins/surround.lua | 14 + .../lua/TheSiahxyz/plugins/telescope.lua | 1084 ++++++++++++++++++ .../lua/TheSiahxyz/plugins/textobject.lua | 140 +++ .../TheSiahxyz/lua/TheSiahxyz/plugins/todo.lua | 77 ++ .../lua/TheSiahxyz/plugins/treesitter.lua | 62 ++ .../TheSiahxyz/lua/TheSiahxyz/plugins/urlview.lua | 149 +++ .../lua/TheSiahxyz/plugins/virt-column.lua | 17 + .../TheSiahxyz/lua/TheSiahxyz/plugins/wiki.lua | 172 +++ .../TheSiahxyz/lua/TheSiahxyz/plugins/zenmode.lua | 46 + .../lua/TheSiahxyz/snippets/markdown.lua | 187 ++++ .../lua/TheSiahxyz/snippets/neetcode1.lua | 103 ++ .../lua/TheSiahxyz/snippets/neetcode2.lua | 104 ++ .../TheSiahxyz/lua/TheSiahxyz/snippets/quarto.lua | 28 + .../lua/TheSiahxyz/snippets/whichkey.lua | 18 + .../TheSiahxyz/lua/TheSiahxyz/utils/cheatsheet.lua | 13 + .../lua/TheSiahxyz/utils/cheatsheet/grid.lua | 105 ++ .../lua/TheSiahxyz/utils/cheatsheet/init.lua | 116 ++ .../TheSiahxyz/lua/TheSiahxyz/utils/icons.lua | 168 +++ .../TheSiahxyz/lua/TheSiahxyz/utils/markdown.lua | 26 + .../TheSiahxyz/lua/TheSiahxyz/utils/snippet.lua | 38 + .../TheSiahxyz/lua/TheSiahxyz/utils/tasks.lua | 227 ++++ .../TheSiahxyz/lua/TheSiahxyz/utils/tmux.lua | 63 ++ .../TheSiahxyz/lua/TheSiahxyz/utils/utils.lua | 112 ++ .../TheSiahxyz/lua/thesiahxyz/core/autocmds.lua | 391 ------- .../TheSiahxyz/lua/thesiahxyz/core/keymaps.lua | 809 -------------- ar/.config/TheSiahxyz/lua/thesiahxyz/core/lazy.lua | 39 - .../TheSiahxyz/lua/thesiahxyz/core/options.lua | 47 - ar/.config/TheSiahxyz/lua/thesiahxyz/health.lua | 45 - ar/.config/TheSiahxyz/lua/thesiahxyz/init.lua | 15 - .../TheSiahxyz/lua/thesiahxyz/plugins/ai.lua | 286 ----- .../TheSiahxyz/lua/thesiahxyz/plugins/cloak.lua | 42 - .../TheSiahxyz/lua/thesiahxyz/plugins/cmp.lua | 331 ------ .../lua/thesiahxyz/plugins/colorizer.lua | 76 -- .../lua/thesiahxyz/plugins/colorschemes.lua | 350 ------ .../TheSiahxyz/lua/thesiahxyz/plugins/comment.lua | 8 - .../TheSiahxyz/lua/thesiahxyz/plugins/compiler.lua | 53 - .../TheSiahxyz/lua/thesiahxyz/plugins/context.lua | 25 - .../TheSiahxyz/lua/thesiahxyz/plugins/csv.lua | 55 - .../TheSiahxyz/lua/thesiahxyz/plugins/dadbod.lua | 53 - .../TheSiahxyz/lua/thesiahxyz/plugins/dap.lua | 310 ------ .../TheSiahxyz/lua/thesiahxyz/plugins/docker.lua | 222 ---- .../TheSiahxyz/lua/thesiahxyz/plugins/git.lua | 215 ---- .../TheSiahxyz/lua/thesiahxyz/plugins/goyo.lua | 39 - .../TheSiahxyz/lua/thesiahxyz/plugins/grug-far.lua | 31 - .../TheSiahxyz/lua/thesiahxyz/plugins/harpoon2.lua | 110 -- .../TheSiahxyz/lua/thesiahxyz/plugins/image.lua | 210 ---- .../TheSiahxyz/lua/thesiahxyz/plugins/init.lua | 83 -- .../TheSiahxyz/lua/thesiahxyz/plugins/keys.lua | 114 -- .../TheSiahxyz/lua/thesiahxyz/plugins/lf.lua | 121 -- .../TheSiahxyz/lua/thesiahxyz/plugins/lsp.lua | 674 ------------ .../TheSiahxyz/lua/thesiahxyz/plugins/lualine.lua | 273 ----- .../TheSiahxyz/lua/thesiahxyz/plugins/macro.lua | 172 --- .../TheSiahxyz/lua/thesiahxyz/plugins/markdown.lua | 551 ---------- .../TheSiahxyz/lua/thesiahxyz/plugins/marks.lua | 16 - .../TheSiahxyz/lua/thesiahxyz/plugins/mini.lua | 1162 -------------------- .../TheSiahxyz/lua/thesiahxyz/plugins/navic.lua | 52 - .../TheSiahxyz/lua/thesiahxyz/plugins/neo-tree.lua | 141 --- .../TheSiahxyz/lua/thesiahxyz/plugins/obsidian.lua | 616 ----------- .../TheSiahxyz/lua/thesiahxyz/plugins/outline.lua | 11 - .../TheSiahxyz/lua/thesiahxyz/plugins/project.lua | 12 - .../TheSiahxyz/lua/thesiahxyz/plugins/python.lua | 55 - .../TheSiahxyz/lua/thesiahxyz/plugins/quickfix.lua | 76 -- .../lua/thesiahxyz/plugins/refactoring.lua | 78 -- .../TheSiahxyz/lua/thesiahxyz/plugins/sessions.lua | 60 - .../TheSiahxyz/lua/thesiahxyz/plugins/silicon.lua | 145 --- .../TheSiahxyz/lua/thesiahxyz/plugins/snippets.lua | 72 -- .../lua/thesiahxyz/plugins/stay-centered.lua | 28 - .../TheSiahxyz/lua/thesiahxyz/plugins/surround.lua | 14 - .../lua/thesiahxyz/plugins/telescope.lua | 1084 ------------------ .../lua/thesiahxyz/plugins/textobject.lua | 140 --- .../TheSiahxyz/lua/thesiahxyz/plugins/todo.lua | 77 -- .../lua/thesiahxyz/plugins/treesitter.lua | 62 -- .../TheSiahxyz/lua/thesiahxyz/plugins/urlview.lua | 149 --- .../lua/thesiahxyz/plugins/virt-column.lua | 17 - .../TheSiahxyz/lua/thesiahxyz/plugins/wiki.lua | 172 --- .../TheSiahxyz/lua/thesiahxyz/plugins/zenmode.lua | 46 - .../lua/thesiahxyz/snippets/markdown.lua | 187 ---- .../lua/thesiahxyz/snippets/neetcode1.lua | 103 -- .../lua/thesiahxyz/snippets/neetcode2.lua | 104 -- .../TheSiahxyz/lua/thesiahxyz/snippets/quarto.lua | 28 - .../lua/thesiahxyz/snippets/whichkey.lua | 18 - .../TheSiahxyz/lua/thesiahxyz/utils/cheatsheet.lua | 13 - .../lua/thesiahxyz/utils/cheatsheet/grid.lua | 105 -- .../lua/thesiahxyz/utils/cheatsheet/init.lua | 116 -- .../TheSiahxyz/lua/thesiahxyz/utils/icons.lua | 168 --- .../TheSiahxyz/lua/thesiahxyz/utils/markdown.lua | 26 - .../TheSiahxyz/lua/thesiahxyz/utils/snippet.lua | 38 - .../TheSiahxyz/lua/thesiahxyz/utils/tasks.lua | 227 ---- .../TheSiahxyz/lua/thesiahxyz/utils/tmux.lua | 63 -- .../TheSiahxyz/lua/thesiahxyz/utils/utils.lua | 112 -- ar/.config/TheSiahxyz/shortcuts.lua | 432 ++++++++ ar/.config/shell/bm-dirs | 4 +- 138 files changed, 11783 insertions(+), 11351 deletions(-) create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/core/autocmds.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/core/keymaps.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/core/lazy.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/core/options.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/health.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/init.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/ai.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cloak.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cmp.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorizer.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorschemes.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/comment.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/compiler.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/context.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/csv.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dadbod.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dap.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/docker.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/git.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/goyo.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/grug-far.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/harpoon2.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/image.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/init.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/keys.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lf.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lsp.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lualine.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/macro.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/markdown.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/marks.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/mini.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/navic.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/neo-tree.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/obsidian.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/outline.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/project.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/python.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/quickfix.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/refactoring.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/sessions.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/silicon.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/snippets.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/stay-centered.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/surround.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/telescope.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/textobject.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/todo.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/treesitter.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/urlview.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/virt-column.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/wiki.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/zenmode.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/snippets/markdown.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/snippets/neetcode1.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/snippets/neetcode2.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/snippets/quarto.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/snippets/whichkey.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/cheatsheet.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/cheatsheet/grid.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/cheatsheet/init.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/icons.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/markdown.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/snippet.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/tasks.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/tmux.lua create mode 100644 ar/.config/TheSiahxyz/lua/TheSiahxyz/utils/utils.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/core/autocmds.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/core/keymaps.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/core/lazy.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/core/options.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/health.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/init.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/ai.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/cloak.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/cmp.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/colorizer.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/colorschemes.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/comment.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/compiler.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/context.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/csv.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/dadbod.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/dap.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/docker.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/git.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/goyo.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/grug-far.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/harpoon2.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/image.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/init.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/keys.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/lf.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/lsp.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/lualine.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/macro.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/markdown.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/marks.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/mini.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/navic.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/neo-tree.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/obsidian.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/outline.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/project.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/python.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/quickfix.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/refactoring.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/sessions.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/silicon.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/snippets.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/stay-centered.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/surround.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/telescope.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/textobject.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/todo.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/treesitter.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/urlview.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/virt-column.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/wiki.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/plugins/zenmode.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/snippets/markdown.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/snippets/neetcode1.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/snippets/neetcode2.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/snippets/quarto.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/snippets/whichkey.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/cheatsheet.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/cheatsheet/grid.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/cheatsheet/init.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/icons.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/markdown.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/snippet.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/tasks.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/tmux.lua delete mode 100644 ar/.config/TheSiahxyz/lua/thesiahxyz/utils/utils.lua create mode 100644 ar/.config/TheSiahxyz/shortcuts.lua (limited to 'ar') diff --git a/ar/.config/TheSiahxyz/ftplugin/markdown.lua b/ar/.config/TheSiahxyz/ftplugin/markdown.lua index 439e2a6..e27cd21 100644 --- a/ar/.config/TheSiahxyz/ftplugin/markdown.lua +++ b/ar/.config/TheSiahxyz/ftplugin/markdown.lua @@ -55,11 +55,11 @@ local function set_foldmethod_expr() -- doesn't have them set if vim.fn.has("nvim-0.10") == 1 then vim.opt.foldmethod = "expr" - vim.wo.foldexpr = "v:lua.require'thesiahxyz.utils.markdown'.foldexpr()" + vim.wo.foldexpr = "v:lua.require'TheSiahxyz.utils.markdown'.foldexpr()" vim.opt.foldtext = "" else vim.opt.foldmethod = "indent" - vim.wo.foldtext = "v:lua.require'thesiahxyz.utils.markdown'.foldexpr()" + vim.wo.foldtext = "v:lua.require'TheSiahxyz.utils.markdown'.foldexpr()" end vim.opt.foldlevel = 99 end @@ -251,7 +251,7 @@ vim.api.nvim_create_autocmd("FileType", { end, }) --- This setting makes markdown auto-set the 80 text width limit when typing +-- this setting makes markdown auto-set the 80 text width limit when typing -- vim.cmd('set fo+=a') if is_in_obsidian_repo() then vim.bo.textwidth = 175 -- No limit for Obsidian repository @@ -436,13 +436,13 @@ end, { desc = "Fold all headings level 4 or above" }) vim.keymap.set( { "o", "x" }, "il", - "lua require('various-textobjs').mdlink('inner')", + "lua require('various-textobjs').mdlink('inner')", { buffer = true, desc = "Link" } ) vim.keymap.set( { "o", "x" }, "al", - "lua require('various-textobjs').mdlink('outer')", + "lua require('various-textobjs').mdlink('outer')", { buffer = true, desc = "Link" } ) diff --git a/ar/.config/TheSiahxyz/init.lua b/ar/.config/TheSiahxyz/init.lua index caa926e..c459a26 100644 --- a/ar/.config/TheSiahxyz/init.lua +++ b/ar/.config/TheSiahxyz/init.lua @@ -1 +1 @@ -require("thesiahxyz") +require("TheSiahxyz") diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/autocmds.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/autocmds.lua new file mode 100644 index 0000000..2fbff6c --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/autocmds.lua @@ -0,0 +1,391 @@ +local function augroup(name) + return vim.api.nvim_create_augroup("TheSiahxyz_" .. name, { clear = true }) +end + +local autocmd = vim.api.nvim_create_autocmd + +-- Change the color of symlink files to distinguish between directory and symlink files +autocmd("FileType", { + group = augroup("highlight_linked_files"), + pattern = "netrw", + callback = function() + vim.cmd("highlight NetrwSymlink guifg=#689D6A ctermfg=214") + end, +}) + +-- Check if we need to reload the file when it changed +autocmd({ "FocusGained", "TermClose", "TermLeave" }, { + group = augroup("check_time"), + callback = function() + if vim.o.buftype ~= "nofile" then + vim.cmd("checktime") + end + end, +}) + +-- Highlight on yank +autocmd("TextYankPost", { + group = augroup("highlight_yank"), + callback = function() + vim.highlight.on_yank() + end, +}) + +-- Resize splits if window got resized +autocmd({ "VimResized" }, { + group = augroup("window_config"), + callback = function() + local current_tab = vim.fn.tabpagenr() + vim.cmd("tabdo wincmd =") + vim.cmd("tabnext " .. current_tab) + end, +}) + +-- Go to last loc when opening a buffer +autocmd("BufReadPost", { + group = augroup("last_loc"), + callback = function(event) + local exclude = { "gitcommit" } + local buf = event.buf + if vim.tbl_contains(exclude, vim.bo[buf].filetype) or vim.b[buf].TheSiahxyz_last_loc then + return + end + vim.b[buf].TheSiahxyz_last_loc = true + local mark = vim.api.nvim_buf_get_mark(buf, '"') + local lcount = vim.api.nvim_buf_line_count(buf) + if mark[1] > 0 and mark[1] <= lcount then + pcall(vim.api.nvim_win_set_cursor, 0, mark) + end + end, +}) + +-- Close some filetypes with +autocmd("FileType", { + group = augroup("close_with_q"), + pattern = { + "checkhealth", + "dbout", + "gitsigns-blame", + "grug-far", + "help", + "lspinfo", + "Lazy", + "neotest-output", + "neotest-output-panel", + "neotest-summary", + "notify", + "PlenaryTestPopup", + "qf", + "query", + "spectre_panel", + "startuptime", + "terminal", + "tsplayground", + }, + callback = function(event) + vim.bo[event.buf].buflisted = false + vim.keymap.set("n", "q", "close", { buffer = event.buf, silent = true }) + end, +}) +autocmd("FileType", { + group = augroup("q_as_bd"), + pattern = "netrw", + callback = function(event) + vim.bo[event.buf].buflisted = false + vim.keymap.set("n", "q", function() + vim.cmd("bd") + end, { buffer = event.buf, silent = true }) + end, +}) + +-- Make it easier to close man-files when opened inline +autocmd("FileType", { + group = augroup("man_close"), + pattern = { "man" }, + callback = function(event) + vim.bo[event.buf].buflisted = false + end, +}) + +-- Fix conceallevel for json files +autocmd({ "FileType" }, { + group = augroup("json_config"), + pattern = { "json", "jsonc", "json5" }, + callback = function() + vim.opt_local.conceallevel = 0 + end, +}) + +-- Auto create dir when saving a file, in case some intermediate directory does not exist +autocmd({ "BufWritePre" }, { + group = augroup("create_dir"), + callback = function(event) + if event.match:match("^%w%w+:[\\/][\\/]") then + return + end + local file = vim.uv.fs_realpath(event.match) or event.match + vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p") + end, +}) + +-- Automatically delete all trailing whitespace and newlines at end of file on save +local file_save = augroup("file_save") +autocmd("BufWritePre", { + group = file_save, + pattern = "*", + callback = function() + local cursor_pos = vim.api.nvim_win_get_cursor(0) + vim.cmd([[ %s/\s\+$//e ]]) -- Remove trailing spaces + vim.cmd([[ %s/\n\+\%$//e ]]) -- Remove trailing newlines + local line_count = vim.api.nvim_buf_line_count(0) + local line = math.min(cursor_pos[1], line_count) + local col = cursor_pos[2] + -- Optional: clamp column if line got shorter + local line_text = vim.api.nvim_buf_get_lines(0, line - 1, line, false)[1] or "" + col = math.min(col, #line_text) + vim.api.nvim_win_set_cursor(0, { line, col }) + end, +}) + +-- Add a trailing newline for C files +autocmd("BufWritePre", { + group = file_save, + pattern = "*.[ch]", + callback = function() + vim.cmd([[ %s/\%$/\r/e ]]) + end, +}) + +-- Go to insert mode in terminal +local win_enter = augroup("win_enter") +autocmd("WinEnter", { + group = win_enter, + callback = function() + if vim.bo.buftype == "terminal" then + vim.cmd("startinsert") + end + end, +}) + +-- Correct email signature delimiter in neomutt files +autocmd("BufWritePre", { + group = file_save, + pattern = "*neomutt*", + callback = function() + vim.cmd([[ %s/^--$/-- /e ]]) + end, +}) + +local function organize_imports() + local params = { + command = "pyright.organizeimports", + arguments = { vim.uri_from_bufnr(0) }, + } + vim.lsp.buf.execute_command(params) +end + +autocmd("LspAttach", { + group = augroup("lsp_attach"), + callback = function(e) + local client = vim.lsp.get_client_by_id(e.data.client_id) + if client and client.name == "pyright" then + vim.api.nvim_create_user_command( + "PyrightOrganizeImports", + organize_imports, + { desc = "Organize imports (lsp)" } + ) + end + vim.keymap.set("n", "gD", function() + vim.lsp.buf.definition() + end, { buffer = e.buf, desc = "Go to definition (lsp)" }) + vim.keymap.set("n", "K", function() + vim.lsp.buf.hover() + end, { buffer = e.buf, desc = "Go to keywords (lsp)" }) + vim.keymap.set("n", "ls", function() + vim.lsp.buf.workspace_symbol() + end, { buffer = e.buf, desc = "Workspace symbol (lsp)" }) + vim.keymap.set("n", "lo", function() + vim.diagnostic.open_float() + end, { buffer = e.buf, desc = "Open diagnostic" }) + vim.keymap.set("n", "lc", function() + vim.lsp.buf.code_action() + end, { buffer = e.buf, desc = "Code action (lsp)" }) + vim.keymap.set("n", "lr", function() + vim.lsp.buf.references() + end, { buffer = e.buf, desc = "References (lsp)" }) + vim.keymap.set("n", "ln", function() + vim.lsp.buf.rename() + end, { buffer = e.buf, desc = "Rename (lsp)" }) + vim.keymap.set("n", "lh", function() + vim.lsp.buf.signature_help() + end, { buffer = e.buf, desc = "Signature help (lsp)" }) + vim.keymap.set("n", "]d", function() + vim.diagnostic.goto_next() + end, { buffer = e.buf, desc = "Next diagnostic" }) + vim.keymap.set("n", "[d", function() + vim.diagnostic.goto_prev() + end, { buffer = e.buf, desc = "Previous diagnostic" }) + end, +}) + +-- Save file as sudo on files that require root permission +vim.api.nvim_create_user_command("SudoWrite", function() + vim.cmd([[ + write !sudo tee % 2>/dev/null + edit! + ]]) +end, {}) +vim.api.nvim_create_user_command("SudoWritequit", function() + vim.cmd([[ + write !sudo tee % 2>/dev/null + edit! + quit! + ]]) +end, {}) + +-- Markdown for specific files and directories +autocmd({ "BufRead", "BufNewFile" }, { + pattern = { "/tmp/calcurse*", "~/.calcurse/notes/*" }, + command = "set filetype=markdown", +}) + +-- Groff for specific file extensions +autocmd({ "BufRead", "BufNewFile" }, { + pattern = { "*.ms", "*.me", "*.mom", "*.man" }, + callback = function() + vim.cmd([[ + set columns=90 + set filetype=groff + set linebreak + set textwidth=0 + set wrap + set wrapmargin=0 + ]]) + end, +}) + +-- TeX for .tex files +autocmd({ "BufRead", "BufNewFile" }, { + pattern = { "*.tex" }, + command = "set filetype=tex", +}) + +-- When shortcut files are updated, renew bash and lf configs with new material: +autocmd("BufWritePost", { + group = augroup("bookmarks"), + pattern = { "bm-files", "bm-dirs" }, + callback = function() + -- Execute the 'shortcuts' shell command + local result = vim.fn.system("shortcuts") + -- Display an error message only if the 'shortcuts' command fails + if vim.v.shell_error ~= 0 then + -- Display an error message if the 'shortcuts' command fails + vim.api.nvim_echo({ { "failed to update shortcuts: " .. result, "ErrorMsg" } }, true, {}) + end + end, +}) + +-- Source lfrc if it's edited +local lf_config = augroup("lf_config") +autocmd("BufWritePost", { + group = lf_config, + pattern = { "lfrc" }, + callback = function() + vim.cmd("silent !source ~/.config/lf/lfrc") + end, +}) + +-- Set vimwiki's index filetype to vimwiki instead of markdown +local vimwiki_config = augroup("vimwiki_config") +autocmd({ "BufRead", "BufNewFile" }, { + group = vimwiki_config, + pattern = vim.fn.expand("~/.local/share/vimwiki") .. "/**/*.md", + callback = function(args) + vim.bo[args.buf].filetype = "vimwiki" + end, +}) + +-- Run xrdb whenever Xdefaults or Xresources are updated. +local x_config = augroup("x_config") +autocmd({ "BufRead", "BufNewFile" }, { + group = x_config, + pattern = { "Xresources", "Xdefaults", "xresources", "xdefaults" }, + callback = function() + vim.bo.filetype = "xdefaults" + end, +}) +autocmd("BufWritePost", { + group = x_config, + pattern = { "Xresources", "Xdefaults", "xresources", "xdefaults" }, + callback = function() + vim.cmd("silent !xrdb %") + end, +}) + +-- Recompile suckless programs on config edit. +local home = os.getenv("HOME") +local suckless_config = vim.api.nvim_create_augroup("suckless_config", { clear = true }) + +autocmd("BufWritePost", { + group = suckless_config, + pattern = home .. "/.local/src/suckless/dmenu/config.def.h", + callback = function() + vim.cmd("silent !cd " .. home .. "/.local/src/suckless/dmenu/ && sudo make install") + end, +}) + +autocmd("BufWritePost", { + group = suckless_config, + pattern = home .. "/.local/src/suckless/dwmblocks/config.def.h", + callback = function() + vim.cmd( + "silent !cd " + .. home + .. "/.local/src/suckless/dwmblocks/ && sudo make install && { killall -q dwmblocks; setsid -f dwmblocks; }" + ) + end, +}) + +autocmd("BufWritePost", { + group = suckless_config, + pattern = home .. "/.local/src/suckless/slock/config.def.h", + callback = function() + vim.cmd("silent !cd " .. home .. "/.local/src/suckless/slock/ && sudo make install") + end, +}) + +local suckless_keys = augroup("suckless_keys") +autocmd("BufWritePost", { + group = suckless_keys, + pattern = home .. "/.local/src/suckless/dwm/config.def.h", + callback = function() + vim.cmd("silent !" .. home .. "/.local/bin/extractkeys") + end, +}) + +autocmd("BufWritePost", { + group = suckless_keys, + pattern = home .. "/.local/src/suckless/st/config.def.h", + callback = function() + vim.cmd("silent !" .. home .. "/.local/bin/extractkeys") + end, +}) + +autocmd("BufWritePost", { + group = augroup("suckless_doc"), + pattern = home .. "/.local/src/suckless/dwm/thesiah-default.mom", + callback = function() + vim.cmd("silent !cd " .. home .. "/.local/src/suckless/dwm/ && rm -f thesiah.mom") + end, +}) + +autocmd({ "BufRead", "BufEnter" }, { + pattern = { "*.c", "*.cpp", "*.h", "*.hpp" }, + callback = function() + local suckless_path = vim.fn.expand("~/.local/src/suckless"):gsub("/+$", "") + local file_path = vim.fn.expand("%:p"):gsub("/+$", "") + if file_path:sub(1, #suckless_path) == suckless_path then + vim.b.autoformat = false + end + end, +}) diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/keymaps.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/keymaps.lua new file mode 100644 index 0000000..c8ae8f2 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/keymaps.lua @@ -0,0 +1,809 @@ +-- Ascii +vim.keymap.set("n", "a1", ":.!toilet -w 200 -f bfraktur", { desc = "Ascii art bfraktur" }) +vim.keymap.set("n", "a2", ":.!toilet -w 200 -f emboss", { desc = "Ascii art emboss" }) +vim.keymap.set("n", "a3", ":.!toilet -w 200 -f emboss2", { desc = "Ascii art emboss2" }) +vim.keymap.set("n", "a4", ":.!toilet -w 200 -f future", { desc = "Ascii art future" }) +vim.keymap.set("n", "a5", ":.!toilet -w 200 -f pagga", { desc = "Ascii art pagga" }) +vim.keymap.set("n", "a6", ":.!toilet -w 200 -f wideterm", { desc = "Ascii art wideterm" }) +vim.keymap.set("n", "a7", ":.!figlet -w 200 -f standard", { desc = "Ascii art standard" }) +vim.keymap.set("n", "a8", ":.!figlet -w 200 -f slant", { desc = "Ascii art slant" }) +vim.keymap.set("n", "a9", ":.!figlet -w 200 -f big", { desc = "Ascii art big" }) +vim.keymap.set("n", "a0", ":.!figlet -w 200 -f shadow", { desc = "Ascii art shadow" }) + +-- Buffers +vim.keymap.set({ "n", "v", "x", "t" }, "", "bd!", { desc = "Delete buffer" }) +vim.keymap.set({ "i", "n", "t" }, "", "bprevious", { desc = "Previous buffer" }) +vim.keymap.set({ "i", "n", "t" }, "", "bnext", { desc = "Next buffer" }) +vim.keymap.set({ "n", "t" }, "", "bprevious", { desc = "Previous buffer" }) +vim.keymap.set({ "n", "t" }, "", "bnext", { desc = "Next buffer" }) +vim.keymap.set("n", "", "e #", { desc = "Switch to last buffer" }) +vim.keymap.set({ "n", "v", "x", "t" }, "bd", ":bd", { desc = "Close buffer" }) +vim.keymap.set({ "n", "v", "x", "t" }, "BD", ":bd!", { desc = "Force close buffer" }) +vim.keymap.set("n", "bn", "enew", { desc = "Open new buffer" }) +vim.keymap.set("n", "bc", "e!", { desc = "Clear edit" }) +vim.keymap.set({ "i", "x", "n", "s" }, "", "w", { desc = "Save current buffer" }) +vim.keymap.set({ "n", "v" }, "wq", "wq", { desc = "Save current buffer and quit" }) +vim.keymap.set({ "n", "v" }, "WQ", "wqa", { desc = "Save all buffers and quit" }) +vim.keymap.set({ "n", "v" }, "qq", "q!", { desc = "Force quit" }) +vim.keymap.set({ "n", "v" }, "QQ", "qa!", { desc = "Force quit all" }) +vim.keymap.set("n", "rnf", function() + local current_name = vim.fn.expand("%:p") -- Get the full path of the current file + local directory = vim.fn.expand("%:p:h") -- Get the directory of the current file + local new_name = vim.fn.input("New filename: ", directory .. "/") -- Prompt for the new name + if new_name == "" or new_name == current_name then + return -- Do nothing if no input or name hasn't changed + end + vim.cmd("silent !mv " .. vim.fn.shellescape(current_name) .. " " .. vim.fn.shellescape(new_name)) + vim.cmd("edit " .. vim.fn.fnameescape(new_name)) + vim.cmd("bdelete " .. vim.fn.bufnr(current_name)) +end, { noremap = true, silent = true, desc = "Rename file" }) +vim.keymap.set("n", "ms", function() + vim.cmd("new | put=execute('messages') | setlocal buftype=nofile") + local buf = vim.api.nvim_get_current_buf() + local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) + local filtered_lines = {} + for _, line in ipairs(lines) do + local trimmed_line = line:match("^%s*(.-)%s*$") -- Remove leading and trailing whitespace + if trimmed_line ~= "" then + table.insert(filtered_lines, trimmed_line) -- Only add non-empty lines + end + end + vim.fn.setreg('"', table.concat(filtered_lines, "\n")) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, filtered_lines) + vim.keymap.set("n", "q", function() + vim.api.nvim_buf_delete(buf, { force = true }) + end, { buffer = buf, desc = "Close message buffer" }) +end, { desc = "Open messages, trim, and copy content" }) + +-- Cd +vim.keymap.set("n", "gcd", ":cd %:p:h:pwd", { desc = "Go to current file path" }) +vim.keymap.set("n", "gcD", function() + local realpath = vim.fn.systemlist("readlink -f " .. vim.fn.shellescape(vim.fn.expand("%:p")))[1] + vim.cmd("cd " .. vim.fn.fnameescape(vim.fn.fnamemodify(realpath, ":h"))) + vim.cmd("pwd") +end, { desc = "Go to real path of current file" }) +vim.keymap.set("n", "gc.", ":cd ..:pwd", { desc = "Go to current file path" }) + +-- Check health +vim.keymap.set("n", "ch", ":checkhealth", { desc = "Check neovim health" }) + +-- Clear search with +vim.keymap.set({ "i", "n" }, "", "noh", { desc = "Clear search highlights" }) + +-- Clear search / diff update / redraw +vim.keymap.set( + "n", + "R", + "nohlsearchdiffupdatenormal! ", + { desc = "Redraw / Clear hlsearch / Diff Update" } +) + +-- Copy +vim.keymap.set("n", "cp", function() + local filepath = vim.fn.expand("%") -- Get the current filepath + local filename = vim.fn.expand("%:t") -- Get the current filename + local file_root = vim.fn.expand("%:r") -- Get the file root (without extension) + local file_ext = vim.fn.expand("%:e") -- Get the file extension + local new_filename = file_root .. "_copied" -- Start with the base for new filename + local num = 1 + while vim.fn.filereadable(new_filename .. "." .. file_ext) == 1 do + new_filename = file_root .. "_copied_" .. num + num = num + 1 + end + new_filename = new_filename .. "." .. file_ext + local cmd = "cp " .. filepath .. " " .. new_filename + + -- Wrap input in pcall to handle Ctrl-c interruptions + local ok, confirm = pcall(vim.fn.input, 'Do you want to copy "' .. filename .. '"? (y/n): ') + + -- If interrupted (Ctrl-c), return silently + if not ok or confirm == nil or confirm == "" then + return + end + + -- Handle positive confirmation + if confirm:lower() == "y" or confirm:lower() == "yes" then + vim.cmd("silent !" .. cmd) + vim.cmd("silent edit " .. new_filename) + end +end, { silent = true, desc = "Copy current file" }) +vim.keymap.set( + "n", + "cP", + ':let @+ = expand("%:p"):lua print("Copied path to: " .. vim.fn.expand("%:p"))', + { desc = "Copy current file name and path" } +) + +-- Cut, Yank & Paste +vim.keymap.set({ "n", "v" }, "y", [["+y]], { desc = "Yank to clipboard" }) +vim.keymap.set("n", "Y", [["+Y]], { desc = "Yank line to clipboard" }) +vim.keymap.set({ "n", "v" }, "", ":%y", { desc = "Yank current file to clipboard" }) +vim.keymap.set({ "n", "v", "x" }, "pp", [["+p]], { desc = "Paste from clipboard after cursor" }) +vim.keymap.set({ "n", "v", "x" }, "PP", [["+P]], { desc = "Paste from clipboard before cursor" }) +vim.keymap.set({ "n", "v", "x" }, "pP", [["_dP]], { desc = "Paste over and preserve clipboard" }) +vim.keymap.set({ "n", "v" }, "dd", [["+d]], { desc = "Delete and yank to clipboard" }) +vim.keymap.set({ "n", "v" }, "DD", [["_d]], { desc = "Delete without storing in clipboard" }) +vim.keymap.set("n", "", ":%d_", { desc = "Delete all lines to black hole register" }) + +-- Diagnostic +local diagnostic_goto = function(next, severity) + local go = next and vim.diagnostic.goto_next or vim.diagnostic.goto_prev + severity = severity and vim.diagnostic.severity[severity] or nil + return function() + go({ severity = severity }) + end +end +-- vim.keymap.set("n", "[d", diagnostic_goto(false), { desc = "Previous diagnostic" }) +-- vim.keymap.set("n", "]d", diagnostic_goto(true), { desc = "Next diagnostic" }) +vim.keymap.set("n", "[e", diagnostic_goto(false, "ERROR"), { desc = "Previous error" }) +vim.keymap.set("n", "]e", diagnostic_goto(true, "ERROR"), { desc = "Next error" }) +vim.keymap.set("n", "[w", diagnostic_goto(false, "WARN"), { desc = "Previous warning" }) +vim.keymap.set("n", "]w", diagnostic_goto(true, "WARN"), { desc = "Next warning" }) +vim.keymap.set("n", "od", vim.diagnostic.open_float, { desc = "Open diagnostic message" }) +vim.keymap.set("n", "la", vim.diagnostic.setloclist, { desc = "Add diagnostics to location list" }) + +-- Disable +vim.keymap.set("n", "Q", "", { desc = "Disable q command" }) + +-- Explore +vim.keymap.set("n", "ex", vim.cmd.Ex, { desc = "Open explorer" }) +vim.keymap.set("n", "es", vim.cmd.Sex, { desc = "Open explorer (horizontal split)" }) +vim.keymap.set("n", "ev", vim.cmd.Vex, { desc = "Open explorer (vertical split)" }) +vim.keymap.set("n", "qe", function() + if vim.bo.filetype == "netrw" then + vim.cmd("bd") + end +end, { desc = "Close explorer (netrw)" }) + +-- Fix List & Trouble +vim.keymap.set("n", "[o", "lprevzz", { desc = "Previous location" }) +vim.keymap.set("n", "]o", "lnextzz", { desc = "Next location" }) +vim.keymap.set("n", "[q", "cprevzz", { desc = "Previous quickfix" }) +vim.keymap.set("n", "]q", "cnextzz", { desc = "Next quickfix" }) +vim.keymap.set( + "n", + "rw", + [[:%s/\<\>//gI]], + { desc = "Search and replace word under cursor" } +) +vim.keymap.set("n", "oo", "lopen", { desc = "Open location list" }) +vim.keymap.set("n", "oq", "copen", { desc = "Open quickfix list" }) + +-- Formats +vim.keymap.set("n", "cF", vim.lsp.buf.format, { desc = "Format buffer by default lsp" }) + +-- Full path +vim.keymap.set("n", "zf", function() + local word = vim.fn.expand("") -- Get full text under the cursor (handles paths with slashes) + if word:match("%$") then + local expanded_path = vim.fn.expand(word) + if expanded_path ~= word then + vim.cmd("normal! ciW" .. expanded_path) -- Replace entire word under cursor + end + end +end, { desc = "Expand and replace path under cursor" }) + +-- Git +-- create repository +vim.keymap.set("n", "gR", function() + -- Check if GitHub CLI is installed + local gh_installed = vim.fn.system("command -v gh") + if gh_installed == "" then + print("GitHub CLI is not installed. Please install it using 'brew install gh'.") + return + end + -- Get the current working directory and extract the repository name + local cwd = vim.fn.getcwd() + local repo_name = vim.fn.fnamemodify(cwd, ":t") + if repo_name == "" then + print("Failed to extract repository name from the current directory.") + return + end + -- Display the message and ask for confirmation + local confirmation = vim.fn.input('The name of the repo will be: "' .. repo_name .. '"\nType "yes" to continue: ') + if confirmation:lower() ~= "yes" then + print("Operation canceled.") + return + end + -- Check if the repository already exists on GitHub + local check_repo_command = + string.format("gh repo view %s/%s", vim.fn.system("gh api user --jq '.login'"):gsub("%s+", ""), repo_name) + local check_repo_result = vim.fn.systemlist(check_repo_command) + if not string.find(table.concat(check_repo_result), "Could not resolve to a Repository") then + print("Repository '" .. repo_name .. "' already exists on GitHub.") + return + end + -- Prompt for repository type + local repo_type = vim.fn.input("Enter the repository type (private/public): "):lower() + if repo_type ~= "private" and repo_type ~= "public" then + print("Invalid repository type. Please enter 'private' or 'public'.") + return + end + -- Set the repository type flag + local repo_type_flag = repo_type == "private" and "--private" or "--public" + -- Initialize the git repository and create the GitHub repository + local init_command = string.format("cd %s && git init", vim.fn.shellescape(cwd)) + vim.fn.system(init_command) + local create_command = + string.format("cd %s && gh repo create %s %s --source=.", vim.fn.shellescape(cwd), repo_name, repo_type_flag) + local create_result = vim.fn.system(create_command) + -- Print the result of the repository creation command + if string.find(create_result, "https://github.com") then + print("Repository '" .. repo_name .. "' created successfully.") + else + print("Failed to create the repository: " .. create_result) + end +end, { desc = "Create GitHub repository" }) +-- open repository +local function open_github_link(use_root) + -- Get the full path of the current file + local file_path = vim.fn.expand("%:p") + if file_path == "" then + print("No file is currently open") + return + end + + -- Get the Git repository root + local git_root = vim.fn.systemlist("git rev-parse --show-toplevel")[1] + if not git_root or git_root == "" then + print("Could not determine the root directory for the GitHub repository") + return + end + + -- Get the origin URL of the repository + local origin_url = vim.fn.systemlist("git config --get remote.origin.url")[1] + if not origin_url or origin_url == "" then + print("Could not determine the origin URL for the GitHub repository") + return + end + + -- Get the current branch name + local branch_name = vim.fn.systemlist("git rev-parse --abbrev-ref HEAD")[1] + if not branch_name or branch_name == "" then + print("Could not determine the current branch name") + return + end + + -- Convert the origin URL to a GitHub HTTPS URL + local repo_url = origin_url:gsub("git@github.com:", "https://github.com/"):gsub("%.git$", "") + + local github_url + if use_root then + -- Use the root repository URL + github_url = repo_url + else + -- Generate the link for the current file + local relative_path = file_path:sub(#git_root + 2) -- Extract the relative path + github_url = repo_url .. "/blob/" .. branch_name .. "/" .. relative_path + end + + -- Open the URL in the default browser + local command = "xdg-open " .. vim.fn.shellescape(github_url) + vim.fn.system(command) + + -- Print the opened URL + print("Opened GitHub link: " .. github_url) +end + +-- Keybinding for opening the current file link +vim.keymap.set("n", "go", function() + open_github_link(false) -- Use the current file link +end, { desc = "Open GitHub link for the current file" }) + +-- Keybinding for opening the repository root link +vim.keymap.set("n", "gO", function() + open_github_link(true) -- Use the root repository URL +end, { desc = "Open GitHub repository root" }) + +-- paste a github link and add it in this format +vim.keymap.set({ "n", "v", "i" }, "", function() + -- Insert the text in the desired format + vim.cmd('normal! a[](){:target="_blank"} ') + vim.cmd("normal! F(pv2F/lyF[p") + -- Leave me in normal mode or command mode + vim.cmd("stopinsert") +end, { desc = "Paste github link" }) + +-- Health +vim.keymap.set("n", "ch", ":checkhealth", { desc = "Check neovim health" }) + +-- Highlights under cursor +vim.keymap.set("n", "ip", vim.show_pos, { desc = "Inspect position" }) + +-- Keywordprg +vim.keymap.set("n", "K", "norm! K", { desc = "Look up keyword" }) + +-- Lines +-- vim.keymap.set("n", "", "m .-2==", { desc = "Move line up" }) +-- vim.keymap.set("n", "", "m .+1==", { desc = "Move line down" }) +vim.keymap.set( + "i", + "", + "m .-2==gi", + { noremap = true, silent = true, desc = "Move line up in insert mode" } +) +vim.keymap.set( + "i", + "", + "m .+1==gi", + { noremap = true, silent = true, desc = "Move line down in insert mode" } +) +vim.keymap.set("v", "", ":m '<-2gv=gv", { desc = "Move selected lines up" }) +vim.keymap.set("v", "", ":m '>+1gv=gv", { desc = "Move selected lines down" }) + +-- Markdown +vim.keymap.set({ "n", "v" }, "gk", function() + -- `?` - Start a search backwards from the current cursor position. + -- `^` - Match the beginning of a line. + -- `##` - Match 2 ## symbols + -- `\\+` - Match one or more occurrences of prev element (#) + -- `\\s` - Match exactly one whitespace character following the hashes + -- `.*` - Match any characters (except newline) following the space + -- `$` - Match extends to end of line + vim.cmd("silent! ?^##\\+\\s.*$") + -- Clear the search highlight + vim.cmd("nohlsearch") +end, { desc = "Go to previous markdown header" }) +vim.keymap.set({ "n", "v" }, "gj", function() + -- `/` - Start a search forwards from the current cursor position. + -- `^` - Match the beginning of a line. + -- `##` - Match 2 ## symbols + -- `\\+` - Match one or more occurrences of prev element (#) + -- `\\s` - Match exactly one whitespace character following the hashes + -- `.*` - Match any characters (except newline) following the space + -- `$` - Match extends to end of line + vim.cmd("silent! /^##\\+\\s.*$") + -- Clear the search highlight + vim.cmd("nohlsearch") +end, { desc = "Go to next markdown header" }) + +-- Marks +vim.keymap.set("n", "mD", function() + -- Delete all marks in the current buffer + vim.cmd("delmarks!") + print("All marks deleted.") +end, { desc = "Delete all marks" }) + +-- Ownerships +vim.keymap.set("n", "cx", "!chmod +x %", { silent = true, desc = "Make file executable" }) + +-- Remap Default +vim.keymap.set("i", "jk", "", { noremap = true, silent = true, desc = "Escape to normal mode" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Escape to normal mode" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Insert at beginning of line" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Move to end of line" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Move left" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Move right" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Move down" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "Move up" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "New line above" }) +vim.keymap.set("i", "", "", { noremap = true, silent = true, desc = "New line below" }) +vim.keymap.set("n", "", ":", { noremap = true, desc = "Enter command mode" }) +vim.keymap.set("n", "J", "mzJ`z", { noremap = true, desc = "Join lines and keep cursor position" }) +vim.keymap.set("n", "n", "'Nn'[v:searchforward].'zv'", { expr = true, desc = "Next search result and center" }) +vim.keymap.set("x", "n", "'Nn'[v:searchforward]", { expr = true, desc = "Next search result in visual mode" }) +vim.keymap.set("o", "n", "'Nn'[v:searchforward]", { expr = true, desc = "Next search result in operator-pending mode" }) +vim.keymap.set("n", "N", "'nN'[v:searchforward].'zv'", { expr = true, desc = "Previous search result and center" }) +vim.keymap.set("x", "N", "'nN'[v:searchforward]", { expr = true, desc = "Previous search result in visual mode" }) +vim.keymap.set( + "o", + "N", + "'nN'[v:searchforward]", + { expr = true, desc = "Previous search result in operator-pending mode" } +) +vim.keymap.set("n", "x", '"_x', { desc = "Delete character without yanking" }) +local scroll_percentage = 0.50 +vim.keymap.set("n", "", function() + local lines = math.floor(vim.api.nvim_win_get_height(0) * scroll_percentage) + vim.cmd("normal! " .. lines .. "jzz") +end, { noremap = true, silent = true, desc = "Scroll down and center" }) +vim.keymap.set("n", "", function() + local lines = math.floor(vim.api.nvim_win_get_height(0) * scroll_percentage) + vim.cmd("normal! " .. lines .. "kzz") +end, { noremap = true, silent = true, desc = "Scroll up and center" }) +-- vim.keymap.set("n", "", "zz", { noremap = true, silent = true, desc = "Scroll down and center" }) +-- vim.keymap.set("n", "", "zz", { noremap = true, silent = true, desc = "Scroll up and center" }) +vim.keymap.set("n", "", "zz", { noremap = true, silent = true, desc = "Page up and center" }) +vim.keymap.set("n", "", "zz", { noremap = true, silent = true, desc = "Page down and center" }) +vim.keymap.set("n", "{", "{zz", { noremap = true, silent = true, desc = "Move to previous paragraph and center" }) +vim.keymap.set("n", "}", "}zz", { noremap = true, silent = true, desc = "Move to next paragraph and center" }) +vim.keymap.set("n", "G", "Gzz", { noremap = true, silent = true, desc = "Go to bottom of file and center" }) +vim.keymap.set("n", "gg", "ggzz", { noremap = true, silent = true, desc = "Go to top of file and center" }) +vim.keymap.set("n", "gd", "gdzz", { noremap = true, silent = true, desc = "Go to definition and center" }) +vim.keymap.set("n", "", "zz", { noremap = true, silent = true, desc = "Jump forward in jumplist and center" }) +vim.keymap.set( + "n", + "", + "zz", + { noremap = true, silent = true, desc = "Jump backward in jumplist and center" } +) +vim.keymap.set( + "n", + "%", + "%zz", + { noremap = true, silent = true, desc = "Jump to matching pair (e.g. brackets) and center" } +) +vim.keymap.set( + "n", + "*", + "*zz", + { noremap = true, silent = true, desc = "Search for next occurrence of word under cursor and center" } +) +vim.keymap.set( + "n", + "#", + "#zz", + { noremap = true, silent = true, desc = "Search for previous occurrence of word under cursor and center" } +) + +vim.keymap.set( + { "n", "x" }, + "j", + "v:count == 0 ? 'gj' : 'j'", + { expr = true, silent = true, desc = "Move down (visual line)" } +) +vim.keymap.set( + { "n", "x" }, + "", + "v:count == 0 ? 'gj' : 'j'", + { expr = true, silent = true, desc = "Move down (visual line)" } +) +vim.keymap.set( + { "n", "x" }, + "k", + "v:count == 0 ? 'gk' : 'k'", + { expr = true, silent = true, desc = "Move up (visual line)" } +) +vim.keymap.set( + { "n", "x" }, + "", + "v:count == 0 ? 'gk' : 'k'", + { expr = true, silent = true, desc = "Move up (visual line)" } +) +vim.keymap.set("v", "<", "", ">gv", { desc = "Indent right and stay in visual mode" }) +vim.keymap.set("v", "J", ":m '>+1gv=gv", { desc = "Move line down in visual mode" }) +vim.keymap.set("v", "K", ":m '<-2gv=gv", { desc = "Move line up in visual mode" }) +vim.keymap.set("n", "sl", "vg_", { desc = "Select to end of line" }) +vim.keymap.set("n", "sp", "ggVGp", { desc = "Select all and paste" }) +vim.keymap.set("n", "sv", "ggVG", { desc = "Select all" }) +vim.keymap.set("n", "gp", "`[v`]", { desc = "Select pasted text" }) +vim.keymap.set("n", "ss", ":s/\\v", { desc = "Search and replace on line" }) +vim.keymap.set("n", "SS", ":%s/\\v", { desc = "Search and replace in file" }) +vim.keymap.set("v", "", ":s/\\%V", { desc = "Search only in visual selection using %V atom" }) +vim.keymap.set("v", "", '"hy:%s/\\vh//g', { desc = "Change selection" }) + +-- Remove +local function delete_current_file() + local filepath = vim.fn.expand("%:p") + local filename = vim.fn.expand("%:t") -- Get the current filename + if filepath and filepath ~= "" then + -- Check if trash utility is installed + if vim.fn.executable("trash") == 0 then + vim.api.nvim_echo({ + { "- Trash utility not installed. Make sure to install it first\n", "ErrorMsg" }, + { "- Install `trash-cli`\n", nil }, + }, false, {}) + return + end + -- Prompt for confirmation before deleting the file + vim.ui.input({ + prompt = 'Do you want to delete "' .. filename .. '"? (y/n): ', + }, function(input) + if input == nil then + return + end + + if input:lower() == "y" or input:lower() == "yes" then + -- Delete the file using trash app + local success, _ = pcall(function() + vim.fn.system({ "trash", vim.fn.fnameescape(filepath) }) + end) + if success then + vim.api.nvim_echo({ + { "File deleted from disk:\n", "Normal" }, + { filepath, "Normal" }, + }, false, {}) + -- Close the buffer after deleting the file + vim.cmd("bd!") + else + vim.api.nvim_echo({ + { "Failed to delete file:\n", "ErrorMsg" }, + { filepath, "ErrorMsg" }, + }, false, {}) + end + else + vim.api.nvim_echo({ + { "File deletion canceled.", "Normal" }, + }, false, {}) + end + end) + else + vim.api.nvim_echo({ + { "No file to delete", "WarningMsg" }, + }, false, {}) + end +end + +vim.keymap.set("n", "rm", function() + delete_current_file() +end, { desc = "Remove current file" }) + +-- Scripts +vim.keymap.set("n", "rr", function() + vim.cmd("w") + vim.cmd("split | resize 10 | terminal compiler " .. vim.fn.expand("%:p")) +end, { noremap = true, silent = true, desc = "Run compiler interactively" }) +vim.api.nvim_set_keymap( + "n", + "RR", + ":!opout %", + { noremap = true, silent = true, desc = "Docs viewer" } +) + +-- Source +-- source nvim config +vim.keymap.set("n", "SO", function() + vim.cmd("so") +end, { desc = "Source current file" }) +-- reload zsh configuration by sourcing ~/.config/zsh/.zshrc in a separate shell +vim.keymap.set("n", "SZ", function() + -- Define the command to source zshrc + local command = "source ~/.config/zsh/.zshrc" + -- Execute the command in a new Zsh shell + local full_command = "zsh -c '" .. command .. "'" + -- Run the command and capture the output + local output = vim.fn.system(full_command) + -- Check the exit status of the command + local exit_code = vim.v.shell_error + if exit_code == 0 then + vim.api.nvim_echo({ { "Successfully sourced ~/.config/zsh/.zshrc", "NormalMsg" } }, false, {}) + else + vim.api.nvim_echo({ + { "Failed to source ~/.config/zsh/.zshrc:", "ErrorMsg" }, + { output, "ErrorMsg" }, + }, false, {}) + end +end, { desc = "Source zshrc" }) +-- source shortcuts from bm-files and bm-folders +local shortcuts_file = vim.fn.expand("~/.config/nvim/shortcuts.lua") +local file = io.open(shortcuts_file, "r") +if file then + file:close() + vim.cmd("silent! source " .. shortcuts_file) +end + +-- Spell +vim.keymap.set("n", "zp", function() + vim.opt.spelllang = { "en", "ko", "cjk" } + vim.cmd("echo 'Spell language set to English, Korean, and CJK'") +end, { desc = "Spelling language English, Korean, and CJK" }) +-- repeat the replacement done by |z=| for all matches with the replaced word in the current window. +vim.keymap.set("n", "z.", function() + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(":spellr\n", true, false, true), "m", true) +end, { desc = "Spelling repeat" }) + +-- Sudo +vim.keymap.set("n", "SW", "SudoWrite", { silent = true, desc = "Save file with sudo" }) +vim.keymap.set("n", "SWQ", "SudoWritequit", { silent = true, desc = "Save and quit with sudo" }) + +-- Surround +vim.keymap.set("n", "sau", function() + local line = vim.api.nvim_get_current_line() + local col = vim.api.nvim_win_get_cursor(0)[2] + 1 -- Adjust for 0-index in Lua + -- This makes the `s` optional so it matches both http and https + local pattern = "https?://[^ ,;'\"<>%s)]*" + -- Find the starting and ending positions of the URL + local s, e = string.find(line, pattern) + while s and e do + if s <= col and e >= col then + -- When the cursor is within the URL + local url = string.sub(line, s, e) + -- Update the line with backticks around the URL + local new_line = string.sub(line, 1, s - 1) .. "`" .. url .. "`" .. string.sub(line, e + 1) + vim.api.nvim_set_current_line(new_line) + vim.cmd("silent write") + return + end + -- Find the next URL in the line + s, e = string.find(line, pattern, e + 1) + -- Save the file to update trouble list + end + print("No URL found under cursor") +end, { desc = "Add surrounding to URL" }) +vim.keymap.set("v", "bl", function() + -- Get the selected text range + local start_row, start_col = unpack(vim.fn.getpos("'<"), 2, 3) + local end_row, end_col = unpack(vim.fn.getpos("'>"), 2, 3) + -- Get the selected lines + local lines = vim.api.nvim_buf_get_lines(0, start_row - 1, end_row, false) + local selected_text = table.concat(lines, "\n"):sub(start_col, #lines == 1 and end_col or -1) + if selected_text:match("^%*%*.*%*%*$") then + vim.notify("Text already bold", vim.log.levels.INFO) + else + vim.cmd("normal 2gsa*") + end +end, { desc = "Bold current selection" }) +vim.keymap.set("n", "gbd", function() + local cursor_pos = vim.api.nvim_win_get_cursor(0) + local current_buffer = vim.api.nvim_get_current_buf() + local start_row = cursor_pos[1] - 1 + local col = cursor_pos[2] + -- Get the current line + local line = vim.api.nvim_buf_get_lines(current_buffer, start_row, start_row + 1, false)[1] + -- Check if the cursor is on an asterisk + if line:sub(col + 1, col + 1):match("%*") then + vim.notify("Cursor is on an asterisk, run inside the bold text", vim.log.levels.WARN) + return + end + -- Search for '**' to the left of the cursor position + local left_text = line:sub(1, col) + local bold_start = left_text:reverse():find("%*%*") + if bold_start then + bold_start = col - bold_start + end + -- Search for '**' to the right of the cursor position and in following lines + local right_text = line:sub(col + 1) + local bold_end = right_text:find("%*%*") + local end_row = start_row + while not bold_end and end_row < vim.api.nvim_buf_line_count(current_buffer) - 1 do + end_row = end_row + 1 + local next_line = vim.api.nvim_buf_get_lines(current_buffer, end_row, end_row + 1, false)[1] + if next_line == "" then + break + end + right_text = right_text .. "\n" .. next_line + bold_end = right_text:find("%*%*") + end + if bold_end then + bold_end = col + bold_end + end + -- Remove '**' markers if found, otherwise bold the word + if bold_start and bold_end then + -- Extract lines + local text_lines = vim.api.nvim_buf_get_lines(current_buffer, start_row, end_row + 1, false) + local text = table.concat(text_lines, "\n") + -- Calculate positions to correctly remove '**' + -- vim.notify("bold_start: " .. bold_start .. ", bold_end: " .. bold_end) + local new_text = text:sub(1, bold_start - 1) .. text:sub(bold_start + 2, bold_end - 1) .. text:sub(bold_end + 2) + local new_lines = vim.split(new_text, "\n") + -- Set new lines in buffer + vim.api.nvim_buf_set_lines(current_buffer, start_row, end_row + 1, false, new_lines) + -- vim.notify("Unbolded text", vim.log.levels.INFO) + else + -- Bold the word at the cursor position if no bold markers are found + local before = line:sub(1, col) + local after = line:sub(col + 1) + local inside_surround = before:match("%*%*[^%*]*$") and after:match("^[^%*]*%*%*") + if inside_surround then + vim.cmd("normal gsd*.") + else + vim.cmd("normal viw") + vim.cmd("normal 2gsa*") + end + vim.notify("Bolded current word", vim.log.levels.INFO) + end +end, { desc = "Toggle bold" }) + +-- Tab +vim.keymap.set("n", "l", "tablast", { desc = "Last Tab" }) +vim.keymap.set("n", "]]", "tablast", { desc = "Last Tab" }) +vim.keymap.set("n", "o", "tabonly", { desc = "Close Other Tabs" }) +vim.keymap.set("n", "f", "tabfirst", { desc = "First Tab" }) +vim.keymap.set("n", "[[", "tabfirst", { desc = "First Tab" }) +vim.keymap.set("n", "", "tabnew", { desc = "New Tab" }) +vim.keymap.set("n", "n", "tabnext", { desc = "Next Tab" }) +vim.keymap.set("n", "]", "tabnext", { desc = "Next Tab" }) +vim.keymap.set("n", "d", "tabclose", { desc = "Close Tab" }) +vim.keymap.set("n", "p", "tabprevious", { desc = "Previous Tab" }) +vim.keymap.set("n", "[", "tabprevious", { desc = "Previous Tab" }) + +-- Terminal +vim.keymap.set("n", "te", "term", { desc = "Open terminal" }) +vim.keymap.set("n", "t-", "sp term://zsh | startinsert", { desc = "Split terminal (horizontal)" }) +vim.keymap.set("n", "t|", "vsp term://zsh | startinsert", { desc = "Split terminal (vertical)" }) +vim.keymap.set("t", "", "", { desc = "Escape terminal mode" }) +vim.keymap.set("t", "", "wincmd h", { desc = "Move to left window" }) +vim.keymap.set("t", "", "wincmd j", { desc = "Move to window below" }) +vim.keymap.set("t", "", "wincmd k", { desc = "Move to window above" }) +vim.keymap.set("t", "", "wincmd l", { desc = "Move to right window" }) +vim.keymap.set("t", "l", "clear", { silent = true, desc = "Clear terminal" }) +vim.keymap.set("t", "", "iexit", { desc = "Close terminal" }) +vim.keymap.set("t", "", "close", { desc = "Close terminal" }) +vim.keymap.set("t", "", "close", { desc = "Close terminal" }) + +-- Tmux +if vim.env.TMUX then + vim.keymap.set( + "n", + "tm", + "silent !~/.config/tmux/plugins/tmux-fzf/scripts/session.sh", + { desc = "Find tmux session" } + ) + vim.keymap.set("n", "RS", function() + vim.fn.system("restartnvim") + end, { noremap = true, silent = true, desc = "Restart nvim (tmux)" }) +end + +-- Todo +-- detect todos and toggle between ":" and ";", or show a message if not found +-- this is to "mark them as done" +vim.keymap.set("n", "td", function() + -- Get the current line + local current_line = vim.fn.getline(".") + -- Get the current line number + local line_number = vim.fn.line(".") + if string.find(current_line, "TODO:") then + -- Replace the first occurrence of ":" with ";" + local new_line = current_line:gsub("TODO:", "TODO;") + -- Set the modified line + vim.fn.setline(line_number, new_line) + elseif string.find(current_line, "TODO;") then + -- Replace the first occurrence of ";" with ":" + local new_line = current_line:gsub("TODO;", "TODO:") + -- Set the modified line + vim.fn.setline(line_number, new_line) + else + vim.cmd("echo 'todo item not detected'") + end +end, { desc = "Toggle TODO item done or not" }) + +-- Windows +vim.keymap.set("n", "", "", { desc = "Move to left window" }) +vim.keymap.set("n", "", "", { desc = "Move to window below" }) +vim.keymap.set("n", "", "", { desc = "Move to window above" }) +vim.keymap.set("n", "", "", { desc = "Move to right window" }) +-- vim.keymap.set("n", "", "resize +2", { desc = "Increase window height" }) +-- vim.keymap.set("n", "", "resize -2", { desc = "Decrease window height" }) +-- vim.keymap.set("n", "", "vertical resize -2", { desc = "Decrease window width" }) +-- vim.keymap.set("n", "", "vertical resize +2", { desc = "Increase window width" }) + +function WordDefinition(input) + -- Function to run the dict command and return its output + local function get_output(word) + local escaped_word = vim.fn.shellescape(word) + return vim.fn.system("dict " .. escaped_word) + end + + -- Function to process the word for singular/plural handling + local function get_definition(word) + -- Attempt to derive the singular form + local singular = word + if word:sub(-2) == "es" then + singular = word:sub(1, -3) -- Remove 'es' + elseif word:sub(-1) == "s" then + singular = word:sub(1, -2) -- Remove 's' + end + + -- Fetch output for both singular and original word + local singular_output = get_output(singular) + local original_output = get_output(word) + + -- Determine which output to prioritize + if singular ~= word and not vim.startswith(singular_output, "No definitions found") then + return singular_output -- Use singular if valid and different + else + return original_output -- Otherwise, use the original word + end + end + + -- Get the definition and output for the word + local output = get_definition(input) + + -- Create a new buffer and display the result + local bufnr = vim.api.nvim_create_buf(false, true) + vim.api.nvim_set_current_buf(bufnr) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.split(output, "\n")) +end +vim.api.nvim_set_keymap( + "n", + "k", + ":lua WordDefinition(vim.fn.expand(''))", + { noremap = true, silent = true, desc = "Word definition" } +) + +-- Lazy +vim.keymap.set("n", "L", "Lazy", { desc = "Open lazy plugin manager" }) + +-- Mason +vim.keymap.set("n", "M", "Mason", { desc = "Open mason" }) diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/lazy.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/lazy.lua new file mode 100644 index 0000000..52eff22 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/lazy.lua @@ -0,0 +1,39 @@ +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` and `maplocalleader` before +-- loading lazy.nvim so that mappings are correct. +-- This is also a good place to setup other settings (vim.opt) +-- vim.g.mapleader = " " +-- vim.g.maplocalleader = "\\" + +-- Setup lazy.nvim +require("lazy").setup({ + -- highlight-start + spec = { + -- import your plugins + { import = "TheSiahxyz.plugins" }, + }, + -- highlight-end + -- Configure any other settings here. See the documentation for more details. + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "catppuccin" } }, + -- automatically check for plugin updates + checker = { enabled = false }, + -- automatically check for config file changes and reload the ui + change_detection = { enabled = false }, +}) diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/options.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/options.lua new file mode 100644 index 0000000..86f4b49 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/core/options.lua @@ -0,0 +1,47 @@ +vim.g.have_nerd_font = true +-- vim.g.netrw_browse_split = 0 +-- vim.g.netrw_banner = 1 +-- vim.g.netrw_browsex_viewer = "xdg-open" +-- vim.g.netrw_liststyle = 0 +-- vim.g.netrw_list_hide = "^.git" +-- vim.g.netrw_winsize = 25 +-- vim.g.loaded_netrw = 1 +-- vim.g.loaded_netrwPlugin = 1 +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" +vim.o.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal,localoptions" +vim.opt.backup = false +vim.opt.breakindent = true +vim.opt.conceallevel = 1 +vim.opt.cursorline = true +vim.opt.encoding = "utf-8" +vim.opt.expandtab = true +vim.opt.fileencoding = "utf-8" +vim.opt.hlsearch = true +vim.opt.ignorecase = true +vim.opt.inccommand = "split" +vim.opt.incsearch = true +vim.opt.isfname:append("@-@") +vim.opt.list = true +vim.opt.listchars = { tab = " ", trail = " ", nbsp = " " } +vim.opt.mouse = "a" +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.scrolloff = 8 +vim.opt.shiftwidth = 2 +vim.opt.showmode = false +vim.opt.signcolumn = "yes" +vim.opt.smartcase = true +vim.opt.smartindent = true +vim.opt.softtabstop = 2 +vim.opt.spell = false +vim.opt.splitbelow = true +vim.opt.splitright = true +vim.opt.swapfile = false +vim.opt.tabstop = 2 +vim.opt.termguicolors = true +vim.opt.timeoutlen = 300 +vim.opt.updatetime = 300 +vim.opt.undofile = true +vim.opt.undodir = os.getenv("HOME") .. "/.local/share/history/vim_history" +vim.opt.wrap = false diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/health.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/health.lua new file mode 100644 index 0000000..dba5f3a --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/health.lua @@ -0,0 +1,45 @@ +local check_version = function() + local verstr = string.format("%s.%s.%s", vim.version().major, vim.version().minor, vim.version().patch) + if not vim.version.cmp then + vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr)) + return + end + + if vim.version.cmp(vim.version(), { 0, 9, 4 }) >= 0 then + vim.health.ok(string.format("Neovim version is: '%s'", verstr)) + else + vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr)) + end +end + +local check_external_reqs = function() + -- Basic utils: `git`, `make`, `unzip` + for _, exe in ipairs({ "git", "make", "unzip", "rg" }) do + local is_executable = vim.fn.executable(exe) == 1 + if is_executable then + vim.health.ok(string.format("Found executable: '%s'", exe)) + else + vim.health.warn(string.format("Could not find executable: '%s'", exe)) + end + end + + return true +end + +return { + check = function() + vim.health.start("TheSiahxyz") + + vim.health.info([[NOTE: Not every warning is a 'must-fix' in `:checkhealth` + + Fix only warnings for plugins and languages you intend to use. + Mason will give warnings for languages that are not installed. + You do not need to install, unless you want to use those languages!]]) + + local uv = vim.uv or vim.loop + vim.health.info("System Information: " .. vim.inspect(uv.os_uname())) + + check_version() + check_external_reqs() + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/init.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/init.lua new file mode 100644 index 0000000..58a3470 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/init.lua @@ -0,0 +1,15 @@ +-- Core +require("TheSiahxyz.core.options") +require("TheSiahxyz.core.keymaps") +require("TheSiahxyz.core.autocmds") +require("TheSiahxyz.core.lazy") + +-- Custom +for _, file in ipairs(vim.fn.readdir(vim.fn.stdpath("config") .. "/lua/TheSiahxyz/utils", [[v:val =~ '\.lua$']])) do + require("TheSiahxyz.utils." .. file:gsub("%.lua$", "")) +end + +-- Plenary +function R(name) + require("plenary.reload").reload_module(name) +end diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/ai.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/ai.lua new file mode 100644 index 0000000..45aa240 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/ai.lua @@ -0,0 +1,286 @@ +return { + { + "robitx/gp.nvim", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "G", group = "GPT" }, + { "Gg", group = "Gp" }, + { "GW", group = "Whisper" }, + }) + end, + config = function() + local function keymapOptions(desc) + return { + noremap = true, + silent = true, + nowait = true, + desc = desc, + } + end + + local conf = { + -- For customization, refer to Install > Configuration in the Documentation/Readme + -- openai_api_key = { "pass", "show", "api/chatGPT/nvim" }, + openai_api_key = { "pass", "show", "api/chatGPT/nvim" }, + providers = { + openai = { + disable = false, + endpoint = "https://api.openai.com/v1/chat/completions", + -- secret = { "pass", "show", "api/chatGPT/nvim" }, + }, + }, + hooks = { + -- GpInspectPlugin provides a detailed inspection of the plugin state + InspectPlugin = function(plugin, params) + local bufnr = vim.api.nvim_create_buf(false, true) + local copy = vim.deepcopy(plugin) + local key = copy.config.openai_api_key or "" + copy.config.openai_api_key = key:sub(1, 3) .. string.rep("*", #key - 6) .. key:sub(-3) + local plugin_info = string.format("Plugin structure:\n%s", vim.inspect(copy)) + local params_info = string.format("Command params:\n%s", vim.inspect(params)) + local lines = vim.split(plugin_info .. "\n" .. params_info, "\n") + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) + vim.api.nvim_win_set_buf(0, bufnr) + end, + + -- GpInspectLog for checking the log file + InspectLog = function(plugin, params) + local log_file = plugin.config.log_file + local buffer = plugin.helpers.get_buffer(log_file) + if not buffer then + vim.cmd("e " .. log_file) + else + vim.cmd("buffer " .. buffer) + end + end, + + -- GpImplement rewrites the provided selection/range based on comments in it + Implement = function(gp, params) + local template = "Having following from {{filename}}:\n\n" + .. "```{{filetype}}\n{{selection}}\n```\n\n" + .. "Please rewrite this according to the contained instructions." + .. "\n\nRespond exclusively with the snippet that should replace the selection above." + + local agent = gp.get_command_agent() + gp.logger.info("Implementing selection with agent: " .. agent.name) + + gp.Prompt( + params, + gp.Target.rewrite, + agent, + template, + nil, -- command will run directly without any prompting for user input + nil -- no predefined instructions (e.g. speech-to-text from Whisper) + ) + end, + + -- your own functions can go here, see README for more examples like + -- :GpExplain, :GpUnitTests.., :GpTranslator etc. + + -- example of making :%GpChatNew a dedicated command which + -- opens new chat with the entire current buffer as a context + BufferChatNew = function(gp, _) + -- call GpChatNew command in range mode on whole buffer + vim.api.nvim_command("%" .. gp.config.cmd_prefix .. "ChatNew") + end, + + -- example of adding command which opens new chat dedicated for translation + Translator = function(gp, params) + local chat_system_prompt = "You are a Translator, please translate between English and Korean." + gp.cmd.ChatNew(params, chat_system_prompt) + + -- -- you can also create a chat with a specific fixed agent like this: + -- local agent = gp.get_chat_agent("ChatGPT4o") + -- gp.cmd.ChatNew(params, chat_system_prompt, agent) + end, + + -- example of adding command which writes unit tests for the selected code + UnitTests = function(gp, params) + local template = "I have the following code from {{filename}}:\n\n" + .. "```{{filetype}}\n{{selection}}\n```\n\n" + .. "Please respond by writing table driven unit tests for the code above." + local agent = gp.get_command_agent() + gp.Prompt(params, gp.Target.enew, agent, template) + end, + + -- example of adding command which explains the selected code + Explain = function(gp, params) + local template = "I have the following code from {{filename}}:\n\n" + .. "```{{filetype}}\n{{selection}}\n```\n\n" + .. "Please respond by explaining the code above." + local agent = gp.get_chat_agent() + gp.Prompt(params, gp.Target.popup, agent, template) + end, + + -- example of usig enew as a function specifying type for the new buffer + CodeReview = function(gp, params) + local template = "I have the following code from {{filename}}:\n\n" + .. "```{{filetype}}\n{{selection}}\n```\n\n" + .. "Please analyze for code smells and suggest improvements." + local agent = gp.get_chat_agent() + gp.Prompt(params, gp.Target.enew("markdown"), agent, template) + end, + }, + } + require("gp").setup(conf) + + -- Setup shortcuts here (see Usage > Shortcuts in the Documentation/Readme) + vim.keymap.set({ "n", "i" }, "Gc", "GpChatNew", keymapOptions("New chat")) + vim.keymap.set({ "n", "i" }, "Gb", "GpBufferChatNew", keymapOptions("New buffer chat")) + vim.keymap.set({ "n", "i" }, "Gt", "GpChatToggle", keymapOptions("Toggle chat")) + vim.keymap.set({ "n", "i" }, "Gf", "GpChatFinder", keymapOptions("Chat finder")) + + vim.keymap.set("v", "Gc", ":'<,'>GpChatNew", keymapOptions("Chat new")) + vim.keymap.set("v", "Gb", ":'<,'>GpBufferChatNew", keymapOptions("Buffer chat new")) + vim.keymap.set("v", "Gp", ":'<,'>GpChatPaste", keymapOptions("Chat paste")) + vim.keymap.set("v", "Gt", ":'<,'>GpChatToggle", keymapOptions("Toggle chat")) + + vim.keymap.set({ "n", "i" }, "Gh", "gpchatnew split", keymapOptions("New chat split")) + vim.keymap.set({ "n", "i" }, "Gv", "gpchatnew vsplit", keymapOptions("New chat vsplit")) + vim.keymap.set({ "n", "i" }, "Gn", "gpchatnew tabnew", keymapOptions("New chat tabnew")) + + vim.keymap.set("v", "Gh", ":'<,'>GpChatNew split", keymapOptions("Chat new split")) + vim.keymap.set("v", "Gv", ":'<,'>GpChatNew vsplit", keymapOptions("Chat new vsplit")) + vim.keymap.set("v", "Gn", ":'<,'>GpChatNew tabnew", keymapOptions("Chat new tabnew")) + + -- Prompt commands + vim.keymap.set({ "n", "i" }, "Gw", "GpRewrite", keymapOptions("Inline rewrite")) + vim.keymap.set({ "n", "i" }, "Gr", "GpCodeReview", keymapOptions("Code review")) + vim.keymap.set({ "n", "i" }, "G]", "GpAppend", keymapOptions("Append (after)")) + vim.keymap.set({ "n", "i" }, "G[", "GpPrepend", keymapOptions("Prepend (before)")) + + vim.keymap.set("v", "Gw", ":'<,'>GpRewrite", keymapOptions("Rewrite")) + vim.keymap.set("v", "Gr", ":'<,'>GpCodeReview", keymapOptions("Code review")) + vim.keymap.set("v", "G]", ":'<,'>GpAppend", keymapOptions("Append (after)")) + vim.keymap.set("v", "G[", ":'<,'>GpPrepend", keymapOptions("Prepend (before)")) + vim.keymap.set("v", "Gi", ":'<,'>GpImplement", keymapOptions("Implement selection")) + + vim.keymap.set({ "n", "i" }, "Ggp", "GpPopup", keymapOptions("Popup")) + vim.keymap.set({ "n", "i" }, "Gge", "GpEnew", keymapOptions("GpEnew")) + vim.keymap.set({ "n", "i" }, "Ggc", "GpNew", keymapOptions("GpNew")) + vim.keymap.set({ "n", "i" }, "Ggv", "GpVnew", keymapOptions("GpVnew")) + vim.keymap.set({ "n", "i" }, "Ggn", "GpTabnew", keymapOptions("GpTabnew")) + + vim.keymap.set("v", "Ggp", ":'<,'>GpPopup", keymapOptions("Popup")) + vim.keymap.set("v", "Gge", ":'<,'>GpEnew", keymapOptions("GpEnew")) + vim.keymap.set("v", "Ggc", ":'<,'>GpNew", keymapOptions("GpNew")) + vim.keymap.set("v", "Ggv", ":'<,'>GpVnew", keymapOptions("GpVnew")) + vim.keymap.set("v", "Ggn", ":'<,'>GpTabnew", keymapOptions("GpTabnew")) + + vim.keymap.set({ "n", "i" }, "Gx", "GpContext", keymapOptions("Toggle context")) + vim.keymap.set("v", "Gx", ":'<,'>GpContext", keymapOptions("Toggle context")) + + vim.keymap.set({ "n", "i", "v", "x" }, "Ggs", "GpStop", keymapOptions("Stop")) + vim.keymap.set({ "n", "i", "v", "x" }, "Gg]", "GpNextAgent", keymapOptions("Next agent")) + + -- optional Whisper commands with prefix w + vim.keymap.set({ "n", "i" }, "GWw", "GpWhisper", keymapOptions("Whisper")) + vim.keymap.set("v", "GWw", ":'<,'>GpWhisper", keymapOptions("Whisper")) + + vim.keymap.set({ "n", "i" }, "GWr", "GpWhisperRewrite", keymapOptions("Inline rewrite")) + vim.keymap.set({ "n", "i" }, "GW]", "GpWhisperAppend", keymapOptions("Append (after)")) + vim.keymap.set({ "n", "i" }, "GW[", "GpWhisperPrepend", keymapOptions("Prepend (before) ")) + + vim.keymap.set("v", "GWr", ":'<,'>GpWhisperRewrite", keymapOptions("Rewrite")) + vim.keymap.set("v", "GW]", ":'<,'>GpWhisperAppend", keymapOptions("Append (after)")) + vim.keymap.set("v", "GW[", ":'<,'>GpWhisperPrepend", keymapOptions("Prepend (before)")) + + vim.keymap.set({ "n", "i" }, "GWp", "GpWhisperPopup", keymapOptions("Popup")) + vim.keymap.set({ "n", "i" }, "GWe", "GpWhisperEnew", keymapOptions("Enew")) + vim.keymap.set({ "n", "i" }, "GWc", "GpWhisperNew", keymapOptions("New")) + vim.keymap.set({ "n", "i" }, "GWv", "GpWhisperVnew", keymapOptions("Vnew")) + vim.keymap.set({ "n", "i" }, "GWn", "GpWhisperTabnew", keymapOptions("Tabnew")) + + vim.keymap.set("v", "GWp", ":'<,'>GpWhisperPopup", keymapOptions("Popup")) + vim.keymap.set("v", "GWe", ":'<,'>GpWhisperEnew", keymapOptions("Enew")) + vim.keymap.set("v", "GWc", ":'<,'>GpWhisperNew", keymapOptions("New")) + vim.keymap.set("v", "GWv", ":'<,'>GpWhisperVnew", keymapOptions("Vnew")) + vim.keymap.set("v", "GWn", ":'<,'>GpWhisperTabnew", keymapOptions("Tabnew")) + end, + }, + -- { + -- "zbirenbaum/copilot.lua", + -- cmd = "Copilot", + -- build = ":Copilot auth", + -- event = "InsertEnter", + -- dependencies = { + -- "hrsh7th/nvim-cmp", + -- { "AndreM222/copilot-lualine" }, + -- { + -- "zbirenbaum/copilot-cmp", + -- config = function() + -- require("copilot_cmp").setup() + -- end, + -- }, + -- }, + -- config = function() + -- require("copilot").setup({ + -- panel = { + -- enabled = true, + -- auto_refresh = true, + -- keymap = { + -- jump_prev = "[a", + -- jump_next = "]a", + -- accept = "", + -- refresh = "gr", + -- open = "", + -- }, + -- layout = { + -- position = "right", -- | top | left | right + -- ratio = 0.4, + -- }, + -- }, + -- suggestion = { + -- enabled = true, + -- auto_trigger = true, + -- hide_during_completion = true, + -- debounce = 75, + -- keymap = { + -- accept = "", + -- accept_word = false, + -- accept_line = false, + -- next = "", + -- prev = "", + -- dismiss = "", + -- }, + -- }, + -- filetypes = { + -- cvs = false, + -- gitcommit = false, + -- gitrebase = false, + -- help = true, + -- hgcommit = false, + -- markdown = true, + -- sh = function() + -- if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), "^%.env.*") then + -- -- disable for .env files + -- return false + -- end + -- return true + -- end, + -- svn = false, + -- yaml = false, + -- ["."] = false, + -- ["*"] = true, + -- }, + -- copilot_node_command = "node", -- Node.js version must be > 18.x + -- server_opts_overrides = {}, + -- }) + -- + -- local cmp = require("cmp") + -- cmp.event:on("menu_opened", function() + -- vim.b.copilot_suggestion_hidden = true + -- end) + -- + -- cmp.event:on("menu_closed", function() + -- vim.b.copilot_suggestion_hidden = false + -- end) + -- end, + -- + -- vim.keymap.set("n", "ct", function() + -- require("copilot.suggestion").toggle_auto_trigger() + -- end, { noremap = true, silent = true, desc = "Toggle copilot" }), + -- }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cloak.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cloak.lua new file mode 100644 index 0000000..ab26f00 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cloak.lua @@ -0,0 +1,42 @@ +return { + "laytan/cloak.nvim", + lazy = false, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "c", group = "Cloak" }, + }) + end, + config = function() + require("cloak").setup({ + enabled = true, + cloak_character = "*", + -- The applied highlight group (colors) on the cloaking, see `:h highlight`. + highlight_group = "Comment", + patterns = { + { + -- Match any file starting with ".env". + -- This can be a table to match multiple file patterns. + file_pattern = { + ".env*", + "wrangler.toml", + ".dev.vars", + "address*", + "*api*", + }, + -- Match an equals sign and any character after it. + -- This can also be a table of patterns to cloak, + -- example: cloak_pattern = { ":.+", "-.+" } for yaml files. + cloak_pattern = { "=.+", ":.+", "-.+" }, + }, + }, + }) + end, + keys = { + { "ce", "CloakEnable", desc = "Enable cloak" }, + { "cd", "CloakDisable", desc = "Disable cloak" }, + { "cl", "CloakPreviewLine", desc = "Preview line cloak" }, + { "zC", "CloakToggle", desc = "Toggle cloak" }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cmp.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cmp.lua new file mode 100644 index 0000000..2dd46f3 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/cmp.lua @@ -0,0 +1,331 @@ +local trigger_text = ";" + +return { + { + "hrsh7th/nvim-cmp", + event = "InsertEnter", + dependencies = { + "hrsh7th/cmp-buffer", -- source for text in buffer + "hrsh7th/cmp-path", -- source for file system paths + "hrsh7th/cmp-cmdline", -- source for cmd + "hrsh7th/cmp-vsnip", + "hrsh7th/vim-vsnip", + { + "L3MON4D3/LuaSnip", + version = "v2.*", -- Replace by the latest released major (first number of latest release) + build = "make install_jsregexp", + }, + "saadparwaiz1/cmp_luasnip", -- for autocompletion + "rafamadriz/friendly-snippets", -- useful snippets + "onsails/lspkind.nvim", -- vs-code like pictograms + "uga-rosa/cmp-dictionary", -- dictionary & spell + }, + config = function() + local cmp = require("cmp") + local luasnip = require("luasnip") + local has_words_before = function() + unpack = unpack or table.unpack + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 + and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end + + require("luasnip.loaders.from_vscode").lazy_load() + + cmp.setup({ + completion = { + completeopt = "menu,menuone,preview,noselect", + }, + snippet = { -- configure how nvim-cmp interacts with snippet engine + expand = function(args) + require("luasnip").lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.select_prev_item(), -- previous suggestion + [""] = cmp.mapping.select_next_item(), -- next suggestion + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.complete(), -- show completion suggestions + [""] = cmp.mapping.abort(), -- close completion window + [""] = cmp.mapping.close(), + [""] = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() + -- this way you will only jump inside the snippet region + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + -- sources for autocompletion + sources = cmp.config.sources({ + { name = "buffer" }, -- text within current buffer + { name = "crates" }, + { name = "copilot" }, + { name = "dictionary", keyword_length = 2 }, + { name = "emoji" }, + { name = "luasnip" }, -- snippets + { name = "nvim_lsp" }, + { name = "nvim_lua", priority = 100 }, + { name = "path" }, -- file system paths + { name = "projects", priority = 100 }, + { name = "snippets" }, + { name = "vim-dadbod-completion" }, -- Enable dadbod completion source + { name = "vsnip" }, + }), + + -- configure lspkind for vs-code like pictograms in completion menu + formatting = { + expandable_indicator = true, + fields = { + "abbr", + "kind", + "menu", + }, + format = require("lspkind").cmp_format({ + mode = "symbol_text", + maxwidth = 50, + ellipsis_char = "...", + menu = { + buffer = "[Buffer]", + luasnip = "[LuaSnip]", + nvim_lsp = "[LSP]", + nvim_lua = "[Lua]", + projects = "[Projects]", + emoji = "[Emoji]", + vsnip = "[Snippet]", + }, + }), + }, + }) + + -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline({ "/", "?" }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = "buffer" }, + }, + }) + + -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline(":", { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = "path" }, + }, { + { name = "cmdline" }, + }), + matching = { disallow_symbol_nonprefix_matching = false }, + }) + + -- sql + cmp.setup.filetype({ "sql" }, { + sources = { + { name = "vim-dadbod-completion" }, + { name = "buffer" }, + }, + }) + + local lspkind = require("lspkind") + lspkind.init({ + symbol_map = { + Copilot = "", + }, + }) + + vim.api.nvim_set_hl(0, "CmpItemKindCopilot", { fg = "#6CC644" }) + + require("cmp_dictionary").setup({ + paths = { "/usr/share/dict/words" }, + exact_length = 2, + first_case_insensitive = true, + document = { + enable = true, + command = { "wn", "${label}", "-over" }, + }, + }) + end, + }, + -- { + -- "saghen/blink.cmp", + -- version = "*", + -- -- build = "cargo build --release", + -- opts_extend = { + -- "sources.completion.enabled_providers", + -- "sources.compat", + -- "sources.default", + -- }, + -- enabled = true, + -- dependencies = { + -- { + -- "L3MON4D3/LuaSnip", + -- version = "v2.*", + -- build = "make install_jsregexp", + -- }, + -- "rafamadriz/friendly-snippets", + -- { + -- "saghen/blink.compat", + -- optional = true, -- make optional so it's only enabled if any extras need it + -- opts = {}, + -- version = "*", + -- }, + -- "kristjanhusak/vim-dadbod-completion", + -- "giuxtaposition/blink-cmp-copilot", + -- }, + -- event = "InsertEnter", + -- opts = function(_, opts) + -- opts.sources = vim.tbl_deep_extend("force", opts.sources or {}, { + -- default = { "lsp", "path", "snippets", "buffer", "copilot", "luasnip", "dadbod" }, + -- providers = { + -- lsp = { + -- name = "lsp", + -- enabled = true, + -- module = "blink.cmp.sources.lsp", + -- fallbacks = { "snippets", "luasnip", "buffer" }, + -- score_offset = 90, -- the higher the number, the higher the priority + -- }, + -- luasnip = { + -- name = "luasnip", + -- enabled = true, + -- module = "blink.cmp.sources.luasnip", + -- min_keyword_length = 2, + -- fallbacks = { "snippets" }, + -- score_offset = 85, + -- max_items = 8, + -- }, + -- path = { + -- name = "Path", + -- module = "blink.cmp.sources.path", + -- score_offset = 3, + -- -- When typing a path, I would get snippets and text in the + -- -- suggestions, I want those to show only if there are no path + -- -- suggestions + -- fallbacks = { "snippets", "luasnip", "buffer" }, + -- opts = { + -- trailing_slash = false, + -- label_trailing_slash = true, + -- get_cwd = function(context) + -- return vim.fn.expand(("#%d:p:h"):format(context.bufnr)) + -- end, + -- show_hidden_files_by_default = true, + -- }, + -- }, + -- buffer = { + -- name = "Buffer", + -- enabled = true, + -- max_items = 3, + -- module = "blink.cmp.sources.buffer", + -- min_keyword_length = 4, + -- }, + -- snippets = { + -- name = "Snippets", + -- enabled = true, + -- max_items = 3, + -- module = "blink.cmp.sources.snippets", + -- min_keyword_length = 4, + -- score_offset = 80, -- the higher the number, the higher the priority + -- }, + -- -- Example on how to configure dadbod found in the main repo + -- -- https://github.com/kristijanhusak/vim-dadbod-completion + -- dadbod = { + -- name = "Dadbod", + -- module = "vim_dadbod_completion.blink", + -- score_offset = 85, -- the higher the number, the higher the priority + -- }, + -- -- Third class citizen mf always talking shit + -- copilot = { + -- name = "Copilot", + -- enabled = true, + -- module = "blink-cmp-copilot", + -- min_keyword_length = 6, + -- score_offset = -100, -- the higher the number, the higher the priority + -- async = true, + -- }, + -- }, + -- -- command line completion, thanks to dpetka2001 in reddit + -- -- https://www.reddit.com/r/neovim/comments/1hjjf21/comment/m37fe4d/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button + -- cmdline = function() + -- local type = vim.fn.getcmdtype() + -- if type == "/" or type == "?" then + -- return { "buffer" } + -- end + -- if type == ":" then + -- return { "cmdline" } + -- end + -- return {} + -- end, + -- }) + -- + -- -- This comes from the luasnip extra, if you don't add it, won't be able to + -- -- jump forward or backward in luasnip snippets + -- opts.snippets = { + -- expand = function(snippet) + -- require("luasnip").lsp_expand(snippet) + -- end, + -- active = function(filter) + -- if filter and filter.direction then + -- return require("luasnip").jumpable(filter.direction) + -- end + -- return require("luasnip").in_snippet() + -- end, + -- jump = function(direction) + -- require("luasnip").jump(direction) + -- end, + -- } + -- + -- opts.appearance = { + -- -- sets the fallback highlight groups to nvim-cmp's highlight groups + -- -- useful for when your theme doesn't support blink.cmp + -- -- will be removed in a future release, assuming themes add support + -- use_nvim_cmp_as_default = false, + -- -- set to 'mono' for 'Nerd Font Mono' or 'normal' for 'Nerd Font' + -- -- adjusts spacing to ensure icons are aligned + -- nerd_font_variant = "mono", + -- } + -- + -- opts.completion = { + -- accept = { + -- -- experimental auto-brackets support + -- auto_brackets = { + -- enabled = true, + -- }, + -- }, + -- menu = { + -- draw = { + -- treesitter = { "lsp" }, + -- }, + -- }, + -- documentation = { + -- auto_show = true, + -- auto_show_delay_ms = 200, + -- }, + -- ghost_text = { enabled = true }, + -- } + -- + -- opts.keymap = { + -- preset = "super-tab", + -- } + -- + -- return opts + -- end, + -- }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorizer.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorizer.lua new file mode 100644 index 0000000..bd82542 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorizer.lua @@ -0,0 +1,76 @@ +return { + "catgoose/nvim-colorizer.lua", + event = "BufReadPre", + opts = { -- set to setup table + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "zh", group = "Colorizer" }, + }) + end, + config = function() + require("colorizer").setup({ + filetypes = { "*" }, -- Filetype options. Accepts table like `user_default_options` + buftypes = {}, -- Buftype options. Accepts table like `user_default_options` + -- Boolean | List of usercommands to enable. See User commands section. + user_commands = true, -- Enable all or some usercommands + lazy_load = false, -- Lazily schedule buffer highlighting setup function + user_default_options = { + names = false, -- "Name" codes like Blue or red. Added from `vim.api.nvim_get_color_map()` + names_opts = { -- options for mutating/filtering names. + lowercase = true, -- name:lower(), highlight `blue` and `red` + camelcase = true, -- name, highlight `Blue` and `Red` + uppercase = true, -- name:upper(), highlight `BLUE` and `RED` + strip_digits = false, -- ignore names with digits, + -- highlight `blue` and `red`, but not `blue3` and `red4` + }, + -- Expects a table of color name to #RRGGBB value pairs. # is optional + -- Example: { cool = "#107dac", ["notcool"] = "#ee9240" } + -- Set to false to disable, for example when setting filetype options + names_custom = false, -- Custom names to be highlighted: table|function|false + RGB = true, -- #RGB hex codes + RGBA = true, -- #RGBA hex codes + RRGGBB = true, -- #RRGGBB hex codes + RRGGBBAA = true, -- #RRGGBBAA hex codes + AARRGGBB = true, -- 0xAARRGGBB hex codes + rgb_fn = true, -- CSS rgb() and rgba() functions + hsl_fn = true, -- CSS hsl() and hsla() functions + css = true, -- Enable all CSS *features*: + -- names, RGB, RGBA, RRGGBB, RRGGBBAA, AARRGGBB, rgb_fn, hsl_fn + css_fn = false, -- Enable all CSS *functions*: rgb_fn, hsl_fn + -- Tailwind colors. boolean|'normal'|'lsp'|'both'. True sets to 'normal' + tailwind = true, -- Enable tailwind colors + tailwind_opts = { -- Options for highlighting tailwind names + update_names = false, -- When using tailwind = 'both', update tailwind names from LSP results. See tailwind section + }, + -- parsers can contain values used in `user_default_options` + sass = { enable = false, parsers = { "css" } }, -- Enable sass colors + -- Highlighting mode. 'background'|'foreground'|'virtualtext' + mode = "background", -- Set the display mode + -- Virtualtext character to use + virtualtext = "■", + -- Display virtualtext inline with color. boolean|'before'|'after'. True sets to 'after' + virtualtext_inline = false, + -- Virtualtext highlight mode: 'background'|'foreground' + virtualtext_mode = "foreground", + -- update color values even if buffer is not focused + -- example use: cmp_menu, cmp_docs + always_update = false, + -- hooks to invert control of colorizer + hooks = { + -- called before line parsing. Accepts boolean or function that returns boolean + -- see hooks section below + disable_line_highlight = false, + }, + }, + }) + end, + keys = { + { "zha", "ColorizerAttachToBuffer", desc = "Attach colorizer" }, + { "zhd", "ColorizerDetachFromBuffer", desc = "Detach colorizer" }, + { "zhr", "ColorizerReloadAllBuffers", desc = "Refresh colorizer" }, + { "zht", "ColorizerToggle", desc = "Toggle colorizer" }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorschemes.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorschemes.lua new file mode 100644 index 0000000..8fce515 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/colorschemes.lua @@ -0,0 +1,350 @@ +function ColorMyPencils(color) + color = color or "catppuccin" + vim.cmd.colorscheme(color) + local set = vim.api.nvim_set_hl + set(0, "Normal", { bg = "NONE" }) + set(0, "NormalFloat", { bg = "NONE" }) + set(0, "@comment.todo", { bg = "NONE" }) + set(0, "@comment.note", { bg = "NONE" }) + set(0, "@comment.warning", { bg = "NONE" }) + set(0, "@comment.error", { bg = "NONE" }) + set(0, "@number", { bg = "NONE" }) + set(0, "@string.special.url", { bg = "NONE" }) +end + +return { + { "junegunn/seoul256.vim" }, + { + "catppuccin/nvim", + name = "catppuccin", + config = function() + require("catppuccin").setup({ + flavour = "auto", -- latte, frappe, macchiato, mocha + background = { -- :h background + light = "latte", + dark = "mocha", + }, + transparent_background = true, -- disables setting the background color. + show_end_of_buffer = false, -- shows the '~' characters after the end of buffers + term_colors = false, -- sets terminal colors (e.g. `g:terminal_color_0`) + dim_inactive = { + enabled = true, -- dims the background color of inactive window + shade = "dark", + percentage = 0.15, -- percentage of the shade to apply to the inactive window + }, + no_italic = false, -- Force no italic + no_bold = false, -- Force no bold + no_underline = false, -- Force no underline + styles = { -- Handles the styles of general hi groups (see `:h highlight-args`): + comments = { "italic" }, -- Change the style of comments + conditionals = { "italic" }, + loops = {}, + functions = {}, + keywords = {}, + strings = {}, + variables = {}, + numbers = {}, + booleans = {}, + properties = {}, + types = {}, + operators = {}, + -- miscs = {}, -- Uncomment to turn off hard-coded styles + }, + color_overrides = {}, + custom_highlights = {}, + default_integrations = true, + integrations = { + aerial = true, + alpha = true, + blink_cmp = true, + cmp = true, + dashboard = true, + flash = true, + gitsigns = true, + headlines = true, + illuminate = true, + indent_blankline = { enabled = true, scope_color = "peach", colored_indent_levels = true }, + leap = true, + lsp_trouble = true, + mason = true, + markdown = true, + mini = true, + native_lsp = { + enabled = true, + underlines = { + errors = { "undercurl" }, + hints = { "undercurl" }, + warnings = { "undercurl" }, + information = { "undercurl" }, + }, + }, + navic = { enabled = true, custom_bg = "NONE" }, + neotest = true, + neotree = true, + noice = true, + notify = true, + semantic_tokens = true, + telescope = true, + treesitter = true, + treesitter_context = true, + which_key = true, + }, + highlight_overrides = { + mocha = function(mocha) + return { + LineNr = { fg = mocha.overlay2 }, + CursorLineNr = { fg = mocha.sky }, + Normal = { bg = "NONE" }, -- normal text + NormalNC = { bg = "NONE" }, + } + end, + }, + }) + + ColorMyPencils() + end, + }, + { + "ellisonleao/gruvbox.nvim", + priority = 1000, + -- opts = ..., + config = function() + require("gruvbox").setup({ + terminal_colors = true, -- add neovim terminal colors + undercurl = true, + underline = true, + bold = true, + italic = { + strings = true, + emphasis = true, + comments = true, + operators = false, + folds = true, + }, + strikethrough = true, + invert_selection = false, + invert_signs = false, + invert_tabline = false, + invert_intend_guides = false, + inverse = true, -- invert background for search, diffs, statuslines and errors + contrast = "", -- can be "hard", "soft" or empty string + palette_overrides = { + dark1 = "NONE", + }, + overrides = {}, + dim_inactive = true, + transparent_mode = true, + }) + end, + }, + { + "rose-pine/neovim", + name = "rose-pine", + config = function() + require("rose-pine").setup({ + variant = "auto", -- auto, main, moon, or dawn + dark_variant = "main", -- main, moon, or dawn + dim_inactive_windows = false, + extend_background_behind_borders = true, + enable = { + terminal = true, + legacy_highlights = true, -- Improve compatibility for previous versions of Neovim + migrations = true, -- Handle deprecated options automatically + }, + styles = { + bold = true, + italic = false, + transparency = true, + }, + groups = { + border = "muted", + link = "iris", + panel = "surface", + + error = "love", + hint = "iris", + info = "foam", + note = "pine", + todo = "rose", + warn = "gold", + + git_add = "foam", + git_change = "rose", + git_delete = "love", + git_dirty = "rose", + git_ignore = "muted", + git_merge = "iris", + git_rename = "pine", + git_stage = "iris", + git_text = "rose", + git_untracked = "subtle", + + h1 = "iris", + h2 = "foam", + h3 = "rose", + h4 = "gold", + h5 = "pine", + h6 = "foam", + }, + palette = { + -- Override the builtin palette per variant + -- moon = { + -- base = '#18191a', + -- overlay = '#363738', + -- }, + }, + highlight_groups = { + -- Comment = { fg = "foam" }, + -- VertSplit = { fg = "muted", bg = "muted" }, + }, + before_highlight = function(group, highlight, palette) + -- Disable all undercurls + -- if highlight.undercurl then + -- highlight.undercurl = false + -- end + -- + -- Change palette colour + -- if highlight.fg == palette.pine then + -- highlight.fg = palette.foam + -- end + end, + }) + -- vim.cmd("colorscheme rose-pine") + -- vim.cmd("colorscheme rose-pine-main") + -- vim.cmd("colorscheme rose-pine-moon") + -- vim.cmd("colorscheme rose-pine-dawn") + end, + }, + { + "Mofiqul/dracula.nvim", + config = function() + local dracula = require("dracula") + dracula.setup({ + -- customize dracula color palette + colors = { + bg = "#282A36", + fg = "#F8F8F2", + selection = "#44475A", + comment = "#6272A4", + red = "#FF5555", + orange = "#FFB86C", + yellow = "#F1FA8C", + green = "#50fa7b", + purple = "#BD93F9", + cyan = "#8BE9FD", + pink = "#FF79C6", + bright_red = "#FF6E6E", + bright_green = "#69FF94", + bright_yellow = "#FFFFA5", + bright_blue = "#D6ACFF", + bright_magenta = "#FF92DF", + bright_cyan = "#A4FFFF", + bright_white = "#FFFFFF", + menu = "#21222C", + visual = "#3E4452", + gutter_fg = "#4B5263", + nontext = "#3B4048", + white = "#ABB2BF", + black = "#191A21", + }, + -- show the '~' characters after the end of buffers + show_end_of_buffer = true, -- default false + -- use transparent background + transparent_bg = true, -- default false + -- set custom lualine background color + lualine_bg_color = "#44475a", -- default nil + -- set italic comment + italic_comment = true, -- default false + -- overrides the default highlights with table see `:h synIDattr` + overrides = {}, + -- You can use overrides as table like this + -- overrides = { + -- NonText = { fg = "white" }, -- set NonText fg to white + -- NvimTreeIndentMarker = { link = "NonText" }, -- link to NonText highlight + -- Nothing = {} -- clear highlight of Nothing + -- }, + -- Or you can also use it like a function to get color from theme + -- overrides = function (colors) + -- return { + -- NonText = { fg = colors.white }, -- set NonText fg to white of theme + -- } + -- end, + }) + end, + }, + { + "neanias/everforest-nvim", + priority = 1000, -- make sure to load this before all the other start plugins + -- Optional; default configuration will be used if setup isn't called. + config = function() + require("everforest").setup({ + ---Controls the "hardness" of the background. Options are "soft", "medium" or "hard". + ---Default is "medium". + background = "hard", + ---How much of the background should be transparent. 2 will have more UI + ---components be transparent (e.g. status line background) + transparent_background_level = 2, + ---Whether italics should be used for keywords and more. + italics = false, + ---Disable italic fonts for comments. Comments are in italics by default, set + ---this to `true` to make them _not_ italic! + disable_italic_comments = false, + ---By default, the colour of the sign column background is the same as the as normal text + ---background, but you can use a grey background by setting this to `"grey"`. + sign_column_background = "none", + ---The contrast of line numbers, indent lines, etc. Options are `"high"` or + ---`"low"` (default). + ui_contrast = "low", + ---Dim inactive windows. Only works in Neovim. Can look a bit weird with Telescope. + --- + ---When this option is used in conjunction with show_eob set to `false`, the + ---end of the buffer will only be hidden inside the active window. Inside + ---inactive windows, the end of buffer filler characters will be visible in + ---dimmed symbols. This is due to the way Vim and Neovim handle `EndOfBuffer`. + dim_inactive_windows = false, + ---Some plugins support highlighting error/warning/info/hint texts, by + ---default these texts are only underlined, but you can use this option to + ---also highlight the background of them. + diagnostic_text_highlight = false, + ---Which colour the diagnostic text should be. Options are `"grey"` or `"coloured"` (default) + diagnostic_virtual_text = "coloured", + ---Some plugins support highlighting error/warning/info/hint lines, but this + ---feature is disabled by default in this colour scheme. + diagnostic_line_highlight = false, + ---By default, this color scheme won't colour the foreground of |spell|, instead + ---colored under curls will be used. If you also want to colour the foreground, + ---set this option to `true`. + spell_foreground = false, + ---Whether to show the EndOfBuffer highlight. + show_eob = true, + ---Style used to make floating windows stand out from other windows. `"bright"` + ---makes the background of these windows lighter than |hl-Normal|, whereas + ---`"dim"` makes it darker. + --- + ---Floating windows include for instance diagnostic pop-ups, scrollable + ---documentation windows from completion engines, overlay windows from + ---installers, etc. + --- + ---NB: This is only significant for dark backgrounds as the light palettes + ---have the same colour for both values in the switch. + float_style = "bright", + ---Inlay hints are special markers that are displayed inline with the code to + ---provide you with additional information. You can use this option to customize + ---the background color of inlay hints. + --- + ---Options are `"none"` or `"dimmed"`. + inlay_hints_background = "none", + ---You can override specific highlights to use other groups or a hex colour. + ---This function will be called with the highlights and colour palette tables. + ---@param highlight_groups Highlights + ---@param palette Palette + on_highlights = function(highlight_groups, palette) end, + ---You can override colours in the palette to use different hex colours. + ---This function will be called once the base and background colours have + ---been mixed on the palette. + ---@param palette Palette + colours_override = function(palette) end, + }) + end, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/comment.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/comment.lua new file mode 100644 index 0000000..eb93c01 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/comment.lua @@ -0,0 +1,8 @@ +return { + "numToStr/Comment.nvim", + lazy = false, + opts = {}, + config = function() + require("Comment").setup() + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/compiler.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/compiler.lua new file mode 100644 index 0000000..9dad4f8 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/compiler.lua @@ -0,0 +1,53 @@ +return { + { -- This plugin + "Zeioth/compiler.nvim", + cmd = { "CompilerOpen", "CompilerToggleResults", "CompilerRedo" }, + dependencies = { "stevearc/overseer.nvim", "nvim-telescope/telescope.nvim" }, + opts = {}, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "r", group = "Compiler/Refactoring" }, + }) + end, + keys = { + -- Open compiler + vim.api.nvim_set_keymap( + "n", + "ro", + "CompilerOpen", + { noremap = true, silent = true, desc = "Open compiler" } + ), + + -- Redo last selected option + vim.api.nvim_set_keymap( + "n", + "re", + "CompilerStop" -- (Optional, to dispose all tasks before redo) + .. "CompilerRedo", + { noremap = true, silent = true, desc = "Recompile" } + ), + -- Toggle compiler results + vim.api.nvim_set_keymap( + "n", + "rt", + "CompilerToggleResults", + { noremap = true, silent = true, desc = "Toggle compiler" } + ), + }, + }, + { -- The task runner we use + "stevearc/overseer.nvim", + commit = "6271cab7ccc4ca840faa93f54440ffae3a3918bd", + cmd = { "CompilerOpen", "CompilerToggleResults", "CompilerRedo" }, + opts = { + task_list = { + direction = "bottom", + min_height = 25, + max_height = 25, + default_detail = 1, + }, + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/context.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/context.lua new file mode 100644 index 0000000..e2d8d2b --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/context.lua @@ -0,0 +1,25 @@ +return { + "nvim-treesitter/nvim-treesitter-context", + cmd = { "TSContextEnable", "TSContextDisable", "TSContextToggle" }, + config = function() + require("treesitter-context").setup({ + enable = false, -- Enable this plugin (Can be enabled/disabled later via commands) + max_lines = 3, -- How many lines the window should span. Values <= 0 mean no limit. + min_window_height = 1, -- Minimum editor window height to enable context. Values <= 0 mean no limit. + line_numbers = true, + multiline_threshold = 20, -- Maximum number of lines to show for a single context + trim_scope = "outer", -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' + mode = "cursor", -- Line used to calculate context. Choices: 'cursor', 'topline' + -- Separator between context and content. Should be a single character string, like '-'. + -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. + separator = nil, + zindex = 20, -- The Z-index of the context window + on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching + }) + + vim.keymap.set("n", "[t", function() + require("treesitter-context").go_to_context(vim.v.count1) + end, { silent = true, desc = "Go to context" }) + vim.keymap.set({ "n", "v" }, "zc", "TSContextToggle", { desc = "Toggle context" }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/csv.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/csv.lua new file mode 100644 index 0000000..bcf0239 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/csv.lua @@ -0,0 +1,55 @@ +return { + { + "hat0uma/csvview.nvim", + cmd = { "CsvViewEnable", "CsvViewDisable", "CsvViewToggle" }, + event = { "BufReadPre *.csv" }, -- Lazy-load the plugin when a CSV file is about to be read + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "cs", group = "csv" }, + }) + end, + config = function() + require("csvview").setup() + + vim.api.nvim_create_autocmd("BufRead", { + pattern = "*.csv", + callback = function() + vim.cmd("CsvViewEnable") + end, + }) + + vim.api.nvim_create_autocmd("FileType", { + pattern = "csv", + callback = function() + vim.keymap.set( + "n", + "zv", + "CsvViewToggle", + { desc = "Toggle CSV view", buffer = true } + ) + end, + }) + end, + keys = { + { + "csv", + function() + local delimiter = vim.fn.input("Delimiter (e.g., ,): ") + local quote_char = vim.fn.input("Quote char (e.g., '): ") + local comment = vim.fn.input("Comment char (e.g., #): ") + local command = string.format( + ":CsvViewToggle delimiter=%s quote_char=%s comment=%s", + delimiter, + quote_char, + comment + ) + + vim.cmd(command) + end, + desc = "Toggle CSV view", + }, + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dadbod.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dadbod.lua new file mode 100644 index 0000000..5004a1c --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dadbod.lua @@ -0,0 +1,53 @@ +return { + "kristijanhusak/vim-dadbod-ui", + dependencies = { + { "tpope/vim-dadbod", lazy = true }, + { "kristijanhusak/vim-dadbod-completion", ft = { "sql", "mysql", "plsql" }, lazy = true }, + }, + cmd = { + "DBUI", + "DBUIToggle", + "DBUIAddConnection", + "DBUIFindBuffer", + }, + init = function() + -- Your DBUI configuration + vim.g.db_ui_use_nerd_fonts = 1 + local home = vim.fn.expand("~") + vim.g.dbs = { + firefox = "sqlite://" .. home .. "/.mozilla/firefox/si.default/places.sqlite", + mysql = "mariadb://user:password@localhost/mysql", + postsql = "postgresql://postgres:mypassword@localhost:5432/postgresql", + qutebrowser = "sqlite://" .. home .. "/.local/share/qutebrowser/history.sqlite", + sqlite = "sqlite://" .. home .. "/.local/share/db/sqlite.db", + } + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "d", group = "DB" }, + }) + end, + config = function() + local function db_completion() + require("cmp").setup.buffer({ sources = { { name = "vim-dadbod-completion" } } }) + end + vim.api.nvim_create_autocmd("FileType", { + pattern = { + "sql", + "mysql", + "plsql", + }, + callback = function() + vim.schedule(db_completion) + end, + }) + end, + keys = { + { "du", "DBUI", desc = "DB UI" }, + { "dt", "DBUIToggle", desc = "Toggle DB UI" }, + { "da", "DBUIAddConnection", desc = "Add connection" }, + { "df", "DBUIFindBuffer", desc = "Find buffer" }, + { "dr", "DBUIRenameBuffer", desc = "Rename buffer" }, + { "di", "DBUILastQueryInfo", desc = "Last query info" }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dap.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dap.lua new file mode 100644 index 0000000..fac4e5c --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/dap.lua @@ -0,0 +1,310 @@ +local function get_args(config) + local args = type(config.args) == "function" and (config.args() or {}) or config.args or {} + config = vim.deepcopy(config) + ---@cast args string[] + config.args = function() + local new_args = vim.fn.input("Run with args: ", table.concat(args, " ")) --[[@as string]] + return vim.split(vim.fn.expand(new_args) --[[@as string]], " ") + end + return config +end + +return { + { + "mfussenegger/nvim-dap", + recommended = true, + desc = "Debugging support. Requires language specific adapters to be configured. (see lang extras)", + dependencies = { + "rcarriga/nvim-dap-ui", + -- virtual text for the debugger + { + "theHamsta/nvim-dap-virtual-text", + opts = {}, + }, + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "dp", group = "Debug" }, + { "dP", group = "Debug (Python)" }, + }) + end, + config = function() + -- load mason-nvim-dap here, after all adapters have been setup + vim.api.nvim_set_hl(0, "DapStoppedLine", { default = true, link = "Visual" }) + + local dap = require("dap") + dap.configurations.java = { + { + type = "java", + request = "attach", + name = "Debug (Attach) - Remote", + hostName = "127.0.0.1", + port = 5005, + }, + } + + local dap_icons = { + Stopped = { "󰁕 ", "DiagnosticWarn", "DapStoppedLine" }, + Breakpoint = " ", + BreakpointCondition = " ", + BreakpointRejected = { " ", "DiagnosticError" }, + LogPoint = ".>", + } + + for name, sign in pairs(dap_icons) do + sign = type(sign) == "table" and sign or { sign } + vim.fn.sign_define( + "Dap" .. name, + { text = sign[1], texthl = sign[2] or "DiagnosticInfo", linehl = sign[3], numhl = sign[3] } + ) + end + + -- setup dap config by VsCode launch.json file + local vscode = require("dap.ext.vscode") + local json = require("plenary.json") + vscode.json_decode = function(str) + return vim.json.decode(json.json_strip_comments(str)) + end + end, + keys = { + { + "dpB", + function() + require("dap").set_breakpoint(vim.fn.input("Breakpoint condition: ")) + end, + desc = "Dap breakpoint condition", + }, + { + "dpb", + function() + require("dap").toggle_breakpoint() + end, + desc = "Dap toggle breakpoint", + }, + { + "dpc", + function() + require("dap").continue() + end, + desc = "Dap continue", + }, + { + "dpa", + function() + require("dap").continue({ before = get_args }) + end, + desc = "Dap run with args", + }, + { + "dpC", + function() + require("dap").run_to_cursor() + end, + desc = "Dap run to cursor", + }, + { + "dpg", + function() + require("dap").goto_() + end, + desc = "Dap go to line (no execute)", + }, + { + "dpi", + function() + require("dap").step_into() + end, + desc = "Dap step into", + }, + { + "dpj", + function() + require("dap").down() + end, + desc = "Dap down", + }, + { + "dpk", + function() + require("dap").up() + end, + desc = "Dap up", + }, + { + "dpl", + function() + require("dap").run_last() + end, + desc = "Dap run last", + }, + { + "dpo", + function() + require("dap").step_out() + end, + desc = "Dap step out", + }, + { + "dpO", + function() + require("dap").step_over() + end, + desc = "Dap step over", + }, + { + "dpp", + function() + require("dap").pause() + end, + desc = "Dap pause", + }, + { + "dpr", + function() + require("dap").repl.toggle() + end, + desc = "Dap toggle repl", + }, + { + "dps", + function() + require("dap").session() + end, + desc = "Dap session", + }, + { + "dpt", + function() + require("dap").terminate() + end, + desc = "Dap terminate", + }, + { + "dpw", + function() + require("dap.ui.widgets").hover() + end, + desc = "Dap widgets", + }, + { + "dpR", + "lua require('dapui').open({ reset = true })", + desc = "Dap UI reset", + }, + }, + }, + { + "mfussenegger/nvim-dap-python", + ft = "python", + dependencies = { "mfussenegger/nvim-dap", "rcarriga/nvim-dap-ui" }, + config = function() + local path = "~/.local/share/nvim/mason/packages/debugpy/venv/bin/python" + require("dap-python").setup(path) + end, + keys = { + { + "dPt", + function() + require("dap-python").test_method() + end, + desc = "Dap debug method", + ft = "python", + }, + { + "dPc", + function() + require("dap-python").test_class() + end, + desc = "Dap debug class", + ft = "python", + }, + }, + }, + { + "rcarriga/nvim-dap-ui", + dependencies = { "mfussenegger/nvim-dap", "nvim-neotest/nvim-nio" }, + config = function() + local dap = require("dap") + local dapui = require("dapui") + dapui.setup({ + icons = { expanded = "▾", collapsed = "▸", current_frame = "*" }, + controls = { + icons = { + pause = "⏸", + play = "▶", + step_into = "⏎", + step_over = "⏭", + step_out = "⏮", + step_back = "b", + run_last = "▶▶", + terminate = "⏹", + disconnect = "⏏", + }, + }, + }) + + dap.listeners.before.attach.dapui_config = function() + dapui.open() + end + dap.listeners.before.launch.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 + + dap.listeners.after.event_initialized["dapui_config"] = function() + dapui.open() + end + dap.listeners.after.event_terminated["dapui_config"] = function() + dapui.close() + end + dap.listeners.after.event_exited["dapui_config"] = function() + dapui.close() + end + end, + keys = { + { + "dpu", + function() + require("dapui").toggle() + end, + desc = "Dap UI", + }, + { + "dpe", + function() + require("dapui").eval() + end, + desc = "Dap eval", + }, + }, + }, + { + "jay-babu/mason-nvim-dap.nvim", + dependencies = "mason.nvim", + cmd = { "DapInstall", "DapUninstall" }, + opts = { + -- Makes a best effort to setup the various debuggers with + -- reasonable debug configurations + automatic_installation = true, + + -- You can provide additional configuration to the handlers, + -- see mason-nvim-dap README for more information + handlers = {}, + + -- You'll need to check that you have the required things installed + -- online, please don't ask me how to install them :) + ensure_installed = { + -- Update this to ensure that you have the debuggers for the langs you want + }, + }, + -- mason-nvim-dap is loaded when nvim-dap loads + config = function() end, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/docker.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/docker.lua new file mode 100644 index 0000000..7bc26d5 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/docker.lua @@ -0,0 +1,222 @@ +return { + "https://codeberg.org/esensar/nvim-dev-container", + dependencies = "nvim-treesitter/nvim-treesitter", + config = function() + require("devcontainer").setup({ + config_search_start = function() + -- By default this function uses vim.loop.cwd() + -- This is used to find a starting point for .devcontainer.json file search + -- Since by default, it is searched for recursively + -- That behavior can also be disabled + end, + workspace_folder_provider = function() + -- By default this function uses first workspace folder for integrated lsp if available and vim.loop.cwd() as a fallback + -- This is used to replace `${localWorkspaceFolder}` in devcontainer.json + -- Also used for creating default .devcontainer.json file + end, + terminal_handler = function(command) + -- By default this function creates a terminal in a new tab using :terminal command + -- It also removes statusline when that tab is active, to prevent double statusline + -- It can be overridden to provide custom terminal handling + end, + nvim_installation_commands_provider = function(path_binaries, version_string) + -- Returns table - list of commands to run when adding neovim to container + -- Each command can either be a string or a table (list of command parts) + -- Takes binaries available in path on current container and version_string passed to the command or current version of neovim + end, + devcontainer_json_template = function() + -- Returns table - list of lines to set when creating new devcontainer.json files + -- As a template + -- Used only when using functions from commands module or created commands + end, + -- Can be set to false to prevent generating default commands + -- Default commands are listed below + generate_commands = true, + -- By default no autocommands are generated + -- This option can be used to configure automatic starting and cleaning of containers + autocommands = { + -- can be set to true to automatically start containers when devcontainer.json is available + init = false, + -- can be set to true to automatically remove any started containers and any built images when exiting vim + clean = false, + -- can be set to true to automatically restart containers when devcontainer.json file is updated + update = false, + }, + -- can be changed to increase or decrease logging from library + log_level = "info", + -- can be set to true to disable recursive search + -- in that case only .devcontainer.json and .devcontainer/devcontainer.json files will be checked relative + -- to the directory provided by config_search_start + disable_recursive_config_search = false, + -- can be set to false to disable image caching when adding neovim + -- by default it is set to true to make attaching to containers faster after first time + cache_images = true, + -- By default all mounts are added (config, data and state) + -- This can be changed to disable mounts or change their options + -- This can be useful to mount local configuration + -- And any other mounts when attaching to containers with this plugin + attach_mounts = { + neovim_config = { + -- enables mounting local config to /root/.config/nvim in container + enabled = false, + -- makes mount readonly in container + options = { "readonly" }, + }, + neovim_data = { + -- enables mounting local data to /root/.local/share/nvim in container + enabled = false, + -- no options by default + options = {}, + }, + -- Only useful if using neovim 0.8.0+ + neovim_state = { + -- enables mounting local state to /root/.local/state/nvim in container + enabled = false, + -- no options by default + options = {}, + }, + }, + -- This takes a list of mounts (strings) that should always be added to every run container + -- This is passed directly as --mount option to docker command + -- Or multiple --mount options if there are multiple values + always_mount = {}, + -- This takes a string (usually either "podman" or "docker") representing container runtime - "devcontainer-cli" is also partially supported + -- That is the command that will be invoked for container operations + -- If it is nil, plugin will use whatever is available (trying "podman" first) + container_runtime = nil, + -- Similar to container runtime, but will be used if main runtime does not support an action - useful for "devcontainer-cli" + backup_runtime = nil, + -- This takes a string (usually either "podman-compose" or "docker-compose") representing compose command - "devcontainer-cli" is also partially supported + -- That is the command that will be invoked for compose operations + -- If it is nil, plugin will use whatever is available (trying "podman-compose" first) + compose_command = nil, + -- Similar to compose command, but will be used if main command does not support an action - useful for "devcontainer-cli" + backup_compose_command = nil, + }) + end, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "d", group = "Docker" }, + { "db", group = "Build (docker)" }, + { "dc", group = "Compose (docker)" }, + { "do", group = "Open (docker)" }, + { "dr", group = "Run (docker)" }, + }) + end, + keys = { + { + "dcu", + function() + require("devcontainer.commands").compose_up() + end, + desc = "Compose up (docker)", + }, + { + "dcd", + function() + require("devcontainer.commands").compose_down() + end, + desc = "Compose down (docker)", + }, + { + "dcD", + function() + require("devcontainer.commands").compose_rm() + end, + desc = "Compose remove (docker)", + }, + { + "dbb", + function() + require("devcontainer.commands").docker_build() + end, + desc = "Build (docker)", + }, + { + "dri", + function() + require("devcontainer.commands").docker_image_run() + end, + desc = "Image run (docker)", + }, + { + "dbr", + function() + require("devcontainer.commands").docker_build_and_run() + end, + desc = "Build & run (docker)", + }, + { + "dba", + function() + require("devcontainer.commands").docker_build_run_and_attach() + end, + desc = "Build & attach (docker)", + }, + { + "ds", + function() + require("devcontainer.commands").start_auto() + end, + desc = "Start (docker)", + }, + { + "da", + function() + require("devcontainer.commands").attach_auto() + end, + desc = "Attach (docker)", + }, + { + "drr", + function() + require("devcontainer.commands").exec("devcontainer", "ls", { on_success = function(result) end }) + end, + desc = "Execute (docker)", + }, + { + "dx", + function() + require("devcontainer.commands").stop_auto() + end, + desc = "Stop (docker)", + }, + { + "dX", + function() + require("devcontainer.commands").stop_all() + end, + desc = "Stop all (docker)", + }, + { + "dD", + function() + require("devcontainer.commands").remove_all() + end, + desc = "Remove all (docker)", + }, + { + "dol", + function() + require("devcontainer.commands").open_logs() + end, + desc = "Open logs (docker)", + }, + { + "doc", + function() + require("devcontainer.commands").open_nearest_devcontainer_config() + end, + desc = "Open nearest config (docker)", + }, + { + "de", + function() + require("devcontainer.commands").edit_devcontainer_config() + end, + desc = "Edit nearest config (docker)", + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/git.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/git.lua new file mode 100644 index 0000000..399b263 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/git.lua @@ -0,0 +1,215 @@ +return { + { + "moyiz/git-dev.nvim", + event = "VeryLazy", + opts = {}, + config = function() + require("git-dev").setup() + + local function copy_git_repo_url() + -- Get the Git repository root + local git_root = vim.fn.system("git rev-parse --show-toplevel"):gsub("\n", "") + if git_root == "" then + vim.notify("Not inside a Git repository", vim.log.levels.WARN) + return nil + end + + -- Get the remote URL + local remote_url = vim.fn.system("git config --get remote.origin.url"):gsub("\n", "") + if remote_url == "" then + vim.notify("No remote URL found", vim.log.levels.WARN) + return nil + end + + -- Convert SSH URL to HTTPS if needed + if remote_url:match("^git@") then + remote_url = remote_url:gsub("git@", "https://"):gsub(":", "/") + end + + -- Remove `.git` from the remote URL + remote_url = remote_url:gsub("%.git$", "") + + -- Get the relative path of the current file + local file_path = vim.fn.expand("%:~:.") + if file_path == "" then + vim.notify("No file currently open", vim.log.levels.WARN) + return nil + end + + -- Get the relative path to the repository root + local relative_path = + vim.fn.system("git ls-files --full-name " .. vim.fn.shellescape(file_path)):gsub("\n", "") + + -- Combine the remote URL with the relative file path + local full_url = remote_url .. "/" .. relative_path + + -- Copy to clipboard + vim.fn.setreg("+", full_url) + vim.notify("Copied to clipboard: " .. full_url, vim.log.levels.INFO) + + return full_url + end + + -- Keybinding to copy the Git repository URL + vim.keymap.set("n", "cg", function() + copy_git_repo_url() + end, { desc = "Copy git repository URL to clipboard" }) + + -- Function to open a repository from the clipboard + vim.keymap.set("n", "eg", function() + local url = vim.fn.getreg("+") -- Get URL from clipboard + if not url or url == "" then + vim.notify("Clipboard is empty. Copy a valid URL first.", vim.log.levels.WARN) + return + end + if url:match("^https://") then + require("git-dev").open(url) + else + vim.notify("Not a valid URL: " .. url, vim.log.levels.ERROR) + end + end, { desc = "Open Git repository from clipboard" }) + end, + }, + { + "lewis6991/gitsigns.nvim", + opts = { + signs = { + add = { text = "▎" }, + change = { text = "▎" }, + delete = { text = "" }, + topdelete = { text = "" }, + changedelete = { text = "▎" }, + untracked = { text = "▎" }, + }, + signs_staged = { + add = { text = "▎" }, + change = { text = "▎" }, + delete = { text = "" }, + topdelete = { text = "" }, + changedelete = { text = "▎" }, + }, + on_attach = function(buffer) + local gs = package.loaded.gitsigns + + local function map(mode, l, r, desc) + vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc }) + end + + -- stylua: ignore start + map("n", "]h", function() + if vim.wo.diff then + vim.cmd.normal({ "]c", bang = true }) + else + gs.nav_hunk("next") + end + end, "Next hunk") + map("n", "[h", function() + if vim.wo.diff then + vim.cmd.normal({ "[c", bang = true }) + else + gs.nav_hunk("prev") + end + end, "Previous hunk") + map("n", "]H", function() gs.nav_hunk("last") end, "Last hunk") + map("n", "[H", function() gs.nav_hunk("first") end, "First hunk") + map({ "n", "v" }, "gs", ":Gitsigns stage_hunk", "Stage hunk") + map({ "n", "v" }, "gr", ":Gitsigns reset_hunk", "Reset hunk") + map("n", "gS", gs.stage_buffer, "Stage buffer") + map("n", "gu", gs.undo_stage_hunk, "Undo stage hunk") + map("n", "gR", gs.reset_buffer, "Reset buffer") + map("n", "gpv", gs.preview_hunk_inline, "Preview hunk inline") + map("n", "gb", function() gs.blame_line({ full = true }) end, "Blame line") + map("n", "gB", function() gs.blame() end, "Blame buffer") + map("n", "gd", gs.diffthis, "Diff this") + map("n", "gD", function() gs.diffthis("~") end, "Diff this ~") + -- map("n", "gD", function() gs.diffthis("@") end, "Diff this @") + map({ "o", "x" }, "ih", ":Gitsigns select_hunk", "GitSigns select hunk") + map("n", "gtb", gs.toggle_current_line_blame, "Toggle line blame") + map("n", "gtd", gs.toggle_deleted, "Toggle delete") + end, + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "g", group = "Git" }, + { "gt", group = "Toggle" }, + }) + end, + }, + { + "kdheepak/lazygit.nvim", + cmd = { + "LazyGit", + "LazyGitConfig", + "LazyGitCurrentFile", + "LazyGitFilter", + "LazyGitFilterCurrentFile", + }, + -- optional for floating window border decoration + dependencies = { + "nvim-lua/plenary.nvim", + }, + -- setting the keybinding for LazyGit with 'keys' is recommended in + -- order to load the plugin when the command is run for the first time + keys = { + { "gg", "LazyGit", desc = "Lazygit" }, + }, + }, + { + "mbbill/undotree", + config = function() + vim.keymap.set("n", "gu", vim.cmd.UndotreeToggle, { desc = "Undo tree" }) + end, + }, + { + "tpope/vim-fugitive", + config = function() + local TheSiahxyz_Fugitive = vim.api.nvim_create_augroup("TheSiahxyz_Fugitive", {}) + local autocmd = vim.api.nvim_create_autocmd + autocmd("BufWinEnter", { + group = TheSiahxyz_Fugitive, + pattern = "*", + callback = function() + if vim.bo.ft ~= "fugitive" then + return + end + + local bufnr = vim.api.nvim_get_current_buf() + vim.keymap.set("n", "P", function() + vim.cmd.Git("push") + end, { buffer = bufnr, remap = false, desc = "Git push" }) + vim.keymap.set("n", "p", function() + vim.cmd.Git({ "pull", "--rebase" }) + end, { buffer = bufnr, remap = false, desc = "Git pull" }) + vim.keymap.set( + "n", + "o", + ":Git push -u origin ", + { buffer = bufnr, remap = false, desc = "Git push origin" } + ) + vim.keymap.set( + "n", + "h", + ":Git push home ", + { buffer = bufnr, remap = false, desc = "Git push home" } + ) + end, + }) + autocmd("FileType", { + group = TheSiahxyz_Fugitive, + pattern = "fugitive", + callback = function(event) + vim.bo[event.buf].buflisted = false + vim.keymap.set("n", "q", "close", { buffer = event.buf, silent = true }) + end, + }) + end, + keys = { + { mode = "n", "g", ":Git ", desc = "Git" }, + { mode = "n", "gf", vim.cmd.Git, desc = "Git fugitive" }, + { mode = "n", "gm", "diffget //2", desc = "Git diff on my side" }, + { mode = "n", "go", "diffget //3", desc = "Git diff on their side" }, + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/goyo.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/goyo.lua new file mode 100644 index 0000000..86b9a03 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/goyo.lua @@ -0,0 +1,39 @@ +return { + "junegunn/goyo.vim", + dependencies = "junegunn/seoul256.vim", + config = function() + -- Enable Goyo by default for mutt writing + vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { + group = vim.api.nvim_create_augroup("TheSiahxyz_goyo_config", { clear = true }), + pattern = "/tmp/neomutt*", + callback = function() + vim.g.goyo_width = 80 + vim.g.seoul256_background = 235 + vim.cmd([[ + Goyo + set bg=light + set linebreak + set wrap + set textwidth=0 + set wrapmargin=0 + set background=dark + colorscheme seoul256 + ]]) + vim.api.nvim_buf_set_keymap( + 0, + "n", + "gd", + ":Goyo|x!", + { noremap = true, silent = true, desc = "Goyo quit" } + ) + vim.api.nvim_buf_set_keymap( + 0, + "n", + "gq", + ":Goyo|q!", + { noremap = true, silent = true, desc = "Goyo abort" } + ) + end, + }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/grug-far.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/grug-far.lua new file mode 100644 index 0000000..ca0de7d --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/grug-far.lua @@ -0,0 +1,31 @@ +return { + "MagicDuck/grug-far.nvim", + --- Ensure existing keymaps and opts remain unaffected + config = function(_, opts) + require("grug-far").setup(opts) + vim.api.nvim_create_autocmd("FileType", { + pattern = "grug-far", + callback = function() + -- Map to quit after ensuring we're in normal mode + vim.keymap.set({ "i", "n" }, "", "stopinsert | bd!", { buffer = true }) + end, + }) + end, + keys = { + { + "rc", + function() + local grug = require("grug-far") + local ext = vim.bo.buftype == "" and vim.fn.expand("%:e") + grug.open({ + transient = true, + prefills = { + filesFilter = ext and ext ~= "" and "*." .. ext or nil, + }, + }) + end, + mode = { "n", "v" }, + desc = "Search and Replace", + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/harpoon2.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/harpoon2.lua new file mode 100644 index 0000000..c68f385 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/harpoon2.lua @@ -0,0 +1,110 @@ +return { + "ThePrimeagen/harpoon", + branch = "harpoon2", + opts = { + menu = { + width = vim.api.nvim_win_get_width(0) - 4, + }, + settings = { + save_on_toggle = true, + }, + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "h", group = "Harpoon" }, + { "hr", group = "Replace harpoon slot" }, + { "", group = "Harpoon list delete" }, + }) + end, + config = function(_, opts) + local harpoon = require("harpoon") + + -- Apply the base configuration + harpoon.setup(opts) + + -- Extend functionality + harpoon:extend({ + UI_CREATE = function(cx) + vim.keymap.set("n", "", function() + harpoon.ui:select_menu_item({ vsplit = true }) + end, { buffer = cx.bufnr }) + + vim.keymap.set("n", "", function() + harpoon.ui:select_menu_item({ split = true }) + end, { buffer = cx.bufnr }) + + vim.keymap.set("n", "", function() + harpoon.ui:select_menu_item({ tabedit = true }) + end, { buffer = cx.bufnr }) + end, + }) + end, + keys = function() + local keys = { + { + "ha", + function() + require("harpoon"):list():add() + end, + desc = "Add buffer to harpoon list", + }, + { + "hi", + function() + require("harpoon"):list():prepend() + end, + desc = "Prepend buffer to harpoon list", + }, + { + "", + function() + local harpoon = require("harpoon") + harpoon.ui:toggle_quick_menu(harpoon:list()) + end, + desc = "Open harpoon list menu", + }, + { + "", + function() + require("harpoon"):list():prev({ ui_nav_wrap = false }) + end, + desc = "Previous harpoon list", + }, + { + "", + function() + require("harpoon"):list():next({ ui_nav_wrap = false }) + end, + desc = "Next harpoon list", + }, + } + + for i = 0, 9 do + table.insert(keys, { + "", + function() + require("harpoon"):list():select(i) + end, + desc = "Harpoon list " .. i, + }) + table.insert(keys, { + "h" .. i, + function() + require("harpoon"):list():select(i) + end, + desc = "Harpoon list " .. i, + }) + table.insert(keys, { + "hr" .. i, + function() + require("harpoon"):list():replace_at(i) + end, + desc = "Replace buffer at harpoon slot " .. i, + }) + end + + return keys + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/image.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/image.lua new file mode 100644 index 0000000..a4f126f --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/image.lua @@ -0,0 +1,210 @@ +return { + "HakonHarnes/img-clip.nvim", + event = "VeryLazy", + opts = { + -- add options here + -- or leave it empty to use the default settings + }, + config = function(_, opts) + require("img-clip").setup(opts) + + vim.keymap.set({ "n", "v", "i" }, "", function() + local pasted_image = require("img-clip").paste_image() + if pasted_image then + -- "Update" saves only if the buffer has been modified since the last save + vim.cmd("silent! update") + -- Get the current line + local line = vim.api.nvim_get_current_line() + -- Move cursor to end of line + vim.api.nvim_win_set_cursor(0, { vim.api.nvim_win_get_cursor(0)[1], #line }) + -- I reload the file, otherwise I cannot view the image after pasted + vim.cmd("edit!") + end + end, { desc = "Paste image from clipboard" }) + + vim.keymap.set("n", "oi", function() + local function get_image_path() + -- Get the current line + local line = vim.api.nvim_get_current_line() + -- Patterns to match image paths + local patterns = { + "%[.-%]%((.-)%)", -- Markdown style: ![alt text](image_path) + "%[%[(.-)%]%]", -- Double square brackets: [[image_path]] + } + + for _, pattern in ipairs(patterns) do + local _, _, image_path = string.find(line, pattern) + if image_path then + return image_path + end + end + + return nil -- Return nil if no pattern matches + end + + local function file_exists(filepath) + -- Check if the file exists + local f = io.open(filepath, "r") + if f then + f:close() + return true + end + return false + end + + -- Get the image path + local image_path = get_image_path() + if image_path then + -- Check if the image path starts with "http" or "https" + if string.sub(image_path, 1, 4) == "http" then + print("URL image, use 'gx' to open it in the default browser.") + else + -- Construct absolute image path + local current_file_path = vim.fn.expand("%:p:h") + local absolute_image_path = current_file_path .. "/" .. image_path + -- Check if the image exists in the current path + if not file_exists(absolute_image_path) then + -- If not found, search ../Screenshots/ + local fallback_path = vim.fn.fnamemodify(current_file_path, ":h") + .. "/Screenshots/" + .. image_path + if file_exists(fallback_path) then + absolute_image_path = fallback_path + else + print("Image not found in either current directory or ../Screenshots/") + return + end + end + -- Construct command to open image in Preview + local command = "nsxiv -aiop " .. vim.fn.shellescape(absolute_image_path) + -- Execute the command + local success = os.execute(command) + if success then + print("Opened image: " .. absolute_image_path) + else + print("Failed to open image: " .. absolute_image_path) + end + end + else + print("No image found under the cursor") + end + end, { desc = "Open image under cursor" }) + + vim.keymap.set("n", "di", function() + local function get_image_path() + local line = vim.api.nvim_get_current_line() + -- Patterns to match image paths + local patterns = { + "%[.-%]%((.-)%)", -- Markdown style: ![alt text](image_path) + "%[%[(.-)%]%]", -- Double square brackets: [[image_path]] + } + + for _, pattern in ipairs(patterns) do + local _, _, image_path = string.find(line, pattern) + if image_path then + return image_path + end + end + + return nil -- Return nil if no pattern matches + end + + local function file_exists(filepath) + local f = io.open(filepath, "r") + if f then + f:close() + return true + end + return false + end + + local image_path = get_image_path() + if image_path then + if string.sub(image_path, 1, 4) == "http" then + vim.api.nvim_echo({ { "URL image cannot be deleted from disk.", "WarningMsg" } }, false, {}) + return + end + + local current_file_path = vim.fn.expand("%:p:h") + local absolute_image_path = current_file_path .. "/" .. image_path + + -- Check if file exists + if not file_exists(absolute_image_path) then + -- Search fallback directory + local fallback_path = vim.fn.fnamemodify(current_file_path, ":h") .. "/Screenshots/" .. image_path + if file_exists(fallback_path) then + absolute_image_path = fallback_path + else + print("Image not found in either current directory or ../Screenshots/") + return + end + end + + -- Verify if trash utility exists + if vim.fn.executable("trash") == 0 then + vim.api.nvim_echo({ + { "- Trash utility not installed. Install `trash-cli`.\n", "ErrorMsg" }, + }, false, {}) + return + end + + vim.ui.select({ "yes", "no" }, { prompt = "Delete image file? " }, function(choice) + if choice == "yes" then + -- Attempt to delete using trash + local command = { "trash", absolute_image_path } + local success, err = pcall(vim.fn.system, command) + + -- Debug message for troubleshooting + print("Debug: Trash command -", table.concat(command, " ")) + + if success and vim.fn.filereadable(absolute_image_path) == 0 then + vim.api.nvim_echo({ + { "Image file deleted using trash:\n", "Normal" }, + { absolute_image_path, "Normal" }, + }, false, {}) + require("image").clear() + vim.cmd("edit!") + vim.cmd("normal! dd") + else + -- If trash fails, log the error + vim.api.nvim_echo({ + { "Trash deletion failed. Error:\n", "ErrorMsg" }, + { err or "Unknown error", "ErrorMsg" }, + }, false, {}) + end + else + vim.api.nvim_echo({ { "Image deletion canceled.", "Normal" } }, false, {}) + end + end) + else + print("No image found under the cursor") + end + end, { desc = "Delete image file under cursor" }) + + -- Refresh the images in the current buffer + -- Useful if you delete an actual image file and want to see the changes + -- without having to re-open neovim + vim.keymap.set("n", "ir", function() + -- First I clear the images + require("image").clear() + -- I'm using [[ ]] to escape the special characters in a command + -- vim.cmd([[lua require("image").clear()]]) + -- Reloads the file to reflect the changes + vim.cmd("edit!") + print("Images refreshed") + end, { desc = "Refresh images" }) + + -- Set up a keymap to clear all images in the current buffer + vim.keymap.set("n", "ic", function() + -- This is the command that clears the images + require("image").clear() + -- I'm using [[ ]] to escape the special characters in a command + -- vim.cmd([[lua require("image").clear()]]) + print("Images cleared") + end, { desc = "Clear images" }) + end, + keys = { + -- suggested keymap + { "pi", "PasteImage", desc = "Paste image from clipboard" }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/init.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/init.lua new file mode 100644 index 0000000..0bcf162 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/init.lua @@ -0,0 +1,83 @@ +return { + { "nvim-lua/plenary.nvim" }, + { + "aserowy/tmux.nvim", + config = function() + require("tmux").setup({ + copy_sync = { + -- enables copy sync. by default, all registers are synchronized. + -- to control which registers are synced, see the `sync_*` options. + enable = false, + + -- ignore specific tmux buffers e.g. buffer0 = true to ignore the + -- first buffer or named_buffer_name = true to ignore a named tmux + -- buffer with name named_buffer_name :) + ignore_buffers = { empty = false }, + + -- TMUX >= 3.2: all yanks (and deletes) will get redirected to system + -- clipboard by tmux + redirect_to_clipboard = false, + + -- offset controls where register sync starts + -- e.g. offset 2 lets registers 0 and 1 untouched + register_offset = 0, + + -- overwrites vim.g.clipboard to redirect * and + to the system + -- clipboard using tmux. If you sync your system clipboard without tmux, + -- disable this option! + sync_clipboard = true, + + -- synchronizes registers *, +, unnamed, and 0 till 9 with tmux buffers. + sync_registers = true, + + -- synchronizes registers when pressing p and P. + sync_registers_keymap_put = true, + + -- synchronizes registers when pressing (C-r) and ". + sync_registers_keymap_reg = true, + + -- syncs deletes with tmux clipboard as well, it is adviced to + -- do so. Nvim does not allow syncing registers 0 and 1 without + -- overwriting the unnamed register. Thus, ddp would not be possible. + sync_deletes = true, + + -- syncs the unnamed register with the first buffer entry from tmux. + sync_unnamed = true, + }, + navigation = { + -- cycles to opposite pane while navigating into the border + cycle_navigation = false, + + -- enables default keybindings (C-hjkl) for normal mode + enable_default_keybindings = true, + + -- prevents unzoom tmux when navigating beyond vim border + persist_zoom = true, + }, + resize = { + -- enables default keybindings (A-hjkl) for normal mode + enable_default_keybindings = false, + + -- sets resize steps for x axis + resize_step_x = 2, + + -- sets resize steps for y axis + resize_step_y = 2, + }, + }) + + vim.keymap.set("n", "", function() + require("tmux").resize_left() + end, { desc = "Decrease window width" }) + vim.keymap.set("n", "", function() + require("tmux").resize_bottom() + end, { desc = "Decrease window height" }) + vim.keymap.set("n", "", function() + require("tmux").resize_top() + end, { desc = "Increase window height" }) + vim.keymap.set("n", "", function() + require("tmux").resize_right() + end, { desc = "Increase window width" }) + end, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/keys.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/keys.lua new file mode 100644 index 0000000..b263414 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/keys.lua @@ -0,0 +1,114 @@ +return { + { + "nvzone/showkeys", + cmd = "ShowkeysToggle", + opts = {}, + keys = { + { "zk", "ShowkeysToggle", desc = "Toggle keys" }, + }, + }, + { + "folke/which-key.nvim", + event = "VeryLazy", + cmd = "WhichKey", + dependencies = { "echasnovski/mini.icons", "nvim-tree/nvim-web-devicons" }, + opts = { + preset = "classic", -- false | "classic" | "modern" | "helix" + keys = { + scroll_down = "", + scroll_up = "", + }, + }, + config = function(_, opts) + local wk = require("which-key") + wk.setup(opts) + wk.add({ + { + mode = { "n", "v" }, + { "g", group = "Goto" }, + { "g`", group = "Marks" }, + { "g'", group = "Marks" }, + { "gs", group = "Search/Surround" }, + { "gx", desc = "Open with system app" }, + { "s", group = "Surround/Search & replace on line" }, + { "S", group = "Surround/Search & replace in file" }, + { "z", group = "Fold" }, + { "`", group = "Marks" }, + { "'", group = "Marks" }, + { '"', group = "Registers" }, + { "]", group = "Next" }, + { "]]", group = "Next" }, + { "[", group = "Prev" }, + { "[[", group = "Prev" }, + { "=", group = "Line paste" }, + { "", group = "Windows" }, + { "", group = "Leader" }, + { "a", group = "Ascii" }, + { + "b", + group = "Buffer", + expand = function() + return require("which-key.extras").expand.buf() + end, + }, + { "B", group = "Buffer (force)" }, + { "C", group = "Goto realpath" }, + { "d", group = "Delete" }, + { "D", group = "Delete (blackhole)" }, + { "e", group = "Explorer" }, + { "i", group = "Inspect" }, + { "l", group = "Location" }, + { "L", group = "Lazy" }, + { "M", group = "Mason" }, + { "o", group = "Open" }, + { "p", group = "Paste" }, + { "P", group = "Paste" }, + { "q", group = "Quit" }, + { "rn", group = "Rename" }, + { "sk", group = "Keys" }, + { "S", group = "Save/Source" }, + { "w", group = "Which-key" }, + { "W", group = "Save all" }, + { "z", group = "Toggle" }, + { "", group = "Tabs" }, + { "", group = "Local Leader (bookmarks)" }, + { "", group = "Bookmarks (explorer)" }, + { "", group = "Bookmarks (mini)" }, + { "t", group = "Task" }, + }, + { + mode = { "n", "v", "x" }, + { "gw", desc = "Visible in window" }, + { "g%", desc = "Match backward" }, + { "g;", desc = "Last change" }, + { "Q", group = "Quit all" }, + }, + }) + end, + keys = { + { + "?", + function() + require("which-key").show({ global = false }) + end, + desc = "Buffer local keymaps (which-key)", + }, + { + "wk", + function() + local ok, input = pcall(vim.fn.input, "WhichKey: ") + if ok and input ~= "" then + vim.cmd("WhichKey " .. input) + end + end, + desc = "Which-key query lookup", + }, + { + "wK", + "WhichKey", + mode = { "n", "v", "x" }, + desc = "Which-key all key", + }, + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lf.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lf.lua new file mode 100644 index 0000000..3f82222 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lf.lua @@ -0,0 +1,121 @@ +return { + "lmburns/lf.nvim", + dependencies = { + { + "akinsho/toggleterm.nvim", + version = "*", + config = function() + require("toggleterm").setup({ + open_mapping = [[]], -- or { [[]], [[]] } if you also use a Japanese keyboard. + }) + vim.keymap.set( + "n", + "", + "ToggleTerm direction=float name=Terminal", + { desc = "Toggle float terminal" } + ) + vim.keymap.set( + "n", + "", + "ToggleTermToggleAll", + { desc = "Toggle all float terminals" } + ) + vim.keymap.set("n", "", "TermSelect", { desc = "Select float terminal" }) + + local function set_opfunc(opfunc) + _G._opfunc = opfunc -- Define the function globally + vim.go.operatorfunc = "v:lua._opfunc" -- Assign the global function + end + + local trim_spaces = false + vim.keymap.set("v", "", function() + require("toggleterm").send_lines_to_terminal("single_line", trim_spaces, { args = vim.v.count }) + end, { desc = "Send line to terminal" }) + -- Replace with these for the other two options + -- require("toggleterm").send_lines_to_terminal("visual_lines", trim_spaces, { args = vim.v.count }) + -- require("toggleterm").send_lines_to_terminal("visual_selection", trim_spaces, { args = vim.v.count }) + + -- For use as an operator map: + -- Send motion to terminal + vim.keymap.set("n", "", function() + set_opfunc(function(motion_type) + require("toggleterm").send_lines_to_terminal(motion_type, false, { args = vim.v.count }) + end) + vim.api.nvim_feedkeys("g@", "n", false) + end, { desc = "Send motions to terminal" }) + -- Double the command to send line to terminal + vim.keymap.set("n", "", function() + set_opfunc(function(motion_type) + require("toggleterm").send_lines_to_terminal(motion_type, false, { args = vim.v.count }) + end) + vim.api.nvim_feedkeys("g@_", "n", false) + end, { desc = "Send double command to terminal" }) + -- Send whole file + vim.keymap.set("n", "", function() + set_opfunc(function(motion_type) + require("toggleterm").send_lines_to_terminal(motion_type, false, { args = vim.v.count }) + end) + vim.api.nvim_feedkeys("ggg@G''", "n", false) + end, { desc = "Send whole file to terminal (clipboard)" }) + end, + }, + }, + config = function() + vim.g.lf_netrw = 1 + local fn = vim.fn + + -- Defaults + require("lf").setup({ + default_action = "drop", -- Default action when `Lf` opens a file + default_actions = { + ["e"] = "tabedit", + [""] = "tab drop", + [""] = "vsplit", + [""] = "split", + }, + winblend = 0, -- Pseudotransparency level + direction = "float", -- Window type + border = "rounded", -- Border kind + height = fn.float2nr(fn.round(0.75 * vim.o.lines)), -- Height of the *floating* window + width = fn.float2nr(fn.round(0.75 * vim.o.columns)), -- Width of the *floating* window + escape_quit = true, -- Map escape to the quit command + focus_on_open = true, -- Focus the current file when opening Lf + mappings = true, -- Enable terminal buffer mapping + tmux = true, -- Tmux statusline can be disabled + disable_netrw_warning = true, -- Don't display a message when opening a directory + highlights = { + Normal = { link = "Normal" }, -- Use normal highlighting + NormalFloat = { link = "NormalFloat" }, -- Use float highlighting + FloatBorder = { link = "@constant" }, -- Use constant highlighting + }, + + -- Layout configurations + layout_mapping = "", -- Resize window with this key + views = { + { width = 0.800, height = 0.800 }, + { width = 0.600, height = 0.600 }, + { width = 0.950, height = 0.950 }, + { width = 0.500, height = 0.500, col = 0, row = 0 }, + { width = 0.500, height = 0.500, col = 0, row = 0.5 }, + { width = 0.500, height = 0.500, col = 0.5, row = 0 }, + { width = 0.500, height = 0.500, col = 0.5, row = 0.5 }, + }, + }) + + vim.keymap.set("n", "el", "Lf") + + -- Autocommand to set key mapping in terminal buffer + vim.api.nvim_create_autocmd("User", { + pattern = "LfTermEnter", + callback = function(a) + vim.api.nvim_buf_set_keymap( + a.buf, + "t", + "q", + "q", + { nowait = true, noremap = true, silent = true } + ) + end, + }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lsp.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lsp.lua new file mode 100644 index 0000000..ecf3f86 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lsp.lua @@ -0,0 +1,674 @@ +return { + { + "neovim/nvim-lspconfig", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { + "mason-org/mason.nvim", + "mason-org/mason-lspconfig.nvim", + "WhoIsSethDaniel/mason-tool-installer.nvim", + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + "hrsh7th/cmp-cmdline", + "hrsh7th/nvim-cmp", + { + "L3MON4D3/LuaSnip", + version = "v2.*", + build = "make install_jsregexp", + }, + "mfussenegger/nvim-lint", + "saadparwaiz1/cmp_luasnip", + "j-hui/fidget.nvim", + { "folke/neoconf.nvim", cmd = "Neoconf", config = false, dependencies = { "nvim-lspconfig" } }, + { + "folke/lazydev.nvim", + ft = "lua", -- only load on lua files + opts = { + library = { + -- See the configuration section for more details + -- Load luvit types when the `vim.uv` word is found + { path = "${3rd}/luv/library", words = { "vim%.uv" } }, + }, + }, + }, + "stevearc/conform.nvim", + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "tf", group = "Format" }, + }) + end, + config = function() + local cmp = require("cmp") + local cmp_lsp = require("cmp_nvim_lsp") + local capabilities = vim.tbl_deep_extend( + "force", + {}, + vim.lsp.protocol.make_client_capabilities(), + cmp_lsp.default_capabilities() + ) + local lspconfig = require("lspconfig") + + require("fidget").setup({ + progress = { + poll_rate = false, -- How and when to poll for progress messages + suppress_on_insert = true, -- Suppress new messages while in insert mode + ignore_done_already = true, -- Ignore new tasks that are already complete + ignore_empty_message = true, -- Ignore new tasks that don't contain a message + clear_on_detach = function(client_id) -- Clear notification group when LSP server detaches + local client = vim.lsp.get_client_by_id(client_id) + return client and client.name or nil + end, + -- ignore = { "lua_ls" }, + }, + notification = { + window = { + normal_hl = "Comment", -- Base highlight group in the notification window + winblend = 0, -- Background color opacity in the notification window + border = "none", -- Border around the notification window + zindex = 45, -- Stacking priority of the notification window + max_width = 0, -- Maximum width of the notification window + max_height = 0, -- Maximum height of the notification window + x_padding = 1, -- Padding from right edge of window boundary + y_padding = 0, -- Padding from bottom edge of window boundary + align = "bottom", -- How to align the notification window + relative = "editor", -- What the notification window position is relative to + }, + }, + integration = { + ["nvim-tree"] = { + enable = false, -- Integrate with nvim-tree/nvim-tree.lua (if installed) + }, + }, + }) + + require("mason").setup() + require("mason-lspconfig").setup({ + ensure_installed = { + "bashls", + "dockerls", + "docker_compose_language_service", + "harper_ls", + "jdtls", + "jsonls", + "lua_ls", + "mutt_ls", + "pyright", + "ruff", + }, + automatic_installation = true, + handlers = { + function(server_name) -- default handler (optional) + require("lspconfig")[server_name].setup({ + capabilities = capabilities, + }) + end, + ["bashls"] = function() + lspconfig.bashls.setup({ + capabilities = capabilities, + }) + end, + ["dockerls"] = function() + lspconfig.dockerls.setup({ + capabilities = capabilities, + -- settings = { + -- python = { + -- disableLanguageServices = false, + -- disableOrganizeImports = false, + -- }, + -- }, + }) + end, + ["docker_compose_language_service"] = function() + lspconfig.docker_compose_language_service.setup({ + capabilities = capabilities, + -- settings = { + -- python = { + -- disableLanguageServices = false, + -- disableOrganizeImports = false, + -- }, + -- }, + }) + end, + ["harper_ls"] = function() + lspconfig.harper_ls.setup({ + capabilities = capabilities, + filetypes = { "markdown", "python" }, + settings = { + ToDoHyphen = false, + -- SentenceCapitalization = true, + -- SpellCheck = true, + isolateEnglish = true, + markdown = { + -- [ignores this part]() + -- [[ also ignores my marksman links ]] + IgnoreLinkTitle = true, + }, + }, + }) + end, + ["jdtls"] = function() + lspconfig.jdtls.setup({ + capabilities = capabilities, + }) + end, + ["jsonls"] = function() + lspconfig.jsonls.setup({ + capabilities = capabilities, + settings = { + json = { + format = { + enable = true, + }, + validate = { enable = true }, + }, + }, + }) + end, + ["lua_ls"] = function() + lspconfig.lua_ls.setup({ + capabilities = capabilities, + settings = { + Lua = { + runtime = { version = "Lua 5.4" }, + diagnostics = { + globals = { "bit", "vim", "it", "describe", "before_each", "after_each" }, + }, + }, + }, + }) + end, + ["mutt_ls"] = function() + lspconfig.mutt_ls.setup({ + capabilities = capabilities, + }) + end, + ["pyright"] = function() + lspconfig.pyright.setup({ + capabilities = capabilities, + settings = { + python = { + disableLanguageServices = false, + disableOrganizeImports = false, + }, + }, + }) + end, + ["ruff"] = function() + lspconfig.ruff.setup({ + capabilities = capabilities, + -- settings = { + -- python = { + -- disableLanguageServices = false, + -- disableOrganizeImports = false, + -- }, + -- }, + }) + end, + }, + }) + + local lint = require("lint") + lint.linters_by_ft = { + dockerfile = { "hadolint" }, + javascript = { "eslint_d" }, + typescript = { "eslint_d" }, + javascriptreact = { "eslint_d" }, + typescriptreact = { "eslint_d" }, + svelte = { "eslint_d" }, + python = { "pylint" }, + sh = { "shellcheck" }, + } + + local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true }) + vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave", "TextChanged" }, { + group = lint_augroup, + callback = function() + lint.try_lint() + end, + }) + + require("mason-tool-installer").setup({ + ensure_installed = { + "beautysh", -- zsh formatter + "black", -- python formatter + "debugpy", -- python debuger + "eslint_d", -- eslint linter + "hadolint", -- docker linter + "isort", -- python formatter + "java-debug-adapter", -- java debugger + "java-test", -- java test + "markdown-toc", -- markdown toc + "prettier", -- prettier formatter + "pylint", -- python linter + "ruff", -- python formatter + "shellcheck", -- bash lint + "shfmt", -- sh formatter + "stylua", -- lua formatter + }, + integrations = { + ["mason-lspconfig"] = true, + ["mason-null-ls"] = false, + ["mason-nvim-dap"] = true, + }, + }) + + local cmp_select = { behavior = cmp.SelectBehavior.Select } + local luasnip = require("luasnip") + + cmp.setup({ + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) -- For `luasnip` users. + end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.scroll_docs(-4), -- Up + [""] = cmp.mapping.scroll_docs(4), -- Down + [""] = cmp.mapping.select_prev_item(cmp_select), + [""] = cmp.mapping.select_next_item(cmp_select), + [""] = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "luasnip" }, -- For luasnip users. + { name = "buffer" }, + }), + }) + + vim.diagnostic.config({ + update_in_insert = true, + float = { + header = "", + border = "rounded", + prefix = "", + source = "if_many", + }, + }) + + require("conform").setup({ + formatters_by_ft = { + bash = { "shfmt" }, + css = { "prettier" }, + graphql = { "prettier" }, + html = { "prettier" }, + javascript = { "prettier" }, + javascriptreact = { "prettier" }, + json = { "prettier" }, + liquid = { "prettier" }, + lua = { "stylua" }, + markdown = { "prettier" }, + python = { "ruff", "isort", "black" }, + sh = { "shfmt" }, + svelte = { "prettier" }, + typescript = { "prettier" }, + typescriptreact = { "prettier" }, + vimwiki = { "prettier" }, + yaml = { "prettier" }, + zsh = { "beautysh" }, + }, + default_format_opts = {}, + format_on_save = function(bufnr) + -- Disable with a global or buffer-local variable + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + return { lsp_format = "fallback", timeout_ms = 1000, async = false } + end, + }) + + vim.api.nvim_create_user_command("FormatDisable", function(args) + if args.bang then + vim.b.disable_autoformat = true + else + vim.g.disable_autoformat = true + end + end, { + desc = "Disable autoformat-on-save", + bang = true, + }) + vim.api.nvim_create_user_command("FormatEnable", function() + vim.b.disable_autoformat = false + vim.g.disable_autoformat = false + end, { + desc = "Re-enable autoformat-on-save", + }) + end, + keys = { + { + "lf", + function() + require("conform").format({ async = true }) + end, + mode = { "n", "v" }, + desc = "Format buffer by lsp", + }, + { + "ci", + "PyrightOrganizeImports", + desc = "Organize imports", + }, + { + "bl", + function() + require("lint").try_lint() + end, + desc = "Buffer lint", + }, + { + "le", + "FormatEnable", + desc = "Enable format", + }, + { + "ld", + "FormatDisable", + desc = "Disable format", + }, + { + "lD", + "FormatDisable!", + desc = "Disable current buffer format", + }, + }, + }, + -- { + -- "neovim/nvim-lspconfig", + -- event = { "BufReadPre", "BufNewFile" }, + -- dependencies = { + -- "mason-org/mason.nvim", + -- "mason-org/mason-lspconfig.nvim", + -- "WhoIsSethDaniel/mason-tool-installer.nvim", + -- "hrsh7th/cmp-nvim-lsp", + -- "hrsh7th/cmp-buffer", + -- "hrsh7th/cmp-path", + -- "hrsh7th/cmp-cmdline", + -- { + -- "L3MON4D3/LuaSnip", + -- version = "v2.*", + -- build = "make install_jsregexp", + -- }, + -- "mfussenegger/nvim-lint", + -- "saadparwaiz1/cmp_luasnip", + -- "j-hui/fidget.nvim", + -- { "folke/neoconf.nvim", cmd = "Neoconf", config = false, dependencies = { "nvim-lspconfig" } }, + -- { + -- "folke/lazydev.nvim", + -- ft = "lua", -- only load on lua files + -- opts = { + -- library = { + -- -- See the configuration section for more details + -- -- Load luvit types when the `vim.uv` word is found + -- { path = "${3rd}/luv/library", words = { "vim%.uv" } }, + -- }, + -- }, + -- }, + -- "stevearc/conform.nvim", + -- "saghen/blink.cmp", + -- }, + -- init = function() + -- local wk = require("which-key") + -- wk.add({ + -- mode = { "n", "v", "x" }, + -- { "tf", group = "Format" }, + -- }) + -- end, + -- opts = { + -- servers = { + -- lua_ls = { + -- settings = { + -- Lua = { + -- workspace = { + -- checkThirdParty = false, + -- }, + -- codeLens = { + -- enable = true, + -- }, + -- completion = { + -- callSnippet = "Replace", + -- }, + -- doc = { + -- privateName = { "^_" }, + -- }, + -- hint = { + -- enable = true, + -- setType = false, + -- paramType = true, + -- paramName = "Disable", + -- semicolon = "Disable", + -- arrayIndex = "Disable", + -- }, + -- runtime = { version = "Lua 5.4" }, + -- diagnostics = { + -- globals = { "bit", "vim", "it", "describe", "before_each", "after_each" }, + -- }, + -- }, + -- }, + -- }, + -- pyright = { + -- settings = { + -- python = { + -- disableLanguageServices = false, + -- disableOrganizeImports = false, + -- }, + -- }, + -- }, + -- }, + -- }, + -- config = function(_, opts) + -- local cmp = require("blink.cmp") + -- local lspconfig = require("lspconfig") + -- + -- require("mason").setup() + -- + -- for server, config in pairs(opts.servers) do + -- -- passing config.capabilities to blink.cmp merges with the capabilities in your + -- -- `opts[server].capabilities, if you've defined it + -- config.capabilities = cmp.get_lsp_capabilities(config.capabilities) + -- lspconfig[server].setup(config) + -- require("mason-lspconfig").setup({ + -- ensure_installed = { server }, + -- handlers = { + -- [server] = function() + -- lspconfig[server].setup(config) + -- end, + -- }, + -- }) + -- end + -- + -- require("fidget").setup({ + -- progress = { + -- poll_rate = 0, -- How and when to poll for progress messages + -- suppress_on_insert = true, -- Suppress new messages while in insert mode + -- ignore_done_already = true, -- Ignore new tasks that are already complete + -- ignore_empty_message = true, -- Ignore new tasks that don't contain a message + -- clear_on_detach = function(client_id) -- Clear notification group when LSP server detaches + -- local client = vim.lsp.get_client_by_id(client_id) + -- return client and client.name or nil + -- end, + -- ignore = { "lua_ls" }, + -- }, + -- notification = { + -- window = { + -- normal_hl = "Comment", -- Base highlight group in the notification window + -- winblend = 0, -- Background color opacity in the notification window + -- border = "none", -- Border around the notification window + -- zindex = 45, -- Stacking priority of the notification window + -- max_width = 0, -- Maximum width of the notification window + -- max_height = 0, -- Maximum height of the notification window + -- x_padding = 1, -- Padding from right edge of window boundary + -- y_padding = 0, -- Padding from bottom edge of window boundary + -- align = "bottom", -- How to align the notification window + -- relative = "editor", -- What the notification window position is relative to + -- }, + -- }, + -- integration = { + -- ["nvim-tree"] = { + -- enable = false, -- Integrate with nvim-tree/nvim-tree.lua (if installed) + -- }, + -- }, + -- }) + -- + -- local lint = require("lint") + -- lint.linters_by_ft = { + -- javascript = { "eslint_d" }, + -- typescript = { "eslint_d" }, + -- javascriptreact = { "eslint_d" }, + -- typescriptreact = { "eslint_d" }, + -- svelte = { "eslint_d" }, + -- python = { "pylint" }, + -- sh = { "shellcheck" }, + -- } + -- + -- local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true }) + -- vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave", "TextChanged" }, { + -- group = lint_augroup, + -- callback = function() + -- lint.try_lint() + -- end, + -- }) + -- + -- require("mason-tool-installer").setup({ + -- ensure_installed = { + -- "beautysh", -- zsh formatter + -- "black", -- python formatter + -- "debugpy", -- python debuger + -- "eslint_d", -- eslint linter + -- "isort", -- python formatter + -- "markdown-toc", -- markdown toc + -- "prettier", -- prettier formatter + -- "pylint", -- python linter + -- "ruff", -- python formatter + -- "shellcheck", -- bash lint + -- "shfmt", -- sh formatter + -- "stylua", -- lua formatter + -- }, + -- integrations = { + -- ["mason-lspconfig"] = true, + -- ["mason-null-ls"] = false, + -- ["mason-nvim-dap"] = true, + -- }, + -- }) + -- + -- vim.diagnostic.config({ + -- -- update_in_insert = true, + -- float = { + -- focusable = false, + -- style = "minimal", + -- border = "rounded", + -- source = "always", + -- header = "", + -- prefix = "", + -- }, + -- }) + -- + -- require("conform").setup({ + -- formatters_by_ft = { + -- bash = { "shfmt" }, + -- css = { "prettier" }, + -- graphql = { "prettier" }, + -- html = { "prettier" }, + -- javascript = { "prettier" }, + -- javascriptreact = { "prettier" }, + -- json = { "prettier" }, + -- liquid = { "prettier" }, + -- lua = { "stylua" }, + -- markdown = { "prettier" }, + -- python = { "ruff", "isort", "black" }, + -- sh = { "shfmt" }, + -- svelte = { "prettier" }, + -- typescript = { "prettier" }, + -- typescriptreact = { "prettier" }, + -- yaml = { "prettier" }, + -- zsh = { "beautysh" }, + -- }, + -- default_format_opts = {}, + -- format_on_save = function(bufnr) + -- -- Disable with a global or buffer-local variable + -- if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + -- return + -- end + -- return { lsp_format = "fallback", timeout_ms = 1000, async = false } + -- end, + -- }) + -- + -- vim.api.nvim_create_user_command("FormatDisable", function(args) + -- if args.bang then + -- vim.b.disable_autoformat = true + -- else + -- vim.g.disable_autoformat = true + -- end + -- end, { + -- desc = "Disable autoformat-on-save", + -- bang = true, + -- }) + -- vim.api.nvim_create_user_command("FormatEnable", function() + -- vim.b.disable_autoformat = false + -- vim.g.disable_autoformat = false + -- end, { + -- desc = "Re-enable autoformat-on-save", + -- }) + -- end, + -- keys = { + -- { + -- mode = { "n", "v" }, + -- "lf", + -- function() + -- require("conform").format({ async = true }) + -- end, + -- desc = "Format buffer by lsp", + -- }, + -- { + -- "ci", + -- "PyrightOrganizeImports", + -- desc = "Organize imports", + -- }, + -- { + -- "bl", + -- function() + -- require("lint").try_lint() + -- end, + -- desc = "Buffer lint", + -- }, + -- { + -- "le", + -- "FormatEnable", + -- desc = "Enable format", + -- }, + -- { + -- "ld", + -- "FormatDisable", + -- desc = "Disable format", + -- }, + -- { + -- "lD", + -- "FormatDisable!", + -- desc = "Disable current buffer format", + -- }, + -- }, + -- }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lualine.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lualine.lua new file mode 100644 index 0000000..9c4f0d9 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/lualine.lua @@ -0,0 +1,273 @@ +return { + "nvim-lualine/lualine.nvim", + dependencies = { "nvim-tree/nvim-web-devicons" }, + config = function() + local navic = require("nvim-navic") + require("lualine").setup({ + options = { + icons_enabled = true, + theme = "auto", + section_separators = { left = "", right = "" }, + component_separators = { left = "", right = "" }, + disabled_filetypes = { + statusline = {}, + winbar = {}, + }, + ignore_focus = {}, + always_divide_middle = true, + globalstatus = false, + refresh = { + statusline = 100, + tabline = 100, + winbar = 100, + }, + }, + sections = { + lualine_a = { + { + "mode", + fmt = function(str) + return str:sub(1, 1) + end, + }, + { + function() + local has_noice, noice = pcall(require, "noice") + if has_noice and noice.api and noice.api.status and noice.api.status.mode then + return noice.api.status.mode.get() or "" + else + return "" + end + end, + cond = function() + local has_noice, noice = pcall(require, "noice") + return has_noice + and noice.api + and noice.api.status + and noice.api.status.mode + and noice.api.status.mode.has() + end, + color = { bg = "#ff9e64" }, + }, + }, + lualine_b = { + "branch", + { + "diff", + colored = true, -- Displays a colored diff status if set to true + diff_color = { + -- Same color values as the general color option can be used here. + added = "LuaLineDiffAdd", -- Changes the diff's added color + modified = "LuaLineDiffChange", -- Changes the diff's modified color + removed = "LuaLineDiffDelete", -- Changes the diff's removed color you + }, + symbols = { added = "+", modified = "~", removed = "-" }, -- Changes the symbols used by the diff. + source = nil, -- A function that works as a data source for diff. + -- It must return a table as such: + -- { added = add_count, modified = modified_count, removed = removed_count } + -- or nil on failure. count <= 0 won't be displayed. + }, + { + "diagnostics", + -- Table of diagnostic sources, available sources are: + -- 'nvim_lsp', 'nvim_diagnostic', 'nvim_workspace_diagnostic', 'coc', 'ale', 'vim_lsp'. + -- or a function that returns a table as such: + -- { error=error_cnt, warn=warn_cnt, info=info_cnt, hint=hint_cnt } + sources = { "nvim_lsp", "nvim_diagnostic", "nvim_workspace_diagnostic", "coc" }, + + -- Displays diagnostics for the defined severity types + sections = { "error", "warn", "info", "hint" }, + + diagnostics_color = { + -- Same values as the general color option can be used here. + error = "DiagnosticError", -- Changes diagnostics' error color. + warn = "DiagnosticWarn", -- Changes diagnostics' warn color. + info = "DiagnosticInfo", -- Changes diagnostics' info color. + hint = "DiagnosticHint", -- Changes diagnostics' hint color. + }, + symbols = { + error = " ", + warn = " ", + info = " ", + hint = " ", + }, + colored = true, -- Displays diagnostics status in color if set to true. + update_in_insert = true, -- Update diagnostics in insert mode. + always_visible = false, -- Show diagnostics even if there are none. + }, + { + function() + local ok, neocomposer = pcall(require, "NeoComposer.ui") + if ok and neocomposer and neocomposer.status_recording then + return neocomposer.status_recording() + end + return "" + end, + }, + }, + lualine_c = { + { + "filename", + file_status = true, -- Displays file status (readonly status, modified status) + newfile_status = true, -- Display new file status (new file means no write after created) + path = 3, -- 0: Just the filename + -- 1: Relative path + -- 2: Absolute path + -- 3: Absolute path, with tilde as the home directory + -- 4: Filename and parent dir, with tilde as the home directory + + shorting_target = 40, -- Shortens path to leave 40 spaces in the window + -- for other components. (terrible name, any suggestions?) + symbols = { + modified = "[*]", -- Text to show when the file is modified. + readonly = "[r]", -- Text to show when the file is non-modifiable or readonly. + unnamed = "[?]", -- Text to show for unnamed buffers. + newfile = "[%%]", -- Text to show for newly created file before first write + }, + }, + }, + lualine_x = { + { + function() + local has_noice, noice = pcall(require, "noice") + if has_noice and noice.api and noice.api.status and noice.api.status.mode then + return noice.api.status.search.get() or "" + else + return "" + end + end, + cond = function() + local has_noice, noice = pcall(require, "noice") + return has_noice + and noice.api + and noice.api.status + and noice.api.status.search + and noice.api.status.search.has() + end, + color = { bg = "#ff9e64" }, + }, + "copilot", + { + function() + return require("molten.status").initialized() + end, + }, + "encoding", + "fileformat", + { + "filetype", + colored = true, -- Displays filetype icon in color if set to true + icon_only = true, -- Display only an icon for filetype + icon = { align = "right" }, -- Display filetype icon on the right hand side + -- icon = {'X', align='right'} + -- Icon string ^ in table is ignored in filetype component + }, + }, + lualine_y = { + "progress", + }, + lualine_z = { + { + function() + local is_tmux = os.getenv("TMUX") ~= nil + if is_tmux then + return "" + end + return os.date("%H:%M") + end, + }, + }, + }, + inactive_sections = {}, + tabline = { + lualine_a = { + { + "tabs", + tab_max_length = 40, -- Maximum width of each tab. The content will be shorten dynamically (example: apple/orange -> a/orange) + max_length = vim.o.columns / 3, -- Maximum width of tabs component. + -- Note: + -- It can also be a function that returns + -- the value of `max_length` dynamically. + mode = 0, -- 0: Shows tab_nr + -- 1: Shows tab_name + -- 2: Shows tab_nr + tab_name + + path = nil, -- 0: just shows the filename + -- 1: shows the relative path and shorten $HOME to ~ + -- 2: shows the full path + -- 3: shows the full path and shorten $HOME to ~ + + -- Automatically updates active tab color to match color of other components (will be overidden if buffers_color is set) + use_mode_colors = true, + + -- tabs_color = { + -- -- Same values as the general color option can be used here. + -- active = "lualine_{section}_normal", -- Color for active tab. + -- inactive = "lualine_{section}_inactive", -- Color for inactive tab. + -- }, + -- + show_modified_status = false, -- Shows a symbol next to the tab name if the file has been modified. + symbols = { + modified = "*", -- Text to show when the file is modified. + }, + + fmt = function(name, context) + -- Show + if buffer is modified in tab + local buflist = vim.fn.tabpagebuflist(context.tabnr) + local winnr = vim.fn.tabpagewinnr(context.tabnr) + local bufnr = buflist[winnr] + local mod = vim.fn.getbufvar(bufnr, "&mod") + + return name .. (mod == 1 and " +" or "") + end, + }, + }, + lualine_b = { + { + function() + local function buffer_status() + local buffers = vim.fn.getbufinfo({ buflisted = true }) + local current_buf = vim.fn.bufnr() + local current_buffer_index = 0 + local modified_symbol = vim.bo.modified and "●" or "" + for i, buf in ipairs(buffers) do + if buf.bufnr == current_buf then + current_buffer_index = i + break + end + end + return string.format("%s%d/%d", modified_symbol, current_buffer_index, #buffers) + end + return buffer_status() + end, + }, + }, + lualine_c = { + { + function() + return navic.get_location() + end, + cond = function() + return navic.is_available() + end, + }, + }, + lualine_x = {}, + lualine_y = {}, + lualine_z = {}, + }, + winbar = {}, + inactive_winbar = {}, + extensions = {}, + }) + + local lualine_hidden = true + vim.keymap.set({ "n", "v" }, "zl", function() + lualine_hidden = not lualine_hidden + require("lualine").hide({ + place = { "statusline", "tabline", "winbar" }, + unhide = lualine_hidden, + }) + end, { desc = "Toggle lualine" }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/macro.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/macro.lua new file mode 100644 index 0000000..2af1b49 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/macro.lua @@ -0,0 +1,172 @@ +return { + -- { + -- "kr40/nvim-macros", + -- lazy = false, + -- cmd = { "MacroSave", "MacroYank", "MacroSelect", "MacroDelete" }, + -- opts = {}, + -- config = function() + -- require("nvim-macros").setup({ + -- json_file_path = vim.fn.expand("~/.local/share/thesiah/macros.json"), -- Location where the macros will be stored + -- default_macro_register = "q", -- Use as default register for :MacroYank and :MacroSave and :MacroSelect Raw functions + -- json_formatter = "none", -- can be "none" | "jq" | "yq" used to pretty print the json file (jq or yq must be installed!) + -- }) + -- vim.keymap.set("n", "yQ", ":MacroYank", { desc = "Yank macro" }) + -- vim.keymap.set("n", "wQ", ":MacroSave", { desc = "Save macro" }) + -- vim.keymap.set("n", "fQ", ":MacroSelect", { desc = "Search macro" }) + -- vim.keymap.set("n", "xQ", ":MacroDelete", { desc = "Delete macro" }) + -- end, + -- }, + -- { + -- "desdic/macrothis.nvim", + -- opts = {}, + -- config = function() + -- require("macrothis").setup({ + -- datafile = (function() + -- local path = vim.fn.expand("~/.local/share/thesiah/macros.json") + -- + -- -- Create directory if it doesn't exist + -- local dir = vim.fn.fnamemodify(path, ":h") + -- if vim.fn.isdirectory(dir) == 0 then + -- vim.fn.mkdir(dir, "p") + -- end + -- + -- -- Create file if it doesn't exist or is empty + -- if vim.fn.filereadable(path) == 0 or vim.fn.getfsize(path) == 0 then + -- local file = io.open(path, "w") + -- if file then + -- file:write("[]") + -- file:close() + -- end + -- end + -- + -- return path + -- end)(), + -- run_register = "Q", -- content of register z is replaced when running/editing a macro + -- editor = { -- Edit window + -- width = 100, + -- height = 2, + -- style = "minimal", + -- border = "rounded", + -- }, + -- clipboard_register = '"', + -- default_register = "q", -- Use this register when loading a macro (will never prompt for register if set) + -- }) + -- require("telescope").load_extension("macrothis") + -- vim.keymap.set("n", "fQ", ":Telescope macrothis", { desc = "Find macro" }) + -- end, + -- keys = { + -- { + -- "dQ", + -- function() + -- require("macrothis").delete() + -- end, + -- desc = "Delete macro", + -- }, + -- { + -- "eQ", + -- function() + -- require("macrothis").edit() + -- end, + -- desc = "Edit macro", + -- }, + -- { + -- "lQ", + -- function() + -- require("macrothis").load() + -- end, + -- desc = "Load macro", + -- }, + -- { + -- "rnQ", + -- function() + -- require("macrothis").rename() + -- end, + -- desc = "Rename macro", + -- }, + -- { + -- "rQ", + -- function() + -- require("macrothis").quickfix() + -- end, + -- desc = "Run macro on all files in quickfix", + -- }, + -- { + -- "rq", + -- function() + -- require("macrothis").run() + -- end, + -- desc = "Run macro", + -- }, + -- { + -- "wQ", + -- function() + -- require("macrothis").save() + -- end, + -- desc = "Save macro", + -- }, + -- { + -- "eR", + -- function() + -- require("macrothis").register() + -- end, + -- desc = "Edit register", + -- }, + -- { + -- "yr", + -- function() + -- require("macrothis").copy_register_printable() + -- end, + -- desc = "Copy register as printable", + -- }, + -- { + -- "yq", + -- function() + -- require("macrothis").copy_macro_printable() + -- end, + -- desc = "Copy macro as printable", + -- }, + -- }, + -- }, + { + "ecthelionvi/NeoComposer.nvim", + dependencies = { "kkharji/sqlite.lua" }, + opts = {}, + config = function() + require("NeoComposer").setup({ + notify = true, + delay_timer = 150, + queue_most_recent = false, + window = { + width = 80, + height = 10, + border = "rounded", + winhl = { + Normal = "ComposerNormal", + }, + }, + colors = { + bg = "NONE", + fg = "#ff9e64", + red = "#ec5f67", + blue = "#5fb3b3", + green = "#99c794", + }, + keymaps = { + play_macro = "Q", + yank_macro = "yq", + stop_macro = "cq", + toggle_record = "q", + cycle_next = "", + cycle_prev = "", + toggle_macro_menu = "", + }, + }) + + require("telescope").load_extension("macros") + + vim.keymap.set("n", "sm", ":Telescope macros", { desc = "Search macros" }) + vim.keymap.set("n", "em", ":EditMacros", { desc = "Edit macros" }) + vim.keymap.set("n", "xm", ":ClearNeoComposer", { desc = "Clear macros" }) + end, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/markdown.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/markdown.lua new file mode 100644 index 0000000..600c664 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/markdown.lua @@ -0,0 +1,551 @@ +-- Select the current cell +local function select_cell() + local bufnr = vim.api.nvim_get_current_buf() + local current_row = vim.api.nvim_win_get_cursor(0)[1] + local current_col = vim.api.nvim_win_get_cursor(0)[2] + + local start_line = nil + local end_line = nil + local line_count = vim.api.nvim_buf_line_count(bufnr) + + -- Find the start of the cell (looking for opening markers or headers) + for line = current_row, 1, -1 do + local line_content = vim.api.nvim_buf_get_lines(bufnr, line - 1, line, false)[1] + if line_content:match("^```%s*[%w_%-]+") then + start_line = line + break + end + end + + -- If no start line is found, assume start of the file + if not start_line then + start_line = 1 + end + + -- Find the end of the cell (looking for the next opening marker or header) + for line = start_line + 1, line_count do + local line_content = vim.api.nvim_buf_get_lines(bufnr, line - 1, line, false)[1] + if line_content:match("^```%s*[%w_%-]+") then + end_line = line - 1 + break + end + end + + -- If no end line is found, assume end of the file + if not end_line then + end_line = line_count + end + + return current_row, current_col, start_line, end_line +end + +-- Delete the current cell +local function delete_cell() + local _, _, start_line, end_line = select_cell() -- Use select_cell to get start and end lines of the cell + if start_line and end_line then + -- Move cursor to the start of the cell + vim.api.nvim_win_set_cursor(0, { start_line, 0 }) + + -- Enter visual line mode to select the cell + vim.cmd("normal! V") + -- Move cursor to the end of the cell to extend selection + vim.api.nvim_win_set_cursor(0, { end_line, 0 }) + + -- Delete the selected lines + vim.cmd("normal! d") + end +end + +-- Navigate to the next or previous cell +local function navigate_cell(up) + local bufnr = vim.api.nvim_get_current_buf() + local line_count = vim.api.nvim_buf_line_count(bufnr) + local _, _, start_line, end_line = select_cell() -- Get the start and end lines of the current cell + + local target_line = nil + + if up then + -- Find the previous cell start, skipping any closing markers + for line = start_line - 1, 1, -1 do + local line_content = vim.api.nvim_buf_get_lines(bufnr, line - 1, line, false)[1] + if line_content:match("^```%s*[%w_%-]+") or line_content:match("^%s*#+%s") then + target_line = line + break + end + end + else + -- Find the next cell start, skipping any closing markers + for line = end_line + 1, line_count do + local line_content = vim.api.nvim_buf_get_lines(bufnr, line - 1, line, false)[1] + if line_content:match("^```%s*[%w_%-]+") or line_content:match("^%s*#+%s") then + target_line = line + break + end + end + end + + -- Navigate to the target line if found, otherwise stay at the current position + if target_line then + -- If the target is a code block, move cursor to the line right after the opening marker + local target_line_content = vim.api.nvim_buf_get_lines(bufnr, target_line - 1, target_line, false)[1] + if target_line_content:match("^```%s*[%w_%-]+") then + vim.api.nvim_win_set_cursor(0, { target_line + 1, 0 }) -- Move inside the code block + else + vim.api.nvim_win_set_cursor(0, { target_line, 0 }) -- Move to the markdown header line + end + else + if up then + vim.api.nvim_win_set_cursor(0, { 1, 0 }) -- Move to start of file if no previous cell found + else + vim.api.nvim_win_set_cursor(0, { line_count, 0 }) -- Move to end of file if no next cell found + end + end +end + +-- Insert a new cell with specific content +local function insert_cell(content) + local _, _, _, end_line = select_cell() + local bufnr = vim.api.nvim_get_current_buf() + local line = end_line + if end_line ~= 1 then + line = end_line - 1 + vim.api.nvim_win_set_cursor(0, { end_line - 1, 0 }) + else + line = end_line + vim.api.nvim_win_set_cursor(0, { end_line, 0 }) + end + + vim.cmd("normal!2o") + vim.api.nvim_buf_set_lines(bufnr, line, line + 1, false, { content }) + vim.cmd("normal!2o") + vim.cmd("normal!k") +end + +-- Insert a new code cell +local function insert_code_cell() + insert_cell("```python") -- For regular code cells +end + +return { + { + "ixru/nvim-markdown", + config = function() + vim.g.vim_markdown_no_default_key_mappings = 1 + end, + }, + { + "MeanderingProgrammer/render-markdown.nvim", + -- dependencies = { "nvim-treesitter/nvim-treesitter", "echasnovski/mini.nvim" }, -- if you use the mini.nvim suite + dependencies = { "nvim-treesitter/nvim-treesitter", "echasnovski/mini.icons" }, -- if you use standalone mini plugins + -- dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, -- if you prefer nvim-web-devicons + ---@module 'render-markdown' + ---@type render.md.UserConfig + opts = {}, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "mr", group = "Markdown render" }, + }) + end, + config = function() + -- require("obsidian").get_client().opts.ui.enable = false + -- vim.api.nvim_buf_clear_namespace(0, vim.api.nvim_get_namespaces()["ObsidianUI"], 0, -1) + require("render-markdown").setup({ + bullet = { + -- Turn on / off list bullet rendering + enabled = false, + }, + code = { + enabled = true, -- disable code rendering for .ipynb files + sign = true, + -- Width of the code block background. + -- | block | width of the code block | + -- | full | full width of the window | + width = "block", + }, + file_types = { "markdown", "vimwiki" }, + heading = { + enabled = true, + sign = false, + icons = { "󰎤 ", "󰎧 ", "󰎪 ", "󰎭 ", "󰎱 ", "󰎳 " }, + }, + ignore = function(bufnr) + local name = vim.api.nvim_buf_get_name(bufnr) + return name:lower():match("%.ipynb$") ~= nil + end, + }) + vim.treesitter.language.register("markdown", "vimwiki") + + local opts = { noremap = true, silent = true } + vim.keymap.set("n", "mrt", function() + require("render-markdown").buf_toggle() + end, vim.tbl_extend("force", opts, { desc = "Toggle render-markdown" })) + vim.keymap.set("n", "mre", function() + require("render-markdown").buf_enable() + end, vim.tbl_extend("force", opts, { desc = "Enable render-markdown" })) + vim.keymap.set("n", "mrx", function() + require("render-markdown").buf_disable() + end, vim.tbl_extend("force", opts, { desc = "Disable render-markdown" })) + vim.keymap.set("n", "mr+", function() + require("render-markdown").expand() + end, vim.tbl_extend("force", opts, { desc = "Expand conceal margin" })) + vim.keymap.set("n", "mr-", function() + require("render-markdown").contract() + end, vim.tbl_extend("force", opts, { desc = "Contract conceal margin" })) + vim.keymap.set("n", "mrl", function() + require("render-markdown").log() + end, vim.tbl_extend("force", opts, { desc = "Open render-markdown log" })) + vim.keymap.set("n", "mrc", function() + require("render-markdown").config() + end, vim.tbl_extend("force", opts, { desc = "Show render-markdown config diff" })) + vim.keymap.set("n", "mrd", function() + require("render-markdown").debug() + end, vim.tbl_extend("force", opts, { desc = "Debug render-markdown marks" })) + end, + }, + { + -- Install markdown preview, use npx if available. + "iamcco/markdown-preview.nvim", + cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, + ft = { "markdown" }, + build = function(plugin) + if vim.fn.executable("npx") then + vim.cmd("!cd " .. plugin.dir .. " && cd app && npx --yes yarn install") + else + vim.cmd([[Lazy load markdown-preview.nvim]]) + vim.fn["mkdp#util#install"]() + end + end, + init = function() + if vim.fn.executable("npx") then + vim.g.mkdp_filetypes = { "markdown" } + end + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "m", group = "Markdown/Map" }, + }) + end, + keys = { + { "mp", "MarkdownPreview", desc = "Markdown preview" }, + { "mx", "MarkdownPreviewStop", desc = "Markdown stop" }, + { "md", "MarkdownPreviewToggle", desc = "Markdown toggle" }, + }, + }, + { + "brianhuster/live-preview.nvim", + dependencies = { + -- You can choose one of the following pickers + "nvim-telescope/telescope.nvim", + -- "ibhagwan/fzf-lua", + -- "echasnovski/mini.pick", + }, + cmd = { "LivePreview start", "LivePreview close", "LivePreview pick", "LivePreview help" }, + init = function() + if vim.fn.executable("npx") then + vim.g.mkdp_filetypes = { "markdown" } + end + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "ml", group = "Markdown live" }, + }) + end, + keys = { + { "mlp", "LivePreview start", desc = "Markdown live preview" }, + { "mlx", "LivePreview close", desc = "Markdown live close" }, + { "mlc", "LivePreview pick", desc = "Markdown live pick" }, + { "mlh", "LivePreview help", desc = "Markdown live help" }, + }, + }, + { + "ellisonleao/glow.nvim", + cmd = "Glow", + config = function() + require("glow").setup({ + border = "single", -- floating window border config + style = "dark", -- filled automatically with your current editor background, you can override using glow json style + }) + end, + keys = { + { "mf", "Glow", desc = "Floating markdown preview" }, + }, + }, + { + "dhruvasagar/vim-open-url", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "g", group = "Search word under curosr" }, + { "gB", group = "Open url in browser" }, + { "gG", group = "Google search word under cursor" }, + { "gW", group = "Wikipedia search word under cursor" }, + }) + end, + }, + { + "AckslD/nvim-FeMaco.lua", + config = function() + require("femaco").setup() + end, + }, + { + "goerz/jupytext.nvim", + version = "0.2.0", + lazy = false, + config = function() + require("jupytext").setup({ + jupytext = "jupytext", + format = "markdown", + update = true, + filetype = require("jupytext").get_filetype, + new_template = require("jupytext").default_new_template(), + sync_patterns = { "*.md", "*.py", "*.jl", "*.R", "*.Rmd", "*.qmd" }, + autosync = true, + handle_url_schemes = true, + }) + end, + keys = { + { "", insert_code_cell, desc = "Insert Code Cell" }, + { "", delete_cell, desc = "Delete Cell" }, + { + "", + function() + navigate_cell(true) + end, + desc = "Previous Cell", + }, + { "", navigate_cell, desc = "Next Cell" }, + }, + }, + { + "vhyrro/luarocks.nvim", + priority = 1001, -- this plugin needs to run before anything else + init = function() + package.path = package.path + .. ";" + .. vim.fn.expand("$HOME") + .. "/.config/luarocks/share/lua/5.1/magick/init.lua;" + end, + opt = { + rocks = { "magick" }, + }, + }, + { "benlubas/image-save.nvim", cmd = "SaveImage" }, + { + "3rd/image.nvim", + dependencies = { "leafo/magick", "vhyrro/luarocks.nvim" }, + config = function() + require("image").setup({ + backend = "ueberzug", -- or "kitty", whatever backend you would like to use + processor = "magick_rock", -- or "magick_cli" + integrations = { + markdown = { + enabled = true, + clear_in_insert_mode = false, + download_remote_images = false, + only_render_image_at_cursor = false, + floating_windows = false, -- if true, images will be rendered in floating markdown windows + filetypes = { "markdown", "quarto" }, -- markdown extensions (ie. quarto) can go here + }, + neorg = { + enabled = true, + filetypes = { "norg" }, + }, + typst = { + enabled = true, + filetypes = { "typst" }, + }, + html = { + enabled = false, + }, + css = { + enabled = false, + }, + }, + max_width = 100, + max_height = 8, + max_height_window_percentage = math.huge, + max_width_window_percentage = math.huge, + window_overlap_clear_enabled = true, -- toggles images when windows are overlapped + window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "fidget", "" }, + editor_only_render_when_focused = true, -- auto show/hide images when the editor gains/looses focus + tmux_show_only_in_active_window = true, -- auto show/hide images in the correct Tmux window (needs visual-activity off) + hijack_file_patterns = { "*.png", "*.jpg", "*.jpeg", "*.gif", "*.webp", "*.avif" }, -- render image files as images when opened + }) + end, + }, + { + "quarto-dev/quarto-nvim", + dependencies = { + { + "jmbuhr/otter.nvim", + lazy = false, + dependencies = { + "nvim-treesitter/nvim-treesitter", + }, + opts = {}, + config = function() + require("otter").setup() + end, + }, + "hrsh7th/nvim-cmp", + "neovim/nvim-lspconfig", + }, + ft = { "quarto", "markdown" }, + command = "QuartoActivate", + config = function() + require("quarto").setup({ + debug = false, + closePreviewOnExit = true, + lspFeatures = { + languages = { "r", "python", "rust" }, + chunks = "all", + diagnostics = { + enabled = true, + triggers = { "BufWritePost" }, + }, + completion = { + enabled = true, + }, + }, + keymap = { + hover = "H", + definition = "gd", + rename = "rn", + references = "gr", + format = "gf", + }, + codeRunner = { + enabled = true, + default_method = "molten", + ft_runners = { + bash = "slime", + python = "molten", + }, + never_run = { "yaml" }, -- filetypes which are never sent to a code runner + }, + }) + local runner = require("quarto.runner") + vim.keymap.set("n", "jc", runner.run_cell, { silent = true, desc = "Run cell" }) + vim.keymap.set("n", "jC", runner.run_above, { silent = true, desc = "Run above cell" }) + vim.keymap.set("n", "jl", runner.run_line, { silent = true, desc = "Run line" }) + vim.keymap.set("v", "jv", runner.run_range, { silent = true, desc = "Run block" }) + vim.keymap.set("n", "ja", runner.run_all, { silent = true, desc = "Run all" }) + vim.keymap.set("n", "jA", function() + runner.run_all(true) + end, { desc = "run all cells of all languages", silent = true }) + vim.keymap.set( + "n", + "jp", + require("quarto").quartoPreview, + { noremap = true, silent = true, desc = "Preview the quarto document" } + ) + -- to create a cell in insert mode, I have the ` snippet + vim.keymap.set( + "n", + "cc", + "i```python\n```O", + { silent = true, desc = "Create a new code cell" } + ) + vim.keymap.set( + "n", + "cs", + "i```\r\r```{}", + { noremap = true, silent = true, desc = "Split code cell" } + ) + end, + }, + { + "benlubas/molten-nvim", + version = "^1.0.0", -- use version <2.0.0 to avoid breaking changes + dependencies = { "3rd/image.nvim" }, + build = ":UpdateRemotePlugins", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "j", group = "Molten (Jupyter)" }, + }) + + vim.g.molten_auto_image_popup = true + vim.g.molten_auto_init_behavior = "raise" + vim.g.molten_auto_open_html_in_browser = false + -- I find auto open annoying, keep in mind setting this option will require setting + -- a keybind for `:noautocmd MoltenEnterOutput` to open the output again + vim.g.molten_auto_open_output = false + vim.g.molten_cover_empty_lines = false + vim.g.molten_cover_lines_starting_with = {} + vim.g.molten_copy_output = false + vim.g.molten_enter_output_behavior = "open_then_enter" + -- this guide will be using image.nvim + -- Don't forget to setup and install the plugin if you want to view image outputs + vim.g.molten_image_provider = "image.nvim" + vim.g.molten_output_show_more = false + vim.g.molten_output_win_max_height = 30 + vim.g.molten_output_win_style = "minimal" + -- this will make it so the output shows up below the \`\`\` cell delimiter + vim.g.molten_virt_lines_off_by_1 = true + -- Output as virtual text. Allows outputs to always be shown, works with images, but can + -- be buggy with longer images + vim.g.molten_virt_text_output = true + -- optional, works for virt text and the output window + vim.g.molten_wrap_output = true + vim.g.molten_virt_text_max_lines = 20 + end, + config = function() + -- image nvim options table. Pass to `require('image').setup` + vim.keymap.set("n", "jJ", ":MoltenInit", { silent = true, desc = "Init molten" }) + vim.keymap.set("n", "j[", ":MoltenPrev", { silent = true, desc = "Go to prev code cell" }) + vim.keymap.set("n", "j]", ":MoltenNext", { silent = true, desc = "Go to next code cell" }) + vim.keymap.set( + "n", + "jo", + ":MoltenEvaluateOperator", + { silent = true, desc = "Evaluate operator" } + ) + vim.keymap.set("n", "jL", ":MoltenEvaluateLine", { silent = true, desc = "Evaluate line" }) + vim.keymap.set("n", "jr", ":MoltenReevaluateCell", { silent = true, desc = "Re-evaluate cell" }) + vim.keymap.set( + "v", + "jV", + ":MoltenEvaluateVisualgv", + { silent = true, desc = "Evaluate visual block" } + ) + vim.keymap.set("n", "jd", ":MoltenDelete", { silent = true, desc = "Delete molten" }) + vim.keymap.set("n", "js", ":MoltenShowOutput", { silent = true, desc = "Show output" }) + vim.keymap.set("n", "jh", ":MoltenHideOutput", { silent = true, desc = "Hide output" }) + vim.keymap.set( + "n", + "jm", + ":noautocmd MoltenEnterOutput", + { silent = true, desc = "Enter output" } + ) + vim.api.nvim_create_autocmd("User", { + pattern = "MoltenInitPost", + callback = function() + require("quarto").activate() + end, + }) + vim.keymap.set("n", "ji", ":MoltenImagePopup", { silent = true, desc = "Pop-up image" }) + vim.keymap.set("n", "jw", ":MoltenOpenInBrowser", { silent = true, desc = "Open in browser" }) + vim.keymap.set("n", "jj", function() + local venv_path = os.getenv("VIRTUAL_ENV") + if venv_path then + local venv_name = vim.fn.fnamemodify(venv_path, ":t") + vim.cmd(("MoltenInit %s"):format(venv_name)) + else + vim.cmd("MoltenInit python3") + end + end, { desc = "Init default molten" }) + end, + }, + { + "mipmip/vim-scimark", + config = function() + vim.keymap.set("n", "si", ":OpenInScim", { desc = "Sc-im" }) + end, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/marks.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/marks.lua new file mode 100644 index 0000000..d59d0f1 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/marks.lua @@ -0,0 +1,16 @@ +return { + "chentoast/marks.nvim", + config = function() + require("marks").setup() + end, + init = function() + local wk = require("which-key") + wk.add({ + { + mode = { "n", "v" }, + { "m", group = "Marks" }, + { "dm", desc = "Delete marks" }, + }, + }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/mini.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/mini.lua new file mode 100644 index 0000000..d9ea466 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/mini.lua @@ -0,0 +1,1162 @@ +-- Updated pattern to match what Echasnovski has in the documentation +-- https://github.com/echasnovski/mini.nvim/blob/c6eede272cfdb9b804e40dc43bb9bff53f38ed8a/doc/mini-files.txt#L508-L529 + +-- Define a function to update MiniJump highlight based on Search +local function update_mini_jump_highlight() + local search_hl = vim.api.nvim_get_hl(0, { name = "Search" }) + vim.api.nvim_set_hl(0, "MiniJump", { + fg = search_hl.fg, + bg = search_hl.bg, + bold = search_hl.bold or false, + }) +end + +return { + { + "echasnovski/mini.ai", + version = false, + config = function() + require("mini.ai").setup({ + -- Table with textobject id as fields, textobject specification as values. + -- Also use this to disable builtin textobjects. See |MiniAi.config|. + custom_textobjects = nil, + + -- Module mappings. Use `''` (empty string) to disable one. + mappings = { + -- Main textobject prefixes + around = "a", + inside = "i", + + -- Next/last variants + around_next = "an", + inside_next = "in", + around_last = "al", + inside_last = "il", + + -- Move cursor to corresponding edge of `a` textobject + goto_left = "g[", + goto_right = "g]", + }, + + -- Number of lines within which textobject is searched + n_lines = 50, + + -- How to search for object (first inside current line, then inside + -- neighborhood). One of 'cover', 'cover_or_next', 'cover_or_prev', + -- 'cover_or_nearest', 'next', 'previous', 'nearest'. + search_method = "cover_or_next", + + -- Whether to disable showing non-error feedback + -- This also affects (purely informational) helper messages shown after + -- idle time if user input is required. + silent = false, + }) + end, + }, + { + "echasnovski/mini.bracketed", + version = false, + config = function() + require("mini.bracketed").setup({ + buffer = { suffix = "", options = {} }, + comment = { suffix = "", options = {} }, + conflict = { suffix = "", options = {} }, + diagnostic = { suffix = "", options = {} }, + file = { suffix = "", options = {} }, + indent = { suffix = "", options = {} }, + jump = { suffix = "", options = {} }, + location = { suffix = "", options = {} }, + oldfile = { suffix = "", options = {} }, + quickfix = { suffix = "", options = {} }, + treesitter = { suffix = "", options = {} }, + undo = { suffix = "", options = {} }, + window = { suffix = "", options = {} }, + yank = { suffix = "", options = {} }, + }) + + vim.keymap.set("n", "[B", "lua MiniBracketed.buffer('first')", { desc = "Buffer first" }) + vim.keymap.set( + "n", + "[b", + "lua MiniBracketed.buffer('backward')", + { desc = "Buffer backward" } + ) + vim.keymap.set( + "n", + "]b", + "lua MiniBracketed.buffer('forward')", + { desc = "Buffer forward" } + ) + vim.keymap.set("n", "]B", "lua MiniBracketed.buffer('last')", { desc = "Buffer last" }) + vim.keymap.set("n", "[C", "lua MiniBracketed.comment('first')", { desc = "Comment first" }) + vim.keymap.set( + "n", + "[c", + "lua MiniBracketed.comment('backward')", + { desc = "Comment backward" } + ) + vim.keymap.set( + "n", + "]c", + "lua MiniBracketed.comment('forward')", + { desc = "Comment forward" } + ) + vim.keymap.set("n", "]C", "lua MiniBracketed.comment('last')", { desc = "Comment last" }) + vim.keymap.set( + "n", + "[X", + "lua MiniBracketed.conflict('first')", + { desc = "Conflict first" } + ) + vim.keymap.set( + "n", + "[x", + "lua MiniBracketed.conflict('backward')", + { desc = "Conflict backward" } + ) + vim.keymap.set( + "n", + "]x", + "lua MiniBracketed.conflict('forward')", + { desc = "Conflict forward" } + ) + vim.keymap.set("n", "]X", "lua MiniBracketed.conflict('last')", { desc = "Conflict last" }) + vim.keymap.set( + "n", + "[D", + "lua MiniBracketed.diagnostic('first')", + { desc = "Diagnostic first" } + ) + vim.keymap.set( + "n", + "[d", + "lua MiniBracketed.diagnostic('backward')", + { desc = "Diagnostic backward" } + ) + vim.keymap.set( + "n", + "]d", + "lua MiniBracketed.diagnostic('forward')", + { desc = "Diagnostic forward" } + ) + vim.keymap.set( + "n", + "]D", + "lua MiniBracketed.diagnostic('last')", + { desc = "Diagnostic last" } + ) + vim.keymap.set("n", "[F", "lua MiniBracketed.file('first')", { desc = "File first" }) + vim.keymap.set("n", "[f", "lua MiniBracketed.file('backward')", { desc = "File backward" }) + vim.keymap.set("n", "]f", "lua MiniBracketed.file('forward')", { desc = "File forward" }) + vim.keymap.set("n", "]F", "lua MiniBracketed.file('last')", { desc = "File last" }) + vim.keymap.set("n", "[I", "lua MiniBracketed.indent('first')", { desc = "Indent first" }) + vim.keymap.set( + "n", + "[i", + "lua MiniBracketed.indent('backward')", + { desc = "Indent backward" } + ) + vim.keymap.set( + "n", + "]i", + "lua MiniBracketed.indent('forward')", + { desc = "Indent forward" } + ) + vim.keymap.set("n", "]I", "lua MiniBracketed.indent('last')", { desc = "Indent last" }) + vim.keymap.set("n", "[J", "lua MiniBracketed.jump('first')", { desc = "Jump first" }) + vim.keymap.set("n", "[j", "lua MiniBracketed.jump('backward')", { desc = "Jump backward" }) + vim.keymap.set("n", "]j", "lua MiniBracketed.jump('forward')", { desc = "Jump forward" }) + vim.keymap.set("n", "]J", "lua MiniBracketed.jump('last')", { desc = "Jump last" }) + vim.keymap.set( + "n", + "[L", + "lua MiniBracketed.location('first')", + { desc = "Location first" } + ) + vim.keymap.set( + "n", + "[l", + "lua MiniBracketed.location('backward')", + { desc = "Location backward" } + ) + vim.keymap.set( + "n", + "]l", + "lua MiniBracketed.location('forward')", + { desc = "Location forward" } + ) + vim.keymap.set("n", "]L", "lua MiniBracketed.location('last')", { desc = "Location last" }) + vim.keymap.set("n", "[O", "lua MiniBracketed.oldfile('first')", { desc = "Oldfile first" }) + vim.keymap.set( + "n", + "[o", + "lua MiniBracketed.oldfile('backward')", + { desc = "Oldfile backward" } + ) + vim.keymap.set( + "n", + "]o", + "lua MiniBracketed.oldfile('forward')", + { desc = "Oldfile forward" } + ) + vim.keymap.set("n", "]O", "lua MiniBracketed.oldfile('last')", { desc = "Oldfile last" }) + vim.keymap.set( + "n", + "[Q", + "lua MiniBracketed.quickfix('first')", + { desc = "Quickfix first" } + ) + vim.keymap.set( + "n", + "[q", + "lua MiniBracketed.quickfix('backward')", + { desc = "Quickfix backward" } + ) + vim.keymap.set( + "n", + "]q", + "lua MiniBracketed.quickfix('forward')", + { desc = "Quickfix forward" } + ) + vim.keymap.set("n", "]Q", "lua MiniBracketed.quickfix('last')", { desc = "Quickfix last" }) + vim.keymap.set( + "n", + "[T", + "lua MiniBracketed.treesitter('first')", + { desc = "Treesitter first" } + ) + vim.keymap.set( + "n", + "[t", + "lua MiniBracketed.treesitter('backward')", + { desc = "Treesitter backward" } + ) + vim.keymap.set( + "n", + "]t", + "lua MiniBracketed.treesitter('forward')", + { desc = "Treesitter forward" } + ) + vim.keymap.set( + "n", + "]T", + "lua MiniBracketed.treesitter('last')", + { desc = "Treesitter last" } + ) + vim.keymap.set("n", "[U", "lua MiniBracketed.undo('first')", { desc = "Undo first" }) + vim.keymap.set("n", "[u", "lua MiniBracketed.undo('backward')", { desc = "Undo backward" }) + vim.keymap.set("n", "]u", "lua MiniBracketed.undo('forward')", { desc = "Undo forward" }) + vim.keymap.set("n", "]U", "lua MiniBracketed.undo('last')", { desc = "Undo last" }) + vim.keymap.set("n", "w0", "lua MiniBracketed.window('first')", { desc = "Window first" }) + vim.keymap.set( + "n", + "w[", + "lua MiniBracketed.window('backward')", + { desc = "Window backward" } + ) + vim.keymap.set( + "n", + "w]", + "lua MiniBracketed.window('forward')", + { desc = "Window forward" } + ) + vim.keymap.set("n", "w$", "lua MiniBracketed.window('last')", { desc = "Window last" }) + vim.keymap.set("n", "[Y", "lua MiniBracketed.yank('first')", { desc = "Yank first" }) + vim.keymap.set("n", "[y", "lua MiniBracketed.yank('backward')", { desc = "Yank backward" }) + vim.keymap.set("n", "]y", "lua MiniBracketed.yank('forward')", { desc = "Yank forward" }) + vim.keymap.set("n", "]Y", "lua MiniBracketed.yank('last')", { desc = "Yank last" }) + end, + }, + { + "echasnovski/mini.files", + opts = { + -- I didn't like the default mappings, so I modified them + -- Module mappings created only inside explorer. + -- Use `''` (empty string) to not create one. + mappings = { + close = "q", + -- Use this if you want to open several files + go_in = "l", + -- This opens the file, but quits out of mini.files (default L) + go_in_plus = "", + -- I swapped the following 2 (default go_out: h) + -- go_out_plus: when you go out, it shows you only 1 item to the right + -- go_out: shows you all the items to the right + go_out = "H", + go_out_plus = "h", + -- Default + reset = ",", + -- Default @ + reveal_cwd = ".", + show_help = "g?", + -- Default = + synchronize = "s", + trim_left = "<", + trim_right = ">", + toggle_hidden = nil, + change_cwd = nil, + go_in_horizontal = nil, + go_in_vertical = nil, + go_in_horizontal_plus = nil, + go_in_vertical_plus = nil, + }, + options = { + use_as_default_explorer = true, + permanent_delete = false, + }, + windows = { + preview = true, + width_focus = 25, + width_preview = 40, + }, + }, + keys = { + { + "ee", + function() + if not MiniFiles.close() then + require("mini.files").open(vim.api.nvim_buf_get_name(0), true) + end + end, + desc = "Open mini.files", + }, + { + "eE", + function() + require("mini.files").open(vim.uv.cwd(), true) + end, + desc = "Open mini.files (cwd)", + }, + }, + config = function(_, opts) + require("mini.files").setup(opts) + + local show_dotfiles = true + local filter_show = function(fs_entry) + return true + end + local filter_hide = function(fs_entry) + return not vim.startswith(fs_entry.name, ".") + end + + local toggle_dotfiles = function() + show_dotfiles = not show_dotfiles + local new_filter = show_dotfiles and filter_show or filter_hide + require("mini.files").refresh({ content = { filter = new_filter } }) + end + + local map_split = function(buf_id, lhs, direction, close_on_file) + local rhs = function() + local new_target_window + local cur_target_window = require("mini.files").get_explorer_state().arget_window + + if cur_target_window ~= nil then + vim.api.nvim_win_call(cur_target_window, function() + vim.cmd("belowright " .. direction .. " split") + new_target_window = vim.api.nvim_get_current_win() + end) + + require("mini.files").set_target_window(new_target_window) + require("mini.files").go_in({ close_on_file = close_on_file }) + end + end + + local desc = "Open in " .. direction .. " split" + if close_on_file then + desc = desc .. " and close" + end + vim.keymap.set("n", lhs, rhs, { buffer = buf_id, desc = desc }) + end + + local files_set_cwd = function() + local cur_entry_path = MiniFiles.get_fs_entry().path + local cur_directory = vim.fs.dirname(cur_entry_path) + if cur_directory ~= nil then + vim.fn.chdir(cur_directory) + end + end + + local mini_files = require("mini.files") + local tmux_pane_function = require("TheSiahxyz.utils.tmux").tmux_pane_function + + local open_tmux_pane = function() + local curr_entry = mini_files.get_fs_entry() + if curr_entry then + if curr_entry.fs_type == "directory" then + tmux_pane_function(curr_entry.path) + elseif curr_entry.fs_type == "file" then + local parent_dir = vim.fn.fnamemodify(curr_entry.path, ":h") + tmux_pane_function(parent_dir) + elseif curr_entry.fs_type == "link" then + local resolved_path = vim.fn.resolve(curr_entry.path) + if vim.fn.isdirectory(resolved_path) == 1 then + tmux_pane_function(resolved_path) + else + local parent_dir = vim.fn.fnamemodify(resolved_path, ":h") + tmux_pane_function(parent_dir) + end + else + vim.notify("Unsupported file system entry type", vim.log.levels.WARN) + end + else + vim.notify("No entry selected", vim.log.levels.WARN) + end + end + + local copy_to_clipboard = function() + local curr_entry = mini_files.get_fs_entry() + if curr_entry then + local path = curr_entry.path + -- Escape the path for shell command + local escaped_path = vim.fn.fnameescape(path) + local cmd = vim.fn.has("mac") == 1 + and string.format([[osascript -e 'set the clipboard to POSIX file "%s"']], escaped_path) + or string.format([[echo -n %s | xclip -selection clipboard]], escaped_path) + local result = vim.fn.system(cmd) + if vim.v.shell_error ~= 0 then + vim.notify("Copy failed: " .. result, vim.log.levels.ERROR) + else + vim.notify(vim.fn.fnamemodify(path, ":t"), vim.log.levels.INFO) + vim.notify("Copied to system clipboard", vim.log.levels.INFO) + end + else + vim.notify("No file or directory selected", vim.log.levels.WARN) + end + end + + local zip_and_copy_to_clipboard = function() + local curr_entry = require("mini.files").get_fs_entry() + if curr_entry then + local path = curr_entry.path + local name = vim.fn.fnamemodify(path, ":t") -- Extract the file or directory name + local parent_dir = vim.fn.fnamemodify(path, ":h") -- Get the parent directory + local timestamp = os.date("%y%m%d%H%M%S") -- Append timestamp to avoid duplicates + local zip_path = string.format("/tmp/%s_%s.zip", name, timestamp) -- Path in macOS's tmp directory + -- Create the zip file + local zip_cmd = string.format( + "cd %s && zip -r %s %s", + vim.fn.shellescape(parent_dir), + vim.fn.shellescape(zip_path), + vim.fn.shellescape(name) + ) + local result = vim.fn.system(zip_cmd) + if vim.v.shell_error ~= 0 then + vim.notify("Failed to create zip file: " .. result, vim.log.levels.ERROR) + return + end + -- Copy the zip file to the system clipboard + local copy_cmd = vim.fn.has("mac") == 1 + and string.format([[osascript -e 'set the clipboard to POSIX file "%s"']], zip_path) + or string.format([[echo -n %s | xclip -selection clipboard]], zip_path) + local copy_result = vim.fn.system(copy_cmd) + if vim.v.shell_error ~= 0 then + vim.notify("Failed to copy zip file to clipboard: " .. copy_result, vim.log.levels.ERROR) + return + end + vim.notify(zip_path, vim.log.levels.INFO) + vim.notify("Zipped and copied to clipboard: ", vim.log.levels.INFO) + else + vim.notify("No file or directory selected", vim.log.levels.WARN) + end + end + + local paste_from_clipboard = function() + -- vim.notify("Starting the paste operation...", vim.log.levels.INFO) + if not mini_files then + vim.notify("mini.files module not loaded.", vim.log.levels.ERROR) + return + end + local curr_entry = mini_files.get_fs_entry() -- Get the current file system entry + if not curr_entry then + vim.notify("Failed to retrieve current entry in mini.files.", vim.log.levels.ERROR) + return + end + local curr_dir = curr_entry.fs_type == "directory" and curr_entry.path + or vim.fn.fnamemodify(curr_entry.path, ":h") -- Use parent directory if entry is a file + -- vim.notify("Current directory: " .. curr_dir, vim.log.levels.INFO) + local script = [[ + tell application "System Events" + try + set theFile to the clipboard as alias + set posixPath to POSIX path of theFile + return posixPath + on error + return "error" + end try + end tell + ]] + local output = vim.fn.has("mac") == 1 and vim.fn.system("osascript -e " .. vim.fn.shellescape(script)) + or vim.fn.system("xclip -o -selection clipboard") + if vim.v.shell_error ~= 0 or output:find("error") then + vim.notify("Clipboard does not contain a valid file or directory.", vim.log.levels.WARN) + return + end + local source_path = output:gsub("%s+$", "") -- Trim whitespace from clipboard output + if source_path == "" then + vim.notify("Clipboard is empty or invalid.", vim.log.levels.WARN) + return + end + local dest_path = curr_dir .. "/" .. vim.fn.fnamemodify(source_path, ":t") -- Destination path in current directory + local copy_cmd = vim.fn.isdirectory(source_path) == 1 and { "cp", "-R", source_path, dest_path } + or { "cp", source_path, dest_path } -- Construct copy command + local result = vim.fn.system(copy_cmd) -- Execute the copy command + if vim.v.shell_error ~= 0 then + vim.notify("Paste operation failed: " .. result, vim.log.levels.ERROR) + return + end + -- vim.notify("Pasted " .. source_path .. " to " .. dest_path, vim.log.levels.INFO) + mini_files.synchronize() -- Refresh mini.files to show updated directory content + vim.notify("Pasted successfully.", vim.log.levels.INFO) + end + + local copy_path_to_clipboard = function() + -- Get the current entry (file or directory) + local curr_entry = mini_files.get_fs_entry() + if curr_entry then + -- Convert path to be relative to home directory + local home_dir = vim.fn.expand("~") + local relative_path = curr_entry.path:gsub("^" .. home_dir, "~") + vim.fn.setreg("+", relative_path) -- Copy the relative path to the clipboard register + vim.notify(vim.fn.fnamemodify(relative_path, ":t"), vim.log.levels.INFO) + vim.notify("Path copied to clipboard: ", vim.log.levels.INFO) + else + vim.notify("No file or directory selected", vim.log.levels.WARN) + end + end + + local preview_image = function() + local curr_entry = mini_files.get_fs_entry() + if curr_entry then + -- Preview the file using Quick Look + if vim.fn.has("mac") == 1 then + vim.system({ "qlmanage", "-p", curr_entry.path }, { + stdout = false, + stderr = false, + }) + vim.defer_fn(function() + vim.system({ "osascript", "-e", 'tell application "qlmanage" to activate' }) + end, 200) + else + -- TODO: add previewer for linux + vim.notify("Preview not supported on Linux.", vim.log.levels.WARN) + end + else + vim.notify("No file selected", vim.log.levels.WARN) + end + end + + local preview_image_popup = function() + -- Clear any existing images before rendering the new one + require("image").clear() + local curr_entry = mini_files.get_fs_entry() + if curr_entry and curr_entry.fs_type == "file" then + local ext = vim.fn.fnamemodify(curr_entry.path, ":e"):lower() + local supported_image_exts = { "png", "jpg", "jpeg", "gif", "bmp", "webp", "avif" } + -- Check if the file has a supported image extension + if vim.tbl_contains(supported_image_exts, ext) then + -- Save mini.files state (current path and focused entry) + local current_dir = vim.fn.fnamemodify(curr_entry.path, ":h") + local focused_entry = vim.fn.fnamemodify(curr_entry.path, ":t") -- Extract filename + -- Create a floating window for the image preview + local popup_width = math.floor(vim.o.columns * 0.6) + local popup_height = math.floor(vim.o.lines * 0.6) + local col = math.floor((vim.o.columns - popup_width) / 2) + local row = math.floor((vim.o.lines - popup_height) / 2) + local buf = vim.api.nvim_create_buf(false, true) -- Create a scratch buffer + local win = vim.api.nvim_open_win(buf, true, { + relative = "editor", + row = row, + col = col, + width = popup_width, + height = popup_height, + style = "minimal", + border = "rounded", + }) + -- Declare img_width and img_height at the top + local img_width, img_height + -- Get image dimensions using ImageMagick's identify command + local dimensions = vim.fn.systemlist( + string.format("identify -format '%%w %%h' %s", vim.fn.shellescape(curr_entry.path)) + ) + if #dimensions > 0 then + img_width, img_height = dimensions[1]:match("(%d+) (%d+)") + img_width = tonumber(img_width) + img_height = tonumber(img_height) + end + -- Calculate image display size while maintaining aspect ratio + local display_width = popup_width + local display_height = popup_height + if img_width and img_height then + local aspect_ratio = img_width / img_height + if aspect_ratio > (popup_width / popup_height) then + -- Image is wider than the popup window + display_height = math.floor(popup_width / aspect_ratio) + else + -- Image is taller than the popup window + display_width = math.floor(popup_height * aspect_ratio) + end + end + -- Center the image within the popup window + local image_x = math.floor((popup_width - display_width) / 2) + local image_y = math.floor((popup_height - display_height) / 2) + -- Use image.nvim to render the image + local img = require("image").from_file(curr_entry.path, { + id = curr_entry.path, -- Unique ID + window = win, -- Bind the image to the popup window + buffer = buf, -- Bind the image to the popup buffer + x = image_x, + y = image_y, + width = display_width, + height = display_height, + with_virtual_padding = true, + }) + -- Render the image + if img ~= nil then + img:render() + end + -- Use `stat` or `ls` to get the file size in bytes + local file_size_bytes = "" + if vim.fn.has("mac") == 1 or vim.fn.has("unix") == 1 then + -- For macOS or Linux systems + local handle = io.popen( + "stat -f%z " + .. vim.fn.shellescape(curr_entry.path) + .. " || ls -l " + .. vim.fn.shellescape(curr_entry.path) + .. " | awk '{print $5}'" + ) + if handle then + file_size_bytes = handle:read("*a"):gsub("%s+$", "") -- Trim trailing whitespace + handle:close() + end + else + -- Fallback message if the command isn't available + file_size_bytes = "0" + end + -- Convert the size to MB (if valid) + local file_size_mb = tonumber(file_size_bytes) and tonumber(file_size_bytes) / (1024 * 1024) + or 0 + local file_size_mb_str = string.format("%.2f", file_size_mb) -- Format to 2 decimal places as a string + -- Add image information (filename, size, resolution) + local image_info = {} + table.insert(image_info, "Image File: " .. focused_entry) -- Add only the filename + if tonumber(file_size_bytes) > 0 then + table.insert(image_info, "Size: " .. file_size_mb_str .. " MB") -- Use the formatted string + else + table.insert(image_info, "Size: Unable to detect") -- Fallback if size isn't found + end + if img_width and img_height then + table.insert(image_info, "Resolution: " .. img_width .. " x " .. img_height) + else + table.insert(image_info, "Resolution: Unable to detect") + end + -- Append the image information after the image + local line_count = vim.api.nvim_buf_line_count(buf) + vim.api.nvim_buf_set_lines(buf, line_count, -1, false, { "", "", "" }) -- Add 3 empty lines + vim.api.nvim_buf_set_lines(buf, -1, -1, false, image_info) + -- Keymap for closing the popup and reopening mini.files + local function reopen_mini_files() + if img ~= nil then + img:clear() + end + vim.api.nvim_win_close(win, true) + -- Reopen mini.files in the same directory + require("mini.files").open(current_dir, true) + vim.defer_fn(function() + -- Simulate navigation to the file by searching for the line matching the file + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) -- Get all lines in the buffer + for i, line in ipairs(lines) do + if line:match(focused_entry) then + vim.api.nvim_win_set_cursor(0, { i, 0 }) -- Move cursor to the matching line + break + end + end + end, 50) -- Small delay to ensure mini.files is initialized + end + vim.keymap.set("n", "", reopen_mini_files, { buffer = buf, noremap = true, silent = true }) + else + vim.notify("Not an image file.", vim.log.levels.WARN) + end + else + vim.notify("No file selected or not a file.", vim.log.levels.WARN) + end + end + + local follow_symlink = function() + local curr_entry = mini_files.get_fs_entry() + if curr_entry and curr_entry.fs_type == "file" then + local resolved_path = vim.fn.resolve(curr_entry.path) -- Resolve symlink to original file + if resolved_path ~= curr_entry.path then + vim.notify("Following symlink to: " .. resolved_path, vim.log.levels.INFO) + mini_files.open(resolved_path, true) -- Open the original file in mini.files + else + vim.notify("The file is not a symlink.", vim.log.levels.WARN) + end + else + vim.notify("No file selected or not a valid file.", vim.log.levels.WARN) + end + end + + vim.api.nvim_create_autocmd("User", { + pattern = "MiniFilesBufferCreate", + callback = function() + local buf_id = vim.api.nvim_get_current_buf() + + vim.keymap.set( + "n", + opts.mappings and opts.mappings.toggle_hidden or "g.", + toggle_dotfiles, + { buffer = buf_id, desc = "Toggle hidden files" } + ) + + vim.keymap.set( + "n", + opts.mappings and opts.mappings.change_cwd or "gc", + files_set_cwd, + { buffer = buf_id, desc = "Set cwd" } + ) + + map_split(buf_id, opts.mappings and opts.mappings.go_in_horizontal or "s", "horizontal", false) + map_split(buf_id, opts.mappings and opts.mappings.go_in_vertical or "v", "vertical", false) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_horizontal_plus or "S", + "horizontal", + true + ) + map_split(buf_id, opts.mappings and opts.mappings.go_in_vertical_plus or "V", "vertical", true) + + vim.keymap.set( + "n", + "zt", + open_tmux_pane, + { buffer = buf_id, noremap = true, silent = true, desc = "Open tmux pane" } + ) + vim.keymap.set( + "n", + "zy", + copy_to_clipboard, + { buffer = buf_id, noremap = true, silent = true, desc = "Copy to clipboard" } + ) + vim.keymap.set( + "n", + "zY", + copy_path_to_clipboard, + { buffer = buf_id, desc = "Copy path to clipboard" } + ) + vim.keymap.set( + "n", + "zc", + zip_and_copy_to_clipboard, + { buffer = buf_id, noremap = true, silent = true, desc = "Zip and copy" } + ) + vim.keymap.set( + "n", + "zp", + paste_from_clipboard, + { buffer = buf_id, noremap = true, silent = true, desc = "Paste from clipboard" } + ) + vim.keymap.set( + "n", + "zi", + preview_image, + { buffer = buf_id, noremap = true, silent = true, desc = "Preview image" } + ) + vim.keymap.set( + "n", + "zI", + preview_image_popup, + { buffer = buf_id, noremap = true, silent = true, desc = "Pop-up preview image" } + ) + vim.keymap.set( + "n", + "gl", + follow_symlink, + { buffer = buf_id, noremap = true, silent = true, desc = "Follow link" } + ) + end, + }) + + -- Git status + local nsMiniFiles = vim.api.nvim_create_namespace("mini_files_git") + local autocmd = vim.api.nvim_create_autocmd + local _, MiniFiles = pcall(require, "mini.files") + + -- Cache for git status + local gitStatusCache = {} + local cacheTimeout = 2000 -- Cache timeout in milliseconds + + ---@type table + ---@param status string + ---@return string symbol, string hlGroup + local function mapSymbols(status) + local statusMap = { + -- stylua: ignore start + [" M"] = { symbol = "•", hlGroup = "GitSignsChange"}, -- Modified in the working directory + ["M "] = { symbol = "✹", hlGroup = "GitSignsChange"}, -- modified in index + ["MM"] = { symbol = "≠", hlGroup = "GitSignsChange"}, -- modified in both working tree and index + ["A "] = { symbol = "+", hlGroup = "GitSignsAdd" }, -- Added to the staging area, new file + ["AA"] = { symbol = "≈", hlGroup = "GitSignsAdd" }, -- file is added in both working tree and index + ["D "] = { symbol = "-", hlGroup = "GitSignsDelete"}, -- Deleted from the staging area + ["AM"] = { symbol = "⊕", hlGroup = "GitSignsChange"}, -- added in working tree, modified in index + ["AD"] = { symbol = "-•", hlGroup = "GitSignsChange"}, -- Added in the index and deleted in the working directory + ["R "] = { symbol = "→", hlGroup = "GitSignsChange"}, -- Renamed in the index + ["U "] = { symbol = "‖", hlGroup = "GitSignsChange"}, -- Unmerged path + ["UU"] = { symbol = "⇄", hlGroup = "GitSignsAdd" }, -- file is unmerged + ["UA"] = { symbol = "⊕", hlGroup = "GitSignsAdd" }, -- file is unmerged and added in working tree + ["??"] = { symbol = "?", hlGroup = "GitSignsDelete"}, -- Untracked files + ["!!"] = { symbol = "!", hlGroup = "GitSignsChange"}, -- Ignored files + -- stylua: ignore end + } + + local result = statusMap[status] or { symbol = "?", hlGroup = "NonText" } + return result.symbol, result.hlGroup + end + + ---@param cwd string + ---@param callback function + ---@return nil + local function fetchGitStatus(cwd, callback) + local function on_exit(content) + if content.code == 0 then + callback(content.stdout) + vim.g.content = content.stdout + end + end + vim.system({ "git", "status", "--ignored", "--porcelain" }, { text = true, cwd = cwd }, on_exit) + end + + ---@param str string? + local function escapePattern(str) + return str:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") + end + + ---@param buf_id integer + ---@param gitStatusMap table + ---@return nil + local function updateMiniWithGit(buf_id, gitStatusMap) + vim.schedule(function() + local nlines = vim.api.nvim_buf_line_count(buf_id) + local cwd = vim.fs.root(buf_id, ".git") + local escapedcwd = escapePattern(cwd) + if vim.fn.has("win32") == 1 then + escapedcwd = escapedcwd:gsub("\\", "/") + end + + for i = 1, nlines do + local entry = MiniFiles.get_fs_entry(buf_id, i) + if not entry then + break + end + local relativePath = entry.path:gsub("^" .. escapedcwd .. "/", "") + local status = gitStatusMap[relativePath] + + if status then + local symbol, hlGroup = mapSymbols(status) + vim.api.nvim_buf_set_extmark(buf_id, nsMiniFiles, i - 1, 0, { + -- NOTE: if you want the signs on the right uncomment those and comment + -- the 3 lines after + -- virt_text = { { symbol, hlGroup } }, + -- virt_text_pos = "right_align", + sign_text = symbol, + sign_hl_group = hlGroup, + priority = 2, + }) + else + end + end + end) + end + + -- Thanks for the idea of gettings https://github.com/refractalize/oil-git-status.nvim signs for dirs + ---@param content string + ---@return table + local function parseGitStatus(content) + local gitStatusMap = {} + -- lua match is faster than vim.split (in my experience ) + for line in content:gmatch("[^\r\n]+") do + local status, filePath = string.match(line, "^(..)%s+(.*)") + -- Split the file path into parts + local parts = {} + for part in filePath:gmatch("[^/]+") do + table.insert(parts, part) + end + -- Start with the root directory + local currentKey = "" + for i, part in ipairs(parts) do + if i > 1 then + -- Concatenate parts with a separator to create a unique key + currentKey = currentKey .. "/" .. part + else + currentKey = part + end + -- If it's the last part, it's a file, so add it with its status + if i == #parts then + gitStatusMap[currentKey] = status + else + -- If it's not the last part, it's a directory. Check if it exists, if not, add it. + if not gitStatusMap[currentKey] then + gitStatusMap[currentKey] = status + end + end + end + end + return gitStatusMap + end + + ---@param buf_id integer + ---@return nil + local function updateGitStatus(buf_id) + if not vim.fs.root(vim.uv.cwd(), ".git") then + return + end + + local cwd = vim.fn.expand("%:p:h") + local currentTime = os.time() + if gitStatusCache[cwd] and currentTime - gitStatusCache[cwd].time < cacheTimeout then + updateMiniWithGit(buf_id, gitStatusCache[cwd].statusMap) + else + fetchGitStatus(cwd, function(content) + local gitStatusMap = parseGitStatus(content) + gitStatusCache[cwd] = { + time = currentTime, + statusMap = gitStatusMap, + } + updateMiniWithGit(buf_id, gitStatusMap) + end) + end + end + + ---@return nil + local function clearCache() + gitStatusCache = {} + end + + local function augroup(name) + return vim.api.nvim_create_augroup("MiniFiles_" .. name, { clear = true }) + end + + autocmd("User", { + group = augroup("start"), + pattern = "MiniFilesExplorerOpen", + callback = function() + local bufnr = vim.api.nvim_get_current_buf() + local path = vim.api.nvim_buf_get_name(bufnr) + if path:match("^minifiles://") then + return + end + updateGitStatus(bufnr) + end, + }) + + autocmd("User", { + group = augroup("close"), + pattern = "MiniFilesExplorerClose", + callback = function() + clearCache() + end, + }) + + autocmd("User", { + group = augroup("update"), + pattern = "MiniFilesBufferUpdate", + callback = function(sii) + local bufnr = sii.data.buf_id + local cwd = vim.fn.expand("%:p:h") + if gitStatusCache[cwd] then + updateMiniWithGit(bufnr, gitStatusCache[cwd].statusMap) + end + end, + }) + end, + }, + { + "echasnovski/mini.indentscope", + version = false, -- wait till new 0.7.0 release to put it back on semver + event = "VeryLazy", + opts = { + mappings = { + -- Textobjects + object_scope = "i-", + object_scope_with_border = "a-", + + -- Motions (jump to respective border line; if not present - body line) + goto_top = "g,", + goto_bottom = "g;", + }, + draw = { + animation = function() + return 0 + end, + }, + options = { try_as_border = true }, + symbol = "│", + }, + init = function() + vim.api.nvim_create_autocmd("FileType", { + pattern = { + "help", + "Trouble", + "trouble", + "lazy", + "mason", + }, + callback = function() + vim.b.miniindentscope_disable = true + end, + }) + end, + }, + { + "echasnovski/mini.map", + version = false, + config = function() + require("mini.map").setup( + -- No need to copy this inside `setup()`. Will be used automatically. + { + -- Highlight integrations (none by default) + integrations = nil, + + -- Symbols used to display data + symbols = { + -- Encode symbols. See `:h MiniMap.config` for specification and + -- `:h MiniMap.gen_encode_symbols` for pre-built ones. + -- Default: solid blocks with 3x2 resolution. + encode = nil, + + -- Scrollbar parts for view and line. Use empty string to disable any. + scroll_line = "█", + scroll_view = "┃", + }, + + -- Window options + window = { + -- Whether window is focusable in normal way (with `wincmd` or mouse) + focusable = true, + + -- Side to stick ('left' or 'right') + side = "right", + + -- Whether to show count of multiple integration highlights + show_integration_count = true, + + -- Total width + width = 10, + + -- Value of 'winblend' option + winblend = 25, + + -- Z-index + zindex = 10, + }, + } + ) + end, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "m", group = "Markdown/Map" }, + { "mt", group = "Toggle" }, + }) + end, + keys = { + { "mo", "lua MiniMap.open()", desc = "Open map" }, + { "mm", "lua MiniMap.refresh()", desc = "Refresh map" }, + { "mc", "lua MiniMap.close()", desc = "Close map" }, + { "mtm", "lua MiniMap.toggle()", desc = "Toggle map" }, + { "mts", "lua MiniMap.toggle_side()", desc = "Toggle side map" }, + }, + }, + { + "echasnovski/mini.move", + version = false, + config = function() + -- No need to copy this inside `setup()`. Will be used automatically. + require("mini.move").setup({ + -- Module mappings. Use `''` (empty string) to disable one. + mappings = { + -- Move visual selection in Visual mode. Defaults are Alt (Meta) + hjkl. + left = "", + right = "", + down = "", + up = "", + + -- Move current line in Normal mode + line_left = "", + line_right = "", + line_down = "", + line_up = "", + }, + + -- Options which control moving behavior + options = { + -- Automatically reindent selection during linewise vertical move + reindent_linewise = true, + }, + }) + end, + }, + { + "echasnovski/mini.pairs", + version = false, + event = "VeryLazy", + config = function() + require("mini.pairs").setup() + end, + keys = { + { + "zp", + function() + vim.g.minipairs_disable = not vim.g.minipairs_disable + end, + desc = "Toggle auto pairs", + }, + }, + }, + { + "echasnovski/mini.splitjoin", + version = false, + config = function() + require("mini.splitjoin").setup() + + vim.keymap.set( + "n", + "zj", + ":lua MiniSplitjoin.toggle()", + { noremap = true, silent = true, desc = "Toggle split-join" } + ) + vim.keymap.set( + "n", + "J", + ":lua MiniSplitjoin.join()", + { noremap = true, silent = true, desc = "Join" } + ) + vim.keymap.set( + "n", + "", + ":lua MiniSplitjoin.split()", + { noremap = true, silent = true, desc = "Split" } + ) + end, + }, + { + "echasnovski/mini.trailspace", + version = false, + config = function() + require("mini.trailspace").setup() + vim.keymap.set( + "n", + "zt", + ":lua MiniTrailspace.trim()", + { noremap = true, silent = true, desc = "Trim trailing whitespace" } + ) + vim.keymap.set( + "n", + "zl", + ":lua MiniTrailspace.trim_last_lines()", + { noremap = true, silent = true, desc = "Trim trailing empty lines" } + ) + end, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/navic.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/navic.lua new file mode 100644 index 0000000..89cfa81 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/navic.lua @@ -0,0 +1,52 @@ +return { + "SmiteshP/nvim-navic", + dependencies = { + "neovim/nvim-lspconfig", + }, + config = function() + require("nvim-navic").setup({ + icons = { + File = "󰈙 ", + Module = " ", + Namespace = "󰌗 ", + Package = " ", + Class = "󰌗 ", + Method = "󰆧 ", + Property = " ", + Field = " ", + Constructor = " ", + Enum = "󰕘", + Interface = "󰕘", + Function = "󰊕 ", + Variable = "󰆧 ", + Constant = "󰏿 ", + String = "󰀬 ", + Number = "󰎠 ", + Boolean = "◩ ", + Array = "󰅪 ", + Object = "󰅩 ", + Key = "󰌋 ", + Null = "󰟢 ", + EnumMember = " ", + Struct = "󰌗 ", + Event = " ", + Operator = "󰆕 ", + TypeParameter = "󰊄 ", + }, + lsp = { + auto_attach = true, + preference = nil, + }, + highlight = true, + separator = " > ", + depth_limit = 5, + depth_limit_indicator = "..", + safe_output = true, + lazy_update_context = false, + click = true, + format_text = function(text) + return text + end, + }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/neo-tree.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/neo-tree.lua new file mode 100644 index 0000000..6666f2d --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/neo-tree.lua @@ -0,0 +1,141 @@ +return { + -- { + -- "nvim-neo-tree/neo-tree.nvim", + -- branch = "v3.x", + -- dependencies = { + -- "nvim-lua/plenary.nvim", + -- "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended + -- "MunifTanjim/nui.nvim", + -- { + -- "s1n7ax/nvim-window-picker", -- for open_with_window_picker keymaps + -- version = "2.*", + -- config = function() + -- require("window-picker").setup({ + -- filter_rules = { + -- include_current_win = false, + -- autoselect_one = true, + -- -- filter using buffer options + -- bo = { + -- -- if the file type is one of following, the window will be ignored + -- filetype = { "neo-tree", "neo-tree-popup", "notify" }, + -- -- if the buffer type is one of following, the window will be ignored + -- buftype = { "terminal", "quickfix" }, + -- }, + -- }, + -- }) + -- end, + -- }, + -- { "3rd/image.nvim", opts = {} }, -- Optional image support in preview window: See `# Preview Mode` for more information + -- }, + -- lazy = false, -- neo-tree will lazily load itself + -- ---@module "neo-tree" + -- ---@type neotree.Config? + -- opts = { + -- hijack_netrw_behavior = "disabled", -- netrw disabled, opening a directory opens neo-tree + -- filesystem = { + -- follow_current_file = { enabled = false }, + -- commands = { + -- -- over write default 'delete' command to 'trash'. + -- delete = function(state) + -- if vim.fn.executable("trash") == 0 then + -- vim.api.nvim_echo({ + -- { "- Trash utility not installed. Make sure to install it first\n", nil }, + -- { "- In macOS run `brew install trash`\n", nil }, + -- { "- Or delete the `custom delete command` section in neo-tree", nil }, + -- }, false, {}) + -- return + -- end + -- local inputs = require("neo-tree.ui.inputs") + -- local path = state.tree:get_node().path + -- local msg = "Are you sure you want to trash " .. path + -- inputs.confirm(msg, function(confirmed) + -- if not confirmed then + -- return + -- end + -- + -- vim.fn.system({ "trash", vim.fn.fnameescape(path) }) + -- require("neo-tree.sources.manager").refresh(state.name) + -- end) + -- end, + -- -- Overwrite default 'delete_visual' command to 'trash' x n. + -- delete_visual = function(state, selected_nodes) + -- if vim.fn.executable("trash") == 0 then + -- vim.api.nvim_echo({ + -- { "- Trash utility not installed. Make sure to install it first\n", nil }, + -- { "- In macOS run `brew install trash`\n", nil }, + -- { "- Or delete the `custom delete command` section in neo-tree", nil }, + -- }, false, {}) + -- return + -- end + -- local inputs = require("neo-tree.ui.inputs") + -- + -- -- Function to get the count of items in a table + -- local function GetTableLen(tbl) + -- local len = 0 + -- for _ in pairs(tbl) do + -- len = len + 1 + -- end + -- return len + -- end + -- + -- local count = GetTableLen(selected_nodes) + -- local msg = "Are you sure you want to trash " .. count .. " files?" + -- inputs.confirm(msg, function(confirmed) + -- if not confirmed then + -- return + -- end + -- for _, node in ipairs(selected_nodes) do + -- vim.fn.system({ "trash", vim.fn.fnameescape(node.path) }) + -- end + -- require("neo-tree.sources.manager").refresh(state.name) + -- end) + -- end, + -- }, + -- }, + -- }, + -- keys = { + -- { "e", false }, + -- { "E", false }, + -- { + -- "en", + -- function() + -- local buf_name = vim.api.nvim_buf_get_name(0) + -- -- Function to check if NeoTree is open in any window + -- local function is_neo_tree_open() + -- for _, win in ipairs(vim.api.nvim_list_wins()) do + -- local buf = vim.api.nvim_win_get_buf(win) + -- if vim.bo[buf].filetype == "neo-tree" then + -- return true + -- end + -- end + -- return false + -- end + -- -- Check if the current file exists + -- if + -- vim.fn.filereadable(buf_name) == 1 + -- or vim.fn.isdirectory(vim.fn.fnamemodify(buf_name, ":p:h")) == 1 + -- then + -- if is_neo_tree_open() then + -- -- Close NeoTree if it's open + -- vim.cmd("Neotree close") + -- else + -- -- Open NeoTree and reveal the current file + -- vim.cmd("Neotree reveal") + -- end + -- else + -- -- If the file doesn't exist, execute the logic for R + -- require("neo-tree.command").execute({ toggle = true, dir = vim.uv.cwd() }) + -- end + -- end, + -- desc = "Open neo-tree", + -- }, + -- { + -- "eN", + -- function() + -- require("neo-tree.command").execute({ toggle = true, dir = vim.uv.cwd() }) + -- end, + -- desc = "Open neo-tree (cwd)", + -- }, + -- }, + -- }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/obsidian.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/obsidian.lua new file mode 100644 index 0000000..c5f3a59 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/obsidian.lua @@ -0,0 +1,616 @@ +return { + "epwalsh/obsidian.nvim", + version = "*", -- recommended, use latest release instead of latest commit + lazy = true, + ft = "markdown", + -- Replace the above line with this if you only want to load obsidian.nvim for markdown files in your vault: + -- event = { + -- -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand'. + -- -- E.g. "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/*.md" + -- -- refer to `:h file-pattern` for more examples + -- "BufReadPre path/to/my-vault/*.md", + -- "BufNewFile path/to/my-vault/*.md", + -- }, + dependencies = { + -- Required. + "nvim-lua/plenary.nvim", + -- see below for full list of optional dependencies 👇 + "hrsh7th/nvim-cmp", + "nvim-telescope/telescope.nvim", + "nvim-treesitter/nvim-treesitter", + { + "epwalsh/pomo.nvim", + dependencies = "nvim-lualine/lualine.nvim", + config = function() + require("lualine").setup({ + sections = { + lualine_x = { + function() + local ok, pomo = pcall(require, "pomo") + if not ok then + return "" + end + + local timer = pomo.get_first_to_finish() + if timer == nil then + return "" + end + + return "󰄉 " .. tostring(timer) + end, + "encoding", + "fileformat", + "filetype", + }, + }, + }) + + require("telescope").load_extension("pomodori") + + vim.keymap.set("n", "mp", function() + require("telescope").extensions.pomodori.timers() + end, { desc = "Manage pomodori" }) + end, + }, + }, + cmd = { + "ObsidianOpen", + "ObsidianNew", + "ObsidianQuickSwitch", + "ObsidianFollowLink", + "ObsidianBacklinks", + "ObsidianTags", + "ObsidianToday", + "ObsidianYesterday", + "ObsidianTomorrow", + "ObsidianDailies", + "ObsidianTemplate", + "ObsidianSearch", + "ObsidianLink", + "ObsidianLinkNew", + "ObsidianExtractNote", + "ObsidianWorkspace", + "ObsidianPasteImg", + "ObsidianRename", + "ObsidianToggleCheckbox", + "ObsidianNewFromTemplate", + "ObsidianTOC", + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "o", group = "Open/Obsidian" }, + { "of", group = "Find files (Obsidian)" }, + { "on", group = "Notes (Obsidian)" }, + { "op", group = "Paste (Obsidian)" }, + { "ot", group = "Templates (Obsidian)" }, + }) + end, + config = function() + require("obsidian").setup({ + -- A list of workspace names, paths, and configuration overrides. + -- If you use the Obsidian app, the 'path' of a workspace should generally be + -- your vault root (where the `.obsidian` folder is located). + -- When obsidian.nvim is loaded by your plugin manager, it will automatically set + -- the workspace to the first workspace in the list whose `path` is a parent of the + -- current markdown file being edited. + workspaces = { + { + name = "personal", + path = "~/Private/repos/Obsidian/SI", + -- Optional, override certain settings. + overrides = { + notes_subdir = "", + }, + }, + }, + + -- Alternatively - and for backwards compatibility - you can set 'dir' to a single path instead of + -- 'workspaces'. For example: + -- dir = "~/vaults/work", + + -- Optional, if you keep notes in a specific subdirectory of your vault. + notes_subdir = "", + + -- Optional, set the log level for obsidian.nvim. This is an integer corresponding to one of the log + -- levels defined by "vim.log.levels.*". + log_level = vim.log.levels.INFO, + + daily_notes = { + -- Optional, if you keep daily notes in a separate directory. + folder = "Area/Notes", + -- Optional, if you want to change the date format for the ID of daily notes. + date_format = "%Y-%m-%d", + -- Optional, if you want to change the date format of the default alias of daily notes. + alias_format = "%B %-d, %Y", + -- Optional, default tags to add to each new daily note created. + default_tags = { "daily-notes" }, + -- Optional, if you want to automatically insert a template from your template directory like 'daily.md' + template = nil, + }, + + -- Optional, completion of wiki links, local markdown links, and tags using nvim-cmp. + completion = { + -- Set to false to disable completion. + nvim_cmp = true, + -- Trigger completion at 2 chars. + min_chars = 2, + }, + + -- Optional, configure key mappings. These are the defaults. If you don't want to set any keymappings this + -- way then set 'mappings = {}'. + mappings = { + -- Smart action depending on context, either follow link or toggle checkbox. + [""] = { + action = function() + return require("obsidian").util.smart_action() + end, + opts = { buffer = true, expr = true }, + }, + }, + + -- Where to put new notes. Valid options are + -- * "current_dir" - put new notes in same directory as the current buffer. + -- * "notes_subdir" - put new notes in the default notes subdirectory. + new_notes_location = "current_dir", + + -- Optional, customize how note IDs are generated given an optional title. + ---@param title string|? + ---@return string + note_id_func = function(title) + -- Create note IDs in a Zettelkasten format with a timestamp and a suffix. + -- In this case a note with the title 'My new note' will be given an ID that looks + -- like '1657296016-my-new-note', and therefore the file name '1657296016-my-new-note.md' + local suffix = "" + if title ~= nil then + -- If title is given, transform it into valid file name. + suffix = title:gsub(" ", "-"):gsub("[^A-Za-z0-9-]", ""):lower() + else + -- If title is nil, just add 4 random uppercase letters to the suffix. + for _ = 1, 4 do + suffix = suffix .. string.char(math.random(65, 90)) + end + end + return suffix + end, + + -- Optional, customize how note file names are generated given the ID, target directory, and title. + ---@param spec { id: string, dir: obsidian.Path, title: string|? } + ---@return string|obsidian.Path The full path to the new note. + note_path_func = function(spec) + -- This is equivalent to the default behavior. + local path = spec.dir / "Contents" / tostring(spec.title) + return path:with_suffix(".md") + end, + + -- Optional, customize how wiki links are formatted. You can set this to one of: + -- * "use_alias_only", e.g. '[[Foo Bar]]' + -- * "prepend_note_id", e.g. '[[foo-bar|Foo Bar]]' + -- * "prepend_note_path", e.g. '[[foo-bar.md|Foo Bar]]' + -- * "use_path_only", e.g. '[[foo-bar.md]]' + -- Or you can set it to a function that takes a table of options and returns a string, like this: + wiki_link_func = function(opts) + return require("obsidian.util").wiki_link_path_prefix(opts) + end, + + -- Optional, customize how markdown links are formatted. + markdown_link_func = function(opts) + return require("obsidian.util").markdown_link(opts) + end, + + -- Either 'wiki' or 'markdown'. + preferred_link_style = "wiki", + + -- Optional, boolean or a function that takes a filename and returns a boolean. + -- `true` indicates that you don't want obsidian.nvim to manage frontmatter. + disable_frontmatter = false, + + -- -- Optional, alternatively you can customize the frontmatter data. + -- ---@return table + -- note_frontmatter_func = function(note) + -- -- Add the title of the note as an alias. + -- if note.title then + -- note:add_alias(note.title) + -- end + -- + -- local out = { id = note.id, aliases = note.aliases, tags = note.tags } + -- + -- -- `note.metadata` contains any manually added fields in the frontmatter. + -- -- So here we just make sure those fields are kept in the frontmatter. + -- if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then + -- for k, v in pairs(note.metadata) do + -- out[k] = v + -- end + -- end + -- + -- return out + -- end, + + -- Optional, for templates (see below). + templates = { + folder = "Resource/Templates", + date_format = "%Y-%m-%d", + time_format = "%H:%M", + -- A map for custom variables, the key should be the variable and the value a function + substitutions = {}, + }, + + -- Optional, by default when you use `:ObsidianFollowLink` on a link to an external + -- URL it will be ignored but you can customize this behavior here. + ---@param url string + follow_url_func = function(url) + -- Open the URL in the default web browser. + -- vim.fn.jobstart({ "open", url }) -- Mac OS + vim.fn.jobstart({ "xdg-open", url }) -- linux + -- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows + -- vim.ui.open(url) -- need Neovim 0.10.0+ + end, + + -- Optional, by default when you use `:ObsidianFollowLink` on a link to an image + -- file it will be ignored but you can customize this behavior here. + ---@param img string + follow_img_func = function(img) + -- vim.fn.jobstart({ "qlmanage", "-p", img }) -- Mac OS quick look preview + vim.fn.jobstart({ "nsxiv", "-aiop", img }) -- linux + -- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows + end, + + -- Optional, set to true if you use the Obsidian Advanced URI plugin. + -- https://github.com/Vinzent03/obsidian-advanced-uri + use_advanced_uri = false, + + -- Optional, set to true to force ':ObsidianOpen' to bring the app to the foreground. + open_app_foreground = false, + + picker = { + -- Set your preferred picker. Can be one of 'telescope.nvim', 'fzf-lua', or 'mini.pick'. + name = "telescope.nvim", + -- Optional, configure key mappings for the picker. These are the defaults. + -- Not all pickers support all mappings. + note_mappings = { + -- Create a new note from your query. + new = "", + -- Insert a link to the selected note. + insert_link = "", + }, + tag_mappings = { + -- Add tag(s) to current note. + tag_note = "", + -- Insert a tag at the current location. + insert_tag = "", + }, + }, + + -- Optional, sort search results by "path", "modified", "accessed", or "created". + -- The recommend value is "modified" and `true` for `sort_reversed`, which means, for example, + -- that `:ObsidianQuickSwitch` will show the notes sorted by latest modified time + sort_by = "modified", + sort_reversed = true, + + -- Set the maximum number of lines to read from notes on disk when performing certain searches. + search_max_lines = 1000, + + -- Optional, determines how certain commands open notes. The valid options are: + -- 1. "current" (the default) - to always open in the current window + -- 2. "vsplit" - to open in a vertical split if there's not already a vertical split + -- 3. "hsplit" - to open in a horizontal split if there's not already a horizontal split + open_notes_in = "current", + + -- Optional, define your own callbacks to further customize behavior. + callbacks = { + -- Runs at the end of `require("obsidian").setup()`. + ---@param client obsidian.Client + post_setup = function(client) end, + + -- Runs anytime you enter the buffer for a note. + ---@param client obsidian.Client + ---@param note obsidian.Note + enter_note = function(client, note) end, + + -- Runs anytime you leave the buffer for a note. + ---@param client obsidian.Client + ---@param note obsidian.Note + leave_note = function(client, note) end, + + -- Runs right before writing the buffer for a note. + ---@param client obsidian.Client + ---@param note obsidian.Note + pre_write_note = function(client, note) end, + + -- Runs anytime the workspace is set/changed. + ---@param client obsidian.Client + ---@param workspace obsidian.Workspace + post_set_workspace = function(client, workspace) end, + }, + + -- Optional, configure additional syntax highlighting / extmarks. + -- This requires you have `conceallevel` set to 1 or 2. See `:help conceallevel` for more details. + ui = { + enable = false, -- set to false to disable all additional syntax features + update_debounce = 200, -- update delay after a text change (in milliseconds) + max_file_length = 5000, -- disable UI features for files with more than this many lines + -- Define how various check-boxes are displayed + checkboxes = { + -- NOTE: the 'char' value has to be a single character, and the highlight groups are defined below. + [" "] = { char = "󰄱", hl_group = "ObsidianTodo" }, + ["x"] = { char = "", hl_group = "ObsidianDone" }, + [">"] = { char = "", hl_group = "ObsidianRightArrow" }, + ["~"] = { char = "󰰱", hl_group = "ObsidianTilde" }, + ["!"] = { char = "", hl_group = "ObsidianImportant" }, + -- Replace the above with this if you don't have a patched font: + -- [" "] = { char = "☐", hl_group = "ObsidianTodo" }, + -- ["x"] = { char = "✔", hl_group = "ObsidianDone" }, + + -- You can also add more custom ones... + }, + -- Use bullet marks for non-checkbox lists. + bullets = { char = "•", hl_group = "ObsidianBullet" }, + external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" }, + -- Replace the above with this if you don't have a patched font: + -- external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" }, + reference_text = { hl_group = "ObsidianRefText" }, + highlight_text = { hl_group = "ObsidianHighlightText" }, + tags = { hl_group = "ObsidianTag" }, + block_ids = { hl_group = "ObsidianBlockID" }, + hl_groups = { + -- The options are passed directly to `vim.api.nvim_set_hl()`. See `:help nvim_set_hl`. + ObsidianTodo = { bold = true, fg = "#f78c6c" }, + ObsidianDone = { bold = true, fg = "#89ddff" }, + ObsidianRightArrow = { bold = true, fg = "#f78c6c" }, + ObsidianTilde = { bold = true, fg = "#ff5370" }, + ObsidianImportant = { bold = true, fg = "#d73128" }, + ObsidianBullet = { bold = true, fg = "#89ddff" }, + ObsidianRefText = { underline = true, fg = "#c792ea" }, + ObsidianExtLinkIcon = { fg = "#c792ea" }, + ObsidianTag = { italic = true, fg = "#89ddff" }, + ObsidianBlockID = { italic = true, fg = "#89ddff" }, + ObsidianHighlightText = { bg = "#75662e" }, + }, + }, + + -- Specify how to handle attachments. + attachments = { + -- The default folder to place images in via `:ObsidianPasteImg`. + -- If this is a relative path it will be interpreted as relative to the vault root. + -- You can always override this per image by passing a full path to the command instead of just a filename. + img_folder = "assets/imgs", -- This is the default + + -- Optional, customize the default name or prefix when pasting images via `:ObsidianPasteImg`. + ---@return string + img_name_func = function() + -- Prefix image names with timestamp. + return string.format("%s-", os.time()) + end, + + -- A function that determines the text to insert in the note when pasting an image. + -- It takes two arguments, the `obsidian.Client` and an `obsidian.Path` to the image file. + -- This is the default implementation. + ---@param client obsidian.Client + ---@param path obsidian.Path the absolute path to the image file + ---@return string + img_text_func = function(client, path) + path = client:vault_relative_path(path) or path + return string.format("![%s](%s)", path.name, path) + end, + }, + }) + + vim.api.nvim_create_autocmd("FileType", { + pattern = "markdown", + callback = function() + vim.keymap.set("n", "gl", function() + if require("obsidian").util.cursor_on_markdown_link() then + return "ObsidianFollowLink" + else + return "gl" + end + end, { noremap = false, expr = true, desc = "Follow link (Obsidian)" }) + end, + }) + end, + keys = { + { + "zb", + function() + return require("obsidian").util.toggle_checkbox() + end, + buffer = true, + ft = "markdown", + desc = "Toggle check box (Obsidian)", + }, + { + "ob", + function() + local query = vim.fn.input("Enter query: ") + if query and #query > 0 then + vim.cmd("ObsidianOpen " .. query) + end + end, + ft = "markdown", + desc = "Open note (Obsidian)", + }, + { + "onn", + function() + local title = vim.fn.input("Enter title: ") + if title and #title > 0 then + vim.cmd("ObsidianNew " .. title) + end + end, + ft = "markdown", + desc = "New note (Obsidian)", + }, + { + "os", + "ObsidianQuickSwitch", + ft = "markdown", + desc = "Quick switch (Obsidian)", + }, + { + "oL", + "ObsidianFollowLink", + ft = "markdown", + desc = "Follow link (Obsidian)", + }, + { + "oH", + "ObsidianBacklinks", + ft = "markdown", + desc = "Back link (Obsidian)", + }, + { + "oft", + function() + local tags = vim.fn.input("Enter tag: ") + if tags and #tags > 0 then + vim.cmd("ObsidianTags " .. tags) + end + end, + ft = "markdown", + desc = "Search tag notes (Obsidian)", + }, + { + "ont", + function() + local offset = vim.fn.input("Enter offset: ") + if offset and #offset > 0 then + vim.cmd("ObsidianToday " .. offset) + else + vim.cmd("ObsidianToday") + end + end, + ft = "markdown", + desc = "Today note (Obsidian)", + }, + { + "ony", + "ObsidianYesterday", + ft = "markdown", + desc = "Yesterday note (Obsidian)", + }, + { + "ont", + "ObsidianTomorrow", + ft = "markdown", + desc = "Tomorrow note (Obsidian)", + }, + { + "ond", + function() + local offset = vim.fn.input("Enter offset: ") + if offset and #offset > 0 then + vim.cmd("ObsidianDailies " .. offset) + else + vim.cmd("ObsidianDailies") + end + end, + ft = "markdown", + desc = "Daily notes (Obsidian)", + }, + { + "oti", + "ObsidianTemplate", + ft = "markdown", + desc = "Insert templates (Obsidian)", + }, + { + "ofn", + function() + local note = vim.fn.input("Enter note: ") + if note and #note > 0 then + vim.cmd("ObsidianSearch " .. note) + end + end, + ft = "markdown", + desc = "Search note (Obsidian)", + }, + { + "ow", + function() + local name = vim.fn.input("Enter name: ") + if name and #name > 0 then + vim.cmd("ObsidianWorkspace " .. name) + end + end, + ft = "markdown", + desc = "Workspace name (Obsidian)", + }, + { + "opi", + function() + local image = vim.fn.input("Enter image: ") + if image and #image > 0 then + vim.cmd("ObsidianPasteImg " .. image) + end + end, + ft = "markdown", + desc = "Paste image (Obsidian)", + }, + { + "onr", + function() + local name = vim.fn.input("Enter name: ") + if name and #name > 0 then + vim.cmd("ObsidianRename " .. name) + end + end, + ft = "markdown", + desc = "Rename note (Obsidian)", + }, + { + mode = "v", + "ol", + function() + local query = vim.fn.input("Enter query: ") + if query and #query > 0 then + vim.cmd("ObsidianLink " .. query) + else + vim.cmd("ObsidianLink") + end + end, + ft = "markdown", + desc = "Link query (Obsidian)", + }, + { + mode = "v", + "onl", + function() + local note = vim.fn.input("Enter note: ") + if note and #note > 0 then + vim.cmd("ObsidianLinkNew " .. note) + else + vim.cmd("ObsidianLinkNew") + end + end, + ft = "markdown", + desc = "New link note (Obsidian)", + }, + { + mode = "v", + "ox", + function() + local note = vim.fn.input("Enter note: ") + if note and #note > 0 then + vim.cmd("ObsidianExtractNote " .. note) + else + vim.cmd("ObsidianExtractNote") + end + end, + ft = "markdown", + desc = "New extract text (Obsidian)", + }, + { + "otn", + "ObsidianNewFromTemplate", + ft = "markdown", + desc = "Open new note with template (Obsidian)", + }, + { + "oc", + "ObsidianTOC", + ft = "markdown", + desc = "Open contents (Obsidian)", + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/outline.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/outline.lua new file mode 100644 index 0000000..5d28f7d --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/outline.lua @@ -0,0 +1,11 @@ +return { + "hedyhli/outline.nvim", + lazy = true, + cmd = { "Outline", "OutlineOpen" }, + keys = { -- Example mapping to toggle outline + { "zo", "Outline", desc = "Toggle outline" }, + }, + opts = { + -- Your setup opts here + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/project.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/project.lua new file mode 100644 index 0000000..13ee82b --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/project.lua @@ -0,0 +1,12 @@ +return { + "Zeioth/project.nvim", + dependencies = "nvim-telescope/telescope.nvim", + config = function() + require("project_nvim").setup() + require("telescope").load_extension("projects") + + vim.keymap.set("n", "fpj", function() + require("telescope").extensions.projects.projects() + end, { desc = "Find projects" }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/python.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/python.lua new file mode 100644 index 0000000..bacdd9b --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/python.lua @@ -0,0 +1,55 @@ +return { + -- { + -- "bps/vim-textobj-python", + -- dependencies = { "kana/vim-textobj-user" }, + -- }, + { + "nvim-neotest/neotest", + optional = true, + dependencies = { + "nvim-neotest/neotest-python", + }, + opts = { + adapters = { + ["neotest-python"] = { + -- Here you can specify the settings for the adapter, i.e. + -- runner = "pytest", + -- python = ".venv/bin/python", + }, + }, + }, + }, + { + "linux-cultist/venv-selector.nvim", + dependencies = { + "neovim/nvim-lspconfig", + "mfussenegger/nvim-dap", + "mfussenegger/nvim-dap-python", --optional + { "nvim-telescope/telescope.nvim", branch = "0.1.x", dependencies = { "nvim-lua/plenary.nvim" } }, + }, + lazy = false, + branch = "regexp", -- This is the regexp branch, use this for the new version + ft = "python", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "v", group = "Virtual envs" }, + }) + end, + config = function() + require("venv-selector").setup({ + notify_user_on_activate = true, + search = { + venvs = { + command = "fd /bin/python$ ~/.local/share/venvs --full-path", + }, + }, + }) + end, + keys = { + { "vs", "VenvSelect", desc = "Select virtual env", ft = "python" }, + { "vc", "VenvSelectCached", desc = "Select venv (cache)", ft = "python" }, + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/quickfix.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/quickfix.lua new file mode 100644 index 0000000..f586310 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/quickfix.lua @@ -0,0 +1,76 @@ +return { + { + "folke/trouble.nvim", + cmd = { "Trouble" }, + opts = { + modes = { + lsp = { + win = { position = "right" }, + }, + preview_float = { + mode = "diagnostics", + preview = { + type = "float", + relative = "editor", + border = "rounded", + title = "Preview", + title_pos = "center", + position = { 0, -2 }, + size = { width = 0.3, height = 0.3 }, + zindex = 200, + }, + }, + }, + }, + config = function(_, opts) + require("trouble").setup(opts) + end, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "x", group = "Quickfix (trouble)" }, + }) + end, + keys = { + { "xd", "Trouble diagnostics toggle", desc = "Toggle diagnostics (Trouble)" }, + { + "xD", + "Trouble diagnostics toggle filter.buf=0", + desc = "Toggle buffer Diagnostics (Trouble)", + }, + { "xs", "Trouble symbols toggle", desc = "Toggle symbols (Trouble)" }, + { "xS", "Trouble lsp toggle", desc = "Toggle LSP def/ref/... (Trouble)" }, + { "xl", "Trouble loclist toggle", desc = "Toggle location List (Trouble)" }, + { "xq", "Trouble qflist toggle", desc = "Toggle quickfix List (Trouble)" }, + { + "[x", + function() + if require("trouble").is_open() then + require("trouble").prev({ skip_groups = true, jump = true }) + else + local ok, err = pcall(vim.cmd.cprev) + if not ok then + vim.notify(err, vim.log.levels.ERROR) + end + end + end, + desc = "Previous quickfix (trouble)", + }, + { + "]x", + function() + if require("trouble").is_open() then + require("trouble").next({ skip_groups = true, jump = true }) + else + local ok, err = pcall(vim.cmd.cnext) + if not ok then + vim.notify(err, vim.log.levels.ERROR) + end + end + end, + desc = "Next quickfix (trouble)", + }, + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/refactoring.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/refactoring.lua new file mode 100644 index 0000000..8bcf274 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/refactoring.lua @@ -0,0 +1,78 @@ +return { + "ThePrimeagen/refactoring.nvim", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-treesitter/nvim-treesitter", + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v", "x" }, + { "r", group = "Compiler/Refactoring" }, + { "rb", group = "Extract block" }, + }) + end, + lazy = false, + config = function() + require("refactoring").setup({ + prompt_func_return_type = { + c = true, + cpp = true, + cxx = true, + go = true, + h = true, + hpp = true, + java = true, + lua = true, + python = true, + }, + prompt_func_param_type = { + c = true, + cpp = true, + cxx = true, + go = true, + h = true, + hpp = true, + java = true, + lua = true, + python = true, + }, + printf_statements = {}, + print_var_statements = {}, + show_success_message = false, + }) + vim.keymap.set({ "n", "x" }, "re", function() + return require("refactoring").refactor("Extract Function") + end, { expr = true, desc = "Extract" }) + vim.keymap.set({ "n", "x" }, "rf", function() + return require("refactoring").refactor("Extract Function To File") + end, { expr = true, desc = "Extract to file" }) + vim.keymap.set({ "n", "x" }, "rv", function() + return require("refactoring").refactor("Extract Variable") + end, { expr = true, desc = "Extract variable" }) + vim.keymap.set({ "n", "x" }, "rI", function() + return require("refactoring").refactor("Inline Function") + end, { expr = true, desc = "Refactor inline function" }) + vim.keymap.set({ "n", "x" }, "ri", function() + return require("refactoring").refactor("Inline Variable") + end, { expr = true, desc = "Refactor inline variable" }) + + vim.keymap.set({ "n", "x" }, "rbb", function() + return require("refactoring").refactor("Extract Block") + end, { expr = true, desc = "Extract block" }) + vim.keymap.set({ "n", "x" }, "rbf", function() + return require("refactoring").refactor("Extract Block To File") + end, { expr = true, desc = "Extract block to file" }) + + -- prompt for a refactor to apply when the remap is triggered + vim.keymap.set({ "n", "x" }, "rs", function() + require("refactoring").select_refactor({ prefer_ex_cmd = true }) + end, { desc = "Refactor selection" }) + -- Note that not all refactor support both normal and visual mode + -- load refactoring Telescope extension + require("telescope").load_extension("refactoring") + vim.keymap.set({ "n", "x" }, "rf", function() + require("telescope").extensions.refactoring.refactors() + end, { desc = "Open refactor" }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/sessions.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/sessions.lua new file mode 100644 index 0000000..3a644c1 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/sessions.lua @@ -0,0 +1,60 @@ +return { + "rmagatti/auto-session", + lazy = false, + config = function() + require("auto-session").setup({ + enabled = true, -- Enables/disables auto creating, saving and restoring + root_dir = vim.fn.stdpath("data") .. "/sessions/", -- Root dir where sessions will be stored + auto_save = true, -- Enables/disables auto saving session on exit + auto_restore = false, -- Enables/disables auto restoring session on start + auto_create = true, -- Enables/disables auto creating new session files. Can take a function that should return true/false if a new session file should be created or not + suppressed_dirs = nil, -- Suppress session restore/create in certain directories + allowed_dirs = nil, -- Allow session restore/create in certain directories + auto_restore_last_session = false, -- On startup, loads the last saved session if session for cwd does not exist + git_use_branch_name = true, -- Include git branch name in session name + git_auto_restore_on_branch_change = true, -- Should we auto-restore the session when the git branch changes. Requires git_use_branch_name + lazy_support = true, -- Automatically detect if Lazy.nvim is being used and wait until Lazy is done to make sure session is restored correctly. Does nothing if Lazy isn't being used. Can be disabled if a problem is suspected or for debugging + bypass_save_filetypes = nil, -- List of filetypes to bypass auto save when the only buffer open is one of the file types listed, useful to ignore dashboards + close_unsupported_windows = true, -- Close windows that aren't backed by normal file before autosaving a session + args_allow_single_directory = true, -- Follow normal sesion save/load logic if launched with a single directory as the only argument + args_allow_files_auto_save = false, -- Allow saving a session even when launched with a file argument (or multiple files/dirs). It does not load any existing session first. While you can just set this to true, you probably want to set it to a function that decides when to save a session when launched with file args. See documentation for more detail + continue_restore_on_error = true, -- Keep loading the session even if there's an error + show_auto_restore_notif = false, -- Whether to show a notification when auto-restoring + cwd_change_handling = false, -- Follow cwd changes, saving a session before change and restoring after + lsp_stop_on_restore = false, -- Should language servers be stopped when restoring a session. Can also be a function that will be called if set. Not called on autorestore from startup + restore_error_handler = nil, -- Called when there's an error restoring. By default, it ignores fold errors otherwise it displays the error and returns false to disable auto_save + purge_after_minutes = nil, -- Sessions older than purge_after_minutes will be deleted asynchronously on startup, e.g. set to 14400 to delete sessions that haven't been accessed for more than 10 days, defaults to off (no purging), requires >= nvim 0.10 + log_level = "error", -- Sets the log level of the plugin (debug, info, warn, error). + + session_lens = { + load_on_setup = true, -- Initialize on startup (requires Telescope) + theme_conf = { -- Pass through for Telescope theme options + layout_config = { -- As one example, can change width/height of picker + -- width = 0.8, -- percent of window + -- height = 0.5, + }, + }, + previewer = false, -- File preview for session picker + + mappings = { + -- Mode can be a string or a table, e.g. {"i", "n"} for both insert and normal mode + delete_session = { "i", "" }, + alternate_session = { "i", "" }, + copy_session = { "i", "" }, + }, + + session_control = { + control_dir = vim.fn.stdpath("data") .. "/auto_session/", -- Auto session control dir, for control files, like alternating between two sessions with session-lens + control_filename = "session_control.json", -- File name of the session control file + }, + }, + }) + end, + keys = { + { "fs", "SessionSearch", desc = "Session search" }, + { "ws", "SessionSave", desc = "Save session" }, + { "wx", "SessionDisableAutoSave", desc = "Disable autosave" }, + { "wp", "SessionPurgeOrphaned", desc = "Purge autosave" }, + { "wa", "SessionToggleAutoSave", desc = "Toggle autosave" }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/silicon.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/silicon.lua new file mode 100644 index 0000000..f5bd3fa --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/silicon.lua @@ -0,0 +1,145 @@ +return { + "michaelrommel/nvim-silicon", + lazy = true, + cmd = "Silicon", + main = "nvim-silicon", + opts = { + -- Configuration here, or leave empty to use defaults + -- disable_defaults will disable all builtin default settings apart + -- from the base arguments, that are needed to call silicon at all, see + -- mandatory_options below, also those options can be overridden + -- all of the settings could be overridden in the lua setup call, + -- but this clashes with the use of an external silicon --config=file, + -- see issue #9 + disable_defaults = false, + -- turn on debug messages + debug = false, + -- most of them could be overridden with other + -- the font settings with size and fallback font + -- Example: font = "VictorMono NF=34;Noto Emoji", + font = nil, + -- the theme to use, depends on themes available to silicon + theme = "gruvbox-dark", + -- the background color outside the rendered os window + -- (in hexcode string e.g "#076678") + background = nil, + -- a path to a background image + background_image = nil, + -- the paddings to either side + pad_horiz = 100, + pad_vert = 80, + -- whether to have the os window rendered with rounded corners + no_round_corner = false, + -- whether to put the close, minimize, maximise traffic light + -- controls on the border + no_window_controls = false, + -- whether to turn off the line numbers + no_line_number = false, + -- with which number the line numbering shall start + line_offset = 1, + -- here a function is used to return the actual source code line number + -- line_offset = function(args) + -- return args.line1 + -- end, + + -- the distance between lines of code + line_pad = 0, + -- the rendering of tab characters as so many space characters + tab_width = 4, + -- with which language the syntax highlighting shall be done, should be + -- a function that returns either a language name or an extension like "js" + -- it is set to nil, so you can override it, if you do not set it, we try the + -- filetype first, and if that fails, the extension + language = nil, + -- language = function() + -- return vim.bo.filetype + -- end, + -- language = function() + -- return vim.fn.fnamemodify( + -- vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()), + -- ":e" + -- ) + -- end, + + -- if the shadow below the os window should have be blurred + shadow_blur_radius = 16, + -- the offset of the shadow in x and y directions + shadow_offset_x = 8, + shadow_offset_y = 8, + -- the color of the shadow (in hexcode string e.g "#100808") + shadow_color = nil, + -- whether to strip of superfluous leading whitespace + gobble = true, + -- a string to pad each line with after gobbling removed larger indents, + num_separator = nil, + -- here a bar glyph is used to draw a vertial line and some space + -- num_separator = "\u{258f} ", + + -- whether to put the image onto the clipboard, may produce an error, + -- if run on WSL2 + to_clipboard = false, + -- a string or function returning a string that defines the title + -- showing in the image, only works in silicon versions greater than v0.5.1 + window_title = nil, + -- here a function is used to get the name of the current buffer + -- window_title = function() + -- return vim.fn.fnamemodify( + -- vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()), + -- ":t" + -- ) + -- end, + + -- how to deal with the clipboard on WSL2 + -- possible values are: never, always, auto + wslclipboard = nil, + -- what to do with the temporary screenshot image file when using the Windows + -- clipboard from WSL2, possible values are: keep, delete + wslclipboardcopy = nil, + -- the silicon command, put an absolute location here, if the + -- command is not in your ${PATH} + command = "silicon", + -- a string or function that defines the path to the output image + -- output = nil, + -- here a function is used to create a file in the current directory + output = function() + local home_dir = vim.fn.expand("~") -- Get home directory + local timestamp = os.date("!%Y-%m-%d_%H-%M-%S") -- Get timestamp + local file_name = vim.fn.expand("%:t:r") -- Get the file name without extension + local file_extension = vim.fn.expand("%:e") + return home_dir .. "/" .. timestamp .. "_" .. file_name .. "_" .. file_extension .. ".png" + end, + }, + keys = { + { + "sc", + function() + require("nvim-silicon").clip() + end, + mode = "v", + desc = "Copy code screenshot to clipboard", + }, + { + "sf", + function() + require("nvim-silicon").file() + end, + mode = "v", + desc = "Save code screenshot as file", + }, + { + "ss", + function() + require("nvim-silicon").shoot() + end, + mode = "v", + desc = "Create code screenshot", + }, + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "v" }, + { "s", group = "Snapshot" }, + }) + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/snippets.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/snippets.lua new file mode 100644 index 0000000..96c52a7 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/snippets.lua @@ -0,0 +1,72 @@ +return { + { + "L3MON4D3/LuaSnip", + version = "v2.*", + build = "make install_jsregexp", + dependencies = { + "rafamadriz/friendly-snippets", + config = function() + require("luasnip.loaders.from_vscode").lazy_load() + end, + }, + config = function() + local ls = require("luasnip") + ls.setup({ + link_children = true, + link_roots = false, + keep_roots = false, + update_events = { "TextChanged", "TextChangedI" }, + }) + local c = ls.choice_node + ls.choice_node = function(pos, choices, opts) + if opts then + opts.restore_cursor = true + else + opts = { restore_cursor = true } + end + return c(pos, choices, opts) + end + + require("luasnip.loaders.from_vscode").lazy_load({ + paths = { '"' .. vim.fn.stdpath("config") .. '/lua/TheSiahxyz/snippets"' }, + }) + + vim.cmd.runtime({ args = { "lua/TheSiahxyz/snippets/*.lua" }, bang = true }) -- load custom snippets + + vim.keymap.set({ "i", "x" }, "", function() + if ls.expand_or_jumpable() then + ls.expand_or_jump() + end + end, { silent = true, desc = "Expand snippet or jump to the next snippet node" }) + + vim.keymap.set({ "i", "x" }, "", function() + if ls.jumpable(-1) then + ls.jump(-1) + end + end, { silent = true, desc = "Previous spot in the snippet" }) + + vim.keymap.set({ "i", "x" }, "", function() + if ls.choice_active() then + ls.change_choice(1) + end + end, { silent = true, desc = "Next snippet choice" }) + + vim.keymap.set({ "i", "x" }, "", function() + if ls.choice_active() then + ls.change_choice(-1) + end + end, { silent = true, desc = "Previous snippet choice" }) + end, + keys = { + vim.keymap.set("i", "", function() + return require("luasnip").jumpable(1) and "luasnip-jump-next" or "" + end, { expr = true, silent = true, desc = "Jump to next snippet" }), + vim.keymap.set("s", "", function() + require("luasnip").jump(1) + end, { desc = "Jump to next snippet" }), + vim.keymap.set({ "i", "s" }, "", function() + require("luasnip").jump(-1) + end, { desc = "Jump to Previous Snippet" }), + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/stay-centered.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/stay-centered.lua new file mode 100644 index 0000000..b64880b --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/stay-centered.lua @@ -0,0 +1,28 @@ +return { + "arnamak/stay-centered.nvim", + lazy = false, + config = function() + require("stay-centered").setup({ + -- The filetype is determined by the vim filetype, not the file extension. In order to get the filetype, open a file and run the command: + -- :lua print(vim.bo.filetype) + skip_filetypes = {}, + -- Set to false to disable by default + enabled = true, + -- allows scrolling to move the cursor without centering, default recommended + allow_scroll_move = true, + -- temporarily disables plugin on left-mouse down, allows natural mouse selection + -- try disabling if plugin causes lag, function uses vim.on_key + disable_on_mouse = false, + }) + end, + keys = { + { + "zs", + function() + require("stay-centered").toggle() + end, + mode = { "n", "v" }, + desc = "Toggle stay-centered.nvim", + }, + }, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/surround.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/surround.lua new file mode 100644 index 0000000..f3e0174 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/surround.lua @@ -0,0 +1,14 @@ +return { + "echasnovski/mini.surround", + version = "*", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "s", group = "Surround/Search & replace on line" }, + }) + end, + config = function() + require("mini.surround").setup() + end, +} diff --git a/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/telescope.lua b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/telescope.lua new file mode 100644 index 0000000..0ec51f1 --- /dev/null +++ b/ar/.config/TheSiahxyz/lua/TheSiahxyz/plugins/telescope.lua @@ -0,0 +1,1084 @@ +local have_make = vim.fn.executable("make") == 1 +local have_cmake = vim.fn.executable("cmake") == 1 + +function vim.live_grep_from_project_git_root() + local function get_git_toplevel() + local path = vim.fn.system("git rev-parse --show-toplevel") + if vim.v.shell_error then + return nil + end + return path + end + + local opts = { cwd = get_git_toplevel() } + + require("telescope.builtin").live_grep(opts) +end + +local function find_nvim_plugin_files(prompt_bufnr) + local actions = require("telescope.actions") + local action_state = require("telescope.actions.state") + + actions.close(prompt_bufnr) + + local selection = action_state.get_selected_entry() + if selection and selection.value then + -- Construct the full path + local base_path = vim.fn.stdpath("data") + local full_path = vim.fn.resolve(base_path .. "/" .. selection.value) + + require("mini.files").open(full_path, true) + end +end + +return { + { + "nvim-telescope/telescope-file-browser.nvim", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-telescope/telescope.nvim", + }, + -- init = function() + -- vim.api.nvim_create_autocmd("VimEnter", { + -- group = vim.api.nvim_create_augroup("TelescopeFileBrowserStartDirectory", { clear = true }), + -- desc = "Start telescope-file-browser with directory", + -- once = true, + -- callback = function() + -- if package.loaded["telescope-file-browser.nvim"] then + -- return + -- else + -- local stats = vim.uv.fs_stat(vim.fn.argv(0)) + -- if stats and stats.type == "directory" then + -- require("telescope").extensions.file_browser.file_browser() + -- end + -- end + -- end, + -- }) + -- end, + config = function() + local fb_actions = require("telescope._extensions.file_browser.actions") + + require("telescope").setup({ + extensions = { + file_browser = { + path = vim.uv.cwd(), + cwd = vim.uv.cwd(), + cwd_to_path = false, + grouped = true, + files = true, + add_dirs = true, + depth = 1, + auto_depth = true, + select_buffer = true, + hidden = { file_browser = false, folder_browser = false }, + respect_gitignore = vim.fn.executable("fd") == 1, + no_ignore = true, + follow_symlinks = true, + browse_files = require("telescope._extensions.file_browser.finders").browse_files, + browse_folders = require("telescope._extensions.file_browser.finders").browse_folders, + hide_parent_dir = false, + collapse_dirs = true, + prompt_path = true, + quiet = true, + dir_icon = "", + dir_icon_hl = "Default", + display_stat = { date = true, size = true, mode = true }, + hijack_netrw = false, + use_fd = true, + git_status = true, + mappings = { + ["i"] = { + [""] = fb_actions.create, + [""] = fb_actions.create_from_prompt, + [""] = fb_actions.rename, + [""] = fb_actions.move, + [""] = fb_actions.copy, + [""] = fb_actions.remove, + [""] = fb_actions.open, + [""] = fb_actions.goto_parent_dir, + [""] = fb_actions.goto_home_dir, + [""] = fb_actions.goto_cwd, + [""] = fb_actions.change_cwd, + [""] = fb_actions.toggle_browser, + [""] = fb_actions.toggle_hidden, + [""] = fb_actions.toggle_all, + [""] = fb_actions.backspace, + }, + ["n"] = { + ["a"] = fb_actions.create, + ["n"] = fb_actions.create_from_prompt, + ["r"] = fb_actions.rename, + ["d"] = fb_actions.move, + ["y"] = fb_actions.copy, + ["Del"] = fb_actions.remove, + ["o"] = fb_actions.open, + ["h"] = fb_actions.goto_parent_dir, + ["gh"] = fb_actions.goto_home_dir, + [""] = fb_actions.goto_cwd, + [""] = fb_actions.change_cwd, + ["f"] = fb_actions.toggle_browser, + ["/"] = fb_actions.toggle_hidden, + ["t"] = fb_actions.toggle_all, + }, + }, + results_title = vim.fn.fnamemodify(vim.uv.cwd(), ":~"), + }, + }, + }) + + require("telescope").load_extension("file_browser") + + vim.keymap.set( + "n", + "et", + ":Telescope file_browser path=%:p:h select_buffer=true", + { desc = "File browser (cwd)" } + ) + vim.keymap.set("n", "eT", ":Telescope file_browser", { desc = "File browser" }) + end, + }, + { + "nvim-telescope/telescope.nvim", + branch = "master", + dependencies = { + { "nvim-lua/plenary.nvim" }, + { + "nvim-telescope/telescope-fzf-native.nvim", + build = have_make and "make" + or "cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build", + enabled = have_make or have_cmake, + config = function() + require("telescope").load_extension("fzf") + end, + }, + { + "nvim-telescope/telescope-github.nvim", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "gh", group = "gh" }, + }) + end, + config = function() + require("telescope").load_extension("gh") + vim.keymap.set({ "n", "v" }, "gi", ":Telescope gh issues ", { desc = "Find gh issues" }) + vim.keymap.set( + { "n", "v" }, + "gp", + ":Telescope gh pull_request ", + { desc = "Find gh pull request" } + ) + vim.keymap.set({ "n", "v" }, "ght", ":Telescope gh gist ", { desc = "Find gh gist" }) + vim.keymap.set({ "n", "v" }, "ghr", ":Telescope gh run ", { desc = "Find gh run" }) + end, + }, + { + "nvim-telescope/telescope-ui-select.nvim", + config = function() + require("telescope").setup({ + extensions = { + ["ui-select"] = { + require("telescope.themes").get_dropdown({ + -- even more opts + }), + + -- pseudo code / specification for writing custom displays, like the one + -- for "codeactions" + -- specific_opts = { + -- make_indexed = function(items) -> indexed_items, width, + -- [kind] = { + -- make_displayer = function(widths) -> displayer + -- make_display = function(displayer) -> function(e) + -- make_ordinal = function(e) -> string + -- }, + -- -- for example to disable the custom builtin "codeactions" display + -- do the following + -- codeactions = false, + -- } + }, + }, + }) + require("telescope").load_extension("ui-select") + end, + }, + { + "jvgrootveld/telescope-zoxide", + dependencies = { "nvim-lua/popup.nvim" }, + config = function() + require("telescope").setup({ + extensions = { + zoxide = { + prompt_title = "[ TheSiahxyz ]", + mappings = { + default = { + action = function(selection) + vim.cmd.cd(selection.path) + end, + after_action = function(selection) + print("Update to (" .. selection.z_score .. ") " .. selection.path) + end, + }, + [""] = { + action = require("telescope._extensions.zoxide.utils").create_basic_command( + "split" + ), + opts = { desc = "split" }, + }, + [""] = { + action = require("telescope._extensions.zoxide.utils").create_basic_command( + "vsplit" + ), + }, + [""] = { + action = require("telescope._extensions.zoxide.utils").create_basic_command( + "edit" + ), + }, + [""] = { + keepinsert = true, + action = function(selection) + require("telescope").extensions.file_browser.file_browser({ + cwd = selection.path, + }) + end, + }, + }, + }, + }, + }) + require("telescope").load_extension("zoxide") + + vim.keymap.set("n", "fz", function() + require("telescope").extensions.zoxide.list() + end, { desc = "Find files (zoxide)" }) + end, + }, + { + "nvim-telescope/telescope-live-grep-args.nvim", + -- This will not install any breaking changes. + -- For major updates, this must be adjusted manually. + version = "^1.0.0", + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n", "v" }, + { "f", group = "Find" }, + { "fl", group = "Live grep" }, + }) + end, + config = function() + local lga_actions = require("telescope-live-grep-args.actions") + local actions = require("telescope.actions") + + require("telescope").setup({ + extensions = { + live_grep_args = { + auto_quoting = true, -- enable/disable auto-quoting + -- define mappings, e.g. + mappings = { -- extend mappings + i = { + [""] = lga_actions.quote_prompt(), + [""] = lga_actions.quote_prompt({ postfix = " --iglob " }), + -- freeze the current list and start a fuzzy search in the frozen list + [""] = actions.to_fuzzy_refine, + }, + }, + vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + "--follow", + "--hidden", + "--no-ignore", + }, + -- ... also accepts theme settings, for example: + -- theme = "dropdown", -- use dropdown theme + -- theme = { }, -- use own theme spec + -- layout_config = { mirror=true }, -- mirror preview pane + }, + }, + }) + require("telescope").load_extension("live_grep_args") + vim.keymap.set("n", "flf", function() + require("telescope").extensions.live_grep_args.live_grep_args() + end, { desc = "Find live grep args" }) + + local live_grep_args_shortcuts = require("telescope-live-grep-args.shortcuts") + vim.keymap.set( + "n", + "ss", + live_grep_args_shortcuts.grep_word_under_cursor, + { desc = "Search shortcuts (Live grep)" } + ) + + local function search_git(visual) + -- Retrieve the git root path + local handle = io.popen("git rev-parse --show-toplevel") + if not handle then + print("Error: Unable to open git handle") + return + end + + local git_root_path = handle:read("*a"):gsub("%s+", "") + handle:close() + + if not git_root_path or git_root_path == "" then + print("Error: Unable to retrieve git root path") + return + end + + local opts = { + prompt_title = visual and ("Visual-Grep in " .. git_root_path) + or ("Live-Grep in " .. git_root_path), + shorten_path = false, + cwd = git_root_path, + file_ignore_patterns = { ".git", ".png", "tags" }, + initial_mode = "insert", + selection_strategy = "reset", + theme = require("telescope.themes").get_dropdown({}), + } + + if visual then + -- Capture the selected text in visual mode + vim.cmd('normal! "vy') + local visual_selection = vim.fn.getreg("v") + opts.search = visual_selection + require("telescope.builtin").grep_string(opts) + else + require("telescope.builtin").live_grep(opts) + end + end + + vim.keymap.set("n", "flg", function() + search_git(false) + end, { remap = true, silent = false, desc = "Live grep in the git root folder" }) + + vim.keymap.set("v", "flg", function() + search_git(true) + end, { remap = true, silent = false, desc = "Grep in the git root folder" }) + -- Retrieve the current tmux session path + -- This will not change when we navigate to a different pane + local function search_tmux(visual) + local handle = io.popen("tmux display-message -p '#{session_path}'") + if not handle then + print("Error: Unable to open tmux handle") + return + end + + local tmux_session_path = handle:read("*a"):gsub("%s+", "") + handle:close() + + if not tmux_session_path or tmux_session_path == "" then + print("Error: Unable to retrieve tmux session path") + return + end + + local opts = { + prompt_title = visual and ("Visual-Grep in " .. tmux_session_path) + or ("Live-Grep in " .. tmux_session_path), + shorten_path = false, + cwd = tmux_session_path, + file_ignore_patterns = { ".git", ".png", "tags" }, + initial_mode = "insert", + selection_strategy = "reset", + theme = require("telescope.themes").get_dropdown({}), + } + + if visual then + require("telescope.builtin").grep_string(opts) + else + require("telescope.builtin").live_grep(opts) + end + end + + vim.keymap.set("n", "flt", function() + search_tmux(false) + end, { remap = true, silent = false, desc = "Live grep in the current tmux session folder" }) + + vim.keymap.set("v", "flt", function() + search_tmux(true) + end, { remap = true, silent = false, desc = "Grep string in the current tmux session folder" }) + vim.api.nvim_set_keymap( + "v", + "fls", + 'y:Telescope live_grep default_text=0 search_dirs={"$PWD"}', + { noremap = true, silent = true, desc = "Live grep default text" } + ) + vim.keymap.set("n", "f/", function() + require("telescope.builtin").current_buffer_fuzzy_find( + require("telescope.themes").get_dropdown({ + winblend = 10, + previewer = false, + relative = "editor", + }) + ) + end, { desc = "Find in current buffer" }) + end, + }, + { + "xiyaowong/telescope-emoji.nvim", + config = function() + require("telescope").setup({ + extensions = { + emoji = { + action = function(emoji) + -- argument emoji is a table. + -- {name="", value="", cagegory="", description=""} + + vim.fn.setreg("*", emoji.value) + print([[Press p or "*p to paste this emoji]] .. emoji.value) + + -- insert emoji when picked + -- vim.api.nvim_put({ emoji.value }, 'c', false, true) + end, + }, + }, + }) + require("telescope").load_extension("emoji") + end, + keys = { + { "se", ":Telescope emoji", desc = "Search emoji" }, + }, + }, + { + "nvim-telescope/telescope-bibtex.nvim", + requires = { + { "nvim-telescope/telescope.nvim" }, + }, + config = function() + local bibtex_actions = require("telescope-bibtex.actions") + require("telescope").setup({ + extensions = { + bibtex = { + -- Use context awareness + context = true, + -- Use non-contextual behavior if no context found + -- This setting has no effect if context = false + context_fallback = true, + mappings = { + i = { + [""] = bibtex_actions.key_append("%s"), -- format is determined by filetype if the user has not set it explictly + [""] = bibtex_actions.entry_append, + [""] = bibtex_actions.citation_append("{{author}} ({{year}}), {{title}}."), + }, + }, + }, + }, + }) + require("telescope").load_extension("bibtex") + end, + keys = { + { + "sB", + function() + require("telescope").extensions.bibtex.bibtex() + end, + desc = "Search bibtex", + }, + }, + }, + { + "mzlogin/vim-markdown-toc", + keys = { + { "tg", "GenTocGFM", desc = "Generate ToC to GFM" }, + { "tr", "GenTocRedcarpet", desc = "Generate ToC to Redcarpet" }, + { "tl", "GenTocGitLab", desc = "Generate ToC to Gitlab" }, + { "tm", "GenTocMarked", desc = "Generate ToC to Marked" }, + }, + }, + { + "ThePrimeagen/harpoon", + branch = "harpoon2", + dependencies = { "nvim-lua/plenary.nvim" }, + }, + { + "folke/trouble.nvim", + }, + }, + init = function() + local wk = require("which-key") + wk.add({ + mode = { "n" }, + { "f", group = "Find" }, + { "fp", group = "Private/Public" }, + { "s", group = "Search" }, + { "sb", group = "Buffer" }, + }) + end, + config = function() + local actions = require("telescope.actions") + local actions_state = require("telescope.actions.state") + local actions_layout = require("telescope.actions.layout") + local open_with_trouble = require("trouble.sources.telescope").open + local add_to_trouble = require("trouble.sources.telescope").add + + require("telescope").setup({ + defaults = { + mappings = { + i = { + [""] = add_to_trouble, + [""] = actions.complete_tag, + [""] = function(prompt_bufnr) + local selection = actions_state.get_selected_entry() + local dir = vim.fn.fnamemodify(selection.path, ":p:h") + actions.close(prompt_bufnr) + -- Depending on what you want put `cd`, `lcd`, `tcd` + vim.cmd(string.format("silent lcd %s", dir)) + end, + [""] = actions.nop, + [""] = actions.nop, + [""] = actions.nop, + [""] = actions_layout.toggle_preview, + [""] = actions.preview_scrolling_down, + [""] = actions.preview_scrolling_up, + [""] = actions.preview_scrolling_left, + [""] = actions.preview_scrolling_right, + [""] = actions.send_to_qflist + actions.open_qflist, + [""] = actions.send_selected_to_qflist + actions.open_qflist, + [""] = open_with_trouble, + [""] = actions.select_horizontal, + [""] = { "", type = "command" }, + [""] = actions.insert_original_cword, + [""] = actions.insert_original_cWORD, + [""] = actions.insert_original_cfile, + [""] = actions.insert_original_cline, + [""] = actions.nop, + [""] = actions.nop, + }, + n = { + ["q"] = actions.close, + [""] = add_to_trouble, + [""] = actions.close, + [""] = actions.nop, + [""] = actions.nop, + [""] = actions_layout.toggle_preview, + [""] = actions.nop, + [""] = actions.complete_tag, + [""] = { + function(prompt_bufnr) + local selection = actions_state.get_selected_entry() + local dir = vim.fn.fnamemodify(selection.path, ":p:h") + actions.close(prompt_bufnr) + -- Depending on what you want put `cd`, `lcd`, `tcd` + vim.cmd(string.format("silent lcd %s", dir)) + end, + opts = { desc = "Change directory" }, + }, + [""] = actions.preview_scrolling_down, + [""] = actions.preview_scrolling_up, + [""] = actions.preview_scrolling_left, + [""] = actions.preview_scrolling_right, + [""] = actions.send_to_qflist + actions.open_qflist, + [""] = actions.send_selected_to_qflist + actions.open_qflist, + [""] = open_with_trouble, + [""] = actions.select_horizontal, + ["