nvim.git

nvim

~
git clone https://github.com/debuman/nvim.git
commit 0a72d0d596aa36427c12d491fb6ba2742b0521d5
Author: Decoy Zero <110329244+DecoyZero@users.noreply.github.com>
Date: Tue, 20 Aug 2024 21:56:09 +0900

dd

Diffstat:
A.gitattributes | 2++
A.stylua.toml | 2++
Aafter/queries/ecma/textobjects.scm | 5+++++
Ainit.lua | 2++
Alazy-lock.json | 45+++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/core/init.lua | 2++
Alua/josean/core/keymaps.lua | 32++++++++++++++++++++++++++++++++
Alua/josean/core/options.lua | 42++++++++++++++++++++++++++++++++++++++++++
Alua/josean/lazy.lua | 25+++++++++++++++++++++++++
Alua/josean/plugins/alpha-nvim.lua | 37+++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/auto-session.lua | 16++++++++++++++++
Alua/josean/plugins/bufferline.lua | 11+++++++++++
Alua/josean/plugins/colorizer.lua | 5+++++
Alua/josean/plugins/colorscheme.lua | 48++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/comment.lua | 19+++++++++++++++++++
Alua/josean/plugins/dressing.lua | 4++++
Alua/josean/plugins/formatting.lua | 39+++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/gitsigns.lua | 5+++++
Alua/josean/plugins/harpoon.lua | 24++++++++++++++++++++++++
Alua/josean/plugins/init.lua | 7+++++++
Alua/josean/plugins/linting.lua | 30++++++++++++++++++++++++++++++
Alua/josean/plugins/lsp/lspconfig.lua | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/lsp/mason.lua | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/lsp/none-ls.lua | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/lualine.lua | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/nvim-autopairs.lua | 30++++++++++++++++++++++++++++++
Alua/josean/plugins/nvim-cmp.lua | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/nvim-surround.lua | 6++++++
Alua/josean/plugins/nvim-tree.lua | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/nvim-treesitter-text-objects.lua | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/nvim-treesitter.lua | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/nvim-web-devicons.lua | 13+++++++++++++
Alua/josean/plugins/telescope.lua | 36++++++++++++++++++++++++++++++++++++
Alua/josean/plugins/vim-maximizer.lua | 6++++++
Alua/josean/plugins/which-key.lua | 13+++++++++++++
35 files changed, 1156 insertion(+), 0 deletion(-)

diff --git a/.gitattributes b/.gitattributes
@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto
diff --git a/.stylua.toml b/.stylua.toml
@@ -0,0 +1,2 @@
+indent_type = "Spaces"
+indent_width = 2
diff --git a/after/queries/ecma/textobjects.scm b/after/queries/ecma/textobjects.scm
@@ -0,0 +1,5 @@
+; extends
+(object
+  (pair
+    key: (_) @property.lhs
+    value: (_) @property.inner @property.rhs) @property.outer)
diff --git a/init.lua b/init.lua
@@ -0,0 +1,2 @@
+require("josean.core")
+require("josean.lazy")
diff --git a/lazy-lock.json b/lazy-lock.json
@@ -0,0 +1,45 @@
+{
+  "Comment.nvim": { "branch": "master", "commit": "0236521ea582747b58869cb72f70ccfa967d2e89" },
+  "LuaSnip": { "branch": "master", "commit": "480b032f6708573334f4437d3f83307d143f1a72" },
+  "alpha-nvim": { "branch": "main", "commit": "234822140b265ec4ba3203e3e0be0e0bb826dff5" },
+  "auto-session": { "branch": "main", "commit": "3eb26b949e1b90798e84926848551046e2eb0721" },
+  "bufferline.nvim": { "branch": "main", "commit": "6ecd37e0fa8b156099daedd2191130e083fb1490" },
+  "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" },
+  "cmp-nvim-lsp": { "branch": "main", "commit": "44b16d11215dce86f253ce0c30949813c0a90765" },
+  "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
+  "cmp_luasnip": { "branch": "master", "commit": "18095520391186d634a0045dacaa346291096566" },
+  "conform.nvim": { "branch": "master", "commit": "3f8927532bc8ce4fc4b5b75eab1bf8f1fc83f6b9" },
+  "dressing.nvim": { "branch": "master", "commit": "73a7d54b5289000108c7f52402a36cf380fced67" },
+  "friendly-snippets": { "branch": "main", "commit": "0368bee1cecaf3c58d436524234baad4c0e0b8cb" },
+  "gitsigns.nvim": { "branch": "main", "commit": "bdeba1cec3faddd89146690c10b9a87949c0ee66" },
+  "harpoon": { "branch": "master", "commit": "21f4c47c6803d64ddb934a5b314dcb1b8e7365dc" },
+  "lazy.nvim": { "branch": "main", "commit": "96584866b9c5e998cbae300594d0ccfd0c464627" },
+  "lspkind.nvim": { "branch": "master", "commit": "57610d5ab560c073c465d6faf0c19f200cb67e6e" },
+  "lualine.nvim": { "branch": "master", "commit": "45e27ca739c7be6c49e5496d14fcf45a303c3a63" },
+  "mason-lspconfig.nvim": { "branch": "main", "commit": "81e30dd629de24cbb26d08073ee938ab40006695" },
+  "mason-null-ls.nvim": { "branch": "main", "commit": "d1f7258f80867f718d643d88eee66959671a4bef" },
+  "mason-tool-installer.nvim": { "branch": "main", "commit": "83dcddb6477f9ba5db98971ef27bd18bdca921b4" },
+  "mason.nvim": { "branch": "main", "commit": "d66c60e17dd6fd8165194b1d14d21f7eb2c1697a" },
+  "none-ls.nvim": { "branch": "main", "commit": "bbd8c0c2b8a47ff2e0a97868afdf3fc640f1ad1e" },
+  "nvim-autopairs": { "branch": "master", "commit": "de4f7138a68d5d5063170f2182fd27faf06b0b54" },
+  "nvim-cmp": { "branch": "main", "commit": "5dce1b778b85c717f6614e3f4da45e9f19f54435" },
+  "nvim-colorizer.lua": { "branch": "master", "commit": "dde3084106a70b9a79d48f426f6d6fec6fd203f7" },
+  "nvim-lint": { "branch": "master", "commit": "67f74e630a84ecfa73a82783c487bdedd8cecdc3" },
+  "nvim-lsp-file-operations": { "branch": "master", "commit": "0ae13ac58136c6175638b6e1ba04cb487dd22272" },
+  "nvim-lspconfig": { "branch": "master", "commit": "50fcf96ec5a6e7bfdcbbea4f905c33e85408f170" },
+  "nvim-surround": { "branch": "main", "commit": "0d6882635817a2677749a330127d12ac30a4f3c8" },
+  "nvim-tree.lua": { "branch": "master", "commit": "934469b9b6df369e198fb3016969e56393b0dc07" },
+  "nvim-treesitter": { "branch": "master", "commit": "dd4e2dbc002dfce109d621e8bdcd9d89438b0a32" },
+  "nvim-treesitter-textobjects": { "branch": "master", "commit": "bd103502252027434ec42f628d2dbf54821d4ce6" },
+  "nvim-ts-autotag": { "branch": "main", "commit": "6be1192965df35f94b8ea6d323354f7dc7a557e4" },
+  "nvim-ts-context-commentstring": { "branch": "main", "commit": "95e9ba9de4289d221666b66fd930d157c7ca08c6" },
+  "nvim-web-devicons": { "branch": "master", "commit": "45d0237c427baba8cd05e0ab26d30e2ee58c2c82" },
+  "plenary.nvim": { "branch": "master", "commit": "9ce85b0f7dcfe5358c0be937ad23e456907d410b" },
+  "telescope-fzf-native.nvim": { "branch": "main", "commit": "6c921ca12321edaa773e324ef64ea301a1d0da62" },
+  "telescope.nvim": { "branch": "0.1.x", "commit": "54930e1abfc94409e1bb9266e752ef8379008592" },
+  "vim-ReplaceWithRegister": { "branch": "master", "commit": "aad1e8fa31cb4722f20fe40679caa56e25120032" },
+  "vim-maximizer": { "branch": "master", "commit": "2e54952fe91e140a2e69f35f22131219fcd9c5f1" },
+  "vim-nightfly-guicolors": { "branch": "master", "commit": "06ad2689ebd251a71c6caeb9fb47e231773c9b47" },
+  "vim-tmux-navigator": { "branch": "master", "commit": "7db70e08ea03b3e4d91f63713d76134512e28d7e" },
+  "which-key.nvim": { "branch": "main", "commit": "7ccf476ebe0445a741b64e36c78a682c1c6118b7" }
+}
\ No newline at end of file
diff --git a/lua/josean/core/init.lua b/lua/josean/core/init.lua
@@ -0,0 +1,2 @@
+require("josean.core.keymaps")
+require("josean.core.options")
diff --git a/lua/josean/core/keymaps.lua b/lua/josean/core/keymaps.lua
@@ -0,0 +1,32 @@
+-- set leader key to space
+vim.g.mapleader = " "
+
+local keymap = vim.keymap -- for conciseness
+
+---------------------
+-- General Keymaps -------------------
+
+-- use jk to exit insert mode
+keymap.set("i", "jk", "<ESC>", { desc = "Exit insert mode with jk" })
+
+-- clear search highlights
+keymap.set("n", "<leader>nh", ":nohl<CR>", { desc = "Clear search highlights" })
+
+-- delete single character without copying into register
+-- keymap.set("n", "x", '"_x')
+
+-- increment/decrement numbers
+keymap.set("n", "<leader>+", "<C-a>", { desc = "Increment number" }) -- increment
+keymap.set("n", "<leader>-", "<C-x>", { desc = "Decrement number" }) -- decrement
+
+-- window management
+keymap.set("n", "<leader>sv", "<C-w>v", { desc = "Split window vertically" }) -- split window vertically
+keymap.set("n", "<leader>sh", "<C-w>s", { desc = "Split window horizontally" }) -- split window horizontally
+keymap.set("n", "<leader>se", "<C-w>=", { desc = "Make splits equal size" }) -- make split windows equal width & height
+keymap.set("n", "<leader>sx", "<cmd>close<CR>", { desc = "Close current split" }) -- close current split window
+
+keymap.set("n", "<leader>to", "<cmd>tabnew<CR>", { desc = "Open new tab" }) -- open new tab
+keymap.set("n", "<leader>tx", "<cmd>tabclose<CR>", { desc = "Close current tab" }) -- close current tab
+keymap.set("n", "<leader>tn", "<cmd>tabn<CR>", { desc = "Go to next tab" }) --  go to next tab
+keymap.set("n", "<leader>tp", "<cmd>tabp<CR>", { desc = "Go to previous tab" }) --  go to previous tab
+keymap.set("n", "<leader>tf", "<cmd>tabnew %<CR>", { desc = "Open current buffer in new tab" }) --  move current buffer to new tab
diff --git a/lua/josean/core/options.lua b/lua/josean/core/options.lua
@@ -0,0 +1,42 @@
+local opt = vim.opt -- for conciseness
+
+-- line numbers
+opt.relativenumber = true -- show relative line numbers
+opt.number = true -- shows absolute line number on cursor line (when relative number is on)
+
+-- tabs & indentation
+opt.tabstop = 2 -- 2 spaces for tabs (prettier default)
+opt.shiftwidth = 2 -- 2 spaces for indent width
+opt.expandtab = true -- expand tab to spaces
+opt.autoindent = true -- copy indent from current line when starting new one
+
+-- line wrapping
+opt.wrap = false -- disable line wrapping
+
+-- search settings
+opt.ignorecase = true -- ignore case when searching
+opt.smartcase = true -- if you include mixed case in your search, assumes you want case-sensitive
+
+-- cursor line
+opt.cursorline = true -- highlight the current cursor line
+
+-- appearance
+
+-- turn on termguicolors for nightfly colorscheme to work
+-- (have to use iterm2 or any other true color terminal)
+opt.termguicolors = true
+opt.background = "dark" -- colorschemes that can be light or dark will be made dark
+opt.signcolumn = "yes" -- show sign column so that text doesn't shift
+
+-- backspace
+opt.backspace = "indent,eol,start" -- allow backspace on indent, end of line or insert mode start position
+
+-- clipboard
+opt.clipboard:append("unnamedplus") -- use system clipboard as default register
+
+-- split windows
+opt.splitright = true -- split vertical window to the right
+opt.splitbelow = true -- split horizontal window to the bottom
+
+-- turn off swapfile
+opt.swapfile = false
diff --git a/lua/josean/lazy.lua b/lua/josean/lazy.lua
@@ -0,0 +1,25 @@
+local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
+if not vim.loop.fs_stat(lazypath) then
+  vim.fn.system({
+    "git",
+    "clone",
+    "--filter=blob:none",
+    "https://github.com/folke/lazy.nvim.git",
+    "--branch=stable", -- latest stable release
+    lazypath,
+  })
+end
+vim.opt.rtp:prepend(lazypath)
+
+require("lazy").setup({ { import = "josean.plugins" }, { import = "josean.plugins.lsp" } }, {
+  install = {
+    colorscheme = { "nightfly" },
+  },
+  checker = {
+    enabled = true,
+    notify = false,
+  },
+  change_detection = {
+    notify = false,
+  },
+})
diff --git a/lua/josean/plugins/alpha-nvim.lua b/lua/josean/plugins/alpha-nvim.lua
@@ -0,0 +1,37 @@
+return {
+  "goolord/alpha-nvim",
+  event = "VimEnter",
+  dependencies = { "nvim-tree/nvim-web-devicons" },
+  config = function()
+    local alpha = require("alpha")
+    local dashboard = require("alpha.themes.dashboard")
+
+    -- Set header
+    dashboard.section.header.val = {
+      "                                                     ",
+      "  ███╗   ██╗███████╗ ██████╗ ██╗   ██╗██╗███╗   ███╗ ",
+      "  ████╗  ██║██╔════╝██╔═══██╗██║   ██║██║████╗ ████║ ",
+      "  ██╔██╗ ██║█████╗  ██║   ██║██║   ██║██║██╔████╔██║ ",
+      "  ██║╚██╗██║██╔══╝  ██║   ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ",
+      "  ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ",
+      "  ╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═══╝  ╚═╝╚═╝     ╚═╝ ",
+      "                                                     ",
+    }
+
+    -- Set menu
+    dashboard.section.buttons.val = {
+      dashboard.button("e", "  > New File", "<cmd>ene<CR>"),
+      dashboard.button("SPC ee", "  > Toggle file explorer", "<cmd>NvimTreeToggle<CR>"),
+      dashboard.button("SPC ff", "󰱼 > Find File", "<cmd>Telescope find_files<CR>"),
+      dashboard.button("SPC fs", "  > Find Word", "<cmd>Telescope live_grep<CR>"),
+      dashboard.button("SPC wr", "󰁯  > Restore Session For Current Directory", "<cmd>SessionRestore<CR>"),
+      dashboard.button("q", " > Quit NVIM", "<cmd>qa<CR>"),
+    }
+
+    -- Send config to alpha
+    alpha.setup(dashboard.opts)
+
+    -- Disable folding on alpha buffer
+    vim.cmd([[autocmd FileType alpha setlocal nofoldenable]])
+  end,
+}
diff --git a/lua/josean/plugins/auto-session.lua b/lua/josean/plugins/auto-session.lua
@@ -0,0 +1,16 @@
+return {
+  "rmagatti/auto-session",
+  config = function()
+    local auto_session = require("auto-session")
+
+    auto_session.setup({
+      auto_restore_enabled = false,
+      auto_session_suppress_dirs = { "~/", "~/Dev/", "~/Downloads", "~/Documents", "~/Desktop/" },
+    })
+
+    local keymap = vim.keymap
+
+    keymap.set("n", "<leader>wr", "<cmd>SessionRestore<CR>", { desc = "Restore session for cwd" }) -- restore last workspace session for current directory
+    keymap.set("n", "<leader>ws", "<cmd>SessionSave<CR>", { desc = "Save session for auto session root dir" }) -- save workspace session for current working directory
+  end,
+}
diff --git a/lua/josean/plugins/bufferline.lua b/lua/josean/plugins/bufferline.lua
@@ -0,0 +1,11 @@
+return {
+  "akinsho/bufferline.nvim",
+  dependencies = { "nvim-tree/nvim-web-devicons" },
+  version = "*",
+  opts = {
+    options = {
+      mode = "tabs",
+      separator_style = "slant",
+    },
+  },
+}
diff --git a/lua/josean/plugins/colorizer.lua b/lua/josean/plugins/colorizer.lua
@@ -0,0 +1,5 @@
+return {
+  "NvChad/nvim-colorizer.lua",
+  event = { "BufReadPre", "BufNewFile" },
+  config = true,
+}
diff --git a/lua/josean/plugins/colorscheme.lua b/lua/josean/plugins/colorscheme.lua
@@ -0,0 +1,48 @@
+return {
+  {
+    "bluz71/vim-nightfly-guicolors",
+    priority = 1000, -- make sure to load this before all the other start plugins
+    config = function()
+      -- load the colorscheme here
+      vim.cmd([[colorscheme nightfly]])
+    end,
+  },
+  -- {
+  --   "folke/tokyonight.nvim",
+  --   priority = 1000, -- make sure to load this before all the other start plugins
+  --   config = function()
+  --     local bg = "#011628"
+  --     local bg_dark = "#011423"
+  --     local bg_highlight = "#143652"
+  --     local bg_search = "#0A64AC"
+  --     local bg_visual = "#275378"
+  --     local fg = "#CBE0F0"
+  --     local fg_dark = "#B4D0E9"
+  --     local fg_gutter = "#627E97"
+  --     local border = "#547998"
+  --
+  --     require("tokyonight").setup({
+  --       style = "night",
+  --       on_colors = function(colors)
+  --         colors.bg = bg
+  --         colors.bg_dark = bg_dark
+  --         colors.bg_float = bg_dark
+  --         colors.bg_highlight = bg_highlight
+  --         colors.bg_popup = bg_dark
+  --         colors.bg_search = bg_search
+  --         colors.bg_sidebar = bg_dark
+  --         colors.bg_statusline = bg_dark
+  --         colors.bg_visual = bg_visual
+  --         colors.border = border
+  --         colors.fg = fg
+  --         colors.fg_dark = fg_dark
+  --         colors.fg_float = fg
+  --         colors.fg_gutter = fg_gutter
+  --         colors.fg_sidebar = fg_dark
+  --       end,
+  --     })
+  --     -- load the colorscheme here
+  --     vim.cmd([[colorscheme tokyonight]])
+  --   end,
+  -- },
+}
diff --git a/lua/josean/plugins/comment.lua b/lua/josean/plugins/comment.lua
@@ -0,0 +1,19 @@
+return {
+  "numToStr/Comment.nvim",
+  event = { "BufReadPre", "BufNewFile" },
+  dependencies = {
+    "JoosepAlviste/nvim-ts-context-commentstring",
+  },
+  config = function()
+    -- import comment plugin safely
+    local comment = require("Comment")
+
+    local ts_context_commentstring = require("ts_context_commentstring.integrations.comment_nvim")
+
+    -- enable comment
+    comment.setup({
+      -- for commenting tsx and jsx files
+      pre_hook = ts_context_commentstring.create_pre_hook(),
+    })
+  end,
+}
diff --git a/lua/josean/plugins/dressing.lua b/lua/josean/plugins/dressing.lua
@@ -0,0 +1,4 @@
+return {
+  "stevearc/dressing.nvim",
+  event = "VeryLazy",
+}
diff --git a/lua/josean/plugins/formatting.lua b/lua/josean/plugins/formatting.lua
@@ -0,0 +1,39 @@
+return {
+  "stevearc/conform.nvim",
+  lazy = true,
+  event = { "BufReadPre", "BufNewFile" }, -- to disable, comment this out
+  config = function()
+    local conform = require("conform")
+
+    conform.setup({
+      formatters_by_ft = {
+        javascript = { "prettier" },
+        typescript = { "prettier" },
+        javascriptreact = { "prettier" },
+        typescriptreact = { "prettier" },
+        svelte = { "prettier" },
+        css = { "prettier" },
+        html = { "prettier" },
+        json = { "prettier" },
+        yaml = { "prettier" },
+        markdown = { "prettier" },
+        graphql = { "prettier" },
+        lua = { "stylua" },
+        python = { "isort", "black" },
+      },
+      format_on_save = {
+        lsp_fallback = true,
+        async = false,
+        timeout_ms = 1000,
+      },
+    })
+
+    vim.keymap.set({ "n", "v" }, "<leader>mp", function()
+      conform.format({
+        lsp_fallback = true,
+        async = false,
+        timeout_ms = 1000,
+      })
+    end, { desc = "Format file or range (in visual mode)" })
+  end,
+}
diff --git a/lua/josean/plugins/gitsigns.lua b/lua/josean/plugins/gitsigns.lua
@@ -0,0 +1,5 @@
+return {
+  "lewis6991/gitsigns.nvim",
+  event = { "BufReadPre", "BufNewFile" },
+  config = true,
+}
diff --git a/lua/josean/plugins/harpoon.lua b/lua/josean/plugins/harpoon.lua
@@ -0,0 +1,24 @@
+return {
+  "ThePrimeagen/harpoon",
+  dependencies = {
+    "nvim-lua/plenary.nvim",
+  },
+  config = function()
+    -- set keymaps
+    local keymap = vim.keymap -- for conciseness
+
+    keymap.set(
+      "n",
+      "<leader>hm",
+      "<cmd>lua require('harpoon.mark').add_file()<cr>",
+      { desc = "Mark file with harpoon" }
+    )
+    keymap.set("n", "<leader>hn", "<cmd>lua require('harpoon.ui').nav_next()<cr>", { desc = "Go to next harpoon mark" })
+    keymap.set(
+      "n",
+      "<leader>hp",
+      "<cmd>lua require('harpoon.ui').nav_prev()<cr>",
+      { desc = "Go to previous harpoon mark" }
+    )
+  end,
+}
diff --git a/lua/josean/plugins/init.lua b/lua/josean/plugins/init.lua
@@ -0,0 +1,7 @@
+return {
+  "nvim-lua/plenary.nvim", -- lua functions that many plugins use
+
+  "christoomey/vim-tmux-navigator", -- tmux & split window navigation
+
+  "inkarkat/vim-ReplaceWithRegister", -- replace with register contents using motion (gr + motion)
+}
diff --git a/lua/josean/plugins/linting.lua b/lua/josean/plugins/linting.lua
@@ -0,0 +1,30 @@
+return {
+  "mfussenegger/nvim-lint",
+  lazy = true,
+  event = { "BufReadPre", "BufNewFile" }, -- to disable, comment this out
+  config = function()
+    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" },
+    }
+
+    local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true })
+
+    vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, {
+      group = lint_augroup,
+      callback = function()
+        lint.try_lint()
+      end,
+    })
+
+    vim.keymap.set("n", "<leader>l", function()
+      lint.try_lint()
+    end, { desc = "Trigger linting for current file" })
+  end,
+}
diff --git a/lua/josean/plugins/lsp/lspconfig.lua b/lua/josean/plugins/lsp/lspconfig.lua
@@ -0,0 +1,161 @@
+return {
+  "neovim/nvim-lspconfig",
+  event = { "BufReadPre", "BufNewFile" },
+  dependencies = {
+    "hrsh7th/cmp-nvim-lsp",
+    { "antosha417/nvim-lsp-file-operations", config = true },
+  },
+  config = function()
+    -- import lspconfig plugin
+    local lspconfig = require("lspconfig")
+
+    -- import cmp-nvim-lsp plugin
+    local cmp_nvim_lsp = require("cmp_nvim_lsp")
+
+    local keymap = vim.keymap -- for conciseness
+
+    local opts = { noremap = true, silent = true }
+    local on_attach = function(client, bufnr)
+      opts.buffer = bufnr
+
+      -- set keybinds
+      opts.desc = "Show LSP references"
+      keymap.set("n", "gR", "<cmd>Telescope lsp_references<CR>", opts) -- show definition, references
+
+      opts.desc = "Go to declaration"
+      keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration
+
+      opts.desc = "Show LSP definitions"
+      keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts) -- show lsp definitions
+
+      opts.desc = "Show LSP implementations"
+      keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts) -- show lsp implementations
+
+      opts.desc = "Show LSP type definitions"
+      keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts) -- show lsp type definitions
+
+      opts.desc = "See available code actions"
+      keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection
+
+      opts.desc = "Smart rename"
+      keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts) -- smart rename
+
+      opts.desc = "Show buffer diagnostics"
+      keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts) -- show  diagnostics for file
+
+      opts.desc = "Show line diagnostics"
+      keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts) -- show diagnostics for line
+
+      opts.desc = "Go to previous diagnostic"
+      keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer
+
+      opts.desc = "Go to next diagnostic"
+      keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer
+
+      opts.desc = "Show documentation for what is under cursor"
+      keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor
+
+      opts.desc = "Restart LSP"
+      keymap.set("n", "<leader>rs", ":LspRestart<CR>", opts) -- mapping to restart lsp if necessary
+    end
+
+    -- used to enable autocompletion (assign to every lsp server config)
+    local capabilities = cmp_nvim_lsp.default_capabilities()
+
+    -- Change the Diagnostic symbols in the sign column (gutter)
+    -- (not in youtube nvim video)
+    local signs = { Error = " ", Warn = " ", Hint = "󰠠 ", Info = " " }
+    for type, icon in pairs(signs) do
+      local hl = "DiagnosticSign" .. type
+      vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" })
+    end
+
+    -- configure html server
+    lspconfig["html"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+    })
+
+    -- configure typescript server with plugin
+    lspconfig["tsserver"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+    })
+
+    -- configure css server
+    lspconfig["cssls"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+    })
+
+    -- configure tailwindcss server
+    lspconfig["tailwindcss"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+    })
+
+    -- configure svelte server
+    lspconfig["svelte"].setup({
+      capabilities = capabilities,
+      on_attach = function(client, bufnr)
+        on_attach(client, bufnr)
+
+        vim.api.nvim_create_autocmd("BufWritePost", {
+          pattern = { "*.js", "*.ts" },
+          callback = function(ctx)
+            if client.name == "svelte" then
+              client.notify("$/onDidChangeTsOrJsFile", { uri = ctx.file })
+            end
+          end,
+        })
+      end,
+    })
+
+    -- configure prisma orm server
+    lspconfig["prismals"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+    })
+
+    -- configure graphql language server
+    lspconfig["graphql"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+      filetypes = { "graphql", "gql", "svelte", "typescriptreact", "javascriptreact" },
+    })
+
+    -- configure emmet language server
+    lspconfig["emmet_ls"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+      filetypes = { "html", "typescriptreact", "javascriptreact", "css", "sass", "scss", "less", "svelte" },
+    })
+
+    -- configure python server
+    lspconfig["pyright"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+    })
+
+    -- configure lua server (with special settings)
+    lspconfig["lua_ls"].setup({
+      capabilities = capabilities,
+      on_attach = on_attach,
+      settings = { -- custom settings for lua
+        Lua = {
+          -- make the language server recognize "vim" global
+          diagnostics = {
+            globals = { "vim" },
+          },
+          workspace = {
+            -- make language server aware of runtime files
+            library = {
+              [vim.fn.expand("$VIMRUNTIME/lua")] = true,
+              [vim.fn.stdpath("config") .. "/lua"] = true,
+            },
+          },
+        },
+      },
+    })
+  end,
+}
diff --git a/lua/josean/plugins/lsp/mason.lua b/lua/josean/plugins/lsp/mason.lua
@@ -0,0 +1,56 @@
+return {
+  "williamboman/mason.nvim",
+  dependencies = {
+    "williamboman/mason-lspconfig.nvim",
+    "WhoIsSethDaniel/mason-tool-installer.nvim",
+  },
+  config = function()
+    -- import mason
+    local mason = require("mason")
+
+    -- import mason-lspconfig
+    local mason_lspconfig = require("mason-lspconfig")
+
+    local mason_tool_installer = require("mason-tool-installer")
+
+    -- enable mason and configure icons
+    mason.setup({
+      ui = {
+        icons = {
+          package_installed = "✓",
+          package_pending = "➜",
+          package_uninstalled = "✗",
+        },
+      },
+    })
+
+    mason_lspconfig.setup({
+      -- list of servers for mason to install
+      ensure_installed = {
+        "tsserver",
+        "html",
+        "cssls",
+        "tailwindcss",
+        "svelte",
+        "lua_ls",
+        "graphql",
+        "emmet_ls",
+        "prismals",
+        "pyright",
+      },
+      -- auto-install configured servers (with lspconfig)
+      automatic_installation = true, -- not the same as ensure_installed
+    })
+
+    mason_tool_installer.setup({
+      ensure_installed = {
+        "prettier", -- prettier formatter
+        "stylua", -- lua formatter
+        "isort", -- python formatter
+        "black", -- python formatter
+        "pylint", -- python linter
+        "eslint_d", -- js linter
+      },
+    })
+  end,
+}
diff --git a/lua/josean/plugins/lsp/none-ls.lua b/lua/josean/plugins/lsp/none-ls.lua
@@ -0,0 +1,74 @@
+return {
+  "nvimtools/none-ls.nvim", -- configure formatters & linters
+  lazy = true,
+  -- event = { "BufReadPre", "BufNewFile" }, -- to enable uncomment this
+  dependencies = {
+    "jay-babu/mason-null-ls.nvim",
+  },
+  config = function()
+    local mason_null_ls = require("mason-null-ls")
+
+    local null_ls = require("null-ls")
+
+    local null_ls_utils = require("null-ls.utils")
+
+    mason_null_ls.setup({
+      ensure_installed = {
+        "prettier", -- prettier formatter
+        "stylua", -- lua formatter
+        "black", -- python formatter
+        "pylint", -- python linter
+        "eslint_d", -- js linter
+      },
+    })
+
+    -- for conciseness
+    local formatting = null_ls.builtins.formatting -- to setup formatters
+    local diagnostics = null_ls.builtins.diagnostics -- to setup linters
+
+    -- to setup format on save
+    local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
+
+    -- configure null_ls
+    null_ls.setup({
+      -- add package.json as identifier for root (for typescript monorepos)
+      root_dir = null_ls_utils.root_pattern(".null-ls-root", "Makefile", ".git", "package.json"),
+      -- setup formatters & linters
+      sources = {
+        --  to disable file types use
+        --  "formatting.prettier.with({disabled_filetypes: {}})" (see null-ls docs)
+        formatting.prettier.with({
+          extra_filetypes = { "svelte" },
+        }), -- js/ts formatter
+        formatting.stylua, -- lua formatter
+        formatting.isort,
+        formatting.black,
+        diagnostics.pylint,
+        diagnostics.eslint_d.with({ -- js/ts linter
+          condition = function(utils)
+            return utils.root_has_file({ ".eslintrc.js", ".eslintrc.cjs" }) -- only enable if root has .eslintrc.js or .eslintrc.cjs
+          end,
+        }),
+      },
+      -- configure format on save
+      on_attach = function(current_client, bufnr)
+        if current_client.supports_method("textDocument/formatting") then
+          vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
+          vim.api.nvim_create_autocmd("BufWritePre", {
+            group = augroup,
+            buffer = bufnr,
+            callback = function()
+              vim.lsp.buf.format({
+                filter = function(client)
+                  --  only use null-ls for formatting instead of lsp server
+                  return client.name == "null-ls"
+                end,
+                bufnr = bufnr,
+              })
+            end,
+          })
+        end
+      end,
+    })
+  end,
+}
diff --git a/lua/josean/plugins/lualine.lua b/lua/josean/plugins/lualine.lua
@@ -0,0 +1,71 @@
+return {
+  "nvim-lualine/lualine.nvim",
+  dependencies = { "nvim-tree/nvim-web-devicons" },
+  config = function()
+    local lualine = require("lualine")
+    local lazy_status = require("lazy.status") -- to configure lazy pending updates count
+
+    local colors = {
+      blue = "#65D1FF",
+      green = "#3EFFDC",
+      violet = "#FF61EF",
+      yellow = "#FFDA7B",
+      red = "#FF4A4A",
+      fg = "#c3ccdc",
+      bg = "#112638",
+      inactive_bg = "#2c3043",
+    }
+
+    local my_lualine_theme = {
+      normal = {
+        a = { bg = colors.blue, fg = colors.bg, gui = "bold" },
+        b = { bg = colors.bg, fg = colors.fg },
+        c = { bg = colors.bg, fg = colors.fg },
+      },
+      insert = {
+        a = { bg = colors.green, fg = colors.bg, gui = "bold" },
+        b = { bg = colors.bg, fg = colors.fg },
+        c = { bg = colors.bg, fg = colors.fg },
+      },
+      visual = {
+        a = { bg = colors.violet, fg = colors.bg, gui = "bold" },
+        b = { bg = colors.bg, fg = colors.fg },
+        c = { bg = colors.bg, fg = colors.fg },
+      },
+      command = {
+        a = { bg = colors.yellow, fg = colors.bg, gui = "bold" },
+        b = { bg = colors.bg, fg = colors.fg },
+        c = { bg = colors.bg, fg = colors.fg },
+      },
+      replace = {
+        a = { bg = colors.red, fg = colors.bg, gui = "bold" },
+        b = { bg = colors.bg, fg = colors.fg },
+        c = { bg = colors.bg, fg = colors.fg },
+      },
+      inactive = {
+        a = { bg = colors.inactive_bg, fg = colors.semilightgray, gui = "bold" },
+        b = { bg = colors.inactive_bg, fg = colors.semilightgray },
+        c = { bg = colors.inactive_bg, fg = colors.semilightgray },
+      },
+    }
+
+    -- configure lualine with modified theme
+    lualine.setup({
+      options = {
+        theme = my_lualine_theme,
+      },
+      sections = {
+        lualine_x = {
+          {
+            lazy_status.updates,
+            cond = lazy_status.has_updates,
+            color = { fg = "#ff9e64" },
+          },
+          { "encoding" },
+          { "fileformat" },
+          { "filetype" },
+        },
+      },
+    })
+  end,
+}
diff --git a/lua/josean/plugins/nvim-autopairs.lua b/lua/josean/plugins/nvim-autopairs.lua
@@ -0,0 +1,30 @@
+return {
+  "windwp/nvim-autopairs",
+  event = { "InsertEnter" },
+  dependencies = {
+    "hrsh7th/nvim-cmp",
+  },
+  config = function()
+    -- import nvim-autopairs
+    local autopairs = require("nvim-autopairs")
+
+    -- configure autopairs
+    autopairs.setup({
+      check_ts = true, -- enable treesitter
+      ts_config = {
+        lua = { "string" }, -- don't add pairs in lua string treesitter nodes
+        javascript = { "template_string" }, -- don't add pairs in javscript template_string treesitter nodes
+        java = false, -- don't check treesitter on java
+      },
+    })
+
+    -- import nvim-autopairs completion functionality
+    local cmp_autopairs = require("nvim-autopairs.completion.cmp")
+
+    -- import nvim-cmp plugin (completions plugin)
+    local cmp = require("cmp")
+
+    -- make autopairs and completion work together
+    cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done())
+  end,
+}
diff --git a/lua/josean/plugins/nvim-cmp.lua b/lua/josean/plugins/nvim-cmp.lua
@@ -0,0 +1,56 @@
+return {
+  "hrsh7th/nvim-cmp",
+  event = "InsertEnter",
+  dependencies = {
+    "hrsh7th/cmp-buffer", -- source for text in buffer
+    "hrsh7th/cmp-path", -- source for file system paths
+    "L3MON4D3/LuaSnip", -- snippet engine
+    "saadparwaiz1/cmp_luasnip", -- for autocompletion
+    "rafamadriz/friendly-snippets", -- useful snippets
+    "onsails/lspkind.nvim", -- vs-code like pictograms
+  },
+  config = function()
+    local cmp = require("cmp")
+
+    local luasnip = require("luasnip")
+
+    local lspkind = require("lspkind")
+
+    -- loads vscode style snippets from installed plugins (e.g. friendly-snippets)
+    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)
+          luasnip.lsp_expand(args.body)
+        end,
+      },
+      mapping = cmp.mapping.preset.insert({
+        ["<C-k>"] = cmp.mapping.select_prev_item(), -- previous suggestion
+        ["<C-j>"] = cmp.mapping.select_next_item(), -- next suggestion
+        ["<C-b>"] = cmp.mapping.scroll_docs(-4),
+        ["<C-f>"] = cmp.mapping.scroll_docs(4),
+        ["<C-Space>"] = cmp.mapping.complete(), -- show completion suggestions
+        ["<C-e>"] = cmp.mapping.abort(), -- close completion window
+        ["<CR>"] = cmp.mapping.confirm({ select = false }),
+      }),
+      -- sources for autocompletion
+      sources = cmp.config.sources({
+        { name = "nvim_lsp" },
+        { name = "luasnip" }, -- snippets
+        { name = "buffer" }, -- text within current buffer
+        { name = "path" }, -- file system paths
+      }),
+      -- configure lspkind for vs-code like pictograms in completion menu
+      formatting = {
+        format = lspkind.cmp_format({
+          maxwidth = 50,
+          ellipsis_char = "...",
+        }),
+      },
+    })
+  end,
+}
diff --git a/lua/josean/plugins/nvim-surround.lua b/lua/josean/plugins/nvim-surround.lua
@@ -0,0 +1,6 @@
+return {
+  "kylechui/nvim-surround",
+  event = { "BufReadPre", "BufNewFile" },
+  version = "*", -- Use for stability; omit to use `main` branch for the latest features
+  config = true,
+}
diff --git a/lua/josean/plugins/nvim-tree.lua b/lua/josean/plugins/nvim-tree.lua
@@ -0,0 +1,61 @@
+return {
+  "nvim-tree/nvim-tree.lua",
+  dependencies = { "nvim-tree/nvim-web-devicons" },
+  config = function()
+    local nvimtree = require("nvim-tree")
+
+    -- recommended settings from nvim-tree documentation
+    vim.g.loaded_netrw = 1
+    vim.g.loaded_netrwPlugin = 1
+
+    -- change color for arrows in tree to light blue
+    vim.cmd([[ highlight NvimTreeFolderArrowClosed guifg=#3FC5FF ]])
+    vim.cmd([[ highlight NvimTreeFolderArrowOpen guifg=#3FC5FF ]])
+
+    -- configure nvim-tree
+    nvimtree.setup({
+      view = {
+        width = 35,
+        relativenumber = true,
+      },
+      -- change folder arrow icons
+      renderer = {
+        indent_markers = {
+          enable = true,
+        },
+        icons = {
+          glyphs = {
+            folder = {
+              arrow_closed = "", -- arrow when folder is closed
+              arrow_open = "", -- arrow when folder is open
+            },
+          },
+        },
+      },
+      -- disable window_picker for
+      -- explorer to work well with
+      -- window splits
+      actions = {
+        open_file = {
+          window_picker = {
+            enable = false,
+          },
+        },
+      },
+      filters = {
+        custom = { ".DS_Store" },
+      },
+      git = {
+        ignore = false,
+      },
+    })
+
+    -- set keymaps
+    local keymap = vim.keymap -- for conciseness
+
+    keymap.set("n", "<leader>ee", "<cmd>NvimTreeToggle<CR>", { desc = "Toggle file explorer" }) -- toggle file explorer
+    keymap.set("n", "<leader>ef", "<cmd>NvimTreeFindFileToggle<CR>", { desc = "Toggle file explorer on current file" }) -- toggle file explorer on current file
+    keymap.set("n", "<leader>ec", "<cmd>NvimTreeCollapse<CR>", { desc = "Collapse file explorer" }) -- collapse file explorer
+    keymap.set("n", "<leader>er", "<cmd>NvimTreeRefresh<CR>", { desc = "Refresh file explorer" }) -- refresh file explorer
+  end,
+}
diff --git a/lua/josean/plugins/nvim-treesitter-text-objects.lua b/lua/josean/plugins/nvim-treesitter-text-objects.lua
@@ -0,0 +1,110 @@
+return {
+  "nvim-treesitter/nvim-treesitter-textobjects",
+  lazy = true,
+  config = function()
+    require("nvim-treesitter.configs").setup({
+      textobjects = {
+        select = {
+          enable = true,
+
+          -- Automatically jump forward to textobj, similar to targets.vim
+          lookahead = true,
+
+          keymaps = {
+            -- You can use the capture groups defined in textobjects.scm
+            ["a="] = { query = "@assignment.outer", desc = "Select outer part of an assignment" },
+            ["i="] = { query = "@assignment.inner", desc = "Select inner part of an assignment" },
+            ["l="] = { query = "@assignment.lhs", desc = "Select left hand side of an assignment" },
+            ["r="] = { query = "@assignment.rhs", desc = "Select right hand side of an assignment" },
+
+            -- works for javascript/typescript files (custom capture I created in after/queries/ecma/textobjects.scm)
+            ["a:"] = { query = "@property.outer", desc = "Select outer part of an object property" },
+            ["i:"] = { query = "@property.inner", desc = "Select inner part of an object property" },
+            ["l:"] = { query = "@property.lhs", desc = "Select left part of an object property" },
+            ["r:"] = { query = "@property.rhs", desc = "Select right part of an object property" },
+
+            ["aa"] = { query = "@parameter.outer", desc = "Select outer part of a parameter/argument" },
+            ["ia"] = { query = "@parameter.inner", desc = "Select inner part of a parameter/argument" },
+
+            ["ai"] = { query = "@conditional.outer", desc = "Select outer part of a conditional" },
+            ["ii"] = { query = "@conditional.inner", desc = "Select inner part of a conditional" },
+
+            ["al"] = { query = "@loop.outer", desc = "Select outer part of a loop" },
+            ["il"] = { query = "@loop.inner", desc = "Select inner part of a loop" },
+
+            ["af"] = { query = "@call.outer", desc = "Select outer part of a function call" },
+            ["if"] = { query = "@call.inner", desc = "Select inner part of a function call" },
+
+            ["am"] = { query = "@function.outer", desc = "Select outer part of a method/function definition" },
+            ["im"] = { query = "@function.inner", desc = "Select inner part of a method/function definition" },
+
+            ["ac"] = { query = "@class.outer", desc = "Select outer part of a class" },
+            ["ic"] = { query = "@class.inner", desc = "Select inner part of a class" },
+          },
+        },
+        swap = {
+          enable = true,
+          swap_next = {
+            ["<leader>na"] = "@parameter.inner", -- swap parameters/argument with next
+            ["<leader>n:"] = "@property.outer", -- swap object property with next
+            ["<leader>nm"] = "@function.outer", -- swap function with next
+          },
+          swap_previous = {
+            ["<leader>pa"] = "@parameter.inner", -- swap parameters/argument with prev
+            ["<leader>p:"] = "@property.outer", -- swap object property with prev
+            ["<leader>pm"] = "@function.outer", -- swap function with previous
+          },
+        },
+        move = {
+          enable = true,
+          set_jumps = true, -- whether to set jumps in the jumplist
+          goto_next_start = {
+            ["]f"] = { query = "@call.outer", desc = "Next function call start" },
+            ["]m"] = { query = "@function.outer", desc = "Next method/function def start" },
+            ["]c"] = { query = "@class.outer", desc = "Next class start" },
+            ["]i"] = { query = "@conditional.outer", desc = "Next conditional start" },
+            ["]l"] = { query = "@loop.outer", desc = "Next loop start" },
+
+            -- You can pass a query group to use query from `queries/<lang>/<query_group>.scm file in your runtime path.
+            -- Below example nvim-treesitter's `locals.scm` and `folds.scm`. They also provide highlights.scm and indent.scm.
+            ["]s"] = { query = "@scope", query_group = "locals", desc = "Next scope" },
+            ["]z"] = { query = "@fold", query_group = "folds", desc = "Next fold" },
+          },
+          goto_next_end = {
+            ["]F"] = { query = "@call.outer", desc = "Next function call end" },
+            ["]M"] = { query = "@function.outer", desc = "Next method/function def end" },
+            ["]C"] = { query = "@class.outer", desc = "Next class end" },
+            ["]I"] = { query = "@conditional.outer", desc = "Next conditional end" },
+            ["]L"] = { query = "@loop.outer", desc = "Next loop end" },
+          },
+          goto_previous_start = {
+            ["[f"] = { query = "@call.outer", desc = "Prev function call start" },
+            ["[m"] = { query = "@function.outer", desc = "Prev method/function def start" },
+            ["[c"] = { query = "@class.outer", desc = "Prev class start" },
+            ["[i"] = { query = "@conditional.outer", desc = "Prev conditional start" },
+            ["[l"] = { query = "@loop.outer", desc = "Prev loop start" },
+          },
+          goto_previous_end = {
+            ["[F"] = { query = "@call.outer", desc = "Prev function call end" },
+            ["[M"] = { query = "@function.outer", desc = "Prev method/function def end" },
+            ["[C"] = { query = "@class.outer", desc = "Prev class end" },
+            ["[I"] = { query = "@conditional.outer", desc = "Prev conditional end" },
+            ["[L"] = { query = "@loop.outer", desc = "Prev loop end" },
+          },
+        },
+      },
+    })
+
+    local ts_repeat_move = require("nvim-treesitter.textobjects.repeatable_move")
+
+    -- vim way: ; goes to the direction you were moving.
+    vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move)
+    vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)
+
+    -- Optionally, make builtin f, F, t, T also repeatable with ; and ,
+    vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f)
+    vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F)
+    vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t)
+    vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T)
+  end,
+}
diff --git a/lua/josean/plugins/nvim-treesitter.lua b/lua/josean/plugins/nvim-treesitter.lua
@@ -0,0 +1,61 @@
+return {
+  {
+    "nvim-treesitter/nvim-treesitter",
+    event = { "BufReadPre", "BufNewFile" },
+    build = ":TSUpdate",
+    dependencies = {
+      "nvim-treesitter/nvim-treesitter-textobjects",
+      "windwp/nvim-ts-autotag",
+    },
+    config = function()
+      -- import nvim-treesitter plugin
+      local treesitter = require("nvim-treesitter.configs")
+
+      -- configure treesitter
+      treesitter.setup({ -- enable syntax highlighting
+        highlight = {
+          enable = true,
+        },
+        -- enable indentation
+        indent = { enable = true },
+        -- enable autotagging (w/ nvim-ts-autotag plugin)
+        autotag = {
+          enable = true,
+        },
+        -- ensure these language parsers are installed
+        ensure_installed = {
+          "json",
+          "javascript",
+          "typescript",
+          "tsx",
+          "yaml",
+          "html",
+          "css",
+          "prisma",
+          "markdown",
+          "markdown_inline",
+          "svelte",
+          "graphql",
+          "bash",
+          "lua",
+          "vim",
+          "dockerfile",
+          "gitignore",
+          "query",
+        },
+        incremental_selection = {
+          enable = true,
+          keymaps = {
+            init_selection = "<C-space>",
+            node_incremental = "<C-space>",
+            scope_incremental = false,
+            node_decremental = "<bs>",
+          },
+        },
+      })
+
+      -- enable nvim-ts-context-commentstring plugin for commenting tsx and jsx
+      require('ts_context_commentstring').setup {}
+    end,
+  },
+}
diff --git a/lua/josean/plugins/nvim-web-devicons.lua b/lua/josean/plugins/nvim-web-devicons.lua
@@ -0,0 +1,13 @@
+return {
+  "nvim-tree/nvim-web-devicons",
+  config = function()
+    require("nvim-web-devicons").set_icon({
+      gql = {
+        icon = "",
+        color = "#e535ab",
+        cterm_color = "199",
+        name = "GraphQL",
+      },
+    })
+  end,
+}
diff --git a/lua/josean/plugins/telescope.lua b/lua/josean/plugins/telescope.lua
@@ -0,0 +1,36 @@
+return {
+  "nvim-telescope/telescope.nvim",
+  branch = "0.1.x",
+  dependencies = {
+    "nvim-lua/plenary.nvim",
+    { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
+    "nvim-tree/nvim-web-devicons",
+  },
+  config = function()
+    local telescope = require("telescope")
+    local actions = require("telescope.actions")
+
+    telescope.setup({
+      defaults = {
+        path_display = { "truncate " },
+        mappings = {
+          i = {
+            ["<C-k>"] = actions.move_selection_previous, -- move to prev result
+            ["<C-j>"] = actions.move_selection_next, -- move to next result
+            ["<C-q>"] = actions.send_selected_to_qflist + actions.open_qflist,
+          },
+        },
+      },
+    })
+
+    telescope.load_extension("fzf")
+
+    -- set keymaps
+    local keymap = vim.keymap -- for conciseness
+
+    keymap.set("n", "<leader>ff", "<cmd>Telescope find_files<cr>", { desc = "Fuzzy find files in cwd" })
+    keymap.set("n", "<leader>fr", "<cmd>Telescope oldfiles<cr>", { desc = "Fuzzy find recent files" })
+    keymap.set("n", "<leader>fs", "<cmd>Telescope live_grep<cr>", { desc = "Find string in cwd" })
+    keymap.set("n", "<leader>fc", "<cmd>Telescope grep_string<cr>", { desc = "Find string under cursor in cwd" })
+  end,
+}
diff --git a/lua/josean/plugins/vim-maximizer.lua b/lua/josean/plugins/vim-maximizer.lua
@@ -0,0 +1,6 @@
+return {
+  "szw/vim-maximizer",
+  keys = {
+    { "<leader>sm", "<cmd>MaximizerToggle<CR>", desc = "Maximize/minimize a split" },
+  },
+}
diff --git a/lua/josean/plugins/which-key.lua b/lua/josean/plugins/which-key.lua
@@ -0,0 +1,13 @@
+return {
+  "folke/which-key.nvim",
+  event = "VeryLazy",
+  init = function()
+    vim.o.timeout = true
+    vim.o.timeoutlen = 500
+  end,
+  opts = {
+    -- your configuration comes here
+    -- or leave it empty to use the default settings
+    -- refer to the configuration section below
+  },
+}