Files
claude_filter/install.py
T

324 lines
9.9 KiB
Python
Raw Normal View History

2026-09-16 07:40:02 +00:00
#!/usr/bin/env python3
"""
Claude Filter Vim Plugin - Automatic Installation Script
Detects Vim/Neovim installation and installs the plugin with proper handling
for existing installations (updates/overrides).
Features:
- Auto-detects Vim vs Neovim
- Auto-detects config directory
- Installs both Lua (Neovim) and VimScript (Vim) versions
- Handles existing installations (updates)
- Cross-platform (Linux, macOS, Windows)
"""
import os
import sys
import shutil
import argparse
from pathlib import Path
class PluginInstaller:
def __init__(self, verbose=False, override=False):
self.verbose = verbose
self.override = override
self.installed = []
self.errors = []
def log(self, message, level="INFO"):
"""Log messages if verbose mode is enabled"""
if self.verbose or level in ["ERROR", "SUCCESS"]:
prefix = "✅" if level == "SUCCESS" else "❌" if level == "ERROR" else "ℹ️"
print(f"{prefix} [{level}] {message}")
def check_editor_installed(self):
"""Check which editors are installed"""
editors = {}
# Check Neovim
if shutil.which("nvim"):
editors["neovim"] = True
self.log("Neovim detected")
else:
editors["neovim"] = False
self.log("Neovim not found", "WARN")
# Check Vim
if shutil.which("vim"):
editors["vim"] = True
self.log("Vim detected")
else:
editors["vim"] = False
self.log("Vim not found", "WARN")
return editors
def get_neovim_config_dir(self):
"""Get Neovim config directory (works on all platforms)"""
# Check XDG_CONFIG_HOME first (Linux/macOS)
xdg_config = os.environ.get("XDG_CONFIG_HOME")
if xdg_config:
nvim_dir = Path(xdg_config) / "nvim"
if nvim_dir.exists():
return nvim_dir
# Check standard locations
home = Path.home()
# macOS
if sys.platform == "darwin":
nvim_dir = home / ".config" / "nvim"
if nvim_dir.exists():
return nvim_dir
# Linux
if sys.platform.startswith("linux"):
nvim_dir = home / ".config" / "nvim"
if nvim_dir.exists():
return nvim_dir
# Windows
if sys.platform == "win32":
# Try AppData first
appdata = os.environ.get("APPDATA")
if appdata:
nvim_dir = Path(appdata) / "nvim"
if nvim_dir.exists():
return nvim_dir
# Try local AppData
local_appdata = os.environ.get("LOCALAPPDATA")
if local_appdata:
nvim_dir = Path(local_appdata) / "nvim"
if nvim_dir.exists():
return nvim_dir
# Fallback: Create in ~/.config/nvim
return home / ".config" / "nvim"
def get_vim_config_dir(self):
"""Get Vim config directory"""
home = Path.home()
# Check for .vim directory
vim_dir = home / ".vim"
if vim_dir.exists():
return vim_dir
# Windows: check vimfiles
if sys.platform == "win32":
vimfiles = home / "vimfiles"
if vimfiles.exists():
return vimfiles
# Default to .vim
return vim_dir
def install_neovim_plugin(self):
"""Install Lua version for Neovim"""
self.log("Installing Neovim plugin...")
nvim_dir = self.get_neovim_config_dir()
plugin_dir = nvim_dir / "plugin"
# Create directory if it doesn't exist
plugin_dir.mkdir(parents=True, exist_ok=True)
# Source and destination
source = Path(__file__).parent / "plugin" / "claude_filter.lua"
destination = plugin_dir / "claude_filter.lua"
if not source.exists():
self.log(f"Source file not found: {source}", "ERROR")
self.errors.append(f"Neovim: Source file not found")
return False
# Check if already installed
if destination.exists():
if not self.override:
self.log(f"Already installed at {destination}")
self.log("Use --override to update")
return True
else:
self.log(f"Removing existing: {destination}")
destination.unlink()
# Copy file
try:
shutil.copy2(source, destination)
self.log(f"✅ Installed to {destination}", "SUCCESS")
self.installed.append(("Neovim", destination))
return True
except Exception as e:
self.log(f"Failed to copy: {e}", "ERROR")
self.errors.append(f"Neovim: {str(e)}")
return False
def install_vim_plugin(self):
"""Install VimScript version for Vim"""
self.log("Installing Vim plugin...")
vim_dir = self.get_vim_config_dir()
plugin_dir = vim_dir / "plugin"
# Create directory if it doesn't exist
plugin_dir.mkdir(parents=True, exist_ok=True)
# Source and destination
source = Path(__file__).parent / "plugin" / "claude_filter.vim"
destination = plugin_dir / "claude_filter.vim"
if not source.exists():
self.log(f"Source file not found: {source}", "ERROR")
self.errors.append(f"Vim: Source file not found")
return False
# Check if already installed
if destination.exists():
if not self.override:
self.log(f"Already installed at {destination}")
self.log("Use --override to update")
return True
else:
self.log(f"Removing existing: {destination}")
destination.unlink()
# Copy file
try:
shutil.copy2(source, destination)
self.log(f"✅ Installed to {destination}", "SUCCESS")
self.installed.append(("Vim", destination))
return True
except Exception as e:
self.log(f"Failed to copy: {e}", "ERROR")
self.errors.append(f"Vim: {str(e)}")
return False
def install(self):
"""Main installation logic"""
self.log("=" * 60)
self.log("Claude Filter Vim Plugin - Installer", "SUCCESS")
self.log("=" * 60)
# Check what's installed
editors = self.check_editor_installed()
if not any(editors.values()):
self.log("Neither Vim nor Neovim found on this system", "ERROR")
self.log("Install one of them first:")
self.log(" - Neovim: https://neovim.io")
self.log(" - Vim: https://www.vim.org")
return False
success = True
# Install for Neovim
if editors["neovim"]:
if not self.install_neovim_plugin():
success = False
# Install for Vim
if editors["vim"]:
if not self.install_vim_plugin():
success = False
# Summary
self.log("=" * 60)
if self.installed:
self.log("Installation Summary:", "SUCCESS")
for editor, path in self.installed:
self.log(f" {editor}: {path}")
if self.errors:
self.log("Errors encountered:", "ERROR")
for error in self.errors:
self.log(f" - {error}")
self.log("=" * 60)
# Usage instructions
if self.installed:
self.log("\n✅ Installation successful!\n", "SUCCESS")
self.log("Usage:")
self.log(" 1. Select text in visual mode (V + arrows)")
self.log(" 2. Press <leader>a (usually comma+a)")
self.log(" 3. Enter your instruction")
self.log(" 4. Text is transformed instantly")
self.log("\nDocumentation:")
self.log(" - Quick start: QUICK_START.md")
self.log(" - Detailed setup: SETUP.md")
self.log(" - Test cases: TEST_CASES.md")
self.log(" - Technical details: TECHNICAL.md")
return True
else:
self.log("Installation failed", "ERROR")
return False
def verify_installation(self):
"""Verify that plugin files exist and are readable"""
self.log("\nVerifying installation...")
all_good = True
for editor, path in self.installed:
if path.exists() and path.is_file():
size = path.stat().st_size
self.log(f"✓ {editor} plugin verified ({size} bytes)")
else:
self.log(f"✗ {editor} plugin not found at {path}", "ERROR")
all_good = False
return all_good
def main():
parser = argparse.ArgumentParser(
description="Install Claude Filter Vim plugin",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python3 install.py # Install with auto-detection
python3 install.py --verbose # Show detailed output
python3 install.py --override # Update existing installation
python3 install.py -v -o # Both verbose and override
"""
)
parser.add_argument(
"-v", "--verbose",
action="store_true",
help="Show detailed installation messages"
)
parser.add_argument(
"-o", "--override",
action="store_true",
help="Override existing installation (update)"
)
parser.add_argument(
"--verify",
action="store_true",
help="Only verify existing installation"
)
args = parser.parse_args()
installer = PluginInstaller(verbose=args.verbose, override=args.override)
if args.verify:
installer.install()
installer.verify_installation()
else:
success = installer.install()
if success:
installer.verify_installation()
sys.exit(0)
else:
sys.exit(1)
if __name__ == "__main__":
main()