Skip to content

fix: support fuse-t on macOS - #20

Merged
uhs-robert merged 9 commits into
mainfrom
fix/fuse-t-macos
Sep 11, 2026
Merged

uhs-robert merged 9 commits into
mainfrom
fix/fuse-t-macos

Conversation

@uhs-robert

@uhs-robert uhs-robert commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses #19 by adding compatibility for fuse-t's NFS-backed SSHFS mounts and its SSHFS 2.9 option names.

  • detect fuse-t:/... (nfs, ...) mounts in the system mount table
  • represent fuse-t mounts with remote_metadata_available = false when the original SSH host/path cannot be recovered
  • fall back to mounted-path find/grep instead of attempting remote SSH operations with inferred metadata
  • apply the same fallback to hooks.on_mount.auto_run = "live_find" / "live_grep"
  • refuse SSH terminal actions cleanly when remote host metadata is unavailable rather than attempting SSH with display-only fallback metadata
  • detect the installed SSHFS major version and translate the existing 3.x cache configuration to 2.x names when needed
    • dir_cachecache
    • dcache_timeoutcache_timeout
    • dcache_max_sizecache_max_size
  • preserve explicitly configured 2.x option values over translated values
  • warn once when SSHFS version detection fails instead of silently assuming 3.x names
  • move automatic cleanup from VimLeave to VimLeavePre
  • run unmount attempts synchronously so fuse-t cleanup completes before Neovim teardown
  • document macFUSE and fuse-t as supported macOS options

Architecture

System mount state remains authoritative for whether a mount exists. The existing lockfile remains responsible only for tracking Neovim process ownership/reference counting; this avoids conflating mount discovery with process coordination.

fuse-t's NFS mount table does not preserve the original SSH remote specification. Rather than inventing authoritative host/path data or introducing a persistent mount registry in this compatibility fix, active fuse-t mounts expose that limitation through remote_metadata_available = false. Operations with a mounted-filesystem equivalent fall back to the mounted path; SSH-terminal actions refuse cleanly because they require a real remote host.

Testing

Automated regression coverage is included, on top of the shared harness from #25. Run it with make test.

  • fuse-t mount detection through both mount and findmnt, alongside Linux fuse.sshfs and macFUSE output
  • fuse-t mounts expose remote_metadata_available = false, keep remote_path unset rather than inventing /, and do not error on a missing remote spec
  • unrelated NFS mounts under the base directory are excluded
  • live find/grep and the on_mount auto_run presets fall back to mounted-path operations without remote metadata
  • SSH terminal actions refuse rather than dialing the mount directory name as a host
  • SSHFS 3.x options stay unchanged; 2.x translates dir_cache/dcache_timeout/dcache_max_size, with explicit 2.x values winning
  • version probe failures (unparseable, non-zero exit, missing binary) warn once and never raise
  • synchronous unmounting with its clean, lazy and force escalation order
  • VimLeavePre registration for the exit hook

This remains a draft pending validation on real hardware with fuse-t + fuse-t-sshfs, which the unit suite deliberately does not simulate.

Closes #19

Wrap the `sshfs --version` wait in a 2 second timeout so a hung binary
cannot block Neovim indefinitely, and parse the version from combined
stdout/stderr regardless of exit code, since some builds report the
version on stderr or exit non-zero. Also apply stylua formatting.
The findmnt branch queried only fuse.sshfs and returned early on success,
so any fuse-t mount was missed whenever findmnt was installed. Query
fuse.sshfs and nfs together, request FSTYPE ahead of TARGET so the target
stays the greedy trailing field, and classify each row: a fuse-t source
yields a mount without remote metadata, fuse.sshfs keeps its remote spec,
and unrelated NFS mounts are skipped.
Adds the regression suite issue #24 lists for this PR, on top of the
shared harness.

Covers fuse-t mount detection through both `mount` and `findmnt`, the
absence of remote metadata (no invented remote path, display-only host
fallback, no error on a missing remote spec), and the exclusion of
unrelated NFS mounts. Covers the metadata-aware fallbacks: live
find/grep and the on_mount auto_run presets drop to mounted-path
operations, while SSH terminal actions refuse rather than dialing the
mount directory name as a host.

Covers SSHFS option translation for 2.x implementations, including
untouched 3.x options, explicit 2.x values winning over translated
ones, and the three version-probe failure modes.

Covers synchronous unmounting with its clean, lazy, and force
escalation order, and the move of the exit hook to VimLeavePre.

The two baseline mount parsing fixtures are updated for the fields and
findmnt columns this PR introduces.

Refs #24
uhs-robert added a commit that referenced this pull request Aug 31, 2026
The assertion that SSHTest never runs sshfs was too broad. Once the
fuse-t work in #20 lands, build_mount_command probes `sshfs --version`
to decide whether to render 3.x or 2.x cache option names, so the
preflight legitimately spawns sshfs without mounting anything. Narrow
the assertion to what it was meant to catch: an actual mount.
# Conflicts:
#	lua/sshfs/lib/sshfs.lua
A failed sshfs --version probe was cached for the whole session, so one
timeout silently disabled fuse-t option translation until restart. A
"host:" remote spec also parsed to an empty path, which is truthy in Lua
and so slipped past every `remote_path or "."` fallback.
The suite stubs OS calls, so this mainly guards the few probes that shell
out for real and any future spec that forgets a stub. fuse-t itself still
needs a real machine.
@uhs-robert
uhs-robert marked this pull request as ready for review September 11, 2026 01:39
@uhs-robert
uhs-robert merged commit 54e7e10 into main Sep 11, 2026
3 checks passed
@uhs-robert
uhs-robert deleted the fix/fuse-t-macos branch September 11, 2026 01:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support fuse-t on macOS (NFS-backed mounts + sshfs 2.9 option names)

1 participant