{"id":30268925,"url":"https://github.com/ph1losof/ecolog.nvim","last_synced_at":"2026-01-25T09:01:29.303Z","repository":{"id":267352940,"uuid":"900979344","full_name":"ph1losof/ecolog.nvim","owner":"ph1losof","description":"The most sophisticated all-in-one toolkit to work with .env files and environment variables in NeoVim","archived":false,"fork":false,"pushed_at":"2026-01-14T16:52:05.000Z","size":1358,"stargazers_count":169,"open_issues_count":3,"forks_count":11,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-14T19:20:51.814Z","etag":null,"topics":["neovim","neovim-lua-plugin","neovim-plugin","neovim-plugins","nvim","nvim-cmp","nvim-plugin"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ph1losof.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-09T20:24:42.000Z","updated_at":"2026-01-14T18:55:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"b2316ddc-81f9-4413-b076-dd5ea468535d","html_url":"https://github.com/ph1losof/ecolog.nvim","commit_stats":null,"previous_names":["philosofonusus/ecolog.nvim","t3ntxcl3s/ecolog.nvim","ssstba/ecolog.nvim","ph1losof/ecolog.nvim"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/ph1losof/ecolog.nvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph1losof%2Fecolog.nvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph1losof%2Fecolog.nvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph1losof%2Fecolog.nvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph1losof%2Fecolog.nvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ph1losof","download_url":"https://codeload.github.com/ph1losof/ecolog.nvim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph1losof%2Fecolog.nvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28750622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T08:31:04.260Z","status":"ssl_error","status_checked_at":"2026-01-25T08:30:28.859Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["neovim","neovim-lua-plugin","neovim-plugin","neovim-plugins","nvim","nvim-cmp","nvim-plugin"],"created_at":"2025-08-16T01:02:43.401Z","updated_at":"2026-01-25T09:01:29.293Z","avatar_url":"https://github.com/ph1losof.png","language":"Lua","readme":"# 🌲 ecolog.nvim\n\n\u003cdiv align=\"center\"\u003e\n\n![Neovim](https://img.shields.io/badge/NeoVim-%2357A143.svg?\u0026style=for-the-badge\u0026logo=neovim\u0026logoColor=white)\n![Lua](https://img.shields.io/badge/lua-%232C2D72.svg?style=for-the-badge\u0026logo=lua\u0026logoColor=white)\n\nEcolog (эколог) - your environment guardian in Neovim. Named after the Russian word for \"environmentalist\", this plugin protects and manages your environment variables with the same care an ecologist shows for nature.\n\nA Neovim plugin for seamless environment variable integration and management. Provides intelligent autocompletion, type checking, and value peeking for environment variables in your projects. All in one place.\n\n\u003e 💡 **LATEST INFO**: Please set branch to **v1** or consider **beta** if possible, **beta** is a complete rewrite of ecolog.nvim from the ground up.\n\n![CleanShot 2025-01-03 at 21 20 37](https://github.com/user-attachments/assets/f19c9979-7334-44ac-8845-77db2e93d187)\n\n\u003c/div\u003e\n\n## Table of Contents\n\n- [Installation](#-installation)\n  - [Plugin Setup](#plugin-setup)\n- [Features](#-features)\n- [Usage](#-usage)\n  - [Available Commands](#available-commands)\n- [Environment File Priority](#-environment-file-priority)\n- [Shell Variables Integration](#-shell-variables-integration)\n  - [Basic Usage](#basic-usage)\n  - [Advanced Configuration](#advanced-configuration)\n  - [Configuration Options](#configuration-options)\n  - [Features](#features)\n  - [Best Practices](#best-practices)\n- [Monorepo Support](#-monorepo-support)\n  - [Configuration](#configuration)\n  - [Workspace Detection](#workspace-detection)\n  - [Environment File Resolution](#environment-file-resolution)\n  - [Workspace Switching](#workspace-switching)\n  - [Advanced Configuration](#advanced-configuration-1)\n- [Variable Interpolation](#-variable-interpolation)\n  - [Supported Syntax](#supported-syntax)\n  - [Examples](#examples)\n  - [Configuration Options](#configuration-options-1)\n  - [Features](#features-1)\n  - [Best Practices](#best-practices-1)\n- [Supported Languages](#-supported-languages)\n  - [Currently Supported](#currently-supported)\n  - [Adding new languages and custom providers](#-custom-providers)\n- [Custom Environment File Patterns](#-custom-environment-file-patterns)\n  - [Basic Usage](#basic-usage-1)\n  - [Pattern Format](#pattern-format)\n  - [Examples](#examples)\n  - [Features](#features-1)\n- [Custom Sort Functions](#-custom-sort-functions)\n  - [File Sorting](#file-sorting)\n  - [Variable Sorting](#variable-sorting)\n- [Integrations](#-integrations)\n  - [Nvim-cmp Integration](#nvim-cmp-integration)\n  - [Blink-cmp Integration](#blink-cmp-integration)\n  - [Omnifunc Integration](#omnifunc-integration)\n    - [Setup](#setup)\n    - [Usage](#usage)\n    - [Shelter Mode Integration](#shelter-mode-integration)\n    - [Manual Setup](#manual-setup)\n  - [LSP Integration](#lsp-integration-experimental)\n  - [LSP Saga Integration](#lsp-saga-integration)\n  - [Telescope Integration](#telescope-integration)\n  - [FZF Integration](#fzf-integration)\n  - [Snacks Integration](#snacks-integration)\n  - [Custom Actions for Pickers](#custom-actions-for-pickers)\n  - [Statusline Integration](#statusline-integration)\n  - [AWS Secrets Manager](#aws-secrets-manager)\n  - [HashiCorp Vault Secrets](#hashicorp-vault-secrets)\n- [Shelter Previewers](#-shelter-previewers)\n  - [Telescope Previewer](#telescope-previewer)\n  - [FZF Previewer](#fzf-previewer)\n  - [Snacks Previewer](#snacks-previewer)\n- [Shelter Mode](#️-shelter-mode)\n  - [Configuration](#-configuration)\n  - [Features](#-features-1)\n    - [Module-specific Masking](#module-specific-masking)\n    - [Partial Masking](#partial-masking)\n  - [Commands](#-commands)\n  - [Example](#-example)\n  - [Pattern-based Protection](#pattern-based-protection)\n  - [Customization](#-customization)\n  - [Best Practices](#-best-practices)\n- [Ecolog Types](#-ecolog-types)\n  - [Type Configuration](#type-configuration)\n  - [Custom Type Definition](#custom-type-definition)\n- [Tips](#-tips)\n- [Theme Integration](#-theme-integration)\n- [Author Setup](#️-author-setup)\n- [Comparisons](#-comparisons)\n  - [Environment Variable Completion](#environment-variable-completion-vs-cmp-dotenv)\n  - [Security Features](#security-features-vs-cloaknvim)\n  - [Environment Management](#environment-management-vs-telescope-envnvim)\n  - [File Management](#file-management-vs-dotenvnvim)\n  - [Key Benefits of ecolog.nvim](#key-benefits-of-ecolognvim)\n- [Contributing](#-contributing)\n- [License](#-license)\n\n## 📦 Installation\n\nUsing [lazy.nvim](https://github.com/folke/lazy.nvim):\n\n### Plugin Setup\n\n\u003e 💡 **Quick Start**: If you want to quickly start with ecolog.nvim, check out the [author's personal setup](#️-author-setup) section.\n\n```lua\n{\n  'ph1losof/ecolog.nvim',\n  branch = \"v1\",\n  -- Optional: you can add some keybindings\n  -- (I personally use lspsaga so check out lspsaga integration or lsp integration for a smoother experience without separate keybindings)\n  keys = {\n    { '\u003cleader\u003ege', '\u003ccmd\u003eEcologGoto\u003ccr\u003e', desc = 'Go to env file' },\n    { '\u003cleader\u003eep', '\u003ccmd\u003eEcologPeek\u003ccr\u003e', desc = 'Ecolog peek variable' },\n    { '\u003cleader\u003ees', '\u003ccmd\u003eEcologSelect\u003ccr\u003e', desc = 'Switch env file' },\n  },\n  -- Lazy loading is done internally\n  lazy = false,\n  opts = {\n    integrations = {\n        -- WARNING: for both cmp integrations see readme section below\n        nvim_cmp = true, -- If you dont plan to use nvim_cmp set to false, enabled by default\n        -- If you are planning to use blink cmp uncomment this line\n        -- blink_cmp = true,\n    },\n    -- Enables shelter mode for sensitive values\n    shelter = {\n        configuration = {\n            -- Partial mode configuration:\n            -- false: completely mask values (default)\n            -- true: use default partial masking settings\n            -- table: customize partial masking\n            -- partial_mode = false,\n            -- or with custom settings:\n            partial_mode = {\n                show_start = 3,    -- Show first 3 characters\n                show_end = 3,      -- Show last 3 characters\n                min_mask = 3,      -- Minimum masked characters\n            },\n            mask_char = \"*\",   -- Character used for masking\n            mask_length = nil, -- Optional: fixed length for masked portion (defaults to value length)\n            skip_comments = false, -- Skip masking comment lines in environment files (default: false)\n        },\n        modules = {\n            cmp = true,       -- Enabled to mask values in completion\n            peek = false,      -- Enable to mask values in peek view\n            files = true, -- Enabled to mask values in file buffers\n            telescope = false, -- Enable to mask values in telescope integration\n            telescope_previewer = false, -- Enable to mask values in telescope preview buffers\n            fzf = false,       -- Enable to mask values in fzf picker\n            fzf_previewer = false, -- Enable to mask values in fzf preview buffers\n            snacks_previewer = false,    -- Enable to mask values in snacks previewer\n            snacks = false,    -- Enable to mask values in snacks picker\n        }\n    },\n    -- true by default, enables built-in types (database_url, url, etc.)\n    types = true,\n    path = vim.fn.getcwd(), -- Path to search for .env files\n    preferred_environment = \"development\", -- Optional: prioritize specific env files\n    -- Controls how environment variables are extracted from code and how cmp works\n    provider_patterns = true, -- true by default, when false will not check provider patterns\n  },\n}\n```\n\nTo use the latest features and improvements, you can use the beta branch:\n\n```lua\n{\n  'ph1losof/ecolog.nvim',\n  branch = 'beta',\n  -- ... rest of your configuration\n}\n```\n\n\u003e Even though beta branch may contain more experimental changes, new and shiny features will appear faster here.\n\u003e Consider using it as a contribution to the development of the main branch. Since you can share your feedback.\n\nSetup auto-completion with `nvim-cmp`:\n\n```lua\nrequire('cmp').setup({\n  sources = {\n    { name = 'ecolog' },\n    -- your other sources...\n  },\n})\n```\n\nIf you use `blink.cmp` see [Blink-cmp Integration guide](#blink-cmp-integration)\n\n## ✨ Features\n\n🔍 **Advanced Environment Variable Management**\n\n- Intelligent variable detection across multiple languages\n- Real-time file monitoring and cache updates\n- Support for custom environment file patterns\n- Priority-based environment file loading\n- Shell variables integration\n- vim.env synchronization\n- Advanced variable interpolation with shell-like syntax\n\n🤖 **Smart Autocompletion**\n\n- Context-aware suggestions with nvim-cmp and blink-cmp\n- Type-safe completions with validation\n- Intelligent provider detection\n- Language-specific completion triggers\n- Comment and metadata support in completions\n\n🛡️ **Enhanced Security Features**\n\n- Configurable shelter mode for sensitive data\n- Partial masking with customizable patterns\n- Per-feature security controls\n- Real-time visual masking\n- Temporary value reveal functionality\n- Screen sharing protection\n\n🔄 **Integrations**\n\n- LSP integration for hover and definition\n- Telescope integration with fuzzy finding\n- FZF integration with preview support\n- LSP Saga integration\n- Custom provider API for language support\n\n📁 **Multi-Environment Support**\n\n- Multiple .env file handling\n- Custom file pattern matching\n- Priority-based loading system\n- Environment-specific configurations\n- Custom sort functions for file priority\n\n🏢 **Monorepo Support**\n\n- Automatic workspace detection (Turborepo, Nx, Lerna, Rush, etc.)\n- Intelligent environment file resolution strategies\n- Workspace-aware variable completion and display\n- Automatic and manual workspace switching\n- Cross-workspace environment file management\n\n💡 **Type System**\n\n- Built-in type validation\n- Custom type definitions\n- Pattern-based type detection\n- Value transformation support\n- Type-aware completion and validation\n\n🎨 **UI/UX Features**\n\n- Theme integration with existing colorschemes\n- Customizable highlighting\n- Rich preview windows\n- Inline documentation\n- Status indicators\n\n## 🔄 Variable Interpolation\n\nEcolog supports advanced variable interpolation with shell-like syntax in your environment files.\n\n### Supported Syntax\n\n- **Basic Variables**: `$VAR` or `${VAR}`\n- **Default Values**: `${VAR:-default}` (use default if VAR is unset or empty)\n- **Alternate Values**: `${VAR-alternate}` (use alternate if VAR is unset)\n- **Command Substitution**: `$(command)`\n- **Quoted Strings**:\n  - Single quotes (`'...'`): No interpolation\n  - Double quotes (`\"...\"`): With interpolation\n\n### Examples\n\n```sh\n# Basic variable interpolation\nAPP_URL=${HOST}:${PORT}\n\n# Default values\nAPI_TIMEOUT=${TIMEOUT:-5000}\nDB_HOST=${DATABASE_HOST:-localhost}\n\n# Alternate values\nCACHE_DIR=${CUSTOM_CACHE-/tmp/cache}\n\n# Command substitution\nGIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)\nTIMESTAMP=$(date +%Y%m%d)\n\n# Nested interpolation\nDATABASE_URL=\"postgres://${DB_USER:-postgres}:${DB_PASS}@${DB_HOST:-localhost}:${DB_PORT:-5432}/${DB_NAME}\"\n```\n\n### Security\n\nBy default, Ecolog sanitizes potentially dangerous characters in command substitutions to prevent command injection attacks. Characters like `;`, `|`, `` ` ``, `$`, `()` are removed from commands before execution.\n\nFor example:\n\n```sh\n# This dangerous command:\nHACK=$(echo hello; rm -rf /)\n\n# Gets sanitized to:\nHACK=$(echo hello rm -rf /)\n```\n\n#### Disabling Security (Advanced)\n\nIn trusted environments where you need complex shell commands, you can disable security sanitization:\n\n```lua\nrequire('ecolog').setup({\n  interpolation = {\n    enabled = true,\n    disable_security = true,  -- ⚠️ Use with caution!\n    -- ... other options\n  }\n})\n```\n\n**⚠️ Warning**: Only disable security in trusted environments. When `disable_security = true`, all shell command characters are allowed, which can be dangerous if environment files contain malicious commands.\n\n### Configuration Options\n\nYou can customize the interpolation behavior through the plugin's configuration:\n\n```lua\nrequire('ecolog').setup({\n  -- Enable interpolation with default settings\n  interpolation = true,\n\n  -- Or disable interpolation\n  interpolation = false,\n\n  -- Or customize interpolation settings\n  interpolation = {\n    enabled = true,              -- Enable/disable interpolation\n    max_iterations = 10,         -- Maximum iterations for nested interpolation\n    warn_on_undefined = true,    -- Warn about undefined variables\n    fail_on_cmd_error = false,  -- How to handle command substitution errors\n    disable_security = false,    -- Disable security sanitization for command substitution\n    features = {\n      variables = true,         -- Enable variable interpolation ($VAR, ${VAR})\n      defaults = true,         -- Enable default value syntax (${VAR:-default})\n      alternates = true,       -- Enable alternate value syntax (${VAR-alternate})\n      commands = true,         -- Enable command substitution ($(command))\n      escapes = true,         -- Enable escape sequences (\\n, \\t, etc.)\n    }\n  }\n})\n```\n\nThe configuration options are:\n\n| Option              | Type    | Default | Description                                               |\n| ------------------- | ------- | ------- | --------------------------------------------------------- |\n| enabled             | boolean | false   | Enable/disable interpolation                              |\n| max_iterations      | number  | 10      | Maximum iterations for nested variable interpolation      |\n| warn_on_undefined   | boolean | true    | Whether to warn when undefined variables are referenced   |\n| fail_on_cmd_error   | boolean | false   | Whether to error or warn on command substitution failures |\n| disable_security    | boolean | false   | Disable security sanitization for command substitution    |\n| features            | table   | -       | Control specific interpolation features                   |\n| features.variables  | boolean | true    | Enable variable interpolation ($VAR, ${VAR})              |\n| features.defaults   | boolean | true    | Enable default value syntax (${VAR:-default})             |\n| features.alternates | boolean | true    | Enable alternate value syntax (${VAR-alternate})          |\n| features.commands   | boolean | true    | Enable command substitution ($(command))                  |\n| features.escapes    | boolean | true    | Enable escape sequences (\\n, \\t, etc.)                    |\n\n### Features\n\n- **Recursive Interpolation**: Variables can reference other variables\n- **Shell Integration**: Access shell environment variables\n- **Error Handling**: Configurable warnings and error handling\n- **Command Substitution**: Execute shell commands and use their output\n- **Escape Sequences**: Support for common escape sequences (`\\n`, `\\t`, etc.)\n- **Quote Handling**: Proper handling of single and double quotes\n- **Default Values**: Support for default and alternate value syntax\n- **Safety Limits**: Prevention of infinite recursion with iteration limits\n- **Security Sanitization**: Built-in protection against command injection attacks\n\n### Best Practices\n\n1. Use braces `${}` for clarity and to avoid ambiguity\n2. Provide default values for optional variables\n3. Use single quotes for literal strings\n4. Be cautious with command substitution in production environments\n5. Keep nesting levels reasonable for better maintainability\n6. Use feature flags to enhance security:\n   - Disable `commands` in production to prevent command injection\n   - Disable `alternates` and `defaults` if not needed\n   - Keep `variables` enabled for basic interpolation\n   - Consider disabling `escapes` if not using special characters\n7. Use security settings appropriately:\n   - Keep `disable_security = false` (default) in untrusted environments\n   - Only set `disable_security = true` in trusted environments where you need complex shell commands\n   - Be aware that disabling security allows potentially dangerous characters like `;`, `|`, `` ` ``, `$`, `()` in command substitutions\n\n## 🌍 Supported Languages\n\n### Currently Supported\n\nEcolog provides intelligent environment variable detection and completion for multiple programming languages:\n\n| Language   | File Extensions  | Environment Variable Access Patterns                                                                 |\n| ---------- | ---------------- | ---------------------------------------------------------------------------------------------------- |\n| TypeScript | .ts, .tsx        | `process.env.VAR`, `process.env['VAR']`, `import.meta.env.VAR`, `Bun.env.VAR`, `Deno.env.get('VAR')` |\n| JavaScript | .js, .jsx        | `process.env.VAR`, `process.env['VAR']`, `Bun.env.VAR`                                               |\n| Python     | .py              | `os.environ.get('VAR')`                                                                              |\n| PHP        | .php             | `getenv('VAR')`, `$_ENV['VAR']`, `$_SERVER['VAR']`                                                   |\n| Lua        | .lua             | `os.getenv('VAR')`                                                                                   |\n| Go         | .go              | `os.Getenv('VAR')`                                                                                   |\n| Rust       | .rs              | `env::var('VAR')`, `std::env::var('VAR')`, `std::env::var_os('VAR')`                                 |\n| Java       | .java            | `System.getenv('VAR')`, `env.get('VAR')`                                                             |\n| C#         | .cs, .csharp     | `Environment.GetEnvironmentVariable('VAR')`, `System.Environment.GetEnvironmentVariable('VAR')`      |\n| Ruby       | .rb              | `ENV['VAR']`, `ENV.fetch('VAR')`                                                                     |\n| Shell      | .sh, .bash, .zsh | `$VAR`, `${VAR}`                                                                                     |\n| Kotlin     | .kt, .kotlin     | `System.getenv('VAR')`                                                                               |\n| Dockerfile | Dockerfile       | `${VAR}`                                                                                             |\n\nEach language provider is optimized for its specific environment variable access patterns and supports both completion and detection. The providers are loaded lazily to maintain performance.\n\n### 🔌 Custom Providers\n\nYou can add support for additional languages by registering custom providers. Each provider defines how environment variables are detected and extracted in specific file types.\n\n### Example: Adding a Custom Provider\n\n```lua\nrequire('ecolog').setup({\n  providers = {\n    {\n      -- Pattern to match environment variable access\n      pattern = \"ENV%[['\\\"]%w['\\\"]%]\",\n      -- Filetype(s) this provider supports (string or table)\n      filetype = \"custom_lang\",\n      -- Function to extract variable name from the line\n      extract_var = function(line, col)\n        local before_cursor = line:sub(1, col + 1)\n        return before_cursor:match(\"ENV%['\\\"['\\\"]%]$\")\n      end,\n      -- Function to return completion trigger pattern\n      get_completion_trigger = function()\n        return \"ENV['\"\n      end\n    }\n  }\n})\n```\n\nEach provider must specify:\n\n1. `pattern`: A Lua pattern to match environment variable access in the code\n2. `filetype`: The filetype(s) this provider supports (string or table)\n3. `extract_var`: Function to extract the variable name from the line\n4. `get_completion_trigger`: Function to return the completion trigger pattern\n\nThe provider will be automatically loaded when editing files of the specified filetype.\n\n## 🚀 Usage\n\n### Available Commands\n\n| Command                                    | Description                                                                           |\n| ------------------------------------------ | ------------------------------------------------------------------------------------- |\n| `:EcologPeek [variable_name]`              | Peek at environment variable value and metadata                                       |\n| `:EcologPeek`                              | Peek at environment variable under cursor                                             |\n| `:EcologRefresh`                           | Refresh environment variable cache                                                    |\n| `:EcologSelect`                            | Open a selection window to choose environment file                                    |\n| `:EcologSelect [file_path]`                | Directly load a specific environment file without selection prompt                    |\n| `:EcologGoto`                              | Open selected environment file in buffer                                              |\n| `:EcologGotoVar`                           | Go to specific variable definition in env file                                        |\n| `:EcologGotoVar [variable_name]`           | Go to specific variable definition in env file with variable under cursor             |\n| `:EcologShelterToggle [command] [feature]` | Control shelter mode for masking sensitive values                                     |\n| `:EcologShelterLinePeek`                   | Temporarily reveal value on current line in env file                                  |\n| `:Telescope ecolog env`                    | Alternative way to open Telescope picker                                              |\n| `:EcologTelescope`                         | Open environment variables picker using telescope (must have telescope installed)     |\n| `:EcologFzf`                               | Alternative way to open fzf-lua picker (must have fzf-lua installed)                  |\n| `:EcologSnacks`                            | Open environment variables picker using snacks.nvim (must have snacks.nvim installed) |\n| `:EcologEnvGet`                            | Get the value of a specific environment variable                                      |\n| `:EcologEnvSet`                            | Sets the value of a specified environment variable                                    |\n| `:EcologCopy [variable_name]`              | Copy raw value of environment variable to clipboard                                   |\n| `:EcologCopy`                              | Copy raw value of environment variable under cursor to clipboard                      |\n| `:EcologAWSConfig`                         | Open configuration menu for AWS Secrets Manager (region, profile, secrets)            |\n| `:EcologVaultConfig`                       | Open configuration menu for HCP Vault (organization, project, apps)                   |\n| `:EcologInterpolationToggle`               | Toggle environment variable interpolation on/off                                      |\n| `:EcologShellToggle`                       | Loads and unloads shell variables                                                     |\n\n## 📝 Environment File Priority\n\nOnly one environment file is selected and loaded at a time, based on the following priority order:\n\n1. `.env.{preferred_environment}` (if preferred_environment is set)\n2. `.env`\n3. Other `.env.*` files (alphabetically)\n\nThe first available file in this priority order will be selected. Environment variables from shell and secret managers may still be merged with the selected file's variables.\n\n## 🔌 Shell Variables Integration\n\nEcolog can load environment variables directly from your shell environment. This is useful when you want to:\n\n- Access system environment variables\n- Work with variables set by your shell profile\n- Handle dynamic environment variables\n\n#### Basic Usage\n\nEnable shell variable loading with default settings:\n\n```lua\nrequire('ecolog').setup({\n  load_shell = true\n})\n```\n\n#### Advanced Configuration\n\nFor more control over shell variable handling:\n\n```lua\nrequire('ecolog').setup({\n  load_shell = {\n    enabled = true,     -- Enable shell variable loading\n    override = false,   -- When false, .env files take precedence over shell variables\n    -- Optional: filter specific shell variables\n    filter = function(key, value)\n      -- Example: only load specific variables\n      return key:match(\"^(PATH|HOME|USER)$\") ~= nil\n    end,\n    -- Optional: transform shell variables before loading\n    transform = function(key, value)\n      -- Example: prefix shell variables for clarity\n      return \"[shell] \" .. value\n    end\n  }\n})\n```\n\n#### Configuration Options\n\n| Option      | Type          | Default | Description                                                |\n| ----------- | ------------- | ------- | ---------------------------------------------------------- |\n| `enabled`   | boolean       | `false` | Enable/disable shell variable loading                      |\n| `override`  | boolean       | `false` | When true, shell variables take precedence over .env files |\n| `filter`    | function\\|nil | `nil`   | Optional function to filter which shell variables to load  |\n| `transform` | function\\|nil | `nil`   | Optional function to transform shell variable values       |\n\n#### Features\n\n- Full integration with all Ecolog features (completion, peek, shelter mode)\n- Shell variables are marked with \"shell\" as their source\n- Configurable precedence between shell and .env file variables\n- Optional filtering and transformation of shell variables\n- Type detection and value transformation support\n\n#### Best Practices\n\n1. Use `filter` to limit which shell variables are loaded to avoid cluttering\n2. Consider using `transform` to clearly mark shell-sourced variables\n3. Be mindful of the `override` setting when working with both shell and .env variables\n4. Apply shelter mode settings to shell variables containing sensitive data\n\n## 🏢 Monorepo Support\n\nEcolog provides comprehensive monorepo support for managing environment variables across multiple workspaces and projects. This feature automatically detects monorepo structures and provides intelligent workspace-aware environment variable management.\n\n### Basic Configuration\n\nEnable monorepo support with default settings:\n\n```lua\nrequire('ecolog').setup({\n  monorepo = true,  -- Enable with default configuration\n  -- or\n  monorepo = {\n    enabled = true,\n    auto_switch = true,  -- Automatically switch to workspace based on current file\n  }\n})\n```\n\n### Advanced Configuration\n\nThe new monorepo system supports advanced configuration with provider-based detection and performance optimization:\n\n```lua\nrequire('ecolog').setup({\n  monorepo = {\n    enabled = true,\n    auto_switch = true,\n    notify_on_switch = false,  -- Show notifications when switching workspaces\n\n    -- Provider configuration\n    providers = {\n      -- Built-in providers (loaded automatically)\n      builtin = {\n        \"turborepo\",\n        \"nx\",\n        \"lerna\",\n        \"yarn_workspaces\",\n        \"cargo_workspaces\"\n      },\n      -- Custom providers\n      custom = {\n        {\n          module = \"my_custom_provider\",\n          config = { custom_option = \"value\" }\n        }\n      }\n    },\n\n    -- Performance settings\n    performance = {\n      -- Cache configuration\n      cache = {\n        max_entries = 1000,\n        default_ttl = 300000,     -- 5 minutes\n        cleanup_interval = 60000  -- 1 minute\n      },\n\n      -- Auto-switch throttling\n      auto_switch_throttle = {\n        min_interval = 100,           -- Minimum ms between checks\n        debounce_delay = 250,         -- Debounce delay for rapid changes\n        same_file_skip = true,        -- Skip if same file\n        workspace_boundary_only = true, -- Only check when crossing boundaries\n        max_checks_per_second = 10    -- Rate limiting\n      }\n    }\n  }\n})\n```\n\n### Plugin System Configuration\n\nThe new monorepo system supports a plugin architecture for extensibility:\n\n```lua\nrequire('ecolog').setup({\n  monorepo = {\n    enabled = true,\n\n    -- Plugin configuration\n    plugins = {\n      -- Load plugins from directory\n      directory = \"/path/to/my/monorepo/plugins\",\n\n      -- Or register plugins directly\n      list = {\n        {\n          name = \"my_monorepo_plugin\",\n          providers = {\n            {\n              type = \"simple\",\n              name = \"my_simple_provider\",\n              detection = {\n                file_markers = { \"my-workspace.json\" }\n              },\n              workspace = {\n                patterns = { \"apps/*\", \"libs/*\" }\n              }\n            }\n          },\n          hooks = {\n            before_detection = function(path)\n              print(\"Detecting monorepo at:\", path)\n            end,\n            after_workspace_switch = function(new_workspace, old_workspace)\n              print(\"Switched to workspace:\", new_workspace and new_workspace.name or \"none\")\n            end\n          }\n        }\n      }\n    }\n  }\n})\n```\n\n### Workspace Detection\n\nThe new system uses provider-specific detection instead of global constants:\n\n#### Built-in Providers\n\nEach provider has its own detection logic and workspace patterns:\n\n| Provider             | Detection Files                        | Workspace Patterns                     |\n| -------------------- | -------------------------------------- | -------------------------------------- |\n| **Turborepo**        | `turbo.json`                           | `apps/*`, `packages/*`                 |\n| **NX**               | `nx.json`, `workspace.json`            | `apps/*`, `libs/*`, `tools/*`, `e2e/*` |\n| **Lerna**            | `lerna.json`                           | `packages/*`                           |\n| **Yarn Workspaces**  | `package.json` (with workspaces field) | `packages/*`, `apps/*`, `services/*`   |\n| **Cargo Workspaces** | `Cargo.toml` (with workspace section)  | `crates/*`, `libs/*`, `bins/*`         |\n\n#### Custom Provider Example\n\n```lua\n-- File: lua/my_custom_provider.lua\nlocal BaseProvider = require(\"ecolog.monorepo.detection.providers.base\")\n\nlocal MyCustomProvider = {}\nsetmetatable(MyCustomProvider, { __index = BaseProvider })\n\nfunction MyCustomProvider.new(config)\n  local default_config = {\n    name = \"my_custom_provider\",\n    detection = {\n      strategies = { \"file_markers\" },\n      file_markers = { \"my-monorepo.json\" },\n      max_depth = 4,\n      cache_duration = 300000,\n    },\n    workspace = {\n      patterns = { \"workspaces/*\", \"projects/*\" },\n      priority = { \"workspaces\", \"projects\" }\n    },\n    env_resolution = {\n      strategy = \"workspace_first\",\n      inheritance = true,\n      override_order = { \"workspace\", \"root\" }\n    },\n    priority = 50,\n  }\n\n  local merged_config = config and vim.tbl_deep_extend(\"force\", default_config, config) or default_config\n  local instance = BaseProvider.new(merged_config)\n  setmetatable(instance, { __index = MyCustomProvider })\n  return instance\nend\n\nreturn MyCustomProvider\n```\n\n### Factory-Based Provider Creation\n\n```lua\n-- Using the factory system for quick custom providers\nlocal Factory = require(\"ecolog.monorepo.detection.providers.factory\")\n\n-- Create from template\nlocal my_provider = Factory.create_from_template(\"js_monorepo\", {\n  name = \"my_js_provider\",\n  detection = {\n    file_markers = { \"my-package.json\" }\n  },\n  workspace = {\n    patterns = { \"my-apps/*\", \"my-packages/*\" }\n  }\n})\n\n-- Register the provider\nlocal monorepo = require(\"ecolog.monorepo\")\nmonorepo.register_provider(my_provider.new())\n```\n\n### Environment File Resolution\n\nEach provider defines its own environment file resolution strategy:\n\n#### Resolution Strategies\n\n1. **`workspace_first`** (default): Workspace files take precedence over root files\n2. **`root_first`**: Root files take precedence over workspace files\n3. **`workspace_only`**: Only load workspace environment files\n\n#### Provider-Specific Resolution\n\nEach provider can define its own resolution strategy:\n\n```lua\n-- Example: Custom provider with specific resolution\nlocal MyProvider = {}\nsetmetatable(MyProvider, { __index = BaseProvider })\n\nfunction MyProvider.new(config)\n  local default_config = {\n    name = \"my_provider\",\n    -- Provider-specific resolution strategy\n    env_resolution = {\n      strategy = \"workspace_first\",\n      inheritance = true,\n      override_order = { \"workspace\", \"root\" }\n    },\n    -- Provider-specific workspace patterns\n    workspace = {\n      patterns = { \"my-apps/*\", \"my-packages/*\" },\n      priority = { \"my-apps\", \"my-packages\" }\n    }\n  }\n\n  local merged_config = config and vim.tbl_deep_extend(\"force\", default_config, config) or default_config\n  local instance = BaseProvider.new(merged_config)\n  setmetatable(instance, { __index = MyProvider })\n  return instance\nend\n\nreturn MyProvider\n```\n\n#### Available Templates\n\nThe factory system provides pre-configured templates:\n\n```lua\nlocal Factory = require(\"ecolog.monorepo.detection.providers.factory\")\n\n-- Available templates: \"simple\", \"js_monorepo\", \"generic\"\nlocal templates = Factory.get_available_templates()\n\n-- Create from template\nlocal provider = Factory.create_from_template(\"js_monorepo\", {\n  name = \"my_js_provider\",\n  detection = {\n    file_markers = { \"my-package.json\" }\n  }\n})\n```\n\n### Workspace Switching\n\n#### Automatic Workspace Switching\n\nWhen `auto_switch = true`, Ecolog automatically switches to the appropriate workspace based on your current file location:\n\n```lua\n-- Opens file in apps/frontend/src/component.tsx\n-- Automatically switches to apps/frontend workspace\n-- Loads environment files from apps/frontend/.env, apps/frontend/.env.local, etc.\n```\n\n#### Manual Workspace Selection\n\nWhen `auto_switch = false`, use `:EcologSelect` to manually choose environment files from all workspaces:\n\n```vim\n:EcologSelect\n```\n\nThis will show files with workspace context:\n\n```\n1. .env.local (apps/frontend)\n2. .env (apps/frontend)\n3. .env.local (apps/backend)\n4. .env (apps/backend)\n5. .env.local (packages/shared)\n6. .env (root)\n```\n\n#### Workspace Context Display\n\nAll ecolog integrations display workspace context for better identification:\n\n- **File Selection**: Shows workspace path in file listings\n- **Completion**: Displays workspace context in completion details\n- **Pickers**: Shows workspace information in Telescope, FZF, and Snacks\n- **Peek Window**: Displays workspace context in source information\n- **Statusline**: Shows current workspace and environment file\n\n### Performance\n\n#### Caching System\n\n```lua\nrequire('ecolog').setup({\n  monorepo = {\n    performance = {\n      cache = {\n        max_entries = 1000,        -- Maximum cache entries\n        default_ttl = 300000,      -- 5 minutes default TTL\n        cleanup_interval = 60000   -- 1 minute cleanup interval\n      }\n    }\n  }\n})\n```\n\n#### Auto-Switch Throttling\n\n```lua\nrequire('ecolog').setup({\n  monorepo = {\n    performance = {\n      auto_switch_throttle = {\n        min_interval = 100,               -- Minimum ms between checks\n        debounce_delay = 250,             -- Debounce rapid changes\n        same_file_skip = true,            -- Skip if same file\n        workspace_boundary_only = true,   -- Only check at boundaries\n        max_checks_per_second = 10        -- Rate limiting\n      }\n    }\n  }\n})\n```\n\n### API Usage Examples\n\n```lua\nlocal monorepo = require(\"ecolog.monorepo\")\n\n-- Setup with custom configuration\nmonorepo.setup({\n  enabled = true,\n  providers = {\n    builtin = { \"turborepo\", \"nx\" }\n  }\n})\n\n-- Detection\nlocal root_path, provider, info = monorepo.detect_monorepo_root()\nif root_path then\n  print(\"Found monorepo at:\", root_path)\n  print(\"Provider:\", provider.name)\nend\n\n-- Get workspaces\nlocal workspaces = monorepo.get_workspaces(root_path, provider)\nfor _, workspace in ipairs(workspaces) do\n  print(\"Workspace:\", workspace.name, \"at\", workspace.path)\nend\n\n-- Manual workspace switching\nlocal current_workspace = monorepo.find_current_workspace(nil, workspaces)\nif current_workspace then\n  monorepo.set_current_workspace(current_workspace)\nend\n\n-- Register custom provider\nlocal custom_provider = Factory.create_simple_provider({\n  name = \"my_provider\",\n  detection = {\n    file_markers = { \"my-config.json\" }\n  }\n})\nmonorepo.register_provider(custom_provider.new())\n\n-- Statistics and monitoring\nlocal stats = monorepo.get_stats()\nprint(\"Monorepo stats:\", vim.inspect(stats))\n```\n\n## 💡 vim.env Integration\n\nEcolog can automatically sync your environment variables with Neovim's built-in `vim.env` table, making them available to any Neovim process or plugin.\n\n### Configuration\n\nEnable vim.env module in your setup:\n\n```lua\n{\n  vim_env = true, -- false by default\n}\n```\n\n### Features\n\n- Automatically syncs environment variables to `vim.env`\n- Updates `vim.env` in real-time when environment files change\n- Cleans up variables when they are removed from the environment file\n- Provides commands to inspect the current state\n\n### Example\n\n```lua\n-- In your config\nrequire('ecolog').setup({\n  vim_env = true,\n  -- ... other options\n})\n\n-- After setup, variables from your .env file will be available in vim.env:\nprint(vim.env.DATABASE_URL) -- prints your database URL\nprint(vim.env.API_KEY)      -- prints your API key\n```\n\n### Provider Patterns\n\nThe `provider_patterns` option controls how environment variables are extracted from your code and how completion works. It can be configured in two ways:\n\n1. As a boolean (for backward compatibility):\n\n   ```lua\n   provider_patterns = true  -- Enables both extraction and completion with language patterns\n   -- or\n   provider_patterns = false -- Disables both, falls back to word under cursor and basic completion\n   ```\n\n2. As a table for fine-grained control:\n   ```lua\n   provider_patterns = {\n     extract = true,  -- Controls variable extraction from code\n     cmp = true      -- Controls completion behavior\n   }\n   ```\n\n#### Extract Mode\n\nThe `extract` field controls how variables are extracted from code for features like peek, goto definition, etc:\n\n- When `true` (default): Only recognizes environment variables through language-specific patterns\n  - Example: In JavaScript, only matches `process.env.MY_VAR` or `import.meta.env.MY_VAR`\n  - Example: In Python, only matches `os.environ.get('MY_VAR')` or `os.environ['MY_VAR']`\n\n- When `false`: Falls back to the word under cursor if no language provider matches\n  - Useful when you want to peek at any word that might be an environment variable\n  - Less strict but might give false positives\n\n#### Completion Mode\n\nThe `cmp` field controls how completion behaves:\n\n- When `true` (default):\n  - Uses language-specific triggers (e.g., `process.env.` in JavaScript)\n  - Only completes in valid environment variable contexts\n  - Formats completions according to language patterns\n\n- When `false`:\n  - Uses a basic trigger (any character)\n  - Completes environment variables anywhere\n  - Useful for more flexible but less context-aware completion\n\n#### Example Configurations\n\n1. Default behavior (strict mode):\n\n   ```lua\n   provider_patterns = {\n     extract = true,  -- Only extract vars from language patterns\n     cmp = true      -- Only complete in valid contexts\n   }\n   ```\n\n2. Flexible extraction, strict completion:\n\n   ```lua\n   provider_patterns = {\n     extract = false,  -- Extract any word as potential var\n     cmp = true       -- Only complete in valid contexts\n   }\n   ```\n\n3. Strict extraction, flexible completion:\n\n   ```lua\n   provider_patterns = {\n     extract = true,   -- Only extract vars from language patterns\n     cmp = false      -- Complete anywhere\n   }\n   ```\n\n4. Maximum flexibility:\n   ```lua\n   provider_patterns = {\n     extract = false,  -- Extract any word as potential var\n     cmp = false      -- Complete anywhere\n   }\n   ```\n\nThis affects all features that extract variables from code (peek, goto definition, etc.) and how completion behaves.\n\n## 💡 Custom Environment File Patterns\n\nEcolog supports custom patterns for matching environment files. This allows you to define your own naming conventions and directory structures beyond the default `.env*` pattern.\n\n#### Basic Usage\n\nSet a single custom pattern:\n\n```lua\nrequire('ecolog').setup({\n  env_file_patterns = { \"config/env.*\" } -- Matches env.any_here file in the config directory\n})\n```\n\nUse multiple patterns:\n\n```lua\nrequire('ecolog').setup({\n  env_file_patterns = {\n    \"config/.env\",      -- Matches .env file in config directory\n    \"config/.env.*\",    -- Matches any .env.* file in config directory\n    \"environments/*\"    -- Matches any file in environments directory\n  }\n})\n```\n\n#### Pattern Format\n\n- Patterns use glob/wildcard syntax (e.g., `*` matches any characters)\n- Patterns are relative to the project root (`path` option)\n- Default patterns (`.env`, `.envrc`, `.env.*`) are used if no custom patterns are specified\n- When custom patterns are specified, ONLY those patterns are used (defaults are not included)\n\n#### Pattern Matching Rules\n\n1. **Directory Structure**: Patterns can include directories (e.g., `config/.env`, `environments/.env.*`)\n2. **File Extensions**: Use `.*` to match any extension (e.g., `.env.*` matches `.env.development`, `.env.test`)\n3. **Wildcards**: Use `*` to match any characters (e.g., `config/*` matches any file in the config directory)\n\n#### Examples\n\n```lua\n-- Match specific environments in config directory\nenv_file_patterns = {\n  \"config/.env.development\",\n  \"config/.env.production\"\n}\n\n-- Match all env files in multiple directories\nenv_file_patterns = {\n  \"config/env/*\",\n  \"environments/*\",\n  \".env*\"\n}\n\n-- Match specific naming convention\nenv_file_patterns = {\n  \"env.*.config\",\n  \"env.*.local\"\n}\n```\n\n#### Default Behavior\n\nIf no custom patterns are specified, Ecolog uses these default patterns:\n\n- `.env` - Main environment file\n- `.envrc` - Shell environment file\n- `.env.*` - Environment-specific files (e.g., `.env.development`, `.env.test`)\n\n## 🔄 Custom Sort Functions\n\nEcolog provides two types of sort functions to customize how both environment files and variables are ordered in various interfaces:\n\n1. **File Sorting (`sort_file_fn`)**: Controls how environment files are prioritized and ordered\n2. **Variable Sorting (`sort_var_fn`)**: Controls how environment variables are sorted in completion, pickers, and other interfaces\n\n### File Sorting (`sort_file_fn`)\n\nEcolog allows you to customize how environment files are sorted using the `sort_file_fn` option (previously named `sort_fn`). This is useful when you need specific ordering beyond the default alphabetical sorting.\n\n#### Basic Usage\n\n```lua\nrequire('ecolog').setup({\n  sort_file_fn = function(a, b)\n    -- Sort by file size (smaller files first)\n    local a_size = vim.fn.getfsize(a)\n    local b_size = vim.fn.getfsize(b)\n    return a_size \u003c b_size\n  end\n})\n```\n\n#### Examples\n\n1. **Priority-based sorting**:\n\n```lua\nsort_file_fn = function(a, b)\n  local priority = {\n    [\".env.production\"] = 1,\n    [\".env.staging\"] = 2,\n    [\".env.development\"] = 3,\n    [\".env\"] = 4\n  }\n  local a_name = vim.fn.fnamemodify(a, \":t\")\n  local b_name = vim.fn.fnamemodify(b, \":t\")\n  return (priority[a_name] or 99) \u003c (priority[b_name] or 99)\nend\n```\n\n2. **Sort by modification time**:\n\n```lua\nsort_file_fn = function(a, b)\n  local a_time = vim.fn.getftime(a)\n  local b_time = vim.fn.getftime(b)\n  return a_time \u003e b_time  -- Most recently modified first\nend\n```\n\n3. **Sort by environment type**:\n\n```lua\nsort_file_fn = function(a, b)\n  -- Extract environment type from filename\n  local function get_env_type(file)\n    local name = vim.fn.fnamemodify(file, \":t\")\n    return name:match(\"^%.env%.(.+)$\") or \"\"\n  end\n  return get_env_type(a) \u003c get_env_type(b)\nend\n```\n\n### Variable Sorting (`sort_var_fn`)\n\nThe `sort_var_fn` option allows you to customize how environment variables are sorted in various interfaces (completion, pickers, etc.).\n\n#### Basic Usage\n\n```lua\nrequire('ecolog').setup({\n  sort_var_fn = function(a, b)\n    -- Sort by variable name length (shorter names first)\n    return #a.name \u003c #b.name\n  end\n})\n```\n\n#### Examples\n\n1. **Sort by value type**:\n\n```lua\nsort_var_fn = function(a, b)\n  -- Sort variables with types before those without\n  if a.type and not b.type then\n    return true\n  elseif not a.type and b.type then\n    return false\n  end\n  -- Then sort alphabetically by name\n  return a.name \u003c b.name\nend\n```\n\n2. **Sort by source priority**:\n\n```lua\nsort_var_fn = function(a, b)\n  local priority = {\n    [\".env.local\"] = 1,\n    [\".env\"] = 2,\n    [\"shell\"] = 3\n  }\n  local a_priority = priority[a.source] or 99\n  local b_priority = priority[b.source] or 99\n  return a_priority \u003c b_priority\nend\n```\n\n3. **Sort by custom categories**:\n\n```lua\nsort_var_fn = function(a, b)\n  -- Sort API keys first, then database variables, then others\n  local function get_category(var)\n    if var.name:match(\"_KEY$\") then return 1\n    elseif var.name:match(\"^DB_\") then return 2\n    else return 3 end\n  end\n  local a_cat = get_category(a)\n  local b_cat = get_category(b)\n  if a_cat ~= b_cat then\n    return a_cat \u003c b_cat\n  end\n  return a.name \u003c b.name\nend\n```\n\n#### Features\n\n- Custom sorting logic for both environment files and variables\n- Access to full file paths for file sorting\n- Access to variable metadata (name, type, source, value) for variable sorting\n- Real-time sorting when files or variables change\n- Affects all interfaces where variables are displayed (completion, pickers, etc.)\n\n## 🔌 Integrations\n\n### Nvim-cmp Integration\n\nAdd `ecolog` to your nvim-cmp sources:\n\n```lua\nrequire('cmp').setup({\n  sources = {\n    { name = 'ecolog' },\n    -- your other sources...\n  },\n})\n```\n\nNvim-cmp integration is enabled by default. To disable it:\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    nvim_cmp = false,\n  },\n})\n```\n\nSee [Currently Supported Languages](#currently-supported) for available completion triggers and [Custom Providers](#-custom-providers) for adding support for additional languages.\n\n### Blink-cmp Integration\n\nPS: When blink_cmp is enabled, nvim_cmp is disabled by default.\n\nEcolog provides an integration with [blink.cmp](https://github.com/saghen/blink.cmp) for environment variable completions. To enable it:\n\n1. Enable the integration in your Ecolog setup:\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    blink_cmp = true,\n  },\n})\n```\n\n2. Configure Blink CMP to use the Ecolog source:\n\n```lua\n{\n  \"saghen/blink.cmp\",\n  opts = {\n    sources = {\n      default = { 'ecolog', 'lsp', 'path', 'snippets', 'buffer' },\n      providers = {\n        ecolog = { name = 'ecolog', module = 'ecolog.integrations.cmp.blink_cmp' },\n      },\n    },\n  },\n}\n```\n\nSee [Currently Supported Languages](#currently-supported) for available completion triggers and [Custom Providers](#-custom-providers) for adding support for additional languages.\n\n### Omnifunc Integration\n\nEcolog provides a built-in omnifunc integration that enables environment variable completion using Vim's native completion system (`\u003cC-x\u003e\u003cC-o\u003e`). This is particularly useful if you prefer not to use nvim-cmp or blink-cmp, or want a lightweight completion option.\n\n#### Setup\n\nThe omnifunc integration is disabled by default. To enable it:\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    omnifunc = true,  -- Enable omnifunc integration with automatic setup (default)\n    -- Or with configuration options:\n    omnifunc = {\n      auto_setup = false,  -- Disable automatic setup, allowing manual configuration\n    },\n  },\n})\n```\n\nWhen enabled with `auto_setup = true` (the default), Ecolog will automatically set itself as the omnifunc provider for filetypes that don't already have one configured.\n\n#### Usage\n\n1. In insert mode, type a language-specific environment variable trigger (e.g., `process.env.` for JavaScript)\n2. Press `\u003cC-x\u003e\u003cC-o\u003e` to trigger omni completion\n3. Navigate through completions using `\u003cC-n\u003e` and `\u003cC-p\u003e`\n4. The preview window will automatically appear at the top of your screen showing:\n   - Variable type\n   - Current value\n   - Source file\n   - Any associated comments\n5. To close the preview window after completion:\n   - It will close automatically when you leave insert mode\n   - Or press `\u003cC-w\u003e\u003cC-z\u003e` to close it manually\n6. Press `\u003cEnter\u003e` to select a completion\n\nThe preview window will show information in this format:\n\n```\nVARIABLE_NAME [type] = value # comment (if any)\n```\n\n#### Shelter Mode Integration\n\nThe omnifunc integration respects shelter mode settings. When shelter mode is enabled for cmp:\n\n```lua\nrequire('ecolog').setup({\n  shelter = {\n    modules = {\n      cmp = true,  -- Enable shelter mode for all completion interfaces including omnifunc\n    }\n  }\n})\n```\n\nVariable values will be masked in the completion menu according to your shelter mode configuration. Note that this setting affects all completion interfaces (nvim-cmp, blink-cmp, and omnifunc) since they share the same completion infrastructure.\n\n#### Manual Setup\n\nIf you prefer to have full control over where and when the omnifunc is set, you can disable automatic setup with `auto_setup = false` and configure it manually:\n\n```lua\n-- In your configuration, for specific filetypes:\nvim.api.nvim_create_autocmd(\"FileType\", {\n  pattern = { \"javascript\", \"typescript\", \"python\" },  -- Add your desired filetypes\n  callback = function()\n    vim.bo.omnifunc = \"v:lua.require'ecolog.integrations.cmp.omnifunc'.complete\"\n  end,\n})\n\n-- Or for a specific buffer:\nvim.bo.omnifunc = \"v:lua.require'ecolog.integrations.cmp.omnifunc'.complete\"\n```\n\nThis gives you full control over when and where Ecolog's environment variable completion is available. The automatic setup only applies to filetypes without existing omnifunc settings, ensuring it doesn't override your existing configurations.\n\n### LSP Integration (Experimental)\n\n\u003e ⚠️ **Warning**: The LSP integration is currently experimental and may interfere with your existing LSP setup. Use with caution.\n\nEcolog provides optional LSP integration that enhances the hover and definition functionality for environment variables. When enabled, it will:\n\n- Show environment variable values when hovering over them\n- Jump to environment variable definitions using goto-definition\n\nmeaning you dont need any custom keymaps\n\n#### Setup\n\nTo enable LSP integration, add this to your Neovim configuration:\n\n```lua\nrequire('ecolog').setup({\n    integrations = {\n        lsp = true,\n    }\n})\n```\n\nPS: If you're using lspsaga, please see section [LSP Saga Integration](#lsp-saga-integration) don't use lsp integration use one or the other.\n\n#### Features\n\n- **Hover Preview**: When you hover (K) over an environment variable, it will show the value and metadata in a floating window\n- **Goto Definition**: Using goto-definition (gd) on an environment variable will jump to its definition in the .env file\n\n#### Known Limitations\n\n1. The integration overrides the default LSP hover and definition handlers\n2. May conflict with other plugins that modify LSP hover behavior\n3. Performance impact on LSP operations (though optimized and should be unnoticable)\n\n#### Disabling LSP Integration\n\nIf you experience any issues, you can disable the LSP integration:\n\n```lua\nrequire('ecolog').setup({\n    integrations = {\n        lsp = false,\n    }\n})\n```\n\nPlease report such issues on our GitHub repository\n\n### LSP Saga Integration\n\nEcolog provides integration with [lspsaga.nvim](https://github.com/nvimdev/lspsaga.nvim) that enhances hover and goto-definition functionality for environment variables while preserving Saga's features for other code elements.\n\n#### Setup\n\nTo enable LSP Saga integration, add this to your configuration:\n\n```lua\nrequire('ecolog').setup({\n    integrations = {\n        lspsaga = true,\n    }\n})\n```\n\nPS: If you're using lspsaga then don't use lsp integration use one or the other.\n\n#### Features\n\nThe integration adds two commands that intelligently handle both environment variables and regular code:\n\n1. **EcologSagaHover**:\n   - Shows environment variable value when hovering over env vars\n   - Falls back to Saga's hover for other code elements\n   - Automatically replaces existing Saga hover keymaps\n\n2. **EcologSagaGD** (Goto Definition):\n   - Jumps to environment variable definition in .env file\n   - Uses Saga's goto definition for other code elements\n   - Automatically replaces existing Saga goto-definition keymaps\n\n\u003e 💡 **Note**: When enabled, the integration automatically detects and updates your existing Lspsaga keymaps to use Ecolog's enhanced functionality. No manual keymap configuration required!\n\n#### Example Configuration\n\n```lua\n{\n  'ph1losof/ecolog.nvim',\n  opts = {\n    integrations = {\n      lspsaga = true,\n    }\n  },\n}\n```\n\n\u003e 💡 **Note**: The LSP Saga integration provides a smoother experience than the experimental LSP integration if you're already using Saga in your setup.\n\n### Telescope Integration\n\nFirst, load the extension:\n\n```lua\nrequire('telescope').load_extension('ecolog')\n```\n\nThen configure it in your Telescope setup (optional):\n\n```lua\nrequire('telescope').setup({\n  extensions = {\n    ecolog = {\n      shelter = {\n        -- Whether to show masked values when copying to clipboard\n        mask_on_copy = false,\n      },\n      -- Default keybindings\n      mappings = {\n        -- Key to copy value to clipboard\n        copy_value = \"\u003cC-y\u003e\",\n        -- Key to copy name to clipboard\n        copy_name = \"\u003cC-n\u003e\",\n        -- Key to append value to buffer\n        append_value = \"\u003cC-a\u003e\",\n        -- Key to append name to buffer (defaults to \u003cCR\u003e)\n        append_name = \"\u003cCR\u003e\",\n        -- Key to edit environment variable\n        edit_var = \"\u003cC-e\u003e\",\n      },\n    }\n  }\n})\n```\n\n### FZF Integration\n\nEcolog integrates with [fzf-lua](https://github.com/ibhagwan/fzf-lua) to provide a fuzzy finder interface for environment variables.\n\n#### Setup\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    fzf = {\n      shelter = {\n        mask_on_copy = false, -- Whether to mask values when copying\n      },\n      mappings = {\n        copy_value = \"ctrl-y\",  -- Copy variable value to clipboard\n        copy_name = \"ctrl-n\",   -- Copy variable name to clipboard\n        append_value = \"ctrl-a\", -- Append value at cursor position\n        append_name = \"enter\",   -- Append name at cursor position\n        edit_var = \"ctrl-e\",     -- Edit environment variable\n      },\n    }\n  }\n})\n```\n\nYou can trigger the FZF picker using `:EcologFzf` command.\n\n#### Features\n\n- 🔍 Fuzzy search through environment variables\n- 📋 Copy variable names or values to clipboard\n- ⌨️ Insert variables into your code\n- ✏️ Edit environment variables directly from the picker\n- 🛡️ Integrated with shelter mode for sensitive data protection\n- 📝 Real-time updates when environment files change\n\n#### Usage\n\nOpen the environment variables picker:\n\n```vim\n:EcologFzf\n```\n\n#### Default Keymaps\n\n| Key       | Action                  |\n| --------- | ----------------------- |\n| `\u003cEnter\u003e` | Insert variable name    |\n| `\u003cC-y\u003e`   | Copy value to clipboard |\n| `\u003cC-n\u003e`   | Copy name to clipboard  |\n| `\u003cC-a\u003e`   | Append value to buffer  |\n| `\u003cC-e\u003e`   | Edit variable value     |\n\nAll keymaps are customizable through the configuration.\n\n### Snacks Integration\n\nEcolog integrates with [snacks.nvim](https://github.com/folke/snacks.nvim) to provide a modern and beautiful picker interface for environment variables.\n\n#### Setup\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    snacks = {\n      shelter = {\n        mask_on_copy = false, -- Whether to mask values when copying\n      },\n      keys = {\n        copy_value = \"\u003cC-y\u003e\",  -- Copy variable value to clipboard\n        copy_name = \"\u003cC-u\u003e\",   -- Copy variable name to clipboard\n        append_value = \"\u003cC-a\u003e\", -- Append value at cursor position\n        append_name = \"\u003cCR\u003e\",   -- Append name at cursor position\n        edit_var = \"\u003cC-e\u003e\",     -- Edit environment variable\n      },\n      layout = {  -- Any Snacks layout configuration\n        preset = \"dropdown\",\n        preview = false,\n      },\n    }\n  }\n})\n```\n\nYou can trigger the Snacks picker using `:EcologSnacks` command.\n\n#### Features\n\n- 🎨 Beautiful VSCode-like interface\n- 🔍 Real-time fuzzy search\n- 📋 Copy variable names or values to clipboard\n- ⌨️ Insert variables into your code\n- ✏️ Edit environment variables directly from the picker\n- 🛡️ Integrated with shelter mode for sensitive data protection\n- 📝 Live updates when environment files change\n- 🎯 Syntax highlighting for better readability\n\n#### Usage\n\nOpen the environment variables picker:\n\n```vim\n:EcologSnacks\n```\n\n#### Default Keymaps\n\n| Key     | Action                  |\n| ------- | ----------------------- |\n| `\u003cCR\u003e`  | Insert variable name    |\n| `\u003cC-y\u003e` | Copy value to clipboard |\n| `\u003cC-u\u003e` | Copy name to clipboard  |\n| `\u003cC-a\u003e` | Append value to buffer  |\n| `\u003cC-e\u003e` | Edit variable value     |\n\nAll keymaps are customizable through the configuration.\n\n### Custom Actions for Pickers\n\nAll picker integrations (Telescope, FZF, and Snacks) support custom actions. This allows you to define your own key mappings and actions to perform on environment variables.\n\n#### Adding Custom Actions\n\nYou can add custom actions in your Neovim configuration when setting up Ecolog:\n\n```lua\nrequire(\"ecolog\").setup({\n  -- Your other configuration options\n  integrations = {\n    telescope = {\n      custom_actions = {\n        -- Define a custom action that appends the variable with special formatting\n        format_var = {\n          key = \"\u003cC-f\u003e\",\n          callback = function(item, picker)\n            -- item contains: name, value, masked_value, source, type\n            return \"${\" .. item.name .. \"}\"\n          end,\n          opts = {\n            close_on_action = true, -- Close the picker after action\n            notify = true,          -- Show notification after action\n            message = \"Formatted variable appended\" -- Custom notification message\n          }\n        }\n      }\n    },\n    fzf = {\n      custom_actions = {\n        -- Similar structure for FZF custom actions\n      }\n    },\n    snacks = {\n      custom_actions = {\n        -- Similar structure for Snacks custom actions\n      }\n    }\n  }\n})\n```\n\n#### Adding Actions After Setup\n\nYou can also add custom actions after Ecolog has been set up:\n\n```lua\n-- For Telescope\nrequire(\"telescope\").extensions.ecolog.add_action(\n  \"format_var\",          -- Action name\n  \"\u003cC-f\u003e\",               -- Key mapping\n  function(item, picker) -- Callback function\n    return \"${\" .. item.name .. \"}\"\n  end,\n  {                      -- Options\n    close_on_action = true,\n    notify = true,\n    message = \"Formatted variable appended\"\n  }\n)\n\n-- For FZF\nrequire(\"ecolog.integrations.fzf\").add_action(\"format_var\", \"ctrl-f\", function(item, picker)\n  return \"${\" .. item.name .. \"}\"\nend, { notify = true })\n\n-- For Snacks\nrequire(\"ecolog.integrations.snacks\").add_action(\"format_var\", \"\u003cC-f\u003e\", function(item, picker)\n  return \"${\" .. item.name .. \"}\"\nend, { close_on_action = true })\n```\n\n#### Custom Action Parameters\n\n- `name`: A unique name for the action\n- `key`: A string or table of strings representing the key mappings\n- `callback`: A function that receives:\n  - `item`: The selected environment variable data\n  - `picker`: The picker instance\n- `opts`: Options table with:\n  - `close_on_action`: Whether to close the picker after action (default: true)\n  - `notify`: Whether to show a notification after action (default: true)\n  - `message`: Custom notification message\n\nThe `item` parameter contains the following fields:\n\n- `name`: The environment variable name\n- `value`: The actual value\n- `masked_value`: The masked value (if shelter.mask_on_copy is enabled)\n- `source`: The source of the variable\n- `type`: The type of the variable\n\n### Statusline Integration\n\nEcolog provides a built-in statusline component that shows your current environment file, variable count, and shelter mode status. It supports both native statusline and lualine integration.\n\n#### Setup\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    statusline = {\n      hidden_mode = false,  -- Hide when no env file is loaded\n      icons = {\n        enabled = true,     -- Enable icons in statusline\n        env = \"🌲\",         -- Icon for environment file\n        shelter = \"🛡️\",     -- Icon for shelter mode\n      },\n      format = {\n        env_file = function(name)\n          return name       -- Format environment file name\n        end,\n        vars_count = function(count)\n          return string.format(\"%d vars\", count)  -- Format variables count\n        end,\n      },\n      highlights = {\n        enabled = true,           -- Enable custom highlights\n        env_file = \"Directory\",   -- Highlight group for file name\n        vars_count = \"Number\",    -- Highlight group for vars count\n        icons = \"Special\"\n      },\n    }\n  }\n})\n```\n\n#### Native Statusline\n\nAdd to your statusline:\n\n```lua\nvim.o.statusline = \"%{%v:lua.require'ecolog'.get_status()%}\"\n```\n\n#### Lualine Integration\n\nAdd to your lualine config:\n\n```lua\nrequire('lualine').setup({\n  sections = {\n    lualine_x = {\n      require('ecolog.integrations.statusline').lualine(),\n    }\n  }\n})\n```\n\n#### Features\n\n- Shows current environment file name\n- Displays number of loaded variables\n- Indicates shelter mode status\n- Configurable icons and formatting\n- Custom highlighting support\n- Automatic updates on file changes\n- Optional hiding when no env file is loaded\n\n#### Advanced Highlighting\n\nThe statusline integration supports customizable highlighting with both highlight group names and hex color codes:\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    statusline = {\n      highlights = {\n        enabled = true,\n        -- Using highlight groups\n        env_file = \"Directory\",   -- Highlight group for file name\n        vars_count = \"Number\",    -- Highlight group for vars count\n        icons = \"Special\",        -- Highlight group for icons\n\n        -- OR using hex color codes\n        env_file = \"#7FBBB3\",     -- Hex color for file name\n        vars_count = \"#A7C080\",   -- Hex color for vars count\n        icons = \"#ED8796\",        -- Hex color for icons\n\n        -- OR different highlights for env and shelter icons\n        icons = {\n          env = \"String\",         -- Highlight group for env icon\n          shelter = \"WarningMsg\"  -- Highlight group for shelter icon\n        },\n        -- OR with hex colors\n        icons = {\n          env = \"#83C092\",        -- Hex color for env icon\n          shelter = \"#E67E80\"     -- Hex color for shelter icon\n        }\n      },\n    }\n  }\n})\n```\n\nThe highlighting system automatically detects the format and applies the appropriate highlighting:\n\n- Highlight group names: Links to existing highlight groups in your colorscheme\n- Hex color codes: Creates dynamic highlight groups with the specified colors\n- Table with env/shelter keys: Allows different highlights for each mode\n\nBoth the native statusline and lualine integration fully support these highlighting options for all elements (file name, variable count, and icons), ensuring a consistent appearance across different statusline implementations.\n\n### AWS Secrets Manager\n\nThe AWS Secrets Manager integration allows you to load secrets from AWS Secrets Manager into your environment variables. This integration requires the AWS CLI to be installed and configured with appropriate credentials.\n\n\u003e ⚠️ **Note**: This is a WIP feature and may have breaking changes in future releases.\n\n#### Configuration\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    secret_managers = {\n      aws = {\n        enabled = true, -- Enable AWS Secrets Manager integration\n        override = false, -- When true, AWS secrets take precedence over .env files and shell variables\n        region = \"us-west-2\", -- Required: AWS region where your secrets are stored\n        profile = \"default\", -- Optional: AWS profile to use\n        secrets = { -- Optional: List of secret names to fetch on startup\n          \"my-app/dev/database\",\n          \"my-app/dev/api\"\n        },\n        filter = function(key, value) -- Optional: Filter function for secrets\n          return true -- Return true to include the secret, false to exclude it\n        end,\n        transform = function(key, value) -- Optional: Transform function for secret values\n          return value -- Return the transformed value\n        end\n      }\n    }\n  }\n})\n```\n\n#### Features\n\n- Load secrets from AWS Secrets Manager into your environment variables\n- Support for both JSON and plain text secrets:\n  - JSON secrets: Each key-value pair becomes a separate environment variable\n  - Plain text secrets: The last part of the secret name is used as the variable name\n- Interactive secret selection with visual feedback\n- Integration with shelter mode for sensitive data protection\n- Automatic credential validation and error handling\n- Support for AWS profiles and regions\n- Direct configuration access through `:EcologAWSConfig` command\n- Real-time configuration changes with automatic secret reloading\n- Parallel secret loading with retry support\n- Proper cleanup on Neovim exit\n\n#### Interactive Configuration\n\nThe `:EcologAWSConfig` command provides access to three main configuration options:\n\n1. **Region**: Select or change the AWS region\n2. **Profile**: Choose the AWS profile to use\n3. **Secrets**: Select which secrets to load\n\nEach option can be accessed directly using:\n\n```vim\n:EcologAWSConfig region    \" Configure AWS region\n:EcologAWSConfig profile   \" Configure AWS profile\n:EcologAWSConfig secrets   \" Configure which secrets to load\n```\n\nDefault keybindings in the configuration UI:\n\n| Key       | Action                              |\n| --------- | ----------------------------------- |\n| `j`/`k`   | Navigate through options            |\n| `\u003cspace\u003e` | Toggle selection (for multi-select) |\n| `\u003cCR\u003e`    | Select option or confirm selection  |\n| `q`/`ESC` | Close without changes               |\n\n#### Requirements\n\n- AWS CLI v2 installed and configured (`aws --version` should show version 2.x.x)\n- AWS CLI must be authenticated with valid credentials using one of:\n  - `aws configure` to set up credentials\n  - AWS SSO login (`aws sso login`)\n  - Environment variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY)\n  - IAM role with appropriate permissions\n- Appropriate AWS credentials with permissions to access the specified secrets\n\n#### Error Handling\n\nThe integration provides clear error messages for common issues:\n\n- Invalid or missing AWS credentials\n- Network connectivity problems\n- Access denied errors\n- Region configuration issues\n- Missing or invalid secrets\n- Command timeout errors\n- AWS CLI installation issues\n\n### HashiCorp Vault Secrets\n\nThe HashiCorp Vault Secrets integration allows you to load secrets from HCP Vault Secrets into your environment variables. This integration requires the HCP CLI to be installed and configured with appropriate credentials.\n\n\u003e ⚠️ **Note**: This is a WIP feature and may have breaking changes in future releases.\n\n#### Configuration\n\n```lua\nrequire('ecolog').setup({\n  integrations = {\n    secret_managers = {\n      vault = {\n        enabled = true, -- Enable HCP Vault Secrets integration\n        override = false, -- When true, Vault secrets take precedence over .env files and shell variables\n        apps = { -- Optional: List of application names to fetch secrets from by default\n          \"sample-app\",\n          \"database\"\n        },\n        filter = function(key, value) -- Optional: Filter function for secrets\n          return true -- Return true to include the secret, false to exclude it\n        end,\n        transform = function(key, value) -- Optional: Transform function for secret values\n          return value -- Return the transformed value\n        end\n      }\n    }\n  }\n})\n```\n\n#### Features\n\n- Load secrets from HCP Vault Secrets into your environment variables\n- Support for both JSON and plain text secrets:\n  - JSON secrets: Each key-value pair becomes a separate environment variable\n  - Plain text secrets: The secret name is used as the variable name\n- Interactive application and secret selection with visual feedback\n- Integration with shelter mode for sensitive data protection\n- Automatic credential validation and error handling\n- Support for HCP service principal authentication\n- Direct configuration access through `:EcologVaultConfig` command\n- Real-time configuration changes with automatic secret reloading\n- Proper cleanup on Neovim exit\n\n#### Interactive Configuration\n\nThe `:EcologVaultConfig` command provides access to three main configuration options:\n\n1. **Organization**: Select or change the HCP organization\n2. **Project**: Choose the HCP project to use\n3. **Apps**: Select which applications to load secrets from\n\nEach option can be accessed directly using:\n\n```vim\n:EcologVaultConfig organization    \" Configure HCP organization\n:EcologVaultConfig project        \" Configure HCP project\n:EcologVaultConfig apps           \" Configure which apps to load secrets from\n```\n\nDefault keybindings in the configuration UI:\n\n| Key       | Action                              |\n| --------- | ----------------------------------- |\n| `j`/`k`   | Navigate through options            |\n| `\u003cspace\u003e` | Toggle selection (for multi-select) |\n| `\u003cCR\u003e`    | Select option or confirm selection  |\n| `q`/`ESC` | Close without changes               |\n\n#### Requirements\n\n- HCP CLI installed (`hcp --version` should be available)\n- HCP CLI must be authenticated with valid credentials using one of:\n  - HCP service principal credentials (client ID and client secret)\n  - `hcp auth login` command\n- Appropriate HCP permissions to access the specified applications and secrets\n\n#### Error Handling\n\nThe integration provides clear error messages for common issues:\n\n- Invalid or missing HCP credentials\n- Network connectivity problems\n- Access denied errors\n- Missing or invalid applications\n- Missing or invalid secrets\n- Command timeout errors\n- HCP CLI installation issues\n\n### 🔍 Shelter Previewers\n\n`ecolog.nvim` integrates with various file pickers to provide a secure way to use file picker without leaking sensitive data, when searching for files.\n\n- Secure environment file previews\n- Configurable masking behavior\n- Minimal memory footprint\n- Efficient buffer management\n- Integration with fzf-lua, telescope and snacks.picker\n\n#### Telescope Previewer\n\nConfiguration:\n\n```lua\nrequire('ecolog').setup({\n  shelter = {\n    modules = {\n      telescope_previewer = true, -- Mask values in telescope preview buffers\n    }\n  }\n})\n```\n\n#### FZF Previewer\n\nConfiguration:\n\n```lua\nrequire('ecolog').setup({\n  shelter = {\n    modules = {\n      fzf_previewer = true, -- Mask values in fzf preview buffers\n    }\n  }\n})\n```\n\n#### Snacks Previewer\n\nConfiguration:\n\n```lua\nrequire('ecolog').setup({\n  shelter = {\n    modules = {\n      snacks_previewer = true,    -- Mask values in snacks previewer\n    }\n  }\n})\n```\n\n## 🛡️ Shelter Mode\n\nShelter mode provides a secure way to work with sensitive environment variables by masking their values in different contexts. This feature helps prevent accidental exposure of sensitive data like API keys, passwords, tokens, and other credentials.\n\n### 🔧 Configuration\n\n```lua\nrequire('ecolog').setup({\n    shelter = {\n        configuration = {\n            -- Partial mode configuration:\n            -- false: completely mask values (default)\n            -- true: use default partial masking settings\n            -- table: customize partial masking\n            -- partial_mode = false,\n            -- or with custom settings:\n            partial_mode = {\n                show_start = 3,    -- Show first 3 characters\n                show_end = 3,      -- Show last 3 characters\n                min_mask = 3,      -- Minimum masked characters\n            },\n            mask_char = \"*\",   -- Character used for masking\n            mask_length = nil, -- Optional: fixed length for masked portion (defaults to value length)\n            skip_comments = false, -- Skip masking comment lines in environment files (default: false)\n        },\n        modules = {\n            cmp = false,       -- Mask values in completion\n            peek = false,      -- Mask values in peek view\n            files = false,     -- Mask values in files\n            telescope = false, -- Mask values in telescope integration\n            telescope_previewer = false, -- Mask values in telescope preview buffers\n            fzf = false,       -- Mask values in fzf picker\n            fzf_previewer = false, -- Mask values in fzf preview buffers\n            snacks = false,    -- Mask values in snacks picker\n            snacks_previewer = false,    -- Mask values in snacks previewer\n        }\n    },\n    path = vim.fn.getcwd(), -- Path to search for .env files\n    preferred_environment = \"development\", -- Optional: prioritize specific env files\n})\n```\n\n### 🎯 Features\n\n#### Module-specific Masking\n\n1. **Completion Menu (`cmp = true`)**\n   - Masks values in nvim-cmp completion menu\n   - Protects sensitive data during autocompletion\n\n2. **Peek View (`peek = true`)**\n   - Masks values when using EcologPeek command\n   - Allows secure variable inspection\n\n3. **File View (`files = true`)**\n   - Masks values directly in .env files\n   - Use `:EcologShelterLinePeek` to temporarily reveal values\n\n4. **Telescope Preview (`telescope_previewer = true`)**\n   - Masks values in telescope preview buffers\n   - Automatically applies to any `.env` file previewed in telescope with support of custom env file patterns\n   - Maintains masking state across buffer refreshes\n\n5. **FZF Preview (`fzf_previewer = true`)**\n   - Masks values in fzf-lua preview buffers\n   - Automatically applies to any `.env` file previewed in fzf-lua with support of custom env file patterns\n   - Supports all fzf-lua commands that show previews (files, git_files, live_grep, etc.)\n   - Maintains masking state across buffer refreshes\n   - Optimized for performance with buffer content caching\n\n6. **FZF Picker (`fzf = true`)**\n   - Masks values in fzf-lua picker\n\n7. **Telescope Integration (`telescope = true`)**\n   - Masks values in telescope picker from integration\n\n8. **Snacks Integration (`snacks = true`, `snacks_previewer = true`)**\n   - Masks values in snacks picker and previewer\n   - Provides secure browsing of environment variables\n\n#### Partial Masking\n\nThree modes of operation:\n\n1. **Full Masking (Default)**\n\n   ```lua\n   partial_mode = false\n   -- Example: \"my-secret-key\" -\u003e \"************\"\n   ```\n\n2. **Default Partial Masking**\n\n   ```lua\n   partial_mode = true\n   -- Example: \"my-secret-key\" -\u003e \"my-***-key\"\n   ```\n\n3. **Custom Partial Masking**\n   ```lua\n   partial_mode = {\n       show_start = 4,    -- Show more start characters\n       show_end = 2,      -- Show fewer end characters\n       min_mask = 3,      -- Minimum mask length\n   }\n   -- Example: \"my-secret-key\" -\u003e \"my-s***ey\"\n   ```\n\n#### Masking Length Control\n\nYou can control the length of masked portions using the `mask_length` option:\n\n1. **Full Masking Mode**:\n\n   ```lua\n   shelter = {\n       configuration = {\n           partial_mode = false,\n           mask_length = 5  -- All masked values will be 5 characters long\n       }\n   }\n   -- Examples:\n   -- \"my-secret-key\" -\u003e \"*****\"    -- Long value becomes 5 chars\n   -- \"short\" -\u003e \"*****\"            -- Short value padded to 5 chars\n   -- \"very-long-secret\" -\u003e \"*****\" -- Long value truncated to 5 chars\n   ```\n\n2. **Partial Masking Mode**:\n   ```lua\n   shelter = {\n       configuration = {\n           partial_mode = true,\n           mask_length = 5  -- Masked portion will be 5 characters\n       }\n   }\n   -- Example: \"my-secret-key\" -\u003e \"my-*****-key\"\n   -- Example: \"short-key\" -\u003e \"sho*****key\"\n   ```\n\nWhen `mask_length` is not set (nil), the masked portion will match the length of the original value.\n\n### 🎮 Commands\n\n`:EcologShelterToggle` provides flexible control over shelter mode:\n\n1. Basic Usage:\n\n   ```vim\n   :EcologShelterToggle              \" Toggle between all-off and initial settings\n   ```\n\n2. Global Control:\n\n   ```vim\n   :EcologShelterToggle enable       \" Enable all shelter modes\n   :EcologShelterToggle disable      \" Disable all shelter modes\n   ```\n\n3. Feature-Specific Control:\n\n   ```vim\n   :EcologShelterToggle enable cmp   \" Enable shelter for completion only\n   :EcologShelterToggle disable peek \" Disable shelter for peek only\n   :EcologShelterToggle enable files \" Enable shelter for file display\n   ```\n\n4. Quick Value Reveal:\n\n   ```vim\n   :EcologShelterLinePeek           \" Temporarily reveal value on current line\n   ```\n\n   - Shows the actual value for the current line\n   - Value is hidden again when cursor moves away\n   - Only works when shelter mode is enabled for files\n\n### 📝 Example\n\nOriginal `.env` file:\n\n```env\n# Authentication\nJWT_SECRET=my-super-secret-key\nAUTH_TOKEN=\"bearer 1234567890\"\n\n# Database Configuration\nDB_HOST=localhost\nDB_USER=admin\nDB_PASS=secure_password123\n```\n\nWith full masking (partial_mode = false):\n\n```env\n# Authentication\nJWT_SECRET=********************\nAUTH_TOKEN=******************\n\n# Database Configuration\nDB_HOST=*********\nDB_USER=*****\nDB_PASS=******************\n```\n\n#### Partial Masking Examples\n\nWith default settings (show_start=3, show_end=3, min_mask=3):\n\n```\n\"mysecretkey\"     -\u003e \"mys***key\"    # Enough space for min_mask (3) characters\n\"secret\"          -\u003e \"******\"        # Not enough space for min_mask between shown parts\n\"api_key\"         -\u003e \"*******\"       # Would only have 1 char for masking, less than min_mask\n\"very_long_key\"   -\u003e \"ver*****key\"   # Plenty of space for masking\n```\n\nThe min_mask setting ensures that sensitive values are properly protected by requiring\na minimum number of masked characters between the visible parts. If this minimum\ncannot be met, the entire value is masked for security.\n\n### Configuration Options\n\nThe files module can be configured in two ways:\n\n1. **Simple boolean configuration**:\n\n```lua\nshelter = {\n    modules = {\n        files = true  -- Simply enable/disable files module\n    }\n}\n```\n\n2. **Detailed configuration with options**:\n\n```lua\nshelter = {\n    modules = {\n        files = {\n            shelter_on_leave = false,  -- Control automatic re-enabling of shelter when leaving buffer\n            disable_cmp = true,        -- Disable completion in sheltered buffers (default: true)\n            skip_comments = false,     -- Skip masking comment lines in environment files (default: false)\n        }\n    },\n    configuration = {\n        skip_comments = false,     -- Skip masking comment lines in environment files (default: false)\n    }\n}\n```\n\nWhen `shelter_on_leave` is enabled (default when using boolean configuration), the shelter mode will automatically re-enable itself when you leave an environment file buffer. This provides an extra layer of security by ensuring sensitive data is always masked when not actively being viewed.\n\nThe `disable_cmp` option (enabled by default) will automatically disable both nvim-cmp and blink-cmp completions in sheltered buffers. This prevents sensitive values from being exposed through the completion menu while editing environment files. Completion is automatically re-enabled when unsheltering the buffer.\n\nThe `skip_comments` option (disabled by default) allows you to keep comments visible while masking the actual environment variable values. This can be useful when you want to maintain readability of documentation in your environment files while still protecting sensitive data.\n\n### Enhanced Comment Masking\n\nEcolog now intelligently masks key-value pairs found in comments. This provides additional security for comments that might contain sensitive information. For example:\n\n```env\n# Configuration for testing - api_key=MY_SECRET_KEY user=admin\nDB_URL=postgres://user:password@localhost:5432/db\n```\n\nWith comment masking enabled (the default), any key-value pairs in comments will also be masked, providing more comprehensive protection. This feature works across:\n\n- CMP completion popups (nvim-cmp, blink-cmp, omnifunc)\n- Peek information windows\n- File buffers (when shelter is enabled)\n\n### Pattern-based Protection\n\nYou can define different masking rules based on variable names or file sources:\n\n```lua\nshelter = {\n    configuration = {\n        -- Pattern-based rules take precedence\n        patterns = {\n            [\"*_KEY\"] = \"full\",      -- Always fully mask API keys\n            [\"TEST_*\"] = \"none\",     -- Never mask test variables\n        },\n        -- Source-based rules as fallback\n        sources = {\n            [\".env.*\"] = \"full\",\n            [\".env.local\"] = \"none\",\n            [\"shell\"] = \"none\",\n        },\n    }\n}\n```\n\n## 🎨 Customization\n\n1. **Custom Mask Character**:\n\n   ```lua\n   shelter = {\n       configuration = {\n          mask_char = \"•\"  -- Use dots\n       }\n   }\n   -- or\n   shelter = {\n       configuration = {\n          mask_char = \"█\"  -- Use blocks\n       }\n   }\n   ```\n\n2. **Custom Highlighting**:\n   ```lua\n   shelter = {\n       configuration = {\n          highlight_group = \"NonText\"  -- Use a different highlight group for masked values\n       }\n   }\n   ```\n\n### 💡 Best Practices\n\n1. Enable shelter mode by default for production environments\n2. Use file shelter mode during screen sharing or pair programming\n3. Enable completion shelter mode to prevent accidental exposure in screenshots\n4. Use source-based masking to protect sensitive files\n5. Apply stricter masking rules for production and staging environments\n6. Keep development and test files less restricted for better workflow\n\n## 🛡 Ecolog Types\n\nEcolog includes a flexible type system for environment variables with built-in and custom types.\n\n### Type Configuration\n\nConfigure types through the `types` option in setup:\n\n```lua\nrequire('ecolog').setup({\n  custom_types = {\n      semver = {\n        pattern = \"^v?%d+%.%d+%.%d+%-?[%w]*$\",\n        validate = function(value)\n          local major, minor, patch = value:match(\"^v?(%d+)%.(%d+)%.(%d+)\")\n          return major and minor and patch\n        end,\n      },\n     aws_region = {\n      pattern = \"^[a-z]{2}%-[a-z]+%-[0-9]$\",\n      validate = function(value)\n        local valid_regions = {\n          [\"us-east-1\"] = true,\n          [\"us-west-2\"] = true,\n          -- ... etc\n        }\n        return valid_regions[value] == true\n      end\n    }\n  },\n  types = {\n    -- Built-in types\n    url = true,          -- URLs (http/https)\n    localhost = true,    -- Localhost URLs\n    ipv4 = true,        -- IPv4 addresses\n    database_url = true, -- Database connection strings\n    number = true,       -- Integers and decimals\n    boolean = true,      -- true/false/yes/no/1/0\n    json = true,         -- JSON objects and arrays\n    iso_date = true,     -- ISO 8601 dates (YYYY-MM-DD)\n    iso_time = true,     -- ISO 8601 times (HH:MM:SS)\n    hex_color = true,    -- Hex color codes (#RGB or #RRGGBB)\n  }\n})\n```\n\nYou can also:\n\n- Enable all built-in types: `types = true`\n- Disable all built-in types: `types = false`\n- Enable specific types and add custom ones:\n\n```lua\nrequire('ecolog').setup({\n  custom_types = {\n    jwt = {\n      pattern = \"^[A-Za-z0-9%-_]+%.[A-Za-z0-9%-_]+%.[A-Za-z0-9%-_]+$\",\n      validate = function(value)\n        local parts = vim.split(value, \".\", { plain = true })\n        return #parts == 3\n      end\n    },\n  }\n  types = {\n    url = true,\n    number = true,\n  }\n})\n```\n\n### Custom Type Definition\n\nEach custom type requires:\n\n1. **`pattern`** (required): A Lua pattern string for initial matching\n2. **`validate`** (optional): A function for additional validation\n3. **`transform`** (optional): A function to transform the value\n\nExample usage in .env files:\n\n```env\nVERSION=v1.2.3                  # Will be detected as semver type\nREGION=us-east-1               # Will be detected as aws_region type\nAUTH_TOKEN=eyJhbG.eyJzd.iOiJ  # Will be detected as jwt type\n```\n\n## 💡 Tips\n\n1. **Selective Protection**: Enable shelter mode only for sensitive environments:\n\n   ```lua\n   -- In your config\n   if vim.fn.getcwd():match(\"production\") then\n     require('ecolog').setup({\n       shelter = {\n           configuration = {\n               partial_mode = {\n                   show_start = 3,    -- Number of characters to show at start\n                   show_end = 3,      -- Number of characters to show at end\n                   min_mask = 3,      -- Minimum number of mask characters\n               },\n               mask_char = \"*\",   -- Character used for masking\n               -- Mask all values from production files\n               sources = {\n                   [\".env.prod\"] = \"full\",\n                   [\".env.local\"] = \"partial\",\n                   [\"shell\"] = \"none\",\n               },\n           },\n           modules = {\n               cmp = true,       -- Mask values in completion\n               peek = true,      -- Mask values in peek view\n               files = true,     -- Mask values in files\n               telescope = false, -- Mask values in telescope\n               telescope_previewer = false, -- Mask values in telescope preview buffers\n           }\n       },\n       path = vim.fn.getcwd(), -- Path to search for .env files\n       preferred_environment = \"development\", -- Optional: prioritize specific env files\n     })\n   end\n   ```\n\n2. **Source-based Protection**: Use different masking levels based on file sources:\n\n   ```lua\n   shelter = {\n       configuration = {\n           -- Mask values based on their source file\n           sources = {\n               [\".env.prod\"] = \"full\",\n               [\".env.local\"] = \"partial\",\n               [\"shell\"] = \"none\",\n           },\n           -- Pattern-based rules take precedence\n           patterns = {\n               [\"*_KEY\"] = \"full\",      -- Always fully mask API keys\n               [\"TEST_*\"] = \"none\",     -- Never mask test variables\n           },\n       }\n   }\n   ```\n\n3. **Custom Masking**: Use different characters for masking:\n\n   ```lua\n   shelter = {\n       configuration = {\n          mask_char = \"•\"  -- Use dots\n       }\n   }\n   -- or\n   shelter = {\n       configuration = {\n          mask_char = \"█\"  -- Use blocks\n       }\n   }\n   -- or\n   shelter = {\n       configuration = {\n          highlight_group = \"NonText\"  -- Use a different highlight group for masked values\n       }\n   }\n   ```\n\n   The `highlight_group` option allows you to customize the highlight group used for masked values. By default, it uses the `Comment` highlight group. You can use any valid Neovim highlight group name.\n\n4. **Temporary Viewing**: Use `:EcologShelterToggle disable` temporarily when you need to view values, then re-enable with `:EcologShelterToggle enable`\n\n5. **Security Best Practices**:\n   - Enable shelter mode by default for production environments\n   - Use file shelter mode during screen sharing or pair programming\n   - Enable completion shelter mode to prevent accidental exposure in screenshots\n   - Use source-based masking to protect sensitive files\n   - Apply stricter masking rules for production and staging environments\n   - Keep development and test files less restricted for better workflow\n\n## 🎨 Theme Integration\n\nThe plugin seamlessly integrates with your current colorscheme:\n\n| Element        | Color Source |\n| -------------- | ------------ |\n| Variable names | `Identifier` |\n| Types          | `Type`       |\n| Values         | `String`     |\n| Sources        | `Directory`  |\n\n## 🛠️ Author Setup\n\nIt's author's (`ph1losof`) personal setup for ecolog.nvim, it is opionated. However, it usefull to quickly get started especially if you don't want to think much of a setup and reading docs:\n\n\u003e **Note**: Additional setup is required for [blink-cmp](#blink-cmp-integration) and [statusline](#statusline-integration) integrations.\n\n```lua\n  {\n    'ph1losof/ecolog.nvim',\n    branch = \"v1\",\n    keys = {\n      { '\u003cleader\u003ee', '', desc = '+ecolog', mode = { 'n', 'v' } },\n      { '\u003cleader\u003eel', '\u003cCmd\u003eEcologShelterLinePeek\u003ccr\u003e', desc = 'Peek line' },\n      { '\u003cleader\u003eey', '\u003cCmd\u003eEcologCopy\u003ccr\u003e', desc = 'Copy value under cursor' },\n      { '\u003cleader\u003eei', '\u003cCmd\u003eEcologInterpolationToggle\u003ccr\u003e', desc = 'Toggle interpolation' },\n      { '\u003cleader\u003eeh', '\u003cCmd\u003eEcologShellToggle\u003ccr\u003e', desc = 'Toggle shell variables' },\n      { '\u003cleader\u003ege', '\u003ccmd\u003eEcologGoto\u003ccr\u003e', desc = 'Go to env file' },\n      { '\u003cleader\u003eec', '\u003ccmd\u003eEcologSnacks\u003ccr\u003e', desc = 'Open a picker' },\n      { '\u003cleader\u003eeS', '\u003ccmd\u003eEcologSelect\u003ccr\u003e', desc = 'Switch env file' },\n      { '\u003cleader\u003ees', '\u003ccmd\u003eEcologShelterToggle\u003ccr\u003e', desc = 'Shelter toggle' },\n    },\n    opts = {\n      preferred_environment = 'local',\n      types = true,\n      monorepo = {\n        enabled = true,\n        auto_switch = true,\n        notify_on_switch = false,\n      },\n      providers = {\n        {\n          pattern = '{{[%w_]+}}?$',\n          filetype = 'http',\n          extract_var = function(line, col)\n            local utils = require 'ecolog.utils'\n            return utils.extract_env_var(line, col, '{{([%w_]+)}}?$')\n          end,\n          get_completion_trigger = function()\n            return '{{'\n          end,\n        },\n      },\n      interpolation = {\n        enabled = true,\n        features = {\n          commands = false,\n        },\n      },\n      sort_var_fn = function(a, b)\n        if a.source == 'shell' and b.source ~= 'shell' then\n          return false\n        end\n        if a.source ~= 'shell' and b.source == 'shell' then\n          return true\n        end\n\n        return a.name \u003c b.name\n      end,\n      integrations = {\n        lspsaga = true,\n        blink_cmp = true,\n        snacks = true,\n        statusline = {\n          hidden_mode = true,\n          icons = { enabled = true, env = 'E', shelter = 'S' },\n          highlights = {\n            env_file = 'Directory',\n            vars_count = 'Number',\n          },\n        },\n      },\n      shelter = {\n        configuration = {\n          patterns = {\n            ['DATABASE_URL'] = 'full',\n          },\n          sources = {\n            ['.env.example'] = 'none',\n          },\n          partial_mode = {\n            min_mask = 5,\n            show_start = 1,\n            show_end = 1,\n          },\n          mask_char = '*',\n        },\n        modules = {\n          files = true,\n          peek = false,\n          snacks_previewer = true,\n          snacks = false,\n          cmp = true,\n        },\n      },\n      path = vim.fn.getcwd(),\n    },\n  }\n```\n\n## 🔄 Comparisons\n\nWhile `ecolog.nvim` has many great and unique features, here are some comparisons with other plugins in neovim ecosystem in **_their specific fields_**:\n\n### Environment Variable Completion (vs [cmp-dotenv](https://github.com/jcha0713/cmp-dotenv))\n\n| Feature                    | ecolog.nvim                                                                                         | cmp-dotenv                                                  |\n| -------------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |\n| Language-aware Completion  | ✅ Fully configurable context-aware triggers for multiple languages and filetypes                   | ❌ Basic environment variable completion only on every char |\n| Type System                | ✅ Built-in type validation and custom types                                                        | ❌ No type system                                           |\n| Nvim-cmp support           | ✅ Nvim-cmp integration                                                                             | ✅ Nvim-cmp integration                                     |\n| Blink-cmp support          | ✅ Native blink-cmp integration                                                                     | ❌ Doesn't support blink-cmp natively                       |\n| Omnifunc support           | ✅ Native vim's omnifunc                                                                            | ❌ Doesn't support omnifunc                                 |\n| Multi-line env variables   | ✅ Full support                                                                                     | ❌ No support                                               |\n| Documentation Support      | ✅ Rich documentation with type info and source                                                     | 🟡 Basic documentation support                              |\n| Shell Variable Integration | ✅ Configurable shell variable loading and filtering                                                | 🟡 Basic shell variable support                             |\n| Sorting                    | ✅ Built-in fully customizable sorting for both variables and files, involving all all integrations | ❌ No sorting supported                                     |\n| Multiple Environment Files | ✅ Priority-based loading with custom sorting and switching between multiple environment files      | 🟡 Basic environment variable loading                       |\n\n### Security Features (vs [cloak.nvim](https://github.com/laytan/cloak.nvim))\n\n| Feature                      | ecolog.nvim                                                                                                                                                                  | cloak.nvim                                                                                                    |\n| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| Partial Value Masking        | ✅ Configurable partial masking with patterns                                                                                                                                | 🟡 Full masking only                                                                                          |\n| Pattern-based Security       | ✅ Custom patterns for different security levels                                                                                                                             | 🟡 Basic pattern matching                                                                                     |\n| Preview Protection           | ✅ Telescope/FZF/Snacks picker preview protection                                                                                                                            | 🟡 Only Telescope preview protection                                                                          |\n| Avoid value leaking          | ✅ Full support, never leak environment variables                                                                                                                            | ❌ Doesn't support masking on startup and pasting content from insert mode, flashes values                    |\n| Mask on leave                | ✅ Supports                                                                                                                                                                  | ✅ Supports                                                                                                   |\n| Completion disable           | ✅ Supports both blink-cmp and nvim-cmp, configurable                                                                                                                        | 🟡 Only nvim-cmp and can't disable                                                                            |\n| Custom mask and highlights   | ✅ Supports                                                                                                                                                                  | ✅ Supports                                                                                                   |\n| Multi-line env variables     | ✅ Full support                                                                                                                                                              | ❌ No support                                                                                                 |\n| Performance                  | ✅ Significantly better performance and memory usage, especially in previewer buffers due to LRU caching, on benchmarks faster when opening/processing files. ~2.5ms startup | 🟡 Significantly slower on file processing. However, due to minimal implementation startup time is much lower |\n| Line of code                 | 🟡 ~2500+ LOC actively used on average, the rest is lazy loaded                                                                                                              | ✅ Only ~300 LOC                                                                                              |\n| Supports custom integrations | ✅ Supports all ecolog.nvim features telescope-lua, snacks, fzf-lua, cmp, peek and etc.                                                                                      | 🟡 Only works in file buffers and telescope previewer                                                         |\n| Setup and Docs               | 🟡 Docs are big due to the amount of features, but it's well documented and the plugin provides a lot of defaults, so it should be relatively easy to setup                  | ✅ Well documented and easy to setup                                                                          |\n| Filetype support             | 🟡 Supports only `sh` and `.env` files                                                                                                                                       | ✅ Can work in any filetype                                                                                   |\n\n### Environment Management (vs [telescope-env.nvim](https://github.com/LinArcX/telescope-env.nvim))\n\n| Feature                     | ecolog.nvim                                 | telescope-env.nvim      |\n| --------------------------- | ------------------------------------------- | ----------------------- |\n| Environment Variable Search | ✅ Basic search                             | ✅ Basic search         |\n| Customizable keymaps        | ✅ Fully customizable                       | ✅ Fully customizable   |\n| Value Preview               | ✅ Protected value preview                  | 🟡 Basic value preview  |\n| Multiple Picker Support     | ✅ Telescope, Snacks picker and FZF support | 🟡 Telescope only       |\n| Security Features           | ✅ Integrated security in previews          | ❌ No security features |\n| Custom Sort/Filter          | ✅ Advanced sorting and filtering options   | 🟡 Basic sorting only   |\n\n### File Management (vs [dotenv.nvim](https://github.com/ellisonleao/dotenv.nvim))\n\n| Feature                      | ecolog.nvim                                            | dotenv.nvim                                      |\n| ---------------------------- | ------------------------------------------------------ | ------------------------------------------------ |\n| Environment File Detection   | ✅ Custom patterns and priority-based loading          | 🟡 Basic env file loading                        |\n| Multi-line env variables     | ✅ Full support                                        | ❌ No support                                    |\n| Monorepo support             | ✅ Support for monorepo environments and custom config | 🟡 No direct support, configuration very limited |\n| Multiple Environment Support | ✅ Advanced environment file switching                 | 🟡 Basic environment support                     |\n| Shell Variable Integration   | ✅ Configurable shell variable loading and filtering   | ❌ No shell integration                          |\n\n### Key Benefits of ecolog.nvim\n\n1. **All-in-One Solution**: Most importantly it combines features from multiple plugins into a cohesive environment management suite which also opens new possibilties\n2. **Language Intelligence**: Provides language-specific completions and integrations\n3. **Advanced Security**: Offers the most comprehensive security features for sensitive data\n4. **Type System**: Unique type system for validation and documentation\n5. **Rich Integrations**: Seamless integration with LSP, Telescope, FZF, EcologPeek and more\n6. **Performance**: Optimzed for speed and efficiency in mind\n7. **Extensibility**: Custom providers and types for extending functionality\n\n## 🤝 Contributing\n\nContributions are welcome! Feel free to:\n\n- 🐛 Report bugs\n- 💡 Suggest features\n- 🔧 Submit pull requests\n\n## 📄 License\n\nMIT License - See [LICENSE](./LICENSE) for details.\n\n---\n\n\u003cdiv align=\"center\"\u003e\nMade with ❤️ by \u003ca href=\"https://github.com/ph1losof\"\u003eTENTACLE\u003c/a\u003e\n\u003c/div\u003e\n","funding_links":[],"categories":["Lua"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fph1losof%2Fecolog.nvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fph1losof%2Fecolog.nvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fph1losof%2Fecolog.nvim/lists"}