Information Density: Neovim – Signal Evidence & AI Readability

Neovim

(https://neovim.io) 📸 Data Snapshot: May 24, 2026
Information Density — The Lens

Classify each sentence as substantive or hollow. Grounding markers — numbers, currencies, dates, technical units, named entities — outweigh marketing adjectives. When fluff sits right next to hard evidence, the fluff is forgiven.

Info Density Power-words vs. Substance ratio.
29 Impact Weight: 30 / 100
97% Reputation

The site exhibits extremely high information density, favoring technical specifications over power words. Headings like API Definitions and Buffer update events lead directly into granular technical data such as msgpack-rpc constraints and C99 standard types (int64_t, double). The body text is almost entirely devoid of generic marketing fluff, instead providing specific metrics like 30 percent less source-code than Vim. There is virtually no heading saturation with industry buzzwords; every [H2] and [H3] serves as a functional anchor for technical content.

Information Density is read straight from the body copy: how much of the text carries grounded, checkable substance versus hollow filler. Below is the clean text the engine analyzed, then the industry’s known generic-claim patterns to weigh it against.

📝 The Narrative — clean text per page (the substance-vs-filler signal)
HOMEPAGE · THIN (https://neovim.io) Neovim
[H2] FAQ
What is the project status?
The current stable release
version is 0.12 (RSS). See the
roadmap for progress and plans.
Is Neovim trying to turn Vim into an IDE?
With 30% less source-code than Vim, the vision of Neovim is to
enable new applications without compromising Vim’s traditional roles.
Will Neovim deprecate Vimscript?
No. Lua is built-in, but Vimscript is supported with the world’s most advanced
Vimscript engine.
Which plugins does Neovim support?
Vim 8.x plugins and much
more.

[H2] GUIs
Neovim UIs are “inverted plugins”. Here are some popular ones:
Firenvim (Nvim in your web
browser!)
vscode-neovim (Nvim
in VSCode!)
Neovide
Goneovim
GNvim (GTK4)
FVim
Nvy
Neovim Qt (Qt5)
VimR (macOS)
More…
717 chars
SUB-PAGE (https://neovim.io/doc/user/api/) Api – Neovim docs
[H1] Api

Nvim :help pages, generated
from source
using the tree-sitter-vimdoc parser.

Nvim API api
Nvim exposes a powerful API that can be used by plugins and external processes
via RPC, Lua and Vimscript (eval-api).
Applications can also embed libnvim to work with the C API directly.
[H2] API Usage api-rpc RPC rpc
msgpack-rpc
RPC is the main way to control Nvim programmatically. Nvim implements the
MessagePack-RPC protocol with these extra (out-of-spec) constraints:
Responses must be given in reverse order of requests (like "unwinding
a stack").
Nvim processes all messages (requests and notifications) in the order they
are received.
MessagePack-RPC specification:
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
https://github.com/msgpack/msgpack/blob/0b8f5ac/spec.md
Many clients use the API: user interfaces (GUIs), remote plugins, scripts like
"nvr" (https://github.com/mhinz/neovim-remote). Even Nvim itself can control
other Nvim instances. API clients can:
Call any API function
Listen for events
Receive remote calls from Nvim
The RPC API is like a more powerful version of Vim's "clientserver" feature.
[H3] CONNECTING rpc-connecting
See channel-intro for various ways to open a channel. Channel-opening
functions take an rpc key in the options dict. RPC channels can also be
opened by other processes connecting to TCP/IP sockets or named pipes listened
to by Nvim.
Nvim creates a default RPC socket at startup, given by v:servername. To
start with a TCP/IP socket instead, use --listen with a TCP-style address:nvim --listen 127.0.0.1:6666
More endpoints can be started with serverstart().
Note that localhost TCP sockets are generally less secure than named pipes,
and can lead to vulnerabilities like remote code execution.
Connecting to the socket is the easiest way a programmer can test the API,
which can be done through any msgpack-rpc client library or full-featured
api-client. Here's a Ruby script that prints "hello world!" in the current
Nvim instance:
#!/usr/bin/env ruby
# Requires msgpack-rpc: gem install msgpack-rpc
#
# To run this script, use Nvim's built-in terminal emulator:
#
# :term ./hello.rb
#
# Or from another shell by setting NVIM:
# $ NVIM=[address] ./hello.rb
require 'msgpack/rpc'
require 'msgpack/rpc/transport/unix'
nvim = MessagePack::RPC::Client.new(MessagePack::RPC::UNIXTransport.new, ENV['NVIM'])
result = nvim.call(:nvim_command, 'echo "hello world!"')
A better way is to use the Python REPL with the "pynvim" package, where API
functions can be called interactively:
>>> from pynvim import attach
>>> nvim = attach('socket', path='[address]')
>>> nvim.command('echo "hello world!"')
You can also embed Nvim via jobstart(), and communicate using rpcrequest()
and rpcnotify():
let nvim = jobstart(['nvim', '--embed'], {'rpc': v:true})
echo rpcrequest(nvim, 'nvim_eval', '"Hello " . "world!"')
call jobstop(nvim)
[H2] API Definitions api-definitions
api-types
The Nvim C API defines custom types for all function parameters. Some are just
typedefs around C99 standard types, others are Nvim-defined data structures.
Basic types
API Type C type
------------------------------------------------------------------------
Nil
Boolean bool
Integer (signed 64-bit integer) int64_t
Float (IEEE 754 double precision) double
String {char* data, size_t size} struct
Array kvec
Dict (msgpack: map) kvec
Object any of the above
Note:
Empty Array is accepted as a valid Dictionary parameter.
Functions cannot cross RPC boundaries. But API functions (e.g.
nvim_create_autocmd()) may support Lua function parameters for non-RPC
invocations.
Special types (msgpack EXT)
These are integer typedefs discriminated as separate Object subtypes. They
can be treated as opaque integers, but are mutually incompatible: Buffer may
be passed as an integer but not as Window or Tabpage.
The EXT object data is the (integer) object handle. The EXT type codes given
in the api-metadata types key are stable: they will not change and are
thus forward-compatible.
EXT Type C type Data
------------------------------------------------------------------------
Buffer enum value kObjectTypeBuffer |bufnr()|
Window enum value kObjectTypeWindow |window-ID|
Tabpage enum value kObjectTypeTabpage internal handle
api-indexing
Most of the API uses 0-based indices, and ranges are end-exclusive. For the
end of a range, -1 denotes the last line/column.
Exception: the following API functions use "mark-like" indexing (1-based
lines, 0-based columns):
nvim_get_mark()
nvim_buf_get_mark()
nvim_buf_set_mark()
nvim_win_get_cursor()
nvim_win_set_cursor()
Exception: the following API functions use extmarks indexing (0-based
indices, end-inclusive):
nvim_buf_del_extmark()
nvim_buf_get_extmark_by_id()
nvim_buf_get_extmarks()
nvim_buf_set_extmark()
api-fast deferred schedule
Most API functions are deferred: they are queued ("scheduled") on the main
loop and processed sequentially with normal input. If the editor is waiting
for user input in a "modal" fashion (e.g. an input() prompt), a deferred
request will block.
Non-deferred (fast) functions such nvim_get_mode(), nvim_input(), or any
Lua callback, are executed immediately (not sequenced in the input queue).
Lua code can use vim.in_fast_event() to detect a fast context, where it
may interact with Lua state but not "editor" state (textlock, options,
window layout, …).
To perform editor operations, Lua code must schedule via vim.defer_fn() or
vim.schedule(), or wait until vim.in_fast_event() returns false.
[H2] API metadata api-metadata
The Nvim C API is automatically exposed to RPC by the build system, which
parses headers in src/nvim/api/* and generates dispatch-functions mapping RPC
API method names to public C API functions, converting/validating arguments
and return values.
Nvim exposes its API metadata as a Dictionary with these items:
version Nvim version, API level/compatibility
version.api_level API version integer api-level
version.api_compatible API is backwards-compatible with this level
version.api_prerelease Declares the API as unstable/unreleased
(version.api_prerelease && fn.since == version.api_level)
functions API function signatures, containing api-types info
describing the return value and parameters.
ui_events UI event signatures
ui_options Supported ui-options
{fn}.since API level where function {fn} was introduced
{fn}.deprecated_since API level where function {fn} was deprecated
types Custom handle types defined by Nvim
error_types Possible error types returned by API functions
About the functions map:
Container types may be decorated with type/size constraints, e.g.
ArrayOf(Buffer) or ArrayOf(Integer, 2).
Functions considered to be methods that operate on instances of Nvim
special types (msgpack EXT) have the "method=true" flag. The receiver type
is that of the first argument. Method names are prefixed with nvim_ plus
a type name, e.g. nvim_buf_get_lines is the get_lines method of
a Buffer instance. dev-api
Global functions have the "method=false" flag and are prefixed with just
nvim_, e.g. nvim_list_bufs.
api-mapping
External programs (clients) can use the metadata to discover the API, using
any of these approaches:
Connect to a running Nvim instance and call nvim_get_api_info() via
msgpack-RPC. This is best for clients written in dynamic languages which
can define functions at runtime.
Use the --api-info startup arg. Useful for statically-compiled clients.
Example (requires Python "pyyaml" and "msgpack-python" modules):nvim --api-info | python -c 'import msgpack, sys, yaml; yaml.dump(msgpack.unpackb(sys.stdin.buffer.read()), sys.stdout)'
Use the api_info() function.
:lua vim.print(vim.fn.api_info())
" Example using filter() to exclude non-deprecated API functions:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val.name')
[H2] API contract api-contract
The Nvim API is composed of functions and events.
Clients call functions like those described at api-global.
Clients can subscribe to ui-events, api-buffer-updates, etc.
API function names are prefixed with "nvim_".
API event names are prefixed with "nvim_" and suffixed with "_event".
As Nvim evolves the API may change in compliance with this CONTRACT:
New functions and events may be added.
Any such extensions are OPTIONAL: old clients may ignore them.
New functions MAY CHANGE before release. Clients can dynamically check
api_prerelease, api-metadata.
Function signatures will NOT CHANGE after release, except as follows:
Map/list parameters/results may be EXTENDED (new fields may be added).
Such new fields are OPTIONAL: old clients MAY ignore them.
Existing fields will not be removed.
Return type MAY CHANGE from void to non-void. Old clients MAY ignore the
new return value.
An optional opts parameter may be ADDED.
Optional parameters may be ADDED following an opts parameter.
Event parameters will not be removed or reordered (after release).
Events may be EXTENDED: new parameters may be added.
Deprecated functions will not be removed until Nvim 2.0.
"Private" interfaces are NOT covered by this contract:
Undocumented (not in :help) functions or events of any kind
nvim__x ("double underscore") functions
The idea is "versionless evolution", in the words of Rich Hickey:
Relaxing a requirement should be a compatible change.
Strengthening a promise should be a compatible change.
[H2] Buffer update events api-buffer-updates
API clients can "attach" to Nvim buffers to subscribe to buffer update events.
This is similar to TextChanged but more powerful and granular.
Call nvim_buf_attach() to receive these events on the channel:
nvim_buf_lines_event
nvim_buf_lines_event[{buf}, {changedtick}, {firstline}, {lastline}, {linedata}, {more}]
When the buffer text between {firstline} and {lastline} (end-exclusive,
zero-indexed) were changed to the new text in the {linedata} list. The
granularity is a line, i.e. if a single character is changed in the
editor, the entire line is sent.
When {changedtick} is v:null this means the screen lines (display)
changed but not the buffer contents. {linedata} contains the changed
screen lines. This happens when 'inccommand' shows a buffer preview.
Parameters:
{buf} (integer) Buffer id
{changedtick} (integer) Value of b:changedtick. If you send an API
command back to Nvim you can check b:changedtick as
part of your request to ensure that no other changes
have been made.
{firstline} (integer) The first line that was replaced.
Zero-indexed: if line 1 was replaced then {firstline}
will be zero, not one. Always less than or equal to
the number of lines that were in the buffer before the
lines were replaced.
{lastline} (integer) The first line that was not replaced (i.e.
the range {firstline}, {lastline} is end-exclusive).
Zero-indexed: if line numbers 2 to 5 were replaced,
this will be 5 instead of 6. Always less than or equal
to the number of lines that were in the buffer before
the lines were replaced. Will be -1 if the event is
part of the initial update after attaching.
{linedata} (string[]) Contents of the new buffer lines. Newline
characters are omitted; empty lines are sent as empty
strings.
{more} (boolean) true for a "multipart" change notification:
the current change was chunked into multiple
nvim_buf_lines_event notifications (e.g. because it
was too big).
nvim_buf_changedtick_event[{buf}, {changedtick}] nvim_buf_changedtick_event
When b:changedtick was incremented but no text was changed. Relevant for
undo/redo.
Parameters:
{buf} (integer) Buffer id
{changedtick} (integer) New value of b:changedtick.
nvim_buf_detach_event[{buf}] nvim_buf_detach_event
When buffer is detached (i.e. updates are disabled). Triggered explicitly by
nvim_buf_detach() or implicitly in these cases:
Buffer was abandoned and 'hidden' is not set.
Buffer was reloaded, e.g. with :edit or an external change triggered
:checktime or 'autoread'.
Generally: whenever the buffer contents are unloaded from memory.
Parameters:
{buf} (integer) Buffer id
EXAMPLE
Calling nvim_buf_attach() with send_buffer=true on an empty buffer, emits:nvim_buf_lines_event[{buf}, {changedtick}, 0, -1, [""], v:false]
User adds two lines to the buffer, emits:nvim_buf_lines_event[{buf}, {changedtick}, 0, 0, ["line1", "line2"], v:false]
User moves to a line containing the text "Hello world" and inserts "!", emits:nvim_buf_lines_event[{buf}, {changedtick}, {linenr}, {linenr} + 1,
["Hello world!"], v:false]
User moves to line 3 and deletes 20 lines using "20dd", emits:nvim_buf_lines_event[{buf}, {changedtick}, 2, 22, [], v:false]
User selects lines 3-5 using linewise-visual mode and then types "p" to
paste a block of 6 lines, emits:nvim_buf_lines_event[{buf}, {changedtick}, 2, 5,
['pasted line 1', 'pasted line 2', 'pasted line 3', 'pasted line 4',
'pasted line 5', 'pasted line 6'],
v:false
]
User reloads the buffer with ":edit", emits:nvim_buf_detach_event[{buf}]
LUA
api-buffer-updates-lua
In-process plugins can receive buffer updates via Lua callbacks. These
callbacks are called frequently in various contexts; textlock prevents
changing buffer contents and window layout (such operations must be
scheduled). Moving the cursor is allowed, but it is restored afterwards.
nvim_buf_attach() will take keyword args for the callbacks. "on_lines" will
receive parameters ("lines", {buf}, {changedtick}, {firstline}, {lastline},
{new_lastline}, {old_byte_size} [, {old_utf32_size}, {old_utf16_size}]).
Unlike remote channel events the text contents are not passed. The new text can
be accessed inside the callback as
vim.api.nvim_buf_get_lines(buf, firstline, new_lastline, true)
{old_byte_size} is the total size of the replaced region {firstline} to
{lastline} in bytes, including the final newline after {lastline}. if
utf_sizes is set to true in nvim_buf_attach() keyword args, then the
UTF-32 and UTF-16 sizes of the deleted region is also passed as additional
arguments {old_utf32_size} and {old_utf16_size}.
"on_changedtick" is invoked when b:changedtick was incremented but no text
was changed. The parameters received are ("changedtick", {buf}, {changedtick}).
api-lua-detach
In-process Lua callbacks can detach by returning true. This will detach all
callbacks attached with the same nvim_buf_attach() call.
[H2] Buffer highlighting api-highlights
Nvim allows plugins to add position-based highlights to buffers. This is
similar to matchaddpos() but with some key differences. The added highlights
are associated with a buffer and adapts to line insertions and deletions,
similar to signs. It is also possible to manage a set of highlights as a group
and delete or replace all at once.
The intended use case are linter or semantic highlighter plugins that monitor
a buffer for changes, and in the background compute highlights to the buffer.
Another use case are plugins that show output in an append-o
15000 chars
SUB-PAGE (https://neovim.io/sponsors/) Sponsors – Neovim
[H1] Sponsor Neovim
Donate to Neovim
[H2] 100% of funds go to development
We don't have an "administrative" staff. Funding goes directly to software development.

[H2] Funds are managed by OpenCollective

Email: [email protected]
Open Source Collective 501(c)(6)
EIN: 82-2037583
440 N Barranca Ave #3939 Covina, CA 91723 United States
[email protected]
Details
You can also donate via GitHub Sponsors,
which will be routed to OpenCollective.
[H2] How are funds used?

Funding makes it possible for core developers to work full-time for
a month or longer, accelerating projects like Lua stdlib, treesitter
parser engine, LSP framework, extended marks, embedded terminal, job
control, RPC API, and remote UIs.
We have minimal infrastructure costs, which are funded from
non-sponsor sources such as the Store.
Those sources are routed to OpenCollective, so expenses will show up in OpenCollective.
[H2] What is expected of a funded contributor?

Funded work is a way to support active contributors who have weeks of time to focus on the
project. This opportunity is available to contributors who have a developed a reputation for
reliable, high-quality contributions (code/documentation, GitHub review comments, and GitHub
technical discussions; not IRC or other "ephemeral" places).
It works like this: funded contributors are expected to focus full-time for weeks or
even months, yielding tangible, high-quality contributions, with conspicuous, reliable,
regular activity on GitHub.

[H1] Sponsors

[IMG: Rizin]

[IMG: Route4Me Route Planner]

[H2] Original fundraiser sponsors

[IMG: Digital Ocean logo]

[IMG: SuperJer logo]

[IMG: Bountysource logo]

[IMG: Ryan Durk logo]
1739 chars
SUB-PAGE (https://neovim.io/charter/) Vision – Neovim
[H1] Vision
Neovim is a refactor, and sometimes redactor, in the tradition of Vim (which
itself derives from Stevie).
It is not a rewrite but a continuation and extension of Vim. Many clones and
derivatives exist, some very clever—but none are Vim. Neovim is built
for users who want the good parts of Vim, and more.
[H3] Goals
Extensible. Usable. Vim.
Retain the character of Vim—fast, versatile, quasi-minimal.
Enable new contributors, remove barriers to entry.
Unblock plugin authors.
Deliver a first-class Lua interface, as an alternative to Vimscript.
Favor composability (long-term thinking) instead of new, incompatible concepts (short-term thinking).
Leverage ongoing Vim development.
Optimize “out of the box”, for new users but especially regular users.
Deliver a consistent cross-platform experience, targeting all libuv-supported platforms.
In matters of taste/ambiguity, favor tradition/compatibility…
…but prefer usability if the benefits are extreme.
[H3] Non-goals
Support Vim9script
Turn Vim into an IDE
Limit third-party applications (such as IDEs!) built with Neovim
Deprecate Vimscript
Conform to POSIX vi
[H3] Project management
Maintainers: Neovim team
Maintainer notes: MAINTAIN.md

[H3] What is Neovim?
Neovim is a Vim-based text editor engineered for
extensibility
and usability,
to encourage new applications and
contributions.
Vision
Roadmap
[H3] Discuss
Visit
#neovim:matrix.org
or #neovim on irc.libera.chat to chat with the team.
Follow @Neovim on X
Mastodon
Bluesky
1498 chars
🧭 Industry Context — common generic-claim patterns in Software, SaaS & Tech Products to weigh the text against
Generic Claims: the all-in-one platform, trusted by thousands of companies, increase productivity by X percent, save hours every week, the leading platform for, built for teams of all sizes…
Red Flags: AI claims without explaining what the AI does, customer logos without case study or testimonial evidence, no live product access or demo, SOC 2 claims without audit period or report availability, productivity claims without methodology, pricing hidden behind sales calls only…
Semantic Drift Patterns: homepage claims AI-powered but product is rules-based, claims enterprise-grade but pricing page shows startup tiers only, homepage shows Fortune 500 logos but case studies are small businesses, claims all-in-one but integration page shows critical missing pieces, free plan promoted but core features require expensive upgrade…
Proof Expectations: live product demo or free trial access, specific feature documentation with screenshots, verified customer logos with published case studies, third-party review scores on G2, Capterra, or TrustRadius, published uptime SLA and status page, security certifications with audit dates…