Neovim

11 readers
0 users here now

Neovim is an hyperextensible Vim-based text editor. Learn more at neovim.io.

founded 2 years ago
MODERATORS
1
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Informal-Addendum435 on 2025-11-12 11:18:13+00:00.

2
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Moshem1 on 2025-11-12 10:16:23+00:00.


the incredible neovim builtin difftool (https://neovim.io/doc/user/plugins.html#difftool)

eliminated for me the need to have my own implementation of diffing directories from within neovim.

Here's a small wrapper I created that seems more logical, since you need to load it and I do want to load it on-demand.

--------------
-- Difftool --
--------------
vim.api.nvim_create_user_command('DirDiff', function(opts)
  if vim.tbl_count(opts.fargs) ~= 2 then
    vim.notify('DirDiff requires exactly two directory arguments', vim.log.levels.ERROR)
    return
  end

  vim.cmd 'tabnew'
  vim.cmd.packadd 'nvim.difftool'
  require('difftool').open(opts.fargs[1], opts.fargs[2], {
    rename = {
      detect = false,
    },
    ignore = { '.git' },
  })
end, { complete = 'dir', nargs = '*' })

Usage:

:DirDiff directory1 directory2

let me know if you find it useful.

3
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/vimburton on 2025-11-12 07:24:07+00:00.

4
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/SillyEnglishKinnigit on 2025-11-11 22:44:26+00:00.


The MiniMax config provided by u/echasnovski is fantastic. Minimal, easy to modify (once you get used to the setup) and has become my DD for nvim related work. I've abandoned my attempts and rolling my own with Lazy because this does 98% of what I am looking for out of the box.

5
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/jessevdp on 2025-11-11 10:40:00+00:00.


I'm working on a new nvim configuration based on the nightly version utilizing vim.pack.add. I noticed that nvim-treesitter has been rewritten on the main branch: "This is a full, incompatible, rewrite."

As part of the rewrite there is no longer a convenient built in way to auto install parsers.

Also, since I'm using vim.pack.add I have to find a way to ensure :TSUpdate is run when the plugin updates.

I came up with the following. How did I do?

vim.pack.add({
  { src = "https://github.com/nvim-treesitter/nvim-treesitter", version = "main" },
}, { confirm = false })

local ts = require("nvim-treesitter")
local augroup = vim.api.nvim_create_augroup("myconfig.treesitter", { clear = true })

vim.api.nvim_create_autocmd("FileType", {
  group = augroup,
  pattern = { "*" },
  callback = function(event)
    local filetype = event.match
    local lang = vim.treesitter.language.get_lang(filetype)
    local is_installed, error = vim.treesitter.language.add(lang)

    if not is_installed then
      local available_langs = ts.get_available()
      local is_available = vim.tbl_contains(available_langs, lang)

      if is_available then
        vim.notify("Installing treesitter parser for " .. lang, vim.log.levels.INFO)
        ts.install({ lang }):wait(30 * 1000)
      end
    end

    local ok, _ = pcall(vim.treesitter.start, event.buf, lang)
    if not ok then return end

    vim.bo[event.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
    vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
  end
})

vim.api.nvim_create_autocmd("PackChanged", {
  group = augroup,
  pattern = { "nvim-treesitter" },
  callback = function(event)
    vim.notify("Updating treesitter parsers", vim.log.levels.INFO)
    ts.update(nil, { summary = true }):wait(30 * 1000)
  end
})

BTW, I actually like this rewrite and how it forced me to learn a little bit more about how neovim works with treesitter, what parts are built into neovim vs. what is handled by the plugin, etc.

6
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/nvtrev on 2025-11-11 13:33:35+00:00.

7
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/domsch1988 on 2025-11-10 08:32:23+00:00.


Basically, the first idea, that feels natural, is to use hjkl for movement basically everywhere. But i'm seriously running out of modifiers here.

  • Without Mods -> Movement in nvim
  • Alt -> Splits inside Neovim or Splits in the terminal (clashes already)
  • Alt+Shift -> Create Splits in Terminal
  • Alt+Ctrl -> Tab Navigation
  • Ctrl+Shift -> Desktop focus Window in direction
  • Alt+Ctrl+Shift -> Desktop tiling Windows in direction

I still have the Super/Windows key and that gets used depending on the PC i'm working on, but really, especially when trying to run Neovim in a terminal while also utilising splits in the terminal and some level of Desktop window management, i just run out of modifiers to use here.

How does everyone else work with this? Do you just use different keys for navigation in terminal splits or window managers?

8
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Lavinraj on 2025-11-10 13:18:56+00:00.

9
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/damien__f1 on 2025-11-10 13:16:34+00:00.

10
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/ARROW3568 on 2025-11-09 03:02:05+00:00.


This unlocks so many workflows.

11
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/frodo_swaggins233 on 2025-11-08 17:15:44+00:00.


Found a way to run dynamic indent guides based on the current window's shiftwidth without a plugin:

" Default listchars with tab modified
set listchars=tab:\│\ ,precedes:>,extends:<

autocmd OptionSet shiftwidth call s:SetSpaceIndentGuides(v:option\_new)
autocmd BufWinEnter \* call s:SetSpaceIndentGuides(&l:shiftwidth)

function! s:SetSpaceIndentGuides(sw) abort
 let indent = a:sw ? a:sw : &tabstop
 if &l:listchars == ""
 let &l:listchars = &listchars
 endif
 let listchars = substitute(&listchars, 'leadmultispace:.{-},', '', 'g')
 let newlead = "\┆"
 for i in range(indent - 1)
 let newlead .= "\ "
 endfor
 let &l:listchars = "leadmultispace:" .. newlead .. "," .. listchars
endfunction

It leverages the leadmultispace setting from listchars and updates it every time shiftwidth changes or a buffer is opened inside a window. If shiftwidth isn't set the tabstop value is used.

12
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/saltyflow on 2025-11-08 14:02:46+00:00.

13
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Swimming_Lecture_234 on 2025-11-08 01:48:52+00:00.

14
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/ghegi on 2025-11-08 10:27:05+00:00.

15
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Saghen on 2025-11-07 15:31:39+00:00.

16
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/linkarzu on 2025-11-07 13:53:23+00:00.


Let's get to know Justin Keyes more on a personal level, let's learn about his computer workflow, preferred OS, favorite terminals, Neovim history, upcoming Neovim features, thoughts on security, his favorite movies and way more

Video timeline in the first comment (trying this because if the message is too long, I think my post gets flagged)

17
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Informal-Addendum435 on 2025-11-07 03:59:34+00:00.


Both are good motion plugins. What are the biggest differences? Which one do you prefer using, which one do you prefer writing extensions for?

Here were my thoughts after using each for a very very short amount of time.

flash.nvim

Good

  • pleasant interface, the bright highlighted sequence-so-far and label are fun to look at
  • flash remote is a very cool idea
  • even though I don't like the visual interface of f, being able to f down lines to the next instance of a character is sometimes nice; but imo something for a user to set up, not the plugin

Bad

  • the label changes while you are typing the pattern, which I think is very bad
  • I would like toggle search to only last as long as this search, next time I do search, I want it to be normal search again
  • I do NOT want it to override f by default, I didn't even set up a keybind for that! What other secret stuff is it doing???
  • using the f, I find the gray-out overlay and all the label colors very distracting, especially because the screen stays grayed-out even after the f jump completes, and forces me to make an extra escape keystroke if I want to look at non-grayed out vim (e.g. df)
  • pressing u after doing dr<jump to word>iw goes to the deleted word, i think it should not
  • changes behaviour of t, eg ctx places you in insert mode if nothing matches x
  • After pressing f or t or F etc., a lot of my screen stays grayed-out for too long
  • Flash remote I am in insert mode
if (process.env.npm_config_host) {
  host = ⎸

I want to copy process.env.npm_config_host from the line above into where I am right now. The necessary flash sequence was <C-o>yrpgi) (and I had to pause after pressing p to read the label) and it didn't put me back into insert mode (the mode I was originally in) after!!

First I want to tell my intention, everything I already know ("yank a remote paragraph"), and then mark the reference point, leaving the non-deterministic part to the end (search pattern, labels, stuff). Tearing the operation and the text object apart can be a bit confusing with years of Vim muscle memory

A better yank-remote-flow for me would also be yriw, the flash/leap automatically starts after iw.

leap.nvim

Good

  • Labels appear very soon and do not change
  • The label choices are good, very safe
  • The immediate jump to first match is nice
  • Equivalence classes are really nice; being able to type u instead of ü is necessary for motion plugins imo.

Bad

  • When there are label groups, the letter you will have to type for a label is not visible soon enough. Why doesn't leap make the label 2-wide for example, and show the whole sequence you will have to type? <space><label> Another solution would be to highlight THE WHOLE block, and show labels inside it, but because you can see it's in a highlighted block you know it's not the active one yet.
  • The label doesn't appear until after I've typed the first character of the pattern
  • The immediate jump to first match is surprising and anti-muscle memory?
  • No immediate visual feedback that leap has begun

Is the immediate jump to first match in leap.nvim anti-muscle memory? It's a bit surprising that when I'm looking at a target and start typing its pattern, no label appears next to it (and because I'm looking at that one only and the human eyes are so limited, maybe I don't see labels anywhere on the screen... did I even press my activate-leap keybind?? Am I leaping right now or wreaking havoc at my current cursor?)


Which plugin would be easier to write extensions for to solve my pain points?

Which ones do you prefer using and why?

18
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Financial_Lemon_6606 on 2025-11-06 14:49:42+00:00.


I've been thinking about quite how much is built in to NeoVim / Vim that I just don't take advantage of..

For example, I don't think I've ever done more than play with marks, different registers, the change list and ctags.. But with the exception of ctags (are they still relevant now with LSP's?) I think they all would have been useful to me at various times!

Are there any other hidden gems that are just built in that you think are underutilised?

19
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/smnatale on 2025-11-06 14:50:17+00:00.


Stop chasing the latest plugins, you can create powerful IDE-like features with auto commands!

20
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/4Necrom on 2025-11-05 22:57:32+00:00.


convy.nvim prompts an interactive Formats selection window when fed no arguments

Check the full docs at convy.nvim

✨ Features

  • 🔄 Convert between multiple formats: ASCII, base64, bin, decimal, hex, octal
  • 🤖 Auto-detection of input format
  • 🎯 Smart selection: works with visual selection or word-under-cursor
  • 🎨 Interactive floating window UI for format selection

🚀 Usage

Let's say you need to convert the following from DEC to ASCII: 72,101,108,108,111

Using vim's substitute you'd have to select the numbers and execute the following in cmdline:

        :'<,'>s/\%V\v(\d+)[,s]*/\=nr2char(submatch(1))/g

Good luck remembering that!

With convy.nvim I can simply do <leader>ca, which you can set to any of these:

        :Convy auto ascii
        :lua require("convy").convert("auto", "ascii", true)
        :Convy # opens an interactive selection menu

🏆 Roadmap

  • [ ] Drop visual-mode flag for util.function that guesses if we
  • executed Convy in visual mode
    • [ ] Colors (RGB, HSL, ...)
    • [ ] Sizes (px, mm, in, ...)
    • [ ] Temperatures (C, F, ...)
  • [x] Interactive UI for selecting input/output formats
  • [x] Tab completion for conversion formats
  • [x] Automatic format detection

This is my very first Neovim plugin, I created it because I've come across various situations where I'd need to convert something to another format but the existing Neovim plugins wouldn't be up to the task (format missing, unable to use visual selection range, cmdline-only, format X converts to Y but not Z, etc ...), and using vim's substitute would be too much of a tedious task.

I also created this because I wanted to learn how to create Neovim plugins, and I hope I did it right. Please don't hesitate to contribute or give me tips.

21
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/DavsX on 2025-11-05 08:59:50+00:00.


Hello, I'd like to ask how are people resolving more complicated merge conflicts with e.g. 30 lines long conflicts on a notebook using neovim?

I am currently using DiffView, but given that I have relatively small screen on my notebook, resolving longer conflicts are still a pain using a 3-way merge screen.

Does anyone have any tips/plugins/workflows that make this somewhat easier? (again..I'm not talking about ~5 lines long conflicts - those are easy to solve)

Thanks

22
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/manshutthefckup on 2025-11-05 16:59:01+00:00.

23
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Kaikacy on 2025-11-05 16:28:18+00:00.

24
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/Le_BuG63 on 2025-11-05 08:52:05+00:00.

25
 
 
This is an automated archive made by the Lemmit Bot.

The original was posted on /r/neovim by /u/aktauk on 2025-11-04 09:20:56+00:00.


Hi all,

I'm always interested in reducing the number of plugins I rely on. Neovim keeps making good progress in that regard (tpope/vim-unimpaired and tpope/vim-commentary were the penultimate removals).

When I saw the builtin vim.pack plugin manager, I thought I'd try it too. I was previously using mini.deps, and the API is similar enough that I wanted to check how/if it worked well (and didn't regress startup time) by shimming the API instead of search/replacing everything:

-- A shim that allows using the mini.deps API, backed by vim.pack.
local mini = {
 deps = {
 add = function(minispec)
 local opts = { confirm = false }
 for \_, dep in ipairs(minispec.depends or {}) do
 -- Add dependencies too. From the docs:
 --
 -- Adding plugin second and more times during single session does
 -- nothing: only the data from the first adding is registered.
 vim.pack.add({ { src = "<https://github.com/>" .. dep } }, opts)
 end
 return vim.pack.add({ { src = "<https://github.com/>" .. minispec.source, data = minispec } }, opts)
 end,
 later = vim.schedule,
 }
}

-- later...
mini.deps.add({ source = "nvim-lualine/lualine.nvim", })

And after I'm rebuild Neovim, I upgrade using:

nvim --headless -c 'lua ran = false ; vim.schedule(function() vim.pack.update(nil, { force = true }) ; ran = true end) ; vim.wait(1000, function() return ran end)' -c 'TSUpdateSync' -c 'qa'

I think it's not exactly equivalent (especially later, as I'm sure @echasnovski will point out). I'll do the actual search/replace later, but this appears to work

view more: next ›