escapeSystemdPath relied on lib.strings.normalizePath, which only
collapses duplicate slashes and does not drop "." path components the
way systemd's path_simplify() does. A path like /mnt/./foo was thus
escaped to mnt-.-foo instead of mnt-foo, and systemd refused the
generated unit ("Where= setting doesn't match unit name").
Reimplement the simplification to match `systemd-escape --path` exactly:
drop "." and empty components, collapse a leading ".." run in an
absolute path to the root, and throw on any input systemd-escape
rejects (a non-leading "..", or a relative path that reduces to
nothing). Parity is checked against the systemd-escape binary over a
battery of edge cases and fuzzed inputs. While here, hoist the constant
escape table and partial applications out of the per-call lambda so
they are built once rather than on every call, making the function
~2.5x faster.
Resolves: https://github.com/NixOS/nixpkgs/issues/515270
Assisted-by: Claude:claude-opus-4-8
Previously, the tested plugin appeared in `rtp` under two paths:
- `/nix/store/<hash>-vimPlugins-my-plugin` from `$out`
- `/build/.local/share/nvim/site/pack/nvimRequireCheckHook/opt/testPlugin`
from `packadd testPlugin`
This was causing problems for plugins that use
`vim.api.nvim_get_runtime_file()`. For example, plugins that use
`blink.lib` to load rust modules fail the require check because
`blink.lib` uses this function to locate rust shared libraries and
raises an error when duplicate libraries are found.
The plugin is already loaded via `packadd testPlugin`, so adding `$out`
to `rtp` is unnecessary. Remove `$out` from `rtp` to avoid duplicate
runtime entries, and add a regression test to ensure the plugin appears
in `rtp` only once.
Co-authored-by: Austin Horstman <khaneliman12@gmail.com>