I settled on vim for its technical merits but Bram using his goodwill to fund a charity like this for so long always made me feel good about my choice.
One question is: will more plugin authors move to Vim9Script? It seems that Neovim users have generally moved towards Lua-based plugins, so there's less of a motivation to produce plugins that support both Neovim and Vim9.
>Full support for the Wayland UI
I really hope they never deprecate X11 support :) I doubt they will, but if they do, it will leave the BSDs without a good alternative.
cool
While walking around a file with keyboard, sometimes a random line's indent is removed - that is, text goes left-flushed. AND it's not a tracked change that can be UNDOne - as if it never happened / always has-been-so. Have not been able to correlate this to any other thing. It happens like once a few days, very rarely it might happen twice within minutes. Sometimes i notice that, sometimes i don't and (luckily) python screams of broken indentation. If the file isn't deeply nested python.. good luck.
Has anyone "achieved" such a thing?
So - on the occasion of VIm 9.2 coming out - do people have a recommendation for a gentle path to "leveling up" one's VIm skills and engagement?
Only joking of course, actually quite refreshing to see a new version announcement of something this major without any AI nonsense.
Congratulations on the new release! Looking forward to applying these awesome improvements.
Also, I cannot think of an extension / new feature that makes sense as a part of Vim (if I want something more, I want a lot more. I don't want Vim to do a lot more, for the sake of simplicity and conformity, that's a job for vscode with Vim extension).
At the same time I wouldn't object to someone adding features to this program. But they have to try really hard to convince me to start relying on that feature (I wouldn't, because I would miss it on Ubuntu 20.04 and I will forget how I used to work without that feature).
I tried nvim a few years ago and honestly didn't find anything advantageous there. But since I had `:sh` in muscle memory and it was a bit (very?) different there I gave up on nvim.
In the end I just kept quiet about the fact that it ships in all the Linux package repos.
(Just to be clear, I fully support what Bram did here)
But Lua support in Neovim is the primary reason I moved over from Emacs. Elisp and Vim are both so heart sink for me.
That said I'd have preferred something other than Lua if I had the choice.
Honestly a lot of this is that I hate Lua. With so much of the infrastructure moving in that direction it's basically unavoidable. XDG support was honestly one of the things holding me back; I'm glad that this is finally fixed.
the scripting language is.. okay, but u have to try doing something practical in it, to get a feeling.
see my vimrc, being updating it since ~2000
https://github.com/svilendobrev/svd_bin/blob/master/qini/_vi...
And the VimL Primer[2] by B. Klein
But Vim is a whole culture that starts with ed(1), the standard editor. You do edit based on line numbers and regex addressing and commands. Then there was ex(1) that added more features. vi(1) added a `visual` mode to ex(1), and some commands can now be done in relation to the position of the cursor. Vim is the improved version of vi(1), a lot more commands and a scripting language.
The plugin system is similar to everything that was unix at that time, relying on a variable like $PATH. Any path added to that variable (runtimepath for vim), should follow some patterns for subdirectories and the file will be loaded according to a certain logic. Plugin managers actually manage that variable and do a few things aside (isolating plugins, downloading from forges,...)
[0]: https://pragprog.com/titles/dnvim2/practical-vim-second-edit...
[1]: https://pragprog.com/titles/modvim/modern-vim/
[2]: https://www.oreilly.com/library/view/the-viml-primer/9781680...
It seems they didn't publish the tag yet though.
I was such a proponent.
If I'm entirely reading code for bugs, then using voice to text to the AI to correct the problem... What typing am I doing?
Still love the idea of Vim.
Actual Intelligence. It's connected to fingers/hands/arms/torso that is using it.
Same. I know we as a community would never agree on what that language should be, but in my dreams it would have been ruby. Even javascript would have been better for me than Lua.
Obviously vim doesn't need AI, but one feature I really wish vim had was native support for multiple cursors.
It's the feature that lured me away to Sublime Text in the first place many years ago, and it's a pre-requisite for pretty much every editor I use these days, from VSCode to Zed.
There are plugins, but multicursor is such a powerful force-multiplier that I think a native implementation would benefit.
On Linux, this is commonly accomplished using Red Hat Satellite [1], although many other tools are also available to use instead.
Getting approval to install something like Vim can literally take months of effort and arguing.
[1] https://docs.redhat.com/en/documentation/red_hat_satellite/6...
Ctrl-V, then move down the lines you want to edit, Shift-I to insert text on multiple lines at once.
One little thought is, has there been much drama between the vim and neovim communities? (I guess community can be defined broadly enough that the answer to that question is always “yes,” but I haven’t seen much). They both seem completely happy to just do their own thing. I think the perennial argument just exits in the mind of some fans.
It is nice to see a pair of projects with so much potential for competition coexisting peacefully. Plenty of room on the internet I guess.
Not that I agree with your parent comment or anything (I don’t), I use Helix so don’t really have a dog in this fight, I think it’s fine for them all to coexist.
I can't prove it, but I am willing to bet my entire salary that the costs of all the new extra bureaucratic overhead introduced for small purchases, nullified or even exceeded all their savings, when the remaining engineers and managers paid six figures have to spend more of their time writing, reviewing and approving paperclip orders instead of you know, running the company, fulfilling customer demands and innovating.
I'm pretty new to this, but I have a feeling these are all the signs of a company it's worth jumping ship from ASAP as there's no chance of things improving back from this. Sure, AMD managed to turn the ship around with cost cutting, but our CEO is not Lisa Su, he's a boomer who cuts where the clueless $BIG_4 consultants tell him to cut, and big_4 doesn't care about innovation or the company being relevant in 10 years, they care about showing some immediate results/positive cash to justify their outrageous rates.
But if you wanted to install it separately on a computer that didn't have it already, then you'd need to get it “approved.”
Why?
If you need multi-cursor to do manual search and replace in text, then don't, just do automatic search and replace, maybe scoped to a block. If you need multi-cursor for refactoring or renaming a variable across entire source file, then don't, use LSP plugin (or switch to Neovim) and do the proper refactoring action.
Sure, there are legit cases of using multi-cursor in Vim, but they are rare. So it's not worth to put it into Vim itself.
The Vim project is happy to announce that Vim 9.2 has been released.
Vim 9.2 brings significant enhancements to the Vim9 scripting language, improved diff mode, comprehensive completion features, and platform-specific improvements including experimental Wayland support.
CTRL-X CTRL-R). New 'completeopt' flags like nosort and nearest offer finer control over how matches are displayed and ordered.$HOME/.config/vim for user configuration.:Tutor) provides a modernized learning experience beyond the traditional vimtutor.Significant language enhancements including native support for Enums, Generic functions, and the Tuple data type. Built-in functions are now integrated as object methods, and classes now support protected _new() methods and :defcompile for full method compilation.
The maturity of Vim9 script's modern constructs is now being leveraged by advanced AI development tools. Contributor Yegappan Lakshmanan recently demonstrated the efficacy of these new features through two projects generated using GitHub Copilot:
Vim 9.2 introduces significant enhancements to how changes are visualized and aligned in diff mode:
'diffopt' setting. This aligns changes between buffers on similar lines, greatly improving diff highlighting accuracy.'diffanchors' option allows you to specify anchor points (comma-separated addresses) to split and independently diff buffer sections, ensuring better alignment in complex files."inline" sub-option for 'diffopt'. Note that "inline:simple" has been added to the default 'diffopt' value.Here are some examples for the improved inline highlighting:
inline:simple (old behavior)

inline:char

inline:word

Several long-standing defaults have been updated to better suit modern hardware and workflows. These values have been removed from defaults.vim as they are now the internal defaults.
| Option | Old Default | New Default (9.2) |
|---|---|---|
'history' |
50 | 200 (More undo/command history saved) |
'backspace' |
"" (empty) | "indent,eol,start" (Normal backspace behavior) |
'diffopt' |
"internal,filler" | "internal,filler,closeoff,indent-heuristic,inline:char" |
'fontsize' (GTK) |
10pt | 12pt (Optimized for High-DPI monitors) |
'showcmd' |
Off (Unix) | On (Always visible in non-compatible mode) |
'ruler' |
Off | On (Shows cursor position by default) |
These examples demonstrate how to use the powerful new completion and introspection tools available in Vim 9.2.
Vim's standard completion frequently checks for user input while searching for new matches. It is responsive irrespective of file size. This makes it well-suited for smooth auto-completion.
vim9script
def InsComplete()
if getcharstr(1) == '' && getline('.')->strpart(0, col('.') - 1) =~ '\k$'
SkipTextChangedIEvent()
feedkeys("\<c-n>", "n")
endif
enddef
def SkipTextChangedIEvent(): string
# Suppress next event caused by <c-e> (or <c-n> when no matches found)
set eventignore+=TextChangedI
timer_start(1, (_) => {
set eventignore-=TextChangedI
})
return ''
enddef
set cot=menuone,popup,noselect inf
autocmd TextChangedI * InsComplete()
inoremap <silent> <c-e> <c-r>=<SID>SkipTextChangedIEvent()<cr><c-e>
vim9script
var selected_match = null_string
var allfiles: list<string>
def GrepComplete(arglead: string, cmdline: string, cursorpos: number): list<any>
return arglead->len() > 1 ? systemlist($'grep -REIHns "{arglead}"' ..
' --exclude-dir=.git --exclude=".*" --exclude="tags" --exclude="*.swp"') : []
enddef
def VisitFile()
if (selected_match != null_string)
var qfitem = getqflist({lines: [selected_match]}).items[0]
if qfitem->has_key('bufnr') && qfitem.lnum > 0
var pos = qfitem.vcol > 0 ? 'setcharpos' : 'setpos'
exec $':b +call\ {pos}(".",\ [0,\ {qfitem.lnum},\ {qfitem.col},\ 0]) {qfitem.bufnr}'
setbufvar(qfitem.bufnr, '&buflisted', 1)
endif
endif
enddef
def FuzzyFind(arglead: string, _: string, _: number): list<string>
if allfiles == null_list
allfiles = systemlist($'find {get(g:, "fzfind_root", ".")} \!
\( -path "*/.git" -prune -o -name "*.swp" \) -type f -follow')
endif
return arglead == '' ? allfiles : allfiles->matchfuzzy(arglead)
enddef
def FuzzyBuffer(arglead: string, _: string, _: number): list<string>
var bufs = execute('buffers', 'silent!')->split("\n")
var altbuf = bufs->indexof((_, v) => v =~ '^\s*\d\+\s\+#')
if altbuf != -1
[bufs[0], bufs[altbuf]] = [bufs[altbuf], bufs[0]]
endif
return arglead == '' ? bufs : bufs->matchfuzzy(arglead)
enddef
def SelectItem()
selected_match = ''
if getcmdline() =~ '^\s*\%(Grep\|Find\|Buffer\)\s'
var info = cmdcomplete_info()
if info != {} && info.pum_visible && !info.matches->empty()
selected_match = info.selected != -1 ? info.matches[info.selected] : info.matches[0]
setcmdline(info.cmdline_orig) # Preserve search pattern in history
endif
endif
enddef
command! -nargs=+ -complete=customlist,GrepComplete Grep VisitFile()
command! -nargs=* -complete=customlist,FuzzyBuffer Buffer exe 'b ' .. selected_match->matchstr('\d\+')
command! -nargs=* -complete=customlist,FuzzyFind Find exe !empty(selected_match) ? $'e {selected_match}' : ''
nnoremap <leader>g :Grep<space>
nnoremap <leader>G :Grep <c-r>=expand("<cword>")<cr>
nnoremap <leader><space> :<c-r>=execute('let fzfind_root="."')\|''<cr>Find<space><c-@>
nnoremap <leader>fv :<c-r>=execute('let fzfind_root="$HOME/.vim"')\|''<cr>Find<space><c-@>
nnoremap <leader>fV :<c-r>=execute('let fzfind_root="$VIMRUNTIME"')\|''<cr>Find<space><c-@>
nnoremap <leader><bs> :Buffer <c-@>
autocmd CmdlineEnter : allfiles = null_list
autocmd CmdlineLeavePre : SelectItem()
vim9script
def CmdComplete()
var [cmdline, curpos] = [getcmdline(), getcmdpos()]
if getchar(1, {number: true}) == 0 # Typehead is empty
&& !pumvisible() && curpos == cmdline->len() + 1
&& cmdline =~ '\%(\w\|[*/:.-]\)$' && cmdline !~ '^\d\+$'
feedkeys("\<C-@>", "ti")
SkipCmdlineChanged()
timer_start(0, (_) => getcmdline()->substitute('\%x00', '', 'g')->setcmdline())
endif
enddef
def SkipCmdlineChanged(key = ''): string
set ei+=CmdlineChanged
timer_start(0, (_) => execute('set ei-=CmdlineChanged'))
return key != '' ? ((pumvisible() ? "\<c-e>" : '') .. key) : ''
enddef
set wim=noselect:lastused,full wop=pum wcm=<C-@> wmnu
autocmd CmdlineChanged : CmdComplete()
autocmd CmdlineEnter : set bo+=error
autocmd CmdlineLeave : set bo-=error
cnoremap <expr> <up> SkipCmdlineChanged("\<up>")
cnoremap <expr> <down> SkipCmdlineChanged("\<down>")
For automatic popup menu completion as you type in search or : commands, include this in your .vimrc:
vim9script
def CmdComplete()
var [cmdline, curpos, cmdmode] = [getcmdline(), getcmdpos(), expand('<afile>') == ':']
var trigger_char = '\%(\w\|[*/:.-]\)$'
var not_trigger_char = '^\%(\d\|,\|+\|-\)\+$'
if getchar(1, {number: true}) == 0
&& !wildmenumode() && curpos == cmdline->len() + 1
&& (!cmdmode || (cmdline =~ trigger_char && cmdline !~ not_trigger_char))
SkipCmdlineChanged()
feedkeys("\<C-@>", "t")
timer_start(0, (_) => getcmdline()->substitute('\%x00', '', 'ge')->setcmdline())
endif
enddef
def SkipCmdlineChanged(key = ''): string
set ei+=CmdlineChanged
timer_start(0, (_) => execute('set ei-=CmdlineChanged'))
return key == '' ? '' : ((wildmenumode() ? "\<C-E>" : '') .. key)
enddef
set wim=noselect:lastused,full wop=pum wcm=<C-@> wmnu
autocmd CmdlineChanged :,/,? CmdComplete()
# Optional: Preserve history recall behavior
cnoremap <expr> <Up> SkipCmdlineChanged("\<Up>")
cnoremap <expr> <Down> SkipCmdlineChanged("\<Down>")
# Optional: Customize popup height
autocmd CmdlineEnter : set bo+=error | exec $'set ph={max([10, winheight(0) - 4])}'
autocmd CmdlineEnter /,? set bo+=error ph=8
autocmd CmdlineLeave :,/,? set bo-=error ph&
Many bugs have been fixed since the release of Vim 9.1, including security vulnerabilities, memory leaks and potential crashes.
For over 30 years, Vim has been "Charityware," supporting children in Kibaale, Uganda. Following the passing of Bram Moolenaar, the ICCF Holland foundation was dissolved, and its mission has been carried forward by a new partner.
For information on how to support this cause, please visit the Sponsor page.
We would like to thank everybody who contributed to the project through patches, translations, and bug reports. We are very grateful for any support.
You can find the new release on the Download page.
February 14th, 2026

When you're being outcompeted and outmaneuvered it's important to slow down and make sure you save a few dollars wherever possible, apparently.
https://aider.chat/docs/usage/watch.html
I imagine with vim, from the document you're editing, you'd go:
:ter
to get a terminal. Fire up aider with --watch-files in the terminal. Hop back up to the file and start telling it what to do. Hit L when it's done to see the changes.
That's just a guess but after writing it out I kinda want to try it.
When I use aider it's via its chat interface and then I load the file with vim in another terminal tab to follow along but I think --watch-files with vim would be fun.
I still have PyCharm, especially for working with data which I do a lot it helps quite a bit, but by default I'm back to a very vanilla Vim setup. Others have mentioned tmux which is great and I'd use anyway especially over ssh, but even just terminal tabs for instances of agents are fine frankly.
Bonus point linking the name to the hellish corporation in Max Payne.
Also Ruby has been getting quite fast since YJIT (and now ZJIT):
lua array index starting at 1 gets me at least once whenever i sit down to write a library for my nvim or wezterm.
But the people who did the work wanted Lua, and I have no problem with that. That's their privilege as the people doing the work. I'm still free to fork it and make ruby or js or whatever (Elixir would be awesome!) first-class.
[0] I've been using vim-multiple-cursors for years, it's abandoned but still works ok most of the time.
https://groups.google.com/g/vim_dev/c/65jjGqS1_VQ/m/fFiFrrIB...
Vim 8 did add support for asynchronous jobs, due to the pressure of Neovim fork.
limitations on what you can install on such machines can be quite draconian, including forbidding anything that IT Security and similar departments may not like.
Fabrice Bellard! https://github.com/bellard/mquickjs
(I agree with you, just wanted to note this super neat project)
There is a large class of problems now for which I consider the chosen programming language to be irrelevant. I don't vibe code my driver code/systems programming stuff, but my helper scripts, gdb extensions, etc are mostly written or maintained by an LLM now.
it’s pretty great to have my vimconfig give red squiggle in editor if i’m doing it wrong before i save & reload.
but i’ve not followed vim9 script as its evolved perhaps there’s a good type checker for it at this point?
even before neovim, there were vim extensions written in lua so it feels gravity of lua code has been considerable for a long time.
to me vim9script feels like perl5/raku split - evolution too late to grow new users, a remnant for a niche that will fade to oblivion slowly over the next 10 years.
Totally worth it
as an aside i’m curious how quickjs/mquickjs compares to mruby in speed and size. something to ponder
Just an honest opinion of someone who didn’t have skin in the game. Not sure if it helps.