:colder is amazing. I can grep while I'm grepping then return to my grepping.
omg thanks for that! I've been struggling with mentally keeping track of my grep-ception stack.
I usually end up keeping my "main" activity in quickfix, and performing "sub-greps" in a different terminal.
Wow. TIL.
I do wish there was a clojure-aware grep, like for finding uses of keywords, namespaces, functions, etc.
Some of that may be possible with cider, but having a cli tool would compose better in certain situations.
you can set grepprg
and surely one of them should be smart enough to parse clojure identifiers
I use ag
as mine
@nate sounds almost like you want tags - I have a tags config for clojure
--exclude=.git
--exclude=.svn
--exclude=resources/*
--exclude=*/resources/*
--exclude=*/public/*
--exclude=.repl/*
--exclude=*/.repl/*
--exclude=out/*
--exclude=*/out/*
--exclude=target/*
--exclude=*/target/*
--exclude=*min.js
--langdef=Clojure
--langmap=Clojure:.clj.cljc.cljs
--regex-clojure=/\([ \t]*create-ns[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/n,namespace/
--regex-clojure=/\([ \t]*defn[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/f,function/
--regex-clojure=/\([ \t]*defn-[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/p,private function/
--regex-clojure=/\([ \t]*defmacro[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/m,macro/
--regex-clojure=/\([ \t]*definline[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/i,inline/
--regex-clojure=/\([ \t]*defmulti[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/a,multimethod definition/
--regex-clojure=/\([ \t]*defmethod[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/b,multimethod instance/
--regex-clojure=/\([ \t]*defonce[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/c,definition (once)/
--regex-clojure=/\([ \t]*defstruct[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/s,struct/
--regex-clojure=/\([ \t]*deftype[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/s,struct/
--regex-clojure=/\([ \t]*defrecord[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/s,struct/
--regex-clojure=/\([ \t]*intern[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/v,intern/
--regex-clojure=/\([ \t]*ns[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/n,namespace/
--regex-clojure=/\([ \t]*def[ \t]+(\^:[^\t ]+)*[ \t]*([^0-9:#@][^ \t\[{(]+)/\2/d,definition/
should probably be updated so it also knows about newer features like spec, but ctags runs fast and then creates a db that jumps to the definition or usage of a token
as in, you could run ctags followed by tag jump in the same amount of time most grep runs would take
I use that, coupled with vim-vista to jump around my file 🙂
we should have a community maintained ctags config for clojure, because I'm sure mine could be improved but it's much better than the other ones I've seen
That is a great idea
and who knows how many people have tried to duplicate that same config...
for starters all those usages of [ \t]*
which should surely be "whitespace*"
Which ctags do you use?
I use Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
which has Clojure built-in as a parser
oh, maybe I should try that one, I haven't tried new versions in a while
It's probably not as complete as your defs
https://github.com/universal-ctags/ctags/blob/master/parsers/clojure.c
oh yeah, that doesn't know about def, defmulti, defprotocol...
unless there's an implicit "all things starting with def" rule, but then why have a rule for "defn"
but who knows, I'm rusty at reading C
@noisesmith thanks for the tip. I used to use ctags all the time when I was a perl/python/go programmer. I'll try it out again.
I am sure you have something similar but I use this script usually
#!/bin/sh
# intended usage is the extended ctags, not eg. the OSX default, using the
# custom ctags regexes I set up for clojure
find . -name '*.clj' | xargs ctags
after that, C-] over a symbol takes me to a def (usually), and C-o takes me back again (standard vim commands of course)I wonder if C-]
can be configured to be smart about namespace aliases...
I guess clojure mode could rebind C-]
to be smart about removing the ns prefix at the very least, if not smart about picking the target based on that prefix...
> Gutentags is a plugin that takes care of the much needed management of tags files in Vim. It will (re)generate tag files as you work while staying completely out of your way. https://github.com/ludovicchabant/vim-gutentags
Also super useful: vim-fzf has :Tags
(Tags in the project (`ctags -R`)) and :BTags
(Tags in the current buffer) commands
https://github.com/junegunn/fzf.vim
yeah, fzf is great (and a great back-end for defining new commands that sort through lists of things in general)
@nate a fun project might be to use the kondo analyzer to write the grep tool you mentioned.
Totally!
or maybe the parcera babashka pod
seems like that might be more amenable to searching
Parcera doesn't necessarily have details like namespace aliases that are in play.
oooh - a babashka based tag generator for clojure :D
(plus a binding of C-]
that knows about ns / ns-alias...)
@noisesmith can tags be used to find where a keyword is used?
Maybe I'm thinking the wrong thing, buut, I'm thinking of finding uses of ::user/foo
By searching for :http://user.xxx/foo
Or I guess vice versa too
tags allow types of references, I know there's separate definitions for "def" "macro" "function" etc. - I bet there's one that fits for keywords
but that logic would need to be split between the tag generator (make it expand to the full ns) and the tag lookup (use file specific alias)
but I like tags because they exist already, they have extensive infrastructure in the editor, and they carry many semantic distinctions that other kinds of search can't distinguish
even def vs. usage is a huge win
Existing things are good. That's why I proposed grep as a format to copy.
I can wire it into vim-grepper and be cooking
keyword finding is nuanced because you can destructure in multiple ways and use namespace aliases that are all missed by grep
same with namespace usages
Yeah, that's why a custom grep is super helpful there. I actually am less interested in var search, because I find that's pretty uniform.
precisely
You could generate the arguments to grep by referring to an index of namespace aliases...
bonus: make it work with classpath entries (jars, relative paths...)
:help cscope
interesting - how common are cscope compatible analysis tools?
No idea
Maybe we'd create the first
Just an example of a modern use of cscope dbs. Although perhaps lsp is a better use of time.
there's already an LSP for clojure
but there's direct vim / LSP integration too
Yeah, I'm just asking if that's a better avenue I guess