Hey vimers- vim was my first “programmer” editor and since then I went through various others (Xcode, JetBrains, Spacemacs, Emacs, VSCose). Now I’m thinking to circling back to vim, I think I still remember most commands :)
What’s a good way to get started? I see neovim is the way to go these days, and there’s a few Clojure related plugins already. Any other tips for modern vim development?
FWIW I prefer GUIs to the terminal, looks like there’s a few neovim guis available.
I use neovim with conjure - works really well.
(coupled with clojure-lsp)
There's a channel #conjure that may be helpful if you consider looking at it 🙂
What about non-Clojure stuff? I remember that 10 years ago I had a nice .vimrc file for fuzzy finders etc. What’s the consensus these days for quality of life plugins?
(I backed neovim when it was announced thinking it will probably fail but it was a nice moonshot - glad to see it going strong!)
there are tonnes of modern plugins - like fzf for fuzzy searching, others include vim-clap, vim-which-key, vim-sandwich etc...
I use vim petty much as my go-to editor, for nearly everything. When I have to use Kotlin/Java, I jump into IntelliJ
before install any plugin I recommend to try the vanilla way. There are a lot of articles about it: https://vimways.org/
one of my favorite: https://vimways.org/2018/death-by-a-thousand-files/
i use vim for everything, even including stuff like java where i've noticed that people tend to use IDEs i've found the experience of writing java in vim with LSP integration is surprisingly good
even before i started integrating LSP into my vim setup, i had a reasonably good experience just editing java code ("blindly") in vim and running the project from the command line (via gradle, mvn, etc., or even just java
) after i make changes
What @dave said. All of it. 👍 For me there was more C# than Java, though.
i occasionally write C# at work, and i do it in vim 🙂
without LSP integration, unfortunately, because the version of mono we use is so old, the LSP server doesn't support it 😑
That's hard to answer, since there are so many plugins, and such a wide variety of setups you can construct with them. All I can say is what works for me: https://github.com/walterl/dotfiles/blob/master/_config/nvim/init.vim#L72-L158 (I'm clearly not a purist like @kalmiz 😝)
Ha! Ditto. Luckily that's many years past for me 🙂
When I say I use vim for "everything"/"most things", it means that I have a keyboard shortcut to pop up nvim in a new terminal, setup for Markdown editing, so that I can write longer Slack messages (or emails) too. :neckbeard:
ooh, i like that idea
i have a vims
(mnemonic: "vim scratch") shell alias that opens vim editing a file with a name like /tmp/scratch-20200806090055.adoc
, or a different extension if i provide one, e.g. vims clj
for a scratch clj file
a keyboard shortcut is the next level 😄
Ok so neovim with Conjure works nicely. What do I gain with Clojure-lsp? Haven’t looked closely yet.
things like completion, autocomplete, jumping to different definitions
fwiw, I don't use any LSP but I've heard very good things, I think it can complement other tools really well (as @dharrigan is pointing out!). Neovim 0.5+ will have a built in LSP client too! So you won't need to install CoC etc (although I guess there will be tradeoffs)
completion and linting are the main things i get out of clojure-lsp
I am sort of a neanderthal - I like the facilities of the repl itself. I use the very good :terminal
provided by neovim, plus neoterm
which provides simple commands for sending a region to one of the terminals (eg. the current form). It doesn't automatically change to the namespace I'm in, but gives me the direct repl experience (actual log of things I ran and printouts, etc.)
I use fzf for finding files in other people's projects, in my own projects my namespace layout is sane so I don't need it :D
I use :grep
with ag
as my grepprg
then the standard :cope
to browse and jump to results, C-I / C-O to go forward and back through recent jumps
and :tabe
to keep groups of buffers organized
Not trying to sell you on it or make you switch but for the record: Conjure keeps a log buffer with trimmed snippets in comments of what you ran and the resulting stdout / err and results as data within a Clojure buffer that you can edit and re-eval etc 😄 I felt like all the other tools lacked that easy access to history and context behind your evals, the log buffer tries to address that.
finally q:
to browse recent :
commands as an editable buffer isntead of the crappy :
mode keybindings
(you may have already dismissed it for other reasons too, but yeah, thought it was a feature worth mentioning)
terminal also gives me an identical UI to a repl on staging via ssh, a clj stdio repl, an nrepl client, or a socket repl
I have looked at conjure, but it doesn't fit my criteria for features/complexity tradeoff right now
Yep, sounds totally fine to me
Your setup sounds super simple but effective, I like it
Less to go wrong too!
funny thing, the initial motivation was when I switched to being a senior engineer and mentoring other devs
I realized that I couldn't pull up to pair with Amy and show her how to do something in sublimetext!
I was using emacs at the time as well, and CIDER was breaking every week
what I realized was that if I used a less "magical" toolset, I learned things that were guaranteed to work if the coworker was using clojure, period
and I realized that the things that were total deal breaker needed features were provided by the :reload
arg to require
, load-file
, doc
, javadoc
, apropos
, find-doc
and that the kind of code that was written by people who use "jump to source" as an instant shortcut is too often absolute shit
orzo code - lots of meaningless tiny pieces with poorly defined relationships
do you @noisesmith have a .vimrc file somewhere publicly? I don't get the :reload
arg thing
oh - that's not vim, that's clojure (require 'some.ns :reload)
ah right
didn't know that actually
thanks
there's also :reload-all
which recursively reloads
good to use basic stuff, in the end one knows more stuff:)
@timok here's a trick you might like: (do (require 'my.sut.ns :reload-all) (doto 'my.sut.ns-test (require :reload) (in-ns) (clojure.test/run-tests)))
if I do that all in one line, iterating my tests for the current ns I'm working on is just a question of up-arrow followed by newline in the repl
I will try that out
and after a repl restart, that single line fully recreates my testing flow to iterate again
then the test failures remind me of what I was working on, and I can ignore the tools and just do my flow
sounds good and I want to become a neanderthal as well:)
using too many plugins that kind of not work the way I want them
I'm not trying to start a new religion, but I'm happy to assist if you want to know how to do a particular task directly with the clojure repl
I get completion and jumping to namespaces from Conjure. How is completion different from autocomplete?
I’d love to see a screencast of your workflow @noisesmith
I might even have time for that soon haha
that'd be awesome
If I understand correctly you launch a whatever REPL that allows you to type stuff, then use the editor to just simulate the typing
Hope you have time due to vacation ;)
it's a scheduled layoff, Funding CIrcle is laying off all US engineering
but if I'm being honest I'm overdue to spend some time on my own long term software projects anyway
and those will involve Clojure
and I can actually afford to take time off, I've been careful with money
@noisesmith I've been considering something similar recently. Things like jump to definition would be my big miss, but I experimented with having my repl handle that a little while ago.
clojure.repl/source is right there of course (as well as <http://clojure.java.io/resource|clojure.java.io/resource>
to find the specific object that contains your function)
user=> (require '[<http://clojure.java.io|clojure.java.io> :as io])
nil
user=> (io/resource "clojure/core.clj")
#object[java.net.URL 0x74e81ce0 "jar:file:/home/justin/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/core.clj"]
user=>
I might even write a little helper that turns "jar:file:/home/justin/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/core.clj"
into a path nvim can open
I'm sure that's something fireplace, conjure, etc. all have implemented already
I tried that and ran into a vim bug. If you search the github issue tracker for my name it's my only one.
in my neovim :e /home/justin/.m2/repository/org/clojure/clojure/1.10.1.jar
works as expected, and from there I can open clojure/core.clj
as a second step
Right. You can do it in two steps. I think you can't put it on the path is what I'm thinking of.
I was trying to setup all the stuff for gf etc to work out of the box.
oh, right, it would be nice if this was one op if you do it frequently
I did do exactly this with regexps in an old version of Conjure 😄 the new nREPL based one just leans on nREPL
It's become a core part of my workflow to jump and tweak. Couldn't imagine having it be a 3+ step process
https://github.com/Olical/conjure/blob/d9d514db3ef7fcf36bacc402aba511663a73bfbc/fnl/conjure/client/clojure/nrepl/action.fnl#L147-L159 if you squint and ignore the fennel you can sort of see what Conjure does for this now
@noisesmith I'd love to see such a screencast too 🙂
my hot take (see the convo in #off-topic for way too much detail) is that a dev flow where I need to jump around that much is a sign of a design problem / failure to encapsulate properly