Hacker News new | past | comments | ask | show | jobs | submit login
Neovim 0.5 is overpowering (crispgm.com)
753 points by imbnwa on May 26, 2021 | hide | past | favorite | 421 comments

I'm most excited for the treesitter integration and its potential to amplify Vim's "killer feature": text editing as a language.

Vim's editing language feels most powerful when I'm using its text objects: "ciw" means "change in word", "cis" means "change in sentence", and so on. But Vim's built-in text objects are not always a perfect match for the code you're editing. Suppose you want to change the first argument of a function, for example; there's no built-in "first-argument" text object. But Treesitter integration makes it easy to create text objects that understand the AST. Without much effort, users will be able to make mappings like `cia1` to "change in argument 1", and these mappings will work across all languages with Treesitter support.

I'm excited about it because Vim's usual syntax highlighting is rather fragile. As far as I understand it Vim does the highlighting in the same thread, and to ensure good performance it enforces a time limit for the file parsing. In larger files this frequently leads to weirdly flickering highlighting when scrolling.

Going from that to actual syntax parsing is a dream come true.

That explains a lot. I often have a syntax highlighting quirk where it thinks that a fold has an open quotation mark in it. And will highlight everything below the fold as if it's a part of a string. I unfold, and clears it all up. but it's annoying in the moment.

I look forward to all of this

You can often fix it with `:syntax sync fromstart`, but Vim's syntax highlighting just keeps being a bit weird.

I usually just keep space bound along the lines of:

    :noremap <silent> <Space> :silent noh <Bar>echo<cr>:syn sync fromstart<cr>

This recalculates syntax highlighting as well as removes highlighting on search results/etc.

Basically, whenever stuff "looks weird", just mash space in normal mode and it fixes it. The fact that I have this bound to something like space should tell you how often I end up using it. :)

I recently gained a liking to search result highlighting, it's much more useful than I originally thought. The problem is not the highlighting itself but its persistence. I added a few autocmds to automatically hide it in certain events and a manual shortcut. Works better for me now, though it is annoying that `:noh` has some weird special status that makes it nonfunctional in autocmd.

I evaluated few plugins around this and this one I liked the most: https://github.com/romainl/vim-cool

I tend to avoid plugins for things that I can just do myself with a few keybindings or autocmds. I like that aspect of Vim (and Emacs) where the user is less reliant on plugins because there isn't really a clear, fixed boundary between configuration, scripting and external extensions. Though it comes with downsides (e.g. when plugin developers make the questionable decision of overriding user configuration).

I added 'autocmd BufEnter * syntax sync minlines=4000' to my .vimrc to make it buffer more of large files initially, so it gets less confused when you reopen a file and it resumes at a prior location deep inside and has no syntax highlighting.

I guess fromstart would work as well, but is probably best manually run like you do so a very large file doesn't bring the system to a halt.

That's why that happens, and a fix - thanks!

Do you find your brain can actually work that way? My issue with all of these relative jump points, repeat this N times, etc of VIM is by the time I’ve calculated in my mind what the command should be I’d have already done it with just standard navigation/mark/yank/repeat. But perhaps you have galaxy brain ;)

The way vim works is actually the opposite of what your brain wants, this is one of the reasons why learning vim tricks is hard.

The vim model is "action-object" (eg dw, delete word). A more natural, friendly and interactive model is the opposite, "object-action": first you select the text, your editor highlights the text, then you apply actions to the selection, one by one, and see what happens after each one. Because the text is highlighted beforehand and you see the effect of each action in real time, building chains of commands is much easier and friendly for novices. If you make a mistake, you see its effects and correct it immediately. In vim you have to build the command chain beforehand and calculate in your head what will happen. If you memorize the commands its fine, but if you don't, it's painful.

This "object-action" model is used by kakoune (https://kakoune.org/why-kakoune/why-kakoune.html), along with native multicursor support I have found it to be a great alternative after years of not being able to memorize vim commands. Documentation is scarcer at this point, though.

You've oddly crystallized why Kakoune has so far failed to grab me!

The description you gave of the actions one takes in editing makes sense: in most non-modal editors, you select the text you want to take actions on, then choose the action to take. But, I can do that in literally every modeless editor! That's the way essentially all of them work.

But when people write of "Vim as a text editing language" as many comments here do, the action -> object model -- again, at least for me -- fits the pattern. We say "I'm going to the store," not "store I'm going to," unless Yoda we are. And, most programming languages that aren't purely object-oriented tend to follow a rough pattern of "action(parameter)". So in editors like Sublime Text (or VSCode or BBEdit or...) I tend to do editing in an entirely visual way, Vim approaches editing in a more language-based way, and when you describe edits in language, "[verb] the [noun]" is pretty natural.

In English, sure. Not in Hindi for example (मैं खाना खाता हूँ - 'I food eat') or in .. object-oriented methods of many programming languages.

I don't think there's anything special about that mapping, whichever way around. I'm not inclined to think I'd perceive things or act any differently if my main way of describing things (English) had a different grammar - a rose would smell just as sweet.

I can see some value, especially for beginners, in 'highlight while object selecting, then act' (which you can do in vim with visual select and then action, e.g. instead of c2w do v2wc - or v2w -wait no that's not what I want-).

I do prefer it as it is though, probably just because I'm used to it, but I think of it as 'up to' rather than 'define the object', since it is always anchored (at least, without any plugins doing differently like is being discussed with Treesitter here, adding context awareness) by the cursor position. So I'm thinking 'change from here to..'. I suppose if one wants to think about 'object first' you could argue vim already is that anyway - you move to the object before typing any of the command.

Some languages use both orders, and the difference is more of a stylistic choice.

Indeed, in Spanish we say "lava la ropa" do the laundry. I am pretty sure that is what my brain wants, action object. Once in object-oriented training I was told that In Cantonese the person does not act on objects but the objects act on themselves: "The deck of cards shuffles itself"

Latin has an extremely flexible word order (some of which Old English had too) which allows all kinds of fun stuff for style and communicating status/education. Japanese with its particle system also allows some good flexibility.

I tend to pick and measure a piece of wood before turning my saw and cutting.

I say that I am cutting the wood. But I select it first before marking it and cutting it.

I noticed that I use the visual mode of vim a lot. With easy motion to highlight words or other object boundaries to quickly jump to.

I tried kakoune and liked it. But after 15y of (neo)vim it's hard to change. That plus how good You completeMe is for vim.

Well, the reality is that WYSIWYG editing of all sorts is object oriented. You first select the object and then the action.

So it’s not clear whether being more comfortable with selecting an object and then performing an action on it is innately easier for humans, or just what we’ve been conditioned to from using word processors, spreadsheets, or even GUI based file explorers.

But if you look at command line usage, it’s the opposite. Every command first requires you to stare the command, and then the object to act on.

I first type cd and then the folder I want to change directory to, compared to selecting the folder and then hitting enter/CMD+O/double clicking ont he GUI.

But people who have used both the GUI and CMD line rarely ever find the order of operation to be a concern for them, so I suspect the object-verb verb-object difference in vim is just a matter of convenience.

I do woodworking and construction work. In real life, I always must select first. Apply action second. So to me this feels more natural.

I think you’re overestimating how well real life actions map to the object/verb dichotomy.

So you’d say that it’s object first because you first get the wood and saw and then decide to saw the wood with it.

I could argue it’s verb first because you first GET the wood and saw.

I’m not saying that I’m right and you’re wrong. In fact, quite the opposite. My point is that I don’t think real life actions can be broken cleanly into object-verb or verb-object, in the first place.

"I need to GET something. I know, I'll GET some WOOD."

"I need some WOOD. I think I'll GET some WOOD."

I think this supports the point - in either case the syntax for the action is 'get wood'.

This whole back and forth in this subthread is ridiculous. People are comparing command syntax (not even a proper PL) with natural language syntax. First one is used to define actions first and foremost, and the second one to describe them.

How we formulate our actions in our head/speech to describe them is mostly irrelevant here.

I have an almost entirely non-visual imagination and internal narrative. Vi and then vim were pretty easy to adopt, and it’s still easy for me to learn new editor-as-a-language functionality. I started using it in the 90s and only figured out the visual stuff in the past few years (for block editing).

That is maybe the key point here. I am the total opposite of you. A friend of mine is like you and he thrives in vim.

I think it's a wonderful thing that the IT ecosystem has created such a variety of different tool methodologies converging on the same purpose. It seems analogous to convergent evolution in biology.

> "[verb] the [noun]" is pretty natural

For an English speaker. There are many human languages that put the verb at the end of clauses. Japanese is one example.

It is pretty common nowadays in functional programming languages to find operators which reverse the order of application or composition, so rather than writing f(g(h(x))) one can instead write “x |> h |> g |> f”. This style is quite popular, which leads me to believe that many people prefer object-action over action-object in same way. (Although perhaps this is more a critique of action-object-object vs object-action-action)

While you didn't refer to any explicit programming language (so your example is correct by definition), I think you may have mixed up something. The order is reversed, but typically not in the way you describe. For your example of f(g(h(x))), you would write (f . g . h) x in Haskell. So for this particular example, the syntactical order is not reversed.

However, you could say the natural order of reading is reversed: The naive way to read (f . g . h) might be "first f, then g, then h", opposite the actual order of execution.

This x |> h |> g |> f syntax is Elixir (and F# perhaps? and surely other langs). In Haskell this is written

  x & h & g & f
And in shell script, this is written

  echo x | h | g | f
This operator is sometimes called the pipeline operator

Anyway, here is some ghci session exemplifying the usage of the & operator

  $ ghci
  λ import Data.Function((&))
  λ a f g h x = x & h & g & f
  λ b f g h x = (f . g . h) x
  λ c = f g h x = f (g (h x))
  λ a (+ 1) (* 2) (+ 3) 1
  λ b (+ 1) (* 2) (+ 3) 1
  λ c (+ 1) (* 2) (+ 3) 1
It's unfortunate that this is named & in Haskell and not |>. And what's worse, it's not in the prelude.

to be honest, idiomatic code in haskell-land tends to be written right-to-left and not left-to-right, so you'd usually write it with the ($) and (.) operators. I personally have gotten used to reading it right to left more, as have probably most people who use haskell extensively. And I think it's only fair that haskell chose a 1 character operator: composing functions and applying them to arguments is the main way to make programs, so it's good that you have to type the least amount characters possible to do it, compared to something like F# where all the function composition and application operator take two characters (|>, <|, >>, <<)

I recently started using (&) a lot (e.g. `something arg1 arg2 & liftIO`) and frankly I think it's fantastic for readability, especially with adaptors like `liftIO` or `void` in `do` blocks. The relevant information is up front in a consistent position in the block; the adaptor is only even noticeable when I actually read the line - rather than being something I need to semi-consciously ignore. I also sometimes use it for chains of pure function application when the alternative is to read bottom-to-top or use where/let bindings with arbitrary names.

`import "flow" Flow` gives you (|>) = ($), (<|) = (&), (<.) = (.) and (.>) (by analogy). I slightly wish it were part of base - the symbols are much more intuitive, and I think that's important for increasing adoption - but I tend not to use it because it's non-standard. Most potential/plausible Haskell users, after all, haven't used Haskell at all, let alone extensively. Such people need to be taken seriously in decision making processes even though they almost necessarily have no voice.

I don't think the number of characters is at all relevant to the decision though: being non-surprising and understandable are far more important than using one vs two chars which in this case pull in both directions and I reckon the balance lies with sticking to the standard.

I'm assuming they were talking about Elixir, which uses that syntax to pipe the result of the left side into the first argument of the function on the right side. The transformation was correct in Elixir, and I can confirm that I at least do think that way.

“Go to the store” is the action and “I’m” is the object, so your example supports the Kakoune case not the Vim case

(These are also English-specific justifications)

Lots of Asian languages have the nouns before verbs.

Whenever you say words “natural”, or “friendly” you actually mean “what I am used to”. As the saying goes “Basically, the only ‘intuitive’ interface is the nipple. After that, it's all learned.” (Usenet discussion about Apple Macintosh).

So, no, I spent couple of years struggling with non-modal editors, where I had that feeling all the time “I have no idea how to do it effectively in this $EDITOR, while I know five keypresses which would do it for me in vim.” Finally, I have liberated myself and switched back to vim.

Irrelevant nit, but:

> “Basically, the only ‘intuitive’ interface is the nipple. After that, it's all learned.”

The nipple is not intuitive for everyone.

One of our children struggled mightily with the nipple and we had a miserable two or three months of breastpumping and finger-feeding before he finally figured it out.

He later corrected it by saying:

> There is no intuitive interface, not even the nipple. It's all learned.

Following-up on irrelevancy: what made you stick? We had the same experience, but gave up after 6 weeks because breastpumping was exhausting, and switched to bottles and artificial milk which our daughter loved immediately.

I think the belief (based on what evidence we're aware of) that breast milk is genuinely better for babies.

My wife and I are both sort of gluttons for punishment if we're convinced something is the right path.

Yeah, just wait until he gets to VIM in a few years.

Just an FYI Kakoune is a modal editor. I've actually tried it and OP has a point, for many of the things that you would use visual mode in vim things are very natural in Kakoune. It's also surprisingly accessible to someone used to vim. That said, it's difficult to leave the huge community behind vim behind.

If your brain prefers that order, you can emulate it in vim by doing v-movement-action, for example viwd to first select an inner word and then delete it.

I tend to do that whenever I'm unsure what my action will actually affect. Pressing one more key is a price I can pay.

I do exactly this when I'm doing complex commands and want to select-verify-run. Most commonly, something like vi(c where I want to confirm how the parentheses are nested before the operation.

I found that over the years, my Vim habits have naturally moved in an "object-action" sort of direction using visual mode. I think a lot of other Vim users end up doing the same.

When I tried Kakoune for a few days, I found it difficult to adapt to the differences, but that's probably to be expected no matter what. One thing I particularly missed was g-v ("restore previous visual mode selection"), which I use constantly in Vim. There's a good chance it's doable, though, and I just didn't figure it out.

Vim uses both models, it uses the object-action model in visual mode.

> The way vim works is actually the opposite of what your brain wants, this is one of the reasons why learning vim tricks is hard.

Do you mean that you think "word change" instead of "change word"? To me this sounds like you have been programming in Java-like languages for too long :)

Strategy Pattern Change Factory get instance word

You forgot the factory that builds the factory that builds the factory to call get on. I’m sure you’ll need a StringBuilder or two too! ;)

So Kakoune is like RPN (Reverse Polish Notation), and Vim is like Polish Notation then?

For sure any user of RPN would agree that it makes more sense to type the operation after the object. Not sure how that translates to modal text editing though.

Are you making a general claim that the brain prefers object-action syntax vs action-object, or just in text editor commands?

I think the only general claim that could be made is that the brain prefers to be certain of what's going to happen/what did happen. To get that you either need to have a good feel for where a motion is going to end up (which is harder the more inexperienced you are, and the more complex/farther the motion), or to get feedback.

Personally, I also struggle with a relatively high rate of accidental (or mis-registered) key presses, or being in the wrong mode, which means that even if I have high confidence in constructing the right command in my head, my confidence in the right command being executed is significantly lower, and direct, always-on feedback thus feels enormously helpful to me.

I suspect your hunch about object-action way brains work is very narrow and will not hold if extrapolated outside the western culture. My suspicion is based on a belief in [Sapi-Whorf hypothesis](https://en.wikipedia.org/wiki/Linguistic_relativity#:~:text=....). The need to reach of the object first is a very English specific language constraint afaik.

Before I finished reading your first sentence, I knew you are a Kakoune evangelist.

object-action may be a more natural order in some languages. I use a language which permits both. So I think you're overstating how much of a deal it is. That said, Kakoune has controversial design choices in a couple of areas:

  * no explicit select mode means not only you're selecting text all the time as you move your cursor (which can be annoying). More importantly, it means there are very few keys left on the keyboard for user defined commands. This comes up all the time on the forums whenever someone asks for a new function or an unused leader key. "Fewer modes" is not a virtue in itself, because modes have other benefits like taking the weight off keyboard.
  * Shell as a scripting language. Really. It's completely awful for maintainability.
  * I continue to argue that multi-cursors are a poor man's search&replace. It doesn't show off-screen matches by default, so you don't know if you're matching anything off-screen or not.
There are Kakoune features I like very much, for example improved integration with commandline utilities. You can more easily use them to process the text inside editor.

No galaxy brain here ;)

I generally don't use counts. If I want to go down a few lines, I don't count the number of lines and use 4j or whatever, I instead use / to search for the exact place I want to move to. This feels more natural and preserves the jump-list, so I can ctrl-o back to where I was.

Same if I want to delete a few words. I don't count how many I want to delete and do 4daw, instead I do daw and press . until I've deleted everything I want gone.

And I make heavy use of text objects when available. If I want to move to the next function, I use the keybinding for that instead of searching or counting lines.

Instead of counting, you can use :set relativenumber (vim/neovim builtin) to quickly see how far away lines are.

(see https://jeffkreeftmeijer.com/vim-number/)

In my opinion the real downside of using <count>j and <count>k to move isn't the counting part, it's the fact that <count>k isn't a jump. That means it doesn't go into the jump list.

You can do something like this:

``` " Does: " For wrapped lines, does gj/gk " For large jumps, adds a spot on the jump list function! tj#jump_direction(letter) let jump_count = v:count

  if jump_count == 0
    call execute(printf('normal! g%s', a:letter))

  if jump_count > 5
    call execute("normal! m'")

  call execute(printf('normal! %d%s', jump_count, a:letter))
endfunction ```

and map j and k to this

I tried to get into that for awhile. I tend to look at the line number where I want to jump, and do <number>gg instead. It has the benefit of allowing me to look at a file and get an idea of what's on lines 400 through 425 (for example).

I just use a fixed count, like 5j5j5j or whatever to get me close, then jjj or whatever.

I use ctrl + u/d to scroll up and down half screen to get near where I want to go.

Try the plugin easy motion. It changed my life.

+1 easy motion makes the default jump-by-search feel really clunky. Typically it is mapped to double-tap leader then object, and it will then highlight those objects with a short-code to jump right to it.


\\w -> will highlight all words after \\b -> all words before \\e -> ends of words after \\ge -> ends of words before \\fe -> all occurences of the char 'e' after \\Fe -> 'e' before \\se -> 'e' in both directions \\j -> lines after \\k -> lines before etc.

but can even use it with traditional search:

\\n -> will highlight all search-matches found by a previous "/" or "?" search after current pos. \\N -> will highlight all search-matches before.

mega useful.

For me, learning about . was what made learning many of (neo)vim’s motions and text objects worthwhile. I use . constantly.

Yeah, just recently I had to edit text like this


  'name1': Enum.Name1,
  'name2': Enum.Name2,
  'name3': Enum.Name3,
by the time I figured out a sequence of keyboard commands I'm pretty sure I could have multicursored it pretty easily, go to name1, create 2 cursors, select word & copy, start typing : Enum., paste selected word, select word, capitalize, type ,

In vim it was something like qdyi'f,i: Enum.<Esc>pbvlUq and then repeat macro.

I found it very slow to even recall.

For some reason the multicursor solution feels faster to me most times.

I'm surprised everyone's forgetting vim already has a proto-multicursor mode. Go into Visual Block mode (Ctrl-V) select all the lines then it's just A<delete ,>: Enum.Name0,

After that you can just select it again in visual mode and g Ctrl-A to get the right numbers.

If anything the g Ctrl-A part makes Vim way better than most multicursor editors.

So the second time, you're entering Visual Block mode or plain Visual mode? What does the g Ctrl+A do?

g Ctrl-A increments all the numbers, but every instance gets incremented by one than the previous. First line would be Enum1, second Enum2, third Enum3. It's a really neat feature imo.

Though I did make a mistake, if you selected everything it'd catch the name numbers too, so you'd have to go into visual block mode and only select the enum parts, then do g Ctrl-A.

That said the numbers probably weren't supposed to be taken seriously now that I think about it.


Or, you could have hit qt, recorded your commands for the first change, and then replicated it for every other line with a simple @t, instead of redoing all the changes each time.

You don't have to learn command. You simply need to know how to edit with VIM.

And multi cursors only work for tabular data. The macro recordings can work for the entire document where you call a macro on a word/regex you searched for, for example.

I always find it strange that people recommend a different letter for the register when recommending macros. Why not just use `qq` and `@q` (with the added advantage that clearing the register is `qqq`) ?

The reason I don’t use q is it’s far too easy for me to accidentally hit a 3rd q when I didn’t intend to and not even realize it.

This was a bigger problem when Apple decided to go with those butterfly keys.

> multi cursors only work for tabular data

There are several plugins which allow for more complex use of multiple cursors.

* https://github.com/mg979/vim-visual-multi

* https://github.com/terryma/vim-multiple-cursors

I did record it with qd...q and repeated it with @d @@

Visual select and normal@t (assuming you saved it in t) is a good way to do it once for every line.

Nope, you can do find > select all to get multiple selections and edit those simultaneously.

This can be done in (neo)vim too, and with a bit better precision and less typing.


is the general form for [g]rabbing lines that match a regex and applying a command over them. You can also chain the command:


I'll admit this isn't exactly something you intuit as easily as a drop-down menu, but (neo)vim does have tools for all these things out of the box.

Huh, somehow it’s never occurred to me to get binary logic by chaining :g and :v in this way—I’ve always done things in more complicated ways to make up for the lack.

Multiple cursors is for quick small editing tasks where you don't bother with a macro.

You probably are familiar, but for some newer folks: I almost always add a "go to beginning of next line" as the end of the macro so that I can e.g. 10@t to repeat it 10 times. Makes it much quicker than @t on each line once you have more than a few.

This looks like the sort of thing you would intuitively solve with visual selection and a regex.


    Vjj:s/\v'(.*)',/'\1': Enum.\u\1,/

This is all just muscle memory. It seems impossible until you get used to it, and then it's the most natural thing in the world.

TIL s/\u, thanks!

I know I’ve read that part of the documentation before, but probably not for over five years. In cases where I’ve wanted something like that, I’ve tended to reach for macros, visual block editing, and s/\=. A few days ago I did a somewhat more complicated one that s/\U wouldn’t be sufficient for:

  :'<,'>s/.*/\="    pub const ".substitute(toupper(submatch(0)), "[^A-Z0-9]\+", "_", "g").": &'static str = \"".submatch(0)."\";"

Vim's documentation is complete and very well-written. I've been using the editor for over 10 years and I still learn new things when perusing :help.

Yes! When I first came from Sublime 2 I thought Vim was irritatingly difficult but hoped it would be worth it. Now I wouldn't program without it.

I think I would've used something like :s/'\(.*\)',/'\1': Enum.\1,/g and then ctrl-v to block-select all the first characters and U to uppercase them.

Vi's not always about finding the most efficient way to do something, but having a composable language to do tricks like these comfortably builds up into your own dialect over time.

I’m often fallback on the sed match-replace strategy for things like this.

For me it's been a matter of practice, and forcing myself to use macros for things even when I was too slow with them to justify it in the moment. It pays off eventually and you can get a nice facility with it.

I also like using

  :g/^/norm $normal_commands
to apply anonymous macros across all lines. It works with visual selections too:

  :'<,'>g/^/norm $normal_commands
And naturally you can replace the ^ with any regex to selectively apply the macro to only lines that match!

Column editing in vim: https://youtu.be/dYDu9Hrg7yM?t=639

I saw a colleague doing the same thing (turn column of #defines into structs in an array) with multiple cursors in an IDE, took him much longer.

I paused to take a drag from my smoke while doing that.

Sorry but column editing is a stripped-down multicursor mode. I use vscode-vim (so, VSCode with Vim mode) and never use column editing because the IDE multicursor is much more powerful. Without being any sort of editing wizard, I'm finding your video example slow and mildly painful to watch

I would have used visual block mode to duplicate the 123 column and insert the remaining content for all three lines simultaneously. If the situation is a bit more complex, I sometimes use regex replace applied to a line range.

> vlU

I think you meant just vU, as you were only capitalising the letter under the cursor.

You can actually also achieve this without entering visual mode: gU{motion} changes to uppercase, so gUl uppercases the letter under the cursor.

Text like that should work well with block selection/block insert mode.

Like vim in general it’s not natural, but with practice you slowly start to pick up muscle memory around it. I try to shoot for easy-to-eyeball tricks, a good one is jumping to the place you want to edit with f + the first char. If there’s duplicates in between, you can use ; to go to the next occurrence of the char on that line. There’s plenty of other tricks like that that, in aggregate, makes it feel like you’re talking to your text editor vs leaving home row to click stuff.

Exactly. The best approach is layering, in my opinion. Learn the basics, maybe a couple of tricks, and then deliberately add one more thing to your toolbox which would improve your productivity. Then incorporate that new trick into your flow until it sticks, then repeat. Eventually your toolbox is getting full and you are able to recall all the things naturally.

I don't use relative jumps or N times repeats, but I do love moving by or dealing with semantic units of things at a time, whether that is a character, w/Word, quoted string, bracket contents, line, paragraph, function, xml tag content etc. and treesitter expands and standardises that across languages, which is nice.

I got relatively good at vim N times counting some years back (but forgotten it now as I don't use vim as much these days). It was a practice thing. I made a point to never repeat a command more than twice and after a while it became second nature. I even got really good at guessing how many lines away things were (but nowadays I just use relative line numbers).

I never became fully fluent, but I also didn't try too hard over the "don't repeat commands" thing. And I got lazy after about a year (but also used other editors a lot more, due to team members using them and such) and over time lost the ability. Some day perhaps I'll make a point to learn again, but for now I mostly use VSCode without vim mode...

For many commands you’ll only have to make that calculation once, and will remember it going forward. Only commands that are extremely rarely used you may forget and have to reconstruct with the calculation again later.

I never use the counts (repeat N times) except for the very simple 55G to go to line 55. It's not useful. But the rest of vim is. I think of it like a chess board. A queen has more moves available than a king. Does that make it harder to move to a certain square with the queen than with the king? Not really, they're both pretty straight forward, if you're not trying to achieve the minimal edit distance to do so. You make big edits when it's obvious and just do smaller edits when it's not. The only commands I have to plan out are search-and-replaces.

Don't worry, you're not alone. 100% of the people I've ever saw using Vim / Neovim spend much longer "calculating" their next command than they would spend just doing in with CMD-D in VSCode.

It's frustrating to see. CMD-D in VSCode does 95% of what's needed, with no mental burden.

But hey, you can't "brag" that you "know VIM" if you use VSCode...

> 100% of the people I've ever saw using Vim / Neovim spend much longer "calculating" their next command than they would spend just doing in with CMD-D in VSCode.

Right, there is mental overhead to calculate moves but often times you can extract out patterns into intuitive key mappings once you've solved the problem once.

For example, this is taken my vimrc:

    nnoremap <silent> s* :let @/='\<'.expand('<cword>').'\>'<CR>cgn
    xnoremap <silent> s* "sy:let @/=@s<CR>cgn
The basic idea here is I can either move the cursor on top of a word or select some text, hit s*, type what I want to change that text to and then hit dot (.) as many times as I want to repeat the change to the next match. It's like being able to use multiple cursors except without needing multiple cursors and I also get to see the result applied once before I start applying it to multiple things. It's also possible to skip matches using existing Vim mappings (n).

I use the above all the time to make changes in spots where I would have used multiple cursors with VSCode.

You prove my point. You had to create this insane macro to solve something that cmd-d does automatically in VSCode. And cmd-d is much more versatile, since the same concept applies to many other use cases.

And sorry I say insane, but not knowing the language, your macro looks absolutely absurd and as obscure as a sample of brainf*ck.

I refuse to learn such a complicated language just to create a macro that replaces cmd-d and cmd-z, just so I can brag that I use Vim.

Clever! I think I might steal these, or make something based on your idea.

Kind of wild: in taking apart your command, I learned three things about Vim that I didn’t know, each one of which is massively useful. And I use it every day!

> I think I might steal these, or make something based on your idea.

Sure thing, if you can improve it let me know.

Here's an even wilder thing. I set those s* mappings up about 2 weeks after using Vim and I still don't know how they work in perfect detail but I was able to find them by Googling. There's definitely a stigma that you need to be some crazy wizard to use Vim but with a bit of repetitive learning and Google you can get pretty far.

Here's a link to my vimrc around a few mappings associated to finding / replacing and multi-cursor-like things: https://github.com/nickjj/dotfiles/blob/085c4ac827290bc7aeea...

Keep in mind, even if you don't use motions, text objects, and counts during interactive editing (my own repertoire is pretty limited for the exact reason you mention here), they can be enormously powerful when used with macros.

You can't calculate those commands because you're not meant to calculate them: They are meant for macros and scripting.

plugins like https://github.com/phaazon/hop.nvim help a lot in cases where it may be hard to tell how to jump to point X

I believe integrating visual mode into your usage flow can help with this a lot.

You could ask the same question to anyone who touch types.

Muscle memory is a marvellous thing.

Not yet! I just moved to 0.5 this weekend. But thanks for the link!

I just have vim-angry installed. It gives me "cia" and friends, though without the count you mention.

Sounds like treesitter will have more flexibility, but for now the vim-angry plugin does what I need it to :-)

Seconded. vim-angry is an excellent plugin that exposes args as text objects.

In an expression such as (foo, ba|r, baz), where | is the cursor, it does the following:

via - (foo, |bar|, baz)

vaa - (foo|, bar|, baz)

vaA - (foo, |bar, |baz)

Aren't these features are subject to external configuration to behave properly? For example, C/C++ and #defines. The user has to configure yet another file for this to work properly. If the build system/tree is so complicated that I can't figure out what the final #defs are (like building MBED programs with literally a thousand #defs), I end up shutting off this feature entirely. This kills me with VSCode & Sublime, but Eclipse derivatives are usually more tightly coupled. What about neovim?

You make your build system emit a compile-definitions.json file that has all the compiler flags for every file you compile and feed it to a language server (rtags or clangd usually, either standalone or part of another plugin like YouCompleteMe). CMake has a flag to do that as part of its configuration step (and remembers it), for other build systems you can use something like bear: https://github.com/rizsotto/Bear .

For future reference, as I found this information to be difficult to find: the flag for CMake is `CMAKE_EXPORT_COMPILE_COMMANDS=YES`. In out-of-source builds, the output file will be in the build directory, therefore one has to create a symlink to ensure the language server finds it in the project root.

I just wish Vim had proper S-expression structural editing support. Many editors have vim support but very few have smartparens/paredit with good integration. If Vim can extend its language to include some basic structural editing, then writing any type of tag based code e.g. JSX would become much more pleasant. For example in VS Code's Flutter plugin there is support for "delete surrounding widget" and "wrap child widget in new widget". They just need better keybinding integration.

Vim uses text objects for that kind of thing, t being the tag text object. `dat` deletes the JSX tag enclosing the cursor, `cit` deletes the contents of the tag and leaves you in insert mode, etc. Matchit (included in neovim) can also be configured to have % match tags as well as the default brackets/parens. LSP text objects are also available for more language specific structural editing.

vim-sexp is very very good and IMO better than smartparens/paredit. I'm not a fan of the paredit-style keybindings by default, but the way it integrates into vim's model is IMO perfect.

But it is not supported in other editors (VS Code, Intellij etc.), it is not like vim-surround or easymotion where almost every major third-party vim implementation supports it.

Are there really no plugins for that? In Doom Emacs "cia" deletes an argument normally, which I assume is done by an evil mode plugin, so I thought there was one for Vim as well.

Various plugins can do it on a per language basis, but tree sitter is a nice abstraction that allows such commands to be done with a simple mapping - then tree sitter (with a per-language plugin) will parse to the same ASTish thing, so any language that has function arguments will have the same commands working the same way.

I'm actually kind of excited about tree-sitter - it's not a neovim feature, it's an independent project that can be used a lot of places. I think the effect will be similar to how LSP changed the landscape from "every editor does some parts of handling language X well, but the parts each editor does are different from each other" to "all the editors get this feature when the language server does", just for syntax highlighting and syntax aware edition.

The plugin you are referring to is evil-args (https://github.com/wcsmith/evil-args), which is included in Doom Emacs by default.

Thank you! I tried this out on my setup, but was disappointed when it didn’t work. I’m new to evil and I’m constantly impressed with how big the ecosystem is!

There are, but they usually rely on regex or other brittle approaches, making it difficult to write well. And currently you'll need to use different plugins for different languages (e.g., jedi for python).

Treesitter builds the AST, making it easier to create robust text objects. And it provides a unified interface for a bunch of different languages, meaning that I don't need to have 10 different plugins, one for each language, just to get access to text objects.

Damn this looks cool. I always want this kind of flexibility. I'm using both Jetbrain products and VS right now, and one pain point is that it's difficult to define new short-key combinations and assign a key to it.

This is one of the biggest strengths of Vim imho. Defining new keybindings is so intuitive and flexible you wonder why it's usually done differently.

With Vim you basically just tell it to map any sequence of inputs to any other sequence of inputs. If you know how to do something in Vim you can define a keybinding for it. And because Vim is 100% controllable via the keyboard you can bind anything to a shortcut.

I can never remember what all those different maps do: ':map', ':map!', ':nmap', ':vmap', ':imap', ':cmap', ':smap', ':xmap', ':omap', ':lmap', etc. do. There are bunch of questions on StackOverflow about different mapping options so I wouldn't say it's intuitive at all.

The differences that actually matter are self explanatory: map is for all modes, imap for insert mode, nmap for normal mode and vmap for visual mode (& tmap for terminal mode in NeoVim). The rest can be safely ignored as far as I can tell.

Little confession: I have no idea what e.g. the difference between "nmap" and "nnoremap" is. But after years of randomly mixing them in hundreds of bindings without a noticeable difference it doesn't seem to matter. Just use map, nmap, imap and vmap, avoid duplicates and everything will be fine imho.

You're right, for most simple use cases it doesn't matter. But I once spent an hour on a weird bug that turned out to just be some plugin applying a map that I didn't know about and that I didn't know about map expansion. So I might be biased, but I think a loose understanding is helpful.

The default behavior is to recursively expand and apply your mappings and "noremap" disables this recursion. For example if you do something like

  :map j k
  :map q j
  :noremap w j
q is expanded to k, but w is expanded to j

Thanks for this example, now I get it. It never really clicked for me when I read explanations on SO etc.

nnoremap is "non-recursive remap" since I think its possible to chain nmaps (`nmap A B, nmap B C` will map A to C)

I find that I never want "map" functionality, so I do the opposite, always use "noremap".

Please someone clean that tpope searchlight! Na na na na na na na na tpope!

I would actually pay (although relatively small amount) for better programming text objects. It would feel so much more natural than the currently burned in muscle memory workarounds...

What treesitter module does this fall under? I'm having a hard time finding this in the documentation. Or do users have to add this functionality themselves? Are there reference implementations for what you are describing?

Right, Treesitter just gives the client program a syntax tree; it will be up to Neovim to map that to editing commands. (And the fidelity will depend on the quality of the specific language's Treesitter parser.)

treesitter was the reason why i installed the git version of neovim ;) it is very good. so happy with with it;)

I use nvim in the terminal and gvim/macvim on the desktop. I don't like how the nvim community seems to be throwing themselves wholeheartedly into lua and lua-only plugins (vimscript plugins are better because they work with both vim and neovim). Switching to init.lua also means losing all compatibility with vim, and I cannot fathom why people would want to do that considering that there is nothing that init.vim cannot already do.

I also don't like how there looks to be an upcoming split in the plugin community when Vimscript 9 releases and the neovim community will ignore it while plugin authors in the vim camp (e.g tpope) may start moving their plugins over to it.

That said, the built-in LSP for nvim is very good thing and I plan to migrate away from the node-dependent coc.nvim once nvim 0.5 releases.

> vimscript plugins are better because they work with both vim and neovim

I think you mean "vimscript plugins are better for plugin adoption because they work with both vim and neovim".

From the language-design, performance, documentation, robustness/general codebase quality, and total number of users perspectives, Lua is overwhelmingly better than vimscript.

> I cannot fathom why people would want to do that considering that there is nothing that init.vim cannot already do

Ahh, yes, the Turing-equivalence fallacy: "technology A is theoretically capable of doing everything that B does, therefore they're equivalent". Brainfuck and Python are Turing-equivalent, and yet nobody would seriously argue that they're interchangeable.

Design matters.

Well, yes. Vimscript plugins will see better adoption. Lua matters for compute-heavy plugins.

> Ahh, yes, the Turing-equivalence fallacy: "technology A is theoretically capable of doing everything that B does, therefore they're equivalent".

Language design is not the full picture. init.lua is essentially a thinly-veiled init.vim with lua syntax. You will have to learn init.vim either way. It is extra work to do something in init.lua, and in using it you remove any chances of it ever working with an installation of vim (e.g. vim still has the best GUI options out there).

> From the language-design, performance, documentation, robustness/general codebase quality, and total number of users perspectives, Lua is overwhelmingly better than vimscript.

Even if ahead of Vimscript; from the language-design, performance, documentation and total number of users perspectives Lua sucks very very much.

> I don't like how the nvim community seems to be throwing themselves wholeheartedly into lua and lua-only plugins (vimscript plugins are better because they work with both vim and neovim)

How many decades do we continue to use, support and maintain a terrible DSL like vimscript? I personally don't want to be using vimscript in 2030.

It's time to move on. Lua is a solid choice

The thing is, Vimscript sucks. Using a more mainstream language would be great for a modern advanced editor.

Vim has a ton of Vimscript plugins but I wonder how long it will take the Neovim community to replicate most of their functionality in Lua. I'd guess that not that long.

I spent 10 hours learning enough vimscript to make a command to check if a line is commented, comment it if not, or uncomment if it is, be able to handle multiple filetype and comment chars, and be able to handle proper indentation and multi-line selection.

I have to imagine it would be simpler in other languages. Vimscript is hard.

Out of curiosity, does your's have any benefits over NERDCommenter?

I'm sure mine's strictly worse. It was written when I was working in an environment where it was easier to spend 10 hours on something than it was to get permission / access to download vim plugins from the internet.

Now that calls for story time.


government contractor, yeah. It is insane how much effort there is put into getting butts in chairs for the right number of hours and how little effort goes to actually building something useful.

I’m pretty sure that the primary reason we don’t have more VIM plugins, despite many more emacs users, is vimscript being terrible.

If vim had a more usable scripting language it would have easily surpassed emacs in plugins and more importantly, since plugins would have been more popular, vim would have been developed in a way to make it more extensible and nvim wouldn’t even be needed.

I think you are correct. I think this is why certain Vim "demigods" have arisen (aka tpope). Only a few take the time to learn VimScript. In my humble opinion, when I took the time to try and learn it a while back, I ascertained that it was not worth my time.

Having never written a line of Lua in my life, on the other hand, I was able to pick it up in exponentially less time than the small bit of VimScript that I "know". Lua is not a fantastic language, but it is infinitely better than VimScript.

The philosophy of vim is to be able to do a lot without the need for complex plugins, as opposed to emacs' world view. That's why vim script is good only for simple scripting tasks.

I think emacs having more plugins is a consequence of its design and philosophy, not the extension language itself. After all, emacs lisp is not the best language in the world and only a small group really knows it beyond the basics.

> emacs lisp is not the best language in the world

Emacs-lisp is a Lisp. It may not be the best of Lisps, but even a bad Lisp can be far more powerful than many other non-lispy languages. To understand what makes Emacs so awesome, one has to understand the philosophy of Lisp. Emacs Lisp is not just a text editor, IDE, email client, project management tool, scientific calculator, etc.

Emacs, first and foremost is a Lisp environment. Definitely not the most ideal, but certainly the best one we have today.

> I think emacs having more plugins is a consequence of its design and philosophy, not the extension language itself

I believe, Emacs held the crown of "the most malleable" tool for over forty years, specifically because it builds on top of Lisp.

Number of plugins is not an indicator. They also have to "play nicely" with each other. I just checked - I pull over four hundred Emacs packages in my config, including built-ins and dependency libs. I just cannot imagine any other IDE or text editor with 400 plugins installed. That's just not possible.

Emacs lisp is not a bad language, but it's also not the reason for the existence of Emacs. It is the other way around: it was Emacs that created Emacs lisp. Initially, emacs was created on top of TECO, arguably the worst, most difficult programmable editor ever created. TECO language was so bad that they decided to switch. But emacs, the editor, was successful even running on top of a terrible language that nobody liked at the time.

> Emacs lisp is not a bad language, but it's also not the reason for the existence of Emacs

Early Emacs and the modern GNU/Emacs I think, are two distinct worlds.

I believe Lisp has shaped Emacs into its modern form. I just can't imagine the possibility of building something like Org-mode, with the same level of extensibility and flexibility in any other language that is not a Lisp.

I bet if you ask any serious Emacsen - authors and maintainers of Magit, CIDER, or any other serious Emacs package if they could replicate their work, for example, in Python. I have no doubts, they'd definitely say: "that's nearly impossible"

Funny, because Magit has been ported to Vim, I use it daily.

Magit is not just a user interface. It's also a number of emacs-lisp packages useful on their own. It's Transient that's gaining popularity for building modal key UIs in Emacs. It's Forge that paved the road for nice packages like github.com/anticomputer/gh-notify. It is Org-mode integration and many other things. What you're using is a ported subset of them.

So much better, because what I want is to interact with git, not to manage a hodge podge of libraries.

There are always multiple paths to get something done. Some people prefer automation. Having "a bucket of bolts and nuts" makes it possible to hack your way around things.

Some people like Ferrari. For some - the utilitarian value of it, is minimal. They'd rather have "a bucket of bolts and nuts" instead. They can't go camping in a Ferrari. They can't take their bullmastiff to a vet in it. They can't help a friend to move furniture.

Emacs is that - it's not akin to a shiny, expensive but not very useful car. It's like a transformer - you can build a pickup truck, a camper, an ambulance, or a race car.

But some people like Ferrari. And that's totally fine.

There is a point when it doesn't make any difference if the language sucks or not. What matters is if it is capable. You can say the same about most successful languages: C sucks, shell script sucks, eLisp sucks, LaTeX sucks, but they're all there and will continue to be because they have been capable of support the communities for which they were designed.

Now, you can freely dream about the perfect extension language for UNIX, or vi, or TeX, or emacs, but it won't make any difference because nobody will move from something that works to an unproven extension language just because some people (usually the minority) feel that it is a more comfortable language for them.

> Now, you can freely dream about the perfect extension language for UNIX, or vi, or TeX, or emacs, but it won't make any difference because nobody will move from something that works to an unproven extension language just because some people (usually the minority) feel that it is a more comfortable language for them.

Lua ia an extremely powerful and popular extension language. It probably has at least 10x the users that Vimscript has.

And people willingly choose Lua. Barely anyone chooses Vimscript, they're generally forced to use it.

If anything, Vimscript is the <<unproven>> extension language. It's in Vim because Bram made it the Vim language, but it was never voted on or designed. Vimscript will most likely die with Vim, because I'm quite convinced that outside of trolling attempts, no one will adopt it for another app ;-)

> Vimscript will most likely die with Vim

Which is just fine! Vimscript was created to create simple vim scripts, not to build full programs.

And if you need to do more than Vimscript can do, Vim already provides this: it has native bindings to Lua, among other languages. If Lua was such in demand to write vim scripts, at this point it should have taken over VimScript as the main extension language, but it hasn't, and I guess that unless something huge happens in the community, it won't.

> The thing is, Vimscript sucks. Using a more mainstream language would be great for a modern advanced editor.

Lua sucks, too, and it's hardly mainstream.

As someone who maintains a vimscript plugin... HAHAHAHAHAHAHA

There's API differences between vim8 and neovim that make it a pain to do certain tasks on both (UI manipulation or anything with asynchronous work). Supporting both in the same plugin is annoying. The split is already there and it's only going to get worse, so might as well go with a language that doesn't suck to write. I think upstream vim is the one needing to catch up. Vimscript sucks to write and maintain.

> I also don't like how there looks to be an upcoming split in the plugin community when Vimscript 9 releases and the neovim community will ignore it while plugin authors in the vim camp (e.g tpope) may start moving their plugins over to it.

Honestly Vimscript 9 always felt like a serious case of "not invented here". Bram could have easily chosen one of many existing languages, but instead decided to take Vimscript and make it even more bizarre (this was even more so the case at first as IIRC block delimiters for example were really odd).

Setting that aside, you could also argue that people moving their Vimscript plugins over to Vimscript 9 is a problem on their end because it makes the plugins incompatible with NeoVim. In other words, the argument is basically silly.

Vimscript is terrible though. I switched from Emacs to Vim (and later, neovim) last year and the shock of going from elisp to vimscript was intense.

I even contributed some small patches to a couple of vim plugins which meant writing and debugging vimscript, I hated every second of it.

I'm not a huge fan of Lua either mind you, but I'll take it any day of the week over vimscript.

> I'm not a huge fan of Lua either mind you

If you liked emacs-lisp, perhaps you should try Fennel. It's a tiny Lisp that compiles to Lua with zero overhead.

It's pretty dope.

Oh, that sounds interesting, thanks for the tip!

I've always wanted to write Vim plugins, and as soon as 0.5 hits stable, I'm looking forward to trying! I won't touch VimScript with a 10-foot pole, and I write code for a living. It's not worth my time, and it does not commute to other things that I'd rather be spending my time coding.

But you can use Python to write Vim and NeoVim plugins already. It's arguably an even better language than Lua.

I don't have experience with Vimscript, but I know both Lua and Python. It seems that the biggest benefit is gained by stepping up from Vimscript to any of those two. Switching to the other would only have diminishing returns, if at all.

Apart from that, Lua was explicitly designed to be embedded. Python is designed as a scripting language that can bind to C code, and embedding seems to be an afterthought.

This is demonstrably and unequivocally untrue. Lua is designed to be fast, lightweight, and easy to use as an embedded scripting language. Python is a general-purpose kitchen sink language. Python is 10x bigger, and 10x slower than Lua. It is bad fit for an embedded language.

How many people realistically are willing to write vimscript plugins, vs how many people realistically are willing to write Lua? I know personally, after wresting with vimscript for a couple of days I'd never touch it again, but Lua is nice.

Personally I found the quirks of vimscript interesting when I wrote my first and only plugin: https://github.com/nburns/vim-auto-light-dark

somehow being part of the ~50 year lineage of vi editors and scripting was fun to think about

New vimscript plugins are created constantly. So that isn't a good argument metric.

In a vacuum where there was no need for legacy vim support (lets say vim integrated lua), I can't imagine anyone but a small minority preferring vimscript over lua. My argument isn't that nobody programs vimscript, it's that hardly anyone does it by choice.

> I don't like how the nvim community seems to be throwing themselves wholeheartedly into lua and lua-only plugins

The transition to lua can't come soon enough, imho. The biggest downside to vim is vimscript. Lua is a delightful little language and the sooner it replaces vimscript the better.

There is no other credible alternative to betting on lua.

vim script is too limited and there are no other options, really.

Python plugins are a hassle.

Replacing init.vim with init.lua is, imo, a mistake. Lua is not a config language. I'd sooner use bash. Once you start writing functions tho lua feels more sane.

I recommend checking out gui frontends for nvim on desktop. I've been using neovide[1] for a while now and it's decent. I also found out that you can use nvim as a backend with the vscode-vim plugin which will load your nvim config and scripts.

[1] https://github.com/Kethku/neovide

Neovim 0.5 is awesome. It has native LSP support, Lua configuration support that it feels like true revolution over past versions.

But, getting into optimal setup in neovim/vim involves lot of configuration. Here is mine if you want to refer:


I don't agree that it requires a lot of configuration. Here is the "starter" configuration (~280 lines) that I made for helping debug user issues with the built-in language server client:


You think 280loc as a starter is not much?

Sure, although this is fairly "batteries included". Very rough numbers:

- 34 lines to set up plugin manager/install plugins

- 43 for keybinds

- 35 for documentation

- 50 for autocompletion

- 20 for customizing one language server for plugin development (sumneko)

It adds up for sure, and neovim/vim/emacs are not ever likely going to be as plug & play as vscode/intellij, but I would argue the target user for vim/neovim/emacs is someone who wants more customization, which is almost always going to mean the configuration is more verbose.

If you have concrete suggestions on cutting down this config in particular, you can file an issue/PR. The main reason I created this, was because we (core neovim team) get a lot of "I just want something that works" type feedback (which to many includes autocompletion and default keybinds, which are almost 1/3 of the config)

VSC has tons of customizations available, perhaps even beating Vim in the number of exposed configurations. The problem with Vim configurations is that a lot of them feel obvious, and the ergonomics of dealing with configs is painful and frequently calls you to reference outside material.

I'm not sure I'd say that it beats vim/neovim, but I agree with your point about ergonomics. I would say the vim manual is a fantastic resource, I've never felt the need to reference outside material.

Neovim has already integrated many of the "obvious defaults" (see :help nvim-defaults), but if you're a user and feel that something is missed you should file an issue.

I personally don't mind that the defaults may not be what I'd like, as once they are set, I spend very little time modifying my system configuration. I realize this can be a barrier to new users though.

Thanks for making your configuration available, I want to try out Neovim because it's an exciting project and having carefully constructed configurations available as a starting point will make it easier. Your configuration doesn't look too long to me, my own Emacs configurations are much, much longer and not at all stable--every so often I declare Emacs bankruptcy and start over.

Now, some off-topic musings:

I switched to Emacs from vi in the 80's, and I put up with it for the many powerful packages it has. Lisp as a configuration language has served Emacs well for decades, but I've always been aware that it narrows the number of contributors to those that are comfortable with Lisp. Progress towards modernizing the Emacs extension language has been slow...and it will still be a Lisp like language (Scheme).

I'm rooting for Neovim and I'd like to see a project like this for Emacs that would modernize it's UI, UX and underlying extension language. This will likely never happen while I'm still programming. Imagine the difficulty of recreating just the org-mode package!

If you’re interested in projects working on “modernising” Emacs check out https://github.com/emacs-ng/emacs-ng

No affiliation and haven’t even used it - but it seems to have legs.

I don’t know how I missed that project. While very ambitious, I feel that it’s direction is the most practical proposal I’ve heard to modernize Emacs.

I tried out the native LSP support few months ago and the docs + features for it seemed poor. I went back to coc.vim

Have you checked it out recently? I overhauled the documentation twice since January. Most recently, I dramatically simplified the documentation based on user feedback, expanded the wiki pages, and created an "advanced" readme for power users.

I haven't! It was actually late last year I checked it out so I'll have to give it another shot.

thank you

The documentation is there, but it's a bit lacking/confusing here and there. It's also mostly foundational work, and you still need to cobble things together (either manually or using a plugin).

With that said, you can build things quite nicely with it. For example, I have a custom linter setup, custom loclist/quickfix list formatting and populating from LSP data, and a bunch of other things; all using the foundational work coming in NeoVim 0.5.

If anybody is curious, you can find my NeoVim configuration here: https://gitlab.com/yorickpeterse/dotfiles/-/tree/master/dotf...

p.s. In case anybody wonders "why Lua?", for me this mostly comes down to this: I hate Lua, but I hate Vimscript even more.

The features are all there, and I found the documentation was pretty good. There were cases where I had to dig through help pages and github issues to configure things a certain way.

I had the same experience maybe 6 months ago, hopefully having a "blessed" implementation will help/has helped this situation.

I actually was surprised to see the state of the LSP docs in general. Maybe I was missing it, but all the docs I could find only had C# examples of the various objects. I was surprised I couldn't find an exhaustive list of the JSON documents and JSON-RPC endpoints which make up the standard.

I was in the same boat, but I'm taking some time off work and I'm very happy with the Lua support. New link to my dotfiles to come. In the mean time, here are my current ones, in case they help anybody out: https://github.com/hoov/dotfiles. I use MacOS, WSL2, and Debian unstable.

It is awesome, but I have been running into bugs with it. Memory out of bounds errors, freezing when my project is misconfigured, it doesn't feel stable yet. Is that just me?

Have you filed your issues on our issue tracker (neovim/neovim, not neovim/nvim-lspconfig)? If not, please do! I haven't run into these issue myself, but if you can provide a minimal repro happy to take a look.

I think it may just be you. I’ve been using nightly builds for months now, and haven’t seen what you describe even once.

... and here is a playlist demoing my config, including how-to: https://youtube.com/playlist?list=PLu-ydI-PCl0OEG0ZEqLRRuCrM...

> But, getting into optimal setup in neovim/vim involves lot of configuration.

I haven't found this to be true. I've basically copied the configs from READMEs and have everything working.

I’m with the parent. I have to copy and paste all of these different little snippets (in the arcane viml language, although now maybe I can configure with kia?) and annotate what they do, and sometimes they compose poorly and other times they don’t work at all. Many plugins are only available via some of the package managers do you have to use several package managers with their own conventions.

Honestly the thing I like best about vim are the keybindings, and while many other editors try to reproduce them, they rarely get it right. The only one I’ve found that comes close enough is vs code and it doesn’t search properly (case insensitive) and it uses a sane regex language instead of whatever regex language vim uses.

I specifically dislike the vim philosophy that defaults should be insane and the user should have to configure things to their liking with all of the expertise that entails. VS code does a much better job in this regard (though it has its own quirks).

I think the vim philosophy is slightly different. The vim philosophy is if it worked yesterday, it works today. This means, for the most part but not exclusively, not making breaking changes. This means, by proxy, that the defaults were set a long time ago and are unlikely to change. It's a difference in who they consider the most important users, the ones already using it or the new users that might use it in the future.

I think those of us who have been vim users for a while can still appreciate intuitive design. :) Moreover, this could be entirely backwards compatible--you could have a single boolean "sane-defaults" flag which defaults to false (for our dear legacy users) but which new users can override.

Exactly. This lets configurations accrete over time and ultimately get to a place where you don't have to think about your changes and they "just work" for you.

I think emacs is more likely to have breaking changes, but I haven't used it a terrible amount, so I can't really say.

> I think emacs is more likely to have breaking changes

Matter of fact - stuff in Emacs breaks all the time. Frankly, Emacs simply defies any logic - sometimes you feel it shouldn't work at all, yet it does.

You see, when talking about differences of configuring Emacs and any other text editor or IDE, one has to understand - there's really no "configuration" in common sense. Emacs is a Lisp environment where you run your programs. You can download, import, and use other programs. Very often those programs "talk" to each other. Sometimes (of course), the line of communication breaks, and then you have to step in and patch them up so they can continue working together.

That's the biggest headache and confusion for beginners. They shy away from learning Emacs Lisp, and they think they can focus on learning Emacs fundamentals by using some "minimal configuration".

But only after understanding the basics of Lisp - structural editing, evaluating s-expressions, macro-expansion, etc., one could appreciate the enormous capabilities of Emacs. And when something breaks, it's quite simple to spot the problem and put a workaround.

What's a good x-platform GUI for it?

Your comment triggers my OCD in 2-3 different ways:

1. First you start numbering with 1.

2. Then you start numbering with 0.

3. You provide links for all but the first element in the list, which, combined with my first 2 points, results in a juxtaposition of "2" and "0", suggesting to my subconscious that I missed something.

Well done.

Corrected Now.

VimR [0] is a nice OSX GUI for Neovim.

FireNvim [1] is a browser plugin which embeds a Neovim editor window in HTML textareas

[0] https://github.com/qvacua/vimr

[1] https://github.com/glacambre/firenvim

Neovide looks amazing, thanks for linking it!

Big fan of Neovim 0.5! It's not released yet, but I'm already using it as my Clojure "IDE" at work, and all my nvim configs are written in Fennel, a lispy language that compiles to Lua. I guess it's time for me to start donating to Olical, Technomancy, and the Neovim crew, they do some amazing work!

If you want to learn (Neo)Vim and don't mind a dose of hyperactive video learning, I recommend watching ThePrimeagen his youtube videos. I've been using Vim for years, but still learned new things over there: https://www.youtube.com/c/ThePrimeagen/videos?view=0&sort=da

Oh, also: I kinda instigated this thing, sorry TJ: https://clips.twitch.tv/PrettyAgreeableMagePanicVis-4IhDSOhr...

unacceptable ;)

NeoVIM seems like a big upgrade over a lot of editors.

As a very casual Emacs user who never got excited enough for the "self-documenting and programmable editor" idea, VIM gets more appealing by the day for me. I am also using Spacemacs for a year or so and it's definitely better than normal Emacs. Haven't tried Doom Emacs and I doubt that I will, regardless of a lot of positive feedback.

I mean, Emacs is alright but I am just not in the club of the people who'll use 25% of their workday chasing an Elisp error and maybe fix a plugin in the process. Always hated the heavy IDEs like Eclipse and IDEA so this led me to Emacs but I still prefer stuff to come semi-configured out of the box. I know that NeoVIM will require some love for that but I'm prepared to do it because it looks like much less work than Emacs.

I'll try Emacs' `native-comp` branch for supposed quicker Elisp operation but I don't have much hope that it will help my grievances.

Sadly, my 19 years of casual Emacs usage are coming to an end soon.

I'm looking forward to trying NeoVIM.

For me, Spacemacs with evil mode and Vim are quite similar, but I always end up going back to Vim because it's just a) way faster for me, and b) it integrates into my workflow better.

For example, I don't want an extension to take care of git for me (magit), it's easier for me to just alt tab or bring a terminal in vim and do it there.

I find Emacs users prefer to do everything in the editor, while I'd rather have one tool do one job. Of course what job exactly should a tool do is subjective, and varies from user to user :)

Vim surely tales some "learning tax", new users are encouraged not to add every plugin they can find, instead, try to do things "the vim way". But that is also subjective.

My experience with Vim was just make it more friendly first (installing things like NerdTREE and making it behave more like other editors I was used to), then slowly learn how to do what those plugins do with just vanilla vim, and see if I can either remove them or replace them with a more "barebones" and "vim-compatible" plugin.

For example, I now use vim-dirvish which is like a better `netrw` (Vim's default file browser).

I am biased of course, but I think Vim/Neovim is just great, and always worth checking out.

> I am just not in the club of the people who'll use 25% of their workday chasing an Elisp error

Yes, experienced Emacs users do write some emacs-lisp all the time. But despite the popular belief, it's not about chasing and fixing Elisp errors.

I, for example, write emacs-lisp functions just because I can. Here are some typical examples:

- I have a GitHub link to an issue or a pull-request, I want to download the description of it and make it a proper Org-mode link.

- I want to automatically make a git branch name based on a ticket number (it retrieves the title and shortens it up)

- I want to turn a piece of EDN to JSON and vice-versa

- I want to diff two last pieces I copied into clipboard (side-by-side or otherwise)

- I want to grab a specific value for a Heroku app (based on the context I'm in)

And much more. Of course, one can use any scripting language to do all that, but it won't be integrated with your IDE.

I am not here to shit on Emacs -- I recognize that I am not its audience. Took me a long time because I was in denial but eventually I figured it out.

But I get Elisp warnings and errors every day. And mind you, I did abandon my monstrous init file a year ago and just yielded to Spacemacs with very minimal changes like font, cursor customization et. al. -- basically just 7-8 of these. It has a ton of stuff in it though. Spacemacs isn't a lightweight Emacs. Being on macOS might be another thing, too, I don't know.

Even with that, there is trouble on a regular basis. I would think an all-in-one package deal would have better debugging and proper care but oh well. :(

Again, not here to degrade Emacs itself, I am only here to share that the amount of effort I am willing to invest to maintain my local installation is apparently not enough to have a well-running editor, and that I will be giving up on it because of that.

> Spacemacs isn't a lightweight Emacs

No, it's not. Many people make a mistake, thinking that Doom, Prelude, or Spacemacs are ready-to-use, out-of-the-box solutions. They are more like collections of recipes. You have to judiciously remove things. You need to know how to use the built-in profiler.

> and that I will be giving up on it because of that

And that's okay. I myself abandoned Emacs and moved back to other things several times, until I finally learned how to make it work for me.

> ...still prefer stuff to come semi-configured out of the box

Maybe I'm weird, but stock GNU Emacs as out of the box is perfect for me. Tried configuring it with various bells-and-whistles over the years, but I always come back to stock Emacs.

(And no, despite using Emacs for 25 years I don't write elisp.)

Well it absolutely isn't for me, f.ex. I constantly need project-wide functionality like find files by name or contents. Just using C-x C-f all the time is much more inefficient.

I'm a long time (20+ years) vim user, and neovim doesn't fit my use case. I've tried it, most recently today, to have a look at LSP and treesitter. Treesitter added different syntax colors, but the result wasn't necessarily better than vanilla vim. More like an overly decorated christmas tree. LSP and other "make it into an IDE" I usually turn off after a few minutes, it's more of a hindrance than a help. I mainly code in python and don't care for intellisense.

Other than that, there's 3 real showstoppers for me:

- the obsession with Lua (I personally don't like Lua much, and even to configure treesitter I have to inject little snippets of lua code into my .vimrc). You've got people even trying to rewrite their entire .vimrc in lua, which results in an enormously verbose mess if you ask me. Lua is also what drives the vim and neovim communities further apart.

- they removed gvim (which is what I use in most cases). There is no comparable third party GUI like gvim available. They're all either abandoned, unstable or simply very different with lots of bling and gimmicks.

- neovim feels less stable than vim. It just crashed on me a few minutes ago when I was trying to configure treesitter. I copy pasted the necessary snippet in my .vimrc and neovim crashes until I take it out. In the 20 years I use vim, I don't think I've ever had it crash on me. Neovim seems more of a "move fast & break things" development model, but I write code for a living so I prefer the rock solid stability of vim.

So I'll stay firmly in the vim camp. I appreciate neovim for what it did (kickstart the vim development, which was stagnating at a certain point) but I wished they had re-merged soon after that initial goal was met. Now the communities have split and are drifting ever farther apart. Soon with vimscript9 plugins on one side and lua plugins on the other, the spaghetti will be even harder to untangle.

Yeah, I've used Vim since the mid-nineties too. At first it was my "edit a config file in my RedHat 5.2" tool. Later, the more and more actual software dev I did, it became a daily driver. I am pretty sold on the "Vim way".

I have a workflow. It's hard for me to adopt new things into my worflow because my workflow works so well. I finally made the switch to NeoVim just over a year ago because I wanted to see what the fuss was about. I have to say, it's now firmly entrenched in my workflow. It's to the point where I'd be annoyed if I had to go back.

The one sticky point about your post that I wanted to highlight:

>I personally don't like Lua much

I can say that almost anything is better than VimScript... I hate every moment I have to mess around with it. The hardest part is, I don't use it for anything else so every time I dive in, I have to remember how it works. At least Lua is a multipurpose language and documentation/help are plentiful.

But, I get that the whole intellisense, popup windows, bling... those things are not for everyone. If they don't enhance your workflow, then you're never going to desire them.

I'll ignore the other parts I disagree with in this post, since it's cool to have different views but I just wanted to post that it may someday be possible to run vim9script plugins in neovim :)

I'm working on a project that might allow at least 90% or higher compat here: https://github.com/tjdevries/vim9jit

Of course, vim9script isn't complete yet, so the spec isn't all the way done, but it may someday be possible to run them in neovim.

Additionally, if someone actually just wanted to port all the C code to run or has some other way to make vim9script run, neovim is not opposed to making that happen.

> Treesitter added different syntax colors, but the result wasn't necessarily better than vanilla vim. More like an overly decorated christmas tree.

The problem here is that people use treesitter to add more colours to distinguish more types of tokens. For me this is too much and the colours lose their meaning. I recently switched to a colour scheme that only changes the colours for strings, numbers and comments. Treesitter allowed be to add very targeted minimal highlighting. For example, I know highlight the first line of a function definition. This makes it very easy to see function scopes.

We don't really need more highlighting, but meaningful highlighting. With treesitter you can do both.

Just a note on stability, you reference Neovim crashing when setting up Treesitter. That means you’re using an unstable version of Neovim as Treesitter and Lua configuration are in the unreleased version 0.5.

I’ve been using only stable Vim and Neovim and have not had either of them crash on me that I can remember.

> they removed gvim (which is what I use in most cases). There is no comparable third party GUI like gvim available. They're all either abandoned, unstable or simply very different with lots of bling and gimmicks.

I'm not sure I understand what you're missing from neovim-qt?


I suppose maybe we have diffuse cases - but I'm fairly certain I'm running qt neovim, and not nvim in a terminal - and I'm not aware of any issues?

Thanks. I'd previously tried and failed a couple of times to get a NeoVim gui installed, mainly because I wanted to try one of those ligature fonts that display -> as → and the like. There seemed to be a few different options, in various states of being abandoned, or unpackaged, or needing libraries not in my OS, or ...

Turns out now all that's needed for Ubuntu is sudo apt install neovim-qt. Thank you for prompting me to look at this again.

However, on running it, the window seemed very wide, so one of the first things I tried was `:set columns=80` — and nothing happened. Checking :h 'co`, it looks like it's supposed to work.

Ah, and it seems the (released version of) QT gui doesn't support ligature fonts yet. The FiraCode website says it works with NeoVim-gtk: https://github.com/tonsky/FiraCode#user-content-editor-compa...

Maybe I'll give that another go ...

Does your language not support Unicode?

Some of my stuff is in Raku, which indeed supports Unicode operators. But other coding isn't, and it'd be nice to use ligature fonts for those.

Whenever I read about LSP I'm reminded of Jonathan Blow's talk Preventing the Collapse of Civilization where he talks about LSP and how it turns your single app into a fragile distributed system[1].

The sheer complexity of going from vi, to vim (and plethora of plugins), to vim + LSP is simply insane to me. It does feel like we've all lost our minds.

[1] https://www.youtube.com/watch?v=pW-SOdj4Kkk&t=2546s

I didn't watch the whole talk just the part you linked. I'm sure he makes some good points. But yeah, this guy does not understand why we have lsp's at all.

An LSP is a program that parses and internalizes a project written in a particular language and serves information, diagnostics, and edits, to a generic editor. The protocol is broad enough to serve all the "smart" language-aware functions provided by full-blown IDEs.

This allows one LSP to be used in ... many different editors. The advantage to the users is obvious: if go has one standard LSP, people who use neovim, vscode, vim, emacs etc all have an interest in maintaining that one LSP and will contribute to it in various ways.

Let me give you a few reasons why not only is it fine that it's a separate process, but you want it to be in a separate process.

1. LSPs will be better written if they themselves are written using runtime and the language that they serve.

2. LSPs can potentially hold a lot of memory. Sometimes you need to manage them, and potentially even cut them off, for example if you have a few very large java projects that you're switching between. Generally if they are separate processes, you can just kill them without affecting the editor. Additionally this also means the editor itself doesn't risk a memory leak caused by a rouge LSP server.

3. Subprocess management is not that hard. The editors can do it. Neovim does it pretty well in my experience. The presenter acts as if the server is some totally separate thing that you have to manage yourself. In reality the language server process is launched, managed, and owned by the editor, and often just communicates over stdin and stdout, not that there's anything wrong with ports.

Using multiple processes to distribute work among programs that do one thing well has always been the UNIX way.

He's definitely got a point. I had some memory problem with a business calculation I was running, I needed all the memory I could get.

So I looked at the various memory hogs on the linux installation and could see that every Vim invocation had a node process hanging off of it as a child, that's the Coc code completion/language server client running. (Action => only trigger coc for certain filetypes)

And I had vscodium running too, and it had its own long lived subprocesses hanging off of it, for language support, etc.

A lot of apps are like this - humongous clusters of processes (firefox, teams, vscode, and also Vim with the right plugins...)

I agree with you when it comes to basic config. Vimscript is better for setting options, basic mappings and events. Anything more complex then that is a pita in vimscript.

Agree totally. My experience with NVim 0.5, which is what most configs require, was errors and instability all over the place. I also don't like telescope which froze nvim on me completely.

It always feels really nice knowing that people are getting excited by your work. Thanks for the shoutout!

(I'm tjdevries)

Happy to answer any nvim questions while I'm here.

Is anyone in the nvim community working on unifying UI widgets (popovers and pickers) for eventual inclusion in nvim itself?

Consistent UI for users and great UI APIs for plugin devs would be a nice perk.

I have a couple of nvim plugins in flight and building the UI has been the hardest part so far. (A couple of examples: https://imgur.com/a/RZV2eYJ )


We want to create interfaces to make this simpler for people to use.

One example is here: https://github.com/mjlbach/neovim-ui which is just in a separate repo to make it easier to work on rather than one huge PR.

This is an extension of the ideas that I started in https://github.com/nvim-lua/popup.nvim and a few other places.

The idea would to be to create interfaces that users, plugins and/or GUIs could override to provide a unified experience while still being customizable for users.

(and as a self plug, I think we have a lot of interesting ideas in telescope.nvim about UI that could be upstreamed over time)

Thank you for the nice work!

My pleasure :)

When is it going to get released?

https://twitter.com/TeejDeVries/status/1396881477263036417 ;)

(I hope you are in on the meme, otherwise I am sorry for posting our "inside joke" response)

Jokes (and especially inside jokes) don't really go over well here on HN.

There's a milestone and date here https://github.com/neovim/neovim/milestone/19 But the meme probably is just as accurate

I see a lot of hate on Lua here. Anecdotal but I never wrote any plugins in vimscript. Since moving to Lua a week ago i’ve already written one, and will continue to where I find a use case.

Vimscript sucks, using Lua will make it easier for people to contribute I think.

I agree that vim script needs replacement, but I don't know that Lua was the correct answer.

It's not a super-popular language and makes some things harder than necessary. Base 1 arrays means you are almost certain to bake in bugs accidentally. Meta tables are even worse though. They result in many subtly different object systems. Maybe that's not as bad in a unified project, but it's the path to a fractured ecosystem. The builtin string library is very barebones which isn't a great place to be in a text editor. Finally, the "regex" match function is hyper limited.

I'd argue that either Python or JavaScript would be better.

1-based indexing is boring subject, you just get used to it like you did with 0-based indexing. FORTRAN and Matlab also use it and Julia apparently supports both.

The OOP through meta tables is bit more interesting discussion. Meta tables also enable other dispatching mechanisms, if you want to get fancy. In my case I find it makes me reach for OOP less often, which in turn reduces code complexity. I agree that it's frustrating when different libs are each using own OOP implementation. It doesn't matter too much because all those implementations are light and don't pollute the code base. Fractured ecosystem is both good and bad thing.

The string handling is kind of a pain point, especially if you are spoiled by Python. I have no idea how Neovim + Lua handle Unicode text?

Python is huge & complex language, as well as 10x slower than Lua. JS has more rough edges due to historical baggage, also a fast VM would be much much harder to integrate than Lua. I'd say they would both be worse choices for maintainability and Neovim usability.

1-based indexing matters if you only code Lua occasionally (as you say, you get used to it when coding it all the time).

JS has better string builtins than Python IMO.

QuickJS is made for embedding and has similar performance to Lua (slightly slower). I don't think you'd want to embed a large VM like v8 anyway.


I didn't know about QuickJS, last time I checked Duktape was most suitable for these cases. I see QuickJS was made by Fabrice Bellard himself. While linked benchmark is impressive for QuickJS, in case of Neovim they chose to embed LuaJIT which is ~10x faster than "official" PUC Lua. I see your point though, QuickJS would still be a good choice. JS and Lua are not that different once you set aside syntax differences.


People generally dislike change. I don’t think it’s about _lua_, anything new would receive the same treatment.

That's great to hear :) As you write more plugins, make sure to submit ideas to Neovim core about how to make Lua even easier and/or more integrated!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact