diff --git a/README.md b/README.md
index e6afaa6..33e6725 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,14 @@
# Moshe Avni's DotFiles
-(also, how to bootstrap a brand new Mac laptop)
+
+
+
## Usage
-0. Install xcode-select (for basically everything...)
+### (also, how to bootstrap a brand new Mac laptop)
+
+0. Install xcode-select (for basically everything…)
```bash
xcode-select --install
@@ -15,8 +19,9 @@
```bash
/bin/bash -c \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
+ eval "$(/opt/homebrew/bin/brew shellenv)" # to make brew available before we load `~/.zshrc` that has "$PATH"
brew update
- brew install git
+ brew install git stow
```
2. Clone this repo:
@@ -26,71 +31,74 @@
cd ~ && git clone git@github.com:mosheavni/dotfiles.git .dotfiles && cd .dotfiles
```
-3. Install brew dependencies (generated with `brew bundle dump`)
-
- ```bash
- brew bundle
- ```
-
-4. Install [asdf-vm](https://asdf-vm.com/guide/getting-started.html) and its
- plugins
+3. Install [antidote](https://antidote.sh/)
```bash
- git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
+ git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-~}/.antidote
```
- > **_NOTE:_** Reload shell
+4. Stow the .dotfiles and reload the shell:
```bash
- while read -r plugin_line;do
- asdf plugin-add $(awk '{print $1}' <<<"$plugin_line")
- done < asdf/.tool-versions
- asdf install
+ ./start.sh
+ source ~/.zshrc
```
-5. Open [Wezterm](https://wezfurlong.org/wezterm/index.html) and start using a real terminal.
-
-6. Install [antidote](https://antidote.sh/)
+5. Install brew dependencies (generated with `brew bundle dump`)
```bash
- git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-~}/.antidote
+ brew bundle
```
-7. Run `./start.sh` to create the symlinks between the repo dir and the home dir:
+6. Open [Wezterm](https://wezfurlong.org/wezterm/index.html) and start using a real terminal.
-8. Install npm packages
+7. Install [asdf-vm](https://asdf-vm.com/guide/getting-started.html) plugins
```bash
- npm install -g $(printf "%s " $( Install requires Neovim 0.10+. Always review the code before installing a configuration.
+
+Clone the repository and install the plugins:
+
+```sh
+git clone git@github.com:mosheavni/dotfiles ~/.config/mosheavni/dotfiles
+```
+
+Open Neovim with this config:
+
+```sh
+NVIM_APPNAME=mosheavni/dotfiles/nvim/.config/nvim nvim
+```
## Additional stuff
@@ -98,10 +106,8 @@
- Download and install [docker](https://www.docker.com/products/docker-desktop)
-- Change clipy shortcuts, and load snippets
+- Change clipy and maccy shortcuts, and load snippets
- Install [magnet](https://apps.apple.com/us/app/magnet/id441258766?mt=12)
-- Install [Mac Media Key Forwarder](https://github.com/milgra/macmediakeyforwarder)
-
- Install Snagit
diff --git a/asdf/.tool-versions b/asdf/.tool-versions
index c4cf975..e40f577 100644
--- a/asdf/.tool-versions
+++ b/asdf/.tool-versions
@@ -5,12 +5,12 @@ golang 1.23.1
helm 3.14.4
java corretto-8.422.05.1
jq 1.6
-kubectl 1.30.10
+kubectl 1.31.7
kubectx 0.9.5
minikube 1.32.0
mysql 8.0.34
neovim nightly
-nodejs 20.10.0
+nodejs 20.17.0
python 3.11.8
semver 3.4.0
terraform 1.5.5
@@ -23,4 +23,4 @@ maven 3.6.3
lua 5.1.5
rust stable
vim 9.1.0958
-nodejs 20.10.0
+ripgrep 14.1.1
diff --git a/git/.gitconfig b/git/.gitconfig
index f20c40e..8802443 100644
--- a/git/.gitconfig
+++ b/git/.gitconfig
@@ -2,8 +2,101 @@
excludesfile = ~/.gitignore_global
pager = delta
editor = vim
+
[user]
- email = ofekn@netapp.com
- name = onacht
+ name = ofek nacht
+ email = ofek.nacht@flexera.com
+
+[checkout]
+ defaultRemote = origin
+
[pull]
- rebase = false
+ rebase = false
+
+[help]
+ autocorrect = 1
+
+[branch]
+ autosetupmerge = always
+
+[alias]
+ log = log --pretty=log
+ lb = log --graph --simplify-by-decoration --pretty=shorter --all --notes --date-order --relative-date
+ adog = log --all --decorate --oneline --graph
+
+[init]
+ defaultBranch = master
+
+[interactive]
+ diffFilter = delta --color-only
+
+[delta]
+ features = decorations arctic-fox
+ navigate = true # use n and N to move between diff sections
+ line-numbers = true
+ light = false # set to true if you're in a terminal w/ a light background color (e.g. the default macOS terminal)
+ side-by-side = true
+
+[delta "arctic-fox"]
+ dark = true
+ syntax-theme = Nord
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ file-style = omit
+ hunk-header-decoration-style = "#5E81AC" ul
+ hunk-header-file-style = blue ul bold
+ hunk-header-line-number-style = yellow box bold
+ hunk-header-style = file line-number syntax bold italic
+ plus-style = brightgreen
+ plus-emph-style = black green
+ minus-style = brightred
+ minus-emph-style = black red
+ line-numbers = true
+ line-numbers-minus-style = brightred
+ line-numbers-plus-style = brightgreen
+ line-numbers-left-style = "#5E81AC"
+ line-numbers-right-style = "#5E81AC"
+ line-numbers-zero-style = "#4C566A"
+ zero-style = syntax
+ whitespace-error-style = black bold
+ blame-code-style = syntax
+ blame-format = "{author:<18} {commit:<6} {timestamp:<15}"
+ blame-palette = "#2E3440" "#3B4252" "#434C5E"
+ merge-conflict-begin-symbol = ~
+ merge-conflict-end-symbol = ~
+ merge-conflict-ours-diff-header-style = yellow bold
+ merge-conflict-ours-diff-header-decoration-style = "#5E81AC" box
+ merge-conflict-theirs-diff-header-style = yellow bold
+ merge-conflict-theirs-diff-header-decoration-style = "#5E81AC" box
+
+[delta "interactive"]
+ keep-plus-minus-markers = false
+
+[delta "decorations"]
+ commit-decoration-style = blue ol
+ commit-style = raw
+ file-style = omit
+ hunk-header-decoration-style = blue box
+ hunk-header-file-style = red
+ hunk-header-line-number-style = "#067a00"
+ hunk-header-style = file line-number syntax
+
+[merge]
+ conflictstyle = diff3
+
+[diff]
+ colorMoved = default
+
+[color]
+ branch = true
+ decorate = true
+ diff = true
+ grep = true
+ interactive = true
+ pager = true
+ showbranch = true
+ status = true
+ ui = true
diff --git a/node/.default-npm-packages b/node/.default-npm-packages
index 09eaef0..7f0325b 100644
--- a/node/.default-npm-packages
+++ b/node/.default-npm-packages
@@ -3,5 +3,6 @@ eslint
eslint-config-react-app
neovim
npm
+quicktype
typescript
yarn
diff --git a/nvim/.config/nvim/Makefile b/nvim/.config/nvim/Makefile
new file mode 100644
index 0000000..24b345d
--- /dev/null
+++ b/nvim/.config/nvim/Makefile
@@ -0,0 +1,7 @@
+.PHONY: test prepare
+
+prepare:
+ git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ../plenary.nvim
+
+test:
+ nvim --headless --noplugin -u scripts/minimal_init.vim -c "PlenaryBustedDirectory lua/tests/ { minimal_init = './scripts/minimal_init.vim' }"
diff --git a/nvim/.config/nvim/ftplugin/fugitive.lua b/nvim/.config/nvim/after/ftplugin/fugitive.lua
similarity index 96%
rename from nvim/.config/nvim/ftplugin/fugitive.lua
rename to nvim/.config/nvim/after/ftplugin/fugitive.lua
index 49bad00..dbc8897 100644
--- a/nvim/.config/nvim/ftplugin/fugitive.lua
+++ b/nvim/.config/nvim/after/ftplugin/fugitive.lua
@@ -1,7 +1,7 @@
local git_funcs = require 'user.git'
vim.schedule(function()
- local buf = git_funcs.get_fugitive_buffer()
+ local buf = git_funcs.get_fugitive_buffer() or 0
vim.api.nvim_buf_set_keymap(buf, 'n', 't', '', {
noremap = true,
silent = true,
diff --git a/nvim/.config/nvim/ftplugin/fugitiveblame.lua b/nvim/.config/nvim/ftplugin/fugitiveblame.lua
index 17f508e..1bcba3d 100644
--- a/nvim/.config/nvim/ftplugin/fugitiveblame.lua
+++ b/nvim/.config/nvim/ftplugin/fugitiveblame.lua
@@ -41,9 +41,9 @@ vim.schedule(function()
local commit_hash = get_commit_hash()
vim.cmd 'wincmd p'
-- selene: allow(undefined_variable)
- Snacks.gitbrowse.open {
+ require('user.gitbrowse').open {
what = 'commit',
- branch = commit_hash,
+ commit = commit_hash,
}
end,
})
diff --git a/nvim/.config/nvim/ftplugin/k8s_containers.lua b/nvim/.config/nvim/ftplugin/k8s_containers.lua
index 7f3f3a0..85abbb2 100644
--- a/nvim/.config/nvim/ftplugin/k8s_containers.lua
+++ b/nvim/.config/nvim/ftplugin/k8s_containers.lua
@@ -1,5 +1,5 @@
local mappings = require 'kubectl.mappings'
-local pod_view = require 'kubectl.views.pods'
+local pod_view = require 'kubectl.resources.pods'
local tables = require 'kubectl.utils.tables'
vim.api.nvim_buf_set_keymap(0, 'n', '(kubectl.browse)', '', {
diff --git a/nvim/.config/nvim/ftplugin/k8s_fallback.lua b/nvim/.config/nvim/ftplugin/k8s_fallback.lua
deleted file mode 100644
index f0527e2..0000000
--- a/nvim/.config/nvim/ftplugin/k8s_fallback.lua
+++ /dev/null
@@ -1,29 +0,0 @@
-local commands = require 'kubectl.actions.commands'
-local tables = require 'kubectl.utils.tables'
-
-vim.schedule(function()
- vim.api.nvim_buf_set_keymap(0, 'n', '(kubectl.select)', '', {
- noremap = true,
- silent = true,
- desc = 'Go to application',
- callback = function()
- local _, buf_name = pcall(vim.api.nvim_buf_get_var, 0, 'buf_name')
- local lower_buf_name = string.lower(buf_name)
-
- if lower_buf_name == 'applications' or lower_buf_name == 'applications.argoproj.io' then
- local name = tables.getCurrentSelection(2)
- if not name then
- return
- end
- local ingress_host = commands.shell_command(
- 'kubectl',
- { 'get', 'ingress', '-n', 'argocd', '-l', 'app.kubernetes.io/component=server', '-o', 'jsonpath={.items[].spec.rules[].host}' }
- )
-
- local final_host = string.format('https://%s/applications/argocd/%s', ingress_host, name)
- vim.notify('Opening ' .. final_host)
- vim.ui.open(final_host)
- end
- end,
- })
-end)
diff --git a/nvim/.config/nvim/ftplugin/k8s_pods.lua b/nvim/.config/nvim/ftplugin/k8s_pods.lua
deleted file mode 100644
index bedda21..0000000
--- a/nvim/.config/nvim/ftplugin/k8s_pods.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-local ResourceBuilder = require 'kubectl.resourcebuilder'
-local commands = require 'kubectl.actions.commands'
-local pod_view = require 'kubectl.views.pods'
-
-vim.schedule(function()
- vim.api.nvim_buf_set_keymap(0, 'n', 'gk', '', {
- noremap = true,
- silent = true,
- desc = 'Kill prompt',
- callback = function()
- local name, ns = pod_view.getCurrentSelection()
- local builder = ResourceBuilder:new 'kubectl_drain'
- local pod_def = {
- ft = 'k8s_kill_pod',
- display = string.format('Kill pod: %s/%s?', ns, name),
- resource = ns .. '/' .. name,
- cmd = { 'delete', 'pod', name, '-n', ns },
- }
- local data = {
- { text = 'cascade:', value = 'background', options = { 'background', 'orphan', 'foreground' }, cmd = '--cascade', type = 'option' },
- { text = 'dry run:', value = 'none', options = { 'none', 'server', 'client' }, cmd = '--dry-run', type = 'option' },
- { text = 'grade period:', value = '-1', cmd = '--grace-period', type = 'option' },
- { text = 'timeout:', value = '0s', cmd = '--timeout', type = 'option' },
- { text = 'force:', value = 'false', options = { 'false', 'true' }, cmd = '--force', type = 'flag' },
- }
-
- builder:action_view(pod_def, data, function(args)
- commands.shell_command_async('kubectl', args)
- end)
- end,
- })
-end)
diff --git a/nvim/.config/nvim/ftplugin/ruby.lua b/nvim/.config/nvim/ftplugin/ruby.lua
new file mode 100644
index 0000000..eb9e1c6
--- /dev/null
+++ b/nvim/.config/nvim/ftplugin/ruby.lua
@@ -0,0 +1,53 @@
+local function sort_brewfile()
+ if vim.fn.expand '%:t' ~= 'Brewfile' then
+ return
+ end
+
+ local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
+ local taps = {}
+ local brews = {}
+ local casks = {}
+ local others = {}
+
+ for _, line in ipairs(lines) do
+ if line:match '^tap ' then
+ table.insert(taps, line)
+ elseif line:match '^brew ' then
+ table.insert(brews, line)
+ elseif line:match '^cask ' then
+ table.insert(casks, line)
+ else
+ table.insert(others, line)
+ end
+ end
+
+ table.sort(taps)
+ table.sort(brews)
+ table.sort(casks)
+
+ local sorted_lines = {}
+ for _, line in ipairs(taps) do
+ table.insert(sorted_lines, line)
+ end
+ for _, line in ipairs(brews) do
+ table.insert(sorted_lines, line)
+ end
+ for _, line in ipairs(casks) do
+ table.insert(sorted_lines, line)
+ end
+ for _, line in ipairs(others) do
+ table.insert(sorted_lines, line)
+ end
+
+ vim.api.nvim_buf_set_lines(0, 0, -1, false, sorted_lines)
+end
+
+if vim.fn.expand '%:t' == 'Brewfile' then
+ -- autocmd BufWritePre
+
+ vim.api.nvim_create_autocmd('BufWritePre', {
+ group = vim.api.nvim_create_augroup('SortBrewfile', { clear = true }),
+ pattern = 'Brewfile',
+ callback = sort_brewfile,
+ })
+end
diff --git a/nvim/.config/nvim/init.lua b/nvim/.config/nvim/init.lua
index 25332e4..a46e093 100644
--- a/nvim/.config/nvim/init.lua
+++ b/nvim/.config/nvim/init.lua
@@ -5,4 +5,3 @@ require 'user.options'
require 'user.keymaps'
require('lazy').setup('plugins', require('user.lazy').config)
require 'user.autocommands'
-require 'user.number-separators'
diff --git a/nvim/.config/nvim/lazy-lock.json b/nvim/.config/nvim/lazy-lock.json
index 70a0a54..d093003 100644
--- a/nvim/.config/nvim/lazy-lock.json
+++ b/nvim/.config/nvim/lazy-lock.json
@@ -1,116 +1,107 @@
{
- "2048.nvim": { "branch": "main", "commit": "aee7c41a9a9473117465132768ae4b4da97435c3" },
- "CopilotChat.nvim": { "branch": "main", "commit": "16d897fd43d07e3b54478ccdb2f8a16e4df4f45a" },
+ "CopilotChat.nvim": { "branch": "main", "commit": "44f37584bdd2d1b984e4ce64f5378a773ba0fa1e" },
"CursorLineCurrentWindow": { "branch": "master", "commit": "b4eeea98b0d139772969fd243a8802a9883fd2a8" },
- "LuaSnip": { "branch": "master", "commit": "faf3c94a44508cec1b961406d36cc65113ff3b98" },
- "SchemaStore.nvim": { "branch": "main", "commit": "0098dde21296a454ae1426f9ac47340dd38c27ce" },
- "auto-indent.nvim": { "branch": "main", "commit": "46801cf8857d42a20a73c40b0a5d3dfe8b2b6192" },
- "carbon-now.nvim": { "branch": "main", "commit": "f13c3c611a6aa22cca028bfe2cec63c7f67f2c87" },
- "cellular-automaton.nvim": { "branch": "main", "commit": "1606e9d5d04ff254023c3f3c62842d065708d6d3" },
+ "LuaSnip": { "branch": "master", "commit": "de10d8414235b0a8cabfeba60d07c24304e71f5c" },
+ "SchemaStore.nvim": { "branch": "main", "commit": "a28cc71857f11a7370d81f5ba3c1f5bb8383b732" },
+ "avante.nvim": { "branch": "main", "commit": "5e4eb8652b4776f139282a343f04a3a8c7f23cb0" },
+ "blink.download": { "branch": "main", "commit": "d95072328fb8293cc62c2574b0de2026e74d6f92" },
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
"cmp-calc": { "branch": "main", "commit": "5947b412da67306c5b68698a02a846760059be2e" },
"cmp-cmdline": { "branch": "main", "commit": "d126061b624e0af6c3a556428712dd4d4194ec6d" },
"cmp-dap": { "branch": "master", "commit": "ea92773e84c0ad3288c3bc5e452ac91559669087" },
- "cmp-git": { "branch": "main", "commit": "483ffb9a7471409a841df099d7c13556234365a4" },
- "cmp-nvim-lsp": { "branch": "main", "commit": "99290b3ec1322070bcfb9e846450a46f6efa50f0" },
+ "cmp-git": { "branch": "main", "commit": "b24309c386c9666c549a1abaedd4956541676d06" },
+ "cmp-nvim-lsp": { "branch": "main", "commit": "a8912b88ce488f411177fc8aed358b04dc246d7b" },
"cmp-nvim-lsp-signature-help": { "branch": "main", "commit": "031e6ba70b0ad5eee49fd2120ff7a2e325b17fa7" },
- "cmp-nvim-lua": { "branch": "main", "commit": "f12408bdb54c39c23e67cab726264c10db33ada8" },
- "cmp-path": { "branch": "main", "commit": "c6635aae33a50d6010bf1aa756ac2398a2d54c32" },
+ "cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
"cmp-tabnine": { "branch": "main", "commit": "c0167cdc86c15e782c5461ee62aebee89231c2ed" },
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
- "conform.nvim": { "branch": "master", "commit": "6feb2f28f9a9385e401857b21eeac3c1b66dd628" },
- "copilot.lua": { "branch": "master", "commit": "a620a5a97b73faba009a8160bab2885316e1451c" },
+ "conform.nvim": { "branch": "master", "commit": "973f3cb73887d510321653044791d7937c7ec0fa" },
+ "copilot.lua": { "branch": "master", "commit": "0f2fd3829dd27d682e46c244cf48d9715726f612" },
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
- "fidget.nvim": { "branch": "main", "commit": "d9ba6b7bfe29b3119a610892af67602641da778e" },
+ "fidget.nvim": { "branch": "main", "commit": "2cb5edb2dd6700a958a446b20bb2be04d318da9d" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
- "fzf-lua": { "branch": "main", "commit": "97f665a38d73a6541d98b542c79b4bead8e85d4c" },
+ "fzf-lua": { "branch": "main", "commit": "2f9e1af8cbff922543c2f259040d518517b8e294" },
"git-conflict.nvim": { "branch": "main", "commit": "4bbfdd92d547d2862a75b4e80afaf30e73f7bbb4" },
- "git-dev.nvim": { "branch": "master", "commit": "f8894349d04b2d922f2d170c5d66db729236d86f" },
- "gitsigns.nvim": { "branch": "main", "commit": "8b729e489f1475615dc6c9737da917b3bc163605" },
- "hardtime.nvim": { "branch": "main", "commit": "1a3648a53002c2911ccb88e9c9f876cdc6c43ad6" },
+ "gitsigns.nvim": { "branch": "main", "commit": "6e3c66548035e50db7bd8e360a29aec6620c3641" },
+ "go.nvim": { "branch": "master", "commit": "3279d15d146ab2eae6ad9bc930f3c8fc62a3697b" },
+ "guihua.lua": { "branch": "master", "commit": "87bea7b98429405caf2a0ce4d029b027bb017c70" },
"jsonpath.nvim": { "branch": "main", "commit": "2d889eb9c39893e030e902b854122a1615c042ea" },
- "kubectl.nvim": { "branch": "main", "commit": "47e8d739c5016809a16eb760a02812eddee9f763" },
+ "kubectl.nvim": { "branch": "main", "commit": "efce9ba09a76666e60cdd1d10b24aee664fedb7b" },
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
"lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" },
- "leap.nvim": { "branch": "main", "commit": "189102b07cdd24de3bd7132e57da8c9614c385fc" },
- "leetcode.nvim": { "branch": "master", "commit": "db7e1cd6b9191b34b4c1f2f96e4e3949cde9f951" },
+ "leap.nvim": { "branch": "main", "commit": "02bf52e49c72cc5dabb53ec9494d10d304f0b2c9" },
+ "leetcode.nvim": { "branch": "master", "commit": "422b6beb4a64eca0524fbff94edd9550c156afc5" },
"linediff.vim": { "branch": "main", "commit": "ddae71ef5f94775d101c1c70032ebe8799f32745" },
"lspkind-nvim": { "branch": "master", "commit": "d79a1c3299ad0ef94e255d045bed9fa26025dab6" },
- "lualine.nvim": { "branch": "master", "commit": "0c6cca9f2c63dadeb9225c45bc92bb95a151d4af" },
+ "lualine.nvim": { "branch": "master", "commit": "b8c23159c0161f4b89196f74ee3a6d02cdc3a955" },
"luvit-meta": { "branch": "main", "commit": "1df30b60b1b4aecfebc785aa98943db6c6989716" },
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
- "markview.nvim": { "branch": "main", "commit": "68c9603b6f88fd962444f8579024418fe5e170f1" },
- "mason-lspconfig.nvim": { "branch": "main", "commit": "d24b3f1612e53f9d54d866b16bedab51813f2bf1" },
+ "markview.nvim": { "branch": "main", "commit": "2d68c060ad4387d9895577af43c3ace41a80de5d" },
"mason-null-ls.nvim": { "branch": "main", "commit": "de19726de7260c68d94691afb057fa73d3cc53e7" },
- "mason-nvim-dap.nvim": { "branch": "main", "commit": "4c2cdc69d69fe00c15ae8648f7e954d99e5de3ea" },
- "mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" },
- "mini.ai": { "branch": "main", "commit": "b91997d220086e92edc1fec5ce82094dcc234291" },
- "mini.cursorword": { "branch": "main", "commit": "ab63cc74975f4e107dbb490f6d3040eacfc1c023" },
- "mini.hipatterns": { "branch": "main", "commit": "e5083df391171dc9d8172645606f8496d9443374" },
- "mini.indentscope": { "branch": "main", "commit": "8af2569a7d7fd37300dfa760e44e71efbbf322fd" },
- "mini.notify": { "branch": "main", "commit": "3a06b21dd0b335b95d125eae813276113b5e9ce7" },
- "mini.operators": { "branch": "main", "commit": "b79a95958c57e127704bbeb1dc11a511954fc888" },
- "mini.pairs": { "branch": "main", "commit": "69864a2efb36c030877421634487fd90db1e4298" },
- "mini.splitjoin": { "branch": "main", "commit": "70240d5d3881ff1b2b1d7902450f98a6fa303800" },
- "mini.surround": { "branch": "main", "commit": "5aab42fcdcf31fa010f012771eda5631c077840a" },
+ "mason-nvim-dap.nvim": { "branch": "main", "commit": "86389a3dd687cfaa647b6f44731e492970034baa" },
+ "mason.nvim": { "branch": "main", "commit": "7dc4facca9702f95353d5a1f87daf23d78e31c2a" },
+ "mcphub.nvim": { "branch": "main", "commit": "424e8c988e2e958da6f2182e40d52ee54bb18b8c" },
+ "mini.ai": { "branch": "main", "commit": "1cd4f021a05c29acd4ab511c0981da14217daf38" },
+ "mini.cursorword": { "branch": "main", "commit": "52834085b4ad175a050343cd96c4517def711cc5" },
+ "mini.hipatterns": { "branch": "main", "commit": "2b78f3d475d60ea1793a6d595ff65a0db9ac3a67" },
+ "mini.indentscope": { "branch": "main", "commit": "f1567c6f46c250b22f4ad1b847a042464742b11d" },
+ "mini.notify": { "branch": "main", "commit": "e18f9fc783c7a26fab9c8a094d97dc768e56f558" },
+ "mini.operators": { "branch": "main", "commit": "e72b5afec4c339aebd601a56e9ae3ef13d2f5d1a" },
+ "mini.pairs": { "branch": "main", "commit": "42407ccb80ec59c84e7c91d815f42ed90a8cc093" },
+ "mini.splitjoin": { "branch": "main", "commit": "51909e9883ab206f5a92deb9ca685317387586a4" },
+ "mini.surround": { "branch": "main", "commit": "7a8606333affe7ce637a0ba91bbafc46fc42bfa0" },
"nginx.vim": { "branch": "master", "commit": "cffaec54f0c7f9518de053634413a20e90eac825" },
"none-ls-shellcheck.nvim": { "branch": "main", "commit": "0f84461241e76e376a95fb7391deac82dc3efdbf" },
- "none-ls.nvim": { "branch": "main", "commit": "db2a48b79cfcdab8baa5d3f37f21c78b6705c62e" },
- "nui.nvim": { "branch": "main", "commit": "f535005e6ad1016383f24e39559833759453564e" },
- "nvim-bqf": { "branch": "main", "commit": "e20417d5e589e03eaaaadc4687904528500608be" },
+ "none-ls.nvim": { "branch": "main", "commit": "5fcb73913a9290f78097e34420fe0e6130c5c33c" },
+ "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
+ "nvim-autopairs": { "branch": "master", "commit": "23320e75953ac82e559c610bec5a90d9c6dfa743" },
+ "nvim-bqf": { "branch": "main", "commit": "17680cda3538913e88dd4c6456c837db9ace40ae" },
"nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" },
- "nvim-dap": { "branch": "master", "commit": "b0f983507e3702f073bfe1516846e58b56d4e42f" },
- "nvim-dap-go": { "branch": "main", "commit": "8763ced35b19c8dc526e04a70ab07c34e11ad064" },
+ "nvim-dap": { "branch": "master", "commit": "a479e25ed5b5d331fb46ee4b9e160ff02ac64310" },
"nvim-dap-python": { "branch": "master", "commit": "261ce649d05bc455a29f9636dc03f8cdaa7e0e2c" },
- "nvim-dap-ui": { "branch": "master", "commit": "73a26abf4941aa27da59820fd6b028ebcdbcf932" },
+ "nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" },
"nvim-dap-vscode-js": { "branch": "main", "commit": "03bd29672d7fab5e515fc8469b7d07cc5994bbf6" },
- "nvim-hlslens": { "branch": "main", "commit": "1e650c136f9f9d5fefe34947ad27c80010d3321f" },
- "nvim-lspconfig": { "branch": "master", "commit": "3ea99227e316c5028f57a4d86a1a7fd01dd876d0" },
- "nvim-lua-gf": { "branch": "main", "commit": "ca712497b2bab6351518917be219e9bfd8d63e4f" },
+ "nvim-hlslens": { "branch": "main", "commit": "95ced18ebaf19c1bdb64982a614ee8a9d7ee8e51" },
+ "nvim-lspconfig": { "branch": "master", "commit": "45ff1914044de7dbd4cd85053dc09f47312a2f4d" },
"nvim-luaref": { "branch": "main", "commit": "9cd3ed50d5752ffd56d88dd9e395ddd3dc2c7127" },
"nvim-navic": { "branch": "master", "commit": "f887d794a0f4594882814d7780980a949200a238" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-pqf": { "branch": "main", "commit": "148ee2ca8b06d83fd9bf6f9b9497724ad39a07d6" },
- "nvim-tree.lua": { "branch": "master", "commit": "ebcaccda1c575fa19a8087445276e6671e2b9b37" },
+ "nvim-tree.lua": { "branch": "master", "commit": "feb901a09e0a0caf4f98eb18b70404c898d1df1e" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
- "nvim-treesitter-context": { "branch": "master", "commit": "404502e607c3b309e405be9112c438c721153372" },
- "nvim-treesitter-textobjects": { "branch": "master", "commit": "0f051e9813a36481f48ca1f833897210dbcfffde" },
+ "nvim-treesitter-context": { "branch": "master", "commit": "dca8726fea2c14e1ce6adbaa76a04816fbfaff61" },
+ "nvim-treesitter-textobjects": { "branch": "master", "commit": "71385f191ec06ffc60e80e6b0c9a9d5daed4824c" },
"nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" },
- "nvim-ufo": { "branch": "main", "commit": "3c7a3570e9c9dc198a2ad4491b0b0e51c4d4ba08" },
- "nvim-web-devicons": { "branch": "master", "commit": "1fb58cca9aebbc4fd32b086cb413548ce132c127" },
- "oil.nvim": { "branch": "master", "commit": "685cdb4ffa74473d75a1b97451f8654ceeab0f4a" },
- "oklch-color-picker.nvim": { "branch": "master", "commit": "21975260558453158161c054bc9fd0191af609a6" },
- "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" },
+ "nvim-ufo": { "branch": "main", "commit": "80fe8215ba566df2fbf3bf4d25f59ff8f41bc0e1" },
+ "nvim-web-devicons": { "branch": "master", "commit": "c2599a81ecabaae07c49ff9b45dcd032a8d90f1a" },
+ "octo.nvim": { "branch": "master", "commit": "86192674d685cf9076d0228e50d281f840d2c889" },
+ "oil.nvim": { "branch": "master", "commit": "bbad9a76b2617ce1221d49619e4e4b659b3c61fc" },
+ "oklch-color-picker.nvim": { "branch": "master", "commit": "e4ea564534a7a80257ee7c2ddb9e60715e60c43c" },
+ "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" },
- "rose-pine": { "branch": "main", "commit": "6b9840790cc7acdfadde07f308d34b62dd9cc675" },
+ "rose-pine": { "branch": "main", "commit": "72befaffeac38db7bdd49e0549eaa2c4806dd878" },
+ "smart-splits.nvim": { "branch": "master", "commit": "52ee119752ee7e98a2a62f0f172926b5fbbc28a5" },
"snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" },
"sqlite.lua": { "branch": "master", "commit": "50092d60feb242602d7578398c6eb53b4a8ffe7b" },
- "statuscol.nvim": { "branch": "0.10", "commit": "b0de00dfcf583bdd94284d844aac1b134d47c578" },
- "switch.vim": { "branch": "main", "commit": "f4b831b86e1e65af8c4f8be6434e15bef98d111e" },
+ "statuscol.nvim": { "branch": "main", "commit": "c46172d0911aa5d49ba5f39f4351d1bb7aa289cc" },
+ "switch.vim": { "branch": "main", "commit": "4017a58f7ed8a2d76a288e36130affe8eb55e83a" },
"template-string.nvim": { "branch": "main", "commit": "da5f326b65fb74fd068aa1d8b55461b64c8fb23b" },
- "term-edit.nvim": { "branch": "master", "commit": "b190a91178ef98beefac2ec0823db047978ea327" },
- "treemonkey.nvim": { "branch": "main", "commit": "1fe117cc25b283c33209136e8d48cea078939d6d" },
- "treesitter-terraform-doc.nvim": { "branch": "main", "commit": "130e0e47d4d436e9efefb786613f83c4498ec309" },
- "trouble.nvim": { "branch": "main", "commit": "85bedb7eb7fa331a2ccbecb9202d8abba64d37b3" },
+ "treemonkey.nvim": { "branch": "main", "commit": "b13e9024f51c8a12ce2196fb49ceb793338ed66e" },
+ "treesitter-terraform-doc.nvim": { "branch": "main", "commit": "e959c1f19f12642da05587443523dc09cf7991a8" },
"ts-comments.nvim": { "branch": "main", "commit": "1bd9d0ba1d8b336c3db50692ffd0955fe1bb9f0c" },
- "twilight.nvim": { "branch": "main", "commit": "1584c0b0a979b71fd86b18d302ba84e9aba85b1b" },
- "vim-bufsurf": { "branch": "master", "commit": "e6dbc7ad66c7e436e5eb20d304464e378bd7f28c" },
- "vim-dadbod": { "branch": "master", "commit": "e95afed23712f969f83b4857a24cf9d59114c2e6" },
- "vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" },
- "vim-dadbod-ui": { "branch": "master", "commit": "460432301a5cb280ea265ddfa15c9f3dcd1d26b7" },
+ "typr": { "branch": "main", "commit": "bdd9ef7143702851edd1dac85101e0a537056d2f" },
+ "vim-dadbod": { "branch": "master", "commit": "9f0ca8bcef704659820a95c3bbd2c262583a66a1" },
"vim-dirdiff": { "branch": "master", "commit": "84bc8999fde4b3c2d8b228b560278ab30c7ea4c9" },
"vim-easy-align": { "branch": "master", "commit": "9815a55dbcd817784458df7a18acacc6f82b1241" },
- "vim-fugitive": { "branch": "master", "commit": "4a745ea72fa93bb15dd077109afbb3d1809383f2" },
- "vim-kubernetes": { "branch": "master", "commit": "f477818c30efe4914e9a047ba1105b524d78e1b5" },
+ "vim-fugitive": { "branch": "master", "commit": "61b51c09b7c9ce04e821f6cf76ea4f6f903e3cf4" },
"vim-lister": { "branch": "master", "commit": "ec903e615f867f910cd8adc73f5906d521f3f214" },
- "vim-matchup": { "branch": "master", "commit": "56c714495ec7f40cf2c7e92fb124067c7951e650" },
- "vim-sh-indent": { "branch": "master", "commit": "982fbbc34f9c66af1f6b58b643d0f4ef32b7d8c8" },
+ "vim-matchup": { "branch": "master", "commit": "b4efd6a97380b99bb9f5eb80c9002e061402c288" },
"vim-startuptime": { "branch": "master", "commit": "b6f0d93f6b8cf6eee0b4c94450198ba2d6a05ff6" },
"vim-swap": { "branch": "master", "commit": "9358bfdc5e377aa13e7c2c2dd8699ba32b0dcf83" },
- "wezterm-types": { "branch": "main", "commit": "1518752906ba3fac0060d9efab6e4d3ec15d4b5a" },
- "winresizer": { "branch": "master", "commit": "9bd559a03ccec98a458e60c705547119eb5350f3" },
- "yaml-companion.nvim": { "branch": "main", "commit": "70321546727e4f04e86075a54afe8e6ef40286dc" },
- "yaml.nvim": { "branch": "main", "commit": "20ee341ecb17dfa9110437490e903b51f5295225" },
+ "volt": { "branch": "main", "commit": "7b8c5e790120d9f08c8487dcb80692db6d2087a1" },
+ "wezterm-types": { "branch": "main", "commit": "f2f0d0f6e60ddeb34b70b3f1312b922d4a04bbad" },
+ "yaml-companion.nvim": { "branch": "main", "commit": "eecef97d2d825576cc1a830e9ec939e9218357e1" },
+ "yaml.nvim": { "branch": "main", "commit": "09bbf7d936606d97f2c1d2e51171a602bc76b65e" },
"yanky.nvim": { "branch": "main", "commit": "04775cc6e10ef038c397c407bc17f00a2f52b378" }
}
diff --git a/nvim/.config/nvim/lua/core/init.lua b/nvim/.config/nvim/lua/core/init.lua
index c361817..12e4c3a 100644
--- a/nvim/.config/nvim/lua/core/init.lua
+++ b/nvim/.config/nvim/lua/core/init.lua
@@ -15,65 +15,58 @@ function _G.P(v, r)
if r then
print(vim.inspect(v))
else
- vim.notify(vim.inspect(v), 2, {
+ vim.notify(vim.inspect(v), vim.log.levels.WARN, {
title = 'P debug',
icon = '✎',
})
end
return v
end
+
local original_vim_print = vim.print
+---@diagnostic disable-next-line: duplicate-set-field
vim.print = function(...)
local str = type(...) == 'table' and vim.inspect(...) or ...
original_vim_print(str)
end
--- Write a temporary file, optionally delete on exit, set filetype and open in a
--- new buffer
--- @param should_delete boolean whether to delete the file on exit
--- @param ft string filetype to set
--- @params new boolean whether to open in a new buffer
--- @params vertical boolean whether to open in a vertical split (only if new is true)
--- @returns nil
+---Write a temporary file with specified options
+---@param opts? {should_delete?: boolean, ft?: string, new?: boolean, vertical?: boolean}
+---@return string tmp The path to the temporary file
function _G.tmp_write(opts)
- local defaults = {
+ opts = opts or {}
+ local final_opts = vim.tbl_deep_extend('force', {
should_delete = true,
ft = nil,
new = true,
vertical = false,
- }
- local final_opts = vim.tbl_extend('force', defaults, opts)
- local should_delete = final_opts.should_delete
- local ft = final_opts.ft
- local new = final_opts.new
- local vertical = final_opts.vertical
+ }, opts)
+
local tmp = vim.fn.tempname()
- if new then
- if vertical then
- vim.cmd 'vnew'
- else
- vim.cmd 'new'
- end
+
+ if final_opts.new then
+ vim.cmd(final_opts.vertical and 'vnew' or 'new')
end
- if ft then
- local extension = require('user.utils').filetype_to_extension[ft] or ft
- vim.api.nvim_set_option_value('filetype', ft, { buf = 0 })
+ if final_opts.ft then
+ local extension = require('user.utils').filetype_to_extension[final_opts.ft] or final_opts.ft
+ vim.bo.filetype = final_opts.ft
tmp = tmp .. '.' .. extension
end
- vim.cmd(string.format('write %s', tmp))
+
+ vim.cmd('write ' .. vim.fn.fnameescape(tmp))
vim.cmd 'edit'
- -- Create autocmd to delete the file on exit
- if should_delete then
- vim.api.nvim_create_autocmd({ 'VimLeavePre' }, {
+ if final_opts.should_delete then
+ vim.api.nvim_create_autocmd('VimLeavePre', {
buffer = 0,
- command = 'delete("' .. tmp .. '")',
+ callback = function()
+ vim.fn.delete(tmp)
+ end,
})
end
return tmp
end
--- leader key - before mapping lsp maps
vim.g.mapleader = ' '
vim.g.maplocalleader = ' '
diff --git a/nvim/.config/nvim/lua/core/lazy-bootstrap.lua b/nvim/.config/nvim/lua/core/lazy-bootstrap.lua
index 9ab1a67..f2b6792 100644
--- a/nvim/.config/nvim/lua/core/lazy-bootstrap.lua
+++ b/nvim/.config/nvim/lua/core/lazy-bootstrap.lua
@@ -1,5 +1,5 @@
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
-if not vim.loop.fs_stat(lazypath) then
+if not vim.uv.fs_stat(lazypath) then
vim
.system({
'git',
diff --git a/nvim/.config/nvim/lua/plugins/ai.lua b/nvim/.config/nvim/lua/plugins/ai.lua
new file mode 100644
index 0000000..ffe9776
--- /dev/null
+++ b/nvim/.config/nvim/lua/plugins/ai.lua
@@ -0,0 +1,181 @@
+local model = 'gpt-5'
+return {
+ {
+ 'zbirenbaum/copilot.lua',
+ event = { 'InsertEnter' },
+ config = function()
+ require('copilot').setup {
+ copilot_node_command = 'node',
+ filetypes = { ['*'] = true },
+ panel = {
+ enabled = true,
+ auto_refresh = false,
+ keymap = {
+ jump_prev = '[[',
+ jump_next = ']]',
+ accept = '',
+ refresh = 'gr',
+ open = '',
+ },
+ },
+ suggestion = {
+ auto_trigger = true,
+ keymap = {
+ accept = '',
+ },
+ },
+ }
+ end,
+ },
+ {
+ 'ravitemer/mcphub.nvim',
+ cmd = { 'MCPHub' },
+ dependencies = {
+ 'nvim-lua/plenary.nvim',
+ },
+ build = 'npm install -g mcp-hub@latest', -- Installs `mcp-hub` node binary globally
+ opts = {
+ extensions = {
+ avante = {
+ make_slash_commands = true, -- make /slash commands from MCP server prompts
+ },
+ copilotchat = {
+ enabled = true,
+ convert_tools_to_functions = true, -- Convert MCP tools to CopilotChat functions
+ convert_resources_to_functions = true, -- Convert MCP resources to CopilotChat functions
+ add_mcp_prefix = true, -- Add "mcp_" prefix to function names
+ },
+ },
+ },
+ },
+ {
+ 'CopilotC-Nvim/CopilotChat.nvim',
+ enabled = true,
+ cmd = {
+ 'CopilotChat',
+ 'CopilotChatAgents',
+ 'CopilotChatClose',
+ 'CopilotChatCommit',
+ 'CopilotChatCommitStaged',
+ 'CopilotChatDebugInfo',
+ 'CopilotChatDocs',
+ 'CopilotChatExplain',
+ 'CopilotChatFix',
+ 'CopilotChatFixDiagnostic',
+ 'CopilotChatLoad',
+ 'CopilotChatModels',
+ 'CopilotChatOpen',
+ 'CopilotChatOptimize',
+ 'CopilotChatReset',
+ 'CopilotChatReview',
+ 'CopilotChatSave',
+ 'CopilotChatStop',
+ 'CopilotChatTests',
+ 'CopilotChatToggle',
+ },
+ dependencies = {
+ 'zbirenbaum/copilot.lua',
+ 'nvim-lua/plenary.nvim',
+ 'ravitemer/mcphub.nvim',
+ },
+ build = 'make tiktoken',
+ opts = {
+ -- https://docs.github.com/en/copilot/using-github-copilot/ai-models/choosing-the-right-ai-model-for-your-task
+ model = model,
+ question_header = ' User ',
+ answer_header = ' Copilot ',
+ error_header = ' Error ',
+ },
+ keys = {
+ { 'ccc', 'CopilotChat', mode = { 'n', 'v' } },
+ { 'ccs', 'CopilotChatStop' },
+ {
+ 'ccp',
+ function()
+ local actions = require 'CopilotChat.actions'
+ require('CopilotChat.integrations.fzflua').pick(actions.prompt_actions())
+ end,
+ desc = 'CopilotChat - Prompt actions',
+ mode = { 'n', 'v' },
+ },
+ },
+ },
+ {
+ 'yetone/avante.nvim',
+ enabled = false,
+ version = false, -- Never set this value to "*"! Never!
+ keys = {
+ { 'ccc', 'AvanteChat', mode = { 'n', 'v' } },
+ { 'ccs', 'AvanteStop' },
+ },
+ cmd = { 'AvanteChat' },
+ opts = {
+ disabled_tools = {
+ 'list_files', -- Built-in file operations
+ 'search_files',
+ 'read_file',
+ 'create_file',
+ 'rename_file',
+ 'delete_file',
+ 'create_dir',
+ 'rename_dir',
+ 'delete_dir',
+ 'bash', -- Built-in terminal access
+ },
+ provider = 'copilot',
+ providers = {
+ copilot = {
+ -- model = 'gpt-4.1',
+ model = model,
+ },
+ },
+
+ -- mcphub
+ -- system_prompt as function ensures LLM always has latest MCP server state
+ -- This is evaluated for every message, even in existing chats
+ system_prompt = function()
+ local hub = require('mcphub').get_hub_instance()
+ return hub and hub:get_active_servers_prompt() or ''
+ end,
+ -- Using function prevents requiring mcphub before it's loaded
+ custom_tools = function()
+ return {
+ require('mcphub.extensions.avante').mcp_tool(),
+ }
+ end,
+ },
+ -- if you want to build from source then do `make BUILD_FROM_SOURCE=true`
+ build = 'make',
+ -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows
+ dependencies = {
+ 'nvim-treesitter/nvim-treesitter',
+ 'nvim-lua/plenary.nvim',
+ 'MunifTanjim/nui.nvim',
+ {
+ -- support for image pasting
+ 'HakonHarnes/img-clip.nvim',
+ event = 'VeryLazy',
+ opts = {
+ -- recommended settings
+ default = {
+ embed_image_as_base64 = false,
+ prompt_for_file_name = false,
+ drag_and_drop = {
+ insert_mode = true,
+ },
+ -- required for Windows users
+ use_absolute_path = true,
+ },
+ },
+ },
+ -- {
+ -- -- Make sure to set this up properly if you have lazy=true
+ -- 'MeanderingProgrammer/render-markdown.nvim',
+ -- opts = {
+ -- file_types = { 'markdown', 'Avante' },
+ -- },
+ -- ft = { 'markdown', 'Avante' },
+ -- },
+ },
+ },
+}
diff --git a/nvim/.config/nvim/lua/plugins/cmpconf.lua b/nvim/.config/nvim/lua/plugins/cmpconf.lua
index 4034e42..4dc75b8 100644
--- a/nvim/.config/nvim/lua/plugins/cmpconf.lua
+++ b/nvim/.config/nvim/lua/plugins/cmpconf.lua
@@ -2,11 +2,10 @@
local M = {
'hrsh7th/nvim-cmp',
version = false, -- last release is way too old
- enabled = true,
event = { 'InsertEnter', 'CmdlineEnter' },
dependencies = {
'rafamadriz/friendly-snippets',
- { 'L3MON4D3/LuaSnip', build = 'make install_jsregexp' },
+ { 'L3MON4D3/LuaSnip', build = 'make install_jsregexp' },
'saadparwaiz1/cmp_luasnip',
'onsails/lspkind-nvim',
{ 'tzachar/cmp-tabnine', build = './install.sh' },
@@ -14,38 +13,9 @@ local M = {
'hrsh7th/cmp-calc',
'hrsh7th/cmp-cmdline',
'hrsh7th/cmp-nvim-lsp',
- 'hrsh7th/cmp-nvim-lua',
'hrsh7th/cmp-path',
'petertriho/cmp-git',
'hrsh7th/cmp-nvim-lsp-signature-help',
- {
- 'zbirenbaum/copilot.lua',
- config = function()
- vim.schedule(function()
- require('copilot').setup {
- copilot_node_command = '/usr/local/bin/node',
- filetypes = { ['*'] = true },
- panel = {
- enabled = true,
- auto_refresh = false,
- keymap = {
- jump_prev = '[[',
- jump_next = ']]',
- accept = '',
- refresh = 'gr',
- open = '',
- },
- },
- suggestion = {
- auto_trigger = true,
- keymap = {
- accept = '',
- },
- },
- }
- end)
- end,
- },
},
}
@@ -67,7 +37,6 @@ M.config = function()
git = '[Git]',
luasnip = '[Snpt]',
nvim_lsp = '[LSP]',
- nvim_lua = '[Vim]',
path = '[Path]',
calc = '[Calc]',
['vim-dadbod-completion'] = '[DB]',
@@ -80,6 +49,13 @@ M.config = function()
local custom_kinds_hl = {}
vim.api.nvim_set_hl(0, 'CmpItemKindTabNine', { link = 'Green' })
cmp.setup {
+ enabled = function()
+ local ft = vim.api.nvim_get_option_value('filetype', { buf = 0 })
+ if string.find(ft, 'k8s_') then
+ return false
+ end
+ return true
+ end,
native_menu = false,
view = {
entries = {
@@ -180,17 +156,16 @@ M.config = function()
},
},
sources = cmp.config.sources {
- { name = 'nvim_lsp', priority = 100 },
+ { name = 'nvim_lsp_signature_help', priority = 101 },
+ { name = 'nvim_lsp', priority = 100 },
{ name = 'luasnip' },
- { name = 'nvim_lua' },
{
name = 'lazydev',
group_index = 0, -- set group index to 0 to skip loading LuaLS completions
},
- { name = 'nvim_lsp_signature_help' },
{ name = 'cmp_tabnine' },
{ name = 'path' },
- { name = 'buffer', keyword_length = 4 },
+ { name = 'buffer', keyword_length = 4 },
{ name = 'calc' },
},
snippet = {
@@ -204,7 +179,7 @@ M.config = function()
},
}
- cmp.setup.filetype('gitcommit', {
+ cmp.setup.filetype({ 'gitcommit', 'octo' }, {
sources = cmp.config.sources({
{ name = 'git' },
}, {
@@ -249,6 +224,9 @@ M.config = function()
}),
})
+ local cmp_autopairs = require 'nvim-autopairs.completion.cmp'
+ cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done())
+
require('luasnip.loaders.from_vscode').lazy_load()
require('luasnip.loaders.from_vscode').lazy_load { paths = '~/.config/nvim/snippets' }
end
diff --git a/nvim/.config/nvim/lua/plugins/conform.lua b/nvim/.config/nvim/lua/plugins/conform.lua
index 7a05141..df6c1ac 100644
--- a/nvim/.config/nvim/lua/plugins/conform.lua
+++ b/nvim/.config/nvim/lua/plugins/conform.lua
@@ -58,6 +58,7 @@ return {
vim.ui.select(vim.list_extend(lsp_fmts, conform_fmts), {
prompt = 'Select LSP client',
+ title = 'LSP clients',
format_item = function(client)
return client.name
end,
@@ -88,7 +89,7 @@ return {
---@module "conform"
---@type conform.setupOpts
opts = {
- log_level = vim.log.levels.DEBUG,
+ log_level = vim.log.levels.INFO,
formatters_by_ft = {
Jenkinsfile = { 'npm-groovy-lint' },
astro = { 'prettierd' },
@@ -106,7 +107,13 @@ return {
less = { 'prettierd' },
lua = { 'stylua' },
markdown = { 'cbfmt', 'injected', 'markdownlint' },
- python = { 'isort', 'black' },
+ python = function(bufnr)
+ if require('conform').get_formatter_info('ruff_format', bufnr).available then
+ return { 'ruff_format' }
+ else
+ return { 'isort', 'black' }
+ end
+ end,
scss = { 'prettierd' },
sh = { 'shfmt' },
svelte = { 'prettierd' },
@@ -131,6 +138,6 @@ return {
formatters = {},
},
init = function()
- vim.o.formatexpr = "v:lua.require'conform'.formatexpr()"
+ vim.o.formatexpr = "v:lua.require'conform'.formatexpr({timeout_ms=5000})"
end,
}
diff --git a/nvim/.config/nvim/lua/plugins/dap.lua b/nvim/.config/nvim/lua/plugins/dap.lua
index 5264095..6ea2fbd 100644
--- a/nvim/.config/nvim/lua/plugins/dap.lua
+++ b/nvim/.config/nvim/lua/plugins/dap.lua
@@ -5,16 +5,19 @@ local actions = function()
['continue (F5)'] = function()
dap.continue()
end,
- ['step over'] = function()
+ ['step over (do)'] = function()
dap.step_over()
end,
- ['step into'] = function()
+ ['step into (di)'] = function()
dap.step_into()
end,
- ['step out'] = function()
+ ['step out (dO)'] = function()
dap.step_out()
end,
- ['toggle breakpoint'] = function()
+ ['terminate (dq)'] = function()
+ dap.terminate()
+ end,
+ ['toggle breakpoint (db)'] = function()
dap.toggle_breakpoint()
end,
['clear all breakpoints'] = function()
@@ -26,7 +29,7 @@ local actions = function()
['run last'] = function()
dap.run_last()
end,
- ['ui'] = function()
+ ['ui (du)'] = function()
dapui.toggle()
end,
['log level trace'] = function()
@@ -58,20 +61,40 @@ local M = {
'mxsdev/nvim-dap-vscode-js',
'theHamsta/nvim-dap-virtual-text',
'jay-babu/mason-nvim-dap.nvim',
- { 'leoluz/nvim-dap-go', lazy = true },
},
}
M.keys = {
{ '', 'lua require("dap").continue()' },
- { 'bp', 'lua require("dap").toggle_breakpoint()' },
+ { 'db', 'lua require("dap").toggle_breakpoint()' },
}
M.config = function()
+ local dap = require 'dap'
+ local dapui = require 'dapui'
+ local dap_python = require 'dap-python'
local cmp = require 'cmp'
local mason_nvim_dap = require 'mason-nvim-dap'
+
+ dapui.setup()
+ dap.listeners.after.event_initialized['dapui_config'] = function()
+ dapui.open {}
+ end
+ dap.listeners.before.event_terminated['dapui_config'] = function()
+ dapui.close {}
+ end
+ dap.listeners.before.event_exited['dapui_config'] = function()
+ dapui.close {}
+ end
+
+ ---@diagnostic disable-next-line: missing-fields
+ require('nvim-dap-virtual-text').setup {
+ commented = true, -- Show virtual text alongside comment
+ }
+
---@diagnostic disable-next-line: missing-fields
mason_nvim_dap.setup {
+ automatic_installation = true,
ensure_installed = {
'bash',
'chrome',
@@ -84,56 +107,56 @@ M.config = function()
-- all sources with no handler get passed here
-- Keep original functionality
- require('mason-nvim-dap').default_setup(config)
+ mason_nvim_dap.default_setup(config)
end,
},
}
- -- mason_nvim_dap.setup_handlers()
- local dap = require 'dap'
- local dapui = require 'dapui'
- dapui.setup()
- require('nvim-dap-virtual-text').setup { enabled = true }
+ dap_python.setup 'python3'
+ dap.adapters.bashdb = {
+ type = 'executable',
+ command = vim.fn.stdpath 'data' .. '/mason/packages/bash-debug-adapter/bash-debug-adapter',
+ name = 'bashdb',
+ }
+ local dap_conf_sh = {
+ {
+ type = 'bashdb',
+ request = 'launch',
+ name = 'Launch file',
+ showDebugOutput = true,
+ pathBashdb = vim.fn.stdpath 'data' .. '/mason/packages/bash-debug-adapter/extension/bashdb_dir/bashdb',
+ pathBashdbLib = vim.fn.stdpath 'data' .. '/mason/packages/bash-debug-adapter/extension/bashdb_dir',
+ trace = true,
+ file = '${file}',
+ program = '${file}',
+ cwd = '${workspaceFolder}',
+ pathCat = 'cat',
+ pathBash = '/opt/homebrew/bin/bash',
+ pathMkfifo = 'mkfifo',
+ pathPkill = 'pkill',
+ args = {},
+ env = {},
+ terminalKind = 'integrated',
+ },
+ }
+ dap.configurations.sh = dap_conf_sh
+ dap.configurations.bash = dap_conf_sh
- vim.fn.sign_define('DapBreakpoint', { text = '🛑', texthl = '', linehl = '', numhl = '' })
- vim.fn.sign_define('DapBreakpointRejected', { text = '❓', texthl = '', linehl = '', numhl = '' })
- vim.fn.sign_define('DapStopped', { text = '⭕️', texthl = '', linehl = '', numhl = '' })
+ vim.fn.sign_define('DapBreakpoint', { text = '', texthl = 'DiagnosticSignError', linehl = '', numhl = '' })
+ vim.fn.sign_define('DapBreakpointRejected', { text = '', texthl = 'DiagnosticSignError', linehl = '', numhl = '' })
+ vim.fn.sign_define('DapStopped', { text = '', texthl = 'DiagnosticSignWarn', linehl = 'Visual', numhl = 'DiagnosticSignWarn' })
-- Actions
local the_actions = actions()
require('user.menu').add_actions('DAP', the_actions)
vim.keymap.set('n', 'dm', function()
- vim.ui.select(vim.tbl_keys(the_actions), { prompt = 'Choose DAP action' }, function(choice)
+ vim.ui.select(vim.tbl_keys(the_actions), { prompt = 'Choose DAP action', title = 'DAP Actions' }, function(choice)
if choice then
the_actions[choice]()
end
end)
end)
- -- Python
- require('dap-python').setup(vim.fn.stdpath 'data' .. '/mason/packages/debugpy/venv/bin/python3')
-
- table.insert(dap.configurations.python, {
- justMyCode = false,
- })
-
- -- lua
- dap.configurations.lua = {
- {
- type = 'nlua',
- request = 'attach',
- name = 'Attach to running Neovim instance',
- },
- }
-
- dap.adapters.nlua = function(callback, config)
- ---@diagnostic disable-next-line: undefined-field
- callback { type = 'server', host = config.host or '127.0.0.1', port = config.port or 8086 }
- end
-
- -- go
- require('dap-go').setup()
-
-------------
-- Set CMP --
-------------
@@ -143,12 +166,48 @@ M.config = function()
{ name = 'dap' },
},
})
+
---@diagnostic disable-next-line: missing-fields
cmp.setup {
enabled = function()
return vim.api.nvim_get_option_value('buftype', { buf = 0 }) ~= 'prompt' or require('cmp_dap').is_dap_buffer()
end,
}
+
+ -------------
+ -- keymaps --
+ -------------
+ local opts = { noremap = true, silent = true, buffer = true }
+
+ -- Continue / Start
+ vim.keymap.set('n', 'dc', function()
+ dap.continue()
+ end, opts)
+
+ -- Step Over
+ vim.keymap.set('n', 'do', function()
+ dap.step_over()
+ end, opts)
+
+ -- Step Into
+ vim.keymap.set('n', 'di', function()
+ dap.step_into()
+ end, opts)
+
+ -- Step Out
+ vim.keymap.set('n', 'dO', function()
+ dap.step_out()
+ end, opts)
+
+ -- Keymap to terminate debugging
+ vim.keymap.set('n', 'dq', function()
+ dap.terminate()
+ end, opts)
+
+ -- Toggle DAP UI
+ vim.keymap.set('n', 'du', function()
+ dapui.toggle()
+ end, opts)
end
return M
diff --git a/nvim/.config/nvim/lua/plugins/databases.lua b/nvim/.config/nvim/lua/plugins/databases.lua
index 2e4fce3..2271f4d 100644
--- a/nvim/.config/nvim/lua/plugins/databases.lua
+++ b/nvim/.config/nvim/lua/plugins/databases.lua
@@ -1,6 +1,7 @@
local M = {
{
'tpope/vim-dadbod',
+ enabled = false,
cmd = {
'DB',
'DBUI',
@@ -14,6 +15,31 @@ local M = {
'DBCompletionClearCache',
},
init = function()
+ vim.g.db_ui_use_nerd_fonts = 1
+ local sql_helpers = {
+ Count = 'SELECT COUNT(*) FROM `{table}`;',
+ List = 'SELECT * FROM `{table}` LIMIT 10;',
+ Indexes = 'SHOW INDEXES FROM `{table}`;',
+ ForeignKeys = 'SHOW CREATE TABLE `{table}`;',
+ PrimaryKeys = 'SHOW KEYS FROM `{table}` WHERE Key_name = "PRIMARY";',
+ }
+ vim.g.db_ui_table_helpers = {
+ sqlite = sql_helpers,
+ mysql = sql_helpers,
+ mongodb = {
+ Count = 'db.{table}.countDocuments({});',
+ List = 'db.{table}.find().limit(10).toArray();',
+ Indexes = 'db.{table}.getIndexes();',
+ Collections = 'db.getCollectionNames();',
+ DatabaseInfo = 'db.stats();',
+ },
+ redis = {
+ Keys = 'KEYS *;',
+ List = 'LRANGE {table} 0 10;', -- Assuming you're using a list type
+ Hash = 'HGETALL {table};', -- Assuming you're using a hash type
+ DatabaseInfo = 'INFO;',
+ },
+ }
require('user.menu').add_actions('Database', {
['Add Connection'] = function()
vim.cmd 'DBUIAddConnection'
@@ -39,18 +65,8 @@ local M = {
})
end,
dependencies = {
- {
- 'kristijanhusak/vim-dadbod-ui',
- config = function()
- vim.g.db_ui_table_helpers = {
- sqlite = {
- Schema = '.schema "{table}"',
- Count = 'SELECT COUNT(*) FROM "{table}"',
- },
- }
- end,
- },
- 'kristijanhusak/vim-dadbod-completion',
+ { 'kristijanhusak/vim-dadbod-ui' },
+ { 'kristijanhusak/vim-dadbod-completion', ft = { 'sql', 'mysql', 'plsql' }, lazy = true },
},
},
}
diff --git a/nvim/.config/nvim/lua/plugins/functionality.lua b/nvim/.config/nvim/lua/plugins/functionality.lua
index c20d7c5..51d3740 100644
--- a/nvim/.config/nvim/lua/plugins/functionality.lua
+++ b/nvim/.config/nvim/lua/plugins/functionality.lua
@@ -12,83 +12,37 @@ local M = {
end,
},
{
- 'mosheavni/vim-kubernetes',
- ft = 'yaml',
- config = function()
- require('user.menu').add_actions('Kubernetes', {
- ['Apply (:KubeApply)'] = function()
- vim.cmd [[KubeApply]]
- end,
- ['Apply Directory (:KubeApplyDir)'] = function()
- vim.cmd [[KubeApplyDir]]
- end,
- ['Create (:KubeCreate)'] = function()
- vim.cmd [[KubeCreate]]
- end,
- ['Decode Secret (:KubeDecodeSecret)'] = function()
- vim.cmd [[KubeDecodeSecret]]
- end,
- ['Delete (:KubeDelete)'] = function()
- vim.cmd [[KubeDelete]]
- end,
- ['Delete Dir (:KubeDeleteDir)'] = function()
- vim.cmd [[KubeDeleteDir]]
- end,
- ['Encode Secret (:KubeEncodeSecret)'] = function()
- vim.cmd [[KubeEncodeSecret]]
- end,
- ['Recreate (:KubeRecreate)'] = function()
- vim.cmd [[KubeRecreate]]
- end,
- })
- end,
- },
- {
- 'chomosuke/term-edit.nvim',
- event = 'TermOpen',
- opts = {
- prompt_end = '%$ ',
- },
- version = '1.*',
- },
- {
- 'mosheavni/vim-dirdiff',
+ 'mosheavni/vim-dirdiff', -- todo convert to difftool
cmd = { 'DirDiff' },
init = function()
require('user.menu').add_actions('Diff', {
['Between 2 directories'] = function()
local pretty_print = require('user.utils').pretty_print
- vim.ui.input({ prompt = 'Directory A: ' }, function(a)
- if not a or a == '' then
- pretty_print 'Canceled.'
- return
- end
- vim.ui.input({ prompt = 'Directory B: ' }, function(b)
- if not b or b == '' then
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Directory A: ' }, function(a)
+ if not a or a == '' then
pretty_print 'Canceled.'
return
end
- vim.cmd('DirDiff ' .. a .. ' ' .. b)
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Directory B: ' }, function(b)
+ if not b or b == '' then
+ pretty_print 'Canceled.'
+ return
+ end
+ vim.cmd('DirDiff ' .. a .. ' ' .. b)
+ end)
+ end, 100)
end)
- end)
+ end, 100)
end,
})
end,
},
{
- 'simeji/winresizer',
- keys = { '' },
- config = function()
- vim.g.winresizer_vert_resize = 4
- vim.g.winresizer_start_key = ''
- end,
- init = function()
- require('user.menu').add_actions(nil, {
- ['Resize window ()'] = function()
- vim.fn.feedkeys(vim.keycode '')
- end,
- })
- end,
+ 'windwp/nvim-autopairs',
+ event = 'InsertEnter',
+ opts = {},
},
{
'iamcco/markdown-preview.nvim',
@@ -107,27 +61,64 @@ local M = {
end,
},
{
- 'AndrewRadev/linediff.vim',
- cmd = { 'Linediff' },
- },
- {
- 'ellisonleao/carbon-now.nvim',
- cmd = 'CarbonNow',
- opts = { open_cmd = 'open' },
+ 'gbprod/yanky.nvim',
+ dependencies = { 'kkharji/sqlite.lua' },
+ cmd = { 'YankyRingHistory' },
+ keys = {
+ 'yy',
+ { 'p', '(YankyPutAfter)', mode = { 'n', 'x' } },
+ { 'P', '(YankyPutBefore)', mode = { 'n', 'x' } },
+ { '', '(YankyCycleForward)' },
+ { '', '(YankyCycleBackward)' },
+ { 'y', 'YankyRingHistory' },
+ },
+ opts = {
+ ring = {
+ history_length = 100,
+ storage = 'sqlite',
+ sync_with_numbered_registers = true,
+ cancel_event = 'update',
+ },
+ },
init = function()
- require('user.menu').add_actions('Carbon', {
- ['Create a beautiful image of the code'] = function()
- vim.cmd.CarbonNow()
+ require('user.menu').add_actions('Yanky', {
+ ['Yank history'] = function()
+ vim.cmd 'YankyRingHistory'
end,
})
end,
},
+ {
+ 'AndrewRadev/linediff.vim',
+ cmd = { 'Linediff' },
+ },
{
'stevearc/oil.nvim',
cmd = { 'Oil' },
- ---@module 'oil'
- ---@type oil.SetupOpts
- opts = {},
+ keys = {
+ { '', "lua require('oil').open_float()" },
+ },
+ opts = {
+ -- Configuration for the floating window in oil.open_float
+ float = {
+ -- optionally override the oil buffers window title with custom function: fun(winid: integer): string
+ get_win_title = nil,
+ -- preview_split: Split direction: "auto", "left", "right", "above", "below".
+ -- max_width and max_height can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
+ max_width = 0.6,
+ max_height = 0.7,
+ preview_split = 'right',
+ -- This is the config that will be passed to nvim_open_win.
+ -- Change values here to customize the layout
+ override = function(conf)
+ return conf
+ end,
+ },
+ view_options = {
+ -- Show files and directories that start with "."
+ show_hidden = true,
+ },
+ },
},
{
'kawre/leetcode.nvim',
@@ -159,6 +150,27 @@ local M = {
},
},
},
+ {
+ 'mrjones2014/smart-splits.nvim',
+ config = function()
+ require('smart-splits').setup()
+ vim.keymap.set('n', '', require('smart-splits').resize_left)
+ vim.keymap.set('n', '', require('smart-splits').resize_down)
+ vim.keymap.set('n', '', require('smart-splits').resize_up)
+ vim.keymap.set('n', '', require('smart-splits').resize_right)
+ -- moving between splits
+ vim.keymap.set('n', '', require('smart-splits').move_cursor_left)
+ vim.keymap.set('n', '', require('smart-splits').move_cursor_down)
+ vim.keymap.set('n', '', require('smart-splits').move_cursor_up)
+ vim.keymap.set('n', '', require('smart-splits').move_cursor_right)
+ end,
+ },
+ {
+ 'nvzone/typr',
+ dependencies = 'nvzone/volt',
+ opts = {},
+ cmd = { 'Typr', 'TyprStats' },
+ },
}
return M
diff --git a/nvim/.config/nvim/lua/plugins/fzf.lua b/nvim/.config/nvim/lua/plugins/fzf.lua
index 442d504..111c8ad 100644
--- a/nvim/.config/nvim/lua/plugins/fzf.lua
+++ b/nvim/.config/nvim/lua/plugins/fzf.lua
@@ -9,13 +9,11 @@ return {
{ 'hh', ':FzfLua help_tags', silent = true },
{ 'i', ':FzfLua oldfiles', silent = true },
{
- 'ccp',
- function()
- local actions = require 'CopilotChat.actions'
- require('CopilotChat.integrations.fzflua').pick(actions.prompt_actions())
- end,
- desc = 'CopilotChat - Prompt actions',
- mode = { 'n', 'v' },
+ '',
+ require('fzf-lua').complete_path,
+ mode = 'i',
+ silent = true,
+ desc = 'Fuzzy complete path',
},
{
'',
@@ -25,30 +23,25 @@ return {
require('fzf-lua').git_branches {
actions = {
- ['default'] = function(selected)
- actions.git_switch(selected)
- require('user.git').reload_fugitive_index()
- end,
+ ['default'] = {
+ fn = function(selected, opts)
+ actions.git_switch(selected, opts)
+ require('user.git').reload_fugitive_index()
+ end,
+ header = 'switch',
+ },
-- perform checkout instead of switch
['ctrl-s'] = {
fn = function(selected)
- local branch = selected[1]
- local _, ret, stderr = require('user.utils').get_os_command_output({ 'git', 'checkout', branch }, vim.fn.getcwd())
- require('user.git').reload_fugitive_index()
- if ret == 0 then
- utils.info('Switched to branch ' .. branch)
- return
- else
- local msg = string.format('Error when switching to branch: %s. Git returned:\n%s', branch, table.concat(stderr or {}, '\n'))
- utils.err(msg)
- end
+ local branch = vim.trim(selected[1])
+ require('user.git').checkout(branch)
end,
reload = false,
- header = 'switch',
+ header = 'checkout',
},
['ctrl-y'] = {
fn = function(selected)
- local branch = selected[1]
+ local branch = vim.trim(selected[1])
vim.fn.setreg('+', branch)
utils.info('Yanked branch name ' .. branch)
end,
@@ -58,9 +51,9 @@ return {
['ctrl-r'] = {
fn = function(selected)
require('fzf-lua.utils').fzf_exit()
- local branch = selected[1]
+ local branch = vim.trim(selected[1])
vim.defer_fn(function()
- vim.ui.input({ prompt = 'Rename branch: ', default = selected[1] }, function(new_name)
+ vim.ui.input({ prompt = 'Rename branch: ', default = branch }, function(new_name)
if not new_name or new_name == '' then
utils.warn 'Action aborted'
return
@@ -83,8 +76,8 @@ return {
},
['ctrl-x'] = {
fn = function(selected)
- local branch = selected[1]
- vim.ui.select({ 'Yes', 'No' }, { prompt = 'Are you sure you want to delete the branch ' .. branch }, function(yes_or_no)
+ local branch = vim.trim(selected[1])
+ vim.ui.select({ 'Yes', 'No' }, { prompt = 'Are you sure you want to delete the branch ' .. branch .. '?' }, function(yes_or_no)
if yes_or_no == 'No' then
utils.warn 'Action aborted'
return
@@ -121,38 +114,33 @@ return {
header = 'delete',
},
},
- cmd = [=[git for-each-ref --sort=-committerdate --format="%(refname:short)" | grep -n . | sed "s?origin/??g" | sort -t: -k2 -u | sort -n | cut -d: -f2]=],
+ cmd = 'git-branches.zsh',
}
end,
},
{
'/',
- function()
- require('fzf-lua').live_grep {
- multiprocess = true,
- rg_opts = [=[--column --line-number --hidden --no-heading --color=always --smart-case --max-columns=4096 -g '!.git' -e]=],
- }
- end,
+ require('fzf-lua').live_grep,
},
},
cmd = { 'FzfLua', 'ListFilesFromBranch' },
config = function()
require('fzf-lua').setup {
'default-title',
- previewers = {
- builtin = {
- syntax_limit_b = 1024 * 100, -- 100KB
- extensions = {
- png = { 'viu', '-b' },
- jpg = { 'viu', '-b' },
- },
- },
+ fzf_opts = {
+ ['--cycle'] = true,
+ ['--history'] = vim.fn.stdpath 'data' .. '/fzf-lua-history', -- - next, - previous
+ },
+ files = {
+ git_icons = true,
},
oldfiles = {
cwd_only = true,
include_current_session = true,
},
grep = {
+ multiprocess = true,
+ RIPGREP_CONFIG_PATH = vim.env.HOME .. '/.ripgreprc',
-- One thing I missed from Telescope was the ability to live_grep and the
-- run a filter on the filenames.
-- Ex: Find all occurrences of "enable" but only in the "plugins" directory.
@@ -162,10 +150,12 @@ return {
rg_glob = true, -- enable glob parsing
glob_flag = '--iglob', -- case insensitive globs
glob_separator = '%s%-%-', -- query separator pattern (lua): ' --'
+ hidden = true,
},
keymap = { fzf = { ['ctrl-q'] = 'select-all+accept' } },
}
- require('fzf-lua').register_ui_select(function(_, items)
+
+ require('fzf-lua').register_ui_select(function(opts, items)
local min_h, max_h = 0.15, 0.70
local h = (#items + 4) / vim.o.lines
if h < min_h then
@@ -173,7 +163,9 @@ return {
elseif h > max_h then
h = max_h
end
- return { winopts = { height = h, width = 0.60, row = 0.40 } }
+ opts.title = opts.title or 'Select'
+
+ return { winopts = { title = opts.title, height = h, width = 0.60, row = 0.40 } }
end)
end,
}
diff --git a/nvim/.config/nvim/lua/plugins/git.lua b/nvim/.config/nvim/lua/plugins/git.lua
index 7a352ca..7a43020 100644
--- a/nvim/.config/nvim/lua/plugins/git.lua
+++ b/nvim/.config/nvim/lua/plugins/git.lua
@@ -9,7 +9,9 @@ local actions = function()
end,
['Create Pull Request (pr in git buffer)'] = git_funcs.create_pull_request,
['Checkout new branch (:Gcb {new_branch})'] = function()
- git_funcs.create_new_branch { args = '' }
+ vim.defer_fn(function()
+ git_funcs.create_new_branch { args = '' }
+ end, 100)
end,
['Set upstream to HEAD'] = git_funcs.set_upstream_head,
['Blame'] = function()
@@ -50,14 +52,16 @@ local actions = function()
['Delete tag'] = git_funcs.ui_select_delete_tag,
['Find in all commits'] = function()
local rev_list = vim.fn.FugitiveExecute({ 'rev-list', '--all' }).stdout
- vim.ui.input({ prompt = 'Enter search term: ' }, function(search_term)
- if not search_term then
- git_funcs.prnt 'Canceled.'
- return
- end
- git_funcs.prnt('Searching for ' .. search_term .. ' in all commits...')
- vim.cmd('silent Ggrep ' .. vim.fn.fnameescape(search_term) .. ' ' .. table.concat(rev_list, ' '))
- end)
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Enter search term: ' }, function(search_term)
+ if not search_term then
+ git_funcs.prnt 'Canceled.'
+ return
+ end
+ git_funcs.prnt('Searching for ' .. search_term .. ' in all commits...')
+ vim.cmd('silent Ggrep ' .. vim.fn.fnameescape(search_term) .. ' ' .. table.concat(rev_list, ' '))
+ end)
+ end, 100)
end,
['Push (:Gp)'] = git_funcs.push,
['Pull (:Gl)'] = git_funcs.pull,
@@ -72,9 +76,14 @@ end
local diff_actions = {
['[Diffview] Diff File History'] = function()
- vim.ui.input({ prompt = 'Enter file path (empty for all files, % for current): ' }, function(file_to_check)
- vim.cmd('DiffviewFileHistory ' .. file_to_check)
- end)
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Enter file path (empty for all files, % for current): ' }, function(file_to_check)
+ if not file_to_check then
+ return
+ end
+ vim.cmd('DiffviewFileHistory ' .. file_to_check)
+ end)
+ end, 100)
end,
['[Diffview] Diff with branch'] = function()
git_funcs.ui_select_remotes(function(remote)
@@ -86,6 +95,9 @@ local diff_actions = {
['[Diffview] Diff close'] = function()
vim.cmd 'DiffviewClose'
end,
+ ['[Diffview] stashes'] = function()
+ vim.cmd 'DiffviewFileHistory -g --range=stash'
+ end,
}
local fugitive_config = function()
@@ -103,17 +115,22 @@ local fugitive_config = function()
-- Toggle fugitive --
---------------------
vim.keymap.set('n', 'gg', function()
- local _, fugitive_buf = pcall(vim.fn.bufname, '.git/')
- if fugitive_buf == '' then
- vim.cmd 'Git'
- else
- local bufnr = vim.fn.bufnr(fugitive_buf)
- if vim.bo[bufnr].buflisted then
- vim.cmd('bd ' .. fugitive_buf)
- else
- vim.cmd 'Git'
+ local to_close = {}
+ for _, win in ipairs(vim.api.nvim_list_wins()) do
+ local buf = vim.api.nvim_win_get_buf(win)
+ if vim.bo[buf].filetype == 'fugitive' then
+ to_close[#to_close + 1] = win
end
end
+ if #to_close > 0 then
+ for _, win in ipairs(to_close) do
+ if vim.api.nvim_win_is_valid(win) then
+ pcall(vim.api.nvim_win_close, win, true)
+ end
+ end
+ return
+ end
+ vim.cmd 'Git'
end)
--------------------------------
@@ -183,7 +200,7 @@ local fugitive_config = function()
vim.keymap.set('n', 'gm', function()
local git_actions = require('user.menu').get_actions { prefix = 'Git' }
- vim.ui.select(vim.tbl_keys(git_actions), { prompt = 'Choose git action: ' }, function(choice)
+ vim.ui.select(vim.tbl_keys(git_actions), { title = 'Git actions', prompt = 'Choose git action: ' }, function(choice)
if not choice then
utils.pretty_print('Canceled.', 'Git Actions', '')
return
@@ -220,42 +237,6 @@ local M = {
'Cpr',
},
},
- {
- 'moyiz/git-dev.nvim',
- opts = {
- ephemeral = false,
- read_only = false,
- opener = function(dir)
- vim.cmd('NvimTreeOpen ' .. vim.fn.fnameescape(dir))
- end,
- },
- keys = {
- {
- 'go',
- function()
- local repo = vim.fn.input 'Repository name / URI: '
- if repo ~= '' then
- require('git-dev').open(repo)
- end
- end,
- desc = '[O]pen a remote git repository',
- },
- },
- config = function(_, opts)
- require('user.menu').add_actions('Git', {
- ['Open a remote git repository (go)'] = function()
- vim.ui.input({ prompt = 'Enter git repository URL: ' }, function(url)
- if not url then
- return
- end
- require('git-dev').open(url)
- end)
- end,
- })
- require('git-dev').setup(opts)
- end,
- },
-
{
'akinsho/git-conflict.nvim',
version = '*',
@@ -304,8 +285,18 @@ local M = {
},
keys = {
-- { 'gd', 'DiffviewFileHistory', mode = { 'n', 'v' }, desc = 'Diffview files' },
- { 'gd', diff_actions['[Diffview] Diff File History'], mode = 'n', desc = 'Diffview files' },
- { 'gd', ':DiffviewFileHistory', mode = 'v', desc = 'Diffview selection' },
+ {
+ 'gd',
+ diff_actions['[Diffview] Diff File History'],
+ mode = 'n',
+ desc = 'Diffview files',
+ },
+ {
+ 'gd',
+ ':DiffviewFileHistory',
+ mode = 'v',
+ desc = 'Diffview selection',
+ },
},
config = function()
require 'diffview'
diff --git a/nvim/.config/nvim/lua/plugins/hlslens.lua b/nvim/.config/nvim/lua/plugins/hlslens.lua
deleted file mode 100644
index 21193ea..0000000
--- a/nvim/.config/nvim/lua/plugins/hlslens.lua
+++ /dev/null
@@ -1,13 +0,0 @@
-return {
- 'kevinhwang91/nvim-hlslens',
- keys = {
- { 'n', [[execute('normal! ' . v:count1 . 'n')lua require('hlslens').start()zz]] },
- { 'N', [[execute('normal! ' . v:count1 . 'N')lua require('hlslens').start()zz]] },
- { '*', [[*lua require('hlslens').start()]] },
- { '#', [[#lua require('hlslens').start()]] },
- { 'g*', [[g*lua require('hlslens').start()]] },
- { 'g#', [[g#lua require('hlslens').start()]] },
- },
- event = 'CmdlineEnter',
- opts = {},
-}
diff --git a/nvim/.config/nvim/lua/plugins/init.lua b/nvim/.config/nvim/lua/plugins/init.lua
index c35cac6..a6f545e 100644
--- a/nvim/.config/nvim/lua/plugins/init.lua
+++ b/nvim/.config/nvim/lua/plugins/init.lua
@@ -1,46 +1,26 @@
+---@class PluginSpec[]
+--- Plugin specifications for Lazy.nvim plugin manager
+--- This file contains the core plugin configurations for Neovim
local M = {
- ------------------------------------
- -- Language Server Protocol (LSP) --
- ------------------------------------
{
- 'folke/trouble.nvim',
- opts = {},
- cmd = 'Trouble',
- },
- {
- 'sam4llis/nvim-lua-gf',
- ft = 'lua',
- },
- {
- 'NStefan002/2048.nvim',
- cmd = 'Play2048',
- config = true,
+ 'nvim-lua/plenary.nvim',
+ cmd = {
+ 'PlenaryBustedFile',
+ 'PlenaryBustedDirectory',
+ },
+ keys = {
+ { 'tf', 'PlenaryBustedFile %', mode = 'n' },
+ },
},
{
'milisims/nvim-luaref',
ft = 'lua',
},
+ { 'Bilal2453/luvit-meta', lazy = true },
{
'chr4/nginx.vim',
ft = 'nginx',
},
- {
- 'ton/vim-bufsurf',
- event = { 'BufReadPre', 'BufNewFile' },
- keys = {
- { ']b', '(buf-surf-forward)' },
- { '[b', '(buf-surf-back)' },
- },
- },
- {
- 'chrisbra/vim-sh-indent',
- ft = { 'sh', 'bash', 'zsh' },
- },
- { 'Bilal2453/luvit-meta', lazy = true },
-
- --------------
- -- Quickfix --
- --------------
{
'yorickpeterse/nvim-pqf',
opts = {},
@@ -56,10 +36,6 @@ local M = {
'kevinhwang91/nvim-bqf',
ft = 'qf',
},
-
- -----------------------
- -- Text Manipulation --
- -----------------------
{
'junegunn/vim-easy-align',
keys = { { 'ga', '(EasyAlign)', mode = { 'v', 'n' } } },
@@ -85,7 +61,7 @@ local M = {
vim.fn['switch#NormalizedCase'] { 'enable', 'disable' },
vim.fn['switch#NormalizedCase'] { 'Always', 'Never' },
vim.fn['switch#NormalizedCase'] { 'debug', 'info', 'warning', 'error', 'critical' },
- { '==', '!=' },
+ { '==', '!=', '~=' },
{
[fk] = [=[\=toupper(submatch(1)) . submatch(2)]=],
[sk] = [=[\=tolower(substitute(submatch(0), '\(\l\)\(\u\)', '\1_\2', 'g'))]=],
@@ -141,23 +117,6 @@ local M = {
{ 'S', '(leap-backward-to)' },
},
},
- {
- 'atusy/treemonkey.nvim',
- keys = {
- {
- 'm',
- function()
- require 'nvim-treesitter.configs'
- ---@diagnostic disable-next-line: missing-fields
- require('treemonkey').select {
- ignore_injections = false,
- action = require('treemonkey.actions').unite_selection,
- }
- end,
- mode = { 'x', 'o' },
- },
- },
- },
{
'axelvc/template-string.nvim',
ft = { 'typescript', 'javascript', 'typescriptreact', 'javascriptreact', 'python' },
@@ -165,60 +124,26 @@ local M = {
config = true,
},
{
- 'machakann/vim-swap',
+ 'kevinhwang91/nvim-hlslens',
keys = {
- { 'sw', '(swap-interactive)', mode = { 'n', 'v' } },
- { 'g<', '(swap-prev)' },
- { 'g>', '(swap-next)' },
+ { 'n', [[execute('normal! ' . v:count1 . 'n')lua require('hlslens').start()zzzv]] },
+ { 'N', [[execute('normal! ' . v:count1 . 'N')lua require('hlslens').start()zzzv]] },
+ { '*', [[*lua require('hlslens').start()N]] },
+ { '#', [[#lua require('hlslens').start()n]] },
+ { 'g*', [[g*lua require('hlslens').start()]] },
+ { 'g#', [[g#lua require('hlslens').start()]] },
},
- init = function()
- vim.g.swap_no_default_key_mappings = true
- end,
- },
- {
- 'vidocqh/auto-indent.nvim',
- event = 'InsertEnter',
+ event = 'CmdlineEnter',
opts = {},
},
{
- 'CopilotC-Nvim/CopilotChat.nvim',
- cmd = {
- 'CopilotChat',
- 'CopilotChatAgents',
- 'CopilotChatClose',
- 'CopilotChatCommit',
- 'CopilotChatCommitStaged',
- 'CopilotChatDebugInfo',
- 'CopilotChatDocs',
- 'CopilotChatExplain',
- 'CopilotChatFix',
- 'CopilotChatFixDiagnostic',
- 'CopilotChatLoad',
- 'CopilotChatModels',
- 'CopilotChatOpen',
- 'CopilotChatOptimize',
- 'CopilotChatReset',
- 'CopilotChatReview',
- 'CopilotChatSave',
- 'CopilotChatStop',
- 'CopilotChatTests',
- 'CopilotChatToggle',
- },
- dependencies = {
- { 'zbirenbaum/copilot.lua' }, -- or github/copilot.vim
- { 'nvim-lua/plenary.nvim' }, -- for curl, log wrapper
- },
- build = 'make tiktoken', -- Only on MacOS or Linux
- opts = {
- model = 'claude-3.5-sonnet',
- question_header = ' User ', -- Header to use for user questions
- answer_header = ' Copilot ', -- Header to use for AI answers
- error_header = ' Error ', -- Header to use for errors
- },
+ 'machakann/vim-swap',
keys = {
- { 'ccc', 'CopilotChat', mode = { 'n', 'v' } },
- { 'ccs', 'CopilotChatStop' },
+ { 'sw', '(swap-interactive)', mode = { 'n', 'v' } },
},
+ init = function()
+ vim.g.swap_no_default_key_mappings = true
+ end,
},
-- DONE ✅
diff --git a/nvim/.config/nvim/lua/plugins/kubectl.lua b/nvim/.config/nvim/lua/plugins/kubectl.lua
index e026a25..03439e5 100644
--- a/nvim/.config/nvim/lua/plugins/kubectl.lua
+++ b/nvim/.config/nvim/lua/plugins/kubectl.lua
@@ -1,16 +1,25 @@
return {
'Ramilito/kubectl.nvim',
+ version = '2.*',
+ dependencies = 'saghen/blink.download',
+ dev = false,
opts = {
- log_level = vim.log.levels.DEBUG,
- diff = { bin = 'kdiff' },
- headers = true,
- hints = true,
- context = true,
- heartbeat = true,
- kubernetes_versions = true,
+ kubectl_cmd = {
+ persist_context_change = true,
+ },
auto_refresh = {
enabled = true,
+ interval = 300, -- milliseconds
+ },
+
+ headers = {
+ enabled = true,
+ hints = true,
+ context = true,
+ heartbeat = true,
},
+ -- log_level = vim.log.levels.DEBUG,
+ diff = { bin = 'kdiff' },
filter = {
apply_on_select_from_history = false,
max_history = 100,
@@ -20,20 +29,24 @@ return {
timestamps = false,
prefix = false,
},
- lineage = {
- enabled = false,
- },
- completion = {
- follow_cursor = false,
+ alias = {
+ apply_on_select_from_history = true,
+ max_history = 30,
},
+ -- lineage = {
+ -- enabled = false,
+ -- },
+ -- completion = {
+ -- follow_cursor = false,
+ -- },
},
cmd = { 'Kubectl', 'Kubectx', 'Kubens' },
keys = {
{ 'k', 'lua require("kubectl").toggle()' },
- { '', '(kubectl.kill)', ft = 'k8s_*' },
- { '7', '(kubectl.view_nodes)', ft = 'k8s_*' },
- { '8', '(kubectl.view_overview)', ft = 'k8s_*' },
- { '', '(kubectl.view_top)', ft = 'k8s_*' },
+ { '7', '(kubectl.view_nodes)', ft = 'k8s_*' },
+ { '8', '(kubectl.view_daemonsets)', ft = 'k8s_*' },
+ { '9', '(kubectl.view_statefulsets)', ft = 'k8s_*' },
+ { '', '(kubectl.view_top)', ft = 'k8s_*' },
{
'Z',
function()
@@ -47,6 +60,7 @@ return {
state.setFilter(faults_filter)
end,
desc = 'Toggle faults',
+ ft = 'k8s_*',
},
},
init = function()
@@ -56,6 +70,31 @@ return {
pattern = 'k8s_*',
callback = function()
vim.opt.titlestring = 'k8s: %t'
+ if vim.bo.filetype == 'k8s_yaml' then
+ vim.bo.filetype = 'yaml'
+ end
+ end,
+ })
+ vim.api.nvim_create_autocmd('User', {
+ group = group,
+ pattern = 'K8sContextChanged',
+ callback = function(ctx)
+ vim.system({ 'kubectl', 'config', 'use-context', ctx.data.context }, { text = true }, function(results)
+ if not results then
+ vim.notify(results, vim.log.levels.INFO)
+ end
+ end)
+ end,
+ })
+ vim.api.nvim_create_autocmd('User', {
+ group = group,
+ pattern = 'K8sResourceSelected',
+ callback = function(ctx)
+ local kubectl_user = require 'user.kubectl'
+ local kind = ctx.data.kind
+ if kubectl_user[kind] and kubectl_user[kind].select then
+ kubectl_user[kind].select(ctx.data.name, ctx.data.ns)
+ end
end,
})
end,
diff --git a/nvim/.config/nvim/lua/plugins/look-and-feel.lua b/nvim/.config/nvim/lua/plugins/look-and-feel.lua
index 995676a..9d53180 100644
--- a/nvim/.config/nvim/lua/plugins/look-and-feel.lua
+++ b/nvim/.config/nvim/lua/plugins/look-and-feel.lua
@@ -6,77 +6,26 @@ local M = {
-------------------
-- Colorscheme --
-------------------
- {
- 'navarasu/onedark.nvim',
- enabled = false,
- config = function()
- require('onedark').setup {
- style = 'dark',
- highlights = {
- EndOfBuffer = { fg = '#61afef' },
- },
- }
- require('onedark').load()
- end,
- },
{
'rose-pine/neovim',
name = 'rose-pine',
opts = {
+ variant = 'moon', -- auto, main, moon, dawn
styles = {
bold = true,
italic = true,
transparency = true,
},
+ highlight_groups = {
+ StatusLine = { fg = 'love', bg = 'love', blend = 10 },
+ StatusLineNC = { fg = 'subtle', bg = 'surface' },
+ },
},
config = function(_, opts)
require('rose-pine').setup(opts)
vim.cmd [[colorscheme rose-pine]]
end,
},
- {
- 'sainnhe/sonokai',
- enabled = false,
- config = function()
- vim.cmd [[
- let g:sonokai_style = 'shusia'
- let g:sonokai_transparent_background = 1
- colorscheme sonokai
- ]]
- vim.api.nvim_set_hl(0, 'WinSeparator', { fg = '#797D7D' })
- require('user.menu').add_actions('Colorscheme', {
- ['Toggle Sonokai Style'] = function()
- local styles = { 'default', 'atlantis', 'andromeda', 'shusia', 'maia', 'espresso' }
- local current_value = vim.g.sonokai_style
- local index = require('user.utils').tbl_get_next(styles, current_value)
- vim.g.sonokai_style = styles[index]
- vim.cmd [[colorscheme sonokai]]
- require('user.utils').pretty_print('Set sonokai_style to ' .. styles[index])
- end,
- })
- end,
- },
- {
- 'sainnhe/gruvbox-material',
- enabled = false,
- config = function()
- -- load the colorscheme here
- vim.cmd [[
- let g:gruvbox_material_better_performance = 1
- let g:gruvbox_material_background = 'hard' " soft | medium | hard
- colorscheme gruvbox-material
- ]]
- end,
- },
- {
- 'tiagovla/tokyodark.nvim',
- enabled = false,
- opts = {},
- config = function(_, opts)
- require('tokyodark').setup(opts) -- calling setup is optional
- vim.cmd [[colorscheme tokyodark]]
- end,
- },
-----------
-- other --
@@ -84,6 +33,15 @@ local M = {
{
'nvim-tree/nvim-web-devicons',
lazy = true,
+ opts = {
+ override_by_extension = {
+ hcl = {
+ icon = '',
+ color = '#7182D0',
+ name = 'HCL',
+ },
+ },
+ },
},
{
'eero-lehtinen/oklch-color-picker.nvim',
@@ -93,13 +51,7 @@ local M = {
},
},
keys = {
- { 'p', 'lua require("oklch-color-picker").pick_under_cursor()' },
- },
- },
- {
- 'eandrju/cellular-automaton.nvim',
- keys = {
- { 'fml', 'CellularAutomaton make_it_rain' },
+ { 'pc', 'lua require("oklch-color-picker").pick_under_cursor()' },
},
},
{
@@ -113,14 +65,8 @@ local M = {
})
end,
},
- {
- 'folke/twilight.nvim',
- cmd = { 'Twilight', 'TwilightEnable', 'TwilightDisable' },
- opts = {},
- },
{
'luukvbaal/statuscol.nvim',
- branch = '0.10',
event = { 'BufReadPre', 'BufNewFile' },
config = function()
local builtin = require 'statuscol.builtin'
@@ -138,14 +84,45 @@ local M = {
}
end,
},
+ {
+ 'kevinhwang91/nvim-ufo',
+ dependencies = { 'kevinhwang91/promise-async' },
+ event = 'BufReadPost',
+ keys = {
+ { 'fo', 'lua require("ufo").openAllFolds()' },
+ { 'fc', 'lua require("ufo").closeAllFolds()' },
+ { 'fp', 'lua require("ufo").peekFoldedLinesUnderCursor()' },
+ },
+ opts = {
+ open_fold_hl_timeout = 0,
+ },
+
+ init = function()
+ ---@diagnostic disable-next-line: inject-field
+ vim.o.foldcolumn = '1' -- '0' is not bad
+ ---@diagnostic disable-next-line: inject-field
+ vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
+ ---@diagnostic disable-next-line: inject-field
+ vim.o.foldlevelstart = 99
+ ---@diagnostic disable-next-line: inject-field
+ vim.o.foldenable = true
+ end,
+ },
{
'vim-scripts/CursorLineCurrentWindow',
event = 'BufReadPost',
},
{
'OXY2DEV/markview.nvim',
- ft = 'markdown', -- If you decide to lazy-load anyway
- opts = { initial_state = false },
+ lazy = true,
+ -- For `nvim-treesitter` users.
+ priority = 49,
+ opts = {
+ preview = {
+ filetypes = { 'markdown', 'codecompanion' },
+ ignore_buftypes = {},
+ },
+ },
},
}
diff --git a/nvim/.config/nvim/lua/plugins/lsp.lua b/nvim/.config/nvim/lua/plugins/lsp.lua
index fd9c516..c8e3594 100644
--- a/nvim/.config/nvim/lua/plugins/lsp.lua
+++ b/nvim/.config/nvim/lua/plugins/lsp.lua
@@ -4,13 +4,12 @@ local M = {
}
M.init = require('user.lsp.config').init
-
M.config = require('user.lsp.config').setup
M.dependencies = {
'nvimtools/none-ls.nvim',
{
- 'williamboman/mason.nvim',
+ 'mason-org/mason.nvim',
cmd = 'Mason',
keys = { { 'cm', 'Mason', desc = 'Mason' } },
build = ':MasonUpdate',
@@ -20,7 +19,6 @@ M.dependencies = {
},
},
},
- 'williamboman/mason-lspconfig.nvim',
{
'j-hui/fidget.nvim',
opts = {
@@ -40,12 +38,7 @@ M.dependencies = {
config = function(_, opts)
local navic = require 'nvim-navic'
navic.setup(opts)
- _G.get_winbar = function()
- return vim.api.nvim_win_get_config(0).relative == '' and require('nvim-navic').get_location() or vim.fn.expand '%:~:.'
- end
-
- -- vim.o.winbar = "%{%v:lua.require'nvim-navic'.get_location()%}"
- vim.o.winbar = '%{%v:lua._G.get_winbar()%}'
+ vim.o.winbar = "%{%v:lua.require'nvim-navic'.get_location()%}"
end,
},
}
@@ -93,14 +86,41 @@ local language_specific_plugins = {
library = {
-- See the configuration section for more details
-- Load luvit types when the `vim.uv` word is found
- { path = 'luvit-meta/library', words = { 'vim%.uv' } },
+ { path = '${3rd}/luv/library', words = { 'vim%.uv' } },
+ { path = 'snacks.nvim', words = { 'Snacks' } },
{ path = 'wezterm-types', mods = { 'wezterm' } },
},
},
- -- config = function(_,opts)
- -- require("lazydev").setup(opts)
- -- require('cmp').register_source('lazydev', )
- -- end
+ },
+ {
+ 'ray-x/go.nvim',
+ dependencies = { -- optional packages
+ 'ray-x/guihua.lua',
+ 'neovim/nvim-lspconfig',
+ 'nvim-treesitter/nvim-treesitter',
+ },
+ opts = {
+ lsp_cfg = true,
+ lsp_gofumpt = true,
+ lsp_inlay_hints = {
+ enable = false,
+ },
+ dap_vt = true,
+ },
+ config = function(_, opts)
+ require('go').setup(opts)
+ local format_sync_grp = vim.api.nvim_create_augroup('GoFormat', {})
+ vim.api.nvim_create_autocmd('BufWritePre', {
+ pattern = '*.go',
+ callback = function()
+ require('go.format').goimports()
+ end,
+ group = format_sync_grp,
+ })
+ end,
+ event = { 'CmdlineEnter' },
+ ft = { 'go', 'gomod' },
+ build = ':lua require("go.install").update_all_sync()', -- if you need to install/update all binaries
},
}
diff --git a/nvim/.config/nvim/lua/plugins/lualine.lua b/nvim/.config/nvim/lua/plugins/lualine.lua
index a1c9c67..236ec59 100644
--- a/nvim/.config/nvim/lua/plugins/lualine.lua
+++ b/nvim/.config/nvim/lua/plugins/lualine.lua
@@ -8,19 +8,35 @@ M.config = function()
-- Color table for highlights
-- stylua: ignore
+ -- local colors = {
+ -- bg = '#202328',
+ -- fg = '#bbc2cf',
+ -- aqua = '#6EB0A3',
+ -- yellow = '#ECBE7B',
+ -- cyan = '#008080',
+ -- darkblue = '#081633',
+ -- green = '#a9b665',
+ -- orange = '#FF8800',
+ -- violet = '#a9a1e1',
+ -- magenta = '#c678dd',
+ -- blue = '#51afef',
+ -- red = '#ec5f67',
+ -- }
+
+local palette = require("rose-pine.palette")
local colors = {
- bg = '#202328',
- fg = '#bbc2cf',
- aqua = '#6EB0A3',
- yellow = '#ECBE7B',
- cyan = '#008080',
- darkblue = '#081633',
- green = '#a9b665',
- orange = '#FF8800',
- violet = '#a9a1e1',
- magenta = '#c678dd',
- blue = '#51afef',
- red = '#ec5f67',
+ bg = palette.base,
+ fg = palette.text,
+ aqua = palette.rose, -- Changed to rose for better contrast
+ yellow = palette.gold,
+ cyan = palette.foam, -- Changed to foam for better visibility
+ darkblue = palette.surface,
+ green = palette.pine,
+ orange = palette.iris, -- Changed to iris for better distinction
+ violet = palette.iris,
+ magenta = palette.rose, -- Changed to rose for consistency
+ blue = palette.foam,
+ red = palette.love,
}
local conditions = {
@@ -40,7 +56,7 @@ M.config = function()
end,
}
- local my_branch = { 'branch', icon = '', color = { fg = colors.violet, gui = 'bold' } }
+ local my_branch = { 'branch', icon = '', color = { fg = colors.aqua, gui = 'bold' } }
local borders = {
left = {
@@ -99,7 +115,6 @@ M.config = function()
}
-- lualine
- local navic = require 'nvim-navic'
local config = {
options = {
-- Disable sections and component separators
@@ -163,25 +178,25 @@ M.config = function()
icon = '',
color = function()
local mode_color = {
- n = colors.red,
- i = colors.green,
- v = colors.blue,
- [''] = colors.blue,
- V = colors.blue,
- c = colors.magenta,
- no = colors.red,
- s = colors.orange,
- S = colors.orange,
- ic = colors.yellow,
- R = colors.violet,
- Rv = colors.violet,
- cv = colors.red,
- ce = colors.red,
- r = colors.cyan,
- rm = colors.cyan,
- ['r?'] = colors.cyan,
- ['!'] = colors.red,
- t = colors.cyan,
+ n = palette.rose, -- Normal mode
+ i = palette.pine, -- Insert mode
+ v = palette.foam, -- Visual mode
+ [''] = palette.foam, -- Visual block
+ V = palette.foam, -- Visual line
+ c = palette.love, -- Command mode
+ no = palette.love, -- Normal operator pending
+ s = palette.gold, -- Select mode
+ S = palette.gold, -- Select line
+ ic = palette.iris, -- Insert completion
+ R = palette.iris, -- Replace mode
+ Rv = palette.iris, -- Virtual replace
+ cv = palette.love, -- Ex mode
+ ce = palette.love, -- Normal ex
+ r = palette.foam, -- Hit-enter prompt
+ rm = palette.foam, -- More prompt
+ ['r?'] = palette.foam, -- Confirm
+ ['!'] = palette.love, -- Shell
+ t = palette.pine, -- Terminal
}
return { fg = mode_color[vim.fn.mode()] }
end,
@@ -201,9 +216,9 @@ M.config = function()
sources = { 'nvim_diagnostic' },
symbols = { error = ' ', warn = ' ', info = ' ' },
diagnostics_color = {
- color_error = { fg = colors.red },
- color_warn = { fg = colors.yellow },
- color_info = { fg = colors.cyan },
+ color_error = { fg = palette.love },
+ color_warn = { fg = palette.gold },
+ color_info = { fg = palette.foam },
},
}
@@ -230,7 +245,7 @@ M.config = function()
ins_left {
'filename',
cond = conditions.buffer_not_empty,
- color = { fg = colors.aqua, gui = 'bold' },
+ color = { fg = 'subtle', gui = 'bold' },
}
-------------------
diff --git a/nvim/.config/nvim/lua/plugins/mini.lua b/nvim/.config/nvim/lua/plugins/mini.lua
index d39d661..707bfee 100644
--- a/nvim/.config/nvim/lua/plugins/mini.lua
+++ b/nvim/.config/nvim/lua/plugins/mini.lua
@@ -93,6 +93,13 @@ local M = {
{
the_king .. 'surround',
version = false,
+ keys = {
+ { 'S', 'lua MiniSurround.add("visual")', mode = 'v' },
+ { 'yss' },
+ { 'ys' },
+ { 'ds' },
+ { 'cs' },
+ },
opts = {
mappings = {
add = 'ys',
@@ -137,8 +144,13 @@ local M = {
{
the_king .. 'pairs',
version = false,
+ enabled = false, -- use nvim-autopairs instead
event = 'InsertEnter',
- opts = {},
+ opts = {
+ mappings = {
+ ['`'] = { action = 'closeopen', pair = '``', neigh_pattern = '[^\\`].', register = { cr = false } },
+ },
+ },
},
{
the_king .. 'operators',
diff --git a/nvim/.config/nvim/lua/plugins/null-ls.lua b/nvim/.config/nvim/lua/plugins/null-ls.lua
index 69ac504..da9f824 100644
--- a/nvim/.config/nvim/lua/plugins/null-ls.lua
+++ b/nvim/.config/nvim/lua/plugins/null-ls.lua
@@ -8,11 +8,9 @@ local M = {
}
M.config = function()
local null_ls = require 'null-ls'
- local default_on_attach = require('user.lsp.on-attach').default
-- null-ls
null_ls.setup {
- on_attach = default_on_attach,
debug = true,
sources = {
null_ls.builtins.code_actions.gitsigns,
@@ -21,7 +19,6 @@ M.config = function()
require('user.lsp.code-actions').toggle_function_params,
require('user.lsp.code-actions').library_current_branch,
require 'none-ls-shellcheck.code_actions',
- null_ls.builtins.diagnostics.golangci_lint,
null_ls.builtins.diagnostics.hadolint,
null_ls.builtins.diagnostics.markdownlint,
null_ls.builtins.diagnostics.proselint,
diff --git a/nvim/.config/nvim/lua/plugins/octo.lua b/nvim/.config/nvim/lua/plugins/octo.lua
new file mode 100644
index 0000000..1129d01
--- /dev/null
+++ b/nvim/.config/nvim/lua/plugins/octo.lua
@@ -0,0 +1,53 @@
+local octo_string = 'Octo: '
+return {
+ 'pwntester/octo.nvim',
+ -- dev = true,
+ keys = { { 'o', 'Octo', desc = 'Octo menu' } },
+ cmd = 'Octo',
+ -- dependencies = {
+ -- 'nvim-lua/plenary.nvim',
+ -- 'nvim-telescope/telescope.nvim',
+ -- },
+ opts = {
+ use_local_fs = true, -- use local files on right side of reviews
+ enable_builtin = true, -- shows a list of builtin actions when no action is provided
+ default_merge_method = 'squash',
+ default_delete_branch = true, -- whether to delete branch when merging pull request with either `Octo pr merge` or from picker (can be overridden with `delete`/`nodelete` argument to `Octo pr merge`)
+ picker = 'fzf-lua',
+ picker_config = {
+ use_emojis = true,
+ },
+ users = 'assignable', -- Users for assignees or reviewers. Values: "search" | "mentionable" | "assignable"
+ pull_requests = {
+ use_branch_name_as_title = true, -- sets branch name to be the name for the PR
+ },
+ mappings = {
+ notification = {
+ read = { lhs = '' },
+ done = { lhs = '' },
+ unsubscribe = { lhs = '' },
+ },
+ },
+ },
+ config = function(_, opts)
+ local octo_config = require 'octo.config'
+ local default_opts = octo_config.get_default_values()
+ for _, actions in pairs(default_opts.mappings) do
+ for _, details in pairs(actions) do
+ if details.desc then
+ details.desc = octo_string .. details.desc
+ end
+ end
+ end
+ -- require('octo').setup(opts)
+ -- setup octo and merge opts with default opts
+ require('octo').setup(vim.tbl_deep_extend('force', default_opts, opts))
+ end,
+ init = function()
+ -- keymap gk to open fzf.lua's keymaps with a ready prompt for
+ -- "Octo: " to see all octo keymaps when you press gk
+ vim.keymap.set('n', 'gk', function()
+ require('fzf-lua').keymaps { query = octo_string }
+ end, { desc = 'Octo: Keymaps' })
+ end,
+}
diff --git a/nvim/.config/nvim/lua/plugins/snacks.lua b/nvim/.config/nvim/lua/plugins/snacks.lua
index 4f8624b..b9973fa 100644
--- a/nvim/.config/nvim/lua/plugins/snacks.lua
+++ b/nvim/.config/nvim/lua/plugins/snacks.lua
@@ -25,20 +25,6 @@ return {
},
},
keys = {
- {
- '.',
- function()
- Snacks.scratch()
- end,
- desc = 'Toggle Scratch Buffer',
- },
- {
- 'S',
- function()
- Snacks.scratch.select()
- end,
- desc = 'Select Scratch Buffer',
- },
{
'bd',
function()
@@ -93,30 +79,6 @@ return {
desc = 'Prev Reference',
mode = { 'n', 't' },
},
- {
- 'gh',
- function()
- Snacks.gitbrowse.open()
- end,
- },
- {
- 'N',
- desc = 'Neovim News',
- function()
- Snacks.win {
- file = vim.api.nvim_get_runtime_file('doc/news.txt', false)[1],
- width = 0.6,
- height = 0.6,
- wo = {
- spell = false,
- wrap = false,
- signcolumn = 'yes',
- statuscolumn = ' ',
- conceallevel = 3,
- },
- }
- end,
- },
},
init = function()
vim.api.nvim_create_user_command('Rename', function()
diff --git a/nvim/.config/nvim/lua/plugins/tree.lua b/nvim/.config/nvim/lua/plugins/tree.lua
index f51db84..ebc1e6d 100644
--- a/nvim/.config/nvim/lua/plugins/tree.lua
+++ b/nvim/.config/nvim/lua/plugins/tree.lua
@@ -19,7 +19,7 @@ local function on_attach(bufnr)
sort_current = sort_current + 1
end
api.tree.reload()
- require('user.utils').pretty_print('Sort Method: ' .. SORT_METHODS[sort_current])
+ vim.notify('Sort Method: ' .. SORT_METHODS[sort_current])
end
-- mark operation
@@ -48,21 +48,6 @@ local function on_attach(bufnr)
end
end)
end
- local mark_remove = function()
- local marks = api.marks.list()
- if #marks == 0 then
- table.insert(marks, api.tree.get_node_under_cursor())
- end
- vim.ui.input({ prompt = string.format('Remove/Delete %s files? [y/n] ', #marks) }, function(input)
- if input == 'y' then
- for _, node in ipairs(marks) do
- api.fs.remove(node)
- end
- api.marks.clear()
- api.tree.reload()
- end
- end)
- end
local mark_copy = function()
local marks = api.marks.list()
if #marks == 0 then
@@ -115,6 +100,8 @@ local function on_attach(bufnr)
vim.keymap.del('n', 's', { buffer = bufnr })
vim.keymap.del('n', '', { buffer = bufnr })
vim.keymap.del('n', 'bd', { buffer = bufnr })
+ vim.keymap.del('n', 'm', { buffer = bufnr })
+ vim.keymap.del('n', 'bmv', { buffer = bufnr })
vim.keymap.set('n', 'h', lefty, opts 'Left')
vim.keymap.set('n', '', lefty, opts 'Left')
@@ -127,8 +114,6 @@ local function on_attach(bufnr)
vim.keymap.set('n', 'K', mark_move_k, opts 'Toggle Bookmark Up')
vim.keymap.set('n', 'dd', mark_cut, opts 'Cut File(s)')
- vim.keymap.set('n', 'df', mark_trash, opts 'Trash File(s)')
- vim.keymap.set('n', 'dF', mark_remove, opts 'Remove File(s)')
vim.keymap.set('n', 'yy', mark_copy, opts 'Copy File(s)')
vim.keymap.set('n', 'mv', api.marks.bulk.move, opts 'Move Bookmarked')
@@ -143,6 +128,34 @@ local function on_attach(bufnr)
vim.system({ 'mv', file_src, file_out }, { text = true }):wait()
end
vim.keymap.set('n', 'r', move_file_to, opts 'Move File To')
+
+ vim.keymap.set('n', 'Z', function()
+ local node = api.tree.get_node_under_cursor()
+ local file_path = node['absolute_path']
+ local file_dir = vim.fn.fnamemodify(file_path, ':h')
+ local file_type = vim.trim(vim.system({ 'file', '--mime-type', '-b', file_path }, { text = true }):wait().stdout)
+
+ local function run(cmd)
+ local ok = vim.system(cmd, { text = true }):wait()
+ if ok.code ~= 0 then
+ vim.notify('Extraction failed: ' .. table.concat(cmd, ' '), vim.log.levels.ERROR)
+ return false
+ end
+ return true
+ end
+
+ if file_type == 'application/gzip' then
+ run { 'tar', 'xzf', file_path, '-C', file_dir }
+ elseif file_type == 'application/zip' then
+ run { 'unzip', file_path, '-d', file_dir }
+ elseif file_type == 'application/x-bzip2' then
+ run { 'tar', 'xjf', file_path, '-C', file_dir }
+ else
+ vim.notify('Unsupported file type for extraction: ' .. file_type, vim.log.levels.WARN)
+ return
+ end
+ vim.notify('Extracted: ' .. file_path)
+ end, opts 'Extract File')
end
local M = {
diff --git a/nvim/.config/nvim/lua/plugins/treesitter.lua b/nvim/.config/nvim/lua/plugins/treesitter.lua
index 8c05da1..915063d 100644
--- a/nvim/.config/nvim/lua/plugins/treesitter.lua
+++ b/nvim/.config/nvim/lua/plugins/treesitter.lua
@@ -5,21 +5,40 @@ local actions = function()
end,
}
end
+
local M = {
'nvim-treesitter/nvim-treesitter',
build = function()
pcall(require('nvim-treesitter.install').update { with_sync = true })
end,
dependencies = {
+ 'OXY2DEV/markview.nvim',
'nvim-treesitter/nvim-treesitter-textobjects',
- 'Afourcat/treesitter-terraform-doc.nvim',
+ { 'Afourcat/treesitter-terraform-doc.nvim', ft = 'terraform', cmd = 'OpenDoc' },
'nvim-treesitter/nvim-treesitter-context',
{ 'folke/ts-comments.nvim', opts = {} },
{
'windwp/nvim-ts-autotag',
- ft = { 'html', 'javascript', 'jsx', 'markdown', 'typescript', 'xml' },
+ ft = { 'html', 'javascript', 'jsx', 'markdown', 'typescript', 'xml', 'markdown' },
opts = {},
},
+ {
+ 'atusy/treemonkey.nvim',
+ keys = {
+ {
+ 'm',
+ function()
+ require 'nvim-treesitter.configs'
+ ---@diagnostic disable-next-line: missing-fields
+ require('treemonkey').select {
+ ignore_injections = false,
+ action = require('treemonkey.actions').unite_selection,
+ }
+ end,
+ mode = { 'x', 'o' },
+ },
+ },
+ },
},
event = 'BufReadPost',
}
@@ -37,10 +56,14 @@ M.opts = {
'gitcommit',
'gitignore',
'go',
+ 'gomod',
+ 'gosum',
'gotmpl',
+ 'gowork',
'graphql',
'groovy',
'hcl',
+ 'helm',
'hjson',
'html',
'http',
@@ -96,6 +119,7 @@ M.config = function(_, opts)
---@diagnostic disable-next-line: missing-fields
require('nvim-treesitter.configs').setup(opts)
+ vim.treesitter.language.register('markdown', 'octo')
vim.opt.foldmethod = 'expr'
vim.opt.foldexpr = 'nvim_treesitter#foldexpr()'
diff --git a/nvim/.config/nvim/lua/plugins/ufo.lua b/nvim/.config/nvim/lua/plugins/ufo.lua
deleted file mode 100644
index dc8d039..0000000
--- a/nvim/.config/nvim/lua/plugins/ufo.lua
+++ /dev/null
@@ -1,26 +0,0 @@
-local M = {
- 'kevinhwang91/nvim-ufo',
- dependencies = { 'kevinhwang91/promise-async' },
- event = 'BufReadPost',
- keys = {
- { 'fo', 'lua require("ufo").openAllFolds()' },
- { 'fc', 'lua require("ufo").closeAllFolds()' },
- { 'fp', 'lua require("ufo").peekFoldedLinesUnderCursor()' },
- },
- opts = {
- open_fold_hl_timeout = 0,
- },
-
- init = function()
- ---@diagnostic disable-next-line: inject-field
- vim.o.foldcolumn = '1' -- '0' is not bad
- ---@diagnostic disable-next-line: inject-field
- vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
- ---@diagnostic disable-next-line: inject-field
- vim.o.foldlevelstart = 99
- ---@diagnostic disable-next-line: inject-field
- vim.o.foldenable = true
- end,
-}
-
-return M
diff --git a/nvim/.config/nvim/lua/plugins/yanky.lua b/nvim/.config/nvim/lua/plugins/yanky.lua
deleted file mode 100644
index e64f136..0000000
--- a/nvim/.config/nvim/lua/plugins/yanky.lua
+++ /dev/null
@@ -1,30 +0,0 @@
-local M = {
- 'gbprod/yanky.nvim',
- dependencies = { 'kkharji/sqlite.lua' },
- cmd = { 'YankyRingHistory' },
- keys = {
- 'yy',
- { 'p', '(YankyPutAfter)', mode = { 'n', 'x' } },
- { 'P', '(YankyPutBefore)', mode = { 'n', 'x' } },
- { '', '(YankyCycleForward)' },
- { '', '(YankyCycleBackward)' },
- { 'y', 'YankyRingHistory' },
- },
- opts = {
- ring = {
- history_length = 100,
- storage = 'sqlite',
- sync_with_numbered_registers = true,
- cancel_event = 'update',
- },
- },
- init = function()
- require('user.menu').add_actions('Yanky', {
- ['Yank history'] = function()
- vim.cmd 'YankyRingHistory'
- end,
- })
- end,
-}
-
-return M
diff --git a/nvim/.config/nvim/lua/tests/utils_spec.lua b/nvim/.config/nvim/lua/tests/utils_spec.lua
new file mode 100644
index 0000000..af40ac3
--- /dev/null
+++ b/nvim/.config/nvim/lua/tests/utils_spec.lua
@@ -0,0 +1,9 @@
+--# selene: allow(undefined_variable)
+local utils = require 'user.utils'
+local eq = assert.are.same
+
+describe('user.utils', function()
+ it('return an emoji of country', function()
+ eq(utils.country_os_to_emoji 'US', '🇺🇸')
+ end)
+end)
diff --git a/nvim/.config/nvim/lua/user/actions.lua b/nvim/.config/nvim/lua/user/actions.lua
index 67c46a7..1d490b2 100644
--- a/nvim/.config/nvim/lua/user/actions.lua
+++ b/nvim/.config/nvim/lua/user/actions.lua
@@ -8,37 +8,43 @@ local find_in_project = function(opts)
}
local bang = opts.literal_search and '' or '!'
local noautocmd_str = opts.noautocmd and 'noautocmd ' or ''
- vim.ui.input({ prompt = 'Enter search term (blank for word under cursor): ' }, function(search_term)
- local original_search_term = search_term
- if search_term then
- search_term = ' ' .. search_term
- end
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Enter search term (blank for word under cursor)❯ ' }, function(search_term)
+ local original_search_term = search_term
+ if search_term then
+ search_term = ' ' .. search_term
+ end
- vim.cmd(noautocmd_str .. 'RipGrepCWORD' .. bang .. search_term)
- opts.callback(original_search_term)
- end)
+ vim.cmd(noautocmd_str .. 'RipGrepCWORD' .. bang .. search_term)
+ opts.callback(original_search_term)
+ end)
+ end, 100)
end
local search_and_replace = function(literal_search)
find_in_project {
literal_search = literal_search,
callback = function(search_term)
- vim.ui.input({ prompt = 'Enter Replace term: ' }, function(replace_term)
- if not replace_term then
- pretty_print 'Canceled.'
- return
- end
- vim.ui.input({
- prompt = 'Enter flags (g=global, c=confirm, i=case insensitive, e=ignore errors, n=only count): ',
- default = 'gce',
- }, function(flags)
- if not flags then
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Enter Replace term❯ ' }, function(replace_term)
+ if not replace_term then
pretty_print 'Canceled.'
return
end
- vim.cmd('silent noautocmd cdo %s?' .. search_term .. '?' .. replace_term .. '?' .. flags)
+ vim.defer_fn(function()
+ vim.ui.input({
+ prompt = 'Enter flags (g=global, c=confirm, i=case insensitive, e=ignore errors, n=only count)❯ ',
+ default = 'gce',
+ }, function(flags)
+ if not flags then
+ pretty_print 'Canceled.'
+ return
+ end
+ vim.cmd('silent noautocmd cdo %s?' .. search_term .. '?' .. replace_term .. '?' .. flags)
+ end)
+ end, 100)
end)
- end)
+ end, 100)
end,
noautocmd = true,
}
@@ -53,10 +59,10 @@ return {
['Find in pwd (regex search) ()'] = function()
find_in_project { literal_search = false }
end,
- ['Search and Replace in pwd (literal search)'] = function()
+ ['Search and Replace in cwd (literal search)'] = function()
search_and_replace(true)
end,
- ['Search and Replace in pwd (regex search)'] = function()
+ ['Search and Replace in cwd (regex search)'] = function()
search_and_replace(false)
end,
['Replace word under cursor (r)'] = function()
@@ -80,11 +86,6 @@ return {
['[Folds] Close all folds (fc)'] = function()
vim.cmd 'normal! zM'
end,
- ['[Terraform] Add -target macro to register q'] = function()
- -- set q register to -target
- vim.fn.setreg('q', [[yss'I-target=A \j]])
- pretty_print('Macro q set to -target', 'Terraform')
- end,
['[Terraform] Remove terragrunt files'] = function()
require('lazy').load { plugins = { 'vim-fugitive' } }
local scan_dir = require 'plenary.scandir'
@@ -107,6 +108,9 @@ return {
v? will be ?d
%s?\v^\s*#\s*(.*) will be (.*)?\1 \2?
]]
+ -- set q register to -target
+ vim.fn.setreg('q', [[yss'I-target=A \j]])
+ pretty_print('Macro q set to -target', 'Terraform')
end,
['Basic groovy format'] = function()
vim.cmd.BasicGroovyFormat()
@@ -122,6 +126,7 @@ return {
end
local text = [[
+--# selene: allow(undefined_variable)
-- Reload the file when it changes on disk
local group = vim.api.nvim_create_augroup("ReloadModule", {clear = true})
vim.api.nvim_create_autocmd("BufWritePost", {
diff --git a/nvim/.config/nvim/lua/user/additional-schemas.lua b/nvim/.config/nvim/lua/user/additional-schemas.lua
index 18a5404..a1d362a 100644
--- a/nvim/.config/nvim/lua/user/additional-schemas.lua
+++ b/nvim/.config/nvim/lua/user/additional-schemas.lua
@@ -6,6 +6,7 @@ local M = {
Accept = 'application/vnd.github+json',
['X-GitHub-Api-Version'] = '2022-11-28',
},
+ schema_modeline = '# yaml-language-server: $schema=',
}
M.schema_url = 'https://raw.githubusercontent.com/' .. M.schemas_catalog .. '/' .. M.schema_catalog_branch
@@ -36,6 +37,9 @@ end
M.crds_as_schemas = function()
local schemas = {}
+ if not M.all_crds or #M.all_crds == 0 then
+ M.init()
+ end
for _, crd in ipairs(M.all_crds) do
local crd_name = '[datreeio] ' .. crd:gsub('%.json$', ''):gsub('/', '-'):gsub('_', '-')
local schema_url = {
@@ -48,13 +52,13 @@ M.crds_as_schemas = function()
end
M.list_schemas = function()
- vim.ui.select(M.all_crds, { prompt = 'Select schema: ' }, function(selection)
+ vim.ui.select(M.all_crds, { title = 'Schemas', prompt = 'Select schema❯ ' }, function(selection)
if not selection then
require('user.utils').pretty_print 'Canceled.'
return
end
local schema_url = M.schema_url .. '/' .. selection
- local schema_modeline = '# yaml-language-server: $schema=' .. schema_url
+ local schema_modeline = M.schema_modeline .. schema_url
vim.api.nvim_buf_set_lines(0, 0, 0, false, { schema_modeline })
vim.notify('Added schema modeline: ' .. schema_modeline)
end)
diff --git a/nvim/.config/nvim/lua/user/autocommands.lua b/nvim/.config/nvim/lua/user/autocommands.lua
index 33fa76b..9b3f632 100644
--- a/nvim/.config/nvim/lua/user/autocommands.lua
+++ b/nvim/.config/nvim/lua/user/autocommands.lua
@@ -14,7 +14,7 @@ autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, {
})
autocmd('FileChangedShellPost', {
- desc = 'Actions when the file is changed outside of Neovim',
+ desc = 'Reload when the file is changed outside of Neovim',
group = reload_file_group,
callback = function()
vim.notify('File changed, reloading the buffer', vim.log.levels.WARN)
@@ -41,6 +41,7 @@ autocmd('UIEnter', {
end,
})
+-- VeryLazy
autocmd('User', {
desc = 'Setup non-critical stuff after lazy has loaded',
group = first_load,
@@ -119,15 +120,6 @@ autocmd('BufReadPost', {
end,
})
-autocmd('DirChanged', {
- group = buffer_settings,
- callback = function()
- local cwd = vim.fn.getcwd()
- local hostname = vim.fn.hostname()
- os.execute('printf "\\033]7;file://' .. hostname .. cwd .. '\\033\\\\"')
- end,
-})
-
-- Special filetypes
local special_filetypes = augroup 'SpecialFiletype'
autocmd({ 'FileType' }, {
diff --git a/nvim/.config/nvim/lua/user/difftool.lua b/nvim/.config/nvim/lua/user/difftool.lua
new file mode 100644
index 0000000..a6c91e1
--- /dev/null
+++ b/nvim/.config/nvim/lua/user/difftool.lua
@@ -0,0 +1,291 @@
+---@class DiffLayout
+---@field left_win integer|nil Window handle for left diff
+---@field right_win integer|nil Window handle for right diff
+
+---@class DiffToolModule
+local M = {}
+
+---@type DiffLayout
+local layout = {
+ left_win = nil,
+ right_win = nil,
+}
+
+-- Set up a consistent layout with two diff windows and quickfix at bottom
+---@return boolean setup_needed True if new layout needed to be created
+local function setup_layout()
+ if layout.left_win and vim.api.nvim_win_is_valid(layout.left_win) then
+ return false
+ end
+
+ -- Save current window as left window
+ layout.left_win = vim.api.nvim_get_current_win()
+
+ -- Create right window
+ vim.cmd 'vsplit'
+ layout.right_win = vim.api.nvim_get_current_win()
+ return true
+end
+
+---@param winnr integer Window handle
+---@param file string File path
+local function edit_in(winnr, file)
+ vim.api.nvim_win_call(winnr, function()
+ local current = vim.fs.abspath(vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winnr)))
+
+ -- Check if the current buffer is already the target file
+ if current == (file and vim.fs.abspath(file) or '') then
+ return
+ end
+
+ -- Read the file into the buffer
+ vim.cmd.edit(vim.fn.fnameescape(file))
+ end)
+end
+
+-- Diff two files
+---@param left_file string Path to left file
+---@param right_file string Path to right file
+local function diff_files(left_file, right_file)
+ setup_layout()
+ edit_in(layout.left_win, left_file)
+ edit_in(layout.right_win, right_file)
+
+ -- Apply diff settings efficiently
+ vim.cmd 'diffoff!'
+ local diffthis = vim.cmd.diffthis
+ vim.api.nvim_win_call(layout.left_win, diffthis)
+ vim.api.nvim_win_call(layout.right_win, diffthis)
+end
+
+---@class FileMapping
+---@field left string|nil
+---@field right string|nil
+
+---@param dir string Directory path
+---@param is_left boolean Whether this is the left directory
+---@param all_paths table Accumulated path mappings
+local function process_directory(dir, is_left, all_paths)
+ local files = vim.fs.find(function()
+ return true
+ end, {
+ limit = math.huge,
+ path = dir,
+ follow = false,
+ })
+
+ for _, full_path in ipairs(files) do
+ if vim.fn.isdirectory(full_path) == 0 then
+ local rel_path = full_path:sub(#dir + 1)
+ full_path = vim.fn.resolve(full_path)
+ all_paths[rel_path] = all_paths[rel_path] or { left = nil, right = nil }
+ if is_left then
+ all_paths[rel_path].left = full_path
+ else
+ all_paths[rel_path].right = full_path
+ end
+ end
+ end
+end
+
+---@param left_file string|nil Path to left file
+---@param right_file string|nil Path to right file
+---@return boolean files_differ True if files have different content
+local function files_differ(left_file, right_file)
+ -- If one file doesn't exist, they differ
+ if not left_file or not right_file then
+ return true
+ end
+
+ -- Check if files exist
+ if vim.fn.filereadable(left_file) == 0 or vim.fn.filereadable(right_file) == 0 then
+ return true
+ end
+
+ -- Read and compare file contents
+ local left_lines = vim.fn.readfile(left_file)
+ local right_lines = vim.fn.readfile(right_file)
+
+ -- Quick check: different number of lines
+ if #left_lines ~= #right_lines then
+ return true
+ end
+
+ -- Compare line by line
+ for i = 1, #left_lines do
+ if left_lines[i] ~= right_lines[i] then
+ return true
+ end
+ end
+
+ return false
+end
+
+---@param left_dir string Left directory path
+---@param right_dir string Right directory path
+local function diff_directories(left_dir, right_dir)
+ setup_layout()
+
+ ---@type table
+ local all_paths = {}
+
+ -- Process both directories
+ process_directory(left_dir, true, all_paths)
+ process_directory(right_dir, false, all_paths)
+
+ -- Convert to quickfix entries
+ ---@type table[] Quickfix entries
+ local qf_entries = {}
+
+ for rel_path, files in pairs(all_paths) do
+ local status, left_file, right_file = 'M', files.left, files.right
+
+ if not left_file then
+ status = 'A' -- Added (only in right)
+ left_file = left_dir .. rel_path
+ elseif not right_file then
+ status = 'D' -- Deleted (only in left)
+ right_file = right_dir .. rel_path
+ end
+
+ -- Only add to quickfix if files actually differ
+ if files_differ(left_file, right_file) then
+ qf_entries[#qf_entries + 1] = {
+ filename = right_file,
+ text = status,
+ user_data = {
+ diff = true,
+ rel = rel_path,
+ left = left_file,
+ right = right_file,
+ left_dir = left_dir,
+ right_dir = right_dir,
+ },
+ }
+ end
+ end
+
+ -- Sort entries by filename for consistency
+ table.sort(qf_entries, function(a, b)
+ return a.user_data.rel < b.user_data.rel
+ end)
+
+ vim.fn.setqflist({}, 'r', {
+ ---@diagnostic disable-next-line: assign-type-mismatch
+ nr = '$',
+ title = 'DiffTool',
+ items = qf_entries,
+ quickfixtextfunc = function(info)
+ local items = vim.fn.getqflist({ id = info.id, items = 1 }).items
+ local out = {}
+ for i = info.start_idx, info.end_idx do
+ local entry = items[i]
+ local status_text = entry.text
+ local description = ''
+
+ if entry.user_data and entry.user_data.diff then
+ if status_text == 'A' then
+ description = ' (only in ' .. vim.fn.fnamemodify(entry.user_data.right_dir, ':t') .. ')'
+ elseif status_text == 'D' then
+ description = ' (missing from ' .. vim.fn.fnamemodify(entry.user_data.right_dir, ':t') .. ')'
+ end
+ end
+
+ out[#out + 1] = status_text .. description .. ' ' .. entry.user_data.rel
+ end
+ return out
+ end,
+ })
+
+ vim.cmd 'botright copen'
+ vim.cmd.cfirst()
+end
+
+---Setup the difftool with highlighting and commands
+function M.setup()
+ local ns_id = vim.api.nvim_create_namespace 'difftool_qf'
+
+ -- Pre-compile patterns for performance
+ local patterns = {
+ add = '^A ',
+ delete = '^D ',
+ modify = '^M ',
+ }
+
+ -- Define highlight groups globally (not in namespace)
+ vim.api.nvim_set_hl(0, 'DiffToolAdd', { link = 'GitSignsAdd' })
+ vim.api.nvim_set_hl(0, 'DiffToolDelete', { link = 'GitSignsDelete' })
+ vim.api.nvim_set_hl(0, 'DiffToolModify', { link = 'GitSignsChange' })
+
+ vim.api.nvim_create_autocmd('BufWinEnter', {
+ pattern = 'quickfix',
+ callback = function()
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_clear_namespace(bufnr, ns_id, 0, -1)
+
+ local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
+ for i, line in ipairs(lines) do
+ local hl_group
+ if line:match(patterns.add) then
+ hl_group = 'DiffToolAdd'
+ elseif line:match(patterns.delete) then
+ hl_group = 'DiffToolDelete'
+ elseif line:match(patterns.modify) then
+ hl_group = 'DiffToolModify'
+ end
+
+ if hl_group then
+ vim.api.nvim_buf_set_extmark(bufnr, ns_id, i - 1, 0, {
+ hl_group = hl_group,
+ end_col = #line,
+ priority = 1000,
+ strict = false,
+ })
+ end
+ end
+ end,
+ })
+
+ vim.api.nvim_create_autocmd('BufWinEnter', {
+ pattern = '*',
+ callback = function(args)
+ local qf_info = vim.fn.getqflist { idx = 0 }
+ local qf_list = vim.fn.getqflist()
+ local entry = qf_list[qf_info.idx]
+
+ -- Check if the entry is a diff entry
+ if not (entry and entry.user_data and entry.user_data.diff and args.buf == entry.bufnr) then
+ return
+ end
+
+ vim.schedule(function()
+ diff_files(entry.user_data.left, entry.user_data.right)
+ end)
+ end,
+ })
+
+ vim.api.nvim_create_user_command('DiffTool', function(opts)
+ if #opts.fargs < 2 then
+ vim.notify('Usage: DiffTool ', vim.log.levels.ERROR)
+ return
+ end
+
+ local left, right = opts.fargs[1], opts.fargs[2]
+ local is_dir = vim.fn.isdirectory(left) == 1 and vim.fn.isdirectory(right) == 1
+ local is_file = vim.fn.filereadable(left) == 1 and vim.fn.filereadable(right) == 1
+
+ if is_dir then
+ diff_directories(left, right)
+ elseif is_file then
+ diff_files(left, right)
+ else
+ vim.notify('Both arguments must be files or directories', vim.log.levels.ERROR)
+ end
+ end, {
+ nargs = '*',
+ force = true,
+ complete = 'file',
+ })
+end
+
+return M
diff --git a/nvim/.config/nvim/lua/user/git.lua b/nvim/.config/nvim/lua/user/git.lua
index a01d126..75c8c14 100644
--- a/nvim/.config/nvim/lua/user/git.lua
+++ b/nvim/.config/nvim/lua/user/git.lua
@@ -72,12 +72,35 @@ end
M.get_branch = function(cb)
run_git({ 'branch', '--show-current' }, nil, function(branch)
- cb(vim.trim(branch))
+ local branch = vim.trim(branch)
+ if branch == '' then
+ M.get_short_commit(function(commit_hash)
+ M.prnt('No branch found, using commit hash: ' .. commit_hash)
+ cb(commit_hash)
+ end)
+ else
+ cb(vim.trim(branch))
+ end
end)
end
M.get_branch_sync = function()
- return vim.trim(run_git_sync({ 'branch', '--show-current' }, nil).stdout)
+ local branch = vim.trim(run_git_sync({ 'branch', '--show-current' }, nil).stdout)
+ if branch == '' then
+ return M.get_short_commit_sync()
+ else
+ return branch
+ end
+end
+
+M.get_short_commit = function(cb)
+ run_git({ 'rev-parse', '--short', 'HEAD' }, nil, function(commit_hash)
+ cb(vim.trim(commit_hash))
+ end)
+end
+
+M.get_short_commit_sync = function()
+ return vim.trim(run_git_sync({ 'rev-parse', '--short', 'HEAD' }, nil).stdout)
end
M.get_remotes = function(cb)
@@ -119,9 +142,13 @@ M.get_branches_sync = function(remote_name)
return branches
end
+M.checkout = function(branch_name)
+ run_git({ 'checkout', branch_name }, 'Checking out ' .. branch_name)
+end
+
M.push = function(cb)
M.get_branch(function(branch)
- run_git({ 'push', 'origin', branch }, 'Pushing to ' .. branch .. '...', cb)
+ run_git({ 'push', '-u', 'origin', branch }, 'Pushing to ' .. branch .. '...', cb)
end)
end
@@ -157,9 +184,9 @@ M.create_new_branch = function(branch_opts)
if branch_opts.args ~= '' then
return run_git({ 'checkout', '-b', branch_opts.args }, 'Creating new branch ' .. branch_opts.args)
end
- vim.ui.input({ prompt = 'Enter new branch name: ' }, function(input)
+ vim.ui.input({ prompt = 'Enter new branch name❯ ' }, function(input)
if not input then
- return
+ return M.prnt 'Canceled.'
end
if not input:match '^[a-zA-Z0-9_-]+$' then
return M.prnt('Invalid branch name', vim.log.levels.ERROR)
@@ -207,19 +234,19 @@ end
M.ui_select_remotes = function(cb)
M.get_remotes(function(remotes)
local remote_list = vim.tbl_keys(remotes)
- with_ui_select(remote_list, { prompt = 'Select remote: ' }, cb)
+ with_ui_select(remote_list, { title = 'Remotes', prompt = 'Select remote❯ ' }, cb)
end)
end
M.ui_select_tags = function(cb)
M.get_tags(function(tags)
- with_ui_select(tags, { prompt = 'Select tag: ' }, cb, false)
+ with_ui_select(tags, { title = 'Tags', prompt = 'Select tag❯ ' }, cb, false)
end)
end
M.ui_select_branches = function(remote_name, cb)
M.get_branches(remote_name, function(branches)
- with_ui_select(branches, { prompt = 'Select branch: ' }, cb, false)
+ with_ui_select(branches, { title = 'Branches', prompt = 'Select branch❯ ' }, cb, false)
end)
end
@@ -240,14 +267,13 @@ M.ui_select_merge_remote_branch = function()
end
M.ui_select_create_tag = function()
- require('fzf-lua.utils').fzf_exit()
vim.defer_fn(function()
- vim.ui.input({ prompt = 'Enter tag name: ' }, function(tag_name)
+ vim.ui.input({ prompt = 'Enter tag name❯ ' }, function(tag_name)
if not tag_name then
return M.prnt 'Canceled.'
end
run_git({ 'tag', tag_name }, 'Creating tag: ' .. tag_name, function()
- with_ui_select({ 'Yes', 'No' }, { prompt = 'Push?' }, function(choice)
+ with_ui_select({ 'Yes', 'No' }, { prompt = 'Push❯ ' }, function(choice)
if choice == 'Yes' then
M.prnt('Pushing tag ' .. tag_name .. '...')
run_git({ 'push', '--tags' }, nil, function()
@@ -262,11 +288,23 @@ M.ui_select_create_tag = function()
end, 100)
end
+M.ui_select_rename_branch = function(branch_name, cb)
+ -- require('fzf-lua.utils').fzf_exit()
+ vim.defer_fn(function()
+ vim.ui.input({ prompt = 'Enter new branch name❯ ', default = branch_name }, function(new_name)
+ if not new_name then
+ return M.prnt 'Canceled.'
+ end
+ run_git({ 'branch', '-m', branch_name, new_name }, 'Renaming branch: ' .. branch_name .. ' to ' .. new_name, cb)
+ end)
+ end, 100)
+end
+
M.ui_select_delete_tag = function()
M.ui_select_tags(function(tag)
M.prnt('Deleting tag ' .. tag .. ' locally...')
run_git({ 'tag', '-d', tag }, nil, function()
- with_ui_select({ 'Yes', 'No' }, { prompt = 'Delete tag ' .. tag .. ' from remote?' }, function(choice)
+ with_ui_select({ 'Yes', 'No' }, { prompt = 'Delete tag ' .. tag .. ' from remote❯ ' }, function(choice)
if choice == 'Yes' then
M.ui_select_remotes(function(remote)
M.prnt('Deleting tag ' .. tag .. ' from remote ' .. remote .. '...')
diff --git a/nvim/.config/nvim/lua/user/gitbrowse.lua b/nvim/.config/nvim/lua/user/gitbrowse.lua
new file mode 100644
index 0000000..06a5dbc
--- /dev/null
+++ b/nvim/.config/nvim/lua/user/gitbrowse.lua
@@ -0,0 +1,216 @@
+---@class user.gitbrowse
+---@overload fun(opts?: user.gitbrowse.Config)
+local M = setmetatable({}, {
+ __call = function(t, ...)
+ return t.open(...)
+ end,
+})
+
+M.meta = {
+ desc = 'Open the current file, branch, commit, or repo in a browser (e.g. GitHub, GitLab, Bitbucket)',
+}
+
+local uv = vim.uv or vim.loop
+
+---@class user.gitbrowse.Config
+---@field url_patterns? table>
+local defaults = {
+ notify = true, -- show notification on open
+ -- Handler to open the url in a browser
+ ---@param url string
+ open = function(url)
+ vim.ui.open(url)
+ end,
+ ---@type "repo" | "branch" | "file" | "commit"
+ what = 'file', -- what to open. not all remotes support all types
+ branch = nil, ---@type string?
+ commit = nil, ---@type string?
+ line_start = nil, ---@type number?
+ line_end = nil, ---@type number?
+ -- patterns to transform remotes to an actual URL
+ -- stylua: ignore
+ remote_patterns = {
+ { "^(https?://.*)%.git$" , "%1" },
+ { "^git@(.+):(.+)%.git$" , "https://%1/%2" },
+ { "^git@(.+):(.+)$" , "https://%1/%2" },
+ { "^git@(.+)/(.+)$" , "https://%1/%2" },
+ { "^ssh://git@(.*)$" , "https://%1" },
+ { "^ssh://([^:/]+)(:%d+)/(.*)$" , "https://%1/%3" },
+ { "^ssh://([^/]+)/(.*)$" , "https://%1/%2" },
+ { "ssh%.dev%.azure%.com/v3/(.*)/(.*)$", "dev.azure.com/%1/_git/%2" },
+ { "^https://%w*@(.*)" , "https://%1" },
+ { "^git@(.*)" , "https://%1" },
+ { ":%d+" , "" },
+ { "%.git$" , "" },
+ },
+ url_patterns = {
+ ['github%.com'] = {
+ branch = '/tree/{branch}',
+ file = '/blob/{branch}/{file}#L{line_start}-L{line_end}',
+ commit = '/commit/{commit}',
+ },
+ ['gitlab%.com'] = {
+ branch = '/-/tree/{branch}',
+ file = '/-/blob/{branch}/{file}#L{line_start}-L{line_end}',
+ commit = '/-/commit/{commit}',
+ },
+ ['bitbucket%.org'] = {
+ branch = '/src/{branch}',
+ file = '/src/{branch}/{file}#lines-{line_start}-L{line_end}',
+ commit = '/commits/{commit}',
+ },
+ },
+}
+
+---@class user.gitbrowse.Fields
+---@field branch? string
+---@field file? string
+---@field line_start? number
+---@field line_end? number
+---@field commit? string
+---@field line_count? number
+
+---@private
+---@param remote string
+---@param opts? user.gitbrowse.Config
+function M.get_repo(remote, opts)
+ opts = vim.tbl_deep_extend('force', defaults, opts or {})
+ local ret = remote
+ for _, pattern in ipairs(opts.remote_patterns) do
+ ret = ret:gsub(pattern[1], pattern[2]) --[[@as string]]
+ end
+ return ret:find 'https://' == 1 and ret or ('https://%s'):format(ret)
+end
+
+---@param repo string
+---@param fields user.gitbrowse.Fields
+---@param opts? user.gitbrowse.Config
+function M.get_url(repo, fields, opts)
+ opts = vim.tbl_deep_extend('force', defaults, opts or {})
+ for remote, patterns in pairs(opts.url_patterns) do
+ if repo:find(remote) then
+ local pattern = patterns[opts.what]
+ if type(pattern) == 'string' then
+ return repo .. pattern:gsub('(%b{})', function(key)
+ return fields[key:sub(2, -2)] or key
+ end)
+ elseif type(pattern) == 'function' then
+ return repo .. pattern(fields)
+ end
+ end
+ end
+ return repo
+end
+
+---@param cmd string[]
+---@param err string
+local function system(cmd, err)
+ local proc = vim.fn.system(cmd)
+ if vim.v.shell_error ~= 0 then
+ vim.notify { err, proc }
+ error '__ignore__'
+ end
+ return vim.split(vim.trim(proc), '\n')
+end
+
+---@param hash string
+---@param cwd string
+---@return boolean
+local function is_valid_commit_hash(hash, cwd)
+ if not (hash:match '^[a-fA-F0-9]+$' and #hash >= 7) then
+ return false
+ end
+ system({ 'git', '-C', cwd, 'rev-parse', '--verify', hash }, 'Invalid commit hash')
+ return true
+end
+
+---@param opts? user.gitbrowse.Config
+function M.open(opts)
+ opts = vim.tbl_deep_extend('force', defaults, opts or {})
+ local ok, err = pcall(M._open, opts) -- errors are handled with notifications
+ if not ok and err ~= '__ignore__' then
+ error(err)
+ end
+end
+
+---@param opts? user.gitbrowse.Config
+function M._open(opts)
+ opts = vim.tbl_deep_extend('force', defaults, opts or {})
+ local file = vim.api.nvim_buf_get_name(0) ---@type string?
+ file = file and (uv.fs_stat(file) or {}).type == 'file' and vim.fs.normalize(file) or nil
+ local cwd = file and vim.fn.fnamemodify(file, ':h') or vim.fn.getcwd()
+ local word = vim.fn.expand ''
+ local commit_to_check = opts.commit or word
+ local is_commit = commit_to_check and is_valid_commit_hash(commit_to_check, cwd)
+
+ ---@type user.gitbrowse.Fields
+ local fields = {
+ branch = opts.branch or system({ 'git', '-C', cwd, 'rev-parse', 'HEAD' }, 'Failed to get current branch')[1],
+ file = file and system({ 'git', '-C', cwd, 'ls-files', '--full-name', file }, 'Failed to get git file path')[1],
+ line_start = opts.line_start,
+ line_end = opts.line_end,
+ commit = is_commit and commit_to_check or nil,
+ }
+
+ -- Get visual selection range if in visual mode
+ if vim.fn.mode():find '[vV]' then
+ vim.fn.feedkeys(':', 'nx')
+ local line_start = vim.api.nvim_buf_get_mark(0, '<')[1]
+ local line_end = vim.api.nvim_buf_get_mark(0, '>')[1]
+ vim.fn.feedkeys('gv', 'nx')
+ -- Ensure line_start is always the smaller number
+ if line_start > line_end then
+ line_start, line_end = line_end, line_start
+ end
+ fields.line_start = line_start
+ fields.line_end = line_end
+ else
+ fields.line_start = fields.line_start or vim.fn.line '.'
+ fields.line_end = fields.line_end or fields.line_start
+ end
+ fields.line_count = fields.line_end - fields.line_start + 1
+
+ opts.what = is_commit and 'commit' or opts.what == 'commit' and not fields.commit and 'file' or opts.what
+ opts.what = not is_commit and opts.what == 'file' and not fields.file and 'branch' or opts.what
+ opts.what = not is_commit and opts.what == 'branch' and not fields.branch and 'repo' or opts.what
+
+ local remotes = {} ---@type {name:string, url:string}[]
+
+ for _, line in ipairs(system({ 'git', '-C', cwd, 'remote', '-v' }, 'Failed to get git remotes')) do
+ local name, remote = line:match '(%S+)%s+(%S+)%s+%(fetch%)'
+ if name and remote then
+ local repo = M.get_repo(remote, opts)
+ if repo then
+ table.insert(remotes, {
+ name = name,
+ url = M.get_url(repo, fields, opts),
+ })
+ end
+ end
+ end
+
+ local function open(remote)
+ if remote then
+ if opts.notify ~= false then
+ vim.notify(('Opening [%s](%s)'):format(remote.name, remote.url))
+ end
+ opts.open(remote.url)
+ end
+ end
+
+ if #remotes == 0 then
+ return vim.notify 'No git remotes found'
+ elseif #remotes == 1 then
+ return open(remotes[1])
+ end
+
+ vim.ui.select(remotes, {
+ prompt = 'Select remote to browse',
+ title = 'Git remotes',
+ format_item = function(item)
+ return item.name .. (' '):rep(8 - #item.name) .. ' 🔗 ' .. item.url
+ end,
+ }, open)
+end
+
+return M
diff --git a/nvim/.config/nvim/lua/user/grep.lua b/nvim/.config/nvim/lua/user/grep.lua
new file mode 100644
index 0000000..f713c8c
--- /dev/null
+++ b/nvim/.config/nvim/lua/user/grep.lua
@@ -0,0 +1,87 @@
+local M = {}
+
+-- Default options
+-- Default options
+local default_opts = {
+ keymap = {
+ search = '', -- The keybinding to trigger search
+ },
+ grep = {
+ literal_flag = '-F', -- Default literal search flag
+ format = '%f:%l:%c:%m', -- Default grep format
+ -- Built-in grep command fallback
+ cmd = 'grep -n -r --exclude=%s . $*',
+ },
+ -- ripgrep configuration
+ rg = {
+ cmd = "rg --vimgrep --no-heading --smart-case --hidden --follow -g '!{%s}' -uu $*",
+ literal_flag = '-F',
+ format = '%f:%l:%c:%m,%f:%l:%m',
+ },
+ -- silver searcher configuration
+ ag = {
+ cmd = "ag --vimgrep --smart-case --hidden --follow --ignore '!{%s}' $*",
+ literal_flag = '-Q',
+ format = '%f:%l:%c:%m',
+ },
+}
+
+-- Set grepprg based on available tools
+local function setup_grep(opts)
+ local wildignore = vim.o.wildignore
+
+ if vim.fn.executable 'rg' == 1 then
+ vim.o.grepprg = string.format(opts.rg.cmd, wildignore)
+ vim.g.grep_literal_flag = opts.rg.literal_flag
+ vim.o.grepformat = opts.rg.format
+ elseif vim.fn.executable 'ag' == 1 then
+ vim.o.grepprg = string.format(opts.ag.cmd, wildignore)
+ vim.g.grep_literal_flag = opts.ag.literal_flag
+ vim.o.grepformat = opts.ag.format
+ else
+ vim.o.grepprg = string.format(opts.grep.cmd, vim.fn.shellescape(wildignore))
+ vim.g.grep_literal_flag = opts.grep.literal_flag
+ vim.o.grepformat = opts.grep.format
+ end
+end
+
+local function rip_grep_cword(bang, visualmode, search_word)
+ if visualmode then
+ search_word = require('user.utils').get_visual_selection()
+ end
+
+ if not search_word or search_word == '' then
+ search_word = vim.fn.expand ''
+ end
+
+ local search_message_literally = 'for ' .. search_word
+ if bang then
+ search_message_literally = 'literally for ' .. search_word
+ search_word = (vim.g.grep_literal_flag or '') .. ' -- ' .. vim.fn.shellescape(search_word)
+ end
+
+ vim.api.nvim_echo({ { ('Searching ' .. search_message_literally), 'None' } }, false, {})
+ vim.cmd('silent grep! ' .. search_word)
+end
+
+function M.setup(opts)
+ opts = vim.tbl_deep_extend('force', default_opts, opts or {})
+
+ setup_grep(opts)
+
+ -- Create user commands
+ vim.api.nvim_create_user_command('RipGrepCWORD', function(cmd_opts)
+ rip_grep_cword(cmd_opts.bang, false, cmd_opts.args)
+ end, { bang = true, range = true, nargs = '?', complete = 'file_in_path' })
+
+ vim.api.nvim_create_user_command('RipGrepCWORDVisual', function(cmd_opts)
+ rip_grep_cword(cmd_opts.bang, true, cmd_opts.args)
+ end, { bang = true, range = true, nargs = '?', complete = 'file_in_path' })
+
+ -- Map keys
+ vim.keymap.set({ 'n', 'v' }, opts.keymap.search, function()
+ return vim.fn.mode() == 'v' and ':RipGrepCWORDVisual!' or ':RipGrepCWORD!'
+ end, { remap = false, expr = true })
+end
+
+return M
diff --git a/nvim/.config/nvim/lua/user/keymaps.lua b/nvim/.config/nvim/lua/user/keymaps.lua
index 8a2d68f..dbf0ba9 100644
--- a/nvim/.config/nvim/lua/user/keymaps.lua
+++ b/nvim/.config/nvim/lua/user/keymaps.lua
@@ -6,57 +6,57 @@ map({ 'n', 'x' }, '', "v:count == 0 ? 'gj' : 'j'", { desc = 'Down', expr =
map({ 'n', 'x' }, 'k', "v:count == 0 ? 'gk' : 'k'", { desc = 'Up', expr = true, silent = true })
map({ 'n', 'x' }, '', "v:count == 0 ? 'gk' : 'k'", { desc = 'Up', expr = true, silent = true })
--- Select all file visually
-map('n', 'sa', 'ggVG', { remap = false, desc = 'Visually select entire buffer' })
-
-- Map 0 to first non-blank character
-map('n', '0', '^', { remap = false, desc = 'Go to the first non-blank character' })
-map('v', '0', '^', { remap = false, desc = 'Go to the first non-blank character' })
+map({ 'n', 'v' }, '0', '^', { remap = false, desc = 'Go to the first non-blank character' })
--- Move to the end of the line
-map('n', 'L', '$ze10zl', { remap = false, desc = 'Go to the end of the line and move view' })
-map('v', 'L', '$', { remap = false })
-map('n', 'H', '0zs10zh', { remap = false })
-map('v', 'H', '0', { remap = false })
+-- Move view left or right
+map('n', 'L', '5zl', { remap = false, desc = 'Move view to the right' })
+map('v', 'L', '$', { remap = false, desc = 'Move view to the right' })
+map('n', 'H', '5zh', { remap = false, desc = 'Move view to the left' })
+map('v', 'H', '0', { remap = false, desc = 'Move view to the left' })
-- indent/unindent visual mode selection with tab/shift+tab
-map('v', '', '>gv')
-map('v', '', '', '>gv', { desc = 'Indent selected text' })
+map('v', '', '', '')
-map('c', '', '')
-map('c', '', '')
-map('c', '', '')
+map('c', '', '', { desc = 'Move left in command line' })
+map('c', '', '', { desc = 'Move down in command line' })
+map('c', '', '', { desc = 'Move up in command line' })
+map('c', '', '', { desc = 'Move right in command line' })
-- Add undo break-points
-map('i', ',', ',u', { remap = false })
-map('i', '.', '.u', { remap = false })
-map('i', ';', ';u', { remap = false })
+map('i', ',', ',