├── README.md ├── alacritty ├── alacritty.yml └── setup.sh ├── intellij ├── .ideavimrc └── setup.sh ├── lazygit ├── .czrc ├── config.yml └── setup.sh ├── lf ├── lfrc └── setup.sh ├── nvim ├── docs.md ├── init.lua ├── lua │ └── axie │ │ ├── general │ │ ├── init.lua │ │ ├── keymaps.lua │ │ └── options.lua │ │ ├── init.lua │ │ ├── lazy │ │ ├── init.lua │ │ └── lazy-lock.json │ │ ├── migration │ │ ├── old.lua │ │ └── tabular.lua │ │ ├── plugins │ │ ├── editor │ │ │ ├── autolist.lua │ │ │ ├── autopairs.lua │ │ │ ├── biscuits.lua │ │ │ ├── comment.lua │ │ │ ├── copilot.lua │ │ │ ├── debug │ │ │ │ ├── dap.lua │ │ │ │ ├── dap_telescope.lua │ │ │ │ └── dapui.lua │ │ │ ├── indentline.lua │ │ │ ├── init.lua │ │ │ ├── package.lua │ │ │ ├── pasteimage.lua │ │ │ ├── regexplainer.lua │ │ │ ├── test.lua │ │ │ ├── todo.lua │ │ │ └── treesitter.lua │ │ ├── lsp │ │ │ ├── aerial.lua │ │ │ ├── code_actions.lua │ │ │ ├── completion.lua │ │ │ ├── config.lua │ │ │ ├── init.lua │ │ │ ├── install.lua │ │ │ ├── null.lua │ │ │ ├── options.lua │ │ │ ├── rename.lua │ │ │ ├── setup.lua │ │ │ ├── signature.lua │ │ │ └── snippets │ │ │ │ ├── all.lua │ │ │ │ ├── cpp.lua │ │ │ │ ├── init.lua │ │ │ │ ├── lua.lua │ │ │ │ └── markdown.lua │ │ ├── misc │ │ │ ├── firenvim.lua │ │ │ └── init.lua │ │ ├── project │ │ │ ├── diffview.lua │ │ │ ├── gitlinker.lua │ │ │ ├── gitsigns.lua │ │ │ └── init.lua │ │ ├── themes │ │ │ ├── catppuccin.lua │ │ │ ├── init.lua │ │ │ ├── kanagawa.lua │ │ │ ├── material.lua │ │ │ ├── onedark.lua │ │ │ ├── themer.lua │ │ │ └── tundra.lua │ │ ├── ui │ │ │ ├── alpha.lua │ │ │ ├── barbar.lua │ │ │ ├── init.lua │ │ │ ├── neotree.lua │ │ │ ├── notify.lua │ │ │ ├── scrollbar.lua │ │ │ ├── statuscolumn.lua │ │ │ ├── statusline.lua │ │ │ ├── telescope.lua │ │ │ ├── toggleterm.lua │ │ │ ├── urlview.lua │ │ │ ├── whichkey.lua │ │ │ └── zen.lua │ │ └── utility │ │ │ ├── dial.lua │ │ │ ├── hlslens.lua │ │ │ ├── iconpicker.lua │ │ │ ├── init.lua │ │ │ ├── neoscroll.lua │ │ │ └── sessions.lua │ │ ├── utils │ │ ├── config.lua │ │ └── init.lua │ │ └── winbar.lua └── setup.sh ├── picom ├── picom.conf └── setup.sh ├── polybar ├── config.ini ├── launch.sh ├── scripts │ ├── check-arch-updates.sh │ ├── check-aur-updates.sh │ ├── covid.sh │ ├── get_spotify_status.sh │ ├── pavolume.sh │ ├── pub-ip.sh │ ├── scroll_spotify_status.sh │ ├── spotify1.sh │ ├── tempcores.sh │ ├── tesla.sh │ └── weather.py └── setup.sh ├── rofi ├── config.rasi ├── setup.sh └── theme.rasi ├── scripts ├── gitignore.sh └── gitspeed.sh ├── sddm ├── Xsetup ├── setup.sh └── theme.conf ├── selene.toml ├── setup-utilities.sh ├── setup.sh ├── stylua.toml ├── tmux ├── scripts │ ├── aliases.sh │ └── autostart.sh ├── setup.sh └── tmux.conf ├── tools └── setup.sh ├── vim.toml ├── vim ├── .vimrc └── setup.sh ├── xmonad ├── .gitignore ├── scripts │ ├── autostart.sh │ ├── picom-toggle.sh │ ├── set-screen-resolution-in-virtualbox.sh │ └── system-overview ├── setup.sh ├── wall.jpg ├── xmonad-default.hs ├── xmonad.cabal └── xmonad.hs └── zsh ├── .gitignore ├── .zprofile ├── .zsh_linux ├── .zsh_mac ├── .zshenv ├── .zshrc ├── setup.sh ├── spaceship.zsh ├── starship.toml └── utilities.sh /README.md: -------------------------------------------------------------------------------- 1 | # Arch btw 2 | 3 | TODO: use nix 4 | 5 | ## OBS 6 | 7 | Install OBS and v4l2loopback-dkms for virtual camera support (Linux) 8 | -------------------------------------------------------------------------------- /alacritty/alacritty.yml: -------------------------------------------------------------------------------- 1 | font: 2 | normal: 3 | family: JetBrainsMono Nerd Font Mono 4 | style: Regular 5 | bold: 6 | family: JetBrainsMono Nerd Font Mono 7 | style: Bold 8 | italic: 9 | family: JetBrainsMono Nerd Font Mono 10 | style: Italic 11 | bold_italic: 12 | family: JetBrainsMono Nerd Font Mono 13 | style: Bold Italic 14 | 15 | window: 16 | opacity: 0.8 17 | option_as_alt: OnlyLeft 18 | 19 | key_bindings: 20 | # linux 21 | - { key: Return, mods: Shift, chars: "\x1b[13;2u" } 22 | - { key: Return, mods: Control, action: SpawnNewInstance } 23 | # macOS 24 | - { key: T, mods: Command, action: CreateNewWindow } 25 | - { key: N, mods: Command, action: SpawnNewInstance } 26 | - { key: F, mods: Command|Shift, action: ToggleFullScreen } 27 | -------------------------------------------------------------------------------- /alacritty/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install alacritty" 5 | if ! check_dependency alacritty && confirm "$action"; then 6 | if is_linux; then 7 | sudo pacman -S alacritty 8 | elif is_mac; then 9 | brew install --cask alacritty 10 | else 11 | echo "Failed to $action: unsupported OS" 12 | fi 13 | fi 14 | 15 | action="install JetBrains Mono font" 16 | if confirm "$action"; then 17 | if is_linux; then 18 | yay -S ttf-jetbrains-mono-nerd 19 | elif is_mac; then 20 | brew tap homebrew/cask-fonts 21 | brew install --cask font-jetbrains-mono-nerd-font 22 | else 23 | echo "Failed to $action: unsupported OS" 24 | fi 25 | fi 26 | 27 | action="link config" 28 | if confirm "$action"; then 29 | link_config $HOME/dotconfig/alacritty/alacritty.yml $HOME/.config/alacritty/alacritty.yml 30 | fi 31 | 32 | action="set up tabs" 33 | if is_mac && confirm "$action"; then 34 | defaults write org.alacritty AppleWindowTabbingMode -string always 35 | fi 36 | -------------------------------------------------------------------------------- /intellij/.ideavimrc: -------------------------------------------------------------------------------- 1 | source ~/.vimrc 2 | 3 | set ideajoin 4 | set ideamarks 5 | set idearefactormode=keep 6 | 7 | map s :source ~/.ideavimrc 8 | map w :write 9 | map a (GotoAction) 10 | map z (ToggleZenMode) 11 | map ff (GotoFile) 12 | map fg (FindInPath) 13 | 14 | map gg (ActivateCommitToolWindow) 15 | map gG (Git.Menu) 16 | map g; (Annotate) 17 | map gw (Github.Open.In.Browser) 18 | map gp (Github.Create.Pull.Request) 19 | map gdb (Git.CompareWithBranch) 20 | 21 | map (FileStructurePopup) 22 | map (NextTab) 23 | map (PreviousTab) 24 | map \\ (FileStructurePopup) 25 | 26 | map [d (GotoPrevError) 27 | map ]d (GotoNextError) 28 | map [f (MethodUp) 29 | map ]f (MethodDown) 30 | nmap ]g (VcsShowNextChangeMarker) 31 | nmap [g (VcsShowPrevChangeMarker) 32 | nmap [m (MethodUp) 33 | nmap ]m (MethodDown) 34 | 35 | map K (QuickJavaDoc) 36 | map gK (ShowErrorDescription) 37 | map gD (GotoTypeDeclaration) 38 | map gr (FindUsages) 39 | map gi (QuickImplementations) 40 | map gx gd 41 | map ra (ShowIntentionActions) 42 | map rA (Refactorings.QuickListPopupAction) 43 | map rr (Generate) 44 | map rn (RenameElement) 45 | map rN (RenameFile) 46 | map rc (Coverage) 47 | 48 | map tt (RunClass) 49 | map tT (DebugClass) 50 | 51 | map db (ToggleLineBreakpoint) 52 | map dB (EditBreakpoint) 53 | map dc (ChooseDebugConfiguration) 54 | map dC (Debug) 55 | map dj (StepOut) 56 | map dk (StepInto) 57 | map dl (StepOver) 58 | map dq (Stop) 59 | map d; (ActivateDebugToolWindow) 60 | map d/ (ViewBreakpoints) 61 | 62 | let g:NERDTreeMapQuit = ';' 63 | 64 | " NOTE: requires Which-Key plugin from Marketplace 65 | set which-key 66 | set notimeout 67 | let g:WhichKey_ShowVimActions = "true" 68 | let g:WhichKey_DefaultDelay = 1000 69 | 70 | " TODO: https://youtrack.jetbrains.com/issue/VIM-2178 for multiple cursors 71 | -------------------------------------------------------------------------------- /intellij/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="link IdeaVim config" 5 | if confirm "$action"; then 6 | link_config "$HOME/dotconfig/intellij/.ideavimrc" "$HOME/.ideavimrc" 7 | fi 8 | 9 | action="disable MacOS press and hold" 10 | if confirm "$action"; then 11 | defaults write -g ApplePressAndHoldEnabled -bool false 12 | fi 13 | -------------------------------------------------------------------------------- /lazygit/.czrc: -------------------------------------------------------------------------------- 1 | // vim: set ft=json: 2 | { "path": "cz-conventional-changelog" } 3 | -------------------------------------------------------------------------------- /lazygit/config.yml: -------------------------------------------------------------------------------- 1 | keybinding: 2 | universal: 3 | openRecentRepos: "" 4 | createPatchOptionsMenu: "" 5 | 6 | customCommands: 7 | - key: "Z" 8 | context: "files" 9 | command: "git cz" 10 | description: "commit with commitizen" 11 | loadingText: "opening commitizen commit tool" 12 | subprocess: true 13 | - key: "" 14 | context: "global" 15 | command: "git push --force" 16 | description: "git force push" 17 | loadingText: "push (force, without --force-with-lease)" 18 | prompts: 19 | - type: "confirm" 20 | title: "Confirm:" 21 | body: "Are you sure you want to force push to {{.CheckedOutBranch.Name}}?" 22 | - key: "G" 23 | context: "localBranches" 24 | command: "gh pr checkout {{index .PromptResponses 0}}" 25 | description: "check out GitHub PR" 26 | loadingText: "checking out PR" 27 | prompts: 28 | - type: "input" 29 | title: "GitHub PR #id:" 30 | - key: "" 31 | context: "localBranches" 32 | command: "{{index .PromptResponses 0}} {{.SelectedLocalBranch.Name}}" 33 | description: "git rebase (onto checked-out branch)" 34 | loadingText: "rebasing" 35 | prompts: 36 | - type: "menu" 37 | title: "Rebase '{{.SelectedLocalBranch.Name}}' onto '{{.CheckedOutBranch.Name}}'" 38 | options: 39 | - name: "simple rebase" 40 | value: "git rebase" 41 | - name: "interactive rebase" 42 | value: "git rebase --interactive" 43 | -------------------------------------------------------------------------------- /lazygit/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install lazygit" 5 | if ! check_dependency lazygit && confirm "$action"; then 6 | if is_linux; then 7 | sudo pacman -S lazygit 8 | elif is_mac; then 9 | brew install lazygit 10 | else 11 | echo "Failed to $action: unsupported OS" 12 | fi 13 | fi 14 | 15 | action="install commitizen" 16 | if ! check_dependency commitizen && confirm "$action"; then 17 | npm install -g commitizen cz-conventional-changelog 18 | fi 19 | 20 | action="link commitizen config" 21 | if confirm "$action"; then 22 | link_config "$HOME/dotconfig/lazygit/.czrc" "$HOME/.czrc" 23 | fi 24 | 25 | action="link lazygit config" 26 | if confirm "$action"; then 27 | if is_linux; then 28 | link_config "$HOME/dotconfig/lazygit/config.yml" "$HOME/.config/lazygit/config.yml" 29 | elif is_mac; then 30 | link_config "$HOME/dotconfig/lazygit/config.yml" "$HOME/Library/Application Support/lazygit/config.yml" 31 | else 32 | echo "Failed to $action: unsupported OS" 33 | fi 34 | fi 35 | -------------------------------------------------------------------------------- /lf/lfrc: -------------------------------------------------------------------------------- 1 | # zoxide integration 2 | cmd z %{{ 3 | result="$(zoxide query --exclude $PWD $@)" 4 | lf -remote "send $id cd $result" 5 | }} 6 | 7 | cmd zi ${{ 8 | result="$(zoxide query -i)" 9 | lf -remote "send $id cd $result" 10 | }} 11 | 12 | # trash-cli integration 13 | cmd trash %trash-put $fx 14 | 15 | # cd 16 | cmd dump ${{ 17 | set -f 18 | # if file under cursor, use parent directory instead 19 | [[ -f $f ]] && dir=$PWD || dir=$f 20 | echo $dir > /tmp/lf-last-dir 21 | }} 22 | 23 | cmd q quit 24 | map o open 25 | map E push :dumpq 26 | -------------------------------------------------------------------------------- /lf/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install lf" 5 | if ! check_dependency "lf" && confirm "$action"; then 6 | if is_linux; then 7 | sudo pacman -S lf 8 | elif is_mac; then 9 | brew install lf 10 | else 11 | echo "Failed to $action: unsupported OS" 12 | fi 13 | fi 14 | 15 | action="link config" 16 | if confirm "$action"; then 17 | link_config "$HOME/dotconfig/lf/lfrc" "$HOME/.config/lf/lfrc" 18 | fi 19 | -------------------------------------------------------------------------------- /nvim/init.lua: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------- 2 | ----------------------------------------------------------- 3 | -- _____ ____ ___.______________ _____ ____ ___ -- 4 | -- / _ \ \ \/ /| \_ _____/ / _ \ \ \/ / -- 5 | -- / /_\ \ \ / | || __)_ / /_\ \ \ / -- 6 | -- / | \/ \ | || \/ | \/ \ -- 7 | -- \____|__ /___/\ \|___/_______ /\____|__ /___/\ \ -- 8 | -- \/ \_/ \/ \/ \_/ -- 9 | ----------------------------------------------------------- 10 | ----------------------------------------------------------- 11 | 12 | vim.loader.enable() 13 | require("axie") 14 | -- require("minimal") 15 | -------------------------------------------------------------------------------- /nvim/lua/axie/general/init.lua: -------------------------------------------------------------------------------- 1 | local utils = require("axie.utils") 2 | local override_filetype = utils.override_filetype 3 | 4 | -- Disable relative numbers for insert mode 5 | local numberToggleGroup = vim.api.nvim_create_augroup("NumberToggle", { clear = true }) 6 | vim.api.nvim_create_autocmd("InsertLeave", { 7 | desc = "Enable relative numbers", 8 | group = numberToggleGroup, 9 | callback = function() 10 | local ignored = { "TelescopePrompt" } 11 | if not vim.tbl_contains(ignored, vim.bo.filetype) then 12 | vim.opt_local.relativenumber = true 13 | end 14 | end, 15 | }) 16 | vim.api.nvim_create_autocmd("InsertEnter", { 17 | desc = "Disable relative numbers", 18 | group = numberToggleGroup, 19 | callback = function() 20 | vim.opt_local.relativenumber = false 21 | end, 22 | }) 23 | 24 | vim.api.nvim_create_autocmd("VimResized", { 25 | desc = "autoresize nvim", 26 | command = "wincmd =", 27 | }) 28 | 29 | vim.api.nvim_create_autocmd("TextYankPost", { 30 | desc = "highlight yank", 31 | callback = function() 32 | vim.highlight.on_yank({ higroup = "IncSearch", timeout = 200 }) 33 | end, 34 | }) 35 | 36 | -- Write and quit typos 37 | local typos = { "W", "Wq", "WQ", "Wqa", "WQa", "WQA", "WqA", "Q", "Qa", "QA" } 38 | for _, cmd in ipairs(typos) do 39 | vim.api.nvim_create_user_command(cmd, function(opts) 40 | vim.api.nvim_cmd({ 41 | cmd = cmd:lower(), 42 | bang = opts.bang, 43 | mods = { noautocmd = true }, 44 | }, {}) 45 | end, { bang = true }) 46 | end 47 | 48 | -- Terraform filetypes 49 | override_filetype({ ".*%.terraformrc", ".*%.terraform.rc" }, "terraform") 50 | override_filetype({ ".*%.tfstate" }, "json") 51 | -------------------------------------------------------------------------------- /nvim/lua/axie/general/options.lua: -------------------------------------------------------------------------------- 1 | local default_folds = require("axie.utils.config").default_folds 2 | local vim_apply = require("axie.utils").vim_apply 3 | 4 | -- TODO: https://github.com/tpope/vim-sensible/blob/master/plugin/sensible.vim 5 | -- Grouped by :options 6 | vim_apply(vim.opt, { 7 | -- 2 moving around, searching and patterns 8 | whichwrap = "bs<>", 9 | incsearch = true, -- live search preview 10 | inccommand = "split", -- live substitution preview 11 | ignorecase = true, 12 | smartcase = true, 13 | 14 | -- 4 displaying text 15 | scrolloff = 1, 16 | sidescrolloff = 2, 17 | -- NOTE: pretty-fold configures the `fold` fillchar 18 | fillchars = { foldclose = "", foldopen = "", foldsep = " " }, 19 | list = true, 20 | -- NOTE: indent-blankline covers first tab character so not visible 21 | listchars = { tab = "→ ", trail = "·", extends = "▶", precedes = "◀", nbsp = "␣" }, 22 | number = true, 23 | relativenumber = true, 24 | numberwidth = 1, 25 | 26 | -- 5 syntax, highlighting and spelling 27 | hlsearch = true, 28 | termguicolors = true, 29 | cursorline = true, 30 | -- cursorcolumn = true, 31 | colorcolumn = "80", 32 | -- spell = true, 33 | spelllang = "en_au", 34 | 35 | -- 6 multiple windows 36 | laststatus = 3, 37 | hidden = true, 38 | splitbelow = true, 39 | splitright = true, 40 | pumblend = 15, 41 | 42 | -- 9 using the mouse 43 | mouse = "a", 44 | mousemodel = "extend", 45 | 46 | -- 11 messages and info 47 | showmode = false, 48 | ruler = true, 49 | 50 | -- 13 editing text 51 | undofile = true, -- persistent undo 52 | completeopt = { "menu", "menuone", "noselect" }, 53 | showmatch = true, 54 | 55 | -- 14 tabs and indenting 56 | -- REF: https://arisweedler.medium.com/tab-settings-in-vim-1ea0863c5990 57 | tabstop = 2, 58 | shiftwidth = 2, 59 | expandtab = true, 60 | softtabstop = 2, 61 | autoindent = true, 62 | smartindent = true, 63 | -- cindent = true, -- fix markdown code block indents, but may randomly indent sometimes 64 | -- cinoptions 65 | 66 | -- 15 folding (zopen/zclose, zReveal/zMinimise) 67 | -- TODO: use TS query to find all functions/methods - vifzc, repeat with classes, then zR 68 | -- BUG: sometimes opened folds close to default level when switching focus (if not ":e") 69 | foldenable = default_folds, 70 | foldlevel = 0, -- default levels folded 71 | foldlevelstart = 0, -- default for functional languages 72 | foldcolumn = "auto", 73 | foldmethod = "expr", 74 | foldexpr = "v:lua.vim.treesitter.foldexpr()", 75 | -- foldminlines = 1, -- min lines required for a fold (default) 76 | -- foldnestmax = 3, -- maximum nesting of folds 77 | 78 | -- 18 reading and writing files 79 | writebackup = true, 80 | autoread = true, 81 | 82 | -- 19 the swap file 83 | swapfile = false, 84 | -- updatetime = 1500, 85 | 86 | -- 20 command line editing 87 | wildmode = "full", 88 | wildmenu = true, 89 | wildoptions = "tagfile", 90 | 91 | -- 25 various 92 | -- signcolumn = "number", -- TODO: find a way put symbol next to line number 93 | }) 94 | 95 | -- vim.opt.cpoptions:append(">") 96 | 97 | -- netrw settings (for directory tree view) 98 | vim_apply(vim.g, { 99 | -- loaded_netrw = 1, -- disables netrw 100 | netrw_liststyle = 3, -- tree style 101 | netrw_preview = 1, -- vertical splits for previews 102 | netrw_altv = true, -- opens vsplit to right 103 | }) 104 | 105 | -- NOTE: want comment continue in some cases (e.g. java(s) docstring) 106 | vim.api.nvim_create_autocmd("BufEnter", { 107 | desc = "Disable automatic comment insertion", 108 | group = vim.api.nvim_create_augroup("AutoComment", {}), 109 | callback = function() 110 | vim.opt_local.formatoptions:remove({ "c", "r", "o" }) 111 | end, 112 | }) 113 | 114 | -- Enable spellcheck conditionally based on filetypes 115 | vim.api.nvim_create_autocmd("BufEnter", { 116 | desc = "Enable spellcheck", 117 | group = vim.api.nvim_create_augroup("SpellCheck", {}), 118 | callback = function() 119 | local ft = vim.bo.filetype 120 | local enabled_filetypes = { "markdown", "text", "" } 121 | if vim.tbl_contains(enabled_filetypes, ft) or vim.fn.empty(vim.bo.filetype) ~= 0 then 122 | vim.opt_local.spell = true 123 | end 124 | end, 125 | }) 126 | 127 | -- Filetype foldlevelstart override 128 | if default_folds then 129 | local foldlevels = { 130 | java = 2, 131 | markdown = 1, 132 | } 133 | vim.api.nvim_create_autocmd("FileType", { 134 | desc = "Larger fold level", 135 | pattern = vim.tbl_keys(foldlevels), 136 | callback = function(opts) 137 | local filetype = vim.api.nvim_buf_get_option(opts.buf, "filetype") 138 | vim.opt_local.foldlevel = foldlevels[filetype] 139 | end, 140 | }) 141 | end 142 | -------------------------------------------------------------------------------- /nvim/lua/axie/init.lua: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------- 2 | ----------------------------------------------------------- 3 | -- _____ ____ ___.______________ _____ ____ ___ -- 4 | -- / _ \ \ \/ /| \_ _____/ / _ \ \ \/ / -- 5 | -- / /_\ \ \ / | || __)_ / /_\ \ \ / -- 6 | -- / | \/ \ | || \/ | \/ \ -- 7 | -- \____|__ /___/\ \|___/_______ /\____|__ /___/\ \ -- 8 | -- \/ \_/ \/ \/ \_/ -- 9 | ----------------------------------------------------------- 10 | ----------------------------------------------------------- 11 | 12 | -- General config 13 | require("axie.general") 14 | require("axie.general.options") 15 | require("axie.general.keymaps") 16 | 17 | -- Plugins config 18 | require("axie.lazy").setup() 19 | 20 | -- Set up language servers 21 | require("axie.plugins.lsp.setup").servers() 22 | 23 | -- Winbar 24 | require("axie.winbar").activate() 25 | -------------------------------------------------------------------------------- /nvim/lua/axie/lazy/init.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local utils = require("axie.utils") 4 | 5 | function M.bootstrap() 6 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 7 | if not vim.loop.fs_stat(lazypath) then 8 | vim.fn.system({ 9 | "git", 10 | "clone", 11 | "--filter=blob:none", 12 | "--single-branch", 13 | "https://github.com/folke/lazy.nvim.git", 14 | lazypath, 15 | }) 16 | end 17 | vim.opt.runtimepath:prepend(lazypath) 18 | end 19 | 20 | function M.report_startuptime() 21 | vim.api.nvim_create_autocmd("User", { 22 | pattern = "LazyVimStarted", 23 | group = vim.api.nvim_create_augroup("LazyStartuptime", {}), 24 | callback = function() 25 | local stats = require("lazy").stats() 26 | vim.notify(string.format(" Startup Time: %.3f ms", stats.startuptime), vim.log.levels.WARN) 27 | vim.defer_fn(function() 28 | vim.api.nvim_echo({ { "" } }, false, {}) 29 | end, 3000) 30 | require("axie.plugins.ui.alpha").update_startuptime(stats.loaded, stats.startuptime) 31 | end, 32 | }) 33 | end 34 | 35 | function M.init() 36 | vim.keymap.set("n", "s", "Lazy") 37 | end 38 | 39 | function M.setup() 40 | M.bootstrap() 41 | M.init() 42 | M.report_startuptime() 43 | 44 | local colorscheme = require("axie.utils.config").colorscheme 45 | require("lazy").setup("axie.plugins", { 46 | defaults = { lazy = true }, 47 | concurrency = utils.get_os() == "mac" and 50 or nil, 48 | lockfile = vim.fn.expand("~/dotconfig/nvim/lua/axie/lazy/lazy-lock.json"), 49 | dev = { path = vim.fn.expand("~/dev/nvim-plugins"), fallback = true }, 50 | install = { 51 | missing = true, 52 | colorscheme = { colorscheme }, 53 | }, 54 | checker = { enabled = true, notify = false }, 55 | }) 56 | require("lazy.view.config").dimmed_commits = 57 | { "build", "chore", "ci", "doc", "style", "refactor", "perf", "test", "fix", "highlight", "injection", "indents" } 58 | end 59 | 60 | local resolve_keys = { "config", "init", "keys", "cmd", "opts" } 61 | 62 | function M.transform_spec(specs, category) 63 | return vim.tbl_map(function(spec) 64 | -- Make all tables 65 | if type(spec) == "string" then 66 | spec = { spec } 67 | end 68 | local plugin_name = spec[1] 69 | 70 | -- Resolve keys automatically 71 | local mod_name = spec.settings 72 | if type(mod_name) == "string" then 73 | if not string.match(mod_name, "%.") then 74 | mod_name = string.format("plugins.%s.%s", category, mod_name) 75 | end 76 | mod_name = "axie." .. mod_name 77 | 78 | local ok, mod = pcall(require, mod_name) 79 | if not ok then 80 | utils.notify(string.format("%s: failed to load module %s", plugin_name, mod_name), vim.log.levels.ERROR) 81 | vim.notify(string.format("-- ERROR LOADING: %s --\n%s", plugin_name, vim.inspect(mod)), vim.log.levels.ERROR) 82 | else 83 | for _, resolve_key in ipairs(resolve_keys) do 84 | if mod[resolve_key] then 85 | spec[resolve_key] = mod[resolve_key] 86 | end 87 | end 88 | end 89 | spec.settings = nil 90 | end 91 | 92 | -- Recursively transform dependencies 93 | if type(spec.dependencies) == "table" then 94 | spec.dependencies = M.transform_spec(spec.dependencies, category) 95 | end 96 | 97 | return spec 98 | end, specs) 99 | end 100 | 101 | return M 102 | -------------------------------------------------------------------------------- /nvim/lua/axie/migration/old.lua: -------------------------------------------------------------------------------- 1 | ----------------------- 2 | -- General Utilities -- 3 | ----------------------- 4 | local general_utilities = function(use) 5 | -- Emacs Orgmode 6 | -- ALT: vimwiki (more for notes/diary), neorg (too different from md), mind.nvim 7 | -- NOTE: https://github.com/nvim-orgmode/orgmode/blob/master/DOCS.md#getting-started-with-orgmode 8 | -- POSSIBLE: can this use vim.ui.select? 9 | -- TRY: https://github.com/nvim-neorg/neorg-telescope 10 | -- TRY: https://github.com/danymat/neorg-gtd-things 11 | -- ALT: mind.nvim 12 | -- NOTE: remove treesitter.lua org if not using 13 | use({ 14 | "nvim-orgmode/orgmode", 15 | requires = { 16 | "nvim-treesitter/nvim-treesitter", 17 | "akinsho/org-bullets.nvim", 18 | }, 19 | config = function() 20 | local orgmode = require("orgmode") 21 | orgmode.setup_ts_grammar() 22 | orgmode.setup({ 23 | org_agenda_file = { "~/wiki/**" }, 24 | mappings = { 25 | global = { 26 | org_agenda = "oa", 27 | org_capture = "oc", 28 | }, 29 | }, 30 | }) 31 | end, 32 | }) 33 | 34 | -- Stabilise buffers 35 | -- TEMP: replace with `splitkeep` 36 | use({ 37 | "luukvbaal/stabilize.nvim", 38 | config = function() 39 | -- for stabilising quickfix list (trouble.nvim) 40 | require("stabilize").setup({ 41 | nested = "QuickFixCmdPost,DiagnosticChanged *", 42 | }) 43 | end, 44 | }) 45 | 46 | -- Focused splits 47 | -- ALT: https://github.com/anuvyklack/windows.nvim 48 | use({ 49 | "beauwilliams/focus.nvim", 50 | -- TODO: cmds 51 | event = "BufEnter", 52 | keys = { 53 | { "\\f", "FocusToggle", desc = "Focus toggle" }, 54 | { "\\z", "FocusMaxOrEqual", desc = "Maximise toggle" }, 55 | }, 56 | config = function() 57 | local colorcolumn_width = 80 -- NOTE: for some reason `tonumber(vim.o.colorcolumn)` doesn't work 58 | require("focus").setup({ 59 | -- TEMP: https://github.com/beauwilliams/focus.nvim/issues/82 60 | autoresize = false, 61 | cursorline = false, 62 | number = false, 63 | signcolumn = false, 64 | colorcolumn = { enable = true, width = colorcolumn_width }, 65 | excluded_filetypes = { "toggleterm", "qf", "help", "Mundo" }, 66 | }) 67 | end, 68 | }) 69 | 70 | -- Open with sudo 71 | -- NOTE: eunuch requires an askpass helper, suda.vim asks for password everytime 72 | -- use("tpope/vim-eunuch") 73 | use({ 74 | "lambdalisue/suda.vim", 75 | cmd = { "SudaRead", "SudaWrite" }, 76 | }) 77 | 78 | -- howdoi query 79 | use({ 80 | "zane-/howdoi.nvim", 81 | after = "telescope.nvim", 82 | config = function() 83 | local telescope = require("telescope") 84 | telescope.load_extension("howdoi") 85 | vim.keymap.set("n", "fH", telescope.extensions.howdoi.howdoi) 86 | end, 87 | }) 88 | end 89 | 90 | ------------------ 91 | -- UI Utilities -- 92 | ------------------ 93 | local ui_utilities = function(use) 94 | -- Shade inactive windows 95 | -- NOTE: doesn't work with transparent backgrounds https://github.com/sunjon/Shade.nvim/issues/7 96 | use({ 97 | "sunjon/shade.nvim", 98 | disable = true, 99 | config = function() 100 | require("shade").setup({ 101 | overlay_opacity = 90, 102 | opacity_step = 1, 103 | keys = { 104 | -- leader z instead of s? 105 | brightness_up = "sk", 106 | brightness_down = "sj", 107 | toggle = "ss", 108 | }, 109 | }) 110 | end, 111 | }) 112 | 113 | -- Highlight based on mode 114 | use({ 115 | "mvllow/modes.nvim", 116 | disable = true, 117 | config = function() 118 | require("modes").setup() 119 | end, 120 | }) 121 | end 122 | 123 | ----------------------------------- 124 | -- General Programming Utilities -- 125 | ----------------------------------- 126 | local general_programming_utilities = function(use) 127 | -- Align lines by character 128 | use("godlygeek/tabular", "tabular") 129 | end 130 | 131 | --------------------------------- 132 | -- Compilation, Test and Debug -- 133 | --------------------------------- 134 | local compilation_test_debug = function(use) 135 | -- Interactive scratchpad with virtual text?? 136 | use("metakirby5/codi.vim") 137 | 138 | -- Jupyter notebook 139 | 140 | -- Code runner 141 | -- NOTE: doesn't support many languages, nor REPL mode 142 | -- ALT: https://github.com/michaelb/sniprun (full file support?) 143 | -- ALT: iron.nvim 144 | use({ 145 | "arjunmahishi/run-code.nvim", 146 | cmd = { "RunCodeBlock", "RunCodeFile", "RunCodeSelected", "ReloadRunCode" }, 147 | setup = function() 148 | local filetype_map = require("axie.utils").filetype_map 149 | vim.keymap.set("n", "\\r", "RunCodeFile") 150 | vim.keymap.set("v", "\\r", "RunCodeSelected") 151 | filetype_map("markdown", "n", "\\r", "RunCodeBlock") 152 | end, 153 | }) 154 | 155 | -- Make 156 | use("neomake/neomake") 157 | 158 | -- Compiler (e.g. :Dispatch python3.9 %) 159 | use("tpope/vim-dispatch") 160 | end 161 | 162 | ------------------- 163 | -- LSP Utilities -- 164 | ------------------- 165 | local lsp_utilities = function(use) 166 | -- LSP diagnostics lines 167 | use({ 168 | "https://git.sr.ht/~whynothugo/lsp_lines.nvim", 169 | disable = true, 170 | config = function() 171 | local lsp_lines = require("lsp_lines") 172 | lsp_lines.setup() 173 | vim.diagnostic.config({ virtual_text = false }) 174 | vim.keymap.set("", "l|", lsp_lines.toggle, { desc = "toggle lsp lines" }) 175 | end, 176 | }) 177 | 178 | -- Code action menu with diff preview 179 | -- NOTE: seems like lspsaga has this https://dev.neovim.pro/lspsaga/codeaction/ 180 | use({ 181 | "weilbith/nvim-code-action-menu", 182 | disable = true, 183 | cmd = "CodeActionMenu", 184 | }) 185 | 186 | -- Markdown code block edit 187 | use({ 188 | "AckslD/nvim-FeMaco.lua", 189 | cmd = "FeMaco", 190 | ft = "markdown", 191 | keys = { { ",e", "FeMaco", desc = "Edit code block" } }, 192 | opts = { 193 | post_open_float = function(winnr) 194 | vim.api.nvim_win_set_option(winnr, "winblend", 10) 195 | end, 196 | }, 197 | }) 198 | end 199 | -------------------------------------------------------------------------------- /nvim/lua/axie/migration/tabular.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.setup() 4 | -- NOTE: Prettier removes this automatic alignment 5 | -- USE: 6 | vim.keymap.set( 7 | "i", 8 | "|", 9 | "|:lua require('axie.plugins.tabular').md_cucumber_table()a", 10 | { desc = "markdown cucumber table automatic alignment", silent = true } 11 | ) 12 | end 13 | 14 | -- Auto align for markdown cucumber table 15 | -- https://gist.github.com/tpope/287147#gistcomment-3637398 16 | function M.md_cucumber_table() 17 | if vim.bo.filetype ~= "markdown" then 18 | return 19 | end 20 | 21 | local cmd = vim.cmd 22 | local fn = vim.fn 23 | local pattern = "^%s*|%s.*%s|%s*$" 24 | local lineNumber = fn.line(".") 25 | local currentColumn = fn.col(".") 26 | local previousLine = fn.getline(lineNumber - 1) 27 | local currentLine = fn.getline(".") 28 | local nextLine = fn.getline(lineNumber + 1) 29 | 30 | if 31 | fn.exists(":Tabularize") 32 | and currentLine:match("^%s*|") 33 | and (previousLine:match(pattern) or nextLine:match(pattern)) 34 | then 35 | local column = #currentLine:sub(1, currentColumn):gsub("[^|]", "") 36 | local position = #fn.matchstr(currentLine:sub(1, currentColumn), ".*|\\s*\\zs.*") 37 | cmd("Tabularize/|/l1") -- `l` means left aligned and `1` means one space of cell padding 38 | cmd("normal! 0") 39 | fn.search(("[^|]*|"):rep(column) .. ("\\s\\{-\\}"):rep(position), "ce", lineNumber) 40 | end 41 | end 42 | 43 | return M 44 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/autolist.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | local autolist = require("autolist") 5 | autolist.setup() 6 | autolist.create_mapping_hook("i", "", autolist.new) 7 | autolist.create_mapping_hook("i", "", autolist.indent) 8 | autolist.create_mapping_hook("i", "", autolist.indent, "") 9 | autolist.create_mapping_hook("n", "dd", autolist.force_recalculate) 10 | autolist.create_mapping_hook("n", "o", autolist.new) 11 | autolist.create_mapping_hook("n", "O", autolist.new_before) 12 | autolist.create_mapping_hook("n", ">>", autolist.indent) 13 | autolist.create_mapping_hook("n", "<<", autolist.indent) 14 | autolist.create_mapping_hook("n", "", autolist.force_recalculate) 15 | autolist.create_mapping_hook("n", "x", autolist.invert_entry, "") 16 | end 17 | 18 | return M 19 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/autopairs.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- insert mode "alt-e" 4 | -- NOTE: vim surround visual selection: S_ as well 5 | M.opts = { fast_wrap = {} } 6 | 7 | function M.config(_, opts) 8 | require("nvim-autopairs").setup(opts) 9 | 10 | local cmp_autopairs = require("nvim-autopairs.completion.cmp") 11 | local cmp = require("cmp") 12 | cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) 13 | end 14 | 15 | return M 16 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/biscuits.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.opts = { 4 | on_events = { "CursorMoved", "CursorMovedI" }, 5 | toggle_keybind = "", 6 | show_on_start = false, 7 | -- cursor_line_only = true, 8 | default_config = { 9 | max_length = 24, 10 | min_distance = 4, 11 | prefix_string = " 󰘍 ", 12 | }, 13 | } 14 | 15 | return M 16 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/comment.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { { "gc", mode = { "n", "v" } }, { "gb", mode = { "n", "v" } } } 4 | 5 | function M.config() 6 | require("Comment").setup({ 7 | pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(), 8 | ignore = "^$", -- ignore empty lines 9 | }) 10 | 11 | ---Textobject for adjacent commented lines (gcgc, gcu) 12 | -- TEMP: https://github.com/numToStr/Comment.nvim/issues/22 13 | local function commented_lines_textobject() 14 | local U = require("Comment.utils") 15 | local cl = vim.api.nvim_win_get_cursor(0)[1] -- current line 16 | local range = { srow = cl, scol = 0, erow = cl, ecol = 0 } 17 | local ctx = { 18 | ctype = U.ctype.linewise, 19 | range = range, 20 | } 21 | local cstr = require("Comment.ft").calculate(ctx) or vim.bo.commentstring 22 | local ll, rr = U.unwrap_cstr(cstr) 23 | local padding = true 24 | local is_commented = U.is_commented(ll, rr, padding) 25 | 26 | local line = vim.api.nvim_buf_get_lines(0, cl - 1, cl, false) 27 | if next(line) == nil or not is_commented(line[1]) then 28 | return 29 | end 30 | 31 | local rs, re = cl, cl -- range start and end 32 | repeat 33 | rs = rs - 1 34 | line = vim.api.nvim_buf_get_lines(0, rs - 1, rs, false) 35 | until next(line) == nil or not is_commented(line[1]) 36 | rs = rs + 1 37 | repeat 38 | re = re + 1 39 | line = vim.api.nvim_buf_get_lines(0, re - 1, re, false) 40 | until next(line) == nil or not is_commented(line[1]) 41 | re = re - 1 42 | 43 | vim.fn.execute("normal! " .. rs .. "GV" .. re .. "G") 44 | end 45 | 46 | for _, keymap in ipairs({ "gc", "u" }) do 47 | vim.keymap.set( 48 | "o", 49 | keymap, 50 | commented_lines_textobject, 51 | { silent = true, desc = "Textobject for adjacent commented lines" } 52 | ) 53 | end 54 | end 55 | 56 | return M 57 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/copilot.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = "Copilot" 4 | 5 | M.keys = { 6 | -- https://github.com/community/community/discussions/29817#discussioncomment-4217615 7 | { "", "copilot#Accept()", mode = "i", expr = true, silent = true, replace_keycodes = false }, 8 | { "", "copilot#Dismiss()", mode = "i", expr = true, silent = true }, 9 | { "", "copilot#Previous()", mode = "i", expr = true, silent = true }, 10 | { "", "copilot#Next()", mode = "i", expr = true, silent = true }, 11 | { "", "Copilot panel", mode = "i" }, 12 | } 13 | 14 | function M.init() 15 | vim.g.copilot_enabled = require("axie.utils.config").copilot_enabled 16 | vim.g.copilot_no_tab_map = true 17 | 18 | -- vim.api.nvim_set_hl(0, "CopilotSuggestion", { fg = "#6c7086" }) -- Catppuccin Overlay0 19 | end 20 | 21 | return M 22 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/debug/dap.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: up down bindings 4 | M.keys = { 5 | { 6 | "d.", 7 | function() 8 | require("dap").run_last() 9 | end, 10 | desc = "Run last", 11 | }, 12 | { 13 | "db", 14 | function() 15 | require("dap").toggle_breakpoint() 16 | end, 17 | desc = "Toggle breakpoint", 18 | }, 19 | { 20 | "dB", 21 | function() 22 | local condition = vim.fn.input("Breakpoint condition: ") 23 | require("dap").set_breakpoint(condition) 24 | end, 25 | desc = "Set conditional breakpoint", 26 | }, 27 | { 28 | "dj", 29 | function() 30 | require("dap").step_out() 31 | end, 32 | desc = "Step out", 33 | }, 34 | { 35 | "dk", 36 | function() 37 | require("dap").step_into() 38 | end, 39 | desc = "Step into", 40 | }, 41 | { 42 | "dl", 43 | function() 44 | require("dap").step_over() 45 | end, 46 | desc = "Step over", 47 | }, 48 | { 49 | "dq", 50 | function() 51 | require("dap").close() 52 | end, 53 | desc = "Close", 54 | }, 55 | { 56 | "dK", 57 | function() 58 | require("dap.ui.widgets").hover() 59 | end, 60 | desc = "Hover", 61 | }, 62 | } 63 | 64 | function M.config() 65 | local sign = function(name, opts) 66 | opts = vim.tbl_extend("keep", opts, { 67 | linehl = "", 68 | numhl = "", 69 | }) 70 | vim.fn.sign_define(name, opts) 71 | end 72 | 73 | sign("DapBreakpoint", { text = "●", texthl = "DapBreakpoint" }) 74 | sign("DapBreakpointCondition", { text = "●", texthl = "DapBreakpointCondition" }) 75 | sign("DapLogPoint", { text = "◆", texthl = "DapLogPoint" }) 76 | end 77 | 78 | return M 79 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/debug/dap_telescope.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { 5 | "dc", 6 | function() 7 | require("telescope").extensions.dap.configurations() 8 | end, 9 | desc = "Configurations", 10 | }, 11 | { 12 | "d?", 13 | function() 14 | require("telescope").extensions.dap.commands() 15 | end, 16 | desc = "Commands", 17 | }, 18 | { 19 | "df", 20 | function() 21 | require("telescope").extensions.dap.frames() 22 | end, 23 | desc = "Frames", 24 | }, 25 | { 26 | "dv", 27 | function() 28 | require("telescope").extensions.dap.variables() 29 | end, 30 | desc = "Variables", 31 | }, 32 | { 33 | "d/", 34 | function() 35 | require("telescope").extensions.dap.list_breakpoints() 36 | end, 37 | desc = "Breakpoints", 38 | }, 39 | } 40 | 41 | return M 42 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/debug/dapui.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.opts = { 4 | layouts = { 5 | { 6 | elements = { 7 | -- Elements can be strings or table with id and size keys. 8 | { id = "scopes", size = 0.25 }, 9 | "breakpoints", 10 | "stacks", 11 | "watches", 12 | }, 13 | size = 40, -- 40 columns 14 | position = "left", 15 | }, 16 | { 17 | elements = { 18 | { id = "repl", size = 0.3 }, 19 | { id = "console", size = 0.7 }, 20 | }, 21 | size = 0.25, -- 25% of total lines 22 | position = "bottom", 23 | }, 24 | }, 25 | } 26 | 27 | function M.config(_, opts) 28 | local dap = require("dap") 29 | local dapui = require("dapui") 30 | dapui.setup(opts) 31 | 32 | -- Open terminal to side 33 | local dapui_terminal = dap.defaults.fallback.terminal_win_cmd 34 | dap.defaults.fallback.terminal_win_cmd = function() 35 | local result = dapui_terminal() 36 | dapui.open(2) -- open dapui repl + console 37 | return result 38 | end 39 | 40 | vim.keymap.set("n", "d;", function() 41 | local windows = require("dapui.windows") 42 | -- just repl + console open 43 | if not windows.layouts[1]:is_open() and windows.layouts[2]:is_open() then 44 | dapui.close(2) 45 | end 46 | dapui.toggle() 47 | end, { desc = "Toggle UI" }) 48 | vim.keymap.set("n", "dd", function() 49 | dapui.toggle(2) 50 | end, { desc = "Toggle UI console" }) 51 | end 52 | return M 53 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/indentline.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { { "\\i", "IndentBlankLineToggle", desc = "Toggle indent line" } } 4 | 5 | M.opts = { 6 | char = "▏", 7 | show_current_context = true, 8 | show_current_context_start = true, 9 | use_treesitter = true, 10 | -- TODO: incorporate more default g:indent_blankline_context_patterns? 11 | context_patterns = { 12 | "class", 13 | "return", 14 | "function", 15 | "method", 16 | "^if", 17 | "if", 18 | "^while", 19 | "jsx_element", 20 | "^for", 21 | "for", 22 | "^object", 23 | "^table", 24 | "block", 25 | "arguments", 26 | "if_statement", 27 | "else_clause", 28 | "jsx_element", 29 | "jsx_self_closing_element", 30 | "try_statement", 31 | "catch_clause", 32 | "import_statement", 33 | "operation_type", 34 | }, 35 | -- exclude vim which key 36 | filetype_exclude = { 37 | "terminal", 38 | "alpha", 39 | "help", 40 | "man", 41 | "lspinfo", 42 | "toggleterm", 43 | "glowpreview", 44 | "checkhealth", 45 | "aerial", 46 | "", 47 | }, 48 | -- char_highlight_list = { 49 | -- "IndentBlanklineIndent1", 50 | -- "IndentBlanklineIndent2", 51 | -- "IndentBlanklineIndent3", 52 | -- "IndentBlanklineIndent4", 53 | -- "IndentBlanklineIndent5", 54 | -- "IndentBlanklineIndent6", 55 | -- }, 56 | } 57 | 58 | return M 59 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/init.lua: -------------------------------------------------------------------------------- 1 | local spec = { 2 | -- ALT: https://github.com/zbirenbaum/copilot.lua with https://github.com/zbirenbaum/copilot-cmp 3 | { "github/copilot.vim", event = "InsertEnter", settings = "copilot" }, 4 | { 5 | "jackMort/ChatGPT.nvim", 6 | cmd = { "ChatGPT", "ChatGPTActAs", "ChatGPTEditWithInstructions" }, 7 | keys = { 8 | { "rc", "ChatGPT", desc = "ChatGPT" }, 9 | { 10 | "rC", 11 | "ChatGPTEditWithInstructions", 12 | desc = "ChatGPTEditWithInstructions", 13 | mode = { "n", "v" }, 14 | }, 15 | { "rk", "ChatGPTActAs", desc = "ChatGPTActAs" }, 16 | }, 17 | opts = { popup_input = { submit = "" } }, 18 | }, 19 | { "folke/todo-comments.nvim", event = "VeryLazy", settings = "todo" }, 20 | 21 | { 22 | -- TODO: automatically install parsers for new file types (don't download all) 23 | "nvim-treesitter/nvim-treesitter", 24 | build = ":TSUpdate", 25 | event = "BufReadPost", 26 | settings = "treesitter", 27 | }, 28 | { "nvim-treesitter/nvim-treesitter-textobjects", event = "BufReadPost" }, 29 | -- TODO: use fork https://github.com/HiPhish/nvim-ts-rainbow2 instead? 30 | -- https://github.com/HiPhish/rainbow-delimiters.nvim 31 | { "p00f/nvim-ts-rainbow", event = "BufReadPost" }, 32 | { "lukas-reineke/indent-blankline.nvim", event = "BufReadPost", settings = "indentline" }, 33 | { "code-biscuits/nvim-biscuits", event = "BufReadPost", settings = "biscuits" }, 34 | { "zbirenbaum/neodim", branch = "v2", event = "LspAttach", config = true }, 35 | { 36 | "danymat/neogen", 37 | cmd = "Neogen", 38 | keys = { { "/", "Neogen", desc = "Generate docstring" } }, 39 | opts = { snippet_engine = "luasnip" }, 40 | }, 41 | { 42 | "numToStr/Comment.nvim", 43 | -- language-aware commentstring 44 | dependencies = "JoosepAlviste/nvim-ts-context-commentstring", 45 | settings = "comment", 46 | }, 47 | { "tpope/vim-surround", event = "VeryLazy" }, 48 | { 49 | "andymass/vim-matchup", 50 | event = "BufReadPost", 51 | config = function() 52 | vim.g.matchup_matchparen_offscreen = { method = "status_manual" } 53 | vim.cmd.highlight("MatchParen", "guibg=NONE") 54 | end, 55 | }, 56 | { "windwp/nvim-autopairs", event = "InsertEnter", settings = "autopairs" }, 57 | { 58 | "windwp/nvim-ts-autotag", 59 | ft = { 60 | "html", 61 | "javascript", 62 | "typescript", 63 | "javascriptreact", 64 | "typescriptreact", 65 | "svelte", 66 | "vue", 67 | "tsx", 68 | "jsx", 69 | "rescript", 70 | "xml", 71 | "php", 72 | "markdown", 73 | "glimmer", 74 | "handlebars", 75 | "hbs", 76 | }, 77 | config = true, 78 | }, 79 | -- NOTE: requires treesitter regex 80 | { "bennypowers/nvim-regexplainer", build = ":TSUpdate regex", settings = "regexplainer" }, 81 | { "nacro90/numb.nvim", event = "CmdlineEnter", opts = { number_only = true } }, 82 | 83 | -- IDE tools 84 | { 85 | "mfussenegger/nvim-dap", 86 | dependencies = { 87 | { "rcarriga/nvim-dap-ui", settings = "plugins.editor.debug.dapui" }, 88 | { "theHamsta/nvim-dap-virtual-text", config = true }, 89 | }, 90 | settings = "plugins.editor.debug.dap", 91 | }, 92 | { "nvim-telescope/telescope-dap.nvim", settings = "plugins.editor.debug.dap_telescope" }, 93 | { 94 | "mfussenegger/nvim-dap-python", 95 | ft = "python", 96 | config = function() 97 | -- SETUP: pip install debugpy 98 | local dap_python = require("dap-python") 99 | dap_python.setup() 100 | dap_python.test_runner = "pytest" 101 | end, 102 | }, 103 | { 104 | "jbyuki/one-small-step-for-vimkind", 105 | ft = "lua", 106 | config = function() 107 | local dap = require("dap") 108 | dap.configurations.lua = { 109 | { 110 | type = "nlua", 111 | request = "attach", 112 | name = "Attach to running Neovim instance", 113 | }, 114 | } 115 | 116 | dap.adapters.nlua = function(callback, config) 117 | callback({ type = "server", host = config.host or "127.0.0.1", port = config.port or 8086 }) 118 | end 119 | end, 120 | }, 121 | 122 | { 123 | "nvim-neotest/neotest", 124 | cmd = "Neotest", 125 | dependencies = { 126 | "nvim-lua/plenary.nvim", 127 | "nvim-neotest/neotest-go", 128 | "haydenmeade/neotest-jest", 129 | "nvim-neotest/neotest-python", 130 | "nvim-neotest/neotest-plenary", 131 | -- "mrcjkb/neotest-haskell", 132 | { "nvim-neotest/neotest-vim-test", dependencies = "vim-test/vim-test" }, 133 | }, 134 | settings = "test", 135 | }, 136 | 137 | -- Python indenting issues 138 | -- https://github.com/nvim-treesitter/nvim-treesitter/issues/1136 139 | { "Vimjas/vim-python-pep8-indent", ft = "python" }, 140 | { "vuki656/package-info.nvim", ft = "json", settings = "package" }, 141 | { 142 | -- NOTE: requires xclip (X11), wl-clipboard (Wayland) or pngpaste (MacOS) 143 | "ekickx/clipboard-image.nvim", 144 | ft = { "markdown", "latex", "plaintex", "tex", "org" }, 145 | settings = "pasteimage", 146 | }, 147 | { 148 | "iamcco/markdown-preview.nvim", 149 | ft = "markdown", 150 | build = function() 151 | vim.fn["mkdp#util#install"]() 152 | end, 153 | keys = { { ",O", "MarkdownPreview" } }, 154 | }, 155 | { 156 | "ellisonleao/glow.nvim", 157 | ft = "markdown", 158 | keys = { { ",o", "Glow" } }, 159 | opts = { 160 | border = "rounded", 161 | pager = false, 162 | }, 163 | }, 164 | { 165 | -- NOTE: (tab) to indent after auto continue, (dedent) to unindent 166 | "gaoDean/autolist.nvim", 167 | ft = { "markdown", "text", "txt", "tex", "plaintex" }, 168 | dependencies = { "hrsh7th/nvim-cmp", "windwp/nvim-autopairs" }, 169 | settings = "autolist", 170 | }, 171 | } 172 | 173 | return require("axie.lazy").transform_spec(spec, "editor") 174 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/package.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { 5 | ",pp", 6 | function() 7 | require("package-info").toggle() 8 | end, 9 | desc = "Toggle package versions", 10 | }, 11 | { 12 | ",pu", 13 | function() 14 | require("package-info").update() 15 | end, 16 | desc = "Update package", 17 | }, 18 | { 19 | ",pd", 20 | function() 21 | require("package-info").delete() 22 | end, 23 | desc = "Delete package", 24 | }, 25 | { 26 | ",pi", 27 | function() 28 | require("package-info").install() 29 | end, 30 | desc = "Install package", 31 | }, 32 | { 33 | ",pv", 34 | function() 35 | require("package-info").change_version() 36 | end, 37 | desc = "Change version", 38 | }, 39 | } 40 | 41 | M.config = true 42 | 43 | return M 44 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/pasteimage.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { { ",p", "PasteImg", desc = "Paste image" } } 4 | 5 | function M.config() 6 | local relative_dir = vim.fn.fnamemodify(vim.fn.expand("%"), ":h") 7 | local request_img_name = function() 8 | vim.fn.inputsave() 9 | local name = vim.fn.input("Image Name: ") 10 | vim.fn.inputrestore() 11 | return name ~= "" and name or os.date("%Y-%m-%d-%H-%M-%S") 12 | end 13 | 14 | require("clipboard-image").setup({ 15 | default = { 16 | img_dir = "images", 17 | img_dir_txt = "images", 18 | img_name = request_img_name, 19 | }, 20 | markdown = { 21 | -- img_dir = { relative_dir, "images" }, -- relative to current buffer file 22 | img_dir = relative_dir .. "/images", -- relative to current buffer file 23 | }, 24 | }) 25 | end 26 | 27 | return M 28 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/regexplainer.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = { 4 | "RegexplainerShow", 5 | "RegexplainerHide", 6 | "RegexplainerToggle", 7 | "RegexplainerYank", 8 | "RegexplainerShowSplit", 9 | "RegexplainerShowPopup", 10 | "RegexplainerDebug", 11 | } 12 | 13 | M.keys = { "gR" } 14 | 15 | M.opts = { 16 | auto = false, 17 | display = "popup", 18 | popup = { 19 | border = { 20 | padding = { 0, 0 }, 21 | style = "rounded", 22 | }, 23 | win_options = { winblend = 20 }, 24 | }, 25 | mappings = { toggle = "gR" }, 26 | } 27 | 28 | return M 29 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/test.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- 1 for just status, 2 for reason, 3 for topmost stack trace, etc. 4 | local ERROR_LIMIT = 3 5 | 6 | function M.test_summary() 7 | local notify = require("axie.utils").notify 8 | local buffers = vim.api.nvim_list_bufs() 9 | for _, bufnr in ipairs(buffers) do 10 | -- find result buffer 11 | local buf_name = vim.api.nvim_buf_get_name(bufnr) 12 | if buf_name:find("[dap-repl]", 0, 1) then 13 | -- display notification 14 | local buf_lines = vim.api.nvim_buf_get_lines(bufnr, 1, -1, false) 15 | 16 | local notification = "" 17 | local error_line_count = 0 18 | for _, line in ipairs(buf_lines) do 19 | if line:find("^[✔️❌]") then 20 | error_line_count = 0 21 | else 22 | -- Normal line within error block 23 | error_line_count = error_line_count + 1 24 | end 25 | 26 | if error_line_count < ERROR_LIMIT then 27 | notification = notification .. line .. "\n" 28 | end 29 | end 30 | 31 | notify(notification:sub(0, -2)) 32 | return 33 | end 34 | end 35 | notify("No tests found 😢", vim.log.levels.ERROR) 36 | end 37 | 38 | M.keys = { 39 | { 40 | "tt", 41 | function() 42 | require("neotest").run.run() 43 | end, 44 | desc = "Test nearest", 45 | }, 46 | { 47 | "tT", 48 | function() 49 | require("neotest").run.run({ strategy = "dap" }) 50 | end, 51 | desc = "Debug nearest", 52 | }, 53 | { 54 | "tf", 55 | function() 56 | require("neotest").run.run(vim.fn.expand("%")) 57 | end, 58 | desc = "Test file", 59 | }, 60 | { 61 | "tF", 62 | function() 63 | require("neotest").run.run({ vim.fn.expand("%"), strategy = "dap" }) 64 | end, 65 | desc = "Debug file", 66 | }, 67 | { 68 | "tr", 69 | function() 70 | require("neotest").run.run_last() 71 | end, 72 | desc = "Test last", 73 | }, 74 | { 75 | "tR", 76 | function() 77 | require("neotest").run.run_last({ strategy = "dap" }) 78 | end, 79 | desc = "Debug last", 80 | }, 81 | { 82 | "t;", 83 | function() 84 | -- TODO: enter = true 85 | require("neotest").summary.toggle() 86 | end, 87 | desc = "Test summary", 88 | }, 89 | { 90 | "tp", 91 | function() 92 | require("neotest").output.open() 93 | end, 94 | desc = "Test output", 95 | }, 96 | { 97 | "tP", 98 | function() 99 | require("neotest").output_panel.toggle() 100 | end, 101 | desc = "Test output panel", 102 | }, 103 | { 104 | "tq", 105 | function() 106 | require("neotest").run.stop() 107 | end, 108 | desc = "Quit test", 109 | }, 110 | { 111 | "[t", 112 | function() 113 | require("neotest").jump.prev({ status = "failed" }) 114 | end, 115 | desc = "Previous failed test", 116 | }, 117 | { 118 | "]t", 119 | function() 120 | require("neotest").jump.next({ status = "failed" }) 121 | end, 122 | desc = "Next failed test", 123 | }, 124 | { 125 | "[T", 126 | function() 127 | require("neotest").jump.prev() 128 | end, 129 | desc = "Previous test", 130 | }, 131 | { 132 | "]T", 133 | function() 134 | require("neotest").jump.next() 135 | end, 136 | desc = "Next test", 137 | }, 138 | } 139 | 140 | function M.config() 141 | local adapter_config = { 142 | go = { 143 | filetypes = { "go" }, 144 | }, 145 | jest = { 146 | filetypes = { "javascript", "typescript", "javascriptreact", "typescriptreact", "coffee" }, 147 | }, 148 | python = { 149 | filetypes = { "python" }, 150 | runner = "pytest", 151 | }, 152 | plenary = { 153 | filetypes = { "lua" }, 154 | }, 155 | -- haskell = { 156 | -- filetypes = { "haskell" }, 157 | -- }, 158 | } 159 | 160 | local adapters = {} 161 | local adapter_filetypes = {} 162 | for adapter, opts in pairs(adapter_config) do 163 | local ok, neotest_adapter = pcall(require, "neotest-" .. adapter) 164 | if ok then 165 | table.insert(adapters, neotest_adapter(opts)) 166 | vim.list_extend(adapter_filetypes, opts.filetypes) 167 | else 168 | require("axie.utils").notify(string.format("Could not load neotest-%s adapter", adapter), vim.log.levels.ERROR) 169 | end 170 | end 171 | 172 | table.insert(adapters, require("neotest-vim-test")({ ignore_file_types = adapter_filetypes })) 173 | 174 | require("neotest").setup({ 175 | adapters = adapters, 176 | -- floating = { options = { winblend = 80 } }, 177 | quickfix = { open = false }, 178 | }) 179 | end 180 | 181 | return M 182 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/editor/todo.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { 5 | "[c", 6 | function() 7 | require("todo-comments").jump_prev() 8 | end, 9 | desc = "Previous todo comment", 10 | }, 11 | { 12 | "]c", 13 | function() 14 | require("todo-comments").jump_next() 15 | end, 16 | desc = "Next todo comment", 17 | }, 18 | { 19 | "fq", 20 | "TodoQuickFix", 21 | desc = "Project todo comments", 22 | }, 23 | } 24 | 25 | M.opts = { 26 | keywords = { 27 | FIX = { 28 | icon = " ", 29 | color = "error", 30 | alt = { "FIXME", "BUG", "BAD", "FIXIT", "ISSUE", "HELP", "PRIOR", "PRIORITY", "PROBLEM" }, 31 | }, 32 | WARN = { 33 | icon = " ", 34 | color = "error", 35 | alt = { "WARNING", "XXX", "BAD", "ERROR" }, 36 | }, 37 | TODO = { 38 | icon = " ", 39 | color = "hint", 40 | alt = { "NEW", "ACTION", "ACTIONABLE", "OPTIONAL", "MAYBE" }, 41 | }, 42 | HACK = { 43 | icon = "󰈸 ", 44 | color = "warning", 45 | alt = { "TEMP", "TEMPORARY", "CHANGE", "UPDATE", "CONFIRM", "CHECK" }, 46 | }, 47 | PERF = { 48 | icon = " ", 49 | color = "warning", 50 | alt = { "PERFORMANCE", "OPTIM", "OPTIMIZE", "OPTIMISE", "EFFICIENCY", "TEST", "EXT", "EXTENSION" }, 51 | }, 52 | NOTE = { 53 | icon = "󰍨 ", 54 | color = "info", 55 | alt = { 56 | "INFO", 57 | "INSTALL", 58 | "SETUP", 59 | "GUIDE", 60 | "ASSUMPTION", 61 | "ASSUME", 62 | "ASSUMES", 63 | "SOURCE", 64 | "REFERENCE", 65 | "REF", 66 | "REFACTOR", 67 | "DEP", 68 | "DEPENDENCY", 69 | "DEPENDENCIES", 70 | }, 71 | }, 72 | QUESTION = { 73 | icon = " ", 74 | color = "error", 75 | alt = { "IDK", "THOUGHT", "POSSIBLE" }, 76 | }, 77 | BOOKMARK = { 78 | icon = " ", 79 | color = "warning", 80 | alt = { 81 | "READ", 82 | "WATCH", 83 | "LOOK", 84 | "SEE", 85 | "REVIEW", 86 | "HERE", 87 | "IMPORTANT", 88 | "BIG", 89 | "LINK", 90 | "USEFUL", 91 | "HELPFUL", 92 | }, 93 | }, 94 | IDEA = { 95 | icon = " ", 96 | color = "hint", 97 | alt = { "SUGGEST", "SUGGESTION", "TRY", "CONSIDER", "ALT", "ALTERNATIVE", "INSPO", "INSPIRATION", "RANDOM" }, 98 | }, 99 | FORK = { 100 | icon = " ", 101 | color = "hint", 102 | }, 103 | }, 104 | highlight = { 105 | pattern = [[.*<(KEYWORDS)\s*]], 106 | before = "empty", 107 | keyword = "bg", 108 | after = "fg", 109 | }, 110 | search = { 111 | -- NOTE: doesn't seem to work 112 | -- regex that will be used to match keywords. 113 | -- don't replace the (KEYWORDS) placeholder 114 | -- pattern = [[\b(KEYWORDS):]], -- ripgrep regex 115 | pattern = [[\b(KEYWORDS)\b]], -- match without the extra colon. You'll likely get false positives 116 | }, 117 | } 118 | 119 | return M 120 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/aerial.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { "", "AerialToggle", desc = "Aerial symbols" }, 5 | { "\\", "AerialNavToggle", desc = "Aerial nav" }, 6 | } 7 | 8 | function M.config() 9 | local aerial = require("aerial") 10 | aerial.setup({ 11 | -- close_behavior = "close", 12 | highlight_on_hover = true, 13 | highlight_on_jump = 200, 14 | close_on_select = true, 15 | -- fold code from tree (overwrites treesitter foldexpr) 16 | manage_folds = false, 17 | -- link_tree_to_folds = true, 18 | -- link_folds_to_tree = true, 19 | show_guides = true, 20 | guides = { 21 | mid_item = "│ ", 22 | last_item = "└ ", 23 | }, 24 | filter_kind = false, 25 | icons = require("axie.utils.config").symbol_icons, 26 | -- fall back to treesitter if LSP not available 27 | backends = { "lsp", "treesitter", "markdown", "man" }, 28 | keymaps = { 29 | ["<"] = { 30 | callback = aerial.tree_decrease_fold_level, 31 | desc = "Decrease the fold level of the tree", 32 | nowait = true, 33 | }, 34 | [">"] = { 35 | callback = aerial.tree_increase_fold_level, 36 | desc = "Increase the fold level of the tree", 37 | nowait = true, 38 | }, 39 | }, 40 | }) 41 | end 42 | 43 | return M 44 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/code_actions.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---Filter lsp results 4 | local function filter_null(lsp_results) 5 | for client_id, _ in pairs(lsp_results) do 6 | if vim.lsp.get_client_by_id(client_id).name == "null-ls" then 7 | lsp_results[client_id] = nil 8 | break 9 | end 10 | end 11 | return lsp_results 12 | end 13 | 14 | ---Builtin vim.lsp.buf.code_actions 15 | ---@param ignore_null_ls boolean|nil @Optional parameter to ignore null-ls (default: false) 16 | ---@param context table|nil @Optional parameter to pass to vim.lsp.buf.code_actions 17 | function M.native(ignore_null_ls, context) 18 | ignore_null_ls = ignore_null_ls or false 19 | 20 | -- Override vim.notify 21 | local original_notify = vim.notify 22 | vim.notify = function() 23 | vim.api.nvim_echo({ { "󰇸 No code actions available", "WarningMsg" } }, false, {}) 24 | end 25 | 26 | -- Attach to vim.lsp.buf_request_all 27 | local buf_request_all = vim.lsp.buf_request_all 28 | vim.lsp.buf_request_all = function(bufnr, method, params, callback) 29 | return buf_request_all(bufnr, method, params, function(lsp_results) 30 | vim.lsp.buf_request_all = buf_request_all 31 | if ignore_null_ls then 32 | lsp_results = filter_null(lsp_results) 33 | end 34 | 35 | local res = callback(lsp_results) 36 | vim.notify = original_notify 37 | return res 38 | end) 39 | end 40 | 41 | vim.lsp.buf.code_action({ context = context }) 42 | end 43 | 44 | local lightbulb_enabled = false 45 | 46 | function M.setup_lightbulb() 47 | if not lightbulb_enabled then 48 | vim.api.nvim_create_autocmd({ "CursorHold" }, { 49 | desc = "Check for available code actions", 50 | group = vim.api.nvim_create_augroup("LightBulb", {}), 51 | callback = function() 52 | local bufnr = vim.api.nvim_get_current_buf() 53 | local context = { diagnostics = vim.lsp.diagnostic.get_line_diagnostics() } 54 | local params = vim.lsp.util.make_range_params() 55 | params.context = context 56 | 57 | vim.lsp.buf_request_all(bufnr, "textDocument/codeAction", params, function(results) 58 | results = vim.tbl_filter(function(result) 59 | return not vim.tbl_isempty(result) 60 | end, filter_null(results)) 61 | 62 | local status = vim.tbl_isempty(results) and "" or " Code Action Available" 63 | vim.api.nvim_echo({ { status, "WarningMsg" } }, false, {}) 64 | end) 65 | end, 66 | }) 67 | lightbulb_enabled = true 68 | end 69 | end 70 | 71 | return M 72 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/completion.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local DEFAULT_PRIORITY = 2 4 | 5 | function M.config() 6 | -- setup cmp 7 | local cmp = require("cmp") 8 | local lspkind = require("lspkind") 9 | 10 | local sources = { 11 | -- copilot = { label = "Copilot", priority = 4 }, 12 | nvim_lsp = { label = "LSP", priority = 3 }, 13 | buffer = { label = "Buffer", priority = 1 }, 14 | luasnip = { label = "LuaSnip", priority = 5 }, 15 | path = { label = "Path" }, 16 | calc = { label = "Calc" }, 17 | emoji = { label = "Emoji" }, 18 | spell = { label = "Spell", priority = 1 }, 19 | latex_symbols = { label = "LaTeX" }, 20 | npm = { label = "npm" }, 21 | git = { label = "Git" }, 22 | -- cmdline = { label = "[Cmd]" }, 23 | orgmode = { label = "Org" }, 24 | -- treesitter = "[TS]", 25 | -- ["vim-dadbod-completion"] = "[DB]", 26 | } 27 | 28 | local source_config = {} 29 | for source_name, source_settings in pairs(sources) do 30 | table.insert(source_config, { 31 | name = source_name, 32 | priority = source_settings.priority or DEFAULT_PRIORITY, 33 | }) 34 | end 35 | 36 | local function cmp_map(...) 37 | return cmp.mapping(..., { "i", "c" }) 38 | end 39 | 40 | local function filter_mode(mappings, mode) 41 | local res = {} 42 | for k, v in pairs(mappings) do 43 | if v[mode] then 44 | res[k] = { [mode] = v[mode] } 45 | end 46 | end 47 | return res 48 | end 49 | 50 | local mappings = { 51 | [""] = cmp_map(cmp.mapping.scroll_docs(-4)), 52 | [""] = cmp_map(cmp.mapping.scroll_docs(4)), 53 | [""] = { 54 | i = cmp.mapping.abort(), 55 | c = cmp.mapping.close(), 56 | }, 57 | [""] = cmp_map(cmp.mapping.confirm({ 58 | behavior = cmp.ConfirmBehavior.Insert, 59 | select = false, 60 | })), 61 | -- Toggle cmp menu 62 | -- [""] = cmp_map(cmp.mapping.complete()), 63 | [""] = { 64 | i = function() 65 | if cmp.visible() then 66 | cmp.abort() 67 | else 68 | cmp.complete() 69 | end 70 | end, 71 | c = function() 72 | if cmp.visible() then 73 | cmp.close() 74 | else 75 | cmp.complete() 76 | end 77 | end, 78 | }, 79 | [""] = { 80 | i = function(fallback) 81 | if cmp.visible() then 82 | cmp.select_next_item() 83 | else 84 | fallback() 85 | end 86 | end, 87 | c = function() 88 | if cmp.visible() then 89 | cmp.select_next_item() 90 | else 91 | -- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", true, true, true), "ni", true) 92 | vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", true, false, true), "tn", false) 93 | end 94 | end, 95 | }, 96 | [""] = { 97 | i = function(fallback) 98 | if cmp.visible() then 99 | cmp.select_prev_item() 100 | else 101 | fallback() 102 | end 103 | end, 104 | c = function() 105 | if cmp.visible() then 106 | cmp.select_next_item() 107 | else 108 | vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", true, false, true), "tn", false) 109 | end 110 | end, 111 | }, 112 | } 113 | 114 | cmp.setup({ 115 | -- preselect = cmp.PreselectMode.None, 116 | snippet = { 117 | expand = function(args) 118 | require("luasnip").lsp_expand(args.body) 119 | end, 120 | }, 121 | mapping = cmp.mapping.preset.insert(filter_mode(mappings, "i")), 122 | sources = source_config, 123 | formatting = { 124 | fields = { "kind", "abbr", "menu" }, 125 | format = lspkind.cmp_format({ 126 | mode = "symbol", 127 | before = function(entry, vim_item) 128 | local source = sources[entry.source.name] 129 | vim_item.kind = source.kind or vim_item.kind 130 | vim_item.menu = "[" .. source.label .. "]" 131 | -- vim_item.menu = source.label 132 | return vim_item 133 | end, 134 | }), 135 | }, 136 | sorting = { 137 | comparators = { 138 | cmp.config.compare.offset, 139 | cmp.config.compare.exact, 140 | cmp.config.compare.score, 141 | require("cmp-under-comparator").under, 142 | cmp.config.compare.kind, 143 | cmp.config.compare.sort_text, 144 | cmp.config.compare.length, 145 | cmp.config.compare.order, 146 | }, 147 | }, 148 | experimental = { 149 | ghost_text = true, -- preview 150 | }, 151 | }) 152 | 153 | -- Command mode completion 154 | local cmdline_mappings = cmp.mapping.preset.cmdline(filter_mode(mappings, "c")) 155 | local cmdline_view = { entries = "wildmenu" } 156 | 157 | -- Use buffer source for `/`. 158 | cmp.setup.cmdline("/", { 159 | mapping = cmdline_mappings, 160 | view = cmdline_view, 161 | sources = { 162 | { name = "buffer" }, 163 | }, 164 | }) 165 | 166 | -- Use cmdline & path source for ':'. 167 | cmp.setup.cmdline(":", { 168 | mapping = cmdline_mappings, 169 | view = cmdline_view, 170 | sources = cmp.config.sources({ 171 | { name = "path" }, 172 | }, { 173 | -- { name = "cmdline" }, 174 | }), 175 | }) 176 | end 177 | 178 | return M 179 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/config.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: filter/sort severity? 4 | -- Highlight line number instead of icons (https://github.com/neovim/nvim-lspconfig/wiki/UI-customization#highlight-line-number-instead-of-having-icons-in-sign-column) 5 | 6 | M.keys = { 7 | { "l?", "LspInfo" }, 8 | { "lR", "LspRestart" }, 9 | } 10 | 11 | function M.config() 12 | local diagnostics_icons = require("axie.utils.config").diagnostics_icons 13 | 14 | -- Gutter diagnostic symbols 15 | for type, icon in pairs(diagnostics_icons) do 16 | local hl = "DiagnosticSign" .. type 17 | vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl }) 18 | end 19 | 20 | -- Diagnostic virtual text 21 | vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { 22 | virtual_text = { 23 | prefix = diagnostics_icons.VirtualText, 24 | spacing = 4, 25 | source = "always", 26 | format = function(diagnostic) 27 | return string.format("%s [%s]", diagnostic.message, diagnostic.source) 28 | end, 29 | }, 30 | signs = true, 31 | underline = true, 32 | update_in_insert = true, 33 | }) 34 | 35 | -- Diagnostic source 36 | vim.diagnostic.config({ 37 | float = { source = "always" }, 38 | }) 39 | 40 | -- Hover rounded borders with transparent background 41 | local function customise_handler(handler) 42 | local overrides = { border = "rounded" } 43 | return vim.lsp.with(function(...) 44 | local _, winnr = handler(...) 45 | if winnr then 46 | vim.api.nvim_win_set_option(winnr, "winblend", 20) 47 | end 48 | end, overrides) 49 | end 50 | 51 | vim.lsp.handlers["textDocument/hover"] = customise_handler(vim.lsp.handlers.hover) 52 | vim.lsp.handlers["textDocument/signatureHelp"] = customise_handler(vim.lsp.handlers.signature_help) 53 | 54 | -- LspInfo rounded borders 55 | require("lspconfig.ui.windows").default_options.border = "rounded" 56 | vim.api.nvim_set_hl(0, "LspInfoBorder", { link = "FloatBorder" }) 57 | 58 | -- Code actions lightbulb 59 | vim.api.nvim_create_autocmd("LspAttach", { 60 | group = vim.api.nvim_create_augroup("LightbulbSetup", {}), 61 | callback = require("axie.plugins.lsp.code_actions").setup_lightbulb, 62 | }) 63 | end 64 | 65 | return M 66 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/init.lua: -------------------------------------------------------------------------------- 1 | local spec = { 2 | -- LSP setup 3 | { "neovim/nvim-lspconfig", settings = "config" }, 4 | { 5 | "williamboman/mason.nvim", 6 | lazy = false, 7 | dependencies = { 8 | "williamboman/mason-lspconfig.nvim", 9 | "WhoIsSethDaniel/mason-tool-installer.nvim", 10 | }, 11 | settings = "install", 12 | }, 13 | { "jose-elias-alvarez/null-ls.nvim", event = "VeryLazy", settings = "null" }, 14 | "ThePrimeagen/refactoring.nvim", 15 | "CKolkey/ts-node-action", 16 | 17 | -- LSP server extensions 18 | -- "jose-elias-alvarez/typescript.nvim", -- for dynamic renames? 19 | "b0o/schemastore.nvim", 20 | "folke/neodev.nvim", 21 | { 22 | "mfussenegger/nvim-jdtls", 23 | init = function() 24 | local filetype_map = require("axie.utils").filetype_map 25 | filetype_map("java", "n", "tm", function() 26 | require("jdtls").test_nearest_method({ 27 | after_test = require("axie.plugins.editor.test").test_summary, 28 | }) 29 | end, { desc = "Test method" }) 30 | filetype_map("java", "n", "tc", function() 31 | require("jdtls").test_class({ 32 | after_test = require("axie.plugins.editor.test").test_summary, 33 | }) 34 | end, { desc = "Test class" }) 35 | filetype_map("java", "n", "t;", function() 36 | require("axie.plugins.editor.test").test_summary() 37 | end, { desc = "Test summary" }) 38 | end, 39 | }, 40 | "simrat39/rust-tools.nvim", 41 | 42 | -- LSP essentials 43 | { 44 | "hrsh7th/nvim-cmp", 45 | event = { "InsertEnter", "CmdlineEnter" }, 46 | dependencies = { 47 | "hrsh7th/cmp-nvim-lsp", 48 | "onsails/lspkind-nvim", 49 | "lukas-reineke/cmp-under-comparator", 50 | "saadparwaiz1/cmp_luasnip", 51 | "hrsh7th/cmp-buffer", 52 | "hrsh7th/cmp-path", 53 | "hrsh7th/cmp-calc", 54 | "hrsh7th/cmp-emoji", 55 | -- "hrsh7th/cmp-cmdline", 56 | "f3fora/cmp-spell", 57 | "kdheepak/cmp-latex-symbols", 58 | { "David-Kunz/cmp-npm", ft = "json", config = true }, 59 | { "petertriho/cmp-git", opts = { filetypes = { "*" } } }, 60 | -- "quangnguyen30192/cmp-nvim-tags", 61 | -- "tpope/vim-dadbod", 62 | -- "kristijanhusak/vim-dadbod-ui", 63 | -- "kristijanhusak/vim-dadbod-completion", 64 | -- "tzachar/cmp-fzy-buffer", 65 | -- "tzachar/cmp-fuzzy-path", 66 | }, 67 | settings = "completion", 68 | }, 69 | { 70 | "L3MON4D3/LuaSnip", 71 | event = "InsertEnter", 72 | dependencies = "rafamadriz/friendly-snippets", -- snippet collection 73 | settings = "snippets", 74 | }, 75 | 76 | "ray-x/lsp_signature.nvim", 77 | { 78 | "lvimuser/lsp-inlayhints.nvim", 79 | opts = { inlay_hints = { highlight = "Comment" } }, 80 | }, 81 | 82 | -- LSP utils 83 | { "stevearc/aerial.nvim", settings = "aerial" }, 84 | { 85 | "j-hui/fidget.nvim", 86 | tag = "legacy", 87 | event = "LspAttach", 88 | opts = { window = { relative = "editor", blend = 0 } }, 89 | }, 90 | } 91 | 92 | return require("axie.lazy").transform_spec(spec, "lsp") 93 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/install.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { "lI", "Mason", desc = "LSP installer" }, 5 | { "lU", "MasonToolsUpdate", desc = "Update Mason tools" }, 6 | } 7 | 8 | function M.config() 9 | -- setup lspconfig 10 | require("mason").setup() 11 | require("mason-lspconfig").setup() 12 | 13 | -- auto install 14 | local ensure_installed = require("axie.plugins.lsp.setup").ensure_installed 15 | local null_ensure_installed = require("axie.plugins.lsp.null").ensure_installed 16 | vim.list_extend(ensure_installed, null_ensure_installed) 17 | 18 | require("mason-tool-installer").setup({ 19 | ensure_installed = ensure_installed, 20 | auto_update = false, 21 | run_on_start = true, 22 | }) 23 | end 24 | 25 | return M 26 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/null.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.ensure_installed = { 4 | "stylua", 5 | -- formatter -- 6 | "black", 7 | "isort", 8 | -- "goimports", 9 | "prettierd", 10 | "shfmt", 11 | -- "google-java-format", 12 | -- linter -- 13 | -- "selene", 14 | "editorconfig-checker", 15 | -- "golangci-lint", 16 | "pylint", 17 | "shellcheck", 18 | } 19 | 20 | -- Use null-ls formatting if any of the given filetypes is supported 21 | -- @param ls_filetypes of language server to be checked 22 | function M.use_null_formatting(filetype) 23 | local null_ls = require("null-ls") 24 | local null_ls_sources = require("null-ls.sources") 25 | 26 | local sources = null_ls_sources.get_available(filetype, null_ls.methods.FORMATTING) 27 | return not vim.tbl_isempty(vim.tbl_filter(function(source) 28 | return source.name ~= "trim_whitespace" 29 | end, sources)) 30 | end 31 | 32 | function M.formatting_sources() 33 | local null_ls = require("null-ls") 34 | local formatting = null_ls.builtins.formatting 35 | return { 36 | -- NOTE: sumneko_lua has builtin EmmyLuaCodeStyle support 37 | formatting.stylua, -- lua 38 | formatting.black, -- python 39 | formatting.isort, -- python 40 | -- NOTE: this superset of gofmt is preferred if installed 41 | formatting.goimports, -- go 42 | formatting.brittany, -- haskell (yay -S brittany) 43 | formatting.clang_format.with({ disabled_filetypes = { "java" } }), -- c* 44 | -- make: pip install cmakelang (~/.local/bin/cmake-format) 45 | formatting.cmake_format.with({ 46 | filetypes = { "cmake", "make" }, -- TODO: check if this is necessary 47 | }), 48 | formatting.google_java_format, -- java 49 | formatting.prettierd.with({ 50 | extra_filetypes = { 51 | -- https://prettier.io/docs/en/plugins.html#official-plugins 52 | "php", 53 | "pug", 54 | "ruby", 55 | "xml", 56 | -- https://prettier.io/docs/en/plugins.html#community-plugins 57 | "apex", -- npm install -g prettier-plugin-apex 58 | "elm", -- npm install -g prettier-plugin-elm 59 | -- "java", -- npm install -g prettier-plugin-java 60 | "sol", -- npm install -g prettier-plugin-solidity 61 | "toml", -- npm install -g prettier-plugin-toml 62 | "svelte", -- npm install -g prettier-plugin-svelte 63 | "kotlin", -- npm install -g prettier-plugin-kotlin 64 | "sh", -- npm install -g prettier-plugin-sh 65 | "dockerfile", 66 | "jproperties", 67 | "conf", 68 | "zsh", -- https://github.com/mvdan/sh/issues/120 69 | "gitignore", 70 | }, 71 | }), 72 | formatting.buildifier, -- bazel 73 | -- ISSUE: false positives (e.g. ans -> and) may cause compilation problems 74 | -- formatting.codespell, -- default 75 | -- formatting.buf, -- protobuf (yay -S buf) 76 | formatting.trim_whitespace, -- default 77 | } 78 | end 79 | 80 | function M.diagnostic_sources() 81 | local null_ls = require("null-ls") 82 | local diagnostics = null_ls.builtins.diagnostics 83 | return { 84 | diagnostics.pylint, -- python 85 | -- lua 86 | diagnostics.selene.with({ 87 | extra_args = { "--config", vim.fn.expand("~/.config/selene.toml") }, 88 | condition = function(utils) 89 | return utils.root_has_file({ "selene.toml" }) 90 | end, 91 | }), 92 | diagnostics.cppcheck, -- c/c++ (sudo pacman -S cppcheck) 93 | -- gcc: yay -S gccdiag or compile from source 94 | diagnostics.gccdiag.with({ 95 | condition = function(utils) 96 | return utils.root_has_file({ "compile_commands.json" }) 97 | end, 98 | }), 99 | -- TODO: override diagnostic format? 100 | diagnostics.shellcheck, -- sh 101 | -- default 102 | diagnostics.editorconfig_checker.with({ 103 | condition = function(utils) 104 | return utils.root_has_file({ ".editorconfig" }) 105 | end, 106 | }), 107 | -- diagnostics.buf, -- protobuf 108 | -- diagnostics.trail_space, -- default 109 | } 110 | end 111 | 112 | function M.code_action_sources() 113 | local null_ls = require("null-ls") 114 | local code_actions = null_ls.builtins.code_actions 115 | 116 | return { 117 | code_actions.shellcheck, -- sh 118 | code_actions.gitsigns, 119 | code_actions.refactoring, 120 | code_actions.ts_node_action, 121 | } 122 | end 123 | 124 | function M.hover_sources() 125 | local null_ls = require("null-ls") 126 | local hover = null_ls.builtins.hover 127 | return { 128 | hover.dictionary, 129 | } 130 | end 131 | 132 | function M.config() 133 | -- Combine sources 134 | local sources = require("axie.utils").list_flatten_once({ 135 | require("axie.plugins.lsp.null").formatting_sources(), 136 | require("axie.plugins.lsp.null").diagnostic_sources(), 137 | require("axie.plugins.lsp.null").code_action_sources(), 138 | require("axie.plugins.lsp.null").hover_sources(), 139 | }) 140 | 141 | -- Setup null-ls 142 | require("null-ls").setup({ 143 | sources = sources, 144 | on_attach = require("axie.plugins.lsp.options").default_on_attach, 145 | -- debug = true, 146 | }) 147 | end 148 | 149 | return M 150 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/rename.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---Calls vim.lsp.buf.rename without the symbol name as default placeholder text 4 | function M.rename_empty() 5 | -- Override vim.ui.input function to remove default text 6 | local original_ui_input = vim.ui.input 7 | vim.ui.input = function(opts, on_confirm) 8 | opts.default = "" 9 | original_ui_input(opts, on_confirm) 10 | vim.ui.input = original_ui_input 11 | end 12 | 13 | vim.lsp.buf.rename() 14 | end 15 | 16 | -- REF: https://github.com/neovim/neovim/blob/master/runtime/lua/vim/lsp/handlers.lua 17 | function M.rename_handler(...) 18 | local result = select(2, ...) 19 | local ctx = select(3, ...) 20 | 21 | M.notify_handler(result) 22 | vim.lsp.handlers[ctx.method](...) 23 | end 24 | 25 | ---------------------------------------- 26 | -- Notifies successful rename changes -- 27 | ---------------------------------------- 28 | 29 | function M.notify_handler(result) 30 | if not result then 31 | return 32 | end 33 | 34 | local notify = require("axie.utils").notify 35 | local msg = "" 36 | local num_changes = 0 37 | 38 | -- prefer documentChanges over changes (under workspaceEdit) 39 | -- https://microsoft.github.io/language-server-protocol/specifications/specification-3-14 40 | local changes = {} 41 | if result.documentChanges then 42 | for _, entry in ipairs(result.documentChanges) do 43 | local edits = entry.edits 44 | if edits then 45 | local filename = vim.uri_to_fname(entry.textDocument.uri) 46 | filename = vim.fn.fnamemodify(filename, ":.") 47 | msg = msg .. ("%d changes in %s"):format(#edits, filename) .. "\n" 48 | num_changes = num_changes + #edits 49 | end 50 | changes[entry.textDocument.uri] = edits 51 | end 52 | elseif result.changes then 53 | changes = result.changes 54 | for uri, edits in pairs(changes) do 55 | local filename = vim.uri_to_fname(uri) 56 | filename = vim.fn.fnamemodify(filename, ":.") 57 | msg = msg .. ("%d changes in %s"):format(#edits, filename) .. "\n" 58 | num_changes = num_changes + #edits 59 | end 60 | end 61 | msg = msg:sub(1, #msg - 1) 62 | notify(msg, vim.log.levels.INFO, { 63 | title = ("Succesfully renamed with %d changes"):format(num_changes), 64 | }) 65 | 66 | -- set qflist 67 | M.set_qflist(changes) 68 | end 69 | 70 | ----------------------------------------------------------------------------------------------------- 71 | -- Set qflist helper function from renamer.nvim (ft my bug fix) -- 72 | -- SOURCE: https://github.com/filipdutescu/renamer.nvim/blob/develop/lua/renamer/utils.lua#L48-L79 -- 73 | ----------------------------------------------------------------------------------------------------- 74 | 75 | function M.set_qflist(changes) 76 | if changes then 77 | local qf_list, i = {}, 0 78 | for file, data in pairs(changes) do 79 | local buf_id = -1 80 | if vim.uri and vim.uri.uri_to_bufnr then 81 | buf_id = vim.uri.uri_to_bufnr(file) 82 | else 83 | local file_path = string.gsub(file, "file://", "") 84 | buf_id = vim.fn.bufadd(file_path) 85 | end 86 | vim.fn.bufload(buf_id) 87 | file = string.gsub(file, "file://", "") 88 | 89 | for _, change in ipairs(data) do 90 | local row, col = change.range.start.line, change.range.start.character 91 | i = i + 1 92 | local line = vim.api.nvim_buf_get_lines(buf_id, row, row + 1, false) 93 | qf_list[i] = { 94 | text = line and line[1], 95 | filename = file, 96 | lnum = row + 1, 97 | col = col + 1, 98 | } 99 | end 100 | end 101 | 102 | if qf_list and i > 0 then 103 | vim.fn.setqflist(qf_list) 104 | end 105 | end 106 | end 107 | 108 | return M 109 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/setup.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.ensure_installed = { 4 | --------------- 5 | -- Scripting -- 6 | --------------- 7 | "pyright", 8 | "lua-language-server", 9 | "bash-language-server", 10 | --------------------- 11 | -- Web Development -- 12 | --------------------- 13 | -- "dockerfile-language-server", 14 | "typescript-language-server", 15 | "emmet-ls", 16 | "json-lsp", 17 | -- "eslint_d", 18 | -- "css-lsp", 19 | -- "html-lsp", 20 | ------------------- 21 | -- Miscellaneous -- 22 | ------------------- 23 | -- "jdtls", 24 | -- "java-debug-adapter", 25 | -- "java-test", 26 | "clangd", 27 | "ltex-ls", 28 | -- "cmake-language-server", 29 | -- "rust-analyzer", 30 | -- "gopls", 31 | -- "haskell-language-server", 32 | -- "sqls", 33 | -- "texlab", 34 | } 35 | 36 | --- Setup a language server with lspconfig 37 | ---@param name string @The name of the language server 38 | ---@param opts table @Optional table of options to pass to the language server 39 | function M.setup_lspconfig(name, opts) 40 | opts = opts or require("axie.plugins.lsp.options").get(name) 41 | if opts.autostart or opts.autostart == nil then 42 | require("lspconfig")[name].setup(opts) 43 | end 44 | end 45 | 46 | --- Setup a language server using the `cb` function provided 47 | ---@param name string @The name of the language server 48 | ---@param cb function @Setup function for the language server 49 | ---@param key string @Optional key in dictionary passed to the setup function containing custom options 50 | function M.setup_custom(name, cb, key) 51 | local opts = require("axie.plugins.lsp.options").get(name) 52 | local pattern = opts.filetypes 53 | if not pattern then 54 | pattern = require("lspconfig.server_configurations." .. name).default_config.filetypes 55 | end 56 | vim.api.nvim_create_autocmd("FileType", { 57 | pattern = pattern, 58 | callback = function() 59 | opts.autostart = true 60 | if key then 61 | cb({ [key] = opts }) 62 | else 63 | cb(opts) 64 | end 65 | end, 66 | }) 67 | end 68 | 69 | --- Setup language servers 70 | function M.servers() 71 | -- Setup installed language servers 72 | local this = require("axie.plugins.lsp.setup") 73 | local installed_servers = require("mason-lspconfig").get_installed_servers() 74 | for _, server in ipairs(installed_servers) do 75 | this.setup_lspconfig(server) 76 | end 77 | 78 | -- Setup language servers via autocmd 79 | this.setup_custom("jdtls", function(opts) 80 | require("jdtls").start_or_attach(opts) 81 | end) 82 | this.setup_custom("rust_analyzer", function(opts) 83 | require("rust-tools").setup(opts) 84 | end, "server") 85 | this.setup_custom("grammarly", function(opts) 86 | vim.keymap.set("n", "\\g", function() 87 | -- Stop Grammarly client if active 88 | local client = vim.lsp.get_active_clients({ bufnr = 0, name = "grammarly" })[1] 89 | if client then 90 | vim.lsp.stop_client(client.id) 91 | else 92 | -- Start Grammarly client 93 | this.setup_lspconfig("grammarly", opts) 94 | end 95 | end, { desc = "Toggle Grammarly", silent = true }) 96 | end) 97 | end 98 | 99 | return M 100 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/signature.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.on_attach(bufnr) 4 | require("lsp_signature").on_attach({ 5 | -- general options 6 | always_trigger = false, 7 | toggle_key = "", 8 | 9 | -- floating window 10 | padding = " ", 11 | transparency = 20, 12 | handler_opts = { border = "rounded" }, 13 | }, bufnr) 14 | end 15 | 16 | return M 17 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/snippets/all.lua: -------------------------------------------------------------------------------- 1 | local ls = require("luasnip") 2 | local s = ls.snippet 3 | local sn = ls.snippet_node 4 | local isn = ls.indent_snippet_node 5 | local t = ls.text_node 6 | local i = ls.insert_node 7 | local f = ls.function_node 8 | local c = ls.choice_node 9 | local d = ls.dynamic_node 10 | local r = ls.restore_node 11 | local events = require("luasnip.util.events") 12 | local ai = require("luasnip.nodes.absolute_indexer") 13 | local fmt = require("luasnip.extras.fmt").fmt 14 | local extras = require("luasnip.extras") 15 | local m = extras.m 16 | local l = extras.l 17 | local rep = extras.rep 18 | local postfix = require("luasnip.extras.postfix").postfix 19 | 20 | local snippets, autosnippets = {}, {} 21 | 22 | local filetype = s("filetype", fmt("// vim: set ft={}:", i(1, "filetype"))) 23 | table.insert(snippets, filetype) 24 | 25 | return snippets, autosnippets 26 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/snippets/cpp.lua: -------------------------------------------------------------------------------- 1 | local ls = require("luasnip") 2 | local s = ls.snippet 3 | local sn = ls.snippet_node 4 | local isn = ls.indent_snippet_node 5 | local t = ls.text_node 6 | local i = ls.insert_node 7 | local f = ls.function_node 8 | local c = ls.choice_node 9 | local d = ls.dynamic_node 10 | local r = ls.restore_node 11 | local events = require("luasnip.util.events") 12 | local ai = require("luasnip.nodes.absolute_indexer") 13 | local fmt = require("luasnip.extras.fmt").fmt 14 | local extras = require("luasnip.extras") 15 | local m = extras.m 16 | local l = extras.l 17 | local rep = extras.rep 18 | local postfix = require("luasnip.extras.postfix").postfix 19 | 20 | local snippets, autosnippets = {}, {} 21 | 22 | -- Competitive programming template 23 | local template = s("cpt", { 24 | t({ 25 | "#include ", 26 | "", 27 | "using namespace std;", 28 | "", 29 | "#define ll long long", 30 | "#define ld long double", 31 | "#define PI M_PI", 32 | "#define INF 1e9", 33 | '#define debug(x) cout << #x << ": " << x << endl;', 34 | "", 35 | "void solve() {", 36 | " ", 37 | }), 38 | i(1, "// TODO"), -- cursor placement on snippet expansion 39 | -- TODO: add choice node for commented lines? use ls.indent_snippet_node? 40 | t({ 41 | "", 42 | "}", 43 | "", 44 | "int main() {", 45 | " // optimise read/write", 46 | " ios_base::sync_with_stdio(0);", 47 | " cin.tie(0); cout.tie(0);", 48 | "", 49 | " // test cases", 50 | " int tc = 1;", 51 | " // cin >> tc;", 52 | " for (int t = 1; t <= tc; ++t) {", 53 | ' // cout << "Case #" << t << ": ";', 54 | " solve();", 55 | " }", 56 | "}", 57 | }), 58 | }) 59 | 60 | table.insert(snippets, template) 61 | 62 | return snippets, autosnippets 63 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/snippets/init.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: choice node vim.ui.select https://github.com/L3MON4D3/LuaSnip/wiki/Misc#choicenode-popup 4 | 5 | M.keys = { 6 | { 7 | "", 8 | function() 9 | local ls = require("luasnip") 10 | if ls.expand_or_jumpable() then 11 | ls.expand_or_jump() 12 | end 13 | end, 14 | mode = { "n", "i", "s" }, 15 | desc = "Snippet jump next", 16 | }, 17 | { 18 | "", 19 | function() 20 | local ls = require("luasnip") 21 | if ls.jumpable(-1) then 22 | ls.jump(-1) 23 | end 24 | end, 25 | mode = { "n", "i", "s" }, 26 | desc = "Snippet jump previous", 27 | }, 28 | { 29 | "", 30 | function() 31 | local ls = require("luasnip") 32 | if ls.choice_active() then 33 | ls.change_choice(-1) 34 | end 35 | end, 36 | mode = { "n", "i" }, 37 | desc = "Snippet choice previous", 38 | }, 39 | { 40 | "", 41 | function() 42 | local ls = require("luasnip") 43 | if ls.choice_active() then 44 | ls.change_choice(1) 45 | end 46 | end, 47 | mode = { "n", "i" }, 48 | desc = "Snippet choice next", 49 | }, 50 | { 51 | "\\S", 52 | function() 53 | require("luasnip.loaders.from_lua").edit_snippet_files() 54 | end, 55 | desc = "Snippet edit", 56 | }, 57 | } 58 | 59 | function M.config() 60 | local ls = require("luasnip") 61 | local types = require("luasnip.util.types") 62 | 63 | ls.config.setup({ 64 | -- dynamic snippet support 65 | history = true, 66 | updateevents = "TextChanged,TextChangedI", 67 | enable_autosnippets = true, 68 | 69 | -- customise virtual text 70 | ext_opts = { 71 | [types.choiceNode] = { 72 | active = { 73 | virt_text = { { "󰌵", "DiagnosticSignWarn" } }, 74 | }, 75 | }, 76 | [types.insertNode] = { 77 | active = { 78 | virt_text = { { "⟵", "DiagnosticSignWarn" } }, 79 | }, 80 | }, 81 | }, 82 | }) 83 | 84 | -- load snippets from rtp (rafamadriz/friendly-snippets) 85 | require("luasnip.loaders.from_vscode").lazy_load() 86 | -- register custom snippets 87 | require("luasnip.loaders.from_lua").lazy_load({ paths = "~/dotconfig/nvim/lua/axie/plugins/lsp/snippets" }) 88 | end 89 | 90 | return M 91 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/snippets/lua.lua: -------------------------------------------------------------------------------- 1 | local ls = require("luasnip") 2 | local s = ls.snippet 3 | local sn = ls.snippet_node 4 | local isn = ls.indent_snippet_node 5 | local t = ls.text_node 6 | local i = ls.insert_node 7 | local f = ls.function_node 8 | local c = ls.choice_node 9 | local d = ls.dynamic_node 10 | local r = ls.restore_node 11 | local events = require("luasnip.util.events") 12 | local ai = require("luasnip.nodes.absolute_indexer") 13 | local fmt = require("luasnip.extras.fmt").fmt 14 | local extras = require("luasnip.extras") 15 | local m = extras.m 16 | local l = extras.l 17 | local rep = extras.rep 18 | local postfix = require("luasnip.extras.postfix").postfix 19 | 20 | local snippets, autosnippets = {}, {} 21 | 22 | local mod = s( 23 | "mod", 24 | fmt( 25 | [[ 26 | local {} = {{}} 27 | {} 28 | return {} 29 | ]], 30 | { 31 | i(1, "M"), 32 | c(2, { 33 | t(""), 34 | fmt( 35 | [[ 36 | 37 | 38 | function {}.config(){} 39 | end 40 | 41 | ]], 42 | { rep(ai[1]), i(1) } 43 | ), 44 | fmt( 45 | [[ 46 | 47 | 48 | function {}.init(){} 49 | end 50 | 51 | function {}.config(){} 52 | end 53 | 54 | ]], 55 | { rep(ai[1]), i(1), rep(ai[1]), i(2) } 56 | ), 57 | }), 58 | c(3, { 59 | rep(ai[1]), 60 | fmt("setmetatable({}, {{{}}})", { rep(ai[1]), i(1) }), 61 | }), 62 | } 63 | ) 64 | ) 65 | table.insert(snippets, mod) 66 | 67 | return snippets, autosnippets 68 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/lsp/snippets/markdown.lua: -------------------------------------------------------------------------------- 1 | local ls = require("luasnip") 2 | local s = ls.snippet 3 | local sn = ls.snippet_node 4 | local isn = ls.indent_snippet_node 5 | local t = ls.text_node 6 | local i = ls.insert_node 7 | local f = ls.function_node 8 | local c = ls.choice_node 9 | local d = ls.dynamic_node 10 | local r = ls.restore_node 11 | local events = require("luasnip.util.events") 12 | local ai = require("luasnip.nodes.absolute_indexer") 13 | local fmt = require("luasnip.extras.fmt").fmt 14 | local extras = require("luasnip.extras") 15 | local m = extras.m 16 | local l = extras.l 17 | local rep = extras.rep 18 | local postfix = require("luasnip.extras.postfix").postfix 19 | 20 | local snippets, autosnippets = {}, {} 21 | 22 | -- Prettier ignore snippet 23 | local ignore = s("ignore", t("")) 24 | table.insert(snippets, ignore) 25 | 26 | return snippets, autosnippets 27 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/misc/firenvim.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | vim.g.firenvim_config = { 5 | localSettings = { 6 | [".*"] = { 7 | takeover = "never", -- Autostart 8 | sync = "change", -- Autosave 9 | cmdline = "neovim", 10 | }, 11 | }, 12 | } 13 | 14 | -- GitHub issues Markdown filetype 15 | require("axie.utils").override_filetype("github.com_*.txt", "markdown") 16 | 17 | -- TODO: setup Nerd Font glyphs (`guifont`) 18 | vim.opt.guifont = "JetBrainsMono Nerd Font Mono" 19 | end 20 | 21 | return M 22 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/misc/init.lua: -------------------------------------------------------------------------------- 1 | local spec = { 2 | -- Common plugin dependencies 3 | "nvim-lua/plenary.nvim", 4 | "nvim-tree/nvim-web-devicons", 5 | "MunifTanjim/nui.nvim", 6 | 7 | -- Misc 8 | { 9 | "willothy/flatten.nvim", 10 | lazy = false, 11 | priority = 1001, 12 | opts = { window = { open = "alternate" }, nest_if_no_args = true }, 13 | }, 14 | { 15 | "glacambre/firenvim", 16 | lazy = false, 17 | build = function() 18 | -- NOTE: need to reinstall on nvim version upgrade 19 | require("lazy").load({ plugins = "firenvim", wait = true }) 20 | vim.fn["firenvim#install"](0) 21 | end, 22 | cond = not not vim.g.started_by_firenvim, 23 | settings = "firenvim", 24 | }, 25 | } 26 | 27 | return require("axie.lazy").transform_spec(spec, "misc") 28 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/project/diffview.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = { 4 | "DiffviewOpen", 5 | "DiffviewFileHistory", 6 | "DiffviewClose", 7 | "DiffviewFocusFiles", 8 | "DiffviewToggleFiles", 9 | "DiffviewRefresh", 10 | "DiffviewLog", 11 | } 12 | 13 | M.keys = { 14 | { "gdd", "DiffviewOpen", desc = "Diffview + merge conflicts" }, 15 | { "gdf", "DiffviewFileHistory %", desc = "Git diff (file)" }, 16 | { "gdr", "DiffviewFileHistory", desc = "Git diff (repo)" }, 17 | { "gdm", "DiffviewOpen main", desc = "Git diff (main)" }, 18 | { "gdM", "DiffviewOpen master", desc = "Git diff (master)" }, 19 | { "gdq", "DiffviewClose", desc = "Git diff close" }, 20 | } 21 | 22 | M.opts = { 23 | view = { 24 | default = { winbar_info = true }, 25 | merge_tool = { winbar_info = true, layout = "diff3_mixed", disable_diagnostics = false }, 26 | file_history = { winbar_info = true }, 27 | }, 28 | } 29 | 30 | return M 31 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/project/gitlinker.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { "gy", mode = { "n", "v" }, desc = "Copy Git line reference URL to clipboard" }, 5 | { 6 | "gY", 7 | function() 8 | require("gitlinker").get_repo_url() 9 | end, 10 | mode = "n", 11 | desc = "Copy Git repo URL to clipboard", 12 | }, 13 | { 14 | "gw", 15 | function() 16 | require("gitlinker").get_buf_range_url("n", { 17 | action_callback = require("gitlinker.actions").open_in_browser, 18 | }) 19 | end, 20 | mode = "n", 21 | desc = "Open Git line reference URL in browser", 22 | }, 23 | { 24 | "gw", 25 | function() 26 | require("gitlinker").get_buf_range_url("v", { 27 | action_callback = require("gitlinker.actions").open_in_browser, 28 | }) 29 | end, 30 | mode = "v", 31 | desc = "Open Git line reference URL in browser", 32 | }, 33 | { 34 | "gW", 35 | function() 36 | require("gitlinker").get_repo_url("n", { 37 | action_callback = require("gitlinker.actions").open_in_browser, 38 | }) 39 | end, 40 | mode = "n", 41 | desc = "Open Git repo URL in browser", 42 | }, 43 | } 44 | 45 | M.opts = { mappings = "gy" } 46 | 47 | return M 48 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/project/gitsigns.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { 5 | "gQ", 6 | function() 7 | require("gitsigns").toggle_numhl() 8 | end, 9 | desc = "Git gutter toggle", 10 | }, 11 | { 12 | "g;", 13 | function() 14 | require("gitsigns").toggle_current_line_blame() 15 | end, 16 | desc = "Git blame toggle", 17 | }, 18 | { 19 | "[g", 20 | function() 21 | require("gitsigns.actions").prev_hunk() 22 | end, 23 | desc = "Previous Git hunk", 24 | }, 25 | { 26 | "]g", 27 | function() 28 | require("gitsigns.actions").next_hunk() 29 | end, 30 | desc = "Next Git hunk", 31 | }, 32 | { 33 | "ih", 34 | function() 35 | require("gitsigns.actions").select_hunk() 36 | end, 37 | mode = { "o", "x" }, 38 | desc = "Select Git hunk", 39 | }, 40 | 41 | -- TODO: toggle stage hunk containing cursor with gh 42 | -- TODO: visual selection for partial range 43 | { 44 | "gh", 45 | function() 46 | require("gitsigns").stage_hunk() 47 | end, 48 | desc = "Git stage hunk", 49 | }, 50 | { 51 | "gH", 52 | function() 53 | require("gitsigns").undo_stage_hunk() 54 | end, 55 | desc = "Git stage hunk (undo)", 56 | }, 57 | { 58 | "gK", 59 | function() 60 | require("gitsigns").preview_hunk() 61 | end, 62 | desc = "Git preview hunk", 63 | }, 64 | 65 | { 66 | "gD", 67 | function() 68 | require("gitsigns").preview_hunk_inline() 69 | end, 70 | desc = "Git toggle deleted lines", 71 | }, 72 | { 73 | "gr", 74 | function() 75 | require("gitsigns").reset_hunk() 76 | end, 77 | desc = "Git reset hunk", 78 | }, 79 | { 80 | "gR", 81 | function() 82 | require("gitsigns").reset_buffer() 83 | end, 84 | desc = "Git reset buffer", 85 | }, 86 | } 87 | 88 | M.opts = { 89 | numhl = true, 90 | signcolumn = false, 91 | current_line_blame = false, 92 | -- TEMP: preview_hunk_inline with syntax highlighting 93 | _inline2 = true, 94 | } 95 | 96 | return M 97 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/project/init.lua: -------------------------------------------------------------------------------- 1 | ----------------------------- 2 | -- Project / Git Utilities -- 3 | ----------------------------- 4 | 5 | -- TODO: nvim ide project settings plugin 6 | -- gh.nvim, litee? 7 | 8 | local spec = { 9 | -- Project stuff 10 | { 11 | -- Project scope 12 | "ahmedkhalf/project.nvim", 13 | event = "VeryLazy", 14 | keys = { { "fP", "Telescope projects", desc = "Recent projects" } }, 15 | config = function() 16 | require("project_nvim").setup() 17 | end, 18 | }, 19 | -- Project settings 20 | { "tpope/vim-sleuth", event = "VeryLazy" }, 21 | 22 | -- Git stuff 23 | { "lewis6991/gitsigns.nvim", event = "BufReadPost", settings = "gitsigns" }, 24 | { "ruifm/gitlinker.nvim", settings = "gitlinker" }, 25 | -- NOTE: can be wrapped with https://github.com/TimUntersberger/neogit 26 | { "sindrets/diffview.nvim", settings = "diffview" }, 27 | -- { 28 | -- -- GitHub issues and pull requests 29 | -- "pwntester/octo.nvim", 30 | -- dependencies = { 31 | -- "nvim-lua/plenary.nvim", 32 | -- "nvim-telescope/telescope.nvim", 33 | -- "nvim-tree/nvim-web-devicons", 34 | -- }, 35 | -- config = function() 36 | -- require("octo").setup() 37 | -- end, 38 | -- }, 39 | } 40 | 41 | return require("axie.lazy").transform_spec(spec, "project") 42 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/catppuccin.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = { "Catppuccin", "CatppuccinCompile" } 4 | 5 | function M.config() 6 | require("catppuccin").setup({ 7 | flavour = "mocha", 8 | compile = { enabled = true }, 9 | dim_inactive = { enabled = false }, 10 | transparent_background = true, 11 | integrations = { 12 | aerial = true, 13 | barbar = true, 14 | -- barbecue = false, 15 | beacon = true, 16 | bufferline = false, 17 | cmp = true, 18 | coc_nvim = false, 19 | dap = { 20 | enabled = true, 21 | enable_ui = true, 22 | }, 23 | dashboard = false, -- startify? 24 | dropbar = { 25 | enabled = true, 26 | color_mode = false, 27 | }, 28 | feline = false, 29 | fern = false, 30 | fidget = false, -- prefer default colours 31 | gitgutter = false, 32 | gitsigns = true, 33 | harpoon = false, 34 | headlines = false, 35 | hop = false, 36 | illuminate = false, 37 | indent_blankline = { 38 | enabled = true, 39 | -- colored_indent_levels = true, 40 | }, 41 | leap = true, 42 | lightspeed = false, 43 | lsp_saga = false, 44 | lsp_trouble = false, 45 | markdown = true, 46 | mason = true, 47 | mini = false, 48 | native_lsp = { 49 | enabled = true, 50 | underlines = { 51 | -- errors = { "undercurl" }, 52 | -- hints = { "undercurl" }, 53 | -- warnings = { "undercurl" }, 54 | -- information = { "undercurl" }, 55 | }, 56 | }, 57 | navic = { 58 | enabled = true, 59 | -- cp.base 60 | custom_bg = "#1E1E2E", 61 | }, 62 | neogit = true, 63 | neotest = true, 64 | neotree = { 65 | enabled = true, 66 | show_root = false, 67 | transparent_panel = true, 68 | }, 69 | noice = false, 70 | notify = true, 71 | nvimtree = false, 72 | octo = false, 73 | overseer = false, 74 | pounce = false, 75 | rainbow_delimiters = false, 76 | sandwich = false, 77 | semantic_tokens = true, 78 | symbols_outline = false, 79 | telekasten = false, 80 | telescope = { enabled = true }, 81 | treesitter = true, 82 | treesitter_context = false, 83 | ts_rainbow = true, 84 | ts_rainbow2 = false, 85 | vim_sneak = false, 86 | vimwiki = true, 87 | which_key = true, 88 | }, 89 | custom_highlights = function(colours) 90 | local float_bg = colours.base 91 | local remaps = { 92 | NormalFloat = { bg = float_bg }, -- NOTE: catppuccin needs a bg colour 93 | ColorColumn = { link = "CursorLine" }, 94 | SpellBad = { fg = colours.red, style = { "italic", "undercurl" } }, 95 | SpellCap = { fg = colours.red, style = { "italic", "undercurl" } }, 96 | SpellLocal = { fg = colours.red, style = { "italic", "undercurl" } }, 97 | SpellRare = { fg = colours.red, style = { "italic", "undercurl" } }, 98 | CmpItemMenu = { fg = colours.surface2 }, 99 | Pmenu = { bg = colours.surface0 }, 100 | WinBar = { bg = float_bg }, 101 | WinBarNC = { bg = float_bg }, 102 | WinBarModified = { fg = colours.yellow, bg = float_bg }, -- same as BufferCurrentMod 103 | NavicIconsFileNC = { fg = colours.flamingo, bg = float_bg }, 104 | ["@parameter"] = { fg = colours.flamingo }, 105 | -- VertSplit = { fg = cp.overlay1 }, 106 | -- SpellBad = { fg = cp.maroon }, 107 | -- SpellCap = { fg = cp.peach }, 108 | -- SpellLocal = { fg = cp.lavender }, 109 | -- SpellRare = { fg = cp.teal }, 110 | } 111 | 112 | -- NvChad Telescope theme (adapted from https://github.com/olimorris/onedarkpro.nvim/issues/31#issue-1160545258) 113 | if require("axie.utils.config").nvchad_theme then 114 | local telescope_results = colours.base 115 | -- local telescope_prompt = cp.surface0 116 | local telescope_prompt = "#302D41" -- black3 from original palette 117 | local fg = colours.surface2 118 | remaps = vim.tbl_extend("force", remaps, { 119 | TelescopeBorder = { fg = telescope_results, bg = telescope_results }, 120 | TelescopePromptBorder = { fg = telescope_prompt, bg = telescope_prompt }, 121 | TelescopePromptCounter = { fg = fg }, 122 | TelescopePromptNormal = { fg = fg, bg = telescope_prompt }, 123 | TelescopePromptPrefix = { fg = colours.green, bg = telescope_prompt }, 124 | TelescopePromptTitle = { fg = telescope_prompt, bg = colours.green }, 125 | TelescopePreviewTitle = { fg = telescope_prompt, bg = colours.maroon }, 126 | TelescopeResultsTitle = { fg = telescope_results, bg = telescope_results }, 127 | TelescopeMatching = { fg = colours.green }, 128 | TelescopeNormal = { bg = telescope_results }, 129 | TelescopeSelection = { bg = telescope_prompt }, 130 | }) 131 | end 132 | return remaps 133 | end, 134 | }) 135 | 136 | vim.api.nvim_cmd({ cmd = "colorscheme", args = { "catppuccin" } }, {}) 137 | end 138 | 139 | return M 140 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/init.lua: -------------------------------------------------------------------------------- 1 | local spec = { 2 | { 3 | -- TODO: replace all with themer.lua? 4 | "themercorp/themer.lua", 5 | enabled = false, 6 | settings = "themer", 7 | }, 8 | { 9 | "catppuccin/nvim", 10 | name = "catppuccin", 11 | lazy = false, 12 | priority = 1000, 13 | settings = "catppuccin", 14 | }, 15 | { 16 | "marko-cerovac/material.nvim", 17 | settings = "material", 18 | }, 19 | { 20 | "rebelot/kanagawa.nvim", 21 | enabled = false, 22 | settings = "kanagawa", 23 | }, 24 | { 25 | -- TODO: replace (too red) 26 | -- ALT: https://github.com/navarasu/onedark.nvim 27 | "olimorris/onedarkpro.nvim", 28 | settings = "onedark", 29 | }, 30 | { 31 | "sam4llis/nvim-tundra", 32 | enabled = false, 33 | settings = "tundra", 34 | }, 35 | } 36 | 37 | return require("axie.lazy").transform_spec(spec, "themes") 38 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/kanagawa.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | local default_colors = require("kanagawa.colors").setup() 5 | require("kanagawa").setup({ 6 | transparent = true, 7 | overrides = { 8 | VertSplit = { fg = default_colors.bg_dark, bg = "NONE" }, 9 | NormalFloat = { fg = default_colors.fg, bg = default_colors.sumiInk2 }, 10 | }, 11 | }) 12 | end 13 | 14 | return M 15 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/material.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | vim.g.material_style = "palenight" 5 | require("material").setup({ 6 | borders = true, 7 | disable = { 8 | background = true, 9 | }, 10 | custom_highlights = { 11 | IndentBlanklineContextChar = { fg = "#C678DD" }, 12 | TelescopeNormal = { bg = "NONE" }, 13 | -- WhichKeyFloat = { bg = "#2632384D" }, 14 | -- TODO: cmp item kind highlights 15 | -- https://github.com/hrsh7th/nvim-cmp/wiki/Menu-Appearance#how-to-add-visual-studio-code-dark-theme-colors-to-the-menu 16 | -- HLGROUP = { link = "OTHER_GROUP" }, 17 | }, 18 | }) 19 | end 20 | 21 | return M 22 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/onedark.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | local onedarkpro = require("onedarkpro") 5 | local color = require("onedarkpro.helpers") 6 | onedarkpro.setup({ 7 | theme = "onedark_vivid", 8 | caching = true, 9 | -- extra from https://github.com/navarasu/onedark.nvim/blob/master/lua/onedark/colors.lua 10 | colors = { 11 | -- NvChad Telescope theme (https://github.com/olimorris/onedarkpro.nvim/issues/31#issue-1160545258) 12 | onedark = { 13 | telescope_prompt = color.lighten(color.get_colors("onedark").bg, 0.97), 14 | telescope_results = color.darken(color.get_colors("onedark").bg, 0.85), 15 | }, 16 | onelight = { 17 | telescope_prompt = color.darken(color.get_colors("onelight").bg, 0.98), 18 | telescope_results = color.darken(color.get_colors("onelight").bg, 0.95), 19 | }, 20 | }, 21 | highlights = { 22 | TSProperty = { fg = "${gray}" }, 23 | TSVariable = { fg = "${fg}" }, 24 | 25 | -- NvChad Telescope theme (https://github.com/olimorris/onedarkpro.nvim/issues/31#issue-1160545258) 26 | TelescopeBorder = { 27 | fg = "${telescope_results}", 28 | bg = "${telescope_results}", 29 | }, 30 | TelescopePromptBorder = { 31 | fg = "${telescope_prompt}", 32 | bg = "${telescope_prompt}", 33 | }, 34 | TelescopePromptCounter = { fg = "${fg}" }, 35 | TelescopePromptNormal = { fg = "${fg}", bg = "${telescope_prompt}" }, 36 | TelescopePromptPrefix = { 37 | fg = "${purple}", 38 | bg = "${telescope_prompt}", 39 | }, 40 | TelescopePromptTitle = { 41 | fg = "${telescope_prompt}", 42 | bg = "${purple}", 43 | }, 44 | 45 | TelescopePreviewTitle = { 46 | fg = "${telescope_results}", 47 | bg = "${green}", 48 | }, 49 | TelescopeResultsTitle = { 50 | fg = "${telescope_results}", 51 | bg = "${telescope_results}", 52 | }, 53 | 54 | TelescopeMatching = { fg = "${purple}" }, 55 | TelescopeNormal = { bg = "${telescope_results}" }, 56 | TelescopeSelection = { bg = "${telescope_prompt}" }, 57 | }, 58 | plugins = { 59 | polyglot = false, 60 | }, 61 | styles = { 62 | -- functions = "bold,italic", 63 | -- variables = "italic", 64 | }, 65 | options = { 66 | transparency = true, 67 | }, 68 | }) 69 | end 70 | 71 | return M 72 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/themer.lua: -------------------------------------------------------------------------------- 1 | -- OPTIONS: 2 | -- - onedark 3 | -- - dracula 4 | -- - kanagawa 5 | 6 | local M = {} 7 | 8 | function M.config() 9 | require("themer").setup({ 10 | transparent = true, 11 | dim_inactive = true, 12 | styles = { 13 | comment = { style = "italic" }, 14 | ["function"] = { style = "italic" }, 15 | functionbuiltin = { style = "italic" }, 16 | variable = { style = "italic" }, 17 | variableBuiltIn = { style = "italic" }, 18 | parameter = { style = "italic" }, 19 | }, 20 | remaps = { 21 | palette = {}, 22 | highlights = { 23 | kanagawa = { 24 | TSKeywordReturn = { fg = "#ff5d62" }, 25 | VertSplit = { fg = "#16161D", bg = "NONE", gui = "NONE" }, 26 | }, 27 | }, 28 | }, 29 | }) 30 | end 31 | 32 | return M 33 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/themes/tundra.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | require("nvim-tundra").setup({ 5 | transparent_background = true, 6 | }) 7 | end 8 | 9 | return M 10 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/alpha.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: customise like https://github.com/goolord/alpha-nvim/discussions/16#discussioncomment-1308930 4 | -- narrower center align 5 | 6 | M.keys = { { "S", "Alpha", desc = "Start menu" } } 7 | 8 | function M.config() 9 | local dashboard = require("alpha.themes.dashboard") 10 | 11 | dashboard.section.header.val = { 12 | [[ _____ ____ ___.______________ _____ ____ ___]], 13 | [[ / _ \ \ \/ /| \_ _____/ / _ \ \ \/ /]], 14 | [[ / /_\ \ \ / | || __)_ / /_\ \ \ / ]], 15 | [[/ | \/ \ | || \/ | \/ \ ]], 16 | [[\____|__ /___/\ \|___/_______ /\____|__ /___/\ \]], 17 | [[ \/ \_/ \/ \/ \_/]], 18 | [[ ]], 19 | [[ > Press [s] to restore your last session < ]], 20 | } 21 | 22 | dashboard.section.buttons.val = { 23 | dashboard.button("n", "󰈔 New File", "enestartinsert"), 24 | dashboard.button("f", "󰍉 Find Files", "lua require'axie.plugins.ui.telescope'.file_search()"), 25 | dashboard.button("g", " Live Grep", "Telescope live_grep"), 26 | dashboard.button("b", " Bookmarks", "Telescope marks"), 27 | -- TODO: orgmode notes 28 | dashboard.button("o", " Recent Files", "Telescope oldfiles"), -- TODO: use frecency 29 | dashboard.button("p", "󰏗 Find Projects", "Telescope projects"), 30 | dashboard.button("s", " Restore Session", "SessionManager load_last_session"), 31 | dashboard.button("S", "󰍨 Find Sessions", "SessionManager load_session"), 32 | dashboard.button("c", "󰗹 Neovim Config", "lua require'axie.plugins.ui.telescope'.dotconfig()"), 33 | dashboard.button("u", " Update Plugins", "Lazy"), 34 | dashboard.button("q", "⏻ Quit Neovim", "qa"), 35 | } 36 | 37 | dashboard.section.footer.val = { 38 | "  https://github.com/axieax/", 39 | "", -- plugins loaded and startup time 40 | } 41 | 42 | require("alpha").setup(dashboard.config) 43 | 44 | local alpha_attach = vim.api.nvim_create_augroup("AlphaAttach", {}) 45 | vim.api.nvim_create_autocmd("FileType", { 46 | desc = "Disable alpha colorcolumn, show alpha in bufferline, calculate startuptime", 47 | group = alpha_attach, 48 | pattern = "alpha", 49 | callback = function() 50 | vim.opt_local.buflisted = true 51 | vim.opt_local.colorcolumn = "" 52 | vim.api.nvim_cmd({ cmd = "file", args = { "dashboard" } }, {}) 53 | end, 54 | }) 55 | end 56 | 57 | function M.update_startuptime(loaded_plugins, startuptime) 58 | local ok, dashboard = pcall(require, "alpha.themes.dashboard") 59 | if ok then 60 | dashboard.section.footer.val[2] = string.format(" %d plugins loaded in %.3f ms", loaded_plugins, startuptime) 61 | else 62 | require("axie.utils").notify("Failed to load dashboard from vim-startuptime", vim.log.levels.ERROR) 63 | end 64 | end 65 | 66 | return M 67 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/barbar.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: see if new buffers can be open in tabs by default 4 | 5 | -- TEMP: https://github.com/romgrk/barbar.nvim/pull/438 6 | M.init = function() 7 | vim.g.barbar_auto_setup = false 8 | end 9 | 10 | M.keys = { 11 | -- Buffer navigation 12 | { "", "BufferNext" }, 13 | { "", "BufferPrevious" }, 14 | { "", "BufferRestore" }, 15 | { "", "BufferClose" }, 16 | { "", "BufferClose!" }, 17 | { "", "BufferPin" }, 18 | 19 | -- Buffer shortcuts 20 | { "", "BufferPick" }, 21 | { "", "BufferGoto 1" }, 22 | { "", "BufferGoto 2" }, 23 | { "", "BufferGoto 3" }, 24 | { "", "BufferGoto 4" }, 25 | { "", "BufferGoto 5" }, 26 | { "", "BufferGoto 6" }, 27 | { "", "BufferGoto 7" }, 28 | { "", "BufferGoto 8" }, 29 | { "", "BufferGoto 9" }, 30 | { "", "BufferLast" }, 31 | 32 | -- Buffer re-order / sort 33 | { "", "BufferMovePrevious" }, 34 | { "", "BufferMoveNext" }, 35 | { "bb", "BufferOrderByBufferNumber" }, 36 | { "bd", "BufferOrderByDirectory" }, 37 | { "bl", "BufferOrderByLanguage" }, 38 | { "bw", "BufferOrderByWindowNumber" }, 39 | } 40 | 41 | M.opts = { 42 | maximum_padding = 1, 43 | -- highlight_inactive_file_icons = true, 44 | icons = { button = "" }, 45 | } 46 | 47 | return M 48 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/init.lua: -------------------------------------------------------------------------------- 1 | local dev_mode = require("axie.utils.config").dev_mode 2 | 3 | local spec = { 4 | { "folke/which-key.nvim", event = "VeryLazy", settings = "whichkey" }, 5 | { "rebelot/heirline.nvim", event = "VeryLazy", settings = "statusline" }, 6 | { "romgrk/barbar.nvim", event = "VeryLazy", settings = "barbar" }, 7 | -- { "akinsho/bufferline.nvim", event = "VeryLazy", config = true }, 8 | { "luukvbaal/statuscol.nvim", event = "VeryLazy", settings = "statuscolumn" }, 9 | { "rcarriga/nvim-notify", settings = "notify" }, 10 | { 11 | "stevearc/oil.nvim", 12 | keys = { 13 | { 14 | ";", 15 | function() 16 | require("oil").toggle_float() 17 | end, 18 | desc = "Edit filesystem", 19 | }, 20 | }, 21 | opts = { float = { padding = 10 } }, 22 | }, 23 | { 24 | -- Tree explorer (filesystem, buffers, git_status) 25 | "nvim-neo-tree/neo-tree.nvim", 26 | branch = "main", 27 | event = "BufEnter", -- for netrw hijack 28 | settings = "neotree", 29 | }, 30 | "mrbjarksen/neo-tree-diagnostics.nvim", 31 | { 32 | "ibhagwan/fzf-lua", 33 | cmd = "FzfLua", 34 | keys = { 35 | { "fzf", "FzfLua files", desc = "Fzf files" }, 36 | { "fzg", "FzfLua live_grep", desc = "Fzf live grep" }, 37 | { "fzG", "FzfLua grep", desc = "Fzf grep" }, 38 | { "fzl", "FzfLua lsp_finder", desc = "Fzf lsp finder" }, 39 | { "fz.", "FzfLua resume", desc = "Fzf grep" }, 40 | { "fz/", "FzfLua lgrep_curbuf", desc = "Fzf search buffer" }, 41 | }, 42 | }, 43 | { "nvim-telescope/telescope.nvim", settings = "telescope" }, 44 | { "nvim-telescope/telescope-fzf-native.nvim", build = "make" }, 45 | { 46 | "nvim-telescope/telescope-file-browser.nvim", 47 | keys = { 48 | { 49 | "fe", 50 | function() 51 | require("telescope").extensions.file_browser.file_browser({ grouped = true }) 52 | end, 53 | desc = "File explorer", 54 | }, 55 | }, 56 | }, 57 | { 58 | "nvim-telescope/telescope-media-files.nvim", 59 | commit = "513e4ee385edd72bf0b35a217b7e39f84b6fe93c", 60 | enabled = function() 61 | return require("axie.utils").get_os() == "linux" 62 | end, 63 | keys = { { "fp", "Telescope media_files", desc = "Media files" } }, 64 | }, 65 | { 66 | "LinArcX/telescope-env.nvim", 67 | keys = { { "fE", "Telescope env env", desc = "Environment variables" } }, 68 | }, 69 | { 70 | "nvim-telescope/telescope-node-modules.nvim", 71 | keys = { { "fN", "Telescope node_modules list", desc = "Node modules" } }, 72 | }, 73 | { 74 | "jvgrootveld/telescope-zoxide", 75 | keys = { { "fZ", "Telescope zoxide list", desc = "Zoxide" } }, 76 | }, 77 | { 78 | "stevearc/dressing.nvim", 79 | event = "VeryLazy", 80 | opts = { 81 | input = { 82 | get_config = function() 83 | local disabled_filetypes = { "neo-tree" } 84 | if vim.tbl_contains(disabled_filetypes, vim.bo.filetype) then 85 | return { enabled = false } 86 | end 87 | end, 88 | }, 89 | }, 90 | }, 91 | { 92 | "AckslD/nvim-neoclip.lua", 93 | dependencies = "tami5/sqlite.lua", 94 | event = "VeryLazy", 95 | keys = { 96 | { "fy", "Telescope neoclip", desc = "Yank history" }, 97 | { "fM", "Telescope macroscope", desc = "Macro history" }, 98 | }, 99 | opts = { enable_persistent_history = true, enable_macro_history = true }, 100 | }, 101 | { "axieax/urlview.nvim", dev = dev_mode, settings = "urlview" }, 102 | { "rainbowhxch/beacon.nvim", event = "VeryLazy" }, 103 | { "petertriho/nvim-scrollbar", event = "VeryLazy", settings = "scrollbar" }, 104 | { "anuvyklack/pretty-fold.nvim", event = "VeryLazy", opts = { fill_char = "-" } }, 105 | { 106 | "anuvyklack/fold-preview.nvim", 107 | dependencies = "anuvyklack/nvim-keymap-amend", 108 | keys = { "zK" }, 109 | config = function() 110 | local pretty_fold_preview = require("fold-preview") 111 | pretty_fold_preview.setup() 112 | 113 | local keymap_amend = require("keymap-amend") 114 | keymap_amend("n", "zK", pretty_fold_preview.mapping.show_close_preview_open_fold) 115 | end, 116 | }, 117 | -- ALT: https://github.com/startup-nvim/startup.nvim 118 | { "goolord/alpha-nvim", event = "BufEnter", settings = "alpha" }, 119 | { "akinsho/toggleterm.nvim", settings = "toggleterm" }, 120 | "tknightz/telescope-termfinder.nvim", 121 | 122 | { 123 | "folke/twilight.nvim", 124 | cmd = "Twilight", 125 | keys = { { "Z", "Twilight", desc = "Dim inactive text" } }, 126 | config = true, 127 | }, 128 | { "folke/zen-mode.nvim", settings = "zen" }, 129 | -- m[ and m] to navigate marks as well 130 | { "chentoast/marks.nvim", event = "VeryLazy", config = true }, 131 | { 132 | "simnalamburt/vim-mundo", 133 | keys = { { "fu", "MundoToggle", desc = "Undo tree" } }, 134 | config = function() 135 | vim.g.mundo_auto_preview_delay = 0 136 | vim.g.mundo_playback_delay = 100 137 | end, 138 | }, 139 | } 140 | 141 | return require("axie.lazy").transform_spec(spec, "ui") 142 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/neotree.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: file nesting 4 | -- TODO: group empty https://github.com/nvim-neo-tree/neo-tree.nvim/issues/552 5 | -- TODO: highlight open buffers 6 | -- TODO: file info (size, perms, time etc.) 7 | 8 | M.cmd = "Neotree" 9 | 10 | M.keys = { { ";", "Neotree toggle", { desc = "File explorer" } } } 11 | 12 | --[[ NOTE: slow startup + hijack if opening to a directory 13 | function M.init() 14 | for _, arg in ipairs(vim.fn.argv()) do 15 | local stat = vim.loop.fs_stat(arg) 16 | if stat and stat.type == "directory" then 17 | require("neo-tree") 18 | end 19 | end 20 | end 21 | ]] 22 | 23 | function M.config() 24 | require("neo-tree").setup({ 25 | sources = { 26 | "filesystem", 27 | "buffers", 28 | "git_status", 29 | "diagnostics", 30 | }, 31 | source_selector = { 32 | winbar = true, 33 | sources = { 34 | { source = "filesystem", display_name = " 󰉓 Files " }, 35 | { source = "buffers", display_name = " 󱔗 Buffers " }, 36 | { source = "git_status", display_name = " 󰊢 Git " }, 37 | { source = "diagnostics", display_name = "  LSP " }, 38 | }, 39 | }, 40 | use_popups_for_input = false, 41 | -- popup_border_style = "rounded", 42 | default_component_configs = { 43 | indent_size = 1, 44 | name = { 45 | trailing_slash = true, 46 | highlight_opened_files = true, 47 | }, 48 | }, 49 | window = { 50 | position = "float", 51 | width = "30%", 52 | popup = { 53 | position = { col = "100%", row = "2" }, 54 | size = function(state) 55 | local root_name = vim.fn.fnamemodify(state.path, ":~") 56 | local root_len = string.len(root_name) + 4 57 | return { 58 | width = math.max(root_len, 50), 59 | height = vim.o.lines - 6, 60 | } 61 | end, 62 | }, 63 | mappings = { 64 | -- relative path in add prompt 65 | a = { 66 | "add", 67 | config = { show_path = "relative" }, 68 | }, 69 | A = { 70 | -- "add_directory", 71 | -- config = { show_path = "relative" }, 72 | "add", 73 | config = { show_path = "absolute" }, 74 | }, 75 | }, 76 | }, 77 | filesystem = { 78 | follow_current_file = { 79 | enabled = true, 80 | leave_dirs_open = false, 81 | }, 82 | group_empty_dirs = true, 83 | bind_to_cwd = false, 84 | hijack_netrw_behavior = "open_current", 85 | use_libuv_file_watcher = true, 86 | filtered_items = { 87 | hide_dotfiles = false, 88 | never_show = { ".git" }, 89 | }, 90 | }, 91 | event_handlers = { 92 | { 93 | -- auto close 94 | event = "file_opened", 95 | handler = function(file_path) 96 | require("neo-tree").close_all() 97 | end, 98 | }, 99 | { 100 | -- show netrw hijacked buffer in buffer list 101 | event = "neo_tree_buffer_enter", 102 | handler = function() 103 | local bufnr = vim.api.nvim_get_current_buf() 104 | vim.schedule(function() 105 | local _, position = pcall(vim.api.nvim_buf_get_var, bufnr, "neo_tree_position") 106 | if position == "current" then 107 | vim.api.nvim_buf_set_option(bufnr, "buflisted", true) 108 | vim.opt_local.winbar = nil 109 | end 110 | end) 111 | end, 112 | }, 113 | { 114 | -- refresh winbar for non-current (NC) windows 115 | event = "neo_tree_window_after_close", 116 | handler = vim.schedule_wrap(require("axie.winbar").show_winbar), 117 | }, 118 | }, 119 | }) 120 | end 121 | 122 | return M 123 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/notify.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { 4 | { "fn", "Telescope notify", desc = "Search notifications" }, 5 | { 6 | "Q", 7 | function() 8 | require("notify").dismiss() 9 | end, 10 | desc = "Dismiss notifications", 11 | }, 12 | } 13 | 14 | function M.config() 15 | require("notify").setup({ 16 | background_colour = "NormalFloat", 17 | render = "minimal", 18 | on_open = function(win) 19 | -- transparent background 20 | -- BUG: does not blend fully with transparent background 21 | -- TRY: https://github.com/folke/zen-mode.nvim/blob/main/lua/zen-mode/view.lua#L198-L210 22 | -- vim.api.nvim_win_set_option(win, "winblend", 40) 23 | -- vim.api.nvim_win_set_config(win, { zindex = 20000 }) 24 | -- vim.api.nvim_win_set_option(win, "winhighlight", "Normal:NormalFloat") 25 | end, 26 | }) 27 | 28 | -- vim.cmd([[ 29 | -- highlight link NotifyERRORBody NormalFloat 30 | -- highlight link NotifyWARNBody NormalFloat 31 | -- highlight link NotifyINFOBody NormalFloat 32 | -- highlight link NotifyDEBUGBody NormalFloat 33 | -- highlight link NotifyTRACEBody NormalFloat 34 | -- ]]) 35 | end 36 | 37 | return M 38 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/scrollbar.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.config() 4 | require("scrollbar").setup({ 5 | -- NOTE: disappears very quickly 6 | show_in_active_only = true, 7 | handle = { highlight = "CursorLine" }, 8 | excluded_filetypes = { 9 | "prompt", 10 | "TelescopePrompt", 11 | "terminal", 12 | "lspinfo", 13 | "alpha", 14 | "toggleterm", 15 | }, 16 | }) 17 | require("scrollbar.handlers.search").setup() 18 | end 19 | 20 | return M 21 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/statuscolumn.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: fold preview on right click 4 | 5 | local function git_hunk_actions() 6 | local actions = require("gitsigns").get_actions() 7 | local items = {} 8 | for name, action in pairs(actions) do 9 | table.insert(items, { name = name, action = action }) 10 | end 11 | 12 | vim.ui.select(items, { 13 | prompt = "Git hunk actions", 14 | format_item = function(item) 15 | return item.name:sub(1, 1):upper() .. item.name:gsub("_", " "):sub(2) 16 | end, 17 | }, function(item) 18 | if item ~= nil then 19 | item.action() 20 | end 21 | end) 22 | end 23 | 24 | function M.config() 25 | local builtin = require("statuscol.builtin") 26 | builtin.diagnostic_click = function(args) 27 | if args.button == "l" then 28 | vim.diagnostic.open_float({ border = "rounded" }) 29 | elseif args.button == "m" then 30 | require("axie.plugins.lsp.code_actions").native(true) 31 | elseif args.button == "r" then 32 | require("axie.plugins.lsp.code_actions").native() 33 | end 34 | end 35 | 36 | local clickmod = "c" 37 | require("statuscol").setup({ 38 | relculright = true, 39 | segments = { 40 | { 41 | sign = { name = { "Dap*" }, maxwidth = 1, auto = true }, 42 | click = "v:lua.ScSa", 43 | }, 44 | { 45 | sign = { name = { "Diagnostic", "todo*" }, maxwidth = 1, auto = true }, 46 | click = "v:lua.ScSa", 47 | }, 48 | { text = { builtin.lnumfunc }, click = "v:lua.ScLa" }, 49 | { 50 | text = { 51 | function(args) 52 | local result = builtin.foldfunc(args) 53 | return result == "" and " " or result 54 | end, 55 | }, 56 | click = "v:lua.ScFa", 57 | }, 58 | { 59 | sign = { name = { ".*" }, maxwidth = 2, colwidth = 1, auto = true, wrap = true }, 60 | click = "v:lua.ScSa", 61 | }, 62 | }, 63 | clickmod = clickmod, 64 | clickhandlers = { 65 | Lnum = function(args) 66 | if args.button == "l" then 67 | -- NOTE: conditional breakpoint with `clickmod` 68 | builtin.toggle_breakpoint(args) 69 | elseif args.button == "m" then 70 | git_hunk_actions() 71 | elseif args.button == "r" then 72 | require("axie.plugins.lsp.code_actions").native() 73 | end 74 | end, 75 | FoldClose = function(args) 76 | if args.button == "l" then 77 | vim.api.nvim_cmd({ 78 | cmd = "normal", 79 | bang = true, 80 | args = { "z" .. (args.mods:find(clickmod) and "O" or "o") }, 81 | }) 82 | elseif args.button == "r" then 83 | require("fold-preview").toggle_preview() 84 | end 85 | end, 86 | }, 87 | }) 88 | end 89 | 90 | return M 91 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/toggleterm.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- TODO: warn before exit if hidden floaterm active 4 | 5 | M.cmd = { 6 | "TermSelect", 7 | "TermExec", 8 | "ToggleTerm", 9 | "ToggleTermToggleAll", 10 | "ToggleTermSendVisualLines", 11 | "ToggleTermSendVisualSelection", 12 | "ToggleTermSendCurrentLine", 13 | "ToggleTermSetName", 14 | } 15 | 16 | function M.attach() 17 | vim.opt_local.spell = false 18 | vim.keymap.set("n", "", "", { silent = true, buffer = 0 }) 19 | vim.keymap.set("t", "", [[]], { desc = "Toggle mode", buffer = 0 }) 20 | vim.keymap.set("n", "", "startinsert", { desc = "Toggle mode", buffer = 0 }) 21 | vim.keymap.set("t", "", [[]], { buffer = 0 }) 22 | end 23 | 24 | function M.init() 25 | local this = require("axie.plugins.ui.toggleterm") 26 | local filetype_map = require("axie.utils").filetype_map 27 | local require_args = require("axie.utils").require_args 28 | filetype_map("html", "n", ",o", require_args(this.liveserver, true), { 29 | desc = "Start liveserver for current file", 30 | }) 31 | filetype_map("html", "n", ",O", require_args(this.liveserver, false), { 32 | desc = "Start liveserver for current project", 33 | }) 34 | 35 | vim.keymap.set("n", "gg", this.lazygit, { desc = "Lazygit" }) 36 | vim.keymap.set("n", "gG", this.lazydocker, { desc = "Lazydocker" }) 37 | 38 | -- NOTE: actually toggles instead of opening a new toggleterm? 39 | -- TODO: toggle vs more in same layout 40 | local directions = { "float", "horizontal", "vertical", "tab" } 41 | for i, direction in ipairs(directions) do 42 | vim.keymap.set( 43 | { "n", "i", "t" }, 44 | string.format("", i), 45 | string.format("%dToggleTerm direction=%s", i, direction), 46 | { desc = "Toggleterm " .. direction } 47 | ) 48 | end 49 | vim.keymap.set({ "n", "i", "t" }, [[]], "Telescope termfinder find", { desc = "Find terminals" }) 50 | end 51 | 52 | function M.config() 53 | require("toggleterm").setup({ 54 | persist_mode = false, 55 | close_on_exit = false, 56 | size = function(term) 57 | if term.direction == "horizontal" then 58 | return 15 59 | elseif term.direction == "vertical" then 60 | return math.ceil(vim.o.columns * 0.5) 61 | end 62 | end, 63 | float_opts = { 64 | border = "curved", 65 | width = math.ceil(vim.o.columns * 0.8), 66 | height = math.ceil(vim.o.lines * 0.8), 67 | highlights = { 68 | border = "FloatBorder", 69 | }, 70 | }, 71 | }) 72 | vim.api.nvim_create_autocmd("TermOpen", { 73 | desc = "Toggleterm attach", 74 | pattern = "term://*", 75 | callback = require("axie.plugins.ui.toggleterm").attach, 76 | }) 77 | vim.api.nvim_create_autocmd("TermClose", { 78 | desc = "Close terminal buffers on success", 79 | callback = function() 80 | if vim.v.event.status == 0 then 81 | vim.api.nvim_buf_delete(0, {}) 82 | end 83 | end, 84 | }) 85 | end 86 | 87 | function M.lazygit() 88 | local lazygit = require("toggleterm.terminal").Terminal:new({ 89 | display_name = "lazygit", 90 | cmd = "lazygit", 91 | direction = "float", 92 | -- float_opts = { highlights = { border = "Normal" } }, 93 | hidden = true, 94 | count = 5, 95 | }) 96 | lazygit:toggle() 97 | end 98 | 99 | function M.lazydocker() 100 | local lazydocker = require("toggleterm.terminal").Terminal:new({ 101 | display_name = "lazydocker", 102 | cmd = "lazydocker", 103 | direction = "float", 104 | -- float_opts = { highlights = { border = "Normal" } }, 105 | hidden = true, 106 | count = 6, 107 | }) 108 | lazydocker:toggle() 109 | end 110 | 111 | function M.liveserver(current_file) 112 | local filename = (current_file or false) and vim.fn.expand("%") or "" 113 | local liveserver = require("toggleterm.terminal").Terminal:new({ 114 | -- INSTALL: npm install -g live-server 115 | cmd = "live-server " .. filename, 116 | direction = "float", 117 | -- float_opts = { highlights = { border = "Normal" } }, 118 | hidden = true, 119 | count = 7, 120 | on_open = function() 121 | vim.api.nvim_buf_set_keymap(0, "t", "", "close", { silent = true }) 122 | end, 123 | }) 124 | liveserver:toggle() 125 | end 126 | 127 | return M 128 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/urlview.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = "UrlView" 4 | 5 | M.keys = { 6 | "[u", 7 | "]u", 8 | { "\\u", "UrlView", desc = "Buffer URLs" }, 9 | { "\\U", "UrlView lazy", desc = "Plugin URLs" }, 10 | } 11 | 12 | function M.config() 13 | require("urlview").setup({ 14 | default_title = "Links", 15 | default_include_branch = true, 16 | log_level_min = vim.log.levels.TRACE, 17 | jump = { 18 | prev = "[U", 19 | next = "]U", 20 | }, 21 | }) 22 | 23 | local search = require("urlview.search") 24 | local search_helpers = require("urlview.search.helpers") 25 | search.jira = search_helpers.generate_custom_search({ 26 | capture = "AXIE%-%d+", 27 | format = "https://jira.axieax.com/browse/%s", 28 | }) 29 | end 30 | 31 | return M 32 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/whichkey.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.opts = { 4 | plugins = { 5 | spelling = { enabled = true }, 6 | -- presets = { operators = false }, -- for modes.nvim 7 | }, 8 | window = { winblend = 20 }, 9 | layout = { align = "center" }, 10 | } 11 | 12 | M.config = function(_, opts) 13 | local wk = require("which-key") 14 | wk.setup(opts) 15 | wk.register({ 16 | ["f"] = { name = "find" }, 17 | ["fz"] = { name = "fzf" }, 18 | ["g"] = { name = "git" }, 19 | ["gd"] = { name = "git diff" }, 20 | ["d"] = { name = "debug" }, 21 | ["l"] = { name = "lsp" }, 22 | ["t"] = { name = "test" }, 23 | ["r"] = { name = "run actions" }, 24 | ["m"] = { name = "harpoon" }, 25 | ["["] = { name = "previous" }, 26 | ["]"] = { name = "next" }, 27 | }) 28 | end 29 | 30 | return M 31 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/ui/zen.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- NOTE: barbar disappears https://github.com/folke/zen-mode.nvim/issues/21 4 | 5 | M.cmd = "ZenMode" 6 | 7 | M.keys = { { "z", "ZenMode", desc = "Focus mode" } } 8 | 9 | function M.config() 10 | local toggle_functions = function() 11 | -- TODO: force off on_open, restore previous state on_close 12 | -- [[ gitsigns ]] 13 | require("gitsigns").toggle_numhl() 14 | -- require("gitsigns").toggle_current_line_blame() 15 | 16 | -- [[ LSP diagnostics ]] 17 | require("axie.utils").toggle_diagnostics() 18 | 19 | -- [[ todo-comment ]] 20 | -- SEE: https://github.com/folke/todo-comments.nvim/issues/27 21 | 22 | -- [[ toggle sidecolumn? ]] 23 | -- require("axie.utils").toggle_signcolumn() 24 | end 25 | 26 | -- Zen mode 27 | require("zen-mode").setup({ 28 | plugins = { 29 | twilight = { enabled = true }, 30 | gitsigns = { enabled = false }, 31 | -- diagnostics = { enabled = false }, -- NOTE: prefer custom diagnostics view 32 | }, 33 | on_open = function(win) 34 | toggle_functions() 35 | end, 36 | on_close = function() 37 | toggle_functions() 38 | end, 39 | }) 40 | end 41 | 42 | return M 43 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/utility/dial.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- ALT: lua function version 4 | M.keys = { 5 | { "", "(dial-increment)", mode = { "n", "v" } }, 6 | { "", "(dial-decrement)", mode = { "n", "v" } }, 7 | { "g", "g(dial-increment)", mode = { "n", "v" } }, 8 | { "g", "g(dial-decrement)", mode = { "n", "v" } }, 9 | } 10 | 11 | function M.config() 12 | local this = require("axie.plugins.utility.dial") 13 | local cyclic_words = this.cyclic_words 14 | local cyclic_symbols = this.cyclic_symbols 15 | local cyclic_dates = this.cyclic_dates 16 | 17 | local augend = require("dial.augend") 18 | require("dial.config").augends:register_group({ 19 | default = { 20 | augend.decimal_fraction.new({}), 21 | augend.integer.alias.decimal_int, 22 | augend.integer.alias.hex, 23 | augend.integer.alias.octal, 24 | augend.integer.alias.binary, 25 | augend.hexcolor.new({}), 26 | augend.paren.alias.quote, 27 | augend.paren.alias.lua_str_literal, 28 | augend.paren.alias.rust_str_literal, 29 | augend.paren.alias.brackets, 30 | -- augend.constant.alias.alpha, 31 | -- augend.constant.alias.Alpha, 32 | augend.semver.alias.semver, 33 | augend.misc.alias.markdown_header, 34 | cyclic_dates("%-H:%M", "min"), 35 | cyclic_dates("%-I:%M", "min"), 36 | cyclic_dates("%-d/%-m/%y", "day"), 37 | cyclic_dates("%-d/%-m/%Y", "day"), 38 | cyclic_words({ "true", "false" }), 39 | cyclic_words({ "on", "off" }), 40 | cyclic_words({ "north", "east", "south", "west" }), 41 | cyclic_words({ "and", "or" }), 42 | cyclic_symbols({ "&&", "||" }), 43 | cyclic_symbols({ "==", "!=" }), 44 | cyclic_symbols({ "===", "!==" }), 45 | cyclic_symbols({ ">", "<" }), 46 | cyclic_symbols({ ">=", "<=" }), 47 | cyclic_symbols({ "+=", "-=", "*=", "/=", "//=", "%=" }), 48 | cyclic_symbols({ "++", "--" }), 49 | }, 50 | }) 51 | end 52 | 53 | -- case_insensitive: lowercase, uppercase, lowercase with first letter uppercase 54 | -- strict_casing = not case_insensitive 55 | function M.cyclic_words(elements, strict_casing) 56 | local augend = require("dial.augend") 57 | return augend.constant.new({ 58 | elements = elements, 59 | word = true, 60 | cyclic = true, 61 | preserve_case = not strict_casing, 62 | }) 63 | end 64 | 65 | function M.cyclic_symbols(elements) 66 | local augend = require("dial.augend") 67 | return augend.constant.new({ 68 | elements = elements, 69 | word = false, 70 | cyclic = true, 71 | }) 72 | end 73 | 74 | function M.cyclic_dates(pattern, default_kind) 75 | local augend = require("dial.augend") 76 | return augend.date.new({ 77 | pattern = pattern, 78 | default_kind = default_kind, 79 | only_valid = true, 80 | clamp = true, 81 | end_sensitive = false, 82 | }) 83 | end 84 | 85 | return M 86 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/utility/hlslens.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.override_lens(render, plist, nearest, idx, r_idx) 4 | local sfw = vim.v.searchforward == 1 5 | local indicator, text, chunks 6 | local abs_r_idx = math.abs(r_idx) 7 | if abs_r_idx >= 1 then 8 | indicator = ("%d%s"):format(abs_r_idx, sfw ~= (r_idx > 1) and "▲" or "▼") 9 | -- elseif abs_r_idx == 1 then 10 | -- indicator = sfw ~= (r_idx == 1) and "▲" or "▼" 11 | else 12 | indicator = "" 13 | end 14 | 15 | local lnum, col = unpack(plist[idx]) 16 | if nearest then 17 | local cnt = #plist 18 | if indicator ~= "" then 19 | text = ("[%s%d/%d]"):format(indicator, idx, cnt) 20 | else 21 | text = ("[%d/%d]"):format(idx, cnt) 22 | end 23 | chunks = { { " ", "Ignore" }, { text, "HlSearchLensNear" } } 24 | else 25 | text = ("[%s%d]"):format(indicator, idx) 26 | chunks = { { " ", "Ignore" }, { text, "HlSearchLens" } } 27 | end 28 | render.set_virt(0, lnum - 1, col - 1, chunks, nearest) 29 | end 30 | 31 | function M.config() 32 | local this = require("axie.plugins.utility.hlslens") 33 | require("hlslens").setup({ 34 | -- statusline overlay instead of virtual text 35 | -- nearest_float_when = "always", 36 | override_lens = this.override_lens, 37 | }) 38 | 39 | -- clear highlighting on double escape 40 | -- ISSUE: delay 41 | -- vim.keymap.set("n", "", [[:let @/=""]], { silent = true }) 42 | 43 | -- other search methods 44 | for _, trigger in ipairs({ "n", "N" }) do 45 | vim.keymap.set( 46 | "n", 47 | trigger, 48 | string.format("execute('normal! ' . v:count1 . '%s')lua require('hlslens').start()zz", trigger) 49 | ) 50 | end 51 | 52 | for _, trigger in ipairs({ "*", "g*", "#", "g#" }) do 53 | vim.keymap.set("n", trigger, trigger .. "lua require'hlslens'.start()zz") 54 | end 55 | 56 | -- vim-visual-multi highlights (ctrl-n) 57 | -- BUG: lens disappear with navigation 58 | local vmlens = vim.api.nvim_create_augroup("VMLens", {}) 59 | vim.api.nvim_create_autocmd("User", { 60 | pattern = "visual_multi_start", 61 | group = vmlens, 62 | callback = this.vmlens_start, 63 | }) 64 | vim.api.nvim_create_autocmd("User", { 65 | pattern = "visual_multi_exit", 66 | group = vmlens, 67 | callback = this.vmlens_exit, 68 | }) 69 | end 70 | 71 | local hlslens_config 72 | local previous_lens 73 | 74 | function M.vmlens_start() 75 | local ok, hlslens = pcall(require, "hlslens") 76 | if ok then 77 | hlslens_config = require("hlslens.config") 78 | previous_lens = hlslens_config.override_lens 79 | hlslens_config.override_lens = require("axie.plugins.utility.hlslens").override_lens 80 | hlslens.start(true) 81 | end 82 | end 83 | 84 | function M.vmlens_exit() 85 | local ok, hlslens = pcall(require, "hlslens") 86 | if ok then 87 | hlslens_config.override_lens = previous_lens 88 | hlslens.start(true) 89 | end 90 | end 91 | 92 | return M 93 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/utility/iconpicker.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = { 4 | "IconPickerInsert", 5 | "IconPickerNormal", 6 | "IconPickerYank", 7 | } 8 | 9 | M.keys = { 10 | { "", "IconPickerInsert", mode = "i", desc = "Icon picker" }, 11 | { "fi", "IconPickerYank", desc = "Icon picker" }, 12 | } 13 | 14 | M.opts = { disable_legacy_commands = true } 15 | 16 | return M 17 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/utility/neoscroll.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.keys = { "", "", "", "", "", "", "zt", "zz", "zb", "{", "}", "gg", "G" } 4 | 5 | -- REF: https://github.com/roobert/neoscroll-motions.nvim 6 | local function calculate_pattern_lines(pattern, backwards) 7 | local current_line = vim.api.nvim_win_get_cursor(0)[1] 8 | local direction = backwards and "b" or "n" 9 | local pattern_line = vim.api.nvim_call_function("search", { pattern, direction }) 10 | local line_diff = pattern_line - current_line 11 | print(current_line, pattern_line, line_diff, direction) 12 | require("neoscroll").scroll(line_diff, true, 50) 13 | end 14 | 15 | M.config = function() 16 | require("neoscroll").setup() 17 | 18 | -- https://github.com/karb94/neoscroll.nvim/issues/55 19 | -- BUG: scrolls to the wrong line sometimes 20 | -- vim.keymap.set("n", "{", function() 21 | -- calculate_pattern_lines("^$", true) 22 | -- end) 23 | -- vim.keymap.set("n", "}", function() 24 | -- calculate_pattern_lines("^$", false) 25 | -- end) 26 | 27 | -- BUG: affects view centering after 28 | -- vim.keymap.set("n", "gg", function() 29 | -- local current_line = vim.api.nvim_win_get_cursor(0)[1] 30 | -- require("neoscroll").scroll(-current_line, true, 50) 31 | -- end) 32 | -- vim.keymap.set("n", "G", function() 33 | -- local current_line = vim.api.nvim_win_get_cursor(0)[1] 34 | -- local num_lines = vim.api.nvim_buf_line_count(0) 35 | -- require("neoscroll").scroll(num_lines - current_line, true, 50) 36 | -- end) 37 | 38 | require("neoscroll.config").set_mappings({ 39 | -- https://github.com/karb94/neoscroll.nvim/issues/55 40 | -- ["{"] = { "scroll", { "-vim.wo.scroll", "true", "250" } }, 41 | -- ["}"] = { "scroll", { "vim.wo.scroll", "true", "250" } }, 42 | -- [""] = { "scroll", { "-vim.wo.scroll", "false", "0" } }, 43 | -- [""] = { "scroll", { "vim.wo.scroll", "false", "0" } }, 44 | -- https://github.com/karb94/neoscroll.nvim/issues/50 45 | -- [""] = { "scroll", { "-0.10", "false", "50" } }, 46 | -- [""] = { "scroll", { "0.10", "false", "50" } }, 47 | }) 48 | -- vim.keymap.set({ "n", "i", "v" }, "", "") 49 | -- vim.keymap.set({ "n", "i", "v" }, "", "") 50 | end 51 | 52 | return M 53 | -------------------------------------------------------------------------------- /nvim/lua/axie/plugins/utility/sessions.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.cmd = "SessionManager" 4 | 5 | M.keys = { 6 | { 7 | "fO", 8 | function() 9 | require("session_manager").load_session() 10 | end, 11 | desc = "Find sessions", 12 | }, 13 | } 14 | 15 | function M.config() 16 | require("session_manager").setup({ 17 | autoload_mode = require("session_manager.config").AutoloadMode.Disabled, 18 | }) 19 | end 20 | 21 | return M 22 | -------------------------------------------------------------------------------- /nvim/lua/axie/utils/config.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.dev_mode = false 4 | M.nvchad_theme = true 5 | M.copilot_enabled = true 6 | M.colorscheme = "catppuccin" 7 | M.default_folds = false 8 | 9 | -- Icons 10 | M.diagnostics_icons = { 11 | Error = "", 12 | Warn = "", 13 | Hint = "󰍉", 14 | -- Hint = "", 15 | Info = "", 16 | VirtualText = "", 17 | } 18 | 19 | M.fileformat_icons = { 20 | unix = "", 21 | mac = "", 22 | dos = "", 23 | } 24 | 25 | M.symbol_icons = { 26 | Root = "", 27 | File = "󰈙", 28 | Folder = "󰉋", 29 | Module = "", 30 | Package = "", -- 󰏖 31 | Namespace = "", -- 󰌗 32 | Struct = "", 33 | Class = "󰠱", --   34 | Function = "󰊕", --  35 | Lambda = "λ", 36 | Method = "󰊕", 37 | Constructor = "", --  38 | Interface = "", 39 | Enum = "", -- 󰒻 40 | EnumMember = "", 41 | Property = "", 42 | Field = "󰜢", -- 󰇽 43 | Object = "󰅩", 44 | Key = "󰌋", 45 | Value = "󰎠", -- 󰕘 46 | Array = "", 47 | Variable = "󰀫", 48 | Constant = "󰏿", --  49 | String = "󰀬", 50 | Number = "󰎠", 51 | Boolean = "󰨙", --  52 | Unit = "", 53 | Null = "󰟢", 54 | Operator = "󰆕", 55 | TypeParameter = "󰉿", -- 󰊄 󰅲 56 | Text = "", 57 | Event = "", 58 | Macro = "", 59 | Reference = "", --  60 | Snippet = "", --  61 | Color = "", 62 | Keyword = "󰌋", 63 | StaticMethod = "󰊕", -- ccls 64 | } 65 | 66 | return M 67 | -------------------------------------------------------------------------------- /nvim/lua/axie/utils/init.lua: -------------------------------------------------------------------------------- 1 | -- Helper functions 2 | -- TODO: apply highlight group 3 | 4 | local M = {} 5 | 6 | -- Applies options to a meta-accessor 7 | -- @param meta_accessor (table) vim meta-accessor, such as vim.opt 8 | -- @param options (table) key-value table for settings to be applied 9 | function M.vim_apply(meta_accessor, options) 10 | for k, v in pairs(options) do 11 | meta_accessor[k] = v 12 | end 13 | end 14 | 15 | --- Sets a given keymap conditionally based on a given filetype 16 | -- @param filetype (string) filetype to register keymap 17 | ---@vararg any `vim.keymap.set` arguments (mode, lhs, rhs, opts) with optional opts 18 | function M.filetype_map(ft, mode, lhs, rhs, opts) 19 | -- set buffer option by default 20 | opts = vim.tbl_extend("keep", opts or {}, { buffer = true }) 21 | vim.api.nvim_create_autocmd("FileType", { 22 | desc = string.format("%s map for %s", ft, lhs), 23 | pattern = ft, 24 | callback = function() 25 | vim.keymap.set(mode, lhs, rhs, opts) 26 | end, 27 | }) 28 | end 29 | 30 | --- Overrides the filetype for files matching the given pattern 31 | ---@param pattern (string|table) pattern to match 32 | ---@param ft (string) filetype to set 33 | function M.override_filetype(pattern, ft) 34 | if type(pattern) == "string" then 35 | pattern = { pattern } 36 | end 37 | 38 | local config = {} 39 | for _, p in ipairs(pattern) do 40 | config[p] = ft 41 | end 42 | 43 | vim.filetype.add({ pattern = config }) 44 | end 45 | 46 | -- Send a notification 47 | -- NOTE: notify plugin accepts table as multi-line string, vim.notify has opts 48 | function M.notify(...) 49 | local ok, notifier = pcall(require, "notify") 50 | if not ok then 51 | notifier = vim 52 | end 53 | notifier.notify(...) 54 | end 55 | 56 | -- Display path of current buffer 57 | function M.display_path() 58 | M.notify(vim.fn.fnamemodify(vim.fn.expand("%"), ":p"), vim.log.levels.INFO, { 59 | title = "Path", 60 | render = "default", 61 | }) 62 | end 63 | 64 | -- Display path of current working directory 65 | function M.display_cwd() 66 | M.notify(vim.loop.cwd(), vim.log.levels.INFO, { 67 | title = "Cwd", 68 | render = "default", 69 | }) 70 | end 71 | 72 | --- vim.tbl_flatten limited to only once (top-level) 73 | ---@param list table @list to flatten 74 | ---@return table @flattened list 75 | function M.list_flatten_once(list) 76 | local result = {} 77 | for _, t in ipairs(list) do 78 | for _, v in ipairs(t) do 79 | table.insert(result, v) 80 | end 81 | end 82 | return result 83 | end 84 | 85 | --- Gets the operating system type 86 | ---@return string @os 87 | function M.get_os() 88 | return vim.loop.os_uname().sysname:lower():gsub("^darwin$", "mac") 89 | end 90 | 91 | --- Reloads a module's require cache 92 | ---@param module_name (string) module to reload 93 | ---@vararg any additional arguments to pass to plenary reload module 94 | function M.reload_module(module_name, ...) 95 | local ok, plenary = pcall(require, "plenary.reload") 96 | if ok then 97 | plenary.reload_module(module_name, ...) 98 | else 99 | M.notify("Could not reload module: " .. module_name, vim.log.levels.ERROR) 100 | end 101 | end 102 | 103 | --- Returns a function which calls f with the given arguments 104 | ---@param f (function|string) function to be called 105 | ---@vararg any arguments to be passed to f 106 | ---@return function 107 | function M.require_args(f, ...) 108 | local args = { ... } 109 | if type(f) == "string" then 110 | f = require(f) 111 | end 112 | return function() 113 | return f(unpack(args)) 114 | end 115 | end 116 | 117 | --- Restores position after calling @func 118 | ---@param func function @to be wrapped 119 | ---@return function 120 | function M.restore_position_wrap(func) 121 | return function(...) 122 | local pos = vim.api.nvim_win_get_cursor(0) 123 | func(...) 124 | vim.api.nvim_win_set_cursor(0, pos) 125 | end 126 | end 127 | 128 | function M.toggle_diagnostics() 129 | if vim.diagnostic.is_disabled() then 130 | vim.diagnostic.enable() 131 | else 132 | vim.diagnostic.disable() 133 | end 134 | end 135 | 136 | return M 137 | -------------------------------------------------------------------------------- /nvim/lua/axie/winbar.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local utils = require("axie.utils") 4 | local symbol_icons = require("axie.utils.config").symbol_icons 5 | 6 | local ignored_filetypes = { 7 | "", 8 | "alpha", 9 | "neo-tree", -- NOTE: managed by neo-tree 10 | "toggleterm", 11 | "lspinfo", 12 | "null-ls-info", 13 | "glowpreview", 14 | "help", 15 | "man", 16 | "prompt", 17 | "mason", 18 | "aerial", 19 | "checkhealth", 20 | "qf", 21 | "netrw", 22 | } 23 | 24 | local function highlight(content, hl_group) 25 | return string.format("%%#%s#%s%%*", hl_group, content) 26 | end 27 | 28 | local function clickable(content, fn_name) 29 | fn_name = "v:lua.require'axie.winbar'." .. fn_name 30 | return string.format("%%0@%s@%s%%T", fn_name, content) 31 | end 32 | 33 | function M.file_icon() 34 | local filetype = vim.fn.expand("%:p:e") 35 | local ok, devicons = pcall(require, "nvim-web-devicons") 36 | if ok then 37 | local icon = devicons.get_icon("", filetype) 38 | if icon then 39 | return icon 40 | end 41 | end 42 | return "" 43 | end 44 | 45 | function M.file_name() 46 | return vim.fn.expand("%:p:t") 47 | end 48 | 49 | local show_context = true 50 | 51 | function M.toggle_context() 52 | show_context = not show_context 53 | end 54 | 55 | function M.context() 56 | if not show_context then 57 | return "" 58 | end 59 | 60 | local ok, aerial = pcall(require, "aerial") 61 | if not ok then 62 | return "" 63 | end 64 | 65 | local symbols = aerial.get_location(false) 66 | local context = table.concat( 67 | vim.tbl_map(function(symbol) 68 | -- anonymous function 69 | if symbol.kind == "Function" and symbol.name == "" then 70 | return highlight(symbol_icons.Lambda, "NavicIconsFunction") 71 | end 72 | 73 | -- highlight function parameters 74 | local text = highlight(symbol.name, "NavicText") 75 | if vim.tbl_contains({ "Function", "Method", "Constructor" }, symbol.kind) then 76 | local name, param_list = string.match(symbol.name, "(.+)%((.*)%)") 77 | if name and param_list then 78 | local params = vim.split(param_list, ", ") 79 | local comma = highlight(", ", "NavicText") 80 | text = highlight(name .. "(", "NavicText") 81 | .. table.concat( 82 | vim.tbl_map(function(param) 83 | return highlight(param, "NavicIconsProperty") 84 | end, params), 85 | comma 86 | ) 87 | .. highlight(")", "NavicText") 88 | end 89 | end 90 | 91 | return highlight(symbol.icon .. " ", "NavicIcons" .. symbol.kind) .. text 92 | end, symbols), 93 | "  " 94 | ) 95 | 96 | return context ~= "" and highlight(":: ", "NavicSeparator") .. context or "" 97 | end 98 | 99 | local focused_win = vim.api.nvim_get_current_win() 100 | 101 | function M.eval() 102 | local is_nc = focused_win ~= vim.api.nvim_get_current_win() 103 | local file_hl = "NavicIconsFile" .. (is_nc and "NC" or "") 104 | local modified = vim.api.nvim_buf_get_option(0, "modified") 105 | 106 | local ok, value = pcall(function() 107 | local components = { 108 | highlight(modified and "*" or "", "WinBarModified"), 109 | highlight(M.file_icon(), file_hl), 110 | highlight(clickable(M.file_name(), "toggle_context"), file_hl), 111 | } 112 | if not is_nc then 113 | table.insert(components, highlight(M.context(), "WinBarContext")) 114 | end 115 | 116 | return table.concat(components, " ") 117 | end) 118 | return ok and value or highlight(value, "ErrorMsg") 119 | end 120 | 121 | function M.show_winbar() 122 | local win = vim.api.nvim_get_current_win() 123 | local filetype = vim.api.nvim_buf_get_option(0, "filetype") 124 | if not vim.tbl_contains(ignored_filetypes, filetype) then 125 | vim.api.nvim_win_set_option(win, "winbar", "%{%v:lua.require'axie.winbar'.eval()%}") 126 | end 127 | focused_win = win 128 | end 129 | 130 | function M.activate() 131 | vim.api.nvim_create_autocmd({ "BufWinEnter", "BufWinLeave" }, { 132 | desc = "Activate Winbar", 133 | group = vim.api.nvim_create_augroup("WinBarGroup", {}), 134 | callback = vim.schedule_wrap(M.show_winbar), 135 | }) 136 | end 137 | 138 | return M 139 | -------------------------------------------------------------------------------- /nvim/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install Neovim" 5 | if ! check_dependency "nvim" && confirm "$action"; then 6 | if is_linux; then 7 | sudo pacman -S neovim 8 | elif is_mac; then 9 | brew install neovim 10 | else 11 | echo "Failed to $action: unsupported OS" 12 | fi 13 | fi 14 | 15 | action="install Neovim Python support" 16 | if ! $OS_PYTHON -c "import neovim" 2> /dev/null && confirm "$action"; then 17 | $OS_PIP install pynvim 18 | fi 19 | 20 | # TEMP: https://github.com/williamboman/mason.nvim/issues/392 21 | action="install prettier extensions" 22 | if confirm "$action"; then 23 | cd "$HOME/.local/share/nvim/mason/packages/prettierd/node_modules/@fsouza/prettierd" && npm install prettier-plugin-sh prettier-plugin-toml 24 | fi 25 | 26 | action="install ripgrep" 27 | if ! check_dependency rg && confirm "$action"; then 28 | if is_linux; then 29 | sudo pacman -S ripgrep 30 | elif is_mac; then 31 | brew install ripgrep 32 | else 33 | echo "Failed to $action: unsupported OS" 34 | fi 35 | fi 36 | 37 | action="link nvim config" 38 | if confirm "$action"; then 39 | link_config "$HOME/dotconfig/nvim" "$HOME/.config/nvim" 40 | fi 41 | 42 | action="link stylua config" 43 | if confirm "$action"; then 44 | link_config "$HOME/dotconfig/stylua.toml" "$HOME/.config/stylua.toml" 45 | fi 46 | 47 | action="link selene config" 48 | if confirm "$action"; then 49 | link_config "$HOME/dotconfig/selene.toml" "$HOME/.config/selene.toml" 50 | link_config "$HOME/dotconfig/vim.toml" "$HOME/.config/vim.toml" 51 | fi 52 | 53 | action="install sqlite for neoclip persistence" 54 | if ! check_dependency sqlite3 && confirm "$action"; then 55 | if is_linux; then 56 | sudo pacman -S sqlite 57 | elif is_mac; then 58 | # NOTE: required to install for Mac even if built-in 59 | brew install sqlite 60 | else 61 | echo "Failed to $action: unsupported OS" 62 | fi 63 | fi 64 | -------------------------------------------------------------------------------- /picom/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install picom fork" 5 | if is_linux && confirm "$action"; then 6 | yay -S picom-jonaburg-git 7 | fi 8 | 9 | action="link config" 10 | if confirm "$action"; then 11 | link_config "$HOME/dotconfig/picom/picom.conf" "$HOME/.config/picom/picom.conf" 12 | fi 13 | -------------------------------------------------------------------------------- /polybar/scripts/check-arch-updates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #source https://github.com/x70b1/polybar-scripts 3 | #source https://github.com/polybar/polybar-scripts 4 | 5 | if ! updates_arch=$(checkupdates 2> /dev/null | wc -l ); then 6 | updates_arch=0 7 | fi 8 | 9 | if [ $updates_arch -gt 0 ]; then 10 | echo $updates_arch 11 | else 12 | echo "0" 13 | fi 14 | -------------------------------------------------------------------------------- /polybar/scripts/check-aur-updates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #source https://github.com/x70b1/polybar-scripts 3 | #source https://github.com/polybar/polybar-scripts 4 | 5 | if ! updates_aur=$(yay -Qum 2> /dev/null | wc -l ); then 6 | updates_aur=0 7 | fi 8 | 9 | if [ $updates_aur -gt 0 ]; then 10 | echo $updates_aur 11 | else 12 | echo "0" 13 | fi 14 | -------------------------------------------------------------------------------- /polybar/scripts/covid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -s https://www.health.nsw.gov.au/Infectious/covid-19/Pages/default.aspx | grep -oP '(?<=>).*?(?=[<|&].*?total new)' 4 | -------------------------------------------------------------------------------- /polybar/scripts/get_spotify_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The name of polybar bar which houses the main spotify module and the control modules. 4 | PARENT_BAR="mainbar-xmonad" 5 | 6 | # Set the source audio player here. 7 | # Players supporting the MPRIS spec are supported. 8 | # Examples: spotify, vlc, chrome, mpv and others. 9 | # Use `playerctld` to always detect the latest player. 10 | # See more here: https://github.com/altdesktop/playerctl/#selecting-players-to-control 11 | PLAYER="spotify" 12 | 13 | # Format of the information displayed 14 | # Eg. {{ artist }} - {{ album }} - {{ title }} 15 | # See more attributes here: https://github.com/altdesktop/playerctl/#printing-properties-and-metadata 16 | FORMAT="{{ title }} - {{ artist }}" 17 | 18 | PLAYERCTL_STATUS=$(playerctl --player=$PLAYER status 2>/dev/null) 19 | EXIT_CODE=$? 20 | 21 | if [ $EXIT_CODE -eq 0 ]; then 22 | STATUS=$PLAYERCTL_STATUS 23 | else 24 | STATUS="No player is running" 25 | fi 26 | 27 | if [ "$1" == "--status" ]; then 28 | echo "$STATUS" 29 | else 30 | if [ "$STATUS" = "Stopped" ]; then 31 | echo "No music is playing" 32 | # A note on hooks: 33 | # In the polybar config, they are supposed to be zero-indexed. 34 | # When making IPC calls, 1-based index numbers are to be used. 35 | # So don't get confused with hook value as 2. 36 | elif [ "$STATUS" = "Paused" ]; then 37 | polybar-msg -p "$(pgrep -f "polybar $PARENT_BAR")" hook spotify-play-pause 2 1>/dev/null 2>&1 38 | playerctl --player=$PLAYER metadata --format "$FORMAT" 39 | elif [ "$STATUS" = "No player is running" ]; then 40 | echo $STATUS 41 | else 42 | polybar-msg -p "$(pgrep -f "polybar $PARENT_BAR")" hook spotify-play-pause 1 1>/dev/null 2>&1 43 | playerctl --player=$PLAYER metadata --format "$FORMAT" 44 | fi 45 | fi 46 | -------------------------------------------------------------------------------- /polybar/scripts/pavolume.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # finds the active sink for pulse audio and increments the volume. useful when you have multiple audio outputs and have a key bound to vol-up and down 4 | 5 | osd='no' 6 | inc='2' 7 | capvol='no' 8 | maxvol='200' 9 | autosync='yes' 10 | 11 | # Muted status 12 | # yes: muted 13 | # no : not muted 14 | curStatus="no" 15 | active_sink="" 16 | limit=$((100 - inc)) 17 | maxlimit=$((maxvol - inc)) 18 | 19 | reloadSink() { 20 | active_sink=$(pacmd list-sinks | awk '/* index:/{print $3}') 21 | } 22 | 23 | function volUp { 24 | 25 | getCurVol 26 | 27 | if [ "$capvol" = 'yes' ] 28 | then 29 | if [ "$curVol" -le 100 ] && [ "$curVol" -ge "$limit" ] 30 | then 31 | pactl set-sink-volume "$active_sink" -- 100% 32 | elif [ "$curVol" -lt "$limit" ] 33 | then 34 | pactl set-sink-volume "$active_sink" -- "+$inc%" 35 | fi 36 | elif [ "$curVol" -le "$maxvol" ] && [ "$curVol" -ge "$maxlimit" ] 37 | then 38 | pactl set-sink-volume "$active_sink" "$maxvol%" 39 | elif [ "$curVol" -lt "$maxlimit" ] 40 | then 41 | pactl set-sink-volume "$active_sink" "+$inc%" 42 | fi 43 | 44 | getCurVol 45 | 46 | if [ ${osd} = 'yes' ] 47 | then 48 | qdbus org.kde.kded /modules/kosd showVolume "$curVol" 0 49 | fi 50 | 51 | if [ ${autosync} = 'yes' ] 52 | then 53 | volSync 54 | fi 55 | } 56 | 57 | function volDown { 58 | 59 | pactl set-sink-volume "$active_sink" "-$inc%" 60 | getCurVol 61 | 62 | if [ ${osd} = 'yes' ] 63 | then 64 | qdbus org.kde.kded /modules/kosd showVolume "$curVol" 0 65 | fi 66 | 67 | if [ ${autosync} = 'yes' ] 68 | then 69 | volSync 70 | fi 71 | 72 | } 73 | 74 | function getSinkInputs { 75 | input_array=$(pacmd list-sink-inputs | grep -B 4 "sink: $1 " | awk '/index:/{print $2}') 76 | } 77 | 78 | function volSync { 79 | getSinkInputs "$active_sink" 80 | getCurVol 81 | 82 | for each in $input_array 83 | do 84 | pactl set-sink-input-volume "$each" "$curVol%" 85 | done 86 | } 87 | 88 | function getCurVol { 89 | curVol=$(pacmd list-sinks | grep -A 15 "index: $active_sink$" | grep 'volume:' | grep -E -v 'base volume:' | awk -F : '{print $3}' | grep -o -P '.{0,3}%'| sed s/.$// | tr -d ' ') 90 | } 91 | 92 | function volMute { 93 | case "$1" in 94 | mute) 95 | pactl set-sink-mute "$active_sink" 1 96 | curVol=0 97 | status=1 98 | ;; 99 | unmute) 100 | pactl set-sink-mute "$active_sink" 0 101 | getCurVol 102 | status=0 103 | ;; 104 | esac 105 | 106 | if [ ${osd} = 'yes' ] 107 | then 108 | qdbus org.kde.kded /modules/kosd showVolume ${curVol} ${status} 109 | fi 110 | 111 | } 112 | 113 | function volMuteStatus { 114 | curStatus=$(pacmd list-sinks | grep -A 15 "index: $active_sink$" | awk '/muted/{ print $2}') 115 | } 116 | 117 | # Prints output for bar 118 | # Listens for events for fast update speed 119 | function listen { 120 | firstrun=0 121 | 122 | pactl subscribe 2>/dev/null | { 123 | while true; do 124 | { 125 | # If this is the first time just continue 126 | # and print the current state 127 | # Otherwise wait for events 128 | # This is to prevent the module being empty until 129 | # an event occurs 130 | if [ $firstrun -eq 0 ] 131 | then 132 | firstrun=1 133 | else 134 | read -r event || break 135 | if ! echo "$event" | grep -e "on card" -e "on sink" 136 | then 137 | # Avoid double events 138 | continue 139 | fi 140 | fi 141 | } &>/dev/null 142 | output 143 | done 144 | } 145 | } 146 | 147 | function output() { 148 | reloadSink 149 | getCurVol 150 | volMuteStatus 151 | if [ "${curStatus}" = 'yes' ] 152 | then 153 | echo " $curVol%" 154 | else 155 | echo " $curVol%" 156 | fi 157 | } #}}} 158 | 159 | reloadSink 160 | case "$1" in 161 | --up) 162 | volUp 163 | ;; 164 | --down) 165 | volDown 166 | ;; 167 | --togmute) 168 | volMuteStatus 169 | if [ "$curStatus" = 'yes' ] 170 | then 171 | volMute unmute 172 | else 173 | volMute mute 174 | fi 175 | ;; 176 | --mute) 177 | volMute mute 178 | ;; 179 | --unmute) 180 | volMute unmute 181 | ;; 182 | --sync) 183 | volSync 184 | ;; 185 | --listen) 186 | # Listen for changes and immediately create new output for the bar 187 | # This is faster than having the script on an interval 188 | listen 189 | ;; 190 | *) 191 | # By default print output for bar 192 | output 193 | ;; 194 | esac 195 | -------------------------------------------------------------------------------- /polybar/scripts/pub-ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # credits 4 | # https://linuxconfig.org/polybar-a-better-wm-panel-for-your-linux-system 5 | 6 | IP=$(dig +short myip.opendns.com @resolver1.opendns.com) 7 | 8 | if pgrep -x openvpn > /dev/null; then 9 | echo VPN: $IP 10 | else 11 | echo $IP 12 | fi 13 | -------------------------------------------------------------------------------- /polybar/scripts/scroll_spotify_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # see man zscroll for documentation of the following parameters 4 | zscroll -l 50 \ 5 | --delay 0.3 \ 6 | --scroll-padding " 󰎈 " \ 7 | --match-command "$HOME/.config/polybar/scripts/get_spotify_status.sh --status" \ 8 | --match-text "Playing" "--scroll 1" \ 9 | --match-text "Paused" "--scroll 0" \ 10 | --update-check true "$HOME/.config/polybar/scripts/get_spotify_status.sh" & 11 | 12 | wait 13 | -------------------------------------------------------------------------------- /polybar/scripts/spotify1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # credits 4 | # https://github.com/NicholasFeldman/dotfiles/blob/master/polybar/.config/polybar/spotify.sh 5 | 6 | main() { 7 | if ! pgrep -x spotify >/dev/null; then 8 | echo ""; exit 9 | fi 10 | 11 | cmd="org.freedesktop.DBus.Properties.Get" 12 | domain="org.mpris.MediaPlayer2" 13 | path="/org/mpris/MediaPlayer2" 14 | 15 | meta=$(dbus-send --print-reply --dest=${domain}.spotify \ 16 | /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:${domain}.Player string:Metadata) 17 | 18 | artist=$(echo "$meta" | sed -nr '/xesam:artist"/,+2s/^ +string "(.*)"$/\1/p' | tail -1 | sed "s/\&/+/g") 19 | album=$(echo "$meta" | sed -nr '/xesam:album"/,+2s/^ +variant +string "(.*)"$/\1/p' | tail -1) 20 | title=$(echo "$meta" | sed -nr '/xesam:title"/,+2s/^ +variant +string "(.*)"$/\1/p' | tail -1 | sed "s/\&/+/g") 21 | 22 | echo "${*:-%artist% - %title%}" | sed "s/%artist%/$artist/g;s/%title%/$title/g;s/%album%/$album/g"i | sed 's/&/\\&/g' 23 | } 24 | 25 | main "$@" -------------------------------------------------------------------------------- /polybar/scripts/tempcores.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # fork from Per-core temperatures : 4 | # https://github.com/jaagr/polybar/wiki/User-contributed-modules#per-core-temperatures 5 | 6 | # Get information from cores temp thanks to sensors 7 | rawData=$( sensors | grep -m 1 Core | awk '{print substr($3, 2, length($3)-5)}' ) 8 | tempCore=($rawData) 9 | 10 | # Define constants : 11 | degree="°C" 12 | temperaturesValues=(40 50 60 70 80 90) 13 | temperaturesColors=("#6bff49" "#f4cb24" "#ff8819" "#ff3205" "#f40202" "#ef02db") 14 | temperaturesIcons=(     ) 15 | 16 | for iCore in ${!tempCore[*]} 17 | do 18 | for iTemp in ${!temperaturesValues[*]} 19 | do 20 | if (( "${tempCore[$iCore]}" < "${temperaturesValues[$iTemp]}" )); then 21 | tmpEcho="%{F${temperaturesColors[$iTemp]}}${tempCore[$iCore]}$degree%{F-}" 22 | finalEcho="$finalEcho $tmpEcho" 23 | break 24 | fi 25 | done 26 | total=$(( ${tempCore[$iCore]} + total )); 27 | done 28 | 29 | sum=$(( $total/${#tempCore[*]} )) 30 | 31 | for iTemp in ${!temperaturesValues[*]} 32 | do 33 | if (( "$sum" < "${temperaturesValues[$iTemp]}" )); then 34 | ## This line will color the icon too 35 | tmpEcho="%{F${temperaturesColors[$iTemp]}}${temperaturesIcons[$iTemp]}%{F-}" 36 | ## This line will NOT color the icon 37 | #tmpEcho="${temperaturesIcons[$iTemp]}" 38 | finalEcho=" $finalEcho $tmpEcho" 39 | break 40 | fi 41 | done 42 | 43 | echo $finalEcho 44 | -------------------------------------------------------------------------------- /polybar/scripts/tesla.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -s https://tfnsw.redbook.com.au/stock_locator/search/Tesla/Model+Y/Rear-Wheel+Drive/0/0/0/0/0/0/0/0/0/0/0/0/Year/1956-2022/1 -A "Mozilla/5.0 (compatible; MSIE 7.01; Windows NT 5.0)" | sed -En 's/^.*
2022 Tesla Model Y Rear-Wheel Drive Auto (.*)<\/span><\/h5>/\1/p' 4 | -------------------------------------------------------------------------------- /polybar/scripts/weather.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Procedure 5 | # Surf to https://openweathermap.org/city 6 | # Fill in your CITY 7 | # e.g. Antwerp Belgium 8 | # Check url 9 | # https://openweathermap.org/city/2803138 10 | # you will the city code at the end 11 | # create an account on this website 12 | # create an api key (free) 13 | # LANG included thanks to krive001 on discord 14 | 15 | 16 | import requests 17 | 18 | CITY = "2803138" 19 | API_KEY = "756edce7e9d4c385ef9499a53492678c" 20 | UNITS = "Metric" 21 | UNIT_KEY = "C" 22 | #UNIT_KEY = "F" 23 | LANG = "en" 24 | #LANG = "nl" 25 | #LANG = "hu" 26 | 27 | REQ = requests.get("http://api.openweathermap.org/data/2.5/weather?id={}&lang={}&appid={}&units={}".format(CITY, LANG, API_KEY, UNITS)) 28 | try: 29 | # HTTP CODE = OK 30 | if REQ.status_code == 200: 31 | CURRENT = REQ.json()["weather"][0]["description"].capitalize() 32 | TEMP = int(float(REQ.json()["main"]["temp"])) 33 | print("{}, {} °{}".format(CURRENT, TEMP, UNIT_KEY)) 34 | else: 35 | print("Error: BAD HTTP STATUS CODE " + str(REQ.status_code)) 36 | except (ValueError, IOError): 37 | print("Error: Unable print the data") 38 | -------------------------------------------------------------------------------- /polybar/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install zscroll" 5 | if is_linux && ! check_dependency zscroll && confirm "$action"; then 6 | yay -S zscroll 7 | fi 8 | 9 | action="install font awesome 5" 10 | if is_linux && confirm "$action"; then 11 | # sudo pacman -S awesome-terminal-fonts 12 | yay -S ttf-font-awesome-5 13 | yay -S nerd-fonts-meslo 14 | fi 15 | 16 | action="link config" 17 | if confirm "$action"; then 18 | link_config "$HOME/dotconfig/polybar" "$HOME/.config/polybar" 19 | fi 20 | -------------------------------------------------------------------------------- /rofi/config.rasi: -------------------------------------------------------------------------------- 1 | /* vim:ft=css */ 2 | /* keys: control (shift) tab to navigate modes */ 3 | 4 | configuration { 5 | modi: "run,ssh,filebrowser,window,windowcd,emoji"; 6 | color-enabled: true; 7 | color-window: "#4d32302f, #4d32302f, #0032302f"; 8 | color-normal: "#0032302f, #d8dee9, #0032302f, #cc458588, #32302f"; 9 | color-active: "#4d1b2b34, #6699cc, #4d343d46, #4d6699cc, #d8dee9"; 10 | color-urgent: "#4d1b2b34, #ec5f67, #4d343d46, #4dec5f67, #d8dee9"; 11 | 12 | separator-style: "solid"; 13 | show-icons: true; 14 | /* drun-icon-theme: "Sardi-Arc"; */ 15 | sidebar-mode: true; 16 | padding: 10; 17 | bw: 0; 18 | scrollbar-width: 0; 19 | line-margin: 0; 20 | lines: 10; 21 | terminal: "alacritty"; 22 | case-sensitive: false; 23 | 24 | /* NOTE: doesn't work, run rofi with -matching fuzzy -sort-method fzf -sort */ 25 | matching: "fuzzy"; 26 | sort: true; 27 | sorting-method: "fzf"; 28 | 29 | 30 | /* width: 50;*/ 31 | /* lines: 15;*/ 32 | /* columns: 2; */ 33 | /* font: "mono 12";*/ 34 | /* bw: 1;*/ 35 | /* location: 0;*/ 36 | /* padding: 5;*/ 37 | /* yoffset: 0;*/ 38 | /* xoffset: 0;*/ 39 | /* fixed-num-lines: true;*/ 40 | /* show-icons: false;*/ 41 | /* terminal: "rofi-sensible-terminal";*/ 42 | /* ssh-client: "ssh";*/ 43 | /* ssh-command: "{terminal} -e {ssh-client} {host} [-p {port}]";*/ 44 | /* run-command: "{cmd}";*/ 45 | /* run-list-command: "";*/ 46 | /* run-shell-command: "{terminal} -e {cmd}";*/ 47 | /* window-command: "wmctrl -i -R {window}";*/ 48 | /* window-match-fields: "all";*/ 49 | /* icon-theme: ;*/ 50 | /* drun-match-fields: "name,generic,exec,categories,keywords";*/ 51 | /* drun-categories: ;*/ 52 | /* drun-show-actions: false;*/ 53 | /* drun-display-format: "{name} [({generic})]";*/ 54 | /* drun-url-launcher: "xdg-open";*/ 55 | /* disable-history: false;*/ 56 | /* ignored-prefixes: "";*/ 57 | /* sort: false;*/ 58 | /* sorting-method: "normal";*/ 59 | /* case-sensitive: false;*/ 60 | /* cycle: true;*/ 61 | /* sidebar-mode: false;*/ 62 | /* eh: 1;*/ 63 | /* auto-select: false;*/ 64 | /* parse-hosts: false;*/ 65 | /* parse-known-hosts: true;*/ 66 | /* combi-modi: "window,run";*/ 67 | /* matching: "normal";*/ 68 | /* tokenize: true;*/ 69 | /* m: "-5";*/ 70 | /* line-margin: 2;*/ 71 | /* line-padding: 1;*/ 72 | /* filter: ;*/ 73 | /* separator-style: "dash";*/ 74 | /* hide-scrollbar: false;*/ 75 | /* fullscreen: false;*/ 76 | /* fake-transparency: false;*/ 77 | /* dpi: -1;*/ 78 | /* threads: 0;*/ 79 | /* scrollbar-width: 8;*/ 80 | /* scroll-method: 0;*/ 81 | /* fake-background: "screenshot";*/ 82 | /* window-format: "{w} {c} {t}";*/ 83 | /* click-to-exit: true;*/ 84 | /* show-match: true;*/ 85 | /* color-normal: ;*/ 86 | /* color-urgent: ;*/ 87 | /* color-active: ;*/ 88 | /* color-window: ;*/ 89 | /* max-history-size: 25;*/ 90 | /* combi-hide-mode-prefix: false;*/ 91 | /* matching-negate-char: '-' /* unsupported */;*/ 92 | /* cache-dir: ;*/ 93 | /* window-thumbnail: false;*/ 94 | /* drun-use-desktop-cache: false;*/ 95 | /* drun-reload-desktop-cache: false;*/ 96 | /* normalize-match: false;*/ 97 | /* pid: "/run/user/1000/rofi.pid";*/ 98 | /* display-window: ;*/ 99 | /* display-windowcd: ;*/ 100 | /* display-run: ;*/ 101 | /* display-ssh: ;*/ 102 | /* display-drun: ;*/ 103 | /* display-combi: ;*/ 104 | /* display-keys: ;*/ 105 | /* display-file-browser: ;*/ 106 | /* kb-primary-paste: "Control+V,Shift+Insert";*/ 107 | /* kb-secondary-paste: "Control+v,Insert";*/ 108 | /* kb-clear-line: "Control+w";*/ 109 | /* kb-move-front: "Control+a";*/ 110 | /* kb-move-end: "Control+e";*/ 111 | /* kb-move-word-back: "Alt+b,Control+Left";*/ 112 | /* kb-move-word-forward: "Alt+f,Control+Right";*/ 113 | /* kb-move-char-back: "Left,Control+b";*/ 114 | /* kb-move-char-forward: "Right,Control+f";*/ 115 | /* kb-remove-word-back: "Control+Alt+h,Control+BackSpace";*/ 116 | /* kb-remove-word-forward: "Control+Alt+d";*/ 117 | /* kb-remove-char-forward: "Delete,Control+d";*/ 118 | /* kb-remove-char-back: "BackSpace,Shift+BackSpace,Control+h";*/ 119 | /* kb-remove-to-eol: "Control+k";*/ 120 | /* kb-remove-to-sol: "Control+u";*/ 121 | /* kb-accept-entry: "Control+j,Control+m,Return,KP_Enter";*/ 122 | /* kb-accept-custom: "Control+Return";*/ 123 | /* kb-accept-alt: "Shift+Return";*/ 124 | /* kb-delete-entry: "Shift+Delete";*/ 125 | /* kb-mode-next: "Shift+Right,Control+Tab";*/ 126 | /* kb-mode-previous: "Shift+Left,Control+ISO_Left_Tab";*/ 127 | /* kb-row-left: "Control+Page_Up";*/ 128 | /* kb-row-right: "Control+Page_Down";*/ 129 | /* kb-row-up: "Up,Control+p,ISO_Left_Tab";*/ 130 | /* kb-row-down: "Down,Control+n";*/ 131 | /* kb-row-tab: "Tab";*/ 132 | /* kb-page-prev: "Page_Up";*/ 133 | /* kb-page-next: "Page_Down";*/ 134 | /* kb-row-first: "Home,KP_Home";*/ 135 | /* kb-row-last: "End,KP_End";*/ 136 | /* kb-row-select: "Control+space";*/ 137 | /* kb-screenshot: "Alt+S";*/ 138 | /* kb-ellipsize: "Alt+period";*/ 139 | /* kb-toggle-case-sensitivity: "grave,dead_grave";*/ 140 | /* kb-toggle-sort: "Alt+grave";*/ 141 | /* kb-cancel: "Escape,Control+g,Control+bracketleft";*/ 142 | /* kb-custom-1: "Alt+1";*/ 143 | /* kb-custom-2: "Alt+2";*/ 144 | /* kb-custom-3: "Alt+3";*/ 145 | /* kb-custom-4: "Alt+4";*/ 146 | /* kb-custom-5: "Alt+5";*/ 147 | /* kb-custom-6: "Alt+6";*/ 148 | /* kb-custom-7: "Alt+7";*/ 149 | /* kb-custom-8: "Alt+8";*/ 150 | /* kb-custom-9: "Alt+9";*/ 151 | /* kb-custom-10: "Alt+0";*/ 152 | /* kb-custom-11: "Alt+exclam";*/ 153 | /* kb-custom-12: "Alt+at";*/ 154 | /* kb-custom-13: "Alt+numbersign";*/ 155 | /* kb-custom-14: "Alt+dollar";*/ 156 | /* kb-custom-15: "Alt+percent";*/ 157 | /* kb-custom-16: "Alt+dead_circumflex";*/ 158 | /* kb-custom-17: "Alt+ampersand";*/ 159 | /* kb-custom-18: "Alt+asterisk";*/ 160 | /* kb-custom-19: "Alt+parenleft";*/ 161 | /* kb-select-1: "Super+1";*/ 162 | /* kb-select-2: "Super+2";*/ 163 | /* kb-select-3: "Super+3";*/ 164 | /* kb-select-4: "Super+4";*/ 165 | /* kb-select-5: "Super+5";*/ 166 | /* kb-select-6: "Super+6";*/ 167 | /* kb-select-7: "Super+7";*/ 168 | /* kb-select-8: "Super+8";*/ 169 | /* kb-select-9: "Super+9";*/ 170 | /* kb-select-10: "Super+0";*/ 171 | /* ml-row-left: "ScrollLeft";*/ 172 | /* ml-row-right: "ScrollRight";*/ 173 | /* ml-row-up: "ScrollUp";*/ 174 | /* ml-row-down: "ScrollDown";*/ 175 | /* me-select-entry: "MousePrimary";*/ 176 | /* me-accept-entry: "MouseDPrimary";*/ 177 | /* me-accept-custom: "Control+MouseDPrimary";*/ 178 | } 179 | /* @import "/usr/share/rofi/themes/android_notification.rasi" */ 180 | @import "./theme.rasi" 181 | -------------------------------------------------------------------------------- /rofi/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install rofi emoji" 5 | if ! check_dependency "rofi-emoji" && confirm "$action"; then 6 | sudo pacman -S rofi-emoji 7 | fi 8 | 9 | action="link config" 10 | if confirm "$action"; then 11 | link_config "$HOME/dotconfig/rofi" "$HOME/.config/rofi" 12 | fi 13 | -------------------------------------------------------------------------------- /rofi/theme.rasi: -------------------------------------------------------------------------------- 1 | /* vim:ft=css */ 2 | /************************************************ 3 | * ROFI Color theme 4 | * User: axieax 5 | * Copyright: axieax 6 | ***********************************************/ 7 | /* http://manpages.ubuntu.com/manpages/bionic/man5/rofi-theme.5.html */ 8 | 9 | * { 10 | blank: rgba ( 0, 0, 0, 0 % ); 11 | selected-normal-foreground: rgba ( 249, 249, 249, 100 % ); 12 | foreground: rgba ( 196, 203, 212, 100 % ); 13 | normal-foreground: @foreground; 14 | alternate-normal-background: @blank; 15 | red: rgba ( 220, 50, 47, 100 % ); 16 | selected-urgent-foreground: rgba ( 249, 249, 249, 100 % ); 17 | blue: rgba ( 38, 139, 210, 100 % ); 18 | urgent-foreground: rgba ( 204, 102, 102, 100 % ); 19 | alternate-urgent-background: rgba ( 75, 81, 96, 90 % ); 20 | active-foreground: rgba ( 101, 172, 255, 100 % ); 21 | lightbg: rgba ( 238, 232, 213, 100 % ); 22 | selected-active-foreground: rgba ( 249, 249, 249, 100 % ); 23 | alternate-active-background: rgba ( 52,73,94, 60 %); 24 | background: rgba ( 50, 48, 47, 85 % ); 25 | alternate-normal-foreground: @foreground; 26 | normal-background: @blank; 27 | lightfg: rgba ( 88, 104, 117, 100 % ); 28 | /* selected-normal-background: rgba ( 64, 132, 214, 70 % ); */ 29 | selected-normal-background: rgba ( 255, 0, 106, 40 % ); 30 | border-color: @blank; 31 | spacing: 2; 32 | separatorcolor: rgba ( 29, 31, 33, 100 % ); 33 | urgent-background: rgba ( 29, 31, 33, 17 % ); 34 | selected-urgent-background: rgba ( 165, 66, 66, 100 % ); 35 | alternate-urgent-foreground: @urgent-foreground; 36 | background-color: @blank; 37 | alternate-active-foreground: @active-foreground; 38 | active-background: rgba ( 29, 31, 33, 17 % ); 39 | selected-active-background: rgba ( 68, 145, 237, 100 % ); 40 | } 41 | 42 | #window { 43 | background-color: @background; 44 | border: 1; 45 | /* border-radius: 12; */ 46 | padding: 5; 47 | } 48 | 49 | #mainbox { 50 | border: 0; 51 | padding: 0; 52 | } 53 | 54 | #message { 55 | border: 2px 0px 0px ; 56 | border-color: @separatorcolor; 57 | padding: 1px ; 58 | } 59 | 60 | #textbox { 61 | text-color: @foreground; 62 | } 63 | 64 | #listview { 65 | fixed-height: 0; 66 | border: 0px 0px 0px ; 67 | border-color: @separatorcolor; 68 | spacing: 2px ; 69 | scrollbar: true; 70 | padding: 2px 0px 0px ; 71 | /* columns: 2; */ 72 | } 73 | 74 | #element { 75 | border: 0; 76 | padding: 1px; 77 | } 78 | #element.normal.normal { 79 | background-color: @normal-background; 80 | text-color: @normal-foreground; 81 | } 82 | #element.normal.urgent { 83 | background-color: @urgent-background; 84 | text-color: @urgent-foreground; 85 | } 86 | #element.normal.active { 87 | background-color: @active-background; 88 | text-color: @active-foreground; 89 | } 90 | #element.selected.normal { 91 | background-color: @selected-normal-background; 92 | text-color: @selected-normal-foreground; 93 | } 94 | #element.selected.urgent { 95 | background-color: @selected-urgent-background; 96 | text-color: @selected-urgent-foreground; 97 | } 98 | #element.selected.active { 99 | background-color: @selected-active-background; 100 | text-color: @selected-active-foreground; 101 | } 102 | #element.alternate.normal { 103 | background-color: @alternate-normal-background; 104 | text-color: @alternate-normal-foreground; 105 | } 106 | #element.alternate.urgent { 107 | background-color: @alternate-urgent-background; 108 | text-color: @alternate-urgent-foreground; 109 | } 110 | #element.alternate.active { 111 | background-color: @alternate-active-background; 112 | text-color: @alternate-active-foreground; 113 | } 114 | 115 | #scrollbar { 116 | width: 4px ; 117 | border: 0; 118 | handle-color: @normal-foreground; 119 | handle-width: 8px ; 120 | padding: 0; 121 | } 122 | 123 | #sidebar { 124 | border: 0px 0px 0px; 125 | padding: 5px 0 0; 126 | border-color: @separatorcolor; 127 | } 128 | 129 | #button { 130 | margin: 0.5em 0 0 0; 131 | spacing: 0; 132 | text-color: @normal-foreground; 133 | horizontal-align: 0.5; 134 | } 135 | #button.selected { 136 | background-color: @selected-normal-background; 137 | text-color: @selected-normal-foreground; 138 | } 139 | 140 | #inputbar { 141 | spacing: 0; 142 | text-color: @normal-foreground; 143 | padding: 1px; 144 | } 145 | 146 | #case-indicator { 147 | spacing: 0; 148 | text-color: @normal-foreground; 149 | } 150 | 151 | #entry { 152 | spacing: 0; 153 | text-color: @normal-foreground; 154 | } 155 | 156 | #prompt { 157 | spacing: 0; 158 | text-color: @normal-foreground; 159 | } 160 | 161 | #inputbar { 162 | children: [ prompt,textbox-prompt-colon,entry,case-indicator ]; 163 | } 164 | 165 | #textbox-prompt-colon { 166 | expand: false; 167 | str: ":"; 168 | margin: 0px 0.3em 0em 0em ; 169 | text-color: @normal-foreground; 170 | } 171 | -------------------------------------------------------------------------------- /scripts/gitignore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | QUERY_API="https://www.toptal.com/developers/gitignore/api" 4 | GITIGNORE=".gitignore" 5 | options=(${@// / }) 6 | 7 | if [[ -z "$options" ]]; then 8 | technologies="$(curl -sL ${QUERY_API}/list | tr "," "\n")" 9 | while true; do 10 | selected="$(echo "$technologies" | fzf)" 11 | if [[ $? = 0 ]]; then 12 | options+=("$selected") 13 | else 14 | break 15 | fi 16 | done 17 | fi 18 | 19 | # generate template 20 | if [[ -n "$options" ]]; then 21 | query="$(echo "${options[@]}" | tr ' ' ',')" 22 | output="$(curl -sL "${QUERY_API}/$query")" 23 | echo -e "$output" 24 | read -p "Save to $GITIGNORE? [y/n] " -n 1 -r 25 | echo 26 | [[ ! $REPLY =~ ^[Yy]$ ]] && exit 1 27 | 28 | if [[ -f "$GITIGNORE" ]]; then 29 | echo "Adding to existing $GITIGNORE file" 30 | output="${output}\n\n$(cat $GITIGNORE)" 31 | fi 32 | echo -e "$output" > $GITIGNORE 33 | echo "$GITIGNORE successfully generated for $query" 34 | fi 35 | -------------------------------------------------------------------------------- /scripts/gitspeed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # REF: https://github.com/starship/starship/issues/4305#issuecomment-1509498359 4 | cd "$1" 5 | git config core.fsmonitor true 6 | git config feature.manyFiles true 7 | git config core.untrackedCache true 8 | # scalar register "$1" 9 | -------------------------------------------------------------------------------- /sddm/Xsetup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Xsetup - run as root before the login dialog appears 3 | 4 | # xrandr --output HDMI-0 --auto --output DP-0 --auto --right-of HDMI-0 5 | -------------------------------------------------------------------------------- /sddm/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install arcolinux-sugar-candy theme" 5 | candy_path=/usr/share/sddm/themes/arcolinux-sugar-candy 6 | if [ ! -d $candy_path ] && confirm "$action"; then 7 | sudo pacman -S arcolinux-sddm-sugar-candy-git 8 | fi 9 | 10 | action="setup display settings" 11 | if confirm "$action"; then 12 | # ensure the following is in /etc/sddm.conf: 13 | # [X11] 14 | # DisplayCommand=/usr/share/sddm/scripts/Xsetup 15 | xsetup_location="/usr/share/sddm/scripts/Xsetup" 16 | link_config "$HOME/dotconfig/sddm/Xsetup" "$xsetup_location" true true 17 | sudo chmod +x "$xsetup_location" 18 | fi 19 | 20 | action="setup preferred config" 21 | if confirm "$action"; then 22 | # copy preferred arco-login background 23 | link_config /usr/share/backgrounds/arcolinux/arco-login.jpg "$candy_path/Backgrounds/arco-login.jpg" true 24 | # update config for arcolinux-sugar-candy theme 25 | link_config "$HOME/dotconfig/sddm/theme.conf" "$candy_path/theme.conf" true true 26 | fi 27 | -------------------------------------------------------------------------------- /sddm/theme.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | background=Backgrounds/arco-login.jpg 3 | DimBackgroundImage="0.0" 4 | ScaleImageCropped="true" 5 | ScreenWidth="1440" 6 | ScreenHeight="900" 7 | FullBlur="false" 8 | PartialBlur="false" 9 | BlurRadius="100" 10 | HaveFormBackground="false" 11 | FormPosition="center" 12 | BackgroundImageHAlignment="center" 13 | BackgroundImageVAlignment="center" 14 | MainColor="white" 15 | AccentColor="#fb884f" 16 | BackgroundColor="#444" 17 | OverrideLoginButtonTextColor="" 18 | InterfaceShadowSize="6" 19 | InterfaceShadowOpacity="0.6" 20 | RoundCorners="20" 21 | ScreenPadding="0" 22 | Font="Noto Sans" 23 | FontSize="" 24 | ForceRightToLeft="false" 25 | ForceLastUser="true" 26 | ForcePasswordFocus="true" 27 | ForceHideCompletePassword="true" 28 | ForceHideVirtualKeyboardButton="false" 29 | ForceHideSystemButtons="false" 30 | AllowEmptyPassword="false" 31 | AllowBadUsernames="false" 32 | Locale="" 33 | HourFormat="HH:mm" 34 | DateFormat="dddd, d of MMMM" 35 | HeaderText="Welcome!" 36 | TranslatePlaceholderUsername="" 37 | TranslatePlaceholderPassword="" 38 | TranslateShowPassword="" 39 | TranslateLogin="" 40 | TranslateLoginFailedWarning="" 41 | TranslateCapslockWarning="" 42 | TranslateSession="" 43 | TranslateSuspend="" 44 | TranslateHibernate="" 45 | TranslateReboot="" 46 | TranslateShutdown="" 47 | TranslateVirtualKeyboardButton="" 48 | -------------------------------------------------------------------------------- /selene.toml: -------------------------------------------------------------------------------- 1 | std = "lua51+vim" 2 | -------------------------------------------------------------------------------- /setup-utilities.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | is_linux() { 3 | # TODO: further filter by distro 4 | # [[ "$OSTYPE" == "linux-gnu"* ]] 5 | [[ "$(uname)" == "Linux" ]] 6 | } 7 | 8 | is_mac() { 9 | # [[ "$OSTYPE" == "darwin"* ]] 10 | [[ "$(uname)" == "Darwin" ]] 11 | } 12 | 13 | if is_mac; then 14 | export OS_PYTHON="python3" 15 | export OS_PIP="pip3" 16 | else 17 | export OS_PYTHON="python" 18 | export OS_PIP="pip" 19 | fi 20 | 21 | confirm() { 22 | action=$1 23 | # TODO: maybe want user to confirm by pressing enter as well? 24 | read -p "Would you like to $action? (y/n): " -n 1 -r 25 | echo 26 | if [[ $REPLY =~ ^[Yy]$ ]]; then 27 | return 0 28 | elif [[ $REPLY =~ ^[Nn]$ ]]; then 29 | return 1 30 | else 31 | confirm "$action" 32 | fi 33 | } 34 | 35 | check_dependency() { 36 | command -v "$1" > /dev/null 2>&1 37 | } 38 | 39 | backup_dst_config() { 40 | dst=$1 41 | as_user=$2 42 | if [ -e "$dst" ]; then 43 | backup="$dst.$(date +%s)" 44 | echo "Backing up $dst to $backup" 45 | $as_user mv "$dst" "$backup" 46 | fi 47 | } 48 | 49 | link_config() { 50 | src=$1 51 | dst=$2 52 | as_root=${3:-false} 53 | copy_only=${4:-false} 54 | [[ $as_root = true ]] && as_user="sudo" || as_user="" 55 | [[ $copy_only = true ]] && command="cp" || command="ln -s" 56 | # create and move to backup if exists 57 | mkdir -p "$(dirname "$dst")" 58 | backup_dst_config "$dst" "$as_user" 59 | $as_user $command "$src" "$dst" 60 | } 61 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | mkdir -p "$HOME/.config" 5 | 6 | setup_app() { 7 | app=$1 8 | action="setup $app" 9 | if confirm "$action"; then 10 | setup_script="$HOME/dotconfig/$app/setup.sh" 11 | chmod +x $setup_script 12 | $setup_script 13 | fi 14 | } 15 | 16 | setup_app tools 17 | setup_app zsh 18 | setup_app alacritty 19 | setup_app nvim 20 | setup_app lazygit 21 | setup_app tmux 22 | setup_app lf 23 | 24 | setup_app vim 25 | setup_app intellij 26 | 27 | setup_app xmonad 28 | setup_app polybar 29 | setup_app rofi 30 | setup_app sddm 31 | 32 | # pavucontrol 33 | # https://community.spotify.com/t5/Desktop-Linux/Microsoft-teams-mutes-Spotify/td-p/5061607 34 | -------------------------------------------------------------------------------- /stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 120 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 2 5 | quote_style = "AutoPreferDouble" 6 | no_call_parentheses = false 7 | -------------------------------------------------------------------------------- /tmux/scripts/aliases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Zoxide-like tmux navigation (inspired by @joshmedeski) 4 | function t() { 5 | DIR=$(zoxide query "$1") 6 | NAME=$(basename "$DIR") 7 | tmux has-session -t "$NAME" 2> /dev/null || tmux new-session -d -s "$NAME" -c "$DIR" 8 | ts "$NAME" 9 | } 10 | 11 | # Delete tmux session 12 | function td() { 13 | tmux delete-session -t "$(tmux list-sessions 2> /dev/null | fzf | cut -d ':' -f1)" 14 | } 15 | 16 | # New tmux session 17 | function tn() { 18 | NAME="$(basename "$PWD")" 19 | SESSION="$NAME" 20 | i=1 21 | while tmux has-session -t "$SESSION" 2> /dev/null; do 22 | SESSION="$NAME-$i" 23 | ((i++)) 24 | done 25 | tmux new-session -s "$SESSION" 26 | } 27 | 28 | # Find / switch sessions 29 | function ts() { 30 | NAME=${1:-$(tmux list-sessions 2> /dev/null | fzf | cut -d ':' -f1)} 31 | if [ -z "$TMUX" ]; then 32 | tmux attach -t "$NAME" 33 | else 34 | tmux switch-client -t "$NAME" 35 | fi 36 | } 37 | 38 | # t query 39 | # NOTE: doesn't handle multiple sessions with the same basename well 40 | function tt() { 41 | t "$(zoxide query -i)" 42 | } 43 | -------------------------------------------------------------------------------- /tmux/scripts/autostart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sauce "$HOME/dotconfig/tmux/scripts/aliases.sh" 4 | 5 | # Autostart tmux 6 | function _tmux_autostart() { 7 | [[ $- != *i* ]] && return # return if non-interactive 8 | [ -n "$INTELLIJ_ENVIRONMENT_READER" ] && return # return if scanned by intellij 9 | if [ -x "$(command -v tmux)" ] && [ -x "$(command -v fzf)" ] && [ -z "$TMUX" ]; then 10 | SESSIONS=$(tmux list-sessions 2> /dev/null | grep -v '(attached)$') 11 | if [ "$?" -eq 0 ]; then 12 | SESSION=$(echo "$SESSIONS" | fzf | cut -d ':' -f1) 13 | if [ -z "$SESSION" ]; then 14 | tn 15 | else 16 | tmux attach -t "$SESSION" 17 | fi 18 | else 19 | tn 20 | fi 21 | 22 | if ! tmux has-session -t "$SESSION" 2>/dev/null; then 23 | exit; 24 | fi 25 | fi 26 | } 27 | -------------------------------------------------------------------------------- /tmux/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install tmux" 5 | if ! check_dependency "tmux" && confirm "$action"; then 6 | if is_linux; then 7 | sudo pacman -S tmux 8 | elif is_mac; then 9 | brew install tmux 10 | else 11 | echo "Failed to $action: unsupported OS" 12 | fi 13 | fi 14 | 15 | action="link config" 16 | if confirm "$action"; then 17 | link_config "$HOME/dotconfig/tmux/tmux.conf" "$HOME/.config/tmux/tmux.conf" 18 | fi 19 | -------------------------------------------------------------------------------- /tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | # REF: https://unix.stackexchange.com/questions/175421/default-tmux-config 2 | 3 | # UI 4 | set -g status-position top 5 | set -sg terminal-overrides ",*:RGB" # nvim colours 6 | set -g status-style 'bg=default' # transparent background 7 | set -g status-left '#[fg=yellow,bold]#S ' 8 | # show path for window status instead of just zsh 9 | set -g window-status-format '#[fg=gray]#{?#{==:#W,zsh},#{b:pane_current_path},#W}' 10 | set -g window-status-current-format '#[fg=lightyellow,bold]#{?#{==:#W,zsh},#{b:pane_current_path},#W}' 11 | set-option -g status-justify centre 12 | set -g status-right '#[fg=lightblue,bold]%H:%M' 13 | 14 | # Settings 15 | set -g mouse on 16 | set -g set-clipboard on 17 | set -g escape-time 0 18 | set -g renumber-windows on 19 | set -g base-index 1 20 | set -g status-interval 1 21 | # set -g detach-on-destroy off 22 | set -g default-terminal 'alacritty' 23 | 24 | # Binds 25 | bind r source-file ~/.config/tmux/tmux.conf 26 | bind R command-prompt -I '#S' "rename-session '%%'" 27 | bind S command-prompt -p "New Session:" "new-session -A -s '%%'" 28 | bind '%' split-window -c '#{pane_current_path}' -h 29 | bind '"' split-window -c '#{pane_current_path}' 30 | bind c new-window -c '#{pane_current_path}' 31 | bind g new-window -c '#{pane_current_path}' -n 'lazygit' lazygit 32 | bind G new-window -c '#{pane_current_path}' -n 'lazydocker' lazydocker 33 | bind z command-prompt -p "Zoxide Search:" "run-shell 'source $HOME/dotconfig/tmux/scripts/aliases.sh && t %%'" 34 | # bind Z run-shell "source $HOME/dotconfig/tmux/scripts/aliases.sh && tt" # NOTE: not working 35 | 36 | bind h select-pane -L 37 | bind j select-pane -D 38 | bind k select-pane -U 39 | bind l select-pane -R 40 | bind b previous-window 41 | bind N previous-window 42 | -------------------------------------------------------------------------------- /tools/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | # Setup core tools 5 | action="install Homebrew" 6 | if is_mac && ! check_dependency brew && confirm "$action"; then 7 | # ASSUMES: curl is installed 8 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 9 | fi 10 | 11 | action="install python3" 12 | if ! check_dependency python3 && confirm "$action"; then 13 | if is_linux; then 14 | sudo pacman -S python python-pip 15 | elif is_mac && confirm "$action"; then 16 | brew install python 17 | else 18 | echo "Failed to $action: unsupported OS" 19 | fi 20 | fi 21 | 22 | action="install node and npm" 23 | if ! check_dependency node && confirm "$action"; then 24 | if is_linux; then 25 | sudo pacman -S nodejs npm 26 | elif is_mac; then 27 | brew install node 28 | else 29 | echo "Failed to $action: unsupported OS" 30 | fi 31 | fi 32 | 33 | action="install yarn" 34 | if ! check_dependency yarn && confirm "$action"; then 35 | npm install --global yarn 36 | fi 37 | 38 | action="install zoxide" 39 | if ! check_dependency zoxide && confirm "$action"; then 40 | if is_linux; then 41 | sudo pacman -S zoxide 42 | elif is_mac; then 43 | brew install zoxide 44 | else 45 | echo "Failed to $action: unsupported OS" 46 | fi 47 | fi 48 | 49 | action="install lsd" 50 | if ! check_dependency lsd && confirm "$action"; then 51 | if is_linux; then 52 | sudo pacman -S lsd 53 | elif is_mac; then 54 | brew install lsd 55 | else 56 | echo "Failed to $action: unsupported OS" 57 | fi 58 | fi 59 | 60 | action="install ripgrep" 61 | if ! check_dependency rg && confirm "$action"; then 62 | if is_linux; then 63 | sudo pacman -S ripgrep 64 | elif is_mac; then 65 | brew install ripgrep 66 | else 67 | echo "Failed to $action: unsupported OS" 68 | fi 69 | fi 70 | 71 | action="install bat" 72 | if ! check_dependency bat && confirm "$action"; then 73 | if is_linux; then 74 | sudo pacman -S bat 75 | elif is_mac; then 76 | brew install bat 77 | else 78 | echo "Failed to $action: unsupported OS" 79 | fi 80 | fi 81 | 82 | action="install fzf" 83 | if ! check_dependency fzf && confirm "$action"; then 84 | if is_linux; then 85 | sudo pacman -S fzf 86 | elif is_mac; then 87 | brew install fzf 88 | else 89 | echo "Failed to $action: unsupported OS" 90 | fi 91 | fi 92 | 93 | action="install fd" 94 | if ! check_dependency fd && confirm "$action"; then 95 | if is_linux; then 96 | sudo pacman -S fd 97 | elif is_mac; then 98 | brew install fd 99 | else 100 | echo "Failed to $action: unsupported OS" 101 | fi 102 | fi 103 | 104 | action="install neofetch" 105 | if ! check_dependency neofetch && confirm "$action"; then 106 | if is_linux; then 107 | sudo pacman -S neofetch 108 | elif is_mac; then 109 | brew install neofetch 110 | else 111 | echo "Failed to $action: unsupported OS" 112 | fi 113 | fi 114 | 115 | action="install gnu-sed" 116 | if is_mac && ! check_dependency gsed && confirm "$action"; then 117 | brew install gnu-sed 118 | fi 119 | -------------------------------------------------------------------------------- /vim.toml: -------------------------------------------------------------------------------- 1 | [vim] 2 | any = true 3 | -------------------------------------------------------------------------------- /vim/.vimrc: -------------------------------------------------------------------------------- 1 | let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim' 2 | if empty(glob(data_dir . '/autoload/plug.vim')) 3 | silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' 4 | autocmd VimEnter * PlugInstall --sync | source $MYVIMRC 5 | endif 6 | 7 | call plug#begin() 8 | Plug 'tpope/vim-commentary' 9 | Plug 'tpope/vim-surround' 10 | Plug 'preservim/nerdtree' 11 | Plug 'machakann/vim-highlightedyank' 12 | 13 | " TODO: find a better-escape plugin (jk) 14 | " Plug 'terryma/vim-multiple-cursors' 15 | " Plug 'mg979/vim-visual-multi' 16 | " Plug 'junegunn/fzf.vim' 17 | " Plug 'romainl/vim-cool' 18 | call plug#end() 19 | 20 | set number relativenumber 21 | set ignorecase smartcase 22 | set incsearch 23 | set visualbell 24 | set hlsearch 25 | set splitbelow 26 | set splitright 27 | 28 | command W w 29 | 30 | function! PasteReplace(type) 31 | execute "normal! `[v`]p" 32 | endfunction 33 | nnoremap \r :set opfunc=PasteReplaceg@ 34 | 35 | nnoremap c :echo expand("%") 36 | nnoremap C :pwd 37 | nnoremap w :update 38 | nnoremap :bnext 39 | nnoremap :bprev 40 | nnoremap :bdelete 41 | nnoremap v ggVG 42 | nnoremap V ggVG"+y 43 | nnoremap gQ ggVGgq 44 | 45 | nnoremap Y y$ 46 | nnoremap \y "+y 47 | vnoremap \y "+y 48 | nnoremap \+ let @+=@" 49 | nnoremap \p "0p 50 | vnoremap \p "0p 51 | inoremap 52 | vnoremap < >gv 54 | nnoremap n nzz 55 | nnoremap N Nzz 56 | nnoremap \c "_c 57 | nnoremap \C "_C 58 | nnoremap :noh 59 | nnoremap :m +1 60 | nnoremap :m -2 61 | 62 | nnoremap ; :NERDTreeToggle 63 | -------------------------------------------------------------------------------- /vim/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="link vim config" 5 | if confirm "$action"; then 6 | link_config "$HOME/dotconfig/vim/.vimrc" "$HOME/.vimrc" 7 | fi 8 | -------------------------------------------------------------------------------- /xmonad/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/haskell 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=haskell 3 | 4 | ### Haskell ### 5 | dist 6 | dist-* 7 | cabal-dev 8 | *.o 9 | *.hi 10 | *.hie 11 | *.chi 12 | *.chs.h 13 | *.dyn_o 14 | *.dyn_hi 15 | .hpc 16 | .hsenv 17 | .cabal-sandbox/ 18 | cabal.sandbox.config 19 | *.prof 20 | *.aux 21 | *.hp 22 | *.eventlog 23 | .stack-work/ 24 | cabal.project.local 25 | cabal.project.local~ 26 | .HTF/ 27 | .ghc.environment.* 28 | 29 | # End of https://www.toptal.com/developers/gitignore/api/haskell 30 | -------------------------------------------------------------------------------- /xmonad/scripts/autostart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function run() { 4 | if ! pgrep $1; then 5 | $@ & 6 | fi 7 | } 8 | 9 | #Set your native resolution IF it does not exist in xrandr 10 | #More info in the script 11 | #run $HOME/.xmonad/scripts/set-screen-resolution-in-virtualbox.sh 12 | 13 | #Find out your monitor name with xrandr or arandr (save and you get this line) 14 | #xrandr --output VGA-1 --primary --mode 1360x768 --pos 0x0 --rotate normal 15 | #xrandr --output DP2 --primary --mode 1920x1080 --rate 60.00 --output LVDS1 --off & 16 | #xrandr --output LVDS1 --mode 1366x768 --output DP3 --mode 1920x1080 --right-of LVDS1 17 | #xrandr --output HDMI2 --mode 1920x1080 --pos 1920x0 --rotate normal --output HDMI1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output VIRTUAL1 --off 18 | 19 | # same as sddm/Xsetup script 20 | # xrandr --output HDMI-0 --auto --output DP-0 --auto --left-of HDMI-0 21 | 22 | ( 23 | sleep 2 24 | run $HOME/.config/polybar/launch.sh 25 | ) & 26 | 27 | #change your keyboard if you need it 28 | #setxkbmap -layout be 29 | 30 | #cursor active at boot 31 | xsetroot -cursor_name left_ptr & 32 | 33 | #start ArcoLinux Welcome App 34 | # run dex $HOME/.config/autostart/arcolinux-welcome-app.desktop 35 | 36 | #Some ways to set your wallpaper besides variety or nitrogen 37 | feh --bg-fill /usr/share/backgrounds/arcolinux/arco-login.jpg & 38 | #start the conky to learn the shortcuts 39 | # (conky -c $HOME/.xmonad/scripts/system-overview) & 40 | 41 | #starting utility applications at boot time 42 | # run variety & 43 | run nm-applet & 44 | run pamac-tray & 45 | run xfce4-power-manager & 46 | # run volumeicon & 47 | numlockx on & 48 | blueberry-tray & 49 | picom & 50 | /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 & 51 | /usr/lib/xfce4/notifyd/xfce4-notifyd & 52 | unclutter & 53 | 54 | if ! pgrep clipman; then 55 | xfce4-clipman & 56 | fi 57 | 58 | #starting user applications at boot time 59 | #nitrogen --restore & 60 | #run caffeine & 61 | #run vivaldi-stable & 62 | #run firefox & 63 | #run thunar & 64 | # run copyq & 65 | # run spotify & # wrapper? 66 | #run atom & 67 | 68 | # Communications 69 | #run telegram-desktop & 70 | run discord & 71 | # run slack & 72 | #run dropbox & 73 | #run insync start & 74 | #run ckb-next -b & 75 | # run thunderbird & 76 | # run evolution & 77 | 78 | # Set keyboard repeat delay 79 | xset r rate 200 25 80 | -------------------------------------------------------------------------------- /xmonad/scripts/picom-toggle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if pgrep -x "picom" > /dev/null 3 | then 4 | killall picom 5 | else 6 | picom -b 7 | fi 8 | -------------------------------------------------------------------------------- /xmonad/scripts/set-screen-resolution-in-virtualbox.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #use xrandr and arandr to know the 4 | #possible resolutions, frequency 5 | #and the names of your monitors 6 | 7 | #IF you know your native resolution and frequency 8 | #for example 1920x1080 @ 60 herz 9 | # type this in your terminal 10 | # gtf 1920 1080 60 11 | # This is the result 12 | # You will need to copy/paste it later. 13 | # 1920x1080 @ 60.00 Hz (GTF) hsync: 67.08 kHz; pclk: 172.80 MHz 14 | # Modeline "1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync 15 | 16 | xrandr --newmode "1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync 17 | xrandr --addmode Virtual1 "1920x1080_60.00" 18 | xrandr --output Virtual1 --primary --mode "1920x1080_60.00" --pos 0x0 --rotate normal 19 | -------------------------------------------------------------------------------- /xmonad/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="link config" 5 | if confirm "$action"; then 6 | link_config "$HOME/dotconfig/xmonad" "$HOME/.xmonad" 7 | fi 8 | -------------------------------------------------------------------------------- /xmonad/wall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axieax/dotconfig/ffb82b76cc407c0e6b3ce10c65671e0d91bbade1/xmonad/wall.jpg -------------------------------------------------------------------------------- /xmonad/xmonad.cabal: -------------------------------------------------------------------------------- 1 | -- Copied from https://github.com/xmonad/xmonad/blob/master/xmonad.cabal -- 2 | name: xmonad 3 | version: 0.17.2.9 4 | synopsis: A tiling window manager 5 | description: xmonad is a tiling window manager for X. Windows are arranged 6 | automatically to tile the screen without gaps or overlap, maximising 7 | screen use. All features of the window manager are accessible from the 8 | keyboard: a mouse is strictly optional. xmonad is written and 9 | extensible in Haskell. Custom layout algorithms, and other extensions, 10 | may be written by the user in config files. Layouts are applied 11 | dynamically, and different layouts may be used on each workspace. 12 | Xinerama is fully supported, allowing windows to be tiled on several 13 | screens. 14 | license: BSD3 15 | license-file: LICENSE 16 | author: Spencer Janssen, Don Stewart, Adam Vogt, David Roundy, Jason Creighton, 17 | Brent Yorgey, Peter Jones, Peter Simons, Andrea Rossato, Devin Mullins, 18 | Lukas Mai, Alec Berryman, Stefan O'Rear, Daniel Wagner, Peter J. Jones, 19 | Daniel Schoepe, Karsten Schoelzel, Neil Mitchell, Joachim Breitner, 20 | Peter De Wachter, Eric Mertens, Geoff Reedy, Michiel Derhaeg, 21 | Philipp Balzarek, Valery V. Vorotyntsev, Alex Tarkovsky, Fabian Beuke, 22 | Felix Hirn, Michael Sloan, Tomas Janousek, Vanessa McHale, Nicolas Pouillard, 23 | Aaron Denney, Austin Seipp, Benno Fünfstück, Brandon S Allbery, Chris Mears, 24 | Christian Thiemann, Clint Adams, Daniel Neri, David Lazar, Ferenc Wagner, 25 | Francesco Ariis, Gábor Lipták, Ivan N. Veselov, Ivan Tarasov, Javran Cheng, 26 | Jens Petersen, Joey Hess, Jonne Ransijn, Josh Holland, Khudyakov Alexey, 27 | Klaus Weidner, Michael G. Sloan, Mikkel Christiansen, Nicolas Dudebout, 28 | Ondřej Súkup, Paul Hebble, Shachaf Ben-Kiki, Siim Põder, Tim McIver, 29 | Trevor Elliott, Wouter Swierstra, Conrad Irwin, Tim Thelion, Tony Zorman 30 | maintainer: xmonad@haskell.org 31 | tested-with: GHC == 8.6.5 || == 8.8.4 || == 8.10.7 || == 9.0.2 || == 9.2.7 || == 9.4.4 || == 9.6.1 32 | category: System 33 | homepage: http://xmonad.org 34 | bug-reports: https://github.com/xmonad/xmonad/issues 35 | build-type: Simple 36 | extra-source-files: README.md 37 | CHANGES.md 38 | CONTRIBUTING.md 39 | INSTALL.md 40 | MAINTAINERS.md 41 | TUTORIAL.md 42 | man/xmonad.1.markdown 43 | man/xmonad.1 44 | man/xmonad.1.html 45 | man/xmonad.hs 46 | util/hpcReport.sh 47 | cabal-version: 1.12 48 | 49 | source-repository head 50 | type: git 51 | location: https://github.com/xmonad/xmonad 52 | 53 | flag pedantic 54 | description: Be pedantic (-Werror and the like) 55 | default: False 56 | manual: True 57 | 58 | library 59 | exposed-modules: XMonad 60 | XMonad.Config 61 | XMonad.Core 62 | XMonad.Layout 63 | XMonad.Main 64 | XMonad.ManageHook 65 | XMonad.Operations 66 | XMonad.StackSet 67 | other-modules: Paths_xmonad 68 | hs-source-dirs: src 69 | build-depends: base >= 4.11 && < 5 70 | , X11 >= 1.10 && < 1.11 71 | , containers 72 | , data-default-class 73 | , directory 74 | , filepath 75 | , mtl 76 | , process 77 | , setlocale 78 | , time 79 | , transformers >= 0.3 80 | , unix 81 | ghc-options: -funbox-strict-fields -Wall -Wno-unused-do-bind 82 | default-language: Haskell2010 83 | 84 | -- Keep this in sync with the oldest version in 'tested-with' 85 | if impl(ghc > 8.6.5) 86 | ghc-options: -Wno-unused-imports 87 | 88 | if flag(pedantic) 89 | ghc-options: -Werror 90 | 91 | executable xmonad 92 | main-is: Main.hs 93 | build-depends: base, xmonad 94 | ghc-options: -Wall -Wno-unused-do-bind 95 | default-language: Haskell2010 96 | 97 | -- Keep this in sync with the oldest version in 'tested-with' 98 | if impl(ghc > 8.6.5) 99 | ghc-options: -Wno-unused-imports 100 | 101 | if flag(pedantic) 102 | ghc-options: -Werror 103 | 104 | test-suite properties 105 | type: exitcode-stdio-1.0 106 | main-is: Properties.hs 107 | other-modules: Instances 108 | Properties.Delete 109 | Properties.Failure 110 | Properties.Floating 111 | Properties.Focus 112 | Properties.GreedyView 113 | Properties.Insert 114 | Properties.Layout.Full 115 | Properties.Layout.Tall 116 | Properties.Screen 117 | Properties.Shift 118 | Properties.Stack 119 | Properties.StackSet 120 | Properties.Swap 121 | Properties.View 122 | Properties.Workspace 123 | Utils 124 | hs-source-dirs: tests 125 | build-depends: base 126 | , QuickCheck >= 2 127 | , quickcheck-classes >= 0.4.3 128 | , X11 129 | , containers 130 | , xmonad 131 | default-language: Haskell2010 132 | 133 | if flag(pedantic) 134 | ghc-options: -Werror 135 | -------------------------------------------------------------------------------- /zsh/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/zsh 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=zsh 3 | 4 | ### Zsh ### 5 | # Zsh compiled script + zrecompile backup 6 | *.zwc 7 | *.zwc.old 8 | 9 | # Zsh completion-optimization dumpfile 10 | *zcompdump* 11 | 12 | # Zsh history 13 | .zsh_history 14 | 15 | # Zsh sessions 16 | .zsh_sessions 17 | 18 | # Zsh zcalc history 19 | .zcalc_history 20 | 21 | # A popular plugin manager's files 22 | ._zinit 23 | .zinit_lstupd 24 | 25 | # zdharma/zshelldoc tool's files 26 | zsdoc/data 27 | 28 | # robbyrussell/oh-my-zsh/plugins/per-directory-history plugin's files 29 | # (when set-up to store the history in the local directory) 30 | .directory_history 31 | 32 | # MichaelAquilina/zsh-autoswitch-virtualenv plugin's files 33 | # (for Zsh plugins using Python) 34 | .venv 35 | 36 | # Zunit tests' output 37 | /tests/_output/* 38 | !/tests/_output/.gitkeep 39 | 40 | # End of https://www.toptal.com/developers/gitignore/api/zsh 41 | -------------------------------------------------------------------------------- /zsh/.zprofile: -------------------------------------------------------------------------------- 1 | source "$ZDOTDIR/utilities.sh" 2 | 3 | pathadd "$HOME/.bin" 4 | pathadd "$HOME/.local/bin" 5 | pathadd "$HOME/bin/path" 6 | pathadd "$HOME/.yarn/bin" 7 | pathadd "$HOME/.local/share/gem/ruby/3.0.0/bin" 8 | pathadd "$HOME/.cargo/bin" 9 | pathadd "$HOME/go/bin" 10 | pathadd "$HOME/.ghcup/bin" 11 | 12 | pathadd "$HOME/Library/Application Support/JetBrains/Toolbox/scripts" 13 | [ -f "/opt/homebrew/bin/brew" ] && eval "$(/opt/homebrew/bin/brew shellenv)" 14 | -------------------------------------------------------------------------------- /zsh/.zsh_mac: -------------------------------------------------------------------------------- 1 | alias diff='git diff' 2 | alias sed='gsed' 3 | -------------------------------------------------------------------------------- /zsh/.zshenv: -------------------------------------------------------------------------------- 1 | export ZDOTDIR="$HOME/dotconfig/zsh" 2 | -------------------------------------------------------------------------------- /zsh/.zshrc: -------------------------------------------------------------------------------- 1 | source "$ZDOTDIR/utilities.sh" 2 | 3 | ### SETTINGS ## 4 | bindkey -v 5 | setopt glob_dots 6 | # setopt share_history 7 | 8 | if [[ -n $SSH_CONNECTION ]]; then 9 | export EDITOR='vim' 10 | export VISUAL='vim' 11 | else 12 | export EDITOR='nvim' 13 | export VISUAL='nvim' 14 | fi 15 | 16 | # use bat as default pager 17 | export MANPAGER="sh -c 'col -bx | bat -l man -p'" 18 | 19 | ### TMUX AUTOSTART ### 20 | sauce "$HOME/dotconfig/tmux/scripts/aliases.sh" 21 | sauce "$HOME/dotconfig/tmux/scripts/autostart.sh" 22 | _tmux_autostart 23 | 24 | ### OH-MY-ZSH ### 25 | export ZSH="$HOME/.oh-my-zsh" 26 | zstyle ':omz:update' mode auto 27 | zstyle ':omz:update' frequency 13 28 | 29 | ENABLE_CORRECTION="true" 30 | plugins=( 31 | git 32 | zoxide 33 | npm 34 | # nvm 35 | pyenv 36 | bazel 37 | terraform 38 | starship 39 | 40 | # notify # NOTE: does not disappear 41 | auto-notify 42 | zsh-autosuggestions 43 | zsh-completions 44 | zsh-syntax-highlighting # NOTE: this has to be the last plugin 45 | ) 46 | fpath+="$ZSH/custom/plugins/zsh-completions/src" 47 | 48 | # ZSH_THEME="spaceship" 49 | sauce $ZSH/oh-my-zsh.sh 50 | 51 | AUTO_NOTIFY_IGNORE+=( 52 | "cd" 53 | "lazygit" 54 | "lf" 55 | ) 56 | 57 | ### ALIASES ### 58 | alias ls='lsd' 59 | alias tree='lsd --tree' 60 | alias la='ls -a' 61 | alias ll='ls -alFh' 62 | alias l='ls' 63 | alias l.="ls -A | grep -E '^\.'" 64 | 65 | alias gi="$HOME/dotconfig/scripts/gitignore.sh" 66 | alias ggs="git status" 67 | alias ggm="git mergetool" 68 | alias ggd="git diff" 69 | alias ggl="git log" 70 | alias ggl="git log" 71 | 72 | alias cd..='cd ..' 73 | alias pdw='pwd' 74 | 75 | alias grep='grep --color=auto' 76 | alias egrep='egrep --color=auto' 77 | alias fgrep='fgrep --color=auto' 78 | alias diff='diff --color' 79 | alias df='df -h' 80 | 81 | alias lg="lazygit" 82 | alias v="nvim" 83 | alias vv="cd $HOME/dotconfig/nvim && $EDITOR" 84 | alias zz="$EDITOR $ZDOTDIR/.zshrc" 85 | alias zzz="clear && source $ZDOTDIR/.zshrc" 86 | 87 | ### OS-SPECIFIC CONFIG ### 88 | OS=$(uname -s) 89 | if [[ "$OS" == "Linux" ]]; then 90 | sauce "$ZDOTDIR/.zsh_linux" 91 | elif [[ "$OS" == "Darwin" ]]; then 92 | sauce "$ZDOTDIR/.zsh_mac" 93 | else 94 | echo "Unsupported OS: $OS" 95 | fi 96 | sauce "$HOME/.zshrc" 97 | 98 | ### CUSTOM FUNCTIONS ### 99 | function qr() { curl qrcode.show/$1 } 100 | 101 | function gch() { git checkout "${1:-$(git branch --all | fzf | awk '{print $1}')}" } 102 | function ggf() { git fetch origin "$1" } 103 | function ggr() { git reset --soft "${1:-$(git log --oneline -100 | fzf | awk '{print $1}')}" } 104 | function ggR() { git reset --hard "${1:-$(git log --oneline -100 | fzf | awk '{print $1}')}" } 105 | function ggN() { 106 | local branch="${1:-$(git branch --show-current)}"; 107 | git fetch origin "$branch" && git reset --hard "origin/$branch" 108 | } 109 | 110 | # lf with cd behaviour 111 | function lf() { 112 | LF_DIR="/tmp/lf-last-dir" 113 | [ -f "$LF_DIR" ] && rm -f "$LF_DIR" 114 | command lf "$@" 115 | if [ -f "$LF_DIR" ]; then 116 | DIR="$(cat "$LF_DIR")" 117 | if [ -d "$DIR" ] && [ "$DIR" != "$(pwd)" ]; then 118 | echo "Changing directory to $DIR" 119 | cd "$DIR" 120 | fi 121 | fi 122 | } 123 | 124 | ### Start Services ### 125 | neofetch 126 | 127 | sauce "$HOME/.ghcup/env" 128 | sauce "$HOME/.nix-profile/etc/profile.d/nix.sh" 129 | 130 | # nvm 131 | # sauce /usr/share/nvm/init-nvm.sh --no-use 132 | # TODO: add default node to path https://www.ioannispoulakas.com/2020/02/22/how-to-speed-up-shell-load-while-using-nvm/ 133 | # nvm alias default node > /dev/null 134 | -------------------------------------------------------------------------------- /zsh/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$HOME/dotconfig/setup-utilities.sh" 3 | 4 | action="install zsh" 5 | if ! check_dependency zsh && confirm "$action"; then 6 | if is_linux; then 7 | sudo pacman -S zsh 8 | elif is_mac; then 9 | brew install zsh 10 | else 11 | echo "Failed to $action: unsupported OS" 12 | fi 13 | fi 14 | 15 | action="install oh-my-zsh" 16 | if [ ! -d "$HOME/.oh-my-zsh" ] && confirm "$action"; then 17 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended 18 | fi 19 | 20 | action="change default shell to zsh" 21 | if confirm "$action"; then 22 | chsh -s "$(which zsh)" 23 | fi 24 | 25 | action="install zsh plugins" 26 | if confirm "$action"; then 27 | ZSH_CUSTOM="$HOME/.oh-my-zsh/custom/plugins" 28 | # git clone https://github.com/marzocchi/zsh-notify.git "$ZSH_CUSTOM/notify" 29 | git clone https://github.com/MichaelAquilina/zsh-auto-notify.git "$ZSH_CUSTOM/auto-notify" 30 | git clone https://github.com/zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/zsh-autosuggestions" 31 | git clone https://github.com/zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/zsh-syntax-highlighting" 32 | git clone https://github.com/zsh-users/zsh-completions.git "$ZSH_CUSTOM/zsh-completions" 33 | fi 34 | 35 | action="link zsh config" 36 | if confirm "$action"; then 37 | link_config "$HOME/dotconfig/zsh/.zshenv" "$HOME/.zshenv" 38 | fi 39 | 40 | action="install starship prompt" 41 | if ! check_dependency starship && confirm "$action"; then 42 | if is_linux; then 43 | sudo pacman -S starship 44 | elif is_mac; then 45 | brew install starship 46 | else 47 | echo "Failed to $action: unsupported OS" 48 | fi 49 | fi 50 | 51 | action="link starship config" 52 | if confirm "$action"; then 53 | link_config "$HOME/dotconfig/zsh/starship.toml" "$HOME/.config/starship.toml" 54 | fi 55 | 56 | # NOTE: starship missing async functionality from spaceship-prompt 57 | # spaceship issues: 58 | # - https://github.com/spaceship-prompt/spaceship-prompt/issues/1193 on linux 59 | # - vi-mode not updating, jeffreytse/zsh-vi-mode has tradeoffs and can't update RS2 60 | # - slow, no hot config refresh 61 | 62 | action="install spaceship prompt" 63 | if confirm "$action"; then 64 | ZSH_CUSTOM="$HOME/.oh-my-zsh/custom/themes" 65 | git clone https://github.com/spaceship-prompt/spaceship-prompt.git "$ZSH_CUSTOM/spaceship-prompt" --depth=1 66 | ln -s "$ZSH_CUSTOM/spaceship-prompt/spaceship.zsh-theme" "$ZSH_CUSTOM/spaceship.zsh-theme" 67 | fi 68 | 69 | action="link spaceship config" 70 | if confirm "$action"; then 71 | link_config "$HOME/dotconfig/zsh/spaceship.zsh" "$HOME/.config/spaceship.zsh" 72 | fi 73 | -------------------------------------------------------------------------------- /zsh/spaceship.zsh: -------------------------------------------------------------------------------- 1 | # TODO: vi-mode char like starship 2 | SPACESHIP_CHAR_SYMBOL="❯" 3 | SPACESHIP_CHAR_SUFFIX=" " 4 | SPACESHIP_DIR_TRUNC_PREFIX="…/" 5 | SPACESHIP_ASYNC_SHOW=false 6 | SPACESHIP_EXIT_CODE_SHOW=true 7 | SPACESHIP_EXIT_CODE_SYMBOL="✘ " 8 | 9 | SPACESHIP_JAVA_SYMBOL=" " 10 | SPACESHIP_JAVA_COLOR="red" 11 | SPACESHIP_GCLOUD_SHOW=false 12 | -------------------------------------------------------------------------------- /zsh/starship.toml: -------------------------------------------------------------------------------- 1 | command_timeout = 1000 2 | 3 | # [git_status] 4 | # disabled = true 5 | 6 | [directory] 7 | truncation_length = 10 8 | truncation_symbol = "…/" 9 | 10 | [gcloud] 11 | disabled = true 12 | 13 | [java] 14 | symbol = " " 15 | -------------------------------------------------------------------------------- /zsh/utilities.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function pathadd() { 4 | if [[ -d "$1" ]]; then 5 | export PATH="$1${PATH:+":${PATH}"}" 6 | fi 7 | } 8 | 9 | function sauce() { 10 | if [[ -f "$1" ]]; then 11 | source "$1" 12 | fi 13 | } 14 | --------------------------------------------------------------------------------