aboutsummaryrefslogtreecommitdiff
path: root/neovim.ps1
diff options
context:
space:
mode:
Diffstat (limited to 'neovim.ps1')
-rwxr-xr-xneovim.ps1917
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