diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7156572..a08c56d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,3 +1,37 @@ +RECURSIVE_START +Recognize that all repositories are nix flake based and often use each other as inputs. Sometimes the options and configuration for one repository will be in another as an input which can be found in the flake.nix file of the repo that calls another as an input. + +common input names as they link to repos: +- gigdot & dotfiles refer to @gignsky/dotfiles +- wrap, wrapd, wrapper, & tarballer refer to @gignsky/wrap +- nufetch & neofetch refer to @gignsky/nufetch +- gigvim refers to @gignsky/gigvim + +Below are rules that must ALWAYS be followed: +1. All progression steps should be displayed as NEW comments with checkbox lists of tasks to be completed, to be checked off via a comment edit while adding a timestamp as well as legnth of time taken to progress to this point and notes about the task, including links to relevant commits, PRs, or issues, etc... +2. Original prompt for agents should be preserved as a comment at the beginning of a PR or issue as well as in the description of the copilot's initial commit on a new PR +3. Make every effort to make every ai agent call as effective as possible in order to preserve as many premium requests as possible +4. ALWAYS attempt to verify that changes compile, often this is as simple as running `nix flake check` or `nix build` in the repository, if the checks fail, continue iterating until they pass +5. Document as much as possible in markdown files either in the docs/ dir or in logical places alongside files and in files + +In all sessions, the order of operations is as follows: +0. Read all of these operations and understand them before continuing +0.a. Create a new comment in the issue or PR that reflects this order of operations with checkboxes and edit the comment marking the checkboxes as you progress +0.a.NOTE: Refer to rule #1 +0.b. Analyze all repository's copilot-instructions looking specifically for the RECURSIVE block described in step x+4, find the diff between these versions, determine the most recent / logical state of the block and immediately replace the block in the active repos instructions with it +1. Analyze the active repos' .github/ folder and its contents for repo specific instructions +2. Analyze the other repo's .github/ fiolder and its contents for general ecosystem updates since last checked +3. Analyze the @gignsky/dotfiles .github/ cortana chatbot markdown file and understand the way in which your are supposed to interact based off of that file +4. Analyze the active repo and ALL its elements and compare and contrast with the active repo's .github/copilot-instructions.md file +5. Based off of information gathered in the previous steps please analyze the expected and actual state of ci/cd in the current repository and make note that the ci/cd pipeline for the current repository exists within the copilot-instructions +6. Update the instructions file to include updated information based off of data gathered in steps 1-5 +7. Step 7 (here) should be replaced with 7..x where x equals the total number of steps that cortana determines are neccary to complete the request from the all powerful lord gig minus seven. Steps continue at item x+1 below. +x+1. Testing pipeline should start here, at a minimum a `nix flake check` needs to pass before this item can be marked completed, if this can't be done then detailed error messages should be left in the comments +x+2. Testing pipeline continues, if changes to the repository would have an effect on the flake outputs the changed outputs themselves should be checked here in as many check boxes as is nececcary +x+3. After flake testing in items x+1 & x+2 (which can be multiple checkboxes and steps) Repeat steps 0-6 and then continue below on step x+4 +x+4. All text between RECURSIVE_START & RECURSIVE_END should be placed at the top of each copilot-instructions.md file in every repository, at this point replace the version from step 0.b with an updated version based on all changes made before this step +RECURSIVE_END + # GigVim - Nix-based Neovim Configuration GigVim is a Nix Flake-based Neovim configuration using the nvf (NeoVim Flake) framework. It provides a highly customizable and reproducible development environment with language support, plugins, and themes configured declaratively. @@ -190,4 +224,4 @@ The configuration automatically includes these tools: - `nix develop` (first time): 15-30 minutes - `nix develop` (incremental): 1-2 minutes -Always set timeouts to at least double these estimates to account for network variability and system performance differences. \ No newline at end of file +Always set timeouts to at least double these estimates to account for network variability and system performance differences. diff --git a/.gitignore b/.gitignore index 726d2d6..6775e8a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,11 @@ result +result-* .direnv +.DS_Store +*.log +/tmp/ +.cache/ +.local/ +node_modules/ +dist/ +build/ diff --git a/docs/plugins/README.md b/docs/plugins/README.md new file mode 100644 index 0000000..11c2744 --- /dev/null +++ b/docs/plugins/README.md @@ -0,0 +1,236 @@ +# Snacks.nvim Integration for GigVim + +## Overview + +This directory contains a comprehensive integration of [folke/snacks.nvim](https://github.com/folke/snacks.nvim) into the GigVim nvf-based Neovim configuration. Snacks.nvim is a collection of 26+ small quality-of-life plugins that enhance the Neovim experience. + +## Files Structure + +``` +docs/plugins/ +├── snacks-nvim.md # Comprehensive documentation +├── snacks-nvim-integration.md # Integration guide +└── snacks-nvim-full-example.nix # Example full configuration + +plugins/optional/ +├── snacks-nvim.nix # Default configuration (recommended) +├── TEMPLATE-snacks-nvim-minimal.nix # Conservative setup +├── TEMPLATE-snacks-nvim-dev.nix # Development-focused setup +└── TEMPLATE-snacks-nvim-full.nix # Comprehensive setup + +flake.nix # Updated with snacks-nvim input +``` + +## Configuration Options + +### 1. Default Configuration (`snacks-nvim.nix`) +**Recommended for most users** + +- **Enabled snacks**: bigfile, dashboard, explorer, indent, input, notifier, picker, quickfile, scope, scroll, statuscolumn, words +- **Features**: Core QoL improvements, file explorer, picker, notifications, smooth scrolling +- **Conflicts**: Moderate - may conflict with existing dashboard or file explorer +- **Usage**: Basic setup with essential enhancements + +### 2. Minimal Configuration (`TEMPLATE-snacks-nvim-minimal.nix`) +**Conservative setup for cautious users** + +- **Enabled snacks**: bigfile, input, notifier, quickfile +- **Features**: Essential improvements only +- **Conflicts**: Minimal - very low risk +- **Usage**: When you want snacks benefits with minimal changes + +### 3. Developer Configuration (`TEMPLATE-snacks-nvim-dev.nix`) +**Development-focused workflows** + +- **Enabled snacks**: Core + debug, picker, profiler, git integration, terminal, scratch buffers +- **Features**: Enhanced development tools, debugging, git integration +- **Conflicts**: Moderate - may conflict with existing git/terminal plugins +- **Usage**: Development environments with enhanced tooling + +### 4. Full Configuration (`TEMPLATE-snacks-nvim-full.nix`) +**Power users wanting all features** + +- **Enabled snacks**: All 26+ snacks with comprehensive configuration +- **Features**: Complete snacks.nvim experience +- **Conflicts**: High - extensive potential conflicts +- **Usage**: Power users who want to fully leverage snacks.nvim + +## Quick Start + +### 1. Choose Configuration +Copy the desired configuration template or use the default: + +```nix +# In your full.nix +let + snacksModule = import ./plugins/optional/snacks-nvim.nix { inherit inputs pkgs; }; +in +{ + imports = [ + ./minimal.nix + snacksModule + ]; +} +``` + +### 2. Build and Test +```bash +# Validate +nix flake check + +# Build +nix build + +# Test +./result/bin/nvim +``` + +### 3. Health Check +```vim +:checkhealth snacks +``` + +## Key Features by Configuration + +### Default Configuration Features + +| Feature | Description | Keybind | +|---------|-------------|---------| +| **File Picker** | Smart file finding with fuzzy search | `ff` | +| **Recent Files** | Quick access to recently opened files | `fr` | +| **Text Search** | Grep across project files | `fg` | +| **Buffer Picker** | Navigate between open buffers | `fb` | +| **File Explorer** | Built-in file tree explorer | `e` | +| **Dashboard** | Beautiful startup dashboard | Auto on startup | +| **Notifications** | Enhanced notification system | `n` (history) | +| **Big File Handling** | Optimized handling of large files | Automatic | +| **Smooth Scrolling** | Smooth scrolling animations | Automatic | +| **Status Column** | Enhanced gutter with git signs | Automatic | +| **Word Navigation** | LSP reference navigation | `]]` / `[[` | + +### Developer Configuration Additions + +| Feature | Description | Keybind | +|---------|-------------|---------| +| **Git Browse** | Open files in browser (GitHub/GitLab) | `gB` | +| **LazyGit** | Integrated LazyGit terminal | `gg` | +| **Terminal** | Floating terminal windows | `` | +| **Scratch Buffers** | Temporary scratch files | `.` | +| **Debug Tools** | Enhanced debugging utilities | `dd()`, `bt()` | +| **Profiler** | Lua performance profiling | `:lua Snacks.profiler` | +| **LSP Integration** | Enhanced LSP pickers | `gd`, `gr`, `gI` | + +## Plugin Integrations + +### Compatible with GigVim +- ✅ **Themes**: Works with all GigVim themes +- ✅ **Language Servers**: Enhances LSP experience +- ✅ **nvf core**: Fully compatible with nvf framework +- ✅ **Mini plugins**: Can coexist with mini.nvim suite + +### Potential Conflicts +- ⚠️ **Telescope**: Picker conflicts (choose one or use different keymaps) +- ⚠️ **Dashboard-nvim**: Dashboard conflicts (disable one) +- ⚠️ **Nvim-tree/Neo-tree**: Explorer conflicts (choose one) +- ⚠️ **Nvim-notify**: Notification conflicts (snacks.notifier replaces) + +## Configuration Examples + +### Enable Additional Snacks +```nix +# Add to your configuration +config.vim.extraPlugins.snacks.setup = '' + require('snacks').setup({ + -- Enable git features + git = { enabled = true }, + gitbrowse = { enabled = true }, + lazygit = { enabled = true }, + + -- Enable zen mode + zen = { + enabled = true, + width = 0.8, + height = 0.8, + }, + }) +''; +``` + +### Custom Keymaps +```nix +# Add custom keymaps +vim.keymap.set("n", "my", function() + require("snacks").picker.files({ cwd = "~/my-project" }) +end, { desc = "My Project Files" }) +``` + +### Custom Styling +```nix +# Customize appearance +styles = { + picker = { + border = "double", + width = 0.9, + height = 0.9, + }, + notification = { + border = "rounded", + wo = { wrap = true }, + }, +} +``` + +## Performance Considerations + +1. **Animations**: Disabled by default in templates for better performance +2. **Lazy Loading**: Some snacks support lazy loading patterns +3. **Selective Enabling**: Only enable needed snacks +4. **Startup Time**: Monitor with profiler snack + +## Migration Guide + +### From Telescope +1. Test snacks.picker functionality +2. Migrate custom telescope configurations +3. Update keymaps gradually +4. Disable telescope when satisfied + +### From Other Plugins +- **Dashboard**: Compare dashboard features and migrate sections +- **File Explorer**: Test file operations and git integration +- **Notifications**: Update notification handling code + +## Troubleshooting + +### Common Issues +1. **Build failures**: Check flake.nix input declaration +2. **Plugin not loading**: Verify extraPlugins configuration +3. **Keymaps conflicts**: Review existing keymaps +4. **Performance issues**: Disable unused snacks + +### Debug Commands +```vim +:lua print(vim.inspect(require("snacks.config"))) +:checkhealth snacks +:lua require("snacks").profiler.start() +``` + +## External Resources + +- [Main Repository](https://github.com/folke/snacks.nvim) +- [Official Documentation](https://github.com/folke/snacks.nvim/tree/main/docs) +- [Examples Directory](https://github.com/folke/snacks.nvim/tree/main/docs/examples) +- [Individual Snack Docs](https://github.com/folke/snacks.nvim/tree/main/docs) + +## Contributing + +To improve this integration: + +1. Test with different nvf setups +2. Document conflicts and solutions +3. Add new configuration patterns +4. Update documentation + +--- + +*This integration provides a comprehensive, documented, and templated approach to using snacks.nvim within the nvf framework, following GigVim's patterns and best practices.* \ No newline at end of file diff --git a/docs/plugins/snacks-nvim-full-example.nix b/docs/plugins/snacks-nvim-full-example.nix new file mode 100644 index 0000000..c9d19e3 --- /dev/null +++ b/docs/plugins/snacks-nvim-full-example.nix @@ -0,0 +1,112 @@ +# Example: Integrating snacks.nvim into full.nix +# This example shows how to add snacks.nvim to the full GigVim configuration + +{ inputs, pkgs, ... }: +let + # Import the themery module with inputs passed through + themeryModule = import ./plugins/optional/themery-nvim.nix { inherit inputs pkgs; }; + + # Import snacks.nvim module with inputs passed through + snacksModule = import ./plugins/optional/snacks-nvim.nix { inherit inputs pkgs; }; +in +{ + imports = [ + ./minimal.nix + themeryModule + snacksModule # Add snacks.nvim to the full configuration + ]; + + # Optional: Override specific snacks.nvim settings + config.vim.extraPlugins.snacks.setup = '' + -- Override or extend the default snacks configuration + local default_config = require('snacks').setup({ + -- Your custom snacks configuration here + -- This will override settings from snacks-nvim.nix + + dashboard = { + enabled = true, + sections = { + { section = "header" }, + { section = "keys", gap = 1, padding = 1 }, + { section = "startup" }, + }, + preset = { + header = [[ + ██████╗ ██╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ +██╔════╝ ██║██╔════╝ ██║ ██║██║████╗ ████║ +██║ ███╗██║██║ ███╗██║ ██║██║██╔████╔██║ +██║ ██║██║██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ +╚██████╔╝██║╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ + ╚═════╝ ╚═╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝]], + keys = { + { icon = " ", key = "f", desc = "Find File", action = ":lua Snacks.picker.files()" }, + { icon = " ", key = "n", desc = "New File", action = ":ene | startinsert" }, + { icon = " ", key = "r", desc = "Recent Files", action = ":lua Snacks.picker.recent()" }, + { icon = " ", key = "g", desc = "Find Text", action = ":lua Snacks.picker.grep()" }, + { icon = " ", key = "c", desc = "Config", action = ":lua Snacks.picker.files({cwd = vim.fn.stdpath('config')})" }, + { icon = "󰒲 ", key = "l", desc = "Lazy", action = ":Lazy" }, + { icon = " ", key = "q", desc = "Quit", action = ":qa" }, + }, + }, + }, + + -- Enable additional snacks for full configuration + git = { enabled = true }, + gitbrowse = { enabled = true }, + lazygit = { + enabled = true, + configure = true, + }, + terminal = { enabled = true }, + scratch = { enabled = true }, + zen = { enabled = true }, + + -- Customize notification settings for full config + notifier = { + enabled = true, + timeout = 4000, + width = { min = 40, max = 0.5 }, + height = { min = 1, max = 0.7 }, + margin = { top = 0, right = 1, bottom = 0 }, + sort = { "level", "added" }, + icons = { + error = " ", + warn = " ", + info = " ", + debug = " ", + trace = " ", + }, + }, + }) + + -- Add additional keymaps for full configuration + local opts = { noremap = true, silent = true } + local snacks = require("snacks") + + -- Additional git keymaps + vim.keymap.set("n", "gg", function() snacks.lazygit() end, + vim.tbl_extend("force", opts, { desc = "LazyGit" })) + vim.keymap.set("n", "gB", function() snacks.gitbrowse() end, + vim.tbl_extend("force", opts, { desc = "Git Browse" })) + vim.keymap.set("v", "gB", function() snacks.gitbrowse() end, + vim.tbl_extend("force", opts, { desc = "Git Browse" })) + + -- Terminal keymaps + vim.keymap.set("n", "", function() snacks.terminal() end, + vim.tbl_extend("force", opts, { desc = "Toggle Terminal" })) + vim.keymap.set("n", "", function() snacks.terminal() end, + vim.tbl_extend("force", opts, { desc = "which_key_ignore" })) + + -- Zen mode keymaps + vim.keymap.set("n", "z", function() snacks.zen() end, + vim.tbl_extend("force", opts, { desc = "Toggle Zen Mode" })) + vim.keymap.set("n", "Z", function() snacks.zen.zoom() end, + vim.tbl_extend("force", opts, { desc = "Toggle Zoom" })) + + -- Scratch buffer keymaps + vim.keymap.set("n", ".", function() snacks.scratch() end, + vim.tbl_extend("force", opts, { desc = "Toggle Scratch Buffer" })) + vim.keymap.set("n", "S", function() snacks.scratch.select() end, + vim.tbl_extend("force", opts, { desc = "Select Scratch Buffer" })) + ''; +} \ No newline at end of file diff --git a/docs/plugins/snacks-nvim-integration.md b/docs/plugins/snacks-nvim-integration.md new file mode 100644 index 0000000..bc3d62e --- /dev/null +++ b/docs/plugins/snacks-nvim-integration.md @@ -0,0 +1,271 @@ +# Snacks.nvim Integration Guide for GigVim + +## Overview + +This guide explains how to integrate snacks.nvim into your GigVim configuration using the nvf (NeoVim Flake) framework. + +## Quick Start + +### 1. Add to flake.nix inputs + +The snacks.nvim input is already added to the flake.nix: + +```nix +snacks-nvim = { + url = "github:folke/snacks.nvim"; + flake = false; +}; +``` + +### 2. Choose Your Configuration Level + +GigVim provides three pre-configured snacks.nvim templates: + +#### Basic Configuration (Recommended for new users) +```nix +# In your full.nix or minimal.nix +imports = [ + # ... other imports + (import ./plugins/optional/snacks-nvim.nix { inherit inputs pkgs; }) +]; +``` + +#### Minimal Configuration (Conservative setup) +```nix +# For minimal overhead +imports = [ + (import ./plugins/optional/TEMPLATE-snacks-nvim-minimal.nix { inherit inputs pkgs; }) +]; +``` + +#### Developer Configuration (Development-focused) +```nix +# For development workflows +imports = [ + (import ./plugins/optional/TEMPLATE-snacks-nvim-dev.nix { inherit inputs pkgs; }) +]; +``` + +#### Full Configuration (All features) +```nix +# For power users wanting all features +imports = [ + (import ./plugins/optional/TEMPLATE-snacks-nvim-full.nix { inherit inputs pkgs; }) +]; +``` + +### 3. Build and Test + +```bash +# Validate configuration +export NIX_CONFIG="experimental-features = nix-command flakes" +nix flake check + +# Build configuration +nix build + +# Test the editor +./result/bin/nvim +``` + +## Configuration Templates + +### snacks-nvim.nix (Default) +- **Snacks enabled**: bigfile, dashboard, explorer, indent, input, notifier, picker, quickfile, scope, scroll, statuscolumn, words +- **Use case**: Balanced setup with core quality-of-life improvements +- **Conflicts**: May conflict with existing dashboard, picker, or file explorer configurations + +### TEMPLATE-snacks-nvim-minimal.nix +- **Snacks enabled**: bigfile, input, notifier, quickfile +- **Use case**: Conservative users wanting minimal changes to their workflow +- **Conflicts**: Minimal risk of conflicts + +### TEMPLATE-snacks-nvim-dev.nix +- **Snacks enabled**: Core + debug, picker, profiler, git integration, terminal, scratch buffers +- **Use case**: Development-focused workflows with debugging and git integration +- **Conflicts**: May conflict with existing git plugins, terminal, or picker configurations + +### TEMPLATE-snacks-nvim-full.nix +- **Snacks enabled**: All 26+ snacks with comprehensive configuration +- **Use case**: Power users who want to leverage all snacks.nvim capabilities +- **Conflicts**: High potential for conflicts with existing plugins + +## Conflict Resolution + +### Common Plugin Conflicts + +1. **Dashboard/Startscreen Conflicts** + - snacks.dashboard conflicts with: alpha-nvim, dashboard-nvim, startify + - Solution: Disable conflicting plugins or set `dashboard = { enabled = false }` + +2. **File Explorer Conflicts** + - snacks.explorer conflicts with: nvim-tree, neo-tree, oil.nvim + - Solution: Disable conflicting plugins or set `explorer = { enabled = false }` + +3. **Picker/Finder Conflicts** + - snacks.picker conflicts with: telescope, fzf-lua + - Solution: Choose one picker system or configure both with different keymaps + +4. **Notification Conflicts** + - snacks.notifier conflicts with: nvim-notify, mini.notify + - Solution: Disable conflicting plugins or set `notifier = { enabled = false }` + +5. **Scroll/Animation Conflicts** + - snacks.scroll conflicts with: neoscroll, smooth-scrolling plugins + - Solution: Disable conflicting plugins or set `scroll = { enabled = false }` + +### nvf-Specific Considerations + +1. **extraPlugins Priority** + - Snacks.nvim should be loaded early (priority = 1000, lazy = false) + - May need to adjust other plugin loading order + +2. **vim.ui Replacements** + - snacks.input replaces vim.ui.input + - May conflict with other UI replacement plugins + +3. **LSP Integration** + - Some snacks integrate with LSP (words, picker, rename) + - Ensure LSP is properly configured before enabling these snacks + +## Customization + +### Enabling/Disabling Individual Snacks + +```nix +# In your configuration file +setup = '' + require('snacks').setup({ + -- Enable specific snacks + dashboard = { enabled = true }, + picker = { enabled = true }, + + -- Disable specific snacks + zen = { enabled = false }, + terminal = { enabled = false }, + + -- Configure snack options + notifier = { + enabled = true, + timeout = 5000, + width = { min = 40, max = 0.6 }, + }, + }) +''; +``` + +### Custom Keymaps + +```nix +# Add custom keymaps in the setup section +vim.keymap.set("n", "my", function() + require("snacks").picker.files({ cwd = "~/my-project" }) +end, { desc = "My Project Files" }) +``` + +### Styling + +```nix +# Customize window styles +styles = { + notification = { + border = "double", + wo = { wrap = true }, + }, + picker = { + border = "rounded", + width = 0.9, + height = 0.9, + }, +}, +``` + +## Health Check + +After setup, run the health check to verify configuration: + +```vim +:checkhealth snacks +``` + +Common issues and solutions: + +- **Missing dependencies**: Install required tools (git, ripgrep, fd) +- **Keymap conflicts**: Review and resolve conflicting keymaps +- **Performance issues**: Disable unused snacks or animations + +## Migration Strategies + +### From Telescope to Snacks Picker + +1. **Gradual migration**: Enable snacks.picker alongside telescope +2. **Different keymaps**: Use different leader keys for each +3. **Feature comparison**: Test equivalent functionality +4. **Full switch**: Disable telescope after successful migration + +### From Dashboard-nvim to Snacks Dashboard + +1. **Compare features**: Ensure snacks.dashboard meets your needs +2. **Custom sections**: Migrate custom dashboard sections +3. **Keymaps**: Update dashboard-related keymaps + +### From Nvim-tree to Snacks Explorer + +1. **Feature parity**: Test file operations and navigation +2. **Keymaps**: Update file explorer keymaps +3. **Integration**: Check integration with git and other tools + +## Performance Considerations + +1. **Disable animations**: Set `animate = { enabled = false }` for better performance +2. **Selective enabling**: Only enable snacks you actively use +3. **Lazy loading**: Some snacks support lazy loading patterns +4. **Startup time**: Monitor startup time with `:StartupTime` or similar + +## Troubleshooting + +### Build Failures + +1. **Missing inputs**: Ensure snacks-nvim input is properly declared +2. **Syntax errors**: Check Nix syntax in configuration files +3. **Import errors**: Verify import paths and parameter passing + +### Runtime Issues + +1. **Plugin not loading**: Check extraPlugins configuration +2. **Keymaps not working**: Verify keymap conflicts and setup +3. **Features missing**: Ensure snacks are explicitly enabled +4. **Performance problems**: Profile and disable problematic snacks + +### Debug Commands + +```vim +" Check snacks configuration +:lua print(vim.inspect(require("snacks.config"))) + +" Debug specific snack +:lua require("snacks").debug.inspect(require("snacks.picker").config) + +" Health check +:checkhealth snacks +``` + +## External Resources + +- [Official Documentation](https://github.com/folke/snacks.nvim) +- [Individual Snack Docs](https://github.com/folke/snacks.nvim/tree/main/docs) +- [Examples](https://github.com/folke/snacks.nvim/tree/main/docs/examples) +- [Health Check Guide](https://github.com/folke/snacks.nvim/blob/main/docs/health.md) + +## Contributing + +To improve these templates or add new configurations: + +1. Test thoroughly with different nvf setups +2. Document any conflicts or issues +3. Follow nvf best practices for plugin integration +4. Update this guide with new findings + +--- + +*This integration guide is maintained as part of the GigVim project and reflects best practices for nvf-based Neovim configurations.* \ No newline at end of file diff --git a/docs/plugins/snacks-nvim.md b/docs/plugins/snacks-nvim.md new file mode 100644 index 0000000..2ebe3fc --- /dev/null +++ b/docs/plugins/snacks-nvim.md @@ -0,0 +1,188 @@ +# Snacks.nvim Plugin Documentation for GigVim + +## Overview + +[Snacks.nvim](https://github.com/folke/snacks.nvim) is a collection of small QoL (Quality of Life) plugins for Neovim developed by Folke Lemaitre. It provides 26+ individual "snacks" (sub-plugins) that enhance the Neovim experience with various utilities, UI improvements, and developer tools. + +## Plugin Philosophy + +Snacks.nvim follows a modular design philosophy where each feature (snack) can be independently enabled or disabled. This allows users to pick and choose only the functionality they need, keeping the configuration lean and performant. + +## Requirements + +- **Neovim** >= 0.9.4 +- **Optional**: [mini.icons](https://github.com/echasnovski/mini.icons) or [nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) +- **Optional**: A [Nerd Font](https://www.nerdfonts.com/) for proper icon support + +## Available Snacks + +### Core UI & Interaction + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[animate](https://github.com/folke/snacks.nvim/blob/main/docs/animate.md)** | Efficient animations with 45+ easing functions | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/animate.md) | +| **[input](https://github.com/folke/snacks.nvim/blob/main/docs/input.md)** | Better `vim.ui.input` replacement | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/input.md) | +| **[notifier](https://github.com/folke/snacks.nvim/blob/main/docs/notifier.md)** | Pretty `vim.notify` notifications | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/notifier.md) | +| **[picker](https://github.com/folke/snacks.nvim/blob/main/docs/picker.md)** | Advanced picker for selecting items | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/picker.md) | +| **[statuscolumn](https://github.com/folke/snacks.nvim/blob/main/docs/statuscolumn.md)** | Enhanced status column | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/statuscolumn.md) | +| **[dashboard](https://github.com/folke/snacks.nvim/blob/main/docs/dashboard.md)** | Beautiful declarative dashboards | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/dashboard.md) | + +### File Management & Navigation + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[explorer](https://github.com/folke/snacks.nvim/blob/main/docs/explorer.md)** | File explorer (picker in disguise) | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/explorer.md) | +| **[bigfile](https://github.com/folke/snacks.nvim/blob/main/docs/bigfile.md)** | Handle big files efficiently | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/bigfile.md) | +| **[quickfile](https://github.com/folke/snacks.nvim/blob/main/docs/quickfile.md)** | Quick file rendering before plugins load | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/quickfile.md) | +| **[bufdelete](https://github.com/folke/snacks.nvim/blob/main/docs/bufdelete.md)** | Delete buffers without disrupting layout | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/bufdelete.md) | +| **[rename](https://github.com/folke/snacks.nvim/blob/main/docs/rename.md)** | LSP-integrated file renaming | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/rename.md) | + +### Git Integration + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[git](https://github.com/folke/snacks.nvim/blob/main/docs/git.md)** | Git utilities | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/git.md) | +| **[gitbrowse](https://github.com/folke/snacks.nvim/blob/main/docs/gitbrowse.md)** | Open files/repos in browser (GitHub, GitLab, etc.) | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/gitbrowse.md) | +| **[lazygit](https://github.com/folke/snacks.nvim/blob/main/docs/lazygit.md)** | LazyGit integration with auto-configured colorscheme | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/lazygit.md) | + +### Development Tools + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[debug](https://github.com/folke/snacks.nvim/blob/main/docs/debug.md)** | Pretty inspect & backtraces for debugging | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/debug.md) | +| **[profiler](https://github.com/folke/snacks.nvim/blob/main/docs/profiler.md)** | Neovim lua profiler | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/profiler.md) | +| **[terminal](https://github.com/folke/snacks.nvim/blob/main/docs/terminal.md)** | Create and toggle floating/split terminals | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/terminal.md) | +| **[scratch](https://github.com/folke/snacks.nvim/blob/main/docs/scratch.md)** | Scratch buffers with persistent files | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/scratch.md) | + +### Visual Enhancements + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[scope](https://github.com/folke/snacks.nvim/blob/main/docs/scope.md)** | Scope detection and text objects | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/scope.md) | +| **[indent](https://github.com/folke/snacks.nvim/blob/main/docs/indent.md)** | Indent guides and scopes | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/indent.md) | +| **[dim](https://github.com/folke/snacks.nvim/blob/main/docs/dim.md)** | Focus by dimming inactive scope | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/dim.md) | +| **[scroll](https://github.com/folke/snacks.nvim/blob/main/docs/scroll.md)** | Smooth scrolling | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/scroll.md) | +| **[zen](https://github.com/folke/snacks.nvim/blob/main/docs/zen.md)** | Zen mode for distraction-free coding | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/zen.md) | +| **[image](https://github.com/folke/snacks.nvim/blob/main/docs/image.md)** | Image viewer using Kitty Graphics Protocol | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/image.md) | + +### Text Processing & LSP + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[words](https://github.com/folke/snacks.nvim/blob/main/docs/words.md)** | Auto-show LSP references and navigation | ‼️ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/words.md) | +| **[notify](https://github.com/folke/snacks.nvim/blob/main/docs/notify.md)** | Utility functions for `vim.notify` | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/notify.md) | + +### Utilities & Infrastructure + +| Snack | Description | Setup Required | External Docs | +|-------|-------------|:--------------:|:-------------:| +| **[layout](https://github.com/folke/snacks.nvim/blob/main/docs/layout.md)** | Window layout management | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/layout.md) | +| **[toggle](https://github.com/folke/snacks.nvim/blob/main/docs/toggle.md)** | Toggle keymaps with which-key integration | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/toggle.md) | +| **[win](https://github.com/folke/snacks.nvim/blob/main/docs/win.md)** | Create and manage floating windows/splits | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/win.md) | +| **[util](https://github.com/folke/snacks.nvim/blob/main/docs/util.md)** | Utility functions for Snacks _(library)_ | ⚪ | [📖](https://github.com/folke/snacks.nvim/blob/main/docs/util.md) | + +**Legend:** +- ‼️ = Requires explicit setup configuration +- ⚪ = Works with minimal or no configuration + +## Integration with nvf (NeoVim Flake) + +Snacks.nvim presents unique challenges for nvf integration due to its: + +1. **Early initialization requirements** (priority = 1000, lazy = false) +2. **Modular architecture** with 26+ individual components +3. **Complex configuration structure** with nested options +4. **Special autocmd setup** that must happen during plugin initialization + +### nvf Integration Strategy + +Since nvf doesn't natively support snacks.nvim, we use the `extraPlugins` mechanism with special considerations: + +1. **Early Setup**: Use `vim.cmd` or init scripts to ensure early initialization +2. **Modular Configuration**: Provide templates for common use cases +3. **Incremental Adoption**: Allow enabling individual snacks as needed +4. **Conflict Resolution**: Handle conflicts with existing nvf plugins + +## Key Configuration Principles + +### 1. Priority and Lazy Loading +```lua +-- Required for proper initialization +priority = 1000, +lazy = false, +``` + +### 2. Explicit Enablement +```lua +-- Each snack must be explicitly enabled +opts = { + bigfile = { enabled = true }, + dashboard = { enabled = true }, + -- ... other snacks +} +``` + +### 3. Init Function for Early Setup +```lua +init = function() + vim.api.nvim_create_autocmd("User", { + pattern = "VeryLazy", + callback = function() + -- Late initialization code + end, + }) +end, +``` + +## Health Check + +Snacks.nvim provides a health check to verify proper setup: + +```vim +:checkhealth snacks +``` + +## Official Resources + +- **Main Repository**: [folke/snacks.nvim](https://github.com/folke/snacks.nvim) +- **Documentation**: [docs/](https://github.com/folke/snacks.nvim/tree/main/docs) +- **Examples**: [docs/examples/](https://github.com/folke/snacks.nvim/tree/main/docs/examples) + +## GigVim Integration Files + +This plugin integration includes: + +1. **Main Configuration**: `plugins/optional/snacks-nvim.nix` - Core plugin setup +2. **Template Files**: Individual snack configuration templates +3. **Examples**: Common configuration patterns for nvf +4. **Documentation**: This file and integration guides + +## Migration Notes + +When adding snacks.nvim to an existing nvf configuration: + +1. **Review Conflicts**: Check for plugins that snacks.nvim might replace +2. **Gradual Migration**: Enable snacks one at a time +3. **Test Thoroughly**: Some snacks modify core Neovim behavior +4. **Backup Configuration**: Keep backups of working configurations + +## Troubleshooting + +### Common Issues + +1. **Plugin doesn't load**: Ensure `lazy = false` and `priority = 1000` +2. **Features not working**: Verify explicit `enabled = true` for each snack +3. **Conflicts with other plugins**: Disable conflicting nvf plugins +4. **Performance issues**: Disable unused snacks to improve startup time + +### Debug Commands + +```vim +:lua print(vim.inspect(require("snacks.config"))) +:checkhealth snacks +:Snacks profiler +``` + +--- + +*This documentation is maintained as part of the GigVim project and reflects the integration patterns specific to nvf-based Neovim configurations.* \ No newline at end of file diff --git a/flake.lock b/flake.lock index 87c6f04..098deff 100644 --- a/flake.lock +++ b/flake.lock @@ -1466,6 +1466,7 @@ ], "nixpkgs": "nixpkgs_17", "nvf": "nvf", + "snacks-nvim": "snacks-nvim", "themery-nvim": "themery-nvim" } }, @@ -1670,6 +1671,22 @@ "type": "github" } }, + "snacks-nvim": { + "flake": false, + "locked": { + "lastModified": 1740868622, + "narHash": "sha256-Gw0Bp2YeoESiBLs3NPnqke3xwEjuiQDDU1CPofrhtig=", + "owner": "folke", + "repo": "snacks.nvim", + "rev": "bc0630e43be5699bb94dadc302c0d21615421d93", + "type": "github" + }, + "original": { + "owner": "folke", + "repo": "snacks.nvim", + "type": "github" + } + }, "sops-nix": { "inputs": { "nixpkgs": [ diff --git a/flake.nix b/flake.nix index 3142d5f..2a39455 100644 --- a/flake.nix +++ b/flake.nix @@ -15,6 +15,10 @@ url = "github:zaldih/themery.nvim"; flake = false; }; + snacks-nvim = { + url = "github:folke/snacks.nvim"; + flake = false; + }; }; outputs = diff --git a/full.nix b/full.nix index d964afc..90f040f 100644 --- a/full.nix +++ b/full.nix @@ -1,11 +1,13 @@ { inputs, pkgs, ... }: let + snacksModule = import ./plugins/optional/snacks-nvim.nix { inherit inputs pkgs; }; # Import the themery module with inputs passed through themeryModule = import ./plugins/optional/themery-nvim.nix { inherit inputs pkgs; }; in { imports = [ ./minimal.nix - themeryModule + # themeryModule + snacksModule ]; } diff --git a/plugins/optional/TEMPLATE-snacks-nvim-dev.nix b/plugins/optional/TEMPLATE-snacks-nvim-dev.nix new file mode 100644 index 0000000..1f50cb9 --- /dev/null +++ b/plugins/optional/TEMPLATE-snacks-nvim-dev.nix @@ -0,0 +1,356 @@ +# Snacks.nvim Developer Configuration Template +# Development-focused snacks for enhanced coding experience +# Documentation: https://github.com/folke/snacks.nvim + +{ inputs, pkgs, lib, ... }: +let + snacks-from-source = pkgs.vimUtils.buildVimPlugin { + name = "snacks-nvim"; + src = inputs.snacks-nvim; + }; +in +{ + config.vim = { + extraPlugins = { + snacks-dev = { + package = snacks-from-source; + setup = '' + -- Developer-focused Snacks.nvim setup + require('snacks').setup({ + -- Core functionality + bigfile = { + enabled = true, + size = 1.5 * 1024 * 1024, -- 1.5MB + }, + + input = { + enabled = true, + }, + + notifier = { + enabled = true, + timeout = 3000, + width = { min = 40, max = 0.4 }, + height = { min = 1, max = 0.6 }, + }, + + quickfile = { + enabled = true, + }, + + -- Developer-specific features + debug = { + enabled = true, + -- Pretty inspect and backtraces for debugging + }, + + picker = { + enabled = true, + win = { + input = { + keys = { + [""] = { "close", mode = { "i", "n" } }, + [""] = { "close", mode = { "i", "n" } }, + [""] = { "select_next", mode = { "i", "n" } }, + [""] = { "select_prev", mode = { "i", "n" } }, + }, + }, + }, + sources = { + files = { + hidden = false, + follow = true, + ignored = true, + }, + grep = { + hidden = false, + follow = true, + ignored = true, + }, + }, + }, + + profiler = { + enabled = true, + -- Performance profiling for Lua code + }, + + git = { + enabled = true, + }, + + gitbrowse = { + enabled = true, + url_patterns = { + ["github%.com"] = { + branch = "/tree/{branch}", + file = "/blob/{branch}/{file}#L{line_start}-L{line_end}", + commit = "/commit/{commit}", + }, + ["gitlab%.com"] = { + branch = "/-/tree/{branch}", + file = "/-/blob/{branch}/{file}#L{line_start}-{line_end}", + commit = "/-/commit/{commit}", + }, + }, + }, + + lazygit = { + enabled = true, + configure = true, + win = { + width = 0.9, + height = 0.9, + border = "rounded", + }, + }, + + rename = { + enabled = true, + -- LSP-integrated file renaming + }, + + scratch = { + enabled = true, + name = "scratch", + ft = function() + if vim.bo.buftype == "" and vim.bo.filetype == "" then + return "markdown" + end + return vim.bo.filetype + end, + root = vim.fn.stdpath("cache") .. "/scratch", + autowrite = true, + autohide = true, + win_by_ft = { + lua = { + keys = { + ["source"] = { + "", + function(self) + local name = "scratch." .. vim.fn.fnamemodify(vim.api.nvim_buf_get_name(self.buf), ":e") + Snacks.debug.run({ buf = self.buf, name = name }) + end, + desc = "Source buffer", + mode = { "n", "x" }, + }, + }, + }, + }, + }, + + terminal = { + enabled = true, + shell = vim.o.shell, + win = { + style = "terminal", + width = 0.8, + height = 0.8, + border = "rounded", + }, + }, + + toggle = { + enabled = true, + notify = true, + which_key = true, + icon = { + enabled = "󰔡 ", + disabled = "󰨆 ", + }, + color = { + enabled = "green", + disabled = "yellow", + }, + }, + + words = { + enabled = true, + debounce = 200, + notify_jump = false, + notify_end = true, + foldopen = true, + jumplist = true, + modes = { "n", "i", "c" }, + }, + + scope = { + enabled = true, + max_size = 50, + min_size = 2, + cursor = true, + treesitter = { + enabled = true, + blocks = { + "function_item", + "function_definition", + "method_definition", + "class_definition", + "do_statement", + "while_statement", + "repeat_statement", + "if_statement", + "for_statement", + }, + }, + }, + + indent = { + enabled = true, + animate = { + enabled = false, -- Disable for performance + }, + scope = { + enabled = true, + animate = false, + }, + }, + + -- Disabled features for focused development experience + animate = { enabled = false }, + bufdelete = { enabled = false }, + dashboard = { enabled = false }, + dim = { enabled = false }, + explorer = { enabled = false }, + image = { enabled = false }, + layout = { enabled = false }, + notify = { enabled = false }, + scroll = { enabled = false }, + statuscolumn = { enabled = false }, + util = { enabled = false }, + win = { enabled = false }, + zen = { enabled = false }, + + -- Development-focused styles + styles = { + notification = { + wo = { wrap = true }, + border = "rounded", + }, + input = { + border = "rounded", + title_pos = "center", + }, + picker = { + border = "rounded", + title_pos = "center", + width = 0.8, + height = 0.8, + }, + terminal = { + border = "rounded", + title_pos = "center", + width = 0.8, + height = 0.8, + }, + }, + }) + + -- Developer-focused keymaps + local opts = { noremap = true, silent = true } + local snacks = require("snacks") + + -- File operations + vim.keymap.set("n", "", function() snacks.picker.smart() end, + vim.tbl_extend("force", opts, { desc = "Smart Find Files" })) + vim.keymap.set("n", "ff", function() snacks.picker.files() end, + vim.tbl_extend("force", opts, { desc = "Find Files" })) + vim.keymap.set("n", "fr", function() snacks.picker.recent() end, + vim.tbl_extend("force", opts, { desc = "Recent Files" })) + vim.keymap.set("n", "fg", function() snacks.picker.grep() end, + vim.tbl_extend("force", opts, { desc = "Grep Files" })) + vim.keymap.set("n", "fb", function() snacks.picker.buffers() end, + vim.tbl_extend("force", opts, { desc = "Find Buffers" })) + vim.keymap.set("n", "fc", function() snacks.picker.files({ cwd = vim.fn.stdpath("config") }) end, + vim.tbl_extend("force", opts, { desc = "Config Files" })) + + -- Git operations + vim.keymap.set("n", "gb", function() snacks.picker.git_branches() end, + vim.tbl_extend("force", opts, { desc = "Git Branches" })) + vim.keymap.set("n", "gl", function() snacks.picker.git_log() end, + vim.tbl_extend("force", opts, { desc = "Git Log" })) + vim.keymap.set("n", "gs", function() snacks.picker.git_status() end, + vim.tbl_extend("force", opts, { desc = "Git Status" })) + vim.keymap.set("n", "gB", function() snacks.gitbrowse() end, + vim.tbl_extend("force", opts, { desc = "Git Browse" })) + vim.keymap.set("v", "gB", function() snacks.gitbrowse() end, + vim.tbl_extend("force", opts, { desc = "Git Browse" })) + vim.keymap.set("n", "gg", function() snacks.lazygit() end, + vim.tbl_extend("force", opts, { desc = "LazyGit" })) + + -- LSP integration + vim.keymap.set("n", "gd", function() snacks.picker.lsp_definitions() end, + vim.tbl_extend("force", opts, { desc = "Goto Definition" })) + vim.keymap.set("n", "gr", function() snacks.picker.lsp_references() end, + vim.tbl_extend("force", opts, { desc = "References" })) + vim.keymap.set("n", "gI", function() snacks.picker.lsp_implementations() end, + vim.tbl_extend("force", opts, { desc = "Goto Implementation" })) + vim.keymap.set("n", "gy", function() snacks.picker.lsp_type_definitions() end, + vim.tbl_extend("force", opts, { desc = "Goto Type Definition" })) + vim.keymap.set("n", "ss", function() snacks.picker.lsp_symbols() end, + vim.tbl_extend("force", opts, { desc = "LSP Symbols" })) + vim.keymap.set("n", "sS", function() snacks.picker.lsp_workspace_symbols() end, + vim.tbl_extend("force", opts, { desc = "LSP Workspace Symbols" })) + + -- Development tools + vim.keymap.set("n", ".", function() snacks.scratch() end, + vim.tbl_extend("force", opts, { desc = "Toggle Scratch Buffer" })) + vim.keymap.set("n", "S", function() snacks.scratch.select() end, + vim.tbl_extend("force", opts, { desc = "Select Scratch Buffer" })) + + vim.keymap.set("n", "", function() snacks.terminal() end, + vim.tbl_extend("force", opts, { desc = "Toggle Terminal" })) + vim.keymap.set("n", "", function() snacks.terminal() end, + vim.tbl_extend("force", opts, { desc = "which_key_ignore" })) + + vim.keymap.set("n", "cR", function() snacks.rename.rename_file() end, + vim.tbl_extend("force", opts, { desc = "Rename File" })) + + -- Word navigation + vim.keymap.set("n", "]]", function() snacks.words.jump(vim.v.count1) end, + vim.tbl_extend("force", opts, { desc = "Next Reference" })) + vim.keymap.set("n", "[[", function() snacks.words.jump(-vim.v.count1) end, + vim.tbl_extend("force", opts, { desc = "Prev Reference" })) + + -- Notifications + vim.keymap.set("n", "n", function() snacks.notifier.show_history() end, + vim.tbl_extend("force", opts, { desc = "Notification History" })) + vim.keymap.set("n", "un", function() snacks.notifier.hide() end, + vim.tbl_extend("force", opts, { desc = "Dismiss All Notifications" })) + + -- Diagnostics and search + vim.keymap.set("n", "sd", function() snacks.picker.diagnostics() end, + vim.tbl_extend("force", opts, { desc = "Diagnostics" })) + vim.keymap.set("n", "sD", function() snacks.picker.diagnostics_buffer() end, + vim.tbl_extend("force", opts, { desc = "Buffer Diagnostics" })) + vim.keymap.set("n", "sh", function() snacks.picker.help() end, + vim.tbl_extend("force", opts, { desc = "Help Pages" })) + vim.keymap.set("n", "sk", function() snacks.picker.keymaps() end, + vim.tbl_extend("force", opts, { desc = "Keymaps" })) + + -- Setup late initialization for development features + vim.api.nvim_create_autocmd("User", { + pattern = "VeryLazy", + callback = function() + -- Setup debugging globals + _G.dd = function(...) snacks.debug.inspect(...) end + _G.bt = function() snacks.debug.backtrace() end + vim.print = _G.dd + + -- Create useful toggle mappings for development + snacks.toggle.option("spell", { name = "Spelling" }):map("us") + snacks.toggle.option("wrap", { name = "Wrap" }):map("uw") + snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("uL") + snacks.toggle.diagnostics():map("ud") + snacks.toggle.line_number():map("ul") + snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }):map("uc") + snacks.toggle.treesitter():map("uT") + snacks.toggle.inlay_hints():map("uh") + snacks.toggle.indent():map("ug") + end, + }) + ''; + }; + }; + }; +} \ No newline at end of file diff --git a/plugins/optional/TEMPLATE-snacks-nvim-full.nix b/plugins/optional/TEMPLATE-snacks-nvim-full.nix new file mode 100644 index 0000000..7a41cf4 --- /dev/null +++ b/plugins/optional/TEMPLATE-snacks-nvim-full.nix @@ -0,0 +1,607 @@ +# Snacks.nvim Full Configuration Template +# This template includes all available snacks with extensive configuration options +# Documentation: https://github.com/folke/snacks.nvim + +{ inputs, pkgs, lib, ... }: +let + snacks-from-source = pkgs.vimUtils.buildVimPlugin { + name = "snacks-nvim"; + src = inputs.snacks-nvim; + }; +in +{ + config.vim = { + extraPlugins = { + snacks-full = { + package = snacks-from-source; + setup = '' + -- Full Snacks.nvim setup with all features enabled + require('snacks').setup({ + -- Animation system + animate = { + enabled = true, + duration = 20, + easing = "linear", + fps = 60, + }, + + -- Big file handling + bigfile = { + enabled = true, + size = 1.5 * 1024 * 1024, -- 1.5MB + setup = function(ctx) + vim.cmd([[NoMatchParen]]) + vim.api.nvim_buf_set_option(ctx.buf, 'foldmethod', 'manual') + vim.api.nvim_buf_set_option(ctx.buf, 'spell', false) + vim.api.nvim_buf_set_option(ctx.buf, 'wrap', false) + vim.api.nvim_buf_set_option(ctx.buf, 'undofile', false) + vim.api.nvim_buf_set_option(ctx.buf, 'swapfile', false) + vim.api.nvim_buf_set_option(ctx.buf, 'synmaxcol', 200) + end, + }, + + -- Buffer deletion + bufdelete = { + enabled = true, + }, + + -- Dashboard + dashboard = { + enabled = true, + sections = { + { section = "header" }, + { section = "keys", gap = 1, padding = 1 }, + { section = "startup" }, + { section = "mru", limit = 10, gap = 1, padding = 1 }, + { section = "projects", limit = 8 }, + }, + preset = { + header = [[ + ██████╗ ██╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ +██╔════╝ ██║██╔════╝ ██║ ██║██║████╗ ████║ +██║ ███╗██║██║ ███╗██║ ██║██║██╔████╔██║ +██║ ██║██║██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ +╚██████╔╝██║╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ + ╚═════╝ ╚═╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝]], + keys = { + { icon = " ", key = "f", desc = "Find File", action = ":lua Snacks.picker.files()" }, + { icon = " ", key = "n", desc = "New File", action = ":ene | startinsert" }, + { icon = " ", key = "r", desc = "Recent Files", action = ":lua Snacks.picker.recent()" }, + { icon = " ", key = "g", desc = "Find Text", action = ":lua Snacks.picker.grep()" }, + { icon = " ", key = "c", desc = "Config", action = ":lua Snacks.picker.files({cwd = vim.fn.stdpath('config')})" }, + { icon = " ", key = "s", desc = "Restore Session", section = "session" }, + { icon = "󰒲 ", key = "l", desc = "Lazy", action = ":Lazy" }, + { icon = " ", key = "q", desc = "Quit", action = ":qa" }, + }, + }, + }, + + -- Debug utilities + debug = { + enabled = true, + -- Pretty inspect and backtraces + }, + + -- Dimming inactive scope + dim = { + enabled = true, + scope = { + min_size = 5, + max_size = 20, + siblings = true, + }, + animate = { + enabled = true, + easing = "outQuad", + duration = 300, + }, + }, + + -- File explorer + explorer = { + enabled = true, + replace_netrw = true, + win = { + width = 40, + height = 0.8, + border = "rounded", + }, + }, + + -- Git utilities + git = { + enabled = true, + }, + + -- Git browse + gitbrowse = { + enabled = true, + url_patterns = { + ["github%.com"] = { + branch = "/tree/{branch}", + file = "/blob/{branch}/{file}#L{line_start}-L{line_end}", + commit = "/commit/{commit}", + }, + ["gitlab%.com"] = { + branch = "/-/tree/{branch}", + file = "/-/blob/{branch}/{file}#L{line_start}-{line_end}", + commit = "/-/commit/{commit}", + }, + }, + }, + + -- Image viewing + image = { + enabled = true, + backends = { "kitty", "viu" }, + integrations = { + markdown = { + enabled = true, + clear_in_insert_mode = false, + download_images = false, + only_render_image_at_cursor = false, + filetypes = { "markdown", "vimwiki" }, + }, + }, + }, + + -- Indent guides + indent = { + enabled = true, + animate = { + enabled = true, + duration = { + step = 20, + total = 500, + }, + easing = "linear", + }, + chunk = { + enabled = true, + only_current = false, + priority = 200, + hl = { + "SnacksIndentChunk1", + "SnacksIndentChunk2", + "SnacksIndentChunk3", + "SnacksIndentChunk4", + "SnacksIndentChunk5", + "SnacksIndentChunk6", + "SnacksIndentChunk7", + "SnacksIndentChunk8", + }, + }, + scope = { + enabled = true, + animate = true, + priority = 200, + hl = { + "SnacksIndentScope1", + "SnacksIndentScope2", + "SnacksIndentScope3", + "SnacksIndentScope4", + "SnacksIndentScope5", + "SnacksIndentScope6", + "SnacksIndentScope7", + "SnacksIndentScope8", + }, + }, + }, + + -- Input replacement + input = { + enabled = true, + icon = " ", + icon_hl = "SnacksInputIcon", + icon_pos = "left", + prompt_pos = "title", + win = { style = "input" }, + }, + + -- Layout management + layout = { + enabled = true, + preset = { + layout = { + box = "horizontal", + { box = "vertical", { win = "main" }, { win = "footer", height = 3 } }, + { box = "vertical", width = 40, { win = "left" }, { win = "left_footer", height = 3 } }, + }, + }, + }, + + -- LazyGit integration + lazygit = { + enabled = true, + configure = true, + win = { + width = 0.9, + height = 0.9, + border = "rounded", + }, + }, + + -- Notifications + notifier = { + enabled = true, + timeout = 3000, + width = { min = 40, max = 0.4 }, + height = { min = 1, max = 0.6 }, + margin = { top = 0, right = 1, bottom = 0 }, + padding = true, + sort = { "level", "added" }, + level = vim.log.levels.TRACE, + icons = { + error = " ", + warn = " ", + info = " ", + debug = " ", + trace = " ", + }, + keep = function(notif) + return vim.fn.fnamemodify(notif.msg[1], ":t") ~= "mini.starter" + end, + }, + + -- Notify utilities + notify = { + enabled = true, + }, + + -- Picker + picker = { + enabled = true, + win = { + input = { + keys = { + [""] = { "close", mode = { "i", "n" } }, + [""] = { "close", mode = { "i", "n" } }, + [""] = { "select_next", mode = { "i", "n" } }, + [""] = { "select_prev", mode = { "i", "n" } }, + }, + }, + }, + sources = { + files = { + hidden = false, + follow = true, + ignored = true, + }, + grep = { + hidden = false, + follow = true, + ignored = true, + }, + }, + }, + + -- Profiler + profiler = { + enabled = true, + -- Lua profiler for performance analysis + }, + + -- Quick file loading + quickfile = { + enabled = true, + exclude = { "gitcommit", "gitrebase" }, + }, + + -- File renaming + rename = { + enabled = true, + -- LSP-integrated file renaming + }, + + -- Scope detection + scope = { + enabled = true, + max_size = 50, + min_size = 2, + edge = true, + cursor = true, + indent = { + enabled = true, + only_current = false, + }, + chunk = { + enabled = true, + only_current = false, + }, + treesitter = { + enabled = true, + blocks = { + "function_item", + "function_definition", + "method_definition", + "class_definition", + "do_statement", + "while_statement", + "repeat_statement", + "if_statement", + "for_statement", + }, + }, + }, + + -- Scratch buffers + scratch = { + enabled = true, + name = "scratch", + ft = function() + if vim.bo.buftype == "" and vim.bo.filetype == "" then + return "markdown" + end + return vim.bo.filetype + end, + icon = nil, + root = vim.fn.stdpath("cache") .. "/scratch", + autowrite = true, + autohide = true, + win_by_ft = { + lua = { + keys = { + ["source"] = { + "", + function(self) + local name = "scratch." .. vim.fn.fnamemodify(vim.api.nvim_buf_get_name(self.buf), ":e") + Snacks.debug.run({ buf = self.buf, name = name }) + end, + desc = "Source buffer", + mode = { "n", "x" }, + }, + }, + }, + }, + }, + + -- Smooth scrolling + scroll = { + enabled = true, + animate = { + duration = { step = 15, total = 250 }, + easing = "linear", + }, + spamming = 10, + -- Smooth scrolling for better UX + }, + + -- Status column + statuscolumn = { + enabled = true, + left = { "mark", "sign" }, + right = { "fold", "git" }, + folds = { + open = true, + git_hl = true, + }, + git = { + patterns = { "GitSign", "MiniDiffSign" }, + }, + refresh = 50, + }, + + -- Terminal + terminal = { + enabled = true, + shell = vim.o.shell, + win = { + style = "terminal", + }, + }, + + -- Toggle utilities + toggle = { + enabled = true, + notify = true, + which_key = true, + icon = { + enabled = "󰔡 ", + disabled = "󰨆 ", + }, + color = { + enabled = "green", + disabled = "yellow", + }, + }, + + -- Utility functions + util = { + enabled = true, + }, + + -- Window management + win = { + enabled = true, + -- Advanced window creation and management + }, + + -- LSP word references + words = { + enabled = true, + debounce = 200, + notify_jump = false, + notify_end = true, + foldopen = true, + jumplist = true, + modes = { "n", "i", "c" }, + }, + + -- Zen mode + zen = { + enabled = true, + toggles = { + dim = true, + git_signs = false, + mini_diff_signs = false, + diagnostics = false, + inlay_hints = false, + }, + show = { + tabline = false, + statusline = false, + }, + win = { + width = 0.8, + height = 0.8, + }, + }, + + -- Global styles + styles = { + notification = { + wo = { wrap = true }, + border = "rounded", + zindex = 100, + ft = "markdown", + }, + input = { + border = "rounded", + title_pos = "center", + icon_pos = "left", + relative = "editor", + zindex = 10, + width = 60, + height = 1, + row = "50%", + col = "50%", + }, + picker = { + border = "rounded", + title_pos = "center", + relative = "editor", + zindex = 10, + width = 0.8, + height = 0.8, + row = "50%", + col = "50%", + }, + terminal = { + border = "rounded", + title_pos = "center", + relative = "editor", + zindex = 10, + width = 0.8, + height = 0.8, + row = "50%", + col = "50%", + }, + }, + }) + + -- Comprehensive keymaps for all features + local opts = { noremap = true, silent = true } + local snacks = require("snacks") + + -- Top-level pickers + vim.keymap.set("n", "", function() snacks.picker.smart() end, + vim.tbl_extend("force", opts, { desc = "Smart Find Files" })) + vim.keymap.set("n", ",", function() snacks.picker.buffers() end, + vim.tbl_extend("force", opts, { desc = "Buffers" })) + vim.keymap.set("n", "/", function() snacks.picker.grep() end, + vim.tbl_extend("force", opts, { desc = "Grep" })) + vim.keymap.set("n", ":", function() snacks.picker.command_history() end, + vim.tbl_extend("force", opts, { desc = "Command History" })) + + -- File operations + vim.keymap.set("n", "ff", function() snacks.picker.files() end, + vim.tbl_extend("force", opts, { desc = "Find Files" })) + vim.keymap.set("n", "fr", function() snacks.picker.recent() end, + vim.tbl_extend("force", opts, { desc = "Recent Files" })) + vim.keymap.set("n", "fg", function() snacks.picker.git_files() end, + vim.tbl_extend("force", opts, { desc = "Git Files" })) + vim.keymap.set("n", "fc", function() snacks.picker.files({ cwd = vim.fn.stdpath("config") }) end, + vim.tbl_extend("force", opts, { desc = "Config Files" })) + + -- Explorer + vim.keymap.set("n", "e", function() snacks.explorer() end, + vim.tbl_extend("force", opts, { desc = "Explorer" })) + + -- Git + vim.keymap.set("n", "gb", function() snacks.picker.git_branches() end, + vim.tbl_extend("force", opts, { desc = "Git Branches" })) + vim.keymap.set("n", "gl", function() snacks.picker.git_log() end, + vim.tbl_extend("force", opts, { desc = "Git Log" })) + vim.keymap.set("n", "gs", function() snacks.picker.git_status() end, + vim.tbl_extend("force", opts, { desc = "Git Status" })) + vim.keymap.set("n", "gB", function() snacks.gitbrowse() end, + vim.tbl_extend("force", opts, { desc = "Git Browse" })) + vim.keymap.set("n", "gg", function() snacks.lazygit() end, + vim.tbl_extend("force", opts, { desc = "LazyGit" })) + + -- Notifications + vim.keymap.set("n", "n", function() snacks.notifier.show_history() end, + vim.tbl_extend("force", opts, { desc = "Notification History" })) + vim.keymap.set("n", "un", function() snacks.notifier.hide() end, + vim.tbl_extend("force", opts, { desc = "Dismiss All Notifications" })) + + -- Buffers + vim.keymap.set("n", "bd", function() snacks.bufdelete() end, + vim.tbl_extend("force", opts, { desc = "Delete Buffer" })) + + -- Scratch + vim.keymap.set("n", ".", function() snacks.scratch() end, + vim.tbl_extend("force", opts, { desc = "Toggle Scratch Buffer" })) + vim.keymap.set("n", "S", function() snacks.scratch.select() end, + vim.tbl_extend("force", opts, { desc = "Select Scratch Buffer" })) + + -- Terminal + vim.keymap.set("n", "", function() snacks.terminal() end, + vim.tbl_extend("force", opts, { desc = "Toggle Terminal" })) + vim.keymap.set("n", "", function() snacks.terminal() end, + vim.tbl_extend("force", opts, { desc = "which_key_ignore" })) + + -- Zen mode + vim.keymap.set("n", "z", function() snacks.zen() end, + vim.tbl_extend("force", opts, { desc = "Toggle Zen Mode" })) + vim.keymap.set("n", "Z", function() snacks.zen.zoom() end, + vim.tbl_extend("force", opts, { desc = "Toggle Zoom" })) + + -- Word navigation + vim.keymap.set("n", "]]", function() snacks.words.jump(vim.v.count1) end, + vim.tbl_extend("force", opts, { desc = "Next Reference" })) + vim.keymap.set("n", "[[", function() snacks.words.jump(-vim.v.count1) end, + vim.tbl_extend("force", opts, { desc = "Prev Reference" })) + + -- LSP integration + vim.keymap.set("n", "gd", function() snacks.picker.lsp_definitions() end, + vim.tbl_extend("force", opts, { desc = "Goto Definition" })) + vim.keymap.set("n", "gr", function() snacks.picker.lsp_references() end, + vim.tbl_extend("force", opts, { desc = "References" })) + vim.keymap.set("n", "gI", function() snacks.picker.lsp_implementations() end, + vim.tbl_extend("force", opts, { desc = "Goto Implementation" })) + vim.keymap.set("n", "gy", function() snacks.picker.lsp_type_definitions() end, + vim.tbl_extend("force", opts, { desc = "Goto Type Definition" })) + + -- File renaming + vim.keymap.set("n", "cR", function() snacks.rename.rename_file() end, + vim.tbl_extend("force", opts, { desc = "Rename File" })) + + -- Toggles (if toggle is enabled) + vim.api.nvim_create_autocmd("User", { + pattern = "VeryLazy", + callback = function() + -- Setup debugging globals + _G.dd = function(...) snacks.debug.inspect(...) end + _G.bt = function() snacks.debug.backtrace() end + vim.print = _G.dd + + -- Create toggle mappings + snacks.toggle.option("spell", { name = "Spelling" }):map("us") + snacks.toggle.option("wrap", { name = "Wrap" }):map("uw") + snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("uL") + snacks.toggle.diagnostics():map("ud") + snacks.toggle.line_number():map("ul") + snacks.toggle.option("conceallevel", { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }):map("uc") + snacks.toggle.treesitter():map("uT") + snacks.toggle.option("background", { off = "light", on = "dark", name = "Dark Background" }):map("ub") + snacks.toggle.inlay_hints():map("uh") + snacks.toggle.indent():map("ug") + snacks.toggle.dim():map("uD") + end, + }) + ''; + }; + }; + }; +} \ No newline at end of file diff --git a/plugins/optional/TEMPLATE-snacks-nvim-minimal.nix b/plugins/optional/TEMPLATE-snacks-nvim-minimal.nix new file mode 100644 index 0000000..f28aa0d --- /dev/null +++ b/plugins/optional/TEMPLATE-snacks-nvim-minimal.nix @@ -0,0 +1,94 @@ +# Snacks.nvim Minimal Configuration Template +# Essential snacks only - recommended for conservative setups +# Documentation: https://github.com/folke/snacks.nvim + +{ inputs, pkgs, lib, ... }: +let + snacks-from-source = pkgs.vimUtils.buildVimPlugin { + name = "snacks-nvim"; + src = inputs.snacks-nvim; + }; +in +{ + config.vim = { + extraPlugins = { + snacks-minimal = { + package = snacks-from-source; + setup = '' + -- Minimal Snacks.nvim setup - only essential features + require('snacks').setup({ + -- Essential snacks that provide significant value with minimal risk + + bigfile = { + enabled = true, + size = 1.5 * 1024 * 1024, -- 1.5MB + }, + + input = { + enabled = true, + -- Better vim.ui.input with nicer styling + }, + + notifier = { + enabled = true, + timeout = 3000, + -- Clean notifications + }, + + quickfile = { + enabled = true, + -- Fast file loading before plugins initialize + }, + + -- All other snacks disabled for minimal setup + animate = { enabled = false }, + bufdelete = { enabled = false }, + dashboard = { enabled = false }, + debug = { enabled = false }, + dim = { enabled = false }, + explorer = { enabled = false }, + git = { enabled = false }, + gitbrowse = { enabled = false }, + image = { enabled = false }, + indent = { enabled = false }, + layout = { enabled = false }, + lazygit = { enabled = false }, + notify = { enabled = false }, + picker = { enabled = false }, + profiler = { enabled = false }, + rename = { enabled = false }, + scope = { enabled = false }, + scratch = { enabled = false }, + scroll = { enabled = false }, + statuscolumn = { enabled = false }, + terminal = { enabled = false }, + toggle = { enabled = false }, + util = { enabled = false }, + win = { enabled = false }, + words = { enabled = false }, + zen = { enabled = false }, + + -- Minimal styles + styles = { + notification = { + border = "rounded", + }, + input = { + border = "rounded", + }, + }, + }) + + -- Minimal keymaps - only for enabled features + local opts = { noremap = true, silent = true } + + -- Notifications + vim.keymap.set("n", "n", function() require("snacks").notifier.show_history() end, + vim.tbl_extend("force", opts, { desc = "Notification History" })) + vim.keymap.set("n", "un", function() require("snacks").notifier.hide() end, + vim.tbl_extend("force", opts, { desc = "Dismiss Notifications" })) + ''; + }; + }; + }; +} \ No newline at end of file diff --git a/plugins/optional/snacks-nvim.nix b/plugins/optional/snacks-nvim.nix new file mode 100644 index 0000000..55069ab --- /dev/null +++ b/plugins/optional/snacks-nvim.nix @@ -0,0 +1,227 @@ +# Snacks.nvim Plugin Configuration for nvf +# A collection of small QoL plugins for Neovim +# Documentation: https://github.com/folke/snacks.nvim + +{ inputs, pkgs, ... }: +let + snacks-from-source = pkgs.vimUtils.buildVimPlugin { + name = "snacks-nvim"; + src = inputs.snacks-nvim; + }; +in +{ + config.vim = { + extraPlugins = { + snacks = { + package = snacks-from-source; + setup = '' + -- Snacks.nvim setup with priority and early loading + require('snacks').setup({ + -- Core snacks that require setup + bigfile = { + enabled = true, + size = 1.5 * 1024 * 1024, -- 1.5MB + ---@param ctx {buf: number, ft: string} + setup = function(ctx) + vim.cmd([[NoMatchParen]]) + vim.api.nvim_buf_set_option(ctx.buf, 'foldmethod', 'manual') + vim.api.nvim_buf_set_option(ctx.buf, 'spell', false) + vim.api.nvim_buf_set_option(ctx.buf, 'wrap', false) + vim.api.nvim_buf_set_option(ctx.buf, 'undofile', false) + vim.api.nvim_buf_set_option(ctx.buf, 'swapfile', false) + vim.api.nvim_buf_set_option(ctx.buf, 'synmaxcol', 200) + end, + }, + + dashboard = { + enabled = true, + sections = { + { section = "header" }, + { section = "keys", gap = 1, padding = 1 }, + { section = "startup" }, + }, + preset = { + keys = { + { icon = " ", key = "f", desc = "Find File", action = ":lua Snacks.picker.files()" }, + { icon = " ", key = "n", desc = "New File", action = ":ene | startinsert" }, + { icon = " ", key = "r", desc = "Recent Files", action = ":lua Snacks.picker.recent()" }, + { icon = " ", key = "g", desc = "Find Text", action = ":lua Snacks.picker.grep()" }, + { icon = "󰒲 ", key = "l", desc = "Lazy", action = ":Lazy" }, + { icon = " ", key = "q", desc = "Quit", action = ":qa" }, + }, + }, + }, + + explorer = { + enabled = true, + replace_netrw = true, + }, + + indent = { + enabled = true, + animate = { + enabled = false, -- Disable animation for better performance in nvf + }, + }, + + input = { + enabled = true, + -- Better vim.ui.input with nicer styling + }, + + notifier = { + enabled = true, + timeout = 3000, + width = { min = 40, max = 0.4 }, + height = { min = 1, max = 0.6 }, + -- Enhanced notification styling + style = "notification", + top_down = true, + }, + + picker = { + enabled = true, + win = { + input = { + keys = { + [""] = { "close", mode = { "i", "n" } }, + [""] = { "close", mode = { "i", "n" } }, + }, + }, + }, + }, + + quickfile = { + enabled = true, + -- Fast file loading before plugins initialize + }, + + scope = { + enabled = true, + -- Treesitter-based scope detection + cursor = true, + indent = { + enabled = true, + }, + }, + + scroll = { + enabled = true, + animate = { + duration = { step = 15, total = 250 }, + easing = "linear", + }, + }, + + statuscolumn = { + enabled = true, + left = { "mark", "sign" }, + right = { "fold", "git" }, + folds = { + open = true, + git_hl = true, + }, + git = { + patterns = { "GitSign", "MiniDiffSign" }, + }, + refresh = 50, + }, + + words = { + enabled = true, + debounce = 200, + -- Auto-show LSP references + }, + + -- Optional snacks (disabled by default for conservative setup) + animate = { enabled = false }, + bufdelete = { enabled = false }, + debug = { enabled = false }, + dim = { enabled = false }, + git = { enabled = false }, + gitbrowse = { enabled = false }, + image = { enabled = false }, + lazygit = { enabled = false }, + layout = { enabled = false }, + notify = { enabled = false }, + profiler = { enabled = false }, + rename = { enabled = false }, + scratch = { enabled = false }, + terminal = { enabled = false }, + toggle = { enabled = false }, + util = { enabled = false }, + win = { enabled = false }, + zen = { enabled = false }, + + -- Global styles for floating windows + styles = { + notification = { + wo = { wrap = true }, + border = "rounded", + }, + input = { + border = "rounded", + }, + picker = { + border = "rounded", + }, + }, + }) + + -- Set up keymaps for core functionality + local opts = { noremap = true, silent = true } + + -- File operations + vim.keymap.set("n", "ff", function() require("snacks").picker.files() end, + vim.tbl_extend("force", opts, { desc = "Find Files" })) + vim.keymap.set("n", "fr", function() require("snacks").picker.recent() end, + vim.tbl_extend("force", opts, { desc = "Recent Files" })) + vim.keymap.set("n", "fg", function() require("snacks").picker.grep() end, + vim.tbl_extend("force", opts, { desc = "Grep Files" })) + vim.keymap.set("n", "fb", function() require("snacks").picker.buffers() end, + vim.tbl_extend("force", opts, { desc = "Find Buffers" })) + + -- Explorer + vim.keymap.set("n", "e", function() require("snacks").explorer() end, + vim.tbl_extend("force", opts, { desc = "Explorer" })) + + -- Notifications + vim.keymap.set("n", "n", function() require("snacks").notifier.show_history() end, + vim.tbl_extend("force", opts, { desc = "Notification History" })) + vim.keymap.set("n", "un", function() require("snacks").notifier.hide() end, + vim.tbl_extend("force", opts, { desc = "Dismiss Notifications" })) + + -- Dashboard + vim.keymap.set("n", "d", function() require("snacks").dashboard.open() end, + vim.tbl_extend("force", opts, { desc = "Dashboard" })) + + -- Word navigation (if enabled) + vim.keymap.set("n", "]]", function() require("snacks").words.jump(vim.v.count1) end, + vim.tbl_extend("force", opts, { desc = "Next Reference" })) + vim.keymap.set("n", "[[", function() require("snacks").words.jump(-vim.v.count1) end, + vim.tbl_extend("force", opts, { desc = "Prev Reference" })) + + -- Set up late initialization for additional features + vim.api.nvim_create_autocmd("User", { + pattern = "VeryLazy", + callback = function() + -- Setup debugging globals (optional) + _G.dd = function(...) + require("snacks").debug.inspect(...) + end + _G.bt = function() + require("snacks").debug.backtrace() + end + + -- Override print for better debugging + if vim.g.snacks_debug then + vim.print = _G.dd + end + end, + }) + ''; + }; + }; + }; +} +