diff options
| author | srdusr <trevorgray@srdusr.com> | 2025-09-24 04:19:28 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2025-09-24 04:19:28 +0200 |
| commit | 7ed2303648bf83bb081d9bd863660ebf2344ce47 (patch) | |
| tree | 702f5f832796b572d0faee31c0eb15507e91f49a /neovim.ps1 | |
| parent | 2a8020a2e9b7ef2ee77ddee14892127a4eb95187 (diff) | |
| download | dotfiles-7ed2303648bf83bb081d9bd863660ebf2344ce47.tar.gz dotfiles-7ed2303648bf83bb081d9bd863660ebf2344ce47.zip | |
Squashed 'common/config/nvim/' changes from 2a8020a..966d12a
966d12a Update/Overhaul
git-subtree-dir: common/config/nvim
git-subtree-split: 966d12ac730c83da90d60ab24eae539b2ea69441
Diffstat (limited to 'neovim.ps1')
| -rwxr-xr-x | neovim.ps1 | 917 |
1 files changed, 917 insertions, 0 deletions
diff --git a/neovim.ps1 b/neovim.ps1 new file mode 100755 index 0000000..a63965e --- /dev/null +++ b/neovim.ps1 @@ -0,0 +1,917 @@ +# Neovim Installation Script for Windows (PowerShell) +# Created By: srdusr (PowerShell port) +# Project: Install/update/uninstall/change version Neovim script for Windows + +#Requires -Version 5.1 + +param( + [switch]$Force, + [switch]$NoPrompt +) + +# Color definitions +$Colors = @{ + Red = "Red" + Green = "Green" + Yellow = "Yellow" + Cyan = "Cyan" +} + +# Global variables +$Script:DownloadCommand = $null +$Script:IsAdmin = $false +$Script:ShowPrompt = $true +$Script:NeovimPath = "$env:LOCALAPPDATA\nvim" +$Script:NeovimBin = "$Script:NeovimPath\bin" +$Script:NeovimExe = "$Script:NeovimBin\nvim.exe" + +# Handle errors +function Write-ErrorMessage { + param([string]$Message) + Write-Host "Error: $Message" -ForegroundColor $Colors.Red +} + +# Handle success messages +function Write-SuccessMessage { + param([string]$Message) + Write-Host $Message -ForegroundColor $Colors.Green +} + +# Handle info messages +function Write-InfoMessage { + param([string]$Message) + Write-Host $Message -ForegroundColor $Colors.Cyan +} + +# Check if running as administrator +function Test-Administrator { + $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() + $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) + return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +} + +# Check if necessary dependencies are installed +function Test-Dependencies { + Write-InfoMessage "Checking dependencies..." + + # Check for download tools + if (Get-Command curl -ErrorAction SilentlyContinue) { + $Script:DownloadCommand = "curl" + Write-InfoMessage "Found curl" + } elseif (Get-Command wget -ErrorAction SilentlyContinue) { + $Script:DownloadCommand = "wget" + Write-InfoMessage "Found wget" + } else { + Write-InfoMessage "Neither curl nor wget found. Will use PowerShell's Invoke-WebRequest" + $Script:DownloadCommand = "powershell" + } + + # Check for admin privileges + $Script:IsAdmin = Test-Administrator + if (-not $Script:IsAdmin) { + Write-Host "Warning: Not running as administrator. Some operations may fail." -ForegroundColor $Colors.Yellow + if (-not $NoPrompt) { + $continue = Read-Host "Continue anyway? (y/n)" + if ($continue -notin @('y', 'yes', 'Y', 'Yes')) { + exit 1 + } + } + } + + return $true +} + +# Find all Neovim installations +function Find-AllNeovimInstallations { + $installations = @() + + # Check common installation paths + $commonPaths = @( + "$env:LOCALAPPDATA\nvim", + "$env:ProgramFiles\Neovim", + "$env:ProgramFiles(x86)\Neovim", + "$env:APPDATA\nvim", + "$env:USERPROFILE\nvim", + "C:\tools\neovim", + "C:\neovim" + ) + + foreach ($path in $commonPaths) { + # Check for nvim.exe in bin subdirectory + if (Test-Path "$path\bin\nvim.exe") { + $installations += @{ + Path = $path + BinPath = "$path\bin" + Type = "Portable" + Version = Get-NeovimVersion -Path "$path\bin\nvim.exe" + } + } + # Check for nvim.exe directly in path + elseif (Test-Path "$path\nvim.exe") { + $installations += @{ + Path = $path + BinPath = $path + Type = "Portable" + Version = Get-NeovimVersion -Path "$path\nvim.exe" + } + } + # Check for nvim-win64 subdirectory (common structure) + elseif (Test-Path "$path\nvim-win64\bin\nvim.exe") { + $installations += @{ + Path = "$path\nvim-win64" + BinPath = "$path\nvim-win64\bin" + Type = "Portable" + Version = Get-NeovimVersion -Path "$path\nvim-win64\bin\nvim.exe" + } + } + } + + # Check for MSI installations in registry + try { + $uninstallKeys = @( + "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", + "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" + ) + + foreach ($keyPath in $uninstallKeys) { + Get-ItemProperty $keyPath -ErrorAction SilentlyContinue | Where-Object { + $_.DisplayName -like "*Neovim*" -or $_.DisplayName -like "*nvim*" + } | ForEach-Object { + $installations += @{ + Path = $_.InstallLocation + BinPath = "$($_.InstallLocation)\bin" + Type = "MSI" + Version = $_.DisplayVersion + UninstallString = $_.UninstallString + ProductCode = $_.PSChildName + } + } + } + } + catch { + Write-InfoMessage "Could not check registry for MSI installations" + } + + # Check PATH for nvim.exe - this is crucial for detecting installations + $pathDirs = $env:PATH -split ';' | Where-Object { $_ -ne "" } + foreach ($dir in $pathDirs) { + $dir = $dir.Trim() + if (Test-Path "$dir\nvim.exe") { + # Determine the installation root + $installRoot = $dir + if ($dir -like "*\bin") { + $installRoot = Split-Path -Parent $dir + } + + # Check if we already found this installation + $alreadyFound = $false + foreach ($existing in $installations) { + if ($existing.Path -eq $installRoot -or $existing.BinPath -eq $dir) { + $alreadyFound = $true + break + } + } + + if (-not $alreadyFound) { + $installations += @{ + Path = $installRoot + BinPath = $dir + Type = "PATH" + Version = Get-NeovimVersion -Path "$dir\nvim.exe" + } + } + } + } + + return $installations +} + +# Get Neovim version from executable +function Get-NeovimVersion { + param([string]$Path) + + try { + $versionOutput = & $Path --version 2>$null | Select-String "NVIM v(\d+\.\d+\.\d+)" | ForEach-Object { $_.Matches[0].Groups[1].Value } + return $versionOutput + } + catch { + return "Unknown" + } +} + +# Complete uninstall of all Neovim instances +function Uninstall-AllNeovim { + param([switch]$Silent) + + Write-InfoMessage "Searching for all Neovim installations..." + $installations = Find-AllNeovimInstallations + + if ($installations.Count -eq 0) { + Write-InfoMessage "No Neovim installations found." + return $true + } + + if (-not $Silent) { + Write-Host "Found $($installations.Count) Neovim installation(s):" -ForegroundColor $Colors.Yellow + for ($i = 0; $i -lt $installations.Count; $i++) { + Write-Host " $($i + 1). $($installations[$i].Type) - $($installations[$i].Path) (v$($installations[$i].Version))" + } + + if (-not $NoPrompt) { + $confirm = Read-Host "Remove all installations? (y/n)" + if ($confirm -notin @('y', 'yes', 'Y', 'Yes')) { + Write-InfoMessage "Uninstall cancelled." + return $false + } + } + } + + $success = $true + foreach ($installation in $installations) { + Write-InfoMessage "Removing $($installation.Type) installation: $($installation.Path)" + + try { + if ($installation.Type -eq "MSI") { + # Uninstall MSI package + if ($installation.UninstallString) { + if ($installation.UninstallString -like "*msiexec*") { + # Extract the product code from the uninstall string + $productCode = $installation.ProductCode + if ($productCode -and $productCode -match "^\{.*\}$") { + $uninstallArgs = "/x `"$productCode`" /quiet /norestart" + Write-InfoMessage "Uninstalling MSI with product code: $productCode" + Start-Process -FilePath "msiexec.exe" -ArgumentList $uninstallArgs -Wait -NoNewWindow + } else { + # Fallback to parsing the uninstall string + $uninstallArgs = $installation.UninstallString -replace "MsiExec.exe", "" -replace "/I\{", "/x{" + $uninstallArgs += " /quiet /norestart" + Write-InfoMessage "Uninstalling MSI with args: $uninstallArgs" + Start-Process -FilePath "msiexec.exe" -ArgumentList $uninstallArgs -Wait -NoNewWindow + } + } else { + # Direct uninstall command + Write-InfoMessage "Running uninstall command: $($installation.UninstallString)" + Invoke-Expression $installation.UninstallString + } + + if ($LASTEXITCODE -eq 0 -or $LASTEXITCODE -eq $null) { + Write-SuccessMessage "Successfully uninstalled MSI package" + } else { + Write-ErrorMessage "MSI uninstall failed with exit code: $LASTEXITCODE" + $success = $false + } + } else { + Write-ErrorMessage "No uninstall string found for MSI package" + $success = $false + } + } else { + # Remove portable installation + if (Test-Path $installation.Path) { + Write-InfoMessage "Removing directory: $($installation.Path)" + # Force kill any processes that might be using files in the directory + Get-Process -Name "nvim*" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue + + # Try to remove the directory + Remove-Item -Path $installation.Path -Recurse -Force -ErrorAction Stop + Write-SuccessMessage "Successfully removed directory: $($installation.Path)" + } else { + Write-InfoMessage "Directory already removed: $($installation.Path)" + } + } + } + catch { + Write-ErrorMessage "Failed to remove $($installation.Path): $_" + # Try alternative removal methods + try { + Write-InfoMessage "Attempting alternative removal method..." + if (Test-Path $installation.Path) { + # Use robocopy to move and delete (works around file locks) + $tempDir = "$env:TEMP\nvim_removal_$(Get-Random)" + robocopy "$($installation.Path)" "$tempDir" /E /MOVE /NFL /NDL /NJH /NJS /NC /NS /NP + Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue + Write-SuccessMessage "Successfully removed using alternative method: $($installation.Path)" + } + } + catch { + Write-ErrorMessage "Alternative removal also failed: $_" + $success = $false + } + } + } + + # Clean up PATH environment variable + Write-InfoMessage "Cleaning up PATH environment variable..." + + # Get both user and system PATH + $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") + $systemPath = "" + + if ($Script:IsAdmin) { + try { + $systemPath = [Environment]::GetEnvironmentVariable("PATH", "Machine") + } + catch { + Write-InfoMessage "Could not access system PATH" + } + } + + # Create patterns for all found installations + $nvimPathPatterns = @() + foreach ($installation in $installations) { + $nvimPathPatterns += [regex]::Escape($installation.BinPath) + $nvimPathPatterns += [regex]::Escape($installation.Path) + } + + # Add common patterns + $nvimPathPatterns += @( + [regex]::Escape($Script:NeovimBin), + [regex]::Escape("$env:ProgramFiles\Neovim\bin"), + [regex]::Escape("$env:ProgramFiles(x86)\Neovim\bin"), + [regex]::Escape("C:\tools\neovim\nvim-win64\bin"), + [regex]::Escape("C:\tools\neovim\nvim-win64") + ) + + # Clean user PATH + $originalUserPath = $userPath + foreach ($pattern in $nvimPathPatterns) { + $userPath = $userPath -replace ";$pattern;", ";" + $userPath = $userPath -replace "^$pattern;", "" + $userPath = $userPath -replace ";$pattern$", "" + $userPath = $userPath -replace "^$pattern$", "" + } + + if ($userPath -ne $originalUserPath) { + try { + [Environment]::SetEnvironmentVariable("PATH", $userPath, "User") + Write-InfoMessage "Cleaned up user PATH" + } + catch { + Write-ErrorMessage "Failed to clean up user PATH: $_" + } + } + + # Clean system PATH if running as admin + if ($Script:IsAdmin -and $systemPath) { + $originalSystemPath = $systemPath + foreach ($pattern in $nvimPathPatterns) { + $systemPath = $systemPath -replace ";$pattern;", ";" + $systemPath = $systemPath -replace "^$pattern;", "" + $systemPath = $systemPath -replace ";$pattern$", "" + $systemPath = $systemPath -replace "^$pattern$", "" + } + + if ($systemPath -ne $originalSystemPath) { + try { + [Environment]::SetEnvironmentVariable("PATH", $systemPath, "Machine") + Write-InfoMessage "Cleaned up system PATH" + } + catch { + Write-ErrorMessage "Failed to clean up system PATH: $_" + } + } + } + + if ($success) { + Write-SuccessMessage "All Neovim installations have been removed successfully!" + } else { + Write-Host "Some installations could not be removed completely." -ForegroundColor $Colors.Yellow + } + + Write-InfoMessage "You may need to restart your shell for PATH changes to take effect." + return $success +} + +# Check if Neovim is already installed +function Test-NeovimInstalled { + if (Test-Path $Script:NeovimExe) { + return $true + } + + # Check if nvim is in PATH + if (Get-Command nvim -ErrorAction SilentlyContinue) { + return $true + } + + return $false +} + +# Download a file - FIXED VERSION +function Get-FileDownload { + param( + [string]$Url, + [string]$OutputPath + ) + + Write-InfoMessage "Downloading from: $Url" + Write-InfoMessage "Saving to: $OutputPath" + + try { + switch ($Script:DownloadCommand) { + "curl" { + # Use Start-Process instead of cmd /c for better compatibility + $curlArgs = @("-L", "--progress-bar", "-o", $OutputPath, $Url) + $process = Start-Process -FilePath "curl" -ArgumentList $curlArgs -Wait -NoNewWindow -PassThru + if ($process.ExitCode -ne 0) { + throw "Curl download failed with exit code: $($process.ExitCode)" + } + } + "wget" { + # Use Start-Process instead of cmd /c for better compatibility + $wgetArgs = @("--progress=bar", "--show-progress", "-O", $OutputPath, $Url) + $process = Start-Process -FilePath "wget" -ArgumentList $wgetArgs -Wait -NoNewWindow -PassThru + if ($process.ExitCode -ne 0) { + throw "Wget download failed with exit code: $($process.ExitCode)" + } + } + "powershell" { + # Enhanced PowerShell download with progress + Write-InfoMessage "Using PowerShell's Invoke-WebRequest..." + $ProgressPreference = 'Continue' + + # Create a WebClient for better progress reporting + $webClient = New-Object System.Net.WebClient + $webClient.Headers.Add("User-Agent", "PowerShell Neovim Installer") + + # Register progress event + Register-ObjectEvent -InputObject $webClient -EventName DownloadProgressChanged -Action { + $Global:DownloadProgress = $Event.SourceEventArgs.ProgressPercentage + Write-Progress -Activity "Downloading Neovim" -Status "Progress: $($Event.SourceEventArgs.ProgressPercentage)%" -PercentComplete $Event.SourceEventArgs.ProgressPercentage + } | Out-Null + + # Download the file + try { + $webClient.DownloadFile($Url, $OutputPath) + Write-Progress -Activity "Downloading Neovim" -Completed + } + finally { + $webClient.Dispose() + # Clean up event handlers + Get-EventSubscriber | Where-Object { $_.SourceObject -eq $webClient } | Unregister-Event + } + } + } + + # Verify the file was downloaded + if (-not (Test-Path $OutputPath)) { + throw "Downloaded file not found at: $OutputPath" + } + + $fileSize = (Get-Item $OutputPath).Length + if ($fileSize -eq 0) { + throw "Downloaded file is empty" + } + + Write-InfoMessage "Download completed successfully. File size: $($fileSize / 1MB) MB" + return $true + } + catch { + Write-ErrorMessage "Download failed: $_" + # Clean up partial download + if (Test-Path $OutputPath) { + Remove-Item -Path $OutputPath -Force -ErrorAction SilentlyContinue + } + return $false + } +} + +# Get available versions from GitHub API +function Get-AvailableVersions { + try { + $apiUrl = "https://api.github.com/repos/neovim/neovim/releases" + $response = Invoke-RestMethod -Uri $apiUrl -UseBasicParsing + return $response | ForEach-Object { $_.tag_name } + } + catch { + Write-ErrorMessage "Failed to fetch available versions: $_" + return @() + } +} + +# Check if a specific version exists +function Test-VersionExists { + param([string]$Version) + + if ($Version -notmatch "^v") { + $Version = "v$Version" + } + + $versions = Get-AvailableVersions + return $versions -contains $Version +} + +# Get the latest stable version +function Get-LatestStableVersion { + try { + $apiUrl = "https://api.github.com/repos/neovim/neovim/releases/latest" + $response = Invoke-RestMethod -Uri $apiUrl -UseBasicParsing + return $response.tag_name + } + catch { + Write-ErrorMessage "Failed to fetch latest version: $_" + return $null + } +} + +# Download specific version +function Get-SpecificVersion { + param([string]$Version) + + if ($Version -notmatch "^v") { + $Version = "v$Version" + } + + try { + $apiUrl = "https://api.github.com/repos/neovim/neovim/releases/tags/$Version" + $response = Invoke-RestMethod -Uri $apiUrl -UseBasicParsing + + # Look for Windows assets + $asset = $response.assets | Where-Object { + $_.name -match "nvim-win64\.zip$" -or + $_.name -match "nvim-win64\.msi$" -or + $_.name -match "nvim-windows\.zip$" + } | Select-Object -First 1 + + if (-not $asset) { + Write-ErrorMessage "No Windows asset found for version ${Version}" + return $null + } + + $fileName = $asset.name + $downloadUrl = $asset.browser_download_url + + Write-InfoMessage "Found asset: $fileName" + + if (Get-FileDownload -Url $downloadUrl -OutputPath $fileName) { + return $fileName + } + } + catch { + Write-ErrorMessage "Failed to download version ${Version}: $_" + } + + return $null +} + +# Install Neovim from downloaded file +function Install-NeovimFromFile { + param( + [string]$FilePath, + [string]$Version = "Unknown", + [switch]$CleanInstall + ) + + try { + if ($CleanInstall) { + Write-InfoMessage "Performing clean installation - removing existing installations..." + Uninstall-AllNeovim -Silent + } + + Write-InfoMessage "Installing Neovim ${Version}..." + + $fileExtension = [System.IO.Path]::GetExtension($FilePath).ToLower() + + if ($fileExtension -eq ".msi") { + # Handle MSI installation + Write-InfoMessage "Installing from MSI package..." + $installArgs = @( + "/i", "`"$FilePath`"" + "/quiet" + "/norestart" + ) + + Start-Process -FilePath "msiexec.exe" -ArgumentList $installArgs -Wait -NoNewWindow + + if ($LASTEXITCODE -eq 0) { + Write-SuccessMessage "Neovim ${Version} installed successfully via MSI!" + + # MSI typically installs to Program Files, add to PATH if needed + $programFiles = "${env:ProgramFiles}\Neovim\bin" + $programFilesX86 = "${env:ProgramFiles(x86)}\Neovim\bin" + + $nvimPath = "" + if (Test-Path "$programFiles\nvim.exe") { + $nvimPath = $programFiles + } elseif (Test-Path "$programFilesX86\nvim.exe") { + $nvimPath = $programFilesX86 + } + + if ($nvimPath) { + $currentPath = [Environment]::GetEnvironmentVariable("PATH", "User") + if ($currentPath -notlike "*$nvimPath*") { + [Environment]::SetEnvironmentVariable("PATH", "$currentPath;$nvimPath", "User") + Write-InfoMessage "Added Neovim to PATH: $nvimPath" + } + } + } else { + Write-ErrorMessage "MSI installation failed with exit code: $LASTEXITCODE" + return $false + } + } + elseif ($fileExtension -eq ".zip") { + # Handle ZIP installation + Write-InfoMessage "Installing from ZIP archive..." + + # Create installation directory + if (Test-Path $Script:NeovimPath) { + Remove-Item -Path $Script:NeovimPath -Recurse -Force + } + New-Item -Path $Script:NeovimPath -ItemType Directory -Force | Out-Null + + # Extract zip file + Write-InfoMessage "Extracting archive..." + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($FilePath, $Script:NeovimPath) + + # Find the nvim.exe in the extracted files + $nvimExe = Get-ChildItem -Path $Script:NeovimPath -Name "nvim.exe" -Recurse | Select-Object -First 1 + if (-not $nvimExe) { + Write-ErrorMessage "Could not find nvim.exe in extracted files" + return $false + } + + $nvimDir = Split-Path -Path (Get-ChildItem -Path $Script:NeovimPath -Name "nvim.exe" -Recurse | Select-Object -First 1).FullName + + # Move files to proper location if needed + if ($nvimDir -ne $Script:NeovimBin) { + if (Test-Path $Script:NeovimBin) { + Remove-Item -Path $Script:NeovimBin -Recurse -Force + } + Move-Item -Path $nvimDir -Destination $Script:NeovimBin -Force + } + + # Add to PATH if not already there + $currentPath = [Environment]::GetEnvironmentVariable("PATH", "User") + if ($currentPath -notlike "*$Script:NeovimBin*") { + [Environment]::SetEnvironmentVariable("PATH", "$currentPath;$Script:NeovimBin", "User") + Write-InfoMessage "Added Neovim to PATH" + } + + Write-SuccessMessage "Neovim ${Version} installed successfully!" + Write-InfoMessage "Location: $Script:NeovimBin" + } + else { + Write-ErrorMessage "Unsupported file type: $fileExtension" + return $false + } + + # Clean up downloaded file + Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue + + Write-InfoMessage "You may need to restart your shell for PATH changes to take effect." + return $true + } + catch { + Write-ErrorMessage "Installation failed: $_" + return $false + } +} + +# Install nightly version +function Install-NightlyVersion { + param([switch]$CleanInstall) + + Write-InfoMessage "Installing Neovim Nightly..." + $url = "https://github.com/neovim/neovim/releases/download/nightly/nvim-win64.zip" + $fileName = "nvim-nightly.zip" + + if (Get-FileDownload -Url $url -OutputPath $fileName) { + return Install-NeovimFromFile -FilePath $fileName -Version "Nightly" -CleanInstall:$CleanInstall + } + return $false +} + +# Install stable version +function Install-StableVersion { + param([switch]$CleanInstall) + + Write-InfoMessage "Installing Neovim Stable..." + $latestVersion = Get-LatestStableVersion + if (-not $latestVersion) { + Write-ErrorMessage "Could not determine latest stable version" + return $false + } + + $fileName = Get-SpecificVersion -Version $latestVersion + if ($fileName) { + return Install-NeovimFromFile -FilePath $fileName -Version "Stable ($latestVersion)" -CleanInstall:$CleanInstall + } + return $false +} + +# Install specific version +function Install-SpecificVersionWrapper { + param( + [string]$Version, + [switch]$CleanInstall + ) + + Write-InfoMessage "Installing Neovim ${Version}..." + + if (-not (Test-VersionExists -Version $Version)) { + Write-ErrorMessage "Version ${Version} does not exist" + return $false + } + + $fileName = Get-SpecificVersion -Version $Version + if ($fileName) { + return Install-NeovimFromFile -FilePath $fileName -Version $Version -CleanInstall:$CleanInstall + } + return $false +} + +# Update/Install version menu +function Show-UpdateMenu { + # Check if there are existing installations + $installations = Find-AllNeovimInstallations + $hasExistingInstalls = $installations.Count -gt 0 + + if ($hasExistingInstalls) { + Write-Host "Existing Neovim installations found:" -ForegroundColor $Colors.Yellow + for ($i = 0; $i -lt $installations.Count; $i++) { + Write-Host " - $($installations[$i].Type) - $($installations[$i].Path) (v$($installations[$i].Version))" + } + Write-Host "" + + if (-not $NoPrompt) { + $cleanInstall = Read-Host "Perform clean installation (remove existing installations)? (y/n)" + $shouldClean = $cleanInstall -in @('y', 'yes', 'Y', 'Yes') + } else { + $shouldClean = $true + } + } else { + $shouldClean = $false + } + + $validChoice = $false + while (-not $validChoice) { + Write-Host "" + Write-Host "Select version to install/update to:" + Write-Host " 1. Nightly" + Write-Host " 2. Stable" + Write-Host " 3. Choose specific version by tag" + + $choice = Read-Host "Enter the number corresponding to your choice (1/2/3)" + + switch ($choice) { + "1" { + $result = Install-NightlyVersion -CleanInstall:$shouldClean + $validChoice = $true + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH","User") + } + "2" { + $result = Install-StableVersion -CleanInstall:$shouldClean + $validChoice = $true + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH","User") + } + "3" { + $version = Read-Host "Enter the specific version (e.g., v0.9.0)" + $result = Install-SpecificVersionWrapper -Version $version -CleanInstall:$shouldClean + $validChoice = $true + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH","User") + } + default { + Write-ErrorMessage "Invalid choice. Please enter 1, 2, or 3." + } + } + } + + return $result +} + +# Uninstall Neovim (wrapper for backward compatibility) +function Uninstall-Neovim { + return Uninstall-AllNeovim +} + +# Check if Neovim is running +function Test-NeovimRunning { + $nvimProcesses = Get-Process -Name "nvim" -ErrorAction SilentlyContinue + if ($nvimProcesses) { + Write-Host "Error: Neovim is currently running. Please close Neovim before proceeding." -ForegroundColor $Colors.Red + + if (-not $NoPrompt) { + $choice = Read-Host "Do you want to forcefully terminate Neovim and continue? (y/n)" + if ($choice -in @('y', 'yes', 'Y', 'Yes')) { + $nvimProcesses | Stop-Process -Force + Write-InfoMessage "Neovim processes terminated" + } else { + Write-InfoMessage "Exiting..." + exit 1 + } + } else { + $nvimProcesses | Stop-Process -Force + Write-InfoMessage "Neovim processes terminated" + } + } +} + +# Check for updates +function Test-Updates { + Write-InfoMessage "Checking for updates..." + + try { + $latestVersion = Get-LatestStableVersion + if (-not $latestVersion) { + Write-ErrorMessage "Could not fetch latest version information" + return + } + + Write-InfoMessage "Latest stable version: $latestVersion" + + $installations = Find-AllNeovimInstallations + if ($hasExistingInstalls) { + Write-InfoMessage "Found $($installations.Count) installation(s):" + foreach ($installation in $installations) { + Write-InfoMessage " - $($installation.Type): v$($installation.Version) at $($installation.Path)" + if ($installation.Version -ne "Unknown" -and "v$($installation.Version)" -ne $latestVersion) { + Write-SuccessMessage " Update available: v$($installation.Version) → $latestVersion" + } elseif ("v$($installation.Version)" -eq $latestVersion) { + Write-InfoMessage " Up to date" + } + } + } else { + Write-InfoMessage "Neovim is not installed" + } + } + catch { + Write-ErrorMessage "Failed to check for updates: $_" + } +} + +# Main function +function Main { + Write-Host "Neovim Installation Script for Windows" -ForegroundColor $Colors.Cyan + Write-Host "=======================================" -ForegroundColor $Colors.Cyan + + # Check dependencies + if (-not (Test-Dependencies)) { + exit 1 + } + + # Check if Neovim is running + Test-NeovimRunning + + # Check if Neovim is installed + $installations = Find-AllNeovimInstallations + if ($installations.Count -gt 0) { + Write-SuccessMessage "Found $($installations.Count) Neovim installation(s):" + foreach ($installation in $installations) { + Write-InfoMessage " - $($installation.Type): v$($installation.Version) at $($installation.Path)" + } + } else { + Write-Host "Neovim is not installed." -ForegroundColor $Colors.Red + if (-not $NoPrompt) { + $choice = Read-Host "Install Neovim? (y/n)" + if ($choice -in @('y', 'yes', 'Y', 'Yes')) { + Show-UpdateMenu + return + } else { + Write-InfoMessage "Exiting..." + return + } + } + } + + # Main menu loop + while ($Script:ShowPrompt) { + Write-Host "" + Write-Host "Select an option:" + Write-Host " 1. Install/update Neovim" + Write-Host " 2. Check for updates" + Write-Host " 3. Uninstall all Neovim installations" + Write-Host " 4. Run Neovim" + Write-Host " 5. Quit" + + $choice = Read-Host "Enter a number or press 'q' to quit" + + switch ($choice) { + "1" { + Show-UpdateMenu + } + "2" { + Test-Updates + } + "3" { + Uninstall-AllNeovim + } + "4" { + if ($installations.Count -gt 0 -or (Get-Command nvim -ErrorAction SilentlyContinue)) { + Write-InfoMessage "Starting Neovim..." + & nvim + } else { + Write-ErrorMessage "Neovim is not installed" + } + } + { $_ -in @("5", "q", "Q", "quit", "exit") } { + Write-InfoMessage "Exiting..." + $Script:ShowPrompt = $false + } + default { + Write-ErrorMessage "Invalid choice. Please choose a valid option by entering the corresponding number or press 'q' to quit." + } + } + } +} + +# Run the main function +Main |
