diff --git a/install.sh b/install.sh index b5934ea..237663c 100755 --- a/install.sh +++ b/install.sh @@ -49,10 +49,23 @@ command_exists() { command -v "$@" >/dev/null 2>&1 } +require_command() { + command_name=$1 + + if ! command_exists "$command_name"; then + error "$command_name is required but not installed. Install it first via your package manager." + exit 1 + fi +} + error() { echo ${RED}"Error: $@"${RESET} >&2 } +skip() { + echo "${YELLOW}Skipping $1${RESET}" +} + setup_color() { # Only use colors if connected to a terminal if [ -t 1 ]; then @@ -75,28 +88,36 @@ setup_color() { apply_dotfiles() { echo "${BLUE}Applying dotfiles...${RESET}" - if ! command_exists lsd; then - error "lsd is required but not installed. Install it first via your package manager." - exit 1 - fi - if ! command_exists tmux; then - error "tmux is required but not installed. Install it first via your package manager." - exit 1 - fi + require_command lsd + require_command tmux + require_command nvim + require_command rg + remove_legacy_dotfile "$HOME/.vimrc" link_dotfile "$DOTFILES_DIR/.zshrc" "$HOME/.zshrc" - link_dotfile "$DOTFILES_DIR/.vimrc" "$HOME/.vimrc" link_dotfile "$DOTFILES_DIR/.zprofile" "$HOME/.zprofile" link_dotfile "$DOTFILES_DIR/.gitconfig" "$HOME/.gitconfig" link_dotfile "$DOTFILES_DIR/.p10k.zsh" "$HOME/.p10k.zsh" mkdir -p "$HOME/.config" + link_dotfile "$DOTFILES_DIR/kitty" "$HOME/.config/kitty" + link_dotfile "$DOTFILES_DIR/nvim" "$HOME/.config/nvim" link_dotfile "$DOTFILES_DIR/tmux" "$HOME/.config/tmux" + install_kitty_icon install_tmux_plugins install_powerlevel10k echo } +remove_legacy_dotfile() { + target_path=$1 + + if [ -L "$target_path" ] || [ -e "$target_path" ]; then + echo "${YELLOW}Removing legacy $target_path${RESET}" + rm -rf "$target_path" + fi +} + replace_dir() { source_path=$1 target_path=$2 @@ -128,6 +149,36 @@ link_dotfile() { echo "${GREEN}Linked $target_path -> $source_path${RESET}" } +install_kitty_icon() { + icon_path="$DOTFILES_DIR/kitty/kitty.app.png" + + if [ "$(uname -s)" != "Darwin" ]; then + return + fi + + if ! command_exists kitty; then + skip "kitty icon setup: kitty is not installed." + return + fi + + if [ ! -d /Applications/kitty.app ]; then + skip "kitty icon setup: /Applications/kitty.app was not found." + return + fi + + if [ ! -f "$icon_path" ]; then + skip "kitty icon setup: $icon_path was not found." + return + fi + + echo "${BLUE}Applying custom kitty icon...${RESET}" + + kitty +runpy 'from kitty.fast_data_types import cocoa_set_app_icon; import sys; cocoa_set_app_icon(*sys.argv[1:]); print("OK")' \ + "$icon_path" /Applications/kitty.app + + echo +} + install_tmux_plugins() { echo "${BLUE}Installing tmux plugins...${RESET}" diff --git a/kitty/kitty.app.png b/kitty/kitty.app.png new file mode 100644 index 0000000..b6fe118 Binary files /dev/null and b/kitty/kitty.app.png differ diff --git a/kitty/kitty.conf b/kitty/kitty.conf new file mode 100644 index 0000000..304bc85 --- /dev/null +++ b/kitty/kitty.conf @@ -0,0 +1,15 @@ +font_family family="JetbrainsMono Nerd Font Mono" +bold_font auto +italic_font auto +bold_italic_font auto + +font_size 14 +adjust_line_height 125% +cursor_blink_interval 0 +enable_audio_bell 0 +hide_window_decorations titlebar-only +macos_show_window_title_in none +macos_titlebar_color background +map ctrl+left previous_tab +map ctrl+right next_tab +window_padding_width 10 diff --git a/nvim/init.lua b/nvim/init.lua new file mode 100644 index 0000000..6774fc1 --- /dev/null +++ b/nvim/init.lua @@ -0,0 +1,4 @@ +vim.g.mapleader = " " +vim.g.maplocalleader = " " + +require("tracer") diff --git a/nvim/lua/tracer/init.lua b/nvim/lua/tracer/init.lua new file mode 100644 index 0000000..0e8e62f --- /dev/null +++ b/nvim/lua/tracer/init.lua @@ -0,0 +1,4 @@ +require("tracer.options") +require("tracer.plugins") +pcall(require, "tracer.plugins.telescope") +require("tracer.statusline") diff --git a/nvim/lua/tracer/options.lua b/nvim/lua/tracer/options.lua new file mode 100644 index 0000000..cca1497 --- /dev/null +++ b/nvim/lua/tracer/options.lua @@ -0,0 +1,49 @@ +local opt = vim.opt + +opt.number = true +opt.cursorline = true +opt.ignorecase = true +opt.laststatus = 2 +opt.termguicolors = true +opt.autoread = true +opt.mouse = "a" +opt.expandtab = true +opt.shiftwidth = 4 +opt.tabstop = 4 +opt.softtabstop = 4 +opt.smartindent = true +opt.wrap = false +opt.wildmode = "longest:full,full" +opt.title = true + +vim.cmd.colorscheme("slate") + +local normalfloat_hl = vim.api.nvim_get_hl(0, { name = "NormalFloat", link = false }) +if normalfloat_hl.bg then + vim.api.nvim_set_hl(0, "FloatBorder", { + fg = normalfloat_hl.bg, + bg = normalfloat_hl.bg, + }) +end + +local cursorline_hl = vim.api.nvim_get_hl(0, { name = "CursorLine", link = false }) +if cursorline_hl.bg then + vim.api.nvim_set_hl(0, "CursorLineBg", { + fg = cursorline_hl.bg, + bg = cursorline_hl.bg, + }) +end + +local autoread_group = vim.api.nvim_create_augroup("tracer_autoread", { clear = true }) + +vim.api.nvim_create_autocmd({ "FocusGained", "TermClose", "TermLeave", "BufEnter" }, { + group = autoread_group, + command = "checktime", +}) + +vim.api.nvim_create_autocmd("FileChangedShellPost", { + group = autoread_group, + callback = function() + vim.notify("File changed on disk. Buffer reloaded.", vim.log.levels.INFO) + end, +}) diff --git a/nvim/lua/tracer/plugins.lua b/nvim/lua/tracer/plugins.lua new file mode 100644 index 0000000..a7f3a86 --- /dev/null +++ b/nvim/lua/tracer/plugins.lua @@ -0,0 +1,134 @@ +local ensure_packer = function() + local fn = vim.fn + local install_path = fn.stdpath("data") .. "/site/pack/packer/start/packer.nvim" + + if fn.empty(fn.glob(install_path)) > 0 then + fn.system({ "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path }) + vim.cmd([[packadd packer.nvim]]) + return true + end + + return false +end + +local packer_bootstrap = ensure_packer() + +require("packer").reset() +vim.g.polyglot_disabled = { "autoindent" } + +require("packer").init({ + compile_path = vim.fn.stdpath("data") .. "/site/plugin/packer_compiled.lua", + display = { + open_fn = function() + return require("packer.util").float({ border = "solid" }) + end, + }, +}) + +require("packer").startup(function(use) + use("wbthomason/packer.nvim") + + -- My plugins here + -- Commenting support. + use("tpope/vim-commentary") + -- Add, change, and delete surrounding text. + use("tpope/vim-surround") + -- Useful commands like :Rename and :SudoWrite. + use("tpope/vim-eunuch") + -- Pairs of handy bracket mappings, like [b and ]b. + use("tpope/vim-unimpaired") + -- Indent autodetection with editorconfig support. + use("tpope/vim-sleuth") + -- Allow plugins to enable repeating of commands. + use("tpope/vim-repeat") + -- Add more languages. + use("sheerun/vim-polyglot") + -- Navigate seamlessly between Vim windows and Tmux panes. + use("christoomey/vim-tmux-navigator") + -- Jump to the last location when opening a file. + use("farmergreg/vim-lastplace") + -- Enable * searching with visually selected text. + use("nelstrom/vim-visual-star-search") + -- Automatically create parent dirs when saving. + use("jessarcher/vim-heritage") + -- Text objects for HTML attributes. + use({ + "whatyouhide/vim-textobj-xmlattr", + requires = "kana/vim-textobj-user", + }) + -- Automatically set the working directory to the project root. + use({ + "airblade/vim-rooter", + setup = function() + -- Instead of this running every time we open a file, we'll just run it once when Vim starts. + vim.g.rooter_manual_only = 1 + end, + config = function() + vim.cmd("Rooter") + end, + }) + -- Automatically add closing brackets, quotes, etc. + use({ + "windwp/nvim-autopairs", + config = function() + require("nvim-autopairs").setup() + end, + }) + -- Add smooth scrolling to avoid jarring jumps + use({ + "karb94/neoscroll.nvim", + config = function() + require("neoscroll").setup() + end, + }) + -- All closing buffers without closing the split window. + use({ + "famiu/bufdelete.nvim", + config = function() + vim.keymap.set("n", "q", ":Bdelete") + end, + }) + -- Split arrays and methods onto multiple lines, or join them back up. + use({ + "AndrewRadev/splitjoin.vim", + config = function() + vim.g.splitjoin_html_attributes_bracket_on_new_line = 1 + vim.g.splitjoin_trailing_comma = 1 + vim.g.splitjoin_php_method_chain_full = 1 + end, + }) + -- Automatically fix indentation when pasting code. + use({ + "sickill/vim-pasta", + config = function() + vim.g.pasta_disabled_filetypes = { "fugitive" } + end, + }) + + -- Fuzzy finder + use({ + "nvim-telescope/telescope.nvim", + requires = { + "nvim-lua/plenary.nvim", + "kyazdani42/nvim-web-devicons", + "nvim-telescope/telescope-live-grep-args.nvim", + { "nvim-telescope/telescope-fzf-native.nvim", run = "make" }, + }, + config = function() + require("tracer.plugins.telescope") + end, + }) + + -- Automatically set up your configuration after cloning packer.nvim + -- Put this at the end after all plugins + if packer_bootstrap then + require("packer").sync() + end +end) + +vim.cmd([[ + augroup packer_user_config + autocmd! + autocmd BufWritePost plugins.lua source | PackerSync + augroup end +]]) diff --git a/nvim/lua/tracer/plugins/telescope.lua b/nvim/lua/tracer/plugins/telescope.lua new file mode 100644 index 0000000..368493c --- /dev/null +++ b/nvim/lua/tracer/plugins/telescope.lua @@ -0,0 +1,58 @@ +local actions = require('telescope.actions') + +vim.cmd([[ + highlight link TelescopePromptTitle PMenuSel + highlight link TelescopePreviewTitle PMenuSel + highlight link TelescopePromptNormal NormalFloat + highlight link TelescopePromptBorder FloatBorder + highlight link TelescopeNormal CursorLine + highlight link TelescopeBorder CursorLineBg +]]) + +require('telescope').setup({ + defaults = { + path_display = { truncate = 1 }, + prompt_prefix = '  ', + selection_caret = ' ', + layout_config = { + prompt_position = 'top', + }, + sorting_strategy = 'ascending', + mappings = { + i = { + [''] = actions.close, + [''] = actions.cycle_history_next, + [''] = actions.cycle_history_prev, + }, + }, + file_ignore_patterns = { '.git/' }, + }, + pickers = { + find_files = { + hidden = true, + }, + buffers = { + previewer = false, + layout_config = { + width = 80, + }, + }, + oldfiles = { + prompt_title = 'History', + }, + lsp_references = { + previewer = false, + }, + }, +}) + +require('telescope').load_extension('fzf') +require('telescope').load_extension('live_grep_args') + +vim.keymap.set('n', 'f', [[lua require('telescope.builtin').find_files()]]) +vim.keymap.set('n', '', [[lua require('telescope.builtin').find_files()]]) +vim.keymap.set('n', 'F', [[lua require('telescope.builtin').find_files({ no_ignore = true, prompt_title = 'All Files' })]]) +vim.keymap.set('n', 'b', [[lua require('telescope.builtin').buffers()]]) +vim.keymap.set('n', 'g', [[lua require('telescope').extensions.live_grep_args.live_grep_args()]]) +vim.keymap.set('n', 'h', [[lua require('telescope.builtin').oldfiles()]]) +vim.keymap.set('n', 's', [[lua require('telescope.builtin').lsp_document_symbols()]])