NeoVim Editor

info

date: 2023-07-07 21:21:01

tags:

category: Java

Created by: Stephan Bösebeck

logged in

ADMIN


NeoVim Editor

Text Editors

This is really a topic that can stir up emotions. Which text editor to choose and configure is a very important decision especially for Unix users. Actually, these users could be divided into three "camps":

  • Vi and its derivatives
  • Emacs and its derivatives or editors that are based on Emacs
  • All others who use something like Jed (usually not console users) or Atom (not console users)

The topic is important because you spend the whole day with your editor, especially if you do it professionally. And if you're an admin on the go, then an editor that doesn't slow down the computer by starting it alone is a must. Historically, there was a considerable dispute between Vi lovers and Emacs users. The concepts could not be more different: VI is minimalist in principle and should also work on the smallest computers with little RAM, whereas Emacs can be blown up to be its own operating system (which is a bit ironic because Emacs can do so much). I have experience with both editors myself. I would like to share a little of my experience here. We will ignore the other editors because their features can be quickly checked off, especially compared to Emacs and Vi. And besides, both editors are clearly the "cooler" choice not only because of their history. emoji github:smirk

a little bit of history

This is really super interesting, because these editors have a long history. They both come from times when neither keyboards nor screens followed a standard. The operation was also not really "standardized" yet. Not to mention graphical user interface or mouse. The very first editors (the predecessors of Vi and emacs) were even line-based, i.e. you only edited one line at a time. One of the most widespread representatives of this genre was the editor ed - which today certainly would no longer be called an editor (in MS-DOS there was also a counterpart called edlin). But from it came the Streaming Editor, sed, which is still part of the standard toolset on Linux/Unix today (with it you can process, modify and adapt inputs very easily using, for example, regular expressions). Normally, at that time, one connected to a computer with a terminal client via a rather slow connection (e.g. 300 baud, i.e. bit/sec - BIT - not megabit or so) using the Telnet protocol. At those slow transmission rates, it was essential to optimize the transmission. So (of course) only text was transmitted (there was nothing else at the time) - but this text was also only 7-bit (almost all transmission protocols at that time assumed that 7 bits would be sufficient). The keyboards were not standardized, especially keys like ALT or CMD were not everywhere. That's why Vi was limited to the lowest common denominator: the keys for the ASCII codes (0-127!) and ESC. This is surprisingly efficient - still. Meanwhile, Emacs took a different approach. Here, too, they had to deal with the same shortcomings of early computers. But they decided to at least require the CTRL key. With that, Emacs could receive its commands via key combinations using CTRL. This led to very cumbersome keyboard shortcuts: typing CTRL-C CTRL-X in quick succession exits EMACS. And that's one of the shorter examples. Another path was taken in the implementation of Emacs. The language of choice for Emacs was Lisp - a language that is currently experiencing a revival as a functional language. But Emacs went a step further. It was not only written in Lisp, but could also be extended with its own functions using Lisp, and Emacs could execute Lisp code. So Emacs was relatively from the beginning a Lisp development environment. Vi was written more or less in C/C++ and therefore was much smaller and also faster - especially at startup. Extensibility was a "problem" for a long time, but a worthy alternative was found with "Vimscript".

Vi on wikipedia emacs on wikipedia

VI vs Emacs

As you can see from the title, I have now arrived in the VI camp. There are several reasons for this. For me, the keyboard shortcuts in Emacs were simply not really intuitive, even though I had used Emacs as my primary development environment for several years. I had taught Emacs to compile, debug, etc. Java projects. And yet the keyboard shortcuts were difficult to get used to. This applies to the entire operation of Emacs, most of the time you have to perform some kind of "monkey moves" on the keyboard to enter a command.

In my opinion, VI solves this more elegantly: you start in the so-called "Normal" mode. In this mode, you can enter commands that do something. For example, "d" to delete something, or "a" to append something. For most commands, you still have to specify a direction, such as when deleting. So you type "d" and then what you want to delete, for example, "w" for all characters up to the word boundary. With the "a" command, you enter the "Insert" mode. There you can edit your text normally. To switch from Insert mode back to Normal mode, use the ESC key. That's pretty much the most important thing you need to know about VI. (Except maybe that you can prefix each command with numbers. For example, 5dw would delete the next 5 words.) However, the default version of Emacs is significantly more powerful than the regular VI. This did not contribute to its popularity. RAM was scarce back then. And if a text editor required 8 MB to function properly, it was really a problem. That's why cynical tongues also say that Emacs is not a text editor, it is an operating system that alone in terms of size outshines Windows (for comparison: Windows at that time only needed 1MB of RAM to function 😉). This led to a little feud between Emacs users and Vi lovers. Vi users came up with alternative meanings for Emacs (Emacs Makes Any Computer Slow or Eight Megabyte And Constantly Swapping). And in reference to the somewhat silly key combinations, Emacs could also stand for Escape Meta Alt Control Shift. A quote that often circulates on the internet is: "Emacs is a great operating system - it lacks a good editor, though." (supposedly attributed to Thomer M. Gil). For fun, one of the celebrities of the GNU/Open Source community, Richard Stallman, even founded a religion based on Emacs: The Church of Emacs - and he himself is St. IGNUcius. The creed of the Church of Emacs is: There is no system but GNU, and Linux is one of its kernels. You should say that 3 times a day 😉 Nerdy humor... Richard M. Stallman: "Emacs started out as a text editor, which became a way of life for many users because they could do all their work on a computer while never exiting from Emacs, and ultimately it became a religion as well." Of course, the VI lovers didn't just stand by and founded their own "religion" as well: The Cult of VI. All in all, this escalated into a real "thing" in the early internet, the "Editor WAR". Many discussions about the two editors were held and somehow neither really "won" (if you can even speak of winning in such a case). Both editors and their derivatives still exist and are very popular.

Vi-Derivative

Since VI was very popular and always available on every Unix system, there were also quick extensions and improvements, such as "Vi Improved" or simply vim. This editor has arrived in the 21st century, can do much more than the regular Vi, and is particularly highly customizable. Of course, there are many graphical interfaces for Vi, such as MacVim, or plugins that provide Vi keyboard shortcuts for text editors (e.g. for IntelliJ). But for a few years now, there has been a new "player" in the Vi arena: NeoVim.

NeoVim

NeoVim is initially exactly the same as Vim was for Vi: an improvement. It is a reinterpretation of the Vi concept and a more modern implementation with new features. For example, NeoVim supports the Lua language for creating extensions (so-called plugins). This makes the editor significantly more powerful, especially compared to the "normal" vim, which also offers a programming language for extensions called "VimScript". However, VimScript has its quirks, so the community has shifted a bit. In general, NeoVim works the same way as Vi if it is not specifically configured. But that's the charm. You can configure NeoVim to your liking. The keyboard shortcuts can be customized. It takes effort, but then you have your own personal text editing environment. It can do exactly what you need, no more and no less.

Plugins

The plugins that can be installed in NeoVim make it extremely powerful. And one might think that the whole thing becomes terribly slow with every additional installed plugin. But that is far from the truth. I have installed and configured quite a few plugins, and still, NeoVim starts up in less than a second for me.

Speed

Speed here both refers to the speed of the editor, but also the speed at which you can do things (vim motions!).

This is, by the way, one of THE special features of NeoVim - the speed at which things happen. This is not something one is accustomed to. Development environments, in particular, suffer from all the features that are needed to work with them effectively. And as a result, they become slow. The best example of this is Eclipse - it was sometimes so bloated that you couldn't even start it without taking a coffee break.

Comparing NeoVim to an IDE like Eclipse is a bit of a stretch, although in other aspects, it is not. The IDEs can do more than what NeoVim currently offers, but it comes really close. However, if we're being honest, the term "IDE" doesn't really feel appropriate for NeoVim. It's more like a "PDE" - "Personal Development Environment." Because both NeoVim, VIM, and Emacs with their derivatives are much more than mere text editors. Comparing them to something like Notepad is truly an insult. And if you keep reading, you will understand why... One of the great features of VI and all its clones is the way you can navigate through the text. The Vim movements are super important to understand. Once you internalize them, you can navigate to any point in the visible editor area with just a few keys. This efficient navigation alone is what makes Vi and its derivatives still so efficient and popular today. There are incredibly useful things that programmers especially appreciate. For example, you can switch to the matching bracket with % - and it works with nested brackets too! That is worth its weight in gold! (especially in programming languages that use a lot of brackets, like Java or C/C++ and RUST). But sometimes, even navigating within a line can be cumbersome. Let's take this line here. If the cursor is somewhere at the beginning, and I want to jump to the word "sometimes," there are several options:

  • I press the w key repeatedly until I reach the right spot (move forward word by word, W would be backward)
  • I press 6w - because I want to jump ahead by 6 words directly
  • I press fm and jump directly to the next m in the line.
These "Vi motions" are extremely efficient, and one should take the time to learn a little more about them from time to time.

All these navigation commands can also be combined with other commands. For example, I can delete the next 5 words in the line by typing 5dw... or I want to delete until the next bracket, so d% - super practical because it takes nesting into account. But you can take it even further... If the cursor is on a word that I want to delete, I simply type diw, and the word is removed. All of this is very confusing for non-Vi users and is only meant to demonstrate the power of this editor and especially the Vim motions. With them, you can do everything without even thinking about the mouse... especially when using a modern derivative of Vi and integrating plugins. Then, there are practically no limits. You could take it so far as to use NeoVim as your own development environment...

NeoVim as an IDE

With the help of plugins, you can configure NeoVim to be a very "personal" IDE. In my case, I can program in Bash, Lua, Python, Rust, Swift and especially Java, and I have all the necessary features in my editor: text completion, snippets, error display, code formatting, code generation (automatic imports in Java, for example), running and debugging tests or entire programs (although I haven't been able to do that with Rust or Swift yet). When comparing it to other IDEs (IntelliJ or NetBeans), which take at least 30 seconds just to start, NeoVim is refreshingly fast. Especially when you are already in the terminal and just want to quickly try something out or make adjustments. Starting up the IDE would be overkill in that case.

In general, it has its charm. I am always working in the command line, whether it's with SSH or locally. If I then want to quickly open a file and have to start up a whole IDE for it, it can quickly become cumbersome. Usually, I leave the IDE running in the background so that I can open the corresponding file when I need it. Of course, a modern IDE like IntelliJ can do a lot, but for quickly going into a project and running a test or making minor changes, this has its advantages. It is really faster than using IntelliJ, for example. This actually happened today. I had to search in several projects because I wasn't 100% sure where it was. It was much faster in the command line than in IntelliJ: I used ripgrep to search for the files in the filesystem, then opened the correct project in nvim. All of this took less time than finding and opening the first project in IntelliJ (and waiting for it to synchronize - there were also some fairly large projects that take a bit of time to start). So the whole process took less than 10 seconds. Another aspect, in my opinion, is the control of VI with its different commands. Quantifying commands also has its advantages (e.g. 15> indents the next 15 lines by one level). And we don't even need to talk about the very powerful search/replace functions. Most of these features can also be obtained in the IDE of your choice if you're interested. There are several plugins for IntelliJ that implement a VI mode and enhance it with some features. All in all, it's also a good compromise. And if you set the settings in IntelliJ to be the same as in NeoVim (or vice versa), switching between them becomes easier, even if you want or need to switch back.

Introduction to NeoVim

NeoVim can usually be easily integrated into the normal software management systems. On Mac, it works best with brew install nvim (neovim is almost always abbreviated as nvim). When you start NeoVim with nvim, the user may initially be somewhat disappointed. The screen that greets you is, to put it mildly, empty - no features, etc. This is because NeoVim initially functions and starts off as a normal VI clone. Now you just need to configure it. The configuration of NeoVim is located in the ~/.config/nvim directory, and the most important file is init.lua. This file is executed when NeoVim starts. Here you enter all the configurations you need. Furthermore, you can also configure plugins, etc. If you're starting from scratch, this can be overwhelming. There are several places on the internet where people share their NeoVim configurations, and I started with that too. However, it didn't take me as far as I hoped. Most configurations are very personal and heavily dependent on what you actually do. Someone who only occasionally works with Java but mainly works with Python will have different priorities than someone who primarily writes Java or C++. That's why I took the trouble to build my own configuration. It's particularly important to "listen" to your own needs. What is important to me when developing? Which features offered by a full-blown IDE like IntelliJ do I actually use? And what do I miss with such an IDE? I have to be honest and say that I didn't really "miss" anything with IntelliJ. Just that sometimes it's terribly inconvenient when switching between branches, and the IDE takes what feels like an eternity to synchronize. And until this is completed, some functions cannot be used. That's annoying... but honestly not a serious problem. Certainly not a reason to switch. Features I need:

  • Syntax highlighting for "my" languages: Java, Bash/Shell, Python, Lua, and Rust. And it's nice that occasionally unknown languages also work "just like that". For example, Swift, or Markdown, or HTML, or JavaScript.
  • Auto-completion and suggests for the aforementioned languages.
  • Error detection and basic code checks (typos, for example).
  • Code actions, such as automatic imports, variable renaming.
  • Debugging should be possible. That's pretty much it. Basic Configuration Here are a few tips on how I put together the configuration:
  1. In the init.lua file, I mainly have references to other files that handle specific tasks. For example, plugin installation has its own files for most plugins.
  2. This approach provides better organization and makes it easier to add or remove features as needed.
  3. You need to familiarize yourself with the Lua programming language. It is syntactically very simple, and if you need an IDE, it shouldn't be difficult to learn. However, some basic knowledge is helpful.
  4. I have my own include file that handles key mappings. This allows for customization. The "problem" is that some plugins have their own settings, so you may need to consider that.
  5. Debugging Lua code can be a bit tricky, and I haven't been able to do it. But you can use normal print statements for debugging. (You can see the output by entering :messages in NeoVim.)
  6. The most important thing is to have fun!

NeoVim Configuration as an IDE

Configuring NeoVim as an IDE can be a bit of a challenge. But that's also the goal, isn't it? emoji github:wink Seriously though, if you're not interested in tinkering and don't want to deal with the command line and related tools, you might want to stick with a "real" development environment or switch to one. Playing around with NeoVim has given me some new ideas. For example, I've modified the test suite of Morphium so that I can now run tests from the command line. This is advantageous even if I'm using IntelliJ. I can run the tests without having to rely on the IDE (and I have more options for separating the tests cleanly!). There are a few concepts that you need to understand to know what's happening. The most important one is support for LSP (Language Server Protocol), which allows errors in the code to be reported to the editor for display. Another concept is DAP (Debug Adapter Protocol), which allows you to start and control debug sessions from the editor. It's important to note that these concepts work independently of the programming language used. So you can debug both Python and Java with NeoVim without needing to switch gears. The same goes for displaying compiler errors, etc. This is all independent of the programming language; you just need the appropriate Language Server (e.g., for Java, Bash, or Python). I've already mentioned what was important to me. There are various plugins that I use. I don't want to simply post a configuration here because, as I mentioned earlier, it's usually not very helpful. If you want to use it, you need to familiarize yourself with the topic. Here is a list of the plugins I use:

  • Packer: This is the most important plugin because it handles downloading and configuring other plugins. It's best to read the documentation on GitHub.
  • Mason: A great plugin that manages the entire LSP/DAP setup. It particularly focuses on installing associated plugins and helpers.
  • Whichkey: Shows me which keys would perform which actions. For example, I have the key combination Lt set up to start a test. If I'm not sure what actions I can take, a menu appears during a pause. If I only type L, a menu with all options is displayed.
  • Null.ls: A formatter for various programming languages. I have it set up with the shortcut lf.
  • Impatient: This plugin reduces the startup time of NeoVim by installing/configuring plugins on demand and asynchronously. This allows NeoVim to start with dozens of plugins in just a few milliseconds.

The Mason plugin is used to install LSP support. It's actually relatively simple for most cases. Syntax highlighting and code formatting usually work out of the box. However, it becomes significantly more challenging when you also want features like autocompletion (IntelliSense) and error display (syntax/compile errors) to be integrated. For this, you need to install the appropriate LSP server. These are usually installed by Mason, but sometimes you may need to do some manual work. Some code formatters also require specific command-line tools. For example, I use astyle to format my Java code (because I prefer its result over the Google formatter). But the great thing is that you can configure and experiment with these settings as you like.

Conclusion

I've been using NeoVim as my primary IDE for a few weeks now, initially only for my hobby projects (e.g., Morphium), but now increasingly for work on large Java projects. The main advantage of NeoVim is its speed. Starting NeoVim and searching for a file is done in milliseconds, while opening a project in IntelliJ takes a lot longer. That's a huge advantage! Cursor navigation using Vim movements is another significant plus and a must-have for any editor, in my opinion. I can reach any part of the screen without having to switch to the mouse. And the best part is that all these navigations can be combined with "real" commands. These keybindings are incredibly powerful but also quite complex. However, once you learn that yip copies the paragraph containing the cursor (and with NeoVim, it goes to the operating system's clipboard, e.g., on a Mac), you'll want to use it everywhere. emoji github:wink And if you quantify these commands, it gets even more fun: 5yip copies the next 5 paragraphs to the clipboard! If you want to be more specific, you can also copy lines 5 to 25 to the clipboard using :5,25y. And if you want something more destructive, you can replace the y in the commands with a d, and instead of copying, it will delete (strictly speaking, it performs a cut, so everything is still in the clipboard afterwards). But of course, such a setup also has its disadvantages, and you have to be willing to accept them. The most significant disadvantage is probably the steep learning curve. This applies not only to Vim motions but also to configuration and how to deal with LSP, etc. It can be quite complicated, and it takes a few days to get used to it. Another potential disadvantage is also an advantage: There is hardly anything "pre-packaged" that fits your needs 100%. You are forced to customize according to your own preferences. Admittedly, this is not everyone's cup of tea, and it doesn't have to be. But if you enjoy tinkering, you should give it a try. I also won't deny that such a setup can be a bit annoying at times. Updates often cause more problems than they solve. But that's something that happens frequently with software. Here, it's just that the various plugin authors make it even more varied than if it came from a single manufacturer. As I said, this kind of setup is not for everyone, but it's surprisingly powerful. And I used to joke to my collegues, "I don't care what you use for development, even VI is fine by me" - and that's exactly what I'm doing now! emoji github:wink