Those who studied vim_dev
and the Vim source and docs, accumulated treasure
from a stream of copious messages and spare impressions. But also from what he
omitted: he never appealed to sensationalism or personal judgements.
Even when treated rudely, Bram usually responded only to advance his understanding of a problem to solve. Bram was one of those humans quietly providing deep value to the universe, but there was no parade and little celebrity.
Bram was anchored to reality, directly interested in results and adjusting what produced them. The “Problem/Solution” mantra in his commit messages is simple yet profoundly effective. He used that approach to help people in Uganda, managing resources directly instead of abstractly.
Bram’s principles (as I observed them) extended beyond mere technical craftsmanship. The ability to adopt a position of modesty is a mind-trick that channels an endeavor through a “narrow waist”, a voluntary constraint. That lens can create a more composable and powerful result. Plugins like unimpaired riff on the theme. And this touches on a central point: the main utility—not ideology, but utility—of “lifestyle software” like Emacs and Vim, is that the ecosystem is alive, and has escape velocity, so its momentum is self-perpetuated.
Neovim has always been intentionally positioned as a derivative of Vim, which means simultaneously it both continues and diverges from Vim. I’m convinced that forks create energy rather than destroy it. So although we can’t deliver Vim without Bram, we can continue some essential parts:
Agide is not a monolitic application. Separate tools can be plugged in. Thus you are not forced to use one editor. … Each tool implements part of the plugin interface.
Vim is not a shell or an Operating System. … This should work the other way around: Use Vim as a component from a shell or in an IDE.
And another thing: Bram didn’t take himself too seriously. He had his own sense of humor.
Neovim is a monument to Vim and Bram. We should be pragmatic, not dogmatic; we should remember what the goal is, and compare our actions to the results.
— Justin M. Keyes
P.S. Jan van den Berg wrote a nice post on Bram’s legacy.
]]>Here are some highlights from Neovim 2022 (Nvim 0.8) development.
Eye candy first!
:set laststatus=3
'winbar'
is like an extra statusline at the top of each window. It complements laststatus=3
:
set winbar=%f
set laststatus=3
'winbar'
and 'statusline'
gained support for mouse-click regions (as ‘tabline’ has had since 2016):
:set cmdheight=0
:set mousescroll=ver:5,hor:2
:set rnu nu
:let &stc='%#NonText#%{&nu?v:lnum:""}%=%{&rnu&&(v:lnum%2)?"\ ".v:relnum:""}%#LineNr#%{&rnu&&!(v:lnum%2)?"\ ".v:relnum:""}'
:set jumpoptions=view
vim.lsp.start({ name = 'godot', cmd = vim.lsp.rpc.connect('127.0.0.1', 6008) })
LspAttach
, LspDetach
. Example:
vim.api.nvim_create_autocmd('LspAttach', {
group = yourGroupID,
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
your_callbac_func(client, args.buf)
end
}
vim.lsp.get_active_clients()
learned to filter (this will be a standard pattern in the Lua stdlib):
get_active_clients({id=42})
get_active_clients({bufnr=99})
get_active_clients({name='tsserver'})
:set diffopt+=linematch:60
vim.g.editorconfig_enable = false
'inccommand'
feature (since 2017), which show the effects of :substitute
(:s/foo/bar
) as you type.:normal
and macros:
:normal
, :global, etc.
vim.api.nvim_create_user_command(
'MyCmd',
my_cmd,
{ …, preview = my_cmd_preview })
:write
command gained the ++p
flag, so this creates parent/dir/ if it doesn’t exist:
:edit parent/dir/file.txt
:write ++p
$XDG_STATE_HOME
(~/.local/state) instead of $XDG_CACHE_HOME
(~/.cache). This change only affects macOS/unix, the Windows locations are unchanged.stdpath('log')
to get the recommended location for log files.:help :Man
) shows an outline (table of contents) in the location list. Now the outline also lists the flags.
before:
9.0ms: sourcing …/runtime/filetype.vim
after:
1.3ms: sourcing …/runtime/filetype.lua
nvim --startuptime
now reports Lua require()
times.
000.010 000.010: --- NVIM STARTING ---
000.198 000.188: event init
...
026.333 001.109 001.101: require('vim.lsp.protocol')
028.144 000.423 000.423: require('vim.lsp._snippet')
...
mouse=nvi
Type ":" (cmdline-mode) to temporarily disable mouse. Right-click shows a popup menu.
Try it!
nvim_cmd([list])
and “user cmd-preview”! And super useful for defining custom cmdline (:
) behavior.
:echo nvim_parse_cmd('.,$g/foo/bar', {})
{
'cmd': 'global',
'args': ['/foo/bar'],
'mods': {…},
'magic': {'file': v:false, 'bar': v:false}
}
nvim_cmd()
to call any Vim legacy command in a structured way, like system([...])
.
fnameescape()
: special chars are controlled by the magic
param.
nvim_cmd({cmd='vimgrep', args={'/%s/j', '**'}}, {})
vim.fs.find()
is now the canonical way to find “root files”, common for LSP configuration.vim.cmd
is the Lua nvim_cmd
wrapper. It supports calling Ex commands as functions instead of strings:
vim.cmd.colorscheme('nightfox')
“Lua plugins are basically the same as a vim plugin, except the file extension is
.lua
instead of.vim
and the file contains Lua code instead of Vimscript.”
Automated generation of the online Nvim documentation was rewritten by replacing an old AWK script with Lua + tree-sitter. We can have nice things.
Compare the old layout (left) to the new one (right):
Nvim now sets the $NVIM
environment variable in jobstart()
and :terminal
jobs, so child processes have an unambiguous hint that they are children of Nvim. The old $NVIM_LISTEN_ADDRESS
, which had conflicting “dual purposes”, is no longer passed to children.
Nvim UIs are just (inverted) plugins. And now nvim
itself is a self-hosting UI: when you run nvim
in a terminal, it starts the TUI as a nvim --embed
child process.
Just like Nvim GUIs, you can connect the nvim
TUI to any Nvim server to see its UI! You can try it right now:
./foo
(creates a foo
file in the current directory):
nvim --listen ./foo
./foo
), connect nvim
to the server:
nvim --remote-ui --server ./foo
'insertmode'
option, which was used in Vim to implement “easy vim”.
:help 'insertmode'
.:help lsp
).
Original article: https://gpanders.com/blog/whats-new-in-neovim-0-7
Neovim 0.7 was just released, bringing with it lots of new features (and of course plenty of bug fixes). You can find the full release notes here, but in this post I’ll cover just a few of the new additions.
Neovim 0.5 saw the introduction of Lua as a first-class citizen in the Neovim
ecosystem: Lua could now be used in the user’s init file, plugins,
colorschemes, ftplugins, etc. Basically, anywhere that you could use a .vim
file, you could now use .lua
instead.
However, there were still some shortcomings in the Lua API at that time. Notably absent was the ability to create autocommands in Lua, as well as bind key mappings directly to Lua functions. In order to do either of these things, users needed to resort to workarounds involving a round trip through Vimscript conversion, which is a bit clunky:
-- Using a Lua function in a key mapping prior to 0.7
local function say_hello()
print("Hello world!")
end
_G.my_say_hello = say_hello
vim.api.nvim_set_keymap("n", "<leader>H", "<Cmd>call v:lua.my_say_hello()<CR>", {noremap = true})
The situation was similar for autocommands and custom user commands.
In Neovim 0.7, it is now possible to use all of the usual configuration primitives (key mappings, autocommands, user commands, etc.) directly in Lua, with no Vimscript conversion necessary. This also makes it possible to bind key mappings and autocommands directly to local Lua functions:
-- Using a Lua function in a key mapping in 0.7
vim.api.nvim_set_keymap("n", "<leader>H", "", {
noremap = true,
callback = function()
print("Hello world!")
end,
})
-- Creating an autocommand in 0.7
vim.api.nvim_create_autocmd("BufEnter", {
pattern = "*",
callback = function(args)
print("Entered buffer " .. args.buf .. "!")
end,
desc = "Tell me when I enter a buffer",
})
-- Creating a custom user command in 0.7
vim.api.nvim_create_user_command("SayHello", function(args)
print("Hello " .. args.args)
end, {
nargs = "*",
desc = "Say hi to someone",
})
You may notice that nvim_set_keymap
must set the Lua callback as a key in
the final table argument, while nvim_create_user_command
can pass the
callback function directly as a positional parameter. This is a consequence of
Neovim’s strict API contract, which mandates that after an API function makes
it into a stable release, it’s signature must not change in any way.
However, because nvim_create_user_command
is a new API function, we are able
to add a bit of convenience by making its second argument accept either a
string or a function.
Neovim 0.7 also includes a Lua-only convenience function vim.keymap.set
for
easily creating new key mappings:
vim.keymap.set("n", "<leader>H", function() print("Hello world!") end)
vim.keymap.set
differs from nvim_set_keymap
in the following ways:
noremap
by default, as this is what users want 99% of the
time.The help docs contain much more information: run :h vim.keymap.set
in Neovim
to learn more.
Finally, users can now use the API function nvim_set_hl
to modify global
highlight groups (the equivalent of using :hi
), opening the door to pure-Lua
colorschemes.
Being a terminal based application, Neovim has long been subject to the
constraints of terminal emulators, one of which being that many keys are
encoded the same and thus indistinguishable to applications running in the
terminal. For example, <Tab>
and <C-I>
use the same representation, as do
<CR>
and <C-M>
. This has long meant that it is not possible to separately
map <C-I>
and <Tab>
: mapping one necessarily maps both.
This has long been a point of annoyance and there are multiple solutions in the wild to address it. Neovim uses Paul Evans’ libtermkey, which in turn makes use of Evans’ own fixterms proposal for encoding modifier keys in an unambiguous way. As long as the terminal emulator controlling Neovim sends keys encoded in this way, Neovim can correctly interpret them.
Neovim 0.7 now correctly distinguishes these modifier key combos in
its own input processing, so users can now map e.g. <Tab>
and <C-I>
separately. In addition, Neovim sends an escape sequence on startup
that signals to the controlling terminal emulator that it supports this style
of key encoding. Some terminal emulators (such as iTerm2, foot, and tmux) use
this sequence to programatically enable the different encoding.
A note of warning: this cuts both ways! You may find that existing mappings to
<Tab>
or <C-I>
(or <CR>
/<C-M>
) no longer work. The fix is easy,
however; simply modify your mapping to use the actual key you want to use.
In addition to disambiguating these modifier pairs, this also enables new
key mappings that were not possible before, such as <C-;>
and <C-1>
.
Support for this depends largely on the terminal you are using, so this will not affect all users.
Neovim 0.7 introduces a new “global” statusline, which can be enabled by
setting laststatus=3
. Instead of having one statusline per window, the
global statusline always runs the full available width of Neovim’s containing
window. This makes it useful to display information that does not change
per-window, such as VCS information or the current working directory. Many
statusline plugins are already making use of this new feature.
In Neovim 0.7 there is a new (experimental) way to do filetype detection. A
quick primer on filetype detection: when you first start Neovim it sources a
file called filetype.vim
in the $VIMRUNTIME
directory. This file creates
several hundred BufRead,BufNewFile
autocommands whose sole purpose is to
infer the filetype of the file based on information about the file, most
commonly the file’s name or extension, but sometimes also using the file’s
contents.
If you profile your startup time with nvim --startuptime
you will notice
that filetype.vim
is one of the slowest files to load. This is because it is
expensive to create so many autocommands. An alternative way to do filetype
detection is to instead create one single autocommand that fires for every
new buffer and then tries to match the filetype through a sequential series of
steps. This is what the new filetype.lua
does.
In addition to using a single autocommand, filetype.lua
uses a table-based
lookup structure, meaning that in many cases filetype detection happens in
constant time. And if your Neovim is compiled with LuaJIT (which it most
likely is), you also get the benefit of just-in-time compilation for this
filetype matching.
This feature is currently opt-in as it does not yet completely match all of
the filetypes covered by filetype.vim
, although it is very close (I have
been using it exclusively for many months without any issues). There are two
ways to opt-in to this feature:
Use filetype.lua
, but fallback to filetype.vim
Add let g:do_filetype_lua = 1
to your init.vim
file. This prevents any
regressions in filetype matching and ensures that filetypes are always
detected at least as well as they are with filetype.vim
. However, you
will pay the startup time cost of both filetype.lua
and filetype.vim
.
Use only filetype.lua
and do not load filetype.vim
at all
Add both let g:do_filetype_lua = 1
and let g:did_load_filetypes = 0
to
your init.vim
. This will exclusively use filetype.lua
for filetype
matching and provides all of the performance benefits outlined above, with
the (small) risk of missed filetype detection.
In addition to performance benefits, filetype.lua
also makes it easy to
add custom filetypes. Simply create a new file ~/.config/nvim/filetype.lua
and call vim.filetype.add
to create new matching rules. For example:
vim.filetype.add({
extension = {
foo = "fooscript",
},
filename = {
["Foofile"] = "fooscript",
},
pattern = {
["~/%.config/foo/.*"] = "fooscript",
}
})
vim.filetype.add
takes a table with 3 (optional) keys corresponding to
“extension”, “filename”, and “pattern” matching. The value of each table entry
can either be a string (in which case it is interpreted as the filetype) or a
function. For example, you may want to override Neovim’s default behavior of
always classifying .h
files as C++ headers by using a heuristic that only
sets the filetype to C++ if the header file includes another C++-style header
(i.e. one without a trailing .h
):
vim.filetype.add({
extension = {
h = function(path, bufnr)
if vim.fn.search("\\C^#include <[^>.]\\+>$", "nw") ~= 0 then
return "cpp"
end
return "c"
end,
},
})
We are bringing filetype.lua
closer to full parity with filetype.vim
every
day. The goal is to make it the default in Neovim 0.8 (with the ability to
opt-out to the traditional filetype.vim
).
Neovim 0.7 brings some of the features of neovim-remote into the core
editor. You can now use nvim --remote
to open a file in an already running
instance of Neovim. An example:
# In one shell session
nvim --listen /tmp/nvim.sock
# In another shell session, opens foo.txt in the first Nvim instance
nvim --server /tmp/nvim.sock --remote foo.txt
One use case for the new remote functionality is the ability to open files from the embedded terminal emulator in the primary Neovim instance, rather than creating an embedded Neovim instance running inside Neovim itself.
Neovim is a loosely structured project of motivated individuals who do the work for fun; thus, any roadmap is always a bit of a guessing game. However, there are some things already brewing that you might see in Neovim 0.8:
The real 0.5 was the friends we made along the way
The long-awaited release of Neovim v0.5.0 finally happened on July 2, 2021. It took longer than everybody had hoped for, but it was worth the wait: With over 4000 commits, it is so big that it broke some of the release tooling. So these notes will not be able to touch on each of the many changes that were made over the course of development and only focus on the most user-visible improvements, of which the biggest are
Neovim 0.5 went far in making Lua a first-class scripting language for Neovim, both for plugin development and for user configuration.
As a reminder, Lua is a small scripting language designed for embedding and is often used in, e.g., game development. Furthermore, there is a just-in-time compiler (LuaJIT, which Neovim is built with on platforms where it is available) that can provide impressive performance on relevant tasks. In essence, Lua was chosen over other languages because it is
For more details on this choice, see Justin M Keyes’ presentation at Vim Conf 2019 and TJ DeVries’ presentation at Vimconf.live.
Let’s look at what this means for plugin authors and users.
Neovim exposes its API natively to Lua via, e.g., vim.api.nvim_open_win()
. It also provides methods for accessing vimscript (ex) commands and variables via, e.g., vim.cmd("echo 'foo'")
and vim.g.syntax_on
, respectively. This allows writing plugins with the same capabilities as those written in Vimscript while exploiting the performance of Lua(JIT) at core programming language tasks like loops. It is also possible to make use of Lua’s own luarocks
plugin ecosystem.
Correspondingly, over the course of the 0.5 development cycle, there has been an explosion in the number of Lua plugins, ranging from rewrites of popular Vimscript plugins to completely new ones that would not have been possible in Vimscript – often from contributors who were completely new to (neo)vim plugin development and were averse to learning Vimscript for that task. As a positive side effect of the long development cycle, many of these are already fully-featured and stable at the time of the 0.5 release!
Here is a small and non-representative list of Lua plugins:
A much more comprehensive list of Neovim plugins can be found at the user-contributed Awesome Neovim collection.
Not all of these plugins are actually written in Lua: there are many other languages (some of which are typed) that compile to Lua, e.g.,
It is also possible to write user configuration in Lua: If there is an init.lua
, it is read instead of init.vim
(these cannot coexist, and having both in your config directory will give an error), and .lua
files in runtime directories (plugin/
, colorscheme/
, after/
etc.) are sourced in addition to (after) Vimscript files. Note that this is entirely optional and not needed to enjoy the new functions introduced in Neovim 0.5; furthermore, not every Vimscript configuration option has a fully native Lua equivalent yet. Extending the native API to cover these as well is part of the goal for Neovim 0.6.
For a comprehensive and up-to-date guide on using Lua for Neovim scripting and configuration, see Getting started using Lua in Neovim. A good model for a Lua configuration using init.lua
is Defaults.nvim.
The Language Server Protocol (LSP) is an open, JSON-RPC-based protocol for communication between code editors and language servers, which provide programming language-specific features such as
and more.
The idea is to separate these features into an editor-independent but language-specific server and a language-independent but editor-specific client, which communicate via the Language Server Protocol over RPC. (It should be pointed out that not every server implements every feature, and the quality of the responses can vary wildly. The “reference implementation” in VS Code also often adds non-standard features that are not covered by the LSP itself.)
Neovim 0.5 provides an LSP client written (mostly) in Lua that provides a highly configurable and extensible way of accessing these features. It does not aim at competing with more feature-rich and “out-of-the-box” plugins like CoC.nvim but is meant to be tailored to your preferences (while still being useable with reasonable defaults). For an overview, see TJ DeVries’ Vimconf.live presentation and his shorter video.
For many language servers, Nvim-lspconfig already provides the necessary configuration to set everything up easily. Alternatively, some languages also have specific LSP plugins that provide a more integrated setup, e.g., for Java and Scala.
To learn more about LSP and how to use it in Neovim, visit Nvim-lspconfig (including its Wiki) and read :h lsp
.
Expect more work on LSP during the 0.5.x development cycle to provide improved configuration options and better coverage of the latest LSP specification (version 3.16 at the point of writing), including semantic highlighting.
Neovim 0.5 adds experimental support for tree-sitter, a library that parses a piece of code into a syntax tree in an incremental and error-resilient way; this means that reparsing that code after an edit is very fast, and parsing error due to, e.g., typos remain localized and do not break parsing further down. This tree can then be efficiently queried to obtain syntax information about the code. This allows for improved and/or faster
and more. Tree-sitter also makes it easy to highlight parts of a file differently if they contain code in a different language. To learn more about tree-sitter, watch Tree-sitter - A new parsing system for programming tools - Max Brunsfield.
The goal is to replace the current vim regular expression-based syntax with tree-sitter, not only for better and faster syntax highlighting but also for new and improved ways of structured text editing. However, tree-sitter support in 0.5 should still be considered as “early access”: It works well enough to test out and see what is possible, but it should not be relied on for productive use due to a number of serious bugs and performance regressions that need to be addressed before tree-sitter in Neovim can be declared stable. Note also that enabling tree-sitter based highlighting for a language currently disables the internal regex-based syntax engine completely for this file type, which may break other features that rely on it. Fixing these issues and improving the API will be a major focus of the development cycle leading up to the 0.6 release.
Also, Neovim itself only provides a (Lua) API for generating and querying the syntax tree using the bundled tree-sitter library; see :h treesitter
. User-facing features like the ones mentioned above are implemented in plugins like
More information on using these features can be found in the Nvim-treesitter README or by watching Thomas Vigouroux’s Vimconf.live presentation.
This is a common question, especially since LSP as of version 3.16 provides “semantic highlighting”. In short, tree-sitter operates on a single file, parsing the file into a syntax tree which is used to support the variety of enhanced code navigation and manipulation functions. On the other hand, language servers operate across multiple files and project libraries, using various different, server-dependent, methods for parsing each file’s syntax tree. (Of course, tree-sitter is one possible choice for this purpose, and is in fact used by, e.g., bash-language-server and wasm-language-server.)
In particular, this means that language servers can use semantic information from a different file to annotate the tree for the current file: For example, a variable declared as const
in one file can be highlighted in red if it is used in a different file – something that tree-sitter cannot do since it only has access to the latter file when highlighting.
For more details, watch TJ DeVries’ presentation on this topic.
Of course, these were not the only major changes in 0.5. Here is a short summary of representative new features.
There is an improved decoration provider API that allows setting and interacting with extmarks (invisible anchored text markers that move when surrounding text is edited), virtual text (text overlays that can now be drawn at any position on screen), and highlights (which is heavily leveraged by nvim-treesitter).
This mockup from a post by @sunjon shows what can be achieved with this API:
The API for floating windows now includes a “z-index” (allowing for control over how floating windows stack) and support for borders.
Neovim now has a built-in function to briefly highlight the yanked region (similarly to https://github.com/machakann/vim-highlightedyank), configurable from Lua. To use it, you can add the following to your init.vim
:
au TextYankPost * lua vim.highlight.on_yank {higroup="IncSearch", timeout=150, on_visual=true}
See :h vim.highlight.on_yank()
for more configuration options.
Of the over 4000 commits in this release, about 1000 were patches and runtime updates ported from Vim – nearly all of them by or with the help of the amazing @janlazo. In particular, the runtime files (syntax files, documentation, etc.) are fully synced with Vim up to May 2021, with many later changes already included as well.
In keeping with the motto of this newsletter, one of the most noticeable positive changes was the growth of the community and of new ways of interacting with it.
Previously, support requests and discussions were spread across Reddit, Gitter, and GitHub Discussions and were either ephemeral or hard to search for. We have now consolidated around a new Neovim Discourse, which is a free and open source forum platform with mailing list and RSS features, in addition to a nice web interface. The Neovim Discourse is an official core project and moderated by core team members.
The official chatroom for Neovim is on Gitter. After the acquisition of Gitter by Matrix (a federated chat protocol), this room can now also be accessed from Matrix; it is also bridged to the IRC network Libera.chat. Due to the increasing number of users, there are now additional, more specific rooms for development of and around neovim, GUIs, and off-topic chat.
(The links above are to the rooms accessed through Element, a web-based Matrix client; you can also access it through any of the many other Matrix clients.)
Due to the global COVID-19 pandemic, VimConf 2020 unfortunately had to be canceled. In its place, a virtual Vimconf.live conference was held, with 16 speakers and over 1000 registered participants from 12 countries. If you have missed it, you can watch the lectures on the Youtube playlist.
Another effect of the pandemic was the rise of interest in the live streaming of open source development on Twitch. Many of the speakers at Vimconf.live are active streamers; in particularly, TJ DeVries regularly streams his work on Neovim as “open open source”, and the release of Neovim 0.5 was streamed live on his channel. (Update: An edited playlist of the release stream is now on YouTube.)
The number of people active in Neovim development also grew. Between 0.4.4 and 0.5.0, there were 301 unique commit authors, compared to 112 between 0.3.8 and 0.4.4 (a comparable time frame).
You can now sponsor Neovim via Github Sponsors or OpenCollective. (BountySource began introducing worrying changes to their Terms of Service agreement and is therefore no longer recommended.)
As already mentioned, further improvements to the headlight features introduced in 0.5 will happen over the 0.5.x release cycle:
Making tree-sitter a stable and faster replacement for syntax highlighting (and beyond) is the major goal for the 0.6.0 release. This includes fundamental work on the decorations API to allow for things like in-line folding or inserting virtual lines and columns (“anti-conceal”).
Beyond that, notable goals are better file change detection as well as further decoupling the TUI (terminal UI) from the Neovim core with the goal of allowing remote TUI instances.
Finally, we are aiming for more regular and frequent releases (at least for patch versions), which will hopefully remove the need for a “neovim 0.6 when?” meme for a change.
A big thank you to everyone involved in the project that helped make Neovim 0.5 a reality – be they contributors, sponsors, bug-reporters, or supporters. In lieu of full credits, here are some of the people you can thank for the features listed in this letter:
:smile
seriously.Finally, thank you to @justinmk and @brammool for your foundational work and your vision – the *vim community is stronger together!
]]>Neovim is a fork of the venerable text-editor vim, focused on extensibility and usability. 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. See a list of differences via :help vim-differences.
If you are interested in contributing to Neovim, visit the github page for details. We have a great test suite and automated CI, so you can just jump in and have a go. Don’t be afraid to open a PR to get comments or just take advantage of the infrastructure!
To get in touch with the team, join the gitter channel (also accessible via IRC), or visit the Neovim subreddit, which many of the developers read. Taking part in conversations is a contribution, too!
The last newsletter covered the release of Neovim v0.3.0, it is now time to do the same thing with the most exciting Neovim release that happened since then: v0.4.4!
Neovim started detecting the background color of the terminal for xterm-compatible terminals (@joshtriplett, #9509)
The 'maxcombine'
option has been removed, it now always default to 6 (@bfredl, #7992)
The 'fillchars'
setting now has an eob
option, letting users configure the character used to represent lines after the end of a buffer (previously hardcoded to ~
) (@FriedSock, #8546)
F
has been added to the default 'shortmess'
option and S
has been removed (@justinmk, #8619, #10136)
The CursorLine
type will now be smarter: if its foreground color is not set, the text of the CursorLine
will use the CursorLine
’s background color and default syntax highlighting colors as foreground (@zhou13, #8578).
The terminal UI can now support undercurl and colored underline, provided that your terminal has support for that (@blueyed, #9052).
Neovim’s 'background'
setting now defaults to dark
to get a consistent setting across platforms (@justinmk, #9205).
'fillchars'
and 'listchars'
now are window-local options (@mhinz, #9539).
The popupmenu can now be made (pseudo) transparent (@bfredl, #9571).
Floating windows! This enables all kinds of useful features, such as big clocks (@bfredl, @dzhou121, #6619)
Autocommands now have a ++once
modifier to let them execute only once (@justinmk, #9706)
A new autocommand event named CompleteChanged
has been implemented (@chemzqm, #9616)
Vim’s TermDebug plugin has been ported to neovim (@kwon-young, #8364).
The wildmenu can now be turned into a popup menu with wildoptions=pum
(@bfredl, #9607). In fact, that’s the default!
There now are two events triggered when a UI connects to and disconnects from Neovim: UIEnter and UILeave (@equalsraf, #6917).
There also are TermEnter
and TermLeave
autocommands triggered when entering/leaving a terminal (usama54321, #8550).
ext_hlstate
extension allows semantic identification of builtin and syntax highlights (@bfredl, #8221).ext_linegrid
extension sends more gradual screen updates for improved performance (@bfredl, #9064).ext_multigrid
extension introduces the concept of a “grid” which is just a rendering surface (@bfredl, @UtkarshMe #8455).ext_messages
extension enables UIs to provide an external command line (@bfredl, @dzhou121 #7466)ext_popupmenu
makes neovim send information about its popup menu (@bfredl #9607).nvim_buf_get_offset
: returns the byte offset of a line (@bfredl, #9180)nvim_buf_is_loaded
: checks if a buffer is loaded (@phodge, #7688).nvim_create_buf
: create a new buffer (@bredl, #9272)nvim_get_context
/nvim_load_context
: explore and restore the editor’s state (@justinmk, #10619.nvim_input_mouse
: perform mouse actions (@bfredl, #9429).nvim_open_win
: creating floating external windowsnvim_set_keymap
: sets a global mapping for a mode (@yilin-yang, #9224).nvim_win_close
: close a window (@bfredl, #9667).nvim_win_set_buf
: sets the current buffer of a window (@justinmk, #9100)nvim_win_set_config
: configure the layout of a window (@mhinz, #9626).nvim_buf_lines_event
will now send events for terminal buffers (@justinmk, #8616).Neovim now always waits for a UI when launched with –embed, unless –headless is also supplied (@bfredl, #9024).
vim.loop
(@zhaozg, @andreypopp, #10123).Neovim contributors have been hard at work and added a lot of new features to v0.5.0 like an LSP client written in Lua and TreeSitter integration. The next Neovim release promises to be fascinating!
The wiki page of related projects is an evergrowing list of projects that somehow make use of Neovim’s extended capabilities. Here’s a gist of additions since the last newsletter:
The following plugins have found their way into our wiki:
Plenty of new API clients:
The python client also has been renamed to “pynvim”.
Maybe 2018/2019 weren’t the years of the Linux desktop, but they sure were the years of the Neovim GUI:
Some posts that talk specifically about Neovim things:
Changed lines since the last newsletter:
git log v0.3.0..v0.4.4 --numstat --pretty=tformat: --numstat | nawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 168844 removed lines: 75466 total lines: 93378
Merged commits:
git log v0.3.0..v0.4.4 --pretty=oneline | wc -l
3477
Different commit authors:
git shortlog -e -s -n v0.3.0..v0.4.4 | wc -l
164
Documentation changes:
git log v0.3.0..v0.4.4 --numstat --pretty=tformat: --numstat runtime/doc | nawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 9226 removed lines: 7002 total lines: 2224
Thank you contributors, sponsors, bug-reporters, supporters. Note that you can now sponsor neovim via github Sponsors or on OpenCollective. Thank you @justinmk for the awesome project and thank you @brammool for your foundational work.
]]>Neovim is a fork of the venerable text-editor vim, focused on extensibility and usability. 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. See a list of differences via :help vim-differences.
If you are interested in contributing to Neovim, visit the github page for details. We have a great test suite and automated CI, so you can just jump in and have a go. Don’t be afraid to open a PR to get comments or just take advantage of the infrastructure!
To get in touch with the team, join the gitter channel (also accessible via IRC), or visit the Neovim subreddit, which many of the developers read. Taking part in conversations is a contribution, too!
New contributor shoutout: @janlazo has been on a rampage for both windows support and porting neovim patches since about September 2017. Thank you!
Old contributor shoutout: @jamessan has been around since March 2014, and, while being generally smart and helpful, has been doing tremendous work on the debian package of neovim. Thank you!
The last newsletter covered everything up to release 0.2.2 of Neovim. Two years have passed, and the project has been as busy as ever improving both user and developer experience. Along the way we released in June 2018 the version 0.3. Though this newsletter arrives late (after version 0.4 was released), we still deemed it worth to introduce 0.3 in case you missed anything (0.4 will be covered in a future newsletter):
As always, check Following HEAD for any breaking changes.
A lot of work has been put into making Neovim work better with different terminal emulators, and is still ongoing (@justinmk, #7664, #7653, #7720, #7640, #7624, @florolf, #7676 and @erw7 #8408)
man.vim
improvements, uses lua for speedup (@keidax, #7623)
Output from system()
and :!
supports multibyte chars, and also handles control chars (CR, TAB) somewhat better (@bfredl, #7844)
Command mappings are supported (@bfredl, #4419)
An unmapped META key will be interpreted as Escape (@justinmk, #8226)
msgsep
for display
to avoid fullscreen scrolling for messages (@bfredl, #8088)
Numbered marks are now saved in shada files (@ZyX-I, #5908)
The --listen
command line option replaces the usage of $NVIM_LISTEN_ADDRESS
(@justinmk, #8247)
Neovim treats stdin as text, rather than commands. If you want to run stdin as normal mode commands, use nvim -s -
(@justinmk, #7679, @ZyX-I, #6299 and @b-r-o-c-k, #8276)
Neovim recognizes mouse events in (u)rxvt (@symphorien, #8309)
Macros apply :lmap
when executing (@hardenedapple, #5658)
The list implementation has been hidden behind an API to foster further improvements (@ZyX-l, #7708). Developers, in particular people that port patches from vim, should have a look at the wiki page.
nvim_list_uis
@geekodour, #8004)nvim_get_commands
(@nimitbhardwaj, @justinmk, #8375)stdpath
(@docwhat, #6272)nvim_set_client_info
, nvim_get_chan_info
and nvim_list_chans
(@bfredl, #6743)nvim_buf_attach
/-detach
implement buffer change notifications. Using these functions, you can subscribe to events that are sent when a buffer has been updated, no matter the source or method (@phodge, @KillTheMule, #7917)Channels: support buffered output and bytes sockets/stdio (@bfredl, #6844)
Neovim had been accepted into the Google Summer of Code(GSOC). We’ve had two students working on interesting developments:
Thanks for your awesome contributions, and thanks to the mentors @bfredl and @justinmk!
The wiki page of related projects is an evergrowing list of projects that somehow make use of Neovim’s extended capabilities. Here’s a gist of additions since the last newsletter:
The following plugins have found their way into our wiki:
If you thought 3 C++ clients wasn’t enough, you will be happy to hear that a 4th contender has entered the arena:
If you happen to prefer a language with no API client listed, a good starting point are the docs, and be sure to come talk about it on the gitter channel.
Three new GUIs were added since the last newsletter:
Some blog posts that talk about some specifically Neovim things:
Testing plugins from Neovim
walks you through using the Neovim test infrastructure for your pluginRpc benchmarks
shows and benchmarks different approaches in using the RPC API to create folds from a plugin.Neovim for Haskell Development
shows how Neovim can help you with your haskell development needsFor quite some time @mhinz has been maintaining neovim-remote. While only available on unices (though windows support is on the table), it solves some use cases people ask about frequently, such as:
To whet your appetite, here’s a little gif
Know more than the wiki? Just edit the page to let the world know!
Changes lines since the last newsletter:
git log --since="2017-12-16" --numstat --pretty=tformat: --numstat|gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 109127 removed lines: 40267 total lines: 68860
Merged commits:
git log --since="2017-12-16"|wc -l
24167
Different commit authors:
git shortlog -e -s -n --since="2017-12-16"|wc -l
129
Documentation changes:
git log --since="2017-12-16" --numstat --pretty=tformat: --numstat runtime/doc|gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 4369 removed lines: 3645 total lines: 724
Thank you contributors, sponsors, bug-reporters, supporters. Thank you @justinmk for the awesome project and thank you @brammool for your foundational work.
]]>In our first GSoC ever, we mentored two students who both completed their projects.
Brock Mammen implemented a C# client for Nvim, and even went further with a Nvim extension for Visual Studio! He also made significant improvements to the build system, particularly for Windows/MSVC.
The multigrid project by Utkarsh Maheshwari involved low-level changes to the UI subsystem:
breaks up the screen grid in per-window grids, allows UIs to set different sizes for each window grid and receive grid based events.
The final product was integrated by mentor Björn Linse
into the Nvim master
branch, providing the foundation for the
floating windows feature.
This demo shows the feature being used in a popular plugin to reveal documentation with completion results:
Our mentors are looking forward to your GSoC proposals in the next weeks! The best way to get familiar with Neovim development is to send a pull request to help out with a small bug or feature request. Working with students on pull requests is extremely helpful for determining mentor-student workflow.
]]>Neovim is a fork of the venerable text-editor vim, focused on extensibility and usability. 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. See a list of differences at :help vim-differences.
If you are interested in contributing to Neovim, read CONTRIBUTING.md to get started. We have a great test suite and automated CI, so you can just jump in and have a go. Don’t be afraid to open a PR to get comments or just take advantage of the infrastructure!
To get in touch with the team, join the gitter channel (also accessible via IRC), or visit the Neovim subreddit, which many of the developers read. Taking part in conversations is a contribution, too!
New contributor shoutout: @ckelsel has been responsible for porting a large number of vim patches, as has @lonerover. Thank you!
Old contributor shoutout: @oni-link isn’t a name you read a lot in the commit logs, but he’s been very helpful in reviewing changes and improving complicated PR’s for quite some time. Thank you!
The last newsletter has gathered some dust, so we want to bring you up-to-date in the Neovim world.
Neovim has had 3(!) releases since back then, so let us recap those first and foremost:
This release brings a host of fixes and improvements. We’ll look at some of them closer below, but be sure to also check out the release page for all the gory details.
:terminal
mode is available in 0.2.1, see below!curl.exe
.:terminal
has seen various improvements (@justinmk, #6185)
Reading from stdin
was removed (@msva, #6298)guicursor
now works in the TUI (@teto, #6423)Whitespace
for whitespace-related listchars
(@zhou13, #6367)DirChanged
is now available for autocommands (@mhinz, #5928)cpoptions
: Use the _
flag to toggle cw
behaviour (@raichoo, @chrisbra, #6235)CTRL-R
now omits trailing ^M
when pasting to the commandline (@justinmk, #6137):edit
filenames without escaping whitespaces (@Kurt-Bonatz, #6119)writefile
now obeys the fsync
option (@ZyX-I, #6427)eval.c
has been refactored and error messages were improved (@ZyX-I, #5119)id
function is now available, and printf(%p)
is finally useful (@ZyX-I, #6095)g:loaded_*
exists (@justinmk, commit)setpos
can now set lowercase marks in other buffers (@hardenedapple, #5753)v:exiting
to see if Neovim is exiting (@mhinz, #5651)Next let’s see what happened in 0.2.1. As before, check out the release notes for details.
:Tutor
have been made (@fmoralesc, #7028)inccommand
now works with leading modifiers like keeppattern
(@jamessan, #6967):cquit
now takes an optional error code as argument (@joshleeb, #7336):checkhealth
is a builtin now, and validates your $VIMRUNTIME
(@justinmk, #7399)cursorcolumn
and colorcolumn
respect syntax highlighting (@zhou13, @justinmk, #7364)FocusGained
event instead of sending the <FocusGained>
pseudokey (@justinmk, #7221)get_keymap
(@tjdevries, #6236)using nvim_get_hl_by_name/by_id
(@teto, #7082)bufhl
can now be used to create new highlighting groups (@bfredl, #7414)menu_get
(@teto, #6322)
menu_get
pretty-prints special chars, making it possible to feed its results back into e.g. nvim_input
(@teto, @KillTheMule, #7340)sockconnect
(@bfredl, #6594)serverstart
now uses uv_getaddrinfo()
, bringing IPv6 support (@mhinz, #6680):execute
call (@ZyX-I, #6914)This is a fast-and-furious containing mostly bug-fixes. See the release-notes for details. Some new features are in, too:
curdir
has been added as a viewoption (@EricR86, #7447):checkhealth
now also validates the runtimepath (@justinmk, #7526)scrollback
now defaults to 10000 (@justinmk, #7556)Want to know what to expect from the next release? Here’s a list to whet your appetite:
CmdlineEnter
and CmdlineLeave
autocommands (@bfredl, #7422)For an overview of planned features, goals and ideas for Neovim head to the road map. Some noteworthy upcoming PRs are:
PSA: If you build Neovim from the latest master, always check Following HEAD for any changes.
The wiki page of related projects has seen quite some additions, check out the full changes here.
API clients are at the heart of Neovim’s architecture, and significantly improve developer experience. Write a plugin in any language you want! Since the last newsletter, we’ve seen the addition of another C++ client, one for Elixir, and a Racket client. The node client got an overhaul and a new maintainer. Thanks @billyvg for taking over! While not totally new, a special shoutout goes to the ruby client for being very well-maintained. Thanks, @alexgenco!
If you happen to prefer a language not yet listed, a good starting point are the docs, and be sure to come talk about it on the gitter channel.
Too much activity has happened on the GUI front to list all new clients, so let’s just have a look at some that stand out. VSCode is using Neovim to properly integrate ex-mode commands, and Sublime Text 3 gained full Neovim integration. The latter also makes use of another cool Neovim-specific feature, the externalized popupmenu, and it only took them 50 LOC. Last but not least, eovim is an enlightenment client for Neovim.
Some students have studied the Architecture of Neovim and published an “analytical essay” about their findings. Be sure to have a look if you are interested in the bigger picture.
Drew Neil of vimcasts fame has started recording casts about Neovim, and began work on a successor to his praised book Practical Vim called Modern Vim. Most of the book will be suitable for Vim 8 and Neovim users, but about 1/3rd of the book will cover Neovim-specific functionality.
One of the founding stones of Neovim has been porting I/O to libuv. So you will be happy to hear that libuv has set out to support more platforms. Neovim, soon coming to a platform near you!
Neovim offers easy testing via the wonderfully simple Lua language. Why aren’t others doing it, you ask? Turns out, they do, or at least, the neomutt project is preparing for it. Very nice to see ideas from Neovim taken up.
Changes lines since the last newsletter:
git log --since="2016-11-01" --numstat --pretty=tformat: --numstat|gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 255393 removed lines: 221106 total lines: 34287
Merged commits:
git log --since="2016-11-01"|wc -l
3110
Different commit authors:
git shortlog -e -s -n --since="2016-11-01"|wc -l
146
Documentation changes:
git log --since="2016-11-01" --numstat --pretty=tformat: --numstat runtime/doc|gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 8579 removed lines: 6577 total lines: 2002
Thank you contributors, sponsors, bug-reporters, supporters. Thank you @justinmk for the awesome project and thank you @brammool for your foundational work.
@brammool and @chrisbra from the vim team have left a few comments on our issue tracker, it’s nice to be working together!
]]>Each minute, a new text editor is born (source: Hacker News). There are endless text editors that address the “common case”.
Instead of another Vim-like text editor, Neovim users want a better Vim. Thousands of small decisions live in the Vim core, accumulated over decades; most of those decisions are still relevant, solving subtle problems that new projects have yet to encounter, digest and decide.
Neovim is a refactor of Vim to make it viable for another 30 years of hacking.
See :help vim-differences
for
a reference of changes and improvements.
Neovim very intentionally builds on the long history of Vim community knowledge
and user habits. That means “switching” from Vim to Neovim is just an
“upgrade”—like installing a new version of Vim. If you log onto a server or
workstation with only Vim, you won’t be lost. If you find an article about Vim,
it likely also applies to Neovim, unless it’s about :smile
.
So if you like Vim, try Neovim. If you love Vim, try this ;)
From the start, one of Neovim’s explicit goals has been:
Simplify maintenance and encourage contributions
We want a hackable Vim: a codebase and community that enables experimentation and low-cost trials of new features.
And there’s evidence of real progress towards that ambition. We’ve successfully executed non-trivial “off-the-roadmap” patches: features which are important to their authors, but not the highest priority for the project.
:tchdir
enables tab-local
“working directory”'statusline'
supports unlimited alignment sections (PR #4489)man.vim
offers completion, improved highlighting, and moreThese patches were included because they:
They are casually mentioned in :help
nvim-features
:)
:smile
?New clients and innovative applications are appearing more frequently than ever.
<neovim-editor>
web
component can be used in your own project, including VS Code, Atom, and
other Electron or nw.js projects!nvim
, progressing rapidly on a new nvim
-based
backend for his well-known VimR project,
a polished GUI for macOS. There are pre-built .app
bundles for
macOS 10.11 at the releases page.:Lispdo
!--servername
, --remote
, etc. nvr
is perfect for
communicating with a parent nvim
instance from a :terminal
buffer.There are clients for go, julia, perl, Java, R, Elixir, Clojure, and more. Visit the related projects wiki page to discover new projects as they emerge!
Clarity and consistency breed contribution. — @robertmeta
In July, Thiago (@tarruda) took a less active role in the project, for personal reasons. He hopes to resume active contributions in the future.
Some have asked for a “BDFL” to be named. @justinmk has that role, unless you want it: we’ve made steps to document the role of maintainer, so that anyone trusted by most contributors can step up in the future.
The ultimate goal is to spread out tasks as horizontally as possible, and to continue to give the “commit bit” to people we’ve grown to trust. There are currently 14 core contributors; we’d like to scale that to 50. We don’t want the project to depend on heroic effort, but a flow of interested parties working within the conventions and etiquette of the Vim community.
The (ongoing) successful funding campaign
yielded libmpack, :terminal
, and major refactors and improvements (e.g.
decoupling the UI logic from the TUI). With Thiago taking a less active role in
the project, the funding is available to other developers.
@ZyX-I, a prolific committer to Neovim (21 kLOC
contributed) and Vim (13 kLOC, including if_python
), agreed to take
the role of “lead developer”, i.e. the developer who receives the funding. His
work on Neovim includes:
msgpackparse()
and os/fileio.c
(buffered I/O)The funding does not always go to one person. It’s available to any core contributor who wants to take a month or more to focus on Neovim.
Because funding is monthly, it is (hopefully) a low-friction decision:
:smile
, somehow), let
the pledge continue!The Neovim API is one of the defining technical and “soft” features of the project. In PR #5535 we formed a strategy for growing the API without breaking clients.
2.0
(if ever).The API should only grow, not break. Each API function is marked by the API level where it first became available. This makes it practical for the numerous Neovim API clients to support any released version of Neovim.
Since PR #4934 you can call the
API of the current nvim
process directly from VimL:
:echo nvim_buf_get_lines(42, 1, 3, v:false)
Try :call nvim_<Tab>
at the command line to see the available API functions,
or install the nvim-api-viewer
plugin to see a nice overview of available API functions.
We take API reliability seriously, and we’ve tried to think carefully about the design. Feedback from plugin and client authors is appreciated!
One year ago we announced our first release, 0.1
. We’ve streamlined the
release process (versioning, tagging, changelogs, announcements).
Some users wonder if 0.1
means Neovim is unstable.
0.1
is considered stable for use on all systems
except Windows.
0.2
.1.0
, some non-API features may break backwards compatibility. This is
uncommon, and these cases are always
documented.0.1.6
we introduced API versioning. Clients can dynamically decide
which functions to use.We follow semver; the recommendations there explain
the intention of the 0.x
series.
More OS packages are appearing. Neovim is part of Debian’s next release! Special thanks to @jamessan (Debian maintainer and Neovim contributor), @fwalch and others who build packages for their favorite systems and work with us to address inevitable compiler/platform quirks.
What did Neovim contributors accomplish since 2014?
By a conservative estimate at least 20,000 new lines of C code have been written. We’ve written 2200 new tests, in addition to passing Vim’s own test suite. 273 different people have contributed to the core project. The core project has more commits in 3 years than Vim in 12 years.
Besides major refactoring and feature work, a ton of time was put into the Neovim continuous integration (CI) system. In a stable but fragile C codebase, maintainers tend to ignore “small” features because they may be too risky. CI reduces fragility so we can welcome feature work large and small, instead of fearing change.
New features can be tested rigorously with screen tests. For example, here’s
a test that exercises the 'wildmode'
UI behavior:
describe("'wildmenu'", function()
it(':sign <tab> shows wildmenu completions', function()
execute('set wildmode=full')
execute('set wildmenu')
feed(':sign <tab>')
screen:expect([[
|
~ |
~ |
define jump list > |
:sign define^ |
]])
end)
end)
After we forked Vim in 2014, there was an unstable period; that gap has become smaller and smaller, and will vanish in 2017. Each regression fix is covered by integration tests. Each pull request builds against 12 different environments. Special thanks to @jszakmeister, @fwalch and @ZyX-I for their work on the build system, and to @oni-link for fixing some very difficult bugs.
One of the strongest impressions from social media is that people really appreciate less friction when they try Neovim. Defaults matter. Tim Pope deserves credit for curating many of the defaults we chose.
@fmoralesc and others thought carefully about how to
implement these defaults without
causing regressions (encoding=utf8
and syntax/filetype were tricky). The work
was tedious, but justified: it’s a one-time cost that helps new users, old
users on new systems (which are everywhere these days: VMs, containers,
servers…), and all users by propagating Vim “best practices”.
Here are some new developments since the last newsletter.
:ruby*
commands are supported (so existing
Vim+ruby plugins work in Neovim, such as Command-t and vim-github-dashboard).
gem install neovim
. You don’t need to worry
about compiling against a specific version.:CheckHealth
detects common problems (like Homebrew’s doctor
). Run it
whenever you install or upgrade Neovim.:help api-highlights
) is similar to
matchaddpos()
, with some key differences: it is associated with a buffer and
adapts to line insertions and deletions. Useful for linter or semantic
highlighter plugins that monitor a buffer for changes and compute highlights
in the background.In PR #4432 @bfredl made the first step to give UIs more control over the display of “widgets”. @romgrk quickly made a proof of concept.
It didn’t take long for an ambitious patch to externalize cmdline, tab, wildmenu, and preview window widgets. The demo shows exciting potential:
This work was possible because @tarruda cleanly separated the terminal-UI (TUI) from the internal screen, so even the built-in TUI is driven by UI events like any other externalized UI.
:substitute
In May 2016 a group of students mentored by Eric Burel contacted us about
contributing to Neovim. From a list of ideas we provided, they decided to
implement a “live preview” for :substitute
. We merged it in
PR #5561, released in 0.1.7
.
Set the inccommand
option to try it:
:set inccommand=split
This feature was made possible by our development model: despite having “no time” for a side-project, we outlined the basic idea, the students made decisions out-of-band, and we provided clarification as needed.
Eric wrote about the experience. Thanks to Eric, the students at ENSIMAG, @KillTheMule, and @bfredl for carrying this feature to a conclusion we are proud of.
Look for the following developments in 2017 for Neovim 0.3
.
eval.c
will be separated into
modules,
marking a point where Neovim’s VimL implementation diverges from Vim’s. This
will be the world’s second alternative VimL implementation
(ZyX’s VimL-to-Lua PR was the first).So that was 2016 for Neovim. Could 2017 be the Year of the Neovim Desktop?
Neovim’s ideas are finding their way into other projects, such as Xi editor and Vim itself, which has seen more activity this year than any other year in its history.
There’s a beehive of activity in the gitter and IRC channels (which are bridged by matrix thanks to @leonerd!). Visit us to talk about the project.
And don’t forget there’s a roadmap at neovim.io if you want to check where the project is headed.
Thanks for reading.
—Justin M. Keyes (@justinmk)
$ git log --grep='\([zZ]y[xX]\)\|\([nN]ikolai [pP]av\)\|\([nN]ikolay [pP]av\)' --numstat --pretty=tformat: --numstat|gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 22590 removed lines: 8620 total lines: 13970
$ git log --grep='[cC]hristian [bB]rab' --numstat --pretty=tformat: --numstat|gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
added lines: 10000 removed lines: 3033 total lines: 6967
$ ohcount msgpack_rpc/ api/ os/ event/ tui/ shada.c rbuffer.c terminal.c memory.c
c 79 14576 2863 16.4% 2154 19593
Hi, this is @tarruda and I will be addressing the Neovim community directly in this newsletter. Other than that, I will try to keep it structured as @jdavis did previously. Let’s get started!
Neovim now has its first public release!
A few months ago, @justinmk created the 0.1 milestone which greatly helped us focus on more urgent tasks that resulted in the first release. We planned many features not yet available in 0.1, but decided to postpone them for future milestones, which will be more frequent after this newsletter.
This illustrates the path Neovim will take from now on: Instead of preparing big releases that take forever to happen, we’ll focus on smaller, frequent and more stable releases.
The 0.1 release is basically just a tag for users looking to compile Neovim in a version that has a minimum level of stability, but future releases may also contain precompiled binaries and even installers (when Windows is officially supported).
Neovim 0.1.0 and 0.1.1 are already available in the releases page and for Homebrew/Linuxbrew and Arch Linux. Check the installation page on the Neovim Wiki for more possibilities to install Neovim (although, at the time of writing, most of these will install the latest development version of Neovim instead of a 0.1.x release).
For those that prefer(or need) to compile manually from git, the build instructions still work as usual.
For those who don’t know yet, Bountysource launched a new platform that allows open source projects to obtain sustainable crowdfunding. This platform is conveniently called “salt”, and Neovim was one of the first projects to use it.
The first campaign was very successful and raised about $35,000, which allowed me to work full-time on Neovim for roughly 6 months. Being very enthusiastic about the project and unable to meet all goals in those months, I continued to dedicate a very significant portion of my time to Neovim, so much that it started hurting my personal and professional life. This continued until February when I saw that I simply couldn’t continue with my old pace. Around that time that @rappo offered me to test the salt platform beta version and I saw it as a way to continue my work on Neovim.
Like it’s predecessor, the salt campaign was very successful and allowed me to continue Neovim contributions (in a healthy way) for the past 8 months, thank you!
Did we ever mention how easy it is to build and install Neovim from source? While it has a good number of dependencies, the build system automatically downloads and builds everything without cluttering your system. Check out the installation page on the Neovim Wiki for the exact steps.
Neovim now follows the XDG directory specification. This was proposed by @ZyX-I when the project started, but only a couple of months ago we received a PR from @Yamakaky which was superseded by @jck in a later PR and again by @ZyX-I in a final PR that was merged recently.
Since following the XDG directory specification, Neovim now looks for user
configuration files such as .nvimrc
and those under ~/.nvim
in the
~/.config
directory, which can be overriden by the $XDG_CONFIG_HOME
environment variable. The specification also states that cache files should be
stored in a separate directory (~/.local/share
), which is where files like
viminfo (now ShaDa) or backup/swap can optionally go.
This change makes it simpler for users to backup and manage their configuration since it will be stored with other programs that also follow the specification, not to mention it keeps the home directory cleaner.
Step by step instructions on how to migrate existing configuration can be found at :h nvim-from-vim.
@ZyX-I major ShaDa PR was merged. It completely replaced the viminfo file for storing user data such as register contents, command history, variables, jump list and so on.
A known problem with viminfo is that two Vim instances running concurrently will override each other’s data. ShaDa is a new storage format created by @ZyX-I that not only fixes the problem but also brings a number of enhancements to Neovim:
cat 1.shada
2.shada > joined.shada
, Neovim will handle this properly when reading”.While the PR is very big, @ZyX-I has taken care of adding great test coverage. Great work @ZyX-I!
It’s no secret that libuv is the event loop library used by Neovim, and it is what makes it possible for us to implement features that require asynchronous communication (not initiated by the user) with the editor with ease. Unfortunately due to how Neovim code is currently organized, integrating libuv was not a trivial task.
The basic idea is that Neovim receives arbitrary events when it is polling for user input, but these events can’t be processed immediately because Neovim can be in a state that simply can’t handle arbitrary actions. So if Neovim receives an event while checking user input, it will put the event in a queue for later processing.
One example is illustrated in the following scenario: Neovim checks if the user typed ctrl+c while the regexp engine is executing, but it can’t process the event as it is received because it may want to execute vimscript that calls the regexp engine again, and the engine is not reentrant since it relies heavily on global variables. So it has to postpone the event for when it’s safe, and determining when it’s safe to process events is itself another problem.
Another complication of integrating with libuv is that sometimes Neovim must only process events from a certain source. For example, while Neovim is sending a msgpack-rpc call, it should only process events that come from:
To allow this kind of selective event processing, Neovim must maintain multiple queues that integrate with each other, and the logic to do this is very repetitive. In one of my latest PRs, some libuv “classes” were wrapped in a way that makes managing these queues much easier.
jemalloc, a high performance general purpose memory allocator, is
now used by default. Since Neovim makes heavy use of dynamic queues (see above)
in its inner loops, malloc(3)
is called a lot more than Vim, so it is
important to use a fast implementation that has consistent performance across
platforms.
In a recent PR, @fmoralesc modified the jemalloc version used by our build system to target jemalloc 4.0 which brings even more performance enhancements and adds support for more platforms.
We now use Travis container-based insfrastructure to run Neovim builds, which makes CI builds to start immediately. This was implemented by @fwalch, which also did many other improvements to our build infrastructure, allowing developers to receive much faster feedback when submitting PRs.
@jszakmeister is running a quickbuild server in his own infrastructure. This gives us a backup CI that double checks Neovim PRs, also running tests in FreeBSD which is not covered by travis. Thank you for improving Neovim robustness @jszakmeister!
Did you know that there is an alternative to syntastic that makes use of Neovim asynchronous capabilities? Neomake is the best plugin for syntatic checking on Neovim: It is extensible like syntastic and the fact that it uses job-control allows it to perform checking in background without blocking the user interface. This is very useful for compiled languages that are slower to check (typescript, java, .NET).
The migration from syntastic is also very trivial, great work @benekastah!
fzf is a command-line fuzzy finder that thanks to its author (@junegunn, the same developer behind vim-plug), has great Neovim support through a plugin that uses our builtin terminal emulator.
FZF is a great alternative to plugins like ctrlp: It is really fast and
has the advantage of running in another process, which can make use of
multi-core systems and doesn’t block Neovim user interface. To see how fast and
responsive it is, just try running :FZF
to search for files on the linux
source tree!
Besides fzf, the user is also encouraged to install fzf.vim, a plugin that exposes some very useful commands that are implemented on top of fzf.
@Shougo has created deoplete.nvim, an asynchronous completion engine written as a remote-plugin that makes use of Neovim async capabilities to allow completions to be computed without blocking the user interface. He decided to write a new plugin from the scratch because Neovim doesn’t support the lua interface required for neocomplete. @Shougo is the sith lord of Vim plugins, here’s a list containing some of his previous work:
The community can expect great things from deoplete.nvim!
(Recently @Shougo posted a slide to explain the ideas behind deoplete.)
Neoterm is a plugin for easily running tests in a terminal window. It was written by @kassio and supports the following test libraries:
Very useful @kassio!
]]>