diff options
| -rw-r--r-- | bootstrap-win/neovim.ps1 | 93 | ||||
| -rwxr-xr-x | bootstrap/neovim.sh | 12 | ||||
| -rw-r--r-- | install-win.ps1 | 18 | ||||
| -rw-r--r-- | neovim-windows-setup.md | 27 | ||||
| -rw-r--r-- | nvim/lua/config/statusline.lua | 11 | ||||
| -rw-r--r-- | nvim/lua/config/usercmds.lua | 12 | ||||
| -rw-r--r-- | readme.md | 16 |
7 files changed, 159 insertions, 30 deletions
diff --git a/bootstrap-win/neovim.ps1 b/bootstrap-win/neovim.ps1 index 548583e..77abf83 100644 --- a/bootstrap-win/neovim.ps1 +++ b/bootstrap-win/neovim.ps1 | |||
| @@ -11,11 +11,15 @@ | |||
| 11 | Aufruf (PowerShell, keine Admin-Rechte noetig): | 11 | Aufruf (PowerShell, keine Admin-Rechte noetig): |
| 12 | .\bootstrap-win\neovim.ps1 | 12 | .\bootstrap-win\neovim.ps1 |
| 13 | 13 | ||
| 14 | Hinweis: Einzelne winget-Paket-IDs (v.a. GnuWin32.Gawk, GnuWin32.Libxml2, | 14 | Hinweis: yamlfmt, gawk und xmllint/libxml2 sind bewusst NICHT enthalten - |
| 15 | google.yamlfmt, mvdan.shfmt, astral-sh.ruff) konnten in dieser Session | 15 | im Praxistest (24.07.2026) bestaetigt, dass es dafuer keine winget-Pakete |
| 16 | nicht gegen eine aktuelle winget-Quelle verifiziert werden. Schlaegt eine | 16 | unter den urspruenglich vermuteten IDs gibt. Siehe Install-Formatters und |
| 17 | Installation fehl, meldet das Skript das als Warnung (bricht nicht ab) | 17 | neovim-windows-setup.md fuer manuelle Alternativen. mvdan.shfmt und |
| 18 | und nennt den Befehl zum manuellen Nachschlagen ("winget search <name>"). | 18 | astral-sh.ruff liefen im Test erfolgreich durch. |
| 19 | |||
| 20 | Schlaegt eine winget-Installation trotzdem fehl, meldet das Skript das | ||
| 21 | als Warnung (bricht nicht ab) und zeigt die letzten Zeilen der winget- | ||
| 22 | Ausgabe zur Fehlersuche an. | ||
| 19 | 23 | ||
| 20 | C-Compiler fuer nvim-treesitter: kein winget-Paket enthalten, da MSVC auf | 24 | C-Compiler fuer nvim-treesitter: kein winget-Paket enthalten, da MSVC auf |
| 21 | den Zielsystemen bereits vorhanden ist. Neovim muss dafuer aus einer | 25 | den Zielsystemen bereits vorhanden ist. Neovim muss dafuer aus einer |
| @@ -46,6 +50,40 @@ function Test-CommandExists([string]$Name) { | |||
| 46 | return [bool](Get-Command $Name -ErrorAction SilentlyContinue) | 50 | return [bool](Get-Command $Name -ErrorAction SilentlyContinue) |
| 47 | } | 51 | } |
| 48 | 52 | ||
| 53 | function Find-BinaryDirectory([string]$Binary) { | ||
| 54 | # Sucht nach "<Binary>.exe" unter den ueblichen Installationswurzeln. | ||
| 55 | # Deckt den Fall ab, dass ein winget-Paket (v.a. im --silent-Modus) | ||
| 56 | # die PATH-Registrierung ausgelassen hat, obwohl es korrekt installiert | ||
| 57 | # wurde - beobachtet bei LLVM.LLVM/clangd. | ||
| 58 | $searchRoots = @( | ||
| 59 | $env:ProgramFiles, | ||
| 60 | ${env:ProgramFiles(x86)}, | ||
| 61 | (Join-Path $env:LOCALAPPDATA "Programs") | ||
| 62 | ) | Where-Object { $_ -and (Test-Path $_) } | ||
| 63 | |||
| 64 | foreach ($root in $searchRoots) { | ||
| 65 | $found = Get-ChildItem -Path $root -Recurse -Depth 4 -Filter "$Binary.exe" -File -ErrorAction SilentlyContinue | Select-Object -First 1 | ||
| 66 | if ($found) { | ||
| 67 | return $found.DirectoryName | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | return $null | ||
| 72 | } | ||
| 73 | |||
| 74 | function Add-ToUserPath([string]$Dir) { | ||
| 75 | $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") | ||
| 76 | $entries = $userPath -split ";" | ||
| 77 | |||
| 78 | if ($entries -contains $Dir) { | ||
| 79 | return $false | ||
| 80 | } | ||
| 81 | |||
| 82 | [Environment]::SetEnvironmentVariable("PATH", "$userPath;$Dir", "User") | ||
| 83 | $env:PATH = "$env:PATH;$Dir" | ||
| 84 | return $true | ||
| 85 | } | ||
| 86 | |||
| 49 | function Install-WingetPackage([string]$Binary, [string]$Id) { | 87 | function Install-WingetPackage([string]$Binary, [string]$Id) { |
| 50 | if (Test-CommandExists $Binary) { | 88 | if (Test-CommandExists $Binary) { |
| 51 | Write-Skip $Binary | 89 | Write-Skip $Binary |
| @@ -53,10 +91,34 @@ function Install-WingetPackage([string]$Binary, [string]$Id) { | |||
| 53 | } | 91 | } |
| 54 | 92 | ||
| 55 | Write-Step "winget install $Id" | 93 | Write-Step "winget install $Id" |
| 56 | winget install --id $Id -e --source winget --accept-package-agreements --accept-source-agreements --silent | Out-Null | 94 | $output = winget install --id $Id -e --source winget --accept-package-agreements --accept-source-agreements --silent 2>&1 |
| 57 | 95 | ||
| 58 | if ($LASTEXITCODE -ne 0) { | 96 | if ($LASTEXITCODE -ne 0) { |
| 59 | Write-Warn "winget install $Id fehlgeschlagen (Binary '$Binary' nicht gefunden). Pruefen mit: winget search $Id" | 97 | $text = $output -join " " |
| 98 | $lastLine = ($output | Select-Object -Last 3) -join " / " | ||
| 99 | |||
| 100 | if ($text -match "bereits ein vorhandenes Paket|already installed|No applicable update") { | ||
| 101 | # Paket ist laut winget installiert, aber die Binary steht trotzdem | ||
| 102 | # nicht im PATH - z.B. weil der Installer (im --silent-Modus) die | ||
| 103 | # PATH-Registrierung uebersprungen hat. winget search hilft hier | ||
| 104 | # nicht weiter, da das Paket ja gefunden wurde - stattdessen selbst | ||
| 105 | # danach suchen und den User-PATH ergaenzen (dauerhaft + fuer diese | ||
| 106 | # Sitzung). | ||
| 107 | $dir = Find-BinaryDirectory $Binary | ||
| 108 | |||
| 109 | if ($dir) { | ||
| 110 | Add-ToUserPath $dir | Out-Null | ||
| 111 | if (Test-CommandExists $Binary) { | ||
| 112 | Write-Ok "$Id ('$Binary' in $dir gefunden, User-PATH ergaenzt)" | ||
| 113 | } else { | ||
| 114 | Write-Warn "${Id}: $dir zum User-PATH hinzugefuegt, aber '$Binary' laesst sich immer noch nicht ausfuehren - manuell pruefen." | ||
| 115 | } | ||
| 116 | } else { | ||
| 117 | 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." | ||
| 118 | } | ||
| 119 | } else { | ||
| 120 | Write-Warn "winget install $Id fehlgeschlagen (Binary '$Binary' nicht gefunden): $lastLine -- Pruefen mit: winget search $Id" | ||
| 121 | } | ||
| 60 | return | 122 | return |
| 61 | } | 123 | } |
| 62 | 124 | ||
| @@ -115,9 +177,15 @@ function Install-Formatters { | |||
| 115 | Install-WingetPackage -Binary "ruff" -Id "astral-sh.ruff" | 177 | Install-WingetPackage -Binary "ruff" -Id "astral-sh.ruff" |
| 116 | Install-WingetPackage -Binary "shfmt" -Id "mvdan.shfmt" | 178 | Install-WingetPackage -Binary "shfmt" -Id "mvdan.shfmt" |
| 117 | Install-WingetPackage -Binary "stylua" -Id "JohnnyMorganz.StyLua" | 179 | Install-WingetPackage -Binary "stylua" -Id "JohnnyMorganz.StyLua" |
| 118 | Install-WingetPackage -Binary "yamlfmt" -Id "google.yamlfmt" | 180 | |
| 119 | Install-WingetPackage -Binary "gawk" -Id "GnuWin32.Gawk" | 181 | # yamlfmt, gawk, xmllint: im Praxistest bestaetigt, dass es unter diesen |
| 120 | Install-WingetPackage -Binary "xmllint" -Id "GnuWin32.Libxml2" | 182 | # IDs kein winget-Paket gibt ("Es wurde kein Paket gefunden, das den |
| 183 | # Eingabekriterien entspricht"). Kein verifizierter Ersatz gefunden, | ||
| 184 | # deshalb bewusst nicht automatisiert - siehe neovim-windows-setup.md | ||
| 185 | # fuer manuelle Alternativen. conform.nvim faellt bei fehlendem | ||
| 186 | # Formatter fuer die jeweilige Dateiart einfach auf LSP-Formatierung | ||
| 187 | # zurueck (default_format_opts.lsp_format = "fallback"), betrifft also | ||
| 188 | # nur awk/xml/xsd/yaml-Dateien. | ||
| 121 | } | 189 | } |
| 122 | 190 | ||
| 123 | function Install-Tools { | 191 | function Install-Tools { |
| @@ -140,7 +208,10 @@ function Install-Tools { | |||
| 140 | # dauerhaft in den User-PATH kopieren): | 208 | # dauerhaft in den User-PATH kopieren): |
| 141 | # $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") | 209 | # $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") |
| 142 | # [Environment]::SetEnvironmentVariable("PATH", "$userPath;$env:USERPROFILE\dotfiles\windows\bin", "User") | 210 | # [Environment]::SetEnvironmentVariable("PATH", "$userPath;$env:USERPROFILE\dotfiles\windows\bin", "User") |
| 143 | Install-WingetPackage -Binary "make" -Id "GnuWin32.Make" | 211 | # GnuWin32.Make ist im Praxistest fehlgeschlagen (Paket 2006er-Stand, |
| 212 | # unklar ob im winget-Repo ueberhaupt noch gepflegt). ezwinports.make | ||
| 213 | # ist ein aktiver gepflegter GNU-Make-Port fuer Windows. | ||
| 214 | Install-WingetPackage -Binary "make" -Id "ezwinports.make" | ||
| 144 | } | 215 | } |
| 145 | 216 | ||
| 146 | function Install-Lsp { | 217 | function Install-Lsp { |
diff --git a/bootstrap/neovim.sh b/bootstrap/neovim.sh index 6ffefaf..94bf82b 100755 --- a/bootstrap/neovim.sh +++ b/bootstrap/neovim.sh | |||
| @@ -141,6 +141,17 @@ install_lsp() { | |||
| 141 | install_npm vtsls @vtsls/language-server | 141 | install_npm vtsls @vtsls/language-server |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | install_analysis() { | ||
| 145 | # sonar-scanner wird direkt von nvim/lua/config/usercmds.lua (:SonarScan) | ||
| 146 | # und nvim/scripts/sonarqube.sh (:SonarIssues) genutzt. Nur beruflich | ||
| 147 | # unter macOS im Einsatz, deshalb kein FreeBSD-Zweig. | ||
| 148 | case "$OS" in | ||
| 149 | Darwin) | ||
| 150 | install_pkg sonar-scanner sonar-scanner | ||
| 151 | ;; | ||
| 152 | esac | ||
| 153 | } | ||
| 154 | |||
| 144 | main() { | 155 | main() { |
| 145 | check_prerequisites | 156 | check_prerequisites |
| 146 | setup_homebrew_env | 157 | setup_homebrew_env |
| @@ -149,6 +160,7 @@ main() { | |||
| 149 | install_formatters | 160 | install_formatters |
| 150 | install_tools | 161 | install_tools |
| 151 | install_lsp | 162 | install_lsp |
| 163 | install_analysis | ||
| 152 | 164 | ||
| 153 | printf "\nBootstrap abgeschlossen.\n" | 165 | printf "\nBootstrap abgeschlossen.\n" |
| 154 | } | 166 | } |
diff --git a/install-win.ps1 b/install-win.ps1 index 632c25e..15f39e4 100644 --- a/install-win.ps1 +++ b/install-win.ps1 | |||
| @@ -75,8 +75,22 @@ function Copy-Npmrc { | |||
| 75 | return | 75 | return |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | Write-Step "npm\npmrc -> $NpmrcDst" | 78 | # npm/npmrc setzt "prefix=${HOME}/.local", damit globale npm-Installationen |
| 79 | Copy-Item -Force $NpmrcSrc $NpmrcDst | 79 | # unter POSIX ohne sudo/root ins Home-Verzeichnis gehen. HOME ist unter |
| 80 | # Windows i.d.R. nicht gesetzt, ${HOME} wuerde also nicht expandieren. | ||
| 81 | # Der Grund fuer die Einstellung entfaellt unter Windows ohnehin (npm | ||
| 82 | # nutzt dort schon von Haus aus %APPDATA%\npm, automatisch im PATH) - | ||
| 83 | # die Zeile wird beim Kopieren einfach auskommentiert, statt eine zweite | ||
| 84 | # npmrc-Datei zu pflegen. | ||
| 85 | Write-Step "npm\npmrc -> $NpmrcDst (prefix-Zeile auskommentiert)" | ||
| 86 | $lines = Get-Content -Path $NpmrcSrc | ForEach-Object { | ||
| 87 | if ($_ -match "^\s*prefix\s*=") { | ||
| 88 | "; $_ (unter Windows auskommentiert, siehe install-win.ps1: Copy-Npmrc)" | ||
| 89 | } else { | ||
| 90 | $_ | ||
| 91 | } | ||
| 92 | } | ||
| 93 | Set-Content -Path $NpmrcDst -Value $lines | ||
| 80 | Write-Ok $NpmrcDst | 94 | Write-Ok $NpmrcDst |
| 81 | } | 95 | } |
| 82 | 96 | ||
diff --git a/neovim-windows-setup.md b/neovim-windows-setup.md index 24e5bc0..c925f59 100644 --- a/neovim-windows-setup.md +++ b/neovim-windows-setup.md | |||
| @@ -2,28 +2,32 @@ | |||
| 2 | 2 | ||
| 3 | Checkliste für die Übernahme der bestehenden `nvim/`-Config aus dem Dotfiles-Repo auf ein natives Windows-System (kein WSL). Repo selbst bleibt unverändert. | 3 | Checkliste für die Übernahme der bestehenden `nvim/`-Config aus dem Dotfiles-Repo auf ein natives Windows-System (kein WSL). Repo selbst bleibt unverändert. |
| 4 | 4 | ||
| 5 | Alle Windows-Skripte in diesem Repo sind reines PowerShell (kein Git Bash, kein WSL) – mit einer Ausnahme: `windows\bin\gmake.cmd` ist ein trivialer Ein-Zeiler-Wrapper, für den sich eine `.ps1`-Datei nicht lohnt. Falls die Ausführung der `.ps1`-Skripte durch die Execution Policy blockiert wird, entweder pro Aufruf `powershell -ExecutionPolicy Bypass -File .\skript.ps1` verwenden, oder einmalig `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`. | 5 | Alle Windows-Skripte in diesem Repo sind reines PowerShell (kein Git Bash, kein WSL) – mit einer Ausnahme: `windows\bin\gmake.cmd` ist ein trivialer Ein-Zeiler-Wrapper, für den sich eine `.ps1`-Datei nicht lohnt. |
| 6 | 6 | ||
| 7 | ## 0. Von Hand zu erledigen (nicht durch Skripte abgedeckt) | 7 | ## 0. Von Hand zu erledigen (nicht durch Skripte abgedeckt) |
| 8 | 8 | ||
| 9 | - **Execution Policy** setzen (siehe oben), sonst starten die `.ps1`-Skripte gar nicht. | ||
| 10 | - **`winget` selbst muss vorhanden sein** ("App Installer" aus dem Microsoft Store) – `bootstrap-win/neovim.ps1` prüft das und bricht mit klarer Meldung ab, kann `winget` aber nicht selbst nachinstallieren. | 9 | - **`winget` selbst muss vorhanden sein** ("App Installer" aus dem Microsoft Store) – `bootstrap-win/neovim.ps1` prüft das und bricht mit klarer Meldung ab, kann `winget` aber nicht selbst nachinstallieren. |
| 11 | - **Neovim selbst installieren** (`winget install Neovim.Neovim`, Abschnitt 1) – kein Skript hier installiert Neovim, nur seine Config/Abhängigkeiten. | ||
| 12 | - **`delta` installieren** (`git/config` setzt `pager = delta` und `diffFilter = delta --color-only`). War auch unter macOS/FreeBSD nie Teil von `bootstrap/neovim.sh` – wurde dort offenbar immer manuell nachgezogen. Unter Windows z. B. `winget install dandavison.delta` (ID ungeprüft, ggf. `winget search delta` gegenchecken). | ||
| 13 | - **Nach jedem Skript-Lauf ein neues Terminal öffnen**, bevor `nvim` das erste Mal gestartet wird. PATH-Änderungen (durch winget/npm-Installer oder `install-win.ps1`) landen in der Registry, aber die aktuell offene Shell bekommt das nicht automatisch mit. | 10 | - **Nach jedem Skript-Lauf ein neues Terminal öffnen**, bevor `nvim` das erste Mal gestartet wird. PATH-Änderungen (durch winget/npm-Installer oder `install-win.ps1`) landen in der Registry, aber die aktuell offene Shell bekommt das nicht automatisch mit. |
| 14 | - **PATH-Registrierung stichprobenartig prüfen**, vor allem bei den GnuWin32-Paketen (`jq`, `gawk`, `make`, `libxml2`/`xmllint`) – ältere/portable winget-Pakete tragen sich nicht immer automatisch in den PATH ein. Nach einem neuen Terminal kurz `Get-Command jq, gawk, make, xmllint` aufrufen; fehlt eins, dessen Installationsordner manuell zum User-PATH hinzufügen (gleiches Muster wie `Add-BinToUserPath` in `install-win.ps1`). | 11 | - **PATH-Registrierung stichprobenartig prüfen** – manche winget-Pakete tragen sich nicht automatisch in den PATH ein (im Praxistest z. B. `LLVM.LLVM`: bereits installiert, aber `clangd` nicht im PATH, vermutlich weil der `--silent`-Installer die PATH-Registrierung überspringt). Nach einem neuen Terminal kurz `Get-Command clangd, jq, make` aufrufen; fehlt eins, dessen Installationsordner (bei LLVM z. B. `C:\Program Files\LLVM\bin`) manuell zum User-PATH hinzufügen (gleiches Muster wie `Add-BinToUserPath` in `install-win.ps1`). |
| 12 | - **yamlfmt, gawk, xmllint (libxml2) manuell installieren, falls benötigt** – im Praxistest bestätigt, dass es dafür keine winget-Pakete gibt ("Es wurde kein Paket gefunden, das den Eingabekriterien entspricht"), deshalb absichtlich nicht in `bootstrap-win/neovim.ps1` enthalten. Betrifft nur die Formatierung von awk-, xml/xsd- und yaml-Dateien (`conform.nvim` fällt sonst auf LSP-Formatierung zurück). Bekannte Alternativen: yamlfmt via `go install github.com/google/yamlfmt/cmd/yamlfmt@latest` (falls Go installiert) oder Binary von den GitHub-Releases; für gawk/xmllint keine verifizierte Windows-native Quelle gefunden, ggf. `winget search gawk` / `winget search libxml2` selbst prüfen. | ||
| 15 | - **Reihenfolge**: `install-win.ps1` und `bootstrap-win/neovim.ps1` sind unabhängig voneinander, `bootstrap-win/neovim-dict.ps1` ebenso. Empfehlenswert: erst Neovim/Git/Node (Abschnitt 1) installieren, dann beide Bootstrap-Skripte laufen lassen, dann neues Terminal öffnen, dann `nvim` starten (lädt beim ersten Start automatisch alle Lua-Plugins via `lazy.nvim` – Internetverbindung nötig). | 13 | - **Reihenfolge**: `install-win.ps1` und `bootstrap-win/neovim.ps1` sind unabhängig voneinander, `bootstrap-win/neovim-dict.ps1` ebenso. Empfehlenswert: erst Neovim/Git/Node (Abschnitt 1) installieren, dann beide Bootstrap-Skripte laufen lassen, dann neues Terminal öffnen, dann `nvim` starten (lädt beim ersten Start automatisch alle Lua-Plugins via `lazy.nvim` – Internetverbindung nötig). |
| 16 | - **Neovim immer aus einer "Developer PowerShell for VS" starten** (Startmenü-Eintrag, den Visual Studio/die Build Tools mitbringen), nicht aus normalem Windows Terminal/PowerShell. `cl.exe` (MSVC) braucht die `INCLUDE`/`LIB`-Umgebungsvariablen aus `vcvarsall.bat`, die nur in dieser Developer-Shell gesetzt sind – siehe Abschnitt 4. | 14 | - **Neovim immer aus einer "Developer PowerShell for VS" starten** (Startmenü-Eintrag, den Visual Studio/die Build Tools mitbringen), nicht aus normalem Windows Terminal/PowerShell. `cl.exe` (MSVC) braucht die `INCLUDE`/`LIB`-Umgebungsvariablen aus `vcvarsall.bat`, die nur in dieser Developer-Shell gesetzt sind – siehe Abschnitt 4. |
| 17 | 15 | ||
| 18 | ## 1. Grundwerkzeuge installieren | 16 | ## 1. Grundwerkzeuge installieren |
| 19 | 17 | ||
| 18 | Execution Policy einmalig setzen, sonst starten die `.ps1`-Skripte in diesem Repo gar nicht (Alternative pro Aufruf: `powershell -ExecutionPolicy Bypass -File .\skript.ps1`): | ||
| 19 | |||
| 20 | ```powershell | 20 | ```powershell |
| 21 | Set-ExecutionPolicy -Scope CurrentUser RemoteSigned | ||
| 21 | winget install Neovim.Neovim | 22 | winget install Neovim.Neovim |
| 22 | winget install Git.Git | 23 | winget install Git.Git |
| 23 | winget install OpenJS.NodeJS.LTS | 24 | winget install OpenJS.NodeJS.LTS |
| 25 | winget install dandavison.delta | ||
| 24 | ``` | 26 | ``` |
| 25 | 27 | ||
| 26 | (Kein Python nötig – der Python-Provider ist in `options.lua` deaktiviert. Auch kein separater C-Compiler nötig – MSVC ist auf den Zielsystemen bereits vorhanden, siehe Abschnitt 3/4.) | 28 | `delta` wird von `git/config` als Pager vorausgesetzt (`pager = delta`, `diffFilter = delta --color-only`). War auch unter macOS/FreeBSD nie Teil von `bootstrap/neovim.sh` – wurde dort offenbar immer manuell installiert. |
| 29 | |||
| 30 | (Kein Python nötig – der Python-Provider ist in `options.lua` deaktiviert. Auch kein separater C-Compiler nötig – MSVC ist auf den Zielsystemen bereits vorhanden, siehe Abschnitt 3 bzw. 4.) | ||
| 27 | 31 | ||
| 28 | ## 2. Konfiguration einrichten (Windows-nativer Weg) | 32 | ## 2. Konfiguration einrichten (Windows-nativer Weg) |
| 29 | 33 | ||
| @@ -38,7 +42,7 @@ Es kopiert (keine Symlinks, keine Admin-Rechte nötig): | |||
| 38 | - `nvim/` → `%LOCALAPPDATA%\nvim` | 42 | - `nvim/` → `%LOCALAPPDATA%\nvim` |
| 39 | - `git/config` → `%USERPROFILE%\.gitconfig` | 43 | - `git/config` → `%USERPROFILE%\.gitconfig` |
| 40 | - `git/config-up2parts` → `%USERPROFILE%\.config\git\config-up2parts` (Pfad ist im `includeIf` von `git/config` hartkodiert) | 44 | - `git/config-up2parts` → `%USERPROFILE%\.config\git\config-up2parts` (Pfad ist im `includeIf` von `git/config` hartkodiert) |
| 41 | - `npm/npmrc` → `%USERPROFILE%\.npmrc` (nur falls dort noch keine Datei existiert) | 45 | - `npm/npmrc` → `%USERPROFILE%\.npmrc` (nur falls dort noch keine Datei existiert) – die Zeile `prefix=${HOME}/.local` wird dabei auskommentiert: `HOME` ist unter Windows i. d. R. nicht gesetzt, npm nutzt dort ohnehin schon von Haus aus `%APPDATA%\npm` als Präfix |
| 42 | 46 | ||
| 43 | Nach Änderungen im Repo `install-win.ps1` erneut ausführen, um die Kopien zu aktualisieren. | 47 | Nach Änderungen im Repo `install-win.ps1` erneut ausführen, um die Kopien zu aktualisieren. |
| 44 | 48 | ||
| @@ -50,11 +54,12 @@ Nach Änderungen im Repo `install-win.ps1` erneut ausführen, um die Kopien zu a | |||
| 50 | .\bootstrap-win\neovim.ps1 | 54 | .\bootstrap-win\neovim.ps1 |
| 51 | ``` | 55 | ``` |
| 52 | 56 | ||
| 53 | Installiert per `winget`/`npm`: Git, Node, Formatter (jq, prettier, ruff, shfmt, stylua, yamlfmt, gawk, xmllint), Tools (ripgrep, fd, tree-sitter-cli, make) und LSP-Server (basedpyright, bash-language-server, clangd, shellcheck, vscode-langservers-extracted, lua-language-server, prisma, vtsls). Einzelne Pakete, die fehlschlagen, werden als Warnung gemeldet statt das Skript abzubrechen – Details siehe Kopfkommentar im Skript (einige winget-IDs, v. a. GnuWin32.Gawk/Libxml2, google.yamlfmt, mvdan.shfmt, astral-sh.ruff, sind ungeprüft). | 57 | Installiert per `winget`/`npm`: Git, Node, Formatter (jq, prettier, ruff, shfmt, stylua), Tools (ripgrep, fd, tree-sitter-cli, make über `ezwinports.make`) und LSP-Server (basedpyright, bash-language-server, clangd, shellcheck, vscode-langservers-extracted, lua-language-server, prisma, vtsls). Im Praxistest (24.07.2026) erfolgreich; yamlfmt/gawk/xmllint bewusst nicht enthalten (siehe Abschnitt 0). Einzelne Pakete, die trotzdem fehlschlagen, werden als Warnung gemeldet statt das Skript abzubrechen, inklusive der letzten Zeilen der winget-Fehlermeldung. |
| 54 | 58 | ||
| 55 | Kein C-Compiler-Paket enthalten: MSVC ist auf den Zielsystemen bereits vorhanden, `nvim-treesitter` nutzt `cl.exe`. Dafür muss Neovim aber aus einer "Developer PowerShell for VS" gestartet werden (siehe Abschnitt 4). | 59 | Kein C-Compiler-Paket enthalten: MSVC ist auf den Zielsystemen bereits vorhanden, `nvim-treesitter` nutzt `cl.exe`. Dafür muss Neovim aber aus einer "Developer PowerShell for VS" gestartet werden (siehe Abschnitt 4). |
| 56 | 60 | ||
| 57 | `windows\bin` (enthält `gmake.cmd`, Wrapper für `opt.makeprg = "gmake"`) danach einmalig zum PATH hinzufügen (PowerShell, User-Scope – nicht `setx PATH "%PATH%;..."` verwenden, das würde den kompletten Prozess-PATH inkl. System-Anteil dauerhaft in den User-PATH kopieren): | 61 | `windows\bin` (enthält `gmake.cmd`, Wrapper für `opt.makeprg = "gmake"`) danach einmalig zum PATH hinzufügen (PowerShell, User-Scope – nicht `setx PATH "%PATH%;..."` verwenden, das würde den kompletten Prozess-PATH inkl. System-Anteil dauerhaft in den User-PATH kopieren): |
| 62 | |||
| 58 | ```powershell | 63 | ```powershell |
| 59 | $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") | 64 | $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") |
| 60 | [Environment]::SetEnvironmentVariable("PATH", "$userPath;$env:USERPROFILE\dotfiles\windows\bin", "User") | 65 | [Environment]::SetEnvironmentVariable("PATH", "$userPath;$env:USERPROFILE\dotfiles\windows\bin", "User") |
| @@ -63,10 +68,6 @@ $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") | |||
| 63 | ## 4. Bekannte Stolpersteine | 68 | ## 4. Bekannte Stolpersteine |
| 64 | 69 | ||
| 65 | - **C-Compiler für `nvim-treesitter` (MSVC)**: `cl.exe` findet `nvim-treesitter` automatisch, aber nur wenn `INCLUDE`/`LIB` gesetzt sind – das passiert ausschließlich in einer "Developer PowerShell for VS" bzw. "x64 Native Tools Command Prompt", nicht in einer normalen PowerShell/Windows Terminal-Sitzung. Ohne das schlägt die Parser-Kompilierung mit einer Meldung wie "cannot find `<header>`.h" fehl, obwohl `cl.exe` selbst gefunden wird. Neovim also immer aus dieser Developer-Shell heraus starten. | 70 | - **C-Compiler für `nvim-treesitter` (MSVC)**: `cl.exe` findet `nvim-treesitter` automatisch, aber nur wenn `INCLUDE`/`LIB` gesetzt sind – das passiert ausschließlich in einer "Developer PowerShell for VS" bzw. "x64 Native Tools Command Prompt", nicht in einer normalen PowerShell/Windows Terminal-Sitzung. Ohne das schlägt die Parser-Kompilierung mit einer Meldung wie "cannot find `<header>`.h" fehl, obwohl `cl.exe` selbst gefunden wird. Neovim also immer aus dieser Developer-Shell heraus starten. |
| 66 | - **Rechtschreibprüfung (Deutsch)**: `bootstrap-win/neovim-dict.ps1` ausführen – lädt `de.utf-8.spl`/`.sug` nach `%LOCALAPPDATA%\nvim-data\site\spell` (nativer Windows-Datenpfad von Neovim). | ||
| 67 | - **`scripts/sonarqube.sh`** (`:SonarIssues`): reines POSIX-Shellskript, kein Windows-Pendant vorhanden. Läuft nur, wenn ein `sh` im PATH liegt (z. B. `sh.exe` aus Git for Windows im PATH verfügbar machen); ansonsten `:SonarIssues` auf Windows nicht nutzen. | ||
| 68 | - **Clipboard** (`unnamedplus`): funktioniert nativ unter Windows-Neovim ohne Zusatztool – anders als unter WSL, wo `win32yank` nötig wäre. | ||
| 69 | - **`opt.guifont`**: wirkt nur bei GUI-Frontends wie Neovide. Im Windows Terminal muss die Schriftart dort separat eingestellt werden. | ||
| 70 | 71 | ||
| 71 | ## 5. Verifizieren | 72 | ## 5. Verifizieren |
| 72 | 73 | ||
| @@ -100,7 +101,7 @@ winget upgrade LLVM.LLVM | |||
| 100 | 101 | ||
| 101 | Zwei Besonderheiten gegenüber brew/pkg: | 102 | Zwei Besonderheiten gegenüber brew/pkg: |
| 102 | 103 | ||
| 103 | - Ältere/portable Pakete (v. a. die GnuWin32-Reihe: `jq`, `gawk`, `make`, `libxml2`) melden nicht immer zuverlässig eine neue Version. `winget upgrade --all --include-unknown` bezieht auch diese mit ein, installiert dabei aber unter Umständen unnötig neu. | 104 | - Manche Pakete melden nicht immer zuverlässig eine neue Version (z. B. ältere/portable Pakete). `winget upgrade --all --include-unknown` bezieht auch diese mit ein, installiert dabei aber unter Umständen unnötig neu. |
| 104 | - Ein Paket dauerhaft von `--all` ausnehmen: `winget pin add <id>` (Pendant zu `brew pin`). | 105 | - Ein Paket dauerhaft von `--all` ausnehmen: `winget pin add <id>` (Pendant zu `brew pin`). |
| 105 | 106 | ||
| 106 | Die npm-Pakete (`prettier`, `basedpyright`, `bash-language-server`, `vtsls`, `@prisma/language-server`, `vscode-langservers-extracted`) laufen außerhalb von winget und werden separat aktualisiert: | 107 | Die npm-Pakete (`prettier`, `basedpyright`, `bash-language-server`, `vtsls`, `@prisma/language-server`, `vscode-langservers-extracted`) laufen außerhalb von winget und werden separat aktualisiert: |
diff --git a/nvim/lua/config/statusline.lua b/nvim/lua/config/statusline.lua index 0ec6579..8a9c75a 100644 --- a/nvim/lua/config/statusline.lua +++ b/nvim/lua/config/statusline.lua | |||
| @@ -20,6 +20,10 @@ end | |||
| 20 | -- Git branch (buffer-lokal, gecached, kein redraw-spam) | 20 | -- Git branch (buffer-lokal, gecached, kein redraw-spam) |
| 21 | ---------------------------------------------------------------------- | 21 | ---------------------------------------------------------------------- |
| 22 | 22 | ||
| 23 | -- /dev/null gibt es unter Windows nicht (cmd.exe versteht das nicht als | ||
| 24 | -- Pfad und meldet "Das System kann den angegebenen Pfad nicht finden"). | ||
| 25 | local devnull = vim.fn.has("win32") == 1 and "NUL" or "/dev/null" | ||
| 26 | |||
| 23 | local function update_git_branch(bufnr) | 27 | local function update_git_branch(bufnr) |
| 24 | bufnr = bufnr or 0 | 28 | bufnr = bufnr or 0 |
| 25 | 29 | ||
| @@ -35,7 +39,12 @@ local function update_git_branch(bufnr) | |||
| 35 | return | 39 | return |
| 36 | end | 40 | end |
| 37 | 41 | ||
| 38 | local branch = vim.fn.systemlist("git rev-parse --abbrev-ref HEAD 2>/dev/null")[1] | 42 | local branch = vim.fn.systemlist("git rev-parse --abbrev-ref HEAD 2>" .. devnull)[1] |
| 43 | if branch then | ||
| 44 | -- unter Windows bleibt an systemlist()-Zeilen mitunter ein | ||
| 45 | -- trailing \r haengen (^M in der Statuszeile sichtbar) | ||
| 46 | branch = branch:gsub("\r$", "") | ||
| 47 | end | ||
| 39 | 48 | ||
| 40 | if branch and branch ~= "" then | 49 | if branch and branch ~= "" then |
| 41 | vim.b[bufnr].git_branch = " " .. branch .. " " | 50 | vim.b[bufnr].git_branch = " " .. branch .. " " |
diff --git a/nvim/lua/config/usercmds.lua b/nvim/lua/config/usercmds.lua index 9abc50f..529b370 100644 --- a/nvim/lua/config/usercmds.lua +++ b/nvim/lua/config/usercmds.lua | |||
| @@ -66,8 +66,16 @@ local function enable_lsp() | |||
| 66 | vim.cmd("edit") -- triggert Reattach bei vielen Setups | 66 | vim.cmd("edit") -- triggert Reattach bei vielen Setups |
| 67 | end | 67 | end |
| 68 | 68 | ||
| 69 | vim.api.nvim_create_user_command("SonarScan", run_sonar, {}) | 69 | -- sonar-scanner/scripts/sonarqube.sh sind POSIX-only (kein Windows-Pendant), |
| 70 | vim.api.nvim_create_user_command("SonarIssues", load_sonar_issues, {}) | 70 | -- deshalb Kommandos unter Windows gar nicht erst registrieren statt sie |
| 71 | -- dort fehlschlagen zu lassen. | ||
| 72 | local is_windows = vim.fn.has("win32") == 1 | ||
| 73 | |||
| 74 | if not is_windows then | ||
| 75 | vim.api.nvim_create_user_command("SonarScan", run_sonar, {}) | ||
| 76 | vim.api.nvim_create_user_command("SonarIssues", load_sonar_issues, {}) | ||
| 77 | end | ||
| 78 | |||
| 71 | vim.api.nvim_create_user_command("LspOff", disable_lsp, {}) | 79 | vim.api.nvim_create_user_command("LspOff", disable_lsp, {}) |
| 72 | vim.api.nvim_create_user_command("LspOffBuffer", disable_lsp_buffer, {}) | 80 | vim.api.nvim_create_user_command("LspOffBuffer", disable_lsp_buffer, {}) |
| 73 | vim.api.nvim_create_user_command("LspOn", enable_lsp, {}) | 81 | vim.api.nvim_create_user_command("LspOn", enable_lsp, {}) |
| @@ -1,9 +1,11 @@ | |||
| 1 | # Dotfiles | 1 | # Dotfiles |
| 2 | 2 | ||
| 3 | My personal dotfiles for macOS and FreeBSD. | 3 | My personal dotfiles for macOS, FreeBSD and Windows (Beta). |
| 4 | 4 | ||
| 5 | ## Setup | 5 | ## Setup |
| 6 | 6 | ||
| 7 | ### macOS / FreeBSD | ||
| 8 | |||
| 7 | Create the symbolic links: | 9 | Create the symbolic links: |
| 8 | 10 | ||
| 9 | ```sh | 11 | ```sh |
| @@ -17,6 +19,18 @@ Bootstrap the Neovim environment: | |||
| 17 | ./bootstrap/neovim-dict.sh | 19 | ./bootstrap/neovim-dict.sh |
| 18 | ``` | 20 | ``` |
| 19 | 21 | ||
| 22 | ### Windows | ||
| 23 | |||
| 24 | Native PowerShell, no WSL/Git Bash required: | ||
| 25 | |||
| 26 | ```powershell | ||
| 27 | .\install-win.ps1 | ||
| 28 | .\bootstrap-win\neovim.ps1 | ||
| 29 | .\bootstrap-win\neovim-dict.ps1 | ||
| 30 | ``` | ||
| 31 | |||
| 32 | See [neovim-windows-setup.md](neovim-windows-setup.md) for prerequisites (execution policy, MSVC Developer PowerShell for `nvim-treesitter`, ...) and known caveats. | ||
| 33 | |||
| 20 | ## Included configuration | 34 | ## Included configuration |
| 21 | 35 | ||
| 22 | - [abook] | 36 | - [abook] |
