diff options
| -rwxr-xr-x | bootstrap/neovim.sh | 7 | ||||
| -rw-r--r-- | neovim-windows-setup.md | 4 | ||||
| -rw-r--r-- | nvim/ftplugin/json.lua | 8 | ||||
| -rw-r--r-- | nvim/ftplugin/jsonc.lua | 8 | ||||
| -rw-r--r-- | nvim/ftplugin/taskedit.lua | 6 | ||||
| -rw-r--r-- | nvim/ftplugin/taskwarrior.lua | 7 | ||||
| -rw-r--r-- | nvim/init.lua | 6 | ||||
| -rw-r--r-- | nvim/lua/config/autocmds.lua | 21 | ||||
| -rw-r--r-- | nvim/lua/config/filetypes.lua | 56 | ||||
| -rw-r--r-- | nvim/lua/config/keymaps.lua | 14 | ||||
| -rw-r--r-- | nvim/lua/config/options.lua | 3 | ||||
| -rw-r--r-- | nvim/lua/config/statusline.lua | 44 | ||||
| -rw-r--r-- | nvim/lua/config/treesitter.lua | 43 | ||||
| -rw-r--r-- | nvim/lua/plugins/format.lua | 5 | ||||
| -rw-r--r-- | nvim/lua/plugins/git.lua | 2 | ||||
| -rw-r--r-- | nvim/lua/plugins/lint.lua | 31 | ||||
| -rw-r--r-- | nvim/lua/plugins/lsp.lua | 8 | ||||
| -rw-r--r-- | nvim/lua/plugins/ui.lua | 30 |
18 files changed, 169 insertions, 134 deletions
diff --git a/bootstrap/neovim.sh b/bootstrap/neovim.sh index 11059e2..eabee0f 100755 --- a/bootstrap/neovim.sh +++ b/bootstrap/neovim.sh | |||
| @@ -177,13 +177,20 @@ install_lsp() { | |||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | install_analysis() { | 179 | install_analysis() { |
| 180 | # yamllint wird von nvim-lint fuer YAML-Dateien aufgerufen. Unter FreeBSD ist | ||
| 181 | # der Paketname python-versioniert (py311-yamllint), deshalb der Origin-Pfad. | ||
| 182 | # | ||
| 180 | # sonar-scanner wird direkt von nvim/lua/config/usercmds.lua (:SonarScan) | 183 | # sonar-scanner wird direkt von nvim/lua/config/usercmds.lua (:SonarScan) |
| 181 | # und nvim/scripts/sonarqube.sh (:SonarIssues) genutzt. Nur beruflich | 184 | # und nvim/scripts/sonarqube.sh (:SonarIssues) genutzt. Nur beruflich |
| 182 | # unter macOS im Einsatz, deshalb kein FreeBSD-Zweig. | 185 | # unter macOS im Einsatz, deshalb kein FreeBSD-Zweig. |
| 183 | case "$OS" in | 186 | case "$OS" in |
| 184 | Darwin) | 187 | Darwin) |
| 188 | install_pkg yamllint yamllint | ||
| 185 | install_pkg sonar-scanner sonar-scanner | 189 | install_pkg sonar-scanner sonar-scanner |
| 186 | ;; | 190 | ;; |
| 191 | FreeBSD) | ||
| 192 | install_pkg yamllint devel/py-yamllint | ||
| 193 | ;; | ||
| 187 | esac | 194 | esac |
| 188 | } | 195 | } |
| 189 | 196 | ||
diff --git a/neovim-windows-setup.md b/neovim-windows-setup.md index 801beef..72f2b25 100644 --- a/neovim-windows-setup.md +++ b/neovim-windows-setup.md | |||
| @@ -9,7 +9,7 @@ Alle Windows-Skripte in diesem Repo sind reines PowerShell (kein Git Bash, kein | |||
| 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. | 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. |
| 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. | 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. |
| 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`). | 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), djlint 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 die Formatierung von awk-, xml/xsd-, yaml- und jinja-Dateien (`conform.nvim` fällt sonst auf LSP-Formatierung zurück, für `jinja` gibt es aktuell keinen LSP-Fallback). Bekannte Alternativen: yamlfmt via `go install github.com/google/yamlfmt/cmd/yamlfmt@latest` (falls Go installiert) oder Binary von den GitHub-Releases; djlint ist ein reines Python-Paket, daher `pip install djlint` bzw. `pipx install djlint` (Python muss dafür separat installiert sein, siehe Abschnitt 1); für gawk/xmllint keine verifizierte Windows-native Quelle gefunden, ggf. `winget search gawk` / `winget search libxml2` selbst prüfen. | 12 | - **yamlfmt, gawk, xmllint (libxml2), djlint, yamllint 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 die Formatierung von awk-, xml/xsd-, yaml- und jinja-Dateien (`conform.nvim` fällt sonst auf LSP-Formatierung zurück, für `jinja` gibt es aktuell keinen LSP-Fallback). Bekannte Alternativen: yamlfmt via `go install github.com/google/yamlfmt/cmd/yamlfmt@latest` (falls Go installiert) oder Binary von den GitHub-Releases; djlint und yamllint sind reine Python-Pakete, daher `pip install djlint yamllint` bzw. `pipx install djlint` und `pipx install yamllint` (Python muss dafür separat installiert sein, siehe Abschnitt 1) – ohne yamllint linted `nvim-lint` YAML-Dateien unter Windows einfach nicht; für gawk/xmllint keine verifizierte Windows-native Quelle gefunden, ggf. `winget search gawk` / `winget search libxml2` selbst prüfen. |
| 13 | - **Reihenfolge**: `install-win.ps1`, `bootstrap-win/git.ps1`, `bootstrap-win/neovim.ps1` und `bootstrap-win/neovim-dict.ps1` sind unabhängig voneinander. Empfehlenswert: erst Neovim/Node (Abschnitt 1) installieren, dann alle 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`, `bootstrap-win/git.ps1`, `bootstrap-win/neovim.ps1` und `bootstrap-win/neovim-dict.ps1` sind unabhängig voneinander. Empfehlenswert: erst Neovim/Node (Abschnitt 1) installieren, dann alle 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). |
| 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. | 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. |
| 15 | 15 | ||
| @@ -56,7 +56,7 @@ Nach Änderungen im Repo `install-win.ps1` erneut ausführen, um die Kopien zu a | |||
| 56 | .\bootstrap-win\neovim.ps1 | 56 | .\bootstrap-win\neovim.ps1 |
| 57 | ``` | 57 | ``` |
| 58 | 58 | ||
| 59 | 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/djlint 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. | 59 | 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/djlint/yamllint 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. |
| 60 | 60 | ||
| 61 | 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). | 61 | 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). |
| 62 | 62 | ||
diff --git a/nvim/ftplugin/json.lua b/nvim/ftplugin/json.lua index 341b728..a6321ff 100644 --- a/nvim/ftplugin/json.lua +++ b/nvim/ftplugin/json.lua | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | -- Standard-Dateityp für .json-Dateien ist "jsonc" (siehe lua/config/filetypes.lua). | 1 | local opt = vim.opt_local |
| 2 | -- Buffer, deren Dateityp explizit "json" ist, erben dieselben Einstellungen. | 2 | |
| 3 | vim.cmd.runtime("ftplugin/jsonc.lua") | 3 | opt.expandtab = true |
| 4 | opt.shiftwidth = 2 | ||
| 5 | opt.tabstop = 2 | ||
diff --git a/nvim/ftplugin/jsonc.lua b/nvim/ftplugin/jsonc.lua index a6321ff..4c9fd66 100644 --- a/nvim/ftplugin/jsonc.lua +++ b/nvim/ftplugin/jsonc.lua | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | local opt = vim.opt_local | 1 | -- jsonc entsteht nicht durch Dateityp-Erkennung, sondern nur wenn es explizit |
| 2 | 2 | -- gesetzt wird (z.B. per Modeline). Die Einstellungen sind dieselben wie fuer json. | |
| 3 | opt.expandtab = true | 3 | vim.cmd.runtime("ftplugin/json.lua") |
| 4 | opt.shiftwidth = 2 | ||
| 5 | opt.tabstop = 2 | ||
diff --git a/nvim/ftplugin/taskedit.lua b/nvim/ftplugin/taskedit.lua index a905acb..ee8fdf0 100644 --- a/nvim/ftplugin/taskedit.lua +++ b/nvim/ftplugin/taskedit.lua | |||
| @@ -1 +1,5 @@ | |||
| 1 | vim.cmd.runtime("ftplugin/taskwarrior.lua") | 1 | local opt = vim.opt_local |
| 2 | |||
| 3 | opt.autoindent = false | ||
| 4 | opt.indentexpr = "" | ||
| 5 | opt.indentkeys = "" | ||
diff --git a/nvim/ftplugin/taskwarrior.lua b/nvim/ftplugin/taskwarrior.lua deleted file mode 100644 index a3c4537..0000000 --- a/nvim/ftplugin/taskwarrior.lua +++ /dev/null | |||
| @@ -1,7 +0,0 @@ | |||
| 1 | local opt = vim.opt_local | ||
| 2 | |||
| 3 | opt.autoindent = false | ||
| 4 | opt.cindent = false | ||
| 5 | opt.indentexpr = "" | ||
| 6 | opt.indentkeys = "" | ||
| 7 | opt.smartindent = false | ||
diff --git a/nvim/init.lua b/nvim/init.lua index 146ae6c..29c0e40 100644 --- a/nvim/init.lua +++ b/nvim/init.lua | |||
| @@ -1,9 +1,7 @@ | |||
| 1 | require("config.options") | 1 | require("config.options") |
| 2 | require("config.filetypes") | 2 | require("config.filetypes") |
| 3 | 3 | require("config.treesitter").register_extra_filetypes() | |
| 4 | local keymaps = require("config.keymaps") | 4 | require("config.keymaps").set_global() |
| 5 | keymaps.global() | ||
| 6 | |||
| 7 | require("config.autocmds") | 5 | require("config.autocmds") |
| 8 | require("config.usercmds") | 6 | require("config.usercmds") |
| 9 | require("config.lazy") | 7 | require("config.lazy") |
diff --git a/nvim/lua/config/autocmds.lua b/nvim/lua/config/autocmds.lua index 0835670..2cca1df 100644 --- a/nvim/lua/config/autocmds.lua +++ b/nvim/lua/config/autocmds.lua | |||
| @@ -1,7 +1,4 @@ | |||
| 1 | -- https://github.com/nvim-treesitter/nvim-treesitter/blob/main/doc/nvim-treesitter.txt | 1 | -- https://github.com/nvim-treesitter/nvim-treesitter/blob/main/doc/nvim-treesitter.txt |
| 2 | local treesitter_languages = require("config.treesitter").languages | ||
| 3 | local extra_filetypes = require("config.filetypes").extra | ||
| 4 | |||
| 5 | local function enable_treesitter_features() | 2 | local function enable_treesitter_features() |
| 6 | if not pcall(vim.treesitter.start) then return end | 3 | if not pcall(vim.treesitter.start) then return end |
| 7 | 4 | ||
| @@ -10,20 +7,8 @@ local function enable_treesitter_features() | |||
| 10 | vim.bo.indentexpr = "v:lua.require('nvim-treesitter').indentexpr()" | 7 | vim.bo.indentexpr = "v:lua.require('nvim-treesitter').indentexpr()" |
| 11 | end | 8 | end |
| 12 | 9 | ||
| 13 | -- Fuehrt zwei Listen zu einer neuen zusammen, ohne die Eingaben zu veraendern. | ||
| 14 | local function merge(list, extra) | ||
| 15 | local merged = {} | ||
| 16 | for _, item in ipairs(list) do | ||
| 17 | table.insert(merged, item) | ||
| 18 | end | ||
| 19 | for _, item in ipairs(extra) do | ||
| 20 | table.insert(merged, item) | ||
| 21 | end | ||
| 22 | return merged | ||
| 23 | end | ||
| 24 | |||
| 25 | vim.api.nvim_create_autocmd("FileType", { | 10 | vim.api.nvim_create_autocmd("FileType", { |
| 26 | pattern = merge(treesitter_languages, extra_filetypes), | 11 | pattern = require("config.treesitter").filetypes(), |
| 27 | callback = enable_treesitter_features, | 12 | callback = enable_treesitter_features, |
| 28 | }) | 13 | }) |
| 29 | 14 | ||
| @@ -50,7 +35,7 @@ vim.api.nvim_create_autocmd("QuitPre", { | |||
| 50 | vim.api.nvim_create_autocmd("LspAttach", { | 35 | vim.api.nvim_create_autocmd("LspAttach", { |
| 51 | callback = function(event) | 36 | callback = function(event) |
| 52 | local client = vim.lsp.get_client_by_id(event.data.client_id) | 37 | local client = vim.lsp.get_client_by_id(event.data.client_id) |
| 53 | local keymaps = require("config.keymaps") | 38 | |
| 54 | keymaps.lsp(event.buf, client) | 39 | require("config.keymaps").set_lsp(event.buf, client) |
| 55 | end, | 40 | end, |
| 56 | }) | 41 | }) |
diff --git a/nvim/lua/config/filetypes.lua b/nvim/lua/config/filetypes.lua index 2537750..0cb9036 100644 --- a/nvim/lua/config/filetypes.lua +++ b/nvim/lua/config/filetypes.lua | |||
| @@ -1,49 +1,31 @@ | |||
| 1 | -- Custom Filetype-Erkennung fuer Dateien, die sich nicht allein anhand ihrer | 1 | -- Custom Filetype-Erkennung fuer Dateien, die sich nicht allein anhand ihrer |
| 2 | -- Endung unterscheiden lassen (z.B. Ansible-YAML vs. normales YAML). | 2 | -- Endung unterscheiden lassen (z.B. Ansible-YAML vs. normales YAML). |
| 3 | -- | ||
| 4 | -- "yaml.ansible" wird ausserdem in config.treesitter (Autocmd-Pattern) und in | ||
| 5 | -- plugins/lsp.lua (ansiblels.filetypes) verwendet. | ||
| 3 | 6 | ||
| 4 | local M = {} | 7 | -- Ansible-Dateien haben die Endung .yml/.yaml wie normales YAML und sind nur am |
| 5 | 8 | -- Dateinamen bzw. am Pfad erkennbar. Die Patterns sind mit "$" verankert, damit | |
| 6 | -- Name des zusammengesetzten Filetypes fuer Ansible-YAML-Dateien. Wird auch | 9 | -- Jinja-Templates (z.B. tasks/main.yml.j2) weiter als jinja gelten. |
| 7 | -- von plugins/lsp.lua (vim.lsp.config.ansiblels.filetypes) referenziert, damit | ||
| 8 | -- Erkennung und LSP-Konfiguration nicht auseinanderlaufen koennen. | ||
| 9 | M.ANSIBLE_YAML = "yaml.ansible" | ||
| 10 | |||
| 11 | -- Filetypes, die hier zusaetzlich zur eingebauten Erkennung entstehen und | ||
| 12 | -- an anderer Stelle mitberuecksichtigt werden muessen (siehe config.autocmds, | ||
| 13 | -- Treesitter-Aktivierung). | ||
| 14 | M.extra = { M.ANSIBLE_YAML, "jsonc" } | ||
| 15 | |||
| 16 | -- Ansible-Dateien haben die Endung .yml/.yaml wie normales YAML und sind nur | ||
| 17 | -- am Dateinamen bzw. am Pfad erkennbar. Die Patterns sind mit "$" verankert, | ||
| 18 | -- damit Jinja-Templates (z.B. tasks/main.yml.j2) weiter als jinja gelten. | ||
| 19 | vim.filetype.add({ | 10 | vim.filetype.add({ |
| 20 | filename = { | 11 | filename = { |
| 21 | ["playbook.yml"] = M.ANSIBLE_YAML, | 12 | ["playbook.yml"] = "yaml.ansible", |
| 22 | ["playbook.yaml"] = M.ANSIBLE_YAML, | 13 | ["playbook.yaml"] = "yaml.ansible", |
| 23 | ["site.yml"] = M.ANSIBLE_YAML, | 14 | ["site.yml"] = "yaml.ansible", |
| 24 | ["site.yaml"] = M.ANSIBLE_YAML, | 15 | ["site.yaml"] = "yaml.ansible", |
| 25 | ["requirements.yml"] = M.ANSIBLE_YAML, | 16 | ["requirements.yml"] = "yaml.ansible", |
| 26 | ["requirements.yaml"] = M.ANSIBLE_YAML, | 17 | ["requirements.yaml"] = "yaml.ansible", |
| 27 | }, | 18 | }, |
| 28 | pattern = { | 19 | pattern = { |
| 29 | [".*/roles/.*/tasks/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 20 | [".*/roles/.*/tasks/.*%.ya?ml$"] = "yaml.ansible", |
| 30 | [".*/roles/.*/handlers/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 21 | [".*/roles/.*/handlers/.*%.ya?ml$"] = "yaml.ansible", |
| 31 | [".*/tasks/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 22 | [".*/tasks/.*%.ya?ml$"] = "yaml.ansible", |
| 32 | [".*/handlers/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 23 | [".*/handlers/.*%.ya?ml$"] = "yaml.ansible", |
| 33 | [".*/group_vars/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 24 | [".*/group_vars/.*%.ya?ml$"] = "yaml.ansible", |
| 34 | [".*/host_vars/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 25 | [".*/host_vars/.*%.ya?ml$"] = "yaml.ansible", |
| 35 | [".*/playbooks/.*%.ya?ml$"] = M.ANSIBLE_YAML, | 26 | [".*/playbooks/.*%.ya?ml$"] = "yaml.ansible", |
| 36 | }, | 27 | }, |
| 37 | extension = { | 28 | extension = { |
| 38 | j2 = "jinja", | 29 | j2 = "jinja", |
| 39 | -- .json als jsonc behandeln, damit Kommentare erlaubt sind (jsonls meldet | ||
| 40 | -- sie dann nicht als Fehler). | ||
| 41 | json = "jsonc", | ||
| 42 | }, | 30 | }, |
| 43 | }) | 31 | }) |
| 44 | |||
| 45 | -- nvim-treesitter stellt keinen eigenen jsonc-Parser bereit. Der json-Parser | ||
| 46 | -- versteht // und /* */ Kommentare, deshalb wird er fuer jsonc mitbenutzt. | ||
| 47 | vim.treesitter.language.register("json", "jsonc") | ||
| 48 | |||
| 49 | return M | ||
diff --git a/nvim/lua/config/keymaps.lua b/nvim/lua/config/keymaps.lua index 9896a57..bdae127 100644 --- a/nvim/lua/config/keymaps.lua +++ b/nvim/lua/config/keymaps.lua | |||
| @@ -2,7 +2,7 @@ local M = {} | |||
| 2 | 2 | ||
| 3 | local map = vim.keymap.set | 3 | local map = vim.keymap.set |
| 4 | 4 | ||
| 5 | function M.lsp(buffer, client) | 5 | function M.set_lsp(buffer, client) |
| 6 | local opts = { | 6 | local opts = { |
| 7 | buffer = buffer, | 7 | buffer = buffer, |
| 8 | silent = true, | 8 | silent = true, |
| @@ -56,17 +56,23 @@ function M.lsp(buffer, client) | |||
| 56 | set_c_bindings() | 56 | set_c_bindings() |
| 57 | elseif client.name == "basedpyright" or client.name == "pyright" or client.name == "pylsp" then | 57 | elseif client.name == "basedpyright" or client.name == "pyright" or client.name == "pylsp" then |
| 58 | set_python_bindings() | 58 | set_python_bindings() |
| 59 | elseif client.name == "tsserver" or client.name == "vtsls" or client.name == "typescript_tools" then | 59 | elseif |
| 60 | client.name == "ts_ls" | ||
| 61 | or client.name == "tsgo" | ||
| 62 | or client.name == "tsserver" | ||
| 63 | or client.name == "vtsls" | ||
| 64 | or client.name == "typescript_tools" | ||
| 65 | then | ||
| 60 | set_npm_bindings() | 66 | set_npm_bindings() |
| 61 | end | 67 | end |
| 62 | end | 68 | end |
| 63 | end | 69 | end |
| 64 | 70 | ||
| 65 | function M.gitsigns() | 71 | function M.set_gitsigns() |
| 66 | map("n", "<leader>tb", require("gitsigns").toggle_current_line_blame) | 72 | map("n", "<leader>tb", require("gitsigns").toggle_current_line_blame) |
| 67 | end | 73 | end |
| 68 | 74 | ||
| 69 | function M.global() | 75 | function M.set_global() |
| 70 | local opts = { | 76 | local opts = { |
| 71 | silent = true, | 77 | silent = true, |
| 72 | } | 78 | } |
diff --git a/nvim/lua/config/options.lua b/nvim/lua/config/options.lua index b1d2104..55fe983 100644 --- a/nvim/lua/config/options.lua +++ b/nvim/lua/config/options.lua | |||
| @@ -50,9 +50,6 @@ opt.matchpairs:append("<:>") | |||
| 50 | -- automatisches Einlesen geänderter Dateien | 50 | -- automatisches Einlesen geänderter Dateien |
| 51 | opt.autoread = true | 51 | opt.autoread = true |
| 52 | 52 | ||
| 53 | -- Suche rekursiv | ||
| 54 | opt.path:append("**") | ||
| 55 | |||
| 56 | -- Tabs | 53 | -- Tabs |
| 57 | opt.expandtab = false | 54 | opt.expandtab = false |
| 58 | opt.tabstop = 4 | 55 | opt.tabstop = 4 |
diff --git a/nvim/lua/config/statusline.lua b/nvim/lua/config/statusline.lua index 01339d0..ef6f315 100644 --- a/nvim/lua/config/statusline.lua +++ b/nvim/lua/config/statusline.lua | |||
| @@ -46,19 +46,6 @@ local function git_diff() | |||
| 46 | return "" | 46 | return "" |
| 47 | end | 47 | end |
| 48 | 48 | ||
| 49 | ---------------------------------------------------------------------- | ||
| 50 | -- Dateiname mit Modifikationsstatus | ||
| 51 | ---------------------------------------------------------------------- | ||
| 52 | |||
| 53 | local function filename() | ||
| 54 | local name = vim.fn.expand("%:.") | ||
| 55 | if name == "" then name = "[No Name]" end | ||
| 56 | |||
| 57 | if vim.bo.modified then name = name .. " [+]" end | ||
| 58 | |||
| 59 | return " " .. name .. " " | ||
| 60 | end | ||
| 61 | |||
| 62 | ------------------------------------------------------------------------ | 49 | ------------------------------------------------------------------------ |
| 63 | -- Treesitter-Aktivität (buffer-lokal, kein redraw-spam) | 50 | -- Treesitter-Aktivität (buffer-lokal, kein redraw-spam) |
| 64 | ------------------------------------------------------------------------ | 51 | ------------------------------------------------------------------------ |
| @@ -70,6 +57,23 @@ local function treesitter() | |||
| 70 | end | 57 | end |
| 71 | 58 | ||
| 72 | ------------------------------------------------------------------------ | 59 | ------------------------------------------------------------------------ |
| 60 | -- LSP-Clients des Buffers | ||
| 61 | ------------------------------------------------------------------------ | ||
| 62 | |||
| 63 | local function lsp() | ||
| 64 | local clients = vim.lsp.get_clients({ bufnr = 0 }) | ||
| 65 | |||
| 66 | if #clients == 0 then return "" end | ||
| 67 | |||
| 68 | local names = {} | ||
| 69 | for _, client in ipairs(clients) do | ||
| 70 | table.insert(names, client.name) | ||
| 71 | end | ||
| 72 | |||
| 73 | return " " .. table.concat(names, ", ") .. " " | ||
| 74 | end | ||
| 75 | |||
| 76 | ------------------------------------------------------------------------ | ||
| 73 | -- Diagnostik-Counts (buffer-lokal, kein redraw-spam) | 77 | -- Diagnostik-Counts (buffer-lokal, kein redraw-spam) |
| 74 | ------------------------------------------------------------------------ | 78 | ------------------------------------------------------------------------ |
| 75 | 79 | ||
| @@ -103,14 +107,6 @@ local function fileinfo() | |||
| 103 | return string.format(" %s %s ", ft, enc) | 107 | return string.format(" %s %s ", ft, enc) |
| 104 | end | 108 | end |
| 105 | 109 | ||
| 106 | ------------------------------------------------------------------------ | ||
| 107 | -- Cursor-Position (kein redraw-spam) | ||
| 108 | ------------------------------------------------------------------------ | ||
| 109 | |||
| 110 | local function position() | ||
| 111 | return string.format(" %d:%d ", vim.fn.line("."), vim.fn.col(".")) | ||
| 112 | end | ||
| 113 | |||
| 114 | ---------------------------------------------------------------------- | 110 | ---------------------------------------------------------------------- |
| 115 | -- Öffentliche Statusline-Funktion | 111 | -- Öffentliche Statusline-Funktion |
| 116 | ---------------------------------------------------------------------- | 112 | ---------------------------------------------------------------------- |
| @@ -123,16 +119,18 @@ function M.statusline() | |||
| 123 | git(), | 119 | git(), |
| 124 | git_diff(), | 120 | git_diff(), |
| 125 | "%#StatusLine#", | 121 | "%#StatusLine#", |
| 126 | filename(), | 122 | -- %f Dateiname, %m Modifikationsstatus; %(..%) faellt weg, wenn %m leer ist |
| 123 | " %f%( %m%) ", | ||
| 127 | 124 | ||
| 128 | "%=", | 125 | "%=", |
| 129 | 126 | ||
| 130 | -- RIGHT: Feedback & Meta | 127 | -- RIGHT: Feedback & Meta |
| 131 | diagnostics(), | 128 | diagnostics(), |
| 129 | lsp(), | ||
| 132 | treesitter(), | 130 | treesitter(), |
| 133 | fileinfo(), | 131 | fileinfo(), |
| 134 | " %p%% ", | 132 | " %p%% ", |
| 135 | position(), | 133 | " %l:%c ", |
| 136 | }) | 134 | }) |
| 137 | end | 135 | end |
| 138 | 136 | ||
diff --git a/nvim/lua/config/treesitter.lua b/nvim/lua/config/treesitter.lua index e52d637..8e4e4ba 100644 --- a/nvim/lua/config/treesitter.lua +++ b/nvim/lua/config/treesitter.lua | |||
| @@ -10,11 +10,11 @@ M.languages = { | |||
| 10 | -- "jinja", | 10 | -- "jinja", |
| 11 | -- "jinja_inline", | 11 | -- "jinja_inline", |
| 12 | "jq", | 12 | "jq", |
| 13 | "json", -- deckt auch den Dateityp jsonc ab (siehe lua/config/filetypes.lua) | 13 | "json", -- deckt auch den Dateityp jsonc ab (siehe extra_filetypes) |
| 14 | "lua", | 14 | "lua", |
| 15 | "make", | 15 | "make", |
| 16 | "markdown", | 16 | "markdown", |
| 17 | "markdown_inline", | 17 | "markdown_inline", -- kein eigener Dateityp, nur fuer Injections in Markdown |
| 18 | "po", | 18 | "po", |
| 19 | "powershell", | 19 | "powershell", |
| 20 | "prisma", | 20 | "prisma", |
| @@ -27,4 +27,43 @@ M.languages = { | |||
| 27 | "zsh", | 27 | "zsh", |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | -- Filetypes ohne gleichnamigen Parser, samt Parser, den sie nutzen sollen. | ||
| 31 | local extra_filetypes = { | ||
| 32 | -- nvim-treesitter stellt keinen jsonc-Parser bereit; der json-Parser | ||
| 33 | -- versteht // und /* */ Kommentare. | ||
| 34 | jsonc = "json", | ||
| 35 | |||
| 36 | -- Dateityp und Parser heissen unterschiedlich; ohne diese Zuordnung findet | ||
| 37 | -- vim.treesitter.start() keinen Parser und die FileType-Autocmd feuert nicht. | ||
| 38 | sh = "bash", | ||
| 39 | ps1 = "powershell", | ||
| 40 | |||
| 41 | -- Zusammengesetzter Dateityp aus config.filetypes: den Parser loest Neovim | ||
| 42 | -- selbst am Punkt auf, der Eintrag sorgt aber fuer das Autocmd-Pattern -- | ||
| 43 | -- Patterns splitten nicht, "yaml" wuerde fuer "yaml.ansible" nicht feuern. | ||
| 44 | ["yaml.ansible"] = "yaml", | ||
| 45 | } | ||
| 46 | |||
| 47 | -- Macht die Parser der Filetypes ohne gleichnamigen Parser bekannt. | ||
| 48 | function M.register_extra_filetypes() | ||
| 49 | for filetype, parser in pairs(extra_filetypes) do | ||
| 50 | vim.treesitter.language.register(parser, filetype) | ||
| 51 | end | ||
| 52 | end | ||
| 53 | |||
| 54 | -- Filetypes, fuer die Treesitter-Features aktiviert werden. | ||
| 55 | function M.filetypes() | ||
| 56 | local filetypes = {} | ||
| 57 | |||
| 58 | for _, language in ipairs(M.languages) do | ||
| 59 | table.insert(filetypes, language) | ||
| 60 | end | ||
| 61 | |||
| 62 | for filetype in pairs(extra_filetypes) do | ||
| 63 | table.insert(filetypes, filetype) | ||
| 64 | end | ||
| 65 | |||
| 66 | return filetypes | ||
| 67 | end | ||
| 68 | |||
| 30 | return M | 69 | return M |
diff --git a/nvim/lua/plugins/format.lua b/nvim/lua/plugins/format.lua index 476e513..a8d63b8 100644 --- a/nvim/lua/plugins/format.lua +++ b/nvim/lua/plugins/format.lua | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | -- Verfügbare Formater: https://github.com/stevearc/conform.nvim/tree/master/lua/conform/formatters | 1 | -- Verfügbare Formater: https://github.com/stevearc/conform.nvim/tree/master/lua/conform/formatters |
| 2 | 2 | ||
| 3 | local clang = {} | 3 | local clang = {} -- absichtlich leer: c und cpp formatiert clangd, siehe default_format_opts.lsp_format |
| 4 | local djlint = { "djlint" } -- pipx install djlint (macOS & FreeBSD); unter Windows kein winget-Paket, siehe neovim-windows-setup.md | 4 | local djlint = { "djlint" } -- pipx install djlint (macOS & FreeBSD); unter Windows kein winget-Paket, siehe neovim-windows-setup.md |
| 5 | local gawk = { "gawk" } -- brew install gawk, pkg install gawk | 5 | local gawk = { "gawk" } -- brew install gawk, pkg install gawk |
| 6 | local jq = { "jq" } -- brew install jq, pkg install jq | 6 | local jq = { "jq" } -- brew install jq, pkg install jq |
| @@ -27,7 +27,6 @@ return { | |||
| 27 | opts = { | 27 | opts = { |
| 28 | formatters_by_ft = { | 28 | formatters_by_ft = { |
| 29 | awk = gawk, | 29 | awk = gawk, |
| 30 | bash = shfmt, | ||
| 31 | c = clang, | 30 | c = clang, |
| 32 | cpp = clang, | 31 | cpp = clang, |
| 33 | html = prettier, | 32 | html = prettier, |
| @@ -46,7 +45,7 @@ return { | |||
| 46 | formatters = { | 45 | formatters = { |
| 47 | prettier_jsonc = { | 46 | prettier_jsonc = { |
| 48 | inherit = "prettier", | 47 | inherit = "prettier", |
| 49 | prepend_args = { "--parser", "jsonc" }, | 48 | prepend_args = { "--parser", "jsonc", "--trailing-comma", "none" }, |
| 50 | }, | 49 | }, |
| 51 | }, | 50 | }, |
| 52 | default_format_opts = { | 51 | default_format_opts = { |
diff --git a/nvim/lua/plugins/git.lua b/nvim/lua/plugins/git.lua index ed7bafe..b865864 100644 --- a/nvim/lua/plugins/git.lua +++ b/nvim/lua/plugins/git.lua | |||
| @@ -10,7 +10,7 @@ return { | |||
| 10 | }, | 10 | }, |
| 11 | config = function(_, opts) | 11 | config = function(_, opts) |
| 12 | require("gitsigns").setup(opts) | 12 | require("gitsigns").setup(opts) |
| 13 | require("config.keymaps").gitsigns() | 13 | require("config.keymaps").set_gitsigns() |
| 14 | end, | 14 | end, |
| 15 | }, | 15 | }, |
| 16 | } | 16 | } |
diff --git a/nvim/lua/plugins/lint.lua b/nvim/lua/plugins/lint.lua new file mode 100644 index 0000000..2bfcfc7 --- /dev/null +++ b/nvim/lua/plugins/lint.lua | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | -- Verfügbare Linter: https://github.com/mfussenegger/nvim-lint/tree/master/lua/lint/linters | ||
| 2 | -- | ||
| 3 | -- Hier gehören nur Linter hinein, die kein Sprachserver ohnehin schon meldet: | ||
| 4 | -- shellcheck läuft in bashls, clang-tidy in clangd, ansible-lint in ansiblels. | ||
| 5 | |||
| 6 | local ruff = { "ruff" } -- bereits als Formatter installiert, siehe plugins/format.lua | ||
| 7 | local yamllint = { "yamllint" } -- brew install yamllint, pkg install devel/py-yamllint | ||
| 8 | local zsh = { "zsh" } -- kein zusätzliches Werkzeug: ruft `zsh --no-exec` auf | ||
| 9 | |||
| 10 | return { | ||
| 11 | "mfussenegger/nvim-lint", | ||
| 12 | event = { "BufReadPre", "BufNewFile" }, | ||
| 13 | config = function() | ||
| 14 | local lint = require("lint") | ||
| 15 | |||
| 16 | lint.linters_by_ft = { | ||
| 17 | -- ergänzt die Typprüfung von basedpyright um die Lint-Regeln (F, E, UP, B ...) | ||
| 18 | python = ruff, | ||
| 19 | -- kein Sprachserver für YAML im Einsatz; Regeln kommen aus .yamllint des Projekts | ||
| 20 | yaml = yamllint, | ||
| 21 | -- Syntaxprüfung ohne Ausführung; bashls deckt nur sh und bash ab | ||
| 22 | zsh = zsh, | ||
| 23 | } | ||
| 24 | |||
| 25 | vim.api.nvim_create_autocmd({ "BufReadPost", "BufWritePost", "InsertLeave" }, { | ||
| 26 | callback = function() | ||
| 27 | lint.try_lint() | ||
| 28 | end, | ||
| 29 | }) | ||
| 30 | end, | ||
| 31 | } | ||
diff --git a/nvim/lua/plugins/lsp.lua b/nvim/lua/plugins/lsp.lua index a2b37d5..e0ad450 100644 --- a/nvim/lua/plugins/lsp.lua +++ b/nvim/lua/plugins/lsp.lua | |||
| @@ -34,10 +34,6 @@ return { | |||
| 34 | }, | 34 | }, |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | vim.lsp.config.bashls = { | ||
| 38 | filetypes = { "sh", "bash" }, | ||
| 39 | } | ||
| 40 | |||
| 41 | vim.lsp.config.clangd = { | 37 | vim.lsp.config.clangd = { |
| 42 | cmd = { | 38 | cmd = { |
| 43 | "clangd", | 39 | "clangd", |
| @@ -98,7 +94,7 @@ return { | |||
| 98 | } | 94 | } |
| 99 | 95 | ||
| 100 | vim.lsp.config.ansiblels = { | 96 | vim.lsp.config.ansiblels = { |
| 101 | filetypes = { require("config.filetypes").ANSIBLE_YAML }, | 97 | filetypes = { "yaml.ansible" }, -- Erkennung: siehe config.filetypes |
| 102 | settings = { | 98 | settings = { |
| 103 | ansible = { | 99 | ansible = { |
| 104 | validation = { | 100 | validation = { |
| @@ -112,7 +108,7 @@ return { | |||
| 112 | } | 108 | } |
| 113 | 109 | ||
| 114 | vim.lsp.enable({ | 110 | vim.lsp.enable({ |
| 115 | "ansiblels", -- npm install -g @ansible/ansible-language-server & (brew install ansible-lint, pkg install py-ansible-lint) | 111 | "ansiblels", -- npm install -g @ansible/ansible-language-server & (brew install ansible-lint, pkg install sysutils/py-ansible-lint) |
| 116 | "basedpyright", -- npm install -g basedpyright, brew install basedpyright | 112 | "basedpyright", -- npm install -g basedpyright, brew install basedpyright |
| 117 | "bashls", -- npm install -g bash-language-server, pkg install hs-ShellCheck | 113 | "bashls", -- npm install -g bash-language-server, pkg install hs-ShellCheck |
| 118 | "clangd", -- pkg install llvm | 114 | "clangd", -- pkg install llvm |
diff --git a/nvim/lua/plugins/ui.lua b/nvim/lua/plugins/ui.lua index 39a8e28..a308fc8 100644 --- a/nvim/lua/plugins/ui.lua +++ b/nvim/lua/plugins/ui.lua | |||
| @@ -17,27 +17,27 @@ return { | |||
| 17 | 17 | ||
| 18 | vscode.load() | 18 | vscode.load() |
| 19 | 19 | ||
| 20 | -- eigene Anpassungen an der vscode-Palette; muessen nach vscode.load() | 20 | -- eigene Anpassungen an der vscode-Palette |
| 21 | -- gesetzt werden, weil :colorscheme alle Highlight-Gruppen zuruecksetzt | 21 | local set_hl = vim.api.nvim_set_hl |
| 22 | 22 | ||
| 23 | -- Fix: Farbschema für Rechtschreibfehler | 23 | -- Fix: Farbschema für Rechtschreibfehler |
| 24 | vim.api.nvim_set_hl(0, "SpellBad", { fg = "#ffffff", bg = "#5f0000" }) | 24 | set_hl(0, "SpellBad", { fg = "#ffffff", bg = "#5f0000" }) |
| 25 | vim.api.nvim_set_hl(0, "SpellCap", { fg = "#000000", bg = "#ffaf00" }) | 25 | set_hl(0, "SpellCap", { fg = "#000000", bg = "#ffaf00" }) |
| 26 | vim.api.nvim_set_hl(0, "SpellRare", { fg = "#000000", bg = "#5fd7ff" }) | 26 | set_hl(0, "SpellRare", { fg = "#000000", bg = "#5fd7ff" }) |
| 27 | vim.api.nvim_set_hl(0, "SpellLocal", { fg = "#000000", bg = "#5fff87" }) | 27 | set_hl(0, "SpellLocal", { fg = "#000000", bg = "#5fff87" }) |
| 28 | vim.api.nvim_set_hl(0, "CursorLine", { bg = "#252526" }) | 28 | set_hl(0, "CursorLine", { bg = "#252526" }) |
| 29 | vim.api.nvim_set_hl(0, "CursorColumn", { bg = "#252526" }) | 29 | set_hl(0, "CursorColumn", { bg = "#252526" }) |
| 30 | 30 | ||
| 31 | -- Statusline Farben | 31 | -- Statusline Farben |
| 32 | vim.api.nvim_set_hl(0, "StatuslineModeNormal", { fg = "#1e222a", bg = "#61afef", bold = true }) | 32 | set_hl(0, "StatuslineModeNormal", { fg = "#1e222a", bg = "#61afef", bold = true }) |
| 33 | vim.api.nvim_set_hl(0, "StatuslineModeInsert", { fg = "#1e222a", bg = "#98c379", bold = true }) | 33 | set_hl(0, "StatuslineModeInsert", { fg = "#1e222a", bg = "#98c379", bold = true }) |
| 34 | vim.api.nvim_set_hl(0, "StatuslineModeVisual", { fg = "#1e222a", bg = "#c678dd", bold = true }) | 34 | set_hl(0, "StatuslineModeVisual", { fg = "#1e222a", bg = "#c678dd", bold = true }) |
| 35 | vim.api.nvim_set_hl(0, "StatuslineModeReplace", { fg = "#1e222a", bg = "#e86671", bold = true }) | 35 | set_hl(0, "StatuslineModeReplace", { fg = "#1e222a", bg = "#e86671", bold = true }) |
| 36 | vim.api.nvim_set_hl(0, "StatuslineModeCommand", { fg = "#1e222a", bg = "#e5c07b", bold = true }) | 36 | set_hl(0, "StatuslineModeCommand", { fg = "#1e222a", bg = "#e5c07b", bold = true }) |
| 37 | 37 | ||
| 38 | -- NVim-Tree | 38 | -- NVim-Tree |
| 39 | vim.api.nvim_set_hl(0, "NvimTreeOpenedFile", { bold = true }) | 39 | set_hl(0, "NvimTreeOpenedFile", { bold = true }) |
| 40 | vim.api.nvim_set_hl(0, "NvimTreeCursorLine", { bg = "#2A2D2E" }) | 40 | set_hl(0, "NvimTreeCursorLine", { bg = "#2A2D2E" }) |
| 41 | end, | 41 | end, |
| 42 | }, | 42 | }, |
| 43 | 43 | ||
