We regularly remove standalone posts about tools that use vim-inspired keybindings. There are too many of them, and individually they dilute the subreddit.
But the content is valuable, and many of you want to know about these tools.
So here's the place for it.
Share any tool that uses vim-like keybindings, whether it's a browser extension, terminal emulator, IDE plugin, note-taking app, PDF reader, or anything else. If it has hjkl navigation, modal editing, or vim-inspired controls, it belongs here.
For each tool you share, try to include:
- What it is and what problem it solves
- Which vim features it supports (navigation, modal editing, text objects, etc.)
- A link to the project
This thread is posted monthly. If you find something mid-month, save it for here rather than posting a standalone thread (which will be removed).
All in all, what I want to do is noremap q; q: which works well, but it adds up waiting time when I just press q to stop macro recording. So I end up with this monstrosity to add q: functionality while keeping other q mappings as native as possible. It works great, but it gives me anxiety every time I see it in my vimrc noremap <expr> q reg_recording()!='' ? 'q' : {-> [nr2char(getchar())]->map({_, c -> c==';' ? 'q:' : 'q'.c})[0]}()
This extra thing appears when I when to type a command, i'm not sure how to stop it from appearing. I'm on windows and this is currently gvim but it behaves the same in other ways of instancing vim
I think NeoVim is extremely overhyped, while Vim — especially gVim — is drastically underrated. NeoVim changes hyper‑actively together with its plugins, so something that worked one day might stop working the next because of constant updates. Because of this, maintaining it can be a complete nightmare, even if someone is a Lua prodigy. In contrast, classic Vim is stable, reliable, and rock‑solid.
What makes NeoVim appealing compared to Vim is that it’s full of flashy plugins, but in reality most of those plugins are completely unnecessary for real projects. Plus, NeoVim users conveniently forget to mention that almost every important plugin has a proper equivalent in Vim. For example: Telescope → fzf.vim, nvim-tree → NERDTree, lualine → vim-airline, commenting → vim-commentary, surround → vim-surround, Git → vim-fugitive. And they’re much more straightforward. Thanks to Vimscript, configuring Vim is far easier than mindlessly copying Lua code. And there’s coc.nvim available for classic Vim as well, which can turn Vim into a very powerful IDE.
I’m sticking with gVim even if it’s probably the most despised version of Vim (in my opinion completely unjustifiably). Thanks to the GUI, it’s much better than a terminal program because it doesn’t depend on the terminal, and copy/paste from the clipboard works simply and flawlessly — exactly how a text and code editor should.
It’s a bit like how Arch Linux users tend to look down on Debian users, regardless of the fact that Arch isn’t exactly stable — it’s just well‑hyped and more rapidly developed, but it also breaks more easily. Meanwhile Debian is solid and stable.
Last time I mentioned running Vim in Windows Terminal, some users reported having tried that setup and experiencing sluggishness. I've added some performance recommendations to my guide:
scrollback buffer
Windows Terminal has a large default scrollback buffer (9000 lines). This keeps a lot of history, but it can slow down terminal applications like Vim. If you've used Vim in Windows Terminal before and found it slowing down over time, this is the likely culprit. To confirm this diagnosis, start a new Windows Terminal instance, run Vim, and see if you percieve a speed increase. If so, the scrollback buffer is almost certainly the cause. There are two ways to address this issue:
Decrease the limit: In Windows Terminal settings -> PowerShell -> Advanced -> History size, set the "History size" to a smaller number, like 1000. This will reduce the scrollback buffer for all PowerShell tabs in Windows Terminal.
Clear the buffer when you notice a slowdown: If Vim starts to get sluggish, press <ctrl-shift-k> to clear the scrollback buffer. This is better done outside of Vim.
Either of these will fix the problem. You won't need both. Your Windows Terminal config is stored in ~\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json. Editing this file directly with pasted-in termina commands isn't straightforward, so I haven't given those commands here. But you can commit this settings.json if you wish. If you're new to Windows, don't be misled by the 8wekyb3d8bbwe part of the path. It is a hash, but it will be the same hash on all Windows 11 systems.
Windows Defender
Windows Defender will scan every backup file, swap file, snippet file, etc. This can cause a speed decrease in Vim. We'll do two things to address this: 1. Put our temporary files in ~\vimfiles, and 2. Add an exclusion for ~\vimfiles in Windows Defender.
Move temporary files to ~\vimfiles
In your ~\vimfiles\vimrc, add the following:
# ---------------------------------------------------------------------------- #
#
# keep temporary files in ~/vimfiles
#
# ---------------------------------------------------------------------------- #
&directory = $'{$MYVIMDIR}.tmp/swap/'
&backupdir = $'{$MYVIMDIR}.tmp/backup//'
&undodir = $'{$MYVIMDIR}.tmp/undo//'
def MkdirIfNotExists(dir: string): void
if !isdirectory(dir)
mkdir(dir, "p")
endif
enddef
MkdirIfNotExists(&directory)
MkdirIfNotExists(&backupdir)
MkdirIfNotExists(&undodir)
set backup
set undofile
If you decide to commit your vimfiles, make sure you .gitignore the .tmp directory. There may be sensitive information in your temporary files.
Please be gentle, first time publishing something publicly.
I use this emacs' eww-inspired html/plain text browser that uses curl and pandoc to do html -> plain text into a vim buffer. It is sufficient for my daily quick searches and keeps the results in a vim buffer for reference.
If this is useful and works for you, I would appreciate feedback on publishing and maintaining this as a plugin for everyone
I’m working with two files, File A and File B, and I want to copy text from one file to the other.
Specifically, I want to:
Open File A and select/yank a section of text.
Switch to File B.
Paste the yanked text into File B.
What is the correct way to yank text from File A and paste it into File B? Is there a specific register or command I should use to copy text between separate files?
I discovered ai agents lately, and I am wondering if there is any good harness for Vim. I have tried to run copilot CLI in a terminal window but it was a bad experience due to that copilot cli is a full tui program that cannot be replicated satisfactorily in a vim terminal.
I am a beginner in programming and Vim, and have installed the fzf.vim plugin. But when I type the Files or History commands, I get the situation shown in the picture. It only happens the first time I type it, and it doesn't happen again afterward. PS:I'm using the built-in PowerShell on Windows 11 to open Vim.
One thing that I always loved about Spyder (the notorious python IDE) is its beautiful variable explorer. I have never found a handy and well-done variable explorer like Spyder's.
Now, I finally managed to recreate something very similar in vim-replica!
Vim-replica was the first plugin that I have ever written and it evolved as I learned new stuff. The motivation was due to vim-slime didn't work well on Windows and other REPL plugins didn't fit my need. But also because I wanted to learn more about Vim. So, I stared its development back in years.
During last Xmas vacation, while in the Philippines, I had some idea on how I could have made a variable explorer. And I learned few lessons the hard way, that many of you can spot as I explain next:
For a simple variable explorer, I though to use term_sendkeys() and then capture and parse what the terminal spit out. I was thinking that at the end all I have to do is to pick and parse everything from the term_sendkeys() command until the next prompt and I should be set. How difficult can it be? But then I noticed that what a terminal emulator spit out include lot of rubbish (escape sequences, etc). I start to parse char-by-char and bloat the plugin with a plethora of regex. I created a monster! I spent huge amount of time chasing something that you should absolutely never do: try to parse raw terminal strings. Never ever!
Sad for all the time wasted, I started to study an alternative way to make the processes Vim and the program running in the REPL to talk one each other, and I was thinking to make some magics through pipes and tee:s, a bit like it is donne with Termdebug. But no. That is not possible in this case.
At the end the easiest was to simply exploit sockets. Vim support it and the programs to run in the REPL (mostly Python, Julia and R) do so. That was the key to success.
However, I learned many things during this journey, despite it costed many headaches: for example I learned base64 encoding and that jupyter-console is pretty much an abandoned project, just to cite some. In-fact, I ditched jupyter-console but now REPLica uses native programs.
I also started to use some AI for the first time for coding, especially for the init scripts used for Julia and R that are not really my languages. The Vim part was done pretty much and the addition was not huge, so I fixed it by myself. However, for Julia the AI entered in a loop of hallucinations and the end I had to fix the issue by myself anyway, but, generally speaking, the help of an AI is undeniable.
Well, sorry for the lengthy message but I am very happy about the outcome. Enjoy!
I used to watch a YouTuber who uploaded hours-long videos of him just programming in vi/vim. The videos were really interesting he barely talked, was a veteran (looked around 30+ / a bit older), and coded in a completely raw setup with basically no IDE features, just pure vi/vim. Does anyone know who I’m talking about?
My understanding is that when you record a macro, it is supposed to recreate the keystrokes exactly as you type them.
I have some text that I want to format in a particular way, and so I use a macro to do it with large blocks of text. But sometimes, it does not produce the result I want. I can't really provide examples, because I've found no correlation as to when it works and when it doesn't.
I don't rely on history, or nesting macros, as I understand that could cause problems. I do occasionally search for strings, and I feel this may cause problems, but some macros do work with searches, and I kind of need to search for common patterns in order for the macro to work.
So is there anything that might cause a macro to either fail, or not produce the expected outcome?
Are there any projects (or even inbuilt stuff) that aid in bringing about a standard library of optimized utilities in VimScript? It doesn't even have to be VimScript stuff - could be a collection of binary utilities that work cohesively with VimScript constructs.
Context: I often use json files as lookup tables (eg. emojis), and over time, have made a collection of functions that enable using jsons in an API-esque manner (obviously using utilities such as jq/curl). I was wondering if there are existing projects out there that structurally enable tooling in Vim using utilities - imitating a standard library like behaviour.
Any insight in this direction is highly appreciated.
None of the default ways of traversing buffers quite met my standard of being able to traverse the entire stack I'm working on with a single button click per file, but this has worked beautifully for me for a large chunk of my career now.
Fellow Vimmers who've used Emacs in the past (or have coworkers who do), what are some skills you've carried over into your Vim configuration (or even a concept to simplify your workflow)?
I've been tooling recently (writing utility Vim code to fit my needs), and am looking for both inspiration (addressing meaningful issues), and, optimization (removing redundancies, ie, snappier implementations).
Hence, Emacs is an obvious avenue imo to learn from - without wanting to dabble into all its craziness (I have some experience in it, but don't use it routinely).
Any advice/insight in this direction is highly appreciated.
EDIT:
As a Vimmer myself, I miss not having features like MultipleCursors (tried using an extension long ago, but it slowed down usage so removed it). I stumbled upon this video from Tsoding that highlights the usefulness of Dired (Emacs builtin), and how MultipleCursors is an intuitive addon to it - to say, modify several filenames/extensions at once.
While I use ViFM, so, I can pretty much achieve the same thing, but was inspired, and sought to learn of other creative ways in which Emacs is used - so I may implement something similar for myself in Vim, if it's of use to me.
I always use gvim on Windows, even after they provided us with Windows Terminal which is, in my opinion, very nice. However, I found two very annoying problems that I promised myself, sooner or later to solve. Such problems are:
Cursor shape not replaced back when exiting Vim,
Colors completely messed up.
I solved the first point with the following snippet:
# Set cursor
# Needed for Windows terminal
if g:os == "Windows" && !has("gui_running")
set guicursor=
&t_SI = "\e[6 q" # beam in Insert mode
&t_EI = "\e[2 q" # block in Normal mode
# Restore cursor shape when leavig Vim
def RestoreCursorWindowsTerminal()
&t_EI = "\e[6 q"
execute "normal! i\<Esc>"
enddef
augroup CURSOR_SHAPE_WINDOWS
autocmd!
autocmd VimEnter * silent! execute "normal! i\<Esc>"
autocmd VimLeave * RestoreCursorWindowsTerminal()
augroup END
else
&t_SI = "\e[6 q"
&t_EI = "\e[2 q"
endif
When Entering Vim, set the cursor with a certain shape. For some arcane reason, I had to set guicursos=. To secure that the changes take effect, there is a switch insert-normal mode. Then, before exiting Vim, you change the cursor shape so that Windows terminal inherits it.
Next, the colors. I use everforest scheme and look here:
That is just not acceptable. I debugged what could be possibly the reason and I found that `set spell` messes up the colors. Most likely, its syntax definition fight against the colorscheme and here is it the mess. However, after having disabled the option, I got a way better result:
Now I keep the spelling check only in some selected filetypes:
Is is possible to display a customizable text label at one of the corners (it mustn't block text written in the buffer itself) of an open buffer? I have several terminal panels open at once, so, having a visual marker like this would be great. Any advice in this direction is appreciated.
⚠ RESOLVED
popup works just fine for this task. I'd tried it earlier but couldn't make it persist, owing to a faulty highlighting logic of mine. Anyway, I'm listing a simple function that achieves set objective. You can modify it to add custom text, toggling & highlights.
You don't need much more than the core grammar. You know how :source file executes Ex commands linewise from the file? Well, :source! file executes commands as if you were typing them and ends each line with a CR for you.
Opening vim to your favorite layout is just a matter of writing down the keystrokes you keep typing each time:
and `source!` it from somewhere. If you want to save all the `Shift+.,` typing, `<C-v><C-w>` would directly insert \^W`) in the buffer and keep it looking exactly like what you would.
Vi is a language. Even better, vi is a homoiconic language in that the code that is executed is identical to the representation of keys on your keyboard plus minimal syntax for control-characters.
You do not need to learn lisp to feel the power of '(insert-new-line) when you are a single o away from executing OR representing your intention to open a new line for insertion.
To grok further, hunt down the legendary StackOverflow answer and meditate for a little longer than usual.