diff --git a/Brewfile b/Brewfile index 8236ea3..fe45f5b 100644 --- a/Brewfile +++ b/Brewfile @@ -77,6 +77,7 @@ brew "no-more-secrets" brew "nodenv" brew "nvm" brew "ollama" +brew "oh-my-posh" brew "ripgrep" brew "opencode" brew "php" @@ -122,6 +123,7 @@ brew "watch" brew "wget" brew "yarn" brew "yq" +brew "zoxide" brew "antoniorodr/memo/memo" brew "common-fate/granted/granted" brew "ddev/ddev/ddev" diff --git a/DEVOPS_RECOMMENDATIONS.md b/DEVOPS_RECOMMENDATIONS.md index 989e0af..45edd91 100644 --- a/DEVOPS_RECOMMENDATIONS.md +++ b/DEVOPS_RECOMMENDATIONS.md @@ -1,188 +1,93 @@ -# DevOps Analysis and Recommendations - -## Executive Summary - -This document provides a comprehensive DevOps analysis of the dotfiles repository and actionable recommendations to improve automation, security, reliability, and maintainability. - -## Current State Analysis - -### Strengths -- ✅ Simple and functional installation script -- ✅ Good separation of concerns (aliases, functions, exports) -- ✅ Comprehensive package management via Brewfile -- ✅ Git configuration with useful aliases -- ✅ Migration path from Vim to Neovim clearly documented - -### Areas for Improvement - -#### 1. Security Concerns 🔴 HIGH PRIORITY -- **Secrets Management**: `secrets` file is referenced but not properly secured -- **Email Exposure**: Work email exposed in gitconfig -- **No Encryption**: Sensitive configuration stored in plain text -- **No .env Validation**: No checking for sensitive data in commits - -#### 2. Automation & Testing 🟡 MEDIUM PRIORITY -- **No CI/CD Pipeline**: No automated testing of installation process -- **No Validation**: No verification that symlinks work correctly -- **No Environment Testing**: Installation not tested across different OS versions -- **Manual Process**: Entirely manual setup with no error handling - -#### 3. Documentation & Usability 🟡 MEDIUM PRIORITY -- **Limited Documentation**: Basic README, lacks troubleshooting -- **No Component Documentation**: Individual config files not documented -- **No Dependency Checking**: No verification of required tools -- **No Rollback Procedure**: No way to undo installation - -#### 4. Maintenance & Reliability 🟢 LOW PRIORITY -- **No Backup Strategy**: Existing configs could be lost -- **Mixed Editor Config**: Both vim and nvim configs present -- **No Version Management**: No way to track config versions -- **No Update Mechanism**: No automated way to update configs - -## Recommendations - -### Phase 1: Critical Security & Automation (Week 1) - -#### 1.1 Implement Secrets Management -```bash -# Create encrypted secrets management -├── secrets/ -│ ├── .gitkeep -│ ├── README.md -│ └── secrets.example -├── scripts/ -│ ├── setup-secrets.sh -│ └── validate-secrets.sh -``` - -#### 1.2 Add Installation Validation -- Pre-installation system checks -- Post-installation verification -- Rollback capabilities -- Error handling and logging - -#### 1.3 Create Testing Framework -- Automated installation testing -- Configuration validation -- Symlink verification -- Shell syntax checking - -### Phase 2: Enhanced Documentation & CI/CD (Week 2) - -#### 2.1 Comprehensive Documentation -- Component-level documentation -- Troubleshooting guide -- Installation options -- Customization guide - -#### 2.2 GitHub Actions CI/CD -- Automated testing on multiple OS versions -- Shell script linting (shellcheck) -- Configuration validation -- Automated security scanning - -#### 2.3 Backup & Recovery -- Pre-installation backup -- Restore functionality -- Configuration versioning -- Migration helpers - -### Phase 3: Advanced Features (Week 3-4) - -#### 3.1 Modular Installation -- Optional component installation -- Environment-specific configurations -- Role-based setups (work vs personal) -- Dependency management - -#### 3.2 Cross-Platform Support -- Linux compatibility -- Windows WSL support -- macOS version checking -- Package manager detection - -#### 3.3 Monitoring & Maintenance -- Configuration drift detection -- Automated updates -- Health checks -- Performance monitoring - -## Implementation Priority Matrix - -| Feature | Impact | Effort | Priority | -|---------|--------|--------|----------| -| Secrets Management | High | Medium | 🔴 Critical | -| Installation Validation | High | Low | 🔴 Critical | -| CI/CD Pipeline | Medium | Medium | 🟡 High | -| Documentation | Medium | Low | 🟡 High | -| Backup/Recovery | High | Medium | 🟡 High | -| Modular Installation | Low | High | 🟢 Medium | -| Cross-Platform | Low | High | 🟢 Low | - -## Security Best Practices - -### Immediate Actions Required -1. **Remove sensitive data** from version control -2. **Implement secret encryption** using tools like `gpg` or `age` -3. **Add pre-commit hooks** to prevent secrets from being committed -4. **Use environment variables** for sensitive configuration - -### Long-term Security Strategy -1. **Principle of Least Privilege**: Only install what's necessary -2. **Regular Security Audits**: Automated scanning for vulnerabilities -3. **Dependency Pinning**: Pin package versions in Brewfile -4. **Access Control**: Restrict who can modify core configurations - -## Monitoring & Metrics - -### Key Performance Indicators (KPIs) -- Installation success rate -- Time to complete setup -- Configuration drift incidents -- Security vulnerabilities detected -- User satisfaction scores - -### Monitoring Implementation -- Installation time tracking -- Error rate monitoring -- Configuration change detection -- Security scan results - -## Next Steps - -1. **Immediate (This Week)**: - - Remove secrets from repository - - Add basic validation to install script - - Create security guidelines - -2. **Short-term (Next 2 Weeks)**: - - Implement testing framework - - Add CI/CD pipeline - - Create comprehensive documentation - -3. **Long-term (Next Month)**: - - Modular installation system - - Cross-platform support - - Advanced monitoring - -## Cost-Benefit Analysis - -### Benefits -- **Reduced Setup Time**: Automated validation saves 30-60 minutes per setup -- **Improved Security**: Prevents accidental exposure of sensitive data -- **Better Reliability**: Automated testing reduces configuration errors by 80% -- **Enhanced Productivity**: Consistent environments across team/machines - -### Costs -- **Initial Development**: ~20-40 hours for full implementation -- **Maintenance**: ~2-4 hours per month ongoing -- **Learning Curve**: ~4-8 hours for users to adopt new practices - -### ROI -- Break-even after 3-5 installations -- Long-term productivity gains significant -- Reduced security risk exposure - ---- - -*Generated by DevOps Analysis - Recommendations based on industry best practices and security standards* \ No newline at end of file +# Dotfiles Improvement Plan + +This repository already has a solid baseline: a symlink installer with backups, +Bats coverage, shell syntax checks, a security scan, and GitHub Actions on macOS +and Ubuntu. The remaining work should stay incremental and test-backed. + +## Current Baseline + +- `make check` runs lint, security checks, installation tests, and Bats tests. +- `scripts/install-enhanced.sh` validates, backs up, links home files, links + config directories, and bootstraps TPM when enabled. +- `zshrc` is a thin loader for `zsh/*.zsh` modules. +- Zsh plugins are managed by zinit; the prompt is managed by Oh My Posh from + `ohmyposh/`. +- Neovim is the only tracked editor runtime and uses lazy.nvim modules. +- Tmux and Ghostty configs are tracked under `~/.config/` symlink targets. + +## Recommended Next Improvements + +### 1. Split install metadata from shell script constants + +**Why:** `HOME_FILES` and `CONFIG_FILES` are embedded in +`scripts/install-enhanced.sh`, while tests duplicate expectations. + +**Plan:** +1. Add a small manifest file, for example `install-manifest.json` or + `install-manifest.sh`. +2. Have the installer and Bats tests read the same manifest. +3. Keep the first version simple: just home files and config directories. + +**Validation:** `make check` plus one focused test that the manifest drives both +backup and link behavior. + +### 2. Add optional component install selection + +**Why:** Some machines may not need every config directory or every Homebrew +package. + +**Plan:** +1. Add installer flags such as `--only nvim,zsh` or `--skip tmux`. +2. Keep default behavior unchanged. +3. Add Bats coverage for one `--only` and one `--skip` path. + +**Validation:** `make test-bats` and `make install-dry`. + +### 3. Improve shell startup observability + +**Why:** zinit bootstrap and optional tool init happen during shell startup; +failures can otherwise be hard to diagnose. + +**Plan:** +1. Add a lightweight `zsh/README.md` documenting module order and ownership. +2. Add a `make doctor-shell` target or script that checks zinit, Oh My Posh, + fzf, zoxide, and linked config paths. +3. Keep shell startup quiet; put diagnostics in explicit doctor commands. + +**Validation:** zsh syntax checks plus a new script syntax test. + +### 4. Rationalize Homebrew package groups + +**Why:** The Brewfile is comprehensive but hard to scan. + +**Plan:** +1. Group packages with comments: core CLI, shell UX, cloud/Kubernetes, editor, + languages, casks, VS Code extensions, uv tools. +2. Avoid deleting packages in the cleanup pass; make removals separately after + usage review. +3. Consider a generated package inventory doc if the Brewfile keeps growing. + +**Validation:** `brew bundle check --file=Brewfile` when available, otherwise +`make check`. + +### 5. Add security-scan fixtures + +**Why:** The scan now ignores `.git/` internals and reports tracked config +findings, but it would be easier to maintain with explicit fixtures. + +**Plan:** +1. Add small tracked test fixtures for safe and unsafe patterns. +2. Assert tracked-file findings stay visible while ignored/internal files stay quiet. +3. Keep security output concise so real findings are easy to notice. + +**Validation:** `make security` and focused Bats coverage for tracked vs ignored paths. + +## Deferred / Not Recommended Yet + +- **Full cross-platform package abstraction:** useful only if Linux setup becomes + a regular workflow; otherwise it adds maintenance overhead. +- **Encrypted secrets framework:** add only when this repo needs to track secret + templates or machine-specific encrypted material. Prefer environment variables + for now. +- **Aggressive plugin pruning:** audit usage first; do not remove editor, tmux, + or Brewfile packages as part of cosmetic cleanup. diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md index 362a0b9..6ccdfa3 100644 --- a/IMPLEMENTATION_SUMMARY.md +++ b/IMPLEMENTATION_SUMMARY.md @@ -1,212 +1,65 @@ -# DevOps Implementation Summary +# Dotfiles Implementation Summary -## Overview -This document summarizes the comprehensive DevOps improvements implemented for the dotfiles repository based on professional best practices and security standards. +## Current Architecture -## 🎯 Objectives Achieved +This repository manages a personal development environment with symlinked home +files and `~/.config` directories. The installer backs up existing targets before +linking and the test suite verifies syntax, install behavior, and key config +contracts. -### 1. Security & Compliance ✅ -- **Secrets Management**: Implemented secure environment variable handling -- **Security Scanning**: Automated detection of potential security issues -- **Access Control**: Proper file permissions and gitignore patterns -- **Credential Protection**: Externalized sensitive configuration +## Shell -### 2. Automation & CI/CD ✅ -- **GitHub Actions Pipeline**: Multi-platform testing (Ubuntu, macOS) -- **Automated Testing**: Installation validation and syntax checking -- **Quality Gates**: Linting, security checks, configuration validation -- **Build Automation**: Makefile with consistent operations +- `zshrc` is a thin entrypoint that loads `zsh/*.zsh` in lexical order. +- `zsh/00-zinit.zsh` bootstraps zinit, loads Zsh plugins/snippets, and initializes + Oh My Posh when available. +- `ohmyposh/` contains tracked prompt themes linked to `~/.config/ohmyposh`. +- Shared aliases, exports, and functions are sourced from `zsh/10-shared-shell.zsh`. -### 3. Testing & Validation ✅ -- **Installation Testing**: Safe environment testing with rollback -- **Configuration Validation**: Syntax checking for shell and git configs -- **Cross-Platform Testing**: Validation on multiple operating systems -- **Performance Testing**: Installation time monitoring +## Editor -### 4. Documentation & Usability ✅ -- **Comprehensive README**: Updated with professional documentation -- **Troubleshooting Guide**: Common issues and solutions -- **API Documentation**: Clear usage instructions and examples -- **DevOps Guidelines**: Best practices and recommendations +- Neovim is the only tracked editor configuration. +- `nvim/init.vim` delegates behavior to Lua modules under `nvim/lua/config` and + plugin specs under `nvim/lua/plugins`. +- lazy.nvim owns plugin management. -## 🔧 Technical Implementation +## Terminal -### New Directory Structure -``` -dotfiles/ -├── .github/workflows/ # CI/CD automation -│ └── test.yml # GitHub Actions pipeline -├── scripts/ # DevOps scripts -│ ├── install-enhanced.sh # Enhanced installation with validation -│ ├── security-check.sh # Security audit automation -│ └── test-install.sh # Installation testing -├── secrets/ # Secure configuration management -│ ├── README.md # Security documentation -│ ├── secrets.example # Template for sensitive config -│ └── .gitkeep # Directory preservation -├── tests/ # Testing framework -│ └── test_dotfiles.bats # Automated test suite -├── Makefile # Build automation -└── DEVOPS_RECOMMENDATIONS.md # Comprehensive guidelines -``` +- `tmux/` is linked to `~/.config/tmux`. +- The installer can bootstrap TPM unless `DOTFILES_SKIP_TPM_BOOTSTRAP` is set. +- `ghostty/` is linked to `~/.config/ghostty`. -### Enhanced Features - -#### 1. Installation System -- **Backup Creation**: Automatic backup before changes -- **Validation**: Pre and post-installation checks -- **Error Handling**: Graceful failure recovery -- **Dry Run**: Preview changes before execution -- **Verbose Logging**: Detailed operation tracking - -#### 2. Security Framework -- **Secret Detection**: Automated scanning for credentials -- **Email Protection**: Detection of hardcoded email addresses -- **Permission Auditing**: File permission validation -- **Gitignore Enhancement**: Comprehensive security patterns - -#### 3. Testing Infrastructure -- **Syntax Validation**: Shell script and configuration checking -- **Installation Testing**: Safe environment simulation -- **Cross-Platform**: Ubuntu and macOS compatibility -- **Regression Testing**: Prevent breaking changes - -#### 4. CI/CD Pipeline -- **Multi-OS Testing**: Automated validation across platforms -- **Quality Gates**: Mandatory checks before merging -- **Security Scanning**: Automated security audit -- **Performance Monitoring**: Installation time tracking - -## 📊 Benefits Delivered - -### Operational Efficiency -- **80% Faster Setup**: Automated validation reduces manual verification -- **Zero Downtime**: Backup and rollback capabilities -- **Consistent Quality**: Automated testing prevents errors -- **Reduced Support**: Better documentation and error handling - -### Security Posture -- **Proactive Detection**: Automated scanning for security issues -- **Compliance**: Following industry best practices -- **Credential Protection**: Proper secrets management -- **Audit Trail**: Comprehensive logging and tracking - -### Developer Experience -- **Simple Commands**: `make install`, `make test`, `make check` -- **Clear Documentation**: Professional setup and troubleshooting guides -- **Predictable Results**: Validated installation process -- **Quick Recovery**: Easy backup and restore procedures - -## 🚀 Usage Examples - -### Quick Start -```bash -# Clone and install -git clone git@github.com:gsantovena/dotfiles.git ~/.dotfiles -cd ~/.dotfiles -make install -``` +## Automation -### Development Workflow -```bash -# Make changes -vim zshrc - -# Test changes -make test +- `Makefile` exposes the main workflows: `make check`, `make test`, + `make test-bats`, `make lint`, `make security`, and install variants. +- `scripts/install-enhanced.sh` handles validation, backup, symlink creation, + install verification, and TPM bootstrap. +- `scripts/test-install.sh` exercises dry-run and real install behavior in a + temporary home directory. +- `tests/test_dotfiles.bats` protects install contracts and configuration shape. -# Check security -make security +## Validation Baseline -# Install with validation -make install -``` +Run before merging changes: -### Maintenance Operations ```bash -# Full quality check make check - -# Create backup -make backup - -# Clean temporary files -make clean ``` -## 📈 Metrics & KPIs - -### Quality Metrics -- **Test Coverage**: 100% of installation paths tested -- **Security Compliance**: Automated scanning with zero critical issues -- **Documentation Coverage**: Complete API and usage documentation -- **Cross-Platform Support**: Ubuntu and macOS validated - -### Performance Metrics -- **Installation Time**: ~2-3 minutes (baseline established) -- **Error Rate**: <5% with automated recovery -- **User Satisfaction**: Improved through better documentation -- **Maintenance Overhead**: Reduced via automation - -## 🔍 Security Findings & Resolution - -### Current Findings -1. **Password References**: Found in shell configurations (documentation context) -2. **Email Addresses**: Hardcoded in git configuration -3. **Token References**: Vault login functionality in aliases +Useful focused checks: -### Recommended Actions -1. **Environment Variables**: Use `$GIT_USER_EMAIL` instead of hardcoded values -2. **Documentation Review**: Clarify context of password references -3. **Security Training**: Guidelines for handling sensitive data - -## 🎯 Success Criteria Met - -### Primary Objectives ✅ -- ✅ Automated testing and validation -- ✅ Security scanning and compliance -- ✅ Professional documentation -- ✅ CI/CD pipeline implementation -- ✅ Backup and recovery procedures - -### Secondary Objectives ✅ -- ✅ Cross-platform compatibility -- ✅ Performance optimization -- ✅ Error handling improvement -- ✅ Maintenance automation -- ✅ User experience enhancement - -## 🔮 Future Enhancements - -### Short-term (1-2 weeks) -- Fix shellcheck linting warnings -- Address security findings -- Add more granular component testing - -### Medium-term (1-2 months) -- Implement package version pinning -- Add performance monitoring -- Create role-based configurations - -### Long-term (3-6 months) -- Multi-platform package management -- Advanced secret encryption -- Configuration drift detection - -## 📝 Conclusion - -The dotfiles repository has been successfully transformed from a basic personal configuration to a professional-grade DevOps implementation. The improvements deliver measurable benefits in security, reliability, and maintainability while following industry best practices. - -### Key Achievements: -- **Professional Infrastructure**: CI/CD, testing, and automation -- **Security Compliance**: Comprehensive scanning and protection -- **Developer Experience**: Simple commands and clear documentation -- **Operational Excellence**: Backup, recovery, and monitoring - -The implementation provides a solid foundation for ongoing development and maintenance while ensuring security and reliability standards are met. +```bash +zsh -n zshrc +zsh -n zsh/*.zsh +git config --file gitconfig --list +oh-my-posh init zsh --config ohmyposh/zen.toml +``` ---- +## Known Tradeoffs -*Implementation completed: $(date)* -*Total effort: ~20 hours of analysis and development* -*ROI: Break-even after 3-5 installations, significant long-term gains* \ No newline at end of file +- The Brewfile is intentionally broad and personal; package pruning should be a + separate usage audit, not incidental cleanup. +- Some startup integrations are optional and guarded so a fresh machine can run + before every Homebrew package is installed. +- The security scan warns on tracked email configuration; decide separately + whether to keep explicit git identity or move it to machine-local config. diff --git a/README.md b/README.md index 67d1f72..238bda3 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ make install ## 📋 Features -- **Shell Configuration**: Zsh with oh-my-zsh, custom aliases and functions +- **Shell Configuration**: Zsh with zinit-managed plugins, Oh My Posh prompt, custom aliases, and functions - **Editor Setup**: Neovim-only configuration with lazy.nvim plugin management - **Terminal Multiplexer**: Tmux configuration with TPM plugin management - **Git Configuration**: Custom aliases and templates for efficient workflows @@ -62,8 +62,10 @@ dotfiles/ ├── git/ # Git templates and hooks ├── gitconfig # Git configuration ├── nvim/ # Neovim configuration +├── ohmyposh/ # Oh My Posh prompt themes ├── tmux/ # Tmux configuration -├── zshrc # Zsh configuration +├── zsh/ # Modular Zsh configuration +├── zshrc # Zsh module loader ├── Brewfile # Package management └── Makefile # Build automation ``` @@ -105,13 +107,16 @@ make check # Complete quality validation # Validate configurations git config --file gitconfig --list zsh -n zshrc +zsh -n zsh/*.zsh ``` ## 📦 Requirements ### Essential - **Git**: Version control -- **Zsh**: Modern shell (oh-my-zsh recommended) +- **Zsh**: Modern shell +- **zinit**: Zsh plugin manager (bootstrapped automatically by `zsh/00-zinit.zsh`) +- **Oh My Posh**: Prompt engine using configs from `ohmyposh/` - **Homebrew**: Package management (macOS) ### Optional @@ -122,14 +127,15 @@ zsh -n zshrc ### Installation Commands ```bash # macOS -brew install git zsh neovim shellcheck +brew install git zsh neovim shellcheck oh-my-posh # Ubuntu/Debian sudo apt-get update sudo apt-get install git zsh neovim shellcheck +# Install Oh My Posh with your platform package manager or from https://ohmyposh.dev -# Install oh-my-zsh -sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +# Install all Homebrew-managed tools on macOS +brew bundle --file=Brewfile ``` ## 🔄 Neovim-only editor setup @@ -256,7 +262,7 @@ sudo chown -R $USER:$USER ~/.dotfiles ./scripts/test-install.sh # Manual verification -ls -la ~/.zshrc ~/.gitconfig ~/.config/nvim +ls -la ~/.zshrc ~/.gitconfig ~/.config/nvim ~/.config/ohmyposh ``` **Neovim statusline icons look wrong** @@ -268,15 +274,22 @@ brew install --cask font-hack-nerd-font Then select **Hack Nerd Font** in your terminal profile. In iTerm2: Settings → Profiles → Text → Font. -**Oh-my-zsh not loading** +**Zsh prompt or plugins not loading** ```bash -# Install oh-my-zsh first -sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +# Ensure Oh My Posh is installed and the prompt config is linked +brew install oh-my-posh +ls -la ~/.config/ohmyposh/zen.toml + +# Re-run the installer if the symlink is missing +make install # Restart shell exec zsh ``` +The zinit bootstrap in `zsh/00-zinit.zsh` installs zinit into +`${XDG_DATA_HOME:-$HOME/.local/share}/zinit/zinit.git` on first shell startup. + ### Getting Help - Check GitHub Issues for known problems - Run `make check` for comprehensive validation @@ -297,7 +310,7 @@ git clone your-fork cd dotfiles # Make changes -vim some-config-file +nvim some-config-file # Test changes make test @@ -317,12 +330,11 @@ MIT License - see [LICENSE](LICENSE) file for details. ## 🙏 Acknowledgments -- Oh-my-zsh community for shell enhancements +- zinit, Oh My Posh, and Oh My Zsh snippet/plugin communities for shell enhancements - Vim/Neovim community for editor excellence - Homebrew maintainers for package management - Open source contributors who make development better --- -*Last updated: $(date)* -*For DevOps recommendations and improvements, see [DEVOPS_RECOMMENDATIONS.md](DEVOPS_RECOMMENDATIONS.md)* +For the current improvement backlog, see [DEVOPS_RECOMMENDATIONS.md](DEVOPS_RECOMMENDATIONS.md). diff --git a/bash_profile b/bash_profile index 9a3e2d6..65dc582 100644 --- a/bash_profile +++ b/bash_profile @@ -3,8 +3,6 @@ # - https://github.com/paulirish/dotfiles ## -export VAULT_ADDR=https://vault.dm.nfl.com - for file in ~/.{aliases,exports,functions,functions.extra}; do [ -r "$file" ] && source "$file" done diff --git a/dotfiles_s.gif b/dotfiles_s.gif index 203c295..56da0dd 100644 Binary files a/dotfiles_s.gif and b/dotfiles_s.gif differ diff --git a/exports b/exports index 7c90d4e..6afa97c 100644 --- a/exports +++ b/exports @@ -1,4 +1,5 @@ export HISTCONTROL=ignoreboth:erasedups +export VAULT_ADDR=https://vault.dm.nfl.com export GOPATH=$HOME/Projects/Go export PATH=$PATH:$GOPATH/bin:/usr/local/sbin:/usr/local/opt/python@2/bin:$HOME/bin:$HOME/.krew/bin:$HOME/.cargo/bin diff --git a/nvim/lua/config/autocmds.lua b/nvim/lua/config/autocmds.lua index 0645e3d..cb115a4 100644 --- a/nvim/lua/config/autocmds.lua +++ b/nvim/lua/config/autocmds.lua @@ -1,27 +1,23 @@ local augroup = vim.api.nvim_create_augroup local autocmd = vim.api.nvim_create_autocmd -local myvimrc = augroup("myvimrc", { clear = true }) +local nvim_config = augroup("nvim_config", { clear = true }) autocmd("BufWritePost", { - group = myvimrc, + group = nvim_config, pattern = { vim.fn.stdpath("config") .. "/init.vim", - vim.fn.expand("~/.vimrc"), - "~/.vim/vimrc*", - "*/vim/vimrc*", + vim.fn.stdpath("config") .. "/lua/config/*.lua", + vim.fn.stdpath("config") .. "/lua/plugins/*.lua", }, callback = function() vim.cmd("source $MYVIMRC") - if vim.fn.has("gui_running") == 1 then - vim.cmd("source $MYGVIMRC") - end - require("config.personal").echo_vimrc_reloaded() + require("config.personal").echo_config_reloaded() end, }) autocmd({ "BufEnter", "BufWinEnter" }, { - group = myvimrc, + group = nvim_config, callback = function(args) require("config.project-root").apply(args.buf) end, diff --git a/nvim/lua/config/personal.lua b/nvim/lua/config/personal.lua index 88fc9ed..100bcdd 100644 --- a/nvim/lua/config/personal.lua +++ b/nvim/lua/config/personal.lua @@ -6,8 +6,8 @@ function M.show_floating_message(msg) popup.show_floating(msg) end -function M.echo_vimrc_reloaded() - M.show_floating_message("✅ vimrc reloaded!") +function M.echo_config_reloaded() + M.show_floating_message("✅ Neovim config reloaded!") end function M.save_popup() @@ -19,7 +19,7 @@ function M.save_popup_error() end _G.ShowFloatingMessage = M.show_floating_message -_G.EchoVimrcReloaded = M.echo_vimrc_reloaded +_G.EchoConfigReloaded = M.echo_config_reloaded _G.SavePopup = M.save_popup _G.SavePopupError = M.save_popup_error diff --git a/ohmyposh/default.toml b/ohmyposh/default.toml new file mode 100644 index 0000000..a688c54 --- /dev/null +++ b/ohmyposh/default.toml @@ -0,0 +1,165 @@ +console_title_template = '{{ .Shell }} in {{ .Folder }}' +version = 4 +final_space = true + +[palette] + black = '#262B44' + blue = '#4B95E9' + green = '#59C9A5' + orange = '#F07623' + red = '#D81E5B' + white = '#E0DEF4' + yellow = '#F3AE35' + +[secondary_prompt] + template = '<,p:yellow> >  ' + foreground = 'p:black' + background = 'transparent' + +[transient_prompt] + template = '<,p:yellow> {{ .Folder }}  ' + foreground = 'p:black' + background = 'transparent' + +[upgrade] + source = 'cdn' + interval = '168h' + auto = false + notice = false + +[[blocks]] + type = 'prompt' + alignment = 'left' + + [[blocks.segments]] + leading_diamond = '' + trailing_diamond = '' + template = ' {{ if .SSHSession }} {{ end }}{{ .UserName }} ' + foreground = 'p:black' + background = 'p:yellow' + type = 'session' + style = 'diamond' + + [[blocks.segments]] + template = '  {{ path .Path .Location }} ' + foreground = 'p:white' + powerline_symbol = '' + background = 'p:orange' + type = 'path' + style = 'powerline' + + [blocks.segments.options] + style = 'folder' + + [[blocks.segments]] + template = ' {{ if .UpstreamURL }}{{ url .UpstreamIcon .UpstreamURL }} {{ end }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }}  {{ .Working.String }}{{ end }}{{ if .Staging.Changed }}  {{ .Staging.String }}{{ end }} ' + foreground = 'p:black' + powerline_symbol = '' + background = 'p:green' + type = 'git' + style = 'powerline' + background_templates = ['{{ if or (.Working.Changed) (.Staging.Changed) }}p:yellow{{ end }}', '{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:red{{ end }}', '{{ if gt .Ahead 0 }}#49416D{{ end }}', '{{ if gt .Behind 0 }}#7A306C{{ end }}'] + foreground_templates = ['{{ if or (.Working.Changed) (.Staging.Changed) }}p:black{{ end }}', '{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:white{{ end }}', '{{ if gt .Ahead 0 }}p:white{{ end }}'] + + [blocks.segments.options] + branch_template = '{{ trunc 25 .Branch }}' + fetch_status = true + fetch_upstream_icon = true + + [[blocks.segments]] + template = '  ' + foreground = 'p:white' + powerline_symbol = '' + background = 'p:yellow' + type = 'root' + style = 'powerline' + + [[blocks.segments]] + leading_diamond = '' + trailing_diamond = '' + template = ' {{ if gt .Code 0 }}{{ else }}{{ end }} ' + foreground = 'p:white' + background = 'p:blue' + type = 'status' + style = 'diamond' + background_templates = ['{{ if gt .Code 0 }}p:red{{ end }}'] + + [blocks.segments.options] + always_enabled = true + +[[blocks]] + type = 'rprompt' + + [[blocks.segments]] + template = ' ' + foreground = 'p:green' + background = 'transparent' + type = 'node' + style = 'plain' + + [blocks.segments.options] + display_mode = 'files' + fetch_package_manager = false + home_enabled = false + + [[blocks.segments]] + template = ' ' + foreground = 'p:blue' + background = 'transparent' + type = 'go' + style = 'plain' + + [blocks.segments.options] + fetch_version = false + + [[blocks.segments]] + template = ' ' + foreground = 'p:yellow' + background = 'transparent' + type = 'python' + style = 'plain' + + [blocks.segments.options] + display_mode = 'files' + fetch_version = false + fetch_virtual_env = false + + [[blocks.segments]] + template = 'in {{ .Name }} ' + foreground = 'p:white' + background = 'transparent' + type = 'shell' + style = 'plain' + + [[blocks.segments]] + template = 'at {{ .CurrentDate | date "15:04:05" }}' + foreground = 'p:white' + background = 'transparent' + type = 'time' + style = 'plain' + +[[tooltips]] + leading_diamond = '' + trailing_diamond = '' + template = '  {{ .Profile }}{{ if .Region }}@{{ .Region }}{{ end }} ' + foreground = 'p:white' + background = 'p:orange' + type = 'aws' + style = 'diamond' + tips = ['aws'] + + [tooltips.options] + display_default = true + +[[tooltips]] + leading_diamond = '' + trailing_diamond = '' + template = '  {{ .Name }} ' + foreground = 'p:white' + background = 'p:blue' + type = 'az' + style = 'diamond' + tips = ['az'] + + [tooltips.options] + display_default = true diff --git a/ohmyposh/zen.toml b/ohmyposh/zen.toml new file mode 100644 index 0000000..7edb6f0 --- /dev/null +++ b/ohmyposh/zen.toml @@ -0,0 +1,74 @@ +#:schema https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json + +version = 2 +final_space = true +console_title_template = '{{ .Shell }} in {{ .Folder }}' + +[[blocks]] + type = 'prompt' + alignment = 'left' + newline = true + + [[blocks.segments]] + type = 'path' + style = 'plain' + background = 'transparent' + foreground = 'blue' + template = '{{ .Path }}' + + [blocks.segments.properties] + style = 'full' + + [[blocks.segments]] + type = 'git' + style = 'plain' + foreground = 'p:grey' + background = 'transparent' + template = ' {{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed) }}*{{ end }} {{ if gt .Behind 0 }}⇣{{ end }}{{ if gt .Ahead 0 }}⇡{{ end }}' + + [blocks.segments.properties] + branch_icon = '' + commit_icon = '@' + fetch_status = true + +[[blocks]] + type = 'rprompt' + overflow = 'hidden' + + [[blocks.segments]] + type = 'executiontime' + style = 'plain' + foreground = 'yellow' + background = 'transparent' + template = '{{ .FormattedMs }}' + + [blocks.segments.properties] + threshold = 5000 + +[[blocks]] + type = 'prompt' + alignment = 'left' + newline = true + + [[blocks.segments]] + type = 'text' + style = 'plain' + foreground_templates = [ + "{{if gt .Code 0}}red{{end}}", + "{{if eq .Code 0}}magenta{{end}}", + ] + background = 'transparent' + template = '❯' + +[transient_prompt] + foreground_templates = [ + "{{if gt .Code 0}}red{{end}}", + "{{if eq .Code 0}}magenta{{end}}", + ] + background = 'transparent' + template = '❯ ' + +[secondary_prompt] + foreground = 'magenta' + background = 'transparent' + template = '❯❯ ' diff --git a/scripts/install-enhanced.sh b/scripts/install-enhanced.sh index c1d1aa5..eece080 100755 --- a/scripts/install-enhanced.sh +++ b/scripts/install-enhanced.sh @@ -17,7 +17,7 @@ HISTORY_LOGS=${HOME}/.logs SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOTFILES_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" HOME_FILES="bash_profile aliases exports functions git gitconfig zshrc screenrc" -CONFIG_FILES="nvim ghostty tmux" +CONFIG_FILES="nvim ghostty tmux ohmyposh" BACKUP_DIR="${HOME}/.dotfiles-backup-$(date +%Y%m%d_%H%M%S)" TPM_REPO_URL="${TPM_REPO_URL:-https://github.com/tmux-plugins/tpm.git}" TPM_INSTALL_DIR="${TPM_INSTALL_DIR:-$HOME/.config/tmux/plugins/tpm}" diff --git a/scripts/security-check.sh b/scripts/security-check.sh index 0f81891..dc87870 100755 --- a/scripts/security-check.sh +++ b/scripts/security-check.sh @@ -77,7 +77,7 @@ check_emails() { if grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" "$file" > /dev/null 2>&1; then email_files+=("$file") fi - done < <(find "$DOTFILES_DIR" -type f \( -name "*.sh" -o -name "*rc" -o -name "gitconfig" -o -name "aliases" -o -name "exports" -o -name "functions" \) -print0) + done < <(find "$DOTFILES_DIR" -path "$DOTFILES_DIR/.git" -prune -o -type f \( -name "*.sh" -o -name "*rc" -o -name "gitconfig" -o -name "aliases" -o -name "exports" -o -name "functions" \) -print0) if [ ${#email_files[@]} -gt 0 ]; then print_status "$YELLOW" "⚠️ Email addresses found in:" @@ -122,7 +122,7 @@ check_executables() { local unexpected_executables=() while IFS= read -r -d '' file; do - if [ -x "$file" ] && [[ ! "$file" =~ \.sh$ ]] && [[ ! "$file" =~ install-dotfiles\.sh$ ]]; then + if [ -x "$file" ] && [[ ! "$file" =~ \.sh$ ]]; then unexpected_executables+=("$file") fi done < <(find "$DOTFILES_DIR" -type f \( -name "*rc" -o -name "aliases" -o -name "exports" -o -name "functions" -o -name "gitconfig" \) -print0) diff --git a/scripts/test-install.sh b/scripts/test-install.sh index 77739cd..a239d84 100755 --- a/scripts/test-install.sh +++ b/scripts/test-install.sh @@ -186,8 +186,19 @@ test_config_syntax() { if zsh -n "$DOTFILES_DIR/zshrc" 2>/dev/null; then print_status "$GREEN" "✅ zshrc syntax is valid" else - print_status "$YELLOW" "⚠️ zshrc may have syntax issues (some oh-my-zsh features might not be available in test)" + print_status "$YELLOW" "⚠️ zshrc may have syntax issues (some plugin/runtime features might not be available in test)" fi + + for file in "$DOTFILES_DIR"/zsh/*.zsh; do + [ -e "$file" ] || continue + if zsh -n "$file" 2>/dev/null; then + if [ "${VERBOSE:-false}" = true ]; then + print_status "$GREEN" "✅ $(basename "$file") syntax is valid" + fi + else + print_status "$YELLOW" "⚠️ $(basename "$file") may have syntax issues" + fi + done else print_status "$YELLOW" "⚠️ zsh not available for syntax testing" fi diff --git a/tests/test_dotfiles.bats b/tests/test_dotfiles.bats index ea363d9..5983171 100644 --- a/tests/test_dotfiles.bats +++ b/tests/test_dotfiles.bats @@ -163,6 +163,21 @@ EOF for file in "${files[@]}"; do [ -f "$DOTFILES_DIR/$file" ] done + + [ -d "$DOTFILES_DIR/zsh" ] + [ -f "$DOTFILES_DIR/zsh/00-zinit.zsh" ] + [ -f "$DOTFILES_DIR/zsh/10-shared-shell.zsh" ] + [ -f "$DOTFILES_DIR/zsh/20-tools.zsh" ] + [ -f "$DOTFILES_DIR/zsh/30-completions.zsh" ] + [ -f "$DOTFILES_DIR/zsh/40-vendor.zsh" ] + [ -f "$DOTFILES_DIR/zsh/50-keybindings.zsh" ] + [ -f "$DOTFILES_DIR/zsh/55-aliases.zsh" ] + [ -f "$DOTFILES_DIR/zsh/60-zmv.zsh" ] + [ -f "$DOTFILES_DIR/zsh/70-named-directories.zsh" ] + + [ -d "$DOTFILES_DIR/ohmyposh" ] + [ -f "$DOTFILES_DIR/ohmyposh/zen.toml" ] + [ -f "$DOTFILES_DIR/ohmyposh/default.toml" ] } @test "git configuration is valid" { @@ -176,9 +191,21 @@ EOF skip "zsh not available" fi - # Test basic syntax (may not catch all oh-my-zsh issues) + # Test basic syntax (may not catch all plugin/runtime issues) run zsh -n "$DOTFILES_DIR/zshrc" [ "$status" -eq 0 ] + + for file in "$DOTFILES_DIR"/zsh/*.zsh; do + run zsh -n "$file" + [ "$status" -eq 0 ] + done +} + +@test "oh-my-posh prompt configuration is installed and wired into zsh" { + grep -q 'CONFIG_FILES="nvim ghostty tmux ohmyposh"' "$DOTFILES_DIR/scripts/install-enhanced.sh" + grep -q 'brew "oh-my-posh"' "$DOTFILES_DIR/Brewfile" + grep -q 'brew "zoxide"' "$DOTFILES_DIR/Brewfile" + grep -q 'oh-my-posh init zsh --config "$HOME/.config/ohmyposh/zen.toml"' "$DOTFILES_DIR/zsh/00-zinit.zsh" } @test "bash profile syntax" { @@ -289,7 +316,7 @@ EOF grep -q 'keymap("n", ""' "$keymaps_file" grep -q 'BufWritePost' "$autocmds_file" grep -q 'BufEnter' "$autocmds_file" - grep -q 'EchoVimrcReloaded' "$personal_file" + grep -q 'EchoConfigReloaded' "$personal_file" grep -q 'ShowFloatingMessage' "$personal_file" grep -q 'vim.fs.root' "$root_file" } diff --git a/zsh/00-zinit.zsh b/zsh/00-zinit.zsh new file mode 100644 index 0000000..aa6af24 --- /dev/null +++ b/zsh/00-zinit.zsh @@ -0,0 +1,130 @@ +if [[ -f "/opt/homebrew/bin/brew" ]] then + # If you're using macOS, you'll want this enabled + eval "$(/opt/homebrew/bin/brew shellenv)" +fi + +# Set the directory we want to store zinit and plugins +ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git" + +# Download Zinit, if it's not there yet +if [ ! -d "$ZINIT_HOME" ]; then + mkdir -p "$(dirname "$ZINIT_HOME")" + git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME" +fi + +# Source/Load zinit +source "${ZINIT_HOME}/zinit.zsh" + +# Add in zsh plugins +zinit light zsh-users/zsh-syntax-highlighting +zinit light zsh-users/zsh-completions +zinit light zsh-users/zsh-autosuggestions +zinit light Aloxaf/fzf-tab + +# Add in snippets +zinit snippet OMZL::async_prompt.zsh +zinit snippet OMZL::directories.zsh +zinit snippet OMZL::functions.zsh +zinit snippet OMZL::git.zsh +zinit snippet OMZP::command-not-found +zinit snippet OMZP::1password +zinit snippet OMZP::aws +zinit snippet OMZP::bundler +zinit snippet OMZP::brew +zinit snippet OMZP::colorize +zinit snippet OMZP::common-aliases +zinit snippet OMZP::copypath +zinit snippet OMZP::docker +zinit snippet OMZP::docker-compose +zinit snippet OMZP::dotenv +zinit snippet OMZP::gh +zinit snippet OMZP::git +zinit snippet OMZP::git-prompt +zinit snippet OMZP::github +zinit snippet OMZP::gitignore +zinit snippet OMZP::golang +zinit snippet OMZP::helm +zinit snippet OMZP::kubectl +zinit snippet OMZP::kubectx +zinit snippet OMZP::minikube +zinit snippet OMZP::mvn +zinit snippet OMZP::mosh +zinit snippet OMZP::nmap +zinit snippet OMZP::podman +zinit snippet OMZP::pyenv +zinit snippet OMZP::python +zinit snippet OMZP::rbenv +zinit snippet OMZP::ruby +zinit snippet OMZP::rust +zinit snippet OMZP::ssh-agent +zinit snippet OMZP::sudo +zinit snippet OMZP::systemadmin +zinit snippet OMZP::terraform +zinit snippet OMZP::thefuck +zinit snippet OMZP::transfer +zinit snippet OMZP::vagrant +zinit snippet OMZP::vagrant-prompt +zinit snippet OMZP::virtualenv +zinit snippet OMZP::vscode +zinit snippet OMZP::web-search +zinit snippet OMZP::z + +zinit ice depth=1 \ + cloneopts"--filter=blob:none --sparse" \ + atclone"git sparse-checkout set --no-cone plugins/macos" \ + atpull"%atclone" \ + pick"plugins/macos/macos.plugin.zsh" \ + nocompile + +zinit light ohmyzsh/ohmyzsh + +# Load completions +autoload -Uz compinit && compinit + +zinit cdreplay -q + +# Prompt +if command -v oh-my-posh >/dev/null 2>&1; then + eval "$(oh-my-posh init zsh --config "$HOME/.config/ohmyposh/zen.toml")" +fi + +# Keybindings +bindkey -e +bindkey '^p' history-search-backward +bindkey '^n' history-search-forward +bindkey '^[w' kill-region + +# History +HISTSIZE=5000 +HISTFILE=~/.zsh_history +SAVEHIST=$HISTSIZE +HISTDUP=erase +setopt appendhistory +setopt sharehistory +setopt hist_ignore_space +setopt hist_ignore_all_dups +setopt hist_save_no_dups +setopt hist_ignore_dups +setopt hist_find_no_dups + +# Completion styling +zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' +zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" +zstyle ':completion:*' menu no +zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls --color $realpath' +zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath' + +# Aliases +alias ls='ls --color' +alias vim='nvim' +alias vi='vim' +alias c='clear' + +# Shell integrations +if command -v fzf >/dev/null 2>&1; then + eval "$(fzf --zsh)" +fi + +if command -v zoxide >/dev/null 2>&1; then + eval "$(zoxide init --cmd cd zsh)" +fi diff --git a/zsh/10-shared-shell.zsh b/zsh/10-shared-shell.zsh new file mode 100644 index 0000000..0a48add --- /dev/null +++ b/zsh/10-shared-shell.zsh @@ -0,0 +1,10 @@ +# Shell-agnostic shared configuration previously pulled in through bash_profile. + +for file in "$HOME"/.{aliases,exports,functions,functions.extra}; do + [ -r "$file" ] && source "$file" +done +unset file + +if [ -x /usr/local/bin/git-tip ]; then + git-tip +fi diff --git a/zsh/20-tools.zsh b/zsh/20-tools.zsh new file mode 100644 index 0000000..5450032 --- /dev/null +++ b/zsh/20-tools.zsh @@ -0,0 +1,33 @@ +# Tool and runtime initialization. + +[ -r "$HOME/.fzf.zsh" ] && source "$HOME/.fzf.zsh" + +# Google Cloud SDK path and completion scripts installed by Homebrew cask. +GCP_ZSH_PATH="/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc" +GCP_COMPLETION="/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/completion.zsh.inc" + +[ -r "$GCP_ZSH_PATH" ] && source "$GCP_ZSH_PATH" +[ -r "$GCP_COMPLETION" ] && source "$GCP_COMPLETION" +unset GCP_ZSH_PATH GCP_COMPLETION + +if command -v rbenv >/dev/null 2>&1; then + eval "$(rbenv init - zsh)" +fi + +export NVM_DIR="$HOME/.nvm" +[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && source "/opt/homebrew/opt/nvm/nvm.sh" +[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && source "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" + +# THIS MUST BE AT THE END OF THE SDKMAN BLOCK FOR SDKMAN TO WORK. +export SDKMAN_DIR="$HOME/.sdkman" +[ -s "$SDKMAN_DIR/bin/sdkman-init.sh" ] && source "$SDKMAN_DIR/bin/sdkman-init.sh" + +# export PATH="/opt/homebrew/opt/openssl@1.0/bin:$PATH" + +# Add RVM to PATH for scripting. Make sure this is the last PATH variable change. +# export PATH="$PATH:$HOME/.rvm/bin" + +# PostgreSQL +[ -d /opt/homebrew/opt/postgresql@16/bin ] && export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH" + +[ -r "$HOME/.local/bin/env" ] && source "$HOME/.local/bin/env" diff --git a/zsh/30-completions.zsh b/zsh/30-completions.zsh new file mode 100644 index 0000000..c69e51c --- /dev/null +++ b/zsh/30-completions.zsh @@ -0,0 +1,7 @@ +# Additional completions not handled by Oh My Zsh. + +autoload -U +X bashcompinit && bashcompinit + +if [ -x /opt/homebrew/bin/vault ]; then + complete -o nospace -C /opt/homebrew/bin/vault vault +fi diff --git a/zsh/40-vendor.zsh b/zsh/40-vendor.zsh new file mode 100644 index 0000000..b8a6256 --- /dev/null +++ b/zsh/40-vendor.zsh @@ -0,0 +1,24 @@ +# Vendor-generated and machine-local shell integrations. + +# Ping Identity - Added with 'pingctl config' on Thu Jan 12 11:24:43 CST 2023 +PING_IDENTITY_CONFIG="$HOME/.pingidentity/config" +if [ -r "$PING_IDENTITY_CONFIG" ]; then + set -a + source "$PING_IDENTITY_CONFIG" + set +a +fi +unset PING_IDENTITY_CONFIG + +SF_AC_ZSH_SETUP_PATH="$HOME/Library/Caches/sf/autocomplete/zsh_setup" +[ -r "$SF_AC_ZSH_SETUP_PATH" ] && source "$SF_AC_ZSH_SETUP_PATH" +unset SF_AC_ZSH_SETUP_PATH + +# The following lines have been added by Docker Desktop to enable Docker CLI completions. +DOCKER_COMPLETIONS_DIR="$HOME/.docker/completions" +if [ -d "$DOCKER_COMPLETIONS_DIR" ]; then + fpath=("$DOCKER_COMPLETIONS_DIR" $fpath) + autoload -Uz compinit + compinit +fi +unset DOCKER_COMPLETIONS_DIR +# End of Docker CLI completions diff --git a/zsh/50-keybindings.zsh b/zsh/50-keybindings.zsh new file mode 100644 index 0000000..34e6800 --- /dev/null +++ b/zsh/50-keybindings.zsh @@ -0,0 +1,30 @@ +# ZSH Hacks - Dreams of Code + +autoload -Uz edit-command-line +zle -N edit-command-line +bindkey '^X^E' edit-command-line + +# Clear screen but keep current command buffer. +function clear-screen-and-scrollback() { + echoti civis >"$TTY" + printf '%b' '\e[H\e[2J\e[3J' >"$TTY" + echoti cnorm >"$TTY" + zle redisplay +} +zle -N clear-screen-and-scrollback +bindkey '^Xl' clear-screen-and-scrollback + +# Copy current command buffer to clipboard (macOS). +function copy-buffer-to-clipboard() { + echo -n "$BUFFER" | pbcopy + zle -M "Copied to clipboard" +} +zle -N copy-buffer-to-clipboard +bindkey '^Xc' copy-buffer-to-clipboard + +# Insert git commit template (Ctrl+X, G, C). +# \C-b moves cursor back one position. +bindkey -s '^Xgc' 'git commit -m ""\C-b' +bindkey -s '^Xgp' 'git push origin ' +bindkey -s '^Xgs' 'git status\n' +bindkey -s '^Xgl' 'git log --oneline -n 10\n' diff --git a/zsh/55-aliases.zsh b/zsh/55-aliases.zsh new file mode 100644 index 0000000..570c622 --- /dev/null +++ b/zsh/55-aliases.zsh @@ -0,0 +1,5 @@ +# zsh-specific aliases. + +# Task Master aliases added on 7/23/2025. +alias tm='task-master' +alias taskmaster='task-master' diff --git a/zsh/60-zmv.zsh b/zsh/60-zmv.zsh new file mode 100644 index 0000000..ba5d65f --- /dev/null +++ b/zsh/60-zmv.zsh @@ -0,0 +1,12 @@ +# Enable zmv. +autoload -Uz zmv + +# Usage examples: +# zmv '(*).log' '$1.txt' # Rename .log to .txt +# zmv -w '*.log' '*.txt' # Same thing, simpler syntax +# zmv -n '(*).log' '$1.txt' # Dry run (preview changes) +# zmv -i '(*).log' '$1.txt' # Interactive mode (confirm each) + +# Helpful aliases for zmv. +alias zcp='zmv -C' # Copy with patterns +alias zln='zmv -L' # Link with patterns diff --git a/zsh/70-named-directories.zsh b/zsh/70-named-directories.zsh new file mode 100644 index 0000000..a55d071 --- /dev/null +++ b/zsh/70-named-directories.zsh @@ -0,0 +1,5 @@ +# Named Directories - Bookmark Folders. +# Access with ~name syntax, e.g., cd ~dot or ls ~dl. +hash -d github=~/Projects/github.com +hash -d dot=~/.dotfiles +hash -d dl=~/Downloads diff --git a/zshrc b/zshrc index d90c304..14b08b1 100644 --- a/zshrc +++ b/zshrc @@ -1,165 +1,14 @@ -# Path to your oh-my-zsh installation. -export ZSH=$HOME/.oh-my-zsh -# export UPDATE_ZSH_DAYS=13 +# Modular zsh configuration entrypoint. +# +# The real configuration lives in zsh/*.zsh so each concern can be updated +# independently while this file remains safe to symlink as ~/.zshrc. -# ZSH_THEME="nanotech" -# ZSH_THEME="arrow" -# ZSH_THEME="clean" -# ZSH_THEME="intheloop" -# ZSH_THEME="robbyrussell" -# ZSH_THEME="cypher" -# ZSH_THEME="af-magic" -# ZSH_THEME="steeef" -# ZSH_THEME="peepcode" -ZSH_THEME="avit" +_dotfiles_zshrc="${(%):-%N}" +DOTFILES_DIR="${DOTFILES_DIR:-${_dotfiles_zshrc:A:h}}" +unset _dotfiles_zshrc -ZSH_COLORIZE_TOOL="chroma" -ZSH_COLORIZE_STYLE="nordic" +for file in "$DOTFILES_DIR"/zsh/*.zsh(N); do + [ -r "$file" ] && source "$file" +done -# CASE_SENSITIVE="true" -# HYPHEN_INSENSITIVE="true" -# DISABLE_AUTO_UPDATE="true" -# DISABLE_LS_COLORS="true" -# DISABLE_AUTO_TITLE="true" -# ENABLE_CORRECTION="true" -# DISABLE_UNTRACKED_FILES_DIRTY="true" -# HIST_STAMPS="mm/dd/yyyy" -# ZSH_CUSTOM=/path/to/new-custom-folder - -COMPLETION_WAITING_DOTS="true" -plugins=( - 1password - aws - bundler - brew - colorize - common-aliases - copypath - docker - docker-compose - dotenv - gh - git - git-prompt - github - gitignore - golang - helm - knife - knife_ssh - kubectl - kubectx - macos - minikube - mvn - mosh - nmap - podman - pyenv - python - rbenv - ruby - rust - ssh-agent - sudo - systemadmin - terraform - thefuck - transfer - vagrant - vagrant-prompt - virtualenv - vscode - web-search - z - zsh-autosuggestions -) - -# User configuration - -source $ZSH/oh-my-zsh.sh -source $HOME/.bash_profile - -RPROMPT="" - -[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh -zstyle :omz:plugins:ssh-agent agent-forwarding on - -GCP_ZSH_PATH='/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc' -GCP_COMPLETION='/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/completion.zsh.inc' - -[ -f $GCP_ZSH_PATH ] && source $GCP_ZSH_PATH -[ -f $GCP_COMPLETION ] && source $GCP_COMPLETION - -# ---------------- -# rbenv -# ---------------- -eval "$(rbenv init - zsh)" - -export NVM_DIR="$HOME/.nvm" -[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh" # This loads nvm -[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion - -#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! -export SDKMAN_DIR="$HOME/.sdkman" -[[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh" - -#export PATH="/opt/homebrew/opt/openssl@1.0/bin:$PATH" - -# Add RVM to PATH for scripting. Make sure this is the last PATH variable change. -#export PATH="$PATH:$HOME/.rvm/bin" - -# Ping Identity - Added with 'pingctl config' on Thu Jan 12 11:24:43 CST 2023 -set -a -test -f '/Users/gsantovena/.pingidentity/config' && source '/Users/gsantovena/.pingidentity/config' -set +a - -# PostreSQL -export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH" - -autoload -U +X bashcompinit && bashcompinit -complete -o nospace -C /opt/homebrew/bin/vault vault - -SF_AC_ZSH_SETUP_PATH=/Users/gsantovena/Library/Caches/sf/autocomplete/zsh_setup && test -f $SF_AC_ZSH_SETUP_PATH && source $SF_AC_ZSH_SETUP_PATH; # sf autocomplete setup -# The following lines have been added by Docker Desktop to enable Docker CLI completions. -fpath=(/Users/gsantovena/.docker/completions $fpath) -autoload -Uz compinit -compinit -# End of Docker CLI completions - -# Task Master aliases added on 7/23/2025 -alias tm='task-master' -alias taskmaster='task-master' - -. "$HOME/.local/bin/env" - -# ZSH Hacks - Dreams of Code - -autoload -Uz edit-command-line -zle -N edit-command-line -bindkey '^X^E' edit-command-line - -# Clear screen but keep current command buffer -function clear-screen-and-scrollback() { - echoti civis >"$TTY" - printf '%b' '\e[H\e[2J\e[3J' >"$TTY" - echoti cnorm >"$TTY" - zle redisplay -} -zle -N clear-screen-and-scrollback -bindkey '^Xl' clear-screen-and-scrollback - -# Copy current command buffer to clipboard (macOS) -function copy-buffer-to-clipboard() { - echo -n "$BUFFER" | pbcopy - zle -M "Copied to clipboard" -} -zle -N copy-buffer-to-clipboard -bindkey '^Xc' copy-buffer-to-clipboard - -# Insert git commit template (Ctrl+X, G, C) -# \C-b moves cursor back one position -bindkey -s '^Xgc' 'git commit -m ""\C-b' -bindkey -s '^Xgp' 'git push origin ' -bindkey -s '^Xgs' 'git status\n' -bindkey -s '^Xgl' 'git log --oneline -n 10\n' +unset file