1. 24
  1.  

  2. 11

    Switching to using Lua for Neovim seems like it’ll be really powerful. I’m just a little scared to make that final jump, because there’s way to really go back to Vim after doing this. I’ve already leveraged a bunch of Neovim-only stuff, but this is a lot more extreme.

    1. 7

      The Lua support in Neovim is one of the things making me eager to look at it. Lua is a fantastic little language and there’s no reason to be stuck with something like vimscript in 2021.

      1. 5

        I looked a bit at lua, and a lot of stuff seemed much more verbose/awkward to me.

        I kinda of like VimScript 😅 There are a few annoying parts (line continuations, ugh, and I still forget that stupid a: sometimes), but overall I find it works fairly well, especially since lambdas (already some time ago) and the method syntax (also some time ago, but never ported to Neovim) were added. It’s a fairly small language that fits its purpose reasonably well.

        It’s perhaps a bit of an acquired taste though.

        1. 4

          Neovim is claiming that lua is much faster than VimScript. I’ve seen VimScript chug on files with just a few hundred lines, so I’m hoping I can convert my heavier functions to lua and get a speed boost.

          1. 2

            I can’t say I ever ran in to issues with this myself; most of the times I ran in to performance issues it’s because you do something like :%s/<something rather complex on a large file>/, but I’m not sure if Lua will really help with that? From what I can tell, most of the performance issues is when people implement stuff like fuzzy matching in VimScript and similar computation-heavy stuff.

            The new VimScript9 is quite a bit faster (but still slower than LuaJIT), but I haven’t really looked at it.

          2. 1

            I kinda of like VimScript

            Wow, this is the first time in twenty years I’ve heard anyone express an emotion about vimscript other than disgust.

        2. 7

          if you keep your dotfiles in source control (which I recommend if you aren’t already), you have nothing to lose. If you make the switch and decide later that it’s not for you, just revert back to the previous version of your config that uses vimscript.

          1. 3

            That only works until you customize further in lua.

            1. 2

              I’m not sure what you mean. Sure, you lose some further custom lua config (until you port it to vimscript), but you won’t end up worse off than you were before you switched if you have your config in source control.

          2. 4

            I have recently switched not only to Lua, but to Fennel as well and I am pretty happy with result. Now I need to port rest of my config from VimL to Fennel.

            1. 2

              Wow, that’s amazing! Did not know Fennel could be used like this.

              1. 2

                do you notice any delay from having to compile the fennel files to lua on every startup?

                1. 4

                  Slight, but nothing annoying me. In the past I was trying to cut load time as much as possible, but now I stopped giving a damn. I haven’t tried precompilation though.

                2. 1

                  If you’re using a lisp for your editor scripting.. At what point does evil/emacs becometthe saner choice, though?

                  1. 3

                    As soon as Evil will learn into all my favourite quirks of Vim. I have tested Emacs in the past and there was always some small nitpick that was missing and was irritating me. Now I get the best of two worlds.

                3. 2

                  Is there a reason that’s a problem? Neovim is a fork of the vim codebase and migrating to it doesn’t seem all that different from upgrading vim and then using plugins that require the new version as their minimum version. Neovim is basically just vim that is making faster progress on cool new features than mainline vim is.

                  1. 5

                    Neovim 0.5 lets you write your vimrc as a lua script, which Vim8 can’t parse.

                    1. 2

                      The big gotcha I hit with Neovim was that it uses a different format for undo files. I have this in my vimrc:

                      set undodir=${XDG_CACHE_HOME}/vim/undo//
                      set dir=${XDG_CACHE_HOME}/vim/swap//
                      set backupdir=${XDG_CACHE_HOME}/vim/backup//
                      set undofile
                      set undolevels=1000
                      set undoreload=10000
                      

                      This avoids cluttering my working directories with undo / backup / swap files and gives me effectively unlimited persistent undo, my favourite feature of vim. If I run neovim on a file that I’ve edited with vim, it complains. Similarly, if I edit with nvim and then vim, vim can’t read the undo file. I wish they’d change the name of files if they were going to have things for the same purpose as vim but with incompatible formats.

                      1. 3

                        I wish they’d change the name of files if they were going to have things for the same purpose as vim but with incompatible formats

                        This can be achieved with something like

                        if has('nvim')
                          set undodir=${XDG_CACHE_HOME}/nvim/undo//
                          ...
                        else
                          set undodir=${XDG_CACHE_HOME}/vim/undo//
                          ...
                        endif
                        

                        I believe the undofile format became incompatible only very recently, when more information was added to undofiles.

                        1. 1

                          That’s what I did, but it’s annoying that I have to.

                          I was also quite excited by the built-in LSP support, but all of the tutorials I found required incredibly complex configs and didn’t explain how to configure the LSP integration for something like clangd for C/C++.

                    2. 1

                      There are heaps of incompatibilities between Vim and Neovim, and have been for years.

                      https://news.ycombinator.com/item?id=27719968

                    3. 1

                      What are some neovim features that you’ve really liked? I generally see the same things trotted out by fans, like treesitter and in-build LSP, but these aren’t things I’ve felt like I was missing in Vim (I do use LSP, plugins work well for this). I’d love to hear what benefits you have found, as an experienced Vim user?

                      1. 6

                        It’s a bit of a moving target, because a lot of neovim innovations are eventually implemented in vim. That’s what happened with floating windows, async jobs, and terminal emulation. So I guess the feature I really like is being a couple years ahead of everyone else :)

                        There’s also a few smaller things: I really like inccommand, which I don’t think has been ported over yet. And I just found out I can use the lua bindings to do this:

                        local nav_keys = {'h', 'j', 'k', 'l'}
                        for _, key in ipairs(nav_keys) do
                          local c_key = '<c-'..key..'>'
                          vim.api.nvim_set_keymap('n', c_key, '<c-w>'..key, opts)
                          vim.api.nvim_set_keymap('t', c_key, [[<c-\><c-n><c-w>]]..key, opts)
                        end
                        

                        I expect that as I get more comfortable with lua and the neovim API I’ll have more say. I write a lot of custom functions and vimL is one of the worst languages I’ve ever used.

                        EDIT ooh something I just realized I can do:

                        local set_all = function(list)
                        for _, item in pairs(list) do
                          vim.o[item] = true
                        end
                        end
                        
                        set_all {"termguicolors", "hidden", "splitright"}
                        set_all {"number", "relativenumber"}
                        

                        That’ll make it easy to create setting groups.

                        1. 2

                          No, no inccommand in Vim still. I was quite keen on this for a while until I discovered traces.vim which is a lot more powerful.

                          Yeah vimL has its quirks. The actual examples you’ve shown would look pretty similar in vimscript though … although they would use :execute, e.g. exe 'nnoremap' c_key '<c-w>..key. I’ve come to quite like vimL but I realise that puts me pretty firmly in the minority. I hate the line continuations but those are going away in vim9script.

                          It does look like configs will diverge now, to the lua neovim scripts and the Vim vim9script scripts. Which I suppose is good, trying to support 2 diverging editors with a single code-base is annoying, as each add different features.

                          1. 1

                            You can map stuff in loops in regular VimScript:

                            for k in ['h', 'j', 'k', 'l']
                                exe printf('nnoremap <C-%s> <C-w>%s', k, k)
                                exe printf('tnoremap <C-%s> <Cmd>wincmd %s<CR>', k, k)
                            endfor
                            

                            For a somewhat creative use of this you can see this ;-)

                            I guess the issue is that a lot of people just can’t be bothered to invest in learning VimScript, which is fair enough. But pretty much anything you can do in Lua you can do in VimScript, and vice versa.

                            1. 1

                              I guess the issue is that a lot of people just can’t be bothered to invest in learning VimScript, which is fair enough. But pretty much anything you can do in Lua you can do in VimScript, and vice versa.

                              Also, there’s more third party Lua libraries. A while back I needed to fill an autocomplete based on information in a YAML file, but couldn’t figure out how to parse YAML in VimScript. I ended up writing a python script to first convert the file to JSON, then use json_decode. It worked in that case but would have been nicer to just import a library and read the YAML directly.

                              1. 2

                                I think this - the availability of the Lua library ecosystem - is probably a “bigger deal”, looking forward, than the performance/tooling/ergonomics benefits Lua brings over VimScript. I haven’t seen too much adoption of Luarocks packages in plugins yet (though there are some examples, e.g. https://github.com/camspiers/snap), but I expect this to change now that 0.5 is stable.

                                I will also say that, while anything* you can do in Lua you can do in VimScript, I personally find it much easier to do most things in Lua - partially due to familiarity, but also due to the simplicity of the language and the relative lack of footguns, compared to VimScript.

                                *In Neovim specifically, Lua provides access to luv, which I’m not sure you can access from VimScript. In my experience, having the libuv event loop and utility functions readily at hand makes it possible to write functionality which would be at least substantially more painful without these tools.

                                1. 2

                                  I haven’t seen too much adoption of Luarocks packages in plugins yet, but I expect this to change now that 0.5 is stable.

                                  Why do you expect this to change with 0.5? It’s been possible to write Lua plugins since 0.3, with luv becoming available in 0.4. I don’t see anything (besides the hype, maybe? :^) ) in 0.5 that would change the attitude of plugin authors towards Luarocks.

                                  1. 1

                                    It’s true that we’ve had the ability to write Lua plugins for a while now, but there’s been a huge increase in the use of Lua during the later part of the 0.5 development cycle (the past year or so). This, to me, indicates that we may have passed an inflection point in the ease of using Lua for plugin development that will contribute to more people writing Lua plugins, and (potentially) more people using functionality from Luarocks libraries for those plugins (though I admit this also assumes that people need and know about the libraries available through Luarocks).

                                    The hype is another factor, at least at first. And - noting that this runs dangerously close to self-promotion - I think that tools like packer.nvim‘s Luarocks integration (which you can use even if you don’t use packer for plugin management) significantly lower the complexity cost of using Luarocks packages, while also requiring features from 0.5.

                                    1. 2

                                      I see. In my opinion there’s a fundamental issue with the with dependencies where as a plugin author you don’t want to rely on external dependencies (otherwise you’re inevitably going to end up with people opening issues after misconfiguring the dependencies for your plugin…) but vendoring is fairly unattractive too (messes up version control history, you have to manually update everything…). This issue was already there with Vimscript and I don’t think it can be solved by anything else than Vim/Neovim implementing a full-featured plugin manager (which I don’t think it should do).

                                      1. 1

                                        Yeah, that’s definitely true too. I think this is easier with Luarocks because it already supports some basic versioning specification, so you can control what versions of dependencies your users get without needing to vendor. I definitely agree that there shouldn’t be a full-featured plugin manager baked into Vim/Neovim, though - people’s preferences and needs around plugin management are too disparate for there to be a good “one size fits all” option, in my opinion.

                                        1. 2

                                          I think this is easier with Luarocks because it already supports some basic versioning specification

                                          My point was that the package manager that downloads from luarocks itself becomes a dependency, which you want to avoid. So luarocks doesn’t really make things easier there :)

                                2. 1

                                  One way would be to use Python:

                                  :pyx import yaml, vim; vim.vars['x'] = yaml.safe_load('{"hello": [1, 2]}')
                                  

                                  Or Ruby, Racket, Lua, Tcl, Perl, or even Visual Basic. It’s nice that Vim can interface with all that, but the big problem with that is that a lot of people don’t have the scripting support, and if you want things to work on Linux (all distros), macOS, and Windows is nigh-impossible. In reality It’s all pretty useless if as can never use it and have it work for everyone (the reason I didn’t try :lua is because my Vim isn’t compiled with it, and also, because I don’t really know Lua).

                                  Generally Vim tries to minimize required dependencies, which isn’t a bad thing. The Lua interpreter is pretty small so it could be integrated like libvterm or xdiff instead of linking toliblua. But I guess it’s too late for that now :-/