Lisp Programming with Vim (2019)
susam.net
susam.net
From what SLIME provides, one can see that the functionality used for interactive Lisp programming is different what one would use for many other languages. One is not communicating with a "language server", but with the live running application and its embedded development tools. For a Lisp programmer it is interesting where a CLASS is in the source code, but it is slighty more interesting to interact with the live class object (a metaclass object). CLOS (the Common Lisp Object System) was designed for interactive programming. That's also why it is said to be a 'system' and not only a language.
It isn't a crazy challenge, but the bar is higher than counting parens. And obviously Emacs doesn't do this correctly because it dies if someone throws a long line at it (the usual implementation of syntax highlighter is apparently regexp soup).
Apropos Clojure IDEs, m'colleagues and I in my neck of the Emacs-using Clojurist woods tend to send newcomers to VSCode or IntelliJ [2].
As community surveys show over the years, these two have come to own big chunks of the Clojure IDE pie. Well-earned, because both have received excellent Clojure programming support, with smooth REPL integration.
It seems Zed could become a contender too. A long time Clojure programmer friend and die-hard Emacs user recently remarked how Zed's performance might win him over.
[1] https://www.evalapply.org/posts/emerging-from-dotemacs-bankr...
[2] https://github.com/inclojure-org/clojure-by-example?tab=read...
and
https://github.com/inclojure-org/intermediate-clojure-worksh...
The most common "problem" I've seen with people starting to learn Clojure, is that they try to use the REPL approach you'd use in Ruby, Python or NodeJS, namely writing and running small snippets in a standalone REPL prompt, in another window/pane, then copy-paste that into their editor when they're ready. Then repeat that process while working.
While what you actually want to do, is connect your editor to the REPL, put the REPL in the background then evaluate code with a keyboard shortcut from your editor, and see the results in your editor. Once you've taught this to people, their eyes open.
For vim/neovim users, Conjure is great at giving a nice environment quickly and easily. https://github.com/Olical/conjure
For Visual Studio Code, I've heard bunch of people having success with using Calva, but haven't used that myself a lot so can't say how nice it really is. https://github.com/BetterThanTomorrow/calva
In Lisp I would use both. In some Lisp IDEs (MCL, LispWorks, SLIME), evaluating from the editor actually can queue up the form into a Listener (aka REPL) tool. MCL did this by default, LispWorks and SLIME have commands for that.
https://github.com/Olical/conjure/wiki/Client-features
Unfortunately, in the table linked above the CL support in Conjure is so-so. I'm curious what people use for CL or if it's still slimv/vlime.
I did a write up configuring Conjure with neovim here if that's something that's appealing: http://danielwilcox.uk/computers-log-0/
Is vim-fireplace dead for Clojure?
Clojure with Cursive, for a similar experience in Clojure.
Or Raket if going down the Scheme route.
It assumes nothing and tries really hard to avoid you any papercuts. I wish I had found when I tried to learn Lisp. Between learning the language and all the papercuts I just gave up like I did for so many other niche things that caught my interest.
Nowadays I'm experimenting with parinfer in Vim.
It's quirky. First off, it doesn't work well with the lisp mode autonindenting, so that has to be turned off. It doesn't handle some syntax like #; to comment out an object.
I rigged Ctrl-_ to toggle parinfer on and off.
(progn
(cond
(foo bar)
(xyzzy quux)))_ ;; <-- cursor here
If you hit Enter for a new line, it will do this: (progn
(cond
(foo bar)
(xyzzy quux)))
_ ;; <-- cursor here
In parinfer mode, though, that is counterproductive, because you control structure through indentation. Say you want to add a fallback (t 42) case to the cond. You just want dumb indentation that is not Lisp aware and which just copies the indentation of the previous line: (progn
(cond
(foo bar)
(xyzzy quux)))
_ ;; <-- cursor here
Whereby parindent will instantly move the parentheses: (progn
(cond
(foo bar)
(xyzzy quux)
))
So I have it that when parinfer mode turns on, :set nolisp is executed, and vice versa, when parinfer is off, :set lisp goes on.