├── tmate.conf ├── config ├── nvim │ ├── after │ │ ├── ftplugin │ │ │ ├── help.vim │ │ │ ├── gitcommit.vim │ │ │ ├── python.vim │ │ │ ├── fzf.vim │ │ │ ├── kitty.vim │ │ │ └── rst.vim │ │ └── queries │ │ │ ├── lua │ │ │ └── highlights.scm │ │ │ ├── python │ │ │ └── injections.scm │ │ │ ├── vim │ │ │ └── injections.scm │ │ │ └── rust │ │ │ └── highlights.scm │ ├── lua │ │ └── user │ │ │ ├── plugins │ │ │ ├── autosession.lua │ │ │ ├── sayonara.lua │ │ │ ├── colorscheme.lua │ │ │ ├── spotify.lua │ │ │ ├── copilot.lua │ │ │ ├── ui.lua │ │ │ ├── init.lua │ │ │ ├── git.lua │ │ │ ├── format.lua │ │ │ ├── nvim-tree.lua │ │ │ ├── fzf.lua │ │ │ ├── snacks.lua │ │ │ ├── autocompletion.lua │ │ │ └── treesitter.lua │ │ │ ├── plugin-manager.lua │ │ │ ├── utils.lua │ │ │ ├── mappings.lua │ │ │ ├── commands.lua │ │ │ └── options.lua │ ├── init.lua │ ├── Dockerfile │ └── lazy-lock.json ├── bat │ └── config ├── kitty │ ├── dark-theme.auto.conf │ └── kitty.conf ├── systemd │ └── user │ │ └── ssh-agent.service └── gdb │ └── gdbinit ├── stylua.toml ├── local └── share │ └── nautilus │ └── scripts │ ├── README.md │ ├── open-terminal │ ├── shred │ └── clear-metadata ├── .gitignore ├── gnupg └── gpg-agent.conf ├── scripts ├── rust.sh ├── marksman.sh ├── protonvpn.sh ├── luals.sh ├── docker.sh ├── ssh.sh ├── uv.sh ├── create-firefox-profile.sh ├── zsh.sh ├── node.sh ├── fonts.sh ├── nvim.sh └── kitty.sh ├── pypirc ├── bin ├── togglebg └── mount-private ├── yubikey.md ├── ssh.config ├── gnome-extensions.txt ├── gitconfig ├── gitignore ├── .github └── workflows │ └── deploy-image.yml ├── tmux.conf ├── LICENSE ├── firefox-about.txt ├── README.md ├── Makefile └── zshrc /tmate.conf: -------------------------------------------------------------------------------- 1 | source-file ~/.tmux.conf 2 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/help.vim: -------------------------------------------------------------------------------- 1 | setlocal buflisted 2 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/gitcommit.vim: -------------------------------------------------------------------------------- 1 | setlocal spell 2 | -------------------------------------------------------------------------------- /stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | indent_width = 2 3 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/python.vim: -------------------------------------------------------------------------------- 1 | setlocal colorcolumn=81 2 | -------------------------------------------------------------------------------- /config/bat/config: -------------------------------------------------------------------------------- 1 | --theme="TwoDark" 2 | --style="numbers,changes" 3 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/fzf.vim: -------------------------------------------------------------------------------- 1 | setlocal winblend=10 2 | file fzf 3 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/kitty.vim: -------------------------------------------------------------------------------- 1 | setlocal commentstring=#\ %s 2 | -------------------------------------------------------------------------------- /config/nvim/after/queries/lua/highlights.scm: -------------------------------------------------------------------------------- 1 | ; extends 2 | ["{" "}"] @punctuation.bracket 3 | -------------------------------------------------------------------------------- /local/share/nautilus/scripts/README.md: -------------------------------------------------------------------------------- 1 | https://help.ubuntu.com/community/NautilusScriptsHowto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /config/nvim/spell/ 2 | /config/kitty/current-theme* 3 | /config/systemd/user/*.wants 4 | -------------------------------------------------------------------------------- /local/share/nautilus/scripts/open-terminal: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ~/.local/bin/kitty --directory=. 4 | -------------------------------------------------------------------------------- /config/nvim/after/ftplugin/rst.vim: -------------------------------------------------------------------------------- 1 | " Enabled builtin RST indentation support. 2 | let g:rst_style = 1 3 | -------------------------------------------------------------------------------- /gnupg/gpg-agent.conf: -------------------------------------------------------------------------------- 1 | # Cache the password for 2 hours and 6 hours max. 2 | default-cache-ttl 7200 3 | max-cache-ttl 14400 4 | -------------------------------------------------------------------------------- /config/kitty/dark-theme.auto.conf: -------------------------------------------------------------------------------- 1 | # Custom overrides 2 | 3 | active_tab_background #24283b 4 | active_tab_foreground #c0caf5 5 | 6 | # vim:ft=kitty 7 | -------------------------------------------------------------------------------- /scripts/rust.sh: -------------------------------------------------------------------------------- 1 | # Install Rust 2 | # https://www.rust-lang.org/ 3 | 4 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh /dev/stdin -y 5 | -------------------------------------------------------------------------------- /pypirc: -------------------------------------------------------------------------------- 1 | [distutils] 2 | index-servers = 3 | pypi 4 | testpypi 5 | 6 | [pypi] 7 | username = __token__ 8 | 9 | [testpypi] 10 | username = __token__ 11 | -------------------------------------------------------------------------------- /config/nvim/after/queries/python/injections.scm: -------------------------------------------------------------------------------- 1 | ; extends 2 | ; Docstrings 3 | ((expression_statement (string (string_content) @injection.content)) 4 | (#set! injection.language "rst")) 5 | -------------------------------------------------------------------------------- /scripts/marksman.sh: -------------------------------------------------------------------------------- 1 | VERSION=2024-12-18 2 | wget https://github.com/artempyanykh/marksman/releases/download/${VERSION}/marksman-linux-x64 -O ~/.local/bin/marksman 3 | chmod +x ~/.local/bin/marksman 4 | -------------------------------------------------------------------------------- /local/share/nautilus/scripts/shred: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | while read line ; do 4 | if [ -f "$line" ]; then 5 | shred --remove --zero -v -- "$line" 6 | fi 7 | done 8 | -------------------------------------------------------------------------------- /local/share/nautilus/scripts/clear-metadata: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | while read line ; do 4 | if [ -f "$line" ]; then 5 | exiftool -overwrite_original -ALL= -- "$line" 6 | fi 7 | done 8 | -------------------------------------------------------------------------------- /config/nvim/after/queries/vim/injections.scm: -------------------------------------------------------------------------------- 1 | ; extends 2 | ((map_statement 3 | rhs: (map_side) @injection.content) 4 | (#match? @injection.content "^:.+") 5 | (#offset! @injection.content 0 1 0 -4) 6 | (#set! injection.language "vim")) 7 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/autosession.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "rmagatti/auto-session", 4 | config = function() 5 | require("auto-session").setup({ 6 | auto_create = false, 7 | }) 8 | end, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /scripts/protonvpn.sh: -------------------------------------------------------------------------------- 1 | # https://protonvpn.com/support/official-linux-vpn-fedora/ 2 | sudo dnf install -y https://repo.protonvpn.com/fedora-39-stable/protonvpn-stable-release/protonvpn-stable-release-1.0.1-2.noarch.rpm 3 | sudo dnf install -y proton-vpn-gnome-desktop 4 | -------------------------------------------------------------------------------- /config/systemd/user/ssh-agent.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=SSH key agent 3 | 4 | [Service] 5 | Type=simple 6 | Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket 7 | ExecStart=/usr/bin/ssh-agent -t 2h -D -a $SSH_AUTH_SOCK 8 | 9 | [Install] 10 | WantedBy=default.target 11 | -------------------------------------------------------------------------------- /config/nvim/after/queries/rust/highlights.scm: -------------------------------------------------------------------------------- 1 | ; extends 2 | ((impl_item (declaration_list (function_item (identifier) @constructor))) 3 | (#eq? @constructor "new")) 4 | 5 | (call_expression 6 | function: (scoped_identifier 7 | name: (identifier) @constructor) 8 | (#eq? @constructor "new")) 9 | -------------------------------------------------------------------------------- /bin/togglebg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TO_BACKGROUND=light 4 | if [[ "$BACKGROUND" == "light" ]]; then 5 | TO_BACKGROUND=dark 6 | fi 7 | 8 | echo "Changing to" $TO_BACKGROUND 9 | 10 | sed --follow-symlinks -i "s/^export BACKGROUND=.*/export BACKGROUND=${TO_BACKGROUND}/" ~/.zshrc 11 | 12 | echo "Re-open the terminal for the changes to take effect." 13 | -------------------------------------------------------------------------------- /scripts/luals.sh: -------------------------------------------------------------------------------- 1 | # Install Lua Language Server 2 | 3 | VERSION=3.15.0 4 | wget \ 5 | https://github.com/LuaLS/lua-language-server/releases/download/$VERSION/lua-language-server-$VERSION-linux-x64.tar.gz \ 6 | -O /tmp/lua-language-server.tar.gz 7 | 8 | mkdir -p $HOME/lua-language-server 9 | tar -xzf /tmp/lua-language-server.tar.gz -C $HOME/lua-language-server 10 | -------------------------------------------------------------------------------- /bin/mount-private: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | time=60 4 | directory="" 5 | while (( "$#" )); do 6 | case "$1" in 7 | -t|--time) 8 | time=$2 9 | shift 2 10 | ;; 11 | *) 12 | directory=$1 13 | shift 1 14 | ;; 15 | esac 16 | done 17 | 18 | echo "Mounting ~/.$directory -> ~/$directory" 19 | sudo encfs -i $time --public ~/.$directory ~/$directory 20 | -------------------------------------------------------------------------------- /scripts/docker.sh: -------------------------------------------------------------------------------- 1 | curl -fsSL https://get.docker.com | sudo sh 2 | 3 | sudo usermod -aG docker $USER 4 | sudo systemctl enable docker.service 5 | sudo systemctl enable containerd.service 6 | 7 | # Change cgroups. 8 | # Isn't needed for the current version of docker, 9 | # but it's needed for gvisor. 10 | # sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" 11 | -------------------------------------------------------------------------------- /scripts/ssh.sh: -------------------------------------------------------------------------------- 1 | # Setup ssh-agent at login. 2 | # You may need to disable the gnome-keyring daemon 3 | # https://wiki.archlinux.org/index.php/GNOME/Keyring#Disable_keyring_daemon_components. 4 | TARGET_DIR=~/.config/systemd/user 5 | mkdir -p $TARGET_DIR 6 | ln -sf ~/dotfiles/config/systemd/user/ssh-agent.service $TARGET_DIR/ssh-agent.service 7 | systemctl --user enable ssh-agent 8 | systemctl --user start ssh-agent 9 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/sayonara.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | -- Close/hide/delete current buffer. 5 | "mhinz/vim-sayonara", 6 | cmd = "Sayonara", 7 | init = function() 8 | map("n", "q", ":Sayonara", { silent = true, desc = "Close current buffer" }) 9 | map("n", "Q", ":Sayonara!", { silent = true, desc = "Close current buffer, but keep layout" }) 10 | end, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /scripts/uv.sh: -------------------------------------------------------------------------------- 1 | # Install uv 2 | # https://docs.astral.sh/uv/ 3 | curl -LsSf https://astral.sh/uv/install.sh | sh 4 | 5 | # Install tools 6 | uv tool install ipython 7 | uv tool install td-watson 8 | # For formatting in neovim 9 | uv tool install black 10 | uv tool install isort 11 | uv tool install pylint 12 | 13 | # Create neovim environment 14 | cd ~/.local/share/nvim/ 15 | uv venv --python-preference system --system-site-packages 16 | uv pip install pynvim pydbus sphinx 17 | -------------------------------------------------------------------------------- /scripts/create-firefox-profile.sh: -------------------------------------------------------------------------------- 1 | # Create a desktop entry for a Firefox profile. 2 | # Usage: 3 | # - Create the profile with `firefox -ProfileManager` 4 | # - Run create-firefox-profile [profile name] 5 | 6 | PROFILE=$1 7 | echo Creating profile: $PROFILE 8 | TARGET=~/.local/share/applications/firefox-${PROFILE}.desktop 9 | cp /usr/share/applications/org.mozilla.firefox.desktop $TARGET 10 | sed -i "s/Name=Firefox/Name=Firefox $PROFILE/" $TARGET 11 | sed -i "s/Exec=firefox %u/Exec=firefox -P $PROFILE %u/" $TARGET 12 | -------------------------------------------------------------------------------- /scripts/zsh.sh: -------------------------------------------------------------------------------- 1 | # Install ohmyzsh 2 | # https://github.com/ohmyzsh/ohmyzsh 3 | 4 | curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh | sh /dev/stdin --unattended 5 | 6 | # Plugins 7 | git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting 8 | git clone --depth=1 https://github.com/zsh-users/zsh-completions ~/.oh-my-zsh/custom/plugins/zsh-completions 9 | 10 | # Set as default shell 11 | chsh -s $(which zsh) 12 | -------------------------------------------------------------------------------- /config/gdb/gdbinit: -------------------------------------------------------------------------------- 1 | # Pretty print. 2 | set print pretty on 3 | set print array on 4 | 5 | # Number of lines allowed before pagination starts. 6 | set height 500 7 | 8 | # Enable history. 9 | set history save on 10 | set history size 1000 11 | 12 | # Use debuginfod to find debug symbols online. 13 | set debuginfod enabled on 14 | 15 | # Temporarily enable pending breakpoints, so all 16 | # breakpoints are set when the program is started. 17 | set breakpoint pending on 18 | # Set breakpoint when a panic occurs. 19 | break rust_panic 20 | set breakpoint pending off 21 | -------------------------------------------------------------------------------- /scripts/node.sh: -------------------------------------------------------------------------------- 1 | # Allow to install global packages without sudo. 2 | mkdir ~/.npm-packages 3 | npm config set prefix ~/.npm-packages 4 | 5 | npm install -g tree-sitter-cli 6 | # Formatter for js, html, css, json, etc. 7 | npm install -g prettier 8 | # Python LSP 9 | npm install -g pyright 10 | # HTML, CSS, JS, JSON LSP 11 | npm install -g vscode-langservers-extracted 12 | # TypeScript LSP 13 | npm install -g typescript typescript-language-server 14 | npm install -g yaml-language-server 15 | # PHP LSP 16 | npm install -g intelephense 17 | npm install -g bash-language-server 18 | -------------------------------------------------------------------------------- /yubikey.md: -------------------------------------------------------------------------------- 1 | # Yubikey Setup 2 | 3 | - Insert the yubikey and run `ykpamcfg -1 -v` 4 | - Touch the yubikey to complete the operation 5 | - A file will be generated 6 | - Add this line to the files from `/etc/pam.d/` where you want to use the yubikey 7 | 8 | ``` 9 | auth required pam_yubico.so mode=challenge-response 10 | ``` 11 | 12 | Recomended files: 13 | 14 | - `/etc/pam.d/su` (used by the `su` command) 15 | - `/etc/pam.d/gdm-password` (used by the graphical interface at login) 16 | 17 | More information at 18 | https://developers.yubico.com/yubico-pam/Authentication_Using_Challenge-Response.html 19 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/colorscheme.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "folke/tokyonight.nvim", 4 | -- Make sure to load this before other plugins. 5 | priority = 1000, 6 | config = function() 7 | require("tokyonight").setup({ 8 | styles = { comments = { italic = false } }, 9 | }) 10 | 11 | vim.cmd("colorscheme tokyonight-storm") 12 | end, 13 | }, 14 | { 15 | "maxmx03/solarized.nvim", 16 | -- Make sure to load this before other plugins. 17 | priority = 1000, 18 | config = function() 19 | require("solarized").setup({ 20 | variant = "autumn", 21 | }) 22 | -- vim.cmd("colorscheme solarized") 23 | end, 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugin-manager.lua: -------------------------------------------------------------------------------- 1 | -- Bootstrap plugin manager (lazy.nvim). 2 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 3 | if not vim.uv.fs_stat(lazypath) then 4 | local lazyrepo = "https://github.com/folke/lazy.nvim.git" 5 | local out = vim.fn.system({ 6 | "git", 7 | "clone", 8 | "--filter=blob:none", 9 | "--branch=stable", 10 | lazyrepo, 11 | lazypath, 12 | }) 13 | if vim.v.shell_error ~= 0 then 14 | vim.api.nvim_echo({ 15 | { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, 16 | { out, "WarningMsg" }, 17 | { "\nPress any key to exit..." }, 18 | }, true, {}) 19 | vim.fn.getchar() 20 | os.exit(1) 21 | end 22 | end 23 | vim.opt.rtp:prepend(lazypath) 24 | -------------------------------------------------------------------------------- /ssh.config: -------------------------------------------------------------------------------- 1 | AddKeysToAgent yes 2 | 3 | Host *.github.com github.com 4 | IdentityFile ~/.ssh/id_github 5 | 6 | Host *.gitlab.com gitlab.com 7 | IdentityFile ~/.ssh/id_gitlab 8 | 9 | Host *.bitbucket.org bitbucket.org 10 | IdentityFile ~/.ssh/id_bitbucket 11 | 12 | Host *.codeberg.org codeberg.org 13 | IdentityFile ~/.ssh/id_codeberg 14 | 15 | Host *.readthedocs.com 16 | ForwardAgent yes 17 | User readthedocs 18 | IdentityFile ~/rtd-vpn/ssh/id_rtd.com 19 | 20 | Host *.readthedocs.org 21 | ForwardAgent yes 22 | User readthedocs 23 | IdentityFile ~/rtd-vpn/ssh/id_rtd.org 24 | 25 | Host pi 26 | User pi 27 | IdentityFile ~/.ssh/id_pi 28 | 29 | Host mrpi 30 | User mrpi 31 | IdentityFile ~/.ssh/id_mrpi 32 | 33 | # vim: ft=sshconfig 34 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/spotify.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "stsewd/spotify.nvim", 5 | enabled = false, 6 | build = ":UpdateRemotePlugins", 7 | cmd = "Spotify", 8 | init = function() 9 | map("n", "ss", ":Spotify play/pause", { silent = true }) 10 | map("n", "sj", ":Spotify next", { silent = true }) 11 | map("n", "sk", ":Spotify prev", { silent = true }) 12 | map("n", "sc", ":Spotify status", { silent = true }) 13 | end, 14 | config = function() 15 | require("spotify").setup({ 16 | notification = { 17 | extra_opts = { 18 | icon = "", 19 | }, 20 | }, 21 | }) 22 | end, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /gnome-extensions.txt: -------------------------------------------------------------------------------- 1 | # Gnome extensions can't be installed from the command line easily 2 | - https://extensions.gnome.org/extension/517/caffeine/ 3 | - https://extensions.gnome.org/extension/1319/gsconnect/ 4 | - https://extensions.gnome.org/extension/28/gtile/ 5 | - https://extensions.gnome.org/extension/19/user-themes/ 6 | - https://extensions.gnome.org/extension/1262/bing-wallpaper-changer/ 7 | - https://extensions.gnome.org/extension/4164/monitor-window-switcher/ 8 | # This is a fork, since the original hasn't been updated to work with the latest version of Gnome. 9 | - https://extensions.gnome.org/extension/5568/monitor-window-switcher-2/ 10 | - https://extensions.gnome.org/extension/1702/overview-navigation/ 11 | - https://extensions.gnome.org/extension/6670/bluetooth-battery-meter/ 12 | -------------------------------------------------------------------------------- /scripts/fonts.sh: -------------------------------------------------------------------------------- 1 | # Download and install the latast version of jetbrains mono. 2 | # https://www.jetbrains.com/lp/mono/ 3 | 4 | FONT_NAME=JetBrainsMono-2.304.zip 5 | wget -O /tmp/fonts.zip https://download.jetbrains.com/fonts/${FONT_NAME} 6 | unzip -od /tmp/fonts/ /tmp/fonts.zip 7 | 8 | FONTS_DIR=/tmp/fonts/fonts/ttf 9 | FONTS_TARGET_DIR=$HOME/.local/share/fonts/ 10 | mkdir -p $FONTS_TARGET_DIR 11 | 12 | cp -v \ 13 | $FONTS_DIR/JetBrainsMono-Regular.ttf \ 14 | $FONTS_DIR/JetBrainsMono-Bold.ttf \ 15 | $FONTS_DIR/JetBrainsMono-Italic.ttf \ 16 | $FONTS_DIR/JetBrainsMono-BoldItalic.ttf \ 17 | $FONTS_TARGET_DIR 18 | 19 | wget --directory-prefix=$FONTS_TARGET_DIR \ 20 | https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/JetBrainsMono/Ligatures/Regular/JetBrainsMonoNerdFontMono-Regular.ttf 21 | -------------------------------------------------------------------------------- /config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- Bootstrap plugin manager. 2 | require("user.plugin-manager") 3 | 4 | -- Load user options and mappings. 5 | require("user.options") 6 | require("user.mappings") 7 | require("user.commands") 8 | 9 | -- Load plugins. 10 | require("lazy").setup("user.plugins", { 11 | change_detection = { 12 | notify = false, 13 | }, 14 | performance = { 15 | rtp = { 16 | -- Lazy ignores the site directory by default, 17 | -- but we need it to load spell files. 18 | -- Workaround for https://github.com/folke/lazy.nvim/issues/677. 19 | paths = { vim.fn.stdpath("data") .. "/site" }, 20 | disabled_plugins = { 21 | "netrwPlugin", 22 | "tutor", 23 | "gzip", 24 | "tarPlugin", 25 | "zipPlugin", 26 | }, 27 | }, 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /gitconfig: -------------------------------------------------------------------------------- 1 | [user] 2 | name = Santos Gallegos 3 | email = stsewd@proton.me 4 | signingkey = C1AD42C27116CB5A 5 | 6 | [init] 7 | defaultBranch = main 8 | 9 | [push] 10 | default = current 11 | autoSetupRemote = true 12 | 13 | [core] 14 | excludesfile = ~/.gitignore 15 | editor = nvim 16 | pager = delta 17 | 18 | [interactive] 19 | diffFilter = delta --color-only --features=interactive 20 | 21 | [delta] 22 | line-numbers = true 23 | 24 | [delta "light"] 25 | light = true 26 | 27 | [diff] 28 | # Uses different colors to highlight lines in diffs that have been “moved”. 29 | colorMoved = default 30 | algorithm = histogram 31 | 32 | [pull] 33 | ff = only 34 | 35 | [merge] 36 | # Show three parts of the diff when there is a conflict. 37 | conflictStyle = diff3 38 | 39 | [commit] 40 | gpgsign = true 41 | 42 | [hub] 43 | protocol = ssh 44 | -------------------------------------------------------------------------------- /gitignore: -------------------------------------------------------------------------------- 1 | # temporary files 2 | *~ 3 | .~* 4 | 5 | # temporary files which can be created if a process still has a handle open of a deleted file 6 | .fuse_hidden* 7 | 8 | # KDE directory preferences 9 | .directory 10 | 11 | # Linux trash folder which might appear on any partition or disk 12 | .Trash-* 13 | 14 | # .nfs files are created when an open file is removed but is still being accessed 15 | .nfs* 16 | 17 | # Vim 18 | .vim 19 | 20 | # swap 21 | [._]*.s[a-v][a-z] 22 | [._]*.sw[a-p] 23 | [._]s[a-v][a-z] 24 | [._]sw[a-p] 25 | 26 | # temporary 27 | .netrwhist 28 | 29 | # ctags 30 | .ctags 31 | .tags 32 | .notags 33 | tags 34 | 35 | # pyenv 36 | .python-version 37 | 38 | # python 39 | venv 40 | 41 | # mypy 42 | .mypy_cache/ 43 | 44 | # Dotenv 45 | .env 46 | .envrc 47 | 48 | # nvm 49 | .nvmrc 50 | 51 | # pyright 52 | pyrightconfig.json 53 | 54 | # gdb 55 | .gdb_history 56 | -------------------------------------------------------------------------------- /.github/workflows/deploy-image.yml: -------------------------------------------------------------------------------- 1 | name: Create and publish a Docker image 2 | 3 | on: 4 | push: 5 | branches: ["master"] 6 | 7 | env: 8 | REGISTRY: ghcr.io 9 | IMAGE_NAME: stsewd/neovim 10 | 11 | jobs: 12 | build-and-push-image: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: read 16 | packages: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v3 21 | 22 | - name: Log in to the Container registry 23 | uses: docker/login-action@v2 24 | with: 25 | registry: ${{ env.REGISTRY }} 26 | username: ${{ github.actor }} 27 | password: ${{ secrets.GITHUB_TOKEN }} 28 | 29 | - name: Build and push Docker image 30 | uses: docker/build-push-action@v4 31 | with: 32 | context: config/nvim/ 33 | push: true 34 | tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest 35 | -------------------------------------------------------------------------------- /config/nvim/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | # Install latest Neovim 4 | RUN apt update && apt install -y software-properties-common 5 | RUN add-apt-repository ppa:neovim-ppa/unstable 6 | RUN apt update && apt install -y neovim 7 | 8 | RUN apt install -y git curl gnupg 9 | 10 | # Python dependencies 11 | RUN apt install -y python3-dev python3-pip 12 | RUN pip3 install pynvim 13 | 14 | # Node dependencies 15 | RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - 16 | RUN apt install -y nodejs 17 | RUN npm install --global yarn 18 | 19 | # My configuration 20 | RUN git clone --depth 1 \ 21 | https://github.com/stsewd/dotfiles $HOME/dotfiles 22 | 23 | RUN mkdir $HOME/.config/ && \ 24 | ln -s $HOME/dotfiles/config/nvim $HOME/.config/nvim 25 | 26 | WORKDIR /src 27 | CMD bash 28 | 29 | # Run this Dockerfile with 30 | # $ docker run --rm -it -v `pwd`:/src -v $HOME/.local/share/stsewd-nvim/lazy:/root/.local/share/nvim/lazy ghcr.io/stsewd/neovim 31 | # $ nvim 32 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/copilot.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "github/copilot.vim", 5 | config = function() 6 | vim.g.copilot_filetypes = { 7 | ["*"] = true, 8 | } 9 | map("i", "", "(copilot-accept-word)") 10 | end, 11 | }, 12 | { 13 | "CopilotC-Nvim/CopilotChat.nvim", 14 | -- Load the plugin only when these commands are run. 15 | cmd = { 16 | "CopilotChat", 17 | "CopilotChatToggle", 18 | "CopilotChatDebugInfo", 19 | "CopilotChatExplain", 20 | "CopilotChatReview", 21 | "CopilotChatFix", 22 | "CopilotChatOptimize", 23 | "CopilotChatDocs", 24 | "CopilotChatTests", 25 | "CopilotChatFixDiagnostic", 26 | "CopilotChatCommit", 27 | "CopilotChatCommitStaged", 28 | }, 29 | branch = "canary", 30 | dependencies = { 31 | { "github/copilot.vim" }, 32 | { "nvim-lua/plenary.nvim" }, 33 | }, 34 | config = function() 35 | require("CopilotChat").setup() 36 | end, 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/ui.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { "nvim-tree/nvim-web-devicons", lazy = true }, 4 | { 5 | "nvim-lualine/lualine.nvim", 6 | config = function() 7 | require("lualine").setup({ 8 | options = { 9 | theme = "auto", 10 | disabled_filetypes = { "startify", "NvimTree" }, 11 | }, 12 | sections = { 13 | lualine_x = { "filetype" }, 14 | }, 15 | extensions = { "fugitive", "quickfix" }, 16 | }) 17 | end, 18 | }, 19 | { 20 | "akinsho/nvim-bufferline.lua", 21 | config = function() 22 | require("bufferline").setup({ 23 | options = { 24 | offsets = { 25 | { filetype = "NvimTree", text = "Files" }, 26 | }, 27 | }, 28 | }) 29 | 30 | map("n", "j", ":BufferLineCyclePrev", { silent = true }) 31 | map("n", "k", ":BufferLineCycleNext", { silent = true }) 32 | map("n", "gb", ":BufferLinePick", { silent = true }) 33 | end, 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /tmux.conf: -------------------------------------------------------------------------------- 1 | # Set zsh default shell 2 | set-option -g default-shell /bin/zsh 3 | 4 | # Use C-a for command prefix 5 | set-option -g prefix C-a 6 | unbind-key C-b 7 | bind-key C-a send-prefix 8 | 9 | # Use 256 color terminal 10 | set -g default-terminal "tmux-256color" 11 | set-option -ga terminal-overrides ",*256col*:Tc" 12 | 13 | # Enable mouse support for switching panes/windows 14 | setw -g mouse on 15 | 16 | # Command delay? We don't want that, make it short 17 | set -sg escape-time 1 18 | 19 | # Use hjkl to move between panes 20 | bind h select-pane -L 21 | bind l select-pane -R 22 | bind j select-pane -D 23 | bind k select-pane -U 24 | 25 | # Use HJKL for resizing panes 26 | bind -r H resize-pane -L 2 27 | bind -r L resize-pane -R 2 28 | bind -r J resize-pane -D 2 29 | bind -r K resize-pane -U 2 30 | 31 | 32 | # Disable status bar 33 | set -g status off 34 | 35 | # Use the vertical and horizontal symbols to split the screen 36 | bind | split-window -h 37 | bind - split-window -v 38 | 39 | # Use vi-like shortcuts 40 | set -g mode-keys vi 41 | 42 | # Reload the config file with r 43 | bind r source-file ~/.tmux.conf \; display "Reloaded!" 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Santos Gallegos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/init.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "kylechui/nvim-surround", 4 | config = function() 5 | require("nvim-surround").setup({}) 6 | end, 7 | }, 8 | -- TODO: are we using this? 9 | "tpope/vim-repeat", 10 | { 11 | -- Handy bracket mappings 12 | "windwp/nvim-autopairs", 13 | config = function() 14 | require("nvim-autopairs").setup({ 15 | map_c_h = true, 16 | map_cr = false, 17 | -- Disable autopairs when using Snacks' picker 18 | disable_filetype = { "snacks_picker_input" }, 19 | }) 20 | end, 21 | }, 22 | "chaoren/vim-wordmotion", 23 | -- Operator pending mappings ()[]{} 24 | "wellle/targets.vim", 25 | { 26 | -- Jump to any character in the buffer 27 | "ggandor/leap.nvim", 28 | keys = { { "S" }, { "s" } }, 29 | config = function() 30 | require("leap").add_default_mappings() 31 | require("leap").opts.case_sensitive = true 32 | end, 33 | }, 34 | { 35 | "Vimjas/vim-python-pep8-indent", 36 | ft = "python", 37 | }, 38 | { 39 | "stsewd/sphinx.nvim", 40 | build = ":UpdateRemotePlugins", 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /scripts/nvim.sh: -------------------------------------------------------------------------------- 1 | # Install Neovim from nightly release by downloading the precompiled binaries. 2 | 3 | backup=true 4 | dowloaded_file=/tmp/nvim-linux64.tar.gz 5 | backup_dir=/tmp/nvim-backup 6 | 7 | while (( "$#" )); do 8 | case "$1" in 9 | --no-backup) 10 | backup=false 11 | shift 12 | ;; 13 | *) 14 | echo "Invalid argument: $1" 15 | exit 1 16 | ;; 17 | esac 18 | done 19 | 20 | wget -O $dowloaded_file \ 21 | https://github.com/neovim/neovim/releases/download/nightly/nvim-linux-x86_64.tar.gz 22 | 23 | # Was the last command ok? 24 | if [ $? -ne 0 ]; then 25 | echo "Error downloading Neovim" 26 | exit 1 27 | fi 28 | 29 | echo Neovim downloaded 30 | 31 | if [ $backup = true ]; then 32 | echo Backing up old Neovim 33 | mkdir --parents $backup_dir 34 | cp /usr/bin/nvim $backup_dir/bin 35 | cp -r /usr/lib/nvim $backup_dir/lib 36 | cp -r /usr/share/nvim $backup_dir/share 37 | fi 38 | 39 | echo Installing Neovim 40 | # --strip-components=1 removes the first directory from the tarball (nvim-linux64). 41 | sudo tar -xzvf $dowloaded_file -C /usr/ --strip-components=1 42 | echo Neovim installed! 43 | nvim --version 44 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/git.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | -- Show git diff on the numbers column 5 | "lewis6991/gitsigns.nvim", 6 | config = function() 7 | local gitsigns = require("gitsigns") 8 | gitsigns.setup({}) 9 | map("n", "[c", gitsigns.prev_hunk) 10 | map("n", "]c", gitsigns.next_hunk) 11 | map({ "n", "v" }, "hs", ":Gitsigns stage_hunk") 12 | map({ "n", "v" }, "hr", ":Gitsigns reset_hunk") 13 | map("n", "hu", gitsigns.undo_stage_hunk) 14 | map("n", "hp", gitsigns.preview_hunk) 15 | map("n", "hb", function() 16 | gitsigns.blame_line({ full = true }) 17 | end) 18 | map("n", "td", gitsigns.toggle_deleted) 19 | end, 20 | }, 21 | { 22 | -- Git wrapper 23 | "tpope/vim-fugitive", 24 | config = function() 25 | map("n", "gs", ":Git", { silent = true }) 26 | map("n", "ga", ":Gwrite", { silent = true }) 27 | map("n", "gu", ":Gread", { silent = true }) 28 | map("n", "gc", ":Git commit", { silent = true }) 29 | end, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /scripts/kitty.sh: -------------------------------------------------------------------------------- 1 | # Update/install kitty 2 | # https://sw.kovidgoyal.net/kitty/binary/ 3 | curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin launch=n 4 | 5 | BIN_DIR=~/.local/bin/ 6 | mkdir -p $BIN_DIR 7 | ln -sf ~/.local/kitty.app/bin/kitty $BIN_DIR 8 | 9 | # Update the path to the kitty icon and binary in the kitty.desktop file 10 | cp ~/.local/kitty.app/share/applications/kitty.desktop ~/.local/share/applications 11 | KITTY_DESKTOP_FILE=~/.local/share/applications/kitty.desktop 12 | sed -i "s|^Icon=kitty|Icon=/home/$USER/.local/kitty.app/share/icons/hicolor/256x256/apps/kitty.png|g" $KITTY_DESKTOP_FILE 13 | sed -i "s|Exec=kitty|Exec=${BIN_DIR}kitty|g" $KITTY_DESKTOP_FILE 14 | 15 | # Update and set theme. 16 | # https://sw.kovidgoyal.net/kitty/kittens/themes/#auto-color-scheme 17 | mkdir -p ~/.config/kitty/ 18 | kitty +kitten themes --dump-theme 'Tokyo Night Storm' > ~/.config/kitty/dark-theme.auto.conf 19 | kitty +kitten themes --dump-theme 'Solarized Light' > ~/.config/kitty/light-theme.auto.conf 20 | # Overrides 21 | cat config/kitty/dark-theme.auto.conf >> ~/.config/kitty/dark-theme.auto.conf 22 | ln -sf ~/.config/kitty/light-theme.auto.conf ~/.config/kitty/no-preference-theme.auto.conf 23 | -------------------------------------------------------------------------------- /firefox-about.txt: -------------------------------------------------------------------------------- 1 | # about:config 2 | 3 | # Expire cookies after 7 days. 4 | network.cookie.lifetimePolicy = 3 5 | network.cookie.lifetime.days = 5 6 | # TODO: check how to use this option 7 | # network.cookie.maxageCap 8 | 9 | # Show raw punycode to avoid phishing attempts. 10 | network.IDN_show_punycode = true 11 | 12 | # Don't allow websites to prevent use of right-click. 13 | dom.event.contextmenu.enabled = false 14 | 15 | # Don't allow websites to mess up with the clipboard 16 | # Gives problems when pasting in some webs. 17 | # dom.event.clipboardevents.enabled = false 18 | 19 | # Disable website reading how much battery your mobile device or laptop has. 20 | dom.battery.enabled = false 21 | 22 | # Disable 3rd party closed-source Pocket integration. 23 | extensions.pocket.enabled = false 24 | 25 | # Disable preloading of autocomplete URLs. 26 | browser.urlbar.speculativeConnect.enabled = false 27 | 28 | # Disable geolocation. 29 | # geo.enabled = false 30 | 31 | # Disable sending analytics. 32 | # https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon 33 | beacon.enabled = false 34 | 35 | # Disable autofill of forms, you can still see the suggestions once you click on the field. 36 | signon.autofillForms = false 37 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/format.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "stevearc/conform.nvim", 5 | cmd = "ConformInfo", 6 | keys = { "cf" }, 7 | init = function() 8 | vim.o.formatexpr = "v:lua.require'conform'.formatexpr()" 9 | end, 10 | config = function() 11 | local conform = require("conform") 12 | conform.setup({ 13 | formatters_by_ft = { 14 | lua = { "stylua" }, 15 | python = { "isort", "black" }, 16 | rust = { "rustfmt" }, 17 | javascript = { "prettier" }, 18 | html = { "prettier" }, 19 | css = { "prettier" }, 20 | json = { "prettier" }, 21 | yaml = { "prettier" }, 22 | markdown = { "prettier" }, 23 | bash = { "shfmt" }, 24 | sh = { "shfmt" }, 25 | }, 26 | default_format_opts = { 27 | lsp_format = "fallback", 28 | }, 29 | }) 30 | 31 | map("", "cf", function() 32 | if require("conform").format() then 33 | vim.notify("File formatted") 34 | else 35 | vim.notify("No formatter found") 36 | end 37 | end, { desc = "Format current file" }) 38 | end, 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | # vim:ft=kitty 2 | 3 | allow_remote_control yes 4 | 5 | font_family JetBrains Mono Regular 6 | bold_font JetBrains Mono Bold 7 | italic_font JetBrains Mono Italic 8 | bold_italic_font JetBrains Mono Bold Italic 9 | font_size 10 10 | disable_ligatures cursor 11 | 12 | cursor_blink_interval 0 13 | enable_audio_bell no 14 | # Disable Input Method Extension on Wayland. This is typically used 15 | # for inputting text in East Asian languages. However, 16 | # its implementation in Wayland is often buggy and introduces latency 17 | # into the input loop, so disable this if you know you dont need it. 18 | wayland_enable_ime no 19 | # Respect the cursor shape set by kitty. 20 | shell_integration no-cursor 21 | # window_logo_path /path/to/logo.png 22 | 23 | remember_window_size no 24 | initial_window_width 750 25 | initial_window_height 450 26 | 27 | tab_bar_style separator 28 | tab_separator " │ " 29 | tab_switch_strategy last 30 | tab_bar_edge top 31 | 32 | # Mappings 33 | map alt+1 goto_tab 1 34 | map alt+2 goto_tab 2 35 | map alt+3 goto_tab 3 36 | map alt+4 goto_tab 4 37 | map alt+5 goto_tab 5 38 | 39 | map ctrl+shift+t launch --cwd=current --type=tab 40 | 41 | # Show scrollback and last command output in nvim. 42 | map kitty_mod+h launch --stdin-source=@screen_scrollback --type=overlay nvim - 43 | map kitty_mod+g launch --stdin-source=@last_cmd_output --type=overlay nvim - 44 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/nvim-tree.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "nvim-tree/nvim-tree.lua", 5 | cmd = { "NvimTreeToggle", "NvimTreeFindFile" }, 6 | init = function() 7 | map("n", "n", ":NvimTreeToggle", { silent = true }) 8 | map("n", "N", ":NvimTreeFindFile", { silent = true }) 9 | end, 10 | config = function() 11 | require("nvim-tree").setup({ 12 | filters = { 13 | custom = { "^\\.git$", "\\.pyc$", "^\\.venv$", "__pycache__" }, 14 | }, 15 | renderer = { 16 | special_files = {}, 17 | icons = { 18 | show = { 19 | folder_arrow = false, 20 | }, 21 | glyphs = { 22 | default = "", 23 | folder = { 24 | default = "", 25 | open = "", 26 | empty = "", 27 | empty_open = "", 28 | }, 29 | }, 30 | }, 31 | }, 32 | on_attach = function(bufnr) 33 | local api = require("nvim-tree.api") 34 | 35 | -- Default mappings 36 | api.config.mappings.default_on_attach(bufnr) 37 | 38 | -- Custom mappings 39 | local function opts(desc) 40 | return { desc = "nvim-tree: " .. desc, buffer = bufnr, silent = true, nowait = true } 41 | end 42 | map("n", "", api.node.open.no_window_picker, opts("Open: No Window Picker")) 43 | map("n", "<2-LeftMouse>", api.node.open.no_window_picker, opts("Open: No Window Picker")) 44 | end, 45 | }) 46 | 47 | local events = require("nvim-tree.api").events 48 | events.subscribe(events.Event.NodeRenamed, function(data) 49 | Snacks.rename.on_rename_file(data.old_name, data.new_name) 50 | end) 51 | end, 52 | }, 53 | } 54 | -------------------------------------------------------------------------------- /config/nvim/lua/user/utils.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.delete_current_file() 4 | local file = vim.fn.expand("%:p") 5 | -- Unload/close buffer 6 | vim.cmd("bdelete!") 7 | vim.fn.delete(file) 8 | vim.notify("Deleted " .. file) 9 | end 10 | 11 | --- Go to the next/previous git conflict marker. 12 | function M.goto_git_conflict(prev) 13 | prev = prev or false 14 | -- b is for backwards, W is to prevent going back to the first/last line. 15 | local flags = prev and "bW" or "W" 16 | -- Markers can be: `<<<<<<<`, `=======`, `>>>>>>>`. 17 | vim.fn.search("^[<=>|]\\{7}", flags) 18 | end 19 | 20 | --- Go to the next/previous file in the current directory. 21 | function M.goto_file_entry(prev) 22 | prev = prev or false 23 | -- Get the current file name 24 | local current_file = vim.fn.expand("%:p") 25 | local current_dir = vim.fs.dirname(current_file) 26 | 27 | -- Get all the files from the current directory 28 | local files = {} 29 | for filename, type in vim.fs.dir(current_dir) do 30 | if type == "file" then 31 | table.insert(files, filename) 32 | end 33 | end 34 | 35 | table.sort(files) 36 | 37 | -- Get the current file index (lua is 1-based index). 38 | local index = vim.fn.index(files, vim.fs.basename(current_file)) + 1 39 | index = prev and index - 1 or index + 1 40 | if index <= 0 or index > #files then 41 | vim.notify("No more files to go to") 42 | return 43 | end 44 | 45 | local file = vim.fs.joinpath(current_dir, files[index]) 46 | vim.cmd.edit(vim.fn.fnamemodify(file, ":.")) 47 | end 48 | 49 | --- Run a system command asynchronously. 50 | function M.system(cmd, notify_opts) 51 | notify_opts = notify_opts or {} 52 | local onexit = function(result) 53 | local loglevel = result.code == 0 and vim.log.levels.INFO or vim.log.levels.ERROR 54 | 55 | local msg = result.stdout 56 | if result.stderr ~= "" then 57 | msg = msg .. "\n" .. result.stderr 58 | end 59 | vim.notify(msg, loglevel, notify_opts) 60 | end 61 | vim.notify("Running: " .. table.concat(cmd, " "), vim.log.levels.INFO, notify_opts) 62 | vim.system(cmd, { text = true }, vim.schedule_wrap(onexit)) 63 | end 64 | 65 | return M 66 | -------------------------------------------------------------------------------- /config/nvim/lua/user/mappings.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | 3 | vim.g.mapleader = " " 4 | map("n", "w", ":update", { desc = "Save file" }) 5 | map("n", "e", ":e", { desc = "Refresh" }) 6 | map("n", "hh", ":hide", { silent = true, desc = "Hide window" }) 7 | 8 | -- Copy/cut/paste to/from clipboard 9 | map("", "y", '"+y', { desc = "Copy to clipboard" }) 10 | map("", "Y", '"+y$', { desc = "Copy to clipboard" }) 11 | map("", "d", '"+d', { desc = "Cut to clipboard" }) 12 | map("", "D", '"+D', { desc = "Cut to clipboard" }) 13 | map("", "p", '"+p', { desc = "Paste from clipboard" }) 14 | map("", "P", '"+P', { desc = "Paste from clipboard" }) 15 | 16 | -- Scroll 17 | map("n", "", "", { desc = "Scroll up" }) 18 | map("n", "", "", { desc = "Scroll down" }) 19 | map("n", "", "zh", { desc = "Scroll left" }) 20 | map("n", "", "zl", { desc = "Scroll right" }) 21 | 22 | -- Terminal mode mappings 23 | map("t", "", "", { desc = "Exit terminal mode with escape" }) 24 | map("t", "", "", { desc = "Exit terminal mode with escape" }) 25 | map("t", "", "", { desc = "Send escape to the terminal" }) 26 | 27 | -- vim-unimpaired like mappings 28 | map("n", "[n", function() 29 | require("user.utils").goto_git_conflict(true) 30 | end, { desc = "Previous git conflict" }) 31 | map("n", "]n", function() 32 | require("user.utils").goto_git_conflict() 33 | end, { desc = "Next git conflict" }) 34 | 35 | map("n", "[f", function() 36 | require("user.utils").goto_file_entry(true) 37 | end, { desc = "Previous file" }) 38 | map("n", "]f", function() 39 | require("user.utils").goto_file_entry() 40 | end, { desc = "Next file" }) 41 | 42 | map("n", "gp", function() 43 | require("user.utils").system({ "git", "push" }, { title = "Git push", id = "git-push" }) 44 | end, { desc = "Git push" }) 45 | map("n", "gP", function() 46 | require("user.utils").system({ "git", "pull" }, { title = "Git pull", id = "git-pull" }) 47 | end, { desc = "Git pull" }) 48 | 49 | -- Others 50 | map("n", "o", function() 51 | local file_and_line = vim.fn.expand("%:p") .. ":" .. vim.fn.line(".") 52 | vim.fn.setreg("@", file_and_line) 53 | vim.notify("Copied " .. file_and_line) 54 | end, { desc = "Copy current path with line number" }) 55 | -------------------------------------------------------------------------------- /config/nvim/lua/user/commands.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | 3 | vim.cmd("command! U Lazy update") 4 | 5 | -- Remove trailing white spaces 6 | vim.cmd("command! -range=% RemoveTrailing ,s/\\s\\+$//e") 7 | vim.cmd("command! -nargs=+ -complete=file Grep silent grep! cwindow") 8 | 9 | -- Delete the current file 10 | vim.cmd("command! Delete lua require'user.utils'.delete_current_file()") 11 | 12 | vim.api.nvim_create_autocmd("TermOpen", { 13 | group = vim.api.nvim_create_augroup("UserOnTerminalOpen", {}), 14 | pattern = "*", 15 | desc = "Setup terminal window options", 16 | callback = function() 17 | -- Start on insert mode 18 | vim.cmd.startinsert() 19 | -- Execute previous command with 20 | map("n", "", "a", { buffer = true }) 21 | end, 22 | }) 23 | 24 | vim.api.nvim_create_autocmd("TextYankPost", { 25 | group = vim.api.nvim_create_augroup("UserOnTextYankPost", {}), 26 | pattern = "*", 27 | desc = "Highlight on yank", 28 | callback = function() 29 | vim.highlight.on_yank({ timeout = 300 }) 30 | end, 31 | }) 32 | 33 | vim.api.nvim_create_autocmd("OptionSet", { 34 | group = vim.api.nvim_create_augroup("UserOptionSet", {}), 35 | pattern = "background", 36 | desc = "Change colorscheme on background change", 37 | callback = function() 38 | local light = "solarized" 39 | local dark = "tokyonight-storm" 40 | local current = vim.g.colors_name 41 | local new = vim.o.background == "light" and light or dark 42 | if current ~= new then 43 | vim.cmd("colorscheme " .. new) 44 | end 45 | end, 46 | }) 47 | 48 | vim.cmd([[ 49 | " Save current view settings on a per-window, per-buffer basis. 50 | " https://vim.fandom.com/wiki/Avoid_scrolling_when_switch_buffers 51 | function! AutoSaveWinView() 52 | if !exists('w:SavedBufView') 53 | let w:SavedBufView = {} 54 | endif 55 | let w:SavedBufView[bufnr('%')] = winsaveview() 56 | endfunction 57 | 58 | " Restore current view settings. 59 | function! AutoRestoreWinView() 60 | let buf = bufnr('%') 61 | if exists('w:SavedBufView') && has_key(w:SavedBufView, buf) 62 | let v = winsaveview() 63 | let atStartOfFile = v.lnum == 1 && v.col == 0 64 | if atStartOfFile && !&diff 65 | call winrestview(w:SavedBufView[buf]) 66 | endif 67 | unlet w:SavedBufView[buf] 68 | endif 69 | endfunction 70 | 71 | augroup AutoRestoreWinAutoCommand 72 | autocmd! 73 | autocmd BufLeave * call AutoSaveWinView() 74 | autocmd BufEnter * call AutoRestoreWinView() 75 | augroup end 76 | ]]) 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My dotfiles 2 | 3 | - Clone this repo (on your home for example `~/.dotfiles`). 4 | - Make symbolics links of the configuration files you want. 5 | 6 | ## Neovim 7 | 8 | ![1](https://user-images.githubusercontent.com/4975310/236525846-bd3bd8f4-55f3-4be2-8d59-0be68da2a6c3.png) 9 | ![2](https://user-images.githubusercontent.com/4975310/236525835-89f2e10c-cf3e-4018-ac5f-b3253e7765e2.png) 10 | 11 | ### Installation 12 | 13 | - [Install Neovim (nightly version)](https://github.com/neovim/neovim/wiki/Installing-Neovim) 14 | - Make a symbolic link (or just copy the folder) of `config/nvim` to `~/.config/nvim` 15 | - Open neovim, the plugin manager and all plugins will be installed automatically 16 | 17 | ### Test it with Docker 18 | 19 | ```bash 20 | docker run --rm -it -v `pwd`:/src -v $HOME/.local/share/stsewd-nvim/lazy:/root/.local/share/nvim/lazy ghcr.io/stsewd/neovim 21 | ``` 22 | 23 | Open neovim and start coding. 24 | 25 | To update the docker image just run `docker pull ghcr.io/stsewd/neovim` 26 | 27 | ### Configurations 28 | 29 | Check [`config/nvim/`](config/nvim/) for see all the plugins, settings and key-bindings, it's well documented. 30 | 31 | ## Recommended tools 32 | 33 | - [kitty](https://sw.kovidgoyal.net/kitty/) as terminal emulator 34 | - [zsh + ohmyzsh](https://github.com/ohmyzsh/ohmyzsh) as shell 35 | - [Nerd fonts](https://github.com/ryanoasis/nerd-fonts) for a patched font to have nice characters inside Neovim 36 | (I use [JetBrains Mono](https://github.com/ryanoasis/nerd-fonts/blob/master/patched-fonts/JetBrainsMono/Ligatures/Regular/JetBrainsMonoNerdFontMono-Regular.ttf)) 37 | - [JetBrains Mono](https://www.jetbrains.com/lp/mono/) font with ligatures support 38 | - [fzf](https://github.com/junegunn/fzf) for fuzzy search 39 | - [ripgrep](https://github.com/BurntSushi/ripgrep) for recursive search using regular expressions 40 | - [nvm](https://github.com/nvm-sh/nvm) for installing and managing Node versions 41 | - [pyenv](https://github.com/pyenv/pyenv-installer) for installing and managing Python versions 42 | - [hub](https://hub.github.com/) (git wrapper for GitHub) 43 | - [tldr](https://github.com/dbrgn/tealdeer#installing) 44 | 45 | ## After install 46 | 47 | - Create gnome shortcuts: 48 | - Open terminal with ctrl-alt-enter 49 | - Minimize all windows with super-d 50 | - Open file explorer with super-e 51 | - Install the Gnome extensions from [gnome-extensions.txt](gnome-extensions.txt) 52 | - Set the firefox options from [firefox-about.txt](firefox-about.txt) 53 | - Add ssh/gpg keys 54 | - Copy sensitive configs from private gist 55 | - Create additional firefox profiles (scripts/create-firefox-profile.sh) 56 | - Setup yubikey ([yubikey.md](yubikey.md)) 57 | - Setup `gh` and `gh-copilot`: 58 | - `gh auth login` 59 | - `gh extension install github/gh-copilot` 60 | - `:Copilot setup` 61 | -------------------------------------------------------------------------------- /config/nvim/lua/user/options.lua: -------------------------------------------------------------------------------- 1 | -- General 2 | vim.o.title = true 3 | vim.o.mouse = "a" 4 | vim.o.updatetime = 100 5 | vim.o.showmode = false 6 | vim.o.pumblend = 30 7 | vim.o.swapfile = false 8 | vim.o.colorcolumn = "100" 9 | vim.o.scrolloff = 3 10 | vim.opt.diffopt:append("vertical") 11 | vim.opt.spelllang = { "en", "es" } 12 | vim.o.termguicolors = true 13 | -- Recommended by auto-session. 14 | -- Don't save folds, they are calculated on the fly. 15 | vim.o.sessionoptions = "blank,buffers,curdir,help,tabpages,winsize,winpos,terminal,localoptions" 16 | 17 | -- Enable experimental UI for command mode. 18 | -- https://x.com/justinmk/status/1918805272274833443. 19 | -- require('vim._extui').enable({}) 20 | 21 | -- Python provider 22 | -- TODO: Use new autodection method uv tool install pynvim, 23 | -- see :h provider-python. 24 | vim.g.python3_host_prog = vim.env.NVIM_PYTHON_HOST 25 | 26 | -- Lines 27 | vim.o.wrap = false 28 | vim.o.number = true 29 | vim.o.relativenumber = true 30 | vim.o.cursorline = true 31 | 32 | -- Folding 33 | vim.o.foldmethod = "expr" 34 | vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()" 35 | vim.o.foldnestmax = 3 36 | vim.o.foldlevel = 1 37 | vim.o.foldtext = "" 38 | 39 | -- Indentation 40 | vim.o.tabstop = 4 41 | vim.o.shiftwidth = 2 42 | vim.o.softtabstop = 2 43 | vim.o.shiftround = true 44 | vim.o.expandtab = true 45 | 46 | -- Search & replace 47 | vim.o.ignorecase = true 48 | vim.o.smartcase = true 49 | vim.o.gdefault = true 50 | 51 | -- Use rg for :grep 52 | vim.o.grepprg = "rg --vimgrep" 53 | vim.o.grepformat = "%f:%l:%c:%m" 54 | 55 | -- Set up diagnostics. 56 | -- TODO: play with these icons. 57 | -- local signs = { Error = "󰅚 ", Warn = "󰀪 ", Hint = "󰌶 ", Info = " " } 58 | vim.diagnostic.config({ 59 | float = { 60 | -- Don't include a header in the floating window. 61 | header = "", 62 | -- Show bullets only if there is more than one item. 63 | prefix = function(diagnostic, i, total) 64 | return total > 1 and "• " or "" 65 | end, 66 | border = "rounded", 67 | }, 68 | jump = { 69 | on_jump = function(diagnostic, bufnr) 70 | vim.diagnostic.open_float() 71 | end, 72 | }, 73 | -- Use custom signs. 74 | signs = { 75 | text = { 76 | [vim.diagnostic.severity.ERROR] = " ", 77 | [vim.diagnostic.severity.WARN] = " ", 78 | [vim.diagnostic.severity.HINT] = " ", 79 | [vim.diagnostic.severity.INFO] = " ", 80 | }, 81 | }, 82 | }) 83 | 84 | -- Override the default LSP floating preview window to use rounded borders. 85 | local orig_util_open_floating_preview = vim.lsp.util.open_floating_preview 86 | function vim.lsp.util.open_floating_preview(contents, syntax, opts, ...) 87 | opts = opts or {} 88 | opts.border = opts.border or "rounded" 89 | return orig_util_open_floating_preview(contents, syntax, opts, ...) 90 | end 91 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/fzf.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "stsewd/fzf-lua-checkout.nvim", 5 | keys = { 6 | { 7 | "fg", 8 | function() 9 | require("fzf-lua-checkout.list").branches() 10 | end, 11 | desc = "List git branches", 12 | }, 13 | { 14 | "fG", 15 | function() 16 | require("fzf-lua-checkout.list").tags() 17 | end, 18 | desc = "List git tags", 19 | }, 20 | }, 21 | config = function() 22 | require("fzf-lua-checkout").setup() 23 | end, 24 | }, 25 | { 26 | "ibhagwan/fzf-lua", 27 | branch = "main", 28 | keys = { "f" }, 29 | cmd = { "FzfLua" }, 30 | config = function() 31 | local history = vim.fn.stdpath("data") .. "/fzf-lua-history/" 32 | vim.fn.system({ "mkdir", "--parents", history }) 33 | 34 | local fzf = require("fzf-lua") 35 | fzf.setup({ 36 | winopts = { 37 | border = "single", 38 | preview = { 39 | horizontal = "right:45%", 40 | layout = "horizontal", 41 | scrollbar = false, 42 | }, 43 | }, 44 | fzf_opts = { 45 | ["--layout"] = "default", 46 | ["--no-bold"] = "", 47 | ["--pointer"] = "", 48 | ["--marker"] = "+", 49 | ["--prompt"] = " ", 50 | ["--no-separator"] = "", 51 | ["--info"] = "inline: ", 52 | -- History for all commands. 53 | ["--history"] = history .. "all", 54 | }, 55 | keymap = { 56 | builtin = { 57 | [""] = "toggle-help", 58 | [""] = "toggle-fullscreen", 59 | [""] = "toggle-preview-wrap", 60 | [""] = "toggle-preview", 61 | [""] = "preview-page-down", 62 | [""] = "preview-page-up", 63 | }, 64 | }, 65 | previewers = { 66 | builtin = { 67 | extensions = { 68 | ["png"] = { "chafa" }, 69 | ["svg"] = { "chafa" }, 70 | ["jpg"] = { "chafa" }, 71 | }, 72 | }, 73 | }, 74 | files = { 75 | prompt = "  ", 76 | git_icons = false, 77 | fzf_opts = { 78 | ["--history"] = history .. "files", 79 | }, 80 | }, 81 | git = { 82 | branches = { 83 | fzf_opts = { 84 | ["--history"] = history .. "git_branches", 85 | }, 86 | }, 87 | status = { 88 | fzf_opts = { 89 | ["--history"] = history .. "files", 90 | }, 91 | }, 92 | }, 93 | grep = { 94 | git_icons = false, 95 | fzf_opts = { 96 | ["--history"] = history .. "grep", 97 | }, 98 | }, 99 | }) 100 | 101 | -- map("n", "ff", fzf.files) 102 | -- map("n", "fr", function() 103 | -- fzf.grep({ search = "" }) 104 | -- end) 105 | -- map("n", "fR", fzf.grep_project) 106 | -- map("n", "fl", fzf.blines) 107 | -- map("n", "fo", fzf.buffers) 108 | -- map("n", "fs", fzf.git_status) 109 | -- map("n", "fh", fzf.builtin) 110 | -- map("n", "f", fzf.resume) 111 | end, 112 | }, 113 | } 114 | -------------------------------------------------------------------------------- /config/nvim/lazy-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "CopilotChat.nvim": { "branch": "canary", "commit": "451d365928a994cda3505a84905303f790e28df8" }, 3 | "auto-session": { "branch": "main", "commit": "292492ab7af4bd8b9e37e28508bc8ce995722fd5" }, 4 | "blink-cmp-dictionary": { "branch": "master", "commit": "944b3b215b01303672d4213758db7c5c5a1e3c92" }, 5 | "blink.cmp": { "branch": "main", "commit": "b19413d214068f316c78978b08264ed1c41830ec" }, 6 | "conform.nvim": { "branch": "master", "commit": "9b8fa5e0b78168f68bee9bf886dc20f287c61e02" }, 7 | "copilot.vim": { "branch": "release", "commit": "f89e977c87180519ba3b942200e3d05b17b1e2fc" }, 8 | "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, 9 | "fzf-lua": { "branch": "main", "commit": "9d579feab4d3035627150e5e9b6e8fbf5e814ef6" }, 10 | "fzf-lua-checkout.nvim": { "branch": "main", "commit": "e12a49e337e7814b877f82c8451e39cb0717e327" }, 11 | "gitsigns.nvim": { "branch": "main", "commit": "5813e4878748805f1518cee7abb50fd7205a3a48" }, 12 | "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, 13 | "leap.nvim": { "branch": "main", "commit": "f19d43590c4b6d31188ee1ea2954d2b7558a9e11" }, 14 | "lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" }, 15 | "nvim-autopairs": { "branch": "master", "commit": "c2a0dd0d931d0fb07665e1fedb1ea688da3b80b4" }, 16 | "nvim-bufferline.lua": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, 17 | "nvim-lspconfig": { "branch": "master", "commit": "c4f67bf85b01a57e3c130352c0a0e453ab8cd5b9" }, 18 | "nvim-surround": { "branch": "main", "commit": "1098d7b3c34adcfa7feb3289ee434529abd4afd1" }, 19 | "nvim-tree.lua": { "branch": "master", "commit": "eb33612bff2fb31f54946fb5dcadc89e905e81ec" }, 20 | "nvim-treesitter": { "branch": "main", "commit": "4fc09bee78e91bf4ba471cdab4bf9dfa37fde51c" }, 21 | "nvim-treesitter-refactor": { "branch": "master", "commit": "d8b74fa87afc6a1e97b18da23e762efb032dc270" }, 22 | "nvim-treesitter-textobjects": { "branch": "main", "commit": "0d7c800fadcfe2d33089f5726cb8907fc846eece" }, 23 | "nvim-web-devicons": { "branch": "master", "commit": "8dcb311b0c92d460fac00eac706abd43d94d68af" }, 24 | "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, 25 | "schemastore.nvim": { "branch": "main", "commit": "806187c790d93625564708c286e16142d87a5cc9" }, 26 | "sibling-swap.nvim": { "branch": "main", "commit": "75e696c340429769aa34d0bbae1511c8d9660c0b" }, 27 | "snacks.nvim": { "branch": "main", "commit": "fe7cfe9800a182274d0f868a74b7263b8c0c020b" }, 28 | "solarized.nvim": { "branch": "main", "commit": "c0dfe1cbfabd93b546baf5f1408f5df7e02e2050" }, 29 | "sphinx.nvim": { "branch": "master", "commit": "c949f58d0ad6b2a98e31ae877aedbca8620731bb" }, 30 | "spotify.nvim": { "branch": "master", "commit": "38d59e9bcb60bc6ceccbfbc7061b9ac5bee75c53" }, 31 | "targets.vim": { "branch": "master", "commit": "6325416da8f89992b005db3e4517aaef0242602e" }, 32 | "tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" }, 33 | "vim-fugitive": { "branch": "master", "commit": "61b51c09b7c9ce04e821f6cf76ea4f6f903e3cf4" }, 34 | "vim-python-pep8-indent": { "branch": "master", "commit": "60ba5e11a61618c0344e2db190210145083c91f8" }, 35 | "vim-repeat": { "branch": "master", "commit": "65846025c15494983dafe5e3b46c8f88ab2e9635" }, 36 | "vim-sayonara": { "branch": "master", "commit": "75c73f3cf3e96f8c09db5291970243699aadc02c" }, 37 | "vim-wordmotion": { "branch": "master", "commit": "81d9bd298376ab0dc465c85d55afa4cb8d5f47a1" } 38 | } 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | install: 2 | @echo Updating current packages 3 | sudo dnf up --refresh -y 4 | 5 | @echo Installing core packages 6 | sudo dnf install -y \ 7 | openssl \ 8 | openssh-askpass \ 9 | zsh \ 10 | encfs \ 11 | ripgrep \ 12 | fd-find \ 13 | hub \ 14 | direnv \ 15 | bat \ 16 | fzf \ 17 | jq \ 18 | httpie \ 19 | tealdeer \ 20 | tmate \ 21 | gh \ 22 | nmap \ 23 | seahorse \ 24 | pam_yubico \ 25 | git-delta \ 26 | rclone 27 | 28 | # SSH passphrase prompt. 29 | sudo dnf install -y ksshaskpass 30 | 31 | # ExifTool to remove metadata from files/images. 32 | sudo dnf install -y \ 33 | perl-Image-ExifTool \ 34 | ImageMagick 35 | 36 | # Languages 37 | sudo dnf install -y \ 38 | nodejs \ 39 | golang \ 40 | golang-x-tools-gopls \ 41 | ruby \ 42 | ruby-devel \ 43 | clang \ 44 | clang-tools-extra 45 | 46 | # SELinux troubleshooting. 47 | sudo dnf install -y setroubleshoot 48 | # Clipboard provider for Neovim. 49 | sudo dnf install -y wl-clipboard 50 | # Image to ASCII converter (used by Neovim). 51 | sudo dnf install -y chafa 52 | 53 | # Bash LSP dependencies. 54 | sudo dnf install -y shellcheck shfmt 55 | 56 | @echo Installing rpmfusion repos 57 | sudo dnf install -y \ 58 | https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$$(rpm -E %fedora).noarch.rpm \ 59 | https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$$(rpm -E %fedora).noarch.rpm 60 | 61 | @echo Installing additional apps from rpmfusion 62 | sudo dnf install -y \ 63 | gnome-tweak-tool \ 64 | gnome-extensions-app \ 65 | qbittorrent \ 66 | gnome-shell-theme-flat-remix \ 67 | flat-remix-theme \ 68 | vlc 69 | 70 | # Codecs 71 | sudo dnf install -y libavcodec-freeworld 72 | 73 | @echo Installing Proton VPN 74 | ./scripts/protonvpn.sh 75 | 76 | @echo Installing flatpak apps 77 | flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo 78 | flatpak install -y flathub com.spotify.Client 79 | flatpak install -y flathub org.kde.krita 80 | flatpak install -y flathub org.gimp.GIMP 81 | flatpak install -y flathub com.discordapp.Discord 82 | flatpak install -y flathub com.calibre_ebook.calibre 83 | flatpak install -y flathub org.chromium.Chromium 84 | 85 | @echo Install fonts 86 | ./scripts/fonts.sh 87 | 88 | @echo Setup ssh-agent 89 | ./scripts/ssh.sh 90 | 91 | @echo Install kitty 92 | ./scripts/kitty.sh 93 | 94 | @echo Install other apps 95 | ./scripts/docker.sh 96 | ./scripts/nvim.sh --no-backup 97 | ./scripts/rust.sh 98 | ./scripts/node.sh 99 | ./scripts/uv.sh 100 | ./scripts/zsh.sh 101 | ./scripts/luals.sh 102 | ./scripts/marksman.sh 103 | 104 | @echo Installing ruby on rails 105 | gem install rails 106 | 107 | @echo Installing ruby LSP 108 | gem install solargraph 109 | 110 | # Should be called after make install, in a fresh shell. 111 | # Can also be called to update packages. 112 | update: 113 | @echo Updating uv 114 | uv self update 115 | uv tool upgrade --all 116 | 117 | @echo Updating rust packages 118 | cargo install stylua 119 | 120 | @echo Updating node packages 121 | npm update -g 122 | 123 | @echo Updating ruby gems 124 | gem update --system 125 | gem update 126 | 127 | @echo Updating zsh 128 | # https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#how-do-i-update-oh-my-zsh 129 | $(ZSH)/tools/upgrade.sh 130 | 131 | @echo Updating tldr 132 | tldr --update 133 | 134 | @echo Updating rust 135 | rustup self update 136 | rustup component add rust-analyzer 137 | rustup update 138 | 139 | @echo Updating Neovim 140 | ./scripts/nvim.sh 141 | 142 | @echo Updating kitty 143 | ./scripts/kitty.sh 144 | 145 | @echo Updating flatpak apps 146 | flatpak update -y 147 | 148 | @echo Updating gh extensions 149 | gh extension upgrade --all 150 | 151 | symlinks: 152 | ln -sf `pwd`/gitconfig ~/.gitconfig 153 | ln -sf `pwd`/gitignore ~/.gitignore 154 | ln -sf `pwd`/pypirc ~/.pypirc 155 | ln -sf `pwd`/tmux.conf ~/.tmux.conf 156 | ln -sf `pwd`/tmate.conf ~/.tmate.conf 157 | ln -sf `pwd`/zshrc ~/.zshrc 158 | mkdir -p ~/.ssh/ 159 | ln -sf `pwd`/ssh.config ~/.ssh/config 160 | ln -sf `pwd`/config/gdb/ ~/.config/ 161 | ln -sf `pwd`/config/nvim/ ~/.config/ 162 | ln -sf `pwd`/config/bat/ ~/.config/ 163 | ln -sf `pwd`/config/kitty/kitty.conf ~/.config/kitty/kitty.conf 164 | mkdir -p ~/.gnupg/ 165 | ln -sf `pwd`/gnupg/gpg-agent.conf ~/.gnupg/gpg-agent.conf 166 | rm -rf ~/.local/share/nautilus/scripts/ 167 | ln -sf `pwd`/local/share/nautilus/scripts/ ~/.local/share/nautilus/ 168 | 169 | .PHONY: install symlinks update 170 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/snacks.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "folke/snacks.nvim", 5 | priority = 1000, 6 | lazy = false, 7 | opts = { 8 | -- Disable some plugins when opening a big file. 9 | bigfile = { enabled = true }, 10 | -- vim.notify implementation. 11 | notifier = { enabled = true }, 12 | -- Load content as quickly as possible when opening a single file. 13 | quickfile = { enabled = true }, 14 | input = { enabled = true }, 15 | -- Display images when opening an image file, or in markdown files. 16 | image = { 17 | enabled = true, 18 | doc = { 19 | inline = false, 20 | float = false, 21 | }, 22 | }, 23 | gitbrowse = { 24 | notify = false, 25 | -- Add an extra filename pattern to open just the file without the line. 26 | url_patterns = { 27 | ["github%.com"] = { 28 | filename = "/blob/{branch}/{file}", 29 | }, 30 | ["gitlab%.com"] = { 31 | filename = "/-/blob/{branch}/{file}", 32 | }, 33 | ["bitbucket%.org"] = { 34 | filename = "/src/{branch}/{file}", 35 | }, 36 | }, 37 | }, 38 | -- Show indentation lines. 39 | indent = { 40 | indent = { 41 | char = "▏", 42 | }, 43 | scope = { 44 | enabled = false, 45 | }, 46 | }, 47 | picker = { 48 | win = { 49 | input = { 50 | keys = { 51 | [""] = { "history_back", mode = { "i", "n" } }, 52 | [""] = { "history_forward", mode = { "i", "n" } }, 53 | }, 54 | }, 55 | }, 56 | }, 57 | styles = { 58 | input = { 59 | relative = "cursor", 60 | }, 61 | }, 62 | }, 63 | init = function() 64 | vim.api.nvim_create_autocmd("User", { 65 | pattern = "VeryLazy", 66 | callback = function() 67 | -- Create toggle mappings 68 | Snacks.toggle.option("wrap", { name = "Wrap" }):map("uw") 69 | Snacks.toggle.option("spell", { name = "Spell" }):map("us") 70 | Snacks.toggle.diagnostics():map("ud") 71 | 72 | -- Add a :Notifications command to show the notifications history. 73 | vim.cmd("command! Notifications lua Snacks.picker.notifications()") 74 | 75 | map("v", "go", function() 76 | Snacks.gitbrowse() 77 | end, { desc = "Git browse" }) 78 | map("n", "go", function() 79 | Snacks.gitbrowse({ what = "filename" }) 80 | -- TODO: check if we are okay to always open with the current line. 81 | -- Snacks.gitbrowse() 82 | end, { desc = "Git browse" }) 83 | 84 | map("n", "gK", function() 85 | Snacks.image.hover() 86 | end, { desc = "Show image" }) 87 | 88 | -- Picker mappings 89 | map("n", "fh", function() 90 | Snacks.picker.pickers() 91 | end, { desc = "Builtin" }) 92 | map("n", "f", function() 93 | Snacks.picker.resume() 94 | end, { desc = "Resume" }) 95 | 96 | -- File picker mappings 97 | map("n", "ff", function() 98 | Snacks.picker.files({ hidden = true }) 99 | end, { desc = "Files" }) 100 | map("n", "fo", function() 101 | Snacks.picker.buffers() 102 | end, { desc = "Buffers" }) 103 | map("n", "ft", function() 104 | Snacks.picker.smart({ hidden = true }) 105 | end, { desc = "Files" }) 106 | map("n", "fl", function() 107 | Snacks.picker.lines() 108 | end, { desc = "Buffer lines" }) 109 | 110 | -- Grep picker mappings 111 | map("n", "fr", function() 112 | Snacks.picker.grep({ hidden = true }) 113 | end, { desc = "Grep" }) 114 | map("n", "fw", function() 115 | Snacks.picker.grep_word({ hidden = true }) 116 | end, { desc = "Grep" }) 117 | map("n", "fR", function() 118 | Snacks.picker.grep({ need_search = false, live = false, hidden = true }) 119 | end, { desc = "Grep all files" }) 120 | 121 | -- Git picker mappings 122 | map("n", "fs", function() 123 | Snacks.picker.git_status() 124 | end, { desc = "Git status" }) 125 | 126 | -- LSP picker mappings 127 | map("n", "fd", function() 128 | Snacks.picker.diagnostics_buffer() 129 | end, { desc = "Buffer diagnostics" }) 130 | map("n", "fD", function() 131 | Snacks.picker.diagnostics() 132 | end, { desc = "Diagnostics" }) 133 | map("n", "g", function() 134 | Snacks.picker.lsp_definitions() 135 | end, { desc = "Definitions" }) 136 | map("n", "grr", function() 137 | Snacks.picker.lsp_references() 138 | end, { desc = "References" }) 139 | 140 | -- Plugin picker mappings 141 | map("n", "fp", function() 142 | Snacks.picker.lazy() 143 | end, { desc = "Plugins" }) 144 | end, 145 | }) 146 | end, 147 | }, 148 | } 149 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/autocompletion.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "neovim/nvim-lspconfig", 4 | -- Is required to start this plugin at startup. 5 | lazy = false, 6 | dependencies = { 7 | -- Schemas for the JSON LSP. 8 | { "b0o/schemastore.nvim" }, 9 | }, 10 | config = function() 11 | vim.lsp.config("jsonls", { 12 | settings = { 13 | json = { 14 | schemas = require("schemastore").json.schemas(), 15 | validate = { enable = true }, 16 | }, 17 | }, 18 | }) 19 | vim.lsp.config("rust_analyzer", { 20 | settings = { 21 | ["rust-analyzer"] = { 22 | check = { 23 | command = "clippy", 24 | }, 25 | }, 26 | }, 27 | }) 28 | vim.lsp.config("lua_ls", { 29 | on_init = function(client) 30 | -- Set up the Lua language server to use the runtime files for Neovim 31 | -- Taken from https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#lua_ls. 32 | if client.workspace_folders then 33 | local path = client.workspace_folders[1].name 34 | local is_dotifiles = path:match("/dotfiles$") 35 | local has_luarc = vim.uv.fs_stat(path .. "/.luarc.json") or vim.uv.fs_stat(path .. "/.luarc.jsonc") 36 | if not is_dotifiles and has_luarc then 37 | return 38 | end 39 | end 40 | 41 | client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, { 42 | -- The engine that Neovim uses. 43 | runtime = { 44 | version = "LuaJIT", 45 | }, 46 | -- Make the server aware of Neovim runtime files. 47 | workspace = { 48 | checkThirdParty = false, 49 | library = { 50 | vim.env.VIMRUNTIME, 51 | }, 52 | }, 53 | }) 54 | end, 55 | settings = { 56 | Lua = {}, 57 | }, 58 | }) 59 | 60 | vim.lsp.enable({ 61 | "pyright", 62 | "html", 63 | "cssls", 64 | "eslint", 65 | "ts_ls", 66 | "jsonls", 67 | "yamlls", 68 | "clangd", 69 | "bashls", 70 | "marksman", 71 | -- NOTE: esbonio should be installed on each project. 72 | "esbonio", 73 | -- PHP 74 | "intelephense", 75 | "gopls", 76 | "rust_analyzer", 77 | "lua_ls", 78 | }) 79 | end, 80 | }, 81 | { 82 | "saghen/blink.cmp", 83 | dependencies = { 84 | -- Provides snippets for the snippet source 85 | "rafamadriz/friendly-snippets", 86 | { 87 | "Kaiser-Yang/blink-cmp-dictionary", 88 | dependencies = { "nvim-lua/plenary.nvim" }, 89 | }, 90 | }, 91 | -- use a release tag to download pre-built binaries 92 | version = "*", 93 | -- Load the first time we get into insert mode. 94 | -- We don't need this plugin to be loaded at startup. 95 | event = "InsertEnter", 96 | config = function() 97 | require("blink.cmp").setup({ 98 | keymap = { 99 | preset = "enter", 100 | }, 101 | completion = { 102 | documentation = { auto_show = true, auto_show_delay_ms = 50 }, 103 | menu = { 104 | draw = { 105 | columns = { 106 | { "label", "label_description", gap = 1 }, 107 | { "kind_icon", gap = 1, "kind" }, 108 | }, 109 | }, 110 | }, 111 | }, 112 | sources = { 113 | -- Add 'dictionary' to the list 114 | default = { "lsp", "path", "snippets", "buffer", "dictionary" }, 115 | -- default = { "lsp", "path", "snippets", "buffer" }, 116 | -- -- Dowlonad dictionary for cmp-dictionary. 117 | -- local data_dir = vim.fn.stdpath("data") .. "/cmp-dictionary" 118 | -- local url = "https://github.com/neoclide/coc-sources/raw/refs/heads/master/packages/word/10k.txt" 119 | -- local dictionary_path = data_dir .. "/10k.txt" 120 | -- if vim.fn.filereadable(dictionary_path) == 0 then 121 | -- vim.system({ "mkdir", "-p", data_dir }):wait() 122 | -- vim.system({ "wget", "-O", dictionary_path, url }):wait() 123 | -- end 124 | 125 | providers = { 126 | dictionary = { 127 | module = "blink-cmp-dictionary", 128 | name = "Dict", 129 | -- Make sure this is at least 2. 130 | -- 3 is recommended 131 | min_keyword_length = 2, 132 | max_items = 10, 133 | opts = { 134 | -- options for blink-cmp-dictionary 135 | dictionary_files = { vim.fn.stdpath("data") .. "/cmp-dictionary/10k.txt" }, 136 | get_documentation = function(item) 137 | return nil 138 | end, 139 | }, 140 | }, 141 | }, 142 | }, 143 | cmdline = { 144 | enabled = true, 145 | completion = { 146 | menu = { auto_show = true }, 147 | list = { 148 | selection = { 149 | preselect = false, 150 | }, 151 | }, 152 | }, 153 | }, 154 | }) 155 | end, 156 | }, 157 | } 158 | -------------------------------------------------------------------------------- /zshrc: -------------------------------------------------------------------------------- 1 | # If you come from bash you might have to change your $PATH. 2 | export PATH=$HOME/dotfiles/bin:$HOME/.local/bin:$HOME/bin:$PATH 3 | 4 | # Path to your oh-my-zsh installation. 5 | export ZSH=$HOME/.oh-my-zsh 6 | 7 | export EDITOR=nvim 8 | export USE_EDITOR=$EDITOR 9 | export VISUAL=$EDITOR 10 | 11 | # Set name of the theme to load --- if set to "random", it will 12 | # load a random theme each time oh-my-zsh is loaded, in which case, 13 | # to know which specific one was loaded, run: echo $RANDOM_THEME 14 | # See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes 15 | ZSH_THEME="amuse" 16 | 17 | # Set list of themes to pick from when loading at random 18 | # Setting this variable when ZSH_THEME=random will cause zsh to load 19 | # a theme from this variable instead of looking in ~/.oh-my-zsh/themes/ 20 | # If set to an empty array, this variable will have no effect. 21 | # ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) 22 | 23 | # Uncomment the following line to use case-sensitive completion. 24 | # CASE_SENSITIVE="true" 25 | 26 | # Uncomment the following line to use hyphen-insensitive completion. 27 | # Case-sensitive completion must be off. _ and - will be interchangeable. 28 | # HYPHEN_INSENSITIVE="true" 29 | 30 | # Uncomment the following line to disable bi-weekly auto-update checks. 31 | # DISABLE_AUTO_UPDATE="true" 32 | 33 | # Uncomment the following line to automatically update without prompting. 34 | # DISABLE_UPDATE_PROMPT="true" 35 | 36 | # Uncomment the following line to change how often to auto-update (in days). 37 | export UPDATE_ZSH_DAYS=7 38 | 39 | # Uncomment the following line if pasting URLs and other text is messed up. 40 | # DISABLE_MAGIC_FUNCTIONS=true 41 | 42 | # Uncomment the following line to disable colors in ls. 43 | # DISABLE_LS_COLORS="true" 44 | 45 | # Uncomment the following line to disable auto-setting terminal title. 46 | # DISABLE_AUTO_TITLE="true" 47 | 48 | # Uncomment the following line to enable command auto-correction. 49 | # ENABLE_CORRECTION="true" 50 | 51 | # Uncomment the following line to display red dots whilst waiting for completion. 52 | COMPLETION_WAITING_DOTS="true" 53 | 54 | # Uncomment the following line if you want to disable marking untracked files 55 | # under VCS as dirty. This makes repository status check for large repositories 56 | # much, much faster. 57 | # DISABLE_UNTRACKED_FILES_DIRTY="true" 58 | 59 | # Uncomment the following line if you want to change the command execution time 60 | # stamp shown in the history command output. 61 | # You can set one of the optional three formats: 62 | # "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" 63 | # or set a custom format using the strftime function format specifications, 64 | # see 'man strftime' for details. 65 | # HIST_STAMPS="mm/dd/yyyy" 66 | 67 | # Would you like to use another custom folder than $ZSH/custom? 68 | # ZSH_CUSTOM=/path/to/new-custom-folder 69 | 70 | # Which plugins would you like to load? 71 | # Standard plugins can be found in ~/.oh-my-zsh/plugins/* 72 | # Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/ 73 | # Example format: plugins=(rails git textmate ruby lighthouse) 74 | # Add wisely, as too many plugins slow down shell startup. 75 | plugins=( 76 | git 77 | fzf 78 | docker 79 | github 80 | rust 81 | safe-paste 82 | zsh-completions 83 | zsh-syntax-highlighting 84 | ) 85 | 86 | source $ZSH/oh-my-zsh.sh 87 | 88 | autoload -U compinit && compinit 89 | 90 | # ** User configuration ** 91 | 92 | # You may need to manually set your language environment 93 | # export LANG=en_US.UTF-8 94 | 95 | # Preferred editor for local and remote sessions 96 | # if [[ -n $SSH_CONNECTION ]]; then 97 | # export EDITOR='vim' 98 | # else 99 | # export EDITOR='mvim' 100 | # fi 101 | 102 | # Shorter history 103 | export SAVEHIST=1000 104 | export HISTSIZE=$SAVEHIST 105 | 106 | 107 | # Python 108 | alias p='uv run -- python' 109 | alias pp='uv run -- ipython' 110 | 111 | 112 | # Direnv integration 113 | eval "$(direnv hook zsh)" 114 | 115 | 116 | # Integration with fzf 117 | export FZF_DEFAULT_COMMAND='fd --type=file --hidden --exclude=.git' 118 | FZF_DEFAULT_OPTS='--bind=ctrl-space:toggle-preview --bind=ctrl-d:preview-down --bind=ctrl-f:preview-up' 119 | FZF_DEFAULT_OPTS+=' --no-bold --pointer="" --marker="+" --no-separator --info="inline: " --layout=default --prompt=" "' 120 | export FZF_DEFAULT_OPTS 121 | 122 | 123 | # Neovim 124 | export NVIM_PYTHON_HOST=~/.local/share/nvim/.venv/bin/python 125 | 126 | 127 | # nvm 128 | # nvm slows down shell startup, do I really use it? 129 | export NVM_DIR="$HOME/.nvm" 130 | # Witout this it takes 255.23ms 131 | # With this, it takes 312.37ms 132 | # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use # This loads nvm 133 | # With this, it takes 349.82ms 134 | # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm 135 | 136 | # Node/npm 137 | NPM_PACKAGES="${HOME}/.npm-packages" 138 | export PATH="$PATH:$NPM_PACKAGES/bin" 139 | 140 | # Utils 141 | # Check memory usage 142 | alias psmem="ps aux | awk '{print \$6/1024 \" MB\\t\\t\" \$11}' | sort -n" 143 | alias cat=bat 144 | alias ts=tree-sitter 145 | alias up='sudo dnf up --refresh -y' 146 | alias clear-meta='exiftool -overwrite_original -ALL= ' 147 | alias ls='ls --color=auto --hyperlink=auto' 148 | 149 | 150 | # Kitty 151 | alias icat="kitty +kitten icat" 152 | # Completion for kitty 153 | kitty + complete setup zsh | source /dev/stdin 154 | 155 | export BACKGROUND=dark 156 | 157 | # SSH 158 | # Make ssh compatible with kitty 159 | alias ssh="TERM=xterm-256color ssh" 160 | # ssh-agent 161 | export SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/ssh-agent.socket 162 | 163 | # delta 164 | export DELTA_FEATURES=+$BACKGROUND 165 | 166 | # lua-language-server 167 | export PATH="/$HOME/lua-language-server/bin:$PATH" 168 | 169 | # Rust/cargo 170 | . "$HOME/.cargo/env" 171 | -------------------------------------------------------------------------------- /config/nvim/lua/user/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | local map = vim.keymap.set 2 | return { 3 | { 4 | "nvim-treesitter/nvim-treesitter", 5 | branch = "main", 6 | build = ":TSUpdate", 7 | config = function() 8 | require("nvim-treesitter").install({ 9 | -- The usual suspects 10 | "html", 11 | "css", 12 | "scss", -- SASS 13 | "javascript", 14 | "jsdoc", 15 | "typescript", 16 | "tsx", 17 | "lua", 18 | "luadoc", 19 | "luap", -- Lua patterns 20 | "python", 21 | "rust", 22 | "c", 23 | "cpp", 24 | "make", 25 | "cmake", 26 | "bash", 27 | "sql", 28 | "vim", 29 | 30 | -- Config files 31 | "dockerfile", 32 | "ini", 33 | "json", 34 | "jsonc", 35 | "toml", 36 | "yaml", 37 | 38 | -- Treesitter 39 | "comment", 40 | "query", 41 | 42 | -- Markup 43 | "markdown", 44 | "markdown_inline", 45 | "rst", 46 | "vimdoc", 47 | 48 | -- Just in case 49 | "dart", 50 | "go", 51 | "ruby", 52 | "graphql", 53 | "java", 54 | "kotlin", 55 | "latex", 56 | "php", 57 | "phpdoc", 58 | "terraform", 59 | "hcl", 60 | 61 | -- Git 62 | "git_config", 63 | "git_rebase", 64 | "gitattributes", 65 | "gitcommit", 66 | "gitignore", 67 | }) 68 | vim.api.nvim_create_autocmd("FileType", { 69 | pattern = "*", 70 | callback = function() 71 | -- Check if the buffer is loaded 72 | if not vim.api.nvim_buf_is_loaded(0) then 73 | return 74 | end 75 | local tree, _ = vim.treesitter.get_parser(0, nil, {error = false}) 76 | if tree then 77 | -- syntax highlighting, provided by Neovim 78 | vim.treesitter.start() 79 | end 80 | end, 81 | }) 82 | vim.api.nvim_create_autocmd("FileType", { 83 | pattern = { "lua", "rust", "javascript", "zig", "python" }, 84 | callback = function() 85 | -- folds, provided by Neovim 86 | -- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()' 87 | -- -- indentation, provided by nvim-treesitter 88 | -- vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" 89 | end, 90 | }) 91 | end, 92 | }, 93 | { 94 | "nvim-treesitter/nvim-treesitter-refactor", 95 | enabled = false, 96 | keys = { { "grnn" }, { "gd" } }, 97 | config = function() 98 | require("nvim-treesitter.configs").setup({ 99 | refactor = { 100 | highlight_definitions = { 101 | enable = true, 102 | clear_on_cursor_move = false, 103 | }, 104 | smart_rename = { 105 | enable = true, 106 | keymaps = { 107 | smart_rename = "grnn", 108 | }, 109 | }, 110 | navigation = { 111 | enable = true, 112 | keymaps = { 113 | goto_definition = "gd", 114 | }, 115 | }, 116 | }, 117 | }) 118 | end, 119 | }, 120 | { 121 | "nvim-treesitter/nvim-treesitter-textobjects", 122 | branch = "main", 123 | config = function() 124 | require("nvim-treesitter-textobjects").setup({ 125 | move = { 126 | set_jumps = true, 127 | }, 128 | select = { 129 | lookahead = true, 130 | }, 131 | }) 132 | -- Move to next/previous function/class 133 | map({ "n", "x", "o" }, "]m", function() 134 | require("nvim-treesitter-textobjects.move").goto_next_start("@function.outer", "textobjects") 135 | end) 136 | map({ "n", "x", "o" }, "]]", function() 137 | require("nvim-treesitter-textobjects.move").goto_next_start("@class.outer", "textobjects") 138 | end) 139 | 140 | map({ "n", "x", "o" }, "]M", function() 141 | require("nvim-treesitter-textobjects.move").goto_next_end("@function.outer", "textobjects") 142 | end) 143 | map({ "n", "x", "o" }, "][", function() 144 | require("nvim-treesitter-textobjects.move").goto_next_end("@class.outer", "textobjects") 145 | end) 146 | 147 | map({ "n", "x", "o" }, "[m", function() 148 | require("nvim-treesitter-textobjects.move").goto_previous_start("@function.outer", "textobjects") 149 | end) 150 | map({ "n", "x", "o" }, "[[", function() 151 | require("nvim-treesitter-textobjects.move").goto_previous_start("@class.outer", "textobjects") 152 | end) 153 | 154 | map({ "n", "x", "o" }, "[M", function() 155 | require("nvim-treesitter-textobjects.move").goto_previous_end("@function.outer", "textobjects") 156 | end) 157 | map({ "n", "x", "o" }, "[]", function() 158 | require("nvim-treesitter-textobjects.move").goto_previous_end("@class.outer", "textobjects") 159 | end) 160 | 161 | -- Select text objects 162 | map({ "x", "o" }, "af", function() 163 | require("nvim-treesitter-textobjects.select").select_textobject("@function.outer", "textobjects") 164 | end) 165 | map({ "x", "o" }, "if", function() 166 | require("nvim-treesitter-textobjects.select").select_textobject("@function.inner", "textobjects") 167 | end) 168 | map({ "x", "o" }, "ac", function() 169 | require("nvim-treesitter-textobjects.select").select_textobject("@class.outer", "textobjects") 170 | end) 171 | map({ "x", "o" }, "ic", function() 172 | require("nvim-treesitter-textobjects.select").select_textobject("@class.inner", "textobjects") 173 | end) 174 | end, 175 | }, 176 | { 177 | "Wansmer/sibling-swap.nvim", 178 | keys = { { "," }, { "." } }, 179 | config = function() 180 | require("sibling-swap").setup({}) 181 | end, 182 | }, 183 | } 184 | --------------------------------------------------------------------------------