Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

VEM (Vim Environment Manager) is a powerful command-line tool written in Rust that allows you to efficiently manage multiple Vim environments. Whether you’re a developer working on different projects, a writer who needs different configurations, or someone who just likes to experiment with various Vim setups, VEM makes it easy to switch between different .vim configurations.

What is VEM?

VEM stands for Vim Environment Manager. It’s designed to solve the common problem of managing multiple Vim configurations without conflicts or the need to manually backup and restore configuration files.

Key Features

  • πŸš€ Fast: Lightning-fast environment switching powered by Rust
  • πŸ”§ Flexible: Support for unlimited Vim configuration profiles
  • πŸ“ Organized: Keep each environment completely isolated
  • 🎯 Simple: Intuitive command-line interface
  • πŸ”’ Safe: No risk of losing your configurations
  • 🌐 Cross-platform: Works on Linux, macOS, and Windows

Use Cases

For Developers

  • Different environments for different programming languages
  • Project-specific Vim configurations
  • Testing new plugins without affecting your main setup

For Writers

  • Distraction-free writing environment
  • Different themes for different types of content
  • Specialized plugins for markdown, LaTeX, etc.

For Experimenters

  • Try new Vim distributions safely
  • Test bleeding-edge plugins
  • Keep stable and experimental setups separate

How It Works

VEM creates isolated directories for each environment, containing:

  • Individual .vimrc files
  • Separate .vim directories with plugins and configurations
  • Symbolic links for easy switching

When you switch environments, VEM updates your active Vim configuration without modifying your original files.

Getting Started

Ready to start managing your Vim environments efficiently? Check out the Installation guide to get VEM up and running, then follow the Quick Start tutorial to create your first environment.

Installation

VEM can be installed in several ways. Choose the method that works best for your setup.

Prerequisites

  • Operating System: Linux, macOS, or Windows
  • Vim: Any recent version of Vim or Neovim

If you have Rust and Cargo installed:

cargo install vem

This will download, compile, and install the latest version of VEM.

Installing Rust and Cargo

If you don’t have Rust installed, get it from rustup.rs:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

Method 2: Download Pre-built Binaries

Download the latest release for your platform from the GitHub Releases page.

Linux/macOS

# Download and extract (replace with latest version)
wget https://github.com/ryo-arima/vem/releases/latest/download/vem-linux-x86_64
chmod +x vem-linux-x86_64
sudo mv vem-linux-x86_64 /usr/local/bin/vem

Windows

Download the .exe file and place it in a directory that’s in your PATH.

Method 3: Build from Source

git clone https://github.com/ryo-arima/vem.git
cd vem
cargo build --release

The binary will be available at target/release/vem.

Verification

Verify the installation by checking the version:

vem --version

You should see output similar to:

vem 0.1.0

Next Steps

Now that VEM is installed, check out the Quick Start guide to create your first Vim environment!

Quick Start

This guide will help you get started with VEM in just a few minutes. We’ll create your first environment and show you the basic workflow.

Step 1: Create Your First Environment

Let’s create a development environment:

vem create development

This creates a new Vim environment called β€œdevelopment” with:

  • A fresh .vimrc file
  • An empty .vim directory
  • Isolated plugin storage

Step 2: List Your Environments

See all available environments:

vem list

Output:

development

Step 3: Switch to Your Environment

Activate the development environment:

vem switch development

This will:

  • Set up symbolic links to the development environment
  • Make it the active Vim configuration

Step 4: Check Current Environment

Verify which environment is currently active:

vem current

Output:

development

Step 5: Customize Your Environment

Now you can customize this environment:

  1. Edit the .vimrc file:

    vim ~/.vimrc
    
  2. Install plugins in the .vim directory:

    mkdir -p ~/.vim/bundle
    # Install your favorite plugins
    
  3. Any changes you make will only affect the β€œdevelopment” environment.

Step 6: Create Additional Environments

Let’s create a writing environment:

vem create writing

Configure it for writing:

vem switch writing
vim ~/.vimrc

Add writing-specific configurations:

" Writing-focused Vim configuration
set spell
set linebreak
set textwidth=80
colorscheme peachpuff

Step 7: Switch Between Environments

Now you can easily switch between environments:

# Switch to development
vem switch development

# Switch to writing  
vem switch writing

# Check current environment
vem current

Common Workflow

  1. Create environments for different use cases
  2. Switch to the appropriate environment for your task
  3. Customize each environment independently
  4. Switch back whenever you need a different setup

What’s Next?

You’re now ready to manage multiple Vim environments efficiently with VEM!

Commands

VEM provides a simple and intuitive command-line interface. Here’s a comprehensive overview of all available commands.

Command Overview

CommandDescription
createCreate a new Vim environment
listList all available environments
switchSwitch to a specific environment
currentShow the currently active environment
removeRemove an environment

Global Options

All commands support these global options:

  • --help, -h: Show help information
  • --version, -V: Show version information
  • --verbose, -v: Enable verbose output
  • --quiet, -q: Suppress non-essential output

Command Details

vem create <name>

Creates a new Vim environment with the specified name.

Usage:

vem create <environment-name>

Examples:

vem create development
vem create writing
vem create experimental

Options:

  • --from <template>: Create from existing environment (future feature)
  • --description <desc>: Add description to environment (future feature)

Behavior:

  • Creates directory structure under ~/.vem/environments/<name>/
  • Initializes empty .vimrc and .vim/ directory
  • Environment becomes available for switching

Read more β†’

vem list

Lists all available Vim environments.

Usage:

vem list

Options:

  • --detailed, -d: Show detailed information (future feature)
  • --current-first: Show current environment first (future feature)

Output:

development
writing
experimental

Read more β†’

vem switch <name>

Switches to the specified Vim environment.

Usage:

vem switch <environment-name>

Examples:

vem switch development
vem switch writing

Behavior:

  • Updates symbolic links to point to the specified environment
  • Makes the environment active for new Vim sessions
  • Preserves existing Vim sessions

Read more β†’

vem current

Shows the currently active Vim environment.

Usage:

vem current

Output:

development

Exit Codes:

  • 0: Success, environment shown
  • 1: No environment currently active

Read more β†’

vem remove <name>

Removes a Vim environment permanently.

Usage:

vem remove <environment-name>

Examples:

vem remove experimental

Options:

  • --force, -f: Skip confirmation prompt (future feature)
  • --backup: Create backup before removal (future feature)

Safety:

  • Prompts for confirmation before removal
  • Cannot remove currently active environment
  • Permanently deletes all environment data

Read more β†’

Exit Codes

VEM uses standard exit codes:

  • 0: Success
  • 1: General error
  • 2: Invalid command or arguments
  • 3: Environment not found
  • 4: Environment already exists
  • 5: Permission denied

Shell Completion

VEM supports shell completion for bash, zsh, and fish (future feature):

# bash
vem completions bash > /etc/bash_completion.d/vem

# zsh  
vem completions zsh > ~/.zsh/completions/_vem

# fish
vem completions fish > ~/.config/fish/completions/vem.fish

create

The create command creates a new Vim environment with the specified name.

Syntax

vem create <environment-name>

Parameters

  • <environment-name>: The name of the environment to create
    • Must be a valid directory name
    • Cannot contain spaces or special characters
    • Recommended: use lowercase with hyphens (e.g., web-development)

Examples

Basic Usage

# Create a development environment
vem create development

# Create a writing environment
vem create writing

# Create a project-specific environment
vem create my-rust-project

Advanced Examples

# Create environments for different languages
vem create python-dev
vem create javascript-dev
vem create rust-dev

# Create environments for different purposes
vem create minimal
vem create full-featured
vem create presentation

What Gets Created

When you run vem create <name>, VEM creates:

~/.vem/environments/<name>/
β”œβ”€β”€ .vimrc          # Empty Vim configuration file
└── .vim/           # Empty Vim directory for plugins
    β”œβ”€β”€ autoload/   # For plugin managers
    β”œβ”€β”€ bundle/     # For bundled plugins
    β”œβ”€β”€ colors/     # For color schemes
    └── plugin/     # For plugins

Error Conditions

The command will fail if:

  • Environment name already exists
  • Invalid environment name
  • Insufficient permissions
  • Disk space issues

Success Output

$ vem create development
Created environment: development

Error Examples

$ vem create development
Error: Environment 'development' already exists

$ vem create "invalid name"
Error: Environment name cannot contain spaces

$ vem create /invalid/path
Error: Invalid environment name

Next Steps

After creating an environment:

  1. Switch to it: vem switch <name>
  2. Customize the .vimrc file
  3. Install plugins in the .vim directory
  4. Start using your customized environment

See Also

  • switch - Switch to an environment
  • list - List all environments
  • remove - Remove an environment

list

switch

current

remove

ctags

The ctags command manages code tags for efficient navigation across multiple repositories.

Syntax

vem generate ctags <repository> [options]
vem update ctags <repository> [options]  
vem delete ctags <repository> [options]
vem list ctags [options]
vem clean ctags [options]

Subcommands

generate

Generate ctags for a specified repository.

vem generate ctags <repository> [options]

Arguments:

  • <repository>: Repository name defined in vem.toml

Options:

  • --languages=<langs>: Comma-separated list of languages (e.g., python,rust,javascript)
  • --exclude=<patterns>: Additional exclude patterns
  • --tag-set=<name>: Generate specific tag set from configuration
  • --ai-enhance: Enable AI-powered tag enhancement (AI environments only)
  • --force: Overwrite existing tags without confirmation

Examples:

# Generate tags for main project
vem generate ctags main_project

# Generate tags for specific languages
vem generate ctags shared_libs --languages=python,rust

# Generate with AI enhancement
vem generate ctags ai_project --ai-enhance

# Generate specific tag set
vem generate ctags . --tag-set=copilot_context

update

Update existing ctags for a repository.

vem update ctags <repository> [options]

Arguments:

  • <repository>: Repository name or --all for all repositories

Options:

  • --incremental: Update only changed files
  • --force: Force full regeneration
  • --ai-context: Update AI context (AI environments only)
  • --all: Update all configured repositories

Examples:

# Update main project tags
vem update ctags main_project

# Incremental update
vem update ctags shared_libs --incremental

# Update all repositories
vem update ctags --all

# Force full regeneration
vem update ctags ml_models --force

delete

Delete ctags for a repository or specific tag files.

vem delete ctags <repository> [options]

Arguments:

  • <repository>: Repository name

Options:

  • --tag-file=<file>: Delete specific tag file
  • --confirm: Require confirmation (default in basic environments)
  • --no-backup: Skip creating backup
  • --ai-context: Also clean AI context (AI environments)

Examples:

# Delete all tags for repository
vem delete ctags external_deps

# Delete specific tag file
vem delete ctags . --tag-file=project_tags

# Delete without confirmation
vem delete ctags temp_repo --no-confirm

list

List all ctags with status and metadata.

vem list ctags [options]

Options:

  • --format=<fmt>: Output format (table, json, yaml, simple)
  • --repository=<repo>: Filter by repository
  • --status=<status>: Filter by status (active, stale, error)
  • --sort=<field>: Sort by field (name, size, updated)

Examples:

# List all ctags (default format based on environment)
vem list ctags

# List in JSON format
vem list ctags --format=json

# List for specific repository
vem list ctags --repository=main_project

# List only active tags
vem list ctags --status=active

Output Examples:

Table format (Developer Vim):

Name          Repository    Tag File        Last Updated    Size    Status
project       main_project  tags           2024-01-01      1.2MB   Active
shared_libs   shared_libs   shared_tags    2024-01-01      856KB   Active
api_schemas   api_defs      api_tags       2024-01-01      234KB   Stale

JSON format (Modern Neovim):

{
  "workspace": {
    "repository": "current_project",
    "tag_file": "workspace_tags",
    "last_updated": "2024-01-01T12:00:00Z",
    "size": 1048576,
    "lsp_integrated": true,
    "status": "active"
  }
}

Enhanced format (AI Development):

Name            Repository   AI Score   Copilot Ready   Size     Status
ai_comprehensive ml_models   95%        βœ“              2.1MB    Active
copilot_enhanced ai_project  88%        βœ“              1.8MB    Active
ml_pipeline     data_pipe   76%        βœ“              1.2MB    Active

clean

Clean all ctags files and optionally reset AI context.

vem clean ctags [options]

Options:

  • --backup: Create backup before cleaning (default: true)
  • --no-confirm: Skip confirmation prompt
  • --ai-reset: Reset AI context (AI environments only)
  • --cache: Also clean ctags cache directories

Examples:

# Clean all ctags with backup
vem clean ctags

# Clean without confirmation
vem clean ctags --no-confirm

# Clean with AI context reset
vem clean ctags --ai-reset

# Clean everything including cache
vem clean ctags --cache --no-backup

Configuration

Ctags behavior is configured in vem.toml:

Repository Configuration

[ctags.repositories.main_project]
name = "main_project"
path = "."
enabled = true
auto_sync = true
priority = 1

Tag Configuration

[ctags.tags.project]
name = "project"
repositories = ["main_project"]
tag_file = "tags"
languages = ["python", "rust"]
auto_generate = true

Command Configuration

[ctags.commands]
generate_options = ["--recurse=yes", "--sort=yes"]
list_format = "table"
clean_backup = true

Environment-Specific Behavior

Basic Vim

  • Simple tag management
  • Always requires confirmation
  • Text-based output
  • Manual tag generation

Developer Vim

  • Multi-repository support
  • Gutentags integration
  • Table format output
  • Automatic tag updates

Modern Neovim

  • LSP integration
  • JSON format output
  • Telescope integration
  • Workspace-focused tagging

AI Development

  • AI-enhanced tagging
  • Context optimization for Copilot
  • Smart filtering and relevance scoring
  • Cross-repository AI context

Error Handling

Common error scenarios and solutions:

Repository Not Found

Error: Repository 'unknown_repo' not found in configuration

Solution: Check vem.toml for correct repository names

Ctags Executable Missing

Error: ctags executable not found in PATH

Solution: Install universal-ctags or update PATH

Permission Denied

Error: Permission denied writing to tag file

Solution: Check file/directory permissions

Invalid Language

Error: Language 'unknown_lang' not supported by ctags

Solution: Use ctags --list-languages to see supported languages

See Also

Configuration Guide

VEM uses TOML-based configuration files to manage environments, plugins, ctags, and other settings. This guide explains the configuration system and all available options.

Configuration Structure

etc/.vem/
β”œβ”€β”€ envs/                          # Environment-specific configurations
β”‚   β”œβ”€β”€ basic-vim/
β”‚   β”‚   β”œβ”€β”€ vimrc                  # Vim configuration file
β”‚   β”‚   └── vem.toml              # Environment settings
β”‚   β”œβ”€β”€ developer-vim/
β”‚   β”‚   β”œβ”€β”€ vimrc
β”‚   β”‚   └── vem.toml
β”‚   β”œβ”€β”€ modern-nvim/
β”‚   β”‚   β”œβ”€β”€ init.lua              # Neovim configuration
β”‚   β”‚   β”œβ”€β”€ lua/plugins/
β”‚   β”‚   └── vem.toml
β”‚   └── ai-development/
β”‚       β”œβ”€β”€ init.lua
β”‚       └── vem.toml
└── global/                       # Shared configurations
    β”œβ”€β”€ vim/                      # Global Vim settings
    β”œβ”€β”€ nvim/                     # Global Neovim settings  
    β”œβ”€β”€ scripts/                  # Shared VimScript functions
    β”œβ”€β”€ themes/                   # Color schemes
    └── ai-tools/                 # AI tool configurations

vem.toml Reference

Environment Section

[environment]
name = "environment-name"
description = "Environment description"
type = "vim"  # or "neovim"
version = "1.0.0"
author = "Your Name"

Fields:

  • name: Unique environment identifier
  • description: Human-readable description
  • type: Editor type (vim or neovim)
  • version: Environment version
  • author: Environment creator

Editor Configuration

[editor]
type = "vim"  # or "neovim"
config_file = "vimrc"  # or "init.lua" for Neovim
global_configs = [
    "global/vim/common-settings.vim",
    "global/scripts/utility-functions.vim"
]

Fields:

  • type: Editor type
  • config_file: Main configuration file name
  • global_configs: Array of global configuration files to include

Features

[features]
syntax_highlighting = true
line_numbers = true
relative_numbers = false
search_highlighting = true
auto_indent = true
smart_indent = true
mouse_support = true
folding = false
completion = true
treesitter = false  # Neovim only

Plugin Management

[plugins]
enabled = true
manager = "vim-plug"  # Selected plugin manager
auto_install = true

[plugin_managers]
# Plugin manager selection (only one should be true)
vim-plug = true
pathogen = false
vundle = false
dein = false
lazy = false    # Neovim only
packer = false  # Neovim only
paq = false     # Neovim only

# Plugin manager configurations
[plugin_managers.configs]

[plugin_managers.configs.vim-plug]
url = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
install_path = "~/.vim/autoload/plug.vim"
config_block_start = "call plug#begin('~/.vim/plugged')"
config_block_end = "call plug#end()"
install_command = ":PlugInstall"
update_command = ":PlugUpdate"
clean_command = ":PlugClean"
packages = [
    { name = "preservim/nerdtree", description = "File explorer" },
    { name = "junegunn/fzf.vim", description = "Fuzzy finder" },
    # ... more packages
]

Ctags Configuration

[ctags]
enabled = true
executable = "ctags"
global_config_file = "~/.ctags"
auto_generate = true
update_on_save = true

# Global settings
[ctags.global]
languages = ["python", "rust", "javascript", "c", "cpp"]
exclude_patterns = [".git", "node_modules", "target", "__pycache__"]
custom_options = ["--recurse=yes", "--sort=yes"]

# Repository management
[ctags.repositories]

[ctags.repositories.main_project]
name = "main_project"
description = "Main development project"
path = "."
remote_url = ""
branch = "main"
enabled = true
auto_sync = true
priority = 1

# Tag configurations
[ctags.tags]

[ctags.tags.project]
name = "project"
description = "Project-specific tags"
tag_file = "tags"
repositories = ["main_project"]
source_dirs = ["."]
languages = ["python", "rust", "javascript"]
exclude_patterns = [".git", "target", "__pycache__"]
custom_options = ["--recurse=yes", "--sort=yes"]
auto_generate = true

# Command configuration
[ctags.commands]
generate_command = "ctags"
generate_options = ["--recurse=yes", "--sort=yes"]
update_command = "ctags"
update_options = ["--recurse=yes", "--sort=yes", "--append=no"]
list_format = "table"  # table, json, yaml, simple
clean_backup = true
clean_confirm = true

Theme Configuration

[theme]
name = "gruvbox"
variant = "dark"  # or "light"
background = "dark"

Popular themes:

  • gruvbox, nord, dracula, tokyonight
  • catppuccin, onedark, solarized, monokai

Keymaps

[keymaps]
leader = " "
custom_maps = [
    { key = "<C-n>", action = ":NERDTreeToggle<CR>", mode = "n" },
    { key = "<C-p>", action = ":FZF<CR>", mode = "n" },
    { key = "gd", action = "<Plug>(coc-definition)", mode = "n" },
]

Keymap fields:

  • key: Key combination
  • action: Command or function to execute
  • mode: Vim mode (n, i, v, c)
  • type: Optional, lua for Lua functions in Neovim

LSP Configuration

[lsp]
enabled = true
provider = "native"  # or "coc"
auto_install = true
languages = [
    "lua_ls",
    "rust_analyzer", 
    "pyright",
    "tsserver"
]

AI Tools (AI Development Environment)

[ai_tools]
enabled = true

[ai_tools.copilot]
enabled = true
accept_key = "<C-J>"
disable_tab = true

[ai_tools.chatgpt]
enabled = true
api_key_cmd = "echo $OPENAI_API_KEY"
model = "gpt-3.5-turbo"

[ai_tools.codeium]
enabled = true
accept_key = "<C-g>"

System Packages

[packages]
system = [
    { name = "fzf", package_managers = { brew = "fzf", apt = "fzf", yum = "fzf" } },
    { name = "ripgrep", package_managers = { brew = "ripgrep", apt = "ripgrep", yum = "ripgrep" } },
    { name = "ctags", package_managers = { brew = "universal-ctags", apt = "universal-ctags", yum = "ctags" } }
]

Performance Settings

[performance]
swap_files = false
backup_files = true
backup_dir = "~/.vim/backup"
undo_levels = 10000
update_time = 300

Compatibility

[compatibility]
vim_version = "8.0+"
neovim_version = "0.8.0+"  # Neovim environments only

Environment Templates

Basic Vim Template

[environment]
name = "my-basic"
type = "vim"

[features]
syntax_highlighting = true
line_numbers = true

[plugins]
enabled = false

[ctags]
enabled = false

Developer Template

[environment]
name = "my-dev"
type = "vim"

[plugins]
enabled = true
manager = "vim-plug"

[plugin_managers]
vim-plug = true

[ctags]
enabled = true
auto_generate = true

[theme]
name = "gruvbox"

Modern Neovim Template

[environment]
name = "my-nvim"
type = "neovim"

[plugins]
enabled = true
manager = "lazy"

[plugin_managers]
lazy = true

[lsp]
enabled = true
provider = "native"

[treesitter]
enabled = true

[theme]
name = "tokyonight"

Configuration Validation

VEM validates configurations on load:

# Validate current environment configuration
vem config validate

# Validate specific configuration file
vem config validate --file path/to/vem.toml

# Show configuration schema
vem config schema

Best Practices

  1. Keep environments focused: Each environment should serve a specific purpose
  2. Use global configs: Share common settings via global configuration files
  3. Document changes: Add comments to explain custom configurations
  4. Test configurations: Use vem config validate before switching environments
  5. Backup configurations: Keep configuration files in version control

Troubleshooting

Common Issues

  1. Invalid TOML syntax

    vem config validate --file vem.toml
    
  2. Plugin conflicts

    • Check plugin compatibility
    • Verify plugin manager selection
  3. Ctags errors

    • Ensure ctags executable is available
    • Check repository paths and permissions

Debug Mode

# Run VEM with debug logging
RUST_LOG=debug vem switch environment-name

# Show current configuration
vem config show

# List all configuration files
vem config list

Environment Structure

Architecture

VEM follows a clean, modular architecture designed for maintainability, testability, and extensibility. This document outlines the system design and explains how the different components work together.

High-Level Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   CLI Layer     β”‚    β”‚  Business Logic β”‚    β”‚  Data Layer     β”‚
β”‚      (ctl)      │◄──►│     (usc)       │◄──►│     (rep)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                       β”‚
         β–Ό                       β–Ό                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Configuration   β”‚    β”‚    Entities     β”‚    β”‚  File System    β”‚
β”‚     (cnf)       β”‚    β”‚     (ent)       β”‚    β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Layer Responsibilities

Control Layer (ctl/)

The control layer handles user interaction and command parsing.

Responsibilities:

  • Command-line argument parsing
  • User input validation
  • Output formatting
  • Error message display
  • Shell integration

Key Components:

  • cli.rs - Main CLI interface using clap
  • commands/ - Individual command implementations
  • output.rs - Output formatting and display

Use Case Layer (usc/)

The use case layer contains the application’s business logic.

Responsibilities:

  • Environment management workflows
  • Business rule enforcement
  • Coordination between repositories
  • Transaction management

Key Components:

  • environment_manager.rs - Core environment operations
  • switcher.rs - Environment switching logic
  • validator.rs - Business rule validation

Repository Layer (rep/)

The repository layer handles data persistence and retrieval.

Responsibilities:

  • File system operations
  • Data serialization/deserialization
  • Storage abstractions
  • Backup and recovery

Key Components:

  • environment_repository.rs - Environment CRUD operations
  • config_repository.rs - Configuration management
  • file_system.rs - File system abstractions

Entity Layer (ent/)

The entity layer defines the core data structures and domain models.

Responsibilities:

  • Domain model definitions
  • Data validation
  • Business invariants
  • Type safety

Key Components:

  • environment.rs - Environment domain model
  • config.rs - Configuration structures
  • error.rs - Error types and handling

Configuration Layer (cnf/)

The configuration layer manages application settings and environment configurations.

Responsibilities:

  • Application configuration
  • User preferences
  • Default settings
  • Configuration validation

Key Components:

  • app_config.rs - Application-wide settings
  • user_config.rs - User-specific preferences
  • defaults.rs - Default configurations

Data Flow

Environment Creation Flow

graph TD
    A[User runs 'vem create env'] --> B[CLI Parser]
    B --> C[Create Command Handler]
    C --> D[Environment Manager]
    D --> E[Validate Environment Name]
    E --> F[Check If Exists]
    F --> G[Create Directory Structure]
    G --> H[Initialize Config Files]
    H --> I[Save Environment Metadata]
    I --> J[Return Success]

Environment Switching Flow

graph TD
    A[User runs 'vem switch env'] --> B[CLI Parser]
    B --> C[Switch Command Handler]
    C --> D[Environment Switcher]
    D --> E[Validate Environment Exists]
    E --> F[Backup Current State]
    F --> G[Update Symbolic Links]
    G --> H[Update Current Environment]
    H --> I[Return Success]

File System Structure

VEM manages environments in a structured directory layout:

~/.vem/
β”œβ”€β”€ config.json                    # Global VEM configuration
β”œβ”€β”€ current -> environments/dev     # Symlink to current environment
β”œβ”€β”€ environments/                   # All environment definitions
β”‚   β”œβ”€β”€ development/
β”‚   β”‚   β”œβ”€β”€ .vimrc                 # Environment-specific vimrc
β”‚   β”‚   β”œβ”€β”€ .vim/                  # Environment-specific vim directory
β”‚   β”‚   └── meta.json              # Environment metadata
β”‚   β”œβ”€β”€ writing/
β”‚   β”‚   β”œβ”€β”€ .vimrc
β”‚   β”‚   β”œβ”€β”€ .vim/
β”‚   β”‚   └── meta.json
β”‚   └── ...
└── backups/                       # Automatic backups
    β”œβ”€β”€ 2024-01-01_backup.tar.gz
    └── ...

Error Handling Strategy

VEM uses a layered error handling approach:

  1. Domain Errors: Business logic violations (e.g., environment not found)
  2. System Errors: File system, permissions, etc.
  3. User Errors: Invalid input, malformed commands
  4. Internal Errors: Programming errors, panics
#![allow(unused)]
fn main() {
pub enum VemError {
    EnvironmentNotFound(String),
    EnvironmentAlreadyExists(String),
    InvalidEnvironmentName(String),
    FileSystemError(io::Error),
    ConfigurationError(String),
    PermissionDenied(String),
}
}

Testing Strategy

Unit Tests

  • Individual component testing
  • Mock external dependencies
  • Test business logic in isolation

Integration Tests

  • End-to-end command testing
  • File system interaction testing
  • Configuration management testing

Property-Based Tests

  • Environment name validation
  • File system state consistency
  • Command idempotency

Concurrency Model

VEM is designed to handle concurrent operations safely:

  • File Locking: Prevents concurrent modifications
  • Atomic Operations: Ensure consistency during switches
  • Transaction Logs: Enable rollback on failures

Extension Points

The architecture supports future extensions:

  • Plugin System: Via the use case layer
  • Multiple Backends: Via repository abstractions
  • Custom Commands: Via the CLI layer
  • Configuration Formats: Via serialization traits

Performance Considerations

  • Lazy Loading: Environments loaded on demand
  • Caching: Frequently accessed data cached
  • Minimal I/O: Optimize file system operations
  • Parallel Operations: Where safe and beneficial

This architecture ensures VEM remains maintainable and extensible while providing reliable Vim environment management.

Contributing to VEM

Thank you for your interest in contributing to VEM! This guide will help you get started with contributing to the project.

Table of Contents

  1. Getting Started
  2. Development Environment
  3. Code Style and Guidelines
  4. Testing
  5. Submitting Changes
  6. Release Process
  7. Community Guidelines

Getting Started

Prerequisites

Ensure you have the required development tools:

# Rust toolchain (1.70+)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update stable

# Development dependencies
sudo apt-get install universal-ctags vim neovim git

# Additional tools
cargo install cargo-tarpaulin   # Coverage
cargo install cargo-audit       # Security auditing
cargo install cargo-clippy      # Linting

Fork and Clone

  1. Fork the repository on GitHub

  2. Clone your fork:

    git clone https://github.com/YOUR-USERNAME/vem.git
    cd vem
    
  3. Add upstream remote:

    git remote add upstream https://github.com/ryo-arima/vem.git
    
  4. Verify setup:

    git remote -v
    # origin    https://github.com/YOUR-USERNAME/vem.git (fetch)
    # origin    https://github.com/YOUR-USERNAME/vem.git (push)
    # upstream  https://github.com/ryo-arima/vem.git (fetch)
    # upstream  https://github.com/ryo-arima/vem.git (push)
    

Development Environment

Building VEM

# Debug build (development)
cargo build

# Release build (production)
cargo build --release

# Run from source
cargo run -- --help

# Install locally for testing
cargo install --path .

Setting Up Test Environment

# Create test workspace
mkdir -p ~/vem-dev-test
cd ~/vem-dev-test

# Set VEM_HOME for testing
export VEM_HOME="$PWD/.vem"

# Initialize test environment
vem init

# Create sample environments for testing
cp -r ~/vem/etc/.vem/envs/* ~/.vem/environments/

Development Workflow

  1. Create feature branch:

    git checkout -b feature/your-feature-name
    
  2. Make changes following code guidelines

  3. Test changes:

    # Run tests
    make test
    
    # Run linting
    make lint
    
    # Test manually
    cargo run -- create test-env
    
  4. Commit changes:

    git add .
    git commit -m "feat: add your feature description"
    

Code Style and Guidelines

Rust Style

VEM follows Rust standard conventions:

# Format code
cargo fmt

# Check formatting
cargo fmt -- --check

# Lint code
cargo clippy -- -D warnings

# Check security
cargo audit

Code Organization

src/
β”œβ”€β”€ main.rs          # Entry point
β”œβ”€β”€ base.rs          # Core application structure  
β”œβ”€β”€ mod.rs           # Module declarations
β”œβ”€β”€ cnf/             # Configuration management
β”œβ”€β”€ ctl/             # Controllers (command handlers)
β”œβ”€β”€ ent/             # Entities (data structures)
β”œβ”€β”€ rep/             # Repositories (data access)
β”œβ”€β”€ usc/             # Use cases (business logic)
└── util/            # Utilities and helpers

Naming Conventions

  • Files: Snake case (environment_manager.rs)
  • Functions: Snake case (create_environment)
  • Structs: Pascal case (EnvironmentConfig)
  • Constants: Screaming snake case (DEFAULT_CONFIG_PATH)
  • Modules: Snake case (ctags_manager)

Error Handling

Use VEM’s custom error types:

#![allow(unused)]
fn main() {
use crate::util::error::{VemError, Result};

fn example_function() -> Result<String> {
    let config = load_config()
        .map_err(|e| VemError::ConfigError(format!("Failed to load: {}", e)))?;
    
    Ok(config.name.clone())
}
}

Documentation

  • Public functions: Must have doc comments
  • Complex logic: Inline comments explaining why, not what
  • Examples: Include usage examples for public APIs
#![allow(unused)]
fn main() {
/// Creates a new environment with the specified configuration.
/// 
/// # Arguments
/// 
/// * `name` - The name of the environment to create
/// * `config` - Environment configuration
/// 
/// # Examples
/// 
/// ```
/// use vem::environment::create_environment;
/// 
/// let config = EnvironmentConfig::default();
/// create_environment("my-env", config)?;
/// ```
/// 
/// # Errors
/// 
/// Returns `VemError::EnvironmentExists` if environment already exists.
pub fn create_environment(name: &str, config: EnvironmentConfig) -> Result<()> {
    // Implementation
}
}

Testing

Running Tests

# All tests
cargo test

# Unit tests only
cargo test --lib

# Integration tests only  
cargo test --test '*'

# Specific test
cargo test test_create_environment

# With coverage
cargo tarpaulin --out html

Writing Tests

Unit Tests

#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    #[test]
    fn test_parse_environment_config() {
        let toml_content = r#"
            name = "test-env"
            description = "Test environment"
            editor = "vim"
        "#;
        
        let config = parse_config(toml_content).unwrap();
        assert_eq!(config.name, "test-env");
        assert_eq!(config.editor, "vim");
    }

    #[test]
    fn test_create_environment_with_temp_dir() {
        let temp_dir = TempDir::new().unwrap();
        let vem_home = temp_dir.path().join(".vem");
        
        let result = create_environment_at_path(&vem_home, "test", &Config::default());
        assert!(result.is_ok());
        assert!(vem_home.join("environments").join("test").exists());
    }
}
}

Integration Tests

#![allow(unused)]
fn main() {
// tests/integration/environment_management.rs
use std::process::Command;
use tempfile::TempDir;

#[test]
fn test_full_environment_workflow() {
    let temp_dir = TempDir::new().unwrap();
    
    // Create environment
    let output = Command::new("cargo")
        .args(&["run", "--", "create", "test-env"])
        .env("VEM_HOME", temp_dir.path())
        .output()
        .unwrap();
    
    assert!(output.status.success());
    
    // Switch environment
    let output = Command::new("cargo")
        .args(&["run", "--", "switch", "test-env"])
        .env("VEM_HOME", temp_dir.path())
        .output()
        .unwrap();
        
    assert!(output.status.success());
    
    // Verify current environment
    let output = Command::new("cargo")
        .args(&["run", "--", "current"])
        .env("VEM_HOME", temp_dir.path())
        .output()
        .unwrap();
    
    let current = String::from_utf8(output.stdout).unwrap();
    assert!(current.contains("test-env"));
}
}

Test Data Management

Create reusable test fixtures:

#![allow(unused)]
fn main() {
// tests/common/fixtures.rs
use tempfile::TempDir;
use std::path::PathBuf;

pub struct TestEnvironment {
    pub temp_dir: TempDir,
    pub vem_home: PathBuf,
}

impl TestEnvironment {
    pub fn new() -> Self {
        let temp_dir = TempDir::new().unwrap();
        let vem_home = temp_dir.path().join(".vem");
        std::fs::create_dir_all(&vem_home).unwrap();
        
        Self { temp_dir, vem_home }
    }
    
    pub fn create_sample_config(&self, name: &str) -> PathBuf {
        let config_content = format!(r#"
            name = "{}"
            description = "Test environment"
            editor = "vim"
            
            [plugin_managers]
            vim-plug = true
        "#, name);
        
        let config_path = self.vem_home.join("environments").join(name).join("vem.toml");
        std::fs::create_dir_all(config_path.parent().unwrap()).unwrap();
        std::fs::write(&config_path, config_content).unwrap();
        config_path
    }
}
}

Submitting Changes

Pull Request Process

  1. Ensure tests pass:

    make test
    make lint
    
  2. Update documentation if needed

  3. Create descriptive commits:

    # Good commit messages
    git commit -m "feat: add multi-repository ctags support"
    git commit -m "fix: handle empty configuration files gracefully"
    git commit -m "docs: update installation guide for macOS"
    
  4. Push to your fork:

    git push origin feature/your-feature-name
    
  5. Create pull request on GitHub:

    • Use descriptive title
    • Include detailed description
    • Reference related issues
    • Add screenshots for UI changes

Commit Message Format

Use Conventional Commits:

type(scope): description

[optional body]

[optional footer]

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting)
  • refactor: Code refactoring
  • test: Adding or updating tests
  • chore: Maintenance tasks

Examples:

feat(ctags): add multi-repository support
fix(config): handle malformed TOML gracefully
docs(api): update environment management examples
refactor(cli): extract command parsing logic
test(integration): add environment switching tests
chore(deps): update dependencies to latest versions

PR Review Process

  1. Automated checks: CI must pass
  2. Code review: At least one maintainer approval required
  3. Manual testing: Reviewers may test changes locally
  4. Documentation: Ensure docs are updated for user-facing changes

Review Guidelines

For contributors:

  • Respond promptly to review feedback
  • Keep PRs focused and atomic
  • Include tests for new functionality
  • Update documentation for API changes

For reviewers:

  • Be constructive and specific
  • Test changes manually when appropriate
  • Check for security implications
  • Verify backwards compatibility

Release Process

Version Numbering

VEM follows Semantic Versioning:

  • MAJOR: Breaking changes
  • MINOR: New features (backwards compatible)
  • PATCH: Bug fixes (backwards compatible)

Release Steps

  1. Update version in Cargo.toml
  2. Update CHANGELOG.md with release notes
  3. Create release tag:
    git tag -a v1.2.0 -m "Release v1.2.0"
    git push upstream v1.2.0
    
  4. GitHub Actions automatically builds and publishes releases

Release Notes Format

## [1.2.0] - 2024-01-15

### Added
- Multi-repository ctags support
- AI-enhanced context for development tools
- New sample environments (ai-development, modern-nvim)

### Changed
- Improved configuration validation
- Enhanced error messages

### Fixed
- Environment switching on Windows
- TOML parsing edge cases

### Security
- Updated dependencies with security patches

Community Guidelines

Code of Conduct

VEM follows the Rust Code of Conduct. Key points:

  • Be respectful and inclusive
  • Be constructive in discussions and reviews
  • Focus on technical merit of contributions
  • Help newcomers learn and contribute

Communication Channels

  • GitHub Issues: Bug reports and feature requests
  • GitHub Discussions: Questions and general discussion
  • Pull Requests: Code contributions and technical discussions

Getting Help

For new contributors:

  1. Look for issues labeled good first issue
  2. Ask questions in GitHub Discussions
  3. Review existing code and documentation
  4. Start with small improvements

For development questions:

  1. Check existing documentation
  2. Search GitHub Issues and Discussions
  3. Create a discussion post with specific questions

Recognition

Contributors are recognized through:

  • CONTRIBUTORS.md: Listed alphabetically
  • Release notes: Feature contributions acknowledged
  • GitHub: Contributor statistics and graphs

Development Best Practices

Performance Considerations

  • Profile before optimizing: Use cargo bench for benchmarking
  • Memory efficiency: Avoid unnecessary allocations
  • I/O operations: Use async where appropriate
  • Large datasets: Consider streaming for file operations

Security Guidelines

  • Input validation: Sanitize all external inputs
  • File permissions: Use appropriate file modes
  • Path traversal: Validate paths to prevent directory escape
  • Dependencies: Regularly audit with cargo audit

Debugging

# Debug builds include more information
cargo build

# Enable debug logging
RUST_LOG=debug cargo run -- command

# Use debugger
rust-gdb target/debug/vem

# Memory debugging
valgrind --tool=memcheck target/debug/vem command

IDE Setup

VS Code:

  • Install rust-analyzer extension
  • Configure settings.json:
    {
      "rust-analyzer.check.command": "clippy",
      "rust-analyzer.cargo.features": "all"
    }
    

Vim/Neovim:

  • Use rust.vim plugin
  • Configure with Language Server Protocol (LSP)

Documentation

  • Code documentation: Use rustdoc comments (///)
  • User documentation: Update docs/src/ for user-facing changes
  • API documentation: Generate with cargo doc --open
  • Examples: Include usage examples in documentation

Thank You

Your contributions help make VEM better for everyone. Whether you’re fixing bugs, adding features, improving documentation, or helping other users, every contribution is valued and appreciated!

For questions about contributing, please open a GitHub Discussion or contact the maintainers.

Building from Source

This guide explains how to build VEM from source code, set up the development environment, and contribute to the project.

Prerequisites

System Requirements

  • Rust: 1.70 or higher (nightly toolchain recommended for development)
  • Git: For source code management
  • Make: For running build tasks
  • System Dependencies:
    • ctags: Universal Ctags for tag generation
    • fzf: Fuzzy finder (for some sample environments)
    • ripgrep or ag: Fast text search tools

Platform-Specific Requirements

macOS

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install dependencies via Homebrew
brew install universal-ctags fzf ripgrep git make

# Install nightly toolchain (optional, for development)
rustup toolchain install nightly
rustup default nightly

Ubuntu/Debian

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install dependencies
sudo apt update
sudo apt install -y universal-ctags fzf ripgrep git make build-essential

# Install nightly toolchain (optional)
rustup toolchain install nightly
rustup default nightly
# Follow Ubuntu/Debian instructions in WSL
# Or use Windows-specific tools:
# - Install Rust via rustup-init.exe
# - Install dependencies via package managers like Chocolatey

Building VEM

Quick Build

# Clone the repository
git clone https://github.com/ryo-arima/vem.git
cd vem

# Build in release mode
cargo build --release

# The binary will be available at target/release/vem

Development Build

# Clone and setup
git clone https://github.com/ryo-arima/vem.git
cd vem

# Install development dependencies
cargo install cargo-watch cargo-edit cargo-audit

# Build in debug mode (faster compilation)
cargo build

# Run tests
cargo test

# Run with logging
RUST_LOG=debug cargo run -- --help

Development Environment Setup

Using the Makefile

The project includes a Makefile for common development tasks:

# Show available targets
make help

# Run debug builds of sample environments
make debug-basic      # Test basic Vim environment
make debug-developer  # Test developer Vim environment  
make debug-modern     # Test modern Neovim environment
make debug-ai         # Test AI-enhanced environment

# Run all tests
make test-all

# Setup temporary directories for testing
make setup-temp

# Clean build artifacts
make clean

Code Organization

src/
β”œβ”€β”€ main.rs           # Application entry point
β”œβ”€β”€ base.rs           # Base utilities and common code
β”œβ”€β”€ mod.rs            # Module declarations
β”œβ”€β”€ cnf/              # Configuration management
β”‚   └── application.rs
β”œβ”€β”€ ctl/              # Control layer (CLI commands)
β”‚   └── environment.rs
β”œβ”€β”€ ent/              # Entity definitions
β”‚   β”œβ”€β”€ model/
β”‚   β”œβ”€β”€ request/
β”‚   └── response/
β”œβ”€β”€ rep/              # Repository layer (data access)
β”‚   └── environment.rs
β”œβ”€β”€ usc/              # Use case layer (business logic)
β”‚   └── environment.rs
└── util/             # Utilities and helper functions
    β”œβ”€β”€ clone.rs
    β”œβ”€β”€ debug.rs
    β”œβ”€β”€ deserialize.rs
    β”œβ”€β”€ eq.rs
    β”œβ”€β”€ error.rs
    β”œβ”€β”€ logger.rs
    β”œβ”€β”€ mcode.rs
    └── serialize.rs

Running Tests

# Run all tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Run specific test module
cargo test environment

# Run integration tests
cargo test --test integration

# Run tests with coverage (requires cargo-tarpaulin)
cargo install cargo-tarpaulin
cargo tarpaulin --out html

Development Workflow

  1. Create Feature Branch

    git checkout -b feature/new-feature
    
  2. Make Changes

    • Follow the existing code style and patterns
    • Add tests for new functionality
    • Update documentation as needed
  3. Test Changes

    cargo test
    cargo clippy -- -D warnings
    cargo fmt --check
    
  4. Commit Changes

    git add .
    git commit -m "feat: add new feature description"
    
  5. Push and Create PR

    git push origin feature/new-feature
    # Create pull request on GitHub
    

Building Documentation

mdBook Documentation

# Install mdBook
cargo install mdbook

# Serve documentation locally
cd docs
mdbook serve

# Build documentation
mdbook build

# Open documentation
open book/index.html

API Documentation

# Generate API docs
cargo doc --no-deps

# Open API docs
cargo doc --no-deps --open

# Generate docs with private items
cargo doc --no-deps --document-private-items

Cross-Platform Compilation

Target Platforms

VEM supports multiple platforms:

# Add compilation targets
rustup target add x86_64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-gnu
rustup target add x86_64-pc-windows-gnu
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin

# Compile for specific target
cargo build --release --target x86_64-unknown-linux-gnu
cargo build --release --target aarch64-apple-darwin

Using Cross for Linux Targets

# Install cross for easier cross-compilation
cargo install cross

# Build for Linux on macOS/Windows
cross build --release --target x86_64-unknown-linux-gnu
cross build --release --target aarch64-unknown-linux-gnu

Packaging

Create Distribution Packages

# Build release binary
cargo build --release

# Create packages (requires packaging scripts)
./scripts/packages/apt/pack.sh      # Debian/Ubuntu package
./scripts/packages/rpm/pack.sh      # RPM package  
./scripts/packages/brew/pack.sh     # Homebrew formula

Troubleshooting

Common Build Issues

  1. Rust Version Issues

    # Update Rust
    rustup update
    
    # Check version
    rustc --version
    
  2. Missing System Dependencies

    # Install ctags
    brew install universal-ctags  # macOS
    apt install universal-ctags   # Ubuntu
    
  3. Permission Issues

    # Fix cargo permissions
    sudo chown -R $USER ~/.cargo
    

Getting Help

Testing Guide

This guide covers testing strategies, test execution, and quality assurance for VEM.

Testing Philosophy

VEM follows a comprehensive testing approach:

  • Unit tests: Test individual components and functions
  • Integration tests: Test component interactions
  • End-to-end tests: Test complete workflows
  • Configuration validation: Test environment configurations
  • Cross-platform testing: Ensure compatibility across operating systems

Test Structure

tests/
β”œβ”€β”€ unit/           # Unit tests
β”‚   β”œβ”€β”€ config/     # Configuration parsing tests
β”‚   β”œβ”€β”€ ctags/      # Ctags management tests
β”‚   └── environment/# Environment operations tests
β”œβ”€β”€ integration/    # Integration tests
β”‚   β”œβ”€β”€ commands/   # CLI command tests
β”‚   β”œβ”€β”€ workflows/  # Multi-step workflow tests
β”‚   └── fixtures/   # Test data and configurations
└── e2e/           # End-to-end tests
    β”œβ”€β”€ scenarios/  # Real-world usage scenarios
    └── sample_envs/# Test environment configurations

Running Tests

Quick Test Run

# Run all tests
make test

# Run with coverage
make test-coverage

# Run specific test categories
cargo test unit
cargo test integration
cargo test e2e

Detailed Test Execution

Unit Tests

# Test configuration parsing
cargo test config::tests

# Test ctags functionality
cargo test ctags::tests

# Test environment management
cargo test environment::tests

# Test with verbose output
cargo test --verbose

# Test specific function
cargo test test_parse_vem_config

Integration Tests

# Test command execution
cargo test --test commands

# Test environment workflows
cargo test --test workflows

# Test configuration validation
cargo test --test config_validation

End-to-End Tests

# Run E2E tests (requires test environments)
cargo test --test e2e

# Test specific scenarios
cargo test --test e2e test_create_and_switch_environment

# Test cross-platform compatibility
cargo test --test e2e --features cross-platform

Test Environment Setup

Prerequisites

# Install test dependencies
sudo apt-get install universal-ctags vim neovim

# Create test workspace
mkdir -p /tmp/vem-test
cd /tmp/vem-test

# Initialize test git repositories
git init test-repo-1
git init test-repo-2

Sample Test Environments

# Use provided sample environments for testing
cp -r etc/.vem/envs/* /tmp/vem-test/

# Create minimal test environment
vem create test-env --minimal --test-mode

# Test environment switching
vem switch test-env
vem current | grep test-env

Writing Tests

Unit Test Example

#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    #[test]
    fn test_parse_vem_config() {
        let config_content = r#"
            name = "test-env"
            description = "Test environment"
            editor = "vim"
            
            [plugin_managers]
            vim-plug = true
            
            [ctags.repositories.main]
            path = "."
        "#;
        
        let config = parse_vem_config(config_content).unwrap();
        assert_eq!(config.name, "test-env");
        assert_eq!(config.editor, "vim");
        assert!(config.plugin_managers.vim_plug);
    }

    #[test]
    fn test_ctags_generation() {
        let temp_dir = TempDir::new().unwrap();
        let repo_path = temp_dir.path().to_str().unwrap();
        
        // Create test source file
        std::fs::write(
            format!("{}/test.rs", repo_path),
            "fn test_function() {}"
        ).unwrap();
        
        let result = generate_ctags(repo_path, &["rust"]).unwrap();
        assert!(result.tags_generated > 0);
    }
}
}

Integration Test Example

#![allow(unused)]
fn main() {
// tests/integration/commands.rs
use std::process::Command;
use tempfile::TempDir;

#[test]
fn test_create_environment_command() {
    let temp_dir = TempDir::new().unwrap();
    let vem_home = temp_dir.path().join(".vem");
    
    let output = Command::new("vem")
        .env("VEM_HOME", vem_home)
        .args(&["create", "test-env", "--template=basic-vim"])
        .output()
        .expect("Failed to execute command");
    
    assert!(output.status.success());
    assert!(vem_home.join("environments").join("test-env").exists());
}

#[test]
fn test_environment_switching() {
    // Test environment creation, switching, and validation
    let temp_dir = TempDir::new().unwrap();
    let vem_home = temp_dir.path().join(".vem");
    
    // Create environment
    Command::new("vem")
        .env("VEM_HOME", vem_home)
        .args(&["create", "test1"])
        .output()
        .unwrap();
    
    // Switch to environment
    let output = Command::new("vem")
        .env("VEM_HOME", vem_home)
        .args(&["switch", "test1"])
        .output()
        .unwrap();
    
    assert!(output.status.success());
    
    // Verify current environment
    let current = Command::new("vem")
        .env("VEM_HOME", vem_home)
        .args(&["current"])
        .output()
        .unwrap();
    
    let current_name = String::from_utf8(current.stdout).unwrap();
    assert!(current_name.contains("test1"));
}
}

End-to-End Test Example

#![allow(unused)]
fn main() {
// tests/e2e/scenarios.rs
#[test]
fn test_developer_workflow() {
    // Simulate complete developer workflow
    
    // 1. Create new environment
    run_command(&["vem", "create", "dev-env", "--template=developer-vim"]);
    
    // 2. Switch to environment
    run_command(&["vem", "switch", "dev-env"]);
    
    // 3. Generate ctags for project
    run_command(&["vem", "generate", "ctags", "main_project"]);
    
    // 4. Verify ctags were created
    let tags_list = run_command(&["vem", "list", "ctags"]);
    assert!(tags_list.contains("main_project"));
    
    // 5. Update environment configuration
    update_vem_config("dev-env", |config| {
        config.ctags.auto_generate = true;
    });
    
    // 6. Verify configuration persistence
    let current_config = get_environment_config("dev-env");
    assert!(current_config.ctags.auto_generate);
}
}

Configuration Testing

Valid Configuration Tests

#![allow(unused)]
fn main() {
#[test]
fn test_valid_configurations() {
    let configs = vec![
        "etc/.vem/envs/basic-vim/vem.toml",
        "etc/.vem/envs/developer-vim/vem.toml", 
        "etc/.vem/envs/modern-nvim/vem.toml",
        "etc/.vem/envs/ai-development/vem.toml",
    ];
    
    for config_path in configs {
        let content = std::fs::read_to_string(config_path).unwrap();
        let config = parse_vem_config(&content);
        assert!(config.is_ok(), "Invalid config: {}", config_path);
        
        let config = config.unwrap();
        validate_configuration(&config).unwrap();
    }
}

#[test]
fn test_configuration_schemas() {
    // Test TOML schema validation
    let invalid_configs = vec![
        // Missing required fields
        r#"description = "Missing name""#,
        
        // Invalid plugin manager
        r#"
            name = "test"
            [plugin_managers]
            invalid_manager = true
        "#,
        
        // Invalid ctags configuration
        r#"
            name = "test"
            [ctags.repositories.test]
            Missing path
        "#,
    ];
    
    for invalid in invalid_configs {
        let result = parse_vem_config(invalid);
        assert!(result.is_err());
    }
}
}

Performance Testing

Benchmark Tests

#![allow(unused)]
fn main() {
use criterion::{criterion_group, criterion_main, Criterion};

fn benchmark_environment_switching(c: &mut Criterion) {
    c.bench_function("switch environment", |b| {
        b.iter(|| {
            switch_environment("test-env")
        })
    });
}

fn benchmark_ctags_generation(c: &mut Criterion) {
    c.bench_function("generate ctags", |b| {
        b.iter(|| {
            generate_ctags("./test-repo", &["rust", "python"])
        })
    });
}

criterion_group!(benches, benchmark_environment_switching, benchmark_ctags_generation);
criterion_main!(benches);
}

Load Testing

# Test with multiple environments
for i in {1..50}; do
    vem create "test-env-$i" --template=basic-vim &
done
wait

# Test rapid environment switching
for i in {1..20}; do
    vem switch "test-env-$((RANDOM % 50 + 1))"
done

# Test concurrent ctags generation
for repo in repo1 repo2 repo3; do
    vem generate ctags "$repo" &
done
wait

Cross-Platform Testing

Platform-Specific Tests

# Linux-specific tests
make test-linux

# macOS-specific tests  
make test-macos

# Windows-specific tests (if supported)
make test-windows

# Container-based testing
docker run --rm -v $(pwd):/vem ubuntu:latest bash -c "
    cd /vem && 
    apt-get update && 
    apt-get install -y build-essential &&
    make test
"

Compatibility Testing

#![allow(unused)]
fn main() {
#[cfg(target_os = "linux")]
#[test]
fn test_linux_paths() {
    assert_eq!(get_config_dir(), "/home/user/.vem");
}

#[cfg(target_os = "macos")]  
#[test]
fn test_macos_paths() {
    assert_eq!(get_config_dir(), "/Users/user/.vem");
}

#[test]
fn test_cross_platform_compatibility() {
    // Test path handling across platforms
    let path = normalize_path("/some/path");
    assert!(path.is_absolute());
    
    // Test command execution
    let result = execute_command("echo", &["test"]);
    assert!(result.is_ok());
}
}

Continuous Integration

GitHub Actions Configuration

# .github/workflows/test.yml
name: Test

on: [push, pull_request]

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        rust: [stable, beta]
        
    runs-on: ${{ matrix.os }}
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Install Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: ${{ matrix.rust }}
        
    - name: Install dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y universal-ctags vim
        
    - name: Run tests
      run: make test
      
    - name: Run integration tests
      run: make test-integration
      
    - name: Upload coverage
      uses: codecov/codecov-action@v3

Test Coverage

# Generate coverage report
cargo tarpaulin --out html

# View coverage
open target/tarpaulin/coverage.html

# Check coverage thresholds
cargo tarpaulin --fail-under 80

Debugging Tests

Test Debugging

# Run tests with debug output
RUST_LOG=debug cargo test

# Run single test with debugging
cargo test test_name -- --nocapture

# Debug test with gdb
rust-gdb target/debug/deps/vem-test

# Memory debugging with valgrind
valgrind --tool=memcheck cargo test

Test Data Management

# Clean test artifacts
make clean-test

# Reset test environments
rm -rf /tmp/vem-test/*
vem init --test-mode

# Generate test fixtures
make generate-fixtures

# Validate test data
make validate-test-data

Quality Assurance

Code Quality Checks

# Linting
cargo clippy -- -D warnings

# Formatting
cargo fmt --check

# Security audit
cargo audit

# License compliance
cargo license

# Documentation tests
cargo test --doc

Performance Monitoring

# Memory usage profiling
heaptrack vem switch environment-name

# CPU profiling
perf record vem generate ctags large-repo
perf report

# I/O monitoring
iotop -p $(pgrep vem)

This comprehensive testing guide ensures VEM maintains high quality and reliability across all supported platforms and use cases.

API Documentation

VEM provides a comprehensive internal API for managing Vim environments, ctags, and configurations. This document describes the core APIs and their usage.

Core APIs

Environment Management API

Create Environment

#![allow(unused)]
fn main() {
pub fn create_environment(name: &str, template: Option<&str>) -> Result<Environment, VemError>
}

Creates a new Vim environment with the specified name and optional template.

Parameters:

  • name: Environment name (must be unique)
  • template: Optional template name (basic-vim, developer-vim, modern-nvim, ai-development)

Returns: Environment instance or error

Switch Environment

#![allow(unused)]
fn main() {
pub fn switch_environment(name: &str) -> Result<(), VemError>
}

Switches to the specified environment by updating symlinks and configurations.

List Environments

#![allow(unused)]
fn main() {
pub fn list_environments() -> Result<Vec<Environment>, VemError>
}

Returns a list of all available environments.

Ctags Management API

Generate Ctags

#![allow(unused)]
fn main() {
pub fn generate_ctags(
    repository: &str, 
    options: CtagsOptions
) -> Result<CtagsResult, VemError>
}

Generates ctags for the specified repository with given options.

Parameters:

  • repository: Repository name from vem.toml configuration
  • options: Ctags generation options (languages, exclude patterns, etc.)

Update Ctags

#![allow(unused)]
fn main() {
pub fn update_ctags(
    repository: &str,
    incremental: bool
) -> Result<CtagsResult, VemError>
}

Updates existing ctags for the repository.

List Ctags

#![allow(unused)]
fn main() {
pub fn list_ctags(format: ListFormat) -> Result<Vec<CtagsInfo>, VemError>
}

Lists all ctags with their status and metadata.

Configuration API

Load Configuration

#![allow(unused)]
fn main() {
pub fn load_vem_config(path: &Path) -> Result<VemConfig, VemError>
}

Loads and parses a vem.toml configuration file.

Save Configuration

#![allow(unused)]
fn main() {
pub fn save_vem_config(config: &VemConfig, path: &Path) -> Result<(), VemError>
}

Saves configuration to a vem.toml file.

Data Structures

Environment

#![allow(unused)]
fn main() {
pub struct Environment {
    pub name: String,
    pub description: String,
    pub env_type: EnvironmentType,
    pub config_path: PathBuf,
    pub active: bool,
}
}

CtagsInfo

#![allow(unused)]
fn main() {
pub struct CtagsInfo {
    pub name: String,
    pub repository: String,
    pub tag_file: PathBuf,
    pub last_updated: DateTime<Utc>,
    pub size: u64,
    pub status: CtagsStatus,
}
}

VemConfig

#![allow(unused)]
fn main() {
pub struct VemConfig {
    pub environment: EnvironmentConfig,
    pub plugins: PluginConfig,
    pub ctags: CtagsConfig,
    pub theme: ThemeConfig,
}
}

Error Handling

All APIs use the VemError type for consistent error handling:

#![allow(unused)]
fn main() {
pub enum VemError {
    IoError(std::io::Error),
    ConfigError(String),
    EnvironmentNotFound(String),
    CtagsError(String),
    ValidationError(String),
}
}

Usage Examples

Creating and Switching Environments

#![allow(unused)]
fn main() {
use vem::api::{create_environment, switch_environment};

// Create a new development environment
let env = create_environment("my-dev", Some("developer-vim"))?;
println!("Created environment: {}", env.name);

// Switch to the new environment
switch_environment("my-dev")?;
println!("Switched to my-dev environment");
}

Managing Ctags

#![allow(unused)]
fn main() {
use vem::api::{generate_ctags, list_ctags, CtagsOptions, ListFormat};

// Generate ctags for main project
let options = CtagsOptions {
    languages: vec!["rust".to_string(), "python".to_string()],
    exclude_patterns: vec![".git".to_string(), "target".to_string()],
    ..Default::default()
};

generate_ctags("main_project", options)?;

// List all ctags
let ctags_list = list_ctags(ListFormat::Table)?;
for ctag in ctags_list {
    println!("{}: {} ({})", ctag.name, ctag.repository, ctag.status);
}
}

Integration Notes

  • All APIs are designed to be thread-safe
  • Configuration changes are atomic where possible
  • File operations include proper error handling and rollback
  • APIs support both synchronous and asynchronous operations where appropriate

Troubleshooting Guide

This guide helps you diagnose and resolve common issues with VEM.

Diagnostic Commands

Before troubleshooting, gather system information:

# Check VEM version and build info
vem --version

# Verify installation
which vem

# Check current environment
vem current

# List all environments
vem list

# Validate configuration
vem config validate

# Enable debug logging
export RUST_LOG=debug
vem <command>

# Check system dependencies
ctags --version
vim --version
nvim --version

Installation Issues

VEM Command Not Found

Problem: bash: vem: command not found

Solutions:

  1. Verify installation location:

    # Find VEM binary
    find / -name "vem" -type f 2>/dev/null
    
    # Check if installed via package manager
    dpkg -l | grep vem        # Debian/Ubuntu
    rpm -qa | grep vem        # Red Hat/CentOS
    brew list | grep vem      # macOS Homebrew
    
  2. Fix PATH:

    # Add to PATH (temporary)
    export PATH="/usr/local/bin:$PATH"
    
    # Add to shell profile (permanent)
    echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc
    source ~/.bashrc
    
  3. Manual installation:

    # Download and install manually
    wget https://github.com/ryo-arima/vem/releases/latest/download/vem-linux-x64
    chmod +x vem-linux-x64
    sudo mv vem-linux-x64 /usr/local/bin/vem
    

Permission Denied

Problem: Permission denied when running VEM

Solutions:

  1. Fix binary permissions:

    sudo chmod +x /usr/local/bin/vem
    
  2. Fix config directory permissions:

    sudo chown -R $USER:$USER ~/.vem/
    chmod -R 755 ~/.vem/
    
  3. SELinux issues (Red Hat systems):

    # Check SELinux status
    sestatus
    
    # Allow VEM execution
    sudo setsebool -P allow_execheap on
    
    # Or disable SELinux temporarily
    sudo setenforce 0
    

Missing Dependencies

Problem: VEM runs but features don’t work

Solutions:

  1. Install Universal Ctags:

    # Ubuntu/Debian
    sudo apt-get install universal-ctags
    
    # Red Hat/CentOS
    sudo yum install ctags
    
    # macOS
    brew install universal-ctags
    
    # Verify installation
    ctags --version | grep "Universal Ctags"
    
  2. Install Vim/Neovim:

    # Ubuntu/Debian
    sudo apt-get install vim neovim
    
    # macOS
    brew install vim neovim
    
    # Verify versions
    vim --version | head -1
    nvim --version | head -1
    
  3. Install Git:

    # Required for multi-repository features
    sudo apt-get install git
    git --version
    

Environment Management Issues

Environment Creation Fails

Problem: vem create fails with errors

Diagnosis:

# Try with debug output
RUST_LOG=debug vem create test-env

# Check available templates
vem list --templates

# Verify config directory exists
ls -la ~/.vem/

Common causes and solutions:

  1. Config directory doesn’t exist:

    mkdir -p ~/.vem/environments
    
  2. Invalid template:

    # List available templates
    ls etc/.vem/envs/
    
    # Use valid template
    vem create my-env --template=basic-vim
    
  3. Name conflicts:

    # Check existing environments
    vem list
    
    # Use different name
    vem create my-env-2
    
  4. Disk space issues:

    # Check available space
    df -h ~/.vem/
    
    # Clean up if needed
    vem clean --unused
    

Environment Switching Fails

Problem: vem switch doesn’t work properly

Diagnosis:

# Check current environment
vem current

# Try switching with debug output
RUST_LOG=debug vem switch environment-name

# Verify environment exists
vem list | grep environment-name

# Check environment configuration
cat ~/.vem/environments/environment-name/vem.toml

Solutions:

  1. Invalid environment name:

    # List exact names
    vem list
    
    # Use correct name (case-sensitive)
    vem switch "exact-name"
    
  2. Corrupted environment:

    # Validate environment
    vem config validate environment-name
    
    # Recreate if needed
    vem remove environment-name
    vem create environment-name --template=basic-vim
    
  3. Permission issues:

    # Fix permissions
    chmod -R 755 ~/.vem/environments/environment-name/
    

Configuration File Errors

Problem: TOML parsing errors

Example error: invalid TOML syntax at line 15

Diagnosis:

# Validate specific environment
vem config validate environment-name

# Check TOML syntax
toml-lint ~/.vem/environments/environment-name/vem.toml

Common TOML syntax issues:

  1. Missing quotes in strings:

    # Wrong
    name = My Environment
    
    # Correct
    name = "My Environment"
    
  2. Invalid boolean values:

    # Wrong
    enabled = yes
    
    # Correct
    enabled = true
    
  3. Incorrect array syntax:

    # Wrong
    languages = rust, python
    
    # Correct
    languages = ["rust", "python"]
    
  4. Invalid table structure:

    # Wrong
    [ctags.repositories.main
    path = "."
    
    # Correct
    [ctags.repositories.main]
    path = "."
    

Ctags Issues

Ctags Generation Fails

Problem: vem generate ctags produces errors

Diagnosis:

# Test ctags directly
ctags --version
ctags -R . --languages=rust

# Check VEM ctags configuration
vem config show | grep -A 10 ctags

# Try manual generation
RUST_LOG=debug vem generate ctags test-repo

Solutions:

  1. Universal Ctags not installed:

    # Install proper version
    sudo apt-get install universal-ctags
    
    # Verify it's Universal Ctags, not Exuberant
    ctags --version | head -1
    
  2. Invalid repository path:

    # Check path in configuration
    grep -A 5 "repositories" ~/.vem/environments/*/vem.toml
    
    # Update with correct paths
    [ctags.repositories.main]
    path = "/absolute/path/to/repo"
    
  3. Language not supported:

    # List supported languages
    ctags --list-languages
    
    # Use supported language names
    ctags --list-languages | grep -i rust
    
  4. Permission issues:

    # Check repository permissions
    ls -la /path/to/repository
    
    # Fix if needed
    chmod -R 755 /path/to/repository
    

Ctags Files Not Found

Problem: Generated tags don’t appear in editor

Diagnosis:

# Check if tags file exists
ls -la ~/.vem/environments/current/tags

# Verify tags content
head -10 ~/.vem/environments/current/tags

# Check editor configuration
vim -c "set tags?" -c "q"

Solutions:

  1. Tags file not in expected location:

    # Find tags files
    find ~/.vem/ -name "tags" -type f
    
    # Configure editor to use correct path
    # Add to .vimrc:
    set tags=~/.vem/environments/current/tags
    
  2. Editor not configured for ctags:

    # For Vim, add to .vimrc:
    set tags+=./tags;
    set tags+=~/.vem/tags
    
    # For Neovim, add to init.lua:
    vim.opt.tags:append("./tags;")
    vim.opt.tags:append(vim.fn.expand("~/.vem/tags"))
    

Cross-Repository Ctags Issues

Problem: Multi-repository ctags not working

Diagnosis:

# Check repository configuration
vem config show | grep -A 20 repositories

# Verify all paths exist
for repo in $(vem config show | grep "path =" | awk '{print $3}' | tr -d '"'); do
    echo "Checking: $repo"
    ls -la "$repo" || echo "Path not found: $repo"
done

# Test individual repository tagging
ctags -R /path/to/repo1 -f /tmp/test-tags

Solutions:

  1. Missing repository paths:

    # Add all repositories to vem.toml
    [ctags.repositories.main]
    path = "/home/user/project"
    
    [ctags.repositories.shared]
    path = "/home/user/shared-libs"
    remote_url = "git@github.com:company/shared-libs.git"
    
  2. Git repository synchronization:

    # Update repositories before generating tags
    vem ctags update --all-repos
    
    # Or update individual repo
    cd /path/to/shared-repo && git pull
    

Plugin Manager Issues

Plugin Installation Fails

Problem: Plugins not installing in environment

Diagnosis:

# Check plugin manager configuration
grep -A 10 "plugin_managers" ~/.vem/environments/current/vem.toml

# Check if plugin manager is installed
which vim-plug     # or packer, lazy, etc.

# Test plugin manager manually
vim +PlugInstall +qall    # for vim-plug

Solutions:

  1. Plugin manager not enabled:

    [plugin_managers]
    vim-plug = true
    packer = false
    lazy = false
    
  2. Plugin manager not installed:

    # Install vim-plug
    curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
        https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    
    # For Neovim
    sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
           https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
    
  3. Network issues:

    # Test network connectivity
    curl -I https://github.com
    
    # Configure proxy if needed
    git config --global http.proxy http://proxy:port
    
  4. Invalid plugin syntax:

    # Check plugin configuration
    [plugin_managers.configs.vim-plug]
    packages = [
        { name = "tpope/vim-fugitive", description = "Git integration" },
        # Ensure proper TOML array syntax
    ]
    

Plugin Configuration Conflicts

Problem: Plugins interfere with each other

Solutions:

  1. Check for conflicting keybindings:

    " Check current mappings
    :map
    :imap
    :vmap
    
  2. Plugin loading order:

    # Control loading order in vem.toml
    [plugin_managers.configs.vim-plug.options]
    load_order = ["essential", "ui", "language", "completion"]
    
  3. Conditional loading:

    # Load plugins conditionally
    { name = "plugin/name", condition = "has('nvim')" }
    

AI Integration Issues

GitHub Copilot Not Working

Problem: Copilot suggestions not appearing

Diagnosis:

# Check environment configuration
grep -A 10 "ai_tools" ~/.vem/environments/current/vem.toml

# Verify Copilot installation in editor
vim -c "echo exists('g:loaded_copilot')" -c "q"

Solutions:

  1. Copilot not enabled in configuration:

    [ai_tools.copilot]
    enabled = true
    auto_suggest = true
    
  2. Copilot plugin not installed:

    # Add to plugin configuration
    { name = "github/copilot.vim", description = "GitHub Copilot" }
    
  3. Authentication issues:

    # In Vim/Neovim
    :Copilot auth
    :Copilot status
    

AI Context Enhancement Not Working

Problem: AI tools not getting enhanced context

Solutions:

  1. Ensure ctags are generated:

    vem generate ctags main_project
    vem list ctags
    
  2. Check AI configuration:

    [ai_tools.context]
    use_ctags = true
    include_related_files = true
    max_context_lines = 1000
    

Performance Issues

Slow Environment Switching

Problem: vem switch takes too long

Diagnosis:

# Profile switching
time vem switch environment-name

# Check environment size
du -sh ~/.vem/environments/environment-name/

# Monitor system resources
htop    # Check CPU/memory usage during switch

Solutions:

  1. Large plugin installations:

    # Use lazy loading
    [plugin_managers.configs.vim-plug.options]
    lazy_loading = true
    
  2. Reduce unnecessary plugins:

    # Disable unused plugins
    { name = "heavy/plugin", enabled = false }
    
  3. Optimize ctags generation:

    [ctags]
    auto_generate = false    # Disable auto-generation
    exclude_patterns = ["node_modules", "target", ".git"]
    

High Memory Usage

Problem: VEM uses too much memory

Diagnosis:

# Monitor memory usage
ps aux | grep vem
top -p $(pgrep vem)

# Check for memory leaks
valgrind --tool=memcheck vem switch env-name

Solutions:

  1. Reduce ctags scope:

    [ctags]
    max_file_size = "1MB"
    exclude_patterns = ["*.min.js", "vendor/"]
    
  2. Limit concurrent operations:

    # Avoid parallel ctags generation
    vem config set ctags.parallel_generation false
    

Logging and Debugging

Enable Debug Logging

# Environment variable
export RUST_LOG=debug

# Or inline
RUST_LOG=debug vem command

# Specific modules
RUST_LOG=vem::ctags=debug vem generate ctags repo

# Save to file
RUST_LOG=debug vem command 2>&1 | tee debug.log

Log File Locations

# Default log location
~/.vem/logs/vem.log

# View recent logs
tail -f ~/.vem/logs/vem.log

# Search for errors
grep -i error ~/.vem/logs/vem.log

# Rotate large log files
logrotate ~/.vem/logs/

System Information Collection

For bug reports, collect:

#!/bin/bash
# vem-diagnostics.sh

echo "=== VEM Diagnostics ==="
echo "Date: $(date)"
echo "System: $(uname -a)"
echo "VEM Version: $(vem --version)"
echo "Shell: $SHELL"
echo

echo "=== Dependencies ==="
echo "Ctags: $(ctags --version 2>/dev/null | head -1 || echo 'Not installed')"
echo "Vim: $(vim --version 2>/dev/null | head -1 || echo 'Not installed')"
echo "Neovim: $(nvim --version 2>/dev/null | head -1 || echo 'Not installed')"
echo "Git: $(git --version 2>/dev/null || echo 'Not installed')"
echo

echo "=== VEM Configuration ==="
echo "Config directory: ~/.vem/"
ls -la ~/.vem/ 2>/dev/null || echo "Config directory not found"
echo

echo "=== Current Environment ==="
vem current 2>/dev/null || echo "No current environment"
echo

echo "=== Available Environments ==="
vem list 2>/dev/null || echo "Failed to list environments"
echo

echo "=== Recent Logs ==="
tail -20 ~/.vem/logs/vem.log 2>/dev/null || echo "No log file found"

Run with:

chmod +x vem-diagnostics.sh
./vem-diagnostics.sh > vem-debug-info.txt

Getting Help

Community Support

  1. GitHub Issues: Report bugs and request features

    • Include diagnostic information
    • Provide minimal reproduction steps
    • Attach configuration files
  2. Documentation: Check docs for detailed guides

  3. Debug Mode: Always use debug output for issue reports

    RUST_LOG=debug vem problematic-command 2>&1 | tee issue-debug.log
    

Creating Bug Reports

Include in bug reports:

  1. System Information:

    • OS and version
    • VEM version
    • Dependencies versions
  2. Steps to Reproduce:

    • Exact commands run
    • Expected vs actual behavior
    • Error messages
  3. Configuration:

    • Relevant vem.toml sections
    • Environment setup
    • Custom modifications
  4. Debug Output:

    • Full debug logs
    • Stack traces if available
    • System resource usage

This comprehensive troubleshooting guide should help resolve most common VEM issues. When in doubt, enable debug logging and check the specific error messages for more targeted solutions.

Frequently Asked Questions

General Questions

Q: What is VEM?

A: VEM (Vim Environment Manager) is a command-line tool for managing multiple Vim/Neovim configurations. It allows you to switch between different editor environments tailored for specific tasks (development, writing, AI-assisted coding, etc.).

Q: Why use VEM instead of manual configuration management?

A: VEM provides:

  • Isolation: Each environment is completely isolated
  • Easy switching: One command to switch entire configurations
  • Advanced features: Built-in ctags management, AI integration, multi-repository support
  • Templates: Pre-configured environments for common use cases
  • Consistency: TOML-based configuration for all environments

Q: Is VEM compatible with my existing Vim configuration?

A: Yes! VEM can import your existing .vimrc and .vim directory. You can also create a new environment based on your current setup.

Installation & Setup

Q: What are the system requirements?

A:

  • Rust 1.70+ for building from source
  • Universal Ctags (for tag management)
  • Vim 8.0+ or Neovim 0.8.0+
  • Git (for multi-repository features)

Q: How do I install VEM?

A: Several options:

# Pre-built packages (recommended)
wget https://github.com/ryo-arima/vem/releases/latest/vem_amd64.deb
sudo dpkg -i vem_amd64.deb

# Build from source
git clone https://github.com/ryo-arima/vem.git
cd vem && cargo build --release
sudo cp target/release/vem /usr/local/bin/

Q: How do I get started quickly?

A:

# List available sample environments
vem list

# Try the developer environment
vem switch developer-vim

# Or create your own
vem create my-environment --template=basic-vim

Environment Management

Q: How many environments can I have?

A: There’s no hard limit. You can create as many environments as needed. Each environment is stored separately and doesn’t affect others.

Q: Can I share environments between machines?

A: Yes! Environment configurations are stored in TOML files that can be version controlled and shared. The etc/.vem/ directory contains all environment definitions.

Q: How do I backup my environments?

A:

# Backup configuration directory
cp -r ~/.vem ~/vem-backup

# Or just the configurations
tar -czf vem-configs.tar.gz ~/.vem/environments/

Q: Can I use different plugin managers in different environments?

A: Absolutely! Each environment can use a different plugin manager (vim-plug, lazy.nvim, packer, etc.). This is configured in the environment’s vem.toml file.

Ctags Management

Q: What are ctags and why should I use them?

A: Ctags create an index of code symbols (functions, classes, variables) for quick navigation. VEM’s ctags management provides:

  • Multi-repository support
  • Automatic updates
  • AI-enhanced relevance scoring
  • Cross-project navigation

Q: How do I generate ctags for my project?

A:

# Generate tags for current project
vem generate ctags main_project

# Include specific languages
vem generate ctags . --languages=python,rust,javascript

# List all available tags
vem list ctags

Q: Can I use ctags with multiple repositories?

A: Yes! VEM supports multi-repository ctags:

# Configure repositories in vem.toml
[ctags.repositories.shared_libs]
path = "../shared-libraries" 
remote_url = "git@github.com:company/shared-libs.git"

# Generate cross-repository tags
vem generate ctags cross_repo

Q: My ctags aren’t updating automatically. What’s wrong?

A: Check:

  1. auto_generate = true in your vem.toml
  2. Universal Ctags is installed (ctags --version)
  3. Repository paths are correct
  4. File permissions allow writing

AI Integration

Q: How do I set up GitHub Copilot?

A:

  1. Use the ai-development environment:
    vem switch ai-development
    
  2. Install GitHub Copilot extension in your editor
  3. The environment includes pre-configured Copilot settings

Q: Can I use multiple AI tools simultaneously?

A: Yes! The AI development environment supports:

  • GitHub Copilot
  • ChatGPT integration
  • Codeium
  • Custom AI tools

Configure them in your vem.toml:

[ai_tools.copilot]
enabled = true

[ai_tools.codeium] 
enabled = true

Q: How does AI context enhancement work?

A: VEM provides AI tools with rich context from:

  • Ctags for symbol information
  • Cross-repository code awareness
  • Project structure understanding
  • Smart filtering based on relevance

Plugin Management

Q: How do I add plugins to an environment?

A: Edit your environment’s vem.toml:

[plugin_managers.configs.vim-plug]
packages = [
    { name = "tpope/vim-fugitive", description = "Git integration" },
    { name = "preservim/nerdtree", description = "File explorer" }
]

Q: Can I switch plugin managers for an existing environment?

A: Yes, but be careful:

  1. Update the plugin manager selection in vem.toml
  2. Migrate plugin configurations
  3. Reinstall plugins with the new manager

Q: Why isn’t my plugin working?

A: Check:

  1. Plugin is listed in the correct package list
  2. Plugin manager is enabled (vim-plug = true)
  3. Plugin manager is installed
  4. Run plugin manager’s install command (:PlugInstall, etc.)

Troubleshooting

Q: VEM command not found after installation

A:

# Check if VEM is in PATH
which vem

# Add to PATH if needed (add to ~/.bashrc or ~/.zshrc)
export PATH="/usr/local/bin:$PATH"

# Verify installation
vem --version

Q: Environment switching isn’t working

A:

# Check current environment
vem current

# List available environments
vem list

# Try switching with debug output
RUST_LOG=debug vem switch environment-name

Q: Vim/Neovim shows errors after switching environments

A:

  1. Check for syntax errors in configuration files
  2. Verify all plugins are installed
  3. Check for conflicting settings
  4. Use :checkhealth in Neovim for diagnostics

Q: Ctags generation fails

A:

# Check ctags installation
ctags --version

# Verify repository paths
vem config show | grep repositories

# Check permissions
ls -la ~/.vem/

Q: How do I get more detailed error information?

A:

# Enable debug logging
RUST_LOG=debug vem <command>

# Check log files
tail -f ~/.vem/logs/vem.log

# Validate configuration
vem config validate

Performance

Q: VEM seems slow when switching environments

A:

  • Large plugin installations can slow switching
  • Use lazy = false for plugins you don’t need immediately
  • Consider using lighter alternatives for development vs. production environments

Q: Ctags generation is taking too long

A:

  • Exclude unnecessary directories (node_modules, target, .git)
  • Use language-specific filtering
  • Consider incremental updates instead of full regeneration

Contributing

Q: How can I contribute to VEM?

A:

  1. Check the contributing guide
  2. Look for β€œgood first issue” labels on GitHub
  3. Submit bug reports with detailed information
  4. Suggest new features through GitHub Discussions

Q: Can I create custom environment templates?

A: Yes! Create a new environment configuration in etc/.vem/envs/ and share it:

  1. Copy an existing template
  2. Modify settings for your use case
  3. Document the template’s purpose
  4. Submit a pull request

Q: How do I report bugs?

A:

  1. Check existing issues on GitHub
  2. Include VEM version (vem --version)
  3. Provide steps to reproduce
  4. Include relevant configuration files
  5. Add debug output if possible (RUST_LOG=debug)

Advanced Usage

Q: Can I use VEM in scripts or automation?

A: Yes! VEM supports:

# JSON output for parsing
vem list --format=json

# Non-interactive mode
vem switch environment --no-confirm

# Exit codes for scripting
if vem current | grep -q "ai-development"; then
    echo "AI environment active"
fi

Q: How do I integrate VEM with my existing workflow?

A:

  • Add environment switching to your shell prompt
  • Create aliases for common environments
  • Use Git hooks to automatically switch environments
  • Integrate with tmux or terminal multiplexers