I develop Cursive, an IDE for Clojure code, and I spent a long time integrating parinfer smart mode. It was actually really difficult to do well, I wrote a document with feedback about what (among other things I discovered later) that made it hard: https://github.com/parinfer/parinfer.js/wiki/Problems-integr.... I subsequently fixed many of those issues, but it was probably the second hardest thing I've integrated into Cursive, after Leiningen.
It's still a bit quirky, but I use it every day and I love it. Even though I'm proficient enough with paredit, parinfer is just so much easier to use. Several users have commented to me that the parinfer integration is the main thing stopping them switching away to a different editor - it really makes that much difference.
Thank you, Colin! Now you mention it, it makes so much sense that you use Parinfer yourself. The implementation is so great and doesn't feel quirky to me (or maybe I just got used to the quirks).
I've been using Parinfer with IntelliJ (Cursive) ever since I started developing Clojure professionally back in 2018. The best thing about Parinfer, or at least the implementation in Cursive, is that it doesn't preclude you from also mixing in some Paredit commands too.
When you start out with Clojure/Lisp and you aren't totally used to parenthesis you can just use Parinfer to get editor behaviour similar to developing Python. It removes a major pain point of migrating to a Lisp. It used to be the case that you were forced to learn Paredit pretty much from the start.
Your comment about how it makes editing flow like python is spot on, and I've been saying this for years. I'm a long time parinfer-rust user in spacemacs, and it makes me very happy.
However it also made me very strict and opinionated about formatting. One of the main downsides of parinfer comes when you have to interact with someone else's poorly indented or opinionated (wrongly) formatting that goes against the clojure style guide. Parinfer can then ruin otherwise working code because things are out of alignment. To fix this, I set up a function to force format files on open, which mostly works but then for the longest time made me the source of a lot of white space commits. It also struggles with egregiously long files.
Thankfully I eventually got my team on board with force formatting all files and treating non standard formatting as linting errors. We also cut down the largest files one of the other devs made, and that helped a lot.
> It used to be the case that you were forced to learn Paredit pretty much from the start.
I started part-time in Clojure in 2011 and full-time in 2014. I've never felt like I needed any extra tooling for parens. Instead of typing `foo(x)`, I type `(foo x)`. It seems...almost exactly the same to me.
Same with text editors: people will say you need emacs, Cursive, etc. but I just use vim for Clojure, as well as everything else. It works great.
Parinfer was instrumental to me learning Clojure. Paredit felt like operating an airplane cockpit, and Parinfer took that experience and made it much closer to just writing prose, for which I am forever grateful.
I remember people, including Rich Hickey, scoffing at it when it came out, which seemed like kind of a snobbish reaction to something that lowers the barriers of entry.
Paredit was written primarily for the use of its author, Taylor R. Campbell. If you ever met Taylor R. Campbell, you would understand why it feels like an airplane cockpit.
(Think: John Carmack writing something for John Carmack's use, and it turns out you need to be as smart as John Carmack to figure it out.)
I tried Paredit out in the early days; it was heavily inspired by SEdit, the structured editor that came with Xerox's Interlisp-based Lisp machines (an open source version of whose OS is available here: https://interlisp.org). I really liked it, but with time I found it was just another "targeting computer" I had to switch off in order to keep focus on my code, so I ended up not using it for most of my Lisp work.
Chris Oakman ported the parinfer algorithm to Lua [1]. I used this to write a parinfer plugin for Neovim [2]. I use Fennel (a Lisp that compiles to Lua) for all of my Neovim config and so use parinfer everyday. It works exceptionally well (there are occasional hiccups, but no showstoppers).
Neither my plugin nor Chris' script have been updated in 2+ years. That's because it just keeps working. I owe a lot to Shaun and Chris for their work (my plugin is just a little glue code for interacting with the editor, they did all of the hard work).
I've used it for a number of years, but I do believe that while this is really helpful, it's a little incomplete.
It has gaps around pasting content and how to handle that elegantly as well as comment behaviour, if those two things could be reconciled, it would be even more useful :)...
This is really nice, and I am impressed how much effort went into the documentation, to make the demo nice and interactive.
At first I thought this is something new, because it's cool and I haven't heard of it, even though I'm coding in Clojure for about 3 years now. But this project is already 10 years old and hasn't received much attention for the last few years, which is a pity.
I wish it was coming with Calva, my favorite Clojure tooling in VS Code.
> I wish it was coming with Calva, my favorite Clojure tooling in VS Code.
You have this basically already. When you move forms in/out on the indentation levels, notice how the brackets/parenthesis automatically re-arrange themselves? That means it's working :) https://calva.io/parinfer/
Damn, you're right, I didn't notice the notice, nor am I a daily Calva user.
But so what, is there no automatic balancing of parenthesis in Calva? That seems to diminish the value from the extension by a lot, I couldn't imagine coding Clojure and having to manually balance parenthesis.
Something about VSCode makes it hard to add in. I think it lacks the right APIs.
Also, the main maintainer of Calva doesn’t use Parinfer, and so isn’t very motivated to add it either. But if someone were to contribute it, I imagine he’d be very receptive.
I’ve been considering Parinfer, but my issue was that it is a bit unpredictable where parens end up and I have to be careful to not mess up my code structure. Maybe I should give it another try for a longer time period.
My favourite structural editing tool for about a year now is symex[1], which is an Emacs package (and unfortunately not that well known compared to paredit, lispy, etc.). It takes some getting used to at first but after a while you only move around and think in terms of s-expressions, you don’t even see parentheses anymore. It really feels like you are a squirrel climbing trees (hence the image on the repo, I guess). I just hope the dev(s) will be able to get rid of the heavy dependencies on other packages soon.
Great tip. Exactly what I've needed. I'm heavily vim-based and can't stand editing elisp. I don't mind if it's heavy on dependencies since I'm already overburdened with dependencies, what's a few more.
Going from parinfer to editing without parinfer is kind of like going from vim to an editor without vim bindings. In other languages I find myself instinctively moving or editing text around expecting the brackets to magically rearrange themselves, only to be disappointed when they don't.
After using Parinfer for a few years the editing experience felt less like typing and more like a cross between magic and the scene from Ghost in the Shell with the split hands. It's a real shame they weren't able to add it to Calva.
I love innovation in this space, and remember when Parinfer came out having some enlightening discussions with colleagues about how they efficiently edited code.
I've since settled on Lispy and Lispyville in Emacs, and have run into very few issues over the past few years.
There's something about Lispy’s style of editing that appeals to me — the use of hugging parentheses to enable its bindings, combined with Lispyville making all of my Vim bindings safe, makes me very happy.
I'm using a parinfer plugin with Vim for writing TXR Lisp.
There are some issues, but it's usable.
I hacked in a hotkey to toggle it on and off (Ctrl-Underline).
The parinfer code from Vim does not work in the parens->indent direction, only indent->parens. I tried to get it working, but it didn't for me.
It doesn't properly understand the #; syntax for commenting out an object. It's possible for it to get into an endless loop when an undo operation restores invalid syntax; there is a kind of fight between undo and parinfer that has to be interrupted by Ctrl-C.
I try to use paredit-mode, but it never seems to integrate well with evil/vim keybindings. I always end up disabling paredit-mode after a few hours. I'll give this a spin.
I develop Cursive, an IDE for Clojure code, and I spent a long time integrating parinfer smart mode. It was actually really difficult to do well, I wrote a document with feedback about what (among other things I discovered later) that made it hard: https://github.com/parinfer/parinfer.js/wiki/Problems-integr.... I subsequently fixed many of those issues, but it was probably the second hardest thing I've integrated into Cursive, after Leiningen.
It's still a bit quirky, but I use it every day and I love it. Even though I'm proficient enough with paredit, parinfer is just so much easier to use. Several users have commented to me that the parinfer integration is the main thing stopping them switching away to a different editor - it really makes that much difference.
Thank you, Colin! Now you mention it, it makes so much sense that you use Parinfer yourself. The implementation is so great and doesn't feel quirky to me (or maybe I just got used to the quirks).
Thank you I love Parinfer and Cursive
I've been using Parinfer with IntelliJ (Cursive) ever since I started developing Clojure professionally back in 2018. The best thing about Parinfer, or at least the implementation in Cursive, is that it doesn't preclude you from also mixing in some Paredit commands too.
When you start out with Clojure/Lisp and you aren't totally used to parenthesis you can just use Parinfer to get editor behaviour similar to developing Python. It removes a major pain point of migrating to a Lisp. It used to be the case that you were forced to learn Paredit pretty much from the start.
Your comment about how it makes editing flow like python is spot on, and I've been saying this for years. I'm a long time parinfer-rust user in spacemacs, and it makes me very happy.
However it also made me very strict and opinionated about formatting. One of the main downsides of parinfer comes when you have to interact with someone else's poorly indented or opinionated (wrongly) formatting that goes against the clojure style guide. Parinfer can then ruin otherwise working code because things are out of alignment. To fix this, I set up a function to force format files on open, which mostly works but then for the longest time made me the source of a lot of white space commits. It also struggles with egregiously long files.
Thankfully I eventually got my team on board with force formatting all files and treating non standard formatting as linting errors. We also cut down the largest files one of the other devs made, and that helped a lot.
> It used to be the case that you were forced to learn Paredit pretty much from the start.
I started part-time in Clojure in 2011 and full-time in 2014. I've never felt like I needed any extra tooling for parens. Instead of typing `foo(x)`, I type `(foo x)`. It seems...almost exactly the same to me.
Same with text editors: people will say you need emacs, Cursive, etc. but I just use vim for Clojure, as well as everything else. It works great.
If you're a vim key bind user the main vim plugin for IntelliJ works well with Cursive's parinfer implementation
When I tried this in vscode it was problematic
Parinfer was instrumental to me learning Clojure. Paredit felt like operating an airplane cockpit, and Parinfer took that experience and made it much closer to just writing prose, for which I am forever grateful.
I remember people, including Rich Hickey, scoffing at it when it came out, which seemed like kind of a snobbish reaction to something that lowers the barriers of entry.
Rich Hickey was referring to editors that hide parentheses entirely, not paredit nor parinfer. This was explicitly cleared up after the talk
I can't see Hickey not liking parinfer; of course he had to mean something else.
I'm pretty sure he doesn't use it though. Have you seen the formatting of the Clojure source code? It's eclectic.
Aha, really? What editors do that?
Paredit was written primarily for the use of its author, Taylor R. Campbell. If you ever met Taylor R. Campbell, you would understand why it feels like an airplane cockpit.
(Think: John Carmack writing something for John Carmack's use, and it turns out you need to be as smart as John Carmack to figure it out.)
I tried Paredit out in the early days; it was heavily inspired by SEdit, the structured editor that came with Xerox's Interlisp-based Lisp machines (an open source version of whose OS is available here: https://interlisp.org). I really liked it, but with time I found it was just another "targeting computer" I had to switch off in order to keep focus on my code, so I ended up not using it for most of my Lisp work.
Chris Oakman ported the parinfer algorithm to Lua [1]. I used this to write a parinfer plugin for Neovim [2]. I use Fennel (a Lisp that compiles to Lua) for all of my Neovim config and so use parinfer everyday. It works exceptionally well (there are occasional hiccups, but no showstoppers).
Neither my plugin nor Chris' script have been updated in 2+ years. That's because it just keeps working. I owe a lot to Shaun and Chris for their work (my plugin is just a little glue code for interacting with the editor, they did all of the hard work).
[1]: https://github.com/oakmac/parinfer-lua
[2]: https://github.com/gpanders/nvim-parinfer/
I've used it for a number of years, but I do believe that while this is really helpful, it's a little incomplete.
It has gaps around pasting content and how to handle that elegantly as well as comment behaviour, if those two things could be reconciled, it would be even more useful :)...
This is really nice, and I am impressed how much effort went into the documentation, to make the demo nice and interactive.
At first I thought this is something new, because it's cool and I haven't heard of it, even though I'm coding in Clojure for about 3 years now. But this project is already 10 years old and hasn't received much attention for the last few years, which is a pity. I wish it was coming with Calva, my favorite Clojure tooling in VS Code.
> I wish it was coming with Calva, my favorite Clojure tooling in VS Code.
You have this basically already. When you move forms in/out on the indentation levels, notice how the brackets/parenthesis automatically re-arrange themselves? That means it's working :) https://calva.io/parinfer/
Thanks for the link. Unfortunately it seems it is currently removed due to unclear bugs.
Damn, you're right, I didn't notice the notice, nor am I a daily Calva user.
But so what, is there no automatic balancing of parenthesis in Calva? That seems to diminish the value from the extension by a lot, I couldn't imagine coding Clojure and having to manually balance parenthesis.
Something about VSCode makes it hard to add in. I think it lacks the right APIs.
Also, the main maintainer of Calva doesn’t use Parinfer, and so isn’t very motivated to add it either. But if someone were to contribute it, I imagine he’d be very receptive.
AFAIK Calva does have a Parinfer implementation.
I’ve been considering Parinfer, but my issue was that it is a bit unpredictable where parens end up and I have to be careful to not mess up my code structure. Maybe I should give it another try for a longer time period.
My favourite structural editing tool for about a year now is symex[1], which is an Emacs package (and unfortunately not that well known compared to paredit, lispy, etc.). It takes some getting used to at first but after a while you only move around and think in terms of s-expressions, you don’t even see parentheses anymore. It really feels like you are a squirrel climbing trees (hence the image on the repo, I guess). I just hope the dev(s) will be able to get rid of the heavy dependencies on other packages soon.
[1]: https://github.com/drym-org/symex.el/
Great tip. Exactly what I've needed. I'm heavily vim-based and can't stand editing elisp. I don't mind if it's heavy on dependencies since I'm already overburdened with dependencies, what's a few more.
Going from parinfer to editing without parinfer is kind of like going from vim to an editor without vim bindings. In other languages I find myself instinctively moving or editing text around expecting the brackets to magically rearrange themselves, only to be disappointed when they don't.
After using Parinfer for a few years the editing experience felt less like typing and more like a cross between magic and the scene from Ghost in the Shell with the split hands. It's a real shame they weren't able to add it to Calva.
Is there a way to slow down the animation, including editing anything in the web source? I'm having a little trouble following it.
I love innovation in this space, and remember when Parinfer came out having some enlightening discussions with colleagues about how they efficiently edited code.
I've since settled on Lispy and Lispyville in Emacs, and have run into very few issues over the past few years.
There's something about Lispy’s style of editing that appeals to me — the use of hugging parentheses to enable its bindings, combined with Lispyville making all of my Vim bindings safe, makes me very happy.
I'm using a parinfer plugin with Vim for writing TXR Lisp.
There are some issues, but it's usable.
I hacked in a hotkey to toggle it on and off (Ctrl-Underline).
The parinfer code from Vim does not work in the parens->indent direction, only indent->parens. I tried to get it working, but it didn't for me.
It doesn't properly understand the #; syntax for commenting out an object. It's possible for it to get into an endless loop when an undo operation restores invalid syntax; there is a kind of fight between undo and parinfer that has to be interrupted by Ctrl-C.
Otherwise it's mostly fine.
I try to use paredit-mode, but it never seems to integrate well with evil/vim keybindings. I always end up disabling paredit-mode after a few hours. I'll give this a spin.