So you want to write Java in Neovim
ptrtojoel.dev
ptrtojoel.dev
Seconded.
As someone who has spent a lot of time configuring editors, but doesn't enjoy it quite as much as he used to, I gave Java on Neovim a shot this summer.
There are two main routes to go - both of which are described in the article. Either install it yourself, "You read the friendly manual", or use someone else's installer, "You use a distro".
My problem with someone else's installer is that I don't understand what it's doing, which in turn gives me the feeling that it's pulling in the kitchen sink, which is exactly the feeling I hoped to avoid by not using my regular IDE.
My problem with installing it myself is that I have to learn the entire ecosystem including, but not limited to, learning how to use Neovim for more than editing a simple text file, learning the Lua scripting language, learning where Neovim keeps its' configuration files and what to put in them, curating a set of plugins for highlighting, launching code, debugging, etc., figuring out how to configure those plugins for Neovim and finally how to make those plugins play nice together.
In the end it just wasn't for me but if Neovim is your primary editor it might be for you.
> Java has one LSP option for Neovim, and that’s JDTLS (Java Development Tools Language Server) by Eclipse.
Just wanted to mention that there is another LSP for Java, https://github.com/apache/netbeans/tree/master/java/java.lsp..., but I don't know if anyone has gotten it to work with Neovim.
It’s definitely still a kitchen sink, lots of stuff that I wouldn’t configure on my own, but surprisingly discoverable via a popup that shows available keyboard shortcuts that appears after you type LEADER and wait a moment.
It’s also super fast to start up, putting most destros out there especially EMacs ones to shame.
The main downside is it encourages you to spread out your config in multiple Lua files, and overall learn and use more Lua stuff. But I think it’s worth the price.
The Nvim Kickstart Project is a great starting point for your configuration and has it's config file heavily commented to teach you how to setup your own configuration, I highly recommend it.
Why is the bridge not "specify where to find the LSP server"?
I do agree that some nvim setups are just IDE's in your shell, but it's also nice to have everything in one place. I don't like vsc's and Jetbrains's terminals at all, as it gets clunky too quick. To each their own though!
I never want to waste a single brain cycle on a missing semicolon. That is what the editor (or autocomplete or AI or whatever) should be doing for me.
To give an example, let's say you want to make pull requests for an API change across several interdependent repos (e.g., an API change in a framework). So you want to you want to do a find and replace in each repo, then push the changes to a branch, and create a pull request for each one. This can be achieved entirely from the command line, making it really easy to repeat across all the repos that need to be updated.
(With all the above said, I do use most LSP features, like live error checking and autocomplete, but if I were forced to choose, I would give that up before I give up the flexibility of a programmable environment.)
Your brain is an incredibly efficient tool. You should trust it more.
In principle, this effort should even be measurable in calories (though it may be hard to distinguish from the noise of everything else you're thinking).
Perhaps I should have originally been clearer, but I have no clue what these "brain cycles" that keep being mentioned are. If it's some kind of CPU analogy, brains and CPUs are nowhere near analogous in how they work. The brain is an extremely complex system, whose mechanisms we're far from understanding fully and whose activities are mostly unconscious and subconscious processes.
In the context of our discussion, energy expenditure is not really the relevant feature. The more useful "index" would be the "perceived (i.e. conscious) cognitive workload". One is addressed with caloric intake, the other has more explicit psychological ramifications.
It may have been presumptuous of me, but cognitive workload is what I thought GP really meant by "brain cycle" and that's what I was addressing.
The point I was trying to convey is that the brain is very good at moving chunks of work away from conscious processes to subconscious ones (i.e. away from perceived load) through various optimizations. Usually, exposing the brain to deliberate and repetitive tasks will tend to develop certain tacit skills (subconscious shortcuts).
Another subtler point, was that an easy mistake when evaluating how much cognitive work a tacit skill actually demands, is to appreciate it from the perspective of someone who lacks said skill.
He does this mainly when trying to show/explain something to someone in code and when initially drafting something. Not for full blown projects.
I still find it interesting though, because I personally don't nearly have good enough memory to even do that. I have to look things up constantly and rely on auto completion.
I too prefer a much more minimal approach to my text editor. Then what most IDEs provide, but syntax highlighting is luxurious and a must-have for me. In general, I really love colors, especially the simple colors of the terminal. Color can be distracting of course, but it is a phenomenal way to quickly differentiate between related and unrelated parts of the code.
haha I love the tone and I feel you, the state of software (and computing in general) keeps surprising me (in a bad way) as years go by. It feels like it's only getting worse. We can talk about their salaries too !
What’s your type of job?
An important thing is to find a personal sweet spot. For me, using Idea with hundred plugins is just not worth it. Spring plugin comes with thousands of features, but when I disable it, miss very few things, and the bloat is real: slow start, lots of new menu items and icons, new bugs.
I, personally, prefer to use editor on steroids like vscode, with full language-aware support. At the same time I'm using external terminal a lot, doing builds and stuff there. So IDE for me is an entire computer and vscode is part of this IDE.
You forgot the natural root of this hierarchy: ed, the standard text editor.
No, you can't. Comparable plugins don't exist.
Languages that have great and standard tooling will work great. Frameworks that rely on basic language features work great. Projects that rely on standard tooling and features work great. Things just work.
Languages that have 3 decades of legacy warts, languages with no or poorly implemented LSPs, languages where the ecosystem relies heavily on runtime language features, frameworks that rely on behind the scenes magic and conventions, projects where for ten years the whole team only ever used one IDE… yeah, it’s not where vim/helix/vsc shines, and you will fight an uphill battle.
The only language that comes to mind fitting this description is Go ?
Other languages that do ok are OCaml, Elixir/Gleam, Typescript. Go and Rust just have what I consider a "cut above" the others when it comes to both tooling and standar language features.
This.
e.g. Android studio has a great preview feature for composable which makes it a joy to build them. It gives you an option to run just see the live effects of updating code for that composable in (a) IDE (b) Emulator (c) Device.
Requiring building app before having a preview and then waiting between 10 seconds to a minute on every change is what you call joy?
Only languages with negligible market share don't have 3 decades of legacy warts.
Nonetheless, I wouldn't write either of them without a proper IDE.
Languages like Rust, Dart, Go, Kotlin, and Swift emerged when standard tooling was already expected, such as LSP, standard formatting and linting.
I don’t have experience with all of these languages, but I know that Rust and Darr have great tooling maintained by the same people who maintain the language and I can just pick any code editor with LSP support and I can expect the experience to be great.
Combined with ctags and a terminal it’s all I need for the languages I’m familiar with (c, c++, rust, python and several others)
It took a bit of getting used to at first, but then it just becomes normal.
The statement is usually shortened under the assumption that nobody is writing Java by choice, and if you're writing it for work you're forced to use (Employer-provided development tool).
There are other languages that are hard to use without an IDE, but they always are relatively obscure ones and/or blatantly integrate the language itself tightly into the IDE, like Smalltalk or Scratch.
Most languages, it's feasible to write with nothing more than a regex-based keyword detector and symbol tagger. LSPs are overrated, other than the fact that they're a narrow waist for supporting multiple languages in multiple editors.
Java culture promotes long class names and method names, which are often neither unambiguous by prefix nor by initials, which are the 2 basic autocomplete styles (though really, I shouldn't allow the pro-Java argument to consider autocomplete at all, even a stupidly basic one).
Java culture (and to some extent the language itself, due to package-private) expects separation of classes within a project into multiple/nested packages, but package names are expected to be very long and there are no relative imports. And classes from third-party packages will also have horribly long names. New-file templates can help a little if you're willing to suppress "unused import" warnings.
The lack of support for "free functions" (outside a class) adds a ton of verbosity, if you can't fake them via dummy interfaces. Meanwhile, the fact that `this` is implicit makes the question of "what identifiers are in scope" almost as complicated as C++.
But yes, if you're paying attention, Java-the-language can be made somewhat nicer if you ignore Java-the-style (notably, many developers of Java itself are famous for doing this internally). But then you basically give up on the library ecosystem, which is the only reason to write Java in the first place. You can't even add interfaces retroactively!
Yes, I know they say "speed of programming isn't limited by how fast you can type", and it's usually true. But Java proves it can be bad enough to drop your cache.
No, you don't use it often.
You can use it as a poor man's debugging tool, but Java actually has very nice debuggers. You can use it as poor man's logging, but then you have pretty good logging frameworks. Or you can use it as application output, but then you probably want to abstract specific output stream away from most of your business logic code and use interface.
With that said I’m still a sout, puts, Printf, cout << developer.
Also, if it can't even import symbols automatically, then it sounds like a tool problem. Java is like one of the simplest languages, it has no fancy features, has sane imports, ultra-stable tooling, etc.
The point of an IDE is to improve productivity. And I think you just haven't seen someone who knows the ins and outs of an IDE fly while writing Java there.
I actually think the best way to learn Neovim is to build your own configuration with as little plugins as necessary for you to get the job done because it'll force you to learn the Neovim way of doing things. For example instead of relying on tabs I learnt to use the Mark system and it was a great addition to my workflow.
- I like awk grep sed find and many more... and piping things together
- I like the low latency of vim and love walking through code with just a few movers
- I like the ubiquity of using the same tools on any machine, local or remote (including windows now that it has wsl) and bash
All of this even more so than "no mouse setup" or anything, I don't mind using the mouse sometimes.
Simple command line tools become primitives in this language, and they compose together. Learn a few dozen and you have something quite powerful. You can remain in the same mental model to accomplish many tasks. Graphical tools tend to be monoliths that rarely compose, each premised off of a different mental model. This creates friction when moving from one to another.
For better and for worse, the terminal looks pretty much the same now as it did 30 years ago. (There are important improvements in zsh and fish.) Graphical tools tend to evolve quickly. If I don't use a command for 5 years, I can get back up to speed in a few minutes using it's built-in documentation (`--help`). If I don't use a graphical tool for 5 years, I'm pretty close to square one, and need to spend some time with the manual (in a separate application, the browser or PDF reader).
If something is missing from your toolkit, throwing together a proof of concept level CLI is pretty easy. Presumably some people can throw GUIs together very quickly as well. But the CLI is a simpler programming model. (Immediate mode GUIs do narrow this gap, however.)
And now your new CLI can integrate with all your other CLIs out of the box. Eg, a tool that tweaks some values in a JSON file can be used with the `find` command to tweak many JSON files.
(Your mileage may vary. I'm just trying to present a distilled intuition, if I seem to be speaking in absolutes, it's figurative. Whatever workflow works for you is the right one.)
In fact, the whole TUI craziness of IT world fashion is getting back to what used to be daily business in the 1980's and early 1990's.
The most hilarious to me is when people refer to Emacs as a "text editor". I'm not talking about the fact that Emacs shall happily display pictures (inlined in a file like in org-mode for example or in their own window), open binary files, open PDF files, manipulate files over SSH (Tramp), etc.
Heck, as a statement some made Emacs run as PID 1.
But many seem to honestly think Emacs is "notepad with bad shortcuts".
Maybe I'm missing something but navigating and finding/adding files in a structure that's 10-20 directories deep or more seems like a nightmare in pure Vim.
It's a fuzzy file finder.
For your example of `org/example/groupid/packageid/submodule/File.java` I might write "[Ctrl+P] pamodFi[Enter]"
If `File.java` is unique enough, I can just type that and it finds it without issue.
There's also filetree plugins if you really want the visual clutter
Thankfully my company has its own hosted LSP that supports Java (and every other language in our bazel monorepo) so I don’t have to mess around with Eclipse and JDTLS (what happened to eclim?). But at a prior company I just worked without an LSP and just did a lot of referencing Java docs in a browser and split screen files.
Since 2015, I mostly worked on the web version of our cross platform C++ project but have contributed substantially to the Android and iOS libraries as well.
Is it open source?
A real shame, I think Bazel's lack of good IDE options definitely hampers its adoption.
It has support for fzf and zoxide for these uses. As well as a panoply of other goodies (ripgrep, file previews, commands without exiting the file explorer, etc.)
If one is willing to learn helix instead of nvim, I know there's integrations out there between the two as well. I wouldn't be surprised if there were for nvim as well.
the thing i like the most about it is the amount of plugins you can add (including things like looking at nvim's paste ring).
I was also curious. The project has been shut down/archived this August recommending java LSP instead but it seems like there hasn't been a lot of work or a release since 2021
https://github.com/ervandew/eclim
> (Aug. 03, 2024)
> Eclim has reached its end of life. The Language Server Protocol (LSP) and the various implementations are mature enough that eclim has become unnecessary.
> It has been a great run (nearly 20yrs!) and I'm grateful for everyone that helped out, from bug reports to patches, it's been awesome
I haven't found anything better than Neovim+Lazyvim and switched from ST4 a couple of years ago and never looked back.
I think my favorite feature is `gr` (in command mode) to "goto references" for the symbol under the cursor. I use this all the time (as well as `gd` for goto definition which with the LSP is really precise).
I mostly use the file navigation when exploring the structure, which I'm not doing that often.
And which I probably should do with a class browser anyways, which I used to do often in Eclipse, way back in time, but it seems that particular SmallTalk-ism isn't very popular in contemporary IDEs.
For example:
$ mkdir foo
$ cd foo
$ printf 'package jimbo;\npublic class Foo2 {}\n' > fred.java
$ javac -g -d . fred.java
fred.java:2: error: class Foo2 is public, should be declared in a file named Foo2.java
public class Foo2 {}
^
1 error
The only exception that I'm aware of is that inner classes don't have to live in their own filename (given that they're more or less property of the owning class)The Maven-ism that I'm aware of is the by default structure of {src/main/java, src/main/resources, src/test/java, src/test/resources} but (of course) those are customizable via the pom.xml if it jams up your project that much
1: https://docs.oracle.com/javase/specs/jls/se6/html/packages.h... (it's the oldest spec version they still link)
Not only inner classes, you can have many top-level classes on the same file but they cannot be public.
Most jetbrains IDEs I find are indeed comparable to vscode plug-ins and a huge glob of vim plug-ins for most languages, especially the dynamically typed ones where the amount of static analysis you can do is already quite limited.
But for IntelliJ, literally no other editor comes close. Extract method/variable, all the "hey you wrote java 6 but it's 2024 that those 6 lines you wrote are 1 lambda now, do you want to replace", and so many other things.
Did you know that if you paste a maven xml dependency coordinate into a .gradle file, it auto-translates it to gradle format before the paste?
dotnet add package GxHash
dotnet remove package ...Even little things like variable naming, explicit types, and the like were commonly neglected because in the IDE you could just hover your mouse over the variable to see its type. Because that exists and is so commonly used, developers didn't even think about The impact it might have on someone not using the same IDE. This is just one of several practices that I continually ran into when trying to use vim. There are also plenty of readability issues, such as enormously long methods that the IDE collapses for most developers so they never see it and don't have to think about it, but once you aren't using that IDE anymore, you really see all the nastiness and warts.
So long story short, I agree with you about the tooling, but I think it is actually more of a curse than most people realize.
I mean sure, there are projects out there where a healthy dose of tool-agnosticism should not be too much to ask for, but a generalized "they are doing it wrong" about people playing to the strengths of their toolkit is really not warranted. The opposite of structuring around what works well with their tooling is structuring around what works well with your tooling. You ask for exactly the thing you are refusing them. Yeah, IDE-only builds are a bad idea, but that's really a concept that has died a long time ago (even if there are probably a few cases around where it still has not stopped moving yet)
It's like joining a team of roofers and using a hammer while everyone else is using nail guns... sorry, the right tools are faster.
Also FYI you don't need to use a mouse to get the types, moving a cursor over the variable is enough.
You overestimate mental capacity of average Java dev. Most of them are using whatever herd does without knowing why.
Formatting tooling was chosen before several members joined my team. It was chosen due to having far fewer dependencies than ESLint+Typescript+Prettier etc. One package... one setup.
Secondly, what exactly do you think managing is? Someone has to make the ultimate decision and be responsible for it. Perhaps you think a manager is someone who's constantly wandering around taking a vote from everyone on how they want to steer the ship? While I do strive to find concensus among my team that's not leading. Agree to disagree there.
What other platforms and languages have you used recently to compare with java?
Compare:
https://www.jetbrains.com/help/idea/refactoring-source-code.... (note the possible refactors in the sidebar)
With IntelliJ + Java I can do more advanced refactors (change method signature for example) and it compiles without any manual effort.
So my question is, what are projects like Cursor going to do? Surely the solution isn't to assume that JetBrains will do enough innovation in AI IDE features in the next year or two to prevent is wanting to try out all the other AI IDE innovation?
Recently, my company has tried to introduce a “cloud IDE” (the development environment runs in the cloud somewhere). Initially, it only supported VSCode. The only engineers that bothered using it were junior; once people had about 5+ years of experience, they just found it tedious. Once the company included IntelliJ for that cloud IDE, usage spiked massively. (To the point they are restricting usage due to cost.)
These “classic Java IDEs” just launch with features useful for understanding large systems, like, fast navigation and debugging capabilities. Things like “where is method used” or “what implements this interface method” is fast and accurate - i.e., not based on text search. Or the interactive debugger that lets you inspect stream state, track objects, etc.
JetBrains probably won’t be focusing on using AI simply for writing code, but for enhancing all of these other capabilities. This is where I’m not sold on Cursor or Zed replacing these truly language-specific IDEs… yet.
These new upstarts need to improve the ability to navigate and understand. Right now, they only seem to focus on writing, which I don’t think is what’s going to gain traction. I also don’t see any of them doing much other than just fancy autocomplete, which can be awful on a large legacy codebase. So… we’ll see.
This could be generational, I’ve definitely seen poorer DevEx win simply because they gained the attention of younger engineers and lasted long enough.
They kind of have been doing just that, their jetbrains AI assistant has an integration comparable to cursor's, just the model itself isn't as good which is a shame
I have to say that even though sometimes both AIs offer amazing suggestions, it's really distracting to me to have constant multi-line completions being suggested non-stop! And sometimes it's a suggestion that would probably make sense in a widely different context, but you can see how the AI would believe it was appropriate for you anyway and you start wondering about nonsense. I had to disable that.
The line-completion that IntelliJ has by default now was quite a bit better IMO. It really helped and was not so distracting.
Anyway, I can't tell which AI was best, they both seemed similar in capabilities. The JB AI is a bit more well integrated, obviously, so it's a bit easier for me to accept completions for example (with Copilot, sometimes it competes with the normal IDE completions and I can't easily pick one). Anyone has an opinion on that?
I very much agree. The line-completion is a very well done AI integration.
I think there's a lot of potential to integrate AI into IDEs, but it will likely be less of a low-hanging fruit in comparison with simple code completion.
It wouldn't. Diehard Vim and Emacs users might hate each other, but they hate IDEs more.
P.S. If you want to give IntelliJ a try, after installing the vim bindings package, also make sure to install the “string manipulation” package, and set some keybindings, as it’s 100% necessary for quick editing.
It just works.
(though obviously jshell kicks in quite a bit during coding sessions, and on top of that I have several templates and custom shell scripts that help navigate docs easily)
Ask HN: Programmers who don't use autocomplete/LSP, how do you do it? - https://news.ycombinator.com/item?id=42492508 - Dec 2024 (625 comments)
1. Note all the things you like about your current IDE vis-a-vis your development workflow. 5 major Lists will emerge : While Code, While Compiling, While Running, Debugging & Test.
2. Set up a current project you are working on in the IDE in neovim.
3. Take some minutes in the day how much cognitive load it takes to switch and use each one of the things in #1. Then ask yourself the 1million $$$$ Question:
- Does adding a bit of complexity give you an advantage? -
This will probably teach you more about your own current IDE and improvements you could do there than neovim
But I also maintain a vim config for Java development, because in small projects and some small fixes it has a nicer integration with the shell and cli tools there. If you aren't going to do JavaFX, hairy debugging or non-trivial release management it's good enough.
And that's not even getting into the horror show of trying to view the analysis results of any "hello world" setup wherein it does terminate: a reasonable CI integration would submit those findings as comments on the PR but I had to duct tape one together by transforming the SERIF output into ReviewDog to get that outcome
I am quite possibly the biggest JetBrains fanboy you'll encounter, and was thrilled out of my mind when they announced Qodana, but its execution has been a raging dumpster fire
I find it easier to just install language servers using brew. Then the command can be simplified to
cmd = { 'jdtls', '-data', home_dir .. '/.local/state/jdtls/' .. project_name },
My ftplugin/java.lua is about 100 lines, with most of it being settings and key bindings.I don't whant to write Java, let alone in *vim.