clojure-lsp / clojure-lsp

Clojure & ClojureScript Language Server (LSP) implementation

Home Page:https://clojure-lsp.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add "Create clj-kondo hook" actions

mrkam2 opened this issue · comments

Is your feature request related to a problem? Please describe.
I'd like to automate the following, currently manual, steps I need to take to create a new clj-kondo hook:

  1. Update deps.edn file to include "resources" folder into :paths if it isn't there yet.
  2. Create resources/clj-kondo.exports/<my-org>/<my-lib>/config.edn file if it doesn't exist yet.
  3. Update this file content to assoc-in [:hooks :analyze-call <fully-qualified-macro-name>] hooks.<fully-qualified-macro-name> for analyze-call hooks and the same with :macroexpand instead of :analyze-call for the hook of the macro expand type.
  4. Create resources/clj-kondo.exports/<my-org>/<my-lib>/hooks/<namespace path>/<namespace name>.clj file.
  5. Add a new definition to this file - for :analyze-call it should be
(defn <macro-name> [{:keys [node]}]
  (let [[<macro-args>] (rest (:children node))]
     ;; TODO Add your code here.
     {:node node}))

For :macroexpand it should be

(defmacro <macro-name> [<macro-args>]
   ;; TODO Add you code here.
   )

Describe the solution you'd like
I'd like the following workflow. Open a macro in editor, invoke either "create analyze-call hook" or "create macroexpand hook" and have all of these steps performed and my cursor jump to Add your code here line.

It would also be great to have a command to jump from a macro to its hook and back (and maybe to its line in clj-kondo config file).

Reference:
https://github.com/clj-kondo/clj-kondo/blob/master/doc/hooks.md#hooks

Example:
I'm working on my-company/cool-lib project where I have feature/helper.clj namespace that has a macro (defmacro def-rule [name & specs]. I want the following two options:

  1. analyze-call option:
  • resources/clj-kondo.exports/my-company/cool-lib/config.edn file with the following new content:
    {:hooks {:analyze-call {feature.helper/def-rule hooks.feature.helper/def-rule}}}
  • resources/clj-kondo.exports/my-company/cool-lib/hooks/feature/helper.clj file with the following new content:
    (ns hooks.feature.helper
      (:require [clj-kondo.hooks-api :as api]))
    
    (defn def-rule [:{keys [node]}]
      (let [[name & specs] (rest (:children node))]
         ;; TODO Add your code here.
         {:node node}))
  1. macroexpand option:
  • resources/clj-kondo.exports/my-company/cool-lib/config.edn file with the following new content:
    {:hooks {:macroexpand {feature.helper/def-rule hooks.feature.helper/def-rule}}}
  • resources/clj-kondo.exports/my-company/cool-lib/hooks/feature/helper.clj file with the following new content:
    (ns hooks.feature.helper)
    
    (defmacro def-rule [name & specs]
       ;; TODO Add your code here.
       )

You may be interested on this one @borkdude

When exporting configs, don't use hooks/whatever for your clj-kondo namespaces, but use my_company/whatever, to avoid conflicts with others.

When exporting configs, don't use hooks/whatever for your clj-kondo namespaces, but use my_company/whatever, to avoid conflicts with others.

Makes sense. Sounds like we might want to repeat the same <my-org>/<my-lib> if those aren't already part of an original namespace, which makes the path a bit repetitive, especially considering the full path. Something like:
my-company/cool-lib/resources/clj-kondo.exports/my-company/cool-lib/my-company/cool-lib/feature/helper.clj where my-company/cool-lib is repeated 3 times.

I'm wondering if we were able to reduce this to something like this:
my-company/cool-lib/resources/clj-kondo.exports/hooks/feature/helper.clj.

Do you think this may be changed in the future?

Just check what ends up in .clj-kondo and it should be clear how clashes can happen, no changes are planned around this.