aboutsummaryrefslogtreecommitdiff
path: root/bootstrap-win
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2026-08-12 11:38:42 +0200
committerThomas Schmucker <ts@its1.de>2026-08-12 11:38:42 +0200
commitbdc80dabce5e46945ca34ccf74861371485ac2f2 (patch)
treec73ab4900ce8360ab230c7d46e114486bdea0d6a /bootstrap-win
parent189d244d36d4ebb2189b698adb21f51cf1c4176a (diff)
downloaddotfiles-bdc80dabce5e46945ca34ccf74861371485ac2f2.tar.gz
dotfiles-bdc80dabce5e46945ca34ccf74861371485ac2f2.tar.bz2
dotfiles-bdc80dabce5e46945ca34ccf74861371485ac2f2.zip
Normalize line endings
Diffstat (limited to 'bootstrap-win')
-rw-r--r--bootstrap-win/neovim.ps1448
1 files changed, 224 insertions, 224 deletions
diff --git a/bootstrap-win/neovim.ps1 b/bootstrap-win/neovim.ps1
index 7779107..c12ed6b 100644
--- a/bootstrap-win/neovim.ps1
+++ b/bootstrap-win/neovim.ps1
@@ -1,224 +1,224 @@
1#Requires -Version 5.1 1#Requires -Version 5.1
2<# 2<#
3 Windows-natives Pendant zu bootstrap/neovim.sh - nutzt winget/npm statt 3 Windows-natives Pendant zu bootstrap/neovim.sh - nutzt winget/npm statt
4 brew/pkg, daher eigenstaendiges Skript ohne Git-Bash-/WSL-Abhaengigkeit. 4 brew/pkg, daher eigenstaendiges Skript ohne Git-Bash-/WSL-Abhaengigkeit.
5 5
6 Aufruf (keine Admin-Rechte noetig): 6 Aufruf (keine Admin-Rechte noetig):
7 .\bootstrap-win\neovim.ps1 7 .\bootstrap-win\neovim.ps1
8 8
9 yamlfmt, gawk und xmllint sind bewusst nicht enthalten (siehe 9 yamlfmt, gawk und xmllint sind bewusst nicht enthalten (siehe
10 neovim-windows-setup.md). Fehlgeschlagene Installationen werden als 10 neovim-windows-setup.md). Fehlgeschlagene Installationen werden als
11 Warnung gemeldet, das Skript bricht nicht ab. 11 Warnung gemeldet, das Skript bricht nicht ab.
12#> 12#>
13 13
14$ErrorActionPreference = "Stop" 14$ErrorActionPreference = "Stop"
15$script:Failures = @() 15$script:Failures = @()
16 16
17function Write-Ok($msg) { 17function Write-Ok($msg) {
18 Write-Host "OK $msg" -ForegroundColor Green 18 Write-Host "OK $msg" -ForegroundColor Green
19} 19}
20 20
21function Write-Step($msg) { 21function Write-Step($msg) {
22 Write-Host "==> $msg" -ForegroundColor Cyan 22 Write-Host "==> $msg" -ForegroundColor Cyan
23} 23}
24 24
25function Write-Skip($msg) { 25function Write-Skip($msg) {
26 Write-Host "- $msg bereits vorhanden" -ForegroundColor DarkGray 26 Write-Host "- $msg bereits vorhanden" -ForegroundColor DarkGray
27} 27}
28 28
29function Write-Warn($msg) { 29function Write-Warn($msg) {
30 Write-Host "! $msg" -ForegroundColor Yellow 30 Write-Host "! $msg" -ForegroundColor Yellow
31 $script:Failures += $msg 31 $script:Failures += $msg
32} 32}
33 33
34function Test-CommandExists([string]$Name) { 34function Test-CommandExists([string]$Name) {
35 return [bool](Get-Command $Name -ErrorAction SilentlyContinue) 35 return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
36} 36}
37 37
38function Find-BinaryDirectory([string]$Binary) { 38function Find-BinaryDirectory([string]$Binary) {
39 # Deckt den Fall ab, dass winget (v.a. --silent) korrekt installiert, 39 # Deckt den Fall ab, dass winget (v.a. --silent) korrekt installiert,
40 # aber die PATH-Registrierung ausgelassen hat (beobachtet bei LLVM.LLVM). 40 # aber die PATH-Registrierung ausgelassen hat (beobachtet bei LLVM.LLVM).
41 $searchRoots = @( 41 $searchRoots = @(
42 $env:ProgramFiles, 42 $env:ProgramFiles,
43 ${env:ProgramFiles(x86)}, 43 ${env:ProgramFiles(x86)},
44 (Join-Path $env:LOCALAPPDATA "Programs") 44 (Join-Path $env:LOCALAPPDATA "Programs")
45 ) | Where-Object { $_ -and (Test-Path $_) } 45 ) | Where-Object { $_ -and (Test-Path $_) }
46 46
47 foreach ($root in $searchRoots) { 47 foreach ($root in $searchRoots) {
48 $found = Get-ChildItem -Path $root -Recurse -Depth 4 -Filter "$Binary.exe" -File -ErrorAction SilentlyContinue | Select-Object -First 1 48 $found = Get-ChildItem -Path $root -Recurse -Depth 4 -Filter "$Binary.exe" -File -ErrorAction SilentlyContinue | Select-Object -First 1
49 if ($found) { 49 if ($found) {
50 return $found.DirectoryName 50 return $found.DirectoryName
51 } 51 }
52 } 52 }
53 53
54 return $null 54 return $null
55} 55}
56 56
57function Add-ToUserPath([string]$Dir) { 57function Add-ToUserPath([string]$Dir) {
58 $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") 58 $userPath = [Environment]::GetEnvironmentVariable("PATH", "User")
59 $entries = $userPath -split ";" 59 $entries = $userPath -split ";"
60 60
61 if ($entries -contains $Dir) { 61 if ($entries -contains $Dir) {
62 return $false 62 return $false
63 } 63 }
64 64
65 [Environment]::SetEnvironmentVariable("PATH", "$userPath;$Dir", "User") 65 [Environment]::SetEnvironmentVariable("PATH", "$userPath;$Dir", "User")
66 $env:PATH = "$env:PATH;$Dir" 66 $env:PATH = "$env:PATH;$Dir"
67 return $true 67 return $true
68} 68}
69 69
70function Install-WingetPackage([string]$Binary, [string]$Id) { 70function Install-WingetPackage([string]$Binary, [string]$Id) {
71 if (Test-CommandExists $Binary) { 71 if (Test-CommandExists $Binary) {
72 Write-Skip $Binary 72 Write-Skip $Binary
73 return 73 return
74 } 74 }
75 75
76 Write-Step "winget install $Id" 76 Write-Step "winget install $Id"
77 $output = winget install --id $Id -e --source winget --accept-package-agreements --accept-source-agreements --silent 2>&1 77 $output = winget install --id $Id -e --source winget --accept-package-agreements --accept-source-agreements --silent 2>&1
78 78
79 if ($LASTEXITCODE -ne 0) { 79 if ($LASTEXITCODE -ne 0) {
80 $text = $output -join " " 80 $text = $output -join " "
81 $lastLine = ($output | Select-Object -Last 3) -join " / " 81 $lastLine = ($output | Select-Object -Last 3) -join " / "
82 82
83 if ($text -match "bereits ein vorhandenes Paket|already installed|No applicable update") { 83 if ($text -match "bereits ein vorhandenes Paket|already installed|No applicable update") {
84 # Installiert, aber nicht im PATH - Binary suchen und PATH ergaenzen. 84 # Installiert, aber nicht im PATH - Binary suchen und PATH ergaenzen.
85 $dir = Find-BinaryDirectory $Binary 85 $dir = Find-BinaryDirectory $Binary
86 86
87 if ($dir) { 87 if ($dir) {
88 Add-ToUserPath $dir | Out-Null 88 Add-ToUserPath $dir | Out-Null
89 if (Test-CommandExists $Binary) { 89 if (Test-CommandExists $Binary) {
90 Write-Ok "$Id ('$Binary' in $dir gefunden, User-PATH ergaenzt)" 90 Write-Ok "$Id ('$Binary' in $dir gefunden, User-PATH ergaenzt)"
91 } else { 91 } else {
92 Write-Warn "${Id}: $dir zum User-PATH hinzugefuegt, aber '$Binary' laesst sich immer noch nicht ausfuehren - manuell pruefen." 92 Write-Warn "${Id}: $dir zum User-PATH hinzugefuegt, aber '$Binary' laesst sich immer noch nicht ausfuehren - manuell pruefen."
93 } 93 }
94 } else { 94 } else {
95 Write-Warn "$Id ist laut winget bereits installiert, aber '$Binary' wurde nicht gefunden und konnte auch nicht automatisch lokalisiert werden (durchsucht: Program Files, Program Files (x86), $env:LOCALAPPDATA\Programs). Installationsordner manuell suchen und zum PATH hinzufuegen." 95 Write-Warn "$Id ist laut winget bereits installiert, aber '$Binary' wurde nicht gefunden und konnte auch nicht automatisch lokalisiert werden (durchsucht: Program Files, Program Files (x86), $env:LOCALAPPDATA\Programs). Installationsordner manuell suchen und zum PATH hinzufuegen."
96 } 96 }
97 } else { 97 } else {
98 Write-Warn "winget install $Id fehlgeschlagen (Binary '$Binary' nicht gefunden): $lastLine -- Pruefen mit: winget search $Id" 98 Write-Warn "winget install $Id fehlgeschlagen (Binary '$Binary' nicht gefunden): $lastLine -- Pruefen mit: winget search $Id"
99 } 99 }
100 return 100 return
101 } 101 }
102 102
103 Write-Ok $Id 103 Write-Ok $Id
104} 104}
105 105
106function Test-BinaryRuns([string]$Binary, [string[]]$VerifyArgs) { 106function Test-BinaryRuns([string]$Binary, [string[]]$VerifyArgs) {
107 # Einige npm-Pakete (z.B. tree-sitter-cli) installieren nur einen JS-Shim 107 # Einige npm-Pakete (z.B. tree-sitter-cli) installieren nur einen JS-Shim
108 # und laden die eigentliche native Binary per Post-Install-Skript separat 108 # und laden die eigentliche native Binary per Post-Install-Skript separat
109 # von GitHub herunter. Schlaegt dieser Download fehl (Proxy, npm 109 # von GitHub herunter. Schlaegt dieser Download fehl (Proxy, npm
110 # allow-scripts-Policy, Antivirus-Quarantaene), landet der Shim trotzdem 110 # allow-scripts-Policy, Antivirus-Quarantaene), landet der Shim trotzdem
111 # im PATH und Test-CommandExists meldet faelschlich Erfolg. Deshalb hier 111 # im PATH und Test-CommandExists meldet faelschlich Erfolg. Deshalb hier
112 # tatsaechlich ausfuehren statt nur pruefen, ob der Befehlsname 112 # tatsaechlich ausfuehren statt nur pruefen, ob der Befehlsname
113 # aufloesbar ist. 113 # aufloesbar ist.
114 try { 114 try {
115 & $Binary @VerifyArgs *> $null 115 & $Binary @VerifyArgs *> $null
116 return $LASTEXITCODE -eq 0 116 return $LASTEXITCODE -eq 0
117 } catch { 117 } catch {
118 return $false 118 return $false
119 } 119 }
120} 120}
121 121
122function Install-NpmPackage([string]$Binary, [string]$Package, [string[]]$VerifyArgs = $null) { 122function Install-NpmPackage([string]$Binary, [string]$Package, [string[]]$VerifyArgs = $null) {
123 if (Test-CommandExists $Binary) { 123 if (Test-CommandExists $Binary) {
124 if ($VerifyArgs -and -not (Test-BinaryRuns $Binary $VerifyArgs)) { 124 if ($VerifyArgs -and -not (Test-BinaryRuns $Binary $VerifyArgs)) {
125 Write-Warn "'$Binary' ist im PATH, laesst sich aber nicht ausfuehren - vermutlich hat der Post-Install-Download von '$Package' nicht geklappt (Proxy/npm allow-scripts-Policy pruefen: 'npm config get allow-scripts'). 'npm uninstall -g $Package' und neu installieren." 125 Write-Warn "'$Binary' ist im PATH, laesst sich aber nicht ausfuehren - vermutlich hat der Post-Install-Download von '$Package' nicht geklappt (Proxy/npm allow-scripts-Policy pruefen: 'npm config get allow-scripts'). 'npm uninstall -g $Package' und neu installieren."
126 } else { 126 } else {
127 Write-Skip $Binary 127 Write-Skip $Binary
128 } 128 }
129 return 129 return
130 } 130 }
131 131
132 if (-not (Test-CommandExists "npm")) { 132 if (-not (Test-CommandExists "npm")) {
133 Write-Warn "npm wurde nicht gefunden - kann '$Package' nicht installieren." 133 Write-Warn "npm wurde nicht gefunden - kann '$Package' nicht installieren."
134 return 134 return
135 } 135 }
136 136
137 Write-Step "npm install -g $Package" 137 Write-Step "npm install -g $Package"
138 npm install -g $Package | Out-Null 138 npm install -g $Package | Out-Null
139 139
140 if ($LASTEXITCODE -ne 0) { 140 if ($LASTEXITCODE -ne 0) {
141 Write-Warn "npm install -g $Package fehlgeschlagen." 141 Write-Warn "npm install -g $Package fehlgeschlagen."
142 return 142 return
143 } 143 }
144 144
145 if ($VerifyArgs -and -not (Test-BinaryRuns $Binary $VerifyArgs)) { 145 if ($VerifyArgs -and -not (Test-BinaryRuns $Binary $VerifyArgs)) {
146 Write-Warn "npm install -g $Package war erfolgreich, aber '$Binary' laesst sich nicht ausfuehren - vermutlich hat der Post-Install-Download der nativen Binary nicht geklappt (Proxy/npm allow-scripts-Policy pruefen: 'npm config get allow-scripts')." 146 Write-Warn "npm install -g $Package war erfolgreich, aber '$Binary' laesst sich nicht ausfuehren - vermutlich hat der Post-Install-Download der nativen Binary nicht geklappt (Proxy/npm allow-scripts-Policy pruefen: 'npm config get allow-scripts')."
147 return 147 return
148 } 148 }
149 149
150 Write-Ok $Package 150 Write-Ok $Package
151} 151}
152 152
153function Test-Prerequisites { 153function Test-Prerequisites {
154 if (-not (Test-CommandExists "winget")) { 154 if (-not (Test-CommandExists "winget")) {
155 Write-Host "Fehler: winget wurde nicht gefunden. 'App Installer' aus dem Microsoft Store installieren." -ForegroundColor Red 155 Write-Host "Fehler: winget wurde nicht gefunden. 'App Installer' aus dem Microsoft Store installieren." -ForegroundColor Red
156 exit 1 156 exit 1
157 } 157 }
158} 158}
159 159
160function Update-SessionPath { 160function Update-SessionPath {
161 # Registry-PATH-Aenderungen durch winget/npm wirken erst nach diesem Refresh. 161 # Registry-PATH-Aenderungen durch winget/npm wirken erst nach diesem Refresh.
162 $machine = [Environment]::GetEnvironmentVariable("PATH", "Machine") 162 $machine = [Environment]::GetEnvironmentVariable("PATH", "Machine")
163 $user = [Environment]::GetEnvironmentVariable("PATH", "User") 163 $user = [Environment]::GetEnvironmentVariable("PATH", "User")
164 $env:PATH = "$machine;$user" 164 $env:PATH = "$machine;$user"
165} 165}
166 166
167function Install-Prerequisites { 167function Install-Prerequisites {
168 Install-WingetPackage -Binary "git" -Id "Git.Git" 168 Install-WingetPackage -Binary "git" -Id "Git.Git"
169 Install-WingetPackage -Binary "node" -Id "OpenJS.NodeJS.LTS" 169 Install-WingetPackage -Binary "node" -Id "OpenJS.NodeJS.LTS"
170 Update-SessionPath 170 Update-SessionPath
171} 171}
172 172
173function Install-Formatters { 173function Install-Formatters {
174 Install-WingetPackage -Binary "jq" -Id "jqlang.jq" 174 Install-WingetPackage -Binary "jq" -Id "jqlang.jq"
175 Install-NpmPackage -Binary "prettier" -Package "prettier" 175 Install-NpmPackage -Binary "prettier" -Package "prettier"
176 Install-WingetPackage -Binary "ruff" -Id "astral-sh.ruff" 176 Install-WingetPackage -Binary "ruff" -Id "astral-sh.ruff"
177 Install-WingetPackage -Binary "shfmt" -Id "mvdan.shfmt" 177 Install-WingetPackage -Binary "shfmt" -Id "mvdan.shfmt"
178 Install-WingetPackage -Binary "stylua" -Id "JohnnyMorganz.StyLua" 178 Install-WingetPackage -Binary "stylua" -Id "JohnnyMorganz.StyLua"
179 179
180 # yamlfmt, gawk, xmllint: kein winget-Paket gefunden, siehe neovim-windows-setup.md. 180 # yamlfmt, gawk, xmllint: kein winget-Paket gefunden, siehe neovim-windows-setup.md.
181} 181}
182 182
183function Install-Tools { 183function Install-Tools {
184 Install-WingetPackage -Binary "rg" -Id "BurntSushi.ripgrep.MSVC" 184 Install-WingetPackage -Binary "rg" -Id "BurntSushi.ripgrep.MSVC"
185 Install-WingetPackage -Binary "fd" -Id "sharkdp.fd" 185 Install-WingetPackage -Binary "fd" -Id "sharkdp.fd"
186 Install-NpmPackage -Binary "tree-sitter" -Package "tree-sitter-cli" -VerifyArgs @("--version") 186 Install-NpmPackage -Binary "tree-sitter" -Package "tree-sitter-cli" -VerifyArgs @("--version")
187 187
188 # MSVC (cl.exe) ist bereits vorhanden, kein winget-Paket noetig - Neovim 188 # MSVC (cl.exe) ist bereits vorhanden, kein winget-Paket noetig - Neovim
189 # dafuer aber aus einer "Developer PowerShell for VS" starten. 189 # dafuer aber aus einer "Developer PowerShell for VS" starten.
190 Install-WingetPackage -Binary "make" -Id "ezwinports.make" 190 Install-WingetPackage -Binary "make" -Id "ezwinports.make"
191} 191}
192 192
193function Install-Lsp { 193function Install-Lsp {
194 Install-NpmPackage -Binary "basedpyright-langserver" -Package "basedpyright" 194 Install-NpmPackage -Binary "basedpyright-langserver" -Package "basedpyright"
195 Install-NpmPackage -Binary "bash-language-server" -Package "bash-language-server" 195 Install-NpmPackage -Binary "bash-language-server" -Package "bash-language-server"
196 Install-WingetPackage -Binary "clangd" -Id "LLVM.LLVM" 196 Install-WingetPackage -Binary "clangd" -Id "LLVM.LLVM"
197 Install-WingetPackage -Binary "shellcheck" -Id "koalaman.shellcheck" 197 Install-WingetPackage -Binary "shellcheck" -Id "koalaman.shellcheck"
198 Install-NpmPackage -Binary "vscode-html-language-server" -Package "vscode-langservers-extracted" 198 Install-NpmPackage -Binary "vscode-html-language-server" -Package "vscode-langservers-extracted"
199 Install-NpmPackage -Binary "vscode-json-language-server" -Package "vscode-langservers-extracted" 199 Install-NpmPackage -Binary "vscode-json-language-server" -Package "vscode-langservers-extracted"
200 Install-WingetPackage -Binary "lua-language-server" -Id "LuaLS.lua-language-server" 200 Install-WingetPackage -Binary "lua-language-server" -Id "LuaLS.lua-language-server"
201 Install-NpmPackage -Binary "prisma-language-server" -Package "@prisma/language-server" 201 Install-NpmPackage -Binary "prisma-language-server" -Package "@prisma/language-server"
202 Install-NpmPackage -Binary "vtsls" -Package "@vtsls/language-server" 202 Install-NpmPackage -Binary "vtsls" -Package "@vtsls/language-server"
203} 203}
204 204
205function Main { 205function Main {
206 Test-Prerequisites 206 Test-Prerequisites
207 207
208 Install-Prerequisites 208 Install-Prerequisites
209 Install-Formatters 209 Install-Formatters
210 Install-Tools 210 Install-Tools
211 Install-Lsp 211 Install-Lsp
212 212
213 Write-Host "" 213 Write-Host ""
214 if ($script:Failures.Count -eq 0) { 214 if ($script:Failures.Count -eq 0) {
215 Write-Host "Neovim-Bootstrap abgeschlossen." -ForegroundColor Green 215 Write-Host "Neovim-Bootstrap abgeschlossen." -ForegroundColor Green
216 } else { 216 } else {
217 Write-Host "Neovim-Bootstrap abgeschlossen, mit $($script:Failures.Count) Warnung(en):" -ForegroundColor Yellow 217 Write-Host "Neovim-Bootstrap abgeschlossen, mit $($script:Failures.Count) Warnung(en):" -ForegroundColor Yellow
218 foreach ($f in $script:Failures) { 218 foreach ($f in $script:Failures) {
219 Write-Host " - $f" -ForegroundColor Yellow 219 Write-Host " - $f" -ForegroundColor Yellow
220 } 220 }
221 } 221 }
222} 222}
223 223
224Main 224Main