Open-Source Wikis

/

Neovim

/

Systems

/

OS and platform

neovim/neovim

OS and platform

Purpose

src/nvim/os/ is the platform-abstraction layer. It is the only directory in the C tree that knows about Unix vs Windows differences, ptys, environment variables, signal handling, and stdpaths. Everything above os/ calls into it through a uniform C interface; everything below is libuv plus a handful of platform-specific syscalls.

Directory layout

src/nvim/os/
├── defs.h, os.h, os_defs.h    Common types
├── unix_defs.h, win_defs.h    Per-platform typedefs
├── env.c                      Environment variable handling (35k bytes)
├── fs.c                       File-system primitives (40k bytes)
├── fileio.c                   Buffered file I/O
├── input.c                    Read input from stdin / TUI
├── lang.c                     Locale and language detection
├── proc.c                     Process info / signals
├── pty_proc_unix.c, _win.c    PTY implementations
├── pty_conpty_win.c           Windows conpty-specific
├── shell.c                    `:!cmd` and shell escaping (40k bytes)
├── signal.c                   SIGINT / SIGWINCH / SIGTERM
├── stdpaths.c                 XDG paths (config, data, state, cache, log, run)
├── time.c                     Wall clock + monotonic
├── users.c                    System user lookup
├── dl.c                       dlopen wrapper for `libcall()`
├── os_win_console.c           Windows console mode
└── nvim.{manifest,rc}         Win32 resource files

Key abstractions

Function family File Purpose
os_getenv, os_setenv, os_unsetenv env.c Environment access. Wraps libuv plus locale-aware logic.
os_fileinfo, os_path_exists, os_isdir fs.c Stat-like probes.
os_open, os_read, os_write, os_close fs.c File handle ops.
os_resolve_shortcut, os_realpath fs.c Path resolution.
os_call_shell, os_system shell.c Run an external program, optionally capture output.
os_get_hostname, os_get_pid various Lightweight info.
os_proc_* proc.c Process metadata (pid, parent, cwd).
pty_proc_* pty_proc_unix.c/_win.c Spawn a child under a pty (used by :terminal).
stdpaths_get_xdg_var, stdpaths_user_*_subpath stdpaths.c XDG-compliant data/config paths.
os_inchar input.c Block on stdin and return bytes.
os_breakcheck input.c Probe for pending CTRL-C without consuming a key.

How it works

The most-touched function on this list is os_breakcheck. It is what makes Neovim responsive to <C-c> even inside a long-running operation: a hot loop in the editor calls os_breakcheck() periodically, which polls libuv for a single byte and sets got_int if it sees <C-c>. Functions that may take a long time (regex, substitution, :edit of a huge file) bail out as soon as got_int becomes true.

The trade-off: any function that calls os_breakcheck() is not re-entrant. That is why API functions marked api-fast are forbidden from calling it. See Patterns and conventions.

Filesystem path policy

From runtime/doc/dev_arch.txt: forward slashes everywhere except at the edges. The conversion sites are:

  • src/nvim/path.c#slash_adjust — convert outgoing paths to native separators.
  • src/nvim/os/fs.c#FS_PATH calls — input from libuv.
  • src/nvim/path.c#path_to_absolute — combine with cwd.

Windows accepts forward slashes for nearly all syscalls anyway. The conversion exists to make user-visible output match platform conventions (e.g., :pwd prints \ on Windows).

stdpaths

os/stdpaths.c implements XDG Base Directory Specification on Linux/macOS and the Windows equivalent (using FOLDERID_RoamingAppData etc.) on Windows. The user-facing API is stdpath('config' | 'data' | 'cache' | 'state' | 'log' | 'run') in Vimscript and vim.fn.stdpath(...) in Lua. The same paths drive where Neovim looks for init.lua, where shada is written, and where $NVIM_LOG_FILE defaults.

ptys

pty_proc_unix.c opens /dev/ptmx, sets up the child controlling-tty, and spawns through libuv. pty_proc_win.c uses ConPTY (pty_conpty_win.c) on Windows 10+; older Windows fell back to winpty but that path has been removed.

:terminal, vim.system({pty=true}), and jobstart({pty=1}) all flow through these. The vendored libvterm in src/nvim/vterm/ is the in-process terminal emulator that interprets the bytes coming back; see Embedded terminal.

Shell execution

os/shell.c is the largest file in this directory (40 KB). It implements os_call_shell() and os_system() — the workhorses behind :!cmd, system(), systemlist(), and (historically) :make. The bulk of the file is shell-quoting and pipe-handling logic: every shell on every platform escapes arguments slightly differently.

Modern Lua-side code prefers vim.system({argv}) (runtime/lua/vim/_core/system.lua) which spawns directly via libuv and skips the shell entirely.

Integration points

  • Event loop — every async syscall goes through libuv. The OS layer just provides the convenience wrappers.
  • Buffer I/Obufwrite.c and fileio.c call into os/fs.c for the actual reads/writes.
  • :terminal — combines os/pty_proc_*.c + src/nvim/terminal.c + src/nvim/vterm/.
  • Lua vim.fsruntime/lua/vim/fs.lua wraps a subset of os/fs.c plus libuv FS functions for plugin authors.
  • vim.systemruntime/lua/vim/_core/system.lua is the Lua front end to os/proc.c + libuv.

Entry points for modification

  • A new platform-abstracted call: add it to src/nvim/os/<area>.c with a stub for the other platform. The naming convention is os_<verb>_<noun>.
  • A new XDG path: edit os/stdpaths.c and add the corresponding XDG_<NAME>_HOME enum.
  • A new shell quirk: most likely a one-line change in os/shell.c; the file's structure is "switch on the user's shell, escape accordingly".

Key source files

File Purpose
src/nvim/os/fs.c File-system primitives (open/read/write/stat/realpath)
src/nvim/os/env.c Environment variable handling and locale-aware lookups
src/nvim/os/shell.c External shell invocation, quoting, capture
src/nvim/os/input.c Stdin reader, os_breakcheck
src/nvim/os/proc.c Process metadata and signals
src/nvim/os/pty_proc_unix.c Unix pty spawning
src/nvim/os/pty_proc_win.c Windows ConPTY spawning
src/nvim/os/stdpaths.c XDG path resolution
src/nvim/os/time.c Wall clock + monotonic helpers
src/nvim/os/dl.c dlopen wrapper for libcall()
src/nvim/os/signal.c Process signal handlers

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

OS and platform – Neovim wiki | Factory